Added more necessary parts to compression.

This commit is contained in:
Caleb Gardner
2021-02-24 05:58:18 -06:00
parent 8a91e1a1c1
commit a123935250
5 changed files with 66 additions and 6 deletions
+6 -3
View File
@@ -33,6 +33,7 @@ type Writer struct {
//variables used when actually writing. //variables used when actually writing.
superblock superblock superblock superblock
frags []fragment
} }
//NewWriter creates a new with the default options (Gzip compression and allow errors) //NewWriter creates a new with the default options (Gzip compression and allow errors)
@@ -68,10 +69,11 @@ type fileHolder struct {
path string path string
name string name string
symLocation string symLocation string
UID int blockSizes []uint32
GUID int GUID int
perm int perm int
size uint32 size uint64
UID int
folder bool folder bool
symlink bool symlink bool
} }
@@ -164,7 +166,7 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error {
//AddReaderTo adds the data from the given reader to the archive as a file located at the given filepath. //AddReaderTo adds the data from the given reader to the archive as a file located at the given filepath.
//Data from the reader is not read until the squashfs archive is writen. //Data from the reader is not read until the squashfs archive is writen.
//If the given reader implements io.Closer, it will be closed after it is fully read. //If the given reader implements io.Closer, it will be closed after it is fully read.
func (w *Writer) AddReaderTo(filepath string, reader io.Reader) error { func (w *Writer) AddReaderTo(filepath string, reader io.Reader, size uint64) error {
filepath = path.Clean(filepath) filepath = path.Clean(filepath)
if !strings.HasPrefix(filepath, "/") { if !strings.HasPrefix(filepath, "/") {
filepath = "/" + filepath filepath = "/" + filepath
@@ -175,6 +177,7 @@ func (w *Writer) AddReaderTo(filepath string, reader io.Reader) error {
var holder fileHolder var holder fileHolder
holder.path = path.Dir(filepath) holder.path = path.Dir(filepath)
holder.name = path.Base(filepath) holder.name = path.Base(filepath)
holder.size = size
holder.reader = reader holder.reader = reader
w.structure[holder.path] = append(w.structure[holder.path], &holder) w.structure[holder.path] = append(w.structure[holder.path], &holder)
return nil return nil
View File
+21
View File
@@ -0,0 +1,21 @@
package squashfs
type fragment struct {
w *Writer
files []*fileHolder
sizes []uint32
}
func (f *fragment) SizeLeft() uint32 {
totalSize := uint32(0)
for _, siz := range f.sizes {
totalSize += siz
}
return f.w.BlockSize - uint32(totalSize)
}
func (f *fragment) AddFragment(fil *fileHolder) {
//SizeLeft should already be checked
f.files = append(f.files, fil)
f.sizes = append(f.sizes, fil.blockSizes[len(fil.blockSizes)-1])
}
+23
View File
@@ -0,0 +1,23 @@
package squashfs
func (w *Writer) countInodes() (out uint32) {
for _, files := range w.structure {
out++
out += uint32(len(files))
}
return
}
//intilialize the block sizes. These values will be overwritten with their compressed sizes later.
func (w *Writer) calculateBlockSizes(fil *fileHolder) {
tmp := fil.size
for {
if tmp < uint64(w.BlockSize) {
fil.blockSizes = append(fil.blockSizes, uint32(tmp))
break
}
tmp -= uint64(w.BlockSize)
fil.blockSizes = append(fil.blockSizes, w.BlockSize)
}
return
}
+16 -3
View File
@@ -3,21 +3,32 @@ package squashfs
import ( import (
"errors" "errors"
"io" "io"
"io/fs"
"math" "math"
"path" "time"
) )
func (w *Writer) fixFolders() error { func (w *Writer) fixFolders() error {
for folder := range w.structure { for folder := range w.structure {
if folder == "/" { if folder == "/" || w.Contains(folder) {
continue continue
} }
dir, name := path.Dir(folder), path.Base(folder) err := w.AddFolderTo(folder, fs.ModePerm)
if err != nil {
return err
} }
}
return nil
} }
//WriteTo attempts to write the archive to the given io.Writer. //WriteTo attempts to write the archive to the given io.Writer.
//Folder that aren't present (such as if you add a file at /folder/file, but not the folder /folder)
//are added with full permission (777).
func (w *Writer) WriteTo(write io.Writer) (int64, error) { func (w *Writer) WriteTo(write io.Writer) (int64, error) {
err := w.fixFolders()
if err != nil {
return 0, err
}
if w.BlockSize > 1048576 { if w.BlockSize > 1048576 {
w.BlockSize = 1048576 w.BlockSize = 1048576
} else if w.BlockSize < 4096 { } else if w.BlockSize < 4096 {
@@ -28,6 +39,8 @@ func (w *Writer) WriteTo(write io.Writer) (int64, error) {
w.Flags.NoXattr = true w.Flags.NoXattr = true
w.superblock = superblock{ w.superblock = superblock{
Magic: magic, Magic: magic,
InodeCount: w.countInodes(),
CreationTime: uint32(time.Now().Unix()),
BlockSize: w.BlockSize, BlockSize: w.BlockSize,
BlockLog: uint16(math.Log2(float64(w.BlockSize))), BlockLog: uint16(math.Log2(float64(w.BlockSize))),
CompressionType: uint16(w.compressionType), CompressionType: uint16(w.compressionType),