mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Add new logging driver: fluentd
Signed-off-by: TAGOMORI Satoshi <tagomoris@gmail.com>
This commit is contained in:
		
							parent
							
								
									dd408891ba
								
							
						
					
					
						commit
						361a582ba0
					
				
					 33 changed files with 7763 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -3,6 +3,7 @@ package daemon
 | 
			
		|||
// Importing packages here only to make sure their init gets called and
 | 
			
		||||
// therefore they register themselves to the logdriver factory.
 | 
			
		||||
import (
 | 
			
		||||
	_ "github.com/docker/docker/daemon/logger/fluentd"
 | 
			
		||||
	_ "github.com/docker/docker/daemon/logger/gelf"
 | 
			
		||||
	_ "github.com/docker/docker/daemon/logger/journald"
 | 
			
		||||
	_ "github.com/docker/docker/daemon/logger/jsonfilelog"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										129
									
								
								daemon/logger/fluentd/fluentd.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								daemon/logger/fluentd/fluentd.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -884,6 +884,16 @@ container's logging driver. The following options are supported:
 | 
			
		|||
driver.  For detailed information on working with logging drivers, see
 | 
			
		||||
[Configure a logging driver](reference/logging/).
 | 
			
		||||
 | 
			
		||||
#### Logging driver: fluentd
 | 
			
		||||
 | 
			
		||||
Fluentd logging driver for Docker. Writes log messages to fluentd (forward input). `docker logs`
 | 
			
		||||
command is not available for this logging driver.
 | 
			
		||||
 | 
			
		||||
Some options are supported by specifying `--log-opt` as many as needed, like `--log-opt fluentd-address=localhost:24224`.
 | 
			
		||||
 | 
			
		||||
 - `fluentd-address`: specify `host:port` to connect [localhost:24224]
 | 
			
		||||
 - `fluentd-tag`: specify tag for fluentd message, which interpret some markup, ex `{{.ID}}`, `{{.FullID}}` or `{{.Name}}` [docker.{{.ID}}]
 | 
			
		||||
 | 
			
		||||
## Overriding Dockerfile image defaults
 | 
			
		||||
 | 
			
		||||
When a developer builds an image from a [*Dockerfile*](/reference/builder)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,4 +42,9 @@ clone git github.com/syndtr/gocapability 66ef2aa7a23ba682594e2b6f74cf40c0692b49f
 | 
			
		|||
clone git github.com/golang/protobuf 655cdfa588ea
 | 
			
		||||
clone git github.com/Graylog2/go-gelf 6c62a85f1d47a67f2a5144c0e745b325889a8120
 | 
			
		||||
 | 
			
		||||
clone git github.com/fluent/fluent-logger-golang v1.0.0
 | 
			
		||||
# fluent-logger-golang deps
 | 
			
		||||
clone git github.com/philhofer/fwd 899e4efba8eaa1fea74175308f3fae18ff3319fa
 | 
			
		||||
clone git github.com/tinylib/msgp 75ee40d2601edf122ef667e2a07d600d4c44490c
 | 
			
		||||
 | 
			
		||||
clean
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -155,7 +155,7 @@ two memory nodes.
 | 
			
		|||
**--lxc-conf**=[]
 | 
			
		||||
   (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
 | 
			
		||||
 | 
			
		||||
**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*none*"
 | 
			
		||||
**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*none*"
 | 
			
		||||
  Logging driver for container. Default is defined by daemon `--log-driver` flag.
 | 
			
		||||
  **Warning**: `docker logs` command works only for `json-file` logging driver.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -252,7 +252,7 @@ which interface and port to use.
 | 
			
		|||
**--lxc-conf**=[]
 | 
			
		||||
   (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
 | 
			
		||||
 | 
			
		||||
**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*none*"
 | 
			
		||||
**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*none*"
 | 
			
		||||
  Logging driver for container. Default is defined by daemon `--log-driver` flag.
 | 
			
		||||
  **Warning**: `docker logs` command works only for `json-file` logging driver.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,7 +103,7 @@ unix://[/path/to/socket] to use.
 | 
			
		|||
**--label**="[]"
 | 
			
		||||
  Set key=value labels to the daemon (displayed in `docker info`)
 | 
			
		||||
 | 
			
		||||
**--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*none*"
 | 
			
		||||
**--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*none*"
 | 
			
		||||
  Default driver for container logs. Default is `json-file`.
 | 
			
		||||
  **Warning**: `docker logs` command works only for `json-file` logging driver.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										245
									
								
								vendor/src/github.com/fluent/fluent-logger-golang/fluent/fluent.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								vendor/src/github.com/fluent/fluent-logger-golang/fluent/fluent.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto_gen.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										372
									
								
								vendor/src/github.com/fluent/fluent-logger-golang/fluent/proto_gen.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/fluent/fluent-logger-golang/fluent/version.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/src/github.com/fluent/fluent-logger-golang/fluent/version.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
package fluent
 | 
			
		||||
 | 
			
		||||
const Version = "0.5.1"
 | 
			
		||||
							
								
								
									
										311
									
								
								vendor/src/github.com/philhofer/fwd/README.md
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								vendor/src/github.com/philhofer/fwd/README.md
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/philhofer/fwd/reader.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										358
									
								
								vendor/src/github.com/philhofer/fwd/reader.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/philhofer/fwd/writer.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								vendor/src/github.com/philhofer/fwd/writer.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/philhofer/fwd/writer_appengine.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/src/github.com/philhofer/fwd/writer_appengine.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
// +build appengine
 | 
			
		||||
 | 
			
		||||
package fwd
 | 
			
		||||
 | 
			
		||||
func unsafestr(s string) []byte { return []byte(s) }
 | 
			
		||||
							
								
								
									
										18
									
								
								vendor/src/github.com/philhofer/fwd/writer_unsafe.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/src/github.com/philhofer/fwd/writer_unsafe.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/circular.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/src/github.com/tinylib/msgp/msgp/circular.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/defs.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								vendor/src/github.com/tinylib/msgp/msgp/defs.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/edit.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								vendor/src/github.com/tinylib/msgp/msgp/edit.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/elsize.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								vendor/src/github.com/tinylib/msgp/msgp/elsize.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/errors.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								vendor/src/github.com/tinylib/msgp/msgp/errors.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/extension.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										548
									
								
								vendor/src/github.com/tinylib/msgp/msgp/extension.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/integers.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								vendor/src/github.com/tinylib/msgp/msgp/integers.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/json.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										542
									
								
								vendor/src/github.com/tinylib/msgp/msgp/json.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/json_bytes.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										363
									
								
								vendor/src/github.com/tinylib/msgp/msgp/json_bytes.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/number.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								vendor/src/github.com/tinylib/msgp/msgp/number.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/number_appengine.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								vendor/src/github.com/tinylib/msgp/msgp/number_appengine.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/number_unsafe.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								vendor/src/github.com/tinylib/msgp/msgp/number_unsafe.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/read.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1118
									
								
								vendor/src/github.com/tinylib/msgp/msgp/read.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1073
									
								
								vendor/src/github.com/tinylib/msgp/msgp/read_bytes.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1073
									
								
								vendor/src/github.com/tinylib/msgp/msgp/read_bytes.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										38
									
								
								vendor/src/github.com/tinylib/msgp/msgp/size.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/src/github.com/tinylib/msgp/msgp/size.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/write.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										768
									
								
								vendor/src/github.com/tinylib/msgp/msgp/write.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
									
								
								vendor/src/github.com/tinylib/msgp/msgp/write_bytes.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										369
									
								
								vendor/src/github.com/tinylib/msgp/msgp/write_bytes.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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()}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue