serde-generate/runtime/golang/bcs/deserializer.go (64 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates
// SPDX-License-Identifier: MIT OR Apache-2.0
package bcs
import (
"bytes"
"errors"
"github.com/novifinancial/serde-reflection/serde-generate/runtime/golang/serde"
)
// Maximum length allowed for sequences (vectors, bytes, strings) and maps.
const MaxSequenceLength = (1 << 31) - 1
// Maximum number of nested structs and enum variants.
const MaxContainerDepth = 500
const maxUint32 = uint64(^uint32(0))
// `deserializer` extends `serde.BinaryDeserializer` to implement `serde.Deserializer`.
type deserializer struct {
serde.BinaryDeserializer
}
func NewDeserializer(input []byte) serde.Deserializer {
return &deserializer{*serde.NewBinaryDeserializer(input, MaxContainerDepth)}
}
// DeserializeF32 is unimplemented.
func (d *deserializer) DeserializeF32() (float32, error) {
return 0, errors.New("unimplemented")
}
// DeserializeF64 is unimplemented.
func (d *deserializer) DeserializeF64() (float64, error) {
return 0, errors.New("unimplemented")
}
func (d *deserializer) DeserializeBytes() ([]byte, error) {
return d.BinaryDeserializer.DeserializeBytes(d.DeserializeLen)
}
func (d *deserializer) DeserializeStr() (string, error) {
return d.BinaryDeserializer.DeserializeStr(d.DeserializeLen)
}
func (d *deserializer) DeserializeLen() (uint64, error) {
ret, err := d.deserializeUleb128AsU32()
if ret > MaxSequenceLength {
return 0, errors.New("length is too large")
}
return uint64(ret), err
}
func (d *deserializer) DeserializeVariantIndex() (uint32, error) {
return d.deserializeUleb128AsU32()
}
func (d *deserializer) CheckThatKeySlicesAreIncreasing(key1, key2 serde.Slice) error {
if bytes.Compare(d.Input[key1.Start:key1.End], d.Input[key2.Start:key2.End]) >= 0 {
return errors.New("Error while decoding map: keys are not serialized in the expected order")
}
return nil
}
func (d *deserializer) deserializeUleb128AsU32() (uint32, error) {
var value uint64
for shift := 0; shift < 32; shift += 7 {
byte, err := d.Buffer.ReadByte()
if err != nil {
return 0, err
}
digit := byte & 0x7F
value = value | (uint64(digit) << shift)
if value > maxUint32 {
return 0, errors.New("overflow while parsing uleb128-encoded uint32 value")
}
if digit == byte {
if shift > 0 && digit == 0 {
return 0, errors.New("invalid uleb128 number (unexpected zero digit)")
}
return uint32(value), nil
}
}
return 0, errors.New("overflow while parsing uleb128-encoded uint32 value")
}