package tape import "iter" // encoding and decoding functions must not make any allocations type TablePushFunc func(tag uint16, value []byte) (n int, err error) func DecodeTable(data []byte) iter.Seq2[uint16, []byte] { return func(yield func(tag uint16, value []byte) bool) { n := 0 for { tag, nn, err := DecodeI16[uint16](data[n:]) if err != nil { return } n += nn length, nn, err := DecodeGBEU[uint64](data[n:]) if err != nil { return } n += nn value := data[n:n + int(length)] yield(tag, value) n += int(length) } } } func EncodeTable(data []byte) TablePushFunc { return func(tag uint16, value []byte) (n int, err error) { if n >= len(data) { return n, ErrWrongBufferLength } nn, err := EncodeI16(data[n:], uint16(tag)) if err != nil { return n, err } n += nn if n >= len(data) { return n, ErrWrongBufferLength } nn, err = EncodeGBEU(data[n:], uint(len(value))) if err != nil { return n, err } n += nn if n >= len(data) { return n, ErrWrongBufferLength } nn = copy(data[n:], value) n += nn if nn < len(value) { return n, ErrWrongBufferLength } if n >= len(data) { return n, ErrWrongBufferLength } data = data[n:] return n, nil } } func TableSize(itemLengths ...int) int { sum := 0 for _, length := range itemLengths { sum += GBEUSize(uint(length)) + length } return sum }