-
Notifications
You must be signed in to change notification settings - Fork 12
/
reader.go
72 lines (66 loc) · 1.74 KB
/
reader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package cpio
import (
"io"
"io/ioutil"
)
// Reader provides sequential access to the contents of a CPIO archive.
// Reader.Next advances to the next file in the archive (including the first),
// and then Reader can be treated as an io.Reader to access the file's data.
type Reader struct {
r io.Reader // underlying file reader
hdr *Header // current Header
eof int64 // bytes until the end of the current file
}
// NewReader creates a new Reader reading from r.
func NewReader(r io.Reader) *Reader {
return &Reader{
r: r,
}
}
// Read reads from the current file in the CPIO archive. It returns (0, io.EOF)
// when it reaches the end of that file, until Next is called to advance to the
// next file.
//
// Calling Read on special types like TypeLink, TypeSymlink, TypeChar,
// TypeBlock, TypeDir, and TypeFifo returns (0, io.EOF) regardless of what the
// Header.Size claims.
func (r *Reader) Read(p []byte) (n int, err error) {
if r.hdr == nil || r.eof == 0 {
return 0, io.EOF
}
rn := len(p)
if r.eof < int64(rn) {
rn = int(r.eof)
}
n, err = r.r.Read(p[0:rn])
r.eof -= int64(n)
return
}
// Next advances to the next entry in the CPIO archive. 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 (r *Reader) Next() (*Header, error) {
if r.hdr == nil {
return r.next()
}
skp := r.eof + r.hdr.pad
if skp > 0 {
_, err := io.CopyN(ioutil.Discard, r.r, skp)
if err != nil {
return nil, err
}
}
return r.next()
}
func (r *Reader) next() (*Header, error) {
r.eof = 0
hdr, err := readSVR4Header(r.r)
if err != nil {
return nil, err
}
r.hdr = hdr
r.eof = hdr.Size
return hdr, nil
}