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