github.com/chrislusf/greenpack@v3.7.1-0.20170911073826-ad5bd10b7c47+incompatible/msgp/write.go (about)

     1  package msgp
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"math"
     8  	"reflect"
     9  	"sync"
    10  	"time"
    11  )
    12  
    13  // Sizer is an interface implemented
    14  // by types that can estimate their
    15  // size when MessagePack encoded.
    16  // This interface is optional, but
    17  // encoding/marshaling implementations
    18  // may use this as a way to pre-allocate
    19  // memory for serialization.
    20  type Sizer interface {
    21  	Msgsize() int
    22  }
    23  
    24  var (
    25  	// Nowhere is an io.Writer to nowhere
    26  	Nowhere io.Writer = nwhere{}
    27  
    28  	btsType    = reflect.TypeOf(([]byte)(nil))
    29  	writerPool = sync.Pool{
    30  		New: func() interface{} {
    31  			return &Writer{buf: make([]byte, 2048)}
    32  		},
    33  	}
    34  )
    35  
    36  func popWriter(w io.Writer) *Writer {
    37  	wr := writerPool.Get().(*Writer)
    38  	wr.Reset(w)
    39  	return wr
    40  }
    41  
    42  func pushWriter(wr *Writer) {
    43  	wr.w = nil
    44  	wr.wloc = 0
    45  	writerPool.Put(wr)
    46  }
    47  
    48  // freeW frees a writer for use
    49  // by other processes. It is not necessary
    50  // to call freeW on a writer. However, maintaining
    51  // a reference to a *Writer after calling freeW on
    52  // it will cause undefined behavior.
    53  func freeW(w *Writer) { pushWriter(w) }
    54  
    55  // Require ensures that cap(old)-len(old) >= extra.
    56  func Require(old []byte, extra int) []byte {
    57  	l := len(old)
    58  	c := cap(old)
    59  	r := l + extra
    60  	if c >= r {
    61  		return old
    62  	} else if l == 0 {
    63  		return make([]byte, 0, extra)
    64  	}
    65  	// the new size is the greater
    66  	// of double the old capacity
    67  	// and the sum of the old length
    68  	// and the number of new bytes
    69  	// necessary.
    70  	c <<= 1
    71  	if c < r {
    72  		c = r
    73  	}
    74  	n := make([]byte, l, c)
    75  	copy(n, old)
    76  	return n
    77  }
    78  
    79  // nowhere writer
    80  type nwhere struct{}
    81  
    82  func (n nwhere) Write(p []byte) (int, error) { return len(p), nil }
    83  
    84  // Marshaler is the interface implemented
    85  // by types that know how to marshal themselves
    86  // as MessagePack. MarshalMsg appends the marshalled
    87  // form of the object to the provided
    88  // byte slice, returning the extended
    89  // slice and any errors encountered.
    90  type Marshaler interface {
    91  	MarshalMsg([]byte) ([]byte, error)
    92  }
    93  
    94  // Encodable is the interface implemented
    95  // by types that know how to write themselves
    96  // as MessagePack using a *msgp.Writer.
    97  type Encodable interface {
    98  	EncodeMsg(*Writer) error
    99  }
   100  
   101  // Writer is a buffered writer
   102  // that can be used to write
   103  // MessagePack objects to an io.Writer.
   104  // You must call *Writer.Flush() in order
   105  // to flush all of the buffered data
   106  // to the underlying writer.
   107  type Writer struct {
   108  	w    io.Writer
   109  	buf  []byte
   110  	wloc int
   111  }
   112  
   113  // NewWriter returns a new *Writer.
   114  func NewWriter(w io.Writer) *Writer {
   115  	if wr, ok := w.(*Writer); ok {
   116  		return wr
   117  	}
   118  	return popWriter(w)
   119  }
   120  
   121  // NewWriterSize returns a writer with a custom buffer size.
   122  func NewWriterSize(w io.Writer, sz int) *Writer {
   123  	// we must be able to require() 18
   124  	// contiguous bytes, so that is the
   125  	// practical minimum buffer size
   126  	if sz < 18 {
   127  		sz = 18
   128  	}
   129  
   130  	return &Writer{
   131  		w:   w,
   132  		buf: make([]byte, sz),
   133  	}
   134  }
   135  
   136  // Encode encodes an Encodable to an io.Writer.
   137  func Encode(w io.Writer, e Encodable) error {
   138  	wr := NewWriter(w)
   139  	err := e.EncodeMsg(wr)
   140  	if err == nil {
   141  		err = wr.Flush()
   142  	}
   143  	freeW(wr)
   144  	return err
   145  }
   146  
   147  func (mw *Writer) flush() error {
   148  	if mw.wloc == 0 {
   149  		return nil
   150  	}
   151  	n, err := mw.w.Write(mw.buf[:mw.wloc])
   152  	if err != nil {
   153  		if n > 0 {
   154  			mw.wloc = copy(mw.buf, mw.buf[n:mw.wloc])
   155  		}
   156  		return err
   157  	}
   158  	mw.wloc = 0
   159  	return nil
   160  }
   161  
   162  // Flush flushes all of the buffered
   163  // data to the underlying writer.
   164  func (mw *Writer) Flush() error { return mw.flush() }
   165  
   166  // Buffered returns the number bytes in the write buffer
   167  func (mw *Writer) Buffered() int { return len(mw.buf) - mw.wloc }
   168  
   169  func (mw *Writer) avail() int { return len(mw.buf) - mw.wloc }
   170  
   171  func (mw *Writer) bufsize() int { return len(mw.buf) }
   172  
   173  // NOTE: this should only be called with
   174  // a number that is guaranteed to be less than
   175  // len(mw.buf). typically, it is called with a constant.
   176  //
   177  // NOTE: this is a hot code path
   178  func (mw *Writer) require(n int) (int, error) {
   179  	c := len(mw.buf)
   180  	wl := mw.wloc
   181  	if c-wl < n {
   182  		if err := mw.flush(); err != nil {
   183  			return 0, err
   184  		}
   185  		wl = mw.wloc
   186  	}
   187  	mw.wloc += n
   188  	return wl, nil
   189  }
   190  
   191  func (mw *Writer) Append(b ...byte) error {
   192  	if mw.avail() < len(b) {
   193  		err := mw.flush()
   194  		if err != nil {
   195  			return err
   196  		}
   197  	}
   198  	mw.wloc += copy(mw.buf[mw.wloc:], b)
   199  	return nil
   200  }
   201  
   202  // push one byte onto the buffer
   203  //
   204  // NOTE: this is a hot code path
   205  func (mw *Writer) push(b byte) error {
   206  	if mw.wloc == len(mw.buf) {
   207  		if err := mw.flush(); err != nil {
   208  			return err
   209  		}
   210  	}
   211  	mw.buf[mw.wloc] = b
   212  	mw.wloc++
   213  	return nil
   214  }
   215  
   216  func (mw *Writer) prefix8(b byte, u uint8) error {
   217  	const need = 2
   218  	if len(mw.buf)-mw.wloc < need {
   219  		if err := mw.flush(); err != nil {
   220  			return err
   221  		}
   222  	}
   223  	prefixu8(mw.buf[mw.wloc:], b, u)
   224  	mw.wloc += need
   225  	return nil
   226  }
   227  
   228  func (mw *Writer) prefix16(b byte, u uint16) error {
   229  	const need = 3
   230  	if len(mw.buf)-mw.wloc < need {
   231  		if err := mw.flush(); err != nil {
   232  			return err
   233  		}
   234  	}
   235  	prefixu16(mw.buf[mw.wloc:], b, u)
   236  	mw.wloc += need
   237  	return nil
   238  }
   239  
   240  func (mw *Writer) prefix32(b byte, u uint32) error {
   241  	const need = 5
   242  	if len(mw.buf)-mw.wloc < need {
   243  		if err := mw.flush(); err != nil {
   244  			return err
   245  		}
   246  	}
   247  	prefixu32(mw.buf[mw.wloc:], b, u)
   248  	mw.wloc += need
   249  	return nil
   250  }
   251  
   252  func (mw *Writer) prefix64(b byte, u uint64) error {
   253  	const need = 9
   254  	if len(mw.buf)-mw.wloc < need {
   255  		if err := mw.flush(); err != nil {
   256  			return err
   257  		}
   258  	}
   259  	prefixu64(mw.buf[mw.wloc:], b, u)
   260  	mw.wloc += need
   261  	return nil
   262  }
   263  
   264  // Write implements io.Writer, and writes
   265  // data directly to the buffer.
   266  func (mw *Writer) Write(p []byte) (int, error) {
   267  	l := len(p)
   268  	if mw.avail() < l {
   269  		if err := mw.flush(); err != nil {
   270  			return 0, err
   271  		}
   272  		if l > len(mw.buf) {
   273  			return mw.w.Write(p)
   274  		}
   275  	}
   276  	mw.wloc += copy(mw.buf[mw.wloc:], p)
   277  	return l, nil
   278  }
   279  
   280  // implements io.WriteString
   281  func (mw *Writer) writeString(s string) error {
   282  	l := len(s)
   283  	if mw.avail() < l {
   284  		if err := mw.flush(); err != nil {
   285  			return err
   286  		}
   287  		if l > len(mw.buf) {
   288  			_, err := io.WriteString(mw.w, s)
   289  			return err
   290  		}
   291  	}
   292  	mw.wloc += copy(mw.buf[mw.wloc:], s)
   293  	return nil
   294  }
   295  
   296  // Reset changes the underlying writer used by the Writer
   297  func (mw *Writer) Reset(w io.Writer) {
   298  	mw.buf = mw.buf[:cap(mw.buf)]
   299  	mw.w = w
   300  	mw.wloc = 0
   301  }
   302  
   303  // WriteMapHeader writes a map header of the given
   304  // size to the writer
   305  func (mw *Writer) WriteMapHeader(sz uint32) error {
   306  	switch {
   307  	case sz <= 15:
   308  		return mw.push(wfixmap(uint8(sz)))
   309  	case sz <= math.MaxUint16:
   310  		return mw.prefix16(mmap16, uint16(sz))
   311  	default:
   312  		return mw.prefix32(mmap32, sz)
   313  	}
   314  }
   315  
   316  // WriteArrayHeader writes an array header of the
   317  // given size to the writer
   318  func (mw *Writer) WriteArrayHeader(sz uint32) error {
   319  	switch {
   320  	case sz <= 15:
   321  		return mw.push(wfixarray(uint8(sz)))
   322  	case sz <= math.MaxUint16:
   323  		return mw.prefix16(marray16, uint16(sz))
   324  	default:
   325  		return mw.prefix32(marray32, sz)
   326  	}
   327  }
   328  
   329  // WriteNil writes a nil byte to the buffer
   330  func (mw *Writer) WriteNil() error {
   331  	return mw.push(mnil)
   332  }
   333  
   334  // WriteFloat64 writes a float64 to the writer
   335  func (mw *Writer) WriteFloat64(f float64) error {
   336  	return mw.prefix64(mfloat64, math.Float64bits(f))
   337  }
   338  
   339  // WriteFloat32 writes a float32 to the writer
   340  func (mw *Writer) WriteFloat32(f float32) error {
   341  	return mw.prefix32(mfloat32, math.Float32bits(f))
   342  }
   343  
   344  // WriteInt64 writes an int64 to the writer
   345  func (mw *Writer) WriteInt64(i int64) error {
   346  	if i >= 0 {
   347  		switch {
   348  		case i <= math.MaxInt8:
   349  			return mw.push(wfixint(uint8(i)))
   350  		case i <= math.MaxInt16:
   351  			return mw.prefix16(mint16, uint16(i))
   352  		case i <= math.MaxInt32:
   353  			return mw.prefix32(mint32, uint32(i))
   354  		default:
   355  			return mw.prefix64(mint64, uint64(i))
   356  		}
   357  	}
   358  	switch {
   359  	case i >= -32:
   360  		return mw.push(wnfixint(int8(i)))
   361  	case i >= math.MinInt8:
   362  		return mw.prefix8(mint8, uint8(i))
   363  	case i >= math.MinInt16:
   364  		return mw.prefix16(mint16, uint16(i))
   365  	case i >= math.MinInt32:
   366  		return mw.prefix32(mint32, uint32(i))
   367  	default:
   368  		return mw.prefix64(mint64, uint64(i))
   369  	}
   370  }
   371  
   372  // WriteInt8 writes an int8 to the writer
   373  func (mw *Writer) WriteInt8(i int8) error { return mw.WriteInt64(int64(i)) }
   374  
   375  // WriteInt16 writes an int16 to the writer
   376  func (mw *Writer) WriteInt16(i int16) error { return mw.WriteInt64(int64(i)) }
   377  
   378  // WriteInt32 writes an int32 to the writer
   379  func (mw *Writer) WriteInt32(i int32) error { return mw.WriteInt64(int64(i)) }
   380  
   381  // WriteInt writes an int to the writer
   382  func (mw *Writer) WriteInt(i int) error { return mw.WriteInt64(int64(i)) }
   383  
   384  // WriteUint64 writes a uint64 to the writer
   385  func (mw *Writer) WriteUint64(u uint64) error {
   386  	switch {
   387  	case u <= (1<<7)-1:
   388  		return mw.push(wfixint(uint8(u)))
   389  	case u <= math.MaxUint8:
   390  		return mw.prefix8(muint8, uint8(u))
   391  	case u <= math.MaxUint16:
   392  		return mw.prefix16(muint16, uint16(u))
   393  	case u <= math.MaxUint32:
   394  		return mw.prefix32(muint32, uint32(u))
   395  	default:
   396  		return mw.prefix64(muint64, u)
   397  	}
   398  }
   399  
   400  // WriteByte is analogous to WriteUint8
   401  func (mw *Writer) WriteByte(u byte) error { return mw.WriteUint8(uint8(u)) }
   402  
   403  // WriteUint8 writes a uint8 to the writer
   404  func (mw *Writer) WriteUint8(u uint8) error { return mw.WriteUint8(u) }
   405  
   406  // WriteUint16 writes a uint16 to the writer
   407  func (mw *Writer) WriteUint16(u uint16) error { return mw.WriteUint16(u) }
   408  
   409  // WriteUint32 writes a uint32 to the writer
   410  func (mw *Writer) WriteUint32(u uint32) error { return mw.WriteUint32(u) }
   411  
   412  // WriteUint writes a uint to the writer
   413  func (mw *Writer) WriteUint(u uint) error { return mw.WriteUint64(uint64(u)) }
   414  
   415  // WriteBytes writes binary as 'bin' to the writer
   416  func (mw *Writer) WriteBytes(b []byte) error {
   417  	sz := uint32(len(b))
   418  	var err error
   419  	switch {
   420  	case sz <= math.MaxUint8:
   421  		err = mw.prefix8(mbin8, uint8(sz))
   422  	case sz <= math.MaxUint16:
   423  		err = mw.prefix16(mbin16, uint16(sz))
   424  	default:
   425  		err = mw.prefix32(mbin32, sz)
   426  	}
   427  	if err != nil {
   428  		return err
   429  	}
   430  	_, err = mw.Write(b)
   431  	return err
   432  }
   433  
   434  // WriteBytesHeader writes just the size header
   435  // of a MessagePack 'bin' object. The user is responsible
   436  // for then writing 'sz' more bytes into the stream.
   437  func (mw *Writer) WriteBytesHeader(sz uint32) error {
   438  	switch {
   439  	case sz <= math.MaxUint8:
   440  		return mw.prefix8(mbin8, uint8(sz))
   441  	case sz <= math.MaxUint16:
   442  		return mw.prefix16(mbin16, uint16(sz))
   443  	default:
   444  		return mw.prefix32(mbin32, sz)
   445  	}
   446  }
   447  
   448  // WriteBool writes a bool to the writer
   449  func (mw *Writer) WriteBool(b bool) error {
   450  	if b {
   451  		return mw.push(mtrue)
   452  	}
   453  	return mw.push(mfalse)
   454  }
   455  
   456  // WriteString writes a messagepack string to the writer.
   457  // (This is NOT an implementation of io.StringWriter)
   458  func (mw *Writer) WriteString(s string) error {
   459  	sz := uint32(len(s))
   460  	var err error
   461  	switch {
   462  	case sz <= 31:
   463  		err = mw.push(wfixstr(uint8(sz)))
   464  	case sz <= math.MaxUint8:
   465  		err = mw.prefix8(mstr8, uint8(sz))
   466  	case sz <= math.MaxUint16:
   467  		err = mw.prefix16(mstr16, uint16(sz))
   468  	default:
   469  		err = mw.prefix32(mstr32, sz)
   470  	}
   471  	if err != nil {
   472  		return err
   473  	}
   474  	return mw.writeString(s)
   475  }
   476  
   477  // WriteStringHeader writes just the string size
   478  // header of a MessagePack 'str' object. The user
   479  // is responsible for writing 'sz' more valid UTF-8
   480  // bytes to the stream.
   481  func (mw *Writer) WriteStringHeader(sz uint32) error {
   482  	switch {
   483  	case sz <= 31:
   484  		return mw.push(wfixstr(uint8(sz)))
   485  	case sz <= math.MaxUint8:
   486  		return mw.prefix8(mstr8, uint8(sz))
   487  	case sz <= math.MaxUint16:
   488  		return mw.prefix16(mstr16, uint16(sz))
   489  	default:
   490  		return mw.prefix32(mstr32, sz)
   491  	}
   492  }
   493  
   494  // WriteStringFromBytes writes a 'str' object
   495  // from a []byte.
   496  func (mw *Writer) WriteStringFromBytes(str []byte) error {
   497  	sz := uint32(len(str))
   498  	var err error
   499  	switch {
   500  	case sz <= 31:
   501  		err = mw.push(wfixstr(uint8(sz)))
   502  	case sz <= math.MaxUint8:
   503  		err = mw.prefix8(mstr8, uint8(sz))
   504  	case sz <= math.MaxUint16:
   505  		err = mw.prefix16(mstr16, uint16(sz))
   506  	default:
   507  		err = mw.prefix32(mstr32, sz)
   508  	}
   509  	if err != nil {
   510  		return err
   511  	}
   512  	_, err = mw.Write(str)
   513  	return err
   514  }
   515  
   516  // WriteComplex64 writes a complex64 to the writer
   517  func (mw *Writer) WriteComplex64(f complex64) error {
   518  	o, err := mw.require(10)
   519  	if err != nil {
   520  		return err
   521  	}
   522  	mw.buf[o] = mfixext8
   523  	mw.buf[o+1] = Complex64Extension
   524  	big.PutUint32(mw.buf[o+2:], math.Float32bits(real(f)))
   525  	big.PutUint32(mw.buf[o+6:], math.Float32bits(imag(f)))
   526  	return nil
   527  }
   528  
   529  // WriteComplex128 writes a complex128 to the writer
   530  func (mw *Writer) WriteComplex128(f complex128) error {
   531  	o, err := mw.require(18)
   532  	if err != nil {
   533  		return err
   534  	}
   535  	mw.buf[o] = mfixext16
   536  	mw.buf[o+1] = Complex128Extension
   537  	big.PutUint64(mw.buf[o+2:], math.Float64bits(real(f)))
   538  	big.PutUint64(mw.buf[o+10:], math.Float64bits(imag(f)))
   539  	return nil
   540  }
   541  
   542  // WriteMapStrStr writes a map[string]string to the writer
   543  func (mw *Writer) WriteMapStrStr(mp map[string]string) (err error) {
   544  	err = mw.WriteMapHeader(uint32(len(mp)))
   545  	if err != nil {
   546  		return
   547  	}
   548  	for key, val := range mp {
   549  		err = mw.WriteString(key)
   550  		if err != nil {
   551  			return
   552  		}
   553  		err = mw.WriteString(val)
   554  		if err != nil {
   555  			return
   556  		}
   557  	}
   558  	return nil
   559  }
   560  
   561  // WriteMapStrIntf writes a map[string]interface to the writer
   562  func (mw *Writer) WriteMapStrIntf(mp map[string]interface{}) (err error) {
   563  	err = mw.WriteMapHeader(uint32(len(mp)))
   564  	if err != nil {
   565  		return
   566  	}
   567  	for key, val := range mp {
   568  		err = mw.WriteString(key)
   569  		if err != nil {
   570  			return
   571  		}
   572  		err = mw.WriteIntf(val)
   573  		if err != nil {
   574  			return
   575  		}
   576  	}
   577  	return
   578  }
   579  
   580  // WriteTime writes a time.Time object to the wire.
   581  //
   582  // Time is encoded as Unix time, which means that
   583  // location (time zone) data is removed from the object.
   584  // The encoded object itself is 12 bytes: 8 bytes for
   585  // a big-endian 64-bit integer denoting seconds
   586  // elapsed since "zero" Unix time, followed by 4 bytes
   587  // for a big-endian 32-bit signed integer denoting
   588  // the nanosecond offset of the time. This encoding
   589  // is intended to ease portability across languages.
   590  // (Note that this is *not* the standard time.Time
   591  // binary encoding, because its implementation relies
   592  // heavily on the internal representation used by the
   593  // time package.)
   594  func (mw *Writer) WriteTime(t time.Time) error {
   595  	t = t.UTC()
   596  	o, err := mw.require(15)
   597  	if err != nil {
   598  		return err
   599  	}
   600  	mw.buf[o] = mext8
   601  	mw.buf[o+1] = 12
   602  	mw.buf[o+2] = TimeExtension
   603  	putUnix(mw.buf[o+3:], t.Unix(), int32(t.Nanosecond()))
   604  	return nil
   605  }
   606  
   607  // WriteIntf writes the concrete type of 'v'.
   608  // WriteIntf will error if 'v' is not one of the following:
   609  //  - A bool, float, string, []byte, int, uint, or complex
   610  //  - A map of supported types (with string keys)
   611  //  - An array or slice of supported types
   612  //  - A pointer to a supported type
   613  //  - A type that satisfies the msgp.Encodable interface
   614  //  - A type that satisfies the msgp.Extension interface
   615  func (mw *Writer) WriteIntf(v interface{}) error {
   616  	if v == nil {
   617  		return mw.WriteNil()
   618  	}
   619  	switch v := v.(type) {
   620  
   621  	// preferred interfaces
   622  
   623  	case Encodable:
   624  		return v.EncodeMsg(mw)
   625  	case Extension:
   626  		return mw.WriteExtension(v)
   627  
   628  	// concrete types
   629  
   630  	case bool:
   631  		return mw.WriteBool(v)
   632  	case float32:
   633  		return mw.WriteFloat32(v)
   634  	case float64:
   635  		return mw.WriteFloat64(v)
   636  	case complex64:
   637  		return mw.WriteComplex64(v)
   638  	case complex128:
   639  		return mw.WriteComplex128(v)
   640  	case uint8:
   641  		return mw.WriteUint8(v)
   642  	case uint16:
   643  		return mw.WriteUint16(v)
   644  	case uint32:
   645  		return mw.WriteUint32(v)
   646  	case uint64:
   647  		return mw.WriteUint64(v)
   648  	case uint:
   649  		return mw.WriteUint(v)
   650  	case int8:
   651  		return mw.WriteInt8(v)
   652  	case int16:
   653  		return mw.WriteInt16(v)
   654  	case int32:
   655  		return mw.WriteInt32(v)
   656  	case int64:
   657  		return mw.WriteInt64(v)
   658  	case int:
   659  		return mw.WriteInt(v)
   660  	case string:
   661  		return mw.WriteString(v)
   662  	case []byte:
   663  		return mw.WriteBytes(v)
   664  	case map[string]string:
   665  		return mw.WriteMapStrStr(v)
   666  	case map[string]interface{}:
   667  		return mw.WriteMapStrIntf(v)
   668  	case time.Time:
   669  		return mw.WriteTime(v)
   670  	}
   671  
   672  	val := reflect.ValueOf(v)
   673  	if !isSupported(val.Kind()) || !val.IsValid() {
   674  		return fmt.Errorf("msgp: type %s not supported(1)", val)
   675  	}
   676  
   677  	switch val.Kind() {
   678  	case reflect.Ptr:
   679  		if val.IsNil() {
   680  			return mw.WriteNil()
   681  		}
   682  		return mw.WriteIntf(val.Elem().Interface())
   683  	case reflect.Slice:
   684  		return mw.writeSlice(val)
   685  	case reflect.Map:
   686  		return mw.writeMap(val)
   687  	}
   688  	return &ErrUnsupportedType{val.Type()}
   689  }
   690  
   691  func (mw *Writer) writeMap(v reflect.Value) (err error) {
   692  	if v.Elem().Kind() != reflect.String {
   693  		return errors.New("msgp: map keys must be strings")
   694  	}
   695  	ks := v.MapKeys()
   696  	err = mw.WriteMapHeader(uint32(len(ks)))
   697  	if err != nil {
   698  		return
   699  	}
   700  	for _, key := range ks {
   701  		val := v.MapIndex(key)
   702  		err = mw.WriteString(key.String())
   703  		if err != nil {
   704  			return
   705  		}
   706  		err = mw.WriteIntf(val.Interface())
   707  		if err != nil {
   708  			return
   709  		}
   710  	}
   711  	return
   712  }
   713  
   714  func (mw *Writer) writeSlice(v reflect.Value) (err error) {
   715  	// is []byte
   716  	if v.Type().ConvertibleTo(btsType) {
   717  		return mw.WriteBytes(v.Bytes())
   718  	}
   719  
   720  	sz := uint32(v.Len())
   721  	err = mw.WriteArrayHeader(sz)
   722  	if err != nil {
   723  		return
   724  	}
   725  	for i := uint32(0); i < sz; i++ {
   726  		err = mw.WriteIntf(v.Index(int(i)).Interface())
   727  		if err != nil {
   728  			return
   729  		}
   730  	}
   731  	return
   732  }
   733  
   734  func (mw *Writer) writeStruct(v reflect.Value) error {
   735  	if enc, ok := v.Interface().(Encodable); ok {
   736  		return enc.EncodeMsg(mw)
   737  	}
   738  	return fmt.Errorf("msgp: unsupported type: %s", v.Type())
   739  }
   740  
   741  func (mw *Writer) writeVal(v reflect.Value) error {
   742  	if !isSupported(v.Kind()) {
   743  		return fmt.Errorf("msgp: msgp/enc: type %q not supported(2)", v.Type())
   744  	}
   745  
   746  	// shortcut for nil values
   747  	if v.IsNil() {
   748  		return mw.WriteNil()
   749  	}
   750  	switch v.Kind() {
   751  	case reflect.Bool:
   752  		return mw.WriteBool(v.Bool())
   753  
   754  	case reflect.Float32, reflect.Float64:
   755  		return mw.WriteFloat64(v.Float())
   756  
   757  	case reflect.Complex64, reflect.Complex128:
   758  		return mw.WriteComplex128(v.Complex())
   759  
   760  	case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int8:
   761  		return mw.WriteInt64(v.Int())
   762  
   763  	case reflect.Interface, reflect.Ptr:
   764  		if v.IsNil() {
   765  			mw.WriteNil()
   766  		}
   767  		return mw.writeVal(v.Elem())
   768  
   769  	case reflect.Map:
   770  		return mw.writeMap(v)
   771  
   772  	case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint8:
   773  		return mw.WriteUint64(v.Uint())
   774  
   775  	case reflect.String:
   776  		return mw.WriteString(v.String())
   777  
   778  	case reflect.Slice, reflect.Array:
   779  		return mw.writeSlice(v)
   780  
   781  	case reflect.Struct:
   782  		return mw.writeStruct(v)
   783  
   784  	}
   785  	return fmt.Errorf("msgp: msgp/enc: type %q not supported(3)", v.Type())
   786  }
   787  
   788  // is the reflect.Kind encodable?
   789  func isSupported(k reflect.Kind) bool {
   790  	switch k {
   791  	case reflect.Func, reflect.Chan, reflect.Invalid, reflect.UnsafePointer:
   792  		return false
   793  	default:
   794  		return true
   795  	}
   796  }
   797  
   798  // GuessSize guesses the size of the underlying
   799  // value of 'i'. If the underlying value is not
   800  // a simple builtin (or []byte), GuessSize defaults
   801  // to 512.
   802  func GuessSize(i interface{}) int {
   803  	if i == nil {
   804  		return NilSize
   805  	}
   806  
   807  	switch i := i.(type) {
   808  	case Sizer:
   809  		return i.Msgsize()
   810  	case Extension:
   811  		return ExtensionPrefixSize + i.Len()
   812  	case float64:
   813  		return Float64Size
   814  	case float32:
   815  		return Float32Size
   816  	case uint8, uint16, uint32, uint64, uint:
   817  		return UintSize
   818  	case int8, int16, int32, int64, int:
   819  		return IntSize
   820  	case []byte:
   821  		return BytesPrefixSize + len(i)
   822  	case string:
   823  		return StringPrefixSize + len(i)
   824  	case complex64:
   825  		return Complex64Size
   826  	case complex128:
   827  		return Complex128Size
   828  	case bool:
   829  		return BoolSize
   830  	case map[string]interface{}:
   831  		s := MapHeaderSize
   832  		for key, val := range i {
   833  			s += StringPrefixSize + len(key) + GuessSize(val)
   834  		}
   835  		return s
   836  	case map[string]string:
   837  		s := MapHeaderSize
   838  		for key, val := range i {
   839  			s += 2*StringPrefixSize + len(key) + len(val)
   840  		}
   841  		return s
   842  	default:
   843  		return 512
   844  	}
   845  }