-
Notifications
You must be signed in to change notification settings - Fork 244
/
hex.go
58 lines (50 loc) · 1.47 KB
/
hex.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/hexutil/hexutil.go
package types
import (
"encoding/hex"
"fmt"
"reflect"
)
var (
bytesT = reflect.TypeOf(HexBytes(nil))
)
// HexBytes marshals/unmarshals as a JSON string with 0x prefix.
// The empty slice marshals as "0x".
type HexBytes []byte
func (b HexBytes) Bytes() []byte {
result := make([]byte, len(b)*2+2)
copy(result, `0x`)
hex.Encode(result[2:], b)
return result
}
// MarshalText implements encoding.TextMarshaler
func (b HexBytes) MarshalText() ([]byte, error) {
return b.Bytes(), nil
}
// UnmarshalJSON implements json.Unmarshaler.
func (b *HexBytes) UnmarshalJSON(input []byte) error {
if !isString(input) {
return errNonString(bytesT)
}
return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT)
}
// UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The
// length of out determines the required input length. This function is commonly used to
// implement the UnmarshalText method for fixed-size types.
func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error {
raw, err := checkText(input, false)
if err != nil {
return err
}
if len(raw)/2 != len(out) {
return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
}
// Pre-verify syntax before modifying out.
for _, b := range raw {
if decodeNibble(b) == badNibble {
return ErrSyntax
}
}
_, err = hex.Decode(out, raw)
return err
}