| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885 |
- ////////////////////////////////////////////////////////////////////////////////
- //
- // DO NOT MODIFY
- //
- // ┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻
- //
- //
- // This source file was automatically generated by bingen.
- //
- ////////////////////////////////////////////////////////////////////////////////
- package metric
- import (
- "fmt"
- "io"
- "iter"
- "os"
- "reflect"
- "strings"
- "sync"
- "time"
- bstream "github.com/opencost/bingen/pkg/stream"
- stringtable "github.com/opencost/bingen/pkg/table"
- util "github.com/opencost/bingen/pkg/util"
- )
- const (
- // GeneratorPackageName is the package the generator is targetting
- GeneratorPackageName string = "metric"
- // DefaultCodecVersion is used for any resources listed in the Default version set
- DefaultCodecVersion uint8 = 1
- )
- //--------------------------------------------------------------------------
- // Configuration
- //--------------------------------------------------------------------------
- var (
- bingenConfigLock sync.RWMutex
- bingenConfig *BingenConfiguration = DefaultBingenConfiguration()
- )
- // BingenConfiguration is used to set any custom configuration in the way files are encoded
- // or decoded.
- type BingenConfiguration struct {
- // FileBackedStringTableEnabled enables the use of file-backed string tables for streaming
- // bingen decoding.
- FileBackedStringTableEnabled bool
- // FileBackedStringTableDir is the directory to write the string table files for reading.
- FileBackedStringTableDir string
- // FileBackedStringTableMemoMaxBytes limits in-memory memoization for file-backed table lookups.
- // 0 disables memoization.
- FileBackedStringTableMemoMaxBytes int64
- }
- // DefaultBingenConfiguration creates the default implementation of the bingen configuration
- // and returns it.
- func DefaultBingenConfiguration() *BingenConfiguration {
- return &BingenConfiguration{
- FileBackedStringTableEnabled: false,
- FileBackedStringTableDir: os.TempDir(),
- FileBackedStringTableMemoMaxBytes: 0,
- }
- }
- // ConfigureBingen accepts a new *BingenConfiguration instance which updates the internal decoder
- // and encoder behavior.
- func ConfigureBingen(config *BingenConfiguration) {
- bingenConfigLock.Lock()
- defer bingenConfigLock.Unlock()
- if config == nil {
- config = DefaultBingenConfiguration()
- }
- bingenConfig = config
- }
- // IsBingenFileBackedStringTableEnabled accessor for file backed string table configuration
- func IsBingenFileBackedStringTableEnabled() bool {
- bingenConfigLock.RLock()
- defer bingenConfigLock.RUnlock()
- return bingenConfig.FileBackedStringTableEnabled
- }
- // BingenFileBackedStringTableDir returns the directory configured for file backed string tables.
- func BingenFileBackedStringTableDir() string {
- bingenConfigLock.RLock()
- defer bingenConfigLock.RUnlock()
- return bingenConfig.FileBackedStringTableDir
- }
- // BingenFileBackedStringTableMemoMaxBytes returns the maximum bytes used for file-backed memo cache.
- func BingenFileBackedStringTableMemoMaxBytes() int64 {
- bingenConfigLock.RLock()
- defer bingenConfigLock.RUnlock()
- return bingenConfig.FileBackedStringTableMemoMaxBytes
- }
- //--------------------------------------------------------------------------
- // Type Map
- //--------------------------------------------------------------------------
- // Generated type map for resolving interface implementations to to concrete types
- var typeMap map[string]reflect.Type = map[string]reflect.Type{
- "Update": reflect.TypeFor[Update](),
- "UpdateSet": reflect.TypeFor[UpdateSet](),
- }
- //--------------------------------------------------------------------------
- // Type Helpers
- //--------------------------------------------------------------------------
- // isBinaryTag returns true when the first bytes in the provided binary matches the tag
- func isBinaryTag(data []byte, tag string) bool {
- if len(data) < len(tag) {
- return false
- }
- return string(data[:len(tag)]) == tag
- }
- // isReaderBinaryTag is used to peek the header for an io.Reader Buffer
- func isReaderBinaryTag(buff *util.Buffer, tag string) bool {
- data, err := buff.Peek(len(tag))
- if err != nil && err != io.EOF {
- panic(fmt.Sprintf("called Peek() on a non buffered reader: %s", err))
- }
- if len(data) < len(tag) {
- return false
- }
- return string(data[:len(tag)]) == tag
- }
- // typeToString determines the basic properties of the type, the qualifier, package path, and
- // type name, and returns the qualified type
- func typeToString(f interface{}) string {
- qual := ""
- t := reflect.TypeOf(f)
- if t.Kind() == reflect.Ptr {
- t = t.Elem()
- qual = "*"
- }
- return fmt.Sprintf("%s%s.%s", qual, t.PkgPath(), t.Name())
- }
- // resolveType uses the name of a type and returns the package, base type name, and whether
- // or not it's a pointer.
- func resolveType(t string) (pkg string, name string, isPtr bool) {
- isPtr = t[:1] == "*"
- if isPtr {
- t = t[1:]
- }
- slashIndex := strings.LastIndex(t, "/")
- if slashIndex >= 0 {
- t = t[slashIndex+1:]
- }
- parts := strings.Split(t, ".")
- if parts[0] == GeneratorPackageName {
- parts[0] = ""
- }
- pkg = parts[0]
- name = parts[1]
- return
- }
- //--------------------------------------------------------------------------
- // Stream Helpers
- //--------------------------------------------------------------------------
- // StreamFactoryFunc is an alias for a func that creates a BingenStream implementation.
- type StreamFactoryFunc func(io.Reader) bstream.BingenStream
- // Generated streamable factory map for finding the specific new stream methods
- // by T type
- var streamFactoryMap map[reflect.Type]StreamFactoryFunc = map[reflect.Type]StreamFactoryFunc{
- reflect.TypeFor[UpdateSet](): NewUpdateSetStream,
- }
- // NewStreamFor accepts an io.Reader, and returns a new BingenStream for the generic T
- // type provided _if_ it is a registered bingen type that is annotated as 'streamable'. See
- // the streamFactoryMap for generated type listings.
- func NewStreamFor[T any](reader io.Reader) (bstream.BingenStream, error) {
- typeKey := reflect.TypeFor[T]()
- factory, ok := streamFactoryMap[typeKey]
- if !ok {
- return nil, fmt.Errorf("the type: %s is not a registered bingen streamable type", typeKey.Name())
- }
- return factory(reader), nil
- }
- //--------------------------------------------------------------------------
- // Codec Context
- //--------------------------------------------------------------------------
- // EncodingContext is a context object passed to the encoders to ensure reuse of buffer
- // and table data
- type EncodingContext struct {
- Buffer *util.Buffer
- Table stringtable.StringTableWriter
- }
- // NewEncodingContext creates a new EncodingContext instance that will create a new []byte buffer
- // for writing, and return the context
- func NewEncodingContext(tableWriter stringtable.StringTableWriter) *EncodingContext {
- return &EncodingContext{
- Buffer: util.NewBuffer(),
- Table: tableWriter,
- }
- }
- // NewEncodingContextFromWriter creates a new EncodingContext instance that will create a new Buffer
- // from the provided io.Writer and StringTableWriter.
- func NewEncodingContextFromWriter(writer io.Writer, tableWriter stringtable.StringTableWriter) *EncodingContext {
- return &EncodingContext{
- Buffer: util.NewBufferFromWriter(writer),
- Table: tableWriter,
- }
- }
- // NewEncodingContextFromBuffer creates a new EncodingContext instance that will leverage an existing
- // Buffer and StringTableWriter.
- func NewEncodingContextFromBuffer(buffer *util.Buffer, tableWriter stringtable.StringTableWriter) *EncodingContext {
- return &EncodingContext{
- Buffer: buffer,
- Table: tableWriter,
- }
- }
- // ToBytes returns the encoded string table bytes (if applicable) combined with the encoded buffer bytes. If
- // a string table is being used, the string table bytes will be written first to ensure correct ordering for
- // decoding.
- func (ec *EncodingContext) ToBytes() []byte {
- encBytes := ec.Buffer.Bytes()
- if ec.Table != nil {
- buff := util.NewBuffer()
- ec.Table.WriteTo(buff)
- buff.WriteBytes(encBytes)
- return buff.Bytes()
- }
- return encBytes
- }
- // IsStringTable returns true if the table is available
- func (ec *EncodingContext) IsStringTable() bool {
- return ec.Table != nil
- }
- // DecodingContext is a context object passed to the decoders to ensure parent objects
- // reuse as much data as possible
- type DecodingContext struct {
- Buffer *util.Buffer
- Table stringtable.StringTableReader
- }
- // NewDecodingContextFromBytes creates a new DecodingContext instance using an byte slice
- func NewDecodingContextFromBytes(data []byte) *DecodingContext {
- var table stringtable.StringTableReader
- buff := util.NewBufferFromBytes(data)
- // string table header validation
- if isBinaryTag(data, stringtable.BinaryTagStringTable) {
- buff.ReadBytes(len(stringtable.BinaryTagStringTable)) // strip tag length
- // always use a slice string table with a byte array since the
- // data is already in memory
- table = stringtable.NewSliceStringTableReaderFrom(buff)
- }
- return &DecodingContext{
- Buffer: buff,
- Table: table,
- }
- }
- // NewDecodingContextFromReader creates a new DecodingContext instance using an io.Reader
- // implementation
- func NewDecodingContextFromReader(reader io.Reader) *DecodingContext {
- var table stringtable.StringTableReader
- buff := util.NewBufferFromReader(reader)
- if isReaderBinaryTag(buff, stringtable.BinaryTagStringTable) {
- buff.ReadBytes(len(stringtable.BinaryTagStringTable)) // strip tag length
- // create correct string table implementation
- if IsBingenFileBackedStringTableEnabled() {
- table = stringtable.NewFileStringTableReaderFrom(buff, BingenFileBackedStringTableDir(), GeneratorPackageName, BingenFileBackedStringTableMemoMaxBytes())
- } else {
- table = stringtable.NewSliceStringTableReaderFrom(buff)
- }
- }
- return &DecodingContext{
- Buffer: buff,
- Table: table,
- }
- }
- // IsStringTable returns true if the table is available
- func (dc *DecodingContext) IsStringTable() bool {
- return dc.Table != nil && dc.Table.Len() > 0
- }
- // Close will ensure that any string table resources and buffer resources are
- // cleaned up.
- func (dc *DecodingContext) Close() {
- if dc.Table != nil {
- _ = dc.Table.Close()
- dc.Table = nil
- }
- }
- //--------------------------------------------------------------------------
- // Binary Codec
- //--------------------------------------------------------------------------
- // BinEncoder is an encoding interface which defines a context based marshal contract.
- type BinEncoder interface {
- MarshalBinaryWithContext(*EncodingContext) error
- }
- // BinDecoder is a decoding interface which defines a context based unmarshal contract.
- type BinDecoder interface {
- UnmarshalBinaryWithContext(*DecodingContext) error
- }
- //--------------------------------------------------------------------------
- // Update
- //--------------------------------------------------------------------------
- // MarshalBinary serializes the internal properties of this Update instance
- // into a byte array
- func (target *Update) MarshalBinary() (data []byte, err error) {
- ctx := NewEncodingContext(nil)
- e := target.MarshalBinaryWithContext(ctx)
- if e != nil {
- return nil, e
- }
- return ctx.ToBytes(), nil
- }
- // MarshalBinary serializes the internal properties of this Update instance
- // into an io.Writer.
- func (target *Update) MarshalBinaryTo(writer io.Writer) error {
- buff := util.NewBufferFromWriter(writer)
- defer buff.Flush()
- ctx := NewEncodingContextFromBuffer(buff, nil)
- return target.MarshalBinaryWithContext(ctx)
- }
- // MarshalBinaryWithContext serializes the internal properties of this Update instance
- // into a byte array leveraging a predefined context.
- func (target *Update) MarshalBinaryWithContext(ctx *EncodingContext) (err error) {
- // panics are recovered and propagated as errors
- defer func() {
- if r := recover(); r != nil {
- if e, ok := r.(error); ok {
- err = e
- } else if s, ok := r.(string); ok {
- err = fmt.Errorf("unexpected panic: %s", s)
- } else {
- err = fmt.Errorf("unexpected panic: %+v", r)
- }
- }
- }()
- buff := ctx.Buffer
- buff.WriteUInt8(DefaultCodecVersion) // version
- if ctx.IsStringTable() {
- a := ctx.Table.AddOrGet(target.Name)
- buff.WriteInt(a) // write table index
- } else {
- buff.WriteString(target.Name) // write string
- }
- if target.Labels == nil {
- buff.WriteUInt8(uint8(0)) // write nil byte
- } else {
- buff.WriteUInt8(uint8(1)) // write non-nil byte
- // --- [begin][write][map](map[string]string) ---
- buff.WriteInt(len(target.Labels)) // map length
- for v, z := range target.Labels {
- if ctx.IsStringTable() {
- b := ctx.Table.AddOrGet(v)
- buff.WriteInt(b) // write table index
- } else {
- buff.WriteString(v) // write string
- }
- if ctx.IsStringTable() {
- c := ctx.Table.AddOrGet(z)
- buff.WriteInt(c) // write table index
- } else {
- buff.WriteString(z) // write string
- }
- }
- // --- [end][write][map](map[string]string) ---
- }
- buff.WriteFloat64(target.Value) // write float64
- if target.AdditionalInfo == nil {
- buff.WriteUInt8(uint8(0)) // write nil byte
- } else {
- buff.WriteUInt8(uint8(1)) // write non-nil byte
- // --- [begin][write][map](map[string]string) ---
- buff.WriteInt(len(target.AdditionalInfo)) // map length
- for vv, zz := range target.AdditionalInfo {
- if ctx.IsStringTable() {
- d := ctx.Table.AddOrGet(vv)
- buff.WriteInt(d) // write table index
- } else {
- buff.WriteString(vv) // write string
- }
- if ctx.IsStringTable() {
- e := ctx.Table.AddOrGet(zz)
- buff.WriteInt(e) // write table index
- } else {
- buff.WriteString(zz) // write string
- }
- }
- // --- [end][write][map](map[string]string) ---
- }
- return nil
- }
- // UnmarshalBinary uses the data passed byte array to set all the internal properties of
- // the Update type
- func (target *Update) UnmarshalBinary(data []byte) error {
- ctx := NewDecodingContextFromBytes(data)
- defer ctx.Close()
- err := target.UnmarshalBinaryWithContext(ctx)
- if err != nil {
- return err
- }
- return nil
- }
- // UnmarshalBinaryFromReader uses the io.Reader data to set all the internal properties of
- // the Update type
- func (target *Update) UnmarshalBinaryFromReader(reader io.Reader) error {
- ctx := NewDecodingContextFromReader(reader)
- defer ctx.Close()
- err := target.UnmarshalBinaryWithContext(ctx)
- if err != nil {
- return err
- }
- return nil
- }
- // UnmarshalBinaryWithContext uses the context containing a string table and binary buffer to set all the internal properties of
- // the Update type
- func (target *Update) UnmarshalBinaryWithContext(ctx *DecodingContext) (err error) {
- // panics are recovered and propagated as errors
- defer func() {
- if r := recover(); r != nil {
- if e, ok := r.(error); ok {
- err = e
- } else if s, ok := r.(string); ok {
- err = fmt.Errorf("unexpected panic: %s", s)
- } else {
- err = fmt.Errorf("unexpected panic: %+v", r)
- }
- }
- }()
- buff := ctx.Buffer
- version := buff.ReadUInt8()
- if version > DefaultCodecVersion {
- return fmt.Errorf("Invalid Version Unmarshalling Update. Expected %d or less, got %d", DefaultCodecVersion, version)
- }
- var b string
- if ctx.IsStringTable() {
- c := buff.ReadInt() // read string index
- b = ctx.Table.At(c)
- } else {
- b = buff.ReadString() // read string
- }
- a := b
- target.Name = a
- if buff.ReadUInt8() == uint8(0) {
- target.Labels = nil
- } else {
- // --- [begin][read][map](map[string]string) ---
- e := buff.ReadInt() // map len
- d := make(map[string]string, e)
- for range e {
- var v string
- var g string
- if ctx.IsStringTable() {
- h := buff.ReadInt() // read string index
- g = ctx.Table.At(h)
- } else {
- g = buff.ReadString() // read string
- }
- f := g
- v = f
- var z string
- var m string
- if ctx.IsStringTable() {
- n := buff.ReadInt() // read string index
- m = ctx.Table.At(n)
- } else {
- m = buff.ReadString() // read string
- }
- l := m
- z = l
- d[v] = z
- }
- target.Labels = d
- // --- [end][read][map](map[string]string) ---
- }
- o := buff.ReadFloat64() // read float64
- target.Value = o
- if buff.ReadUInt8() == uint8(0) {
- target.AdditionalInfo = nil
- } else {
- // --- [begin][read][map](map[string]string) ---
- q := buff.ReadInt() // map len
- p := make(map[string]string, q)
- for range q {
- var vv string
- var s string
- if ctx.IsStringTable() {
- t := buff.ReadInt() // read string index
- s = ctx.Table.At(t)
- } else {
- s = buff.ReadString() // read string
- }
- r := s
- vv = r
- var zz string
- var w string
- if ctx.IsStringTable() {
- x := buff.ReadInt() // read string index
- w = ctx.Table.At(x)
- } else {
- w = buff.ReadString() // read string
- }
- u := w
- zz = u
- p[vv] = zz
- }
- target.AdditionalInfo = p
- // --- [end][read][map](map[string]string) ---
- }
- return nil
- }
- //--------------------------------------------------------------------------
- // UpdateSet
- //--------------------------------------------------------------------------
- // MarshalBinary serializes the internal properties of this UpdateSet instance
- // into a byte array
- func (target *UpdateSet) MarshalBinary() (data []byte, err error) {
- ctx := NewEncodingContext(stringtable.NewIndexedStringTableWriter())
- e := target.MarshalBinaryWithContext(ctx)
- if e != nil {
- return nil, e
- }
- return ctx.ToBytes(), nil
- }
- // MarshalBinary serializes the internal properties of this UpdateSet instance
- // into an io.Writer.
- func (target *UpdateSet) MarshalBinaryTo(writer io.Writer) error {
- buff := util.NewBufferFromWriter(writer)
- defer buff.Flush()
- // run a pre-pass to collect all strings into the string table and discard all writes to the main
- // buffer. Then, we write the string table, sorted by number of repeated uses (descending), to the
- // main buffer, and use the resulting table as part of the context for the main pass.
- prepass := stringtable.NewPrepassStringTableWriter()
- prepassCtx := NewEncodingContextFromWriter(io.Discard, prepass)
- e := target.MarshalBinaryWithContext(prepassCtx)
- if e != nil {
- return e
- }
- tableWriter := prepass.WriteSortedTo(buff)
- ctx := NewEncodingContextFromBuffer(buff, tableWriter)
- return target.MarshalBinaryWithContext(ctx)
- }
- // MarshalBinaryWithContext serializes the internal properties of this UpdateSet instance
- // into a byte array leveraging a predefined context.
- func (target *UpdateSet) MarshalBinaryWithContext(ctx *EncodingContext) (err error) {
- // panics are recovered and propagated as errors
- defer func() {
- if r := recover(); r != nil {
- if e, ok := r.(error); ok {
- err = e
- } else if s, ok := r.(string); ok {
- err = fmt.Errorf("unexpected panic: %s", s)
- } else {
- err = fmt.Errorf("unexpected panic: %+v", r)
- }
- }
- }()
- buff := ctx.Buffer
- buff.WriteUInt8(DefaultCodecVersion) // version
- // --- [begin][write][reference](time.Time) ---
- a, errA := target.Timestamp.MarshalBinary()
- if errA != nil {
- return errA
- }
- buff.WriteInt(len(a))
- buff.WriteBytes(a)
- // --- [end][write][reference](time.Time) ---
- if target.Updates == nil {
- buff.WriteUInt8(uint8(0)) // write nil byte
- } else {
- buff.WriteUInt8(uint8(1)) // write non-nil byte
- // --- [begin][write][slice]([]Update) ---
- buff.WriteInt(len(target.Updates)) // slice length
- for i := range target.Updates {
- // --- [begin][write][struct](Update) ---
- buff.WriteInt(0) // [compatibility, unused]
- errB := target.Updates[i].MarshalBinaryWithContext(ctx)
- if errB != nil {
- return errB
- }
- // --- [end][write][struct](Update) ---
- }
- // --- [end][write][slice]([]Update) ---
- }
- return nil
- }
- // UnmarshalBinary uses the data passed byte array to set all the internal properties of
- // the UpdateSet type
- func (target *UpdateSet) UnmarshalBinary(data []byte) error {
- ctx := NewDecodingContextFromBytes(data)
- defer ctx.Close()
- err := target.UnmarshalBinaryWithContext(ctx)
- if err != nil {
- return err
- }
- return nil
- }
- // UnmarshalBinaryFromReader uses the io.Reader data to set all the internal properties of
- // the UpdateSet type
- func (target *UpdateSet) UnmarshalBinaryFromReader(reader io.Reader) error {
- ctx := NewDecodingContextFromReader(reader)
- defer ctx.Close()
- err := target.UnmarshalBinaryWithContext(ctx)
- if err != nil {
- return err
- }
- return nil
- }
- // UnmarshalBinaryWithContext uses the context containing a string table and binary buffer to set all the internal properties of
- // the UpdateSet type
- func (target *UpdateSet) UnmarshalBinaryWithContext(ctx *DecodingContext) (err error) {
- // panics are recovered and propagated as errors
- defer func() {
- if r := recover(); r != nil {
- if e, ok := r.(error); ok {
- err = e
- } else if s, ok := r.(string); ok {
- err = fmt.Errorf("unexpected panic: %s", s)
- } else {
- err = fmt.Errorf("unexpected panic: %+v", r)
- }
- }
- }()
- buff := ctx.Buffer
- version := buff.ReadUInt8()
- if version > DefaultCodecVersion {
- return fmt.Errorf("Invalid Version Unmarshalling UpdateSet. Expected %d or less, got %d", DefaultCodecVersion, version)
- }
- // --- [begin][read][reference](time.Time) ---
- a := new(time.Time)
- b := buff.ReadInt() // byte array length
- c := buff.ReadBytes(b)
- errA := a.UnmarshalBinary(c)
- if errA != nil {
- return errA
- }
- target.Timestamp = *a
- // --- [end][read][reference](time.Time) ---
- if buff.ReadUInt8() == uint8(0) {
- target.Updates = nil
- } else {
- // --- [begin][read][slice]([]Update) ---
- e := buff.ReadInt() // slice len
- d := make([]Update, e)
- for i := range e {
- // --- [begin][read][struct](Update) ---
- g := new(Update)
- buff.ReadInt() // [compatibility, unused]
- errB := g.UnmarshalBinaryWithContext(ctx)
- if errB != nil {
- return errB
- }
- f := *g
- // --- [end][read][struct](Update) ---
- d[i] = f
- }
- target.Updates = d
- // --- [end][read][slice]([]Update) ---
- }
- return nil
- }
- //--------------------------------------------------------------------------
- // UpdateSetStream
- //--------------------------------------------------------------------------
- // UpdateSetStream is a single use field stream for the contents of an UpdateSet instance. Instead of creating an instance and populating
- // the fields on that instance, we provide a streaming iterator which yields (BingenFieldInfo, *BingenValue) tuples for each
- // streamable element. All slices and maps will be flattened one depth and each element streamed individually.
- type UpdateSetStream struct {
- reader io.Reader
- ctx *DecodingContext
- err error
- }
- // Closes closes the internal io.Reader used to read and parse the UpdateSet fields.
- // This should be called once the stream is no longer needed.
- func (stream *UpdateSetStream) Close() {
- if closer, ok := stream.reader.(io.Closer); ok {
- closer.Close()
- }
- stream.ctx.Close()
- }
- // Error returns an error if one occurred during the process of streaming the UpdateSet
- // This can be checked after iterating through the Stream().
- func (stream *UpdateSetStream) Error() error {
- return stream.err
- }
- // NewUpdateSetStream creates a new UpdateSetStream, which uses the io.Reader data to stream all internal fields of an UpdateSet instance
- func NewUpdateSetStream(reader io.Reader) bstream.BingenStream {
- ctx := NewDecodingContextFromReader(reader)
- return &UpdateSetStream{
- ctx: ctx,
- reader: reader,
- }
- }
- // Stream returns the iterator which will stream each field of the target type.
- func (stream *UpdateSetStream) Stream() iter.Seq2[bstream.BingenFieldInfo, *bstream.BingenValue] {
- return func(yield func(bstream.BingenFieldInfo, *bstream.BingenValue) bool) {
- var fi bstream.BingenFieldInfo
- ctx := stream.ctx
- buff := ctx.Buffer
- version := buff.ReadUInt8()
- if version > DefaultCodecVersion {
- stream.err = fmt.Errorf("Invalid Version Unmarshalling UpdateSet. Expected %d or less, got %d", DefaultCodecVersion, version)
- return
- }
- fi = bstream.BingenFieldInfo{
- Type: reflect.TypeFor[time.Time](),
- Name: "Timestamp",
- }
- // --- [begin][read][reference](time.Time) ---
- b := new(time.Time)
- c := buff.ReadInt() // byte array length
- d := buff.ReadBytes(c)
- errA := b.UnmarshalBinary(d)
- if errA != nil {
- stream.err = errA
- return
- }
- a := *b
- // --- [end][read][reference](time.Time) ---
- if !yield(fi, bstream.SingleV(a)) {
- return
- }
- fi = bstream.BingenFieldInfo{
- Type: reflect.TypeFor[[]Update](),
- Name: "Updates",
- }
- if buff.ReadUInt8() == uint8(0) {
- if !yield(fi, nil) {
- return
- }
- } else {
- // --- [begin][read][streaming-slice]([]Update) ---
- e := buff.ReadInt() // slice len
- for i := range e {
- // --- [begin][read][struct](Update) ---
- g := new(Update)
- buff.ReadInt() // [compatibility, unused]
- errB := g.UnmarshalBinaryWithContext(ctx)
- if errB != nil {
- stream.err = errB
- return
- }
- f := *g
- // --- [end][read][struct](Update) ---
- if !yield(fi, bstream.PairV(i, f)) {
- return
- }
- }
- // --- [end][read][streaming-slice]([]Update) ---
- }
- }
- }
|