github.com/klaytn/klaytn@v1.12.1/rlp/raw.go (about) 1 // Copyright 2015 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 "io" 21 "reflect" 22 ) 23 24 // RawValue represents an encoded RLP value and can be used to delay 25 // RLP decoding or to precompute an encoding. Note that the decoder does 26 // not verify whether the content of RawValues is valid RLP. 27 type RawValue []byte 28 29 var rawValueType = reflect.TypeOf(RawValue{}) 30 31 // ListSize returns the encoded size of an RLP list with the given 32 // content size. 33 func ListSize(contentSize uint64) uint64 { 34 return uint64(headsize(contentSize)) + contentSize 35 } 36 37 // IntSize returns the encoded size of the integer x. 38 func IntSize(x uint64) int { 39 if x < 0x80 { 40 return 1 41 } 42 return 1 + intsize(x) 43 } 44 45 // Split returns the content of first RLP value and any 46 // bytes after the value as subslices of 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 splits b into the content of an RLP string 56 // and any remaining bytes after the string. 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 // SplitUint64 decodes an integer at the beginning of b. 69 // It also returns the remaining data after the integer in 'rest'. 70 func SplitUint64(b []byte) (x uint64, rest []byte, err error) { 71 content, rest, err := SplitString(b) 72 if err != nil { 73 return 0, b, err 74 } 75 switch { 76 case len(content) == 0: 77 return 0, rest, nil 78 case len(content) == 1: 79 if content[0] == 0 { 80 return 0, b, ErrCanonInt 81 } 82 return uint64(content[0]), rest, nil 83 case len(content) > 8: 84 return 0, b, errUintOverflow 85 default: 86 x, err = readSize(content, byte(len(content))) 87 if err != nil { 88 return 0, b, ErrCanonInt 89 } 90 return x, rest, nil 91 } 92 } 93 94 // SplitList splits b into the content of a list and any remaining 95 // bytes after the list. 96 func SplitList(b []byte) (content, rest []byte, err error) { 97 k, content, rest, err := Split(b) 98 if err != nil { 99 return nil, b, err 100 } 101 if k != List { 102 return nil, b, ErrExpectedList 103 } 104 return content, rest, nil 105 } 106 107 // CountValues counts the number of encoded values in b. 108 func CountValues(b []byte) (int, error) { 109 i := 0 110 for ; len(b) > 0; i++ { 111 _, tagsize, size, err := readKind(b) 112 if err != nil { 113 return 0, err 114 } 115 b = b[tagsize+size:] 116 } 117 return i, nil 118 } 119 120 func readKind(buf []byte) (k Kind, tagsize, contentsize uint64, err error) { 121 if len(buf) == 0 { 122 return 0, 0, 0, io.ErrUnexpectedEOF 123 } 124 b := buf[0] 125 switch { 126 case b < 0x80: 127 k = Byte 128 tagsize = 0 129 contentsize = 1 130 case b < 0xB8: 131 k = String 132 tagsize = 1 133 contentsize = uint64(b - 0x80) 134 // Reject strings that should've been single bytes. 135 if contentsize == 1 && len(buf) > 1 && buf[1] < 128 { 136 return 0, 0, 0, ErrCanonSize 137 } 138 case b < 0xC0: 139 k = String 140 tagsize = uint64(b-0xB7) + 1 141 contentsize, err = readSize(buf[1:], b-0xB7) 142 case b < 0xF8: 143 k = List 144 tagsize = 1 145 contentsize = uint64(b - 0xC0) 146 default: 147 k = List 148 tagsize = uint64(b-0xF7) + 1 149 contentsize, err = readSize(buf[1:], b-0xF7) 150 } 151 if err != nil { 152 return 0, 0, 0, err 153 } 154 // Reject values larger than the input slice. 155 if contentsize > uint64(len(buf))-tagsize { 156 return 0, 0, 0, ErrValueTooLarge 157 } 158 return k, tagsize, contentsize, err 159 } 160 161 func readSize(b []byte, slen byte) (uint64, error) { 162 if int(slen) > len(b) { 163 return 0, io.ErrUnexpectedEOF 164 } 165 var s uint64 166 switch slen { 167 case 1: 168 s = uint64(b[0]) 169 case 2: 170 s = uint64(b[0])<<8 | uint64(b[1]) 171 case 3: 172 s = uint64(b[0])<<16 | uint64(b[1])<<8 | uint64(b[2]) 173 case 4: 174 s = uint64(b[0])<<24 | uint64(b[1])<<16 | uint64(b[2])<<8 | uint64(b[3]) 175 case 5: 176 s = uint64(b[0])<<32 | uint64(b[1])<<24 | uint64(b[2])<<16 | uint64(b[3])<<8 | uint64(b[4]) 177 case 6: 178 s = uint64(b[0])<<40 | uint64(b[1])<<32 | uint64(b[2])<<24 | uint64(b[3])<<16 | uint64(b[4])<<8 | uint64(b[5]) 179 case 7: 180 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]) 181 case 8: 182 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]) 183 } 184 // Reject sizes < 56 (shouldn't have separate size) and sizes with 185 // leading zero bytes. 186 if s < 56 || b[0] == 0 { 187 return 0, ErrCanonSize 188 } 189 return s, nil 190 } 191 192 // AppendUint64 appends the RLP encoding of i to b, and returns the resulting slice. 193 func AppendUint64(b []byte, i uint64) []byte { 194 if i == 0 { 195 return append(b, 0x80) 196 } else if i < 128 { 197 return append(b, byte(i)) 198 } 199 switch { 200 case i < (1 << 8): 201 return append(b, 0x81, byte(i)) 202 case i < (1 << 16): 203 return append(b, 0x82, 204 byte(i>>8), 205 byte(i), 206 ) 207 case i < (1 << 24): 208 return append(b, 0x83, 209 byte(i>>16), 210 byte(i>>8), 211 byte(i), 212 ) 213 case i < (1 << 32): 214 return append(b, 0x84, 215 byte(i>>24), 216 byte(i>>16), 217 byte(i>>8), 218 byte(i), 219 ) 220 case i < (1 << 40): 221 return append(b, 0x85, 222 byte(i>>32), 223 byte(i>>24), 224 byte(i>>16), 225 byte(i>>8), 226 byte(i), 227 ) 228 229 case i < (1 << 48): 230 return append(b, 0x86, 231 byte(i>>40), 232 byte(i>>32), 233 byte(i>>24), 234 byte(i>>16), 235 byte(i>>8), 236 byte(i), 237 ) 238 case i < (1 << 56): 239 return append(b, 0x87, 240 byte(i>>48), 241 byte(i>>40), 242 byte(i>>32), 243 byte(i>>24), 244 byte(i>>16), 245 byte(i>>8), 246 byte(i), 247 ) 248 249 default: 250 return append(b, 0x88, 251 byte(i>>56), 252 byte(i>>48), 253 byte(i>>40), 254 byte(i>>32), 255 byte(i>>24), 256 byte(i>>16), 257 byte(i>>8), 258 byte(i), 259 ) 260 } 261 }