-
Notifications
You must be signed in to change notification settings - Fork 402
/
inmemory.go
117 lines (94 loc) · 2.61 KB
/
inmemory.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
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package asset
import (
"bytes"
"errors"
"net/http"
"os"
"path"
"time"
)
var _ http.FileSystem = (*InmemoryFileSystem)(nil)
// InmemoryFileSystem defines an inmemory http.FileSystem
type InmemoryFileSystem struct {
Root *Asset
Index map[string]*Asset
}
// Inmemory creates an InmemoryFileSystem from
func Inmemory(root *Asset) *InmemoryFileSystem {
fs := &InmemoryFileSystem{}
fs.Root = root
fs.Index = map[string]*Asset{}
fs.reindex("/", "", root)
return fs
}
// reindex inserts a node to the index
func (fs *InmemoryFileSystem) reindex(prefix, name string, file *Asset) {
fs.Index[path.Join(prefix, name)] = file
for _, child := range file.Children {
fs.reindex(path.Join(prefix, name), child.Name, child)
}
}
// Open opens the file at the specified path.
func (fs *InmemoryFileSystem) Open(path string) (http.File, error) {
asset, ok := fs.Index[path]
if !ok {
return nil, os.ErrNotExist
}
return asset.File(), nil
}
// File opens the particular asset as a file.
func (asset *Asset) File() *File {
return &File{*bytes.NewReader(asset.Data), asset}
}
// File defines a readable file
type File struct {
bytes.Reader
*Asset
}
// Readdir reads all file infos from the directory.
func (file *File) Readdir(count int) ([]os.FileInfo, error) {
if !file.Mode.IsDir() {
return nil, errors.New("not a directory")
}
if count > len(file.Children) {
count = len(file.Children)
}
infos := make([]os.FileInfo, 0, count)
for _, child := range file.Children {
infos = append(infos, child.stat())
}
return infos, nil
}
func (asset *Asset) stat() FileInfo {
return FileInfo{
name: asset.Name,
size: int64(len(asset.Data)),
mode: asset.Mode,
modTime: asset.ModTime,
}
}
// Stat returns stats about the file.
func (file *File) Stat() (os.FileInfo, error) { return file.stat(), nil }
// Close closes the file.
func (file *File) Close() error { return nil }
// FileInfo implements file info.
type FileInfo struct {
name string
size int64
mode os.FileMode
modTime time.Time
}
// Name implements os.FileInfo
func (info FileInfo) Name() string { return info.name }
// Size implements os.FileInfo
func (info FileInfo) Size() int64 { return info.size }
// Mode implements os.FileInfo
func (info FileInfo) Mode() os.FileMode { return info.mode }
// ModTime implements os.FileInfo
func (info FileInfo) ModTime() time.Time { return info.modTime }
// IsDir implements os.FileInfo
func (info FileInfo) IsDir() bool { return info.mode.IsDir() }
// Sys implements os.FileInfo
func (info FileInfo) Sys() interface{} { return nil }