Minor work on the Writer
This commit is contained in:
@@ -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
@@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user