github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/rlp/raw.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 //</624342663390302208> 11 12 13 package rlp 14 15 import ( 16 "io" 17 "reflect" 18 ) 19 20 //rawvalue表示已编码的rlp值,可用于延迟 21 //RLP解码或预计算编码。注意解码器可以 22 //不验证rawvalues的内容是否是有效的rlp。 23 type RawValue []byte 24 25 var rawValueType = reflect.TypeOf(RawValue{}) 26 27 //list size返回具有给定的 28 //内容大小。 29 func ListSize(contentSize uint64) uint64 { 30 return uint64(headsize(contentSize)) + contentSize 31 } 32 33 //split返回第一个rlp值和任何 34 //值后的字节作为b的子片。 35 func Split(b []byte) (k Kind, content, rest []byte, err error) { 36 k, ts, cs, err := readKind(b) 37 if err != nil { 38 return 0, nil, b, err 39 } 40 return k, b[ts : ts+cs], b[ts+cs:], nil 41 } 42 43 //splitString将b拆分为rlp字符串的内容 44 //以及字符串后的所有剩余字节。 45 func SplitString(b []byte) (content, rest []byte, err error) { 46 k, content, rest, err := Split(b) 47 if err != nil { 48 return nil, b, err 49 } 50 if k == List { 51 return nil, b, ErrExpectedString 52 } 53 return content, rest, nil 54 } 55 56 //SplitList将b拆分为列表的内容和任何剩余内容 57 //列表后的字节。 58 func SplitList(b []byte) (content, rest []byte, err error) { 59 k, content, rest, err := Split(b) 60 if err != nil { 61 return nil, b, err 62 } 63 if k != List { 64 return nil, b, ErrExpectedList 65 } 66 return content, rest, nil 67 } 68 69 //CountValues统计b中的编码值数目。 70 func CountValues(b []byte) (int, error) { 71 i := 0 72 for ; len(b) > 0; i++ { 73 _, tagsize, size, err := readKind(b) 74 if err != nil { 75 return 0, err 76 } 77 b = b[tagsize+size:] 78 } 79 return i, nil 80 } 81 82 func readKind(buf []byte) (k Kind, tagsize, contentsize uint64, err error) { 83 if len(buf) == 0 { 84 return 0, 0, 0, io.ErrUnexpectedEOF 85 } 86 b := buf[0] 87 switch { 88 case b < 0x80: 89 k = Byte 90 tagsize = 0 91 contentsize = 1 92 case b < 0xB8: 93 k = String 94 tagsize = 1 95 contentsize = uint64(b - 0x80) 96 //拒绝应该是单字节的字符串。 97 if contentsize == 1 && len(buf) > 1 && buf[1] < 128 { 98 return 0, 0, 0, ErrCanonSize 99 } 100 case b < 0xC0: 101 k = String 102 tagsize = uint64(b-0xB7) + 1 103 contentsize, err = readSize(buf[1:], b-0xB7) 104 case b < 0xF8: 105 k = List 106 tagsize = 1 107 contentsize = uint64(b - 0xC0) 108 default: 109 k = List 110 tagsize = uint64(b-0xF7) + 1 111 contentsize, err = readSize(buf[1:], b-0xF7) 112 } 113 if err != nil { 114 return 0, 0, 0, err 115 } 116 //拒绝大于输入切片的值。 117 if contentsize > uint64(len(buf))-tagsize { 118 return 0, 0, 0, ErrValueTooLarge 119 } 120 return k, tagsize, contentsize, err 121 } 122 123 func readSize(b []byte, slen byte) (uint64, error) { 124 if int(slen) > len(b) { 125 return 0, io.ErrUnexpectedEOF 126 } 127 var s uint64 128 switch slen { 129 case 1: 130 s = uint64(b[0]) 131 case 2: 132 s = uint64(b[0])<<8 | uint64(b[1]) 133 case 3: 134 s = uint64(b[0])<<16 | uint64(b[1])<<8 | uint64(b[2]) 135 case 4: 136 s = uint64(b[0])<<24 | uint64(b[1])<<16 | uint64(b[2])<<8 | uint64(b[3]) 137 case 5: 138 s = uint64(b[0])<<32 | uint64(b[1])<<24 | uint64(b[2])<<16 | uint64(b[3])<<8 | uint64(b[4]) 139 case 6: 140 s = uint64(b[0])<<40 | uint64(b[1])<<32 | uint64(b[2])<<24 | uint64(b[3])<<16 | uint64(b[4])<<8 | uint64(b[5]) 141 case 7: 142 s = uint64(b[0])<<48 | uint64(b[1])<<40 | uint64(b[2])<<32 | uint64(b[3])<<24 | uint64(b[4])<<16 | uint64(b[5])<<8 | uint64(b[6]) 143 case 8: 144 s = uint64(b[0])<<56 | uint64(b[1])<<48 | uint64(b[2])<<40 | uint64(b[3])<<32 | uint64(b[4])<<24 | uint64(b[5])<<16 | uint64(b[6])<<8 | uint64(b[7]) 145 } 146 //不合格尺寸小于56(不应有单独的尺寸),尺寸 147 //前导零字节。 148 if s < 56 || b[0] == 0 { 149 return 0, ErrCanonSize 150 } 151 return s, nil 152 } 153