github.com/sosedoff/go-ethereum@v1.9.7/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  	"fmt"
    21  	"io"
    22  	"math/big"
    23  	"reflect"
    24  	"sync"
    25  )
    26  
    27  var (
    28  	// Common encoded values.
    29  	// These are useful when implementing EncodeRLP.
    30  	EmptyString = []byte{0x80}
    31  	EmptyList   = []byte{0xC0}
    32  )
    33  
    34  // Encoder is implemented by types that require custom
    35  // encoding rules or want to encode private fields.
    36  type Encoder interface {
    37  	// EncodeRLP should write the RLP encoding of its receiver to w.
    38  	// If the implementation is a pointer method, it may also be
    39  	// called for nil pointers.
    40  	//
    41  	// Implementations should generate valid RLP. The data written is
    42  	// not verified at the moment, but a future version might. It is
    43  	// recommended to write only a single value but writing multiple
    44  	// values or no value at all is also permitted.
    45  	EncodeRLP(io.Writer) error
    46  }
    47  
    48  // Encode writes the RLP encoding of val to w. Note that Encode may
    49  // perform many small writes in some cases. Consider making w
    50  // buffered.
    51  //
    52  // Please see package-level documentation of encoding rules.
    53  func Encode(w io.Writer, val interface{}) error {
    54  	if outer, ok := w.(*encbuf); ok {
    55  		// Encode was called by some type's EncodeRLP.
    56  		// Avoid copying by writing to the outer encbuf directly.
    57  		return outer.encode(val)
    58  	}
    59  	eb := encbufPool.Get().(*encbuf)
    60  	defer encbufPool.Put(eb)
    61  	eb.reset()
    62  	if err := eb.encode(val); err != nil {
    63  		return err
    64  	}
    65  	return eb.toWriter(w)
    66  }
    67  
    68  // EncodeToBytes returns the RLP encoding of val.
    69  // Please see package-level documentation for the encoding rules.
    70  func EncodeToBytes(val interface{}) ([]byte, error) {
    71  	eb := encbufPool.Get().(*encbuf)
    72  	defer encbufPool.Put(eb)
    73  	eb.reset()
    74  	if err := eb.encode(val); err != nil {
    75  		return nil, err
    76  	}
    77  	return eb.toBytes(), nil
    78  }
    79  
    80  // EncodeToReader returns a reader from which the RLP encoding of val
    81  // can be read. The returned size is the total size of the encoded
    82  // data.
    83  //
    84  // Please see the documentation of Encode for the encoding rules.
    85  func EncodeToReader(val interface{}) (size int, r io.Reader, err error) {
    86  	eb := encbufPool.Get().(*encbuf)
    87  	eb.reset()
    88  	if err := eb.encode(val); err != nil {
    89  		return 0, nil, err
    90  	}
    91  	return eb.size(), &encReader{buf: eb}, nil
    92  }
    93  
    94  type encbuf struct {
    95  	str     []byte      // string data, contains everything except list headers
    96  	lheads  []*listhead // all list headers
    97  	lhsize  int         // sum of sizes of all encoded list headers
    98  	sizebuf []byte      // 9-byte auxiliary buffer for uint encoding
    99  }
   100  
   101  type listhead struct {
   102  	offset int // index of this header in string data
   103  	size   int // total size of encoded data (including list headers)
   104  }
   105  
   106  // encode writes head to the given buffer, which must be at least
   107  // 9 bytes long. It returns the encoded bytes.
   108  func (head *listhead) encode(buf []byte) []byte {
   109  	return buf[:puthead(buf, 0xC0, 0xF7, uint64(head.size))]
   110  }
   111  
   112  // headsize returns the size of a list or string header
   113  // for a value of the given size.
   114  func headsize(size uint64) int {
   115  	if size < 56 {
   116  		return 1
   117  	}
   118  	return 1 + intsize(size)
   119  }
   120  
   121  // puthead writes a list or string header to buf.
   122  // buf must be at least 9 bytes long.
   123  func puthead(buf []byte, smalltag, largetag byte, size uint64) int {
   124  	if size < 56 {
   125  		buf[0] = smalltag + byte(size)
   126  		return 1
   127  	}
   128  	sizesize := putint(buf[1:], size)
   129  	buf[0] = largetag + byte(sizesize)
   130  	return sizesize + 1
   131  }
   132  
   133  // encbufs are pooled.
   134  var encbufPool = sync.Pool{
   135  	New: func() interface{} { return &encbuf{sizebuf: make([]byte, 9)} },
   136  }
   137  
   138  func (w *encbuf) reset() {
   139  	w.lhsize = 0
   140  	if w.str != nil {
   141  		w.str = w.str[:0]
   142  	}
   143  	if w.lheads != nil {
   144  		w.lheads = w.lheads[:0]
   145  	}
   146  }
   147  
   148  // encbuf implements io.Writer so it can be passed it into EncodeRLP.
   149  func (w *encbuf) Write(b []byte) (int, error) {
   150  	w.str = append(w.str, b...)
   151  	return len(b), nil
   152  }
   153  
   154  func (w *encbuf) encode(val interface{}) error {
   155  	rval := reflect.ValueOf(val)
   156  	writer, err := cachedWriter(rval.Type())
   157  	if err != nil {
   158  		return err
   159  	}
   160  	return writer(rval, w)
   161  }
   162  
   163  func (w *encbuf) encodeStringHeader(size int) {
   164  	if size < 56 {
   165  		w.str = append(w.str, 0x80+byte(size))
   166  	} else {
   167  		// TODO: encode to w.str directly
   168  		sizesize := putint(w.sizebuf[1:], uint64(size))
   169  		w.sizebuf[0] = 0xB7 + byte(sizesize)
   170  		w.str = append(w.str, w.sizebuf[:sizesize+1]...)
   171  	}
   172  }
   173  
   174  func (w *encbuf) encodeString(b []byte) {
   175  	if len(b) == 1 && b[0] <= 0x7F {
   176  		// fits single byte, no string header
   177  		w.str = append(w.str, b[0])
   178  	} else {
   179  		w.encodeStringHeader(len(b))
   180  		w.str = append(w.str, b...)
   181  	}
   182  }
   183  
   184  func (w *encbuf) list() *listhead {
   185  	lh := &listhead{offset: len(w.str), size: w.lhsize}
   186  	w.lheads = append(w.lheads, lh)
   187  	return lh
   188  }
   189  
   190  func (w *encbuf) listEnd(lh *listhead) {
   191  	lh.size = w.size() - lh.offset - lh.size
   192  	if lh.size < 56 {
   193  		w.lhsize++ // length encoded into kind tag
   194  	} else {
   195  		w.lhsize += 1 + intsize(uint64(lh.size))
   196  	}
   197  }
   198  
   199  func (w *encbuf) size() int {
   200  	return len(w.str) + w.lhsize
   201  }
   202  
   203  func (w *encbuf) toBytes() []byte {
   204  	out := make([]byte, w.size())
   205  	strpos := 0
   206  	pos := 0
   207  	for _, head := range w.lheads {
   208  		// write string data before header
   209  		n := copy(out[pos:], w.str[strpos:head.offset])
   210  		pos += n
   211  		strpos += n
   212  		// write the header
   213  		enc := head.encode(out[pos:])
   214  		pos += len(enc)
   215  	}
   216  	// copy string data after the last list header
   217  	copy(out[pos:], w.str[strpos:])
   218  	return out
   219  }
   220  
   221  func (w *encbuf) toWriter(out io.Writer) (err error) {
   222  	strpos := 0
   223  	for _, head := range w.lheads {
   224  		// write string data before header
   225  		if head.offset-strpos > 0 {
   226  			n, err := out.Write(w.str[strpos:head.offset])
   227  			strpos += n
   228  			if err != nil {
   229  				return err
   230  			}
   231  		}
   232  		// write the header
   233  		enc := head.encode(w.sizebuf)
   234  		if _, err = out.Write(enc); err != nil {
   235  			return err
   236  		}
   237  	}
   238  	if strpos < len(w.str) {
   239  		// write string data after the last list header
   240  		_, err = out.Write(w.str[strpos:])
   241  	}
   242  	return err
   243  }
   244  
   245  // encReader is the io.Reader returned by EncodeToReader.
   246  // It releases its encbuf at EOF.
   247  type encReader struct {
   248  	buf    *encbuf // the buffer we're reading from. this is nil when we're at EOF.
   249  	lhpos  int     // index of list header that we're reading
   250  	strpos int     // current position in string buffer
   251  	piece  []byte  // next piece to be read
   252  }
   253  
   254  func (r *encReader) Read(b []byte) (n int, err error) {
   255  	for {
   256  		if r.piece = r.next(); r.piece == nil {
   257  			// Put the encode buffer back into the pool at EOF when it
   258  			// is first encountered. Subsequent calls still return EOF
   259  			// as the error but the buffer is no longer valid.
   260  			if r.buf != nil {
   261  				encbufPool.Put(r.buf)
   262  				r.buf = nil
   263  			}
   264  			return n, io.EOF
   265  		}
   266  		nn := copy(b[n:], r.piece)
   267  		n += nn
   268  		if nn < len(r.piece) {
   269  			// piece didn't fit, see you next time.
   270  			r.piece = r.piece[nn:]
   271  			return n, nil
   272  		}
   273  		r.piece = nil
   274  	}
   275  }
   276  
   277  // next returns the next piece of data to be read.
   278  // it returns nil at EOF.
   279  func (r *encReader) next() []byte {
   280  	switch {
   281  	case r.buf == nil:
   282  		return nil
   283  
   284  	case r.piece != nil:
   285  		// There is still data available for reading.
   286  		return r.piece
   287  
   288  	case r.lhpos < len(r.buf.lheads):
   289  		// We're before the last list header.
   290  		head := r.buf.lheads[r.lhpos]
   291  		sizebefore := head.offset - r.strpos
   292  		if sizebefore > 0 {
   293  			// String data before header.
   294  			p := r.buf.str[r.strpos:head.offset]
   295  			r.strpos += sizebefore
   296  			return p
   297  		}
   298  		r.lhpos++
   299  		return head.encode(r.buf.sizebuf)
   300  
   301  	case r.strpos < len(r.buf.str):
   302  		// String data at the end, after all list headers.
   303  		p := r.buf.str[r.strpos:]
   304  		r.strpos = len(r.buf.str)
   305  		return p
   306  
   307  	default:
   308  		return nil
   309  	}
   310  }
   311  
   312  var (
   313  	encoderInterface = reflect.TypeOf(new(Encoder)).Elem()
   314  	big0             = big.NewInt(0)
   315  )
   316  
   317  // makeWriter creates a writer function for the given type.
   318  func makeWriter(typ reflect.Type, ts tags) (writer, error) {
   319  	kind := typ.Kind()
   320  	switch {
   321  	case typ == rawValueType:
   322  		return writeRawValue, nil
   323  	case typ.AssignableTo(reflect.PtrTo(bigInt)):
   324  		return writeBigIntPtr, nil
   325  	case typ.AssignableTo(bigInt):
   326  		return writeBigIntNoPtr, nil
   327  	case kind == reflect.Ptr:
   328  		return makePtrWriter(typ, ts)
   329  	case reflect.PtrTo(typ).Implements(encoderInterface):
   330  		return makeEncoderWriter(typ), nil
   331  	case isUint(kind):
   332  		return writeUint, nil
   333  	case kind == reflect.Bool:
   334  		return writeBool, nil
   335  	case kind == reflect.String:
   336  		return writeString, nil
   337  	case kind == reflect.Slice && isByte(typ.Elem()):
   338  		return writeBytes, nil
   339  	case kind == reflect.Array && isByte(typ.Elem()):
   340  		return writeByteArray, nil
   341  	case kind == reflect.Slice || kind == reflect.Array:
   342  		return makeSliceWriter(typ, ts)
   343  	case kind == reflect.Struct:
   344  		return makeStructWriter(typ)
   345  	case kind == reflect.Interface:
   346  		return writeInterface, nil
   347  	default:
   348  		return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ)
   349  	}
   350  }
   351  
   352  func isByte(typ reflect.Type) bool {
   353  	return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface)
   354  }
   355  
   356  func writeRawValue(val reflect.Value, w *encbuf) error {
   357  	w.str = append(w.str, val.Bytes()...)
   358  	return nil
   359  }
   360  
   361  func writeUint(val reflect.Value, w *encbuf) error {
   362  	i := val.Uint()
   363  	if i == 0 {
   364  		w.str = append(w.str, 0x80)
   365  	} else if i < 128 {
   366  		// fits single byte
   367  		w.str = append(w.str, byte(i))
   368  	} else {
   369  		// TODO: encode int to w.str directly
   370  		s := putint(w.sizebuf[1:], i)
   371  		w.sizebuf[0] = 0x80 + byte(s)
   372  		w.str = append(w.str, w.sizebuf[:s+1]...)
   373  	}
   374  	return nil
   375  }
   376  
   377  func writeBool(val reflect.Value, w *encbuf) error {
   378  	if val.Bool() {
   379  		w.str = append(w.str, 0x01)
   380  	} else {
   381  		w.str = append(w.str, 0x80)
   382  	}
   383  	return nil
   384  }
   385  
   386  func writeBigIntPtr(val reflect.Value, w *encbuf) error {
   387  	ptr := val.Interface().(*big.Int)
   388  	if ptr == nil {
   389  		w.str = append(w.str, 0x80)
   390  		return nil
   391  	}
   392  	return writeBigInt(ptr, w)
   393  }
   394  
   395  func writeBigIntNoPtr(val reflect.Value, w *encbuf) error {
   396  	i := val.Interface().(big.Int)
   397  	return writeBigInt(&i, w)
   398  }
   399  
   400  func writeBigInt(i *big.Int, w *encbuf) error {
   401  	if cmp := i.Cmp(big0); cmp == -1 {
   402  		return fmt.Errorf("rlp: cannot encode negative *big.Int")
   403  	} else if cmp == 0 {
   404  		w.str = append(w.str, 0x80)
   405  	} else {
   406  		w.encodeString(i.Bytes())
   407  	}
   408  	return nil
   409  }
   410  
   411  func writeBytes(val reflect.Value, w *encbuf) error {
   412  	w.encodeString(val.Bytes())
   413  	return nil
   414  }
   415  
   416  func writeByteArray(val reflect.Value, w *encbuf) error {
   417  	if !val.CanAddr() {
   418  		// Slice requires the value to be addressable.
   419  		// Make it addressable by copying.
   420  		copy := reflect.New(val.Type()).Elem()
   421  		copy.Set(val)
   422  		val = copy
   423  	}
   424  	size := val.Len()
   425  	slice := val.Slice(0, size).Bytes()
   426  	w.encodeString(slice)
   427  	return nil
   428  }
   429  
   430  func writeString(val reflect.Value, w *encbuf) error {
   431  	s := val.String()
   432  	if len(s) == 1 && s[0] <= 0x7f {
   433  		// fits single byte, no string header
   434  		w.str = append(w.str, s[0])
   435  	} else {
   436  		w.encodeStringHeader(len(s))
   437  		w.str = append(w.str, s...)
   438  	}
   439  	return nil
   440  }
   441  
   442  func writeInterface(val reflect.Value, w *encbuf) error {
   443  	if val.IsNil() {
   444  		// Write empty list. This is consistent with the previous RLP
   445  		// encoder that we had and should therefore avoid any
   446  		// problems.
   447  		w.str = append(w.str, 0xC0)
   448  		return nil
   449  	}
   450  	eval := val.Elem()
   451  	writer, err := cachedWriter(eval.Type())
   452  	if err != nil {
   453  		return err
   454  	}
   455  	return writer(eval, w)
   456  }
   457  
   458  func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) {
   459  	etypeinfo := cachedTypeInfo1(typ.Elem(), tags{})
   460  	if etypeinfo.writerErr != nil {
   461  		return nil, etypeinfo.writerErr
   462  	}
   463  	writer := func(val reflect.Value, w *encbuf) error {
   464  		if !ts.tail {
   465  			defer w.listEnd(w.list())
   466  		}
   467  		vlen := val.Len()
   468  		for i := 0; i < vlen; i++ {
   469  			if err := etypeinfo.writer(val.Index(i), w); err != nil {
   470  				return err
   471  			}
   472  		}
   473  		return nil
   474  	}
   475  	return writer, nil
   476  }
   477  
   478  func makeStructWriter(typ reflect.Type) (writer, error) {
   479  	fields, err := structFields(typ)
   480  	if err != nil {
   481  		return nil, err
   482  	}
   483  	for _, f := range fields {
   484  		if f.info.writerErr != nil {
   485  			return nil, structFieldError{typ, f.index, f.info.writerErr}
   486  		}
   487  	}
   488  	writer := func(val reflect.Value, w *encbuf) error {
   489  		lh := w.list()
   490  		for _, f := range fields {
   491  			if err := f.info.writer(val.Field(f.index), w); err != nil {
   492  				return err
   493  			}
   494  		}
   495  		w.listEnd(lh)
   496  		return nil
   497  	}
   498  	return writer, nil
   499  }
   500  
   501  func makePtrWriter(typ reflect.Type, ts tags) (writer, error) {
   502  	etypeinfo := cachedTypeInfo1(typ.Elem(), tags{})
   503  	if etypeinfo.writerErr != nil {
   504  		return nil, etypeinfo.writerErr
   505  	}
   506  	// Determine how to encode nil pointers.
   507  	var nilKind Kind
   508  	if ts.nilOK {
   509  		nilKind = ts.nilKind // use struct tag if provided
   510  	} else {
   511  		nilKind = defaultNilKind(typ.Elem())
   512  	}
   513  
   514  	writer := func(val reflect.Value, w *encbuf) error {
   515  		if val.IsNil() {
   516  			if nilKind == String {
   517  				w.str = append(w.str, 0x80)
   518  			} else {
   519  				w.listEnd(w.list())
   520  			}
   521  			return nil
   522  		}
   523  		return etypeinfo.writer(val.Elem(), w)
   524  	}
   525  	return writer, nil
   526  }
   527  
   528  func makeEncoderWriter(typ reflect.Type) writer {
   529  	if typ.Implements(encoderInterface) {
   530  		return func(val reflect.Value, w *encbuf) error {
   531  			return val.Interface().(Encoder).EncodeRLP(w)
   532  		}
   533  	}
   534  	w := func(val reflect.Value, w *encbuf) error {
   535  		if !val.CanAddr() {
   536  			// package json simply doesn't call MarshalJSON for this case, but encodes the
   537  			// value as if it didn't implement the interface. We don't want to handle it that
   538  			// way.
   539  			return fmt.Errorf("rlp: unadressable value of type %v, EncodeRLP is pointer method", val.Type())
   540  		}
   541  		return val.Addr().Interface().(Encoder).EncodeRLP(w)
   542  	}
   543  	return w
   544  }
   545  
   546  // putint writes i to the beginning of b in big endian byte
   547  // order, using the least number of bytes needed to represent i.
   548  func putint(b []byte, i uint64) (size int) {
   549  	switch {
   550  	case i < (1 << 8):
   551  		b[0] = byte(i)
   552  		return 1
   553  	case i < (1 << 16):
   554  		b[0] = byte(i >> 8)
   555  		b[1] = byte(i)
   556  		return 2
   557  	case i < (1 << 24):
   558  		b[0] = byte(i >> 16)
   559  		b[1] = byte(i >> 8)
   560  		b[2] = byte(i)
   561  		return 3
   562  	case i < (1 << 32):
   563  		b[0] = byte(i >> 24)
   564  		b[1] = byte(i >> 16)
   565  		b[2] = byte(i >> 8)
   566  		b[3] = byte(i)
   567  		return 4
   568  	case i < (1 << 40):
   569  		b[0] = byte(i >> 32)
   570  		b[1] = byte(i >> 24)
   571  		b[2] = byte(i >> 16)
   572  		b[3] = byte(i >> 8)
   573  		b[4] = byte(i)
   574  		return 5
   575  	case i < (1 << 48):
   576  		b[0] = byte(i >> 40)
   577  		b[1] = byte(i >> 32)
   578  		b[2] = byte(i >> 24)
   579  		b[3] = byte(i >> 16)
   580  		b[4] = byte(i >> 8)
   581  		b[5] = byte(i)
   582  		return 6
   583  	case i < (1 << 56):
   584  		b[0] = byte(i >> 48)
   585  		b[1] = byte(i >> 40)
   586  		b[2] = byte(i >> 32)
   587  		b[3] = byte(i >> 24)
   588  		b[4] = byte(i >> 16)
   589  		b[5] = byte(i >> 8)
   590  		b[6] = byte(i)
   591  		return 7
   592  	default:
   593  		b[0] = byte(i >> 56)
   594  		b[1] = byte(i >> 48)
   595  		b[2] = byte(i >> 40)
   596  		b[3] = byte(i >> 32)
   597  		b[4] = byte(i >> 24)
   598  		b[5] = byte(i >> 16)
   599  		b[6] = byte(i >> 8)
   600  		b[7] = byte(i)
   601  		return 8
   602  	}
   603  }
   604  
   605  // intsize computes the minimum number of bytes required to store i.
   606  func intsize(i uint64) (size int) {
   607  	for size = 1; ; size++ {
   608  		if i >>= 8; i == 0 {
   609  			return size
   610  		}
   611  	}
   612  }