diff --git a/tape/pairs.go b/tape/pairs.go deleted file mode 100644 index 7a5bd24..0000000 --- a/tape/pairs.go +++ /dev/null @@ -1,83 +0,0 @@ -package tape - -import "iter" - -// DecodePairs decodes message tag/value pairs from a byte slice. It returns an -// iterator over all pairs, where the first value is the tag and the second is -// the value. If data yielded by the iterator is retained, it must be copied -// first. -func DecodePairs(data []byte) (iter.Seq2[uint16, []byte], error) { - // determine section bounds - if len(data) < 2 { return nil, ErrDataTooLarge } - length16, _, _ := DecodeI16[uint16](data[0:2]) - data = data[2:] - length := int(length16) - headerSize := length * 4 - if len(data) < headerSize { return nil, ErrDataTooLarge } - valuesData := data[headerSize:] - - // ensure the value buffer is big enough - var valuesSize int - for index := range length { - offset := index * 4 - end, _, _ := DecodeI16[uint16](data[offset + 2:offset + 4]) - valuesSize = int(end) - } - if valuesSize > len(valuesData) { - return nil, ErrDataTooLarge - } - - // return iterator - return func(yield func(uint16, []byte) bool) { - start := uint16(0) - for index := range length { - offset := index * 4 - key, _, _ := DecodeI16[uint16](data[offset + 0:offset + 2]) - end, _, _ := DecodeI16[uint16](data[offset + 2:offset + 4]) - // if nextValuesOffset < len(valuesData) { - if !yield(key, valuesData[start:end]) { - return - } - // } else { - // if !yield(key, nil) { - // return - // } - // } - start = end - } - }, nil -} - -// EncodePairs encodes message tag/value pairs into a byte slice. -func EncodePairs(pairs map[uint16] []byte) ([]byte, error) { - // determine section bounds - headerSize := 2 + len(pairs) * 4 - valuesSize := 0 - for _, value := range pairs { - valuesSize += len(value) - } - - // generate data - buffer := make([]byte, headerSize + valuesSize) - length16, ok := U16CastSafe(len(pairs)) - if !ok { return nil, ErrDataTooLarge } - EncodeI16[uint16](buffer[0:2], length16) - index := 0 - end := headerSize - for key, value := range pairs { - start := end - end += len(value) - tagOffset := 2 + index * 4 - end16, ok := U16CastSafe(end - headerSize) - if !ok { return nil, ErrDataTooLarge } - - // write tag and length - EncodeI16[uint16](buffer[tagOffset + 0:tagOffset + 2], key) - EncodeI16[uint16](buffer[tagOffset + 2:tagOffset + 4], end16) - - // write value - copy(buffer[start:end], value) - index ++ - } - return buffer, nil -} diff --git a/tape/pairs_test.go b/tape/pairs_test.go deleted file mode 100644 index 31bb7d6..0000000 --- a/tape/pairs_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package tape - -import "slices" -import "testing" - -func TestDecodePairs(test *testing.T) { - pairs := map[uint16] []byte { - 3894: []byte("foo"), - 7: []byte("br"), - } - got, err := DecodePairs([]byte { - 0, 2, - 0, 7, 0, 2, - 15, 54, 0, 5, - 98, 114, - 102, 111, 111}) - if err != nil { test.Fatal(err) } - length := 0 - for key, value := range got { - test.Log(key, value) - if !slices.Equal(pairs[key], value) { test.Fatal("not equal") } - length ++ - } - test.Log("length") - if length != len(pairs) { test.Fatal("wrong length") } -} - -func TestEncodePairs(test *testing.T) { - pairs := map[uint16] []byte { - 3894: []byte("foo"), - 7: []byte("br"), - } - got, err := EncodePairs(pairs) - if err != nil { test.Fatal(err) } - test.Log(got) - valid := slices.Equal(got, []byte { - 0, 2, - 15, 54, 0, 3, - 0, 7, 0, 5, - 102, 111, 111, - 98, 114}) || - slices.Equal(got, []byte { - 0, 2, - 0, 7, 0, 2, - 15, 54, 0, 5, - 98, 114, - 102, 111, 111}) - if !valid { test.Fatal("not equal") } -} - -func FuzzDecodePairs(fuzz *testing.F) { - fuzz.Add([]byte { - 0, 2, - 0, 7, 0, 2, - 15, 54, 0, 5, - 98, 114, - 102, 111, 111}) - fuzz.Fuzz(func(t *testing.T, buffer []byte) { - // ensure it does not panic :P - DecodePairs(buffer) - }) -}