Compare commits
No commits in common. "dd5325b3516c8a04e107356d0f20726e2dccf32e" and "568431f4c330b3a4f71e8295e3c05c6c4c308a0d" have entirely different histories.
dd5325b351
...
568431f4c3
@ -1,7 +1,5 @@
|
|||||||
package tape
|
package tape
|
||||||
|
|
||||||
import "iter"
|
|
||||||
|
|
||||||
// encoding and decoding functions must not make any allocations
|
// encoding and decoding functions must not make any allocations
|
||||||
|
|
||||||
type TablePushFunc func(tag uint16, value []byte) (n int, err error)
|
type TablePushFunc func(tag uint16, value []byte) (n int, err error)
|
||||||
@ -9,8 +7,7 @@ type TablePushFunc func(tag uint16, value []byte) (n int, err error)
|
|||||||
type TablePullFunc func() (tag uint16, value []byte, n int, err error)
|
type TablePullFunc func() (tag uint16, value []byte, n int, err error)
|
||||||
|
|
||||||
func DecodeTable(data []byte) TablePullFunc {
|
func DecodeTable(data []byte) TablePullFunc {
|
||||||
n := 0
|
return func() (tag uint16, value []byte, n int, err error) {
|
||||||
return func() (tag uint16, value []byte, n_ int, err error) {
|
|
||||||
tag, nn, err := DecodeI16[uint16](data[n:])
|
tag, nn, err := DecodeI16[uint16](data[n:])
|
||||||
if err != nil { return tag, value, n, err }
|
if err != nil { return tag, value, n, err }
|
||||||
n += nn
|
n += nn
|
||||||
@ -25,17 +22,6 @@ func DecodeTable(data []byte) TablePullFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DecodeTableIter(data []byte) iter.Seq2[uint16, []byte] {
|
|
||||||
return func(yield func(uint16, []byte) bool) {
|
|
||||||
pull := DecodeTable(data)
|
|
||||||
for {
|
|
||||||
tag, value, _, err := pull()
|
|
||||||
if err != nil { return }
|
|
||||||
if !yield(tag, value) { return }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func EncodeTable(data []byte) TablePushFunc {
|
func EncodeTable(data []byte) TablePushFunc {
|
||||||
return func(tag uint16, value []byte) (n int, err error) {
|
return func(tag uint16, value []byte) (n int, err error) {
|
||||||
if n >= len(data) { return n, ErrWrongBufferLength }
|
if n >= len(data) { return n, ErrWrongBufferLength }
|
||||||
|
|||||||
@ -113,10 +113,10 @@ func DecodeGBEU[T UInt](data []byte) (value T, n int, err error) {
|
|||||||
fullValue *= 0x80
|
fullValue *= 0x80
|
||||||
fullValue += uint64(chunk & 0x7F)
|
fullValue += uint64(chunk & 0x7F)
|
||||||
ccb := chunk >> 7
|
ccb := chunk >> 7
|
||||||
n += 1
|
|
||||||
if ccb == 0 {
|
if ccb == 0 {
|
||||||
return T(fullValue), n, nil
|
return T(fullValue), n, nil
|
||||||
}
|
}
|
||||||
|
n += 1
|
||||||
}
|
}
|
||||||
return 0, n, fmt.Errorf("decoding GBEU: %w", ErrGBEUNotTerminated)
|
return 0, n, fmt.Errorf("decoding GBEU: %w", ErrGBEUNotTerminated)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,16 +21,10 @@ func TestI8(test *testing.T) {
|
|||||||
if err.Error() != "decoding int8: wrong buffer length" { test.Fatal(err) }
|
if err.Error() != "decoding int8: wrong buffer length" { test.Fatal(err) }
|
||||||
|
|
||||||
for number := range uint8(255) {
|
for number := range uint8(255) {
|
||||||
n, err := EncodeI8[uint8](buffer[:1], number)
|
_, err := EncodeI8[uint8](buffer[:1], number)
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 1, n; correct != got {
|
decoded, _, err := DecodeI8[uint8](buffer[:1])
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
decoded, n, err := DecodeI8[uint8](buffer[:1])
|
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 1, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if decoded != number {
|
if decoded != number {
|
||||||
test.Fatalf("%d != %d", decoded, number)
|
test.Fatalf("%d != %d", decoded, number)
|
||||||
}
|
}
|
||||||
@ -50,16 +44,10 @@ func TestI16(test *testing.T) {
|
|||||||
|
|
||||||
for _ = range largeNumberNTestRounds {
|
for _ = range largeNumberNTestRounds {
|
||||||
number := uint16(rand.Int())
|
number := uint16(rand.Int())
|
||||||
n, err := EncodeI16[uint16](buffer[:2], number)
|
_, err := EncodeI16[uint16](buffer[:2], number)
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 2, n; correct != got {
|
decoded, _, err := DecodeI16[uint16](buffer[:2])
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
decoded, n, err := DecodeI16[uint16](buffer[:2])
|
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 2, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if decoded != number {
|
if decoded != number {
|
||||||
test.Fatalf("%d != %d", decoded, number)
|
test.Fatalf("%d != %d", decoded, number)
|
||||||
}
|
}
|
||||||
@ -79,16 +67,10 @@ func TestI32(test *testing.T) {
|
|||||||
|
|
||||||
for _ = range largeNumberNTestRounds {
|
for _ = range largeNumberNTestRounds {
|
||||||
number := uint32(rand.Int())
|
number := uint32(rand.Int())
|
||||||
n, err := EncodeI32[uint32](buffer[:4], number)
|
_, err := EncodeI32[uint32](buffer[:4], number)
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 4, n; correct != got {
|
decoded, _, err := DecodeI32[uint32](buffer[:4])
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
decoded, n, err := DecodeI32[uint32](buffer[:4])
|
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 4, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if decoded != number {
|
if decoded != number {
|
||||||
test.Fatalf("%d != %d", decoded, number)
|
test.Fatalf("%d != %d", decoded, number)
|
||||||
}
|
}
|
||||||
@ -108,16 +90,10 @@ func TestI64(test *testing.T) {
|
|||||||
|
|
||||||
for _ = range largeNumberNTestRounds {
|
for _ = range largeNumberNTestRounds {
|
||||||
number := uint64(rand.Int())
|
number := uint64(rand.Int())
|
||||||
n, err := EncodeI64[uint64](buffer[:8], number)
|
_, err := EncodeI64[uint64](buffer[:8], number)
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 8, n; correct != got {
|
decoded, _, err := DecodeI64[uint64](buffer[:8])
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
decoded, n, err := DecodeI64[uint64](buffer[:8])
|
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 8, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if decoded != number {
|
if decoded != number {
|
||||||
test.Fatalf("%d != %d", decoded, number)
|
test.Fatalf("%d != %d", decoded, number)
|
||||||
}
|
}
|
||||||
@ -141,11 +117,8 @@ func TestGBEU(test *testing.T) {
|
|||||||
if err == nil { test.Fatal("no error") }
|
if err == nil { test.Fatal("no error") }
|
||||||
if err.Error() != "decoding GBEU: GBEU not terminated" { test.Fatal(err) }
|
if err.Error() != "decoding GBEU: GBEU not terminated" { test.Fatal(err) }
|
||||||
|
|
||||||
n, err := EncodeGBEU[uint64](buffer[:], 0x97)
|
_, err = EncodeGBEU[uint64](buffer[:], 0x97)
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 2, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if correct, got := []byte { 0x81, 0x17 }, buffer[:2]; !slices.Equal(correct, got) {
|
if correct, got := []byte { 0x81, 0x17 }, buffer[:2]; !slices.Equal(correct, got) {
|
||||||
message := "not equal:"
|
message := "not equal:"
|
||||||
for _, item := range got {
|
for _, item := range got {
|
||||||
@ -153,20 +126,14 @@ func TestGBEU(test *testing.T) {
|
|||||||
}
|
}
|
||||||
test.Fatal(message)
|
test.Fatal(message)
|
||||||
}
|
}
|
||||||
decoded, n, err := DecodeGBEU[uint64](buffer[:])
|
decoded, _, err := DecodeGBEU[uint64](buffer[:])
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 2, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if correct, got := uint64(0x97), decoded; correct != got {
|
if correct, got := uint64(0x97), decoded; correct != got {
|
||||||
test.Fatalf("not equal: %x", got)
|
test.Fatalf("not equal: %x", got)
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err = EncodeGBEU[uint64](buffer[:], 0x123456)
|
_, err = EncodeGBEU[uint64](buffer[:], 0x123456)
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 3, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if correct, got := []byte { 0xc8, 0xe8, 0x56 }, buffer[:3]; !slices.Equal(correct, got) {
|
if correct, got := []byte { 0xc8, 0xe8, 0x56 }, buffer[:3]; !slices.Equal(correct, got) {
|
||||||
message := "not equal:"
|
message := "not equal:"
|
||||||
for _, item := range got {
|
for _, item := range got {
|
||||||
@ -174,21 +141,15 @@ func TestGBEU(test *testing.T) {
|
|||||||
}
|
}
|
||||||
test.Fatal(message)
|
test.Fatal(message)
|
||||||
}
|
}
|
||||||
decoded, n, err = DecodeGBEU[uint64](buffer[:])
|
decoded, _, err = DecodeGBEU[uint64](buffer[:])
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 3, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if correct, got := uint64(0x123456), decoded; correct != got {
|
if correct, got := uint64(0x123456), decoded; correct != got {
|
||||||
test.Fatalf("not equal: %x", got)
|
test.Fatalf("not equal: %x", got)
|
||||||
}
|
}
|
||||||
|
|
||||||
maxGBEU64 := []byte { 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F }
|
maxGBEU64 := []byte { 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F }
|
||||||
n, err = EncodeGBEU[uint64](buffer[:], 0xFFFFFFFFFFFFFFFF)
|
_, err = EncodeGBEU[uint64](buffer[:], 0xFFFFFFFFFFFFFFFF)
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 10, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if correct, got := maxGBEU64, buffer[:10]; !slices.Equal(correct, got) {
|
if correct, got := maxGBEU64, buffer[:10]; !slices.Equal(correct, got) {
|
||||||
message := "not equal:"
|
message := "not equal:"
|
||||||
for _, item := range got {
|
for _, item := range got {
|
||||||
@ -196,28 +157,19 @@ func TestGBEU(test *testing.T) {
|
|||||||
}
|
}
|
||||||
test.Fatal(message)
|
test.Fatal(message)
|
||||||
}
|
}
|
||||||
decoded, n, err = DecodeGBEU[uint64](buffer[:])
|
decoded, _, err = DecodeGBEU[uint64](buffer[:])
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 10, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if correct, got := uint64(0xFFFFFFFFFFFFFFFF), decoded; correct != got {
|
if correct, got := uint64(0xFFFFFFFFFFFFFFFF), decoded; correct != got {
|
||||||
test.Fatalf("not equal: %x", got)
|
test.Fatalf("not equal: %x", got)
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err = EncodeGBEU[uint64](buffer[:], 11)
|
_, err = EncodeGBEU[uint64](buffer[:], 11)
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 1, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if correct, got := byte(0xb), buffer[0]; correct != got {
|
if correct, got := byte(0xb), buffer[0]; correct != got {
|
||||||
test.Fatal("not equal:", got)
|
test.Fatal("not equal:", got)
|
||||||
}
|
}
|
||||||
decoded, n, err = DecodeGBEU[uint64](buffer[:])
|
decoded, _, err = DecodeGBEU[uint64](buffer[:])
|
||||||
if err != nil { test.Fatal(err) }
|
if err != nil { test.Fatal(err) }
|
||||||
if correct, got := 1, n; correct != got {
|
|
||||||
test.Fatal("not equal:", got)
|
|
||||||
}
|
|
||||||
if correct, got := uint64(0xb), decoded; correct != got {
|
if correct, got := uint64(0xb), decoded; correct != got {
|
||||||
test.Fatalf("not equal: %x", got)
|
test.Fatalf("not equal: %x", got)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user