Minor work on the Writer

This commit is contained in:
Caleb Gardner
2021-02-03 14:03:21 -06:00
parent d89153c3e2
commit 07962426b2
2 changed files with 39 additions and 9 deletions
+20 -6
View File
@@ -19,6 +19,7 @@ type Writer struct {
compressor compression.Compressor compressor compression.Compressor
structure map[string][]*fileHolder structure map[string][]*fileHolder
symlinkTable map[string]string //[oldpath]newpath symlinkTable map[string]string //[oldpath]newpath
folders []string
uidGUIDTable []int uidGUIDTable []int
compressionType int compressionType int
//BlockSize is how large the data blocks are. Can be between 4096 (4KB) and 1048576 (1 MB). //BlockSize is how large the data blocks are. Can be between 4096 (4KB) and 1048576 (1 MB).
@@ -44,12 +45,15 @@ func NewWriterWithOptions(compressionType int, allowErrors bool) (*Writer, error
return nil, errors.New("Incorrect compression type") return nil, errors.New("Incorrect compression type")
} }
if compressionType == 3 { if compressionType == 3 {
return nil, errors.New("LZO compression is not (currently) supported") return nil, errors.New("Lzo compression is not (currently) supported")
} }
return &Writer{ return &Writer{
structure: map[string][]*fileHolder{ structure: map[string][]*fileHolder{
"/": make([]*fileHolder, 0), "/": make([]*fileHolder, 0),
}, },
folders: []string{
"/",
},
symlinkTable: make(map[string]string), symlinkTable: make(map[string]string),
compressionType: compressionType, compressionType: compressionType,
allowErrors: allowErrors, allowErrors: allowErrors,
@@ -71,7 +75,7 @@ type fileHolder struct {
symlink bool symlink bool
} }
//AddFile attempts to add an os.File to the archive at it's root. //AddFile attempts to add an os.File to the archive's root directory.
func (w *Writer) AddFile(file *os.File) error { func (w *Writer) AddFile(file *os.File) error {
return w.AddFileToFolder("/", file) return w.AddFileToFolder("/", file)
} }
@@ -95,8 +99,7 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error {
return errors.New("File already exists at " + filepath) return errors.New("File already exists at " + filepath)
} }
var holder fileHolder var holder fileHolder
holder.path, holder.name = path.Split(filepath) holder.path, holder.name = path.Dir(filepath), path.Base(filepath)
holder.reader = file
stat, err := file.Stat() stat, err := file.Stat()
if err != nil { if err != nil {
return err return err
@@ -118,6 +121,7 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error {
sort.Ints(w.uidGUIDTable) sort.Ints(w.uidGUIDTable)
} }
if holder.symlink { if holder.symlink {
holder.reader = file
target, err := os.Readlink(file.Name()) target, err := os.Readlink(file.Name())
if err != nil { if err != nil {
return err return err
@@ -148,9 +152,15 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error {
dirsAdded = append(dirsAdded, holder.path+"/"+holder.name) dirsAdded = append(dirsAdded, holder.path+"/"+holder.name)
} }
} }
} else if !stat.Mode().IsRegular() { } else if stat.Mode().IsRegular() {
holder.reader = file
} else {
return errors.New("Unsupported file type " + file.Name()) return errors.New("Unsupported file type " + file.Name())
} }
if _, ok := w.structure[holder.path]; ok {
w.folders = append(w.folders, holder.path)
sort.Strings(w.folders)
}
w.structure[holder.path] = append(w.structure[holder.path], &holder) w.structure[holder.path] = append(w.structure[holder.path], &holder)
return nil return nil
} }
@@ -167,8 +177,12 @@ func (w *Writer) AddReaderTo(filepath string, reader io.Reader) error {
return errors.New("File already exists at " + filepath) return errors.New("File already exists at " + filepath)
} }
var holder fileHolder var holder fileHolder
holder.path, holder.name = path.Split(filepath) holder.path, holder.name = path.Dir(filepath), path.Base(filepath)
holder.reader = reader holder.reader = reader
if _, ok := w.structure[holder.path]; ok {
w.folders = append(w.folders, holder.path)
sort.Strings(w.folders)
}
w.structure[holder.path] = append(w.structure[holder.path], &holder) w.structure[holder.path] = append(w.structure[holder.path], &holder)
return nil return nil
} }
+19 -3
View File
@@ -4,25 +4,41 @@ import (
"errors" "errors"
"io" "io"
"math" "math"
"time"
) )
func (w Writer) countInodes() (out uint32) {
out++ // for the root indode
for _, fold := range w.folders {
out += uint32(len(w.structure[fold]))
}
return
}
//WriteTo attempts to write the archive to the given io.Writer. //WriteTo attempts to write the archive to the given io.Writer.
func (w *Writer) WriteTo(write io.Writer) (int64, error) { func (w *Writer) WriteTo(write io.WriteSeeker) (int64, error) {
if w.BlockSize > 1048576 { if w.BlockSize > 1048576 {
w.BlockSize = 1048576 w.BlockSize = 1048576
} else if w.BlockSize < 4096 { } else if w.BlockSize < 4096 {
w.BlockSize = 4096 w.BlockSize = 4096
} }
w.Flags.Duplicates = false
w.Flags.Exportable = false
w.Flags.NoXattr = true
//TODO: set forced Flag values //TODO: set forced Flag values
_ = superblock{ //TODO: make sure we aren't missing folders
super := superblock{
Magic: magic, Magic: magic,
InodeCount: w.countInodes(),
CreationTime: uint32(time.Now().Unix()),
BlockSize: w.BlockSize, BlockSize: w.BlockSize,
BlockLog: uint16(math.Log2(float64(w.BlockSize))),
CompressionType: uint16(w.compressionType), CompressionType: uint16(w.compressionType),
BlockLog: uint16(math.Log2(float64(w.BlockSize))),
Flags: w.Flags.ToUint(), Flags: w.Flags.ToUint(),
IDCount: uint16(len(w.uidGUIDTable)), IDCount: uint16(len(w.uidGUIDTable)),
MajorVersion: 4, MajorVersion: 4,
MinorVersion: 0, MinorVersion: 0,
} }
_ = super
return 0, errors.New("I SAID DON'T") return 0, errors.New("I SAID DON'T")
} }