107 lines
1.8 KiB
Go
107 lines
1.8 KiB
Go
package stream
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io"
|
|
"sync"
|
|
)
|
|
|
|
// ErrNotFoundInMem is returned when an in-memory FileSystem cannot find a file.
|
|
var ErrNotFoundInMem = errors.New("not found")
|
|
|
|
type memfs struct {
|
|
mu sync.RWMutex
|
|
files map[string]*memFile
|
|
}
|
|
|
|
// NewMemFS returns a New in-memory FileSystem
|
|
func NewMemFS() FileSystem {
|
|
return &memfs{
|
|
files: make(map[string]*memFile),
|
|
}
|
|
}
|
|
|
|
func (fs *memfs) Create(key string) (File, error) {
|
|
fs.mu.Lock()
|
|
defer fs.mu.Unlock()
|
|
|
|
file := &memFile{
|
|
name: key,
|
|
r: bytes.NewBuffer(nil),
|
|
}
|
|
file.memReader.memFile = file
|
|
fs.files[key] = file
|
|
return file, nil
|
|
}
|
|
|
|
func (fs *memfs) Open(key string) (File, error) {
|
|
fs.mu.RLock()
|
|
defer fs.mu.RUnlock()
|
|
|
|
if f, ok := fs.files[key]; ok {
|
|
return &memReader{memFile: f}, nil
|
|
}
|
|
return nil, ErrNotFoundInMem
|
|
}
|
|
|
|
func (fs *memfs) Remove(key string) error {
|
|
fs.mu.Lock()
|
|
defer fs.mu.Unlock()
|
|
delete(fs.files, key)
|
|
return nil
|
|
}
|
|
|
|
type memFile struct {
|
|
mu sync.RWMutex
|
|
name string
|
|
r *bytes.Buffer
|
|
memReader
|
|
}
|
|
|
|
func (f *memFile) Name() string {
|
|
return f.name
|
|
}
|
|
|
|
func (f *memFile) Write(p []byte) (int, error) {
|
|
if len(p) > 0 {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
return f.r.Write(p)
|
|
}
|
|
return len(p), nil
|
|
}
|
|
|
|
func (f *memFile) Bytes() []byte {
|
|
f.mu.RLock()
|
|
defer f.mu.RUnlock()
|
|
return f.r.Bytes()
|
|
}
|
|
|
|
func (f *memFile) Close() error {
|
|
return nil
|
|
}
|
|
|
|
type memReader struct {
|
|
*memFile
|
|
n int
|
|
}
|
|
|
|
func (r *memReader) ReadAt(p []byte, off int64) (n int, err error) {
|
|
data := r.Bytes()
|
|
if int64(len(data)) < off {
|
|
return 0, io.EOF
|
|
}
|
|
n, err = bytes.NewReader(data[off:]).ReadAt(p, 0)
|
|
return n, err
|
|
}
|
|
|
|
func (r *memReader) Read(p []byte) (n int, err error) {
|
|
n, err = bytes.NewReader(r.Bytes()[r.n:]).Read(p)
|
|
r.n += n
|
|
return n, err
|
|
}
|
|
|
|
func (r *memReader) Close() error {
|
|
return nil
|
|
}
|