github.com/badrootd/celestia-core@v0.0.0-20240305091328-aa4207a4b25d/libs/bytes/bytes.go (about) 1 package bytes 2 3 import ( 4 "encoding/binary" 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 func (bz HexBytes) MarshalDelimited() ([]byte, error) { 20 lenBuf := make([]byte, binary.MaxVarintLen64) 21 length := uint64(len(bz)) 22 n := binary.PutUvarint(lenBuf, length) 23 24 return append(lenBuf[:n], bz...), nil 25 } 26 27 // Marshal needed for protobuf compatibility 28 func (bz HexBytes) Marshal() ([]byte, error) { 29 return bz, nil 30 } 31 32 // Unmarshal needed for protobuf compatibility 33 func (bz *HexBytes) Unmarshal(data []byte) error { 34 *bz = data 35 return nil 36 } 37 38 // This is the point of Bytes. 39 func (bz HexBytes) MarshalJSON() ([]byte, error) { 40 s := strings.ToUpper(hex.EncodeToString(bz)) 41 jbz := make([]byte, len(s)+2) 42 jbz[0] = '"' 43 copy(jbz[1:], s) 44 jbz[len(jbz)-1] = '"' 45 return jbz, nil 46 } 47 48 // This is the point of Bytes. 49 func (bz *HexBytes) UnmarshalJSON(data []byte) error { 50 if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' { 51 return fmt.Errorf("invalid hex string: %s", data) 52 } 53 bz2, err := hex.DecodeString(string(data[1 : len(data)-1])) 54 if err != nil { 55 return err 56 } 57 *bz = bz2 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 } 81 82 func FromBytes(b []byte) []HexBytes { 83 return []HexBytes{b} 84 }