From 65d23b4620a76418dc4aeca83ce7a991a1945ef0 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Thu, 12 Jan 2017 08:46:02 +0100 Subject: packfile/scanner: reset zlib reader instead of new one (#201) --- plumbing/format/packfile/scanner.go | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'plumbing/format/packfile/scanner.go') diff --git a/plumbing/format/packfile/scanner.go b/plumbing/format/packfile/scanner.go index 1a85639..d8cece6 100644 --- a/plumbing/format/packfile/scanner.go +++ b/plumbing/format/packfile/scanner.go @@ -38,6 +38,7 @@ type ObjectHeader struct { type Scanner struct { r reader + zr readerResetter crc hash.Hash32 // pendingObject is used to detect if an object has been read, or still @@ -275,19 +276,28 @@ func (s *Scanner) NextObject(w io.Writer) (written int64, crc32 uint32, err erro // ReadRegularObject reads and write a non-deltified object // from it zlib stream in an object entry in the packfile. func (s *Scanner) copyObject(w io.Writer) (int64, error) { - zr, err := zlib.NewReader(s.r) - if err != nil { - return -1, fmt.Errorf("zlib reading error: %s", err) + var err error + if s.zr == nil { + zr, err := zlib.NewReader(s.r) + if err != nil { + return 0, fmt.Errorf("zlib initialization error: %s", err) + } + + s.zr = zr.(readerResetter) + } else { + if err := s.zr.Reset(s.r, nil); err != nil { + return 0, fmt.Errorf("zlib reset error: %s", err) + } } defer func() { - closeErr := zr.Close() + closeErr := s.zr.Close() if err == nil { err = closeErr } }() - return io.Copy(w, zr) + return io.Copy(w, s.zr) } // Seek sets a new offset from start, returns the old position before the change @@ -370,6 +380,11 @@ func (r *bufferedSeeker) Seek(offset int64, whence int) (int64, error) { return r.r.Seek(offset, whence) } +type readerResetter interface { + io.ReadCloser + zlib.Resetter +} + type reader interface { io.Reader io.ByteReader -- cgit