diff --git a/bufferedwriter.go b/bufferedwriter.go index 9209559..678d478 100644 --- a/bufferedwriter.go +++ b/bufferedwriter.go @@ -4,12 +4,60 @@ import ( "io" ) -type bufferedWriter struct { - w io.Writer - buffer []bufferedBytes +type bufferedBytes struct { + data []byte + r offsetRange } -type bufferedBytes struct { - data []byte - offset int +type offsetRange struct { + beg int + end int +} + +func (o *offsetRange) offset(off int) { + o.beg += off + o.end += off +} + +func (o offsetRange) within(check int) bool { + return check >= o.beg || check <= o.end +} + +type bufferedWriter struct { + w io.Writer + buffer []bufferedBytes + mainOffset int +} + +func newBufferedWriter(w io.Writer) *bufferedWriter { + var out bufferedWriter + out.w = w + return &out +} + +func (b *bufferedWriter) WriteTo(data []byte, offset int64) (n int, err error) { + if int(offset) == b.mainOffset { + n, err = b.Write(data) + if err != nil { + return + } + } + newBuff := bufferedBytes{ + data: data, + r: offsetRange{ + beg: int(offset), + end: int(offset) + len(data), + }, + } + b.buffer = append(b.buffer, newBuff) + return 0, nil +} + +func (b *bufferedWriter) Write(data []byte) (int, error) { + n, err := b.w.Write(data) + b.mainOffset += n + if err != nil { + return n, err + } + return n, err } diff --git a/writer.go b/writer.go index e5ed92c..ff00b70 100644 --- a/writer.go +++ b/writer.go @@ -21,6 +21,9 @@ type Writer struct { symlinkTable map[string]string //[oldpath]newpath uidGUIDTable []int compressionType int + //BlockSize is how large the data blocks are. Can be between 4096 (4KB) and 1048576 (1 MB). Default is 1048576. + //If BlockSize is not inside that range, it will be set to within the range before writing + BlockSize uint32 //Flags are the SuperblockFlags used when writing the archive. //Currently Duplicates, Exportable, UncompressedXattr, NoXattr values are ignored Flags SuperblockFlags @@ -49,6 +52,7 @@ func NewWriterWithOptions(compressionType int, allowErrors bool) (*Writer, error symlinkTable: make(map[string]string), compressionType: compressionType, allowErrors: allowErrors, + BlockSize: uint32(1048576), }, nil } @@ -61,6 +65,7 @@ type fileHolder struct { UID int GUID int perm int + size uint32 folder bool symlink bool } diff --git a/writer_write.go b/writer_write.go index 2188454..0ee8bab 100644 --- a/writer_write.go +++ b/writer_write.go @@ -3,10 +3,26 @@ package squashfs import ( "errors" "io" + "math" ) //WriteTo attempts to write the archive to the given io.Writer. func (w *Writer) WriteTo(write io.Writer) (int64, error) { - //TODO + if w.BlockSize > 1048576 { + w.BlockSize = 1048576 + } else if w.BlockSize < 4096 { + w.BlockSize = 4096 + } + //TODO: set forced Flag values + _ = superblock{ + Magic: magic, + BlockSize: w.BlockSize, + BlockLog: uint16(math.Log2(float64(w.BlockSize))), + CompressionType: uint16(w.compressionType), + Flags: w.Flags.ToUint(), + IDCount: uint16(len(w.uidGUIDTable)), + MajorVersion: 4, + MinorVersion: 0, + } return 0, errors.New("I SAID DON'T") }