github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/rlp/raw.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2015 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package rlp
    26  
    27  import (
    28  	"io"
    29  	"reflect"
    30  )
    31  
    32  //rawvalue表示已编码的rlp值,可用于延迟
    33  //RLP解码或预计算编码。注意解码器可以
    34  //不验证rawvalues的内容是否是有效的rlp。
    35  type RawValue []byte
    36  
    37  var rawValueType = reflect.TypeOf(RawValue{})
    38  
    39  //list size返回具有给定的
    40  //内容大小。
    41  func ListSize(contentSize uint64) uint64 {
    42  	return uint64(headsize(contentSize)) + contentSize
    43  }
    44  
    45  //split返回第一个rlp值和任何
    46  //值后的字节作为b的子片。
    47  func Split(b []byte) (k Kind, content, rest []byte, err error) {
    48  	k, ts, cs, err := readKind(b)
    49  	if err != nil {
    50  		return 0, nil, b, err
    51  	}
    52  	return k, b[ts : ts+cs], b[ts+cs:], nil
    53  }
    54  
    55  //splitString将b拆分为rlp字符串的内容
    56  //以及字符串后的所有剩余字节。
    57  func SplitString(b []byte) (content, rest []byte, err error) {
    58  	k, content, rest, err := Split(b)
    59  	if err != nil {
    60  		return nil, b, err
    61  	}
    62  	if k == List {
    63  		return nil, b, ErrExpectedString
    64  	}
    65  	return content, rest, nil
    66  }
    67  
    68  //SplitList将b拆分为列表的内容和任何剩余内容
    69  //列表后的字节。
    70  func SplitList(b []byte) (content, rest []byte, err error) {
    71  	k, content, rest, err := Split(b)
    72  	if err != nil {
    73  		return nil, b, err
    74  	}
    75  	if k != List {
    76  		return nil, b, ErrExpectedList
    77  	}
    78  	return content, rest, nil
    79  }
    80  
    81  //CountValues统计b中的编码值数目。
    82  func CountValues(b []byte) (int, error) {
    83  	i := 0
    84  	for ; len(b) > 0; i++ {
    85  		_, tagsize, size, err := readKind(b)
    86  		if err != nil {
    87  			return 0, err
    88  		}
    89  		b = b[tagsize+size:]
    90  	}
    91  	return i, nil
    92  }
    93  
    94  func readKind(buf []byte) (k Kind, tagsize, contentsize uint64, err error) {
    95  	if len(buf) == 0 {
    96  		return 0, 0, 0, io.ErrUnexpectedEOF
    97  	}
    98  	b := buf[0]
    99  	switch {
   100  	case b < 0x80:
   101  		k = Byte
   102  		tagsize = 0
   103  		contentsize = 1
   104  	case b < 0xB8:
   105  		k = String
   106  		tagsize = 1
   107  		contentsize = uint64(b - 0x80)
   108  //拒绝应该是单字节的字符串。
   109  		if contentsize == 1 && len(buf) > 1 && buf[1] < 128 {
   110  			return 0, 0, 0, ErrCanonSize
   111  		}
   112  	case b < 0xC0:
   113  		k = String
   114  		tagsize = uint64(b-0xB7) + 1
   115  		contentsize, err = readSize(buf[1:], b-0xB7)
   116  	case b < 0xF8:
   117  		k = List
   118  		tagsize = 1
   119  		contentsize = uint64(b - 0xC0)
   120  	default:
   121  		k = List
   122  		tagsize = uint64(b-0xF7) + 1
   123  		contentsize, err = readSize(buf[1:], b-0xF7)
   124  	}
   125  	if err != nil {
   126  		return 0, 0, 0, err
   127  	}
   128  //拒绝大于输入切片的值。
   129  	if contentsize > uint64(len(buf))-tagsize {
   130  		return 0, 0, 0, ErrValueTooLarge
   131  	}
   132  	return k, tagsize, contentsize, err
   133  }
   134  
   135  func readSize(b []byte, slen byte) (uint64, error) {
   136  	if int(slen) > len(b) {
   137  		return 0, io.ErrUnexpectedEOF
   138  	}
   139  	var s uint64
   140  	switch slen {
   141  	case 1:
   142  		s = uint64(b[0])
   143  	case 2:
   144  		s = uint64(b[0])<<8 | uint64(b[1])
   145  	case 3:
   146  		s = uint64(b[0])<<16 | uint64(b[1])<<8 | uint64(b[2])
   147  	case 4:
   148  		s = uint64(b[0])<<24 | uint64(b[1])<<16 | uint64(b[2])<<8 | uint64(b[3])
   149  	case 5:
   150  		s = uint64(b[0])<<32 | uint64(b[1])<<24 | uint64(b[2])<<16 | uint64(b[3])<<8 | uint64(b[4])
   151  	case 6:
   152  		s = uint64(b[0])<<40 | uint64(b[1])<<32 | uint64(b[2])<<24 | uint64(b[3])<<16 | uint64(b[4])<<8 | uint64(b[5])
   153  	case 7:
   154  		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])
   155  	case 8:
   156  		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])
   157  	}
   158  //不合格尺寸小于56(不应有单独的尺寸),尺寸
   159  //前导零字节。
   160  	if s < 56 || b[0] == 0 {
   161  		return 0, ErrCanonSize
   162  	}
   163  	return s, nil
   164  }