Setup for differnet types of compression for Writer

Added some TODOs
This commit is contained in:
Caleb Gardner
2021-01-08 14:35:32 -06:00
parent 3f71404a2a
commit 4b3d5d12f8
8 changed files with 119 additions and 20 deletions
+7 -12
View File
@@ -15,23 +15,21 @@ type gzipInit struct {
//Gzip is a decompressor for gzip type compression. Uses zlib for compression and decompression
type Gzip struct {
CompressionLevel int32
HasCustomWindow bool
HasStrategies bool
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
var init gzipInit
err := binary.Read(r, binary.LittleEndian, &init)
err := binary.Read(r, binary.LittleEndian, &gzip.gzipInit)
if err != nil {
return nil, err
}
gzip.CompressionLevel = init.CompressionLevel
//TODO: proper support for window size and strategies
gzip.HasCustomWindow = init.WindowSize != 15
gzip.HasStrategies = init.Strategies != 0 && init.Strategies != 1
gzip.HasCustomWindow = gzip.WindowSize != 15
gzip.HasStrategies = gzip.Strategies != 0 && gzip.Strategies != 1
return &gzip, nil
}
@@ -58,9 +56,6 @@ func (g *Gzip) Compress(data []byte) ([]byte, error) {
if err != nil {
return nil, err
}
err = wrt.Flush()
if err != nil {
return nil, err
}
wrt.Close()
return buf.Bytes(), nil
}
+18
View File
@@ -35,3 +35,21 @@ func (l *Lz4) Decompress(r io.Reader) ([]byte, error) {
_, err := io.Copy(&buf, rdr)
return buf.Bytes(), err
}
//Compress implements compression.Compress
func (l *Lz4) Compress(data []byte) ([]byte, error) {
var buf bytes.Buffer
w := lz4.NewWriter(&buf)
if l.HC {
err := w.Apply(lz4.CompressionLevelOption(lz4.Level9))
if err != nil {
return nil, err
}
}
_, err := w.Write(data)
if err != nil {
return nil, err
}
w.Close()
return buf.Bytes(), nil
}
+15
View File
@@ -23,3 +23,18 @@ func (l *Lzma) Decompress(rdr io.Reader) ([]byte, error) {
}
return buf.Bytes(), nil
}
//Compress implements compression.Compress
func (l *Lzma) Compress(data []byte) ([]byte, error) {
var buf bytes.Buffer
w, err := lzma.NewWriter(&buf)
if err != nil {
return nil, err
}
_, err = w.Write(data)
if err != nil {
return nil, err
}
w.Close()
return buf.Bytes(), nil
}
+20
View File
@@ -53,3 +53,23 @@ func (x *Xz) Decompress(rdr io.Reader) ([]byte, error) {
}
return buf.Bytes(), nil
}
//Compress implements compression.Compress
func (x *Xz) Compress(data []byte) ([]byte, error) {
var buf bytes.Buffer
w, err := xz.NewWriter(&buf)
if err != nil {
return nil, err
}
w.DictCap = int(x.DictionarySize)
err = w.Verify()
if err != nil {
return nil, err
}
_, err = w.Write(data)
if err != nil {
return nil, err
}
w.Close()
return buf.Bytes(), nil
}
+15
View File
@@ -34,3 +34,18 @@ func (z *Zstd) Decompress(r io.Reader) ([]byte, error) {
_, err = io.Copy(&buf, rdr)
return buf.Bytes(), err
}
//Compress impelements compression.Compress
func (z *Zstd) Compress(data []byte) ([]byte, error) {
var buf bytes.Buffer
w, err := zstd.NewWriter(&buf, zstd.WithEncoderLevel(zstd.EncoderLevel(z.CompressionLevel)))
if err != nil {
return nil, err
}
_, err = w.Write(data)
if err != nil {
return nil, err
}
w.Close()
return buf.Bytes(), nil
}
-3
View File
@@ -77,9 +77,6 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
if err != nil {
return nil, err
}
if lz4.HC {
hasUnsupportedOptions = true
}
rdr.decompressor = lz4
case ZstdCompression:
zstd, err := compression.NewZstdCompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 4))
+29 -5
View File
@@ -7,6 +7,8 @@ import (
"os"
"path"
"strings"
"github.com/CalebQ42/squashfs/internal/compression"
)
type fileHolder struct {
@@ -14,6 +16,8 @@ type fileHolder struct {
path string
name string
symLocation string
UID int
GUID int
folder bool
symlink bool
}
@@ -21,19 +25,37 @@ type fileHolder struct {
//Writer is used to creaste squashfs archives. Currently unusable
//TODO: Make usable
type Writer struct {
compressor compression.Compressor
structure map[string][]*fileHolder
symlinkTable map[string]string //[oldpath]newpath
superblock superblock
compressionType int
allowErrors bool //AllowErrors allows errors when adding folders and their children.
allowErrors bool
}
//NewWriter creates a new
//NewWriter creates a new with the default options (Gzip compression and allow errors)
func NewWriter() (*Writer, error) {
return NewWriterWithOptions(GzipCompression, true)
}
//NewWriterWithOptions creates a new squashfs.Writer with the given options.
//compressionType can be of any types, except LZO (which this library doesn't have support for yet)
//allowErrors determines if, when adding folders, it allows errors encountered with it's sub-directories and instead logs the errors.
func NewWriterWithOptions(compressionType int, allowErrors bool) (*Writer, error) {
if compressionType < 0 || compressionType > 6 {
return nil, errors.New("Incorrect compression type")
}
if compressionType == 3 {
return nil, errors.New("LZO compression is not (currently) supported")
}
return &Writer{
structure: map[string][]*fileHolder{
"/": make([]*fileHolder, 0),
},
symlinkTable: make(map[string]string),
compressionType: compressionType,
allowErrors: allowErrors,
}, nil
}
//AddFile attempts to add an os.File to the archive at it's root.
@@ -83,7 +105,7 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error {
return err
}
err = w.AddFileToFolder(holder.path+"/"+holder.name, fil)
if err != nil && !w.AllowErrors {
if err != nil && !w.allowErrors {
for _, dir := range dirsAdded {
w.Remove(dir)
}
@@ -92,7 +114,7 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error {
log.Println("Error while adding", fil.Name())
log.Println(err)
}
if !w.AllowErrors {
if !w.allowErrors {
dirsAdded = append(dirsAdded, holder.path+"/"+holder.name)
}
}
@@ -149,6 +171,7 @@ func (w *Writer) Remove(filepath string) bool {
//
//If this is not run before writing, you may end up with broken symlinks.
func (w *Writer) FixSymlinks() error {
//TODO
return errors.New("DON'T")
}
@@ -164,5 +187,6 @@ func (w *Writer) WriteToFilename(filepath string) error {
//WriteTo attempts to write the archive to the given io.Writer.
func (w *Writer) WriteTo(write io.Writer) (int64, error) {
//TODO
return 0, errors.New("I SAID DON'T")
}
+15
View File
@@ -0,0 +1,15 @@
package squashfs
//TODO: Allow settings the options
// func (w *Writer) SetGzipOptions() error {}
// func (w *Writer) SetLzmaOptions() error {}
// func (w *Writer) SetLzoOptions() error {}
// func (w *Writer) SetXzOptions() error {}
// func (w *Writer) SetLz4Options() error {}
// func (w *Writer) SetZstdOptions() error {}