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 {
|
||||
r.curOffset = 0
|
||||
var size uint16
|
||||
err := binary.Read(r.r, binary.LittleEndian, &size)
|
||||
dat := make([]byte, 2)
|
||||
_, err := r.r.Read(dat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
size := binary.LittleEndian.Uint16(dat)
|
||||
realSize := size &^ 0x8000
|
||||
r.dat = make([]byte, realSize)
|
||||
err = binary.Read(r.r, binary.LittleEndian, &r.dat)
|
||||
_, err = r.r.Read(r.dat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"io/fs"
|
||||
@@ -10,7 +9,6 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/CalebQ42/squashfs/internal/decompress"
|
||||
"github.com/CalebQ42/squashfs/internal/toreader"
|
||||
)
|
||||
|
||||
type FragReaderConstructor func() (io.Reader, error)
|
||||
@@ -80,7 +78,7 @@ func (r FullReader) process(index uint64, fileOffset uint64, pool *sync.Pool, re
|
||||
return
|
||||
}
|
||||
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 {
|
||||
ret.data, ret.err = r.d.Decompress(ret.data)
|
||||
}
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"io/fs"
|
||||
|
||||
@@ -56,7 +55,7 @@ func (r *Reader) advance() error {
|
||||
return nil
|
||||
}
|
||||
r.dat = make([]byte, realSize)
|
||||
err = binary.Read(r.r, binary.LittleEndian, &r.dat)
|
||||
_, err = r.r.Read(r.dat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+2
-2
@@ -130,7 +130,7 @@ func (b FileBase) GetRegFileReaders(r Reader) (data.Reader, data.FullReader, err
|
||||
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() {
|
||||
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
|
||||
}
|
||||
|
||||
func (b *FileBase) GetReader(r *Reader) (data.Reader, error) {
|
||||
func (b FileBase) GetReader(r *Reader) (data.Reader, error) {
|
||||
if !b.IsRegular() {
|
||||
return data.Reader{}, errors.New("not a regular file")
|
||||
}
|
||||
|
||||
+32
-19
@@ -13,7 +13,7 @@ type Directory struct {
|
||||
ParentNum uint32
|
||||
}
|
||||
|
||||
type eDirectoryInit struct {
|
||||
type EDirectory struct {
|
||||
LinkCount uint32
|
||||
Size uint32
|
||||
BlockStart uint32
|
||||
@@ -21,42 +21,55 @@ type eDirectoryInit struct {
|
||||
IndCount uint16
|
||||
Offset uint16
|
||||
XattrInd uint32
|
||||
}
|
||||
|
||||
type EDirectory struct {
|
||||
eDirectoryInit
|
||||
Indexes []DirectoryIndex
|
||||
}
|
||||
|
||||
type directoryIndexInit struct {
|
||||
Ind uint32
|
||||
Start uint32
|
||||
NameSize uint32
|
||||
Indexes []DirectoryIndex
|
||||
}
|
||||
|
||||
type DirectoryIndex struct {
|
||||
directoryIndexInit
|
||||
Name []byte
|
||||
Ind uint32
|
||||
Start uint32
|
||||
NameSize uint32
|
||||
Name []byte
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
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)
|
||||
for i := range d.Indexes {
|
||||
err = binary.Read(r, binary.LittleEndian, &d.Indexes[i].directoryIndexInit)
|
||||
for i := range d.IndCount {
|
||||
dat = make([]byte, 12)
|
||||
_, err = r.Read(dat)
|
||||
if err != nil {
|
||||
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)
|
||||
err = binary.Read(r, binary.LittleEndian, &d.Indexes[i].Name)
|
||||
_, err = r.Read(d.Indexes[i].Name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
+15
-7
@@ -6,15 +6,11 @@ import (
|
||||
"math"
|
||||
)
|
||||
|
||||
type fileInit struct {
|
||||
type File struct {
|
||||
BlockStart uint32
|
||||
FragInd uint32
|
||||
FragOffset uint32
|
||||
Size uint32
|
||||
}
|
||||
|
||||
type File struct {
|
||||
fileInit
|
||||
BlockSizes []uint32
|
||||
}
|
||||
|
||||
@@ -34,16 +30,28 @@ type EFile struct {
|
||||
}
|
||||
|
||||
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 {
|
||||
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)))
|
||||
if f.FragInd == 0xFFFFFFFF && f.Size%blockSize > 0 {
|
||||
toRead++
|
||||
}
|
||||
dat = make([]byte, toRead*4)
|
||||
_, err = r.Read(dat)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -68,6 +68,26 @@ func TestMisc(t *testing.T) {
|
||||
// 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) {
|
||||
tmpDir := "testing"
|
||||
fil, err := preTest(tmpDir)
|
||||
|
||||
Reference in New Issue
Block a user