serde-generate/runtime/golang/bcs/serializer.go (79 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates
// SPDX-License-Identifier: MIT OR Apache-2.0
package bcs
import (
"bytes"
"errors"
"sort"
"github.com/novifinancial/serde-reflection/serde-generate/runtime/golang/serde"
)
// `serializer` extends `serde.BinarySerializer` to implement `serde.Serializer`.
type serializer struct {
serde.BinarySerializer
}
func NewSerializer() serde.Serializer {
return &serializer{*serde.NewBinarySerializer(MaxContainerDepth)}
}
// SerializeF32 is unimplemented
func (s *serializer) SerializeF32(value float32) error {
return errors.New("unimplemented")
}
// SerializeF64 is unimplemented
func (s *serializer) SerializeF64(value float64) error {
return errors.New("unimplemented")
}
func (s *serializer) SerializeStr(value string) error {
return s.BinarySerializer.SerializeStr(value, s.SerializeLen)
}
func (s *serializer) SerializeBytes(value []byte) error {
return s.BinarySerializer.SerializeBytes(value, s.SerializeLen)
}
func (s *serializer) SerializeLen(value uint64) error {
if value > MaxSequenceLength {
return errors.New("length is too large")
}
s.serializeU32AsUleb128(uint32(value))
return nil
}
func (s *serializer) SerializeVariantIndex(value uint32) error {
s.serializeU32AsUleb128(value)
return nil
}
func (s *serializer) SortMapEntries(offsets []uint64) {
if len(offsets) <= 1 {
return
}
data := s.Buffer.Bytes()
slices := make([]serde.Slice, len(offsets))
for i, v := range offsets {
var w uint64
if i+1 < len(offsets) {
w = offsets[i+1]
} else {
w = uint64(len(data))
}
slices[i] = serde.Slice{Start: v, End: w}
}
entries := map_entries{data, slices}
sort.Sort(entries)
buffer := make([]byte, len(data)-int(offsets[0]))
current := buffer[0:0]
for _, slice := range entries.slices {
current = append(current, data[slice.Start:slice.End]...)
}
copy(data[offsets[0]:], current)
}
func (s *serializer) serializeU32AsUleb128(value uint32) {
for value >= 0x80 {
b := byte((value & 0x7f) | 0x80)
_ = s.Buffer.WriteByte(b)
value = value >> 7
}
_ = s.Buffer.WriteByte(byte(value))
}
type map_entries struct {
data []byte
slices []serde.Slice
}
func (a map_entries) Len() int { return len(a.slices) }
func (a map_entries) Less(i, j int) bool {
slice_i := a.data[a.slices[i].Start:a.slices[i].End]
slice_j := a.data[a.slices[j].Start:a.slices[j].End]
return bytes.Compare(slice_i, slice_j) < 0
}
func (a map_entries) Swap(i, j int) { a.slices[i], a.slices[j] = a.slices[j], a.slices[i] }