github.com/bodgit/sevenzip@v1.5.1/internal/deflate/reader.go (about) 1 package deflate 2 3 import ( 4 "errors" 5 "io" 6 "sync" 7 8 "github.com/bodgit/sevenzip/internal/util" 9 "github.com/klauspost/compress/flate" 10 ) 11 12 //nolint:gochecknoglobals 13 var flateReaderPool sync.Pool 14 15 type readCloser struct { 16 c io.Closer 17 fr io.ReadCloser 18 } 19 20 func (rc *readCloser) Close() error { 21 var err error 22 23 if rc.c != nil { 24 if err = rc.fr.Close(); err != nil { 25 return err 26 } 27 28 flateReaderPool.Put(rc.fr) 29 err = rc.c.Close() 30 rc.c, rc.fr = nil, nil 31 } 32 33 return err 34 } 35 36 func (rc *readCloser) Read(p []byte) (int, error) { 37 if rc.fr == nil { 38 return 0, errors.New("deflate: Read after Close") 39 } 40 41 return rc.fr.Read(p) 42 } 43 44 // NewReader returns a new DEFLATE io.ReadCloser. 45 func NewReader(_ []byte, _ uint64, readers []io.ReadCloser) (io.ReadCloser, error) { 46 if len(readers) != 1 { 47 return nil, errors.New("deflate: need exactly one reader") 48 } 49 50 fr, ok := flateReaderPool.Get().(io.ReadCloser) 51 if ok { 52 frf, ok := fr.(flate.Resetter) 53 if ok { 54 if err := frf.Reset(util.ByteReadCloser(readers[0]), nil); err != nil { 55 return nil, err 56 } 57 } 58 } else { 59 fr = flate.NewReader(util.ByteReadCloser(readers[0])) 60 } 61 62 return &readCloser{ 63 c: readers[0], 64 fr: fr, 65 }, nil 66 }