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  }