github.com/simonmittag/ws@v1.1.0-rc.5.0.20210419231947-82b846128245/wsflate/reader.go (about)

     1  package wsflate
     2  
     3  import (
     4  	"io"
     5  )
     6  
     7  // Decompressor is an interface holding deflate decompression implementation.
     8  type Decompressor interface {
     9  	io.Reader
    10  }
    11  
    12  // ReadResetter is an optional interface that Decompressor can implement.
    13  type ReadResetter interface {
    14  	Reset(io.Reader)
    15  }
    16  
    17  // Reader implements decompression from an io.Reader object using Decompressor.
    18  // Essentially Reader is a thin wrapper around Decompressor interface to meet
    19  // PMCE specs.
    20  //
    21  // After all data has been written client should call Flush() method.
    22  // If any error occurs after reading from Reader, all subsequent calls to
    23  // Read() or Close() will return the error.
    24  //
    25  // Reader might be reused for different io.Reader objects after its Reset()
    26  // method has been called.
    27  type Reader struct {
    28  	src  io.Reader
    29  	ctor func(io.Reader) Decompressor
    30  	d    Decompressor
    31  	sr   suffixedReader
    32  	err  error
    33  }
    34  
    35  // NewReader returns a new Reader.
    36  func NewReader(r io.Reader, ctor func(io.Reader) Decompressor) *Reader {
    37  	ret := &Reader{
    38  		src:  r,
    39  		ctor: ctor,
    40  		sr: suffixedReader{
    41  			suffix: compressionReadTail,
    42  		},
    43  	}
    44  	ret.Reset(r)
    45  	return ret
    46  }
    47  
    48  // Reset resets Reader to decompress data from src.
    49  func (r *Reader) Reset(src io.Reader) {
    50  	r.err = nil
    51  	r.src = src
    52  	r.sr.reset(src)
    53  	if x, ok := r.d.(ReadResetter); ok {
    54  		x.Reset(&r.sr)
    55  	} else {
    56  		r.d = r.ctor(&r.sr)
    57  	}
    58  }
    59  
    60  // Read implements io.Reader.
    61  func (r *Reader) Read(p []byte) (n int, err error) {
    62  	if r.err != nil {
    63  		return 0, r.err
    64  	}
    65  	return r.d.Read(p)
    66  }
    67  
    68  // Close closes Reader and a Decompressor instance used under the hood (if it
    69  // implements io.Closer interface).
    70  func (r *Reader) Close() error {
    71  	if r.err != nil {
    72  		return r.err
    73  	}
    74  	if c, ok := r.d.(io.Closer); ok {
    75  		r.err = c.Close()
    76  	}
    77  	return r.err
    78  }
    79  
    80  // Err returns an error happened during any operation.
    81  func (r *Reader) Err() error {
    82  	return r.err
    83  }