Files
squashfs/direntry_fileinfo.go
T
2021-01-30 06:30:00 -06:00

138 lines
2.8 KiB
Go

package squashfs
import (
"io"
"io/fs"
"time"
"github.com/CalebQ42/squashfs/internal/directory"
"github.com/CalebQ42/squashfs/internal/inode"
)
//DirEntry is a child of a directory.
type DirEntry struct {
en *directory.Entry
parent *FS
r *Reader
}
func (r *Reader) newDirEntry(en *directory.Entry, parent *FS) *DirEntry {
return &DirEntry{
en: en,
parent: parent,
r: r,
}
}
//Name returns the DirEntry's name
func (d DirEntry) Name() string {
return d.en.Name
}
//IsDir Yep.
func (d DirEntry) IsDir() bool {
return d.en.Type == inode.DirType
}
//Type returns the type bits of fs.FileMode of the DirEntry.
func (d DirEntry) Type() fs.FileMode {
switch d.en.Type {
case inode.DirType:
return fs.ModeDir
case inode.SymType:
return fs.ModeSymlink
default:
return 0
}
}
//Info returns the fs.FileInfo for the given DirEntry.
func (d DirEntry) Info() (fs.FileInfo, error) {
in, err := d.r.getInodeFromEntry(d.en)
if err != nil {
return nil, err
}
return &FileInfo{
name: d.en.Name,
i: in,
parent: d.parent,
r: d.r,
}, nil
}
//GetInodeFromEntry returns the inode associated with a given directory.Entry
func (r *Reader) getInodeFromEntry(en *directory.Entry) (*inode.Inode, error) {
br, err := r.newMetadataReader(int64(r.super.InodeTableStart + uint64(en.InodeOffset)))
if err != nil {
return nil, err
}
_, err = br.Seek(int64(en.InodeBlockOffset), io.SeekStart)
if err != nil {
return nil, err
}
i, err := inode.ProcessInode(br, r.super.BlockSize)
if err != nil {
return nil, err
}
return i, nil
}
//FileInfo is a fs.FileInfo for a file.
type FileInfo struct {
i *inode.Inode
parent *FS
r *Reader
name string
}
//Name is the file's name.
func (f FileInfo) Name() string {
return f.name
}
//Size is the file's size if it's a regular file. Otherwise, returns 0.
func (f FileInfo) Size() int64 {
switch f.i.Type {
case inode.FileType:
return int64(f.i.Info.(inode.File).Size)
case inode.ExtFileType:
return int64(f.i.Info.(inode.ExtFile).Size)
}
return 0
}
//Mode returns the fs.FileMode bits of the file.
func (f FileInfo) Mode() fs.FileMode {
mode := fs.FileMode(f.i.Permissions)
switch f.i.Type {
case inode.DirType | inode.ExtDirType:
return mode | fs.ModeDir
case inode.ExtDirType:
return mode | fs.ModeDir
case inode.SymType:
return mode | fs.ModeSymlink
case inode.ExtSymType:
return mode | fs.ModeSymlink
}
return mode
}
//ModTime is the last time the file was modified.
func (f FileInfo) ModTime() time.Time {
return time.Unix(int64(f.i.ModifiedTime), 0)
}
//IsDir yep.
func (f FileInfo) IsDir() bool {
return f.i.Type == inode.DirType || f.i.Type == inode.ExtDirType
}
//Sys returns the File for the FileInfo. If something goes wrong, nil is returned.
func (f FileInfo) Sys() interface{} {
fil, err := f.File()
if err != nil {
return nil
}
return fil
}