write.go 19 KB

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