github.com/gochain-io/gochain@v2.2.26+incompatible/rlp/encode.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package rlp 18 19 import ( 20 "fmt" 21 "io" 22 "math/big" 23 "reflect" 24 "sync" 25 ) 26 27 var ( 28 // Common encoded values. 29 // These are useful when implementing EncodeRLP. 30 EmptyString = []byte{0x80} 31 EmptyList = []byte{0xC0} 32 ) 33 34 const ( 35 // MaxHeadSize is the maximum size for a header, in bytes. 36 MaxHeadSize = 9 37 38 // MaxBigIntSize is the maximum size for a BigInt, in bytes. 39 // This is used so we don't have to fully compute big.Int.Bytes(). 40 // 41 // We determine this value by using total currency in circulation plus 42 // additional padding. This can hold 10^77. 43 MaxBigIntSize = 32 44 ) 45 46 // Encoder is implemented by types that require custom 47 // encoding rules or want to encode private fields. 48 type Encoder interface { 49 // EncodeRLP should write the RLP encoding of its receiver to w. 50 // If the implementation is a pointer method, it may also be 51 // called for nil pointers. 52 // 53 // Implementations should generate valid RLP. The data written is 54 // not verified at the moment, but a future version might. It is 55 // recommended to write only a single value but writing multiple 56 // values or no value at all is also permitted. 57 EncodeRLP(io.Writer) error 58 } 59 60 // SliceEncoder is implemented by types that require custom encoding rules for 61 // their elements. 62 type SliceEncoder interface { 63 EncodeRLPElem(int, io.Writer) error 64 } 65 66 // Encode writes the RLP encoding of val to w. Note that Encode may 67 // perform many small writes in some cases. Consider making w 68 // buffered. 69 // 70 // Encode uses the following type-dependent encoding rules: 71 // 72 // If the type implements the Encoder interface, Encode calls 73 // EncodeRLP. This is true even for nil pointers, please see the 74 // documentation for Encoder. 75 // 76 // To encode a pointer, the value being pointed to is encoded. For nil 77 // pointers, Encode will encode the zero value of the type. A nil 78 // pointer to a struct type always encodes as an empty RLP list. 79 // A nil pointer to an array encodes as an empty list (or empty string 80 // if the array has element type byte). 81 // 82 // Struct values are encoded as an RLP list of all their encoded 83 // public fields. Recursive struct types are supported. 84 // 85 // To encode slices and arrays, the elements are encoded as an RLP 86 // list of the value's elements. Note that arrays and slices with 87 // element type uint8 or byte are always encoded as an RLP string. 88 // 89 // A Go string is encoded as an RLP string. 90 // 91 // An unsigned integer value is encoded as an RLP string. Zero always 92 // encodes as an empty RLP string. Encode also supports *big.Int. 93 // 94 // An interface value encodes as the value contained in the interface. 95 // 96 // Boolean values are not supported, nor are signed integers, floating 97 // point numbers, maps, channels and functions. 98 func Encode(w io.Writer, val interface{}) error { 99 if outer, ok := w.(*encbuf); ok { 100 // Encode was called by some type's EncodeRLP. 101 // Avoid copying by writing to the outer encbuf directly. 102 return outer.encode(val) 103 } 104 eb := encbufPool.Get().(*encbuf) 105 defer encbufPool.Put(eb) 106 eb.reset() 107 if err := eb.encode(val); err != nil { 108 return err 109 } 110 return eb.toWriter(w) 111 } 112 113 // EncodeBytes returns the RLP encoding of val. 114 // Please see the documentation of Encode for the encoding rules. 115 func EncodeToBytes(val interface{}) ([]byte, error) { 116 eb := encbufPool.Get().(*encbuf) 117 defer encbufPool.Put(eb) 118 eb.reset() 119 if err := eb.encode(val); err != nil { 120 return nil, err 121 } 122 return eb.toBytes(), nil 123 } 124 125 // EncodeReader returns a reader from which the RLP encoding of val 126 // can be read. The returned size is the total size of the encoded 127 // data. 128 // 129 // Please see the documentation of Encode for the encoding rules. 130 func EncodeToReader(val interface{}) (size int, r io.Reader, err error) { 131 eb := encbufPool.Get().(*encbuf) 132 eb.reset() 133 if err := eb.encode(val); err != nil { 134 return 0, nil, err 135 } 136 return eb.size(), &encReader{buf: eb}, nil 137 } 138 139 type encbuf struct { 140 str []byte // string data, contains everything except list headers 141 lheads []*listhead // all list headers 142 lhsize int // sum of sizes of all encoded list headers 143 sizebuf []byte // 9-byte auxiliary buffer for uint encoding 144 } 145 146 type listhead struct { 147 offset int // index of this header in string data 148 size int // total size of encoded data (including list headers) 149 } 150 151 // encode writes head to the given buffer, which must be at least 152 // 9 bytes long. It returns the encoded bytes. 153 func (head *listhead) encode(buf []byte) []byte { 154 return buf[:puthead(buf, 0xC0, 0xF7, uint64(head.size))] 155 } 156 157 // headsize returns the size of a list or string header 158 // for a value of the given size. 159 func headsize(size uint64) int { 160 if size < 56 { 161 return 1 162 } 163 return 1 + intsize(size) 164 } 165 166 // puthead writes a list or string header to buf. 167 // buf must be at least 9 bytes long. 168 func puthead(buf []byte, smalltag, largetag byte, size uint64) int { 169 if size < 56 { 170 buf[0] = smalltag + byte(size) 171 return 1 172 } else { 173 sizesize := putint(buf[1:], size) 174 buf[0] = largetag + byte(sizesize) 175 return sizesize + 1 176 } 177 } 178 179 // encbufs are pooled. 180 var encbufPool = sync.Pool{ 181 New: func() interface{} { return &encbuf{sizebuf: make([]byte, 9)} }, 182 } 183 184 func (w *encbuf) reset() { 185 w.lhsize = 0 186 if w.str != nil { 187 w.str = w.str[:0] 188 } 189 if w.lheads != nil { 190 w.lheads = w.lheads[:0] 191 } 192 } 193 194 // encbuf implements io.Writer so it can be passed it into EncodeRLP. 195 func (w *encbuf) Write(b []byte) (int, error) { 196 w.str = append(w.str, b...) 197 return len(b), nil 198 } 199 200 func (w *encbuf) encode(val interface{}) error { 201 rval := reflect.ValueOf(val) 202 t := rval.Type() 203 ti, err := cachedTypeInfo(t, tags{}) 204 if err != nil { 205 return err 206 } 207 return ti.writer(rval, w) 208 } 209 210 func (w *encbuf) encodeStringHeader(size int) { 211 if size < 56 { 212 w.str = append(w.str, 0x80+byte(size)) 213 } else { 214 // TODO: encode to w.str directly 215 sizesize := putint(w.sizebuf[1:], uint64(size)) 216 w.sizebuf[0] = 0xB7 + byte(sizesize) 217 w.str = append(w.str, w.sizebuf[:sizesize+1]...) 218 } 219 } 220 221 func (w *encbuf) encodeString(b []byte) { 222 if len(b) == 1 && b[0] <= 0x7F { 223 // fits single byte, no string header 224 w.str = append(w.str, b[0]) 225 } else { 226 w.encodeStringHeader(len(b)) 227 w.str = append(w.str, b...) 228 } 229 } 230 231 func (w *encbuf) list() *listhead { 232 lh := &listhead{offset: len(w.str), size: w.lhsize} 233 w.lheads = append(w.lheads, lh) 234 return lh 235 } 236 237 func (w *encbuf) listEnd(lh *listhead) { 238 lh.size = w.size() - lh.offset - lh.size 239 if lh.size < 56 { 240 w.lhsize += 1 // length encoded into kind tag 241 } else { 242 w.lhsize += 1 + intsize(uint64(lh.size)) 243 } 244 } 245 246 func (w *encbuf) size() int { 247 return len(w.str) + w.lhsize 248 } 249 250 func (w *encbuf) toBytes() []byte { 251 out := make([]byte, w.size()) 252 strpos := 0 253 pos := 0 254 for _, head := range w.lheads { 255 // write string data before header 256 n := copy(out[pos:], w.str[strpos:head.offset]) 257 pos += n 258 strpos += n 259 // write the header 260 enc := head.encode(out[pos:]) 261 pos += len(enc) 262 } 263 // copy string data after the last list header 264 copy(out[pos:], w.str[strpos:]) 265 return out 266 } 267 268 func (w *encbuf) toWriter(out io.Writer) (err error) { 269 strpos := 0 270 for _, head := range w.lheads { 271 // write string data before header 272 if head.offset-strpos > 0 { 273 n, err := out.Write(w.str[strpos:head.offset]) 274 strpos += n 275 if err != nil { 276 return err 277 } 278 } 279 // write the header 280 enc := head.encode(w.sizebuf) 281 if _, err = out.Write(enc); err != nil { 282 return err 283 } 284 } 285 if strpos < len(w.str) { 286 // write string data after the last list header 287 _, err = out.Write(w.str[strpos:]) 288 } 289 return err 290 } 291 292 // encReader is the io.Reader returned by EncodeToReader. 293 // It releases its encbuf at EOF. 294 type encReader struct { 295 buf *encbuf // the buffer we're reading from. this is nil when we're at EOF. 296 lhpos int // index of list header that we're reading 297 strpos int // current position in string buffer 298 piece []byte // next piece to be read 299 } 300 301 func (r *encReader) Read(b []byte) (n int, err error) { 302 for { 303 if r.piece = r.next(); r.piece == nil { 304 // Put the encode buffer back into the pool at EOF when it 305 // is first encountered. Subsequent calls still return EOF 306 // as the error but the buffer is no longer valid. 307 if r.buf != nil { 308 encbufPool.Put(r.buf) 309 r.buf = nil 310 } 311 return n, io.EOF 312 } 313 nn := copy(b[n:], r.piece) 314 n += nn 315 if nn < len(r.piece) { 316 // piece didn't fit, see you next time. 317 r.piece = r.piece[nn:] 318 return n, nil 319 } 320 r.piece = nil 321 } 322 } 323 324 // next returns the next piece of data to be read. 325 // it returns nil at EOF. 326 func (r *encReader) next() []byte { 327 switch { 328 case r.buf == nil: 329 return nil 330 331 case r.piece != nil: 332 // There is still data available for reading. 333 return r.piece 334 335 case r.lhpos < len(r.buf.lheads): 336 // We're before the last list header. 337 head := r.buf.lheads[r.lhpos] 338 sizebefore := head.offset - r.strpos 339 if sizebefore > 0 { 340 // String data before header. 341 p := r.buf.str[r.strpos:head.offset] 342 r.strpos += sizebefore 343 return p 344 } else { 345 r.lhpos++ 346 return head.encode(r.buf.sizebuf) 347 } 348 349 case r.strpos < len(r.buf.str): 350 // String data at the end, after all list headers. 351 p := r.buf.str[r.strpos:] 352 r.strpos = len(r.buf.str) 353 return p 354 355 default: 356 return nil 357 } 358 } 359 360 var ( 361 encoderInterface = reflect.TypeOf(new(Encoder)).Elem() 362 sliceEncoderInterface = reflect.TypeOf(new(SliceEncoder)).Elem() 363 big0 = big.NewInt(0) 364 ) 365 366 // makeWriter creates a writer function for the given type. 367 func makeWriter(typ reflect.Type, ts tags) (writer, error) { 368 kind := typ.Kind() 369 switch { 370 case typ == rawValueType: 371 return writeRawValue, nil 372 case typ.Implements(encoderInterface): 373 return writeEncoder, nil 374 case typ.Implements(sliceEncoderInterface): 375 return writeSliceEncoder(ts), nil 376 case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface): 377 return writeEncoderNoPtr, nil 378 case kind == reflect.Interface: 379 return writeInterface, nil 380 case typ.AssignableTo(reflect.PtrTo(bigInt)): 381 return writeBigIntPtr, nil 382 case typ.AssignableTo(bigInt): 383 return writeBigIntNoPtr, nil 384 case isUint(kind): 385 return writeUint, nil 386 case kind == reflect.Bool: 387 return writeBool, nil 388 case kind == reflect.String: 389 return writeString, nil 390 case kind == reflect.Slice && isByte(typ.Elem()): 391 return writeBytes, nil 392 case kind == reflect.Array && isByte(typ.Elem()): 393 return writeByteArray, nil 394 case kind == reflect.Slice || kind == reflect.Array: 395 return makeSliceWriter(typ, ts) 396 case kind == reflect.Struct: 397 return makeStructWriter(typ) 398 case kind == reflect.Ptr: 399 return makePtrWriter(typ) 400 default: 401 return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) 402 } 403 } 404 405 func isByte(typ reflect.Type) bool { 406 return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface) 407 } 408 409 func writeRawValue(val reflect.Value, w *encbuf) error { 410 w.str = append(w.str, val.Bytes()...) 411 return nil 412 } 413 414 func WriteRawValueTo(w io.Writer, v RawValue) (n int64, err error) { 415 nn, err := w.Write(v) 416 return int64(nn), err 417 } 418 419 func RawValueSize(v RawValue) int { 420 return len(v) 421 } 422 423 func writeUint(val reflect.Value, w *encbuf) error { 424 i := val.Uint() 425 if i == 0 { 426 w.str = append(w.str, 0x80) 427 } else if i < 128 { 428 // fits single byte 429 w.str = append(w.str, byte(i)) 430 } else { 431 // TODO: encode int to w.str directly 432 s := putint(w.sizebuf[1:], i) 433 w.sizebuf[0] = 0x80 + byte(s) 434 w.str = append(w.str, w.sizebuf[:s+1]...) 435 } 436 return nil 437 } 438 439 func WriteUint64To(w io.Writer, v uint64) (n int64, err error) { 440 if v == 0 { 441 nn, err := w.Write([]byte{0x80}) 442 return int64(nn), err 443 } else if v < 128 { 444 // fits single byte 445 nn, err := w.Write([]byte{byte(v)}) 446 return int64(nn), err 447 } 448 449 // Encode value to bytes. 450 buf := make([]byte, 9) 451 sz := putint(buf[1:], v) 452 buf[0] = 0x80 + byte(sz) 453 454 nn, err := w.Write(buf[:sz+1]) 455 return int64(nn), err 456 } 457 458 func AppendUint64(b []byte, v uint64) []byte { 459 if v == 0 { 460 buf := b[len(b):][:1] 461 buf[0] = 0x80 462 return b[:len(b)+1] 463 } else if v < 128 { 464 buf := b[len(b):][:1] 465 buf[0] = byte(v) 466 return b[:len(b)+1] 467 } 468 return AppendHead(b, 0x80, v) 469 } 470 471 func Uint64Size(v uint64) int { 472 if v < 128 { 473 return 1 474 } 475 return intsize(v) + 1 476 } 477 478 func writeBool(val reflect.Value, w *encbuf) error { 479 if val.Bool() { 480 w.str = append(w.str, 0x01) 481 } else { 482 w.str = append(w.str, 0x80) 483 } 484 return nil 485 } 486 487 func WriteBoolTo(w io.Writer, v bool) (n int64, err error) { 488 if v { 489 nn, err := w.Write([]byte{0x01}) 490 return int64(nn), err 491 } 492 nn, err := w.Write([]byte{0x80}) 493 return int64(nn), err 494 } 495 496 func AppendBool(b []byte, v bool) []byte { 497 buf := b[len(b):][:1] 498 if v { 499 buf[0] = 0x01 500 } else { 501 buf[0] = 0x80 502 } 503 return b[:len(b)+1] 504 } 505 506 func BoolSize(v uint64) int { 507 return 1 508 } 509 510 func writeBigIntPtr(val reflect.Value, w *encbuf) error { 511 ptr := val.Interface().(*big.Int) 512 if ptr == nil { 513 w.str = append(w.str, 0x80) 514 return nil 515 } 516 return writeBigInt(ptr, w) 517 } 518 519 func writeBigIntNoPtr(val reflect.Value, w *encbuf) error { 520 i := val.Interface().(big.Int) 521 return writeBigInt(&i, w) 522 } 523 524 func writeBigInt(i *big.Int, w *encbuf) error { 525 if cmp := i.Cmp(big0); cmp == -1 { 526 return fmt.Errorf("rlp: cannot encode negative *big.Int") 527 } else if cmp == 0 { 528 w.str = append(w.str, 0x80) 529 } else { 530 w.encodeString(i.Bytes()) 531 } 532 return nil 533 } 534 535 func WriteBigIntTo(w io.Writer, v *big.Int) (n int64, err error) { 536 if v == nil { 537 nn, err := w.Write([]byte{0x80}) 538 return int64(nn), err 539 } else if cmp := v.Cmp(big0); cmp == 0 { 540 nn, err := w.Write([]byte{0x80}) 541 return int64(nn), err 542 } else if cmp == -1 { 543 return 0, fmt.Errorf("rlp: cannot write negative *big.Int") 544 } 545 return WriteBytesTo(w, v.Bytes()) 546 } 547 548 func AppendBigInt(b []byte, v *big.Int) ([]byte, error) { 549 if v == nil { 550 buf := b[len(b):][:1] 551 buf[0] = 0x80 552 return b[:len(b)+1], nil 553 } else if cmp := v.Cmp(big0); cmp == 0 { 554 buf := b[len(b):][:1] 555 buf[0] = 0x80 556 return b[:len(b)+1], nil 557 } else if cmp == -1 { 558 return nil, fmt.Errorf("rlp: cannot append negative *big.Int") 559 } 560 return AppendBytes(b, v.Bytes()), nil 561 } 562 563 func BigIntSize(v *big.Int) int { 564 if v == nil { 565 return 1 566 } else if cmp := v.Cmp(big0); cmp == 0 { 567 return 1 568 } else if cmp == -1 { 569 return 0 570 } 571 return BytesSize(v.Bytes()) 572 } 573 574 func writeBytes(val reflect.Value, w *encbuf) error { 575 w.encodeString(val.Bytes()) 576 return nil 577 } 578 579 func writeByteArray(val reflect.Value, w *encbuf) error { 580 if !val.CanAddr() { 581 // Slice requires the value to be addressable. 582 // Make it addressable by copying. 583 copy := reflect.New(val.Type()).Elem() 584 copy.Set(val) 585 val = copy 586 } 587 size := val.Len() 588 slice := val.Slice(0, size).Bytes() 589 w.encodeString(slice) 590 return nil 591 } 592 593 func writeString(val reflect.Value, w *encbuf) error { 594 s := val.String() 595 if len(s) == 1 && s[0] <= 0x7f { 596 // fits single byte, no string header 597 w.str = append(w.str, s[0]) 598 } else { 599 w.encodeStringHeader(len(s)) 600 w.str = append(w.str, s...) 601 } 602 return nil 603 } 604 605 func WriteBytesTo(w io.Writer, v []byte) (n int64, err error) { 606 // Fits single byte, no string header 607 if len(v) == 1 && v[0] <= 0x7F { 608 nn, err := w.Write(v) 609 return int64(nn), err 610 } 611 612 // Write header. 613 if len(v) < 56 { 614 nn, err := w.Write([]byte{0x80 + byte(len(v))}) 615 if n += int64(nn); err != nil { 616 return n, err 617 } 618 } else { 619 buf := make([]byte, 9) 620 sz := putint(buf[1:], uint64(len(v))) 621 buf[0] = 0xB7 + byte(sz) 622 nn, err := w.Write(buf[:sz+1]) 623 if n += int64(nn); err != nil { 624 return n, err 625 } 626 } 627 628 nn, err := w.Write(v) 629 n += int64(nn) 630 return n, err 631 } 632 633 func AppendBytes(b, v []byte) []byte { 634 // Fits single byte, no string header 635 if len(v) == 1 && v[0] <= 0x7F { 636 buf := b[len(b):][:1] 637 buf[0] = v[0] 638 return b[:len(b)+1] 639 } 640 641 // Write small header, if possible. 642 if len(v) < 56 { 643 buf := b[len(b):][:1+len(v)] 644 buf[0] = 0x80 + byte(len(v)) 645 copy(buf[1:], v) 646 return b[:len(b)+1+len(v)] 647 } 648 649 b = AppendHead(b, 0xB7, uint64(len(v))) 650 b = b[:len(b)+len(v)] 651 copy(b[len(b)-len(v):], v) 652 return b 653 } 654 655 func BytesSize(v []byte) int { 656 if len(v) == 1 && v[0] <= 0x7F { 657 return 1 658 } else if len(v) < 56 { 659 return 1 + len(v) 660 } 661 return intsize(uint64(len(v))) + 1 + len(v) 662 } 663 664 func WriteListHeaderTo(w io.Writer, v int) (n int64, err error) { 665 if v < 56 { 666 nn, err := w.Write([]byte{0xC0 + byte(v)}) 667 return int64(nn), err 668 } 669 670 buf := make([]byte, 9) 671 sz := putint(buf[1:], uint64(v)) 672 buf[0] = 0xF7 + byte(sz) 673 nn, err := w.Write(buf[:sz+1]) 674 return int64(nn), err 675 } 676 677 // PrependListHeader writes the list header to the beginning of b. 678 // This function assumes that MaxHeadSize has been allocated at the beginning already. 679 // Returns the byte slice starting from the beginning of the header. 680 func PrependListHeader(b []byte) []byte { 681 _ = b[8] // bounds check 682 683 sz := len(b) - MaxHeadSize 684 if sz < 56 { 685 b[8] = 0xC0 + byte(sz) 686 return b[8:] 687 } 688 689 b = b[MaxHeadSize-(intsize(uint64(sz))+1):] 690 AppendHead(b[:0], 0xF7, uint64(sz)) 691 return b 692 } 693 694 func ListHeaderSize(sz int) int { 695 return headsize(uint64(sz)) 696 } 697 698 func writeEncoder(val reflect.Value, w *encbuf) error { 699 return val.Interface().(Encoder).EncodeRLP(w) 700 } 701 702 // writeEncoderNoPtr handles non-pointer values that implement Encoder 703 // with a pointer receiver. 704 func writeEncoderNoPtr(val reflect.Value, w *encbuf) error { 705 if !val.CanAddr() { 706 // We can't get the address. It would be possible to make the 707 // value addressable by creating a shallow copy, but this 708 // creates other problems so we're not doing it (yet). 709 // 710 // package json simply doesn't call MarshalJSON for cases like 711 // this, but encodes the value as if it didn't implement the 712 // interface. We don't want to handle it that way. 713 return fmt.Errorf("rlp: game over: unadressable value of type %v, EncodeRLP is pointer method", val.Type()) 714 } 715 return val.Addr().Interface().(Encoder).EncodeRLP(w) 716 } 717 718 func writeInterface(val reflect.Value, w *encbuf) error { 719 if val.IsNil() { 720 // Write empty list. This is consistent with the previous RLP 721 // encoder that we had and should therefore avoid any 722 // problems. 723 w.str = append(w.str, 0xC0) 724 return nil 725 } 726 eval := val.Elem() 727 ti, err := cachedTypeInfo(eval.Type(), tags{}) 728 if err != nil { 729 return err 730 } 731 return ti.writer(eval, w) 732 } 733 734 func writeSliceEncoder(ts tags) writer { 735 return func(val reflect.Value, w *encbuf) error { 736 if !ts.tail { 737 defer w.listEnd(w.list()) 738 } 739 s := val.Interface().(SliceEncoder) 740 vlen := val.Len() 741 for i := 0; i < vlen; i++ { 742 if err := s.EncodeRLPElem(i, w); err != nil { 743 return err 744 } 745 } 746 return nil 747 } 748 } 749 750 func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) { 751 etypeinfo, err := cachedTypeInfo1(typ.Elem(), tags{}) 752 if err != nil { 753 return nil, err 754 } 755 writer := func(val reflect.Value, w *encbuf) error { 756 if !ts.tail { 757 defer w.listEnd(w.list()) 758 } 759 vlen := val.Len() 760 for i := 0; i < vlen; i++ { 761 if err := etypeinfo.writer(val.Index(i), w); err != nil { 762 return err 763 } 764 } 765 return nil 766 } 767 return writer, nil 768 } 769 770 func makeStructWriter(typ reflect.Type) (writer, error) { 771 fields, err := structFields(typ) 772 if err != nil { 773 return nil, err 774 } 775 writer := func(val reflect.Value, w *encbuf) error { 776 lh := w.list() 777 for _, f := range fields { 778 if err := f.info.writer(val.Field(f.index), w); err != nil { 779 return err 780 } 781 } 782 w.listEnd(lh) 783 return nil 784 } 785 return writer, nil 786 } 787 788 func makePtrWriter(typ reflect.Type) (writer, error) { 789 etypeinfo, err := cachedTypeInfo1(typ.Elem(), tags{}) 790 if err != nil { 791 return nil, err 792 } 793 794 // determine nil pointer handler 795 var nilfunc func(*encbuf) error 796 kind := typ.Elem().Kind() 797 switch { 798 case kind == reflect.Array && isByte(typ.Elem().Elem()): 799 nilfunc = func(w *encbuf) error { 800 w.str = append(w.str, 0x80) 801 return nil 802 } 803 case kind == reflect.Struct || kind == reflect.Array: 804 nilfunc = func(w *encbuf) error { 805 // encoding the zero value of a struct/array could trigger 806 // infinite recursion, avoid that. 807 w.listEnd(w.list()) 808 return nil 809 } 810 default: 811 zero := reflect.Zero(typ.Elem()) 812 nilfunc = func(w *encbuf) error { 813 return etypeinfo.writer(zero, w) 814 } 815 } 816 817 writer := func(val reflect.Value, w *encbuf) error { 818 if val.IsNil() { 819 return nilfunc(w) 820 } else { 821 return etypeinfo.writer(val.Elem(), w) 822 } 823 } 824 return writer, err 825 } 826 827 // putint writes i to the beginning of b in big endian byte 828 // order, using the least number of bytes needed to represent i. 829 func putint(b []byte, i uint64) (size int) { 830 switch { 831 case i < (1 << 8): 832 b[0] = byte(i) 833 return 1 834 case i < (1 << 16): 835 b[0] = byte(i >> 8) 836 b[1] = byte(i) 837 return 2 838 case i < (1 << 24): 839 b[0] = byte(i >> 16) 840 b[1] = byte(i >> 8) 841 b[2] = byte(i) 842 return 3 843 case i < (1 << 32): 844 b[0] = byte(i >> 24) 845 b[1] = byte(i >> 16) 846 b[2] = byte(i >> 8) 847 b[3] = byte(i) 848 return 4 849 case i < (1 << 40): 850 b[0] = byte(i >> 32) 851 b[1] = byte(i >> 24) 852 b[2] = byte(i >> 16) 853 b[3] = byte(i >> 8) 854 b[4] = byte(i) 855 return 5 856 case i < (1 << 48): 857 b[0] = byte(i >> 40) 858 b[1] = byte(i >> 32) 859 b[2] = byte(i >> 24) 860 b[3] = byte(i >> 16) 861 b[4] = byte(i >> 8) 862 b[5] = byte(i) 863 return 6 864 case i < (1 << 56): 865 b[0] = byte(i >> 48) 866 b[1] = byte(i >> 40) 867 b[2] = byte(i >> 32) 868 b[3] = byte(i >> 24) 869 b[4] = byte(i >> 16) 870 b[5] = byte(i >> 8) 871 b[6] = byte(i) 872 return 7 873 default: 874 b[0] = byte(i >> 56) 875 b[1] = byte(i >> 48) 876 b[2] = byte(i >> 40) 877 b[3] = byte(i >> 32) 878 b[4] = byte(i >> 24) 879 b[5] = byte(i >> 16) 880 b[6] = byte(i >> 8) 881 b[7] = byte(i) 882 return 8 883 } 884 } 885 886 func AppendHead(b []byte, prefix byte, v uint64) []byte { 887 switch { 888 case v < (1 << 8): 889 buf := b[len(b):][:2] 890 buf[0] = prefix + 1 891 buf[1] = byte(v) 892 return b[:len(b)+2] 893 case v < (1 << 16): 894 buf := b[len(b):][:3] 895 buf[0] = prefix + 2 896 buf[1] = byte(v >> 8) 897 buf[2] = byte(v) 898 return b[:len(b)+3] 899 case v < (1 << 24): 900 buf := b[len(b):][:4] 901 buf[0] = prefix + 3 902 buf[1] = byte(v >> 16) 903 buf[2] = byte(v >> 8) 904 buf[3] = byte(v) 905 return b[:len(b)+4] 906 case v < (1 << 32): 907 buf := b[len(b):][:5] 908 buf[0] = prefix + 4 909 buf[1] = byte(v >> 24) 910 buf[2] = byte(v >> 16) 911 buf[3] = byte(v >> 8) 912 buf[4] = byte(v) 913 return b[:len(b)+5] 914 case v < (1 << 40): 915 buf := b[len(b):][:6] 916 buf[0] = prefix + 5 917 buf[1] = byte(v >> 32) 918 buf[2] = byte(v >> 24) 919 buf[3] = byte(v >> 16) 920 buf[4] = byte(v >> 8) 921 buf[5] = byte(v) 922 return b[:len(b)+6] 923 case v < (1 << 48): 924 buf := b[len(b):][:7] 925 buf[0] = prefix + 6 926 buf[1] = byte(v >> 40) 927 buf[2] = byte(v >> 32) 928 buf[3] = byte(v >> 24) 929 buf[4] = byte(v >> 16) 930 buf[5] = byte(v >> 8) 931 buf[6] = byte(v) 932 return b[:len(b)+7] 933 case v < (1 << 56): 934 buf := b[len(b):][:8] 935 buf[0] = prefix + 7 936 buf[1] = byte(v >> 48) 937 buf[2] = byte(v >> 40) 938 buf[3] = byte(v >> 32) 939 buf[4] = byte(v >> 24) 940 buf[5] = byte(v >> 16) 941 buf[6] = byte(v >> 8) 942 buf[7] = byte(v) 943 return b[:len(b)+8] 944 default: 945 buf := b[len(b):][:9] 946 buf[0] = prefix + 8 947 buf[1] = byte(v >> 56) 948 buf[2] = byte(v >> 48) 949 buf[3] = byte(v >> 40) 950 buf[4] = byte(v >> 32) 951 buf[5] = byte(v >> 24) 952 buf[6] = byte(v >> 16) 953 buf[7] = byte(v >> 8) 954 buf[8] = byte(v) 955 return b[:len(b)+9] 956 } 957 } 958 959 // intsize computes the minimum number of bytes required to store i. 960 func intsize(i uint64) (size int) { 961 for size = 1; ; size++ { 962 if i >>= 8; i == 0 { 963 return size 964 } 965 } 966 }