diff options
Diffstat (limited to 'llgo/third_party/gofrontend/libgo/go/compress/gzip/gunzip.go')
-rw-r--r-- | llgo/third_party/gofrontend/libgo/go/compress/gzip/gunzip.go | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/llgo/third_party/gofrontend/libgo/go/compress/gzip/gunzip.go b/llgo/third_party/gofrontend/libgo/go/compress/gzip/gunzip.go index 4f398b194a0..72ee55c4fab 100644 --- a/llgo/third_party/gofrontend/libgo/go/compress/gzip/gunzip.go +++ b/llgo/third_party/gofrontend/libgo/go/compress/gzip/gunzip.go @@ -74,14 +74,17 @@ type Reader struct { flg byte buf [512]byte err error + multistream bool } // NewReader creates a new Reader reading the given reader. -// The implementation buffers input and may read more data than necessary from r. +// If r does not also implement io.ByteReader, +// the decompressor may read more data than necessary from r. // It is the caller's responsibility to call Close on the Reader when done. func NewReader(r io.Reader) (*Reader, error) { z := new(Reader) z.r = makeReader(r) + z.multistream = true z.digest = crc32.NewIEEE() if err := z.readHeader(true); err != nil { return nil, err @@ -101,9 +104,30 @@ func (z *Reader) Reset(r io.Reader) error { } z.size = 0 z.err = nil + z.multistream = true return z.readHeader(true) } +// Multistream controls whether the reader supports multistream files. +// +// If enabled (the default), the Reader expects the input to be a sequence +// of individually gzipped data streams, each with its own header and +// trailer, ending at EOF. The effect is that the concatenation of a sequence +// of gzipped files is treated as equivalent to the gzip of the concatenation +// of the sequence. This is standard behavior for gzip readers. +// +// Calling Multistream(false) disables this behavior; disabling the behavior +// can be useful when reading file formats that distinguish individual gzip +// data streams or mix gzip data streams with other data streams. +// In this mode, when the Reader reaches the end of the data stream, +// Read returns io.EOF. If the underlying reader implements io.ByteReader, +// it will be left positioned just after the gzip stream. +// To start the next stream, call z.Reset(r) followed by z.Multistream(false). +// If there is no next stream, z.Reset(r) will return io.EOF. +func (z *Reader) Multistream(ok bool) { + z.multistream = ok +} + // 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 @@ -207,7 +231,11 @@ func (z *Reader) readHeader(save bool) error { } z.digest.Reset() - z.decompressor = flate.NewReader(z.r) + if z.decompressor == nil { + z.decompressor = flate.NewReader(z.r) + } else { + z.decompressor.(flate.Resetter).Reset(z.r, nil) + } return nil } @@ -240,6 +268,10 @@ func (z *Reader) Read(p []byte) (n int, err error) { } // File is ok; is there another? + if !z.multistream { + return 0, io.EOF + } + if err = z.readHeader(false); err != nil { z.err = err return |