Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
60 lines
1.2 KiB
Go
60 lines
1.2 KiB
Go
package ar
|
|
|
|
import (
|
|
"io"
|
|
)
|
|
|
|
type Reader struct {
|
|
currentHeader *Header // Current node header
|
|
r io.Reader // Original reader
|
|
limit int64 // Reader
|
|
}
|
|
|
|
func NewReader(r io.Reader) (*Reader, error) {
|
|
read := make([]byte, len(arMagic))
|
|
if n, err := r.Read(read); err != nil {
|
|
return nil, err
|
|
} else if n != len(arMagic) {
|
|
return nil, ErrInvalidFile
|
|
}
|
|
|
|
return &Reader{
|
|
currentHeader: nil,
|
|
r: r,
|
|
}, nil
|
|
}
|
|
|
|
// Read data from the current ar file
|
|
func (r *Reader) Read(p []byte) (n int, err error) {
|
|
if r.limit <= 0 {
|
|
return 0, io.EOF
|
|
}
|
|
if int64(len(p)) > r.limit {
|
|
p = p[0:r.limit]
|
|
}
|
|
n, err = r.r.Read(p)
|
|
r.limit -= int64(n)
|
|
if r.limit == 0 && (r.currentHeader.Size&1) == 1 {
|
|
r.r.Read(make([]byte, 1)) // Ignore the last byte if the size is odd
|
|
}
|
|
return
|
|
}
|
|
|
|
// Read the next ar file header if available
|
|
func (r *Reader) Next() (*Header, error) {
|
|
if r.limit > 0 {
|
|
return nil, io.EOF
|
|
}
|
|
|
|
head := make([]byte, 60)
|
|
if n, err := r.r.Read(head); err != nil {
|
|
return nil, err
|
|
} else if n != 60 {
|
|
return nil, ErrInvalidFile
|
|
}
|
|
r.currentHeader = &Header{}
|
|
r.currentHeader.parseGnuHeader(head)
|
|
r.limit = r.currentHeader.Size
|
|
return r.currentHeader, nil
|
|
}
|