github.com/ledgerwatch/erigon-lib@v1.0.0/common/bytes64.go (about)

     1  package common
     2  
     3  import (
     4  	"bytes"
     5  	"database/sql/driver"
     6  	"encoding/hex"
     7  	"fmt"
     8  	"reflect"
     9  
    10  	"github.com/ledgerwatch/erigon-lib/common/hexutility"
    11  	"github.com/ledgerwatch/erigon-lib/common/length"
    12  )
    13  
    14  var (
    15  	bytes64T = reflect.TypeOf(Bytes64{})
    16  )
    17  
    18  type Bytes64 [length.Bytes64]byte
    19  
    20  // Hex converts a hash to a hex string.
    21  func (b Bytes64) Hex() string { return hexutility.Encode(b[:]) }
    22  
    23  // UnmarshalJSON parses a hash in hex syntax.
    24  func (b *Bytes64) UnmarshalJSON(input []byte) error {
    25  	return hexutility.UnmarshalFixedJSON(bytes64T, input, b[:])
    26  }
    27  
    28  // UnmarshalText parses a hash in hex syntax.
    29  func (b *Bytes64) UnmarshalText(input []byte) error {
    30  	return hexutility.UnmarshalFixedText("Bytes64", input, b[:])
    31  }
    32  
    33  // MarshalText returns the hex representation of a.
    34  func (b Bytes64) MarshalText() ([]byte, error) {
    35  	bl := b[:]
    36  	result := make([]byte, len(b)*2+2)
    37  	copy(result, hexPrefix)
    38  	hex.Encode(result[2:], bl)
    39  	return result, nil
    40  }
    41  
    42  // Format implements fmt.Formatter.
    43  // Hash supports the %v, %s, %v, %x, %X and %d format verbs.
    44  func (b Bytes64) Format(s fmt.State, c rune) {
    45  	hexb := make([]byte, 2+len(b)*2)
    46  	copy(hexb, "0x")
    47  	hex.Encode(hexb[2:], b[:])
    48  
    49  	switch c {
    50  	case 'x', 'X':
    51  		if !s.Flag('#') {
    52  			hexb = hexb[2:]
    53  		}
    54  		if c == 'X' {
    55  			hexb = bytes.ToUpper(hexb)
    56  		}
    57  		fallthrough
    58  	case 'v', 's':
    59  		s.Write(hexb)
    60  	case 'q':
    61  		q := []byte{'"'}
    62  		s.Write(q)
    63  		s.Write(hexb)
    64  		s.Write(q)
    65  	case 'd':
    66  		fmt.Fprint(s, ([len(b)]byte)(b))
    67  	default:
    68  		fmt.Fprintf(s, "%%!%c(hash=%x)", c, b)
    69  	}
    70  }
    71  
    72  // String implements the stringer interface and is used also by the logger when
    73  // doing full logging into a file.
    74  func (b Bytes64) String() string {
    75  	return b.Hex()
    76  }
    77  
    78  // SetBytes sets the hash to the value of i.
    79  // If b is larger than len(h), b will be cropped from the left.
    80  func (b *Bytes64) SetBytes(i []byte) {
    81  	if len(i) > len(b) {
    82  		i = i[len(i)-length.Hash:]
    83  	}
    84  
    85  	copy(b[length.Hash-len(i):], i)
    86  }
    87  
    88  // Value implements valuer for database/sql.
    89  func (b Bytes64) Value() (driver.Value, error) {
    90  	return b[:], nil
    91  }
    92  
    93  // TerminalString implements log.TerminalStringer, formatting a string for console
    94  // output during logging.
    95  func (b Bytes64) TerminalString() string {
    96  	return fmt.Sprintf("%x…%x", b[:3], b[len(b)-3:])
    97  }