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