summaryrefslogtreecommitdiffstats
path: root/src/dma/vendor/github.com/valyala/fasttemplate
diff options
context:
space:
mode:
Diffstat (limited to 'src/dma/vendor/github.com/valyala/fasttemplate')
-rw-r--r--src/dma/vendor/github.com/valyala/fasttemplate/LICENSE22
-rw-r--r--src/dma/vendor/github.com/valyala/fasttemplate/README.md85
-rw-r--r--src/dma/vendor/github.com/valyala/fasttemplate/template.go317
-rw-r--r--src/dma/vendor/github.com/valyala/fasttemplate/unsafe.go22
-rw-r--r--src/dma/vendor/github.com/valyala/fasttemplate/unsafe_gae.go11
5 files changed, 457 insertions, 0 deletions
diff --git a/src/dma/vendor/github.com/valyala/fasttemplate/LICENSE b/src/dma/vendor/github.com/valyala/fasttemplate/LICENSE
new file mode 100644
index 00000000..7125a63c
--- /dev/null
+++ b/src/dma/vendor/github.com/valyala/fasttemplate/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Aliaksandr Valialkin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/src/dma/vendor/github.com/valyala/fasttemplate/README.md b/src/dma/vendor/github.com/valyala/fasttemplate/README.md
new file mode 100644
index 00000000..3a4d56ce
--- /dev/null
+++ b/src/dma/vendor/github.com/valyala/fasttemplate/README.md
@@ -0,0 +1,85 @@
+fasttemplate
+============
+
+Simple and fast template engine for Go.
+
+Fasttemplate peforms only a single task - it substitutes template placeholders
+with user-defined values. At high speed :)
+
+Take a look at [quicktemplate](https://github.com/valyala/quicktemplate) if you need fast yet powerful html template engine.
+
+*Please note that fasttemplate doesn't do any escaping on template values
+unlike [html/template](http://golang.org/pkg/html/template/) do. So values
+must be properly escaped before passing them to fasttemplate.*
+
+Fasttemplate is faster than [text/template](http://golang.org/pkg/text/template/),
+[strings.Replace](http://golang.org/pkg/strings/#Replace),
+[strings.Replacer](http://golang.org/pkg/strings/#Replacer)
+and [fmt.Fprintf](https://golang.org/pkg/fmt/#Fprintf) on placeholders' substitution.
+
+Below are benchmark results comparing fasttemplate performance to text/template,
+strings.Replace, strings.Replacer and fmt.Fprintf:
+
+```
+$ go test -bench=. -benchmem
+PASS
+BenchmarkFmtFprintf-4 2000000 790 ns/op 0 B/op 0 allocs/op
+BenchmarkStringsReplace-4 500000 3474 ns/op 2112 B/op 14 allocs/op
+BenchmarkStringsReplacer-4 500000 2657 ns/op 2256 B/op 23 allocs/op
+BenchmarkTextTemplate-4 500000 3333 ns/op 336 B/op 19 allocs/op
+BenchmarkFastTemplateExecuteFunc-4 5000000 349 ns/op 0 B/op 0 allocs/op
+BenchmarkFastTemplateExecute-4 3000000 383 ns/op 0 B/op 0 allocs/op
+BenchmarkFastTemplateExecuteFuncString-4 3000000 549 ns/op 144 B/op 1 allocs/op
+BenchmarkFastTemplateExecuteString-4 3000000 572 ns/op 144 B/op 1 allocs/op
+BenchmarkFastTemplateExecuteTagFunc-4 2000000 743 ns/op 144 B/op 3 allocs/op
+```
+
+
+Docs
+====
+
+See http://godoc.org/github.com/valyala/fasttemplate .
+
+
+Usage
+=====
+
+```go
+ template := "http://{{host}}/?q={{query}}&foo={{bar}}{{bar}}"
+ t := fasttemplate.New(template, "{{", "}}")
+ s := t.ExecuteString(map[string]interface{}{
+ "host": "google.com",
+ "query": url.QueryEscape("hello=world"),
+ "bar": "foobar",
+ })
+ fmt.Printf("%s", s)
+
+ // Output:
+ // http://google.com/?q=hello%3Dworld&foo=foobarfoobar
+```
+
+
+Advanced usage
+==============
+
+```go
+ template := "Hello, [user]! You won [prize]!!! [foobar]"
+ t, err := fasttemplate.NewTemplate(template, "[", "]")
+ if err != nil {
+ log.Fatalf("unexpected error when parsing template: %s", err)
+ }
+ s := t.ExecuteFuncString(func(w io.Writer, tag string) (int, error) {
+ switch tag {
+ case "user":
+ return w.Write([]byte("John"))
+ case "prize":
+ return w.Write([]byte("$100500"))
+ default:
+ return w.Write([]byte(fmt.Sprintf("[unknown tag %q]", tag)))
+ }
+ })
+ fmt.Printf("%s", s)
+
+ // Output:
+ // Hello, John! You won $100500!!! [unknown tag "foobar"]
+```
diff --git a/src/dma/vendor/github.com/valyala/fasttemplate/template.go b/src/dma/vendor/github.com/valyala/fasttemplate/template.go
new file mode 100644
index 00000000..91209201
--- /dev/null
+++ b/src/dma/vendor/github.com/valyala/fasttemplate/template.go
@@ -0,0 +1,317 @@
+// Package fasttemplate implements simple and fast template library.
+//
+// Fasttemplate is faster than text/template, strings.Replace
+// and strings.Replacer.
+//
+// Fasttemplate ideally fits for fast and simple placeholders' substitutions.
+package fasttemplate
+
+import (
+ "bytes"
+ "fmt"
+ "github.com/valyala/bytebufferpool"
+ "io"
+)
+
+// ExecuteFunc calls f on each template tag (placeholder) occurrence.
+//
+// Returns the number of bytes written to w.
+//
+// This function is optimized for constantly changing templates.
+// Use Template.ExecuteFunc for frozen templates.
+func ExecuteFunc(template, startTag, endTag string, w io.Writer, f TagFunc) (int64, error) {
+ s := unsafeString2Bytes(template)
+ a := unsafeString2Bytes(startTag)
+ b := unsafeString2Bytes(endTag)
+
+ var nn int64
+ var ni int
+ var err error
+ for {
+ n := bytes.Index(s, a)
+ if n < 0 {
+ break
+ }
+ ni, err = w.Write(s[:n])
+ nn += int64(ni)
+ if err != nil {
+ return nn, err
+ }
+
+ s = s[n+len(a):]
+ n = bytes.Index(s, b)
+ if n < 0 {
+ // cannot find end tag - just write it to the output.
+ ni, _ = w.Write(a)
+ nn += int64(ni)
+ break
+ }
+
+ ni, err = f(w, unsafeBytes2String(s[:n]))
+ nn += int64(ni)
+ s = s[n+len(b):]
+ }
+ ni, err = w.Write(s)
+ nn += int64(ni)
+
+ return nn, err
+}
+
+// Execute substitutes template tags (placeholders) with the corresponding
+// values from the map m and writes the result to the given writer w.
+//
+// Substitution map m may contain values with the following types:
+// * []byte - the fastest value type
+// * string - convenient value type
+// * TagFunc - flexible value type
+//
+// Returns the number of bytes written to w.
+//
+// This function is optimized for constantly changing templates.
+// Use Template.Execute for frozen templates.
+func Execute(template, startTag, endTag string, w io.Writer, m map[string]interface{}) (int64, error) {
+ return ExecuteFunc(template, startTag, endTag, w, func(w io.Writer, tag string) (int, error) { return stdTagFunc(w, tag, m) })
+}
+
+// ExecuteFuncString calls f on each template tag (placeholder) occurrence
+// and substitutes it with the data written to TagFunc's w.
+//
+// Returns the resulting string.
+//
+// This function is optimized for constantly changing templates.
+// Use Template.ExecuteFuncString for frozen templates.
+func ExecuteFuncString(template, startTag, endTag string, f TagFunc) string {
+ tagsCount := bytes.Count(unsafeString2Bytes(template), unsafeString2Bytes(startTag))
+ if tagsCount == 0 {
+ return template
+ }
+
+ bb := byteBufferPool.Get()
+ if _, err := ExecuteFunc(template, startTag, endTag, bb, f); err != nil {
+ panic(fmt.Sprintf("unexpected error: %s", err))
+ }
+ s := string(bb.B)
+ bb.Reset()
+ byteBufferPool.Put(bb)
+ return s
+}
+
+var byteBufferPool bytebufferpool.Pool
+
+// ExecuteString substitutes template tags (placeholders) with the corresponding
+// values from the map m and returns the result.
+//
+// Substitution map m may contain values with the following types:
+// * []byte - the fastest value type
+// * string - convenient value type
+// * TagFunc - flexible value type
+//
+// This function is optimized for constantly changing templates.
+// Use Template.ExecuteString for frozen templates.
+func ExecuteString(template, startTag, endTag string, m map[string]interface{}) string {
+ return ExecuteFuncString(template, startTag, endTag, func(w io.Writer, tag string) (int, error) { return stdTagFunc(w, tag, m) })
+}
+
+// Template implements simple template engine, which can be used for fast
+// tags' (aka placeholders) substitution.
+type Template struct {
+ template string
+ startTag string
+ endTag string
+
+ texts [][]byte
+ tags []string
+ byteBufferPool bytebufferpool.Pool
+}
+
+// New parses the given template using the given startTag and endTag
+// as tag start and tag end.
+//
+// The returned template can be executed by concurrently running goroutines
+// using Execute* methods.
+//
+// New panics if the given template cannot be parsed. Use NewTemplate instead
+// if template may contain errors.
+func New(template, startTag, endTag string) *Template {
+ t, err := NewTemplate(template, startTag, endTag)
+ if err != nil {
+ panic(err)
+ }
+ return t
+}
+
+// NewTemplate parses the given template using the given startTag and endTag
+// as tag start and tag end.
+//
+// The returned template can be executed by concurrently running goroutines
+// using Execute* methods.
+func NewTemplate(template, startTag, endTag string) (*Template, error) {
+ var t Template
+ err := t.Reset(template, startTag, endTag)
+ if err != nil {
+ return nil, err
+ }
+ return &t, nil
+}
+
+// TagFunc can be used as a substitution value in the map passed to Execute*.
+// Execute* functions pass tag (placeholder) name in 'tag' argument.
+//
+// TagFunc must be safe to call from concurrently running goroutines.
+//
+// TagFunc must write contents to w and return the number of bytes written.
+type TagFunc func(w io.Writer, tag string) (int, error)
+
+// Reset resets the template t to new one defined by
+// template, startTag and endTag.
+//
+// Reset allows Template object re-use.
+//
+// Reset may be called only if no other goroutines call t methods at the moment.
+func (t *Template) Reset(template, startTag, endTag string) error {
+ // Keep these vars in t, so GC won't collect them and won't break
+ // vars derived via unsafe*
+ t.template = template
+ t.startTag = startTag
+ t.endTag = endTag
+ t.texts = t.texts[:0]
+ t.tags = t.tags[:0]
+
+ if len(startTag) == 0 {
+ panic("startTag cannot be empty")
+ }
+ if len(endTag) == 0 {
+ panic("endTag cannot be empty")
+ }
+
+ s := unsafeString2Bytes(template)
+ a := unsafeString2Bytes(startTag)
+ b := unsafeString2Bytes(endTag)
+
+ tagsCount := bytes.Count(s, a)
+ if tagsCount == 0 {
+ return nil
+ }
+
+ if tagsCount+1 > cap(t.texts) {
+ t.texts = make([][]byte, 0, tagsCount+1)
+ }
+ if tagsCount > cap(t.tags) {
+ t.tags = make([]string, 0, tagsCount)
+ }
+
+ for {
+ n := bytes.Index(s, a)
+ if n < 0 {
+ t.texts = append(t.texts, s)
+ break
+ }
+ t.texts = append(t.texts, s[:n])
+
+ s = s[n+len(a):]
+ n = bytes.Index(s, b)
+ if n < 0 {
+ return fmt.Errorf("Cannot find end tag=%q in the template=%q starting from %q", endTag, template, s)
+ }
+
+ t.tags = append(t.tags, unsafeBytes2String(s[:n]))
+ s = s[n+len(b):]
+ }
+
+ return nil
+}
+
+// ExecuteFunc calls f on each template tag (placeholder) occurrence.
+//
+// Returns the number of bytes written to w.
+//
+// This function is optimized for frozen templates.
+// Use ExecuteFunc for constantly changing templates.
+func (t *Template) ExecuteFunc(w io.Writer, f TagFunc) (int64, error) {
+ var nn int64
+
+ n := len(t.texts) - 1
+ if n == -1 {
+ ni, err := w.Write(unsafeString2Bytes(t.template))
+ return int64(ni), err
+ }
+
+ for i := 0; i < n; i++ {
+ ni, err := w.Write(t.texts[i])
+ nn += int64(ni)
+ if err != nil {
+ return nn, err
+ }
+
+ ni, err = f(w, t.tags[i])
+ nn += int64(ni)
+ if err != nil {
+ return nn, err
+ }
+ }
+ ni, err := w.Write(t.texts[n])
+ nn += int64(ni)
+ return nn, err
+}
+
+// Execute substitutes template tags (placeholders) with the corresponding
+// values from the map m and writes the result to the given writer w.
+//
+// Substitution map m may contain values with the following types:
+// * []byte - the fastest value type
+// * string - convenient value type
+// * TagFunc - flexible value type
+//
+// Returns the number of bytes written to w.
+func (t *Template) Execute(w io.Writer, m map[string]interface{}) (int64, error) {
+ return t.ExecuteFunc(w, func(w io.Writer, tag string) (int, error) { return stdTagFunc(w, tag, m) })
+}
+
+// ExecuteFuncString calls f on each template tag (placeholder) occurrence
+// and substitutes it with the data written to TagFunc's w.
+//
+// Returns the resulting string.
+//
+// This function is optimized for frozen templates.
+// Use ExecuteFuncString for constantly changing templates.
+func (t *Template) ExecuteFuncString(f TagFunc) string {
+ bb := t.byteBufferPool.Get()
+ if _, err := t.ExecuteFunc(bb, f); err != nil {
+ panic(fmt.Sprintf("unexpected error: %s", err))
+ }
+ s := string(bb.Bytes())
+ bb.Reset()
+ t.byteBufferPool.Put(bb)
+ return s
+}
+
+// ExecuteString substitutes template tags (placeholders) with the corresponding
+// values from the map m and returns the result.
+//
+// Substitution map m may contain values with the following types:
+// * []byte - the fastest value type
+// * string - convenient value type
+// * TagFunc - flexible value type
+//
+// This function is optimized for frozen templates.
+// Use ExecuteString for constantly changing templates.
+func (t *Template) ExecuteString(m map[string]interface{}) string {
+ return t.ExecuteFuncString(func(w io.Writer, tag string) (int, error) { return stdTagFunc(w, tag, m) })
+}
+
+func stdTagFunc(w io.Writer, tag string, m map[string]interface{}) (int, error) {
+ v := m[tag]
+ if v == nil {
+ return 0, nil
+ }
+ switch value := v.(type) {
+ case []byte:
+ return w.Write(value)
+ case string:
+ return w.Write([]byte(value))
+ case TagFunc:
+ return value(w, tag)
+ default:
+ panic(fmt.Sprintf("tag=%q contains unexpected value type=%#v. Expected []byte, string or TagFunc", tag, v))
+ }
+}
diff --git a/src/dma/vendor/github.com/valyala/fasttemplate/unsafe.go b/src/dma/vendor/github.com/valyala/fasttemplate/unsafe.go
new file mode 100644
index 00000000..0498248f
--- /dev/null
+++ b/src/dma/vendor/github.com/valyala/fasttemplate/unsafe.go
@@ -0,0 +1,22 @@
+// +build !appengine
+
+package fasttemplate
+
+import (
+ "reflect"
+ "unsafe"
+)
+
+func unsafeBytes2String(b []byte) string {
+ return *(*string)(unsafe.Pointer(&b))
+}
+
+func unsafeString2Bytes(s string) []byte {
+ sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
+ bh := reflect.SliceHeader{
+ Data: sh.Data,
+ Len: sh.Len,
+ Cap: sh.Len,
+ }
+ return *(*[]byte)(unsafe.Pointer(&bh))
+}
diff --git a/src/dma/vendor/github.com/valyala/fasttemplate/unsafe_gae.go b/src/dma/vendor/github.com/valyala/fasttemplate/unsafe_gae.go
new file mode 100644
index 00000000..cc4ce151
--- /dev/null
+++ b/src/dma/vendor/github.com/valyala/fasttemplate/unsafe_gae.go
@@ -0,0 +1,11 @@
+// +build appengine
+
+package fasttemplate
+
+func unsafeBytes2String(b []byte) string {
+ return string(b)
+}
+
+func unsafeString2Bytes(s string) []byte {
+ return []byte(s)
+}