Setup for differnet types of compression for Writer
Added some TODOs
This commit is contained in:
@@ -15,23 +15,21 @@ type gzipInit struct {
|
|||||||
|
|
||||||
//Gzip is a decompressor for gzip type compression. Uses zlib for compression and decompression
|
//Gzip is a decompressor for gzip type compression. Uses zlib for compression and decompression
|
||||||
type Gzip struct {
|
type Gzip struct {
|
||||||
CompressionLevel int32
|
gzipInit
|
||||||
HasCustomWindow bool
|
HasCustomWindow bool
|
||||||
HasStrategies bool
|
HasStrategies bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewGzipCompressorWithOptions creates a new gzip compressor/decompressor with options read from the given reader.
|
//NewGzipCompressorWithOptions creates a new gzip compressor/decompressor with options read from the given reader.
|
||||||
func NewGzipCompressorWithOptions(r io.Reader) (*Gzip, error) {
|
func NewGzipCompressorWithOptions(r io.Reader) (*Gzip, error) {
|
||||||
var gzip Gzip
|
var gzip Gzip
|
||||||
var init gzipInit
|
err := binary.Read(r, binary.LittleEndian, &gzip.gzipInit)
|
||||||
err := binary.Read(r, binary.LittleEndian, &init)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
gzip.CompressionLevel = init.CompressionLevel
|
|
||||||
//TODO: proper support for window size and strategies
|
//TODO: proper support for window size and strategies
|
||||||
gzip.HasCustomWindow = init.WindowSize != 15
|
gzip.HasCustomWindow = gzip.WindowSize != 15
|
||||||
gzip.HasStrategies = init.Strategies != 0 && init.Strategies != 1
|
gzip.HasStrategies = gzip.Strategies != 0 && gzip.Strategies != 1
|
||||||
return &gzip, nil
|
return &gzip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +56,6 @@ func (g *Gzip) Compress(data []byte) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = wrt.Flush()
|
wrt.Close()
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,3 +35,21 @@ func (l *Lz4) Decompress(r io.Reader) ([]byte, error) {
|
|||||||
_, err := io.Copy(&buf, rdr)
|
_, err := io.Copy(&buf, rdr)
|
||||||
return buf.Bytes(), err
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,3 +23,18 @@ func (l *Lzma) Decompress(rdr io.Reader) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
return buf.Bytes(), nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,3 +53,23 @@ func (x *Xz) Decompress(rdr io.Reader) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
return buf.Bytes(), nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,3 +34,18 @@ func (z *Zstd) Decompress(r io.Reader) ([]byte, error) {
|
|||||||
_, err = io.Copy(&buf, rdr)
|
_, err = io.Copy(&buf, rdr)
|
||||||
return buf.Bytes(), err
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -77,9 +77,6 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if lz4.HC {
|
|
||||||
hasUnsupportedOptions = true
|
|
||||||
}
|
|
||||||
rdr.decompressor = lz4
|
rdr.decompressor = lz4
|
||||||
case ZstdCompression:
|
case ZstdCompression:
|
||||||
zstd, err := compression.NewZstdCompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 4))
|
zstd, err := compression.NewZstdCompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 4))
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/CalebQ42/squashfs/internal/compression"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fileHolder struct {
|
type fileHolder struct {
|
||||||
@@ -14,6 +16,8 @@ type fileHolder struct {
|
|||||||
path string
|
path string
|
||||||
name string
|
name string
|
||||||
symLocation string
|
symLocation string
|
||||||
|
UID int
|
||||||
|
GUID int
|
||||||
folder bool
|
folder bool
|
||||||
symlink bool
|
symlink bool
|
||||||
}
|
}
|
||||||
@@ -21,19 +25,37 @@ type fileHolder struct {
|
|||||||
//Writer is used to creaste squashfs archives. Currently unusable
|
//Writer is used to creaste squashfs archives. Currently unusable
|
||||||
//TODO: Make usable
|
//TODO: Make usable
|
||||||
type Writer struct {
|
type Writer struct {
|
||||||
|
compressor compression.Compressor
|
||||||
structure map[string][]*fileHolder
|
structure map[string][]*fileHolder
|
||||||
symlinkTable map[string]string //[oldpath]newpath
|
symlinkTable map[string]string //[oldpath]newpath
|
||||||
|
superblock superblock
|
||||||
compressionType int
|
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) {
|
func NewWriter() (*Writer, error) {
|
||||||
return NewWriterWithOptions(GzipCompression, true)
|
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) {
|
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.
|
//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
|
return err
|
||||||
}
|
}
|
||||||
err = w.AddFileToFolder(holder.path+"/"+holder.name, fil)
|
err = w.AddFileToFolder(holder.path+"/"+holder.name, fil)
|
||||||
if err != nil && !w.AllowErrors {
|
if err != nil && !w.allowErrors {
|
||||||
for _, dir := range dirsAdded {
|
for _, dir := range dirsAdded {
|
||||||
w.Remove(dir)
|
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("Error while adding", fil.Name())
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
if !w.AllowErrors {
|
if !w.allowErrors {
|
||||||
dirsAdded = append(dirsAdded, holder.path+"/"+holder.name)
|
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.
|
//If this is not run before writing, you may end up with broken symlinks.
|
||||||
func (w *Writer) FixSymlinks() error {
|
func (w *Writer) FixSymlinks() error {
|
||||||
|
//TODO
|
||||||
return errors.New("DON'T")
|
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.
|
//WriteTo attempts to write the archive to the given io.Writer.
|
||||||
func (w *Writer) WriteTo(write io.Writer) (int64, error) {
|
func (w *Writer) WriteTo(write io.Writer) (int64, error) {
|
||||||
|
//TODO
|
||||||
return 0, errors.New("I SAID DON'T")
|
return 0, errors.New("I SAID DON'T")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {}
|
||||||
Reference in New Issue
Block a user