github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/rlp/raw.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  //</624342663390302208>
    11  
    12  
    13  package rlp
    14  
    15  import (
    16  	"io"
    17  	"reflect"
    18  )
    19  
    20  //rawvalue表示已编码的rlp值,可用于延迟
    21  //RLP解码或预计算编码。注意解码器可以
    22  //不验证rawvalues的内容是否是有效的rlp。
    23  type RawValue []byte
    24  
    25  var rawValueType = reflect.TypeOf(RawValue{})
    26  
    27  //list size返回具有给定的
    28  //内容大小。
    29  func ListSize(contentSize uint64) uint64 {
    30  	return uint64(headsize(contentSize)) + contentSize
    31  }
    32  
    33  //split返回第一个rlp值和任何
    34  //值后的字节作为b的子片。
    35  func Split(b []byte) (k Kind, content, rest []byte, err error) {
    36  	k, ts, cs, err := readKind(b)
    37  	if err != nil {
    38  		return 0, nil, b, err
    39  	}
    40  	return k, b[ts : ts+cs], b[ts+cs:], nil
    41  }
    42  
    43  //splitString将b拆分为rlp字符串的内容
    44  //以及字符串后的所有剩余字节。
    45  func SplitString(b []byte) (content, rest []byte, err error) {
    46  	k, content, rest, err := Split(b)
    47  	if err != nil {
    48  		return nil, b, err
    49  	}
    50  	if k == List {
    51  		return nil, b, ErrExpectedString
    52  	}
    53  	return content, rest, nil
    54  }
    55  
    56  //SplitList将b拆分为列表的内容和任何剩余内容
    57  //列表后的字节。
    58  func SplitList(b []byte) (content, rest []byte, err error) {
    59  	k, content, rest, err := Split(b)
    60  	if err != nil {
    61  		return nil, b, err
    62  	}
    63  	if k != List {
    64  		return nil, b, ErrExpectedList
    65  	}
    66  	return content, rest, nil
    67  }
    68  
    69  //CountValues统计b中的编码值数目。
    70  func CountValues(b []byte) (int, error) {
    71  	i := 0
    72  	for ; len(b) > 0; i++ {
    73  		_, tagsize, size, err := readKind(b)
    74  		if err != nil {
    75  			return 0, err
    76  		}
    77  		b = b[tagsize+size:]
    78  	}
    79  	return i, nil
    80  }
    81  
    82  func readKind(buf []byte) (k Kind, tagsize, contentsize uint64, err error) {
    83  	if len(buf) == 0 {
    84  		return 0, 0, 0, io.ErrUnexpectedEOF
    85  	}
    86  	b := buf[0]
    87  	switch {
    88  	case b < 0x80:
    89  		k = Byte
    90  		tagsize = 0
    91  		contentsize = 1
    92  	case b < 0xB8:
    93  		k = String
    94  		tagsize = 1
    95  		contentsize = uint64(b - 0x80)
    96  //拒绝应该是单字节的字符串。
    97  		if contentsize == 1 && len(buf) > 1 && buf[1] < 128 {
    98  			return 0, 0, 0, ErrCanonSize
    99  		}
   100  	case b < 0xC0:
   101  		k = String
   102  		tagsize = uint64(b-0xB7) + 1
   103  		contentsize, err = readSize(buf[1:], b-0xB7)
   104  	case b < 0xF8:
   105  		k = List
   106  		tagsize = 1
   107  		contentsize = uint64(b - 0xC0)
   108  	default:
   109  		k = List
   110  		tagsize = uint64(b-0xF7) + 1
   111  		contentsize, err = readSize(buf[1:], b-0xF7)
   112  	}
   113  	if err != nil {
   114  		return 0, 0, 0, err
   115  	}
   116  //拒绝大于输入切片的值。
   117  	if contentsize > uint64(len(buf))-tagsize {
   118  		return 0, 0, 0, ErrValueTooLarge
   119  	}
   120  	return k, tagsize, contentsize, err
   121  }
   122  
   123  func readSize(b []byte, slen byte) (uint64, error) {
   124  	if int(slen) > len(b) {
   125  		return 0, io.ErrUnexpectedEOF
   126  	}
   127  	var s uint64
   128  	switch slen {
   129  	case 1:
   130  		s = uint64(b[0])
   131  	case 2:
   132  		s = uint64(b[0])<<8 | uint64(b[1])
   133  	case 3:
   134  		s = uint64(b[0])<<16 | uint64(b[1])<<8 | uint64(b[2])
   135  	case 4:
   136  		s = uint64(b[0])<<24 | uint64(b[1])<<16 | uint64(b[2])<<8 | uint64(b[3])
   137  	case 5:
   138  		s = uint64(b[0])<<32 | uint64(b[1])<<24 | uint64(b[2])<<16 | uint64(b[3])<<8 | uint64(b[4])
   139  	case 6:
   140  		s = uint64(b[0])<<40 | uint64(b[1])<<32 | uint64(b[2])<<24 | uint64(b[3])<<16 | uint64(b[4])<<8 | uint64(b[5])
   141  	case 7:
   142  		s = uint64(b[0])<<48 | uint64(b[1])<<40 | uint64(b[2])<<32 | uint64(b[3])<<24 | uint64(b[4])<<16 | uint64(b[5])<<8 | uint64(b[6])
   143  	case 8:
   144  		s = uint64(b[0])<<56 | uint64(b[1])<<48 | uint64(b[2])<<40 | uint64(b[3])<<32 | uint64(b[4])<<24 | uint64(b[5])<<16 | uint64(b[6])<<8 | uint64(b[7])
   145  	}
   146  //不合格尺寸小于56(不应有单独的尺寸),尺寸
   147  //前导零字节。
   148  	if s < 56 || b[0] == 0 {
   149  		return 0, ErrCanonSize
   150  	}
   151  	return s, nil
   152  }
   153