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  }