github.com/bodgit/sevenzip@v1.5.1/internal/bra/reader.go (about) 1 package bra 2 3 import ( 4 "bytes" 5 "errors" 6 "io" 7 ) 8 9 type readCloser struct { 10 rc io.ReadCloser 11 buf bytes.Buffer 12 n int 13 conv converter 14 } 15 16 func (rc *readCloser) Close() (err error) { 17 if rc.rc != nil { 18 err = rc.rc.Close() 19 rc.rc = nil 20 } 21 22 return 23 } 24 25 func (rc *readCloser) Read(p []byte) (int, error) { 26 if rc.rc == nil { 27 return 0, errors.New("bra: Read after Close") 28 } 29 30 if _, err := io.CopyN(&rc.buf, rc.rc, int64(max(len(p), rc.conv.Size())-rc.buf.Len())); err != nil { 31 if !errors.Is(err, io.EOF) { 32 return 0, err 33 } 34 35 if rc.buf.Len() < rc.conv.Size() { 36 rc.n = rc.buf.Len() 37 } 38 } 39 40 rc.n += rc.conv.Convert(rc.buf.Bytes()[rc.n:], false) 41 42 n, err := rc.buf.Read(p[:min(rc.n, len(p))]) 43 44 rc.n -= n 45 46 return n, err 47 } 48 49 func newReader(readers []io.ReadCloser, conv converter) (io.ReadCloser, error) { 50 if len(readers) != 1 { 51 return nil, errors.New("bra: need exactly one reader") 52 } 53 54 return &readCloser{ 55 rc: readers[0], 56 conv: conv, 57 }, nil 58 }