More work on fragments.

This commit is contained in:
Caleb Gardner
2021-02-25 06:22:57 -06:00
parent c9d451e24c
commit 65bc4a5d78
+43 -4
View File
@@ -1,12 +1,17 @@
package squashfs package squashfs
import (
"bytes"
"io"
)
type fragment struct { type fragment struct {
w *Writer w *Writer
files []*fileHolder files []*fileHolder
sizes []uint32 sizes []uint32
} }
func (f *fragment) SizeLeft() uint32 { func (f *fragment) sizeLeft() uint32 {
totalSize := uint32(0) totalSize := uint32(0)
for _, siz := range f.sizes { for _, siz := range f.sizes {
totalSize += siz totalSize += siz
@@ -14,23 +19,57 @@ func (f *fragment) SizeLeft() uint32 {
return f.w.BlockSize - uint32(totalSize) return f.w.BlockSize - uint32(totalSize)
} }
func (f *fragment) AddFragment(fil *fileHolder) { func (f *fragment) addFragment(fil *fileHolder) {
//SizeLeft should already be checked //SizeLeft should already be checked
fil.fragOffset = len(f.files) fil.fragOffset = len(f.files)
f.files = append(f.files, fil) f.files = append(f.files, fil)
f.sizes = append(f.sizes, fil.blockSizes[len(fil.blockSizes)-1]) f.sizes = append(f.sizes, fil.blockSizes[len(fil.blockSizes)-1])
} }
//TODO: give info about the frags for the frag table.
func (w *Writer) writeFragments(write io.WriterAt, off int64) (curOffset int64, err error) {
curOffset = off
var buf bytes.Buffer
var byts []byte
var n int
for _, frag := range w.frags {
blockOffset := 0
for i, fil := range frag.files {
_, err = io.CopyN(&buf, fil.reader, int64(frag.sizes[i]))
if err != nil {
return
}
fil.fragOffset = blockOffset
blockOffset += int(frag.sizes[i])
}
if !w.Flags.UncompressedFragments && w.compressor != nil {
byts, err = w.compressor.Compress(buf.Bytes())
if err != nil {
return
}
} else {
byts = buf.Bytes()
}
n, err = write.WriteAt(byts, curOffset)
curOffset += int64(n)
if err != nil {
return
}
buf.Reset()
}
return
}
func (w *Writer) addToFragments(fil *fileHolder) { func (w *Writer) addToFragments(fil *fileHolder) {
fragSize := fil.blockSizes[len(fil.blockSizes)-1] fragSize := fil.blockSizes[len(fil.blockSizes)-1]
//only fragment if the final block is less then 80% of a full block or AlwaysFragment //only fragment if the final block is less then 80% of a full block or AlwaysFragment
if w.Flags.AlwaysFragment || fragSize < uint32(float32(w.BlockSize)*0.8) { if w.Flags.AlwaysFragment || fragSize < uint32(float32(w.BlockSize)*0.8) {
var possibleFrags []int var possibleFrags []int
for i := range w.frags { for i := range w.frags {
left := w.frags[i].SizeLeft() left := w.frags[i].sizeLeft()
if left == fragSize { if left == fragSize {
fil.fragIndex = i fil.fragIndex = i
w.frags[i].AddFragment(fil) w.frags[i].addFragment(fil)
return return
} else if left > fragSize { } else if left > fragSize {
possibleFrags = append(possibleFrags, i) possibleFrags = append(possibleFrags, i)