github.com/number571/tendermint@v0.34.11-gost/libs/bytes/bytes.go (about) 1 package bytes 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "encoding/json" 7 "fmt" 8 "strings" 9 ) 10 11 // HexBytes enables HEX-encoding for json/encoding. 12 type HexBytes []byte 13 14 var ( 15 _ json.Marshaler = HexBytes{} 16 _ json.Unmarshaler = &HexBytes{} 17 ) 18 19 // Marshal needed for protobuf compatibility 20 func (bz HexBytes) Marshal() ([]byte, error) { 21 return bz, nil 22 } 23 24 // Unmarshal needed for protobuf compatibility 25 func (bz *HexBytes) Unmarshal(data []byte) error { 26 *bz = data 27 return nil 28 } 29 30 // MarshalJSON implements the json.Marshaler interface. The hex bytes is a 31 // quoted hexadecimal encoded string. 32 func (bz HexBytes) MarshalJSON() ([]byte, error) { 33 s := strings.ToUpper(hex.EncodeToString(bz)) 34 jbz := make([]byte, len(s)+2) 35 jbz[0] = '"' 36 copy(jbz[1:], s) 37 jbz[len(jbz)-1] = '"' 38 return jbz, nil 39 } 40 41 // UnmarshalJSON implements the json.Umarshaler interface. 42 func (bz *HexBytes) UnmarshalJSON(data []byte) error { 43 if bytes.Equal(data, []byte("null")) { 44 return nil 45 } 46 47 if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' { 48 return fmt.Errorf("invalid hex string: %s", data) 49 } 50 51 bz2, err := hex.DecodeString(string(data[1 : len(data)-1])) 52 if err != nil { 53 return err 54 } 55 56 *bz = bz2 57 58 return nil 59 } 60 61 // Bytes fulfills various interfaces in light-client, etc... 62 func (bz HexBytes) Bytes() []byte { 63 return bz 64 } 65 66 func (bz HexBytes) String() string { 67 return strings.ToUpper(hex.EncodeToString(bz)) 68 } 69 70 // Format writes either address of 0th element in a slice in base 16 notation, 71 // with leading 0x (%p), or casts HexBytes to bytes and writes as hexadecimal 72 // string to s. 73 func (bz HexBytes) Format(s fmt.State, verb rune) { 74 switch verb { 75 case 'p': 76 s.Write([]byte(fmt.Sprintf("%p", bz))) 77 default: 78 s.Write([]byte(fmt.Sprintf("%X", []byte(bz)))) 79 } 80 }