Skip to content

feature: add seek test case #77

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions xflate/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import (
"io"
"io/ioutil"
"log"
"math"
mathrand "math/rand"
"testing"

"github.com/dsnet/compress/internal/testutil"
"github.com/dsnet/compress/xflate"
Expand Down Expand Up @@ -246,3 +249,112 @@ func Example_gzipFile() {
// got: "ver, white with foam, the driving spray of spume-flakes, the dim\noutlines of the"
// want: "ver, white with foam, the driving spray of spume-flakes, the dim\noutlines of the"
}

type seekItem struct {
off int64
seek int
n int
want string
wantpos int64
readerr error
seekerr string
}

var testSeekPlaintext = []byte("0123456789")

var testSeekItems = []seekItem{

{seek: io.SeekStart, off: 0, n: 20, want: "0123456789"},
{seek: io.SeekStart, off: 0, n: 5, want: "01234"},

{seek: io.SeekCurrent, off: 1, wantpos: 6, n: 1, want: "6"},
{seek: io.SeekCurrent, off: -3, wantpos: 4, n: 3, want: "456"},

{seek: io.SeekStart, off: 1, n: 1, want: "1"},
{seek: io.SeekCurrent, off: 1, wantpos: 3, n: 2, want: "34"},

{seek: io.SeekStart, off: -1, seekerr: "xflate: invalid argument: negative position: -1"},
// {seek: io.SeekStart, off: -1, seekerr: "bytes.Reader.Seek: negative position"},
{seek: io.SeekStart, off: 1 << 33, wantpos: 1 << 33, readerr: io.EOF},
{seek: io.SeekCurrent, off: 1, wantpos: 1<<33 + 1, readerr: io.EOF},

{seek: io.SeekStart, n: 5, want: "01234"},
{seek: io.SeekCurrent, n: 5, want: "56789"},
{seek: io.SeekEnd, off: -1, n: 1, wantpos: 9, want: "9"},

{seek: io.SeekStart, n: 0},
}

func testSeek(t *testing.T, chunkSize int64, tests []seekItem, r io.ReadSeeker) {
for i, tt := range tests {
pos, err := r.Seek(tt.off, tt.seek)
if err == nil && tt.seekerr != "" {
t.Errorf("%d. want seek error %q", i, tt.seekerr)
continue
}
if err != nil && err.Error() != tt.seekerr {
t.Errorf("%d. seek error = %q; want %q", i, err.Error(), tt.seekerr)
continue
}
if tt.wantpos != 0 && tt.wantpos != pos {
t.Errorf("%d. pos = %d, want %d", i, pos, tt.wantpos)
}
buf := make([]byte, tt.n)
n, err := r.Read(buf)
if err != tt.readerr {
t.Errorf("%d. read = %v; want %v", i, err, tt.readerr)
continue
}
got := string(buf[:n])
if got != tt.want {
t.Errorf("%d. got %q; want %q, chunkSize: %v", i, got, tt.want, chunkSize)
}
}
}

func TestSeekDeflate(t *testing.T) {
v_input := testSeekPlaintext

pow := float64(mathrand.Intn(8) + 1)
chunkSize := int64(math.Pow(2, pow))

var wb, rb bytes.Buffer
xw, err := xflate.NewWriter(&wb, &xflate.WriterConfig{
ChunkSize: chunkSize,
})
if err != nil {
t.Errorf("unexpected error: NewWriter() = %v", err)
}
cnt2, err := xw.Write(v_input)
cnt := int64(cnt2)
// cnt, err := io.Copy(xw, bytes.NewReader(v_input))
if err != nil {
t.Errorf("unexpected error: Write() = %v", err)
}
if cnt != int64(len(v_input)) {
t.Errorf("write count mismatch: got %d, want %d", cnt, len(v_input))
}
if err := xw.Close(); err != nil {
t.Errorf("unexpected error: Close() = %v", err)
}

xr, err := xflate.NewReader(bytes.NewReader(wb.Bytes()), &xflate.ReaderConfig{})
if err != nil {
t.Errorf("unexpected error: NewReader() = %v", err)
}

testSeek(t, chunkSize, testSeekItems, xr)

cnt, err = io.Copy(&rb, xr)
if err != nil {
t.Errorf("unexpected error: Read() = %v", err)
}
if cnt != int64(len(v_input)) {
t.Errorf("read count mismatch: got %d, want %d", cnt, len(v_input))
}

if err := xr.Close(); err != nil {
t.Errorf("unexpected error: Close() = %v", err)
}

}
28 changes: 27 additions & 1 deletion xflate/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,37 @@ func (xr *Reader) Reset(rs io.ReadSeeker) error {
// Read reads decompressed data from the underlying io.Reader.
// This method automatically proceeds to the next chunk when the current one
// has been fully read.
func (xr *Reader) Read(buf []byte) (int, error) {
func (xr *Reader) Read(buf []byte) (nn int, errr error) {
end := xr.idx.LastRecord().RawOffset
if xr.offset >= end {
return 0, io.EOF
}

for {
n, err := xr.read(buf[nn:])
if err != nil {
if err == io.EOF && nn > 0 {
return
}
errr = err
return
}
nn += n
if len(buf) == nn {
return
}
}
}
func (xr *Reader) read(buf []byte) (int, error) {

if xr.err != nil {
return 0, xr.err
}

if len(buf) == 0 {
return 0, nil
}

// Discard some data to reach the expected raw offset.
if xr.discard > 0 {
var n int64
Expand Down