diff --git a/low/data/fullreader.go b/low/data/fullreader.go index d075844..1e41eba 100644 --- a/low/data/fullreader.go +++ b/low/data/fullreader.go @@ -9,7 +9,6 @@ import ( "sync" "github.com/CalebQ42/squashfs/internal/decompress" - "github.com/CalebQ42/squashfs/internal/routinemanager" "github.com/CalebQ42/squashfs/internal/toreader" ) @@ -43,6 +42,9 @@ func (r *FullReader) AddFrag(frag FragReaderConstructor) { } func (r *FullReader) SetGoroutineLimit(limit uint16) { + if limit <= 0 { + r.goroutineLimit = 1 + } r.goroutineLimit = limit } @@ -75,9 +77,9 @@ func (r FullReader) process(index uint64, fileOffset uint64, pool *sync.Pool, re } func (r FullReader) WriteTo(w io.Writer) (int64, error) { - if wa, is := w.(io.WriterAt); is { - return r.writeToWriteAt(wa) - } + // if wa, is := w.(io.WriterAt); is { + // return r.writeToWriteAt(wa) + // } var curIndex uint64 var curOffset uint64 var toProcess uint16 @@ -173,74 +175,74 @@ func (r FullReader) WriteTo(w io.Writer) (int64, error) { return wrote, nil } -func (r FullReader) writeToWriteAt(w io.WriterAt) (out int64, outErr error) { - wait := sync.WaitGroup{} - wait.Add(len(r.sizes)) - mgr := routinemanager.NewManager(r.goroutineLimit) - curOffset := r.initialOffset - for i := uint64(0); i < uint64(len(r.sizes)); i++ { - go func(index uint64, fileOffset int64) { - lckNum := mgr.Lock() - defer mgr.Unlock(lckNum) - defer wait.Done() - realSize := r.sizes[index] &^ (1 << 24) - if realSize == 0 { - if index == uint64(len(r.sizes))-1 && r.frag == nil { - _, err := w.WriteAt([]byte{0}, int64((uint64(r.blockSize)*index)+r.finalBlockSize)-1) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - out = max(out, int64((uint64(r.blockSize)*index)+r.finalBlockSize)) - } - return - } - data := make([]byte, realSize) - err := binary.Read(toreader.NewReader(r.r, int64(r.initialOffset)+int64(fileOffset)), binary.LittleEndian, &data) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - if r.sizes[index] == realSize { - data, err = r.d.Decompress(data) - } - if err != nil { - outErr = errors.Join(outErr, err) - return - } - _, err = w.WriteAt(data, int64(uint64(r.blockSize)*index)) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - out = max(out, int64(uint64(r.blockSize)*(index+1))) - }(i, curOffset) - curOffset += int64(r.sizes[i]) &^ (1 << 24) - } - if r.frag != nil { - wait.Add(1) - go func() { - lckNum := mgr.Lock() - defer mgr.Unlock(lckNum) - defer wait.Done() - rdr, err := r.frag() - if err != nil { - outErr = errors.Join(outErr, err) - return - } - dat, err := io.ReadAll(rdr) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - _, err = w.WriteAt(dat, int64(int(r.blockSize)*len(r.sizes))) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - out = int64(int(r.blockSize)*len(r.sizes)) + int64(r.finalBlockSize) - }() - } - wait.Wait() - return -} +// func (r FullReader) writeToWriteAt(w io.WriterAt) (out int64, outErr error) { +// wait := &sync.WaitGroup{} +// wait.Add(len(r.sizes)) +// mgr := routinemanager.NewManager(r.goroutineLimit) +// curOffset := r.initialOffset +// for i := uint64(0); i < uint64(len(r.sizes)); i++ { +// go func(index uint64, fileOffset int64) { +// lckNum := mgr.Lock() +// defer mgr.Unlock(lckNum) +// defer wait.Done() +// realSize := r.sizes[index] &^ (1 << 24) +// if realSize == 0 { +// if index == uint64(len(r.sizes))-1 && r.frag == nil { +// _, err := w.WriteAt([]byte{0}, int64((uint64(r.blockSize)*index)+r.finalBlockSize)-1) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// out = max(out, int64((uint64(r.blockSize)*index)+r.finalBlockSize)) +// } +// return +// } +// data := make([]byte, realSize) +// err := binary.Read(toreader.NewReader(r.r, int64(fileOffset)), binary.LittleEndian, &data) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// if r.sizes[index] == realSize { +// data, err = r.d.Decompress(data) +// } +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// _, err = w.WriteAt(data, int64(uint64(r.blockSize)*index)) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// out = max(out, int64(uint64(r.blockSize)*(index+1))) +// }(i, curOffset) +// curOffset += int64(r.sizes[i]) &^ (1 << 24) +// } +// if r.frag != nil { +// wait.Add(1) +// go func() { +// lckNum := mgr.Lock() +// defer mgr.Unlock(lckNum) +// defer wait.Done() +// rdr, err := r.frag() +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// dat, err := io.ReadAll(rdr) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// _, err = w.WriteAt(dat, int64(int(r.blockSize)*len(r.sizes))) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// out = int64(int(r.blockSize)*len(r.sizes)) + int64(r.finalBlockSize) +// }() +// } +// wait.Wait() +// return +// } diff --git a/squashfs_test.go b/squashfs_test.go index ed74d3f..1e0873d 100644 --- a/squashfs_test.go +++ b/squashfs_test.go @@ -100,8 +100,8 @@ func BenchmarkRace(b *testing.B) { b.Log("Unsquashfs error:", err) } unsquashTime = time.Since(start) - // b.Log("Library took:", libTime.Round(time.Millisecond)) - // b.Log("unsquashfs took:", unsquashTime.Round(time.Millisecond)) + b.Log("Library took:", libTime.Round(time.Millisecond)) + b.Log("unsquashfs took:", unsquashTime.Round(time.Millisecond)) b.Log("unsquashfs is", strconv.FormatFloat(float64(libTime.Milliseconds())/float64(unsquashTime.Milliseconds()), 'f', 2, 64), "times faster") } @@ -124,7 +124,7 @@ func TestExtractQuick(t *testing.T) { } os.RemoveAll(filepath.Join(tmpDir, "testLog.txt")) logFil, _ := os.Create(filepath.Join(tmpDir, "testLog.txt")) - op := DefaultOptions() + op := FastOptions() op.Verbose = true op.IgnorePerm = true op.LogOutput = logFil @@ -167,7 +167,7 @@ func TestExtractQuick(t *testing.T) { } } -var filePath = "bin" +var filePath = "Start.exe" func TestSingleFile(t *testing.T) { tmpDir := "testing" @@ -184,15 +184,11 @@ func TestSingleFile(t *testing.T) { if err != nil { t.Fatal(err) } - err = f.(*File).ExtractWithOptions("testing", &ExtractionOptions{Verbose: true}) + op := DefaultOptions() + op.Verbose = true + err = f.(*File).ExtractWithOptions("testing", op) if err != nil { t.Fatal(err) } t.Fatal("HI") } - -func TestStuff(t *testing.T) { - fil, _ := os.Create("testing/stuff.txt") - _, err := fil.WriteAt([]byte("Yo"), 1024) - t.Fatal(err) -}