Skip to content

Commit

Permalink
All golang Reader implementations should have a Close method that fre…
Browse files Browse the repository at this point in the history
…es resources
  • Loading branch information
danielrh committed Nov 28, 2018
1 parent 4c7ad33 commit a5ca617
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 124 deletions.
18 changes: 18 additions & 0 deletions c/go/brotli/brotli.go
Expand Up @@ -76,6 +76,13 @@ func NewMultiCompressionReader(
return &MultiCompressionReader{options: options, upstream: upstream}
}

func (mself *MultiCompressionReader) Close() error {
if closer, ok := mself.upstream.(io.ReadCloser); ok {
return closer.Close()
}
return nil
}

func (mself *MultiCompressionReader) Read(data []byte) (int, error) {
if mself.upstream != nil {
for mself.upstream != nil {
Expand Down Expand Up @@ -261,6 +268,17 @@ func NewDecompressionReader(upstream io.Reader) *DecompressionReader {
}
}

func (mself *DecompressionReader) Close() error {
if mself.state != nil {
C.BrotliDecoderDestroyInstance(mself.state)
mself.state = nil
}
if closer, ok := mself.upstream.(io.ReadCloser); ok {
return closer.Close()
}
return nil
}

func (mself *DecompressionReader) populateBuffer() error {
for mself.validStart == mself.validEnd && !mself.eof {
var err error
Expand Down
110 changes: 101 additions & 9 deletions c/go/interface_test.go
Expand Up @@ -184,12 +184,12 @@ func TestCompressRoundtripZero(*testing.T) {
Appendable: true,
Magic: true,
}
compressedForm := bytes.NewBuffer(nil)
compressedForm := bytes.NewBuffer(nil)
writer := brotli.NewMultiCompressionWriter(
io.MultiWriter(compressedForm, brotli.NewDecompressionWriter(
outBuffer,
),
),
),
options,
)
err := writer.Close()
Expand Down Expand Up @@ -230,6 +230,65 @@ func TestCompressReader(*testing.T) {
panic(fmt.Sprintf("Buffer too large: %d", len(outBuffer.Bytes())))
}
}
func TestCompressReaderClose(*testing.T) {
data := testData()
inBuffer := bytes.NewBuffer(data[:])
outBuffer := bytes.NewBuffer(nil)
var options = brotli.CompressionOptions{
NumThreads: 1,
Quality: 2,
Catable: true,
Appendable: true,
Magic: true,
}
reader := brotli.NewMultiCompressionReader(
inBuffer,
options,
)
_, err := io.Copy(outBuffer, reader)
if err != nil {
panic(err)
}
if len(outBuffer.Bytes()) == 0 {
panic("Zero output buffer")
}
if len(outBuffer.Bytes()) > 1850280 {
panic(fmt.Sprintf("Buffer too large: %d", len(outBuffer.Bytes())))
}
err = reader.Close()
if err != nil {
panic(err)
}
}

func TestCompressReaderEarlyClose(*testing.T) {
data := testData()
inBuffer := bytes.NewBuffer(data[:])
var options = brotli.CompressionOptions{
NumThreads: 1,
Quality: 2,
Catable: true,
Appendable: true,
Magic: true,
}
reader := brotli.NewMultiCompressionReader(
inBuffer,
options,
)
var smallBuf [1024]byte
count, err := reader.Read(smallBuf[:])
if err != nil {
panic(err)
}
if count != len(smallBuf) {
panic("Underflow for test data: too few bytes of test data")
}
err = reader.Close()
if err != nil {
panic(err)
}
}

func TestCompressReaderRoundtrip(*testing.T) {
data := testData()
inBuffer := bytes.NewBuffer(data[:])
Expand Down Expand Up @@ -259,25 +318,58 @@ func TestCompressReaderRoundtrip(*testing.T) {
}
}

func TestCompressReaderRoundtripZero(*testing.T) {
var data []byte
func TestDecompressReaderEarlyClose(*testing.T) {
data := testData()
inBuffer := bytes.NewBuffer(data[:])
outBuffer := bytes.NewBuffer(nil)
var options = brotli.CompressionOptions{
NumThreads: 1,
Quality: 11,
Quality: 4,
Catable: true,
Appendable: true,
Magic: true,
}
compressedForm := bytes.NewBuffer(nil)
reader := brotli.NewDecompressionReader(
io.TeeReader(
brotli.NewMultiCompressionReader(
inBuffer,
options,
),
compressedForm),
)
var smallBuffer [1027]byte
count, err := reader.Read(smallBuffer[:])
if err != nil {
panic(err)
}
if count < 1024 {
panic("Too small a test buffer")
}
err = reader.Close()
if err != nil {
panic(err)
}
if !bytes.Equal(smallBuffer[:], data[:len(smallBuffer)]) {
panic(fmt.Sprintf("Bytes not equal %x, %x", smallBuffer[:], data[:len(smallBuffer)]))
}
}

func TestCompressReaderRoundtripZero(*testing.T) {
var data []byte
inBuffer := bytes.NewBuffer(data[:])
outBuffer := bytes.NewBuffer(nil)
var options = brotli.CompressionOptions{
NumThreads: 1,
Quality: 11,
Catable: true,
Appendable: true,
Magic: true,
}
compressedForm := bytes.NewBuffer(nil)
reader := brotli.NewDecompressionReader(
io.TeeReader(
brotli.NewMultiCompressionReader(
inBuffer,
options,
),
compressedForm),
)
_, err := io.Copy(outBuffer, reader)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions c/go/main.go
Expand Up @@ -28,10 +28,10 @@ func main() {
if arg == "-d" {
decompress = true
}
if arg == "-dirtree" {
recursiveVerify(os.Args[index+1])
return
}
if arg == "-dirtree" {
recursiveVerify(os.Args[index+1])
return
}
if arg == "-cat" {
toCat = append(toCat, os.Args[index+1:]...)
break
Expand Down

0 comments on commit a5ca617

Please sign in to comment.