1
2
3
4
5
24 package zlib
25
26 import (
27 "bufio"
28 "compress/flate"
29 "errors"
30 "hash"
31 "hash/adler32"
32 "io"
33 )
34
35 const (
36 zlibDeflate = 8
37 zlibMaxWindow = 7
38 )
39
40 var (
41
42 ErrChecksum = errors.New("zlib: invalid checksum")
43
44 ErrDictionary = errors.New("zlib: invalid dictionary")
45
46 ErrHeader = errors.New("zlib: invalid header")
47 )
48
49 type reader struct {
50 r flate.Reader
51 decompressor io.ReadCloser
52 digest hash.Hash32
53 err error
54 scratch [4]byte
55 }
56
57
58
59
60 type Resetter interface {
61
62
63 Reset(r io.Reader, dict []byte) error
64 }
65
66
67
68
69
70
71
72
73 func NewReader(r io.Reader) (io.ReadCloser, error) {
74 return NewReaderDict(r, nil)
75 }
76
77
78
79
80
81
82 func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) {
83 z := new(reader)
84 err := z.Reset(r, dict)
85 if err != nil {
86 return nil, err
87 }
88 return z, nil
89 }
90
91 func (z *reader) Read(p []byte) (int, error) {
92 if z.err != nil {
93 return 0, z.err
94 }
95
96 var n int
97 n, z.err = z.decompressor.Read(p)
98 z.digest.Write(p[0:n])
99 if z.err != io.EOF {
100
101 return n, z.err
102 }
103
104
105 if _, err := io.ReadFull(z.r, z.scratch[0:4]); err != nil {
106 if err == io.EOF {
107 err = io.ErrUnexpectedEOF
108 }
109 z.err = err
110 return n, z.err
111 }
112
113 checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
114 if checksum != z.digest.Sum32() {
115 z.err = ErrChecksum
116 return n, z.err
117 }
118 return n, io.EOF
119 }
120
121
122
123
124 func (z *reader) Close() error {
125 if z.err != nil && z.err != io.EOF {
126 return z.err
127 }
128 z.err = z.decompressor.Close()
129 return z.err
130 }
131
132 func (z *reader) Reset(r io.Reader, dict []byte) error {
133 *z = reader{decompressor: z.decompressor}
134 if fr, ok := r.(flate.Reader); ok {
135 z.r = fr
136 } else {
137 z.r = bufio.NewReader(r)
138 }
139
140
141 _, z.err = io.ReadFull(z.r, z.scratch[0:2])
142 if z.err != nil {
143 if z.err == io.EOF {
144 z.err = io.ErrUnexpectedEOF
145 }
146 return z.err
147 }
148 h := uint(z.scratch[0])<<8 | uint(z.scratch[1])
149 if (z.scratch[0]&0x0f != zlibDeflate) || (z.scratch[0]>>4 > zlibMaxWindow) || (h%31 != 0) {
150 z.err = ErrHeader
151 return z.err
152 }
153 haveDict := z.scratch[1]&0x20 != 0
154 if haveDict {
155 _, z.err = io.ReadFull(z.r, z.scratch[0:4])
156 if z.err != nil {
157 if z.err == io.EOF {
158 z.err = io.ErrUnexpectedEOF
159 }
160 return z.err
161 }
162 checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
163 if checksum != adler32.Checksum(dict) {
164 z.err = ErrDictionary
165 return z.err
166 }
167 }
168
169 if z.decompressor == nil {
170 if haveDict {
171 z.decompressor = flate.NewReaderDict(z.r, dict)
172 } else {
173 z.decompressor = flate.NewReader(z.r)
174 }
175 } else {
176 z.decompressor.(flate.Resetter).Reset(z.r, dict)
177 }
178 z.digest = adler32.New()
179 return nil
180 }
181
View as plain text