mirror of https://github.com/perkeep/perkeep.git
fileembed: extend environment-variable mode to hard-coded directory loading.
also, slurp to memory mode. for App Engine. Change-Id: Ib6de390231e4669e7a6145a8d40b646744fd028c
This commit is contained in:
parent
c38d9f6bc7
commit
916073b87b
|
@ -17,8 +17,9 @@ limitations under the License.
|
||||||
package fileembed
|
package fileembed
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"http"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"http"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -30,6 +31,13 @@ type Files struct {
|
||||||
// Optional environment variable key to override
|
// Optional environment variable key to override
|
||||||
OverrideEnv string
|
OverrideEnv string
|
||||||
|
|
||||||
|
// Optional fallback directory to check, if not in memory.
|
||||||
|
DirFallback string
|
||||||
|
|
||||||
|
// SlurpToMemory controls whether on first access the file is
|
||||||
|
// slurped into memory. It's intended for use with DirFallback.
|
||||||
|
SlurpToMemory bool
|
||||||
|
|
||||||
lk sync.Mutex
|
lk sync.Mutex
|
||||||
file map[string]string
|
file map[string]string
|
||||||
}
|
}
|
||||||
|
@ -38,6 +46,11 @@ type Files struct {
|
||||||
func (f *Files) Add(filename, body string) {
|
func (f *Files) Add(filename, body string) {
|
||||||
f.lk.Lock()
|
f.lk.Lock()
|
||||||
defer f.lk.Unlock()
|
defer f.lk.Unlock()
|
||||||
|
f.add(filename, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// f.lk must be locked
|
||||||
|
func (f *Files) add(filename, body string) {
|
||||||
if f.file == nil {
|
if f.file == nil {
|
||||||
f.file = make(map[string]string)
|
f.file = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
@ -50,16 +63,35 @@ func (f *Files) Open(filename string) (http.File, os.Error) {
|
||||||
}
|
}
|
||||||
f.lk.Lock()
|
f.lk.Lock()
|
||||||
defer f.lk.Unlock()
|
defer f.lk.Unlock()
|
||||||
if f.file == nil {
|
|
||||||
return nil, os.ENOENT
|
|
||||||
}
|
|
||||||
s, ok := f.file[filename]
|
s, ok := f.file[filename]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, os.ENOENT
|
return f.openFallback(filename)
|
||||||
}
|
}
|
||||||
return &file{name: filename, s: s}, nil
|
return &file{name: filename, s: s}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// f.lk is held
|
||||||
|
func (f *Files) openFallback(filename string) (http.File, os.Error) {
|
||||||
|
if f.DirFallback == "" {
|
||||||
|
return nil, os.ENOENT
|
||||||
|
}
|
||||||
|
of, err := os.Open(filepath.Join(f.DirFallback, filename))
|
||||||
|
switch {
|
||||||
|
case err != nil:
|
||||||
|
return nil, err
|
||||||
|
case f.SlurpToMemory:
|
||||||
|
defer of.Close()
|
||||||
|
bs, err := ioutil.ReadAll(of)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s := string(bs)
|
||||||
|
f.add(filename, s)
|
||||||
|
return &file{name: filename, s: s}, nil
|
||||||
|
}
|
||||||
|
return of, nil
|
||||||
|
}
|
||||||
|
|
||||||
type file struct {
|
type file struct {
|
||||||
name string
|
name string
|
||||||
s string
|
s string
|
||||||
|
|
Loading…
Reference in New Issue