diff --git a/tape/array.go b/tape/array.go index 04265d2..2b9273a 100644 --- a/tape/array.go +++ b/tape/array.go @@ -83,7 +83,7 @@ func DecodeVILAIter(data []byte) iter.Seq[[]byte] { } // EncodeVILA encodes a variable item length array. -func EncodeVILA(data []byte, items ...[]byte) ArrayPushFunc { +func EncodeVILA(data []byte) ArrayPushFunc { n := 0 return func(value []byte) (n_ int, err error) { if n >= len(data) { return n_, fmt.Errorf("encoding VILA: %w", ErrWrongBufferLength) } @@ -101,49 +101,47 @@ func EncodeVILA(data []byte, items ...[]byte) ArrayPushFunc { } } -// TODO: Decode, encode, size for string array needs to use VILA +// VILASize returns the size of a variable item length array. +func VILASize(items ...[]byte) int { + size := 0 + for _, item := range items { + size += GBEUSize[uint](uint(len(item))) + size += len(item) + } + return size +} -// DecodeStringArray decodes a packed string array from the given data. +// DecodeStringArray decodes a VILA string array from the given data. func DecodeStringArray[T String](data []byte) (result []T, n int, err error) { - for len(data) > 0 { - if len(data) < 2 { return nil, n, fmt.Errorf("decoding []string: %w", ErrWrongBufferLength) } - itemSize16, nn, _ := DecodeI16[uint16](data[:2]) - itemSize := int(itemSize16) + pull := DecodeVILA(data) + for { + item, nn, err := pull() n += nn - data = data[nn:] - if len(data) < itemSize { return nil, n, fmt.Errorf("decoding []string: %w", ErrWrongBufferLength) } - result = append(result, T(data[:itemSize])) - data = data[itemSize:] - n += itemSize + if err != nil { return nil, n, err } + result = append(result, T(item)) } return result, n, nil } -// EncodeStringArray encodes a packed string array into the given buffer. +// EncodeStringArray encodes a VILA string array into the given buffer. func EncodeStringArray[T String](buffer []byte, value []T) (n int, err error) { + push := EncodeVILA(buffer) for _, item := range value { - length, err := StringSize(item) + nn, err := push([]byte(item)) + n += nn if err != nil { return n, err } - if len(buffer) < 2 + length { return n, fmt.Errorf("encoding []string: %w", ErrWrongBufferLength) } - EncodeI16(buffer[:2], uint16(length)) - buffer = buffer[2:] - copy(buffer, item) - buffer = buffer[length:] - n += 2 + length } - if len(buffer) > 0 { return n, fmt.Errorf("encoding []string: %w", ErrWrongBufferLength) } return n, nil } -// StringArraySize returns the size of a packed string array. Returns 0 and an -// error if the size is too large. -func StringArraySize[T String](value []T) (int, error) { - total := 0 +// StringArraySize returns the size of a VILA string array. +func StringArraySize[T String](value []T) int { + size := 0 for _, item := range value { - total += 2 + len(item) + size += GBEUSize[uint](uint(len(item))) + size += len(item) } - if total > dataMaxSize { return 0, ErrDataTooLarge } - return total, nil + return size } // DecodeI8Array decodes a packed array of 8 bit integers from the given data.