github.com/tirogen/go-ethereum@v1.10.12-0.20221226051715-250cfede41b6/rlp/encode.go (about)

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