123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- // This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
- // license. Its contents can be found at:
- // http://creativecommons.org/publicdomain/zero/1.0/
- package bindata
- import (
- "bytes"
- "compress/gzip"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "unicode/utf8"
- )
- // writeRelease writes the release code file.
- func writeRelease(w io.Writer, c *Config, toc []Asset) error {
- err := writeReleaseHeader(w, c)
- if err != nil {
- return err
- }
- for i := range toc {
- err = writeReleaseAsset(w, c, &toc[i])
- if err != nil {
- return err
- }
- }
- return nil
- }
- // writeReleaseHeader writes output file headers.
- // This targets release builds.
- func writeReleaseHeader(w io.Writer, c *Config) error {
- var err error
- if c.NoCompress {
- if c.NoMemCopy {
- err = header_uncompressed_nomemcopy(w)
- } else {
- err = header_uncompressed_memcopy(w)
- }
- } else {
- if c.NoMemCopy {
- err = header_compressed_nomemcopy(w)
- } else {
- err = header_compressed_memcopy(w)
- }
- }
- if err != nil {
- return err
- }
- return header_release_common(w)
- }
- // writeReleaseAsset write a release entry for the given asset.
- // A release entry is a function which embeds and returns
- // the file's byte content.
- func writeReleaseAsset(w io.Writer, c *Config, asset *Asset) error {
- fd, err := os.Open(asset.Path)
- if err != nil {
- return err
- }
- defer fd.Close()
- if c.NoCompress {
- if c.NoMemCopy {
- err = uncompressed_nomemcopy(w, asset, fd)
- } else {
- err = uncompressed_memcopy(w, asset, fd)
- }
- } else {
- if c.NoMemCopy {
- err = compressed_nomemcopy(w, asset, fd)
- } else {
- err = compressed_memcopy(w, asset, fd)
- }
- }
- if err != nil {
- return err
- }
- return asset_release_common(w, c, asset)
- }
- // sanitize prepares a valid UTF-8 string as a raw string constant.
- // Based on https://code.google.com/p/go/source/browse/godoc/static/makestatic.go?repo=tools
- func sanitize(b []byte) []byte {
- // Replace ` with `+"`"+`
- b = bytes.Replace(b, []byte("`"), []byte("`+\"`\"+`"), -1)
- // Replace BOM with `+"\xEF\xBB\xBF"+`
- // (A BOM is valid UTF-8 but not permitted in Go source files.
- // I wouldn't bother handling this, but for some insane reason
- // jquery.js has a BOM somewhere in the middle.)
- return bytes.Replace(b, []byte("\xEF\xBB\xBF"), []byte("`+\"\\xEF\\xBB\\xBF\"+`"), -1)
- }
- func header_compressed_nomemcopy(w io.Writer) error {
- _, err := fmt.Fprintf(w, `import (
- "bytes"
- "compress/gzip"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "time"
- )
- func bindataRead(data, name string) ([]byte, error) {
- gz, err := gzip.NewReader(strings.NewReader(data))
- if err != nil {
- return nil, fmt.Errorf("Read %%q: %%v", name, err)
- }
- var buf bytes.Buffer
- _, err = io.Copy(&buf, gz)
- clErr := gz.Close()
- if err != nil {
- return nil, fmt.Errorf("Read %%q: %%v", name, err)
- }
- if clErr != nil {
- return nil, err
- }
- return buf.Bytes(), nil
- }
- `)
- return err
- }
- func header_compressed_memcopy(w io.Writer) error {
- _, err := fmt.Fprintf(w, `import (
- "bytes"
- "compress/gzip"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "time"
- )
- func bindataRead(data []byte, name string) ([]byte, error) {
- gz, err := gzip.NewReader(bytes.NewBuffer(data))
- if err != nil {
- return nil, fmt.Errorf("Read %%q: %%v", name, err)
- }
- var buf bytes.Buffer
- _, err = io.Copy(&buf, gz)
- clErr := gz.Close()
- if err != nil {
- return nil, fmt.Errorf("Read %%q: %%v", name, err)
- }
- if clErr != nil {
- return nil, err
- }
- return buf.Bytes(), nil
- }
- `)
- return err
- }
- func header_uncompressed_nomemcopy(w io.Writer) error {
- _, err := fmt.Fprintf(w, `import (
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "reflect"
- "strings"
- "time"
- "unsafe"
- )
- func bindataRead(data, name string) ([]byte, error) {
- var empty [0]byte
- sx := (*reflect.StringHeader)(unsafe.Pointer(&data))
- b := empty[:]
- bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
- bx.Data = sx.Data
- bx.Len = len(data)
- bx.Cap = bx.Len
- return b, nil
- }
- `)
- return err
- }
- func header_uncompressed_memcopy(w io.Writer) error {
- _, err := fmt.Fprintf(w, `import (
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "time"
- )
- `)
- return err
- }
- func header_release_common(w io.Writer) error {
- _, err := fmt.Fprintf(w, `type asset struct {
- bytes []byte
- info os.FileInfo
- }
- type bindataFileInfo struct {
- name string
- size int64
- mode os.FileMode
- modTime time.Time
- }
- func (fi bindataFileInfo) Name() string {
- return fi.name
- }
- func (fi bindataFileInfo) Size() int64 {
- return fi.size
- }
- func (fi bindataFileInfo) Mode() os.FileMode {
- return fi.mode
- }
- func (fi bindataFileInfo) ModTime() time.Time {
- return fi.modTime
- }
- func (fi bindataFileInfo) IsDir() bool {
- return false
- }
- func (fi bindataFileInfo) Sys() interface{} {
- return nil
- }
- `)
- return err
- }
- func compressed_nomemcopy(w io.Writer, asset *Asset, r io.Reader) error {
- _, err := fmt.Fprintf(w, `var _%s = "`, asset.Func)
- if err != nil {
- return err
- }
- gz := gzip.NewWriter(&StringWriter{Writer: w})
- _, err = io.Copy(gz, r)
- gz.Close()
- if err != nil {
- return err
- }
- _, err = fmt.Fprintf(w, `"
- func %sBytes() ([]byte, error) {
- return bindataRead(
- _%s,
- %q,
- )
- }
- `, asset.Func, asset.Func, asset.Name)
- return err
- }
- func compressed_memcopy(w io.Writer, asset *Asset, r io.Reader) error {
- _, err := fmt.Fprintf(w, `var _%s = []byte("`, asset.Func)
- if err != nil {
- return err
- }
- gz := gzip.NewWriter(&StringWriter{Writer: w})
- _, err = io.Copy(gz, r)
- gz.Close()
- if err != nil {
- return err
- }
- _, err = fmt.Fprintf(w, `")
- func %sBytes() ([]byte, error) {
- return bindataRead(
- _%s,
- %q,
- )
- }
- `, asset.Func, asset.Func, asset.Name)
- return err
- }
- func uncompressed_nomemcopy(w io.Writer, asset *Asset, r io.Reader) error {
- _, err := fmt.Fprintf(w, `var _%s = "`, asset.Func)
- if err != nil {
- return err
- }
- _, err = io.Copy(&StringWriter{Writer: w}, r)
- if err != nil {
- return err
- }
- _, err = fmt.Fprintf(w, `"
- func %sBytes() ([]byte, error) {
- return bindataRead(
- _%s,
- %q,
- )
- }
- `, asset.Func, asset.Func, asset.Name)
- return err
- }
- func uncompressed_memcopy(w io.Writer, asset *Asset, r io.Reader) error {
- _, err := fmt.Fprintf(w, `var _%s = []byte(`, asset.Func)
- if err != nil {
- return err
- }
- b, err := ioutil.ReadAll(r)
- if err != nil {
- return err
- }
- if utf8.Valid(b) && !bytes.Contains(b, []byte{0}) {
- fmt.Fprintf(w, "`%s`", sanitize(b))
- } else {
- fmt.Fprintf(w, "%+q", b)
- }
- _, err = fmt.Fprintf(w, `)
- func %sBytes() ([]byte, error) {
- return _%s, nil
- }
- `, asset.Func, asset.Func)
- return err
- }
- func asset_release_common(w io.Writer, c *Config, asset *Asset) error {
- fi, err := os.Stat(asset.Path)
- if err != nil {
- return err
- }
- mode := uint(fi.Mode())
- modTime := fi.ModTime().Unix()
- size := fi.Size()
- if c.NoMetadata {
- mode = 0
- modTime = 0
- size = 0
- }
- if c.Mode > 0 {
- mode = uint(os.ModePerm) & c.Mode
- }
- if c.ModTime > 0 {
- modTime = c.ModTime
- }
- _, err = fmt.Fprintf(w, `func %s() (*asset, error) {
- bytes, err := %sBytes()
- if err != nil {
- return nil, err
- }
- info := bindataFileInfo{name: %q, size: %d, mode: os.FileMode(%d), modTime: time.Unix(%d, 0)}
- a := &asset{bytes: bytes, info: info}
- return a, nil
- }
- `, asset.Func, asset.Func, asset.Name, size, mode, modTime)
- return err
- }
|