github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/common/hexutil/json.go (about)

     1  // Copyright 2016 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 hexutil
    18  
    19  import (
    20  	"encoding/hex"
    21  	"errors"
    22  	"fmt"
    23  	"math/big"
    24  	"strconv"
    25  )
    26  
    27  var (
    28  	jsonNull          = []byte("null")
    29  	jsonZero          = []byte(`"0x0"`)
    30  	errNonString      = errors.New("cannot unmarshal non-string as hex data")
    31  	errNegativeBigInt = errors.New("hexutil.Big: can't marshal negative integer")
    32  )
    33  
    34  // Bytes marshals/unmarshals as a JSON string with 0x prefix.
    35  // The empty slice marshals as "0x".
    36  type Bytes []byte
    37  
    38  // MarshalJSON implements json.Marshaler.
    39  func (b Bytes) MarshalJSON() ([]byte, error) {
    40  	result := make([]byte, len(b)*2+4)
    41  	copy(result, `"0x`)
    42  	hex.Encode(result[3:], b)
    43  	result[len(result)-1] = '"'
    44  	return result, nil
    45  }
    46  
    47  // UnmarshalJSON implements json.Unmarshaler.
    48  func (b *Bytes) UnmarshalJSON(input []byte) error {
    49  	raw, err := checkJSON(input)
    50  	if err != nil {
    51  		return err
    52  	}
    53  	dec := make([]byte, len(raw)/2)
    54  	if _, err = hex.Decode(dec, raw); err != nil {
    55  		err = mapError(err)
    56  	} else {
    57  		*b = dec
    58  	}
    59  	return err
    60  }
    61  
    62  // String returns the hex encoding of b.
    63  func (b Bytes) String() string {
    64  	return Encode(b)
    65  }
    66  
    67  // UnmarshalJSON decodes input as a JSON string with 0x prefix. The length of out
    68  // determines the required input length. This function is commonly used to implement the
    69  // UnmarshalJSON method for fixed-size types:
    70  //
    71  //     type Foo [8]byte
    72  //
    73  //     func (f *Foo) UnmarshalJSON(input []byte) error {
    74  //         return hexutil.UnmarshalJSON("Foo", input, f[:])
    75  //     }
    76  func UnmarshalJSON(typname string, input, out []byte) error {
    77  	raw, err := checkJSON(input)
    78  	if err != nil {
    79  		return err
    80  	}
    81  	if len(raw)/2 != len(out) {
    82  		return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
    83  	}
    84  	// Pre-verify syntax before modifying out.
    85  	for _, b := range raw {
    86  		if decodeNibble(b) == badNibble {
    87  			return ErrSyntax
    88  		}
    89  	}
    90  	hex.Decode(out, raw)
    91  	return nil
    92  }
    93  
    94  // Big marshals/unmarshals as a JSON string with 0x prefix. The zero value marshals as
    95  // "0x0". Negative integers are not supported at this time. Attempting to marshal them
    96  // will return an error.
    97  type Big big.Int
    98  
    99  // MarshalJSON implements json.Marshaler.
   100  func (b *Big) MarshalJSON() ([]byte, error) {
   101  	if b == nil {
   102  		return jsonNull, nil
   103  	}
   104  	bigint := (*big.Int)(b)
   105  	if bigint.Sign() == -1 {
   106  		return nil, errNegativeBigInt
   107  	}
   108  	nbits := bigint.BitLen()
   109  	if nbits == 0 {
   110  		return jsonZero, nil
   111  	}
   112  	enc := fmt.Sprintf(`"0x%x"`, bigint)
   113  	return []byte(enc), nil
   114  }
   115  
   116  // UnmarshalJSON implements json.Unmarshaler.
   117  func (b *Big) UnmarshalJSON(input []byte) error {
   118  	raw, err := checkNumberJSON(input)
   119  	if err != nil {
   120  		return err
   121  	}
   122  	words := make([]big.Word, len(raw)/bigWordNibbles+1)
   123  	end := len(raw)
   124  	for i := range words {
   125  		start := end - bigWordNibbles
   126  		if start < 0 {
   127  			start = 0
   128  		}
   129  		for ri := start; ri < end; ri++ {
   130  			nib := decodeNibble(raw[ri])
   131  			if nib == badNibble {
   132  				return ErrSyntax
   133  			}
   134  			words[i] *= 16
   135  			words[i] += big.Word(nib)
   136  		}
   137  		end = start
   138  	}
   139  	var dec big.Int
   140  	dec.SetBits(words)
   141  	*b = (Big)(dec)
   142  	return nil
   143  }
   144  
   145  // ToInt converts b to a big.Int.
   146  func (b *Big) ToInt() *big.Int {
   147  	return (*big.Int)(b)
   148  }
   149  
   150  // String returns the hex encoding of b.
   151  func (b *Big) String() string {
   152  	return EncodeBig(b.ToInt())
   153  }
   154  
   155  // Uint64 marshals/unmarshals as a JSON string with 0x prefix.
   156  // The zero value marshals as "0x0".
   157  type Uint64 uint64
   158  
   159  // MarshalJSON implements json.Marshaler.
   160  func (b Uint64) MarshalJSON() ([]byte, error) {
   161  	buf := make([]byte, 3, 12)
   162  	copy(buf, `"0x`)
   163  	buf = strconv.AppendUint(buf, uint64(b), 16)
   164  	buf = append(buf, '"')
   165  	return buf, nil
   166  }
   167  
   168  // UnmarshalJSON implements json.Unmarshaler.
   169  func (b *Uint64) UnmarshalJSON(input []byte) error {
   170  	raw, err := checkNumberJSON(input)
   171  	if err != nil {
   172  		return err
   173  	}
   174  	if len(raw) > 16 {
   175  		return ErrUint64Range
   176  	}
   177  	var dec uint64
   178  	for _, byte := range raw {
   179  		nib := decodeNibble(byte)
   180  		if nib == badNibble {
   181  			return ErrSyntax
   182  		}
   183  		dec *= 16
   184  		dec += uint64(nib)
   185  	}
   186  	*b = Uint64(dec)
   187  	return nil
   188  }
   189  
   190  // String returns the hex encoding of b.
   191  func (b Uint64) String() string {
   192  	return EncodeUint64(uint64(b))
   193  }
   194  
   195  // Uint marshals/unmarshals as a JSON string with 0x prefix.
   196  // The zero value marshals as "0x0".
   197  type Uint uint
   198  
   199  // MarshalJSON implements json.Marshaler.
   200  func (b Uint) MarshalJSON() ([]byte, error) {
   201  	return Uint64(b).MarshalJSON()
   202  }
   203  
   204  // UnmarshalJSON implements json.Unmarshaler.
   205  func (b *Uint) UnmarshalJSON(input []byte) error {
   206  	var u64 Uint64
   207  	err := u64.UnmarshalJSON(input)
   208  	if err != nil {
   209  		return err
   210  	} else if u64 > Uint64(^uint(0)) {
   211  		return ErrUintRange
   212  	}
   213  	*b = Uint(u64)
   214  	return nil
   215  }
   216  
   217  // String returns the hex encoding of b.
   218  func (b Uint) String() string {
   219  	return EncodeUint64(uint64(b))
   220  }
   221  
   222  func isString(input []byte) bool {
   223  	return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"'
   224  }
   225  
   226  func bytesHave0xPrefix(input []byte) bool {
   227  	return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X')
   228  }
   229  
   230  func checkJSON(input []byte) (raw []byte, err error) {
   231  	if !isString(input) {
   232  		return nil, errNonString
   233  	}
   234  	if len(input) == 2 {
   235  		return nil, nil // empty strings are allowed
   236  	}
   237  	if !bytesHave0xPrefix(input[1:]) {
   238  		return nil, ErrMissingPrefix
   239  	}
   240  	input = input[3 : len(input)-1]
   241  	if len(input)%2 != 0 {
   242  		return nil, ErrOddLength
   243  	}
   244  	return input, nil
   245  }
   246  
   247  func checkNumberJSON(input []byte) (raw []byte, err error) {
   248  	if !isString(input) {
   249  		return nil, errNonString
   250  	}
   251  	input = input[1 : len(input)-1]
   252  	if len(input) == 0 {
   253  		return nil, nil // empty strings are allowed
   254  	}
   255  	if !bytesHave0xPrefix(input) {
   256  		return nil, ErrMissingPrefix
   257  	}
   258  	input = input[2:]
   259  	if len(input) == 0 {
   260  		return nil, ErrEmptyNumber
   261  	}
   262  	if len(input) > 1 && input[0] == '0' {
   263  		return nil, ErrLeadingZero
   264  	}
   265  	return input, nil
   266  }