Reduce use of binary.Read and, by extention, reflection
This commit is contained in:
@@ -23,14 +23,15 @@ func NewReader(r io.Reader, d decompress.Decompressor) *Reader {
|
|||||||
|
|
||||||
func (r *Reader) advance() error {
|
func (r *Reader) advance() error {
|
||||||
r.curOffset = 0
|
r.curOffset = 0
|
||||||
var size uint16
|
dat := make([]byte, 2)
|
||||||
err := binary.Read(r.r, binary.LittleEndian, &size)
|
_, err := r.r.Read(dat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
size := binary.LittleEndian.Uint16(dat)
|
||||||
realSize := size &^ 0x8000
|
realSize := size &^ 0x8000
|
||||||
r.dat = make([]byte, realSize)
|
r.dat = make([]byte, realSize)
|
||||||
err = binary.Read(r.r, binary.LittleEndian, &r.dat)
|
_, err = r.r.Read(r.dat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
@@ -10,7 +9,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/CalebQ42/squashfs/internal/decompress"
|
"github.com/CalebQ42/squashfs/internal/decompress"
|
||||||
"github.com/CalebQ42/squashfs/internal/toreader"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type FragReaderConstructor func() (io.Reader, error)
|
type FragReaderConstructor func() (io.Reader, error)
|
||||||
@@ -80,7 +78,7 @@ func (r FullReader) process(index uint64, fileOffset uint64, pool *sync.Pool, re
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ret.data = make([]byte, realSize)
|
ret.data = make([]byte, realSize)
|
||||||
ret.err = binary.Read(toreader.NewReader(r.r, int64(r.initialOffset)+int64(fileOffset)), binary.LittleEndian, &ret.data)
|
_, ret.err = r.r.ReadAt(ret.data, r.initialOffset+int64(fileOffset))
|
||||||
if r.sizes[index] == realSize {
|
if r.sizes[index] == realSize {
|
||||||
ret.data, ret.err = r.d.Decompress(ret.data)
|
ret.data, ret.err = r.d.Decompress(ret.data)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -1,7 +1,6 @@
|
|||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
|
||||||
@@ -56,7 +55,7 @@ func (r *Reader) advance() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
r.dat = make([]byte, realSize)
|
r.dat = make([]byte, realSize)
|
||||||
err = binary.Read(r.r, binary.LittleEndian, &r.dat)
|
_, err = r.r.Read(r.dat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -130,7 +130,7 @@ func (b FileBase) GetRegFileReaders(r Reader) (data.Reader, data.FullReader, err
|
|||||||
return outRdr, outFull, nil
|
return outRdr, outFull, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *FileBase) GetFullReader(r *Reader) (data.FullReader, error) {
|
func (b FileBase) GetFullReader(r *Reader) (data.FullReader, error) {
|
||||||
if !b.IsRegular() {
|
if !b.IsRegular() {
|
||||||
return data.FullReader{}, errors.New("not a regular file")
|
return data.FullReader{}, errors.New("not a regular file")
|
||||||
}
|
}
|
||||||
@@ -167,7 +167,7 @@ func (b *FileBase) GetFullReader(r *Reader) (data.FullReader, error) {
|
|||||||
return outFull, nil
|
return outFull, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *FileBase) GetReader(r *Reader) (data.Reader, error) {
|
func (b FileBase) GetReader(r *Reader) (data.Reader, error) {
|
||||||
if !b.IsRegular() {
|
if !b.IsRegular() {
|
||||||
return data.Reader{}, errors.New("not a regular file")
|
return data.Reader{}, errors.New("not a regular file")
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-15
@@ -13,7 +13,7 @@ type Directory struct {
|
|||||||
ParentNum uint32
|
ParentNum uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type eDirectoryInit struct {
|
type EDirectory struct {
|
||||||
LinkCount uint32
|
LinkCount uint32
|
||||||
Size uint32
|
Size uint32
|
||||||
BlockStart uint32
|
BlockStart uint32
|
||||||
@@ -21,42 +21,55 @@ type eDirectoryInit struct {
|
|||||||
IndCount uint16
|
IndCount uint16
|
||||||
Offset uint16
|
Offset uint16
|
||||||
XattrInd uint32
|
XattrInd uint32
|
||||||
}
|
|
||||||
|
|
||||||
type EDirectory struct {
|
|
||||||
eDirectoryInit
|
|
||||||
Indexes []DirectoryIndex
|
Indexes []DirectoryIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
type directoryIndexInit struct {
|
type DirectoryIndex struct {
|
||||||
Ind uint32
|
Ind uint32
|
||||||
Start uint32
|
Start uint32
|
||||||
NameSize uint32
|
NameSize uint32
|
||||||
}
|
|
||||||
|
|
||||||
type DirectoryIndex struct {
|
|
||||||
directoryIndexInit
|
|
||||||
Name []byte
|
Name []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadDir(r io.Reader) (d Directory, err error) {
|
func ReadDir(r io.Reader) (d Directory, err error) {
|
||||||
err = binary.Read(r, binary.LittleEndian, &d)
|
dat := make([]byte, 16)
|
||||||
|
_, err = r.Read(dat)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.BlockStart = binary.LittleEndian.Uint32(dat)
|
||||||
|
d.LinkCount = binary.LittleEndian.Uint32(dat[4:])
|
||||||
|
d.Size = binary.LittleEndian.Uint16(dat[8:])
|
||||||
|
d.Offset = binary.LittleEndian.Uint16(dat[10:])
|
||||||
|
d.ParentNum = binary.LittleEndian.Uint32(dat[12:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadEDir(r io.Reader) (d EDirectory, err error) {
|
func ReadEDir(r io.Reader) (d EDirectory, err error) {
|
||||||
err = binary.Read(r, binary.LittleEndian, &d.eDirectoryInit)
|
dat := make([]byte, 24)
|
||||||
|
_, err = r.Read(dat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
d.LinkCount = binary.LittleEndian.Uint32(dat)
|
||||||
|
d.Size = binary.LittleEndian.Uint32(dat[4:])
|
||||||
|
d.BlockStart = binary.LittleEndian.Uint32(dat[8:])
|
||||||
|
d.ParentNum = binary.LittleEndian.Uint32(dat[12:])
|
||||||
|
d.IndCount = binary.LittleEndian.Uint16(dat[16:])
|
||||||
|
d.Offset = binary.LittleEndian.Uint16(dat[18:])
|
||||||
|
d.XattrInd = binary.LittleEndian.Uint32(dat[20:])
|
||||||
d.Indexes = make([]DirectoryIndex, d.IndCount)
|
d.Indexes = make([]DirectoryIndex, d.IndCount)
|
||||||
for i := range d.Indexes {
|
for i := range d.IndCount {
|
||||||
err = binary.Read(r, binary.LittleEndian, &d.Indexes[i].directoryIndexInit)
|
dat = make([]byte, 12)
|
||||||
|
_, err = r.Read(dat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
d.Indexes[i].Ind = binary.LittleEndian.Uint32(dat)
|
||||||
|
d.Indexes[i].Start = binary.LittleEndian.Uint32(dat[4:])
|
||||||
|
d.Indexes[i].NameSize = binary.LittleEndian.Uint32(dat[8:])
|
||||||
d.Indexes[i].Name = make([]byte, d.Indexes[i].NameSize+1)
|
d.Indexes[i].Name = make([]byte, d.Indexes[i].NameSize+1)
|
||||||
err = binary.Read(r, binary.LittleEndian, &d.Indexes[i].Name)
|
_, err = r.Read(d.Indexes[i].Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-7
@@ -6,15 +6,11 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fileInit struct {
|
type File struct {
|
||||||
BlockStart uint32
|
BlockStart uint32
|
||||||
FragInd uint32
|
FragInd uint32
|
||||||
FragOffset uint32
|
FragOffset uint32
|
||||||
Size uint32
|
Size uint32
|
||||||
}
|
|
||||||
|
|
||||||
type File struct {
|
|
||||||
fileInit
|
|
||||||
BlockSizes []uint32
|
BlockSizes []uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,16 +30,28 @@ type EFile struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ReadFile(r io.Reader, blockSize uint32) (f File, err error) {
|
func ReadFile(r io.Reader, blockSize uint32) (f File, err error) {
|
||||||
err = binary.Read(r, binary.LittleEndian, &f.fileInit)
|
dat := make([]byte, 16)
|
||||||
|
_, err = r.Read(dat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
f.BlockStart = binary.LittleEndian.Uint32(dat)
|
||||||
|
f.FragInd = binary.LittleEndian.Uint32(dat[4:])
|
||||||
|
f.FragOffset = binary.LittleEndian.Uint32(dat[8:])
|
||||||
|
f.Size = binary.LittleEndian.Uint32(dat[12:])
|
||||||
toRead := int(math.Floor(float64(f.Size) / float64(blockSize)))
|
toRead := int(math.Floor(float64(f.Size) / float64(blockSize)))
|
||||||
if f.FragInd == 0xFFFFFFFF && f.Size%blockSize > 0 {
|
if f.FragInd == 0xFFFFFFFF && f.Size%blockSize > 0 {
|
||||||
toRead++
|
toRead++
|
||||||
}
|
}
|
||||||
|
dat = make([]byte, toRead*4)
|
||||||
|
_, err = r.Read(dat)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
f.BlockSizes = make([]uint32, toRead)
|
f.BlockSizes = make([]uint32, toRead)
|
||||||
err = binary.Read(r, binary.LittleEndian, &f.BlockSizes)
|
for i := range toRead {
|
||||||
|
f.BlockSizes[i] = binary.LittleEndian.Uint32(dat[i*4:])
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
@@ -68,6 +68,26 @@ func TestMisc(t *testing.T) {
|
|||||||
// t.Fatal("UM")
|
// t.Fatal("UM")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkExtract(b *testing.B) {
|
||||||
|
tmpDir := "testing"
|
||||||
|
fil, err := preTest(tmpDir)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
libPath := filepath.Join(tmpDir, "ExtractLib")
|
||||||
|
os.RemoveAll(libPath)
|
||||||
|
op := FastOptions()
|
||||||
|
op.IgnorePerm = true
|
||||||
|
rdr, err := NewReader(fil)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
err = rdr.ExtractWithOptions(libPath, op)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkRace(b *testing.B) {
|
func BenchmarkRace(b *testing.B) {
|
||||||
tmpDir := "testing"
|
tmpDir := "testing"
|
||||||
fil, err := preTest(tmpDir)
|
fil, err := preTest(tmpDir)
|
||||||
|
|||||||
Reference in New Issue
Block a user