route/vendor/github.com/go-serve/bindatafs/bindatafs.go

171 lines
3.8 KiB
Go

// Package bindatafs provides wrapper vfs.FileSystem implementation to bridge
// go-bindata-generated assets to be served by http.FileServer.
package bindatafs
import (
"bytes"
"os"
"path"
"syscall"
"golang.org/x/tools/godoc/vfs"
)
// FileSystem is a copy of vfs interface FileSystem
type FileSystem interface {
vfs.Opener
Lstat(path string) (os.FileInfo, error)
Stat(path string) (os.FileInfo, error)
ReadDir(path string) ([]os.FileInfo, error)
String() string
}
// New returns a FileSystem implementation of the given go-bindata generated assets
func New(name string, Asset AssetFunc, AssetDir AssetDirFunc, AssetInfo AssetInfoFunc) FileSystem {
return &binAssets{
name: name,
Asset: Asset,
AssetDir: AssetDir,
AssetInfo: AssetInfo,
}
}
// AssetFunc is the Assets() function generated by go-bindata
type AssetFunc func(name string) ([]byte, error)
// AssetDirFunc is the AssetDir() function generated by go-bindata
type AssetDirFunc func(name string) ([]string, error)
// AssetInfoFunc is the AssetInfo() function generated by go-bindata
type AssetInfoFunc func(name string) (os.FileInfo, error)
type binAssets struct {
name string
Asset AssetFunc
AssetDir AssetDirFunc
AssetInfo AssetInfoFunc
}
func (binAssets *binAssets) Open(pathname string) (file vfs.ReadSeekCloser, err error) {
pathname = binAssets.pathname(pathname)
// if is dir, return a dummy assetDir
if _, err = binAssets.AssetDir(pathname); err == nil {
err = &os.PathError{
Op: "Open",
Path: pathname,
Err: syscall.ENOENT,
}
return
}
// if is a file, return buffered data
var data []byte
if data, err = binAssets.Asset(pathname); err == nil {
file = &FileReader{Reader: bytes.NewReader(data)}
return
}
err = &os.PathError{
Op: "Open",
Path: pathname,
Err: syscall.ENOENT,
}
return
}
func (binAssets *binAssets) Lstat(pathname string) (fi os.FileInfo, err error) {
return binAssets.Stat(pathname)
}
func (binAssets binAssets) pathname(pathname string) string {
if len(pathname) > 0 && pathname[0] == '/' {
return pathname[1:]
}
return pathname
}
func (binAssets *binAssets) Stat(pathname string) (fi os.FileInfo, err error) {
pathname = binAssets.pathname(pathname)
// if is dir, return a dummy assetDir
if _, err = binAssets.AssetDir(pathname); err == nil {
fi = &dirInfo{name: path.Base(pathname)}
return
}
// if is a file, return buffered data
if fi, err = binAssets.AssetInfo(pathname); err == nil {
fi = &fileInfo{name: path.Base(pathname), FileInfo: fi}
return
}
// return standard not found signal
err = &os.PathError{
Op: "Stat",
Path: pathname,
Err: syscall.ENOENT,
}
return
}
func (binAssets *binAssets) ReadDir(pathname string) (fiList []os.FileInfo, err error) {
pathname = binAssets.pathname(pathname)
// if is a file, return error
if _, err = binAssets.AssetInfo(pathname); err == nil {
err = &os.PathError{
Op: "ReadDir",
Path: pathname,
Err: syscall.ENOENT,
}
return
}
// if is dir, return a dummy assetDir
var names []string
if names, err = binAssets.AssetDir(pathname); err != nil {
err = &os.PathError{
Op: "ReadDir",
Path: pathname,
Err: syscall.ENOENT,
}
return
}
// read all names entity to file info
fiList = make([]os.FileInfo, len(names))
for i, name := range names {
fiList[i], err = binAssets.Stat(path.Join(pathname, name))
}
return
}
func (binAssets *binAssets) String() string {
return binAssets.name
}
// FileReader implements vfs.ReadSeekCloser
type FileReader struct {
*bytes.Reader
}
// Read implements io.Reader
func (r *FileReader) Read(p []byte) (int, error) {
return r.Reader.Read(p)
}
// Seek implements io.Seeker
func (r *FileReader) Seek(offset int64, whence int) (int64, error) {
return r.Reader.Seek(offset, whence)
}
// Close implements io.Closer
func (r *FileReader) Close() error {
return nil
}