@@ -118,32 +118,23 @@ func (r *Reader) readFull(p []byte, allowEOF bool) (ok bool) {
118
118
return true
119
119
}
120
120
121
- // Read satisfies the io.Reader interface.
122
- func (r * Reader ) Read (p []byte ) (int , error ) {
123
- if r .err != nil {
124
- return 0 , r .err
125
- }
126
- for {
127
- if r .i < r .j {
128
- n := copy (p , r .decoded [r .i :r .j ])
129
- r .i += n
130
- return n , nil
131
- }
121
+ func (r * Reader ) fill () error {
122
+ for r .i >= r .j {
132
123
if ! r .readFull (r .buf [:4 ], true ) {
133
- return 0 , r .err
124
+ return r .err
134
125
}
135
126
chunkType := r .buf [0 ]
136
127
if ! r .readHeader {
137
128
if chunkType != chunkTypeStreamIdentifier {
138
129
r .err = ErrCorrupt
139
- return 0 , r .err
130
+ return r .err
140
131
}
141
132
r .readHeader = true
142
133
}
143
134
chunkLen := int (r .buf [1 ]) | int (r .buf [2 ])<< 8 | int (r .buf [3 ])<< 16
144
135
if chunkLen > len (r .buf ) {
145
136
r .err = ErrUnsupported
146
- return 0 , r .err
137
+ return r .err
147
138
}
148
139
149
140
// The chunk types are specified at
@@ -153,31 +144,31 @@ func (r *Reader) Read(p []byte) (int, error) {
153
144
// Section 4.2. Compressed data (chunk type 0x00).
154
145
if chunkLen < checksumSize {
155
146
r .err = ErrCorrupt
156
- return 0 , r .err
147
+ return r .err
157
148
}
158
149
buf := r .buf [:chunkLen ]
159
150
if ! r .readFull (buf , false ) {
160
- return 0 , r .err
151
+ return r .err
161
152
}
162
153
checksum := uint32 (buf [0 ]) | uint32 (buf [1 ])<< 8 | uint32 (buf [2 ])<< 16 | uint32 (buf [3 ])<< 24
163
154
buf = buf [checksumSize :]
164
155
165
156
n , err := DecodedLen (buf )
166
157
if err != nil {
167
158
r .err = err
168
- return 0 , r .err
159
+ return r .err
169
160
}
170
161
if n > len (r .decoded ) {
171
162
r .err = ErrCorrupt
172
- return 0 , r .err
163
+ return r .err
173
164
}
174
165
if _ , err := Decode (r .decoded , buf ); err != nil {
175
166
r .err = err
176
- return 0 , r .err
167
+ return r .err
177
168
}
178
169
if crc (r .decoded [:n ]) != checksum {
179
170
r .err = ErrCorrupt
180
- return 0 , r .err
171
+ return r .err
181
172
}
182
173
r .i , r .j = 0 , n
183
174
continue
@@ -186,25 +177,25 @@ func (r *Reader) Read(p []byte) (int, error) {
186
177
// Section 4.3. Uncompressed data (chunk type 0x01).
187
178
if chunkLen < checksumSize {
188
179
r .err = ErrCorrupt
189
- return 0 , r .err
180
+ return r .err
190
181
}
191
182
buf := r .buf [:checksumSize ]
192
183
if ! r .readFull (buf , false ) {
193
- return 0 , r .err
184
+ return r .err
194
185
}
195
186
checksum := uint32 (buf [0 ]) | uint32 (buf [1 ])<< 8 | uint32 (buf [2 ])<< 16 | uint32 (buf [3 ])<< 24
196
187
// Read directly into r.decoded instead of via r.buf.
197
188
n := chunkLen - checksumSize
198
189
if n > len (r .decoded ) {
199
190
r .err = ErrCorrupt
200
- return 0 , r .err
191
+ return r .err
201
192
}
202
193
if ! r .readFull (r .decoded [:n ], false ) {
203
- return 0 , r .err
194
+ return r .err
204
195
}
205
196
if crc (r .decoded [:n ]) != checksum {
206
197
r .err = ErrCorrupt
207
- return 0 , r .err
198
+ return r .err
208
199
}
209
200
r .i , r .j = 0 , n
210
201
continue
@@ -213,15 +204,15 @@ func (r *Reader) Read(p []byte) (int, error) {
213
204
// Section 4.1. Stream identifier (chunk type 0xff).
214
205
if chunkLen != len (magicBody ) {
215
206
r .err = ErrCorrupt
216
- return 0 , r .err
207
+ return r .err
217
208
}
218
209
if ! r .readFull (r .buf [:len (magicBody )], false ) {
219
- return 0 , r .err
210
+ return r .err
220
211
}
221
212
for i := 0 ; i < len (magicBody ); i ++ {
222
213
if r .buf [i ] != magicBody [i ] {
223
214
r .err = ErrCorrupt
224
- return 0 , r .err
215
+ return r .err
225
216
}
226
217
}
227
218
continue
@@ -230,12 +221,44 @@ func (r *Reader) Read(p []byte) (int, error) {
230
221
if chunkType <= 0x7f {
231
222
// Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f).
232
223
r .err = ErrUnsupported
233
- return 0 , r .err
224
+ return r .err
234
225
}
235
226
// Section 4.4 Padding (chunk type 0xfe).
236
227
// Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd).
237
228
if ! r .readFull (r .buf [:chunkLen ], false ) {
238
- return 0 , r .err
229
+ return r .err
239
230
}
240
231
}
232
+
233
+ return nil
234
+ }
235
+
236
+ // Read satisfies the io.Reader interface.
237
+ func (r * Reader ) Read (p []byte ) (int , error ) {
238
+ if r .err != nil {
239
+ return 0 , r .err
240
+ }
241
+
242
+ if err := r .fill (); err != nil {
243
+ return 0 , err
244
+ }
245
+
246
+ n := copy (p , r .decoded [r .i :r .j ])
247
+ r .i += n
248
+ return n , nil
249
+ }
250
+
251
+ // ReadByte satisfies the io.ByteReader interface.
252
+ func (r * Reader ) ReadByte () (byte , error ) {
253
+ if r .err != nil {
254
+ return 0 , r .err
255
+ }
256
+
257
+ if err := r .fill (); err != nil {
258
+ return 0 , err
259
+ }
260
+
261
+ c := r .decoded [r .i ]
262
+ r .i ++
263
+ return c , nil
241
264
}
0 commit comments