Working on file reading (Not working right now)

This commit is contained in:
Caleb Gardner
2020-11-24 22:26:16 -06:00
parent 5761ad59cf
commit 4f058f2f31
5 changed files with 122 additions and 23 deletions
+41 -3
View File
@@ -3,7 +3,15 @@ package squashfs
import ( import (
"bytes" "bytes"
"errors" "errors"
"fmt"
"io" "io"
"github.com/CalebQ42/GoSquashfs/internal/inode"
)
var (
//ErrInodeNotFile is given when giving an inode, but the function requires a file inode.
ErrInodeNotFile = errors.New("Given inode is NOT a file type")
) )
//DataReader reads data from data blocks. //DataReader reads data from data blocks.
@@ -24,8 +32,8 @@ type DataBlock struct {
uncompressedSize uint32 uncompressedSize uint32
} }
//NewDataBlockSize creates a new squashfs.datablock from a given size. //NewDataBlock creates a new squashfs.datablock from a given size.
func NewDataBlockSize(raw uint32) (dbs DataBlock) { func NewDataBlock(raw uint32) (dbs DataBlock) {
dbs.compressed = raw&1<<24 != 1<<24 dbs.compressed = raw&1<<24 != 1<<24
dbs.size = raw &^ 1 << 24 dbs.size = raw &^ 1 << 24
if !dbs.compressed { if !dbs.compressed {
@@ -40,7 +48,7 @@ func (r *Reader) NewDataReader(offset int64, sizes []uint32) (*DataReader, error
dr.r = r dr.r = r
dr.offset = offset dr.offset = offset
for _, size := range sizes { for _, size := range sizes {
dr.blocks = append(dr.blocks, NewDataBlockSize(size)) dr.blocks = append(dr.blocks, NewDataBlock(size))
} }
err := dr.readCurBlock() err := dr.readCurBlock()
if err != nil { if err != nil {
@@ -49,6 +57,32 @@ func (r *Reader) NewDataReader(offset int64, sizes []uint32) (*DataReader, error
return &dr, nil return &dr, nil
} }
//NewDataReaderFromInode creates a new DataReader from a given inode. Inode must be of BasicFile or ExtendedFile types
func (r *Reader) NewDataReaderFromInode(i *inode.Inode) (*DataReader, error) {
var rdr DataReader
switch i.Type {
case inode.BasicFileType:
fil := i.Info.(inode.BasicFile)
rdr.offset = int64(fil.Init.BlockStart)
for _, sizes := range fil.BlockSizes {
rdr.blocks = append(rdr.blocks, NewDataBlock(sizes))
}
case inode.ExtFileType:
fil := i.Info.(inode.ExtendedFile)
rdr.offset = int64(fil.Init.BlockStart)
for _, sizes := range fil.BlockSizes {
rdr.blocks = append(rdr.blocks, NewDataBlock(sizes))
}
default:
return nil, ErrInodeNotFile
}
err := rdr.readCurBlock()
if err != nil {
return nil, err
}
return &rdr, nil
}
func (d *DataReader) readNextBlock() error { func (d *DataReader) readNextBlock() error {
d.curBlock++ d.curBlock++
if d.curBlock >= len(d.blocks) { if d.curBlock >= len(d.blocks) {
@@ -94,10 +128,14 @@ func (d *DataReader) readCurBlock() error {
d.curData = buf.Bytes() d.curData = buf.Bytes()
d.blocks[d.curBlock].begOffset = d.offset d.blocks[d.curBlock].begOffset = d.offset
d.offset += int64(d.blocks[d.curBlock].size) d.offset += int64(d.blocks[d.curBlock].size)
fmt.Println("dat red")
fmt.Println(len(d.curData))
return err return err
} }
func (d *DataReader) Read(p []byte) (int, error) { func (d *DataReader) Read(p []byte) (int, error) {
fmt.Println("dat")
fmt.Println(len(d.curData))
if d.curReadOffset+len(p) < len(d.curData) { if d.curReadOffset+len(p) < len(d.curData) {
for i := 0; i < len(p); i++ { for i := 0; i < len(p); i++ {
p[i] = d.curData[d.curReadOffset+i] p[i] = d.curData[d.curReadOffset+i]
+71 -3
View File
@@ -1,17 +1,85 @@
package squashfs package squashfs
import (
"bytes"
"errors"
"fmt"
"io"
"github.com/CalebQ42/GoSquashfs/internal/inode"
)
//FileReader provides a io.Reader interface for files within
type FileReader struct { type FileReader struct {
r *Reader r *Reader
data *DataReader data *DataReader
fragmentData []byte fragmentData []byte
fragged bool
fragOnly bool
read int
FileSize int //FileSize is the total size of the given file
} }
//TODO: Yes var (
//ErrPathIsNotFile returns when trying to read from a file, but the given path is NOT a file.
ErrPathIsNotFile = errors.New("The given path is not a file")
)
//ReadFile provides a squashfs.FileReader for the file at the given location.
func (r *Reader) ReadFile(location string) (*FileReader, error) { func (r *Reader) ReadFile(location string) (*FileReader, error) {
var rdr FileReader
rdr.r = r
in, err := r.GetInodeFromPath(location)
if err != nil {
return nil, err
}
if in.Type != inode.BasicFileType && in.Type != inode.ExtFileType {
return nil, ErrPathIsNotFile
}
var offset uint32
var sizes []uint32
switch in.Type {
case inode.BasicFileType:
rdr.fragged = in.Info.(inode.BasicFile).Fragmented
rdr.fragOnly = in.Info.(inode.BasicFile).Init.BlockStart == 0
rdr.FileSize = int(in.Info.(inode.BasicFile).Init.Size)
offset = in.Info.(inode.BasicFile).Init.BlockStart
sizes = in.Info.(inode.BasicFile).BlockSizes
case inode.ExtFileType:
rdr.fragged = in.Info.(inode.ExtendedFile).Fragmented
rdr.fragOnly = in.Info.(inode.ExtendedFile).Init.BlockStart == 0
rdr.FileSize = int(in.Info.(inode.ExtendedFile).Init.Size)
offset = in.Info.(inode.ExtendedFile).Init.BlockStart
sizes = in.Info.(inode.ExtendedFile).BlockSizes
}
fmt.Println("HIIII")
if rdr.fragged {
rdr.fragmentData, err = r.GetFragmentDataFromInode(in)
if err != nil {
return nil, err
}
}
if rdr.fragged {
rdr.data, err = r.NewDataReader(int64(offset), sizes[:len(sizes)-1])
} else {
rdr.data, err = r.NewDataReader(int64(offset), sizes)
}
return &rdr, nil
} }
func (f *FileReader) Read(p []byte) (int, error) { func (f *FileReader) Read(p []byte) (int, error) {
fmt.Println("reading!")
var read int
n, err := f.data.Read(p)
read += n
if f.fragged && err == io.EOF {
n, err = bytes.NewBuffer(f.fragmentData).Read(p[read:])
read += n
if err != nil {
return read, err
}
} else if err != nil {
return read, err
}
return read, nil
} }
+2 -8
View File
@@ -1,7 +1,6 @@
package squashfs package squashfs
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
@@ -35,7 +34,6 @@ func (r *Reader) GetFragmentDataFromInode(in *inode.Inode) ([]byte, error) {
} }
fragIndex = bf.Init.FragmentIndex fragIndex = bf.Init.FragmentIndex
fragOffset = bf.Init.FragmentOffset fragOffset = bf.Init.FragmentOffset
fmt.Println(fragIndex, fragOffset, size)
} else if in.Type == inode.ExtFileType { } else if in.Type == inode.ExtFileType {
bf := in.Info.(inode.ExtendedFile) bf := in.Info.(inode.ExtendedFile)
if !bf.Fragmented { if !bf.Fragmented {
@@ -51,6 +49,7 @@ func (r *Reader) GetFragmentDataFromInode(in *inode.Inode) ([]byte, error) {
} else { } else {
return nil, errors.New("Inode type not supported") return nil, errors.New("Inode type not supported")
} }
fmt.Println(fragIndex, fragOffset, size)
fmt.Println("fragment index", fragIndex) fmt.Println("fragment index", fragIndex)
//reading the fragment entry first //reading the fragment entry first
fragEntryRdr, err := r.NewMetadataReader(int64(r.fragOffsets[int(fragIndex/512)])) fragEntryRdr, err := r.NewMetadataReader(int64(r.fragOffsets[int(fragIndex/512)]))
@@ -80,10 +79,5 @@ func (r *Reader) GetFragmentDataFromInode(in *inode.Inode) ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
dataRdr := bytes.NewBuffer(tmp) return tmp, nil
dta, err := r.decompressor.Decompress(dataRdr)
if err != nil {
return nil, err
}
return dta, nil
} }
+7 -8
View File
@@ -1,6 +1,7 @@
package squashfs package squashfs
import ( import (
"fmt"
"io" "io"
"net/http" "net/http"
"os" "os"
@@ -35,23 +36,21 @@ func TestMain(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
rdr.GetFileStructure() //testing code to print out the directory structure
extractionFil := ".DirIcon" // rdr.GetFileStructure()
i, err := rdr.GetInodeFromPath(extractionFil) extractionFil := "code-oss.desktop"
if err != nil {
t.Fatal(err)
}
os.Remove(wd + "/testing/" + extractionFil) os.Remove(wd + "/testing/" + extractionFil)
desk, err := os.Create(wd + "/testing/" + extractionFil) desk, err := os.Create(wd + "/testing/" + extractionFil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
btys, err := rdr.GetFragmentDataFromInode(i) ext, err := rdr.ReadFile(extractionFil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
_, err = desk.Write(btys) n, err := io.Copy(desk, ext)
if err != nil { if err != nil {
fmt.Println("Read", n)
t.Fatal(err) t.Fatal(err)
} }
t.Fatal("No problems here!") t.Fatal("No problems here!")
+1 -1
View File
@@ -76,7 +76,7 @@ func (r *Reader) GetInodeFromEntry(en *directory.Entry) (*inode.Inode, error) {
} }
//GetInodeFromPath returns the inode at the given path, relative to root. //GetInodeFromPath returns the inode at the given path, relative to root.
//The given path can start or without "/". //The given path can start with or without "/"
func (r *Reader) GetInodeFromPath(path string) (*inode.Inode, error) { func (r *Reader) GetInodeFromPath(path string) (*inode.Inode, error) {
path = strings.TrimSuffix(strings.TrimPrefix(path, "/"), "/") path = strings.TrimSuffix(strings.TrimPrefix(path, "/"), "/")
pathDirs := strings.Split(path, "/") pathDirs := strings.Split(path, "/")