cosmos-sdk/collections/codec/int.go

124 lines
2.9 KiB
Go

package codec
import (
"encoding/binary"
"encoding/json"
"fmt"
"strconv"
)
func NewInt64Key[T ~int64]() KeyCodec[T] { return int64Key[T]{} }
type int64Key[T ~int64] struct{}
func (i int64Key[T]) Encode(buffer []byte, key T) (int, error) {
binary.BigEndian.PutUint64(buffer, (uint64)(key))
buffer[0] ^= 0x80
return 8, nil
}
func (i int64Key[T]) Decode(buffer []byte) (int, T, error) {
if len(buffer) < 8 {
return 0, 0, fmt.Errorf("%w: invalid buffer size, wanted: 8", ErrEncoding)
}
u := uint64(buffer[7]) | uint64(buffer[6])<<8 | uint64(buffer[5])<<16 | uint64(buffer[4])<<24 |
uint64(buffer[3])<<32 | uint64(buffer[2])<<40 | uint64(buffer[1])<<48 | uint64(buffer[0]^0x80)<<56
return 8, (T)(u), nil
}
func (i int64Key[T]) Size(_ T) int { return 8 }
func (i int64Key[T]) EncodeJSON(value T) ([]byte, error) {
return []byte(`"` + strconv.FormatInt((int64)(value), 10) + `"`), nil
}
func (i int64Key[T]) DecodeJSON(b []byte) (T, error) {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return 0, err
}
k, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return 0, err
}
return (T)(k), nil
}
func (i int64Key[T]) Stringify(key T) string { return strconv.FormatInt((int64)(key), 10) }
func (i int64Key[T]) KeyType() string {
return "int64"
}
func (i int64Key[T]) EncodeNonTerminal(buffer []byte, key T) (int, error) {
return i.Encode(buffer, key)
}
func (i int64Key[T]) DecodeNonTerminal(buffer []byte) (int, T, error) {
return i.Decode(buffer)
}
func (i int64Key[T]) SizeNonTerminal(_ T) int {
return 8
}
func NewInt32Key[T ~int32]() KeyCodec[T] {
return int32Key[T]{}
}
type int32Key[T ~int32] struct{}
func (i int32Key[T]) Encode(buffer []byte, key T) (int, error) {
binary.BigEndian.PutUint32(buffer, (uint32)(key))
buffer[0] ^= 0x80
return 4, nil
}
func (i int32Key[T]) Decode(buffer []byte) (int, T, error) {
if len(buffer) < 4 {
return 0, 0, fmt.Errorf("%w: invalid buffer size, wanted: 4", ErrEncoding)
}
u := uint32(buffer[3]) | uint32(buffer[2])<<8 | uint32(buffer[1])<<16 | uint32(buffer[0]^0x80)<<24
return 4, (T)(u), nil
}
func (i int32Key[T]) Size(_ T) int { return 4 }
func (i int32Key[T]) EncodeJSON(value T) ([]byte, error) {
return []byte(`"` + strconv.FormatInt((int64)(value), 10) + `"`), nil
}
func (i int32Key[T]) DecodeJSON(b []byte) (T, error) {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return 0, err
}
k, err := strconv.ParseInt(s, 10, 32)
if err != nil {
return 0, err
}
return (T)(k), nil
}
func (i int32Key[T]) Stringify(key T) string { return strconv.FormatInt((int64)(key), 10) }
func (i int32Key[T]) KeyType() string {
return "int32"
}
func (i int32Key[T]) EncodeNonTerminal(buffer []byte, key T) (int, error) {
return i.Encode(buffer, key)
}
func (i int32Key[T]) DecodeNonTerminal(buffer []byte) (int, T, error) {
return i.Decode(buffer)
}
func (i int32Key[T]) SizeNonTerminal(_ T) int {
return 4
}