github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/amino/decoder.go (about) 1 package amino 2 3 import ( 4 "encoding/binary" 5 "errors" 6 "fmt" 7 "math" 8 "time" 9 ) 10 11 // ---------------------------------------- 12 // Signed 13 14 func DecodeVarint8(bz []byte) (i int8, n int, err error) { 15 i64, n, err := DecodeVarint(bz) 16 if err != nil { 17 return 18 } 19 if i64 < int64(math.MinInt8) || i64 > int64(math.MaxInt8) { 20 err = errors.New("EOF decoding int8") 21 return 22 } 23 i = int8(i64) 24 return 25 } 26 27 func DecodeVarint16(bz []byte) (i int16, n int, err error) { 28 i64, n, err := DecodeVarint(bz) 29 if err != nil { 30 return 31 } 32 if i64 < int64(math.MinInt16) || i64 > int64(math.MaxInt16) { 33 err = errors.New("EOF decoding int16") 34 return 35 } 36 i = int16(i64) 37 return 38 } 39 40 func DecodeVarint(bz []byte) (i int64, n int, err error) { 41 i, n = binary.Varint(bz) 42 if n == 0 { 43 // buf too small 44 err = errors.New("buffer too small") 45 } else if n < 0 { 46 // value larger than 64 bits (overflow) 47 // and -n is the number of bytes read 48 n = -n 49 err = errors.New("EOF decoding varint") 50 } 51 return 52 } 53 54 func DecodeInt32(bz []byte) (i int32, n int, err error) { 55 const size int = 4 56 if len(bz) < size { 57 err = errors.New("EOF decoding int32") 58 return 59 } 60 i = int32(binary.LittleEndian.Uint32(bz[:size])) 61 n = size 62 return 63 } 64 65 func DecodeInt64(bz []byte) (i int64, n int, err error) { 66 const size int = 8 67 if len(bz) < size { 68 err = errors.New("EOF decoding int64") 69 return 70 } 71 i = int64(binary.LittleEndian.Uint64(bz[:size])) 72 n = size 73 return 74 } 75 76 // ---------------------------------------- 77 // Unsigned 78 79 func DecodeByte(bz []byte) (b byte, n int, err error) { 80 if len(bz) == 0 { 81 err = errors.New("EOF decoding byte") 82 return 83 } 84 b = bz[0] 85 n = 1 86 return 87 } 88 89 func DecodeUvarint8(bz []byte) (u uint8, n int, err error) { 90 u64, n, err := DecodeUvarint(bz) 91 if err != nil { 92 return 93 } 94 if u64 > uint64(math.MaxUint8) { 95 err = errors.New("EOF decoding uint8") 96 return 97 } 98 u = uint8(u64) 99 return 100 } 101 102 func DecodeUvarint16(bz []byte) (u uint16, n int, err error) { 103 u64, n, err := DecodeUvarint(bz) 104 if err != nil { 105 return 106 } 107 if u64 > uint64(math.MaxUint16) { 108 err = errors.New("EOF decoding uint16") 109 return 110 } 111 u = uint16(u64) 112 return 113 } 114 115 func DecodeUvarint32(bz []byte) (u uint32, n int, err error) { 116 u64, n, err := DecodeUvarint(bz) 117 if err != nil { 118 return 119 } 120 if u64 > uint64(math.MaxUint32) { 121 err = errors.New("EOF decoding uint32") 122 return 123 } 124 u = uint32(u64) 125 return 126 } 127 128 func DecodeUvarint(bz []byte) (u uint64, n int, err error) { 129 u, n = binary.Uvarint(bz) 130 if n == 0 { 131 // buf too small 132 err = errors.New("buffer too small") 133 } else if n < 0 { 134 // value larger than 64 bits (overflow) 135 // and -n is the number of bytes read 136 n = -n 137 err = errors.New("EOF decoding uvarint") 138 } 139 return 140 } 141 142 func DecodeUint32(bz []byte) (u uint32, n int, err error) { 143 const size int = 4 144 if len(bz) < size { 145 err = errors.New("EOF decoding uint32") 146 return 147 } 148 u = binary.LittleEndian.Uint32(bz[:size]) 149 n = size 150 return 151 } 152 153 func DecodeUint64(bz []byte) (u uint64, n int, err error) { 154 const size int = 8 155 if len(bz) < size { 156 err = errors.New("EOF decoding uint64") 157 return 158 } 159 u = binary.LittleEndian.Uint64(bz[:size]) 160 n = size 161 return 162 } 163 164 // ---------------------------------------- 165 // Other Primitives 166 167 func DecodeBool(bz []byte) (b bool, n int, err error) { 168 const size int = 1 169 if len(bz) < size { 170 err = errors.New("EOF decoding bool") 171 return 172 } 173 switch bz[0] { 174 case 0: 175 b = false 176 case 1: 177 b = true 178 default: 179 err = errors.New("invalid bool") 180 } 181 n = size 182 return 183 } 184 185 // NOTE: UNSAFE 186 func DecodeFloat32(bz []byte) (f float32, n int, err error) { 187 const size int = 4 188 if len(bz) < size { 189 err = errors.New("EOF decoding float32") 190 return 191 } 192 i := binary.LittleEndian.Uint32(bz[:size]) 193 f = math.Float32frombits(i) 194 n = size 195 return 196 } 197 198 // NOTE: UNSAFE 199 func DecodeFloat64(bz []byte) (f float64, n int, err error) { 200 const size int = 8 201 if len(bz) < size { 202 err = errors.New("EOF decoding float64") 203 return 204 } 205 i := binary.LittleEndian.Uint64(bz[:size]) 206 f = math.Float64frombits(i) 207 n = size 208 return 209 } 210 211 // ---------------------------------------- 212 // Time and Duration 213 214 // DecodeTimeValue decodes seconds (int64) and nanoseconds (int32) since January 1, 215 // 1970 UTC, and returns the corresponding time. If nanoseconds is not in the 216 // range [0, 999999999], or if seconds is too large, an error is returned. 217 func DecodeTimeValue(bz []byte) (s int64, ns int32, n int, err error) { 218 // Read sec and nanosec. 219 s, n, err = decodeSeconds(&bz) 220 if err != nil { 221 return 222 } 223 ns, err = decodeNanos(&bz, &n) 224 if err != nil { 225 return 226 } 227 // Validations 228 err = validateTimeValue(s, ns) 229 if err != nil { 230 return 231 } 232 return 233 } 234 235 func DecodeTime(bz []byte) (t time.Time, n int, err error) { 236 // Defensively set default to to emptyTime (1970, not 0001) 237 t = emptyTime 238 s, ns, n, err := DecodeTimeValue(bz) 239 if err != nil { 240 return 241 } 242 // Construct time. 243 t = time.Unix(s, int64(ns)) 244 // Strip timezone and monotonic for deep equality. 245 t = t.UTC().Truncate(0) 246 return 247 } 248 249 func DecodeDurationValue(bz []byte) (s int64, ns int32, n int, err error) { 250 // Read sec and nanosec. 251 s, n, err = decodeSeconds(&bz) 252 if err != nil { 253 return 254 } 255 ns, err = decodeNanos(&bz, &n) 256 if err != nil { 257 return 258 } 259 // Validations 260 err = validateDurationValue(s, ns) 261 if err != nil { 262 return 263 } 264 return 265 } 266 267 func DecodeDuration(bz []byte) (d time.Duration, n int, err error) { 268 // Defensively set default to to zeroDuration 269 s, ns, n, err := DecodeDurationValue(bz) 270 if err != nil { 271 return 272 } 273 // Validations 274 err = validateDurationValueGo(s, ns) 275 if err != nil { 276 return 277 } 278 // Construct Duration. 279 d = time.Duration(s*1e9 + int64(ns)) 280 return 281 } 282 283 // If bz is empty, returns err=nil. 284 // Does not validate. 285 func decodeSeconds(bz *[]byte) (int64, int, error) { 286 if len(*bz) == 0 { 287 return 0, 0, nil 288 } 289 // Optionally decode field number 1 and Typ3 (8Byte). 290 // only slide if we need to: 291 var n int 292 fieldNum, typ, _n, err := decodeFieldNumberAndTyp3(*bz) 293 if err != nil { 294 return 0, n, err 295 } 296 switch { 297 case fieldNum == 1 && typ == Typ3Varint: 298 slide(bz, &n, _n) 299 sec, _n, err := DecodeUvarint(*bz) 300 if slide(bz, &n, _n) && err != nil { 301 return 0, n, err 302 } 303 // if seconds where negative before casting them to uint64, we yield 304 // the original signed value: 305 res := int64(sec) 306 return res, n, err 307 case fieldNum == 2 && typ == Typ3Varint: 308 // skip: do not slide, no error, will read again 309 return 0, n, nil 310 default: 311 return 0, n, fmt.Errorf("expected field number 1 <Varint> or field number 2 <Varint> , got %v", fieldNum) 312 } 313 } 314 315 // If bz is empty, returns err=nil. 316 // Validates whether ns is in range, but caller may want to check for non-negativity. 317 func decodeNanos(bz *[]byte, n *int) (int32, error) { 318 if len(*bz) == 0 { 319 return 0, nil 320 } 321 // Optionally decode field number 2 and Typ3 (4Byte). 322 fieldNum, typ, _n, err := decodeFieldNumberAndTyp3(*bz) 323 if err != nil { 324 return 0, err 325 } 326 if fieldNum == 2 && typ == Typ3Varint { 327 slide(bz, n, _n) 328 nsec_, _n, err := DecodeUvarint(*bz) 329 if slide(bz, n, _n) && err != nil { 330 return 0, err 331 } 332 nsec := int64(nsec_) 333 // Validation check. 334 if 1e9 <= nsec || nsec <= -1e9 { 335 return 0, InvalidTimeError(fmt.Sprintf("nanoseconds not in interval [-999999999, 999999999] %v", nsec)) 336 } 337 // this cast from uint64 to int32 is OK, due to above restriction: 338 return int32(nsec), nil 339 } 340 // skip over (no error) 341 return 0, nil 342 } 343 344 // ---------------------------------------- 345 // Byte Slices and Strings 346 347 func DecodeByteSlice(bz []byte) (bz2 []byte, n int, err error) { 348 var count uint64 349 var _n int 350 count, _n, err = DecodeUvarint(bz) 351 if slide(&bz, &n, _n) && err != nil { 352 return 353 } 354 if int(count) < 0 { 355 err = fmt.Errorf("invalid negative length %v decoding []byte", count) 356 return 357 } 358 if len(bz) < int(count) { 359 err = fmt.Errorf("insufficient bytes decoding []byte of length %v: %X", count, bz) 360 return 361 } 362 bz2 = make([]byte, count) 363 copy(bz2, bz[0:count]) 364 n += int(count) 365 return 366 } 367 368 func DecodeString(bz []byte) (s string, n int, err error) { 369 var bz2 []byte 370 bz2, n, err = DecodeByteSlice(bz) 371 s = string(bz2) 372 return 373 }