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 }