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 }