Files
squashfs/internal/compression/gzip.go
T
2021-01-08 14:35:32 -06:00

62 lines
1.5 KiB
Go

package compression
import (
"bytes"
"compress/zlib"
"encoding/binary"
"io"
)
type gzipInit struct {
CompressionLevel int32
WindowSize int16
Strategies int16
}
//Gzip is a decompressor for gzip type compression. Uses zlib for compression and decompression
type Gzip struct {
gzipInit
HasCustomWindow bool
HasStrategies bool
}
//NewGzipCompressorWithOptions creates a new gzip compressor/decompressor with options read from the given reader.
func NewGzipCompressorWithOptions(r io.Reader) (*Gzip, error) {
var gzip Gzip
err := binary.Read(r, binary.LittleEndian, &gzip.gzipInit)
if err != nil {
return nil, err
}
//TODO: proper support for window size and strategies
gzip.HasCustomWindow = gzip.WindowSize != 15
gzip.HasStrategies = gzip.Strategies != 0 && gzip.Strategies != 1
return &gzip, nil
}
//Decompress reads the entirety of the given reader and returns it uncompressed as a byte slice.
func (g *Gzip) Decompress(r io.Reader) ([]byte, error) {
rdr, err := zlib.NewReader(r)
if err != nil {
return nil, err
}
var data bytes.Buffer
_, err = io.Copy(&data, rdr)
if err != nil {
return nil, err
}
return data.Bytes(), nil
}
//Compress compresses the given data (as a byte array) and returns the compressed data.
func (g *Gzip) Compress(data []byte) ([]byte, error) {
var buf bytes.Buffer
wrt := zlib.NewWriter(&buf)
defer wrt.Close()
_, err := wrt.Write(data)
if err != nil {
return nil, err
}
wrt.Close()
return buf.Bytes(), nil
}