github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/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 // ListSize returns the encoded size of an RLP list with the given 49 // content size. 50 func ListSize(contentSize uint64) uint64 { 51 return uint64(headsize(contentSize)) + contentSize 52 } 53 54 // Encode writes the RLP encoding of val to w. Note that Encode may 55 // perform many small writes in some cases. Consider making w 56 // buffered. 57 // 58 // Encode uses the following type-dependent encoding rules: 59 // 60 // If the type implements the Encoder interface, Encode calls 61 // EncodeRLP. This is true even for nil pointers, please see the 62 // documentation for Encoder. 63 // 64 // To encode a pointer, the value being pointed to is encoded. For nil 65 // pointers, Encode will encode the zero value of the type. A nil 66 // pointer to a struct type always encodes as an empty RLP list. 67 // A nil pointer to an array encodes as an empty list (or empty string 68 // if the array has element type byte). 69 // 70 // Struct values are encoded as an RLP list of all their encoded 71 // public fields. Recursive struct types are supported. 72 // 73 // To encode slices and arrays, the elements are encoded as an RLP 74 // list of the value's elements. Note that arrays and slices with 75 // element type uint8 or byte are always encoded as an RLP string. 76 // 77 // A Go string is encoded as an RLP string. 78 // 79 // An unsigned integer value is encoded as an RLP string. Zero always 80 // encodes as an empty RLP string. Encode also supports *big.Int. 81 // 82 // An interface value encodes as the value contained in the interface. 83 // 84 // Boolean values are not supported, nor are signed integers, floating 85 // point numbers, maps, channels and functions. 86 func Encode(w io.Writer, val interface{}) error { 87 if outer, ok := w.(*encbuf); ok { 88 // Encode was called by some type's EncodeRLP. 89 // Avoid copying by writing to the outer encbuf directly. 90 return outer.encode(val) 91 } 92 eb := encbufPool.Get().(*encbuf) 93 eb.reset() 94 defer encbufPool.Put(eb) 95 if err := eb.encode(val); err != nil { 96 return err 97 } 98 return eb.toWriter(w) 99 } 100 101 // EncodeBytes returns the RLP encoding of val. 102 // Please see the documentation of Encode for the encoding rules. 103 func EncodeToBytes(val interface{}) ([]byte, error) { 104 eb := encbufPool.Get().(*encbuf) 105 eb.reset() 106 defer encbufPool.Put(eb) 107 if err := eb.encode(val); err != nil { 108 return nil, err 109 } 110 return eb.toBytes(), nil 111 } 112 113 // EncodeReader returns a reader from which the RLP encoding of val 114 // can be read. The returned size is the total size of the encoded 115 // data. 116 // 117 // Please see the documentation of Encode for the encoding rules. 118 func EncodeToReader(val interface{}) (size int, r io.Reader, err error) { 119 eb := encbufPool.Get().(*encbuf) 120 eb.reset() 121 if err := eb.encode(val); err != nil { 122 return 0, nil, err 123 } 124 return eb.size(), &encReader{buf: eb}, nil 125 } 126 127 type encbuf struct { 128 str []byte // string data, contains everything except list headers 129 lheads []*listhead // all list headers 130 lhsize int // sum of sizes of all encoded list headers 131 sizebuf []byte // 9-byte auxiliary buffer for uint encoding 132 } 133 134 type listhead struct { 135 offset int // index of this header in string data 136 size int // total size of encoded data (including list headers) 137 } 138 139 // encode writes head to the given buffer, which must be at least 140 // 9 bytes long. It returns the encoded bytes. 141 func (head *listhead) encode(buf []byte) []byte { 142 return buf[:puthead(buf, 0xC0, 0xF7, uint64(head.size))] 143 } 144 145 // headsize returns the size of a list or string header 146 // for a value of the given size. 147 func headsize(size uint64) int { 148 if size < 56 { 149 return 1 150 } 151 return 1 + intsize(size) 152 } 153 154 // puthead writes a list or string header to buf. 155 // buf must be at least 9 bytes long. 156 func puthead(buf []byte, smalltag, largetag byte, size uint64) int { 157 if size < 56 { 158 buf[0] = smalltag + byte(size) 159 return 1 160 } else { 161 sizesize := putint(buf[1:], size) 162 buf[0] = largetag + byte(sizesize) 163 return sizesize + 1 164 } 165 } 166 167 // encbufs are pooled. 168 var encbufPool = sync.Pool{ 169 New: func() interface{} { return &encbuf{sizebuf: make([]byte, 9)} }, 170 } 171 172 func (w *encbuf) reset() { 173 w.lhsize = 0 174 if w.str != nil { 175 w.str = w.str[:0] 176 } 177 if w.lheads != nil { 178 w.lheads = w.lheads[:0] 179 } 180 } 181 182 // encbuf implements io.Writer so it can be passed it into EncodeRLP. 183 func (w *encbuf) Write(b []byte) (int, error) { 184 w.str = append(w.str, b...) 185 return len(b), nil 186 } 187 188 func (w *encbuf) encode(val interface{}) error { 189 rval := reflect.ValueOf(val) 190 ti, err := cachedTypeInfo(rval.Type(), tags{}) 191 if err != nil { 192 return err 193 } 194 return ti.writer(rval, w) 195 } 196 197 func (w *encbuf) encodeStringHeader(size int) { 198 if size < 56 { 199 w.str = append(w.str, 0x80+byte(size)) 200 } else { 201 // TODO: encode to w.str directly 202 sizesize := putint(w.sizebuf[1:], uint64(size)) 203 w.sizebuf[0] = 0xB7 + byte(sizesize) 204 w.str = append(w.str, w.sizebuf[:sizesize+1]...) 205 } 206 } 207 208 func (w *encbuf) encodeString(b []byte) { 209 if len(b) == 1 && b[0] <= 0x7F { 210 // fits single byte, no string header 211 w.str = append(w.str, b[0]) 212 } else { 213 w.encodeStringHeader(len(b)) 214 w.str = append(w.str, b...) 215 } 216 } 217 218 func (w *encbuf) list() *listhead { 219 lh := &listhead{offset: len(w.str), size: w.lhsize} 220 w.lheads = append(w.lheads, lh) 221 return lh 222 } 223 224 func (w *encbuf) listEnd(lh *listhead) { 225 lh.size = w.size() - lh.offset - lh.size 226 if lh.size < 56 { 227 w.lhsize += 1 // length encoded into kind tag 228 } else { 229 w.lhsize += 1 + intsize(uint64(lh.size)) 230 } 231 } 232 233 func (w *encbuf) size() int { 234 return len(w.str) + w.lhsize 235 } 236 237 func (w *encbuf) toBytes() []byte { 238 out := make([]byte, w.size()) 239 strpos := 0 240 pos := 0 241 for _, head := range w.lheads { 242 // write string data before header 243 n := copy(out[pos:], w.str[strpos:head.offset]) 244 pos += n 245 strpos += n 246 // write the header 247 enc := head.encode(out[pos:]) 248 pos += len(enc) 249 } 250 // copy string data after the last list header 251 copy(out[pos:], w.str[strpos:]) 252 return out 253 } 254 255 func (w *encbuf) toWriter(out io.Writer) (err error) { 256 strpos := 0 257 for _, head := range w.lheads { 258 // write string data before header 259 if head.offset-strpos > 0 { 260 n, err := out.Write(w.str[strpos:head.offset]) 261 strpos += n 262 if err != nil { 263 return err 264 } 265 } 266 // write the header 267 enc := head.encode(w.sizebuf) 268 if _, err = out.Write(enc); err != nil { 269 return err 270 } 271 } 272 if strpos < len(w.str) { 273 // write string data after the last list header 274 _, err = out.Write(w.str[strpos:]) 275 } 276 return err 277 } 278 279 // encReader is the io.Reader returned by EncodeToReader. 280 // It releases its encbuf at EOF. 281 type encReader struct { 282 buf *encbuf // the buffer we're reading from. this is nil when we're at EOF. 283 lhpos int // index of list header that we're reading 284 strpos int // current position in string buffer 285 piece []byte // next piece to be read 286 } 287 288 func (r *encReader) Read(b []byte) (n int, err error) { 289 for { 290 if r.piece = r.next(); r.piece == nil { 291 encbufPool.Put(r.buf) 292 r.buf = nil 293 return n, io.EOF 294 } 295 nn := copy(b[n:], r.piece) 296 n += nn 297 if nn < len(r.piece) { 298 // piece didn't fit, see you next time. 299 r.piece = r.piece[nn:] 300 return n, nil 301 } 302 r.piece = nil 303 } 304 panic("not reached") 305 } 306 307 // next returns the next piece of data to be read. 308 // it returns nil at EOF. 309 func (r *encReader) next() []byte { 310 switch { 311 case r.buf == nil: 312 return nil 313 314 case r.piece != nil: 315 // There is still data available for reading. 316 return r.piece 317 318 case r.lhpos < len(r.buf.lheads): 319 // We're before the last list header. 320 head := r.buf.lheads[r.lhpos] 321 sizebefore := head.offset - r.strpos 322 if sizebefore > 0 { 323 // String data before header. 324 p := r.buf.str[r.strpos:head.offset] 325 r.strpos += sizebefore 326 return p 327 } else { 328 r.lhpos++ 329 return head.encode(r.buf.sizebuf) 330 } 331 332 case r.strpos < len(r.buf.str): 333 // String data at the end, after all list headers. 334 p := r.buf.str[r.strpos:] 335 r.strpos = len(r.buf.str) 336 return p 337 338 default: 339 return nil 340 } 341 } 342 343 var ( 344 encoderInterface = reflect.TypeOf(new(Encoder)).Elem() 345 big0 = big.NewInt(0) 346 ) 347 348 // makeWriter creates a writer function for the given type. 349 func makeWriter(typ reflect.Type) (writer, error) { 350 kind := typ.Kind() 351 switch { 352 case typ.Implements(encoderInterface): 353 return writeEncoder, nil 354 case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface): 355 return writeEncoderNoPtr, nil 356 case kind == reflect.Interface: 357 return writeInterface, nil 358 case typ.AssignableTo(reflect.PtrTo(bigInt)): 359 return writeBigIntPtr, nil 360 case typ.AssignableTo(bigInt): 361 return writeBigIntNoPtr, nil 362 case isUint(kind): 363 return writeUint, nil 364 case kind == reflect.Bool: 365 return writeBool, nil 366 case kind == reflect.String: 367 return writeString, nil 368 case kind == reflect.Slice && isByte(typ.Elem()): 369 return writeBytes, nil 370 case kind == reflect.Array && isByte(typ.Elem()): 371 return writeByteArray, nil 372 case kind == reflect.Slice || kind == reflect.Array: 373 return makeSliceWriter(typ) 374 case kind == reflect.Struct: 375 return makeStructWriter(typ) 376 case kind == reflect.Ptr: 377 return makePtrWriter(typ) 378 default: 379 return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) 380 } 381 } 382 383 func isByte(typ reflect.Type) bool { 384 return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface) 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 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) (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 lh := w.list() 511 vlen := val.Len() 512 for i := 0; i < vlen; i++ { 513 if err := etypeinfo.writer(val.Index(i), w); err != nil { 514 return err 515 } 516 } 517 w.listEnd(lh) 518 return nil 519 } 520 return writer, nil 521 } 522 523 func makeStructWriter(typ reflect.Type) (writer, error) { 524 fields, err := structFields(typ) 525 if err != nil { 526 return nil, err 527 } 528 writer := func(val reflect.Value, w *encbuf) error { 529 lh := w.list() 530 for _, f := range fields { 531 if err := f.info.writer(val.Field(f.index), w); err != nil { 532 return err 533 } 534 } 535 w.listEnd(lh) 536 return nil 537 } 538 return writer, nil 539 } 540 541 func makePtrWriter(typ reflect.Type) (writer, error) { 542 etypeinfo, err := cachedTypeInfo1(typ.Elem(), tags{}) 543 if err != nil { 544 return nil, err 545 } 546 547 // determine nil pointer handler 548 var nilfunc func(*encbuf) error 549 kind := typ.Elem().Kind() 550 switch { 551 case kind == reflect.Array && isByte(typ.Elem().Elem()): 552 nilfunc = func(w *encbuf) error { 553 w.str = append(w.str, 0x80) 554 return nil 555 } 556 case kind == reflect.Struct || kind == reflect.Array: 557 nilfunc = func(w *encbuf) error { 558 // encoding the zero value of a struct/array could trigger 559 // infinite recursion, avoid that. 560 w.listEnd(w.list()) 561 return nil 562 } 563 default: 564 zero := reflect.Zero(typ.Elem()) 565 nilfunc = func(w *encbuf) error { 566 return etypeinfo.writer(zero, w) 567 } 568 } 569 570 writer := func(val reflect.Value, w *encbuf) error { 571 if val.IsNil() { 572 return nilfunc(w) 573 } else { 574 return etypeinfo.writer(val.Elem(), w) 575 } 576 } 577 return writer, err 578 } 579 580 // putint writes i to the beginning of b in with big endian byte 581 // order, using the least number of bytes needed to represent i. 582 func putint(b []byte, i uint64) (size int) { 583 switch { 584 case i < (1 << 8): 585 b[0] = byte(i) 586 return 1 587 case i < (1 << 16): 588 b[0] = byte(i >> 8) 589 b[1] = byte(i) 590 return 2 591 case i < (1 << 24): 592 b[0] = byte(i >> 16) 593 b[1] = byte(i >> 8) 594 b[2] = byte(i) 595 return 3 596 case i < (1 << 32): 597 b[0] = byte(i >> 24) 598 b[1] = byte(i >> 16) 599 b[2] = byte(i >> 8) 600 b[3] = byte(i) 601 return 4 602 case i < (1 << 40): 603 b[0] = byte(i >> 32) 604 b[1] = byte(i >> 24) 605 b[2] = byte(i >> 16) 606 b[3] = byte(i >> 8) 607 b[4] = byte(i) 608 return 5 609 case i < (1 << 48): 610 b[0] = byte(i >> 40) 611 b[1] = byte(i >> 32) 612 b[2] = byte(i >> 24) 613 b[3] = byte(i >> 16) 614 b[4] = byte(i >> 8) 615 b[5] = byte(i) 616 return 6 617 case i < (1 << 56): 618 b[0] = byte(i >> 48) 619 b[1] = byte(i >> 40) 620 b[2] = byte(i >> 32) 621 b[3] = byte(i >> 24) 622 b[4] = byte(i >> 16) 623 b[5] = byte(i >> 8) 624 b[6] = byte(i) 625 return 7 626 default: 627 b[0] = byte(i >> 56) 628 b[1] = byte(i >> 48) 629 b[2] = byte(i >> 40) 630 b[3] = byte(i >> 32) 631 b[4] = byte(i >> 24) 632 b[5] = byte(i >> 16) 633 b[6] = byte(i >> 8) 634 b[7] = byte(i) 635 return 8 636 } 637 } 638 639 // intsize computes the minimum number of bytes required to store i. 640 func intsize(i uint64) (size int) { 641 for size = 1; ; size++ { 642 if i >>= 8; i == 0 { 643 return size 644 } 645 } 646 panic("not reached") 647 }