package wsflate import ( "io" ) // Decompressor is an interface holding deflate decompression implementation. type Decompressor interface { io.Reader } // ReadResetter is an optional interface that Decompressor can implement. type ReadResetter interface { Reset(io.Reader) } // Reader implements decompression from an io.Reader object using Decompressor. // Essentially Reader is a thin wrapper around Decompressor interface to meet // PMCE specs. // // After all data has been written client should call Flush() method. // If any error occurs after reading from Reader, all subsequent calls to // Read() or Close() will return the error. // // Reader might be reused for different io.Reader objects after its Reset() // method has been called. type Reader struct { src io.Reader ctor func(io.Reader) Decompressor d Decompressor sr suffixedReader err error } // NewReader returns a new Reader. func NewReader(r io.Reader, ctor func(io.Reader) Decompressor) *Reader { ret := &Reader{ src: r, ctor: ctor, sr: suffixedReader{ suffix: compressionReadTail, }, } ret.Reset(r) return ret } // Reset resets Reader to decompress data from src. func (r *Reader) Reset(src io.Reader) { r.err = nil r.src = src r.sr.reset(src) if x, ok := r.d.(ReadResetter); ok { x.Reset(r.sr.iface()) } else { r.d = r.ctor(r.sr.iface()) } } // Read implements io.Reader. func (r *Reader) Read(p []byte) (n int, err error) { if r.err != nil { return 0, r.err } return r.d.Read(p) } // Close closes Reader and a Decompressor instance used under the hood (if it // implements io.Closer interface). func (r *Reader) Close() error { if r.err != nil { return r.err } if c, ok := r.d.(io.Closer); ok { r.err = c.Close() } return r.err } // Err returns an error happened during any operation. func (r *Reader) Err() error { return r.err }