2026-02-17 16:58:00 +01:00
|
|
|
package buffer_test
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
2026-02-22 16:30:37 +01:00
|
|
|
"code.squareroundforest.org/arpio/buffer"
|
2026-02-17 16:58:00 +01:00
|
|
|
"errors"
|
|
|
|
|
"io"
|
2026-02-22 16:30:37 +01:00
|
|
|
"testing"
|
2026-02-17 16:58:00 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestReadBytes(t *testing.T) {
|
2026-02-22 16:30:37 +01:00
|
|
|
for title, cr := range map[string]createReader{"reader": buffer.BufferedReader, "content": testContent} {
|
|
|
|
|
t.Run(title, func(t *testing.T) {
|
|
|
|
|
t.Run("find", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, append(generate(12), []byte("123")...)) {
|
|
|
|
|
t.Fatal("failed to generate right content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find not", func(t *testing.T) {
|
|
|
|
|
g := &gen{max: 1 << 15}
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok || len(b) != 0 {
|
|
|
|
|
t.Fatal("failed to not find delimiter")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find across segments", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(14)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("failed to find delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, append(generate(12), []byte("123")...)) {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find across multiple segments", func(t *testing.T) {
|
|
|
|
|
d := generateFrom([]byte("123"), 12)
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{6},
|
|
|
|
|
customContent: map[int][]byte{6: d},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(8)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes(d, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("failed to find delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, append(generate(6), d...)) {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find not across segments", func(t *testing.T) {
|
|
|
|
|
g := &gen{max: 1 << 15}
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(15)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 24)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("invalid delimiter found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content", len(b), string(b))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find not across multiple segments", func(t *testing.T) {
|
|
|
|
|
g := &gen{max: 1 << 15}
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(15)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("invalid delimiter found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content", len(b), string(b))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find not due to max", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("8"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("invalid delimiter found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find partial", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("12")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("invalid delimiter found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find partial and then full", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{12, 18},
|
|
|
|
|
customContent: map[int][]byte{
|
|
|
|
|
12: []byte("12"),
|
|
|
|
|
18: []byte("123"),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 16)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("invalid delimiter found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("123"), 24)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check := append(
|
|
|
|
|
append(generate(12), append([]byte("12"), generate(18)[14:]...)...),
|
|
|
|
|
[]byte("123")...,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, check) {
|
|
|
|
|
t.Fatal("invalid content", len(b), string(b), len(check), string(check))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find partial across segments", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{7},
|
|
|
|
|
customContent: map[int][]byte{7: []byte("12")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(8)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("invalid delimiter found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find partial across multiple segments", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{7},
|
|
|
|
|
customContent: map[int][]byte{7: []byte("1234567890")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(8)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("1234567890123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("invalid delimiter found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find partial across segments and then full", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{7, 15},
|
|
|
|
|
customContent: map[int][]byte{
|
|
|
|
|
7: []byte("12"),
|
|
|
|
|
15: []byte("123"),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(8)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 10)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("invalid delimiter found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check := append(
|
|
|
|
|
append(generate(7), append([]byte("12"), generate(15)[9:]...)...),
|
|
|
|
|
[]byte("123")...,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, check) {
|
|
|
|
|
t.Fatal("invalid content", len(b), string(b), len(check), string(check))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find partial across multiple segments and then full", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{7, 22},
|
|
|
|
|
customContent: map[int][]byte{
|
|
|
|
|
7: []byte("1234567890"),
|
|
|
|
|
22: []byte("1234567890123"),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(8)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("1234567890123"), 20)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("invalid delimiter found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("1234567890123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check := append(
|
|
|
|
|
append(append(generate(7), []byte("1234567890")...), generate(22)[17:]...),
|
|
|
|
|
[]byte("1234567890123")...,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, check) {
|
|
|
|
|
t.Fatal("invalid content", len(b), string(b), len(check), string(check))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find partial due to max", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 14)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find partial due to max and then full", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 14)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, append(generate(12), []byte("123")...)) {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("null delimiter", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes(nil, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("failed to find delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("failed to generate right content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find not none consumed", func(t *testing.T) {
|
|
|
|
|
g := &gen{}
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if !errors.Is(err, io.EOF) {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("failed to find delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t.Run("reader only", func(t *testing.T) {
|
|
|
|
|
cr := buffer.BufferedReader
|
|
|
|
|
t.Run("error before found", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
errAfter: []int{8},
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(8)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, generate(8)) {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if !errors.Is(err, errTest) {
|
|
|
|
|
t.Fatal("failed to fail", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("error when found", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
errAfter: []int{15},
|
|
|
|
|
fastErr: true,
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(8)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("delimiter", len(b), string(b))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, append(generate(12), []byte("123")...)) {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("unexpected delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, generate(16)[15:]) {
|
|
|
|
|
t.Fatal("invalid content", len(b), string(b))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if !errors.Is(err, errTest) {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("unexpected delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content", len(b), string(b))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("error after found", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
errAfter: []int{18},
|
|
|
|
|
fastErr: true,
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(8)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("delimiter", len(b), string(b))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, append(generate(12), []byte("123")...)) {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("unexpected delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, generate(24)[15:]) {
|
|
|
|
|
t.Fatal("invalid content", len(b), string(b))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if !errors.Is(err, errTest) {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("unexpected delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content", len(b), string(b))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("null read", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 1 << 15,
|
|
|
|
|
nullReadAfter: []int{8, 8},
|
|
|
|
|
customContentAfter: []int{12},
|
|
|
|
|
customContent: map[int][]byte{12: []byte("123")},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(8)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(b) != 0 {
|
|
|
|
|
t.Fatal("invalid content")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, ok, err = r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, append(generate(12), []byte("123")...)) {
|
|
|
|
|
t.Fatal("failed to generate right content")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("find not more than max", func(t *testing.T) {
|
|
|
|
|
g := &gen{
|
|
|
|
|
max: 256,
|
|
|
|
|
fastErr: true,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o := buffer.Options{Pool: buffer.NoPool(256)}
|
|
|
|
|
r := cr(g, o)
|
|
|
|
|
b, ok, err := r.ReadBytes([]byte("123"), 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
t.Fatal("delimiter")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(b, generate(64)) {
|
|
|
|
|
t.Fatal("failed to generate right content")
|
|
|
|
|
}
|
|
|
|
|
})
|
2026-02-17 16:58:00 +01:00
|
|
|
})
|
|
|
|
|
}
|