Files
polaris/vendor/github.com/gobuffalo/packd/memory_box.go
Bobby Brennan 54a4f92695 Pack static assets into packr box for portability
copy config.yaml to docker image

enable external usage of dashboard package

gofmt

fix comment

use packr for assets

add gobuffalo/packr dependency

add dependencies

fix pointer issues

add output-file option
2019-04-18 18:25:16 +00:00

158 lines
2.8 KiB
Go

package packd
import (
"bytes"
"net/http"
"os"
"path/filepath"
"sort"
"strings"
"github.com/gobuffalo/syncx"
"github.com/pkg/errors"
)
var _ Addable = NewMemoryBox()
var _ Finder = NewMemoryBox()
var _ Lister = NewMemoryBox()
var _ HTTPBox = NewMemoryBox()
var _ Haser = NewMemoryBox()
var _ Walkable = NewMemoryBox()
var _ Box = NewMemoryBox()
// MemoryBox is a thread-safe, in-memory, implementation of the Box interface.
type MemoryBox struct {
files *syncx.ByteMap
}
func (m *MemoryBox) Has(path string) bool {
_, ok := m.files.Load(path)
return ok
}
func (m *MemoryBox) List() []string {
var names []string
m.files.Range(func(key string, value []byte) bool {
names = append(names, key)
return true
})
sort.Strings(names)
return names
}
func (m *MemoryBox) Open(path string) (http.File, error) {
cpath := strings.TrimPrefix(path, "/")
if filepath.Ext(cpath) == "" {
// it's a directory
return NewDir(path)
}
if len(cpath) == 0 {
cpath = "index.html"
}
b, err := m.Find(cpath)
if err != nil {
return nil, err
}
cpath = filepath.FromSlash(cpath)
f, err := NewFile(cpath, bytes.NewReader(b))
if err != nil {
return nil, err
}
return f, nil
}
func (m *MemoryBox) FindString(path string) (string, error) {
bb, err := m.Find(path)
return string(bb), err
}
func (m *MemoryBox) Find(path string) (ret []byte, e error) {
res, ok := m.files.Load(path)
if !ok {
var b []byte
lpath := strings.ToLower(path)
err := m.Walk(func(p string, file File) error {
lp := strings.ToLower(p)
if lp != lpath {
return nil
}
res := file.String()
b = []byte(res)
return nil
})
if err != nil {
return b, os.ErrNotExist
}
if len(b) == 0 {
return b, os.ErrNotExist
}
return b, nil
}
return res, nil
}
func (m *MemoryBox) AddString(path string, t string) error {
return m.AddBytes(path, []byte(t))
}
func (m *MemoryBox) AddBytes(path string, t []byte) error {
m.files.Store(path, t)
return nil
}
func (m *MemoryBox) Walk(wf WalkFunc) error {
var err error
m.files.Range(func(path string, b []byte) bool {
var f File
f, err = NewFile(path, bytes.NewReader(b))
if err != nil {
return false
}
err = wf(path, f)
if err != nil {
if errors.Cause(err) == filepath.SkipDir {
err = nil
return true
}
return false
}
return true
})
if errors.Cause(err) == filepath.SkipDir {
return nil
}
return err
}
func (m *MemoryBox) WalkPrefix(pre string, wf WalkFunc) error {
return m.Walk(func(path string, file File) error {
if strings.HasPrefix(path, pre) {
return wf(path, file)
}
return nil
})
}
func (m *MemoryBox) Remove(path string) {
m.files.Delete(path)
m.files.Delete(strings.ToLower(path))
}
// NewMemoryBox returns a configured *MemoryBox
func NewMemoryBox() *MemoryBox {
return &MemoryBox{
files: &syncx.ByteMap{},
}
}