github.com/andybalholm/brotli@v1.0.6/reader.go (about) 1 package brotli 2 3 import ( 4 "errors" 5 "io" 6 ) 7 8 type decodeError int 9 10 func (err decodeError) Error() string { 11 return "brotli: " + string(decoderErrorString(int(err))) 12 } 13 14 var errExcessiveInput = errors.New("brotli: excessive input") 15 var errInvalidState = errors.New("brotli: invalid state") 16 17 // readBufSize is a "good" buffer size that avoids excessive round-trips 18 // between C and Go but doesn't waste too much memory on buffering. 19 // It is arbitrarily chosen to be equal to the constant used in io.Copy. 20 const readBufSize = 32 * 1024 21 22 // NewReader creates a new Reader reading the given reader. 23 func NewReader(src io.Reader) *Reader { 24 r := new(Reader) 25 r.Reset(src) 26 return r 27 } 28 29 // Reset discards the Reader's state and makes it equivalent to the result of 30 // its original state from NewReader, but reading from src instead. 31 // This permits reusing a Reader rather than allocating a new one. 32 // Error is always nil 33 func (r *Reader) Reset(src io.Reader) error { 34 if r.error_code < 0 { 35 // There was an unrecoverable error, leaving the Reader's state 36 // undefined. Clear out everything but the buffer. 37 *r = Reader{buf: r.buf} 38 } 39 40 decoderStateInit(r) 41 r.src = src 42 if r.buf == nil { 43 r.buf = make([]byte, readBufSize) 44 } 45 return nil 46 } 47 48 func (r *Reader) Read(p []byte) (n int, err error) { 49 if !decoderHasMoreOutput(r) && len(r.in) == 0 { 50 m, readErr := r.src.Read(r.buf) 51 if m == 0 { 52 // If readErr is `nil`, we just proxy underlying stream behavior. 53 return 0, readErr 54 } 55 r.in = r.buf[:m] 56 } 57 58 if len(p) == 0 { 59 return 0, nil 60 } 61 62 for { 63 var written uint 64 in_len := uint(len(r.in)) 65 out_len := uint(len(p)) 66 in_remaining := in_len 67 out_remaining := out_len 68 result := decoderDecompressStream(r, &in_remaining, &r.in, &out_remaining, &p) 69 written = out_len - out_remaining 70 n = int(written) 71 72 switch result { 73 case decoderResultSuccess: 74 if len(r.in) > 0 { 75 return n, errExcessiveInput 76 } 77 return n, nil 78 case decoderResultError: 79 return n, decodeError(decoderGetErrorCode(r)) 80 case decoderResultNeedsMoreOutput: 81 if n == 0 { 82 return 0, io.ErrShortBuffer 83 } 84 return n, nil 85 case decoderNeedsMoreInput: 86 } 87 88 if len(r.in) != 0 { 89 return 0, errInvalidState 90 } 91 92 // Calling r.src.Read may block. Don't block if we have data to return. 93 if n > 0 { 94 return n, nil 95 } 96 97 // Top off the buffer. 98 encN, err := r.src.Read(r.buf) 99 if encN == 0 { 100 // Not enough data to complete decoding. 101 if err == io.EOF { 102 return 0, io.ErrUnexpectedEOF 103 } 104 return 0, err 105 } 106 r.in = r.buf[:encN] 107 } 108 }