Removed all the pointers
This commit is contained in:
@@ -19,49 +19,47 @@ import (
|
||||
|
||||
// File represents a file inside a squashfs archive.
|
||||
type File struct {
|
||||
full *data.FullReader
|
||||
rdr *data.Reader
|
||||
parent *FS
|
||||
full data.FullReader
|
||||
rdr data.Reader
|
||||
rdrInit bool
|
||||
parent FS
|
||||
r *Reader
|
||||
b squashfslow.FileBase
|
||||
dirsRead int
|
||||
}
|
||||
|
||||
// Creates a new *File from the given *squashfs.Base
|
||||
func (r *Reader) FileFromBase(b squashfslow.FileBase, parent *FS) *File {
|
||||
return &File{
|
||||
func (r *Reader) FileFromBase(b squashfslow.FileBase, parent FS) File {
|
||||
return File{
|
||||
b: b,
|
||||
parent: parent,
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *File) FS() (*FS, error) {
|
||||
func (f File) FS() (FS, error) {
|
||||
if !f.IsDir() {
|
||||
return nil, errors.New("not a directory")
|
||||
return FS{}, errors.New("not a directory")
|
||||
}
|
||||
d, err := f.b.ToDir(&f.r.Low)
|
||||
d, err := f.b.ToDir(f.r.Low)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return FS{}, err
|
||||
}
|
||||
return &FS{d: d, parent: f.parent, r: f.r}, nil
|
||||
return FS{d: d, parent: &f.parent, r: f.r}, nil
|
||||
}
|
||||
|
||||
// Closes the underlying readers.
|
||||
// Further calls to Read and WriteTo will re-create the readers.
|
||||
// Never returns an error.
|
||||
func (f *File) Close() error {
|
||||
if f.rdr != nil {
|
||||
return f.rdr.Close()
|
||||
}
|
||||
f.rdr = nil
|
||||
f.full = nil
|
||||
f.rdr.Close()
|
||||
f.full.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Returns the file the symlink points to.
|
||||
// If the file isn't a symlink, or points to a file outside the archive, returns nil.
|
||||
func (f *File) GetSymlinkFile() fs.File {
|
||||
func (f File) GetSymlinkFile() fs.File {
|
||||
if !f.IsSymlink() {
|
||||
return nil
|
||||
}
|
||||
@@ -76,21 +74,21 @@ func (f *File) GetSymlinkFile() fs.File {
|
||||
}
|
||||
|
||||
// Returns whether the file is a directory.
|
||||
func (f *File) IsDir() bool {
|
||||
func (f File) IsDir() bool {
|
||||
return f.b.IsDir()
|
||||
}
|
||||
|
||||
// Returns whether the file is a regular file.
|
||||
func (f *File) IsRegular() bool {
|
||||
func (f File) IsRegular() bool {
|
||||
return f.b.IsRegular()
|
||||
}
|
||||
|
||||
// Returns whether the file is a symlink.
|
||||
func (f *File) IsSymlink() bool {
|
||||
func (f File) IsSymlink() bool {
|
||||
return f.b.Inode.Type == inode.Sym || f.b.Inode.Type == inode.ESym
|
||||
}
|
||||
|
||||
func (f *File) Mode() fs.FileMode {
|
||||
func (f File) Mode() fs.FileMode {
|
||||
return f.b.Inode.Mode()
|
||||
}
|
||||
|
||||
@@ -99,7 +97,7 @@ func (f *File) Read(b []byte) (int, error) {
|
||||
if !f.IsRegular() {
|
||||
return 0, errors.New("file is not a regular file")
|
||||
}
|
||||
if f.rdr == nil {
|
||||
if !f.rdrInit {
|
||||
err := f.initializeReaders()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -114,7 +112,7 @@ func (f *File) ReadDir(n int) ([]fs.DirEntry, error) {
|
||||
if !f.IsDir() {
|
||||
return nil, errors.New("file is not a directory")
|
||||
}
|
||||
d, err := f.b.ToDir(&f.r.Low)
|
||||
d, err := f.b.ToDir(f.r.Low)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -141,7 +139,7 @@ func (f *File) ReadDir(n int) ([]fs.DirEntry, error) {
|
||||
}
|
||||
|
||||
// Returns the file's fs.FileInfo
|
||||
func (f *File) Stat() (fs.FileInfo, error) {
|
||||
func (f File) Stat() (fs.FileInfo, error) {
|
||||
uid, err := f.b.Uid(&f.r.Low)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -154,7 +152,7 @@ func (f *File) Stat() (fs.FileInfo, error) {
|
||||
}
|
||||
|
||||
// SymlinkPath returns the symlink's target path. Is the File isn't a symlink, returns an empty string.
|
||||
func (f *File) SymlinkPath() string {
|
||||
func (f File) SymlinkPath() string {
|
||||
switch f.b.Inode.Type {
|
||||
case inode.Sym:
|
||||
return string(f.b.Inode.Data.(inode.Symlink).Target)
|
||||
@@ -170,7 +168,7 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
||||
if !f.IsRegular() {
|
||||
return 0, errors.New("file is not a regular file")
|
||||
}
|
||||
if f.full == nil {
|
||||
if !f.rdrInit {
|
||||
err := f.initializeReaders()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -181,11 +179,17 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
||||
|
||||
func (f *File) initializeReaders() error {
|
||||
var err error
|
||||
f.rdr, f.full, err = f.b.GetRegFileReaders(&f.r.Low)
|
||||
f.rdr, f.full, err = f.b.GetRegFileReaders(f.r.Low)
|
||||
if err == nil {
|
||||
f.rdrInit = true
|
||||
} else {
|
||||
f.rdr.Close()
|
||||
f.full.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (f *File) deviceDevices() (maj uint32, min uint32) {
|
||||
func (f File) deviceDevices() (maj uint32, min uint32) {
|
||||
var dev uint32
|
||||
switch f.b.Inode.Type {
|
||||
case inode.Char, inode.Block:
|
||||
@@ -196,8 +200,8 @@ func (f *File) deviceDevices() (maj uint32, min uint32) {
|
||||
return dev >> 8, dev & 0x000FF
|
||||
}
|
||||
|
||||
func (f *File) path() string {
|
||||
if f.parent == nil {
|
||||
func (f File) path() string {
|
||||
if f.parent.d.Name == "" {
|
||||
return f.b.Name
|
||||
}
|
||||
return filepath.Join(f.parent.path(), f.b.Name)
|
||||
@@ -205,13 +209,13 @@ func (f *File) path() string {
|
||||
|
||||
// Extract the file to the given folder. If the file is a folder, the folder's contents will be extracted to the folder.
|
||||
// Uses default extraction options.
|
||||
func (f *File) Extract(folder string) error {
|
||||
func (f File) Extract(folder string) error {
|
||||
return f.ExtractWithOptions(folder, DefaultOptions())
|
||||
}
|
||||
|
||||
// Extract the file to the given folder. If the file is a folder, the folder's contents will be extracted to the folder.
|
||||
// Allows setting various extraction options via ExtractionOptions.
|
||||
func (f *File) ExtractWithOptions(path string, op *ExtractionOptions) error {
|
||||
func (f File) ExtractWithOptions(path string, op *ExtractionOptions) error {
|
||||
if op.manager == nil {
|
||||
op.manager = routinemanager.NewManager(op.SimultaneousFiles)
|
||||
if op.LogOutput != nil {
|
||||
@@ -227,7 +231,7 @@ func (f *File) ExtractWithOptions(path string, op *ExtractionOptions) error {
|
||||
}
|
||||
switch f.b.Inode.Type {
|
||||
case inode.Dir, inode.EDir:
|
||||
d, err := f.b.ToDir(&f.r.Low)
|
||||
d, err := f.b.ToDir(f.r.Low)
|
||||
if err != nil {
|
||||
if op.Verbose {
|
||||
log.Println("Failed to create squashfs.Directory for", path)
|
||||
|
||||
@@ -21,11 +21,11 @@ type FS struct {
|
||||
}
|
||||
|
||||
// Creates a new *FS from the given squashfs.directory
|
||||
func (r *Reader) FSFromDirectory(d squashfslow.Directory, parent *FS) *FS {
|
||||
return &FS{
|
||||
func (r *Reader) FSFromDirectory(d squashfslow.Directory, parent FS) FS {
|
||||
return FS{
|
||||
d: d,
|
||||
r: r,
|
||||
parent: parent,
|
||||
parent: &parent,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ func (f *FS) Glob(pattern string) (out []string, err error) {
|
||||
}
|
||||
|
||||
// Opens the file at name. Returns a *File as an fs.File.
|
||||
func (f *FS) Open(name string) (fs.File, error) {
|
||||
func (f FS) Open(name string) (fs.File, error) {
|
||||
name = filepath.Clean(name)
|
||||
if !fs.ValidPath(name) {
|
||||
return nil, &fs.PathError{
|
||||
@@ -142,7 +142,7 @@ func (f *FS) Open(name string) (fs.File, error) {
|
||||
Err: fs.ErrNotExist,
|
||||
}
|
||||
}
|
||||
d, err := b.ToDir(&f.r.Low)
|
||||
d, err := b.ToDir(f.r.Low)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -151,7 +151,7 @@ func (f *FS) Open(name string) (fs.File, error) {
|
||||
|
||||
// Returns all DirEntry's for the directory at name.
|
||||
// If name is not a directory, returns an error.
|
||||
func (f *FS) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
func (f FS) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
name = filepath.Clean(name)
|
||||
if !fs.ValidPath(name) {
|
||||
return nil, &fs.PathError{
|
||||
@@ -171,7 +171,7 @@ func (f *FS) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
}
|
||||
|
||||
// Returns the contents of the file at name.
|
||||
func (f *FS) ReadFile(name string) (out []byte, err error) {
|
||||
func (f FS) ReadFile(name string) (out []byte, err error) {
|
||||
name = filepath.Clean(name)
|
||||
if !fs.ValidPath(name) {
|
||||
return nil, &fs.PathError{
|
||||
@@ -194,7 +194,7 @@ func (f *FS) ReadFile(name string) (out []byte, err error) {
|
||||
}
|
||||
|
||||
// Returns the fs.FileInfo for the file at name.
|
||||
func (f *FS) Stat(name string) (fs.FileInfo, error) {
|
||||
func (f FS) Stat(name string) (fs.FileInfo, error) {
|
||||
name = filepath.Clean(name)
|
||||
if !fs.ValidPath(name) {
|
||||
return nil, &fs.PathError{
|
||||
@@ -214,7 +214,7 @@ func (f *FS) Stat(name string) (fs.FileInfo, error) {
|
||||
}
|
||||
|
||||
// Returns the FS at dir
|
||||
func (f *FS) Sub(dir string) (fs.FS, error) {
|
||||
func (f FS) Sub(dir string) (fs.FS, error) {
|
||||
dir = filepath.Clean(dir)
|
||||
if !fs.ValidPath(dir) {
|
||||
return nil, &fs.PathError{
|
||||
@@ -242,26 +242,32 @@ func (f *FS) Sub(dir string) (fs.FS, error) {
|
||||
|
||||
// Extract the FS to the given folder. If the file is a folder, the folder's contents will be extracted to the folder.
|
||||
// Uses default extraction options.
|
||||
func (f *FS) Extract(folder string) error {
|
||||
func (f FS) Extract(folder string) error {
|
||||
return f.File().Extract(folder)
|
||||
}
|
||||
|
||||
// Extract the FS to the given folder. If the file is a folder, the folder's contents will be extracted to the folder.
|
||||
// Allows setting various extraction options via ExtractionOptions.
|
||||
func (f *FS) ExtractWithOptions(folder string, op *ExtractionOptions) error {
|
||||
func (f FS) ExtractWithOptions(folder string, op *ExtractionOptions) error {
|
||||
return f.File().ExtractWithOptions(folder, op)
|
||||
}
|
||||
|
||||
// Returns the FS as a *File
|
||||
func (f *FS) File() *File {
|
||||
func (f FS) File() *File {
|
||||
if f.parent != nil {
|
||||
return &File{
|
||||
b: f.d.FileBase,
|
||||
parent: *f.parent,
|
||||
r: f.r,
|
||||
}
|
||||
}
|
||||
return &File{
|
||||
b: f.d.FileBase,
|
||||
parent: f.parent,
|
||||
r: f.r,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FS) path() string {
|
||||
func (f FS) path() string {
|
||||
if f.parent == nil {
|
||||
return f.d.Name
|
||||
}
|
||||
|
||||
+16
-2
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"io/fs"
|
||||
"math"
|
||||
"runtime"
|
||||
"sync"
|
||||
@@ -23,10 +24,11 @@ type FullReader struct {
|
||||
finalBlockSize uint64
|
||||
blockSize uint32
|
||||
goroutineLimit uint16
|
||||
closed bool
|
||||
}
|
||||
|
||||
func NewFullReader(r io.ReaderAt, initialOffset int64, d decompress.Decompressor, sizes []uint32, finalBlockSize uint64, blockSize uint32) *FullReader {
|
||||
return &FullReader{
|
||||
func NewFullReader(r io.ReaderAt, initialOffset int64, d decompress.Decompressor, sizes []uint32, finalBlockSize uint64, blockSize uint32) FullReader {
|
||||
return FullReader{
|
||||
r: r,
|
||||
d: d,
|
||||
sizes: sizes,
|
||||
@@ -37,6 +39,15 @@ func NewFullReader(r io.ReaderAt, initialOffset int64, d decompress.Decompressor
|
||||
}
|
||||
}
|
||||
|
||||
func (r *FullReader) Close() error {
|
||||
r.closed = true
|
||||
r.r = nil
|
||||
r.d = nil
|
||||
r.frag = nil
|
||||
r.sizes = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *FullReader) AddFrag(frag FragReaderConstructor) {
|
||||
r.frag = frag
|
||||
}
|
||||
@@ -77,6 +88,9 @@ func (r FullReader) process(index uint64, fileOffset uint64, pool *sync.Pool, re
|
||||
}
|
||||
|
||||
func (r FullReader) WriteTo(w io.Writer) (int64, error) {
|
||||
if r.closed {
|
||||
return 0, fs.ErrClosed
|
||||
}
|
||||
// if wa, is := w.(io.WriterAt); is {
|
||||
// return r.writeToWriteAt(wa)
|
||||
// }
|
||||
|
||||
+12
-2
@@ -3,6 +3,7 @@ package data
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"io/fs"
|
||||
|
||||
"github.com/CalebQ42/squashfs/internal/decompress"
|
||||
)
|
||||
@@ -17,10 +18,11 @@ type Reader struct {
|
||||
curIndex uint64
|
||||
finalBlockSize uint64
|
||||
blockSize uint32
|
||||
closed bool
|
||||
}
|
||||
|
||||
func NewReader(r io.Reader, d decompress.Decompressor, sizes []uint32, finalBlockSize uint64, blockSize uint32) *Reader {
|
||||
return &Reader{
|
||||
func NewReader(r io.Reader, d decompress.Decompressor, sizes []uint32, finalBlockSize uint64, blockSize uint32) Reader {
|
||||
return Reader{
|
||||
r: r,
|
||||
d: d,
|
||||
sizes: sizes,
|
||||
@@ -66,6 +68,9 @@ func (r *Reader) advance() error {
|
||||
}
|
||||
|
||||
func (r *Reader) Read(b []byte) (int, error) {
|
||||
if r.closed {
|
||||
return 0, fs.ErrClosed
|
||||
}
|
||||
curRead := 0
|
||||
var toRead int
|
||||
for curRead < len(b) {
|
||||
@@ -83,6 +88,9 @@ func (r *Reader) Read(b []byte) (int, error) {
|
||||
}
|
||||
|
||||
func (r *Reader) Close() error {
|
||||
r.closed = true
|
||||
r.r = nil
|
||||
r.d = nil
|
||||
if r.frag != nil {
|
||||
if l, ok := r.frag.(*io.LimitedReader); ok {
|
||||
if cl, ok := l.R.(io.Closer); ok {
|
||||
@@ -90,6 +98,8 @@ func (r *Reader) Close() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
r.frag = nil
|
||||
r.sizes = nil
|
||||
r.dat = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ type Directory struct {
|
||||
Entries []directory.Entry
|
||||
}
|
||||
|
||||
func (r *Reader) directoryFromRef(ref uint64, name string) (Directory, error) {
|
||||
func (r Reader) directoryFromRef(ref uint64, name string) (Directory, error) {
|
||||
i, err := r.InodeFromRef(ref)
|
||||
if err != nil {
|
||||
return Directory{}, err
|
||||
@@ -54,7 +54,7 @@ func (r *Reader) directoryFromRef(ref uint64, name string) (Directory, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Directory) Open(r *Reader, path string) (FileBase, error) {
|
||||
func (d Directory) Open(r Reader, path string) (FileBase, error) {
|
||||
path = filepath.Clean(path)
|
||||
if path == "." || path == "" {
|
||||
return d.FileBase, nil
|
||||
|
||||
+20
-20
@@ -16,11 +16,11 @@ type FileBase struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (r *Reader) BaseFromInode(i inode.Inode, name string) FileBase {
|
||||
func (r Reader) BaseFromInode(i inode.Inode, name string) FileBase {
|
||||
return FileBase{Inode: i, Name: name}
|
||||
}
|
||||
|
||||
func (r *Reader) BaseFromEntry(e directory.Entry) (FileBase, error) {
|
||||
func (r Reader) BaseFromEntry(e directory.Entry) (FileBase, error) {
|
||||
in, err := r.InodeFromEntry(e)
|
||||
if err != nil {
|
||||
return FileBase{}, err
|
||||
@@ -28,7 +28,7 @@ func (r *Reader) BaseFromEntry(e directory.Entry) (FileBase, error) {
|
||||
return FileBase{Inode: in, Name: e.Name}, nil
|
||||
}
|
||||
|
||||
func (r *Reader) BaseFromRef(ref uint64, name string) (FileBase, error) {
|
||||
func (r Reader) BaseFromRef(ref uint64, name string) (FileBase, error) {
|
||||
in, err := r.InodeFromRef(ref)
|
||||
if err != nil {
|
||||
return FileBase{}, err
|
||||
@@ -36,19 +36,19 @@ func (r *Reader) BaseFromRef(ref uint64, name string) (FileBase, error) {
|
||||
return FileBase{Inode: in, Name: name}, nil
|
||||
}
|
||||
|
||||
func (b *FileBase) Uid(r *Reader) (uint32, error) {
|
||||
func (b FileBase) Uid(r *Reader) (uint32, error) {
|
||||
return r.Id(b.Inode.UidInd)
|
||||
}
|
||||
|
||||
func (b *FileBase) Gid(r *Reader) (uint32, error) {
|
||||
func (b FileBase) Gid(r *Reader) (uint32, error) {
|
||||
return r.Id(b.Inode.GidInd)
|
||||
}
|
||||
|
||||
func (b *FileBase) IsDir() bool {
|
||||
func (b FileBase) IsDir() bool {
|
||||
return b.Inode.Type == inode.Dir || b.Inode.Type == inode.EDir
|
||||
}
|
||||
|
||||
func (b *FileBase) ToDir(r *Reader) (Directory, error) {
|
||||
func (b FileBase) ToDir(r Reader) (Directory, error) {
|
||||
var blockStart uint32
|
||||
var size uint32
|
||||
var offset uint16
|
||||
@@ -75,18 +75,18 @@ func (b *FileBase) ToDir(r *Reader) (Directory, error) {
|
||||
return Directory{}, err
|
||||
}
|
||||
return Directory{
|
||||
FileBase: *b,
|
||||
FileBase: b,
|
||||
Entries: entries,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *FileBase) IsRegular() bool {
|
||||
func (b FileBase) IsRegular() bool {
|
||||
return b.Inode.Type == inode.Fil || b.Inode.Type == inode.EFil
|
||||
}
|
||||
|
||||
func (b *FileBase) GetRegFileReaders(r *Reader) (*data.Reader, *data.FullReader, error) {
|
||||
func (b FileBase) GetRegFileReaders(r Reader) (data.Reader, data.FullReader, error) {
|
||||
if !b.IsRegular() {
|
||||
return nil, nil, errors.New("not a regular file")
|
||||
return data.Reader{}, data.FullReader{}, errors.New("not a regular file")
|
||||
}
|
||||
var blockStart uint64
|
||||
var fragIndex uint32
|
||||
@@ -113,13 +113,13 @@ func (b *FileBase) GetRegFileReaders(r *Reader) (*data.Reader, *data.FullReader,
|
||||
}
|
||||
frag := data.NewReader(toreader.NewReader(r.r, int64(ent.Start)), r.d, []uint32{ent.Size}, uint64(r.Superblock.BlockSize), r.Superblock.BlockSize)
|
||||
frag.Read(make([]byte, fragOffset))
|
||||
return io.LimitReader(frag, int64(fragSize)), nil
|
||||
return io.LimitReader(&frag, int64(fragSize)), nil
|
||||
}
|
||||
outRdr := data.NewReader(toreader.NewReader(r.r, int64(blockStart)), r.d, sizes, fragSize, r.Superblock.BlockSize)
|
||||
if fragIndex != 0xffffffff {
|
||||
f, err := frag()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return data.Reader{}, data.FullReader{}, err
|
||||
}
|
||||
outRdr.AddFrag(f)
|
||||
}
|
||||
@@ -130,9 +130,9 @@ func (b *FileBase) GetRegFileReaders(r *Reader) (*data.Reader, *data.FullReader,
|
||||
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 nil, errors.New("not a regular file")
|
||||
return data.FullReader{}, errors.New("not a regular file")
|
||||
}
|
||||
var blockStart uint64
|
||||
var fragIndex uint32
|
||||
@@ -161,15 +161,15 @@ func (b *FileBase) GetFullReader(r *Reader) (*data.FullReader, error) {
|
||||
}
|
||||
frag := data.NewReader(toreader.NewReader(r.r, int64(ent.Start)), r.d, []uint32{ent.Size}, uint64(r.Superblock.BlockSize), r.Superblock.BlockSize)
|
||||
frag.Read(make([]byte, fragOffset))
|
||||
return io.LimitReader(frag, int64(fragSize)), nil
|
||||
return io.LimitReader(&frag, int64(fragSize)), 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() {
|
||||
return nil, errors.New("not a regular file")
|
||||
return data.Reader{}, errors.New("not a regular file")
|
||||
}
|
||||
var blockStart uint64
|
||||
var fragIndex uint32
|
||||
@@ -193,11 +193,11 @@ func (b *FileBase) GetReader(r *Reader) (*data.Reader, error) {
|
||||
if fragIndex != 0xffffffff {
|
||||
ent, err := r.fragEntry(fragIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return data.Reader{}, err
|
||||
}
|
||||
frag := data.NewReader(toreader.NewReader(r.r, int64(ent.Start)), r.d, []uint32{ent.Size}, uint64(r.Superblock.BlockSize), r.Superblock.BlockSize)
|
||||
frag.Read(make([]byte, fragOffset))
|
||||
outRdr.AddFrag(io.LimitReader(frag, int64(fragSize)))
|
||||
outRdr.AddFrag(io.LimitReader(&frag, int64(fragSize)))
|
||||
}
|
||||
return outRdr, nil
|
||||
}
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/CalebQ42/squashfs/low/inode"
|
||||
)
|
||||
|
||||
func (r *Reader) InodeFromRef(ref uint64) (inode.Inode, error) {
|
||||
func (r Reader) InodeFromRef(ref uint64) (inode.Inode, error) {
|
||||
offset, meta := (ref>>16)+r.Superblock.InodeTableStart, ref&0xFFFF
|
||||
rdr := metadata.NewReader(toreader.NewReader(r.r, int64(offset)), r.d)
|
||||
defer rdr.Close()
|
||||
@@ -18,7 +18,7 @@ func (r *Reader) InodeFromRef(ref uint64) (inode.Inode, error) {
|
||||
return inode.Read(rdr, r.Superblock.BlockSize)
|
||||
}
|
||||
|
||||
func (r *Reader) InodeFromEntry(e directory.Entry) (inode.Inode, error) {
|
||||
func (r Reader) InodeFromEntry(e directory.Entry) (inode.Inode, error) {
|
||||
rdr := metadata.NewReader(toreader.NewReader(r.r, int64(r.Superblock.InodeTableStart)+int64(e.BlockStart)), r.d)
|
||||
defer rdr.Close()
|
||||
rdr.Read(make([]byte, e.Offset))
|
||||
|
||||
+10
-11
@@ -39,21 +39,20 @@ type Reader struct {
|
||||
Superblock superblock
|
||||
}
|
||||
|
||||
func NewReader(r io.ReaderAt) (rdr *Reader, err error) {
|
||||
rdr = new(Reader)
|
||||
func NewReader(r io.ReaderAt) (rdr Reader, err error) {
|
||||
rdr.r = r
|
||||
err = binary.Read(toreader.NewReader(r, 0), binary.LittleEndian, &rdr.Superblock)
|
||||
if err != nil {
|
||||
return nil, errors.Join(errors.New("failed to read superblock"), err)
|
||||
return rdr, errors.Join(errors.New("failed to read superblock"), err)
|
||||
}
|
||||
if !rdr.Superblock.ValidMagic() {
|
||||
return nil, ErrorMagic
|
||||
return rdr, ErrorMagic
|
||||
}
|
||||
if !rdr.Superblock.ValidBlockLog() {
|
||||
return nil, ErrorLog
|
||||
return rdr, ErrorLog
|
||||
}
|
||||
if !rdr.Superblock.ValidVersion() {
|
||||
return nil, ErrorVersion
|
||||
return rdr, ErrorVersion
|
||||
}
|
||||
switch rdr.Superblock.CompType {
|
||||
case ZlibCompression:
|
||||
@@ -61,12 +60,12 @@ func NewReader(r io.ReaderAt) (rdr *Reader, err error) {
|
||||
case LZMACompression:
|
||||
rdr.d, err = decompress.NewLzma()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return rdr, err
|
||||
}
|
||||
case LZOCompression:
|
||||
rdr.d, err = decompress.NewLzo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return rdr, err
|
||||
}
|
||||
case XZCompression:
|
||||
rdr.d = decompress.Xz{}
|
||||
@@ -75,11 +74,11 @@ func NewReader(r io.ReaderAt) (rdr *Reader, err error) {
|
||||
case ZSTDCompression:
|
||||
rdr.d = decompress.Zstd{}
|
||||
default:
|
||||
return nil, errors.New("invalid compression type. possible corrupted archive")
|
||||
return rdr, errors.New("invalid compression type. possible corrupted archive")
|
||||
}
|
||||
rdr.Root, err = rdr.directoryFromRef(rdr.Superblock.RootInodeRef, "")
|
||||
if err != nil {
|
||||
return nil, errors.Join(errors.New("failed to read root directory"), err)
|
||||
return rdr, errors.Join(errors.New("failed to read root directory"), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -207,7 +206,7 @@ func (r *Reader) inodeRef(i uint32) (uint64, error) {
|
||||
return r.exportTable[i], nil
|
||||
}
|
||||
|
||||
func (r *Reader) Inode(i uint32) (inode.Inode, error) {
|
||||
func (r Reader) Inode(i uint32) (inode.Inode, error) {
|
||||
ref, err := r.inodeRef(i)
|
||||
if err != nil {
|
||||
return inode.Inode{}, err
|
||||
|
||||
+4
-4
@@ -77,7 +77,7 @@ func TestReader(t *testing.T) {
|
||||
path := filepath.Join(tmpDir, "extractTest")
|
||||
os.RemoveAll(path)
|
||||
os.MkdirAll(path, 0777)
|
||||
err = extractToDir(rdr, &rdr.Root.FileBase, path)
|
||||
err = extractToDir(rdr, rdr.Root.FileBase, path)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -101,11 +101,11 @@ func TestSingleFile(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = extractToDir(rdr, &b, path)
|
||||
err = extractToDir(rdr, b, path)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
func extractToDir(rdr *Reader, b *FileBase, folder string) error {
|
||||
func extractToDir(rdr Reader, b FileBase, folder string) error {
|
||||
path := filepath.Join(folder, b.Name)
|
||||
if b.IsDir() {
|
||||
d, err := b.ToDir(rdr)
|
||||
@@ -122,7 +122,7 @@ func extractToDir(rdr *Reader, b *FileBase, folder string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = extractToDir(rdr, &nestBast, path)
|
||||
err = extractToDir(rdr, nestBast, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -9,26 +9,26 @@ import (
|
||||
)
|
||||
|
||||
type Reader struct {
|
||||
*FS
|
||||
FS
|
||||
Low squashfslow.Reader
|
||||
}
|
||||
|
||||
func NewReader(r io.ReaderAt) (*Reader, error) {
|
||||
func NewReader(r io.ReaderAt) (Reader, error) {
|
||||
rdr, err := squashfslow.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return Reader{}, err
|
||||
}
|
||||
out := &Reader{
|
||||
Low: *rdr,
|
||||
out := Reader{
|
||||
Low: rdr,
|
||||
}
|
||||
out.FS = &FS{
|
||||
out.FS = FS{
|
||||
d: rdr.Root,
|
||||
r: out,
|
||||
r: &out,
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func NewReaderAtOffset(r io.ReaderAt, offset int64) (*Reader, error) {
|
||||
func NewReaderAtOffset(r io.ReaderAt, offset int64) (Reader, error) {
|
||||
return NewReader(toreader.NewOffsetReader(r, offset))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user