summaryrefslogtreecommitdiff
path: root/vendor/github.com/tinylib/msgp/msgp/write.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tinylib/msgp/msgp/write.go')
-rw-r--r--vendor/github.com/tinylib/msgp/msgp/write.go886
1 files changed, 0 insertions, 886 deletions
diff --git a/vendor/github.com/tinylib/msgp/msgp/write.go b/vendor/github.com/tinylib/msgp/msgp/write.go
deleted file mode 100644
index 352350f90..000000000
--- a/vendor/github.com/tinylib/msgp/msgp/write.go
+++ /dev/null
@@ -1,886 +0,0 @@
-package msgp
-
-import (
- "encoding/binary"
- "encoding/json"
- "errors"
- "io"
- "math"
- "reflect"
- "sync"
- "time"
-)
-
-const (
- // min buffer size for the writer
- minWriterSize = 18
-)
-
-// 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 {
- l := len(old)
- c := cap(old)
- r := l + extra
- if c >= r {
- return old
- } else if l == 0 {
- return make([]byte, 0, extra)
- }
- // the new size is the greater
- // of double the old capacity
- // and the sum of the old length
- // and the number of new bytes
- // necessary.
- c <<= 1
- if c < r {
- c = r
- }
- n := make([]byte, l, c)
- 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() 'minWriterSize'
- // contiguous bytes, so that is the
- // practical minimum buffer size
- if sz < minWriterSize {
- sz = minWriterSize
- }
- buf := make([]byte, sz)
- return NewWriterBuf(w, buf)
-}
-
-// NewWriterBuf returns a writer with a provided buffer.
-// 'buf' is not used when the capacity is smaller than 18,
-// custom buffer is allocated instead.
-func NewWriterBuf(w io.Writer, buf []byte) *Writer {
- if cap(buf) < minWriterSize {
- buf = make([]byte, minWriterSize)
- }
- buf = buf[:cap(buf)]
- return &Writer{
- w: w,
- buf: buf,
- }
-}
-
-// 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
-}
-
-func (mw *Writer) Append(b ...byte) error {
- if mw.avail() < len(b) {
- err := mw.flush()
- if err != nil {
- return err
- }
- }
- mw.wloc += copy(mw.buf[mw.wloc:], b)
- return 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 <= 15:
- 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 <= 15:
- 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)
-}
-
-// WriteFloat writes a float to the writer as either float64
-// or float32 when it represents the exact same value
-func (mw *Writer) WriteFloat(f float64) error {
- f32 := float32(f)
- if float64(f32) == f {
- return mw.prefix32(mfloat32, math.Float32bits(f32))
- }
- return mw.prefix64(mfloat64, math.Float64bits(f))
-}
-
-// 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))
-}
-
-// WriteDuration writes a time.Duration to the writer
-func (mw *Writer) WriteDuration(d time.Duration) error {
- return mw.WriteInt64(int64(d))
-}
-
-// WriteInt64 writes an int64 to the writer
-func (mw *Writer) WriteInt64(i int64) error {
- if i >= 0 {
- switch {
- case i <= math.MaxInt8:
- return mw.push(wfixint(uint8(i)))
- case i <= math.MaxInt16:
- return mw.prefix16(mint16, uint16(i))
- case i <= math.MaxInt32:
- return mw.prefix32(mint32, uint32(i))
- default:
- return mw.prefix64(mint64, uint64(i))
- }
- }
- switch {
- case i >= -32:
- return mw.push(wnfixint(int8(i)))
- case i >= math.MinInt8:
- return mw.prefix8(mint8, uint8(i))
- case i >= math.MinInt16:
- return mw.prefix16(mint16, uint16(i))
- case i >= math.MinInt32:
- 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)-1:
- 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 analogous 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
-}
-
-// WriteBytesHeader writes just the size header
-// of a MessagePack 'bin' object. The user is responsible
-// for then writing 'sz' more bytes into the stream.
-func (mw *Writer) WriteBytesHeader(sz uint32) error {
- switch {
- case sz <= math.MaxUint8:
- return mw.prefix8(mbin8, uint8(sz))
- case sz <= math.MaxUint16:
- return mw.prefix16(mbin16, uint16(sz))
- default:
- return mw.prefix32(mbin32, sz)
- }
-}
-
-// 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 <= 31:
- 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)
-}
-
-// WriteStringHeader writes just the string size
-// header of a MessagePack 'str' object. The user
-// is responsible for writing 'sz' more valid UTF-8
-// bytes to the stream.
-func (mw *Writer) WriteStringHeader(sz uint32) error {
- switch {
- case sz <= 31:
- return mw.push(wfixstr(uint8(sz)))
- case sz <= math.MaxUint8:
- return mw.prefix8(mstr8, uint8(sz))
- case sz <= math.MaxUint16:
- return mw.prefix16(mstr16, uint16(sz))
- default:
- return mw.prefix32(mstr32, sz)
- }
-}
-
-// WriteStringFromBytes writes a 'str' object
-// from a []byte.
-func (mw *Writer) WriteStringFromBytes(str []byte) error {
- sz := uint32(len(str))
- var err error
- switch {
- case sz <= 31:
- 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
- }
- _, err = mw.Write(str)
- return err
-}
-
-// 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 across 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
-}
-
-// WriteTimeExt will write t using the official msgpack extension spec.
-// https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type
-func (mw *Writer) WriteTimeExt(t time.Time) error {
- // Time rounded towards zero.
- secPrec := t.Truncate(time.Second)
- remain := t.Sub(secPrec).Nanoseconds()
- asSecs := secPrec.Unix()
- switch {
- case remain == 0 && asSecs > 0 && asSecs <= math.MaxUint32:
- // 4 bytes
- o, err := mw.require(6)
- if err != nil {
- return err
- }
- mw.buf[o] = mfixext4
- mw.buf[o+1] = byte(msgTimeExtension)
- binary.BigEndian.PutUint32(mw.buf[o+2:], uint32(asSecs))
- return nil
- case asSecs < 0 || asSecs >= (1<<34):
- // 12 bytes
- o, err := mw.require(12 + 3)
- if err != nil {
- return err
- }
- mw.buf[o] = mext8
- mw.buf[o+1] = 12
- mw.buf[o+2] = byte(msgTimeExtension)
- binary.BigEndian.PutUint32(mw.buf[o+3:], uint32(remain))
- binary.BigEndian.PutUint64(mw.buf[o+3+4:], uint64(asSecs))
- default:
- // 8 bytes
- o, err := mw.require(10)
- if err != nil {
- return err
- }
- mw.buf[o] = mfixext8
- mw.buf[o+1] = byte(msgTimeExtension)
- binary.BigEndian.PutUint64(mw.buf[o+2:], uint64(asSecs)|(uint64(remain)<<34))
- }
- return nil
-}
-
-// WriteJSONNumber writes the json.Number to the stream as either integer or float.
-func (mw *Writer) WriteJSONNumber(n json.Number) error {
- if n == "" {
- // The zero value outputs the 0 integer.
- return mw.push(0)
- }
- ii, err := n.Int64()
- if err == nil {
- return mw.WriteInt64(ii)
- }
- ff, err := n.Float64()
- if err == nil {
- return mw.WriteFloat(ff)
- }
- return err
-}
-
-// 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)
- case time.Duration:
- return mw.WriteDuration(v)
- case json.Number:
- return mw.WriteJSONNumber(v)
- }
-
- val := reflect.ValueOf(v)
- if !isSupported(val.Kind()) || !val.IsValid() {
- return errors.New("msgp: type " + val.String() + " not supported")
- }
-
- 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{T: val.Type()}
-}
-
-func (mw *Writer) writeMap(v reflect.Value) (err error) {
- if v.Type().Key().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
-}
-
-// 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
- }
-}