mirror of
https://github.com/vbatts/tar-split.git
synced 2024-11-15 04:58:36 +00:00
Vincent Batts
4e27d04b0b
Have a bit-bucket FilePutter, for when it does not matter. Beginning thoughts on disassembly, but it has things that need thought. Mostly comments in the function for now.
53 lines
1.2 KiB
Go
53 lines
1.2 KiB
Go
package asm
|
|
|
|
import (
|
|
"io"
|
|
|
|
"github.com/vbatts/tar-split/tar/storage"
|
|
)
|
|
|
|
// NewOutputTarStream returns an io.ReadCloser that is an assemble tar archive
|
|
// stream.
|
|
//
|
|
// It takes a FileGetter, for mapping the file payloads that are to be read in,
|
|
// and a storage.Unpacker, which has access to the rawbytes and file order
|
|
// metadata. With the combination of these two items, a precise assembled Tar
|
|
// archive is possible.
|
|
func NewOutputTarStream(fg FileGetter, up storage.Unpacker) io.ReadCloser {
|
|
// ... Since these are interfaces, this is possible, so let's not have a nil pointer
|
|
if fg == nil || up == nil {
|
|
return nil
|
|
}
|
|
pr, pw := io.Pipe()
|
|
go func() {
|
|
for {
|
|
entry, err := up.Next()
|
|
if err != nil {
|
|
pw.CloseWithError(err)
|
|
break
|
|
}
|
|
switch entry.Type {
|
|
case storage.SegmentType:
|
|
if _, err := pw.Write(entry.Payload); err != nil {
|
|
pw.CloseWithError(err)
|
|
break
|
|
}
|
|
case storage.FileType:
|
|
if entry.Size == 0 {
|
|
continue
|
|
}
|
|
fh, err := fg.Get(entry.Name)
|
|
if err != nil {
|
|
pw.CloseWithError(err)
|
|
break
|
|
}
|
|
defer fh.Close()
|
|
if _, err := io.Copy(pw, fh); err != nil {
|
|
pw.CloseWithError(err)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
return pr
|
|
}
|