github.com/mavryk-network/mvgo@v1.19.9/mavryk/utils.go (about) 1 // Copyright (c) 2020-2022 Blockwatch Data Inc. 2 // Author: alex@blockwatch.cc 3 4 package mavryk 5 6 import ( 7 "encoding/hex" 8 "fmt" 9 "io" 10 "sync" 11 ) 12 13 // HexBytes represents bytes as a JSON string of hexadecimal digits 14 type HexBytes []byte 15 16 // UnmarshalText umarshals a hex string to bytes. It implements the 17 // encoding.TextUnmarshaler interface, so that HexBytes can be used in Go 18 // structs in combination with the standard JSON library. 19 func (h *HexBytes) UnmarshalText(data []byte) error { 20 dst := make([]byte, hex.DecodedLen(len(data))) 21 if _, err := hex.Decode(dst, data); err != nil { 22 return err 23 } 24 *h = dst 25 return nil 26 } 27 28 // ReadBytes copies size bytes from r into h. If h is nil or too short, 29 // a new byte slice is allocated. Fails with io.ErrShortBuffer when 30 // less than size bytes can be read from r. 31 func (h *HexBytes) ReadBytes(r io.Reader, size int) error { 32 if cap(*h) < size { 33 *h = make([]byte, size) 34 } else { 35 *h = (*h)[:size] 36 } 37 n, err := r.Read(*h) 38 if err != nil { 39 return err 40 } 41 if n < size { 42 return io.ErrShortBuffer 43 } 44 return nil 45 } 46 47 // MarshalText converts a byte slice to a hex encoded string. It implements the 48 // encoding.TextMarshaler interface, so that HexBytes can be used in Go 49 // structs in combination with the standard JSON library. 50 func (h HexBytes) MarshalText() ([]byte, error) { 51 return []byte(hex.EncodeToString(h)), nil 52 } 53 54 // String converts a byte slice to a hex encoded string 55 func (h HexBytes) String() string { 56 return hex.EncodeToString(h) 57 } 58 59 // Bytes type-casts HexBytes back to a byte slice 60 func (h HexBytes) Bytes() []byte { 61 return []byte(h) 62 } 63 64 // UnmarshalBinary umarshals a binary slice. It implements the 65 // encoding.BinaryUnmarshaler interface. 66 func (h *HexBytes) UnmarshalBinary(data []byte) error { 67 if cap(*h) < len(data) { 68 *h = make([]byte, len(data)) 69 } 70 *h = (*h)[:len(data)] 71 copy(*h, data) 72 return nil 73 } 74 75 // MarshalBinary marshals as binary slice. It implements the 76 // encoding.BinaryMarshaler interface. 77 func (h HexBytes) MarshalBinary() ([]byte, error) { 78 return h, nil 79 } 80 81 // Ratio represents a numeric ratio used in Ithaca constants 82 type Ratio struct { 83 Num int `json:"numerator"` 84 Den int `json:"denominator"` 85 } 86 87 func (r Ratio) Float64() float64 { 88 if r.Den == 0 { 89 return 0 90 } 91 return float64(r.Num) / float64(r.Den) 92 } 93 94 func Short(v any) string { 95 var s string 96 if str, ok := v.(fmt.Stringer); ok { 97 s = str.String() 98 } else { 99 s = v.(string) 100 } 101 if len(s) <= 12 { 102 return s 103 } 104 return s[:8] + "..." + s[len(s)-4:] 105 } 106 107 func panicOnError(err error) { 108 if err != nil { 109 panic(err) 110 } 111 } 112 113 func b2i(b bool) (i int) { 114 // The compiler currently only optimizes this form into movzbl. 115 // See https://0x0f.me/blog/golang-compiler-optimization/ 116 // See issue 6011. 117 if b { 118 i = 1 119 } 120 return 121 } 122 123 var bufPool32 = &sync.Pool{ 124 New: func() any { return make([]byte, 32) }, 125 }