diff --git a/compress.go b/compress.go new file mode 100644 index 0000000..f2f135f --- /dev/null +++ b/compress.go @@ -0,0 +1,17 @@ +package squashfs + +import "reflect" + +func (w *Writer) compressData(data []byte) ([]byte, error) { + if reflect.DeepEqual(data, make([]byte, len(data))) { + return nil, nil + } + compressedData, err := w.compressor.Compress(data) + if err != nil { + return nil, err + } + if len(data) <= len(compressedData) { + return data, nil + } + return compressedData, nil +} diff --git a/internal/compression/gzip.go b/internal/compression/gzip.go index 0a4e591..a5cc629 100644 --- a/internal/compression/gzip.go +++ b/internal/compression/gzip.go @@ -50,9 +50,11 @@ func (g *Gzip) Decompress(r io.Reader) ([]byte, error) { //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) + wrt, err := zlib.NewWriterLevel(&buf, int(g.CompressionLevel)) + if err != nil { + return nil, err + } + _, err = wrt.Write(data) if err != nil { return nil, err } diff --git a/writer.go b/writer.go index 65a990d..decf76d 100644 --- a/writer.go +++ b/writer.go @@ -6,7 +6,9 @@ import ( "log" "os" "path" + "sort" "strings" + "syscall" "github.com/CalebQ42/squashfs/internal/compression" ) @@ -18,6 +20,7 @@ type fileHolder struct { symLocation string UID int GUID int + perm int folder bool symlink bool } @@ -28,7 +31,7 @@ type Writer struct { compressor compression.Compressor structure map[string][]*fileHolder symlinkTable map[string]string //[oldpath]newpath - superblock superblock + uidGUIDTable []int compressionType int allowErrors bool } @@ -87,6 +90,20 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error { } holder.folder = stat.IsDir() holder.symlink = (stat.Mode()&os.ModeSymlink == os.ModeSymlink) + holder.perm = int(stat.Mode().Perm()) + //Thanks to https://stackoverflow.com/questions/58179647/getting-uid-and-gid-of-a-file for uid and guid getting + if stat, ok := stat.Sys().(*syscall.Stat_t); ok { + holder.UID = int(stat.Uid) + holder.GUID = int(stat.Gid) + } + if sort.SearchInts(w.uidGUIDTable, holder.UID) == len(w.uidGUIDTable) { + w.uidGUIDTable = append(w.uidGUIDTable, holder.UID) + sort.Ints(w.uidGUIDTable) + } + if sort.SearchInts(w.uidGUIDTable, holder.GUID) == len(w.uidGUIDTable) { + w.uidGUIDTable = append(w.uidGUIDTable, holder.GUID) + sort.Ints(w.uidGUIDTable) + } if holder.symlink { target, err := os.Readlink(file.Name()) if err != nil {