1
0
Fork 1
mirror of https://github.com/vbatts/tar-split.git synced 2025-07-06 00:08:30 +00:00

tar.Reader(): add NextHeader()

Add a NextHeader() to tar.Reader that can reuse a passed-in Header
structure.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai 2021-12-08 17:32:43 -05:00
parent 80a436fd61
commit 24fae6b6d0

View file

@ -68,15 +68,25 @@ func NewReader(r io.Reader) *Reader {
//
// io.EOF is returned at the end of the input.
func (tr *Reader) Next() (*Header, error) {
return tr.NextHeader(nil)
}
// NextHeader advances to the next entry in the tar archive, attempting
// to reuse the passed-in Header.
// The Header.Size determines how many bytes can be read for the next file.
// Any remaining data in the current file is automatically discarded.
//
// io.EOF is returned at the end of the input.
func (tr *Reader) NextHeader(h *Header) (*Header, error) {
if tr.err != nil {
return nil, tr.err
}
hdr, err := tr.next()
hdr, err := tr.nextHeader(h)
tr.err = err
return hdr, err
}
func (tr *Reader) next() (*Header, error) {
func (tr *Reader) nextHeader(h *Header) (*Header, error) {
var paxHdrs map[string]string
var gnuLongName, gnuLongLink string
@ -108,7 +118,7 @@ func (tr *Reader) next() (*Header, error) {
}
tr.pad = 0
hdr, rawHdr, err := tr.readHeader()
hdr, rawHdr, err := tr.readHeader(h)
if err != nil {
return nil, err
}
@ -127,13 +137,14 @@ func (tr *Reader) next() (*Header, error) {
}
if hdr.Typeflag == TypeXGlobalHeader {
mergePAX(hdr, paxHdrs)
return &Header{
*hdr = Header{
Name: hdr.Name,
Typeflag: hdr.Typeflag,
Xattrs: hdr.Xattrs,
PAXRecords: hdr.PAXRecords,
Format: format,
}, nil
}
return hdr, nil
}
continue // This is a meta header affecting the next header
case TypeGNULongName, TypeGNULongLink:
@ -384,7 +395,7 @@ func parsePAX(r io.Reader) (map[string]string, error) {
// * Exactly 0 bytes are read and EOF is hit.
// * Exactly 1 block of zeros is read and EOF is hit.
// * At least 2 blocks of zeros are read.
func (tr *Reader) readHeader() (*Header, *block, error) {
func (tr *Reader) readHeader(h *Header) (*Header, *block, error) {
// Two blocks of zero bytes marks the end of the archive.
n, err := io.ReadFull(tr.r, tr.blk[:])
if tr.RawAccounting && (err == nil || err == io.EOF) {
@ -415,7 +426,13 @@ func (tr *Reader) readHeader() (*Header, *block, error) {
}
var p parser
hdr := new(Header)
var hdr *Header
if h != nil {
*h = Header{}
hdr = h
} else {
hdr = new(Header)
}
// Unpack the V7 header.
v7 := tr.blk.V7()