github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/rlp/raw.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2015 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package rlp 26 27 import ( 28 "io" 29 "reflect" 30 ) 31 32 //rawvalue表示已编码的rlp值,可用于延迟 33 //RLP解码或预计算编码。注意解码器可以 34 //不验证rawvalues的内容是否是有效的rlp。 35 type RawValue []byte 36 37 var rawValueType = reflect.TypeOf(RawValue{}) 38 39 //list size返回具有给定的 40 //内容大小。 41 func ListSize(contentSize uint64) uint64 { 42 return uint64(headsize(contentSize)) + contentSize 43 } 44 45 //split返回第一个rlp值和任何 46 //值后的字节作为b的子片。 47 func Split(b []byte) (k Kind, content, rest []byte, err error) { 48 k, ts, cs, err := readKind(b) 49 if err != nil { 50 return 0, nil, b, err 51 } 52 return k, b[ts : ts+cs], b[ts+cs:], nil 53 } 54 55 //splitString将b拆分为rlp字符串的内容 56 //以及字符串后的所有剩余字节。 57 func SplitString(b []byte) (content, rest []byte, err error) { 58 k, content, rest, err := Split(b) 59 if err != nil { 60 return nil, b, err 61 } 62 if k == List { 63 return nil, b, ErrExpectedString 64 } 65 return content, rest, nil 66 } 67 68 //SplitList将b拆分为列表的内容和任何剩余内容 69 //列表后的字节。 70 func SplitList(b []byte) (content, rest []byte, err error) { 71 k, content, rest, err := Split(b) 72 if err != nil { 73 return nil, b, err 74 } 75 if k != List { 76 return nil, b, ErrExpectedList 77 } 78 return content, rest, nil 79 } 80 81 //CountValues统计b中的编码值数目。 82 func CountValues(b []byte) (int, error) { 83 i := 0 84 for ; len(b) > 0; i++ { 85 _, tagsize, size, err := readKind(b) 86 if err != nil { 87 return 0, err 88 } 89 b = b[tagsize+size:] 90 } 91 return i, nil 92 } 93 94 func readKind(buf []byte) (k Kind, tagsize, contentsize uint64, err error) { 95 if len(buf) == 0 { 96 return 0, 0, 0, io.ErrUnexpectedEOF 97 } 98 b := buf[0] 99 switch { 100 case b < 0x80: 101 k = Byte 102 tagsize = 0 103 contentsize = 1 104 case b < 0xB8: 105 k = String 106 tagsize = 1 107 contentsize = uint64(b - 0x80) 108 //拒绝应该是单字节的字符串。 109 if contentsize == 1 && len(buf) > 1 && buf[1] < 128 { 110 return 0, 0, 0, ErrCanonSize 111 } 112 case b < 0xC0: 113 k = String 114 tagsize = uint64(b-0xB7) + 1 115 contentsize, err = readSize(buf[1:], b-0xB7) 116 case b < 0xF8: 117 k = List 118 tagsize = 1 119 contentsize = uint64(b - 0xC0) 120 default: 121 k = List 122 tagsize = uint64(b-0xF7) + 1 123 contentsize, err = readSize(buf[1:], b-0xF7) 124 } 125 if err != nil { 126 return 0, 0, 0, err 127 } 128 //拒绝大于输入切片的值。 129 if contentsize > uint64(len(buf))-tagsize { 130 return 0, 0, 0, ErrValueTooLarge 131 } 132 return k, tagsize, contentsize, err 133 } 134 135 func readSize(b []byte, slen byte) (uint64, error) { 136 if int(slen) > len(b) { 137 return 0, io.ErrUnexpectedEOF 138 } 139 var s uint64 140 switch slen { 141 case 1: 142 s = uint64(b[0]) 143 case 2: 144 s = uint64(b[0])<<8 | uint64(b[1]) 145 case 3: 146 s = uint64(b[0])<<16 | uint64(b[1])<<8 | uint64(b[2]) 147 case 4: 148 s = uint64(b[0])<<24 | uint64(b[1])<<16 | uint64(b[2])<<8 | uint64(b[3]) 149 case 5: 150 s = uint64(b[0])<<32 | uint64(b[1])<<24 | uint64(b[2])<<16 | uint64(b[3])<<8 | uint64(b[4]) 151 case 6: 152 s = uint64(b[0])<<40 | uint64(b[1])<<32 | uint64(b[2])<<24 | uint64(b[3])<<16 | uint64(b[4])<<8 | uint64(b[5]) 153 case 7: 154 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]) 155 case 8: 156 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]) 157 } 158 //不合格尺寸小于56(不应有单独的尺寸),尺寸 159 //前导零字节。 160 if s < 56 || b[0] == 0 { 161 return 0, ErrCanonSize 162 } 163 return s, nil 164 }