github.com/annchain/OG@v0.0.9/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 "encoding/json" 22 "fmt" 23 "math/big" 24 "reflect" 25 "strconv" 26 ) 27 28 //go:generate msgp 29 var ( 30 bytesT = reflect.TypeOf(Bytes(nil)) 31 bigT = reflect.TypeOf((*Big)(nil)) 32 uintT = reflect.TypeOf(Uint(0)) 33 uint64T = reflect.TypeOf(Uint64(0)) 34 ) 35 36 // KeyBytes marshals/unmarshals as a JSON string with 0x prefix. 37 // The empty slice marshals as "0x". 38 //msgp:tuple KeyBytes 39 type Bytes []byte 40 41 // MarshalText implements encoding.TextMarshaler 42 func (b Bytes) MarshalText() ([]byte, error) { 43 result := make([]byte, len(b)*2+2) 44 copy(result, `0x`) 45 hex.Encode(result[2:], b) 46 return result, nil 47 } 48 49 func (b Bytes) MarshalJson() ([]byte, error) { 50 s := b.String() 51 return json.Marshal(&s) 52 } 53 54 // UnmarshalJSON implements json.Unmarshaler. 55 func (b *Bytes) UnmarshalJSON(input []byte) error { 56 if !isString(input) { 57 return errNonString(bytesT) 58 } 59 return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT) 60 } 61 62 // UnmarshalText implements encoding.TextUnmarshaler. 63 func (b *Bytes) UnmarshalText(input []byte) error { 64 raw, err := checkText(input, true) 65 if err != nil { 66 return err 67 } 68 dec := make([]byte, len(raw)/2) 69 if _, err = hex.Decode(dec, raw); err != nil { 70 err = mapError(err) 71 } else { 72 *b = dec 73 } 74 return err 75 } 76 77 // String returns the hex encoding of b. 78 func (b Bytes) String() string { 79 return Encode(b) 80 } 81 82 // UnmarshalFixedJSON decodes the input as a string with 0x prefix. The length of out 83 // determines the required input length. This function is commonly used to implement the 84 // UnmarshalJSON method for fixed-size types. 85 func UnmarshalFixedJSON(typ reflect.Type, input, out []byte) error { 86 if !isString(input) { 87 return errNonString(typ) 88 } 89 return wrapTypeError(UnmarshalFixedText(typ.String(), input[1:len(input)-1], out), typ) 90 } 91 92 // UnmarshalFixedText decodes the input as a string with 0x prefix. The length of out 93 // determines the required input length. This function is commonly used to implement the 94 // UnmarshalText method for fixed-size types. 95 func UnmarshalFixedText(typname string, input, out []byte) error { 96 raw, err := checkText(input, true) 97 if err != nil { 98 return err 99 } 100 if len(raw)/2 != len(out) { 101 return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname) 102 } 103 // Pre-verify syntax before modifying out. 104 for _, b := range raw { 105 if decodeNibble(b) == badNibble { 106 return ErrSyntax 107 } 108 } 109 hex.Decode(out, raw) 110 return nil 111 } 112 113 // UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The 114 // length of out determines the required input length. This function is commonly used to 115 // implement the UnmarshalText method for fixed-size types. 116 func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error { 117 raw, err := checkText(input, false) 118 if err != nil { 119 return err 120 } 121 if len(raw)/2 != len(out) { 122 return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname) 123 } 124 // Pre-verify syntax before modifying out. 125 for _, b := range raw { 126 if decodeNibble(b) == badNibble { 127 return ErrSyntax 128 } 129 } 130 hex.Decode(out, raw) 131 return nil 132 } 133 134 // Big marshals/unmarshals as a JSON string with 0x prefix. 135 // The zero value marshals as "0x0". 136 // 137 // Negative integers are not supported at this time. Attempting to marshal them will 138 // return an error. Values larger than 256bits are rejected by Unmarshal but will be 139 // marshaled without error. 140 type Big big.Int 141 142 // MarshalText implements encoding.TextMarshaler 143 func (b Big) MarshalText() ([]byte, error) { 144 return []byte(EncodeBig((*big.Int)(&b))), nil 145 } 146 147 // UnmarshalJSON implements json.Unmarshaler. 148 func (b *Big) UnmarshalJSON(input []byte) error { 149 if !isString(input) { 150 return errNonString(bigT) 151 } 152 return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bigT) 153 } 154 155 // UnmarshalText implements encoding.TextUnmarshaler 156 func (b *Big) UnmarshalText(input []byte) error { 157 raw, err := checkNumberText(input) 158 if err != nil { 159 return err 160 } 161 if len(raw) > 64 { 162 return ErrBig256Range 163 } 164 words := make([]big.Word, len(raw)/bigWordNibbles+1) 165 end := len(raw) 166 for i := range words { 167 start := end - bigWordNibbles 168 if start < 0 { 169 start = 0 170 } 171 for ri := start; ri < end; ri++ { 172 nib := decodeNibble(raw[ri]) 173 if nib == badNibble { 174 return ErrSyntax 175 } 176 words[i] *= 16 177 words[i] += big.Word(nib) 178 } 179 end = start 180 } 181 var dec big.Int 182 dec.SetBits(words) 183 *b = (Big)(dec) 184 return nil 185 } 186 187 // ToInt converts b to a big.Int. 188 func (b *Big) ToInt() *big.Int { 189 return (*big.Int)(b) 190 } 191 192 // String returns the hex encoding of b. 193 func (b *Big) String() string { 194 return EncodeBig(b.ToInt()) 195 } 196 197 // Uint64 marshals/unmarshals as a JSON string with 0x prefix. 198 // The zero value marshals as "0x0". 199 type Uint64 uint64 200 201 // MarshalText implements encoding.TextMarshaler. 202 func (b Uint64) MarshalText() ([]byte, error) { 203 buf := make([]byte, 2, 10) 204 copy(buf, `0x`) 205 buf = strconv.AppendUint(buf, uint64(b), 16) 206 return buf, nil 207 } 208 209 // UnmarshalJSON implements json.Unmarshaler. 210 func (b *Uint64) UnmarshalJSON(input []byte) error { 211 if !isString(input) { 212 return errNonString(uint64T) 213 } 214 return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uint64T) 215 } 216 217 // UnmarshalText implements encoding.TextUnmarshaler 218 func (b *Uint64) UnmarshalText(input []byte) error { 219 raw, err := checkNumberText(input) 220 if err != nil { 221 return err 222 } 223 if len(raw) > 16 { 224 return ErrUint64Range 225 } 226 var dec uint64 227 for _, byte := range raw { 228 nib := decodeNibble(byte) 229 if nib == badNibble { 230 return ErrSyntax 231 } 232 dec *= 16 233 dec += nib 234 } 235 *b = Uint64(dec) 236 return nil 237 } 238 239 // String returns the hex encoding of b. 240 func (b Uint64) String() string { 241 return EncodeUint64(uint64(b)) 242 } 243 244 // Uint marshals/unmarshals as a JSON string with 0x prefix. 245 // The zero value marshals as "0x0". 246 type Uint uint 247 248 // MarshalText implements encoding.TextMarshaler. 249 func (b Uint) MarshalText() ([]byte, error) { 250 return Uint64(b).MarshalText() 251 } 252 253 // UnmarshalJSON implements json.Unmarshaler. 254 func (b *Uint) UnmarshalJSON(input []byte) error { 255 if !isString(input) { 256 return errNonString(uintT) 257 } 258 return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uintT) 259 } 260 261 // UnmarshalText implements encoding.TextUnmarshaler. 262 func (b *Uint) UnmarshalText(input []byte) error { 263 var u64 Uint64 264 err := u64.UnmarshalText(input) 265 if u64 > Uint64(^uint(0)) || err == ErrUint64Range { 266 return ErrUintRange 267 } else if err != nil { 268 return err 269 } 270 *b = Uint(u64) 271 return nil 272 } 273 274 // String returns the hex encoding of b. 275 func (b Uint) String() string { 276 return EncodeUint64(uint64(b)) 277 } 278 279 func isString(input []byte) bool { 280 return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' 281 } 282 283 func bytesHave0xPrefix(input []byte) bool { 284 return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X') 285 } 286 287 func checkText(input []byte, wantPrefix bool) ([]byte, error) { 288 if len(input) == 0 { 289 return nil, nil // empty strings are allowed 290 } 291 if bytesHave0xPrefix(input) { 292 input = input[2:] 293 } else if wantPrefix { 294 return nil, ErrMissingPrefix 295 } 296 if len(input)%2 != 0 { 297 return nil, ErrOddLength 298 } 299 return input, nil 300 } 301 302 func checkNumberText(input []byte) (raw []byte, err error) { 303 if len(input) == 0 { 304 return nil, nil // empty strings are allowed 305 } 306 if !bytesHave0xPrefix(input) { 307 return nil, ErrMissingPrefix 308 } 309 input = input[2:] 310 if len(input) == 0 { 311 return nil, ErrEmptyNumber 312 } 313 if len(input) > 1 && input[0] == '0' { 314 return nil, ErrLeadingZero 315 } 316 return input, nil 317 } 318 319 func wrapTypeError(err error, typ reflect.Type) error { 320 if _, ok := err.(*decError); ok { 321 return &json.UnmarshalTypeError{Value: err.Error(), Type: typ} 322 } 323 return err 324 } 325 326 func errNonString(typ reflect.Type) error { 327 return &json.UnmarshalTypeError{Value: "non-string", Type: typ} 328 }