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