-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
774 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package gzip | ||
|
||
import ( | ||
"bytes" | ||
"compress/gzip" | ||
"io" | ||
) | ||
|
||
// DefaultBufferSize is the default buffer size used by the Compressor. | ||
const DefaultBufferSize = 65536 | ||
|
||
// Compressor is a wrapper around a gzip.Writer that reads from an io.Reader | ||
// and writes to an internal buffer. The internal buffer is used to store | ||
// compressed data until it is read by the caller. | ||
type Compressor struct { | ||
r io.Reader | ||
bufSz int | ||
buf *bytes.Buffer | ||
gzw *gzip.Writer | ||
|
||
nRx int64 | ||
nTx int64 | ||
} | ||
|
||
// NewCompressor returns an instantiated Compressor that reads from r and | ||
// compresses the data using gzip. | ||
func NewCompressor(r io.Reader, bufSz int) (*Compressor, error) { | ||
buf := new(bytes.Buffer) | ||
gzw, err := gzip.NewWriterLevel(buf, gzip.DefaultCompression) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &Compressor{ | ||
r: r, | ||
bufSz: bufSz, | ||
buf: buf, | ||
gzw: gzw, | ||
}, nil | ||
} | ||
|
||
// Read reads compressed data. | ||
func (c *Compressor) Read(p []byte) (n int, err error) { | ||
if c.buf.Len() == 0 && c.gzw != nil { | ||
nn, err := io.CopyN(c.gzw, c.r, int64(c.bufSz)) | ||
c.nRx += nn | ||
c.nTx += int64(len(p)) | ||
if err != nil { | ||
// Time to write the footer. | ||
if err := c.Close(); err != nil { | ||
return 0, err | ||
} | ||
if err != io.EOF { | ||
// Actual error, let caller handle | ||
return 0, err | ||
} | ||
} else if nn > 0 { | ||
// We read some data, but didn't hit any error. | ||
// Just flush the data in the buffer, ready | ||
// to be read. | ||
if err := c.gzw.Flush(); err != nil { | ||
return 0, err | ||
} | ||
} | ||
} | ||
return c.buf.Read(p) | ||
} | ||
|
||
// Close closes the Compressor. | ||
func (c *Compressor) Close() error { | ||
if c.gzw == nil { | ||
return nil | ||
} | ||
if err := c.gzw.Close(); err != nil { | ||
return err | ||
} | ||
c.gzw = nil | ||
return nil | ||
} |
Oops, something went wrong.