github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/rlp/encode.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:45</date> 10 //</624342663100895232> 11 12 13 package rlp 14 15 import ( 16 "fmt" 17 "io" 18 "math/big" 19 "reflect" 20 "sync" 21 ) 22 23 var ( 24 //通用编码值。 25 //这些在实现encoderlp时很有用。 26 EmptyString = []byte{0x80} 27 EmptyList = []byte{0xC0} 28 ) 29 30 //编码器由需要自定义的类型实现 31 //编码规则或要对私有字段进行编码。 32 type Encoder interface { 33 //encoderlp应将其接收器的rlp编码写入w。 34 //如果实现是一个指针方法,它也可以是 35 //要求零指针。 36 // 37 //实现应该生成有效的rlp。写入的数据是 38 //目前尚未验证,但将来的版本可能会验证。它是 39 //建议只写一个值,但写多个值 40 //也允许有值或没有值。 41 EncodeRLP(io.Writer) error 42 } 43 44 //encode将val的rlp编码写入w。注意,encode可以 45 //在某些情况下执行许多小的写入操作。考虑使w 46 //缓冲的。 47 // 48 //encode使用以下与类型相关的编码规则: 49 // 50 //如果类型实现编码器接口,则编码调用 51 //EncodeRLP。这是真的,即使没有指针,请看 52 //编码器文件。 53 // 54 //要对指针进行编码,将对指向的值进行编码。为零 55 //指针,encode将对类型的零值进行编码。零 56 //指向结构类型的指针始终编码为空的rlp列表。 57 //指向数组的nil指针编码为空列表(或空字符串 58 //如果数组具有元素类型byte)。 59 // 60 //结构值被编码为其所有编码的rlp列表 61 //公共领域。支持递归结构类型。 62 // 63 //为了对切片和数组进行编码,元素被编码为rlp 64 //值元素的列表。注意数组和切片 65 //元素类型uint8或byte始终编码为rlp字符串。 66 // 67 //go字符串编码为rlp字符串。 68 // 69 //无符号整数值编码为RLP字符串。零总是 70 //编码为空的rlp字符串。encode还支持*big.int。 71 // 72 //接口值编码为接口中包含的值。 73 // 74 //不支持布尔值,也不支持有符号整数,浮动 75 //点编号、地图、通道和功能。 76 func Encode(w io.Writer, val interface{}) error { 77 if outer, ok := w.(*encbuf); ok { 78 //encode被某个类型的encoderlp调用。 79 //避免通过直接写入外部encbuf进行复制。 80 return outer.encode(val) 81 } 82 eb := encbufPool.Get().(*encbuf) 83 defer encbufPool.Put(eb) 84 eb.reset() 85 if err := eb.encode(val); err != nil { 86 return err 87 } 88 return eb.toWriter(w) 89 } 90 91 //encodeToBytes返回val的rlp编码。 92 //编码规则请参见Encode文档。 93 func EncodeToBytes(val interface{}) ([]byte, error) { 94 eb := encbufPool.Get().(*encbuf) 95 defer encbufPool.Put(eb) 96 eb.reset() 97 if err := eb.encode(val); err != nil { 98 return nil, err 99 } 100 return eb.toBytes(), nil 101 } 102 103 //encodetoreader返回一个读卡器,其中val的rlp编码来自该读卡器 104 //可以阅读。返回的大小是已编码的 105 //数据。 106 // 107 //编码规则请参见Encode文档。 108 func EncodeToReader(val interface{}) (size int, r io.Reader, err error) { 109 eb := encbufPool.Get().(*encbuf) 110 eb.reset() 111 if err := eb.encode(val); err != nil { 112 return 0, nil, err 113 } 114 return eb.size(), &encReader{buf: eb}, nil 115 } 116 117 type encbuf struct { 118 str []byte //字符串数据,包含除列表头以外的所有内容 119 lheads []*listhead // 120 lhsize int //所有编码列表头的大小总和 121 sizebuf []byte //用于uint编码的9字节辅助缓冲区 122 } 123 124 type listhead struct { 125 offset int //字符串数据中此头的索引 126 size int //编码数据的总大小(包括列表头) 127 } 128 129 //编码写入头到给定的缓冲区,该缓冲区必须至少为 130 //9字节长。它返回编码的字节。 131 func (head *listhead) encode(buf []byte) []byte { 132 return buf[:puthead(buf, 0xC0, 0xF7, uint64(head.size))] 133 } 134 135 //headsize返回列表或字符串头的大小 136 //对于给定大小的值。 137 func headsize(size uint64) int { 138 if size < 56 { 139 return 1 140 } 141 return 1 + intsize(size) 142 } 143 144 //puthead将列表或字符串头写入buf。 145 //buf的长度必须至少为9个字节。 146 func puthead(buf []byte, smalltag, largetag byte, size uint64) int { 147 if size < 56 { 148 buf[0] = smalltag + byte(size) 149 return 1 150 } 151 sizesize := putint(buf[1:], size) 152 buf[0] = largetag + byte(sizesize) 153 return sizesize + 1 154 } 155 156 //围场是集合的。 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实现io.writer,以便将其传递到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:直接编码到w.str 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 //适合单字节,无字符串头 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++ //编码为种类标记的长度 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 //在头之前写入字符串数据 232 n := copy(out[pos:], w.str[strpos:head.offset]) 233 pos += n 234 strpos += n 235 //写标题 236 enc := head.encode(out[pos:]) 237 pos += len(enc) 238 } 239 //将字符串数据复制到最后一个列表头之后 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 //在头之前写入字符串数据 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 //写标题 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 //在最后一个列表头后写入字符串数据 263 _, err = out.Write(w.str[strpos:]) 264 } 265 return err 266 } 267 268 //Encrader是EncodeToReader返回的IO.Reader。 269 //它在EOF时释放ENCBUF。 270 type encReader struct { 271 buf *encbuf //我们正在读取的缓冲区。当我们到达终点时,这是零。 272 lhpos int //正在读取的列表标题索引 273 strpos int //字符串缓冲区中的当前位置 274 piece []byte //下一篇要读 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 //在EOF时将编码缓冲区放回池中 281 //是第一次遇到。后续呼叫仍返回EOF 282 //但是缓冲区不再有效。 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 //这件不合适,下次见。 293 r.piece = r.piece[nn:] 294 return n, nil 295 } 296 r.piece = nil 297 } 298 } 299 300 //Next返回下一段要读取的数据。 301 //在EOF时返回零。 302 func (r *encReader) next() []byte { 303 switch { 304 case r.buf == nil: 305 return nil 306 307 case r.piece != nil: 308 //仍有数据可供读取。 309 return r.piece 310 311 case r.lhpos < len(r.buf.lheads): 312 //我们在最后一个列表标题之前。 313 head := r.buf.lheads[r.lhpos] 314 sizebefore := head.offset - r.strpos 315 if sizebefore > 0 { 316 //头前的字符串数据。 317 p := r.buf.str[r.strpos:head.offset] 318 r.strpos += sizebefore 319 return p 320 } 321 r.lhpos++ 322 return head.encode(r.buf.sizebuf) 323 324 case r.strpos < len(r.buf.str): 325 //在所有列表头之后,在末尾字符串数据。 326 p := r.buf.str[r.strpos:] 327 r.strpos = len(r.buf.str) 328 return p 329 330 default: 331 return nil 332 } 333 } 334 335 var ( 336 encoderInterface = reflect.TypeOf(new(Encoder)).Elem() 337 big0 = big.NewInt(0) 338 ) 339 340 //makewriter为给定类型创建一个writer函数。 341 func makeWriter(typ reflect.Type, ts tags) (writer, error) { 342 kind := typ.Kind() 343 switch { 344 case typ == rawValueType: 345 return writeRawValue, nil 346 case typ.Implements(encoderInterface): 347 return writeEncoder, nil 348 case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface): 349 return writeEncoderNoPtr, nil 350 case kind == reflect.Interface: 351 return writeInterface, nil 352 case typ.AssignableTo(reflect.PtrTo(bigInt)): 353 return writeBigIntPtr, nil 354 case typ.AssignableTo(bigInt): 355 return writeBigIntNoPtr, nil 356 case isUint(kind): 357 return writeUint, nil 358 case kind == reflect.Bool: 359 return writeBool, nil 360 case kind == reflect.String: 361 return writeString, nil 362 case kind == reflect.Slice && isByte(typ.Elem()): 363 return writeBytes, nil 364 case kind == reflect.Array && isByte(typ.Elem()): 365 return writeByteArray, nil 366 case kind == reflect.Slice || kind == reflect.Array: 367 return makeSliceWriter(typ, ts) 368 case kind == reflect.Struct: 369 return makeStructWriter(typ) 370 case kind == reflect.Ptr: 371 return makePtrWriter(typ) 372 default: 373 return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) 374 } 375 } 376 377 func isByte(typ reflect.Type) bool { 378 return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface) 379 } 380 381 func writeRawValue(val reflect.Value, w *encbuf) error { 382 w.str = append(w.str, val.Bytes()...) 383 return nil 384 } 385 386 func writeUint(val reflect.Value, w *encbuf) error { 387 i := val.Uint() 388 if i == 0 { 389 w.str = append(w.str, 0x80) 390 } else if i < 128 { 391 //适合单字节 392 w.str = append(w.str, byte(i)) 393 } else { 394 //TODO:直接将int编码为w.str 395 s := putint(w.sizebuf[1:], i) 396 w.sizebuf[0] = 0x80 + byte(s) 397 w.str = append(w.str, w.sizebuf[:s+1]...) 398 } 399 return nil 400 } 401 402 func writeBool(val reflect.Value, w *encbuf) error { 403 if val.Bool() { 404 w.str = append(w.str, 0x01) 405 } else { 406 w.str = append(w.str, 0x80) 407 } 408 return nil 409 } 410 411 func writeBigIntPtr(val reflect.Value, w *encbuf) error { 412 ptr := val.Interface().(*big.Int) 413 if ptr == nil { 414 w.str = append(w.str, 0x80) 415 return nil 416 } 417 return writeBigInt(ptr, w) 418 } 419 420 func writeBigIntNoPtr(val reflect.Value, w *encbuf) error { 421 i := val.Interface().(big.Int) 422 return writeBigInt(&i, w) 423 } 424 425 func writeBigInt(i *big.Int, w *encbuf) error { 426 if cmp := i.Cmp(big0); cmp == -1 { 427 return fmt.Errorf("rlp: cannot encode negative *big.Int") 428 } else if cmp == 0 { 429 w.str = append(w.str, 0x80) 430 } else { 431 w.encodeString(i.Bytes()) 432 } 433 return nil 434 } 435 436 func writeBytes(val reflect.Value, w *encbuf) error { 437 w.encodeString(val.Bytes()) 438 return nil 439 } 440 441 func writeByteArray(val reflect.Value, w *encbuf) error { 442 if !val.CanAddr() { 443 //切片要求值是可寻址的。 444 //通过复制使其可寻址。 445 copy := reflect.New(val.Type()).Elem() 446 copy.Set(val) 447 val = copy 448 } 449 size := val.Len() 450 slice := val.Slice(0, size).Bytes() 451 w.encodeString(slice) 452 return nil 453 } 454 455 func writeString(val reflect.Value, w *encbuf) error { 456 s := val.String() 457 if len(s) == 1 && s[0] <= 0x7f { 458 //适合单字节,无字符串头 459 w.str = append(w.str, s[0]) 460 } else { 461 w.encodeStringHeader(len(s)) 462 w.str = append(w.str, s...) 463 } 464 return nil 465 } 466 467 func writeEncoder(val reflect.Value, w *encbuf) error { 468 return val.Interface().(Encoder).EncodeRLP(w) 469 } 470 471 //WriteEncoderNoptr处理实现编码器的非指针值 472 //带指针接收器。 473 func writeEncoderNoPtr(val reflect.Value, w *encbuf) error { 474 if !val.CanAddr() { 475 //我们找不到地址。它可以使 476 //通过创建一个浅副本可寻址的值,但是 477 //造成其他问题,所以我们还没有做。 478 // 479 //包json只是不调用marshaljson来处理类似的情况 480 //但对值进行编码,就好像它没有实现 481 //接口。我们不想那样处理。 482 return fmt.Errorf("rlp: game over: unadressable value of type %v, EncodeRLP is pointer method", val.Type()) 483 } 484 return val.Addr().Interface().(Encoder).EncodeRLP(w) 485 } 486 487 func writeInterface(val reflect.Value, w *encbuf) error { 488 if val.IsNil() { 489 //写空列表。这与之前的RLP一致 490 //我们拥有的编码器,因此应该避免 491 //问题。 492 w.str = append(w.str, 0xC0) 493 return nil 494 } 495 eval := val.Elem() 496 ti, err := cachedTypeInfo(eval.Type(), tags{}) 497 if err != nil { 498 return err 499 } 500 return ti.writer(eval, w) 501 } 502 503 func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) { 504 etypeinfo, err := cachedTypeInfo1(typ.Elem(), tags{}) 505 if err != nil { 506 return nil, err 507 } 508 writer := func(val reflect.Value, w *encbuf) error { 509 if !ts.tail { 510 defer w.listEnd(w.list()) 511 } 512 vlen := val.Len() 513 for i := 0; i < vlen; i++ { 514 if err := etypeinfo.writer(val.Index(i), w); err != nil { 515 return err 516 } 517 } 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 //确定零指针处理程序 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 //对结构/数组的零值进行编码可能会触发 559 //无限递归,避免这种情况。 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 } 574 return etypeinfo.writer(val.Elem(), w) 575 } 576 return writer, err 577 } 578 579 //putint用big endian字节将i写入b的开头 580 //顺序,使用表示i所需的最小字节数。 581 func putint(b []byte, i uint64) (size int) { 582 switch { 583 case i < (1 << 8): 584 b[0] = byte(i) 585 return 1 586 case i < (1 << 16): 587 b[0] = byte(i >> 8) 588 b[1] = byte(i) 589 return 2 590 case i < (1 << 24): 591 b[0] = byte(i >> 16) 592 b[1] = byte(i >> 8) 593 b[2] = byte(i) 594 return 3 595 case i < (1 << 32): 596 b[0] = byte(i >> 24) 597 b[1] = byte(i >> 16) 598 b[2] = byte(i >> 8) 599 b[3] = byte(i) 600 return 4 601 case i < (1 << 40): 602 b[0] = byte(i >> 32) 603 b[1] = byte(i >> 24) 604 b[2] = byte(i >> 16) 605 b[3] = byte(i >> 8) 606 b[4] = byte(i) 607 return 5 608 case i < (1 << 48): 609 b[0] = byte(i >> 40) 610 b[1] = byte(i >> 32) 611 b[2] = byte(i >> 24) 612 b[3] = byte(i >> 16) 613 b[4] = byte(i >> 8) 614 b[5] = byte(i) 615 return 6 616 case i < (1 << 56): 617 b[0] = byte(i >> 48) 618 b[1] = byte(i >> 40) 619 b[2] = byte(i >> 32) 620 b[3] = byte(i >> 24) 621 b[4] = byte(i >> 16) 622 b[5] = byte(i >> 8) 623 b[6] = byte(i) 624 return 7 625 default: 626 b[0] = byte(i >> 56) 627 b[1] = byte(i >> 48) 628 b[2] = byte(i >> 40) 629 b[3] = byte(i >> 32) 630 b[4] = byte(i >> 24) 631 b[5] = byte(i >> 16) 632 b[6] = byte(i >> 8) 633 b[7] = byte(i) 634 return 8 635 } 636 } 637 638 //IntSize计算存储i所需的最小字节数。 639 func intsize(i uint64) (size int) { 640 for size = 1; ; size++ { 641 if i >>= 8; i == 0 { 642 return size 643 } 644 } 645 } 646