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