From 4432be3b288976fd3f8a398801803020ec78c7f5 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 2 Apr 2013 09:07:43 -0700 Subject: [PATCH] compress/gzip: add Writer.Flush to call flate.Writer's Flush From a discussion on golang-nuts. R=golang-dev, dsymonds, nigeltao, coocood, adg CC=golang-dev https://golang.org/cl/8251043 --- doc/go1.1.html | 8 ++++++ src/pkg/compress/gzip/gzip.go | 24 +++++++++++++++++- src/pkg/compress/gzip/gzip_test.go | 40 ++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/doc/go1.1.html b/doc/go1.1.html index dcbd5e7872..75eb02d45c 100644 --- a/doc/go1.1.html +++ b/doc/go1.1.html @@ -631,6 +631,14 @@ so it implements the io.WriterTo interface. +
  • +The compress/gzip package has +a new Flush +method for its +Writer +type that flushes its underlying flate.Writer. +
  • +
  • The crypto/hmac package has a new function, Equal, to compare two MACs. diff --git a/src/pkg/compress/gzip/gzip.go b/src/pkg/compress/gzip/gzip.go index 3035dfffcc..45558b7428 100644 --- a/src/pkg/compress/gzip/gzip.go +++ b/src/pkg/compress/gzip/gzip.go @@ -28,7 +28,7 @@ type Writer struct { Header w io.Writer level int - compressor io.WriteCloser + compressor *flate.Writer digest hash.Hash32 size uint32 closed bool @@ -191,6 +191,28 @@ func (z *Writer) Write(p []byte) (int, error) { return n, z.err } +// Flush flushes any pending compressed data to the underlying writer. +// +// It is useful mainly in compressed network protocols, to ensure that +// a remote reader has enough data to reconstruct a packet. Flush does +// not return until the data has been written. If the underlying +// writer returns an error, Flush returns that error. +// +// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH. +func (z *Writer) Flush() error { + if z.err != nil { + return z.err + } + if z.closed { + return nil + } + if z.compressor == nil { + z.Write(nil) + } + z.err = z.compressor.Flush() + return z.err +} + // Close closes the Writer. It does not close the underlying io.Writer. func (z *Writer) Close() error { if z.err != nil { diff --git a/src/pkg/compress/gzip/gzip_test.go b/src/pkg/compress/gzip/gzip_test.go index 6f7b593644..4d1af94381 100644 --- a/src/pkg/compress/gzip/gzip_test.go +++ b/src/pkg/compress/gzip/gzip_test.go @@ -157,3 +157,43 @@ func TestLatin1RoundTrip(t *testing.T) { } } } + +func TestWriterFlush(t *testing.T) { + buf := new(bytes.Buffer) + + w := NewWriter(buf) + w.Comment = "comment" + w.Extra = []byte("extra") + w.ModTime = time.Unix(1e8, 0) + w.Name = "name" + + n0 := buf.Len() + if n0 != 0 { + t.Fatalf("buffer size = %d before writes; want 0", n0) + } + + if err := w.Flush(); err != nil { + t.Fatal(err) + } + + n1 := buf.Len() + if n1 == 0 { + t.Fatal("no data after first flush") + } + + w.Write([]byte("x")) + + n2 := buf.Len() + if n1 != n2 { + t.Fatalf("after writing a single byte, size changed from %d to %d; want no change", n1, n2) + } + + if err := w.Flush(); err != nil { + t.Fatal(err) + } + + n3 := buf.Len() + if n2 == n3 { + t.Fatal("Flush didn't flush any data") + } +} -- 2.50.0