Added more necessary parts to compression.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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])
|
||||||
|
}
|
||||||
@@ -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
@@ -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),
|
||||||
|
|||||||
Reference in New Issue
Block a user