github.com/gagliardetto/solana-go@v1.11.0/text/types.go (about) 1 // Copyright 2020 dfuse Platform Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package text 16 17 import ( 18 "encoding/base64" 19 "encoding/binary" 20 "encoding/hex" 21 "fmt" 22 "math/big" 23 ) 24 25 type SafeString string 26 27 func (ss SafeString) TextEncode(encoder *Encoder, option *Option) error { 28 return encoder.ToWriter(string(ss), option.indent, option.fgColor) 29 } 30 31 type Bool bool 32 33 func (b Bool) TextEncode(encoder *Encoder, option *Option) error { 34 return encoder.ToWriter(fmt.Sprintf("%t", bool(b)), option.indent, option.fgColor) 35 } 36 37 type HexBytes []byte 38 39 func (o HexBytes) TextEncode(encoder *Encoder, option *Option) error { 40 return encoder.ToWriter(hex.EncodeToString(o), option.indent, option.fgColor) 41 } 42 43 type Varint16 int16 44 45 func (o Varint16) TextEncode(encoder *Encoder, option *Option) error { 46 return encoder.ToWriter(fmt.Sprintf("%d", int(o)), option.indent, option.fgColor) 47 } 48 49 type Varuint16 uint16 50 51 func (o Varuint16) TextEncode(encoder *Encoder, option *Option) error { 52 return encoder.ToWriter(fmt.Sprintf("%d", int(o)), option.indent, option.fgColor) 53 54 } 55 56 type Varuint32 uint32 57 58 func (o Varuint32) TextEncode(encoder *Encoder, option *Option) error { 59 return encoder.ToWriter(fmt.Sprintf("%d", int(o)), option.indent, option.fgColor) 60 } 61 62 type Varint32 int32 63 64 func (o Varint32) TextEncode(encoder *Encoder, option *Option) error { 65 return encoder.ToWriter(fmt.Sprintf("%d", int(o)), option.indent, option.fgColor) 66 67 } 68 69 type JSONFloat64 float64 70 71 func (f JSONFloat64) TextEncode(encoder *Encoder, option *Option) error { 72 return encoder.ToWriter(fmt.Sprintf("%f", float64(f)), option.indent, option.fgColor) 73 } 74 75 type Int64 int64 76 77 func (i Int64) TextEncode(encoder *Encoder, option *Option) error { 78 return encoder.ToWriter(fmt.Sprintf("%d", int64(i)), option.indent, option.fgColor) 79 } 80 81 type Uint64 uint64 82 83 func (i Uint64) TextEncode(encoder *Encoder, option *Option) error { 84 return encoder.ToWriter(fmt.Sprintf("%d", uint64(i)), option.indent, option.fgColor) 85 } 86 87 // uint128 88 type Uint128 struct { 89 Lo uint64 90 Hi uint64 91 } 92 93 func (i Uint128) BigInt() *big.Int { 94 buf := make([]byte, 16) 95 binary.BigEndian.PutUint64(buf[:], i.Hi) 96 binary.BigEndian.PutUint64(buf[8:], i.Lo) 97 value := (&big.Int{}).SetBytes(buf) 98 return value 99 } 100 101 func (i Uint128) DecimalString() string { 102 return i.BigInt().String() 103 } 104 105 func (i Uint128) TextEncode(encoder *Encoder, option *Option) error { 106 return encoder.ToWriter(i.BigInt().String(), option.indent, option.fgColor) 107 } 108 109 // Int128 110 type Int128 Uint128 111 112 func (i Int128) BigInt() *big.Int { 113 comp := byte(0x80) 114 buf := make([]byte, 16) 115 binary.BigEndian.PutUint64(buf[:], i.Hi) 116 binary.BigEndian.PutUint64(buf[8:], i.Lo) 117 118 var value *big.Int 119 if (buf[0] & comp) == comp { 120 buf = twosComplement(buf) 121 value = (&big.Int{}).SetBytes(buf) 122 value = value.Neg(value) 123 } else { 124 value = (&big.Int{}).SetBytes(buf) 125 } 126 return value 127 } 128 129 func (i Int128) DecimalString() string { 130 return i.BigInt().String() 131 } 132 133 func (i Int128) TextEncode(encoder *Encoder, option *Option) error { 134 return encoder.ToWriter(i.BigInt().String(), option.indent, option.fgColor) 135 } 136 137 type Float128 Uint128 138 139 func (f Float128) TextEncode(encoder *Encoder, option *Option) error { 140 return encoder.ToWriter(Uint128(f).DecimalString(), option.indent, option.fgColor) 141 } 142 143 // Blob 144 145 // Blob is base64 encoded data 146 // https://github.com/EOSIO/fc/blob/0e74738e938c2fe0f36c5238dbc549665ddaef82/include/fc/variant.hpp#L47 147 type Blob string 148 149 // Data returns decoded base64 data 150 func (b Blob) Data() ([]byte, error) { 151 return base64.StdEncoding.DecodeString(string(b)) 152 } 153 154 // String returns the blob as a string 155 func (b Blob) String() string { 156 return string(b) 157 } 158 159 func twosComplement(v []byte) []byte { 160 buf := make([]byte, len(v)) 161 for i, b := range v { 162 buf[i] = b ^ byte(0xff) 163 } 164 one := big.NewInt(1) 165 value := (&big.Int{}).SetBytes(buf) 166 return value.Add(value, one).Bytes() 167 }