-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathminfs.go
134 lines (117 loc) · 3.82 KB
/
minfs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//minfs tries to provide an abstraction of a filesystem and it's most basic components. It's inspired by the godoc tool's vfs component ( https://go.googlesource.com/tools/+/master/godoc/vfs ), as well as Steve Francia's afero project ( https://github.com/spf13/afero )
//However, it tries to be A) more featured than vfs.FileSystem while B) simpler to get up and running than afero.Fs.
package minfs
import (
"errors"
"fmt"
"os"
)
type MinFS interface {
//Create a file. Should throw an error if file already exists.
CreateFile(name string) error
//Write to a file. Should throw an error if file doesn't exists.
WriteFile(name string, b []byte, off int64) (int, error)
//Read from a file.
ReadFile(name string, b []byte, off int64) (int, error)
//Create a directory. Should throw an error if directory already exists.
CreateDirectory(name string) error
ReadDirectory(name string) ([]os.FileInfo, error) //No "." or ".." entries allowed
Move(oldpath string, newpath string) error
//Whether or not a Remove on a non-empty directory succeeds is implementation dependant
Remove(name string) error
Stat(name string) (os.FileInfo, error)
String() string
GetAttribute(path string, attribute string) (interface{}, error)
SetAttribute(path string, attribute string, newvalue interface{}) error
Close() error
}
// minFile isn't actually used in unfs2go, but it's got some code that might be useful so I'll just leave it here.
type minFile struct {
fs MinFS //Filesystem it's in
path string //path being referred to
flag int
perm os.FileMode
currOffset int64
}
func (f minFile) WriteAt(b []byte, off int64) (int, error) {
return f.fs.WriteFile(f.path, b, off)
}
func (f minFile) Stat() (os.FileInfo, error) {
return f.fs.Stat(f.path)
}
func (f minFile) Read(b []byte) (int, error) {
n, err := f.fs.ReadFile(f.path, b, f.currOffset)
f.currOffset += int64(n)
return n, err
}
func (f minFile) WriteString(s string) (int, error) {
return f.Write([]byte(s))
}
func (f minFile) Write(b []byte) (int, error) {
n, err := f.fs.WriteFile(f.path, b, f.currOffset)
f.currOffset += int64(n)
return n, err
}
func (f minFile) Seek(offset int64, whence int) (int64, error) {
fi, err := f.fs.Stat(f.path)
if err != nil {
size := fi.Size()
switch whence {
case 0:
if offset <= size {
f.currOffset = offset
} else {
err = errors.New(fmt.Sprint("Seek Error on", f.path, ": Offset too big 0:", offset, "filesize:", size))
}
case 1:
offset += f.currOffset
if offset <= size {
f.currOffset = offset
} else {
err = errors.New(fmt.Sprint("Seek Error on", f.path, ": Offset too big 1:", offset, "filesize:", size))
}
case 2:
err = errors.New(fmt.Sprint("Seek Error: Dunno how to do this 2:", offset, "filesize:", size))
default:
err = errors.New(fmt.Sprint("Seek Error: Invalid whence:", whence))
}
} else {
err = errors.New(fmt.Sprint("Seek Error on", f.path, ":", err.Error()))
}
return f.currOffset, err
}
func (f minFile) ReadAt(b []byte, off int64) (int, error) {
return f.fs.ReadFile(f.path, b, off)
}
func (f minFile) Close() error {
if f.fs == nil {
return errors.New("Close Error: Already closed " + f.path)
}
f.fs = nil
return nil
}
func (f minFile) Sync() error {
if f.fs == nil {
return errors.New("Sync Error: Already closed " + f.path)
}
f.fs = nil
return nil
}
func (f minFile) Readdir(count int) ([]os.FileInfo, error) {
ta, err := f.fs.ReadDirectory(f.path)
return ta[:count], err
}
func (f minFile) Readdirnames(count int) ([]string, error) {
ta, err := f.fs.ReadDirectory(f.path)
retVal := make([]string, count)
for i, _ := range retVal {
retVal[i] = ta[i].Name()
}
return retVal, err
}
func (f minFile) Name() string {
return f.path + " in " + f.fs.String()
}
func (f minFile) Truncate(newSize int64) error {
return f.fs.SetAttribute(f.path, "size", newSize)
}