Ver código fonte

Add new logging driver: fluentd

Signed-off-by: TAGOMORI Satoshi <tagomoris@gmail.com>
TAGOMORI Satoshi 10 anos atrás
pai
commit
361a582ba0
33 arquivos alterados com 7763 adições e 3 exclusões
  1. 1 0
      daemon/logdrivers_linux.go
  2. 129 0
      daemon/logger/fluentd/fluentd.go
  3. 10 0
      docs/reference/run.md
  4. 5 0
      hack/vendor.sh
  5. 1 1
      man/docker-create.1.md
  6. 1 1
      man/docker-run.1.md
  7. 1 1
      man/docker.1.md
  8. 245 0
      vendor/src/github.com/fluent/fluent-logger-golang/fluent/fluent.go
  9. 24 0
      vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto.go
  10. 372 0
      vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto_gen.go
  11. 3 0
      vendor/src/github.com/fluent/fluent-logger-golang/fluent/version.go
  12. 311 0
      vendor/src/github.com/philhofer/fwd/README.md
  13. 358 0
      vendor/src/github.com/philhofer/fwd/reader.go
  14. 224 0
      vendor/src/github.com/philhofer/fwd/writer.go
  15. 5 0
      vendor/src/github.com/philhofer/fwd/writer_appengine.go
  16. 18 0
      vendor/src/github.com/philhofer/fwd/writer_unsafe.go
  17. 38 0
      vendor/src/github.com/tinylib/msgp/msgp/circular.go
  18. 142 0
      vendor/src/github.com/tinylib/msgp/msgp/defs.go
  19. 241 0
      vendor/src/github.com/tinylib/msgp/msgp/edit.go
  20. 99 0
      vendor/src/github.com/tinylib/msgp/msgp/elsize.go
  21. 142 0
      vendor/src/github.com/tinylib/msgp/msgp/errors.go
  22. 548 0
      vendor/src/github.com/tinylib/msgp/msgp/extension.go
  23. 174 0
      vendor/src/github.com/tinylib/msgp/msgp/integers.go
  24. 542 0
      vendor/src/github.com/tinylib/msgp/msgp/json.go
  25. 363 0
      vendor/src/github.com/tinylib/msgp/msgp/json_bytes.go
  26. 140 0
      vendor/src/github.com/tinylib/msgp/msgp/number.go
  27. 101 0
      vendor/src/github.com/tinylib/msgp/msgp/number_appengine.go
  28. 159 0
      vendor/src/github.com/tinylib/msgp/msgp/number_unsafe.go
  29. 1118 0
      vendor/src/github.com/tinylib/msgp/msgp/read.go
  30. 1073 0
      vendor/src/github.com/tinylib/msgp/msgp/read_bytes.go
  31. 38 0
      vendor/src/github.com/tinylib/msgp/msgp/size.go
  32. 768 0
      vendor/src/github.com/tinylib/msgp/msgp/write.go
  33. 369 0
      vendor/src/github.com/tinylib/msgp/msgp/write_bytes.go

+ 1 - 0
daemon/logdrivers_linux.go

@@ -3,6 +3,7 @@ package daemon
 // Importing packages here only to make sure their init gets called and
 // Importing packages here only to make sure their init gets called and
 // therefore they register themselves to the logdriver factory.
 // therefore they register themselves to the logdriver factory.
 import (
 import (
+	_ "github.com/docker/docker/daemon/logger/fluentd"
 	_ "github.com/docker/docker/daemon/logger/gelf"
 	_ "github.com/docker/docker/daemon/logger/gelf"
 	_ "github.com/docker/docker/daemon/logger/journald"
 	_ "github.com/docker/docker/daemon/logger/journald"
 	_ "github.com/docker/docker/daemon/logger/jsonfilelog"
 	_ "github.com/docker/docker/daemon/logger/jsonfilelog"

+ 129 - 0
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
+}

+ 10 - 0
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
 driver.  For detailed information on working with logging drivers, see
 [Configure a logging driver](reference/logging/).
 [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`.
+
+ - `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
 ## Overriding Dockerfile image defaults
 
 
 When a developer builds an image from a [*Dockerfile*](/reference/builder)
 When a developer builds an image from a [*Dockerfile*](/reference/builder)

+ 5 - 0
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/golang/protobuf 655cdfa588ea
 clone git github.com/Graylog2/go-gelf 6c62a85f1d47a67f2a5144c0e745b325889a8120
 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
 clean

+ 1 - 1
man/docker-create.1.md

@@ -155,7 +155,7 @@ two memory nodes.
 **--lxc-conf**=[]
 **--lxc-conf**=[]
    (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
    (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.
   Logging driver for container. Default is defined by daemon `--log-driver` flag.
   **Warning**: `docker logs` command works only for `json-file` logging driver.
   **Warning**: `docker logs` command works only for `json-file` logging driver.
 
 

+ 1 - 1
man/docker-run.1.md

@@ -252,7 +252,7 @@ which interface and port to use.
 **--lxc-conf**=[]
 **--lxc-conf**=[]
    (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
    (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.
   Logging driver for container. Default is defined by daemon `--log-driver` flag.
   **Warning**: `docker logs` command works only for `json-file` logging driver.
   **Warning**: `docker logs` command works only for `json-file` logging driver.
 
 

+ 1 - 1
man/docker.1.md

@@ -103,7 +103,7 @@ unix://[/path/to/socket] to use.
 **--label**="[]"
 **--label**="[]"
   Set key=value labels to the daemon (displayed in `docker info`)
   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`.
   Default driver for container logs. Default is `json-file`.
   **Warning**: `docker logs` command works only for `json-file` logging driver.
   **Warning**: `docker logs` command works only for `json-file` logging driver.
 
 

+ 245 - 0
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
+}

+ 24 - 0
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"`
+}

+ 372 - 0
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
+}

+ 3 - 0
vendor/src/github.com/fluent/fluent-logger-golang/fluent/version.go

@@ -0,0 +1,3 @@
+package fluent
+
+const Version = "0.5.1"

+ 311 - 0
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 <a href="http://github.com/philhofer/msgp">http://github.com/philhofer/msgp</a>,
+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)

+ 358 - 0
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
+}

+ 224 - 0
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
+}

+ 5 - 0
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) }

+ 18 - 0
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,
+	}))
+}

+ 38 - 0
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
+}

+ 142 - 0
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
+)

+ 241 - 0
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:]...)
+	}
+}

+ 99 - 0
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
+}

+ 142 - 0
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 }

+ 548 - 0
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])
+}

+ 174 - 0
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)
+}

+ 542 - 0
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
+}

+ 363 - 0
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": <num>, "data": "<base64data>"}`
+	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
+}

+ 140 - 0
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")
+	}
+}

+ 101 - 0
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!")
+}

+ 159 - 0
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")
+	}
+}

+ 1118 - 0
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 "<invalid>"
+	}
+}
+
+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
+	}
+}

+ 1073 - 0
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
+	}
+}

+ 38 - 0
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
+)

+ 768 - 0
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
+	}
+}

+ 369 - 0
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()}
+	}
+}