github.com/klaytn/klaytn@v1.12.1/rlp/encode.go (about) 1 // Modifications Copyright 2022 The klaytn Authors 2 // Copyright 2014 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from rlp/encode.go(2022/05/19) 19 // Modified and improved for the klaytn development. 20 21 package rlp 22 23 import ( 24 "errors" 25 "fmt" 26 "io" 27 "math/big" 28 "reflect" 29 30 "github.com/klaytn/klaytn/rlp/internal/rlpstruct" 31 ) 32 33 var ( 34 // Common encoded values. 35 // These are useful when implementing EncodeRLP. 36 EmptyString = []byte{0x80} 37 EmptyList = []byte{0xC0} 38 ) 39 40 var ErrNegativeBigInt = errors.New("rlp: cannot encode negative big.Int") 41 42 // Encoder is implemented by types that require custom 43 // encoding rules or want to encode private fields. 44 type Encoder interface { 45 // EncodeRLP should write the RLP encoding of its receiver to w. 46 // If the implementation is a pointer method, it may also be 47 // called for nil pointers. 48 // 49 // Implementations should generate valid RLP. The data written is 50 // not verified at the moment, but a future version might. It is 51 // recommended to write only a single value but writing multiple 52 // values or no value at all is also permitted. 53 EncodeRLP(io.Writer) error 54 } 55 56 // Encode writes the RLP encoding of val to w. Note that Encode may 57 // perform many small writes in some cases. Consider making w 58 // buffered. 59 // 60 // Please see package-level documentation of encoding rules. 61 func Encode(w io.Writer, val interface{}) error { 62 // Optimization: reuse *encBuffer when called by EncodeRLP. 63 if buf := encBufferFromWriter(w); buf != nil { 64 return buf.encode(val) 65 } 66 67 buf := getEncBuffer() 68 defer encBufferPool.Put(buf) 69 if err := buf.encode(val); err != nil { 70 return err 71 } 72 return buf.writeTo(w) 73 } 74 75 // EncodeToBytes returns the RLP encoding of val. 76 // Please see package-level documentation for the encoding rules. 77 func EncodeToBytes(val interface{}) ([]byte, error) { 78 buf := getEncBuffer() 79 defer encBufferPool.Put(buf) 80 81 if err := buf.encode(val); err != nil { 82 return nil, err 83 } 84 return buf.makeBytes(), nil 85 } 86 87 // EncodeToReader returns a reader from which the RLP encoding of val 88 // can be read. The returned size is the total size of the encoded 89 // data. 90 // 91 // Please see the documentation of Encode for the encoding rules. 92 func EncodeToReader(val interface{}) (size int, r io.Reader, err error) { 93 buf := getEncBuffer() 94 if err := buf.encode(val); err != nil { 95 encBufferPool.Put(buf) 96 return 0, nil, err 97 } 98 // Note: can't put the reader back into the pool here 99 // because it is held by encReader. The reader puts it 100 // back when it has been fully consumed. 101 return buf.size(), &encReader{buf: buf}, nil 102 } 103 104 type listhead struct { 105 offset int // index of this header in string data 106 size int // total size of encoded data (including list headers) 107 } 108 109 // encode writes head to the given buffer, which must be at least 110 // 9 bytes long. It returns the encoded bytes. 111 func (head *listhead) encode(buf []byte) []byte { 112 return buf[:puthead(buf, 0xC0, 0xF7, uint64(head.size))] 113 } 114 115 // headsize returns the size of a list or string header 116 // for a value of the given size. 117 func headsize(size uint64) int { 118 if size < 56 { 119 return 1 120 } 121 return 1 + intsize(size) 122 } 123 124 // puthead writes a list or string header to buf. 125 // buf must be at least 9 bytes long. 126 func puthead(buf []byte, smalltag, largetag byte, size uint64) int { 127 if size < 56 { 128 buf[0] = smalltag + byte(size) 129 return 1 130 } 131 sizesize := putint(buf[1:], size) 132 buf[0] = largetag + byte(sizesize) 133 return sizesize + 1 134 } 135 136 var encoderInterface = reflect.TypeOf(new(Encoder)).Elem() 137 138 // makeWriter creates a writer function for the given type. 139 func makeWriter(typ reflect.Type, ts rlpstruct.Tags) (writer, error) { 140 kind := typ.Kind() 141 switch { 142 case typ == rawValueType: 143 return writeRawValue, nil 144 case typ.AssignableTo(reflect.PtrTo(bigInt)): 145 return writeBigIntPtr, nil 146 case typ.AssignableTo(bigInt): 147 return writeBigIntNoPtr, nil 148 case kind == reflect.Ptr: 149 return makePtrWriter(typ, ts) 150 case reflect.PtrTo(typ).Implements(encoderInterface): 151 return makeEncoderWriter(typ), nil 152 case isUint(kind): 153 return writeUint, nil 154 case kind == reflect.Bool: 155 return writeBool, nil 156 case kind == reflect.String: 157 return writeString, nil 158 case kind == reflect.Slice && isByte(typ.Elem()): 159 return writeBytes, nil 160 case kind == reflect.Array && isByte(typ.Elem()): 161 return makeByteArrayWriter(typ), nil 162 case kind == reflect.Slice || kind == reflect.Array: 163 return makeSliceWriter(typ, ts) 164 case kind == reflect.Struct: 165 return makeStructWriter(typ) 166 case kind == reflect.Interface: 167 return writeInterface, nil 168 default: 169 return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) 170 } 171 } 172 173 func writeRawValue(val reflect.Value, w *encBuffer) error { 174 w.str = append(w.str, val.Bytes()...) 175 return nil 176 } 177 178 func writeUint(val reflect.Value, w *encBuffer) error { 179 w.writeUint64(val.Uint()) 180 return nil 181 } 182 183 func writeBool(val reflect.Value, w *encBuffer) error { 184 w.writeBool(val.Bool()) 185 return nil 186 } 187 188 func writeBigIntPtr(val reflect.Value, w *encBuffer) error { 189 ptr := val.Interface().(*big.Int) 190 if ptr == nil { 191 w.str = append(w.str, 0x80) 192 return nil 193 } 194 if ptr.Sign() == -1 { 195 return ErrNegativeBigInt 196 } 197 w.writeBigInt(ptr) 198 return nil 199 } 200 201 func writeBigIntNoPtr(val reflect.Value, w *encBuffer) error { 202 i := val.Interface().(big.Int) 203 if i.Sign() == -1 { 204 return ErrNegativeBigInt 205 } 206 w.writeBigInt(&i) 207 return nil 208 } 209 210 func writeBytes(val reflect.Value, w *encBuffer) error { 211 w.writeBytes(val.Bytes()) 212 return nil 213 } 214 215 func makeByteArrayWriter(typ reflect.Type) writer { 216 switch typ.Len() { 217 case 0: 218 return writeLengthZeroByteArray 219 case 1: 220 return writeLengthOneByteArray 221 default: 222 length := typ.Len() 223 return func(val reflect.Value, w *encBuffer) error { 224 if !val.CanAddr() { 225 // Getting the byte slice of val requires it to be addressable. Make it 226 // addressable by copying. 227 copy := reflect.New(val.Type()).Elem() 228 copy.Set(val) 229 val = copy 230 } 231 slice := byteArrayBytes(val, length) 232 w.encodeStringHeader(len(slice)) 233 w.str = append(w.str, slice...) 234 return nil 235 } 236 } 237 } 238 239 func writeLengthZeroByteArray(val reflect.Value, w *encBuffer) error { 240 w.str = append(w.str, 0x80) 241 return nil 242 } 243 244 func writeLengthOneByteArray(val reflect.Value, w *encBuffer) error { 245 b := byte(val.Index(0).Uint()) 246 if b <= 0x7f { 247 w.str = append(w.str, b) 248 } else { 249 w.str = append(w.str, 0x81, b) 250 } 251 return nil 252 } 253 254 func writeString(val reflect.Value, w *encBuffer) error { 255 s := val.String() 256 if len(s) == 1 && s[0] <= 0x7f { 257 // fits single byte, no string header 258 w.str = append(w.str, s[0]) 259 } else { 260 w.encodeStringHeader(len(s)) 261 w.str = append(w.str, s...) 262 } 263 return nil 264 } 265 266 func writeInterface(val reflect.Value, w *encBuffer) error { 267 if val.IsNil() { 268 // Write empty list. This is consistent with the previous RLP 269 // encoder that we had and should therefore avoid any 270 // problems. 271 w.str = append(w.str, 0xC0) 272 return nil 273 } 274 eval := val.Elem() 275 writer, err := cachedWriter(eval.Type()) 276 if err != nil { 277 return err 278 } 279 return writer(eval, w) 280 } 281 282 func makeSliceWriter(typ reflect.Type, ts rlpstruct.Tags) (writer, error) { 283 etypeinfo := theTC.infoWhileGenerating(typ.Elem(), rlpstruct.Tags{}) 284 if etypeinfo.writerErr != nil { 285 return nil, etypeinfo.writerErr 286 } 287 288 var wfn writer 289 if ts.Tail { 290 // This is for struct tail slices. 291 // w.list is not called for them. 292 wfn = func(val reflect.Value, w *encBuffer) error { 293 vlen := val.Len() 294 for i := 0; i < vlen; i++ { 295 if err := etypeinfo.writer(val.Index(i), w); err != nil { 296 return err 297 } 298 } 299 return nil 300 } 301 } else { 302 // This is for regular slices and arrays. 303 wfn = func(val reflect.Value, w *encBuffer) error { 304 vlen := val.Len() 305 if vlen == 0 { 306 w.str = append(w.str, 0xC0) 307 return nil 308 } 309 listOffset := w.list() 310 for i := 0; i < vlen; i++ { 311 if err := etypeinfo.writer(val.Index(i), w); err != nil { 312 return err 313 } 314 } 315 w.listEnd(listOffset) 316 return nil 317 } 318 } 319 return wfn, nil 320 } 321 322 func makeStructWriter(typ reflect.Type) (writer, error) { 323 fields, err := structFields(typ) 324 if err != nil { 325 return nil, err 326 } 327 for _, f := range fields { 328 if f.info.writerErr != nil { 329 return nil, structFieldError{typ, f.index, f.info.writerErr} 330 } 331 } 332 333 var writer writer 334 firstOptionalField := firstOptionalField(fields) 335 if firstOptionalField == len(fields) { 336 // This is the writer function for structs without any optional fields. 337 writer = func(val reflect.Value, w *encBuffer) error { 338 lh := w.list() 339 for _, f := range fields { 340 if err := f.info.writer(val.Field(f.index), w); err != nil { 341 return err 342 } 343 } 344 w.listEnd(lh) 345 return nil 346 } 347 } else { 348 // If there are any "optional" fields, the writer needs to perform additional 349 // checks to determine the output list length. 350 writer = func(val reflect.Value, w *encBuffer) error { 351 lastField := len(fields) - 1 352 for ; lastField >= firstOptionalField; lastField-- { 353 if !val.Field(fields[lastField].index).IsZero() { 354 break 355 } 356 } 357 lh := w.list() 358 for i := 0; i <= lastField; i++ { 359 if err := fields[i].info.writer(val.Field(fields[i].index), w); err != nil { 360 return err 361 } 362 } 363 w.listEnd(lh) 364 return nil 365 } 366 } 367 return writer, nil 368 } 369 370 func makePtrWriter(typ reflect.Type, ts rlpstruct.Tags) (writer, error) { 371 nilEncoding := byte(0xC0) 372 if typeNilKind(typ.Elem(), ts) == String { 373 nilEncoding = 0x80 374 } 375 376 etypeinfo := theTC.infoWhileGenerating(typ.Elem(), rlpstruct.Tags{}) 377 if etypeinfo.writerErr != nil { 378 return nil, etypeinfo.writerErr 379 } 380 381 writer := func(val reflect.Value, w *encBuffer) error { 382 if ev := val.Elem(); ev.IsValid() { 383 return etypeinfo.writer(ev, w) 384 } 385 w.str = append(w.str, nilEncoding) 386 return nil 387 } 388 return writer, nil 389 } 390 391 func makeEncoderWriter(typ reflect.Type) writer { 392 if typ.Implements(encoderInterface) { 393 return func(val reflect.Value, w *encBuffer) error { 394 return val.Interface().(Encoder).EncodeRLP(w) 395 } 396 } 397 w := func(val reflect.Value, w *encBuffer) error { 398 if !val.CanAddr() { 399 // package json simply doesn't call MarshalJSON for this case, but encodes the 400 // value as if it didn't implement the interface. We don't want to handle it that 401 // way. 402 return fmt.Errorf("rlp: unadressable value of type %v, EncodeRLP is pointer method", val.Type()) 403 } 404 return val.Addr().Interface().(Encoder).EncodeRLP(w) 405 } 406 return w 407 } 408 409 // putint writes i to the beginning of b in big endian byte 410 // order, using the least number of bytes needed to represent i. 411 func putint(b []byte, i uint64) (size int) { 412 switch { 413 case i < (1 << 8): 414 b[0] = byte(i) 415 return 1 416 case i < (1 << 16): 417 b[0] = byte(i >> 8) 418 b[1] = byte(i) 419 return 2 420 case i < (1 << 24): 421 b[0] = byte(i >> 16) 422 b[1] = byte(i >> 8) 423 b[2] = byte(i) 424 return 3 425 case i < (1 << 32): 426 b[0] = byte(i >> 24) 427 b[1] = byte(i >> 16) 428 b[2] = byte(i >> 8) 429 b[3] = byte(i) 430 return 4 431 case i < (1 << 40): 432 b[0] = byte(i >> 32) 433 b[1] = byte(i >> 24) 434 b[2] = byte(i >> 16) 435 b[3] = byte(i >> 8) 436 b[4] = byte(i) 437 return 5 438 case i < (1 << 48): 439 b[0] = byte(i >> 40) 440 b[1] = byte(i >> 32) 441 b[2] = byte(i >> 24) 442 b[3] = byte(i >> 16) 443 b[4] = byte(i >> 8) 444 b[5] = byte(i) 445 return 6 446 case i < (1 << 56): 447 b[0] = byte(i >> 48) 448 b[1] = byte(i >> 40) 449 b[2] = byte(i >> 32) 450 b[3] = byte(i >> 24) 451 b[4] = byte(i >> 16) 452 b[5] = byte(i >> 8) 453 b[6] = byte(i) 454 return 7 455 default: 456 b[0] = byte(i >> 56) 457 b[1] = byte(i >> 48) 458 b[2] = byte(i >> 40) 459 b[3] = byte(i >> 32) 460 b[4] = byte(i >> 24) 461 b[5] = byte(i >> 16) 462 b[6] = byte(i >> 8) 463 b[7] = byte(i) 464 return 8 465 } 466 } 467 468 // intsize computes the minimum number of bytes required to store i. 469 func intsize(i uint64) (size int) { 470 for size = 1; ; size++ { 471 if i >>= 8; i == 0 { 472 return size 473 } 474 } 475 }