mirror of https://github.com/q191201771/naza
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
2.8 KiB
Go
149 lines
2.8 KiB
Go
// Copyright 2021, Chef. All rights reserved.
|
|
// https://github.com/q191201771/naza
|
|
//
|
|
// Use of this source code is governed by a MIT-style license
|
|
// that can be found in the License file.
|
|
//
|
|
// Author: Chef (191201771@qq.com)
|
|
|
|
package filesystemlayer
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
var ErrNotFound = errors.New("naza filesystemlayer: not found")
|
|
|
|
type FslMemory struct {
|
|
mu sync.Mutex
|
|
files map[string]*file // key filename
|
|
}
|
|
|
|
type file struct {
|
|
buf []byte
|
|
}
|
|
|
|
func NewFslMemory() *FslMemory {
|
|
return &FslMemory{
|
|
files: make(map[string]*file),
|
|
}
|
|
}
|
|
|
|
func (f *FslMemory) Type() FslType {
|
|
return FslTypeMemory
|
|
}
|
|
|
|
func (f *FslMemory) Create(name string) (IFile, error) {
|
|
return f.openFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
|
}
|
|
|
|
func (f *FslMemory) Rename(oldpath string, newpath string) error {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
fi, exist := f.files[oldpath]
|
|
if !exist {
|
|
return ErrNotFound
|
|
}
|
|
delete(f.files, oldpath)
|
|
f.files[newpath] = fi
|
|
return nil
|
|
}
|
|
|
|
func (f *FslMemory) MkdirAll(path string, perm uint32) error {
|
|
return nil
|
|
}
|
|
|
|
func (f *FslMemory) Remove(name string) error {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
_, exist := f.files[name]
|
|
if !exist {
|
|
return ErrNotFound
|
|
}
|
|
delete(f.files, name)
|
|
return nil
|
|
}
|
|
|
|
func (f *FslMemory) RemoveAll(path string) error {
|
|
if !os.IsPathSeparator(path[len(path)-1]) {
|
|
path = fmt.Sprintf("%s%c", path, os.PathSeparator)
|
|
}
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
files := make(map[string]*file)
|
|
for k, v := range f.files {
|
|
if !strings.HasPrefix(k, path) {
|
|
files[k] = v
|
|
}
|
|
}
|
|
f.files = files
|
|
|
|
return nil
|
|
}
|
|
|
|
func (f *FslMemory) ReadFile(filename string) ([]byte, error) {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
fi, exist := f.files[filename]
|
|
if !exist {
|
|
return nil, ErrNotFound
|
|
}
|
|
return fi.clone(), nil
|
|
}
|
|
|
|
func (f *FslMemory) WriteFile(filename string, data []byte, perm uint32) error {
|
|
fi, err := f.openFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = fi.Write(data)
|
|
if err1 := fi.Close(); err == nil {
|
|
err = err1
|
|
}
|
|
return err
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
func (f *FslMemory) openFile(name string, flag int, perm uint32) (IFile, error) {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
fi, ok := f.files[name]
|
|
if !ok {
|
|
fi = &file{}
|
|
f.files[name] = fi
|
|
return fi, nil
|
|
}
|
|
|
|
fi.truncate()
|
|
return fi, nil
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
func (f *file) Write(b []byte) (n int, err error) {
|
|
f.buf = append(f.buf, b...)
|
|
return len(b), nil
|
|
}
|
|
|
|
func (f *file) Close() error {
|
|
return nil
|
|
}
|
|
|
|
func (f *file) truncate() {
|
|
f.buf = nil
|
|
}
|
|
|
|
func (f *file) clone() []byte {
|
|
if f.buf == nil {
|
|
return nil
|
|
}
|
|
b := make([]byte, len(f.buf))
|
|
copy(b, f.buf)
|
|
return b
|
|
}
|