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  }