github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/rlp/encode.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package rlp 13 14 import ( 15 "fmt" 16 "io" 17 "math/big" 18 "reflect" 19 "sync" 20 ) 21 22 var ( 23 // Common encoded values. 24 // These are useful when implementing EncodeRLP. 25 EmptyString = []byte{0x80} 26 EmptyList = []byte{0xC0} 27 ) 28 29 // Encoder is implemented by types that require custom 30 // encoding rules or want to encode private fields. 31 type Encoder interface { 32 // EncodeRLP should write the RLP encoding of its receiver to w. 33 // If the implementation is a pointer method, it may also be 34 // called for nil pointers. 35 // 36 // Implementations should generate valid RLP. The data written is 37 // not verified at the moment, but a future version might. It is 38 // recommended to write only a single value but writing multiple 39 // values or no value at all is also permitted. 40 EncodeRLP(io.Writer) error 41 } 42 43 // Encode writes the RLP encoding of val to w. Note that Encode may 44 // perform many small writes in some cases. Consider making w 45 // buffered. 46 // 47 // Encode uses the following type-dependent encoding rules: 48 // 49 // If the type implements the Encoder interface, Encode calls 50 // EncodeRLP. This is true even for nil pointers, please see the 51 // documentation for Encoder. 52 // 53 // To encode a pointer, the value being pointed to is encoded. For nil 54 // pointers, Encode will encode the zero value of the type. A nil 55 // pointer to a struct type always encodes as an empty RLP list. 56 // A nil pointer to an array encodes as an empty list (or empty string 57 // if the array has element type byte). 58 // 59 // Struct values are encoded as an RLP list of all their encoded 60 // public fields. Recursive struct types are supported. 61 // 62 // To encode slices and arrays, the elements are encoded as an RLP 63 // list of the value's elements. Note that arrays and slices with 64 // element type uint8 or byte are always encoded as an RLP string. 65 // 66 // A Go string is encoded as an RLP string. 67 // 68 // An unsigned integer value is encoded as an RLP string. Zero always 69 // encodes as an empty RLP string. Encode also supports *big.Int. 70 // 71 // An interface value encodes as the value contained in the interface. 72 // 73 // Boolean values are not supported, nor are signed integers, floating 74 // point numbers, maps, channels and functions. 75 func Encode(w io.Writer, val interface{}) error { 76 if outer, ok := w.(*encbuf); ok { 77 // Encode was called by some type's EncodeRLP. 78 // Avoid copying by writing to the outer encbuf directly. 79 return outer.encode(val) 80 } 81 eb := encbufPool.Get().(*encbuf) 82 defer encbufPool.Put(eb) 83 eb.reset() 84 if err := eb.encode(val); err != nil { 85 return err 86 } 87 return eb.toWriter(w) 88 } 89 90 // EncodeBytes returns the RLP encoding of val. 91 // Please see the documentation of Encode for the encoding rules. 92 func EncodeToBytes(val interface{}) ([]byte, error) { 93 eb := encbufPool.Get().(*encbuf) 94 defer encbufPool.Put(eb) 95 eb.reset() 96 if err := eb.encode(val); err != nil { 97 return nil, err 98 } 99 return eb.toBytes(), nil 100 } 101 102 // EncodeReader returns a reader from which the RLP encoding of val 103 // can be read. The returned size is the total size of the encoded 104 // data. 105 // 106 // Please see the documentation of Encode for the encoding rules. 107 func EncodeToReader(val interface{}) (size int, r io.Reader, err error) { 108 eb := encbufPool.Get().(*encbuf) 109 eb.reset() 110 if err := eb.encode(val); err != nil { 111 return 0, nil, err 112 } 113 return eb.size(), &encReader{buf: eb}, nil 114 } 115 116 type encbuf struct { 117 str []byte // string data, contains everything except list headers 118 lheads []*listhead // all list headers 119 lhsize int // sum of sizes of all encoded list headers 120 sizebuf []byte // 9-byte auxiliary buffer for uint encoding 121 } 122 123 type listhead struct { 124 offset int // index of this header in string data 125 size int // total size of encoded data (including list headers) 126 } 127 128 // encode writes head to the given buffer, which must be at least 129 // 9 bytes long. It returns the encoded bytes. 130 func (head *listhead) encode(buf []byte) []byte { 131 return buf[:puthead(buf, 0xC0, 0xF7, uint64(head.size))] 132 } 133 134 // headsize returns the size of a list or string header 135 // for a value of the given size. 136 func headsize(size uint64) int { 137 if size < 56 { 138 return 1 139 } 140 return 1 + intsize(size) 141 } 142 143 // puthead writes a list or string header to buf. 144 // buf must be at least 9 bytes long. 145 func puthead(buf []byte, smalltag, largetag byte, size uint64) int { 146 if size < 56 { 147 buf[0] = smalltag + byte(size) 148 return 1 149 } else { 150 sizesize := putint(buf[1:], size) 151 buf[0] = largetag + byte(sizesize) 152 return sizesize + 1 153 } 154 } 155 156 // encbufs are pooled. 157 var encbufPool = sync.Pool{ 158 New: func() interface{} { return &encbuf{sizebuf: make([]byte, 9)} }, 159 } 160 161 func (w *encbuf) reset() { 162 w.lhsize = 0 163 if w.str != nil { 164 w.str = w.str[:0] 165 } 166 if w.lheads != nil { 167 w.lheads = w.lheads[:0] 168 } 169 } 170 171 // encbuf implements io.Writer so it can be passed it into EncodeRLP. 172 func (w *encbuf) Write(b []byte) (int, error) { 173 w.str = append(w.str, b...) 174 return len(b), nil 175 } 176 177 func (w *encbuf) encode(val interface{}) error { 178 rval := reflect.ValueOf(val) 179 ti, err := cachedTypeInfo(rval.Type(), tags{}) 180 if err != nil { 181 return err 182 } 183 return ti.writer(rval, w) 184 } 185 186 func (w *encbuf) encodeStringHeader(size int) { 187 if size < 56 { 188 w.str = append(w.str, 0x80+byte(size)) 189 } else { 190 // TODO: encode to w.str directly 191 sizesize := putint(w.sizebuf[1:], uint64(size)) 192 w.sizebuf[0] = 0xB7 + byte(sizesize) 193 w.str = append(w.str, w.sizebuf[:sizesize+1]...) 194 } 195 } 196 197 func (w *encbuf) encodeString(b []byte) { 198 if len(b) == 1 && b[0] <= 0x7F { 199 // fits single byte, no string header 200 w.str = append(w.str, b[0]) 201 } else { 202 w.encodeStringHeader(len(b)) 203 w.str = append(w.str, b...) 204 } 205 } 206 207 func (w *encbuf) list() *listhead { 208 lh := &listhead{offset: len(w.str), size: w.lhsize} 209 w.lheads = append(w.lheads, lh) 210 return lh 211 } 212 213 func (w *encbuf) listEnd(lh *listhead) { 214 lh.size = w.size() - lh.offset - lh.size 215 if lh.size < 56 { 216 w.lhsize += 1 // length encoded into kind tag 217 } else { 218 w.lhsize += 1 + intsize(uint64(lh.size)) 219 } 220 } 221 222 func (w *encbuf) size() int { 223 return len(w.str) + w.lhsize 224 } 225 226 func (w *encbuf) toBytes() []byte { 227 out := make([]byte, w.size()) 228 strpos := 0 229 pos := 0 230 for _, head := range w.lheads { 231 // write string data before header 232 n := copy(out[pos:], w.str[strpos:head.offset]) 233 pos += n 234 strpos += n 235 // write the header 236 enc := head.encode(out[pos:]) 237 pos += len(enc) 238 } 239 // copy string data after the last list header 240 copy(out[pos:], w.str[strpos:]) 241 return out 242 } 243 244 func (w *encbuf) toWriter(out io.Writer) (err error) { 245 strpos := 0 246 for _, head := range w.lheads { 247 // write string data before header 248 if head.offset-strpos > 0 { 249 n, err := out.Write(w.str[strpos:head.offset]) 250 strpos += n 251 if err != nil { 252 return err 253 } 254 } 255 // write the header 256 enc := head.encode(w.sizebuf) 257 if _, err = out.Write(enc); err != nil { 258 return err 259 } 260 } 261 if strpos < len(w.str) { 262 // write string data after the last list header 263 _, err = out.Write(w.str[strpos:]) 264 } 265 return err 266 } 267 268 // encReader is the io.Reader returned by EncodeToReader. 269 // It releases its encbuf at EOF. 270 type encReader struct { 271 buf *encbuf // the buffer we're reading from. this is nil when we're at EOF. 272 lhpos int // index of list header that we're reading 273 strpos int // current position in string buffer 274 piece []byte // next piece to be read 275 } 276 277 func (r *encReader) Read(b []byte) (n int, err error) { 278 for { 279 if r.piece = r.next(); r.piece == nil { 280 // Put the encode buffer back into the pool at EOF when it 281 // is first encountered. Subsequent calls still return EOF 282 // as the error but the buffer is no longer valid. 283 if r.buf != nil { 284 encbufPool.Put(r.buf) 285 r.buf = nil 286 } 287 return n, io.EOF 288 } 289 nn := copy(b[n:], r.piece) 290 n += nn 291 if nn < len(r.piece) { 292 // piece didn't fit, see you next time. 293 r.piece = r.piece[nn:] 294 return n, nil 295 } 296 r.piece = nil 297 } 298 } 299 300 // next returns the next piece of data to be read. 301 // it returns nil at EOF. 302 func (r *encReader) next() []byte { 303 switch { 304 case r.buf == nil: 305 return nil 306 307 case r.piece != nil: 308 // There is still data available for reading. 309 return r.piece 310 311 case r.lhpos < len(r.buf.lheads): 312 // We're before the last list header. 313 head := r.buf.lheads[r.lhpos] 314 sizebefore := head.offset - r.strpos 315 if sizebefore > 0 { 316 // String data before header. 317 p := r.buf.str[r.strpos:head.offset] 318 r.strpos += sizebefore 319 return p 320 } else { 321 r.lhpos++ 322 return head.encode(r.buf.sizebuf) 323 } 324 325 case r.strpos < len(r.buf.str): 326 // String data at the end, after all list headers. 327 p := r.buf.str[r.strpos:] 328 r.strpos = len(r.buf.str) 329 return p 330 331 default: 332 return nil 333 } 334 } 335 336 var ( 337 encoderInterface = reflect.TypeOf(new(Encoder)).Elem() 338 big0 = big.NewInt(0) 339 ) 340 341 // makeWriter creates a writer function for the given type. 342 func makeWriter(typ reflect.Type, ts tags) (writer, error) { 343 kind := typ.Kind() 344 switch { 345 case typ == rawValueType: 346 return writeRawValue, nil 347 case typ.Implements(encoderInterface): 348 return writeEncoder, nil 349 case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface): 350 return writeEncoderNoPtr, nil 351 case kind == reflect.Interface: 352 return writeInterface, nil 353 case typ.AssignableTo(reflect.PtrTo(bigInt)): 354 return writeBigIntPtr, nil 355 case typ.AssignableTo(bigInt): 356 return writeBigIntNoPtr, nil 357 case isUint(kind): 358 return writeUint, nil 359 case kind == reflect.Bool: 360 return writeBool, nil 361 case kind == reflect.String: 362 return writeString, nil 363 case kind == reflect.Slice && isByte(typ.Elem()): 364 return writeBytes, nil 365 case kind == reflect.Array && isByte(typ.Elem()): 366 return writeByteArray, nil 367 case kind == reflect.Slice || kind == reflect.Array: 368 return makeSliceWriter(typ, ts) 369 case kind == reflect.Struct: 370 return makeStructWriter(typ) 371 case kind == reflect.Ptr: 372 return makePtrWriter(typ) 373 default: 374 return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) 375 } 376 } 377 378 func isByte(typ reflect.Type) bool { 379 return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface) 380 } 381 382 func writeRawValue(val reflect.Value, w *encbuf) error { 383 w.str = append(w.str, val.Bytes()...) 384 return nil 385 } 386 387 func writeUint(val reflect.Value, w *encbuf) error { 388 i := val.Uint() 389 if i == 0 { 390 w.str = append(w.str, 0x80) 391 } else if i < 128 { 392 // fits single byte 393 w.str = append(w.str, byte(i)) 394 } else { 395 // TODO: encode int to w.str directly 396 s := putint(w.sizebuf[1:], i) 397 w.sizebuf[0] = 0x80 + byte(s) 398 w.str = append(w.str, w.sizebuf[:s+1]...) 399 } 400 return nil 401 } 402 403 func writeBool(val reflect.Value, w *encbuf) error { 404 if val.Bool() { 405 w.str = append(w.str, 0x01) 406 } else { 407 w.str = append(w.str, 0x80) 408 } 409 return nil 410 } 411 412 func writeBigIntPtr(val reflect.Value, w *encbuf) error { 413 ptr := val.Interface().(*big.Int) 414 if ptr == nil { 415 w.str = append(w.str, 0x80) 416 return nil 417 } 418 return writeBigInt(ptr, w) 419 } 420 421 func writeBigIntNoPtr(val reflect.Value, w *encbuf) error { 422 i := val.Interface().(big.Int) 423 return writeBigInt(&i, w) 424 } 425 426 func writeBigInt(i *big.Int, w *encbuf) error { 427 if cmp := i.Cmp(big0); cmp == -1 { 428 return fmt.Errorf("rlp: cannot encode negative *big.Int") 429 } else if cmp == 0 { 430 w.str = append(w.str, 0x80) 431 } else { 432 w.encodeString(i.Bytes()) 433 } 434 return nil 435 } 436 437 func writeBytes(val reflect.Value, w *encbuf) error { 438 w.encodeString(val.Bytes()) 439 return nil 440 } 441 442 func writeByteArray(val reflect.Value, w *encbuf) error { 443 if !val.CanAddr() { 444 // Slice requires the value to be addressable. 445 // Make it addressable by copying. 446 copy := reflect.New(val.Type()).Elem() 447 copy.Set(val) 448 val = copy 449 } 450 size := val.Len() 451 slice := val.Slice(0, size).Bytes() 452 w.encodeString(slice) 453 return nil 454 } 455 456 func writeString(val reflect.Value, w *encbuf) error { 457 s := val.String() 458 if len(s) == 1 && s[0] <= 0x7f { 459 // fits single byte, no string header 460 w.str = append(w.str, s[0]) 461 } else { 462 w.encodeStringHeader(len(s)) 463 w.str = append(w.str, s...) 464 } 465 return nil 466 } 467 468 func writeEncoder(val reflect.Value, w *encbuf) error { 469 return val.Interface().(Encoder).EncodeRLP(w) 470 } 471 472 // writeEncoderNoPtr handles non-pointer values that implement Encoder 473 // with a pointer receiver. 474 func writeEncoderNoPtr(val reflect.Value, w *encbuf) error { 475 if !val.CanAddr() { 476 // We can't get the address. It would be possible to make the 477 // value addressable by creating a shallow copy, but this 478 // creates other problems so we're not doing it (yet). 479 // 480 // package json simply doesn't call MarshalJSON for cases like 481 // this, but encodes the value as if it didn't implement the 482 // interface. We don't want to handle it that way. 483 return fmt.Errorf("rlp: game over: unadressable value of type %v, EncodeRLP is pointer method", val.Type()) 484 } 485 return val.Addr().Interface().(Encoder).EncodeRLP(w) 486 } 487 488 func writeInterface(val reflect.Value, w *encbuf) error { 489 if val.IsNil() { 490 // Write empty list. This is consistent with the previous RLP 491 // encoder that we had and should therefore avoid any 492 // problems. 493 w.str = append(w.str, 0xC0) 494 return nil 495 } 496 eval := val.Elem() 497 ti, err := cachedTypeInfo(eval.Type(), tags{}) 498 if err != nil { 499 return err 500 } 501 return ti.writer(eval, w) 502 } 503 504 func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) { 505 etypeinfo, err := cachedTypeInfo1(typ.Elem(), tags{}) 506 if err != nil { 507 return nil, err 508 } 509 writer := func(val reflect.Value, w *encbuf) error { 510 if !ts.tail { 511 defer w.listEnd(w.list()) 512 } 513 vlen := val.Len() 514 for i := 0; i < vlen; i++ { 515 if err := etypeinfo.writer(val.Index(i), w); err != nil { 516 return err 517 } 518 } 519 return nil 520 } 521 return writer, nil 522 } 523 524 func makeStructWriter(typ reflect.Type) (writer, error) { 525 fields, err := structFields(typ) 526 if err != nil { 527 return nil, err 528 } 529 writer := func(val reflect.Value, w *encbuf) error { 530 lh := w.list() 531 for _, f := range fields { 532 if err := f.info.writer(val.Field(f.index), w); err != nil { 533 return err 534 } 535 } 536 w.listEnd(lh) 537 return nil 538 } 539 return writer, nil 540 } 541 542 func makePtrWriter(typ reflect.Type) (writer, error) { 543 etypeinfo, err := cachedTypeInfo1(typ.Elem(), tags{}) 544 if err != nil { 545 return nil, err 546 } 547 548 // determine nil pointer handler 549 var nilfunc func(*encbuf) error 550 kind := typ.Elem().Kind() 551 switch { 552 case kind == reflect.Array && isByte(typ.Elem().Elem()): 553 nilfunc = func(w *encbuf) error { 554 w.str = append(w.str, 0x80) 555 return nil 556 } 557 case kind == reflect.Struct || kind == reflect.Array: 558 nilfunc = func(w *encbuf) error { 559 // encoding the zero value of a struct/array could trigger 560 // infinite recursion, avoid that. 561 w.listEnd(w.list()) 562 return nil 563 } 564 default: 565 zero := reflect.Zero(typ.Elem()) 566 nilfunc = func(w *encbuf) error { 567 return etypeinfo.writer(zero, w) 568 } 569 } 570 571 writer := func(val reflect.Value, w *encbuf) error { 572 if val.IsNil() { 573 return nilfunc(w) 574 } else { 575 return etypeinfo.writer(val.Elem(), w) 576 } 577 } 578 return writer, err 579 } 580 581 // putint writes i to the beginning of b in big endian byte 582 // order, using the least number of bytes needed to represent i. 583 func putint(b []byte, i uint64) (size int) { 584 switch { 585 case i < (1 << 8): 586 b[0] = byte(i) 587 return 1 588 case i < (1 << 16): 589 b[0] = byte(i >> 8) 590 b[1] = byte(i) 591 return 2 592 case i < (1 << 24): 593 b[0] = byte(i >> 16) 594 b[1] = byte(i >> 8) 595 b[2] = byte(i) 596 return 3 597 case i < (1 << 32): 598 b[0] = byte(i >> 24) 599 b[1] = byte(i >> 16) 600 b[2] = byte(i >> 8) 601 b[3] = byte(i) 602 return 4 603 case i < (1 << 40): 604 b[0] = byte(i >> 32) 605 b[1] = byte(i >> 24) 606 b[2] = byte(i >> 16) 607 b[3] = byte(i >> 8) 608 b[4] = byte(i) 609 return 5 610 case i < (1 << 48): 611 b[0] = byte(i >> 40) 612 b[1] = byte(i >> 32) 613 b[2] = byte(i >> 24) 614 b[3] = byte(i >> 16) 615 b[4] = byte(i >> 8) 616 b[5] = byte(i) 617 return 6 618 case i < (1 << 56): 619 b[0] = byte(i >> 48) 620 b[1] = byte(i >> 40) 621 b[2] = byte(i >> 32) 622 b[3] = byte(i >> 24) 623 b[4] = byte(i >> 16) 624 b[5] = byte(i >> 8) 625 b[6] = byte(i) 626 return 7 627 default: 628 b[0] = byte(i >> 56) 629 b[1] = byte(i >> 48) 630 b[2] = byte(i >> 40) 631 b[3] = byte(i >> 32) 632 b[4] = byte(i >> 24) 633 b[5] = byte(i >> 16) 634 b[6] = byte(i >> 8) 635 b[7] = byte(i) 636 return 8 637 } 638 } 639 640 // intsize computes the minimum number of bytes required to store i. 641 func intsize(i uint64) (size int) { 642 for size = 1; ; size++ { 643 if i >>= 8; i == 0 { 644 return size 645 } 646 } 647 }