@@ -49,7 +49,8 @@ type Scanner struct {
4949
5050 // pendingObject is used to detect if an object has been read, or still
5151 // is waiting to be read
52- pendingObject * ObjectHeader
52+ pendingObject * ObjectHeader
53+ version , objects uint32
5354}
5455
5556// NewParser returns a new Parser that reads from the packfile represented by r.
@@ -70,6 +71,10 @@ func NewScanner(r io.ReadSeeker) *Scanner {
7071// It returns the version and the object count and performs checks on the
7172// validity of the signature and the version fields.
7273func (s * Scanner ) Header () (version , objects uint32 , err error ) {
74+ if s .version != 0 {
75+ return s .version , s .objects , nil
76+ }
77+
7378 sig , err := s .readSignature ()
7479 if err != nil {
7580 if err == io .EOF {
@@ -85,6 +90,7 @@ func (s *Scanner) Header() (version, objects uint32, err error) {
8590 }
8691
8792 version , err = s .readVersion ()
93+ s .version = version
8894 if err != nil {
8995 return
9096 }
@@ -95,6 +101,7 @@ func (s *Scanner) Header() (version, objects uint32, err error) {
95101 }
96102
97103 objects , err = s .readCount ()
104+ s .objects = objects
98105 return
99106}
100107
@@ -141,7 +148,7 @@ func (s *Scanner) readInt32() (uint32, error) {
141148
142149// NextObjectHeader returns the ObjectHeader for the next object in the reader
143150func (s * Scanner ) NextObjectHeader () (* ObjectHeader , error ) {
144- if err := s .discardObjectIfNeeded (); err != nil {
151+ if err := s .doPending (); err != nil {
145152 return nil , err
146153 }
147154
@@ -180,6 +187,18 @@ func (s *Scanner) NextObjectHeader() (*ObjectHeader, error) {
180187 return h , nil
181188}
182189
190+ func (s * Scanner ) doPending () error {
191+ if s .version == 0 {
192+ var err error
193+ s .version , s .objects , err = s .Header ()
194+ if err != nil {
195+ return err
196+ }
197+ }
198+
199+ return s .discardObjectIfNeeded ()
200+ }
201+
183202func (s * Scanner ) discardObjectIfNeeded () error {
184203 if s .pendingObject == nil {
185204 return nil
@@ -275,6 +294,11 @@ func (s *Scanner) copyObject(w io.Writer) (int64, error) {
275294
276295// Seek sets a new offset from start, returns the old position before the change
277296func (s * Scanner ) Seek (offset int64 ) (previous int64 , err error ) {
297+ // if seeking we asume that you are not interested on the header
298+ if s .version == 0 {
299+ s .version = VersionSupported
300+ }
301+
278302 previous , err = s .r .Seek (0 , io .SeekCurrent )
279303 if err != nil {
280304 return - 1 , err
0 commit comments