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