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  }