diff options
Diffstat (limited to 'src/pkg/compress/gzip')
-rw-r--r-- | src/pkg/compress/gzip/gunzip.go | 15 | ||||
-rw-r--r-- | src/pkg/compress/gzip/gunzip_test.go | 36 | ||||
-rw-r--r-- | src/pkg/compress/gzip/gzip.go | 8 | ||||
-rw-r--r-- | src/pkg/compress/gzip/gzip_test.go | 2 |
4 files changed, 55 insertions, 6 deletions
diff --git a/src/pkg/compress/gzip/gunzip.go b/src/pkg/compress/gzip/gunzip.go index 1fb9b0964..4f398b194 100644 --- a/src/pkg/compress/gzip/gunzip.go +++ b/src/pkg/compress/gzip/gunzip.go @@ -89,6 +89,21 @@ func NewReader(r io.Reader) (*Reader, error) { return z, nil } +// Reset discards the Reader z's state and makes it equivalent to the +// result of its original state from NewReader, but reading from r instead. +// This permits reusing a Reader rather than allocating a new one. +func (z *Reader) Reset(r io.Reader) error { + z.r = makeReader(r) + if z.digest == nil { + z.digest = crc32.NewIEEE() + } else { + z.digest.Reset() + } + z.size = 0 + z.err = nil + return z.readHeader(true) +} + // GZIP (RFC 1952) is little-endian, unlike ZLIB (RFC 1950). func get4(p []byte) uint32 { return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 diff --git a/src/pkg/compress/gzip/gunzip_test.go b/src/pkg/compress/gzip/gunzip_test.go index 572fb5848..2471038f5 100644 --- a/src/pkg/compress/gzip/gunzip_test.go +++ b/src/pkg/compress/gzip/gunzip_test.go @@ -284,7 +284,7 @@ var gunzipTests = []gunzipTest{ func TestDecompressor(t *testing.T) { b := new(bytes.Buffer) for _, tt := range gunzipTests { - in := bytes.NewBuffer(tt.gzip) + in := bytes.NewReader(tt.gzip) gzip, err := NewReader(in) if err != nil { t.Errorf("%s: NewReader: %s", tt.name, err) @@ -303,6 +303,26 @@ func TestDecompressor(t *testing.T) { if s != tt.raw { t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.name, n, s, len(tt.raw), tt.raw) } + + // Test Reader Reset. + in = bytes.NewReader(tt.gzip) + err = gzip.Reset(in) + if err != nil { + t.Errorf("%s: Reset: %s", tt.name, err) + continue + } + if tt.name != gzip.Name { + t.Errorf("%s: got name %s", tt.name, gzip.Name) + } + b.Reset() + n, err = io.Copy(b, gzip) + if err != tt.err { + t.Errorf("%s: io.Copy: %v want %v", tt.name, err, tt.err) + } + s = b.String() + if s != tt.raw { + t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.name, n, s, len(tt.raw), tt.raw) + } } } @@ -333,3 +353,17 @@ func TestIssue6550(t *testing.T) { // ok } } + +func TestInitialReset(t *testing.T) { + var r Reader + if err := r.Reset(bytes.NewReader(gunzipTests[1].gzip)); err != nil { + t.Error(err) + } + var buf bytes.Buffer + if _, err := io.Copy(&buf, &r); err != nil { + t.Error(err) + } + if s := buf.String(); s != gunzipTests[1].raw { + t.Errorf("got %q want %q", s, gunzipTests[1].raw) + } +} diff --git a/src/pkg/compress/gzip/gzip.go b/src/pkg/compress/gzip/gzip.go index fe32d6871..3a0bf54e1 100644 --- a/src/pkg/compress/gzip/gzip.go +++ b/src/pkg/compress/gzip/gzip.go @@ -22,8 +22,8 @@ const ( DefaultCompression = flate.DefaultCompression ) -// A Writer is an io.WriteCloser that satisfies writes by compressing data written -// to its wrapped io.Writer. +// A Writer is an io.WriteCloser. +// Writes to a Writer are compressed and written to w. type Writer struct { Header w io.Writer @@ -37,8 +37,8 @@ type Writer struct { err error } -// NewWriter creates a new Writer that satisfies writes by compressing data -// written to w. +// NewWriter returns a new Writer. +// Writes to the returned writer are compressed and written to w. // // It is the caller's responsibility to call Close on the WriteCloser when done. // Writes may be buffered and not flushed until Close. diff --git a/src/pkg/compress/gzip/gzip_test.go b/src/pkg/compress/gzip/gzip_test.go index 119be2e13..09271b24e 100644 --- a/src/pkg/compress/gzip/gzip_test.go +++ b/src/pkg/compress/gzip/gzip_test.go @@ -85,7 +85,7 @@ func TestRoundTrip(t *testing.T) { func TestLatin1(t *testing.T) { latin1 := []byte{0xc4, 'u', 0xdf, 'e', 'r', 'u', 'n', 'g', 0} utf8 := "Äußerung" - z := Reader{r: bufio.NewReader(bytes.NewBuffer(latin1))} + z := Reader{r: bufio.NewReader(bytes.NewReader(latin1))} s, err := z.readString() if err != nil { t.Fatalf("readString: %v", err) |