github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/common/hexutil/json.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  //版权所有2016 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 hexutil
    26  
    27  import (
    28  	"encoding/hex"
    29  	"encoding/json"
    30  	"fmt"
    31  	"math/big"
    32  	"reflect"
    33  	"strconv"
    34  )
    35  
    36  var (
    37  	bytesT  = reflect.TypeOf(Bytes(nil))
    38  	bigT    = reflect.TypeOf((*Big)(nil))
    39  	uintT   = reflect.TypeOf(Uint(0))
    40  	uint64T = reflect.TypeOf(Uint64(0))
    41  )
    42  
    43  //字节封送/取消封送为带0x前缀的JSON字符串。
    44  //空切片封送为“0x”。
    45  type Bytes []byte
    46  
    47  //MarshalText实现Encoding.TextMarshaler
    48  func (b Bytes) MarshalText() ([]byte, error) {
    49  	result := make([]byte, len(b)*2+2)
    50  	copy(result, `0x`)
    51  	hex.Encode(result[2:], b)
    52  	return result, nil
    53  }
    54  
    55  //unmashaljson实现json.unmasheler。
    56  func (b *Bytes) UnmarshalJSON(input []byte) error {
    57  	if !isString(input) {
    58  		return errNonString(bytesT)
    59  	}
    60  	return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT)
    61  }
    62  
    63  //UnmarshalText实现encoding.textUnmarshaller。
    64  func (b *Bytes) UnmarshalText(input []byte) error {
    65  	raw, err := checkText(input, true)
    66  	if err != nil {
    67  		return err
    68  	}
    69  	dec := make([]byte, len(raw)/2)
    70  	if _, err = hex.Decode(dec, raw); err != nil {
    71  		err = mapError(err)
    72  	} else {
    73  		*b = dec
    74  	}
    75  	return err
    76  }
    77  
    78  //字符串返回b的十六进制编码。
    79  func (b Bytes) String() string {
    80  	return Encode(b)
    81  }
    82  
    83  //unmarshalfixedjson将输入解码为带0x前缀的字符串。输出长度
    84  //确定所需的输入长度。此函数通常用于实现
    85  //固定大小类型的unmashaljson方法。
    86  func UnmarshalFixedJSON(typ reflect.Type, input, out []byte) error {
    87  	if !isString(input) {
    88  		return errNonString(typ)
    89  	}
    90  	return wrapTypeError(UnmarshalFixedText(typ.String(), input[1:len(input)-1], out), typ)
    91  }
    92  
    93  //unmarshalfixedtext将输入解码为带0x前缀的字符串。输出长度
    94  //确定所需的输入长度。此函数通常用于实现
    95  //为固定大小类型取消标记文本方法。
    96  func UnmarshalFixedText(typname string, input, out []byte) error {
    97  	raw, err := checkText(input, true)
    98  	if err != nil {
    99  		return err
   100  	}
   101  	if len(raw)/2 != len(out) {
   102  		return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
   103  	}
   104  //
   105  	for _, b := range raw {
   106  		if decodeNibble(b) == badNibble {
   107  			return ErrSyntax
   108  		}
   109  	}
   110  	hex.Decode(out, raw)
   111  	return nil
   112  }
   113  
   114  //unmarshalfixedUnprefixedText将输入解码为带可选0x前缀的字符串。这个
   115  //输出长度决定所需的输入长度。此函数通常用于
   116  //为固定大小类型实现UnmarshalText方法。
   117  func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error {
   118  	raw, err := checkText(input, false)
   119  	if err != nil {
   120  		return err
   121  	}
   122  	if len(raw)/2 != len(out) {
   123  		return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
   124  	}
   125  //在修改out之前预先验证语法。
   126  	for _, b := range raw {
   127  		if decodeNibble(b) == badNibble {
   128  			return ErrSyntax
   129  		}
   130  	}
   131  	hex.Decode(out, raw)
   132  	return nil
   133  }
   134  
   135  //大封送/取消封送作为带有0x前缀的JSON字符串。
   136  //零值封送为“0x0”。
   137  //
   138  //此时不支持负整数。试图封送他们将
   139  //返回一个错误。大于256位的值将被取消标记拒绝,但将
   140  //已正确封送。
   141  type Big big.Int
   142  
   143  //MarshalText实现Encoding.TextMarshaler
   144  func (b Big) MarshalText() ([]byte, error) {
   145  	return []byte(EncodeBig((*big.Int)(&b))), nil
   146  }
   147  
   148  //unmashaljson实现json.unmasheler。
   149  func (b *Big) UnmarshalJSON(input []byte) error {
   150  	if !isString(input) {
   151  		return errNonString(bigT)
   152  	}
   153  	return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bigT)
   154  }
   155  
   156  //UnmarshalText实现编码。textUnmarshaller
   157  func (b *Big) UnmarshalText(input []byte) error {
   158  	raw, err := checkNumberText(input)
   159  	if err != nil {
   160  		return err
   161  	}
   162  	if len(raw) > 64 {
   163  		return ErrBig256Range
   164  	}
   165  	words := make([]big.Word, len(raw)/bigWordNibbles+1)
   166  	end := len(raw)
   167  	for i := range words {
   168  		start := end - bigWordNibbles
   169  		if start < 0 {
   170  			start = 0
   171  		}
   172  		for ri := start; ri < end; ri++ {
   173  			nib := decodeNibble(raw[ri])
   174  			if nib == badNibble {
   175  				return ErrSyntax
   176  			}
   177  			words[i] *= 16
   178  			words[i] += big.Word(nib)
   179  		}
   180  		end = start
   181  	}
   182  	var dec big.Int
   183  	dec.SetBits(words)
   184  	*b = (Big)(dec)
   185  	return nil
   186  }
   187  
   188  //ToInt将b转换为big.int。
   189  func (b *Big) ToInt() *big.Int {
   190  	return (*big.Int)(b)
   191  }
   192  
   193  //字符串返回b的十六进制编码。
   194  func (b *Big) String() string {
   195  	return EncodeBig(b.ToInt())
   196  }
   197  
   198  //uint64以带有0x前缀的JSON字符串封送/取消封送。
   199  //零值封送为“0x0”。
   200  type Uint64 uint64
   201  
   202  //MarshalText实现Encoding.TextMarshaler。
   203  func (b Uint64) MarshalText() ([]byte, error) {
   204  	buf := make([]byte, 2, 10)
   205  	copy(buf, `0x`)
   206  	buf = strconv.AppendUint(buf, uint64(b), 16)
   207  	return buf, nil
   208  }
   209  
   210  //unmashaljson实现json.unmasheler。
   211  func (b *Uint64) UnmarshalJSON(input []byte) error {
   212  	if !isString(input) {
   213  		return errNonString(uint64T)
   214  	}
   215  	return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uint64T)
   216  }
   217  
   218  //UnmarshalText实现编码。textUnmarshaller
   219  func (b *Uint64) UnmarshalText(input []byte) error {
   220  	raw, err := checkNumberText(input)
   221  	if err != nil {
   222  		return err
   223  	}
   224  	if len(raw) > 16 {
   225  		return ErrUint64Range
   226  	}
   227  	var dec uint64
   228  	for _, byte := range raw {
   229  		nib := decodeNibble(byte)
   230  		if nib == badNibble {
   231  			return ErrSyntax
   232  		}
   233  		dec *= 16
   234  		dec += nib
   235  	}
   236  	*b = Uint64(dec)
   237  	return nil
   238  }
   239  
   240  //字符串返回b的十六进制编码。
   241  func (b Uint64) String() string {
   242  	return EncodeUint64(uint64(b))
   243  }
   244  
   245  //
   246  //零值封送为“0x0”。
   247  type Uint uint
   248  
   249  //MarshalText实现Encoding.TextMarshaler。
   250  func (b Uint) MarshalText() ([]byte, error) {
   251  	return Uint64(b).MarshalText()
   252  }
   253  
   254  //unmashaljson实现json.unmasheler。
   255  func (b *Uint) UnmarshalJSON(input []byte) error {
   256  	if !isString(input) {
   257  		return errNonString(uintT)
   258  	}
   259  	return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uintT)
   260  }
   261  
   262  //UnmarshalText实现encoding.textUnmarshaller。
   263  func (b *Uint) UnmarshalText(input []byte) error {
   264  	var u64 Uint64
   265  	err := u64.UnmarshalText(input)
   266  	if u64 > Uint64(^uint(0)) || err == ErrUint64Range {
   267  		return ErrUintRange
   268  	} else if err != nil {
   269  		return err
   270  	}
   271  	*b = Uint(u64)
   272  	return nil
   273  }
   274  
   275  //字符串返回b的十六进制编码。
   276  func (b Uint) String() string {
   277  	return EncodeUint64(uint64(b))
   278  }
   279  
   280  func isString(input []byte) bool {
   281  	return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"'
   282  }
   283  
   284  func bytesHave0xPrefix(input []byte) bool {
   285  	return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X')
   286  }
   287  
   288  func checkText(input []byte, wantPrefix bool) ([]byte, error) {
   289  	if len(input) == 0 {
   290  return nil, nil //允许空字符串
   291  	}
   292  	if bytesHave0xPrefix(input) {
   293  		input = input[2:]
   294  	} else if wantPrefix {
   295  		return nil, ErrMissingPrefix
   296  	}
   297  	if len(input)%2 != 0 {
   298  		return nil, ErrOddLength
   299  	}
   300  	return input, nil
   301  }
   302  
   303  func checkNumberText(input []byte) (raw []byte, err error) {
   304  	if len(input) == 0 {
   305  return nil, nil //允许空字符串
   306  	}
   307  	if !bytesHave0xPrefix(input) {
   308  		return nil, ErrMissingPrefix
   309  	}
   310  	input = input[2:]
   311  	if len(input) == 0 {
   312  		return nil, ErrEmptyNumber
   313  	}
   314  	if len(input) > 1 && input[0] == '0' {
   315  		return nil, ErrLeadingZero
   316  	}
   317  	return input, nil
   318  }
   319  
   320  func wrapTypeError(err error, typ reflect.Type) error {
   321  	if _, ok := err.(*decError); ok {
   322  		return &json.UnmarshalTypeError{Value: err.Error(), Type: typ}
   323  	}
   324  	return err
   325  }
   326  
   327  func errNonString(typ reflect.Type) error {
   328  	return &json.UnmarshalTypeError{Value: "non-string", Type: typ}
   329  }