diff --git a/daemon/logdrivers_linux.go b/daemon/logdrivers_linux.go
index eb2c6a9dd4..ded4d27d58 100644
--- a/daemon/logdrivers_linux.go
+++ b/daemon/logdrivers_linux.go
@@ -3,6 +3,7 @@ package daemon
// Importing packages here only to make sure their init gets called and
// therefore they register themselves to the logdriver factory.
import (
+ _ "github.com/docker/docker/daemon/logger/fluentd"
_ "github.com/docker/docker/daemon/logger/gelf"
_ "github.com/docker/docker/daemon/logger/journald"
_ "github.com/docker/docker/daemon/logger/jsonfilelog"
diff --git a/daemon/logger/fluentd/fluentd.go b/daemon/logger/fluentd/fluentd.go
new file mode 100644
index 0000000000..2fefa57b9a
--- /dev/null
+++ b/daemon/logger/fluentd/fluentd.go
@@ -0,0 +1,129 @@
+package fluentd
+
+import (
+ "bytes"
+ "io"
+ "math"
+ "net"
+ "strconv"
+ "strings"
+ "text/template"
+
+ "github.com/Sirupsen/logrus"
+ "github.com/docker/docker/daemon/logger"
+ "github.com/fluent/fluent-logger-golang/fluent"
+)
+
+type Fluentd struct {
+ tag string
+ containerID string
+ containerName string
+ writer *fluent.Fluent
+}
+
+type Receiver struct {
+ ID string
+ FullID string
+ Name string
+}
+
+const (
+ name = "fluentd"
+ defaultHostName = "localhost"
+ defaultPort = 24224
+ defaultTagPrefix = "docker"
+)
+
+func init() {
+ if err := logger.RegisterLogDriver(name, New); err != nil {
+ logrus.Fatal(err)
+ }
+}
+
+func parseConfig(ctx logger.Context) (string, int, string, error) {
+ host := defaultHostName
+ port := defaultPort
+ tag := "docker." + ctx.ContainerID[:12]
+
+ config := ctx.Config
+
+ if address := config["fluentd-address"]; address != "" {
+ if h, p, err := net.SplitHostPort(address); err != nil {
+ if !strings.Contains(err.Error(), "missing port in address") {
+ return "", 0, "", err
+ }
+ host = h
+ } else {
+ portnum, err := strconv.Atoi(p)
+ if err != nil {
+ return "", 0, "", err
+ }
+ host = h
+ port = portnum
+ }
+ }
+
+ if config["fluentd-tag"] != "" {
+ receiver := &Receiver{
+ ID: ctx.ContainerID[:12],
+ FullID: ctx.ContainerID,
+ Name: ctx.ContainerName,
+ }
+ tmpl, err := template.New("tag").Parse(config["fluentd-tag"])
+ if err != nil {
+ return "", 0, "", err
+ }
+ buf := new(bytes.Buffer)
+ if err := tmpl.Execute(buf, receiver); err != nil {
+ return "", 0, "", err
+ }
+ tag = buf.String()
+ }
+
+ return host, port, tag, nil
+}
+
+func New(ctx logger.Context) (logger.Logger, error) {
+ host, port, tag, err := parseConfig(ctx)
+ if err != nil {
+ return nil, err
+ }
+ logrus.Debugf("logging driver fluentd configured for container:%s, host:%s, port:%d, tag:%s.", ctx.ContainerID, host, port, tag)
+
+ // logger tries to recoonect 2**64 - 1 times
+ // failed (and panic) after 204 years [ 1.5 ** (2**32 - 1) - 1 seconds]
+ log, err := fluent.New(fluent.Config{FluentPort: port, FluentHost: host, RetryWait: 1000, MaxRetry: math.MaxUint32})
+ if err != nil {
+ return nil, err
+ }
+ return &Fluentd{
+ tag: tag,
+ containerID: ctx.ContainerID,
+ containerName: ctx.ContainerName,
+ writer: log,
+ }, nil
+}
+
+func (f *Fluentd) Log(msg *logger.Message) error {
+ data := map[string]string{
+ "container_id": f.containerID,
+ "container_name": f.containerName,
+ "source": msg.Source,
+ "log": string(msg.Line),
+ }
+ // fluent-logger-golang buffers logs from failures and disconnections,
+ // and these are transferred again automatically.
+ return f.writer.PostWithTime(f.tag, msg.Timestamp, data)
+}
+
+func (f *Fluentd) Close() error {
+ return f.writer.Close()
+}
+
+func (f *Fluentd) Name() string {
+ return name
+}
+
+func (s *Fluentd) GetReader() (io.Reader, error) {
+ return nil, logger.ReadLogsNotSupported
+}
diff --git a/docs/reference/run.md b/docs/reference/run.md
index c50dd22c46..02830641d6 100644
--- a/docs/reference/run.md
+++ b/docs/reference/run.md
@@ -884,6 +884,16 @@ container's logging driver. The following options are supported:
driver. For detailed information on working with logging drivers, see
[Configure a logging driver](reference/logging/).
+#### Logging driver: fluentd
+
+Fluentd logging driver for Docker. Writes log messages to fluentd (forward input). `docker logs`
+command is not available for this logging driver.
+
+Some options are supported by specifying `--log-opt` as many as needed, like `--log-opt fluentd-address=localhost:24224 --log-opt fluentd-tag=docker.{{.Name}}`.
+
+ - `fluentd-address`: specify `host:port` to connect [localhost:24224]
+ - `fluentd-tag`: specify tag for fluentd message, which interpret some markup, ex `{{.ID}}`, `{{.FullID}}` or `{{.Name}}` [docker.{{.ID}}]
+
## Overriding Dockerfile image defaults
When a developer builds an image from a [*Dockerfile*](/reference/builder)
diff --git a/hack/vendor.sh b/hack/vendor.sh
index a678d9cb98..9b9b5a02bf 100755
--- a/hack/vendor.sh
+++ b/hack/vendor.sh
@@ -42,4 +42,9 @@ clone git github.com/syndtr/gocapability 66ef2aa7a23ba682594e2b6f74cf40c0692b49f
clone git github.com/golang/protobuf 655cdfa588ea
clone git github.com/Graylog2/go-gelf 6c62a85f1d47a67f2a5144c0e745b325889a8120
+clone git github.com/fluent/fluent-logger-golang v1.0.0
+# fluent-logger-golang deps
+clone git github.com/philhofer/fwd 899e4efba8eaa1fea74175308f3fae18ff3319fa
+clone git github.com/tinylib/msgp 75ee40d2601edf122ef667e2a07d600d4c44490c
+
clean
diff --git a/man/docker-create.1.md b/man/docker-create.1.md
index 3882fbf031..a41ca04bc1 100644
--- a/man/docker-create.1.md
+++ b/man/docker-create.1.md
@@ -155,7 +155,7 @@ two memory nodes.
**--lxc-conf**=[]
(lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
-**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*none*"
+**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*none*"
Logging driver for container. Default is defined by daemon `--log-driver` flag.
**Warning**: `docker logs` command works only for `json-file` logging driver.
diff --git a/man/docker-run.1.md b/man/docker-run.1.md
index 3c75443491..c81f3f8e3e 100644
--- a/man/docker-run.1.md
+++ b/man/docker-run.1.md
@@ -252,7 +252,7 @@ which interface and port to use.
**--lxc-conf**=[]
(lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
-**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*none*"
+**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*none*"
Logging driver for container. Default is defined by daemon `--log-driver` flag.
**Warning**: `docker logs` command works only for `json-file` logging driver.
diff --git a/man/docker.1.md b/man/docker.1.md
index f77038139a..9b9320db3a 100644
--- a/man/docker.1.md
+++ b/man/docker.1.md
@@ -103,7 +103,7 @@ unix://[/path/to/socket] to use.
**--label**="[]"
Set key=value labels to the daemon (displayed in `docker info`)
-**--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*none*"
+**--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*none*"
Default driver for container logs. Default is `json-file`.
**Warning**: `docker logs` command works only for `json-file` logging driver.
diff --git a/vendor/src/github.com/fluent/fluent-logger-golang/fluent/fluent.go b/vendor/src/github.com/fluent/fluent-logger-golang/fluent/fluent.go
new file mode 100644
index 0000000000..f746c51266
--- /dev/null
+++ b/vendor/src/github.com/fluent/fluent-logger-golang/fluent/fluent.go
@@ -0,0 +1,245 @@
+package fluent
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "net"
+ "reflect"
+ "strconv"
+ "sync"
+ "time"
+)
+
+const (
+ defaultHost = "127.0.0.1"
+ defaultPort = 24224
+ defaultTimeout = 3 * time.Second
+ defaultBufferLimit = 8 * 1024 * 1024
+ defaultRetryWait = 500
+ defaultMaxRetry = 13
+ defaultReconnectWaitIncreRate = 1.5
+)
+
+type Config struct {
+ FluentPort int
+ FluentHost string
+ Timeout time.Duration
+ BufferLimit int
+ RetryWait int
+ MaxRetry int
+ TagPrefix string
+}
+
+type Fluent struct {
+ Config
+ conn net.Conn
+ pending []byte
+ reconnecting bool
+ mu sync.Mutex
+}
+
+// New creates a new Logger.
+func New(config Config) (f *Fluent, err error) {
+ if config.FluentHost == "" {
+ config.FluentHost = defaultHost
+ }
+ if config.FluentPort == 0 {
+ config.FluentPort = defaultPort
+ }
+ if config.Timeout == 0 {
+ config.Timeout = defaultTimeout
+ }
+ if config.BufferLimit == 0 {
+ config.BufferLimit = defaultBufferLimit
+ }
+ if config.RetryWait == 0 {
+ config.RetryWait = defaultRetryWait
+ }
+ if config.MaxRetry == 0 {
+ config.MaxRetry = defaultMaxRetry
+ }
+ f = &Fluent{Config: config, reconnecting: false}
+ err = f.connect()
+ return
+}
+
+// Post writes the output for a logging event.
+//
+// Examples:
+//
+// // send string
+// f.Post("tag_name", "data")
+//
+// // send map[string]
+// mapStringData := map[string]string{
+// "foo": "bar",
+// }
+// f.Post("tag_name", mapStringData)
+//
+// // send message with specified time
+// mapStringData := map[string]string{
+// "foo": "bar",
+// }
+// tm := time.Now()
+// f.PostWithTime("tag_name", tm, mapStringData)
+//
+// // send struct
+// structData := struct {
+// Name string `msg:"name"`
+// } {
+// "john smith",
+// }
+// f.Post("tag_name", structData)
+//
+func (f *Fluent) Post(tag string, message interface{}) error {
+ timeNow := time.Now()
+ return f.PostWithTime(tag, timeNow, message)
+}
+
+func (f *Fluent) PostWithTime(tag string, tm time.Time, message interface{}) error {
+ if len(f.TagPrefix) > 0 {
+ tag = f.TagPrefix + "." + tag
+ }
+
+ msg := reflect.ValueOf(message)
+ msgtype := msg.Type()
+
+ if msgtype.Kind() == reflect.Struct {
+ // message should be tagged by "codec" or "msg"
+ kv := make(map[string]interface{})
+ fields := msgtype.NumField()
+ for i := 0; i < fields; i++ {
+ field := msgtype.Field(i)
+ name := field.Name
+ if n1 := field.Tag.Get("msg"); n1 != "" {
+ name = n1
+ } else if n2 := field.Tag.Get("codec"); n2 != "" {
+ name = n2
+ }
+ kv[name] = msg.FieldByIndex(field.Index).Interface()
+ }
+ return f.EncodeAndPostData(tag, tm, kv)
+ }
+
+ if msgtype.Kind() != reflect.Map {
+ return errors.New("messge must be a map")
+ } else if msgtype.Key().Kind() != reflect.String {
+ return errors.New("map keys must be strings")
+ }
+
+ kv := make(map[string]interface{})
+ for _, k := range msg.MapKeys() {
+ kv[k.String()] = msg.MapIndex(k).Interface()
+ }
+
+ return f.EncodeAndPostData(tag, tm, kv)
+}
+
+func (f *Fluent) EncodeAndPostData(tag string, tm time.Time, message interface{}) error {
+ if data, dumperr := f.EncodeData(tag, tm, message); dumperr != nil {
+ return fmt.Errorf("fluent#EncodeAndPostData: can't convert '%s' to msgpack:%s", message, dumperr)
+ // fmt.Println("fluent#Post: can't convert to msgpack:", message, dumperr)
+ } else {
+ f.PostRawData(data)
+ return nil
+ }
+}
+
+func (f *Fluent) PostRawData(data []byte) {
+ f.mu.Lock()
+ f.pending = append(f.pending, data...)
+ f.mu.Unlock()
+ if err := f.send(); err != nil {
+ f.close()
+ if len(f.pending) > f.Config.BufferLimit {
+ f.flushBuffer()
+ }
+ } else {
+ f.flushBuffer()
+ }
+}
+
+func (f *Fluent) EncodeData(tag string, tm time.Time, message interface{}) (data []byte, err error) {
+ timeUnix := tm.Unix()
+ msg := &Message{Tag: tag, Time: timeUnix, Record: message}
+ data, err = msg.MarshalMsg(nil)
+ return
+}
+
+// Close closes the connection.
+func (f *Fluent) Close() (err error) {
+ if len(f.pending) > 0 {
+ _ = f.send()
+ }
+ err = f.close()
+ return
+}
+
+// close closes the connection.
+func (f *Fluent) close() (err error) {
+ if f.conn != nil {
+ f.mu.Lock()
+ defer f.mu.Unlock()
+ } else {
+ return
+ }
+ if f.conn != nil {
+ f.conn.Close()
+ f.conn = nil
+ }
+ return
+}
+
+// connect establishes a new connection using the specified transport.
+func (f *Fluent) connect() (err error) {
+ f.conn, err = net.DialTimeout("tcp", f.Config.FluentHost+":"+strconv.Itoa(f.Config.FluentPort), f.Config.Timeout)
+ return
+}
+
+func e(x, y float64) int {
+ return int(math.Pow(x, y))
+}
+
+func (f *Fluent) reconnect() {
+ go func() {
+ for i := 0; ; i++ {
+ err := f.connect()
+ if err == nil {
+ f.mu.Lock()
+ f.reconnecting = false
+ f.mu.Unlock()
+ break
+ } else {
+ if i == f.Config.MaxRetry {
+ panic("fluent#reconnect: failed to reconnect!")
+ }
+ waitTime := f.Config.RetryWait * e(defaultReconnectWaitIncreRate, float64(i-1))
+ time.Sleep(time.Duration(waitTime) * time.Millisecond)
+ }
+ }
+ }()
+}
+
+func (f *Fluent) flushBuffer() {
+ f.mu.Lock()
+ defer f.mu.Unlock()
+ f.pending = f.pending[0:0]
+}
+
+func (f *Fluent) send() (err error) {
+ if f.conn == nil {
+ if f.reconnecting == false {
+ f.mu.Lock()
+ f.reconnecting = true
+ f.mu.Unlock()
+ f.reconnect()
+ }
+ err = errors.New("fluent#send: can't send logs, client is reconnecting")
+ } else {
+ f.mu.Lock()
+ _, err = f.conn.Write(f.pending)
+ f.mu.Unlock()
+ }
+ return
+}
diff --git a/vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto.go b/vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto.go
new file mode 100644
index 0000000000..268d614dfd
--- /dev/null
+++ b/vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto.go
@@ -0,0 +1,24 @@
+//go:generate msgp
+
+package fluent
+
+//msgp:tuple Entry
+type Entry struct {
+ Time int64 `msg:"time"`
+ Record interface{} `msg:"record"`
+}
+
+//msgp:tuple Forward
+type Forward struct {
+ Tag string `msg:"tag"`
+ Entries []Entry `msg:"entries"`
+ Option interface{} `msg:"option"`
+}
+
+//msgp:tuple Message
+type Message struct {
+ Tag string `msg:"tag"`
+ Time int64 `msg:"time"`
+ Record interface{} `msg:"record"`
+ Option interface{} `msg:"option"`
+}
diff --git a/vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto_gen.go b/vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto_gen.go
new file mode 100644
index 0000000000..afb9d6d31f
--- /dev/null
+++ b/vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto_gen.go
@@ -0,0 +1,372 @@
+package fluent
+
+// NOTE: THIS FILE WAS PRODUCED BY THE
+// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
+// DO NOT EDIT
+
+import (
+ "github.com/tinylib/msgp/msgp"
+)
+
+// DecodeMsg implements msgp.Decodable
+func (z *Entry) DecodeMsg(dc *msgp.Reader) (err error) {
+ var ssz uint32
+ ssz, err = dc.ReadArrayHeader()
+ if err != nil {
+ return
+ }
+ if ssz != 2 {
+ err = msgp.ArrayError{Wanted: 2, Got: ssz}
+ return
+ }
+ z.Time, err = dc.ReadInt64()
+ if err != nil {
+ return
+ }
+ z.Record, err = dc.ReadIntf()
+ if err != nil {
+ return
+ }
+ return
+}
+
+// EncodeMsg implements msgp.Encodable
+func (z Entry) EncodeMsg(en *msgp.Writer) (err error) {
+ err = en.WriteArrayHeader(2)
+ if err != nil {
+ return
+ }
+ err = en.WriteInt64(z.Time)
+ if err != nil {
+ return
+ }
+ err = en.WriteIntf(z.Record)
+ if err != nil {
+ return
+ }
+ return
+}
+
+// MarshalMsg implements msgp.Marshaler
+func (z Entry) MarshalMsg(b []byte) (o []byte, err error) {
+ o = msgp.Require(b, z.Msgsize())
+ o = msgp.AppendArrayHeader(o, 2)
+ o = msgp.AppendInt64(o, z.Time)
+ o, err = msgp.AppendIntf(o, z.Record)
+ if err != nil {
+ return
+ }
+ return
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler
+func (z *Entry) UnmarshalMsg(bts []byte) (o []byte, err error) {
+ {
+ var ssz uint32
+ ssz, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ return
+ }
+ if ssz != 2 {
+ err = msgp.ArrayError{Wanted: 2, Got: ssz}
+ return
+ }
+ }
+ z.Time, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ return
+ }
+ z.Record, bts, err = msgp.ReadIntfBytes(bts)
+ if err != nil {
+ return
+ }
+ o = bts
+ return
+}
+
+func (z Entry) Msgsize() (s int) {
+ s = msgp.ArrayHeaderSize + msgp.Int64Size + msgp.GuessSize(z.Record)
+ return
+}
+
+// DecodeMsg implements msgp.Decodable
+func (z *Forward) DecodeMsg(dc *msgp.Reader) (err error) {
+ var ssz uint32
+ ssz, err = dc.ReadArrayHeader()
+ if err != nil {
+ return
+ }
+ if ssz != 3 {
+ err = msgp.ArrayError{Wanted: 3, Got: ssz}
+ return
+ }
+ z.Tag, err = dc.ReadString()
+ if err != nil {
+ return
+ }
+ var xsz uint32
+ xsz, err = dc.ReadArrayHeader()
+ if err != nil {
+ return
+ }
+ if cap(z.Entries) >= int(xsz) {
+ z.Entries = z.Entries[:xsz]
+ } else {
+ z.Entries = make([]Entry, xsz)
+ }
+ for xvk := range z.Entries {
+ var ssz uint32
+ ssz, err = dc.ReadArrayHeader()
+ if err != nil {
+ return
+ }
+ if ssz != 2 {
+ err = msgp.ArrayError{Wanted: 2, Got: ssz}
+ return
+ }
+ z.Entries[xvk].Time, err = dc.ReadInt64()
+ if err != nil {
+ return
+ }
+ z.Entries[xvk].Record, err = dc.ReadIntf()
+ if err != nil {
+ return
+ }
+ }
+ z.Option, err = dc.ReadIntf()
+ if err != nil {
+ return
+ }
+ return
+}
+
+// EncodeMsg implements msgp.Encodable
+func (z *Forward) EncodeMsg(en *msgp.Writer) (err error) {
+ err = en.WriteArrayHeader(3)
+ if err != nil {
+ return
+ }
+ err = en.WriteString(z.Tag)
+ if err != nil {
+ return
+ }
+ err = en.WriteArrayHeader(uint32(len(z.Entries)))
+ if err != nil {
+ return
+ }
+ for xvk := range z.Entries {
+ err = en.WriteArrayHeader(2)
+ if err != nil {
+ return
+ }
+ err = en.WriteInt64(z.Entries[xvk].Time)
+ if err != nil {
+ return
+ }
+ err = en.WriteIntf(z.Entries[xvk].Record)
+ if err != nil {
+ return
+ }
+ }
+ err = en.WriteIntf(z.Option)
+ if err != nil {
+ return
+ }
+ return
+}
+
+// MarshalMsg implements msgp.Marshaler
+func (z *Forward) MarshalMsg(b []byte) (o []byte, err error) {
+ o = msgp.Require(b, z.Msgsize())
+ o = msgp.AppendArrayHeader(o, 3)
+ o = msgp.AppendString(o, z.Tag)
+ o = msgp.AppendArrayHeader(o, uint32(len(z.Entries)))
+ for xvk := range z.Entries {
+ o = msgp.AppendArrayHeader(o, 2)
+ o = msgp.AppendInt64(o, z.Entries[xvk].Time)
+ o, err = msgp.AppendIntf(o, z.Entries[xvk].Record)
+ if err != nil {
+ return
+ }
+ }
+ o, err = msgp.AppendIntf(o, z.Option)
+ if err != nil {
+ return
+ }
+ return
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler
+func (z *Forward) UnmarshalMsg(bts []byte) (o []byte, err error) {
+ {
+ var ssz uint32
+ ssz, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ return
+ }
+ if ssz != 3 {
+ err = msgp.ArrayError{Wanted: 3, Got: ssz}
+ return
+ }
+ }
+ z.Tag, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ return
+ }
+ var xsz uint32
+ xsz, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ return
+ }
+ if cap(z.Entries) >= int(xsz) {
+ z.Entries = z.Entries[:xsz]
+ } else {
+ z.Entries = make([]Entry, xsz)
+ }
+ for xvk := range z.Entries {
+ {
+ var ssz uint32
+ ssz, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ return
+ }
+ if ssz != 2 {
+ err = msgp.ArrayError{Wanted: 2, Got: ssz}
+ return
+ }
+ }
+ z.Entries[xvk].Time, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ return
+ }
+ z.Entries[xvk].Record, bts, err = msgp.ReadIntfBytes(bts)
+ if err != nil {
+ return
+ }
+ }
+ z.Option, bts, err = msgp.ReadIntfBytes(bts)
+ if err != nil {
+ return
+ }
+ o = bts
+ return
+}
+
+func (z *Forward) Msgsize() (s int) {
+ s = msgp.ArrayHeaderSize + msgp.StringPrefixSize + len(z.Tag) + msgp.ArrayHeaderSize
+ for xvk := range z.Entries {
+ s += msgp.ArrayHeaderSize + msgp.Int64Size + msgp.GuessSize(z.Entries[xvk].Record)
+ }
+ s += msgp.GuessSize(z.Option)
+ return
+}
+
+// DecodeMsg implements msgp.Decodable
+func (z *Message) DecodeMsg(dc *msgp.Reader) (err error) {
+ var ssz uint32
+ ssz, err = dc.ReadArrayHeader()
+ if err != nil {
+ return
+ }
+ if ssz != 4 {
+ err = msgp.ArrayError{Wanted: 4, Got: ssz}
+ return
+ }
+ z.Tag, err = dc.ReadString()
+ if err != nil {
+ return
+ }
+ z.Time, err = dc.ReadInt64()
+ if err != nil {
+ return
+ }
+ z.Record, err = dc.ReadIntf()
+ if err != nil {
+ return
+ }
+ z.Option, err = dc.ReadIntf()
+ if err != nil {
+ return
+ }
+ return
+}
+
+// EncodeMsg implements msgp.Encodable
+func (z *Message) EncodeMsg(en *msgp.Writer) (err error) {
+ err = en.WriteArrayHeader(4)
+ if err != nil {
+ return
+ }
+ err = en.WriteString(z.Tag)
+ if err != nil {
+ return
+ }
+ err = en.WriteInt64(z.Time)
+ if err != nil {
+ return
+ }
+ err = en.WriteIntf(z.Record)
+ if err != nil {
+ return
+ }
+ err = en.WriteIntf(z.Option)
+ if err != nil {
+ return
+ }
+ return
+}
+
+// MarshalMsg implements msgp.Marshaler
+func (z *Message) MarshalMsg(b []byte) (o []byte, err error) {
+ o = msgp.Require(b, z.Msgsize())
+ o = msgp.AppendArrayHeader(o, 4)
+ o = msgp.AppendString(o, z.Tag)
+ o = msgp.AppendInt64(o, z.Time)
+ o, err = msgp.AppendIntf(o, z.Record)
+ if err != nil {
+ return
+ }
+ o, err = msgp.AppendIntf(o, z.Option)
+ if err != nil {
+ return
+ }
+ return
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler
+func (z *Message) UnmarshalMsg(bts []byte) (o []byte, err error) {
+ {
+ var ssz uint32
+ ssz, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ return
+ }
+ if ssz != 4 {
+ err = msgp.ArrayError{Wanted: 4, Got: ssz}
+ return
+ }
+ }
+ z.Tag, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ return
+ }
+ z.Time, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ return
+ }
+ z.Record, bts, err = msgp.ReadIntfBytes(bts)
+ if err != nil {
+ return
+ }
+ z.Option, bts, err = msgp.ReadIntfBytes(bts)
+ if err != nil {
+ return
+ }
+ o = bts
+ return
+}
+
+func (z *Message) Msgsize() (s int) {
+ s = msgp.ArrayHeaderSize + msgp.StringPrefixSize + len(z.Tag) + msgp.Int64Size + msgp.GuessSize(z.Record) + msgp.GuessSize(z.Option)
+ return
+}
diff --git a/vendor/src/github.com/fluent/fluent-logger-golang/fluent/version.go b/vendor/src/github.com/fluent/fluent-logger-golang/fluent/version.go
new file mode 100644
index 0000000000..4ee1555799
--- /dev/null
+++ b/vendor/src/github.com/fluent/fluent-logger-golang/fluent/version.go
@@ -0,0 +1,3 @@
+package fluent
+
+const Version = "0.5.1"
diff --git a/vendor/src/github.com/philhofer/fwd/README.md b/vendor/src/github.com/philhofer/fwd/README.md
new file mode 100644
index 0000000000..8c7d25a87e
--- /dev/null
+++ b/vendor/src/github.com/philhofer/fwd/README.md
@@ -0,0 +1,311 @@
+
+# fwd
+ import "github.com/philhofer/fwd"
+
+The `fwd` package provides a buffered reader
+and writer. Each has methods that help improve
+the encoding/decoding performance of some binary
+protocols.
+
+The `fwd.Writer` and `fwd.Reader` type provide similar
+functionality to their counterparts in `bufio`, plus
+a few extra utility methods that simplify read-ahead
+and write-ahead. I wrote this package to improve serialization
+performance for http://github.com/philhofer/msgp,
+where it provided about a 2x speedup over `bufio`. However,
+care must be taken to understand the semantics of the
+extra methods provided by this package, as they allow
+the user to access and manipulate the buffer memory
+directly.
+
+The extra methods for `fwd.Reader` are `Peek`, `Skip`
+and `Next`. `(*fwd.Reader).Peek`, unlike `(*bufio.Reader).Peek`,
+will re-allocate the read buffer in order to accommodate arbitrarily
+large read-ahead. `(*fwd.Reader).Skip` skips the next `n` bytes
+in the stream, and uses the `io.Seeker` interface if the underlying
+stream implements it. `(*fwd.Reader).Next` returns a slice pointing
+to the next `n` bytes in the read buffer (like `Peek`), but also
+increments the read position. This allows users to process streams
+in aribtrary block sizes without having to manage appropriately-sized
+slices. Additionally, obviating the need to copy the data from the
+buffer to another location in memory can improve performance dramatically
+in CPU-bound applications.
+
+`fwd.Writer` only has one extra method, which is `(*fwd.Writer).Next`, which
+returns a slice pointing to the next `n` bytes of the writer, and increments
+the write position by the length of the returned slice. This allows users
+to write directly to the end of the buffer.
+
+
+
+
+## Constants
+``` go
+const (
+ // DefaultReaderSize is the default size of the read buffer
+ DefaultReaderSize = 2048
+)
+```
+``` go
+const (
+ // DefaultWriterSize is the
+ // default write buffer size.
+ DefaultWriterSize = 2048
+)
+```
+
+
+
+## type Reader
+``` go
+type Reader struct {
+ // contains filtered or unexported fields
+}
+```
+Reader is a buffered look-ahead reader
+
+
+
+
+
+
+
+
+
+### func NewReader
+``` go
+func NewReader(r io.Reader) *Reader
+```
+NewReader returns a new *Reader that reads from 'r'
+
+
+### func NewReaderSize
+``` go
+func NewReaderSize(r io.Reader, n int) *Reader
+```
+NewReaderSize returns a new *Reader that
+reads from 'r' and has a buffer size 'n'
+
+
+
+
+### func (\*Reader) BufferSize
+``` go
+func (r *Reader) BufferSize() int
+```
+BufferSize returns the total size of the buffer
+
+
+
+### func (\*Reader) Buffered
+``` go
+func (r *Reader) Buffered() int
+```
+Buffered returns the number of bytes currently in the buffer
+
+
+
+### func (\*Reader) Next
+``` go
+func (r *Reader) Next(n int) ([]byte, error)
+```
+Next returns the next 'n' bytes in the stream.
+If the returned slice has a length less than 'n',
+an error will also be returned.
+Unlike Peek, Next advances the reader position.
+The returned bytes point to the same
+data as the buffer, so the slice is
+only valid until the next reader method call.
+An EOF is considered an unexpected error.
+
+
+
+### func (\*Reader) Peek
+``` go
+func (r *Reader) Peek(n int) ([]byte, error)
+```
+Peek returns the next 'n' buffered bytes,
+reading from the underlying reader if necessary.
+It will only return a slice shorter than 'n' bytes
+if it also returns an error. Peek does not advance
+the reader. EOF errors are *not* returned as
+io.ErrUnexpectedEOF.
+
+
+
+### func (\*Reader) Read
+``` go
+func (r *Reader) Read(b []byte) (int, error)
+```
+Read implements `io.Reader`
+
+
+
+### func (\*Reader) ReadByte
+``` go
+func (r *Reader) ReadByte() (byte, error)
+```
+ReadByte implements `io.ByteReader`
+
+
+
+### func (\*Reader) ReadFull
+``` go
+func (r *Reader) ReadFull(b []byte) (int, error)
+```
+ReadFull attempts to read len(b) bytes into
+'b'. It returns the number of bytes read into
+'b', and an error if it does not return len(b).
+
+
+
+### func (\*Reader) Reset
+``` go
+func (r *Reader) Reset(rd io.Reader)
+```
+Reset resets the underlying reader
+and the read buffer.
+
+
+
+### func (\*Reader) Skip
+``` go
+func (r *Reader) Skip(n int) (int, error)
+```
+Skip moves the reader forward 'n' bytes.
+Returns the number of bytes skipped and any
+errors encountered. It is analagous to Seek(n, 1).
+If the underlying reader implements io.Seeker, then
+that method will be used to skip forward.
+
+If the reader encounters
+an EOF before skipping 'n' bytes, it
+returns io.ErrUnexpectedEOF. If the
+underlying reader implements io.Seeker, then
+those rules apply instead. (Many implementations
+will not return `io.EOF` until the next call
+to Read.)
+
+
+
+### func (\*Reader) WriteTo
+``` go
+func (r *Reader) WriteTo(w io.Writer) (int64, error)
+```
+WriteTo implements `io.WriterTo`
+
+
+
+## type Writer
+``` go
+type Writer struct {
+ // contains filtered or unexported fields
+}
+```
+Writer is a buffered writer
+
+
+
+
+
+
+
+
+
+### func NewWriter
+``` go
+func NewWriter(w io.Writer) *Writer
+```
+NewWriter returns a new writer
+that writes to 'w' and has a buffer
+that is `DefaultWriterSize` bytes.
+
+
+### func NewWriterSize
+``` go
+func NewWriterSize(w io.Writer, size int) *Writer
+```
+NewWriterSize returns a new writer
+that writes to 'w' and has a buffer
+that is 'size' bytes.
+
+
+
+
+### func (\*Writer) BufferSize
+``` go
+func (w *Writer) BufferSize() int
+```
+BufferSize returns the maximum size of the buffer.
+
+
+
+### func (\*Writer) Buffered
+``` go
+func (w *Writer) Buffered() int
+```
+Buffered returns the number of buffered bytes
+in the reader.
+
+
+
+### func (\*Writer) Flush
+``` go
+func (w *Writer) Flush() error
+```
+Flush flushes any buffered bytes
+to the underlying writer.
+
+
+
+### func (\*Writer) Next
+``` go
+func (w *Writer) Next(n int) ([]byte, error)
+```
+Next returns the next 'n' free bytes
+in the write buffer, flushing the writer
+as necessary. Next will return `io.ErrShortBuffer`
+if 'n' is greater than the size of the write buffer.
+
+
+
+### func (\*Writer) ReadFrom
+``` go
+func (w *Writer) ReadFrom(r io.Reader) (int64, error)
+```
+ReadFrom implements `io.ReaderFrom`
+
+
+
+### func (\*Writer) Write
+``` go
+func (w *Writer) Write(p []byte) (int, error)
+```
+Write implements `io.Writer`
+
+
+
+### func (\*Writer) WriteByte
+``` go
+func (w *Writer) WriteByte(b byte) error
+```
+WriteByte implements `io.ByteWriter`
+
+
+
+### func (\*Writer) WriteString
+``` go
+func (w *Writer) WriteString(s string) (int, error)
+```
+WriteString is analagous to Write, but it takes a string.
+
+
+
+
+
+
+
+
+
+- - -
+Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)
\ No newline at end of file
diff --git a/vendor/src/github.com/philhofer/fwd/reader.go b/vendor/src/github.com/philhofer/fwd/reader.go
new file mode 100644
index 0000000000..b8f0dc5b2c
--- /dev/null
+++ b/vendor/src/github.com/philhofer/fwd/reader.go
@@ -0,0 +1,358 @@
+// The `fwd` package provides a buffered reader
+// and writer. Each has methods that help improve
+// the encoding/decoding performance of some binary
+// protocols.
+//
+// The `fwd.Writer` and `fwd.Reader` type provide similar
+// functionality to their counterparts in `bufio`, plus
+// a few extra utility methods that simplify read-ahead
+// and write-ahead. I wrote this package to improve serialization
+// performance for http://github.com/tinylib/msgp,
+// where it provided about a 2x speedup over `bufio` for certain
+// workloads. However, care must be taken to understand the semantics of the
+// extra methods provided by this package, as they allow
+// the user to access and manipulate the buffer memory
+// directly.
+//
+// The extra methods for `fwd.Reader` are `Peek`, `Skip`
+// and `Next`. `(*fwd.Reader).Peek`, unlike `(*bufio.Reader).Peek`,
+// will re-allocate the read buffer in order to accommodate arbitrarily
+// large read-ahead. `(*fwd.Reader).Skip` skips the next `n` bytes
+// in the stream, and uses the `io.Seeker` interface if the underlying
+// stream implements it. `(*fwd.Reader).Next` returns a slice pointing
+// to the next `n` bytes in the read buffer (like `Peek`), but also
+// increments the read position. This allows users to process streams
+// in aribtrary block sizes without having to manage appropriately-sized
+// slices. Additionally, obviating the need to copy the data from the
+// buffer to another location in memory can improve performance dramatically
+// in CPU-bound applications.
+//
+// `fwd.Writer` only has one extra method, which is `(*fwd.Writer).Next`, which
+// returns a slice pointing to the next `n` bytes of the writer, and increments
+// the write position by the length of the returned slice. This allows users
+// to write directly to the end of the buffer.
+//
+package fwd
+
+import "io"
+
+const (
+ // DefaultReaderSize is the default size of the read buffer
+ DefaultReaderSize = 2048
+
+ // minimum read buffer; straight from bufio
+ minReaderSize = 16
+)
+
+// NewReader returns a new *Reader that reads from 'r'
+func NewReader(r io.Reader) *Reader {
+ return NewReaderSize(r, DefaultReaderSize)
+}
+
+// NewReaderSize returns a new *Reader that
+// reads from 'r' and has a buffer size 'n'
+func NewReaderSize(r io.Reader, n int) *Reader {
+ rd := &Reader{
+ r: r,
+ data: make([]byte, 0, max(minReaderSize, n)),
+ }
+ if s, ok := r.(io.Seeker); ok {
+ rd.rs = s
+ }
+ return rd
+}
+
+// Reader is a buffered look-ahead reader
+type Reader struct {
+ r io.Reader // underlying reader
+
+ // data[n:len(data)] is buffered data; data[len(data):cap(data)] is free buffer space
+ data []byte // data
+ n int // read offset
+ state error // last read error
+
+ // if the reader past to NewReader was
+ // also an io.Seeker, this is non-nil
+ rs io.Seeker
+}
+
+// Reset resets the underlying reader
+// and the read buffer.
+func (r *Reader) Reset(rd io.Reader) {
+ r.r = rd
+ r.data = r.data[0:0]
+ r.n = 0
+ r.state = nil
+ if s, ok := rd.(io.Seeker); ok {
+ r.rs = s
+ } else {
+ r.rs = nil
+ }
+}
+
+// more() does one read on the underlying reader
+func (r *Reader) more() {
+ // move data backwards so that
+ // the read offset is 0; this way
+ // we can supply the maximum number of
+ // bytes to the reader
+ if r.n != 0 {
+ r.data = r.data[:copy(r.data[0:], r.data[r.n:])]
+ r.n = 0
+ }
+ var a int
+ a, r.state = r.r.Read(r.data[len(r.data):cap(r.data)])
+ if a == 0 && r.state == nil {
+ r.state = io.ErrNoProgress
+ return
+ }
+ r.data = r.data[:len(r.data)+a]
+}
+
+// pop error
+func (r *Reader) err() (e error) {
+ e, r.state = r.state, nil
+ return
+}
+
+// pop error; EOF -> io.ErrUnexpectedEOF
+func (r *Reader) noEOF() (e error) {
+ e, r.state = r.state, nil
+ if e == io.EOF {
+ e = io.ErrUnexpectedEOF
+ }
+ return
+}
+
+// buffered bytes
+func (r *Reader) buffered() int { return len(r.data) - r.n }
+
+// Buffered returns the number of bytes currently in the buffer
+func (r *Reader) Buffered() int { return len(r.data) - r.n }
+
+// BufferSize returns the total size of the buffer
+func (r *Reader) BufferSize() int { return cap(r.data) }
+
+// Peek returns the next 'n' buffered bytes,
+// reading from the underlying reader if necessary.
+// It will only return a slice shorter than 'n' bytes
+// if it also returns an error. Peek does not advance
+// the reader. EOF errors are *not* returned as
+// io.ErrUnexpectedEOF.
+func (r *Reader) Peek(n int) ([]byte, error) {
+ // in the degenerate case,
+ // we may need to realloc
+ // (the caller asked for more
+ // bytes than the size of the buffer)
+ if cap(r.data) < n {
+ old := r.data[r.n:]
+ r.data = make([]byte, n+r.buffered())
+ r.data = r.data[:copy(r.data, old)]
+ }
+
+ // keep filling until
+ // we hit an error or
+ // read enough bytes
+ for r.buffered() < n && r.state == nil {
+ r.more()
+ }
+
+ // we must have hit an error
+ if r.buffered() < n {
+ return r.data[r.n:], r.err()
+ }
+
+ return r.data[r.n : r.n+n], nil
+}
+
+// Skip moves the reader forward 'n' bytes.
+// Returns the number of bytes skipped and any
+// errors encountered. It is analagous to Seek(n, 1).
+// If the underlying reader implements io.Seeker, then
+// that method will be used to skip forward.
+//
+// If the reader encounters
+// an EOF before skipping 'n' bytes, it
+// returns io.ErrUnexpectedEOF. If the
+// underlying reader implements io.Seeker, then
+// those rules apply instead. (Many implementations
+// will not return `io.EOF` until the next call
+// to Read.)
+func (r *Reader) Skip(n int) (int, error) {
+
+ // fast path
+ if r.buffered() >= n {
+ r.n += n
+ return n, nil
+ }
+
+ // use seeker implementation
+ // if we can
+ if r.rs != nil {
+ return r.skipSeek(n)
+ }
+
+ // loop on filling
+ // and then erasing
+ o := n
+ for r.buffered() < n && r.state == nil {
+ r.more()
+ // we can skip forward
+ // up to r.buffered() bytes
+ step := min(r.buffered(), n)
+ r.n += step
+ n -= step
+ }
+ // at this point, n should be
+ // 0 if everything went smoothly
+ return o - n, r.noEOF()
+}
+
+// Next returns the next 'n' bytes in the stream.
+// Unlike Peek, Next advances the reader position.
+// The returned bytes point to the same
+// data as the buffer, so the slice is
+// only valid until the next reader method call.
+// An EOF is considered an unexpected error.
+// If an the returned slice is less than the
+// length asked for, an error will be returned,
+// and the reader position will not be incremented.
+func (r *Reader) Next(n int) ([]byte, error) {
+
+ // in case the buffer is too small
+ if cap(r.data) < n {
+ old := r.data[r.n:]
+ r.data = make([]byte, n+r.buffered())
+ r.data = r.data[:copy(r.data, old)]
+ }
+
+ // fill at least 'n' bytes
+ for r.buffered() < n && r.state == nil {
+ r.more()
+ }
+
+ if r.buffered() < n {
+ return r.data[r.n:], r.noEOF()
+ }
+ out := r.data[r.n : r.n+n]
+ r.n += n
+ return out, nil
+}
+
+// skipSeek uses the io.Seeker to seek forward.
+// only call this function when n > r.buffered()
+func (r *Reader) skipSeek(n int) (int, error) {
+ o := r.buffered()
+ // first, clear buffer
+ n -= o
+ r.n = 0
+ r.data = r.data[:0]
+
+ // then seek forward remaning bytes
+ i, err := r.rs.Seek(int64(n), 1)
+ return int(i) + o, err
+}
+
+// Read implements `io.Reader`
+func (r *Reader) Read(b []byte) (int, error) {
+ if len(b) <= r.buffered() {
+ x := copy(b, r.data[r.n:])
+ r.n += x
+ return x, nil
+ }
+ r.more()
+ if r.buffered() > 0 {
+ x := copy(b, r.data[r.n:])
+ r.n += x
+ return x, nil
+ }
+
+ // io.Reader is supposed to return
+ // 0 read bytes on error
+ return 0, r.err()
+}
+
+// ReadFull attempts to read len(b) bytes into
+// 'b'. It returns the number of bytes read into
+// 'b', and an error if it does not return len(b).
+// EOF is considered an unexpected error.
+func (r *Reader) ReadFull(b []byte) (int, error) {
+ var x int
+ l := len(b)
+ for x < l {
+ if r.buffered() == 0 {
+ r.more()
+ }
+ c := copy(b[x:], r.data[r.n:])
+ x += c
+ r.n += c
+ if r.state != nil {
+ return x, r.noEOF()
+ }
+ }
+ return x, nil
+}
+
+// ReadByte implements `io.ByteReader`
+func (r *Reader) ReadByte() (byte, error) {
+ for r.buffered() < 1 && r.state == nil {
+ r.more()
+ }
+ if r.buffered() < 1 {
+ return 0, r.err()
+ }
+ b := r.data[r.n]
+ r.n++
+ return b, nil
+}
+
+// WriteTo implements `io.WriterTo`
+func (r *Reader) WriteTo(w io.Writer) (int64, error) {
+ var (
+ i int64
+ ii int
+ err error
+ )
+ // first, clear buffer
+ if r.buffered() > 0 {
+ ii, err = w.Write(r.data[r.n:])
+ i += int64(ii)
+ if err != nil {
+ return i, err
+ }
+ r.data = r.data[0:0]
+ r.n = 0
+ }
+ for r.state == nil {
+ // here we just do
+ // 1:1 reads and writes
+ r.more()
+ if r.buffered() > 0 {
+ ii, err = w.Write(r.data)
+ i += int64(ii)
+ if err != nil {
+ return i, err
+ }
+ r.data = r.data[0:0]
+ r.n = 0
+ }
+ }
+ if r.state != io.EOF {
+ return i, r.err()
+ }
+ return i, nil
+}
+
+func min(a int, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+
+func max(a int, b int) int {
+ if a < b {
+ return b
+ }
+ return a
+}
diff --git a/vendor/src/github.com/philhofer/fwd/writer.go b/vendor/src/github.com/philhofer/fwd/writer.go
new file mode 100644
index 0000000000..d6f44f555e
--- /dev/null
+++ b/vendor/src/github.com/philhofer/fwd/writer.go
@@ -0,0 +1,224 @@
+package fwd
+
+import "io"
+
+const (
+ // DefaultWriterSize is the
+ // default write buffer size.
+ DefaultWriterSize = 2048
+
+ minWriterSize = minReaderSize
+)
+
+// Writer is a buffered writer
+type Writer struct {
+ w io.Writer // writer
+ buf []byte // 0:len(buf) is bufered data
+}
+
+// NewWriter returns a new writer
+// that writes to 'w' and has a buffer
+// that is `DefaultWriterSize` bytes.
+func NewWriter(w io.Writer) *Writer {
+ if wr, ok := w.(*Writer); ok {
+ return wr
+ }
+ return &Writer{
+ w: w,
+ buf: make([]byte, 0, DefaultWriterSize),
+ }
+}
+
+// NewWriterSize returns a new writer
+// that writes to 'w' and has a buffer
+// that is 'size' bytes.
+func NewWriterSize(w io.Writer, size int) *Writer {
+ if wr, ok := w.(*Writer); ok && cap(wr.buf) >= size {
+ return wr
+ }
+ return &Writer{
+ w: w,
+ buf: make([]byte, 0, max(size, minWriterSize)),
+ }
+}
+
+// Buffered returns the number of buffered bytes
+// in the reader.
+func (w *Writer) Buffered() int { return len(w.buf) }
+
+// BufferSize returns the maximum size of the buffer.
+func (w *Writer) BufferSize() int { return cap(w.buf) }
+
+// Flush flushes any buffered bytes
+// to the underlying writer.
+func (w *Writer) Flush() error {
+ l := len(w.buf)
+ if l > 0 {
+ n, err := w.w.Write(w.buf)
+
+ // if we didn't write the whole
+ // thing, copy the unwritten
+ // bytes to the beginnning of the
+ // buffer.
+ if n < l && n > 0 {
+ w.pushback(n)
+ if err == nil {
+ err = io.ErrShortWrite
+ }
+ }
+ if err != nil {
+ return err
+ }
+ w.buf = w.buf[:0]
+ return nil
+ }
+ return nil
+}
+
+// Write implements `io.Writer`
+func (w *Writer) Write(p []byte) (int, error) {
+ c, l, ln := cap(w.buf), len(w.buf), len(p)
+ avail := c - l
+
+ // requires flush
+ if avail < ln {
+ if err := w.Flush(); err != nil {
+ return 0, err
+ }
+ l = len(w.buf)
+ }
+ // too big to fit in buffer;
+ // write directly to w.w
+ if c < ln {
+ return w.w.Write(p)
+ }
+
+ // grow buf slice; copy; return
+ w.buf = w.buf[:l+ln]
+ return copy(w.buf[l:], p), nil
+}
+
+// WriteString is analagous to Write, but it takes a string.
+func (w *Writer) WriteString(s string) (int, error) {
+ c, l, ln := cap(w.buf), len(w.buf), len(s)
+ avail := c - l
+
+ // requires flush
+ if avail < ln {
+ if err := w.Flush(); err != nil {
+ return 0, err
+ }
+ l = len(w.buf)
+ }
+ // too big to fit in buffer;
+ // write directly to w.w
+ //
+ // yes, this is unsafe. *but*
+ // io.Writer is not allowed
+ // to mutate its input or
+ // maintain a reference to it,
+ // per the spec in package io.
+ //
+ // plus, if the string is really
+ // too big to fit in the buffer, then
+ // creating a copy to write it is
+ // expensive (and, strictly speaking,
+ // unnecessary)
+ if c < ln {
+ return w.w.Write(unsafestr(s))
+ }
+
+ // grow buf slice; copy; return
+ w.buf = w.buf[:l+ln]
+ return copy(w.buf[l:], s), nil
+}
+
+// WriteByte implements `io.ByteWriter`
+func (w *Writer) WriteByte(b byte) error {
+ if len(w.buf) == cap(w.buf) {
+ if err := w.Flush(); err != nil {
+ return err
+ }
+ }
+ w.buf = append(w.buf, b)
+ return nil
+}
+
+// Next returns the next 'n' free bytes
+// in the write buffer, flushing the writer
+// as necessary. Next will return `io.ErrShortBuffer`
+// if 'n' is greater than the size of the write buffer.
+// Calls to 'next' increment the write position by
+// the size of the returned buffer.
+func (w *Writer) Next(n int) ([]byte, error) {
+ c, l := cap(w.buf), len(w.buf)
+ if n > c {
+ return nil, io.ErrShortBuffer
+ }
+ avail := c - l
+ if avail < n {
+ if err := w.Flush(); err != nil {
+ return nil, err
+ }
+ l = len(w.buf)
+ }
+ w.buf = w.buf[:l+n]
+ return w.buf[l:], nil
+}
+
+// take the bytes from w.buf[n:len(w.buf)]
+// and put them at the beginning of w.buf,
+// and resize to the length of the copied segment.
+func (w *Writer) pushback(n int) {
+ w.buf = w.buf[:copy(w.buf, w.buf[n:])]
+}
+
+// ReadFrom implements `io.ReaderFrom`
+func (w *Writer) ReadFrom(r io.Reader) (int64, error) {
+ // anticipatory flush
+ if err := w.Flush(); err != nil {
+ return 0, err
+ }
+
+ w.buf = w.buf[0:cap(w.buf)] // expand buffer
+
+ var nn int64 // written
+ var err error // error
+ var x int // read
+
+ // 1:1 reads and writes
+ for err == nil {
+ x, err = r.Read(w.buf)
+ if x > 0 {
+ n, werr := w.w.Write(w.buf[:x])
+ nn += int64(n)
+
+ if err != nil {
+ if n < x && n > 0 {
+ w.pushback(n - x)
+ }
+ return nn, werr
+ }
+ if n < x {
+ w.pushback(n - x)
+ return nn, io.ErrShortWrite
+ }
+ } else if err == nil {
+ err = io.ErrNoProgress
+ break
+ }
+ }
+ if err != io.EOF {
+ return nn, err
+ }
+
+ // we only clear here
+ // because we are sure
+ // the writes have
+ // suceeded. otherwise,
+ // we retain the data in case
+ // future writes succeed.
+ w.buf = w.buf[0:0]
+
+ return nn, nil
+}
diff --git a/vendor/src/github.com/philhofer/fwd/writer_appengine.go b/vendor/src/github.com/philhofer/fwd/writer_appengine.go
new file mode 100644
index 0000000000..e367f39317
--- /dev/null
+++ b/vendor/src/github.com/philhofer/fwd/writer_appengine.go
@@ -0,0 +1,5 @@
+// +build appengine
+
+package fwd
+
+func unsafestr(s string) []byte { return []byte(s) }
diff --git a/vendor/src/github.com/philhofer/fwd/writer_unsafe.go b/vendor/src/github.com/philhofer/fwd/writer_unsafe.go
new file mode 100644
index 0000000000..a0bf453b39
--- /dev/null
+++ b/vendor/src/github.com/philhofer/fwd/writer_unsafe.go
@@ -0,0 +1,18 @@
+// +build !appengine
+
+package fwd
+
+import (
+ "reflect"
+ "unsafe"
+)
+
+// unsafe cast string as []byte
+func unsafestr(b string) []byte {
+ l := len(b)
+ return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
+ Len: l,
+ Cap: l,
+ Data: (*reflect.StringHeader)(unsafe.Pointer(&b)).Data,
+ }))
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/circular.go b/vendor/src/github.com/tinylib/msgp/msgp/circular.go
new file mode 100644
index 0000000000..35583ba1cf
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/circular.go
@@ -0,0 +1,38 @@
+package msgp
+
+import (
+ "testing"
+)
+
+// EndlessReader is an io.Reader
+// that loops over the same data
+// endlessly. It is used for benchmarking.
+type EndlessReader struct {
+ tb *testing.B
+ data []byte
+ offset int
+}
+
+// NewEndlessReader returns a new endless reader
+func NewEndlessReader(b []byte, tb *testing.B) *EndlessReader {
+ return &EndlessReader{tb: tb, data: b, offset: 0}
+}
+
+// Read implements io.Reader. In practice, it
+// always returns (len(p), nil), although it
+// fills the supplied slice while the benchmark
+// timer is stopped.
+func (c *EndlessReader) Read(p []byte) (int, error) {
+ c.tb.StopTimer()
+ var n int
+ l := len(p)
+ m := len(c.data)
+ for n < l {
+ nn := copy(p[n:], c.data[c.offset:])
+ n += nn
+ c.offset += nn
+ c.offset %= m
+ }
+ c.tb.StartTimer()
+ return n, nil
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/defs.go b/vendor/src/github.com/tinylib/msgp/msgp/defs.go
new file mode 100644
index 0000000000..c634eef1df
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/defs.go
@@ -0,0 +1,142 @@
+// This package is the support library for the msgp code generator (http://github.com/tinylib/msgp).
+//
+// This package defines the utilites used by the msgp code generator for encoding and decoding MessagePack
+// from []byte and io.Reader/io.Writer types. Much of this package is devoted to helping the msgp code
+// generator implement the Marshaler/Unmarshaler and Encodable/Decodable interfaces.
+//
+// This package defines four "families" of functions:
+// - AppendXxxx() appends an object to a []byte in MessagePack encoding.
+// - ReadXxxxBytes() reads an object from a []byte and returns the remaining bytes.
+// - (*Writer).WriteXxxx() writes an object to the buffered *Writer type.
+// - (*Reader).ReadXxxx() reads an object from a buffered *Reader type.
+//
+// Once a type has satisfied the `Encodable` and `Decodable` interfaces,
+// it can be written and read from arbitrary `io.Writer`s and `io.Reader`s using
+// msgp.Encode(io.Writer, msgp.Encodable)
+// and
+// msgp.Decode(io.Reader, msgp.Decodable)
+//
+// There are also methods for converting MessagePack to JSON without
+// an explicit de-serialization step.
+//
+// For additional tips, tricks, and gotchas, please visit
+// the wiki at http://github.com/tinylib/msgp
+package msgp
+
+const last4 = 0x0f
+const first4 = 0xf0
+const last5 = 0x1f
+const first3 = 0xe0
+const last7 = 0x7f
+
+func isfixint(b byte) bool {
+ return b>>7 == 0
+}
+
+func isnfixint(b byte) bool {
+ return b&first3 == mnfixint
+}
+
+func isfixmap(b byte) bool {
+ return b&first4 == mfixmap
+}
+
+func isfixarray(b byte) bool {
+ return b&first4 == mfixarray
+}
+
+func isfixstr(b byte) bool {
+ return b&first3 == mfixstr
+}
+
+func wfixint(u uint8) byte {
+ return u & last7
+}
+
+func rfixint(b byte) uint8 {
+ return b
+}
+
+func wnfixint(i int8) byte {
+ return byte(i) | mnfixint
+}
+
+func rnfixint(b byte) int8 {
+ return int8(b)
+}
+
+func rfixmap(b byte) uint8 {
+ return b & last4
+}
+
+func wfixmap(u uint8) byte {
+ return mfixmap | (u & last4)
+}
+
+func rfixstr(b byte) uint8 {
+ return b & last5
+}
+
+func wfixstr(u uint8) byte {
+ return (u & last5) | mfixstr
+}
+
+func rfixarray(b byte) uint8 {
+ return (b & last4)
+}
+
+func wfixarray(u uint8) byte {
+ return (u & last4) | mfixarray
+}
+
+// These are all the byte
+// prefixes defined by the
+// msgpack standard
+const (
+ // 0XXXXXXX
+ mfixint uint8 = 0x00
+
+ // 111XXXXX
+ mnfixint uint8 = 0xe0
+
+ // 1000XXXX
+ mfixmap uint8 = 0x80
+
+ // 1001XXXX
+ mfixarray uint8 = 0x90
+
+ // 101XXXXX
+ mfixstr uint8 = 0xa0
+
+ mnil uint8 = 0xc0
+ mfalse uint8 = 0xc2
+ mtrue uint8 = 0xc3
+ mbin8 uint8 = 0xc4
+ mbin16 uint8 = 0xc5
+ mbin32 uint8 = 0xc6
+ mext8 uint8 = 0xc7
+ mext16 uint8 = 0xc8
+ mext32 uint8 = 0xc9
+ mfloat32 uint8 = 0xca
+ mfloat64 uint8 = 0xcb
+ muint8 uint8 = 0xcc
+ muint16 uint8 = 0xcd
+ muint32 uint8 = 0xce
+ muint64 uint8 = 0xcf
+ mint8 uint8 = 0xd0
+ mint16 uint8 = 0xd1
+ mint32 uint8 = 0xd2
+ mint64 uint8 = 0xd3
+ mfixext1 uint8 = 0xd4
+ mfixext2 uint8 = 0xd5
+ mfixext4 uint8 = 0xd6
+ mfixext8 uint8 = 0xd7
+ mfixext16 uint8 = 0xd8
+ mstr8 uint8 = 0xd9
+ mstr16 uint8 = 0xda
+ mstr32 uint8 = 0xdb
+ marray16 uint8 = 0xdc
+ marray32 uint8 = 0xdd
+ mmap16 uint8 = 0xde
+ mmap32 uint8 = 0xdf
+)
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/edit.go b/vendor/src/github.com/tinylib/msgp/msgp/edit.go
new file mode 100644
index 0000000000..41f9298646
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/edit.go
@@ -0,0 +1,241 @@
+package msgp
+
+import (
+ "math"
+)
+
+// Locate returns a []byte pointing to the field
+// in a messagepack map with the provided key. (The returned []byte
+// points to a sub-slice of 'raw'; Locate does no allocations.) If the
+// key doesn't exist in the map, a zero-length []byte will be returned.
+func Locate(key string, raw []byte) []byte {
+ s, n := locate(raw, key)
+ return raw[s:n]
+}
+
+// Replace takes a key ("key") in a messagepack map ("raw")
+// and replaces its value with the one provided and returns
+// the new []byte. The returned []byte may point to the same
+// memory as "raw". Replace makes no effort to evaluate the validity
+// of the contents of 'val'. It may use up to the full capacity of 'raw.'
+// Replace returns 'nil' if the field doesn't exist or if the object in 'raw'
+// is not a map.
+func Replace(key string, raw []byte, val []byte) []byte {
+ start, end := locate(raw, key)
+ if start == end {
+ return nil
+ }
+ return replace(raw, start, end, val, true)
+}
+
+// CopyReplace works similarly to Replace except that the returned
+// byte slice does not point to the same memory as 'raw'. CopyReplace
+// returns 'nil' if the field doesn't exist or 'raw' isn't a map.
+func CopyReplace(key string, raw []byte, val []byte) []byte {
+ start, end := locate(raw, key)
+ if start == end {
+ return nil
+ }
+ return replace(raw, start, end, val, false)
+}
+
+// Remove removes a key-value pair from 'raw'. It returns
+// 'raw' unchanged if the key didn't exist.
+func Remove(key string, raw []byte) []byte {
+ start, end := locateKV(raw, key)
+ if start == end {
+ return raw
+ }
+ raw = raw[:start+copy(raw[start:], raw[end:])]
+ return resizeMap(raw, -1)
+}
+
+// HasKey returns whether the map in 'raw' has
+// a field with key 'key'
+func HasKey(key string, raw []byte) bool {
+ sz, bts, err := ReadMapHeaderBytes(raw)
+ if err != nil {
+ return false
+ }
+ var field []byte
+ for i := uint32(0); i < sz; i++ {
+ field, bts, err = ReadStringZC(bts)
+ if err != nil {
+ return false
+ }
+ if UnsafeString(field) == key {
+ return true
+ }
+ }
+ return false
+}
+
+func replace(raw []byte, start int, end int, val []byte, inplace bool) []byte {
+ ll := end - start // length of segment to replace
+ lv := len(val)
+
+ if inplace {
+ extra := lv - ll
+
+ // fastest case: we're doing
+ // a 1:1 replacement
+ if extra == 0 {
+ copy(raw[start:], val)
+ return raw
+
+ } else if extra < 0 {
+ // 'val' smaller than replaced value
+ // copy in place and shift back
+
+ x := copy(raw[start:], val)
+ y := copy(raw[start+x:], raw[end:])
+ return raw[:start+x+y]
+
+ } else if extra < cap(raw)-len(raw) {
+ // 'val' less than (cap-len) extra bytes
+ // copy in place and shift forward
+ raw = raw[0 : len(raw)+extra]
+ // shift end forward
+ copy(raw[end+extra:], raw[end:])
+ copy(raw[start:], val)
+ return raw
+ }
+ }
+
+ // we have to allocate new space
+ out := make([]byte, len(raw)+len(val)-ll)
+ x := copy(out, raw[:start])
+ y := copy(out[x:], val)
+ copy(out[x+y:], raw[end:])
+ return out
+}
+
+// locate does a naive O(n) search for the map key; returns start, end
+// (returns 0,0 on error)
+func locate(raw []byte, key string) (start int, end int) {
+ var (
+ sz uint32
+ bts []byte
+ field []byte
+ err error
+ )
+ sz, bts, err = ReadMapHeaderBytes(raw)
+ if err != nil {
+ return
+ }
+
+ // loop and locate field
+ for i := uint32(0); i < sz; i++ {
+ field, bts, err = ReadStringZC(bts)
+ if err != nil {
+ return 0, 0
+ }
+ if UnsafeString(field) == key {
+ // start location
+ l := len(raw)
+ start = l - len(bts)
+ bts, err = Skip(bts)
+ if err != nil {
+ return 0, 0
+ }
+ end = l - len(bts)
+ return
+ }
+ bts, err = Skip(bts)
+ if err != nil {
+ return 0, 0
+ }
+ }
+ return 0, 0
+}
+
+// locate key AND value
+func locateKV(raw []byte, key string) (start int, end int) {
+ var (
+ sz uint32
+ bts []byte
+ field []byte
+ err error
+ )
+ sz, bts, err = ReadMapHeaderBytes(raw)
+ if err != nil {
+ return 0, 0
+ }
+
+ for i := uint32(0); i < sz; i++ {
+ tmp := len(bts)
+ field, bts, err = ReadStringZC(bts)
+ if err != nil {
+ return 0, 0
+ }
+ if UnsafeString(field) == key {
+ start = len(raw) - tmp
+ bts, err = Skip(bts)
+ if err != nil {
+ return 0, 0
+ }
+ end = len(raw) - len(bts)
+ return
+ }
+ bts, err = Skip(bts)
+ if err != nil {
+ return 0, 0
+ }
+ }
+ return 0, 0
+}
+
+// delta is delta on map size
+func resizeMap(raw []byte, delta int64) []byte {
+ var sz int64
+ switch raw[0] {
+ case mmap16:
+ sz = int64(big.Uint16(raw[1:]))
+ if sz+delta <= math.MaxUint16 {
+ big.PutUint16(raw[1:], uint16(sz+delta))
+ return raw
+ }
+ if cap(raw)-len(raw) >= 2 {
+ raw = raw[0 : len(raw)+2]
+ copy(raw[5:], raw[3:])
+ big.PutUint32(raw[1:], uint32(sz+delta))
+ return raw
+ }
+ n := make([]byte, 0, len(raw)+5)
+ n = AppendMapHeader(n, uint32(sz+delta))
+ return append(n, raw[3:]...)
+
+ case mmap32:
+ sz = int64(big.Uint32(raw[1:]))
+ big.PutUint32(raw[1:], uint32(sz+delta))
+ return raw
+
+ default:
+ sz = int64(rfixmap(raw[0]))
+ if sz+delta < 16 {
+ raw[0] = wfixmap(uint8(sz + delta))
+ return raw
+ } else if sz+delta <= math.MaxUint16 {
+ if cap(raw)-len(raw) >= 2 {
+ raw = raw[0 : len(raw)+2]
+ copy(raw[3:], raw[1:])
+ raw[0] = mmap16
+ big.PutUint16(raw[1:], uint16(sz+delta))
+ return raw
+ }
+ n := make([]byte, 0, len(raw)+5)
+ n = AppendMapHeader(n, uint32(sz+delta))
+ return append(n, raw[1:]...)
+ }
+ if cap(raw)-len(raw) >= 4 {
+ raw = raw[0 : len(raw)+4]
+ copy(raw[5:], raw[1:])
+ raw[0] = mmap32
+ big.PutUint32(raw[1:], uint32(sz+delta))
+ return raw
+ }
+ n := make([]byte, 0, len(raw)+5)
+ n = AppendMapHeader(n, uint32(sz+delta))
+ return append(n, raw[1:]...)
+ }
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/elsize.go b/vendor/src/github.com/tinylib/msgp/msgp/elsize.go
new file mode 100644
index 0000000000..95762e7eeb
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/elsize.go
@@ -0,0 +1,99 @@
+package msgp
+
+// size of every object on the wire,
+// plus type information. gives us
+// constant-time type information
+// for traversing composite objects.
+//
+var sizes = [256]bytespec{
+ mnil: {size: 1, extra: constsize, typ: NilType},
+ mfalse: {size: 1, extra: constsize, typ: BoolType},
+ mtrue: {size: 1, extra: constsize, typ: BoolType},
+ mbin8: {size: 2, extra: extra8, typ: BinType},
+ mbin16: {size: 3, extra: extra16, typ: BinType},
+ mbin32: {size: 5, extra: extra32, typ: BinType},
+ mext8: {size: 3, extra: extra8, typ: ExtensionType},
+ mext16: {size: 4, extra: extra16, typ: ExtensionType},
+ mext32: {size: 6, extra: extra32, typ: ExtensionType},
+ mfloat32: {size: 5, extra: constsize, typ: Float32Type},
+ mfloat64: {size: 9, extra: constsize, typ: Float64Type},
+ muint8: {size: 2, extra: constsize, typ: UintType},
+ muint16: {size: 3, extra: constsize, typ: UintType},
+ muint32: {size: 5, extra: constsize, typ: UintType},
+ muint64: {size: 9, extra: constsize, typ: UintType},
+ mint8: {size: 2, extra: constsize, typ: IntType},
+ mint16: {size: 3, extra: constsize, typ: IntType},
+ mint32: {size: 5, extra: constsize, typ: IntType},
+ mint64: {size: 9, extra: constsize, typ: IntType},
+ mfixext1: {size: 3, extra: constsize, typ: ExtensionType},
+ mfixext2: {size: 4, extra: constsize, typ: ExtensionType},
+ mfixext4: {size: 6, extra: constsize, typ: ExtensionType},
+ mfixext8: {size: 10, extra: constsize, typ: ExtensionType},
+ mfixext16: {size: 18, extra: constsize, typ: ExtensionType},
+ mstr8: {size: 2, extra: extra8, typ: StrType},
+ mstr16: {size: 3, extra: extra16, typ: StrType},
+ mstr32: {size: 5, extra: extra32, typ: StrType},
+ marray16: {size: 3, extra: array16v, typ: ArrayType},
+ marray32: {size: 5, extra: array32v, typ: ArrayType},
+ mmap16: {size: 3, extra: map16v, typ: MapType},
+ mmap32: {size: 5, extra: map32v, typ: MapType},
+}
+
+func init() {
+ // set up fixed fields
+
+ // fixint
+ for i := mfixint; i < 0x80; i++ {
+ sizes[i] = bytespec{size: 1, extra: constsize, typ: IntType}
+ }
+
+ // nfixint
+ for i := uint16(mnfixint); i < 0x100; i++ {
+ sizes[uint8(i)] = bytespec{size: 1, extra: constsize, typ: IntType}
+ }
+
+ // fixstr gets constsize,
+ // since the prefix yields the size
+ for i := mfixstr; i < 0xc0; i++ {
+ sizes[i] = bytespec{size: 1 + rfixstr(i), extra: constsize, typ: StrType}
+ }
+
+ // fixmap
+ for i := mfixmap; i < 0x90; i++ {
+ sizes[i] = bytespec{size: 1, extra: varmode(2 * rfixmap(i)), typ: MapType}
+ }
+
+ // fixarray
+ for i := mfixarray; i < 0xa0; i++ {
+ sizes[i] = bytespec{size: 1, extra: varmode(rfixarray(i)), typ: ArrayType}
+ }
+}
+
+// a valid bytespsec has
+// non-zero 'size' and
+// non-zero 'typ'
+type bytespec struct {
+ size uint8 // prefix size information
+ extra varmode // extra size information
+ typ Type // type
+ _ byte // makes bytespec 4 bytes (yes, this matters)
+}
+
+// size mode
+// if positive, # elements for composites
+type varmode int8
+
+const (
+ constsize varmode = 0 // constant size (size bytes + uint8(varmode) objects)
+ extra8 = -1 // has uint8(p[1]) extra bytes
+ extra16 = -2 // has be16(p[1:]) extra bytes
+ extra32 = -3 // has be32(p[1:]) extra bytes
+ map16v = -4 // use map16
+ map32v = -5 // use map32
+ array16v = -6 // use array16
+ array32v = -7 // use array32
+)
+
+func getType(v byte) Type {
+ return sizes[v].typ
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/errors.go b/vendor/src/github.com/tinylib/msgp/msgp/errors.go
new file mode 100644
index 0000000000..5c24f27103
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/errors.go
@@ -0,0 +1,142 @@
+package msgp
+
+import (
+ "fmt"
+ "reflect"
+)
+
+var (
+ // ErrShortBytes is returned when the
+ // slice being decoded is too short to
+ // contain the contents of the message
+ ErrShortBytes error = errShort{}
+
+ // this error is only returned
+ // if we reach code that should
+ // be unreachable
+ fatal error = errFatal{}
+)
+
+// Error is the interface satisfied
+// by all of the errors that originate
+// from this package.
+type Error interface {
+ error
+
+ // Resumable returns whether
+ // or not the error means that
+ // the stream of data is malformed
+ // and the information is unrecoverable.
+ Resumable() bool
+}
+
+type errShort struct{}
+
+func (e errShort) Error() string { return "msgp: too few bytes left to read object" }
+func (e errShort) Resumable() bool { return false }
+
+type errFatal struct{}
+
+func (f errFatal) Error() string { return "msgp: fatal decoding error (unreachable code)" }
+func (f errFatal) Resumable() bool { return false }
+
+// ArrayError is an error returned
+// when decoding a fix-sized array
+// of the wrong size
+type ArrayError struct {
+ Wanted uint32
+ Got uint32
+}
+
+// Error implements the error interface
+func (a ArrayError) Error() string {
+ return fmt.Sprintf("msgp: wanted array of size %d; got %d", a.Wanted, a.Got)
+}
+
+// Resumable is always 'true' for ArrayErrors
+func (a ArrayError) Resumable() bool { return true }
+
+// IntOverflow is returned when a call
+// would downcast an integer to a type
+// with too few bits to hold its value.
+type IntOverflow struct {
+ Value int64 // the value of the integer
+ FailedBitsize int // the bit size that the int64 could not fit into
+}
+
+// Error implements the error interface
+func (i IntOverflow) Error() string {
+ return fmt.Sprintf("msgp: %d overflows int%d", i.Value, i.FailedBitsize)
+}
+
+// Resumable is always 'true' for overflows
+func (i IntOverflow) Resumable() bool { return true }
+
+// UintOverflow is returned when a call
+// would downcast an unsigned integer to a type
+// with too few bits to hold its value
+type UintOverflow struct {
+ Value uint64 // value of the uint
+ FailedBitsize int // the bit size that couldn't fit the value
+}
+
+// Error implements the error interface
+func (u UintOverflow) Error() string {
+ return fmt.Sprintf("msgp: %d overflows uint%d", u.Value, u.FailedBitsize)
+}
+
+// Resumable is always 'true' for overflows
+func (u UintOverflow) Resumable() bool { return true }
+
+// A TypeError is returned when a particular
+// decoding method is unsuitable for decoding
+// a particular MessagePack value.
+type TypeError struct {
+ Method Type // Type expected by method
+ Encoded Type // Type actually encoded
+}
+
+// Error implements the error interface
+func (t TypeError) Error() string {
+ return fmt.Sprintf("msgp: attempted to decode type %q with method for %q", t.Encoded, t.Method)
+}
+
+// Resumable returns 'true' for TypeErrors
+func (t TypeError) Resumable() bool { return true }
+
+// returns either InvalidPrefixError or
+// TypeError depending on whether or not
+// the prefix is recognized
+func badPrefix(want Type, lead byte) error {
+ t := sizes[lead].typ
+ if t == InvalidType {
+ return InvalidPrefixError(lead)
+ }
+ return TypeError{Method: want, Encoded: t}
+}
+
+// InvalidPrefixError is returned when a bad encoding
+// uses a prefix that is not recognized in the MessagePack standard.
+// This kind of error is unrecoverable.
+type InvalidPrefixError byte
+
+// Error implements the error interface
+func (i InvalidPrefixError) Error() string {
+ return fmt.Sprintf("msgp: unrecognized type prefix 0x%x", byte(i))
+}
+
+// Resumable returns 'false' for InvalidPrefixErrors
+func (i InvalidPrefixError) Resumable() bool { return false }
+
+// ErrUnsupportedType is returned
+// when a bad argument is supplied
+// to a function that takes `interface{}`.
+type ErrUnsupportedType struct {
+ T reflect.Type
+}
+
+// Error implements error
+func (e *ErrUnsupportedType) Error() string { return fmt.Sprintf("msgp: type %q not supported", e.T) }
+
+// Resumable returns 'true' for ErrUnsupportedType
+func (e *ErrUnsupportedType) Resumable() bool { return true }
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/extension.go b/vendor/src/github.com/tinylib/msgp/msgp/extension.go
new file mode 100644
index 0000000000..32a0ada60b
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/extension.go
@@ -0,0 +1,548 @@
+package msgp
+
+import (
+ "fmt"
+ "math"
+)
+
+const (
+ // Complex64Extension is the extension number used for complex64
+ Complex64Extension = 3
+
+ // Complex128Extension is the extension number used for complex128
+ Complex128Extension = 4
+
+ // TimeExtension is the extension number used for time.Time
+ TimeExtension = 5
+)
+
+// our extensions live here
+var extensionReg = make(map[int8]func() Extension)
+
+// RegisterExtension registers extensions so that they
+// can be initialized and returned by methods that
+// decode `interface{}` values. This should only
+// be called during initialization. f() should return
+// a newly-initialized zero value of the extension. Keep in
+// mind that extensions 3, 4, and 5 are reserved for
+// complex64, complex128, and time.Time, respectively,
+// and that MessagePack reserves extension types from -127 to -1.
+//
+// For example, if you wanted to register a user-defined struct:
+//
+// msgp.RegisterExtension(10, func() msgp.Extension { &MyExtension{} })
+//
+// RegisterExtension will panic if you call it multiple times
+// with the same 'typ' argument, or if you use a reserved
+// type (3, 4, or 5).
+func RegisterExtension(typ int8, f func() Extension) {
+ switch typ {
+ case Complex64Extension, Complex128Extension, TimeExtension:
+ panic(fmt.Sprint("msgp: forbidden extension type:", typ))
+ }
+ if _, ok := extensionReg[typ]; ok {
+ panic(fmt.Sprint("msgp: RegisterExtension() called with typ", typ, "more than once"))
+ }
+ extensionReg[typ] = f
+}
+
+// ExtensionTypeError is an error type returned
+// when there is a mis-match between an extension type
+// and the type encoded on the wire
+type ExtensionTypeError struct {
+ Got int8
+ Want int8
+}
+
+// Error implements the error interface
+func (e ExtensionTypeError) Error() string {
+ return fmt.Sprintf("msgp: error decoding extension: wanted type %d; got type %d", e.Want, e.Got)
+}
+
+// Resumable returns 'true' for ExtensionTypeErrors
+func (e ExtensionTypeError) Resumable() bool { return true }
+
+func errExt(got int8, wanted int8) error {
+ return ExtensionTypeError{Got: got, Want: wanted}
+}
+
+// Extension is the interface fulfilled
+// by types that want to define their
+// own binary encoding.
+type Extension interface {
+ // ExtensionType should return
+ // a int8 that identifies the concrete
+ // type of the extension. (Types <0 are
+ // officially reserved by the MessagePack
+ // specifications.)
+ ExtensionType() int8
+
+ // Len should return the length
+ // of the data to be encoded
+ Len() int
+
+ // MarshalBinaryTo should copy
+ // the data into the supplied slice,
+ // assuming that the slice has length Len()
+ MarshalBinaryTo([]byte) error
+
+ UnmarshalBinary([]byte) error
+}
+
+// RawExtension implements the Extension interface
+type RawExtension struct {
+ Data []byte
+ Type int8
+}
+
+// ExtensionType implements Extension.ExtensionType, and returns r.Type
+func (r *RawExtension) ExtensionType() int8 { return r.Type }
+
+// Len implements Extension.Len, and returns len(r.Data)
+func (r *RawExtension) Len() int { return len(r.Data) }
+
+// MarshalBinaryTo implements Extension.MarshalBinaryTo,
+// and returns a copy of r.Data
+func (r *RawExtension) MarshalBinaryTo(d []byte) error {
+ copy(d, r.Data)
+ return nil
+}
+
+// UnmarshalBinary implements Extension.UnmarshalBinary,
+// and sets r.Data to the contents of the provided slice
+func (r *RawExtension) UnmarshalBinary(b []byte) error {
+ if cap(r.Data) >= len(b) {
+ r.Data = r.Data[0:len(b)]
+ } else {
+ r.Data = make([]byte, len(b))
+ }
+ copy(r.Data, b)
+ return nil
+}
+
+// WriteExtension writes an extension type to the writer
+func (mw *Writer) WriteExtension(e Extension) error {
+ l := e.Len()
+ var err error
+ switch l {
+ case 0:
+ o, err := mw.require(3)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mext8
+ mw.buf[o+1] = 0
+ mw.buf[o+2] = byte(e.ExtensionType())
+ case 1:
+ o, err := mw.require(2)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mfixext1
+ mw.buf[o+1] = byte(e.ExtensionType())
+ case 2:
+ o, err := mw.require(2)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mfixext2
+ mw.buf[o+1] = byte(e.ExtensionType())
+ case 4:
+ o, err := mw.require(2)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mfixext4
+ mw.buf[o+1] = byte(e.ExtensionType())
+ case 8:
+ o, err := mw.require(2)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mfixext8
+ mw.buf[o+1] = byte(e.ExtensionType())
+ case 16:
+ o, err := mw.require(2)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mfixext16
+ mw.buf[o+1] = byte(e.ExtensionType())
+ default:
+ switch {
+ case l < math.MaxUint8:
+ o, err := mw.require(3)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mext8
+ mw.buf[o+1] = byte(uint8(l))
+ mw.buf[o+2] = byte(e.ExtensionType())
+ case l < math.MaxUint16:
+ o, err := mw.require(4)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mext16
+ big.PutUint16(mw.buf[o+1:], uint16(l))
+ mw.buf[o+3] = byte(e.ExtensionType())
+ default:
+ o, err := mw.require(6)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mext32
+ big.PutUint32(mw.buf[o+1:], uint32(l))
+ mw.buf[o+5] = byte(e.ExtensionType())
+ }
+ }
+ // we can only write directly to the
+ // buffer if we're sure that it
+ // fits the object
+ if l <= mw.bufsize() {
+ o, err := mw.require(l)
+ if err != nil {
+ return err
+ }
+ return e.MarshalBinaryTo(mw.buf[o:])
+ }
+ // here we create a new buffer
+ // just large enough for the body
+ // and save it as the write buffer
+ err = mw.flush()
+ if err != nil {
+ return err
+ }
+ buf := make([]byte, l)
+ err = e.MarshalBinaryTo(buf)
+ if err != nil {
+ return err
+ }
+ mw.buf = buf
+ mw.wloc = l
+ return nil
+}
+
+// peek at the extension type, assuming the next
+// kind to be read is Extension
+func (m *Reader) peekExtensionType() (int8, error) {
+ p, err := m.r.Peek(2)
+ if err != nil {
+ return 0, err
+ }
+ spec := sizes[p[0]]
+ if spec.typ != ExtensionType {
+ return 0, badPrefix(ExtensionType, p[0])
+ }
+ if spec.extra == constsize {
+ return int8(p[1]), nil
+ }
+ size := spec.size
+ p, err = m.r.Peek(int(size))
+ if err != nil {
+ return 0, err
+ }
+ return int8(p[size-1]), nil
+}
+
+// peekExtension peeks at the extension encoding type
+// (must guarantee at least 1 byte in 'b')
+func peekExtension(b []byte) (int8, error) {
+ spec := sizes[b[0]]
+ size := spec.size
+ if spec.typ != ExtensionType {
+ return 0, badPrefix(ExtensionType, b[0])
+ }
+ if len(b) < int(size) {
+ return 0, ErrShortBytes
+ }
+ // for fixed extensions,
+ // the type information is in
+ // the second byte
+ if spec.extra == constsize {
+ return int8(b[1]), nil
+ }
+ // otherwise, it's in the last
+ // part of the prefix
+ return int8(b[size-1]), nil
+}
+
+// ReadExtension reads the next object from the reader
+// as an extension. ReadExtension will fail if the next
+// object in the stream is not an extension, or if
+// e.Type() is not the same as the wire type.
+func (m *Reader) ReadExtension(e Extension) (err error) {
+ var p []byte
+ p, err = m.r.Peek(2)
+ if err != nil {
+ return
+ }
+ lead := p[0]
+ var read int
+ var off int
+ switch lead {
+ case mfixext1:
+ if int8(p[1]) != e.ExtensionType() {
+ err = errExt(int8(p[1]), e.ExtensionType())
+ return
+ }
+ p, err = m.r.Peek(3)
+ if err != nil {
+ return
+ }
+ err = e.UnmarshalBinary(p[2:])
+ if err == nil {
+ _, err = m.r.Skip(3)
+ }
+ return
+
+ case mfixext2:
+ if int8(p[1]) != e.ExtensionType() {
+ err = errExt(int8(p[1]), e.ExtensionType())
+ return
+ }
+ p, err = m.r.Peek(4)
+ if err != nil {
+ return
+ }
+ err = e.UnmarshalBinary(p[2:])
+ if err == nil {
+ _, err = m.r.Skip(4)
+ }
+ return
+
+ case mfixext4:
+ if int8(p[1]) != e.ExtensionType() {
+ err = errExt(int8(p[1]), e.ExtensionType())
+ return
+ }
+ p, err = m.r.Peek(6)
+ if err != nil {
+ return
+ }
+ err = e.UnmarshalBinary(p[2:])
+ if err == nil {
+ _, err = m.r.Skip(6)
+ }
+ return
+
+ case mfixext8:
+ if int8(p[1]) != e.ExtensionType() {
+ err = errExt(int8(p[1]), e.ExtensionType())
+ return
+ }
+ p, err = m.r.Peek(10)
+ if err != nil {
+ return
+ }
+ err = e.UnmarshalBinary(p[2:])
+ if err == nil {
+ _, err = m.r.Skip(10)
+ }
+ return
+
+ case mfixext16:
+ if int8(p[1]) != e.ExtensionType() {
+ err = errExt(int8(p[1]), e.ExtensionType())
+ return
+ }
+ p, err = m.r.Peek(18)
+ if err != nil {
+ return
+ }
+ err = e.UnmarshalBinary(p[2:])
+ if err == nil {
+ _, err = m.r.Skip(18)
+ }
+ return
+
+ case mext8:
+ p, err = m.r.Peek(3)
+ if err != nil {
+ return
+ }
+ if int8(p[2]) != e.ExtensionType() {
+ err = errExt(int8(p[2]), e.ExtensionType())
+ return
+ }
+ read = int(uint8(p[1]))
+ off = 3
+
+ case mext16:
+ p, err = m.r.Peek(4)
+ if err != nil {
+ return
+ }
+ if int8(p[3]) != e.ExtensionType() {
+ err = errExt(int8(p[3]), e.ExtensionType())
+ return
+ }
+ read = int(big.Uint16(p[1:]))
+ off = 4
+
+ case mext32:
+ p, err = m.r.Peek(6)
+ if err != nil {
+ return
+ }
+ if int8(p[5]) != e.ExtensionType() {
+ err = errExt(int8(p[5]), e.ExtensionType())
+ return
+ }
+ read = int(big.Uint32(p[1:]))
+ off = 6
+
+ default:
+ err = badPrefix(ExtensionType, lead)
+ return
+ }
+
+ p, err = m.r.Peek(read + off)
+ if err != nil {
+ return
+ }
+ err = e.UnmarshalBinary(p[off:])
+ if err == nil {
+ _, err = m.r.Skip(read + off)
+ }
+ return
+}
+
+// AppendExtension appends a MessagePack extension to the provided slice
+func AppendExtension(b []byte, e Extension) ([]byte, error) {
+ l := e.Len()
+ var o []byte
+ var n int
+ switch l {
+ case 0:
+ o, n = ensure(b, 3)
+ o[n] = mext8
+ o[n+1] = 0
+ o[n+2] = byte(e.ExtensionType())
+ return o[:n+3], nil
+ case 1:
+ o, n = ensure(b, 3)
+ o[n] = mfixext1
+ o[n+1] = byte(e.ExtensionType())
+ n += 2
+ case 2:
+ o, n = ensure(b, 4)
+ o[n] = mfixext2
+ o[n+1] = byte(e.ExtensionType())
+ n += 2
+ case 4:
+ o, n = ensure(b, 6)
+ o[n] = mfixext4
+ o[n+1] = byte(e.ExtensionType())
+ n += 2
+ case 8:
+ o, n = ensure(b, 10)
+ o[n] = mfixext8
+ o[n+1] = byte(e.ExtensionType())
+ n += 2
+ case 16:
+ o, n = ensure(b, 18)
+ o[n] = mfixext16
+ o[n+1] = byte(e.ExtensionType())
+ n += 2
+ }
+ switch {
+ case l < math.MaxUint8:
+ o, n = ensure(b, l+3)
+ o[n] = mext8
+ o[n+1] = byte(uint8(l))
+ o[n+2] = byte(e.ExtensionType())
+ n += 3
+ case l < math.MaxUint16:
+ o, n = ensure(b, l+4)
+ o[n] = mext16
+ big.PutUint16(o[n+1:], uint16(l))
+ o[n+3] = byte(e.ExtensionType())
+ n += 4
+ default:
+ o, n = ensure(b, l+6)
+ o[n] = mext32
+ big.PutUint32(o[n+1:], uint32(l))
+ o[n+5] = byte(e.ExtensionType())
+ n += 6
+ }
+ return o, e.MarshalBinaryTo(o[n:])
+}
+
+// ReadExtensionBytes reads an extension from 'b' into 'e'
+// and returns any remaining bytes.
+// Possible errors:
+// - ErrShortBytes ('b' not long enough)
+// - ExtensionTypeErorr{} (wire type not the same as e.Type())
+// - TypeErorr{} (next object not an extension)
+// - InvalidPrefixError
+// - An umarshal error returned from e.UnmarshalBinary
+func ReadExtensionBytes(b []byte, e Extension) ([]byte, error) {
+ l := len(b)
+ if l < 3 {
+ return b, ErrShortBytes
+ }
+ lead := b[0]
+ var (
+ sz int // size of 'data'
+ off int // offset of 'data'
+ typ int8
+ )
+ switch lead {
+ case mfixext1:
+ typ = int8(b[1])
+ sz = 1
+ off = 2
+ case mfixext2:
+ typ = int8(b[1])
+ sz = 2
+ off = 2
+ case mfixext4:
+ typ = int8(b[1])
+ sz = 4
+ off = 2
+ case mfixext8:
+ typ = int8(b[1])
+ sz = 8
+ off = 2
+ case mfixext16:
+ typ = int8(b[1])
+ sz = 16
+ off = 2
+ case mext8:
+ sz = int(uint8(b[1]))
+ typ = int8(b[2])
+ off = 3
+ if sz == 0 {
+ return b[3:], e.UnmarshalBinary(b[3:3])
+ }
+ case mext16:
+ if l < 4 {
+ return b, ErrShortBytes
+ }
+ sz = int(big.Uint16(b[1:]))
+ typ = int8(b[3])
+ off = 4
+ case mext32:
+ if l < 6 {
+ return b, ErrShortBytes
+ }
+ sz = int(big.Uint32(b[1:]))
+ typ = int8(b[5])
+ off = 6
+ default:
+ return b, badPrefix(ExtensionType, lead)
+ }
+
+ if typ != e.ExtensionType() {
+ return b, errExt(typ, e.ExtensionType())
+ }
+
+ // the data of the extension starts
+ // at 'off' and is 'sz' bytes long
+ if len(b[off:]) < sz {
+ return b, ErrShortBytes
+ }
+ tot := off + sz
+ return b[tot:], e.UnmarshalBinary(b[off:tot])
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/integers.go b/vendor/src/github.com/tinylib/msgp/msgp/integers.go
new file mode 100644
index 0000000000..f817d77598
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/integers.go
@@ -0,0 +1,174 @@
+package msgp
+
+/* ----------------------------------
+ integer encoding utilities
+ (inline-able)
+
+ TODO(tinylib): there are faster,
+ albeit non-portable solutions
+ to the code below. implement
+ byteswap?
+ ---------------------------------- */
+
+func putMint64(b []byte, i int64) {
+ b[0] = mint64
+ b[1] = byte(i >> 56)
+ b[2] = byte(i >> 48)
+ b[3] = byte(i >> 40)
+ b[4] = byte(i >> 32)
+ b[5] = byte(i >> 24)
+ b[6] = byte(i >> 16)
+ b[7] = byte(i >> 8)
+ b[8] = byte(i)
+}
+
+func getMint64(b []byte) int64 {
+ return (int64(b[1]) << 56) | (int64(b[2]) << 48) |
+ (int64(b[3]) << 40) | (int64(b[4]) << 32) |
+ (int64(b[5]) << 24) | (int64(b[6]) << 16) |
+ (int64(b[7]) << 8) | (int64(b[8]))
+}
+
+func putMint32(b []byte, i int32) {
+ b[0] = mint32
+ b[1] = byte(i >> 24)
+ b[2] = byte(i >> 16)
+ b[3] = byte(i >> 8)
+ b[4] = byte(i)
+}
+
+func getMint32(b []byte) int32 {
+ return (int32(b[1]) << 24) | (int32(b[2]) << 16) | (int32(b[3]) << 8) | (int32(b[4]))
+}
+
+func putMint16(b []byte, i int16) {
+ b[0] = mint16
+ b[1] = byte(i >> 8)
+ b[2] = byte(i)
+}
+
+func getMint16(b []byte) (i int16) {
+ return (int16(b[1]) << 8) | int16(b[2])
+}
+
+func putMint8(b []byte, i int8) {
+ b[0] = mint8
+ b[1] = byte(i)
+}
+
+func getMint8(b []byte) (i int8) {
+ return int8(b[1])
+}
+
+func putMuint64(b []byte, u uint64) {
+ b[0] = muint64
+ b[1] = byte(u >> 56)
+ b[2] = byte(u >> 48)
+ b[3] = byte(u >> 40)
+ b[4] = byte(u >> 32)
+ b[5] = byte(u >> 24)
+ b[6] = byte(u >> 16)
+ b[7] = byte(u >> 8)
+ b[8] = byte(u)
+}
+
+func getMuint64(b []byte) uint64 {
+ return (uint64(b[1]) << 56) | (uint64(b[2]) << 48) |
+ (uint64(b[3]) << 40) | (uint64(b[4]) << 32) |
+ (uint64(b[5]) << 24) | (uint64(b[6]) << 16) |
+ (uint64(b[7]) << 8) | (uint64(b[8]))
+}
+
+func putMuint32(b []byte, u uint32) {
+ b[0] = muint32
+ b[1] = byte(u >> 24)
+ b[2] = byte(u >> 16)
+ b[3] = byte(u >> 8)
+ b[4] = byte(u)
+}
+
+func getMuint32(b []byte) uint32 {
+ return (uint32(b[1]) << 24) | (uint32(b[2]) << 16) | (uint32(b[3]) << 8) | (uint32(b[4]))
+}
+
+func putMuint16(b []byte, u uint16) {
+ b[0] = muint16
+ b[1] = byte(u >> 8)
+ b[2] = byte(u)
+}
+
+func getMuint16(b []byte) uint16 {
+ return (uint16(b[1]) << 8) | uint16(b[2])
+}
+
+func putMuint8(b []byte, u uint8) {
+ b[0] = muint8
+ b[1] = byte(u)
+}
+
+func getMuint8(b []byte) uint8 {
+ return uint8(b[1])
+}
+
+func getUnix(b []byte) (sec int64, nsec int32) {
+ sec = (int64(b[0]) << 56) | (int64(b[1]) << 48) |
+ (int64(b[2]) << 40) | (int64(b[3]) << 32) |
+ (int64(b[4]) << 24) | (int64(b[5]) << 16) |
+ (int64(b[6]) << 8) | (int64(b[7]))
+
+ nsec = (int32(b[8]) << 24) | (int32(b[9]) << 16) | (int32(b[10]) << 8) | (int32(b[11]))
+ return
+}
+
+func putUnix(b []byte, sec int64, nsec int32) {
+ b[0] = byte(sec >> 56)
+ b[1] = byte(sec >> 48)
+ b[2] = byte(sec >> 40)
+ b[3] = byte(sec >> 32)
+ b[4] = byte(sec >> 24)
+ b[5] = byte(sec >> 16)
+ b[6] = byte(sec >> 8)
+ b[7] = byte(sec)
+ b[8] = byte(nsec >> 24)
+ b[9] = byte(nsec >> 16)
+ b[10] = byte(nsec >> 8)
+ b[11] = byte(nsec)
+}
+
+/* -----------------------------
+ prefix utilities
+ ----------------------------- */
+
+// write prefix and uint8
+func prefixu8(b []byte, pre byte, sz uint8) {
+ b[0] = pre
+ b[1] = byte(sz)
+}
+
+// write prefix and big-endian uint16
+func prefixu16(b []byte, pre byte, sz uint16) {
+ b[0] = pre
+ b[1] = byte(sz >> 8)
+ b[2] = byte(sz)
+}
+
+// write prefix and big-endian uint32
+func prefixu32(b []byte, pre byte, sz uint32) {
+ b[0] = pre
+ b[1] = byte(sz >> 24)
+ b[2] = byte(sz >> 16)
+ b[3] = byte(sz >> 8)
+ b[4] = byte(sz)
+}
+
+func prefixu64(b []byte, pre byte, sz uint64) {
+ b[0] = pre
+ b[1] = byte(sz >> 56)
+ b[2] = byte(sz >> 48)
+ b[3] = byte(sz >> 40)
+ b[4] = byte(sz >> 32)
+ b[5] = byte(sz >> 24)
+ b[6] = byte(sz >> 16)
+ b[7] = byte(sz >> 8)
+ b[8] = byte(sz)
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/json.go b/vendor/src/github.com/tinylib/msgp/msgp/json.go
new file mode 100644
index 0000000000..5c799ff7ba
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/json.go
@@ -0,0 +1,542 @@
+package msgp
+
+import (
+ "bufio"
+ "encoding/base64"
+ "encoding/json"
+ "io"
+ "strconv"
+ "unicode/utf8"
+)
+
+var (
+ null = []byte("null")
+ hex = []byte("0123456789abcdef")
+)
+
+var defuns [_maxtype]func(jsWriter, *Reader) (int, error)
+
+// note: there is an initialization loop if
+// this isn't set up during init()
+func init() {
+ // since none of these functions are inline-able,
+ // there is not much of a penalty to the indirect
+ // call. however, this is best expressed as a jump-table...
+ defuns = [_maxtype]func(jsWriter, *Reader) (int, error){
+ StrType: rwString,
+ BinType: rwBytes,
+ MapType: rwMap,
+ ArrayType: rwArray,
+ Float64Type: rwFloat64,
+ Float32Type: rwFloat32,
+ BoolType: rwBool,
+ IntType: rwInt,
+ UintType: rwUint,
+ NilType: rwNil,
+ ExtensionType: rwExtension,
+ Complex64Type: rwExtension,
+ Complex128Type: rwExtension,
+ TimeType: rwTime,
+ }
+}
+
+// this is the interface
+// used to write json
+type jsWriter interface {
+ io.Writer
+ io.ByteWriter
+ WriteString(string) (int, error)
+}
+
+// CopyToJSON reads MessagePack from 'src' and copies it
+// as JSON to 'dst' until EOF.
+func CopyToJSON(dst io.Writer, src io.Reader) (n int64, err error) {
+ r := NewReader(src)
+ n, err = r.WriteToJSON(dst)
+ freeR(r)
+ return
+}
+
+// WriteToJSON translates MessagePack from 'r' and writes it as
+// JSON to 'w' until the underlying reader returns io.EOF. It returns
+// the number of bytes written, and an error if it stopped before EOF.
+func (r *Reader) WriteToJSON(w io.Writer) (n int64, err error) {
+ var j jsWriter
+ var bf *bufio.Writer
+ if jsw, ok := w.(jsWriter); ok {
+ j = jsw
+ } else {
+ bf = bufio.NewWriterSize(w, 512)
+ j = bf
+ }
+ var nn int
+ for err == nil {
+ nn, err = rwNext(j, r)
+ n += int64(nn)
+ }
+ if err != io.EOF {
+ if bf != nil {
+ bf.Flush()
+ }
+ return
+ }
+ err = nil
+ if bf != nil {
+ err = bf.Flush()
+ }
+ return
+}
+
+func rwNext(w jsWriter, src *Reader) (int, error) {
+ t, err := src.NextType()
+ if err != nil {
+ return 0, err
+ }
+ return defuns[t](w, src)
+}
+
+func rwMap(dst jsWriter, src *Reader) (n int, err error) {
+ var comma bool
+ var sz uint32
+ var field []byte
+
+ sz, err = src.ReadMapHeader()
+ if err != nil {
+ return
+ }
+
+ if sz == 0 {
+ return dst.WriteString("{}")
+ }
+
+ err = dst.WriteByte('{')
+ if err != nil {
+ return
+ }
+ n++
+ var nn int
+ for i := uint32(0); i < sz; i++ {
+ if comma {
+ err = dst.WriteByte(',')
+ if err != nil {
+ return
+ }
+ n++
+ }
+
+ field, err = src.ReadMapKeyPtr()
+ if err != nil {
+ return
+ }
+ nn, err = rwquoted(dst, field)
+ n += nn
+ if err != nil {
+ return
+ }
+
+ err = dst.WriteByte(':')
+ if err != nil {
+ return
+ }
+ n++
+ nn, err = rwNext(dst, src)
+ n += nn
+ if err != nil {
+ return
+ }
+ if !comma {
+ comma = true
+ }
+ }
+
+ err = dst.WriteByte('}')
+ if err != nil {
+ return
+ }
+ n++
+ return
+}
+
+func rwArray(dst jsWriter, src *Reader) (n int, err error) {
+ err = dst.WriteByte('[')
+ if err != nil {
+ return
+ }
+ var sz uint32
+ var nn int
+ sz, err = src.ReadArrayHeader()
+ if err != nil {
+ return
+ }
+ comma := false
+ for i := uint32(0); i < sz; i++ {
+ if comma {
+ err = dst.WriteByte(',')
+ if err != nil {
+ return
+ }
+ n++
+ }
+ nn, err = rwNext(dst, src)
+ n += nn
+ if err != nil {
+ return
+ }
+ comma = true
+ }
+
+ err = dst.WriteByte(']')
+ if err != nil {
+ return
+ }
+ n++
+ return
+}
+
+func rwNil(dst jsWriter, src *Reader) (int, error) {
+ err := src.ReadNil()
+ if err != nil {
+ return 0, err
+ }
+ return dst.Write(null)
+}
+
+func rwFloat32(dst jsWriter, src *Reader) (int, error) {
+ f, err := src.ReadFloat32()
+ if err != nil {
+ return 0, err
+ }
+ src.scratch = strconv.AppendFloat(src.scratch[:0], float64(f), 'f', -1, 64)
+ return dst.Write(src.scratch)
+}
+
+func rwFloat64(dst jsWriter, src *Reader) (int, error) {
+ f, err := src.ReadFloat64()
+ if err != nil {
+ return 0, err
+ }
+ src.scratch = strconv.AppendFloat(src.scratch[:0], f, 'f', -1, 32)
+ return dst.Write(src.scratch)
+}
+
+func rwInt(dst jsWriter, src *Reader) (int, error) {
+ i, err := src.ReadInt64()
+ if err != nil {
+ return 0, err
+ }
+ src.scratch = strconv.AppendInt(src.scratch[:0], i, 10)
+ return dst.Write(src.scratch)
+}
+
+func rwUint(dst jsWriter, src *Reader) (int, error) {
+ u, err := src.ReadUint64()
+ if err != nil {
+ return 0, err
+ }
+ src.scratch = strconv.AppendUint(src.scratch[:0], u, 10)
+ return dst.Write(src.scratch)
+}
+
+func rwBool(dst jsWriter, src *Reader) (int, error) {
+ b, err := src.ReadBool()
+ if err != nil {
+ return 0, err
+ }
+ if b {
+ return dst.WriteString("true")
+ }
+ return dst.WriteString("false")
+}
+
+func rwTime(dst jsWriter, src *Reader) (int, error) {
+ t, err := src.ReadTime()
+ if err != nil {
+ return 0, err
+ }
+ bts, err := t.MarshalJSON()
+ if err != nil {
+ return 0, err
+ }
+ return dst.Write(bts)
+}
+
+func rwExtension(dst jsWriter, src *Reader) (n int, err error) {
+ et, err := src.peekExtensionType()
+ if err != nil {
+ return 0, err
+ }
+
+ // registered extensions can override
+ // the JSON encoding
+ if j, ok := extensionReg[et]; ok {
+ var bts []byte
+ e := j()
+ err = src.ReadExtension(e)
+ if err != nil {
+ return
+ }
+ bts, err = json.Marshal(e)
+ if err != nil {
+ return
+ }
+ return dst.Write(bts)
+ }
+
+ e := RawExtension{}
+ e.Type = et
+ err = src.ReadExtension(&e)
+ if err != nil {
+ return
+ }
+
+ var nn int
+ err = dst.WriteByte('{')
+ if err != nil {
+ return
+ }
+ n++
+
+ nn, err = dst.WriteString(`"type:"`)
+ n += nn
+ if err != nil {
+ return
+ }
+
+ src.scratch = strconv.AppendInt(src.scratch[0:0], int64(e.Type), 10)
+ nn, err = dst.Write(src.scratch)
+ n += nn
+ if err != nil {
+ return
+ }
+
+ nn, err = dst.WriteString(`,"data":"`)
+ n += nn
+ if err != nil {
+ return
+ }
+
+ enc := base64.NewEncoder(base64.StdEncoding, dst)
+
+ nn, err = enc.Write(e.Data)
+ n += nn
+ if err != nil {
+ return
+ }
+ err = enc.Close()
+ if err != nil {
+ return
+ }
+ nn, err = dst.WriteString(`"}`)
+ n += nn
+ return
+}
+
+func rwString(dst jsWriter, src *Reader) (n int, err error) {
+ var p []byte
+ p, err = src.r.Peek(1)
+ if err != nil {
+ return
+ }
+ lead := p[0]
+ var read int
+
+ if isfixstr(lead) {
+ read = int(rfixstr(lead))
+ src.r.Skip(1)
+ goto write
+ }
+
+ switch lead {
+ case mstr8:
+ p, err = src.r.Next(2)
+ if err != nil {
+ return
+ }
+ read = int(uint8(p[1]))
+ case mstr16:
+ p, err = src.r.Next(3)
+ if err != nil {
+ return
+ }
+ read = int(big.Uint16(p[1:]))
+ case mstr32:
+ p, err = src.r.Next(5)
+ if err != nil {
+ return
+ }
+ read = int(big.Uint32(p[1:]))
+ default:
+ err = badPrefix(StrType, lead)
+ return
+ }
+write:
+ p, err = src.r.Next(read)
+ if err != nil {
+ return
+ }
+ n, err = rwquoted(dst, p)
+ return
+}
+
+func rwBytes(dst jsWriter, src *Reader) (n int, err error) {
+ var nn int
+ err = dst.WriteByte('"')
+ if err != nil {
+ return
+ }
+ n++
+ src.scratch, err = src.ReadBytes(src.scratch[:0])
+ if err != nil {
+ return
+ }
+ enc := base64.NewEncoder(base64.StdEncoding, dst)
+ nn, err = enc.Write(src.scratch)
+ n += nn
+ if err != nil {
+ return
+ }
+ err = enc.Close()
+ if err != nil {
+ return
+ }
+ err = dst.WriteByte('"')
+ if err != nil {
+ return
+ }
+ n++
+ return
+}
+
+// Below (c) The Go Authors, 2009-2014
+// Subject to the BSD-style license found at http://golang.org
+//
+// see: encoding/json/encode.go:(*encodeState).stringbytes()
+func rwquoted(dst jsWriter, s []byte) (n int, err error) {
+ var nn int
+ err = dst.WriteByte('"')
+ if err != nil {
+ return
+ }
+ n++
+ start := 0
+ for i := 0; i < len(s); {
+ if b := s[i]; b < utf8.RuneSelf {
+ if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
+ i++
+ continue
+ }
+ if start < i {
+ nn, err = dst.Write(s[start:i])
+ n += nn
+ if err != nil {
+ return
+ }
+ }
+ switch b {
+ case '\\', '"':
+ err = dst.WriteByte('\\')
+ if err != nil {
+ return
+ }
+ n++
+ err = dst.WriteByte(b)
+ if err != nil {
+ return
+ }
+ n++
+ case '\n':
+ err = dst.WriteByte('\\')
+ if err != nil {
+ return
+ }
+ n++
+ err = dst.WriteByte('n')
+ if err != nil {
+ return
+ }
+ n++
+ case '\r':
+ err = dst.WriteByte('\\')
+ if err != nil {
+ return
+ }
+ n++
+ err = dst.WriteByte('r')
+ if err != nil {
+ return
+ }
+ n++
+ default:
+ nn, err = dst.WriteString(`\u00`)
+ n += nn
+ if err != nil {
+ return
+ }
+ err = dst.WriteByte(hex[b>>4])
+ if err != nil {
+ return
+ }
+ n++
+ err = dst.WriteByte(hex[b&0xF])
+ if err != nil {
+ return
+ }
+ n++
+ }
+ i++
+ start = i
+ continue
+ }
+ c, size := utf8.DecodeRune(s[i:])
+ if c == utf8.RuneError && size == 1 {
+ if start < i {
+ nn, err = dst.Write(s[start:i])
+ n += nn
+ if err != nil {
+ return
+ }
+ nn, err = dst.WriteString(`\ufffd`)
+ n += nn
+ if err != nil {
+ return
+ }
+ i += size
+ start = i
+ continue
+ }
+ }
+ if c == '\u2028' || c == '\u2029' {
+ if start < i {
+ nn, err = dst.Write(s[start:i])
+ n += nn
+ if err != nil {
+ return
+ }
+ nn, err = dst.WriteString(`\u202`)
+ n += nn
+ if err != nil {
+ return
+ }
+ err = dst.WriteByte(hex[c&0xF])
+ if err != nil {
+ return
+ }
+ n++
+ }
+ }
+ i += size
+ }
+ if start < len(s) {
+ nn, err = dst.Write(s[start:])
+ n += nn
+ if err != nil {
+ return
+ }
+ }
+ err = dst.WriteByte('"')
+ if err != nil {
+ return
+ }
+ n++
+ return
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/json_bytes.go b/vendor/src/github.com/tinylib/msgp/msgp/json_bytes.go
new file mode 100644
index 0000000000..438caf5392
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/json_bytes.go
@@ -0,0 +1,363 @@
+package msgp
+
+import (
+ "bufio"
+ "encoding/base64"
+ "encoding/json"
+ "io"
+ "strconv"
+ "time"
+)
+
+var unfuns [_maxtype]func(jsWriter, []byte, []byte) ([]byte, []byte, error)
+
+func init() {
+
+ // NOTE(pmh): this is best expressed as a jump table,
+ // but gc doesn't do that yet. revisit post-go1.5.
+ unfuns = [_maxtype]func(jsWriter, []byte, []byte) ([]byte, []byte, error){
+ StrType: rwStringBytes,
+ BinType: rwBytesBytes,
+ MapType: rwMapBytes,
+ ArrayType: rwArrayBytes,
+ Float64Type: rwFloat64Bytes,
+ Float32Type: rwFloat32Bytes,
+ BoolType: rwBoolBytes,
+ IntType: rwIntBytes,
+ UintType: rwUintBytes,
+ NilType: rwNullBytes,
+ ExtensionType: rwExtensionBytes,
+ Complex64Type: rwExtensionBytes,
+ Complex128Type: rwExtensionBytes,
+ TimeType: rwTimeBytes,
+ }
+}
+
+// UnmarshalAsJSON takes raw messagepack and writes
+// it as JSON to 'w'. If an error is returned, the
+// bytes not translated will also be returned. If
+// no errors are encountered, the length of the returned
+// slice will be zero.
+func UnmarshalAsJSON(w io.Writer, msg []byte) ([]byte, error) {
+ var (
+ scratch []byte
+ cast bool
+ dst jsWriter
+ err error
+ )
+ if jsw, ok := w.(jsWriter); ok {
+ dst = jsw
+ cast = true
+ } else {
+ dst = bufio.NewWriterSize(w, 512)
+ }
+ for len(msg) > 0 && err == nil {
+ msg, scratch, err = writeNext(dst, msg, scratch)
+ }
+ if !cast && err == nil {
+ err = dst.(*bufio.Writer).Flush()
+ }
+ return msg, err
+}
+
+func writeNext(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ if len(msg) < 1 {
+ return msg, scratch, ErrShortBytes
+ }
+ t := getType(msg[0])
+ if t == InvalidType {
+ return msg, scratch, InvalidPrefixError(msg[0])
+ }
+ if t == ExtensionType {
+ et, err := peekExtension(msg)
+ if err != nil {
+ return nil, scratch, err
+ }
+ if et == TimeExtension {
+ t = TimeType
+ }
+ }
+ return unfuns[t](w, msg, scratch)
+}
+
+func rwArrayBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ sz, msg, err := ReadArrayHeaderBytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ err = w.WriteByte('[')
+ if err != nil {
+ return msg, scratch, err
+ }
+ for i := uint32(0); i < sz; i++ {
+ if i != 0 {
+ err = w.WriteByte(',')
+ if err != nil {
+ return msg, scratch, err
+ }
+ }
+ msg, scratch, err = writeNext(w, msg, scratch)
+ if err != nil {
+ return msg, scratch, err
+ }
+ }
+ err = w.WriteByte(']')
+ return msg, scratch, err
+}
+
+func rwMapBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ sz, msg, err := ReadMapHeaderBytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ err = w.WriteByte('{')
+ if err != nil {
+ return msg, scratch, err
+ }
+ for i := uint32(0); i < sz; i++ {
+ if i != 0 {
+ err = w.WriteByte(',')
+ if err != nil {
+ return msg, scratch, err
+ }
+ }
+ msg, scratch, err = rwMapKeyBytes(w, msg, scratch)
+ if err != nil {
+ return msg, scratch, err
+ }
+ err = w.WriteByte(':')
+ if err != nil {
+ return msg, scratch, err
+ }
+ msg, scratch, err = writeNext(w, msg, scratch)
+ if err != nil {
+ return msg, scratch, err
+ }
+ }
+ err = w.WriteByte('}')
+ return msg, scratch, err
+}
+
+func rwMapKeyBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ msg, scratch, err := rwStringBytes(w, msg, scratch)
+ if err != nil {
+ if tperr, ok := err.(TypeError); ok && tperr.Encoded == BinType {
+ return rwBytesBytes(w, msg, scratch)
+ }
+ }
+ return msg, scratch, err
+}
+
+func rwStringBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ str, msg, err := ReadStringZC(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ _, err = rwquoted(w, str)
+ return msg, scratch, err
+}
+
+func rwBytesBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ bts, msg, err := ReadBytesZC(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ l := base64.StdEncoding.EncodedLen(len(bts))
+ if cap(scratch) >= l {
+ scratch = scratch[0:l]
+ } else {
+ scratch = make([]byte, l)
+ }
+ base64.StdEncoding.Encode(scratch, bts)
+ err = w.WriteByte('"')
+ if err != nil {
+ return msg, scratch, err
+ }
+ _, err = w.Write(scratch)
+ if err != nil {
+ return msg, scratch, err
+ }
+ err = w.WriteByte('"')
+ return msg, scratch, err
+}
+
+func rwNullBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ msg, err := ReadNilBytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ _, err = w.Write(null)
+ return msg, scratch, err
+}
+
+func rwBoolBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ b, msg, err := ReadBoolBytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ if b {
+ _, err = w.WriteString("true")
+ return msg, scratch, err
+ }
+ _, err = w.WriteString("false")
+ return msg, scratch, err
+}
+
+func rwIntBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ i, msg, err := ReadInt64Bytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ scratch = strconv.AppendInt(scratch[0:0], i, 10)
+ _, err = w.Write(scratch)
+ return msg, scratch, err
+}
+
+func rwUintBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ u, msg, err := ReadUint64Bytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ scratch = strconv.AppendUint(scratch[0:0], u, 10)
+ _, err = w.Write(scratch)
+ return msg, scratch, err
+}
+
+func rwFloatBytes(w jsWriter, msg []byte, f64 bool, scratch []byte) ([]byte, []byte, error) {
+ var f float64
+ var err error
+ var sz int
+ if f64 {
+ sz = 64
+ f, msg, err = ReadFloat64Bytes(msg)
+ } else {
+ sz = 32
+ var v float32
+ v, msg, err = ReadFloat32Bytes(msg)
+ f = float64(v)
+ }
+ if err != nil {
+ return msg, scratch, err
+ }
+ scratch = strconv.AppendFloat(scratch, f, 'f', -1, sz)
+ _, err = w.Write(scratch)
+ return msg, scratch, err
+}
+
+func rwFloat32Bytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ var f float32
+ var err error
+ f, msg, err = ReadFloat32Bytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ scratch = strconv.AppendFloat(scratch[:0], float64(f), 'f', -1, 32)
+ _, err = w.Write(scratch)
+ return msg, scratch, err
+}
+
+func rwFloat64Bytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ var f float64
+ var err error
+ f, msg, err = ReadFloat64Bytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ scratch = strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)
+ _, err = w.Write(scratch)
+ return msg, scratch, err
+}
+
+func rwTimeBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ var t time.Time
+ var err error
+ t, msg, err = ReadTimeBytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ bts, err := t.MarshalJSON()
+ if err != nil {
+ return msg, scratch, err
+ }
+ _, err = w.Write(bts)
+ return msg, scratch, err
+}
+
+func rwExtensionBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
+ var err error
+ var et int8
+ et, err = peekExtension(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+
+ // if it's time.Time
+ if et == TimeExtension {
+ var tm time.Time
+ tm, msg, err = ReadTimeBytes(msg)
+ if err != nil {
+ return msg, scratch, err
+ }
+ bts, err := tm.MarshalJSON()
+ if err != nil {
+ return msg, scratch, err
+ }
+ _, err = w.Write(bts)
+ return msg, scratch, err
+ }
+
+ // if the extension is registered,
+ // use its canonical JSON form
+ if f, ok := extensionReg[et]; ok {
+ e := f()
+ msg, err = ReadExtensionBytes(msg, e)
+ if err != nil {
+ return msg, scratch, err
+ }
+ bts, err := json.Marshal(e)
+ if err != nil {
+ return msg, scratch, err
+ }
+ _, err = w.Write(bts)
+ return msg, scratch, err
+ }
+
+ // otherwise, write `{"type": , "data": ""}`
+ r := RawExtension{}
+ r.Type = et
+ msg, err = ReadExtensionBytes(msg, &r)
+ if err != nil {
+ return msg, scratch, err
+ }
+ scratch, err = writeExt(w, r, scratch)
+ return msg, scratch, err
+}
+
+func writeExt(w jsWriter, r RawExtension, scratch []byte) ([]byte, error) {
+ _, err := w.WriteString(`{"type":`)
+ if err != nil {
+ return scratch, err
+ }
+ scratch = strconv.AppendInt(scratch[0:0], int64(r.Type), 10)
+ _, err = w.Write(scratch)
+ if err != nil {
+ return scratch, err
+ }
+ _, err = w.WriteString(`,"data":"`)
+ if err != nil {
+ return scratch, err
+ }
+ l := base64.StdEncoding.EncodedLen(len(r.Data))
+ if cap(scratch) >= l {
+ scratch = scratch[0:l]
+ } else {
+ scratch = make([]byte, l)
+ }
+ base64.StdEncoding.Encode(scratch, r.Data)
+ _, err = w.Write(scratch)
+ if err != nil {
+ return scratch, err
+ }
+ _, err = w.WriteString(`"}`)
+ return scratch, err
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/number.go b/vendor/src/github.com/tinylib/msgp/msgp/number.go
new file mode 100644
index 0000000000..69afc8ae0f
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/number.go
@@ -0,0 +1,140 @@
+package msgp
+
+import (
+ "strconv"
+)
+
+// The portable parts of the Number implementation
+
+// DecodeMsg implements msgp.Decodable
+func (n *Number) DecodeMsg(r *Reader) error {
+ typ, err := r.NextType()
+ if err != nil {
+ return err
+ }
+ switch typ {
+ case Float32Type:
+ f, err := r.ReadFloat32()
+ if err != nil {
+ return err
+ }
+ n.AsFloat32(f)
+ return nil
+ case Float64Type:
+ f, err := r.ReadFloat64()
+ if err != nil {
+ return err
+ }
+ n.AsFloat64(f)
+ return nil
+ case IntType:
+ i, err := r.ReadInt64()
+ if err != nil {
+ return err
+ }
+ n.AsInt(i)
+ return nil
+ case UintType:
+ u, err := r.ReadUint64()
+ if err != nil {
+ return err
+ }
+ n.AsUint(u)
+ return nil
+ default:
+ return TypeError{Encoded: typ, Method: IntType}
+ }
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler
+func (n *Number) UnmarshalMsg(b []byte) ([]byte, error) {
+ typ := NextType(b)
+ switch typ {
+ case IntType:
+ i, o, err := ReadInt64Bytes(b)
+ if err != nil {
+ return b, err
+ }
+ n.AsInt(i)
+ return o, nil
+ case UintType:
+ u, o, err := ReadUint64Bytes(b)
+ if err != nil {
+ return b, err
+ }
+ n.AsUint(u)
+ return o, nil
+ case Float64Type:
+ f, o, err := ReadFloat64Bytes(b)
+ if err != nil {
+ return b, err
+ }
+ n.AsFloat64(f)
+ return o, nil
+ case Float32Type:
+ f, o, err := ReadFloat32Bytes(b)
+ if err != nil {
+ return b, err
+ }
+ n.AsFloat32(f)
+ return o, nil
+ default:
+ return b, TypeError{Method: IntType, Encoded: typ}
+ }
+}
+
+// Msgsize implements msgp.Sizer
+func (n *Number) Msgsize() int {
+ switch n.typ {
+ case Float32Type:
+ return Float32Size
+ case Float64Type:
+ return Float64Size
+ case IntType:
+ return Int64Size
+ case UintType:
+ return Uint64Size
+ default:
+ return 1 // fixint(0)
+ }
+}
+
+// MarshalJSON implements json.Marshaler
+func (n *Number) MarshalJSON() ([]byte, error) {
+ t := n.Type()
+ if t == InvalidType {
+ return []byte{'0'}, nil
+ }
+ out := make([]byte, 0, 32)
+ switch t {
+ case Float32Type, Float64Type:
+ f, _ := n.Float()
+ return strconv.AppendFloat(out, f, 'f', -1, 64), nil
+ case IntType:
+ i, _ := n.Int()
+ return strconv.AppendInt(out, i, 10), nil
+ case UintType:
+ u, _ := n.Uint()
+ return strconv.AppendUint(out, u, 10), nil
+ default:
+ panic("(*Number).typ is invalid")
+ }
+}
+
+func (n *Number) String() string {
+ switch n.typ {
+ case InvalidType:
+ return "0"
+ case Float32Type, Float64Type:
+ f, _ := n.Float()
+ return strconv.FormatFloat(f, 'f', -1, 64)
+ case IntType:
+ i, _ := n.Int()
+ return strconv.FormatInt(i, 10)
+ case UintType:
+ u, _ := n.Uint()
+ return strconv.FormatUint(u, 10)
+ default:
+ panic("(*Number).typ is invalid")
+ }
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/number_appengine.go b/vendor/src/github.com/tinylib/msgp/msgp/number_appengine.go
new file mode 100644
index 0000000000..c94140df35
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/number_appengine.go
@@ -0,0 +1,101 @@
+// +build appengine
+
+package msgp
+
+// let's just assume appengine
+// uses 64-bit hardware...
+const smallint = false
+
+func UnsafeString(b []byte) string {
+ return string(b)
+}
+
+func UnsafeBytes(s string) []byte {
+ return []byte(s)
+}
+
+type Number struct {
+ ibits uint64 // zero or bits
+ fbits float64 // zero or bits
+ typ Type // zero or type
+}
+
+func (n *Number) AsFloat64(f float64) {
+ n.typ = Float64Type
+ n.fbits = f
+ n.ibits = 0
+}
+
+func (n *Number) AsFloat32(f float32) {
+ n.typ = Float32Type
+ n.fbits = float64(f)
+ n.ibits = 0
+}
+
+func (n *Number) AsInt(i int64) {
+ n.fbits = 0
+ if i == 0 {
+ n.typ = InvalidType
+ n.ibits = 0
+ return
+ }
+ n.ibits = uint64(i)
+ n.typ = IntType
+}
+
+func (n *Number) AsUint(u uint64) {
+ n.ibits = u
+ n.fbits = 0
+ n.typ = UintType
+}
+
+func (n *Number) Float() (float64, bool) {
+ return n.fbits, n.typ == Float64Type || n.typ == Float32Type
+}
+
+func (n *Number) Int() (int64, bool) {
+ return int64(n.ibits), n.typ == IntType
+}
+
+func (n *Number) Uint() (uint64, bool) {
+ return n.ibits, n.typ == UintType
+}
+
+func (n *Number) Type() Type {
+ if n.typ == InvalidType {
+ return IntType
+ }
+ return n.typ
+}
+
+func (n *Number) MarshalMsg(o []byte) ([]byte, error) {
+ switch n.typ {
+ case InvalidType:
+ return AppendInt64(o, 0), nil
+ case IntType:
+ return AppendInt64(o, int64(n.ibits)), nil
+ case UintType:
+ return AppendUint64(o, n.ibits), nil
+ case Float32Type:
+ return AppendFloat32(o, float32(n.fbits)), nil
+ case Float64Type:
+ return AppendFloat64(o, n.fbits), nil
+ }
+ panic("unreachable code!")
+}
+
+func (n *Number) EncodeMsg(w *Writer) error {
+ switch n.typ {
+ case InvalidType:
+ return w.WriteInt64(0)
+ case IntType:
+ return w.WriteInt64(int64(n.ibits))
+ case UintType:
+ return w.WriteUint64(n.ibits)
+ case Float32Type:
+ return w.WriteFloat32(float32(n.fbits))
+ case Float64Type:
+ return w.WriteFloat64(n.fbits)
+ }
+ panic("unreachable code!")
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/number_unsafe.go b/vendor/src/github.com/tinylib/msgp/msgp/number_unsafe.go
new file mode 100644
index 0000000000..8ea04624cc
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/number_unsafe.go
@@ -0,0 +1,159 @@
+// +build !appengine
+
+package msgp
+
+import (
+ "reflect"
+ "unsafe"
+)
+
+const (
+ // spec says int and uint are always
+ // the same size, but that int/uint
+ // size may not be machine word size
+ smallint = unsafe.Sizeof(int(0)) == 4
+)
+
+// UnsafeString returns the byte slice as a volatile string
+// THIS SHOULD ONLY BE USED BY THE CODE GENERATOR.
+// THIS IS EVIL CODE.
+// YOU HAVE BEEN WARNED.
+func UnsafeString(b []byte) string {
+ return *(*string)(unsafe.Pointer(&reflect.StringHeader{Data: uintptr(unsafe.Pointer(&b[0])), Len: len(b)}))
+}
+
+// UnsafeBytes returns the string as a byte slice
+// THIS SHOULD ONLY BE USED BY THE CODE GENERATOR.
+// THIS IS EVIL CODE.
+// YOU HAVE BEEN WARNED.
+func UnsafeBytes(s string) []byte {
+ return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
+ Len: len(s),
+ Cap: len(s),
+ Data: (*(*reflect.StringHeader)(unsafe.Pointer(&s))).Data,
+ }))
+}
+
+// Number can be
+// an int64, uint64, float32,
+// or float64 internally.
+// It can decode itself
+// from any of the native
+// messagepack number types.
+// The zero-value of Number
+// is Int(0). Using the equality
+// operator with Number compares
+// both the type and the value
+// of the number.
+type Number struct {
+ // internally, this
+ // is just a tagged union.
+ // the raw bits of the number
+ // are stored the same way regardless.
+ bits uint64
+ typ Type
+}
+
+// AsFloat64 sets the number to
+// a float64.
+func (n *Number) AsFloat64(f float64) {
+ n.typ = Float64Type
+ n.bits = *(*uint64)(unsafe.Pointer(&f))
+}
+
+// AsInt sets the number to an int64.
+func (n *Number) AsInt(i int64) {
+
+ // we always store int(0)
+ // as {0, InvalidType} in
+ // order to preserve
+ // the behavior of the == operator
+ if i == 0 {
+ n.typ = InvalidType
+ n.bits = 0
+ return
+ }
+
+ n.typ = IntType
+ n.bits = uint64(i)
+}
+
+// AsUint sets the number to a uint64.
+func (n *Number) AsUint(u uint64) {
+ n.typ = UintType
+ n.bits = u
+}
+
+// AsFloat32 sets the number to a float32.
+func (n *Number) AsFloat32(f float32) {
+ n.typ = Float32Type
+ g := float64(f)
+ n.bits = *(*uint64)(unsafe.Pointer(&g))
+}
+
+// Type will return one of:
+// Float64Type, Float32Type, UintType, or IntType.
+func (n *Number) Type() Type {
+ if n.typ == InvalidType {
+ return IntType
+ }
+ return n.typ
+}
+
+// Float casts the number of the float,
+// and returns whether or not that was
+// the underlying type. (This is legal
+// for both float32 and float64 types.)
+func (n *Number) Float() (float64, bool) {
+ return *(*float64)(unsafe.Pointer(&n.bits)), n.typ == Float64Type || n.typ == Float32Type
+}
+
+// Int casts the number as an int64, and
+// returns whether or not that was the
+// underlying type.
+func (n *Number) Int() (int64, bool) {
+ return int64(n.bits), n.typ == IntType || n.typ == InvalidType
+}
+
+// Uint casts the number as a uint64, and returns
+// whether or not that was the underlying type.
+func (n *Number) Uint() (uint64, bool) {
+ return n.bits, n.typ == UintType
+}
+
+// EncodeMsg implements msgp.Encodable
+func (n *Number) EncodeMsg(w *Writer) error {
+ switch n.typ {
+ case InvalidType:
+ return w.WriteInt(0)
+ case IntType:
+ return w.WriteInt64(int64(n.bits))
+ case UintType:
+ return w.WriteUint64(n.bits)
+ case Float64Type:
+ return w.WriteFloat64(*(*float64)(unsafe.Pointer(&n.bits)))
+ case Float32Type:
+ return w.WriteFloat32(float32(*(*float64)(unsafe.Pointer(&n.bits))))
+ default:
+ // this should never ever happen
+ panic("(*Number).typ is invalid")
+ }
+}
+
+// MarshalMsg implements msgp.Marshaler
+func (n *Number) MarshalMsg(b []byte) ([]byte, error) {
+ switch n.typ {
+ case InvalidType:
+ return AppendInt(b, 0), nil
+ case IntType:
+ return AppendInt64(b, int64(n.bits)), nil
+ case UintType:
+ return AppendUint64(b, n.bits), nil
+ case Float64Type:
+ return AppendFloat64(b, *(*float64)(unsafe.Pointer(&n.bits))), nil
+ case Float32Type:
+ return AppendFloat32(b, float32(*(*float64)(unsafe.Pointer(&n.bits)))), nil
+ default:
+ panic("(*Number).typ is invalid")
+ }
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/read.go b/vendor/src/github.com/tinylib/msgp/msgp/read.go
new file mode 100644
index 0000000000..c34482e0f2
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/read.go
@@ -0,0 +1,1118 @@
+package msgp
+
+import (
+ "github.com/philhofer/fwd"
+ "io"
+ "math"
+ "sync"
+ "time"
+)
+
+// where we keep old *Readers
+var readerPool = sync.Pool{New: func() interface{} { return &Reader{} }}
+
+// Type is a MessagePack wire type,
+// including this package's built-in
+// extension types.
+type Type byte
+
+// MessagePack Types
+//
+// The zero value of Type
+// is InvalidType.
+const (
+ InvalidType Type = iota
+
+ // MessagePack built-in types
+
+ StrType
+ BinType
+ MapType
+ ArrayType
+ Float64Type
+ Float32Type
+ BoolType
+ IntType
+ UintType
+ NilType
+ ExtensionType
+
+ // pseudo-types provided
+ // by extensions
+
+ Complex64Type
+ Complex128Type
+ TimeType
+
+ _maxtype
+)
+
+// String implements fmt.Stringer
+func (t Type) String() string {
+ switch t {
+ case StrType:
+ return "str"
+ case BinType:
+ return "bin"
+ case MapType:
+ return "map"
+ case ArrayType:
+ return "array"
+ case Float64Type:
+ return "float64"
+ case Float32Type:
+ return "float32"
+ case BoolType:
+ return "bool"
+ case UintType:
+ return "uint"
+ case IntType:
+ return "int"
+ case ExtensionType:
+ return "ext"
+ case NilType:
+ return "nil"
+ default:
+ return ""
+ }
+}
+
+func freeR(m *Reader) {
+ readerPool.Put(m)
+}
+
+// Unmarshaler is the interface fulfilled
+// by objects that know how to unmarshal
+// themselves from MessagePack.
+// UnmarshalMsg unmarshals the object
+// from binary, returing any leftover
+// bytes and any errors encountered.
+type Unmarshaler interface {
+ UnmarshalMsg([]byte) ([]byte, error)
+}
+
+// Decodable is the interface fulfilled
+// by objects that know how to read
+// themselves from a *Reader.
+type Decodable interface {
+ DecodeMsg(*Reader) error
+}
+
+// Decode decodes 'd' from 'r'.
+func Decode(r io.Reader, d Decodable) error {
+ rd := NewReader(r)
+ err := d.DecodeMsg(rd)
+ freeR(rd)
+ return err
+}
+
+// NewReader returns a *Reader that
+// reads from the provided reader. The
+// reader will be buffered.
+func NewReader(r io.Reader) *Reader {
+ p := readerPool.Get().(*Reader)
+ if p.r == nil {
+ p.r = fwd.NewReader(r)
+ } else {
+ p.r.Reset(r)
+ }
+ return p
+}
+
+// NewReaderSize returns a *Reader with a buffer of the given size.
+// (This is vastly preferable to passing the decoder a reader that is already buffered.)
+func NewReaderSize(r io.Reader, sz int) *Reader {
+ return &Reader{r: fwd.NewReaderSize(r, sz)}
+}
+
+// Reader wraps an io.Reader and provides
+// methods to read MessagePack-encoded values
+// from it. Readers are buffered.
+type Reader struct {
+ r *fwd.Reader
+ scratch []byte
+}
+
+// Read implements `io.Reader`
+func (m *Reader) Read(p []byte) (int, error) {
+ return m.r.Read(p)
+}
+
+// ReadFull implements `io.ReadFull`
+func (m *Reader) ReadFull(p []byte) (int, error) {
+ return m.r.ReadFull(p)
+}
+
+// Reset resets the underlying reader.
+func (m *Reader) Reset(r io.Reader) { m.r.Reset(r) }
+
+// Buffered returns the number of bytes currently in the read buffer.
+func (m *Reader) Buffered() int { return m.r.Buffered() }
+
+// BufferSize returns the capacity of the read buffer.
+func (m *Reader) BufferSize() int { return m.r.BufferSize() }
+
+// NextType returns the next object type to be decoded.
+func (m *Reader) NextType() (Type, error) {
+ p, err := m.r.Peek(1)
+ if err != nil {
+ return InvalidType, err
+ }
+ t := getType(p[0])
+ if t == InvalidType {
+ return t, InvalidPrefixError(p[0])
+ }
+ if t == ExtensionType {
+ v, err := m.peekExtensionType()
+ if err != nil {
+ return InvalidType, err
+ }
+ switch v {
+ case Complex64Extension:
+ return Complex64Type, nil
+ case Complex128Extension:
+ return Complex128Type, nil
+ case TimeExtension:
+ return TimeType, nil
+ }
+ }
+ return t, nil
+}
+
+// IsNil returns whether or not
+// the next byte is a null messagepack byte
+func (m *Reader) IsNil() bool {
+ p, err := m.r.Peek(1)
+ return err == nil && p[0] == mnil
+}
+
+// returns (obj size, obj elements, error)
+// only maps and arrays have non-zero obj elements
+//
+// use uintptr b/c it's guaranteed to be large enough
+// to hold whatever we can fit in memory.
+func getNextSize(r *fwd.Reader) (uintptr, uintptr, error) {
+ b, err := r.Peek(1)
+ if err != nil {
+ return 0, 0, err
+ }
+ lead := b[0]
+ spec := &sizes[lead]
+ size, mode := spec.size, spec.extra
+ if size == 0 {
+ return 0, 0, InvalidPrefixError(lead)
+ }
+ if mode >= 0 {
+ return uintptr(size), uintptr(mode), nil
+ }
+ b, err = r.Peek(int(size))
+ if err != nil {
+ return 0, 0, err
+ }
+ switch mode {
+ case extra8:
+ return uintptr(size) + uintptr(b[1]), 0, nil
+ case extra16:
+ return uintptr(size) + uintptr(big.Uint16(b[1:])), 0, nil
+ case extra32:
+ return uintptr(size) + uintptr(big.Uint32(b[1:])), 0, nil
+ case map16v:
+ return uintptr(size), 2 * uintptr(big.Uint16(b[1:])), nil
+ case map32v:
+ return uintptr(size), 2 * uintptr(big.Uint32(b[1:])), nil
+ case array16v:
+ return uintptr(size), uintptr(big.Uint16(b[1:])), nil
+ case array32v:
+ return uintptr(size), uintptr(big.Uint32(b[1:])), nil
+ default:
+ return 0, 0, fatal
+ }
+}
+
+// Skip skips over the next object, regardless of
+// its type. If it is an array or map, the whole array
+// or map will be skipped.
+func (m *Reader) Skip() error {
+ var (
+ v uintptr // bytes
+ o uintptr // objects
+ err error
+ p []byte
+ )
+
+ // we can use the faster
+ // method if we have enough
+ // buffered data
+ if m.r.Buffered() >= 5 {
+ p, err = m.r.Peek(5)
+ if err != nil {
+ return err
+ }
+ v, o, err = getSize(p)
+ if err != nil {
+ return err
+ }
+ } else {
+ v, o, err = getNextSize(m.r)
+ if err != nil {
+ return err
+ }
+ }
+
+ // 'v' is always non-zero
+ // if err == nil
+ _, err = m.r.Skip(int(v))
+ if err != nil {
+ return err
+ }
+
+ // for maps and slices, skip elements
+ for x := uintptr(0); x < o; x++ {
+ err = m.Skip()
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// ReadMapHeader reads the next object
+// as a map header and returns the size
+// of the map and the number of bytes written.
+// It will return a TypeError{} if the next
+// object is not a map.
+func (m *Reader) ReadMapHeader() (sz uint32, err error) {
+ var p []byte
+ var lead byte
+ p, err = m.r.Peek(1)
+ if err != nil {
+ return
+ }
+ lead = p[0]
+ if isfixmap(lead) {
+ sz = uint32(rfixmap(lead))
+ _, err = m.r.Skip(1)
+ return
+ }
+ switch lead {
+ case mmap16:
+ p, err = m.r.Next(3)
+ if err != nil {
+ return
+ }
+ sz = uint32(big.Uint16(p[1:]))
+ return
+ case mmap32:
+ p, err = m.r.Next(5)
+ if err != nil {
+ return
+ }
+ sz = big.Uint32(p[1:])
+ return
+ default:
+ err = badPrefix(MapType, lead)
+ return
+ }
+}
+
+// ReadMapKey reads either a 'str' or 'bin' field from
+// the reader and returns the value as a []byte. It uses
+// scratch for storage if it is large enough.
+func (m *Reader) ReadMapKey(scratch []byte) ([]byte, error) {
+ out, err := m.ReadStringAsBytes(scratch)
+ if err != nil {
+ if tperr, ok := err.(TypeError); ok && tperr.Encoded == BinType {
+ return m.ReadBytes(scratch)
+ }
+ return nil, err
+ }
+ return out, nil
+}
+
+// MapKeyPtr returns a []byte pointing to the contents
+// of a valid map key. The key cannot be empty, and it
+// must be shorter than the total buffer size of the
+// *Reader. Additionally, the returned slice is only
+// valid until the next *Reader method call. Users
+// should exercise extreme care when using this
+// method; writing into the returned slice may
+// corrupt future reads.
+func (m *Reader) ReadMapKeyPtr() ([]byte, error) {
+ p, err := m.r.Peek(1)
+ if err != nil {
+ return nil, err
+ }
+ lead := p[0]
+ var read int
+ if isfixstr(lead) {
+ read = int(rfixstr(lead))
+ m.r.Skip(1)
+ goto fill
+ }
+ switch lead {
+ case mstr8, mbin8:
+ p, err = m.r.Next(2)
+ if err != nil {
+ return nil, err
+ }
+ read = int(p[1])
+ case mstr16, mbin16:
+ p, err = m.r.Next(3)
+ if err != nil {
+ return nil, err
+ }
+ read = int(big.Uint16(p[1:]))
+ case mstr32, mbin32:
+ p, err = m.r.Next(5)
+ if err != nil {
+ return nil, err
+ }
+ read = int(big.Uint32(p[1:]))
+ default:
+ return nil, badPrefix(StrType, lead)
+ }
+fill:
+ if read == 0 {
+ return nil, ErrShortBytes
+ }
+ return m.r.Next(read)
+}
+
+// ReadArrayHeader reads the next object as an
+// array header and returns the size of the array
+// and the number of bytes read.
+func (m *Reader) ReadArrayHeader() (sz uint32, err error) {
+ var lead byte
+ var p []byte
+ p, err = m.r.Peek(1)
+ if err != nil {
+ return
+ }
+ lead = p[0]
+ if isfixarray(lead) {
+ sz = uint32(rfixarray(lead))
+ _, err = m.r.Skip(1)
+ return
+ }
+ switch lead {
+ case marray16:
+ p, err = m.r.Next(3)
+ if err != nil {
+ return
+ }
+ sz = uint32(big.Uint16(p[1:]))
+ return
+
+ case marray32:
+ p, err = m.r.Next(5)
+ if err != nil {
+ return
+ }
+ sz = big.Uint32(p[1:])
+ return
+
+ default:
+ err = badPrefix(ArrayType, lead)
+ return
+ }
+}
+
+// ReadNil reads a 'nil' MessagePack byte from the reader
+func (m *Reader) ReadNil() error {
+ p, err := m.r.Peek(1)
+ if err != nil {
+ return err
+ }
+ if p[0] != mnil {
+ return badPrefix(NilType, p[0])
+ }
+ _, err = m.r.Skip(1)
+ return err
+}
+
+// ReadFloat64 reads a float64 from the reader.
+// (If the value on the wire is encoded as a float32,
+// it will be up-cast to a float64.)
+func (m *Reader) ReadFloat64() (f float64, err error) {
+ var p []byte
+ p, err = m.r.Peek(9)
+ if err != nil {
+ // we'll allow a coversion from float32 to float64,
+ // since we don't lose any precision
+ if err == io.EOF && len(p) > 0 && p[0] == mfloat32 {
+ ef, err := m.ReadFloat32()
+ return float64(ef), err
+ }
+ return
+ }
+ if p[0] != mfloat64 {
+ // see above
+ if p[0] == mfloat32 {
+ ef, err := m.ReadFloat32()
+ return float64(ef), err
+ }
+ err = badPrefix(Float64Type, p[0])
+ return
+ }
+ f = math.Float64frombits(getMuint64(p))
+ _, err = m.r.Skip(9)
+ return
+}
+
+// ReadFloat32 reads a float32 from the reader
+func (m *Reader) ReadFloat32() (f float32, err error) {
+ var p []byte
+ p, err = m.r.Peek(5)
+ if err != nil {
+ return
+ }
+ if p[0] != mfloat32 {
+ err = badPrefix(Float32Type, p[0])
+ return
+ }
+ f = math.Float32frombits(getMuint32(p))
+ _, err = m.r.Skip(5)
+ return
+}
+
+// ReadBool reads a bool from the reader
+func (m *Reader) ReadBool() (b bool, err error) {
+ var p []byte
+ p, err = m.r.Peek(1)
+ if err != nil {
+ return
+ }
+ switch p[0] {
+ case mtrue:
+ b = true
+ case mfalse:
+ default:
+ err = badPrefix(BoolType, p[0])
+ return
+ }
+ _, err = m.r.Skip(1)
+ return
+}
+
+// ReadInt64 reads an int64 from the reader
+func (m *Reader) ReadInt64() (i int64, err error) {
+ var p []byte
+ var lead byte
+ p, err = m.r.Peek(1)
+ if err != nil {
+ return
+ }
+ lead = p[0]
+
+ if isfixint(lead) {
+ i = int64(rfixint(lead))
+ _, err = m.r.Skip(1)
+ return
+ } else if isnfixint(lead) {
+ i = int64(rnfixint(lead))
+ _, err = m.r.Skip(1)
+ return
+ }
+
+ switch lead {
+ case mint8:
+ p, err = m.r.Next(2)
+ if err != nil {
+ return
+ }
+ i = int64(getMint8(p))
+ return
+
+ case mint16:
+ p, err = m.r.Next(3)
+ if err != nil {
+ return
+ }
+ i = int64(getMint16(p))
+ return
+
+ case mint32:
+ p, err = m.r.Next(5)
+ if err != nil {
+ return
+ }
+ i = int64(getMint32(p))
+ return
+
+ case mint64:
+ p, err = m.r.Next(9)
+ if err != nil {
+ return
+ }
+ i = getMint64(p)
+ return
+
+ default:
+ err = badPrefix(IntType, lead)
+ return
+ }
+}
+
+// ReadInt32 reads an int32 from the reader
+func (m *Reader) ReadInt32() (i int32, err error) {
+ var in int64
+ in, err = m.ReadInt64()
+ if in > math.MaxInt32 || in < math.MinInt32 {
+ err = IntOverflow{Value: in, FailedBitsize: 32}
+ return
+ }
+ i = int32(in)
+ return
+}
+
+// ReadInt16 reads an int16 from the reader
+func (m *Reader) ReadInt16() (i int16, err error) {
+ var in int64
+ in, err = m.ReadInt64()
+ if in > math.MaxInt16 || in < math.MinInt16 {
+ err = IntOverflow{Value: in, FailedBitsize: 16}
+ return
+ }
+ i = int16(in)
+ return
+}
+
+// ReadInt8 reads an int8 from the reader
+func (m *Reader) ReadInt8() (i int8, err error) {
+ var in int64
+ in, err = m.ReadInt64()
+ if in > math.MaxInt8 || in < math.MinInt8 {
+ err = IntOverflow{Value: in, FailedBitsize: 8}
+ return
+ }
+ i = int8(in)
+ return
+}
+
+// ReadInt reads an int from the reader
+func (m *Reader) ReadInt() (i int, err error) {
+ if smallint {
+ var in int32
+ in, err = m.ReadInt32()
+ i = int(in)
+ return
+ }
+ var in int64
+ in, err = m.ReadInt64()
+ i = int(in)
+ return
+}
+
+// ReadUint64 reads a uint64 from the reader
+func (m *Reader) ReadUint64() (u uint64, err error) {
+ var p []byte
+ var lead byte
+ p, err = m.r.Peek(1)
+ if err != nil {
+ return
+ }
+ lead = p[0]
+ if isfixint(lead) {
+ u = uint64(rfixint(lead))
+ _, err = m.r.Skip(1)
+ return
+ }
+ switch lead {
+ case muint8:
+ p, err = m.r.Next(2)
+ if err != nil {
+ return
+ }
+ u = uint64(getMuint8(p))
+ return
+
+ case muint16:
+ p, err = m.r.Next(3)
+ if err != nil {
+ return
+ }
+ u = uint64(getMuint16(p))
+ return
+
+ case muint32:
+ p, err = m.r.Next(5)
+ if err != nil {
+ return
+ }
+ u = uint64(getMuint32(p))
+ return
+
+ case muint64:
+ p, err = m.r.Next(9)
+ if err != nil {
+ return
+ }
+ u = getMuint64(p)
+ return
+
+ default:
+ err = badPrefix(UintType, lead)
+ return
+
+ }
+}
+
+// ReadUint32 reads a uint32 from the reader
+func (m *Reader) ReadUint32() (u uint32, err error) {
+ var in uint64
+ in, err = m.ReadUint64()
+ if in > math.MaxUint32 {
+ err = UintOverflow{Value: in, FailedBitsize: 32}
+ return
+ }
+ u = uint32(in)
+ return
+}
+
+// ReadUint16 reads a uint16 from the reader
+func (m *Reader) ReadUint16() (u uint16, err error) {
+ var in uint64
+ in, err = m.ReadUint64()
+ if in > math.MaxUint16 {
+ err = UintOverflow{Value: in, FailedBitsize: 16}
+ return
+ }
+ u = uint16(in)
+ return
+}
+
+// ReadUint8 reads a uint8 from the reader
+func (m *Reader) ReadUint8() (u uint8, err error) {
+ var in uint64
+ in, err = m.ReadUint64()
+ if in > math.MaxUint8 {
+ err = UintOverflow{Value: in, FailedBitsize: 8}
+ return
+ }
+ u = uint8(in)
+ return
+}
+
+// ReadUint reads a uint from the reader
+func (m *Reader) ReadUint() (u uint, err error) {
+ if smallint {
+ var un uint32
+ un, err = m.ReadUint32()
+ u = uint(un)
+ return
+ }
+ var un uint64
+ un, err = m.ReadUint64()
+ u = uint(un)
+ return
+}
+
+func (m *Reader) ReadByte() (b byte, err error) {
+ var in uint64
+ in, err = m.ReadUint64()
+ if in > math.MaxUint8 {
+ err = UintOverflow{Value: in, FailedBitsize: 8}
+ return
+ }
+ b = byte(in)
+ return
+}
+
+// ReadBytes reads a MessagePack 'bin' object
+// from the reader and returns its value. It may
+// use 'scratch' for storage if it is non-nil.
+func (m *Reader) ReadBytes(scratch []byte) (b []byte, err error) {
+ var p []byte
+ var lead byte
+ p, err = m.r.Peek(2)
+ if err != nil {
+ return
+ }
+ lead = p[0]
+ var read int64
+ switch lead {
+ case mbin8:
+ read = int64(p[1])
+ m.r.Skip(2)
+ case mbin16:
+ p, err = m.r.Next(3)
+ if err != nil {
+ return
+ }
+ read = int64(big.Uint16(p[1:]))
+ case mbin32:
+ p, err = m.r.Next(5)
+ if err != nil {
+ return
+ }
+ read = int64(big.Uint32(p[1:]))
+ default:
+ err = badPrefix(BinType, lead)
+ return
+ }
+ if int64(cap(scratch)) < read {
+ b = make([]byte, read)
+ } else {
+ b = scratch[0:read]
+ }
+ _, err = m.r.ReadFull(b)
+ return
+}
+
+// ReadExactBytes reads a MessagePack 'bin'-encoded
+// object off of the wire into the provided slice. An
+// ArrayError will be returned if the object is not
+// exactly the length of the input slice.
+func (m *Reader) ReadExactBytes(into []byte) error {
+ p, err := m.r.Peek(2)
+ if err != nil {
+ return err
+ }
+ lead := p[0]
+ var read int64 // bytes to read
+ var skip int // prefix size to skip
+ switch lead {
+ case mbin8:
+ read = int64(p[1])
+ skip = 2
+ case mbin16:
+ p, err = m.r.Peek(3)
+ if err != nil {
+ return err
+ }
+ read = int64(big.Uint16(p[1:]))
+ skip = 3
+ case mbin32:
+ p, err = m.r.Peek(5)
+ if err != nil {
+ return err
+ }
+ read = int64(big.Uint32(p[1:]))
+ skip = 5
+ default:
+ return badPrefix(BinType, lead)
+ }
+ if read != int64(len(into)) {
+ return ArrayError{Wanted: uint32(len(into)), Got: uint32(read)}
+ }
+ m.r.Skip(skip)
+ _, err = m.r.ReadFull(into)
+ return err
+}
+
+// ReadStringAsBytes reads a MessagePack 'str' (utf-8) string
+// and returns its value as bytes. It may use 'scratch' for storage
+// if it is non-nil.
+func (m *Reader) ReadStringAsBytes(scratch []byte) (b []byte, err error) {
+ var p []byte
+ var lead byte
+ p, err = m.r.Peek(1)
+ if err != nil {
+ return
+ }
+ lead = p[0]
+ var read int64
+
+ if isfixstr(lead) {
+ read = int64(rfixstr(lead))
+ m.r.Skip(1)
+ goto fill
+ }
+
+ switch lead {
+ case mstr8:
+ p, err = m.r.Next(2)
+ if err != nil {
+ return
+ }
+ read = int64(uint8(p[1]))
+ case mstr16:
+ p, err = m.r.Next(3)
+ if err != nil {
+ return
+ }
+ read = int64(big.Uint16(p[1:]))
+ case mstr32:
+ p, err = m.r.Next(5)
+ if err != nil {
+ return
+ }
+ read = int64(big.Uint32(p[1:]))
+ default:
+ err = badPrefix(StrType, lead)
+ return
+ }
+fill:
+ if int64(cap(scratch)) < read {
+ b = make([]byte, read)
+ } else {
+ b = scratch[0:read]
+ }
+ _, err = m.r.ReadFull(b)
+ return
+}
+
+// ReadString reads a utf-8 string from the reader
+func (m *Reader) ReadString() (s string, err error) {
+ var p []byte
+ var lead byte
+ var read int64
+ p, err = m.r.Peek(1)
+ if err != nil {
+ return
+ }
+ lead = p[0]
+
+ if isfixstr(lead) {
+ read = int64(rfixstr(lead))
+ m.r.Skip(1)
+ goto fill
+ }
+
+ switch lead {
+ case mstr8:
+ p, err = m.r.Next(2)
+ if err != nil {
+ return
+ }
+ read = int64(uint8(p[1]))
+ case mstr16:
+ p, err = m.r.Next(3)
+ if err != nil {
+ return
+ }
+ read = int64(big.Uint16(p[1:]))
+ case mstr32:
+ p, err = m.r.Next(5)
+ if err != nil {
+ return
+ }
+ read = int64(big.Uint32(p[1:]))
+ default:
+ err = badPrefix(StrType, lead)
+ return
+ }
+fill:
+ if read == 0 {
+ s, err = "", nil
+ return
+ }
+ // reading into the memory
+ // that will become the string
+ // itself has vastly superior
+ // worst-case performance, because
+ // the reader buffer doesn't have
+ // to be large enough to hold the string.
+ // the idea here is to make it more
+ // difficult for someone malicious
+ // to cause the system to run out of
+ // memory by sending very large strings.
+ //
+ // NOTE: this works because the argument
+ // passed to (*fwd.Reader).ReadFull escapes
+ // to the heap; its argument may, in turn,
+ // be passed to the underlying reader, and
+ // thus escape analysis *must* conclude that
+ // 'out' escapes.
+ out := make([]byte, read)
+ _, err = m.r.ReadFull(out)
+ if err != nil {
+ return
+ }
+ s = UnsafeString(out)
+ return
+}
+
+// ReadComplex64 reads a complex64 from the reader
+func (m *Reader) ReadComplex64() (f complex64, err error) {
+ var p []byte
+ p, err = m.r.Peek(10)
+ if err != nil {
+ return
+ }
+ if p[0] != mfixext8 {
+ err = badPrefix(Complex64Type, p[0])
+ return
+ }
+ if int8(p[1]) != Complex64Extension {
+ err = errExt(int8(p[1]), Complex64Extension)
+ return
+ }
+ f = complex(math.Float32frombits(big.Uint32(p[2:])),
+ math.Float32frombits(big.Uint32(p[6:])))
+ _, err = m.r.Skip(10)
+ return
+}
+
+// ReadComplex128 reads a complex128 from the reader
+func (m *Reader) ReadComplex128() (f complex128, err error) {
+ var p []byte
+ p, err = m.r.Peek(18)
+ if err != nil {
+ return
+ }
+ if p[0] != mfixext16 {
+ err = badPrefix(Complex128Type, p[0])
+ return
+ }
+ if int8(p[1]) != Complex128Extension {
+ err = errExt(int8(p[1]), Complex128Extension)
+ return
+ }
+ f = complex(math.Float64frombits(big.Uint64(p[2:])),
+ math.Float64frombits(big.Uint64(p[10:])))
+ _, err = m.r.Skip(18)
+ return
+}
+
+// ReadMapStrIntf reads a MessagePack map into a map[string]interface{}.
+// (You must pass a non-nil map into the function.)
+func (m *Reader) ReadMapStrIntf(mp map[string]interface{}) (err error) {
+ var sz uint32
+ sz, err = m.ReadMapHeader()
+ if err != nil {
+ return
+ }
+ for key := range mp {
+ delete(mp, key)
+ }
+ for i := uint32(0); i < sz; i++ {
+ var key string
+ var val interface{}
+ key, err = m.ReadString()
+ if err != nil {
+ return
+ }
+ val, err = m.ReadIntf()
+ if err != nil {
+ return
+ }
+ mp[key] = val
+ }
+ return
+}
+
+// ReadTime reads a time.Time object from the reader.
+// The returned time's location will be set to time.Local.
+func (m *Reader) ReadTime() (t time.Time, err error) {
+ var p []byte
+ p, err = m.r.Peek(15)
+ if err != nil {
+ return
+ }
+ if p[0] != mext8 || p[1] != 12 {
+ err = badPrefix(TimeType, p[0])
+ return
+ }
+ if int8(p[2]) != TimeExtension {
+ err = errExt(int8(p[2]), TimeExtension)
+ return
+ }
+ sec, nsec := getUnix(p[3:])
+ t = time.Unix(sec, int64(nsec)).Local()
+ _, err = m.r.Skip(15)
+ return
+}
+
+// ReadIntf reads out the next object as a raw interface{}.
+// Arrays are decoded as []interface{}, and maps are decoded
+// as map[string]interface{}. Integers are decoded as int64
+// and unsigned integers are decoded as uint64.
+func (m *Reader) ReadIntf() (i interface{}, err error) {
+ var t Type
+ t, err = m.NextType()
+ if err != nil {
+ return
+ }
+ switch t {
+ case BoolType:
+ i, err = m.ReadBool()
+ return
+
+ case IntType:
+ i, err = m.ReadInt64()
+ return
+
+ case UintType:
+ i, err = m.ReadUint64()
+ return
+
+ case BinType:
+ i, err = m.ReadBytes(nil)
+ return
+
+ case StrType:
+ i, err = m.ReadString()
+ return
+
+ case Complex64Type:
+ i, err = m.ReadComplex64()
+ return
+
+ case Complex128Type:
+ i, err = m.ReadComplex128()
+ return
+
+ case TimeType:
+ i, err = m.ReadTime()
+ return
+
+ case ExtensionType:
+ var t int8
+ t, err = m.peekExtensionType()
+ if err != nil {
+ return
+ }
+ f, ok := extensionReg[t]
+ if ok {
+ e := f()
+ err = m.ReadExtension(e)
+ i = e
+ return
+ }
+ var e RawExtension
+ e.Type = t
+ err = m.ReadExtension(&e)
+ i = &e
+ return
+
+ case MapType:
+ mp := make(map[string]interface{})
+ err = m.ReadMapStrIntf(mp)
+ i = mp
+ return
+
+ case NilType:
+ err = m.ReadNil()
+ i = nil
+ return
+
+ case Float32Type:
+ i, err = m.ReadFloat32()
+ return
+
+ case Float64Type:
+ i, err = m.ReadFloat64()
+ return
+
+ case ArrayType:
+ var sz uint32
+ sz, err = m.ReadArrayHeader()
+
+ if err != nil {
+ return
+ }
+ out := make([]interface{}, int(sz))
+ for j := range out {
+ out[j], err = m.ReadIntf()
+ if err != nil {
+ return
+ }
+ }
+ i = out
+ return
+
+ default:
+ return nil, fatal // unreachable
+ }
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/read_bytes.go b/vendor/src/github.com/tinylib/msgp/msgp/read_bytes.go
new file mode 100644
index 0000000000..732fa68d7e
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/read_bytes.go
@@ -0,0 +1,1073 @@
+package msgp
+
+import (
+ "bytes"
+ "encoding/binary"
+ "math"
+ "time"
+)
+
+var big = binary.BigEndian
+
+// NextType returns the type of the next
+// object in the slice. If the length
+// of the input is zero, it returns
+// InvalidType.
+func NextType(b []byte) Type {
+ if len(b) == 0 {
+ return InvalidType
+ }
+ spec := sizes[b[0]]
+ t := spec.typ
+ if t == ExtensionType && len(b) > int(spec.size) {
+ var tp int8
+ if spec.extra == constsize {
+ tp = int8(b[1])
+ } else {
+ tp = int8(b[spec.size-1])
+ }
+ switch tp {
+ case TimeExtension:
+ return TimeType
+ case Complex128Extension:
+ return Complex128Type
+ case Complex64Extension:
+ return Complex64Type
+ default:
+ return ExtensionType
+ }
+ }
+ return t
+}
+
+// IsNil returns true if len(b)>0 and
+// the leading byte is a 'nil' MessagePack
+// byte; false otherwise
+func IsNil(b []byte) bool {
+ if len(b) != 0 && b[0] == mnil {
+ return true
+ }
+ return false
+}
+
+// Raw is raw MessagePack.
+// Raw allows you to read and write
+// data without interpreting its contents.
+type Raw []byte
+
+// MarshalMsg implements msgp.Marshaler.
+// It appends the raw contents of 'raw'
+// to the provided byte slice. If 'raw'
+// is 0 bytes, 'nil' will be appended instead.
+func (r Raw) MarshalMsg(b []byte) ([]byte, error) {
+ i := len(r)
+ if i == 0 {
+ return AppendNil(b), nil
+ }
+ o, l := ensure(b, i)
+ copy(o[l:], []byte(r))
+ return o, nil
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler.
+// It sets the contents of *Raw to be the next
+// object in the provided byte slice.
+func (r *Raw) UnmarshalMsg(b []byte) ([]byte, error) {
+ l := len(b)
+ out, err := Skip(b)
+ if err != nil {
+ return b, err
+ }
+ rlen := l - len(out)
+ if cap(*r) < rlen {
+ *r = make(Raw, rlen)
+ } else {
+ *r = (*r)[0:rlen]
+ }
+ copy(*r, b[:rlen])
+ return out, nil
+}
+
+// EncodeMsg implements msgp.Encodable.
+// It writes the raw bytes to the writer.
+// If r is empty, it writes 'nil' instead.
+func (r Raw) EncodeMsg(w *Writer) error {
+ if len(r) == 0 {
+ return w.WriteNil()
+ }
+ _, err := w.Write([]byte(r))
+ return err
+}
+
+// DecodeMsg implements msgp.Decodable.
+// It sets the value of *Raw to be the
+// next object on the wire.
+func (r *Raw) DecodeMsg(f *Reader) error {
+ *r = (*r)[:0]
+ return appendNext(f, (*[]byte)(r))
+}
+
+// Msgsize implements msgp.Sizer
+func (r Raw) Msgsize() int {
+ l := len(r)
+ if l == 0 {
+ return 1 // for 'nil'
+ }
+ return l
+}
+
+func appendNext(f *Reader, d *[]byte) error {
+ amt, o, err := getNextSize(f.r)
+ if err != nil {
+ return err
+ }
+ var i int
+ *d, i = ensure(*d, int(amt))
+ _, err = f.r.ReadFull((*d)[i:])
+ if err != nil {
+ return err
+ }
+ for o > 0 {
+ err = appendNext(f, d)
+ if err != nil {
+ return err
+ }
+ o--
+ }
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler
+func (r *Raw) MarshalJSON() ([]byte, error) {
+ var buf bytes.Buffer
+ _, err := UnmarshalAsJSON(&buf, []byte(*r))
+ return buf.Bytes(), err
+}
+
+// ReadMapHeaderBytes reads a map header size
+// from 'b' and returns the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a map)
+func ReadMapHeaderBytes(b []byte) (sz uint32, o []byte, err error) {
+ l := len(b)
+ if l < 1 {
+ err = ErrShortBytes
+ return
+ }
+
+ lead := b[0]
+ if isfixmap(lead) {
+ sz = uint32(rfixmap(lead))
+ o = b[1:]
+ return
+ }
+
+ switch lead {
+ case mmap16:
+ if l < 3 {
+ err = ErrShortBytes
+ return
+ }
+ sz = uint32(big.Uint16(b[1:]))
+ o = b[3:]
+ return
+
+ case mmap32:
+ if l < 5 {
+ err = ErrShortBytes
+ return
+ }
+ sz = big.Uint32(b[1:])
+ o = b[5:]
+ return
+
+ default:
+ err = badPrefix(MapType, lead)
+ return
+ }
+}
+
+// ReadMapKeyZC attempts to read a map key
+// from 'b' and returns the key bytes and the remaining bytes
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a str or bin)
+func ReadMapKeyZC(b []byte) ([]byte, []byte, error) {
+ o, b, err := ReadStringZC(b)
+ if err != nil {
+ if tperr, ok := err.(TypeError); ok && tperr.Encoded == BinType {
+ return ReadBytesZC(b)
+ }
+ return nil, b, err
+ }
+ return o, b, nil
+}
+
+// ReadArrayHeaderBytes attempts to read
+// the array header size off of 'b' and return
+// the size and remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not an array)
+func ReadArrayHeaderBytes(b []byte) (sz uint32, o []byte, err error) {
+ if len(b) < 1 {
+ return 0, nil, ErrShortBytes
+ }
+ lead := b[0]
+ if isfixarray(lead) {
+ sz = uint32(rfixarray(lead))
+ o = b[1:]
+ return
+ }
+
+ switch lead {
+ case marray16:
+ if len(b) < 3 {
+ err = ErrShortBytes
+ return
+ }
+ sz = uint32(big.Uint16(b[1:]))
+ o = b[3:]
+ return
+
+ case marray32:
+ if len(b) < 5 {
+ err = ErrShortBytes
+ return
+ }
+ sz = big.Uint32(b[1:])
+ o = b[5:]
+ return
+
+ default:
+ err = badPrefix(ArrayType, lead)
+ return
+ }
+}
+
+// ReadNilBytes tries to read a "nil" byte
+// off of 'b' and return the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a 'nil')
+// - InvalidPrefixError
+func ReadNilBytes(b []byte) ([]byte, error) {
+ if len(b) < 1 {
+ return nil, ErrShortBytes
+ }
+ if b[0] != mnil {
+ return b, badPrefix(NilType, b[0])
+ }
+ return b[1:], nil
+}
+
+// ReadFloat64Bytes tries to read a float64
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a float64)
+func ReadFloat64Bytes(b []byte) (f float64, o []byte, err error) {
+ if len(b) < 9 {
+ if len(b) >= 5 && b[0] == mfloat32 {
+ var tf float32
+ tf, o, err = ReadFloat32Bytes(b)
+ f = float64(tf)
+ return
+ }
+ err = ErrShortBytes
+ return
+ }
+
+ if b[0] != mfloat64 {
+ if b[0] == mfloat32 {
+ var tf float32
+ tf, o, err = ReadFloat32Bytes(b)
+ f = float64(tf)
+ return
+ }
+ err = badPrefix(Float64Type, b[0])
+ return
+ }
+
+ f = math.Float64frombits(getMuint64(b))
+ o = b[9:]
+ return
+}
+
+// ReadFloat32Bytes tries to read a float64
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a float32)
+func ReadFloat32Bytes(b []byte) (f float32, o []byte, err error) {
+ if len(b) < 5 {
+ err = ErrShortBytes
+ return
+ }
+
+ if b[0] != mfloat32 {
+ err = TypeError{Method: Float32Type, Encoded: getType(b[0])}
+ return
+ }
+
+ f = math.Float32frombits(getMuint32(b))
+ o = b[5:]
+ return
+}
+
+// ReadBoolBytes tries to read a float64
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a bool)
+func ReadBoolBytes(b []byte) (bool, []byte, error) {
+ if len(b) < 1 {
+ return false, b, ErrShortBytes
+ }
+ switch b[0] {
+ case mtrue:
+ return true, b[1:], nil
+ case mfalse:
+ return false, b[1:], nil
+ default:
+ return false, b, badPrefix(BoolType, b[0])
+ }
+}
+
+// ReadInt64Bytes tries to read an int64
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError (not a int)
+func ReadInt64Bytes(b []byte) (i int64, o []byte, err error) {
+ l := len(b)
+ if l < 1 {
+ return 0, nil, ErrShortBytes
+ }
+
+ lead := b[0]
+ if isfixint(lead) {
+ i = int64(rfixint(lead))
+ o = b[1:]
+ return
+ }
+ if isnfixint(lead) {
+ i = int64(rnfixint(lead))
+ o = b[1:]
+ return
+ }
+
+ switch lead {
+ case mint8:
+ if l < 2 {
+ err = ErrShortBytes
+ return
+ }
+ i = int64(getMint8(b))
+ o = b[2:]
+ return
+
+ case mint16:
+ if l < 3 {
+ err = ErrShortBytes
+ return
+ }
+ i = int64(getMint16(b))
+ o = b[3:]
+ return
+
+ case mint32:
+ if l < 5 {
+ err = ErrShortBytes
+ return
+ }
+ i = int64(getMint32(b))
+ o = b[5:]
+ return
+
+ case mint64:
+ if l < 9 {
+ err = ErrShortBytes
+ return
+ }
+ i = getMint64(b)
+ o = b[9:]
+ return
+
+ default:
+ err = badPrefix(IntType, lead)
+ return
+ }
+}
+
+// ReadInt32Bytes tries to read an int32
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a int)
+// - IntOverflow{} (value doesn't fit in int32)
+func ReadInt32Bytes(b []byte) (int32, []byte, error) {
+ i, o, err := ReadInt64Bytes(b)
+ if i > math.MaxInt32 || i < math.MinInt32 {
+ return 0, o, IntOverflow{Value: i, FailedBitsize: 32}
+ }
+ return int32(i), o, err
+}
+
+// ReadInt16Bytes tries to read an int16
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a int)
+// - IntOverflow{} (value doesn't fit in int16)
+func ReadInt16Bytes(b []byte) (int16, []byte, error) {
+ i, o, err := ReadInt64Bytes(b)
+ if i > math.MaxInt16 || i < math.MinInt16 {
+ return 0, o, IntOverflow{Value: i, FailedBitsize: 16}
+ }
+ return int16(i), o, err
+}
+
+// ReadInt8Bytes tries to read an int16
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a int)
+// - IntOverflow{} (value doesn't fit in int8)
+func ReadInt8Bytes(b []byte) (int8, []byte, error) {
+ i, o, err := ReadInt64Bytes(b)
+ if i > math.MaxInt8 || i < math.MinInt8 {
+ return 0, o, IntOverflow{Value: i, FailedBitsize: 8}
+ }
+ return int8(i), o, err
+}
+
+// ReadIntBytes tries to read an int
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a int)
+// - IntOverflow{} (value doesn't fit in int; 32-bit platforms only)
+func ReadIntBytes(b []byte) (int, []byte, error) {
+ if smallint {
+ i, b, err := ReadInt32Bytes(b)
+ return int(i), b, err
+ }
+ i, b, err := ReadInt64Bytes(b)
+ return int(i), b, err
+}
+
+// ReadUint64Bytes tries to read a uint64
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a uint)
+func ReadUint64Bytes(b []byte) (u uint64, o []byte, err error) {
+ l := len(b)
+ if l < 1 {
+ return 0, nil, ErrShortBytes
+ }
+
+ lead := b[0]
+ if isfixint(lead) {
+ u = uint64(rfixint(lead))
+ o = b[1:]
+ return
+ }
+
+ switch lead {
+ case muint8:
+ if l < 2 {
+ err = ErrShortBytes
+ return
+ }
+ u = uint64(getMuint8(b))
+ o = b[2:]
+ return
+
+ case muint16:
+ if l < 3 {
+ err = ErrShortBytes
+ return
+ }
+ u = uint64(getMuint16(b))
+ o = b[3:]
+ return
+
+ case muint32:
+ if l < 5 {
+ err = ErrShortBytes
+ return
+ }
+ u = uint64(getMuint32(b))
+ o = b[5:]
+ return
+
+ case muint64:
+ if l < 9 {
+ err = ErrShortBytes
+ return
+ }
+ u = getMuint64(b)
+ o = b[9:]
+ return
+
+ default:
+ err = badPrefix(UintType, lead)
+ return
+ }
+}
+
+// ReadUint32Bytes tries to read a uint32
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a uint)
+// - UintOverflow{} (value too large for uint32)
+func ReadUint32Bytes(b []byte) (uint32, []byte, error) {
+ v, o, err := ReadUint64Bytes(b)
+ if v > math.MaxUint32 {
+ return 0, nil, UintOverflow{Value: v, FailedBitsize: 32}
+ }
+ return uint32(v), o, err
+}
+
+// ReadUint16Bytes tries to read a uint16
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a uint)
+// - UintOverflow{} (value too large for uint16)
+func ReadUint16Bytes(b []byte) (uint16, []byte, error) {
+ v, o, err := ReadUint64Bytes(b)
+ if v > math.MaxUint16 {
+ return 0, nil, UintOverflow{Value: v, FailedBitsize: 16}
+ }
+ return uint16(v), o, err
+}
+
+// ReadUint8Bytes tries to read a uint8
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a uint)
+// - UintOverflow{} (value too large for uint8)
+func ReadUint8Bytes(b []byte) (uint8, []byte, error) {
+ v, o, err := ReadUint64Bytes(b)
+ if v > math.MaxUint8 {
+ return 0, nil, UintOverflow{Value: v, FailedBitsize: 8}
+ }
+ return uint8(v), o, err
+}
+
+// ReadUintBytes tries to read a uint
+// from 'b' and return the value and the remaining bytes.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a uint)
+// - UintOverflow{} (value too large for uint; 32-bit platforms only)
+func ReadUintBytes(b []byte) (uint, []byte, error) {
+ if smallint {
+ u, b, err := ReadUint32Bytes(b)
+ return uint(u), b, err
+ }
+ u, b, err := ReadUint64Bytes(b)
+ return uint(u), b, err
+}
+
+// ReadByteBytes is analagous to ReadUint8Bytes
+func ReadByteBytes(b []byte) (byte, []byte, error) {
+ return ReadUint8Bytes(b)
+}
+
+// ReadBytesBytes reads a 'bin' object
+// from 'b' and returns its vaue and
+// the remaining bytes in 'b'.
+// Possible errors:
+// - ErrShortBytes (too few bytes)
+// - TypeError{} (not a 'bin' object)
+func ReadBytesBytes(b []byte, scratch []byte) (v []byte, o []byte, err error) {
+ return readBytesBytes(b, scratch, false)
+}
+
+func readBytesBytes(b []byte, scratch []byte, zc bool) (v []byte, o []byte, err error) {
+ l := len(b)
+ if l < 1 {
+ return nil, nil, ErrShortBytes
+ }
+
+ lead := b[0]
+ var read int
+ switch lead {
+ case mbin8:
+ if l < 2 {
+ err = ErrShortBytes
+ return
+ }
+
+ read = int(b[1])
+ b = b[2:]
+
+ case mbin16:
+ if l < 3 {
+ err = ErrShortBytes
+ return
+ }
+ read = int(big.Uint16(b[1:]))
+ b = b[3:]
+
+ case mbin32:
+ if l < 5 {
+ err = ErrShortBytes
+ return
+ }
+ read = int(big.Uint32(b[1:]))
+ b = b[5:]
+
+ default:
+ err = badPrefix(BinType, lead)
+ return
+ }
+
+ if len(b) < read {
+ err = ErrShortBytes
+ return
+ }
+
+ // zero-copy
+ if zc {
+ v = b[0:read]
+ o = b[read:]
+ return
+ }
+
+ if cap(scratch) >= read {
+ v = scratch[0:read]
+ } else {
+ v = make([]byte, read)
+ }
+
+ o = b[copy(v, b):]
+ return
+}
+
+// ReadBytesZC extracts the messagepack-encoded
+// binary field without copying. The returned []byte
+// points to the same memory as the input slice.
+// Possible errors:
+// - ErrShortBytes (b not long enough)
+// - TypeError{} (object not 'bin')
+func ReadBytesZC(b []byte) (v []byte, o []byte, err error) {
+ return readBytesBytes(b, nil, true)
+}
+
+func ReadExactBytes(b []byte, into []byte) (o []byte, err error) {
+ l := len(b)
+ if l < 1 {
+ err = ErrShortBytes
+ return
+ }
+
+ lead := b[0]
+ var read uint32
+ var skip int
+ switch lead {
+ case mbin8:
+ if l < 2 {
+ err = ErrShortBytes
+ return
+ }
+
+ read = uint32(b[1])
+ skip = 2
+
+ case mbin16:
+ if l < 3 {
+ err = ErrShortBytes
+ return
+ }
+ read = uint32(big.Uint16(b[1:]))
+ skip = 3
+
+ case mbin32:
+ if l < 5 {
+ err = ErrShortBytes
+ return
+ }
+ read = uint32(big.Uint32(b[1:]))
+ skip = 5
+
+ default:
+ err = badPrefix(BinType, lead)
+ return
+ }
+
+ if read != uint32(len(into)) {
+ err = ArrayError{Wanted: uint32(len(into)), Got: read}
+ return
+ }
+
+ o = b[skip+copy(into, b[skip:]):]
+ return
+}
+
+// ReadStringZC reads a messagepack string field
+// without copying. The returned []byte points
+// to the same memory as the input slice.
+// Possible errors:
+// - ErrShortBytes (b not long enough)
+// - TypeError{} (object not 'str')
+func ReadStringZC(b []byte) (v []byte, o []byte, err error) {
+ l := len(b)
+ if l < 1 {
+ return nil, nil, ErrShortBytes
+ }
+
+ lead := b[0]
+ var read int
+
+ if isfixstr(lead) {
+ read = int(rfixstr(lead))
+ b = b[1:]
+ } else {
+ switch lead {
+ case mstr8:
+ if l < 2 {
+ err = ErrShortBytes
+ return
+ }
+ read = int(b[1])
+ b = b[2:]
+
+ case mstr16:
+ if l < 3 {
+ err = ErrShortBytes
+ return
+ }
+ read = int(big.Uint16(b[1:]))
+ b = b[3:]
+
+ case mstr32:
+ if l < 5 {
+ err = ErrShortBytes
+ return
+ }
+ read = int(big.Uint32(b[1:]))
+ b = b[5:]
+
+ default:
+ err = TypeError{Method: StrType, Encoded: getType(lead)}
+ return
+ }
+ }
+
+ if len(b) < read {
+ err = ErrShortBytes
+ return
+ }
+
+ v = b[0:read]
+ o = b[read:]
+ return
+}
+
+// ReadStringBytes reads a 'str' object
+// from 'b' and returns its value and the
+// remaining bytes in 'b'.
+// Possible errors:
+// - ErrShortBytes (b not long enough)
+// - TypeError{} (not 'str' type)
+// - InvalidPrefixError
+func ReadStringBytes(b []byte) (string, []byte, error) {
+ v, o, err := ReadStringZC(b)
+ return string(v), o, err
+}
+
+// ReadComplex128Bytes reads a complex128
+// extension object from 'b' and returns the
+// remaining bytes.
+// Possible errors:
+// - ErrShortBytes (not enough bytes in 'b')
+// - TypeError{} (object not a complex128)
+// - InvalidPrefixError
+// - ExtensionTypeError{} (object an extension of the correct size, but not a complex128)
+func ReadComplex128Bytes(b []byte) (c complex128, o []byte, err error) {
+ if len(b) < 18 {
+ err = ErrShortBytes
+ return
+ }
+ if b[0] != mfixext16 {
+ err = badPrefix(Complex128Type, b[0])
+ return
+ }
+ if int8(b[1]) != Complex128Extension {
+ err = errExt(int8(b[1]), Complex128Extension)
+ return
+ }
+ c = complex(math.Float64frombits(big.Uint64(b[2:])),
+ math.Float64frombits(big.Uint64(b[10:])))
+ o = b[18:]
+ return
+}
+
+// ReadComplex64Bytes reads a complex64
+// extension object from 'b' and returns the
+// remaining bytes.
+// Possible errors:
+// - ErrShortBytes (not enough bytes in 'b')
+// - TypeError{} (object not a complex64)
+// - ExtensionTypeError{} (object an extension of the correct size, but not a complex64)
+func ReadComplex64Bytes(b []byte) (c complex64, o []byte, err error) {
+ if len(b) < 10 {
+ err = ErrShortBytes
+ return
+ }
+ if b[0] != mfixext8 {
+ err = badPrefix(Complex64Type, b[0])
+ return
+ }
+ if b[1] != Complex64Extension {
+ err = errExt(int8(b[1]), Complex64Extension)
+ return
+ }
+ c = complex(math.Float32frombits(big.Uint32(b[2:])),
+ math.Float32frombits(big.Uint32(b[6:])))
+ o = b[10:]
+ return
+}
+
+// ReadTimeBytes reads a time.Time
+// extension object from 'b' and returns the
+// remaining bytes.
+// Possible errors:
+// - ErrShortBytes (not enough bytes in 'b')
+// - TypeError{} (object not a complex64)
+// - ExtensionTypeError{} (object an extension of the correct size, but not a time.Time)
+func ReadTimeBytes(b []byte) (t time.Time, o []byte, err error) {
+ if len(b) < 15 {
+ err = ErrShortBytes
+ return
+ }
+ if b[0] != mext8 || b[1] != 12 {
+ err = badPrefix(TimeType, b[0])
+ return
+ }
+ if int8(b[2]) != TimeExtension {
+ err = errExt(int8(b[2]), TimeExtension)
+ return
+ }
+ sec, nsec := getUnix(b[3:])
+ t = time.Unix(sec, int64(nsec)).Local()
+ o = b[15:]
+ return
+}
+
+// ReadMapStrIntfBytes reads a map[string]interface{}
+// out of 'b' and returns the map and remaining bytes.
+// If 'old' is non-nil, the values will be read into that map.
+func ReadMapStrIntfBytes(b []byte, old map[string]interface{}) (v map[string]interface{}, o []byte, err error) {
+ var sz uint32
+ o = b
+ sz, o, err = ReadMapHeaderBytes(o)
+
+ if err != nil {
+ return
+ }
+
+ if old != nil {
+ for key := range old {
+ delete(old, key)
+ }
+ v = old
+ } else {
+ v = make(map[string]interface{}, int(sz))
+ }
+
+ for z := uint32(0); z < sz; z++ {
+ if len(o) < 1 {
+ err = ErrShortBytes
+ return
+ }
+ var key []byte
+ key, o, err = ReadMapKeyZC(o)
+ if err != nil {
+ return
+ }
+ var val interface{}
+ val, o, err = ReadIntfBytes(o)
+ if err != nil {
+ return
+ }
+ v[string(key)] = val
+ }
+ return
+}
+
+// ReadIntfBytes attempts to read
+// the next object out of 'b' as a raw interface{} and
+// return the remaining bytes.
+func ReadIntfBytes(b []byte) (i interface{}, o []byte, err error) {
+ if len(b) < 1 {
+ err = ErrShortBytes
+ return
+ }
+
+ k := NextType(b)
+
+ switch k {
+ case MapType:
+ i, o, err = ReadMapStrIntfBytes(b, nil)
+ return
+
+ case ArrayType:
+ var sz uint32
+ sz, b, err = ReadArrayHeaderBytes(b)
+ if err != nil {
+ return
+ }
+ j := make([]interface{}, int(sz))
+ i = j
+ for d := range j {
+ j[d], b, err = ReadIntfBytes(b)
+ if err != nil {
+ return
+ }
+ }
+ return
+
+ case Float32Type:
+ i, o, err = ReadFloat32Bytes(b)
+ return
+
+ case Float64Type:
+ i, o, err = ReadFloat64Bytes(b)
+ return
+
+ case IntType:
+ i, o, err = ReadInt64Bytes(b)
+ return
+
+ case UintType:
+ i, o, err = ReadUint64Bytes(b)
+ return
+
+ case BoolType:
+ i, o, err = ReadBoolBytes(b)
+ return
+
+ case TimeType:
+ i, o, err = ReadTimeBytes(b)
+ return
+
+ case Complex64Type:
+ i, o, err = ReadComplex64Bytes(b)
+ return
+
+ case Complex128Type:
+ i, o, err = ReadComplex128Bytes(b)
+ return
+
+ case ExtensionType:
+ var t int8
+ t, err = peekExtension(b)
+ if err != nil {
+ return
+ }
+ // use a user-defined extension,
+ // if it's been registered
+ f, ok := extensionReg[t]
+ if ok {
+ e := f()
+ o, err = ReadExtensionBytes(b, e)
+ i = e
+ return
+ }
+ // last resort is a raw extension
+ e := RawExtension{}
+ e.Type = int8(t)
+ o, err = ReadExtensionBytes(b, &e)
+ i = &e
+ return
+
+ case NilType:
+ o, err = ReadNilBytes(b)
+ return
+
+ case BinType:
+ i, o, err = ReadBytesBytes(b, nil)
+ return
+
+ case StrType:
+ i, o, err = ReadStringBytes(b)
+ return
+
+ default:
+ err = InvalidPrefixError(b[0])
+ return
+ }
+}
+
+// Skip skips the next object in 'b' and
+// returns the remaining bytes. If the object
+// is a map or array, all of its elements
+// will be skipped.
+// Possible Errors:
+// - ErrShortBytes (not enough bytes in b)
+// - InvalidPrefixError (bad encoding)
+func Skip(b []byte) ([]byte, error) {
+ sz, asz, err := getSize(b)
+ if err != nil {
+ return b, err
+ }
+ if uintptr(len(b)) < sz {
+ return b, ErrShortBytes
+ }
+ b = b[sz:]
+ for asz > 0 {
+ b, err = Skip(b)
+ if err != nil {
+ return b, err
+ }
+ asz--
+ }
+ return b, nil
+}
+
+// returns (skip N bytes, skip M objects, error)
+func getSize(b []byte) (uintptr, uintptr, error) {
+ l := len(b)
+ if l == 0 {
+ return 0, 0, ErrShortBytes
+ }
+ lead := b[0]
+ spec := &sizes[lead] // get type information
+ size, mode := spec.size, spec.extra
+ if size == 0 {
+ return 0, 0, InvalidPrefixError(lead)
+ }
+ if mode >= 0 { // fixed composites
+ return uintptr(size), uintptr(mode), nil
+ }
+ if l < int(size) {
+ return 0, 0, ErrShortBytes
+ }
+ switch mode {
+ case extra8:
+ return uintptr(size) + uintptr(b[1]), 0, nil
+ case extra16:
+ return uintptr(size) + uintptr(big.Uint16(b[1:])), 0, nil
+ case extra32:
+ return uintptr(size) + uintptr(big.Uint32(b[1:])), 0, nil
+ case map16v:
+ return uintptr(size), 2 * uintptr(big.Uint16(b[1:])), nil
+ case map32v:
+ return uintptr(size), 2 * uintptr(big.Uint32(b[1:])), nil
+ case array16v:
+ return uintptr(size), uintptr(big.Uint16(b[1:])), nil
+ case array32v:
+ return uintptr(size), uintptr(big.Uint32(b[1:])), nil
+ default:
+ return 0, 0, fatal
+ }
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/size.go b/vendor/src/github.com/tinylib/msgp/msgp/size.go
new file mode 100644
index 0000000000..ce2f8b16ff
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/size.go
@@ -0,0 +1,38 @@
+package msgp
+
+// The sizes provided
+// are the worst-case
+// encoded sizes for
+// each type. For variable-
+// length types ([]byte, string),
+// the total encoded size is
+// the prefix size plus the
+// length of the object.
+const (
+ Int64Size = 9
+ IntSize = Int64Size
+ UintSize = Int64Size
+ Int8Size = 2
+ Int16Size = 3
+ Int32Size = 5
+ Uint8Size = 2
+ ByteSize = Uint8Size
+ Uint16Size = 3
+ Uint32Size = 5
+ Uint64Size = Int64Size
+ Float64Size = 9
+ Float32Size = 5
+ Complex64Size = 10
+ Complex128Size = 18
+
+ TimeSize = 15
+ BoolSize = 1
+ NilSize = 1
+
+ MapHeaderSize = 5
+ ArrayHeaderSize = 5
+
+ BytesPrefixSize = 5
+ StringPrefixSize = 5
+ ExtensionPrefixSize = 6
+)
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/write.go b/vendor/src/github.com/tinylib/msgp/msgp/write.go
new file mode 100644
index 0000000000..216697fe53
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/write.go
@@ -0,0 +1,768 @@
+package msgp
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "reflect"
+ "sync"
+ "time"
+)
+
+func abs(i int64) int64 {
+ if i < 0 {
+ return -i
+ }
+ return i
+}
+
+// Sizer is an interface implemented
+// by types that can estimate their
+// size when MessagePack encoded.
+// This interface is optional, but
+// encoding/marshaling implementations
+// may use this as a way to pre-allocate
+// memory for serialization.
+type Sizer interface {
+ Msgsize() int
+}
+
+var (
+ // Nowhere is an io.Writer to nowhere
+ Nowhere io.Writer = nwhere{}
+
+ btsType = reflect.TypeOf(([]byte)(nil))
+ writerPool = sync.Pool{
+ New: func() interface{} {
+ return &Writer{buf: make([]byte, 2048)}
+ },
+ }
+)
+
+func popWriter(w io.Writer) *Writer {
+ wr := writerPool.Get().(*Writer)
+ wr.Reset(w)
+ return wr
+}
+
+func pushWriter(wr *Writer) {
+ wr.w = nil
+ wr.wloc = 0
+ writerPool.Put(wr)
+}
+
+// freeW frees a writer for use
+// by other processes. It is not necessary
+// to call freeW on a writer. However, maintaining
+// a reference to a *Writer after calling freeW on
+// it will cause undefined behavior.
+func freeW(w *Writer) { pushWriter(w) }
+
+// Require ensures that cap(old)-len(old) >= extra
+func Require(old []byte, extra int) []byte {
+ if cap(old)-len(old) >= extra {
+ return old
+ }
+ if len(old) == 0 {
+ return make([]byte, 0, extra)
+ }
+ n := make([]byte, len(old), cap(old)-len(old)+extra)
+ copy(n, old)
+ return n
+}
+
+// nowhere writer
+type nwhere struct{}
+
+func (n nwhere) Write(p []byte) (int, error) { return len(p), nil }
+
+// Marshaler is the interface implemented
+// by types that know how to marshal themselves
+// as MessagePack. MarshalMsg appends the marshalled
+// form of the object to the provided
+// byte slice, returning the extended
+// slice and any errors encountered.
+type Marshaler interface {
+ MarshalMsg([]byte) ([]byte, error)
+}
+
+// Encodable is the interface implemented
+// by types that know how to write themselves
+// as MessagePack using a *msgp.Writer.
+type Encodable interface {
+ EncodeMsg(*Writer) error
+}
+
+// Writer is a buffered writer
+// that can be used to write
+// MessagePack objects to an io.Writer.
+// You must call *Writer.Flush() in order
+// to flush all of the buffered data
+// to the underlying writer.
+type Writer struct {
+ w io.Writer
+ buf []byte
+ wloc int
+}
+
+// NewWriter returns a new *Writer.
+func NewWriter(w io.Writer) *Writer {
+ if wr, ok := w.(*Writer); ok {
+ return wr
+ }
+ return popWriter(w)
+}
+
+// NewWriterSize returns a writer with a custom buffer size.
+func NewWriterSize(w io.Writer, sz int) *Writer {
+ // we must be able to require() 18
+ // contiguous bytes, so that is the
+ // practical minimum buffer size
+ if sz < 18 {
+ sz = 18
+ }
+
+ return &Writer{
+ w: w,
+ buf: make([]byte, sz),
+ }
+}
+
+// Encode encodes an Encodable to an io.Writer.
+func Encode(w io.Writer, e Encodable) error {
+ wr := NewWriter(w)
+ err := e.EncodeMsg(wr)
+ if err == nil {
+ err = wr.Flush()
+ }
+ freeW(wr)
+ return err
+}
+
+func (mw *Writer) flush() error {
+ if mw.wloc == 0 {
+ return nil
+ }
+ n, err := mw.w.Write(mw.buf[:mw.wloc])
+ if err != nil {
+ if n > 0 {
+ mw.wloc = copy(mw.buf, mw.buf[n:mw.wloc])
+ }
+ return err
+ }
+ mw.wloc = 0
+ return nil
+}
+
+// Flush flushes all of the buffered
+// data to the underlying writer.
+func (mw *Writer) Flush() error { return mw.flush() }
+
+// Buffered returns the number bytes in the write buffer
+func (mw *Writer) Buffered() int { return len(mw.buf) - mw.wloc }
+
+func (mw *Writer) avail() int { return len(mw.buf) - mw.wloc }
+
+func (mw *Writer) bufsize() int { return len(mw.buf) }
+
+// NOTE: this should only be called with
+// a number that is guaranteed to be less than
+// len(mw.buf). typically, it is called with a constant.
+//
+// NOTE: this is a hot code path
+func (mw *Writer) require(n int) (int, error) {
+ c := len(mw.buf)
+ wl := mw.wloc
+ if c-wl < n {
+ if err := mw.flush(); err != nil {
+ return 0, err
+ }
+ wl = mw.wloc
+ }
+ mw.wloc += n
+ return wl, nil
+}
+
+// push one byte onto the buffer
+//
+// NOTE: this is a hot code path
+func (mw *Writer) push(b byte) error {
+ if mw.wloc == len(mw.buf) {
+ if err := mw.flush(); err != nil {
+ return err
+ }
+ }
+ mw.buf[mw.wloc] = b
+ mw.wloc++
+ return nil
+}
+
+func (mw *Writer) prefix8(b byte, u uint8) error {
+ const need = 2
+ if len(mw.buf)-mw.wloc < need {
+ if err := mw.flush(); err != nil {
+ return err
+ }
+ }
+ prefixu8(mw.buf[mw.wloc:], b, u)
+ mw.wloc += need
+ return nil
+}
+
+func (mw *Writer) prefix16(b byte, u uint16) error {
+ const need = 3
+ if len(mw.buf)-mw.wloc < need {
+ if err := mw.flush(); err != nil {
+ return err
+ }
+ }
+ prefixu16(mw.buf[mw.wloc:], b, u)
+ mw.wloc += need
+ return nil
+}
+
+func (mw *Writer) prefix32(b byte, u uint32) error {
+ const need = 5
+ if len(mw.buf)-mw.wloc < need {
+ if err := mw.flush(); err != nil {
+ return err
+ }
+ }
+ prefixu32(mw.buf[mw.wloc:], b, u)
+ mw.wloc += need
+ return nil
+}
+
+func (mw *Writer) prefix64(b byte, u uint64) error {
+ const need = 9
+ if len(mw.buf)-mw.wloc < need {
+ if err := mw.flush(); err != nil {
+ return err
+ }
+ }
+ prefixu64(mw.buf[mw.wloc:], b, u)
+ mw.wloc += need
+ return nil
+}
+
+// Write implements io.Writer, and writes
+// data directly to the buffer.
+func (mw *Writer) Write(p []byte) (int, error) {
+ l := len(p)
+ if mw.avail() < l {
+ if err := mw.flush(); err != nil {
+ return 0, err
+ }
+ if l > len(mw.buf) {
+ return mw.w.Write(p)
+ }
+ }
+ mw.wloc += copy(mw.buf[mw.wloc:], p)
+ return l, nil
+}
+
+// implements io.WriteString
+func (mw *Writer) writeString(s string) error {
+ l := len(s)
+ if mw.avail() < l {
+ if err := mw.flush(); err != nil {
+ return err
+ }
+ if l > len(mw.buf) {
+ _, err := io.WriteString(mw.w, s)
+ return err
+ }
+ }
+ mw.wloc += copy(mw.buf[mw.wloc:], s)
+ return nil
+}
+
+// Reset changes the underlying writer used by the Writer
+func (mw *Writer) Reset(w io.Writer) {
+ mw.buf = mw.buf[:cap(mw.buf)]
+ mw.w = w
+ mw.wloc = 0
+}
+
+// WriteMapHeader writes a map header of the given
+// size to the writer
+func (mw *Writer) WriteMapHeader(sz uint32) error {
+ switch {
+ case sz < 16:
+ return mw.push(wfixmap(uint8(sz)))
+ case sz < math.MaxUint16:
+ return mw.prefix16(mmap16, uint16(sz))
+ default:
+ return mw.prefix32(mmap32, sz)
+ }
+}
+
+// WriteArrayHeader writes an array header of the
+// given size to the writer
+func (mw *Writer) WriteArrayHeader(sz uint32) error {
+ switch {
+ case sz < 16:
+ return mw.push(wfixarray(uint8(sz)))
+ case sz < math.MaxUint16:
+ return mw.prefix16(marray16, uint16(sz))
+ default:
+ return mw.prefix32(marray32, sz)
+ }
+}
+
+// WriteNil writes a nil byte to the buffer
+func (mw *Writer) WriteNil() error {
+ return mw.push(mnil)
+}
+
+// WriteFloat64 writes a float64 to the writer
+func (mw *Writer) WriteFloat64(f float64) error {
+ return mw.prefix64(mfloat64, math.Float64bits(f))
+}
+
+// WriteFloat32 writes a float32 to the writer
+func (mw *Writer) WriteFloat32(f float32) error {
+ return mw.prefix32(mfloat32, math.Float32bits(f))
+}
+
+// WriteInt64 writes an int64 to the writer
+func (mw *Writer) WriteInt64(i int64) error {
+ a := abs(i)
+ switch {
+ case i < 0 && i > -32:
+ return mw.push(wnfixint(int8(i)))
+ case i >= 0 && i < 128:
+ return mw.push(wfixint(uint8(i)))
+ case a < math.MaxInt8:
+ return mw.prefix8(mint8, uint8(i))
+ case a < math.MaxInt16:
+ return mw.prefix16(mint16, uint16(i))
+ case a < math.MaxInt32:
+ return mw.prefix32(mint32, uint32(i))
+ default:
+ return mw.prefix64(mint64, uint64(i))
+ }
+}
+
+// WriteInt8 writes an int8 to the writer
+func (mw *Writer) WriteInt8(i int8) error { return mw.WriteInt64(int64(i)) }
+
+// WriteInt16 writes an int16 to the writer
+func (mw *Writer) WriteInt16(i int16) error { return mw.WriteInt64(int64(i)) }
+
+// WriteInt32 writes an int32 to the writer
+func (mw *Writer) WriteInt32(i int32) error { return mw.WriteInt64(int64(i)) }
+
+// WriteInt writes an int to the writer
+func (mw *Writer) WriteInt(i int) error { return mw.WriteInt64(int64(i)) }
+
+// WriteUint64 writes a uint64 to the writer
+func (mw *Writer) WriteUint64(u uint64) error {
+ switch {
+ case u < (1 << 7):
+ return mw.push(wfixint(uint8(u)))
+ case u < math.MaxUint8:
+ return mw.prefix8(muint8, uint8(u))
+ case u < math.MaxUint16:
+ return mw.prefix16(muint16, uint16(u))
+ case u < math.MaxUint32:
+ return mw.prefix32(muint32, uint32(u))
+ default:
+ return mw.prefix64(muint64, u)
+ }
+}
+
+// WriteByte is analagous to WriteUint8
+func (mw *Writer) WriteByte(u byte) error { return mw.WriteUint8(uint8(u)) }
+
+// WriteUint8 writes a uint8 to the writer
+func (mw *Writer) WriteUint8(u uint8) error { return mw.WriteUint64(uint64(u)) }
+
+// WriteUint16 writes a uint16 to the writer
+func (mw *Writer) WriteUint16(u uint16) error { return mw.WriteUint64(uint64(u)) }
+
+// WriteUint32 writes a uint32 to the writer
+func (mw *Writer) WriteUint32(u uint32) error { return mw.WriteUint64(uint64(u)) }
+
+// WriteUint writes a uint to the writer
+func (mw *Writer) WriteUint(u uint) error { return mw.WriteUint64(uint64(u)) }
+
+// WriteBytes writes binary as 'bin' to the writer
+func (mw *Writer) WriteBytes(b []byte) error {
+ sz := uint32(len(b))
+ var err error
+ switch {
+ case sz < math.MaxUint8:
+ err = mw.prefix8(mbin8, uint8(sz))
+ case sz < math.MaxUint16:
+ err = mw.prefix16(mbin16, uint16(sz))
+ default:
+ err = mw.prefix32(mbin32, sz)
+ }
+ if err != nil {
+ return err
+ }
+ _, err = mw.Write(b)
+ return err
+}
+
+// WriteBool writes a bool to the writer
+func (mw *Writer) WriteBool(b bool) error {
+ if b {
+ return mw.push(mtrue)
+ }
+ return mw.push(mfalse)
+}
+
+// WriteString writes a messagepack string to the writer.
+// (This is NOT an implementation of io.StringWriter)
+func (mw *Writer) WriteString(s string) error {
+ sz := uint32(len(s))
+ var err error
+ switch {
+ case sz < 32:
+ err = mw.push(wfixstr(uint8(sz)))
+ case sz < math.MaxUint8:
+ err = mw.prefix8(mstr8, uint8(sz))
+ case sz < math.MaxUint16:
+ err = mw.prefix16(mstr16, uint16(sz))
+ default:
+ err = mw.prefix32(mstr32, sz)
+ }
+ if err != nil {
+ return err
+ }
+ return mw.writeString(s)
+}
+
+// WriteComplex64 writes a complex64 to the writer
+func (mw *Writer) WriteComplex64(f complex64) error {
+ o, err := mw.require(10)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mfixext8
+ mw.buf[o+1] = Complex64Extension
+ big.PutUint32(mw.buf[o+2:], math.Float32bits(real(f)))
+ big.PutUint32(mw.buf[o+6:], math.Float32bits(imag(f)))
+ return nil
+}
+
+// WriteComplex128 writes a complex128 to the writer
+func (mw *Writer) WriteComplex128(f complex128) error {
+ o, err := mw.require(18)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mfixext16
+ mw.buf[o+1] = Complex128Extension
+ big.PutUint64(mw.buf[o+2:], math.Float64bits(real(f)))
+ big.PutUint64(mw.buf[o+10:], math.Float64bits(imag(f)))
+ return nil
+}
+
+// WriteMapStrStr writes a map[string]string to the writer
+func (mw *Writer) WriteMapStrStr(mp map[string]string) (err error) {
+ err = mw.WriteMapHeader(uint32(len(mp)))
+ if err != nil {
+ return
+ }
+ for key, val := range mp {
+ err = mw.WriteString(key)
+ if err != nil {
+ return
+ }
+ err = mw.WriteString(val)
+ if err != nil {
+ return
+ }
+ }
+ return nil
+}
+
+// WriteMapStrIntf writes a map[string]interface to the writer
+func (mw *Writer) WriteMapStrIntf(mp map[string]interface{}) (err error) {
+ err = mw.WriteMapHeader(uint32(len(mp)))
+ if err != nil {
+ return
+ }
+ for key, val := range mp {
+ err = mw.WriteString(key)
+ if err != nil {
+ return
+ }
+ err = mw.WriteIntf(val)
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+// WriteTime writes a time.Time object to the wire.
+//
+// Time is encoded as Unix time, which means that
+// location (time zone) data is removed from the object.
+// The encoded object itself is 12 bytes: 8 bytes for
+// a big-endian 64-bit integer denoting seconds
+// elapsed since "zero" Unix time, followed by 4 bytes
+// for a big-endian 32-bit signed integer denoting
+// the nanosecond offset of the time. This encoding
+// is intended to ease portability accross languages.
+// (Note that this is *not* the standard time.Time
+// binary encoding, because its implementation relies
+// heavily on the internal representation used by the
+// time package.)
+func (mw *Writer) WriteTime(t time.Time) error {
+ t = t.UTC()
+ o, err := mw.require(15)
+ if err != nil {
+ return err
+ }
+ mw.buf[o] = mext8
+ mw.buf[o+1] = 12
+ mw.buf[o+2] = TimeExtension
+ putUnix(mw.buf[o+3:], t.Unix(), int32(t.Nanosecond()))
+ return nil
+}
+
+// WriteIntf writes the concrete type of 'v'.
+// WriteIntf will error if 'v' is not one of the following:
+// - A bool, float, string, []byte, int, uint, or complex
+// - A map of supported types (with string keys)
+// - An array or slice of supported types
+// - A pointer to a supported type
+// - A type that satisfies the msgp.Encodable interface
+// - A type that satisfies the msgp.Extension interface
+func (mw *Writer) WriteIntf(v interface{}) error {
+ if v == nil {
+ return mw.WriteNil()
+ }
+ switch v := v.(type) {
+
+ // preferred interfaces
+
+ case Encodable:
+ return v.EncodeMsg(mw)
+ case Extension:
+ return mw.WriteExtension(v)
+
+ // concrete types
+
+ case bool:
+ return mw.WriteBool(v)
+ case float32:
+ return mw.WriteFloat32(v)
+ case float64:
+ return mw.WriteFloat64(v)
+ case complex64:
+ return mw.WriteComplex64(v)
+ case complex128:
+ return mw.WriteComplex128(v)
+ case uint8:
+ return mw.WriteUint8(v)
+ case uint16:
+ return mw.WriteUint16(v)
+ case uint32:
+ return mw.WriteUint32(v)
+ case uint64:
+ return mw.WriteUint64(v)
+ case uint:
+ return mw.WriteUint(v)
+ case int8:
+ return mw.WriteInt8(v)
+ case int16:
+ return mw.WriteInt16(v)
+ case int32:
+ return mw.WriteInt32(v)
+ case int64:
+ return mw.WriteInt64(v)
+ case int:
+ return mw.WriteInt(v)
+ case string:
+ return mw.WriteString(v)
+ case []byte:
+ return mw.WriteBytes(v)
+ case map[string]string:
+ return mw.WriteMapStrStr(v)
+ case map[string]interface{}:
+ return mw.WriteMapStrIntf(v)
+ case time.Time:
+ return mw.WriteTime(v)
+ }
+
+ val := reflect.ValueOf(v)
+ if !isSupported(val.Kind()) || !val.IsValid() {
+ return fmt.Errorf("msgp: type %s not supported", val)
+ }
+
+ switch val.Kind() {
+ case reflect.Ptr:
+ if val.IsNil() {
+ return mw.WriteNil()
+ }
+ return mw.WriteIntf(val.Elem().Interface())
+ case reflect.Slice:
+ return mw.writeSlice(val)
+ case reflect.Map:
+ return mw.writeMap(val)
+ }
+ return &ErrUnsupportedType{val.Type()}
+}
+
+func (mw *Writer) writeMap(v reflect.Value) (err error) {
+ if v.Elem().Kind() != reflect.String {
+ return errors.New("msgp: map keys must be strings")
+ }
+ ks := v.MapKeys()
+ err = mw.WriteMapHeader(uint32(len(ks)))
+ if err != nil {
+ return
+ }
+ for _, key := range ks {
+ val := v.MapIndex(key)
+ err = mw.WriteString(key.String())
+ if err != nil {
+ return
+ }
+ err = mw.WriteIntf(val.Interface())
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+func (mw *Writer) writeSlice(v reflect.Value) (err error) {
+ // is []byte
+ if v.Type().ConvertibleTo(btsType) {
+ return mw.WriteBytes(v.Bytes())
+ }
+
+ sz := uint32(v.Len())
+ err = mw.WriteArrayHeader(sz)
+ if err != nil {
+ return
+ }
+ for i := uint32(0); i < sz; i++ {
+ err = mw.WriteIntf(v.Index(int(i)).Interface())
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+func (mw *Writer) writeStruct(v reflect.Value) error {
+ if enc, ok := v.Interface().(Encodable); ok {
+ return enc.EncodeMsg(mw)
+ }
+ return fmt.Errorf("msgp: unsupported type: %s", v.Type())
+}
+
+func (mw *Writer) writeVal(v reflect.Value) error {
+ if !isSupported(v.Kind()) {
+ return fmt.Errorf("msgp: msgp/enc: type %q not supported", v.Type())
+ }
+
+ // shortcut for nil values
+ if v.IsNil() {
+ return mw.WriteNil()
+ }
+ switch v.Kind() {
+ case reflect.Bool:
+ return mw.WriteBool(v.Bool())
+
+ case reflect.Float32, reflect.Float64:
+ return mw.WriteFloat64(v.Float())
+
+ case reflect.Complex64, reflect.Complex128:
+ return mw.WriteComplex128(v.Complex())
+
+ case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int8:
+ return mw.WriteInt64(v.Int())
+
+ case reflect.Interface, reflect.Ptr:
+ if v.IsNil() {
+ mw.WriteNil()
+ }
+ return mw.writeVal(v.Elem())
+
+ case reflect.Map:
+ return mw.writeMap(v)
+
+ case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint8:
+ return mw.WriteUint64(v.Uint())
+
+ case reflect.String:
+ return mw.WriteString(v.String())
+
+ case reflect.Slice, reflect.Array:
+ return mw.writeSlice(v)
+
+ case reflect.Struct:
+ return mw.writeStruct(v)
+
+ }
+ return fmt.Errorf("msgp: msgp/enc: type %q not supported", v.Type())
+}
+
+// is the reflect.Kind encodable?
+func isSupported(k reflect.Kind) bool {
+ switch k {
+ case reflect.Func, reflect.Chan, reflect.Invalid, reflect.UnsafePointer:
+ return false
+ default:
+ return true
+ }
+}
+
+// GuessSize guesses the size of the underlying
+// value of 'i'. If the underlying value is not
+// a simple builtin (or []byte), GuessSize defaults
+// to 512.
+func GuessSize(i interface{}) int {
+ if i == nil {
+ return NilSize
+ }
+
+ switch i := i.(type) {
+ case Sizer:
+ return i.Msgsize()
+ case Extension:
+ return ExtensionPrefixSize + i.Len()
+ case float64:
+ return Float64Size
+ case float32:
+ return Float32Size
+ case uint8, uint16, uint32, uint64, uint:
+ return UintSize
+ case int8, int16, int32, int64, int:
+ return IntSize
+ case []byte:
+ return BytesPrefixSize + len(i)
+ case string:
+ return StringPrefixSize + len(i)
+ case complex64:
+ return Complex64Size
+ case complex128:
+ return Complex128Size
+ case bool:
+ return BoolSize
+ case map[string]interface{}:
+ s := MapHeaderSize
+ for key, val := range i {
+ s += StringPrefixSize + len(key) + GuessSize(val)
+ }
+ return s
+ case map[string]string:
+ s := MapHeaderSize
+ for key, val := range i {
+ s += 2*StringPrefixSize + len(key) + len(val)
+ }
+ return s
+ default:
+ return 512
+ }
+}
diff --git a/vendor/src/github.com/tinylib/msgp/msgp/write_bytes.go b/vendor/src/github.com/tinylib/msgp/msgp/write_bytes.go
new file mode 100644
index 0000000000..658102efc4
--- /dev/null
+++ b/vendor/src/github.com/tinylib/msgp/msgp/write_bytes.go
@@ -0,0 +1,369 @@
+package msgp
+
+import (
+ "math"
+ "reflect"
+ "time"
+)
+
+// ensure 'sz' extra bytes in 'b' btw len(b) and cap(b)
+func ensure(b []byte, sz int) ([]byte, int) {
+ l := len(b)
+ c := cap(b)
+ if c-l < sz {
+ o := make([]byte, (2*c)+sz) // exponential growth
+ n := copy(o, b)
+ return o[:n+sz], n
+ }
+ return b[:l+sz], l
+}
+
+// AppendMapHeader appends a map header with the
+// given size to the slice
+func AppendMapHeader(b []byte, sz uint32) []byte {
+ switch {
+ case sz < 16:
+ return append(b, wfixmap(uint8(sz)))
+
+ case sz < math.MaxUint16:
+ o, n := ensure(b, 3)
+ prefixu16(o[n:], mmap16, uint16(sz))
+ return o
+
+ default:
+ o, n := ensure(b, 5)
+ prefixu32(o[n:], mmap32, sz)
+ return o
+ }
+}
+
+// AppendArrayHeader appends an array header with
+// the given size to the slice
+func AppendArrayHeader(b []byte, sz uint32) []byte {
+ switch {
+ case sz < 16:
+ return append(b, wfixarray(uint8(sz)))
+
+ case sz < math.MaxUint16:
+ o, n := ensure(b, 3)
+ prefixu16(o[n:], marray16, uint16(sz))
+ return o
+
+ default:
+ o, n := ensure(b, 5)
+ prefixu32(o[n:], marray32, sz)
+ return o
+ }
+}
+
+// AppendNil appends a 'nil' byte to the slice
+func AppendNil(b []byte) []byte { return append(b, mnil) }
+
+// AppendFloat64 appends a float64 to the slice
+func AppendFloat64(b []byte, f float64) []byte {
+ o, n := ensure(b, Float64Size)
+ prefixu64(o[n:], mfloat64, math.Float64bits(f))
+ return o
+}
+
+// AppendFloat32 appends a float32 to the slice
+func AppendFloat32(b []byte, f float32) []byte {
+ o, n := ensure(b, Float32Size)
+ prefixu32(o[n:], mfloat32, math.Float32bits(f))
+ return o
+}
+
+// AppendInt64 appends an int64 to the slice
+func AppendInt64(b []byte, i int64) []byte {
+ a := abs(i)
+ switch {
+ case i < 0 && i > -32:
+ return append(b, wnfixint(int8(i)))
+
+ case i >= 0 && i < 128:
+ return append(b, wfixint(uint8(i)))
+
+ case a < math.MaxInt8:
+ o, n := ensure(b, 2)
+ putMint8(o[n:], int8(i))
+ return o
+
+ case a < math.MaxInt16:
+ o, n := ensure(b, 3)
+ putMint16(o[n:], int16(i))
+ return o
+
+ case a < math.MaxInt32:
+ o, n := ensure(b, 5)
+ putMint32(o[n:], int32(i))
+ return o
+
+ default:
+ o, n := ensure(b, 9)
+ putMint64(o[n:], i)
+ return o
+ }
+}
+
+// AppendInt appends an int to the slice
+func AppendInt(b []byte, i int) []byte { return AppendInt64(b, int64(i)) }
+
+// AppendInt8 appends an int8 to the slice
+func AppendInt8(b []byte, i int8) []byte { return AppendInt64(b, int64(i)) }
+
+// AppendInt16 appends an int16 to the slice
+func AppendInt16(b []byte, i int16) []byte { return AppendInt64(b, int64(i)) }
+
+// AppendInt32 appends an int32 to the slice
+func AppendInt32(b []byte, i int32) []byte { return AppendInt64(b, int64(i)) }
+
+// AppendUint64 appends a uint64 to the slice
+func AppendUint64(b []byte, u uint64) []byte {
+ switch {
+ case u < (1 << 7):
+ return append(b, wfixint(uint8(u)))
+
+ case u < math.MaxUint8:
+ o, n := ensure(b, 2)
+ putMuint8(o[n:], uint8(u))
+ return o
+
+ case u < math.MaxUint16:
+ o, n := ensure(b, 3)
+ putMuint16(o[n:], uint16(u))
+ return o
+
+ case u < math.MaxUint32:
+ o, n := ensure(b, 5)
+ putMuint32(o[n:], uint32(u))
+ return o
+
+ default:
+ o, n := ensure(b, 9)
+ putMuint64(o[n:], u)
+ return o
+
+ }
+}
+
+// AppendUint appends a uint to the slice
+func AppendUint(b []byte, u uint) []byte { return AppendUint64(b, uint64(u)) }
+
+// AppendUint8 appends a uint8 to the slice
+func AppendUint8(b []byte, u uint8) []byte { return AppendUint64(b, uint64(u)) }
+
+// AppendByte is analagous to AppendUint8
+func AppendByte(b []byte, u byte) []byte { return AppendUint8(b, uint8(u)) }
+
+// AppendUint16 appends a uint16 to the slice
+func AppendUint16(b []byte, u uint16) []byte { return AppendUint64(b, uint64(u)) }
+
+// AppendUint32 appends a uint32 to the slice
+func AppendUint32(b []byte, u uint32) []byte { return AppendUint64(b, uint64(u)) }
+
+// AppendBytes appends bytes to the slice as MessagePack 'bin' data
+func AppendBytes(b []byte, bts []byte) []byte {
+ sz := len(bts)
+ var o []byte
+ var n int
+ switch {
+ case sz < math.MaxUint8:
+ o, n = ensure(b, 2+sz)
+ prefixu8(o[n:], mbin8, uint8(sz))
+ n += 2
+ case sz < math.MaxUint16:
+ o, n = ensure(b, 3+sz)
+ prefixu16(o[n:], mbin16, uint16(sz))
+ n += 3
+ default:
+ o, n = ensure(b, 5+sz)
+ prefixu32(o[n:], mbin32, uint32(sz))
+ n += 5
+ }
+ return o[:n+copy(o[n:], bts)]
+}
+
+// AppendBool appends a bool to the slice
+func AppendBool(b []byte, t bool) []byte {
+ if t {
+ return append(b, mtrue)
+ }
+ return append(b, mfalse)
+}
+
+// AppendString appends a string as a MessagePack 'str' to the slice
+func AppendString(b []byte, s string) []byte {
+ sz := len(s)
+ var n int
+ var o []byte
+ switch {
+ case sz < 32:
+ o, n = ensure(b, 1+sz)
+ o[n] = wfixstr(uint8(sz))
+ n++
+ case sz < math.MaxUint8:
+ o, n = ensure(b, 2+sz)
+ prefixu8(o[n:], mstr8, uint8(sz))
+ n += 2
+ case sz < math.MaxUint16:
+ o, n = ensure(b, 3+sz)
+ prefixu16(o[n:], mstr16, uint16(sz))
+ n += 3
+ default:
+ o, n = ensure(b, 5+sz)
+ prefixu32(o[n:], mstr32, uint32(sz))
+ n += 5
+ }
+ return o[:n+copy(o[n:], s)]
+}
+
+// AppendComplex64 appends a complex64 to the slice as a MessagePack extension
+func AppendComplex64(b []byte, c complex64) []byte {
+ o, n := ensure(b, Complex64Size)
+ o[n] = mfixext8
+ o[n+1] = Complex64Extension
+ big.PutUint32(o[n+2:], math.Float32bits(real(c)))
+ big.PutUint32(o[n+6:], math.Float32bits(imag(c)))
+ return o
+}
+
+// AppendComplex128 appends a complex128 to the slice as a MessagePack extension
+func AppendComplex128(b []byte, c complex128) []byte {
+ o, n := ensure(b, Complex128Size)
+ o[n] = mfixext16
+ o[n+1] = Complex128Extension
+ big.PutUint64(o[n+2:], math.Float64bits(real(c)))
+ big.PutUint64(o[n+10:], math.Float64bits(imag(c)))
+ return o
+}
+
+// AppendTime appends a time.Time to the slice as a MessagePack extension
+func AppendTime(b []byte, t time.Time) []byte {
+ o, n := ensure(b, TimeSize)
+ t = t.UTC()
+ o[n] = mext8
+ o[n+1] = 12
+ o[n+2] = TimeExtension
+ putUnix(o[n+3:], t.Unix(), int32(t.Nanosecond()))
+ return o
+}
+
+// AppendMapStrStr appends a map[string]string to the slice
+// as a MessagePack map with 'str'-type keys and values
+func AppendMapStrStr(b []byte, m map[string]string) []byte {
+ sz := uint32(len(m))
+ b = AppendMapHeader(b, sz)
+ for key, val := range m {
+ b = AppendString(b, key)
+ b = AppendString(b, val)
+ }
+ return b
+}
+
+// AppendMapStrIntf appends a map[string]interface{} to the slice
+// as a MessagePack map with 'str'-type keys.
+func AppendMapStrIntf(b []byte, m map[string]interface{}) ([]byte, error) {
+ sz := uint32(len(m))
+ b = AppendMapHeader(b, sz)
+ var err error
+ for key, val := range m {
+ b = AppendString(b, key)
+ b, err = AppendIntf(b, val)
+ if err != nil {
+ return b, err
+ }
+ }
+ return b, nil
+}
+
+// AppendIntf appends the concrete type of 'i' to the
+// provided []byte. 'i' must be one of the following:
+// - 'nil'
+// - A bool, float, string, []byte, int, uint, or complex
+// - A map[string]interface{} or map[string]string
+// - A []T, where T is another supported type
+// - A *T, where T is another supported type
+// - A type that satisfieds the msgp.Marshaler interface
+// - A type that satisfies the msgp.Extension interface
+func AppendIntf(b []byte, i interface{}) ([]byte, error) {
+ if i == nil {
+ return AppendNil(b), nil
+ }
+
+ // all the concrete types
+ // for which we have methods
+ switch i := i.(type) {
+ case Marshaler:
+ return i.MarshalMsg(b)
+ case Extension:
+ return AppendExtension(b, i)
+ case bool:
+ return AppendBool(b, i), nil
+ case float32:
+ return AppendFloat32(b, i), nil
+ case float64:
+ return AppendFloat64(b, i), nil
+ case complex64:
+ return AppendComplex64(b, i), nil
+ case complex128:
+ return AppendComplex128(b, i), nil
+ case string:
+ return AppendString(b, i), nil
+ case []byte:
+ return AppendBytes(b, i), nil
+ case int8:
+ return AppendInt8(b, i), nil
+ case int16:
+ return AppendInt16(b, i), nil
+ case int32:
+ return AppendInt32(b, i), nil
+ case int64:
+ return AppendInt64(b, i), nil
+ case int:
+ return AppendInt64(b, int64(i)), nil
+ case uint:
+ return AppendUint64(b, uint64(i)), nil
+ case uint8:
+ return AppendUint8(b, i), nil
+ case uint16:
+ return AppendUint16(b, i), nil
+ case uint32:
+ return AppendUint32(b, i), nil
+ case uint64:
+ return AppendUint64(b, i), nil
+ case time.Time:
+ return AppendTime(b, i), nil
+ case map[string]interface{}:
+ return AppendMapStrIntf(b, i)
+ case map[string]string:
+ return AppendMapStrStr(b, i), nil
+ case []interface{}:
+ b = AppendArrayHeader(b, uint32(len(i)))
+ var err error
+ for _, k := range i {
+ b, err = AppendIntf(b, k)
+ if err != nil {
+ return b, err
+ }
+ }
+ return b, nil
+ }
+
+ var err error
+ v := reflect.ValueOf(i)
+ switch v.Kind() {
+ case reflect.Array, reflect.Slice:
+ l := v.Len()
+ b = AppendArrayHeader(b, uint32(l))
+ for i := 0; i < l; i++ {
+ b, err = AppendIntf(b, v.Index(i).Interface())
+ if err != nil {
+ return b, err
+ }
+ }
+ return b, nil
+
+ default:
+ return b, &ErrUnsupportedType{T: v.Type()}
+ }
+}