mirror of
https://github.com/vbatts/tar-split.git
synced 2025-03-20 23:34:08 +00:00
The feature of golang having source in a project path with "internal" makes the code only able to be imported by the project itself. https://docs.google.com/document/d/1e8kOo3r51b2BWtTs_1uADIA5djfXhPT36s6eHVRIvaU/edit?tab=t.0 Since we have this carried version of `archive/tar` with our byte accounting patches, it is also means the version of archive/tar has not kept up with upstream. our tar-split libraries do not even utilize all the function calls of our carried archive/tar, so might as well limit anyone else in the world from calling them as well. Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
57 lines
1.7 KiB
Go
57 lines
1.7 KiB
Go
package asm
|
||
|
||
import (
|
||
"bytes"
|
||
"fmt"
|
||
"io"
|
||
|
||
"github.com/vbatts/tar-split/internal/archive/tar"
|
||
"github.com/vbatts/tar-split/tar/storage"
|
||
)
|
||
|
||
// IterateHeaders calls handler for each tar header provided by Unpacker
|
||
func IterateHeaders(unpacker storage.Unpacker, handler func(hdr *tar.Header) error) error {
|
||
// We assume about NewInputTarStream:
|
||
// - There is a separate SegmentType entry for every tar header, but only one SegmentType entry for the full header incl. any extensions
|
||
// - (There is a FileType entry for every tar header, we ignore it)
|
||
// - Trailing padding of a file, if any, is included in the next SegmentType entry
|
||
// - At the end, there may be SegmentType entries just for the terminating zero blocks.
|
||
|
||
var pendingPadding int64 = 0
|
||
for {
|
||
tsEntry, err := unpacker.Next()
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
return nil
|
||
}
|
||
return fmt.Errorf("reading tar-split entries: %w", err)
|
||
}
|
||
switch tsEntry.Type {
|
||
case storage.SegmentType:
|
||
payload := tsEntry.Payload
|
||
if int64(len(payload)) < pendingPadding {
|
||
return fmt.Errorf("expected %d bytes of padding after previous file, but next SegmentType only has %d bytes", pendingPadding, len(payload))
|
||
}
|
||
payload = payload[pendingPadding:]
|
||
pendingPadding = 0
|
||
|
||
tr := tar.NewReader(bytes.NewReader(payload))
|
||
hdr, err := tr.Next()
|
||
if err != nil {
|
||
if err == io.EOF { // Probably the last entry, but let’s let the unpacker drive that.
|
||
break
|
||
}
|
||
return fmt.Errorf("decoding a tar header from a tar-split entry: %w", err)
|
||
}
|
||
if err := handler(hdr); err != nil {
|
||
return err
|
||
}
|
||
pendingPadding = tr.ExpectedPadding()
|
||
|
||
case storage.FileType:
|
||
// Nothing
|
||
default:
|
||
return fmt.Errorf("unexpected tar-split entry type %q", tsEntry.Type)
|
||
}
|
||
}
|
||
}
|