Skip to content

Commit 0f81d41

Browse files
committed
feature: add seek test case
1 parent 39efe44 commit 0f81d41

File tree

2 files changed

+138
-1
lines changed

2 files changed

+138
-1
lines changed

xflate/example_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import (
1414
"io"
1515
"io/ioutil"
1616
"log"
17+
"math"
18+
mathrand "math/rand"
19+
"testing"
1720

1821
"github.com/dsnet/compress/internal/testutil"
1922
"github.com/dsnet/compress/xflate"
@@ -246,3 +249,112 @@ func Example_gzipFile() {
246249
// got: "ver, white with foam, the driving spray of spume-flakes, the dim\noutlines of the"
247250
// want: "ver, white with foam, the driving spray of spume-flakes, the dim\noutlines of the"
248251
}
252+
253+
type seekItem struct {
254+
off int64
255+
seek int
256+
n int
257+
want string
258+
wantpos int64
259+
readerr error
260+
seekerr string
261+
}
262+
263+
var testSeekPlaintext = []byte("0123456789")
264+
265+
var testSeekItems = []seekItem{
266+
267+
{seek: io.SeekStart, off: 0, n: 20, want: "0123456789"},
268+
{seek: io.SeekStart, off: 0, n: 5, want: "01234"},
269+
270+
{seek: io.SeekCurrent, off: 1, wantpos: 6, n: 1, want: "6"},
271+
{seek: io.SeekCurrent, off: -3, wantpos: 4, n: 3, want: "456"},
272+
273+
{seek: io.SeekStart, off: 1, n: 1, want: "1"},
274+
{seek: io.SeekCurrent, off: 1, wantpos: 3, n: 2, want: "34"},
275+
276+
{seek: io.SeekStart, off: -1, seekerr: "xflate: invalid argument: negative position: -1"},
277+
// {seek: io.SeekStart, off: -1, seekerr: "bytes.Reader.Seek: negative position"},
278+
{seek: io.SeekStart, off: 1 << 33, wantpos: 1 << 33, readerr: io.EOF},
279+
{seek: io.SeekCurrent, off: 1, wantpos: 1<<33 + 1, readerr: io.EOF},
280+
281+
{seek: io.SeekStart, n: 5, want: "01234"},
282+
{seek: io.SeekCurrent, n: 5, want: "56789"},
283+
{seek: io.SeekEnd, off: -1, n: 1, wantpos: 9, want: "9"},
284+
285+
{seek: io.SeekStart, n: 0},
286+
}
287+
288+
func testSeek(t *testing.T, chunkSize int64, tests []seekItem, r io.ReadSeeker) {
289+
for i, tt := range tests {
290+
pos, err := r.Seek(tt.off, tt.seek)
291+
if err == nil && tt.seekerr != "" {
292+
t.Errorf("%d. want seek error %q", i, tt.seekerr)
293+
continue
294+
}
295+
if err != nil && err.Error() != tt.seekerr {
296+
t.Errorf("%d. seek error = %q; want %q", i, err.Error(), tt.seekerr)
297+
continue
298+
}
299+
if tt.wantpos != 0 && tt.wantpos != pos {
300+
t.Errorf("%d. pos = %d, want %d", i, pos, tt.wantpos)
301+
}
302+
buf := make([]byte, tt.n)
303+
n, err := r.Read(buf)
304+
if err != tt.readerr {
305+
t.Errorf("%d. read = %v; want %v", i, err, tt.readerr)
306+
continue
307+
}
308+
got := string(buf[:n])
309+
if got != tt.want {
310+
t.Errorf("%d. got %q; want %q, chunkSize: %v", i, got, tt.want, chunkSize)
311+
}
312+
}
313+
}
314+
315+
func TestSeekDeflate(t *testing.T) {
316+
v_input := testSeekPlaintext
317+
318+
pow := float64(mathrand.Intn(8) + 1)
319+
chunkSize := int64(math.Pow(2, pow))
320+
321+
var wb, rb bytes.Buffer
322+
xw, err := xflate.NewWriter(&wb, &xflate.WriterConfig{
323+
ChunkSize: chunkSize,
324+
})
325+
if err != nil {
326+
t.Errorf("unexpected error: NewWriter() = %v", err)
327+
}
328+
cnt2, err := xw.Write(v_input)
329+
cnt := int64(cnt2)
330+
// cnt, err := io.Copy(xw, bytes.NewReader(v_input))
331+
if err != nil {
332+
t.Errorf("unexpected error: Write() = %v", err)
333+
}
334+
if cnt != int64(len(v_input)) {
335+
t.Errorf("write count mismatch: got %d, want %d", cnt, len(v_input))
336+
}
337+
if err := xw.Close(); err != nil {
338+
t.Errorf("unexpected error: Close() = %v", err)
339+
}
340+
341+
xr, err := xflate.NewReader(bytes.NewReader(wb.Bytes()), &xflate.ReaderConfig{})
342+
if err != nil {
343+
t.Errorf("unexpected error: NewReader() = %v", err)
344+
}
345+
346+
testSeek(t, chunkSize, testSeekItems, xr)
347+
348+
cnt, err = io.Copy(&rb, xr)
349+
if err != nil {
350+
t.Errorf("unexpected error: Read() = %v", err)
351+
}
352+
if cnt != int64(len(v_input)) {
353+
t.Errorf("read count mismatch: got %d, want %d", cnt, len(v_input))
354+
}
355+
356+
if err := xr.Close(); err != nil {
357+
t.Errorf("unexpected error: Close() = %v", err)
358+
}
359+
360+
}

xflate/reader.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,32 @@ func (xr *Reader) Reset(rs io.ReadSeeker) error {
159159
// Read reads decompressed data from the underlying io.Reader.
160160
// This method automatically proceeds to the next chunk when the current one
161161
// has been fully read.
162-
func (xr *Reader) Read(buf []byte) (int, error) {
162+
func (xr *Reader) Read(buf []byte) (nn int, errr error) {
163+
end := xr.idx.LastRecord().RawOffset
164+
if xr.offset >= end {
165+
return 0, io.EOF
166+
}
167+
168+
for {
169+
n, err := xr.read(buf[nn:])
170+
if err != nil {
171+
if err == io.EOF && nn > 0 {
172+
return
173+
}
174+
errr = err
175+
return
176+
}
177+
nn += n
178+
if len(buf) == nn {
179+
return
180+
}
181+
}
182+
}
183+
func (xr *Reader) read(buf []byte) (int, error) {
184+
if len(buf) == 0 {
185+
return 0, nil
186+
}
187+
163188
if xr.err != nil {
164189
return 0, xr.err
165190
}

0 commit comments

Comments
 (0)