forked from gobwas/ws
/
reader.go
83 lines (74 loc) · 1.81 KB
/
reader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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)
} else {
r.d = r.ctor(&r.sr)
}
}
// 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
}