Added some data writing logic.

This commit is contained in:
Caleb Gardner
2021-02-26 01:53:16 -06:00
parent 65bc4a5d78
commit 9913b848c6
3 changed files with 110 additions and 3 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ import (
type fragmentEntry struct { type fragmentEntry struct {
Start uint64 Start uint64
Size uint32 Size uint32
// Unused uint32 _ uint32 //unused
} }
//GetFragmentDataFromInode returns the fragment data for a given inode. //GetFragmentDataFromInode returns the fragment data for a given inode.
+108 -1
View File
@@ -1,11 +1,18 @@
package squashfs package squashfs
import "reflect" import (
"io"
"reflect"
"sync"
)
func (w *Writer) compressData(data []byte) ([]byte, error) { func (w *Writer) compressData(data []byte) ([]byte, error) {
if reflect.DeepEqual(data, make([]byte, len(data))) { if reflect.DeepEqual(data, make([]byte, len(data))) {
return nil, nil return nil, nil
} }
if w.Flags.UncompressedData || w.compressor == nil {
return data, nil
}
compressedData, err := w.compressor.Compress(data) compressedData, err := w.compressor.Compress(data)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -15,3 +22,103 @@ func (w *Writer) compressData(data []byte) ([]byte, error) {
} }
return compressedData, nil return compressedData, nil
} }
//Writes the given fileHolder to the WriterAt at the given offset.
//If fil.Reader implements io.ReaderAt, the process is threaded.
func (w *Writer) writeFile(fil *fileHolder, write io.WriterAt, startOffset int64) (endOffset int64, err error) {
endOffset = startOffset
var sizes []uint32
if fil.fragIndex != -1 {
sizes = fil.blockSizes[:len(fil.blockSizes)-1]
} else {
sizes = fil.blockSizes
}
if rdrAt, ok := fil.reader.(io.ReaderAt); ok {
type writeReturn struct {
err error
byts []byte
i int
}
out := make(chan *writeReturn)
var filOffset int64
var sync sync.WaitGroup
sync.Add(len(sizes))
for i, size := range sizes {
go func(offset int64, size uint32, i int) {
var ret writeReturn
ret.i = i
defer func() {
out <- &ret
}()
ret.byts = make([]byte, size)
_, ret.err = rdrAt.ReadAt(ret.byts, offset)
if ret.err != nil {
return
}
ret.byts, ret.err = w.compressData(ret.byts)
sync.Done()
}(filOffset, size, i)
filOffset += int64(size)
}
var curInd int
var holdingArea []*writeReturn
for curInd < len(sizes) {
var tmp *writeReturn
for _, ret := range holdingArea {
if ret.i == curInd {
tmp = ret
break
}
}
if tmp == nil {
tmp = <-out
if tmp.err != nil {
sync.Wait()
return endOffset, tmp.err
}
if tmp.i != curInd {
holdingArea = append(holdingArea, tmp)
continue
}
}
fil.blockSizes[curInd] = uint32(len(tmp.byts))
if len(tmp.byts) == int(w.BlockSize) {
//set uncompressed bit if not compressed
fil.blockSizes[curInd] |= (1 << 24)
}
var n int
n, err = write.WriteAt(tmp.byts, endOffset)
endOffset += int64(n)
if err != nil {
sync.Wait()
return
}
curInd++
}
return
}
var byts []byte
for i, size := range sizes {
byts = make([]byte, size)
_, err = fil.reader.Read(byts)
if err != nil {
return
}
byts, err = w.compressData(byts)
if err != nil {
return
}
fil.blockSizes[i] = uint32(len(byts))
if len(byts) == int(w.BlockSize) {
//set uncompressed bit if not compressed
fil.blockSizes[i] |= (1 << 24)
}
var n int
n, err = write.WriteAt(byts, endOffset)
endOffset += int64(n)
if err != nil {
return
}
}
return
}
+1 -1
View File
@@ -26,7 +26,7 @@ func (w *Writer) fixFolders() error {
//are added with full permission (777). //are added with full permission (777).
// //
//Not working. Yet. //Not working. Yet.
func (w *Writer) WriteTo(write io.Writer) (int64, error) { func (w *Writer) WriteTo(write io.WriterAt) (int64, error) {
err := w.fixFolders() err := w.fixFolders()
if err != nil { if err != nil {
return 0, err return 0, err