github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/rlp/encode.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:45</date>
    10  //</624342663100895232>
    11  
    12  
    13  package rlp
    14  
    15  import (
    16  	"fmt"
    17  	"io"
    18  	"math/big"
    19  	"reflect"
    20  	"sync"
    21  )
    22  
    23  var (
    24  //通用编码值。
    25  //这些在实现encoderlp时很有用。
    26  	EmptyString = []byte{0x80}
    27  	EmptyList   = []byte{0xC0}
    28  )
    29  
    30  //编码器由需要自定义的类型实现
    31  //编码规则或要对私有字段进行编码。
    32  type Encoder interface {
    33  //encoderlp应将其接收器的rlp编码写入w。
    34  //如果实现是一个指针方法,它也可以是
    35  //要求零指针。
    36  //
    37  //实现应该生成有效的rlp。写入的数据是
    38  //目前尚未验证,但将来的版本可能会验证。它是
    39  //建议只写一个值,但写多个值
    40  //也允许有值或没有值。
    41  	EncodeRLP(io.Writer) error
    42  }
    43  
    44  //encode将val的rlp编码写入w。注意,encode可以
    45  //在某些情况下执行许多小的写入操作。考虑使w
    46  //缓冲的。
    47  //
    48  //encode使用以下与类型相关的编码规则:
    49  //
    50  //如果类型实现编码器接口,则编码调用
    51  //EncodeRLP。这是真的,即使没有指针,请看
    52  //编码器文件。
    53  //
    54  //要对指针进行编码,将对指向的值进行编码。为零
    55  //指针,encode将对类型的零值进行编码。零
    56  //指向结构类型的指针始终编码为空的rlp列表。
    57  //指向数组的nil指针编码为空列表(或空字符串
    58  //如果数组具有元素类型byte)。
    59  //
    60  //结构值被编码为其所有编码的rlp列表
    61  //公共领域。支持递归结构类型。
    62  //
    63  //为了对切片和数组进行编码,元素被编码为rlp
    64  //值元素的列表。注意数组和切片
    65  //元素类型uint8或byte始终编码为rlp字符串。
    66  //
    67  //go字符串编码为rlp字符串。
    68  //
    69  //无符号整数值编码为RLP字符串。零总是
    70  //编码为空的rlp字符串。encode还支持*big.int。
    71  //
    72  //接口值编码为接口中包含的值。
    73  //
    74  //不支持布尔值,也不支持有符号整数,浮动
    75  //点编号、地图、通道和功能。
    76  func Encode(w io.Writer, val interface{}) error {
    77  	if outer, ok := w.(*encbuf); ok {
    78  //encode被某个类型的encoderlp调用。
    79  //避免通过直接写入外部encbuf进行复制。
    80  		return outer.encode(val)
    81  	}
    82  	eb := encbufPool.Get().(*encbuf)
    83  	defer encbufPool.Put(eb)
    84  	eb.reset()
    85  	if err := eb.encode(val); err != nil {
    86  		return err
    87  	}
    88  	return eb.toWriter(w)
    89  }
    90  
    91  //encodeToBytes返回val的rlp编码。
    92  //编码规则请参见Encode文档。
    93  func EncodeToBytes(val interface{}) ([]byte, error) {
    94  	eb := encbufPool.Get().(*encbuf)
    95  	defer encbufPool.Put(eb)
    96  	eb.reset()
    97  	if err := eb.encode(val); err != nil {
    98  		return nil, err
    99  	}
   100  	return eb.toBytes(), nil
   101  }
   102  
   103  //encodetoreader返回一个读卡器,其中val的rlp编码来自该读卡器
   104  //可以阅读。返回的大小是已编码的
   105  //数据。
   106  //
   107  //编码规则请参见Encode文档。
   108  func EncodeToReader(val interface{}) (size int, r io.Reader, err error) {
   109  	eb := encbufPool.Get().(*encbuf)
   110  	eb.reset()
   111  	if err := eb.encode(val); err != nil {
   112  		return 0, nil, err
   113  	}
   114  	return eb.size(), &encReader{buf: eb}, nil
   115  }
   116  
   117  type encbuf struct {
   118  str     []byte      //字符串数据,包含除列表头以外的所有内容
   119  lheads  []*listhead //
   120  lhsize  int         //所有编码列表头的大小总和
   121  sizebuf []byte      //用于uint编码的9字节辅助缓冲区
   122  }
   123  
   124  type listhead struct {
   125  offset int //字符串数据中此头的索引
   126  size   int //编码数据的总大小(包括列表头)
   127  }
   128  
   129  //编码写入头到给定的缓冲区,该缓冲区必须至少为
   130  //9字节长。它返回编码的字节。
   131  func (head *listhead) encode(buf []byte) []byte {
   132  	return buf[:puthead(buf, 0xC0, 0xF7, uint64(head.size))]
   133  }
   134  
   135  //headsize返回列表或字符串头的大小
   136  //对于给定大小的值。
   137  func headsize(size uint64) int {
   138  	if size < 56 {
   139  		return 1
   140  	}
   141  	return 1 + intsize(size)
   142  }
   143  
   144  //puthead将列表或字符串头写入buf。
   145  //buf的长度必须至少为9个字节。
   146  func puthead(buf []byte, smalltag, largetag byte, size uint64) int {
   147  	if size < 56 {
   148  		buf[0] = smalltag + byte(size)
   149  		return 1
   150  	}
   151  	sizesize := putint(buf[1:], size)
   152  	buf[0] = largetag + byte(sizesize)
   153  	return sizesize + 1
   154  }
   155  
   156  //围场是集合的。
   157  var encbufPool = sync.Pool{
   158  	New: func() interface{} { return &encbuf{sizebuf: make([]byte, 9)} },
   159  }
   160  
   161  func (w *encbuf) reset() {
   162  	w.lhsize = 0
   163  	if w.str != nil {
   164  		w.str = w.str[:0]
   165  	}
   166  	if w.lheads != nil {
   167  		w.lheads = w.lheads[:0]
   168  	}
   169  }
   170  
   171  //encbuf实现io.writer,以便将其传递到encoderlp。
   172  func (w *encbuf) Write(b []byte) (int, error) {
   173  	w.str = append(w.str, b...)
   174  	return len(b), nil
   175  }
   176  
   177  func (w *encbuf) encode(val interface{}) error {
   178  	rval := reflect.ValueOf(val)
   179  	ti, err := cachedTypeInfo(rval.Type(), tags{})
   180  	if err != nil {
   181  		return err
   182  	}
   183  	return ti.writer(rval, w)
   184  }
   185  
   186  func (w *encbuf) encodeStringHeader(size int) {
   187  	if size < 56 {
   188  		w.str = append(w.str, 0x80+byte(size))
   189  	} else {
   190  //TODO:直接编码到w.str
   191  		sizesize := putint(w.sizebuf[1:], uint64(size))
   192  		w.sizebuf[0] = 0xB7 + byte(sizesize)
   193  		w.str = append(w.str, w.sizebuf[:sizesize+1]...)
   194  	}
   195  }
   196  
   197  func (w *encbuf) encodeString(b []byte) {
   198  	if len(b) == 1 && b[0] <= 0x7F {
   199  //适合单字节,无字符串头
   200  		w.str = append(w.str, b[0])
   201  	} else {
   202  		w.encodeStringHeader(len(b))
   203  		w.str = append(w.str, b...)
   204  	}
   205  }
   206  
   207  func (w *encbuf) list() *listhead {
   208  	lh := &listhead{offset: len(w.str), size: w.lhsize}
   209  	w.lheads = append(w.lheads, lh)
   210  	return lh
   211  }
   212  
   213  func (w *encbuf) listEnd(lh *listhead) {
   214  	lh.size = w.size() - lh.offset - lh.size
   215  	if lh.size < 56 {
   216  w.lhsize++ //编码为种类标记的长度
   217  	} else {
   218  		w.lhsize += 1 + intsize(uint64(lh.size))
   219  	}
   220  }
   221  
   222  func (w *encbuf) size() int {
   223  	return len(w.str) + w.lhsize
   224  }
   225  
   226  func (w *encbuf) toBytes() []byte {
   227  	out := make([]byte, w.size())
   228  	strpos := 0
   229  	pos := 0
   230  	for _, head := range w.lheads {
   231  //在头之前写入字符串数据
   232  		n := copy(out[pos:], w.str[strpos:head.offset])
   233  		pos += n
   234  		strpos += n
   235  //写标题
   236  		enc := head.encode(out[pos:])
   237  		pos += len(enc)
   238  	}
   239  //将字符串数据复制到最后一个列表头之后
   240  	copy(out[pos:], w.str[strpos:])
   241  	return out
   242  }
   243  
   244  func (w *encbuf) toWriter(out io.Writer) (err error) {
   245  	strpos := 0
   246  	for _, head := range w.lheads {
   247  //在头之前写入字符串数据
   248  		if head.offset-strpos > 0 {
   249  			n, err := out.Write(w.str[strpos:head.offset])
   250  			strpos += n
   251  			if err != nil {
   252  				return err
   253  			}
   254  		}
   255  //写标题
   256  		enc := head.encode(w.sizebuf)
   257  		if _, err = out.Write(enc); err != nil {
   258  			return err
   259  		}
   260  	}
   261  	if strpos < len(w.str) {
   262  //在最后一个列表头后写入字符串数据
   263  		_, err = out.Write(w.str[strpos:])
   264  	}
   265  	return err
   266  }
   267  
   268  //Encrader是EncodeToReader返回的IO.Reader。
   269  //它在EOF时释放ENCBUF。
   270  type encReader struct {
   271  buf    *encbuf //我们正在读取的缓冲区。当我们到达终点时,这是零。
   272  lhpos  int     //正在读取的列表标题索引
   273  strpos int     //字符串缓冲区中的当前位置
   274  piece  []byte  //下一篇要读
   275  }
   276  
   277  func (r *encReader) Read(b []byte) (n int, err error) {
   278  	for {
   279  		if r.piece = r.next(); r.piece == nil {
   280  //在EOF时将编码缓冲区放回池中
   281  //是第一次遇到。后续呼叫仍返回EOF
   282  //但是缓冲区不再有效。
   283  			if r.buf != nil {
   284  				encbufPool.Put(r.buf)
   285  				r.buf = nil
   286  			}
   287  			return n, io.EOF
   288  		}
   289  		nn := copy(b[n:], r.piece)
   290  		n += nn
   291  		if nn < len(r.piece) {
   292  //这件不合适,下次见。
   293  			r.piece = r.piece[nn:]
   294  			return n, nil
   295  		}
   296  		r.piece = nil
   297  	}
   298  }
   299  
   300  //Next返回下一段要读取的数据。
   301  //在EOF时返回零。
   302  func (r *encReader) next() []byte {
   303  	switch {
   304  	case r.buf == nil:
   305  		return nil
   306  
   307  	case r.piece != nil:
   308  //仍有数据可供读取。
   309  		return r.piece
   310  
   311  	case r.lhpos < len(r.buf.lheads):
   312  //我们在最后一个列表标题之前。
   313  		head := r.buf.lheads[r.lhpos]
   314  		sizebefore := head.offset - r.strpos
   315  		if sizebefore > 0 {
   316  //头前的字符串数据。
   317  			p := r.buf.str[r.strpos:head.offset]
   318  			r.strpos += sizebefore
   319  			return p
   320  		}
   321  		r.lhpos++
   322  		return head.encode(r.buf.sizebuf)
   323  
   324  	case r.strpos < len(r.buf.str):
   325  //在所有列表头之后,在末尾字符串数据。
   326  		p := r.buf.str[r.strpos:]
   327  		r.strpos = len(r.buf.str)
   328  		return p
   329  
   330  	default:
   331  		return nil
   332  	}
   333  }
   334  
   335  var (
   336  	encoderInterface = reflect.TypeOf(new(Encoder)).Elem()
   337  	big0             = big.NewInt(0)
   338  )
   339  
   340  //makewriter为给定类型创建一个writer函数。
   341  func makeWriter(typ reflect.Type, ts tags) (writer, error) {
   342  	kind := typ.Kind()
   343  	switch {
   344  	case typ == rawValueType:
   345  		return writeRawValue, nil
   346  	case typ.Implements(encoderInterface):
   347  		return writeEncoder, nil
   348  	case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface):
   349  		return writeEncoderNoPtr, nil
   350  	case kind == reflect.Interface:
   351  		return writeInterface, nil
   352  	case typ.AssignableTo(reflect.PtrTo(bigInt)):
   353  		return writeBigIntPtr, nil
   354  	case typ.AssignableTo(bigInt):
   355  		return writeBigIntNoPtr, nil
   356  	case isUint(kind):
   357  		return writeUint, nil
   358  	case kind == reflect.Bool:
   359  		return writeBool, nil
   360  	case kind == reflect.String:
   361  		return writeString, nil
   362  	case kind == reflect.Slice && isByte(typ.Elem()):
   363  		return writeBytes, nil
   364  	case kind == reflect.Array && isByte(typ.Elem()):
   365  		return writeByteArray, nil
   366  	case kind == reflect.Slice || kind == reflect.Array:
   367  		return makeSliceWriter(typ, ts)
   368  	case kind == reflect.Struct:
   369  		return makeStructWriter(typ)
   370  	case kind == reflect.Ptr:
   371  		return makePtrWriter(typ)
   372  	default:
   373  		return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ)
   374  	}
   375  }
   376  
   377  func isByte(typ reflect.Type) bool {
   378  	return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface)
   379  }
   380  
   381  func writeRawValue(val reflect.Value, w *encbuf) error {
   382  	w.str = append(w.str, val.Bytes()...)
   383  	return nil
   384  }
   385  
   386  func writeUint(val reflect.Value, w *encbuf) error {
   387  	i := val.Uint()
   388  	if i == 0 {
   389  		w.str = append(w.str, 0x80)
   390  	} else if i < 128 {
   391  //适合单字节
   392  		w.str = append(w.str, byte(i))
   393  	} else {
   394  //TODO:直接将int编码为w.str
   395  		s := putint(w.sizebuf[1:], i)
   396  		w.sizebuf[0] = 0x80 + byte(s)
   397  		w.str = append(w.str, w.sizebuf[:s+1]...)
   398  	}
   399  	return nil
   400  }
   401  
   402  func writeBool(val reflect.Value, w *encbuf) error {
   403  	if val.Bool() {
   404  		w.str = append(w.str, 0x01)
   405  	} else {
   406  		w.str = append(w.str, 0x80)
   407  	}
   408  	return nil
   409  }
   410  
   411  func writeBigIntPtr(val reflect.Value, w *encbuf) error {
   412  	ptr := val.Interface().(*big.Int)
   413  	if ptr == nil {
   414  		w.str = append(w.str, 0x80)
   415  		return nil
   416  	}
   417  	return writeBigInt(ptr, w)
   418  }
   419  
   420  func writeBigIntNoPtr(val reflect.Value, w *encbuf) error {
   421  	i := val.Interface().(big.Int)
   422  	return writeBigInt(&i, w)
   423  }
   424  
   425  func writeBigInt(i *big.Int, w *encbuf) error {
   426  	if cmp := i.Cmp(big0); cmp == -1 {
   427  		return fmt.Errorf("rlp: cannot encode negative *big.Int")
   428  	} else if cmp == 0 {
   429  		w.str = append(w.str, 0x80)
   430  	} else {
   431  		w.encodeString(i.Bytes())
   432  	}
   433  	return nil
   434  }
   435  
   436  func writeBytes(val reflect.Value, w *encbuf) error {
   437  	w.encodeString(val.Bytes())
   438  	return nil
   439  }
   440  
   441  func writeByteArray(val reflect.Value, w *encbuf) error {
   442  	if !val.CanAddr() {
   443  //切片要求值是可寻址的。
   444  //通过复制使其可寻址。
   445  		copy := reflect.New(val.Type()).Elem()
   446  		copy.Set(val)
   447  		val = copy
   448  	}
   449  	size := val.Len()
   450  	slice := val.Slice(0, size).Bytes()
   451  	w.encodeString(slice)
   452  	return nil
   453  }
   454  
   455  func writeString(val reflect.Value, w *encbuf) error {
   456  	s := val.String()
   457  	if len(s) == 1 && s[0] <= 0x7f {
   458  //适合单字节,无字符串头
   459  		w.str = append(w.str, s[0])
   460  	} else {
   461  		w.encodeStringHeader(len(s))
   462  		w.str = append(w.str, s...)
   463  	}
   464  	return nil
   465  }
   466  
   467  func writeEncoder(val reflect.Value, w *encbuf) error {
   468  	return val.Interface().(Encoder).EncodeRLP(w)
   469  }
   470  
   471  //WriteEncoderNoptr处理实现编码器的非指针值
   472  //带指针接收器。
   473  func writeEncoderNoPtr(val reflect.Value, w *encbuf) error {
   474  	if !val.CanAddr() {
   475  //我们找不到地址。它可以使
   476  //通过创建一个浅副本可寻址的值,但是
   477  //造成其他问题,所以我们还没有做。
   478  //
   479  //包json只是不调用marshaljson来处理类似的情况
   480  //但对值进行编码,就好像它没有实现
   481  //接口。我们不想那样处理。
   482  		return fmt.Errorf("rlp: game over: unadressable value of type %v, EncodeRLP is pointer method", val.Type())
   483  	}
   484  	return val.Addr().Interface().(Encoder).EncodeRLP(w)
   485  }
   486  
   487  func writeInterface(val reflect.Value, w *encbuf) error {
   488  	if val.IsNil() {
   489  //写空列表。这与之前的RLP一致
   490  //我们拥有的编码器,因此应该避免
   491  //问题。
   492  		w.str = append(w.str, 0xC0)
   493  		return nil
   494  	}
   495  	eval := val.Elem()
   496  	ti, err := cachedTypeInfo(eval.Type(), tags{})
   497  	if err != nil {
   498  		return err
   499  	}
   500  	return ti.writer(eval, w)
   501  }
   502  
   503  func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) {
   504  	etypeinfo, err := cachedTypeInfo1(typ.Elem(), tags{})
   505  	if err != nil {
   506  		return nil, err
   507  	}
   508  	writer := func(val reflect.Value, w *encbuf) error {
   509  		if !ts.tail {
   510  			defer w.listEnd(w.list())
   511  		}
   512  		vlen := val.Len()
   513  		for i := 0; i < vlen; i++ {
   514  			if err := etypeinfo.writer(val.Index(i), w); err != nil {
   515  				return err
   516  			}
   517  		}
   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  //确定零指针处理程序
   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  //对结构/数组的零值进行编码可能会触发
   559  //无限递归,避免这种情况。
   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  		}
   574  		return etypeinfo.writer(val.Elem(), w)
   575  	}
   576  	return writer, err
   577  }
   578  
   579  //putint用big endian字节将i写入b的开头
   580  //顺序,使用表示i所需的最小字节数。
   581  func putint(b []byte, i uint64) (size int) {
   582  	switch {
   583  	case i < (1 << 8):
   584  		b[0] = byte(i)
   585  		return 1
   586  	case i < (1 << 16):
   587  		b[0] = byte(i >> 8)
   588  		b[1] = byte(i)
   589  		return 2
   590  	case i < (1 << 24):
   591  		b[0] = byte(i >> 16)
   592  		b[1] = byte(i >> 8)
   593  		b[2] = byte(i)
   594  		return 3
   595  	case i < (1 << 32):
   596  		b[0] = byte(i >> 24)
   597  		b[1] = byte(i >> 16)
   598  		b[2] = byte(i >> 8)
   599  		b[3] = byte(i)
   600  		return 4
   601  	case i < (1 << 40):
   602  		b[0] = byte(i >> 32)
   603  		b[1] = byte(i >> 24)
   604  		b[2] = byte(i >> 16)
   605  		b[3] = byte(i >> 8)
   606  		b[4] = byte(i)
   607  		return 5
   608  	case i < (1 << 48):
   609  		b[0] = byte(i >> 40)
   610  		b[1] = byte(i >> 32)
   611  		b[2] = byte(i >> 24)
   612  		b[3] = byte(i >> 16)
   613  		b[4] = byte(i >> 8)
   614  		b[5] = byte(i)
   615  		return 6
   616  	case i < (1 << 56):
   617  		b[0] = byte(i >> 48)
   618  		b[1] = byte(i >> 40)
   619  		b[2] = byte(i >> 32)
   620  		b[3] = byte(i >> 24)
   621  		b[4] = byte(i >> 16)
   622  		b[5] = byte(i >> 8)
   623  		b[6] = byte(i)
   624  		return 7
   625  	default:
   626  		b[0] = byte(i >> 56)
   627  		b[1] = byte(i >> 48)
   628  		b[2] = byte(i >> 40)
   629  		b[3] = byte(i >> 32)
   630  		b[4] = byte(i >> 24)
   631  		b[5] = byte(i >> 16)
   632  		b[6] = byte(i >> 8)
   633  		b[7] = byte(i)
   634  		return 8
   635  	}
   636  }
   637  
   638  //IntSize计算存储i所需的最小字节数。
   639  func intsize(i uint64) (size int) {
   640  	for size = 1; ; size++ {
   641  		if i >>= 8; i == 0 {
   642  			return size
   643  		}
   644  	}
   645  }
   646