@@ -141,81 +141,97 @@ function Readable(options) {
141
141
// write() some more.
142
142
Readable . prototype . push = function ( chunk , encoding ) {
143
143
var state = this . _readableState ;
144
-
145
- if ( ! state . objectMode && typeof chunk === 'string' ) {
146
- encoding = encoding || state . defaultEncoding ;
147
- if ( encoding !== state . encoding ) {
148
- chunk = Buffer . from ( chunk , encoding ) ;
149
- encoding = '' ;
144
+ var skipChunkCheck ;
145
+
146
+ if ( ! state . objectMode ) {
147
+ if ( typeof chunk === 'string' ) {
148
+ encoding = encoding || state . defaultEncoding ;
149
+ if ( encoding !== state . encoding ) {
150
+ chunk = Buffer . from ( chunk , encoding ) ;
151
+ encoding = '' ;
152
+ }
153
+ skipChunkCheck = true ;
150
154
}
155
+ } else {
156
+ skipChunkCheck = true ;
151
157
}
152
158
153
- return readableAddChunk ( this , state , chunk , encoding , false ) ;
159
+ return readableAddChunk ( this , chunk , encoding , false , skipChunkCheck ) ;
154
160
} ;
155
161
156
162
// Unshift should *always* be something directly out of read()
157
163
Readable . prototype . unshift = function ( chunk ) {
158
- var state = this . _readableState ;
159
- return readableAddChunk ( this , state , chunk , '' , true ) ;
160
- } ;
161
-
162
- Readable . prototype . isPaused = function ( ) {
163
- return this . _readableState . flowing === false ;
164
+ return readableAddChunk ( this , chunk , null , true , false ) ;
164
165
} ;
165
166
166
- function readableAddChunk ( stream , state , chunk , encoding , addToFront ) {
167
- var er = chunkInvalid ( state , chunk ) ;
168
- if ( er ) {
169
- stream . emit ( 'error' , er ) ;
170
- } else if ( chunk === null ) {
167
+ function readableAddChunk ( stream , chunk , encoding , addToFront , skipChunkCheck ) {
168
+ var state = stream . _readableState ;
169
+ if ( chunk === null ) {
171
170
state . reading = false ;
172
171
onEofChunk ( stream , state ) ;
173
- } else if ( state . objectMode || chunk && chunk . length > 0 ) {
174
- if ( state . ended && ! addToFront ) {
175
- const e = new Error ( 'stream.push() after EOF' ) ;
176
- stream . emit ( 'error' , e ) ;
177
- } else if ( state . endEmitted && addToFront ) {
178
- const e = new Error ( ' stream.unshift() after end event' ) ;
179
- stream . emit ( 'error' , e ) ;
180
- } else {
181
- var skipAdd ;
182
- if ( state . decoder && ! addToFront && ! encoding ) {
183
- chunk = state . decoder . write ( chunk ) ;
184
- skipAdd = ( ! state . objectMode && chunk . length === 0 ) ;
185
- }
186
-
187
- if ( ! addToFront )
172
+ } else {
173
+ var er ;
174
+ if ( ! skipChunkCheck )
175
+ er = chunkInvalid ( state , chunk ) ;
176
+ if ( er ) {
177
+ stream . emit ( 'error' , er ) ;
178
+ } else if ( state . objectMode || chunk && chunk . length > 0 ) {
179
+ if ( addToFront ) {
180
+ if ( state . endEmitted )
181
+ stream . emit ( 'error' , new Error ( 'stream.unshift() after end event' ) ) ;
182
+ else
183
+ addChunk ( stream , state , chunk , true ) ;
184
+ } else if ( state . ended ) {
185
+ stream . emit ( 'error' , new Error ( 'stream.push() after EOF' ) ) ;
186
+ } else {
188
187
state . reading = false ;
189
-
190
- // Don't add to the buffer if we've decoded to an empty string chunk and
191
- // we're not in object mode
192
- if ( ! skipAdd ) {
193
- // if we want the data now, just emit it.
194
- if ( state . flowing && state . length === 0 && ! state . sync ) {
195
- stream . emit ( 'data' , chunk ) ;
196
- stream . read ( 0 ) ;
197
- } else {
198
- // update the buffer info.
199
- state . length += state . objectMode ? 1 : chunk . length ;
200
- if ( addToFront )
201
- state . buffer . unshift ( chunk ) ;
188
+ if ( state . decoder && ! encoding ) {
189
+ chunk = state . decoder . write ( chunk ) ;
190
+ if ( state . objectMode || chunk . length !== 0 )
191
+ addChunk ( stream , state , chunk , false ) ;
202
192
else
203
- state . buffer . push ( chunk ) ;
204
-
205
- if ( state . needReadable )
206
- emitReadable ( stream ) ;
193
+ maybeReadMore ( stream , state ) ;
194
+ } else {
195
+ addChunk ( stream , state , chunk , false ) ;
207
196
}
208
197
}
209
-
210
- maybeReadMore ( stream , state ) ;
198
+ } else if ( ! addToFront ) {
199
+ state . reading = false ;
211
200
}
212
- } else if ( ! addToFront ) {
213
- state . reading = false ;
214
201
}
215
202
216
203
return needMoreData ( state ) ;
217
204
}
218
205
206
+ function addChunk ( stream , state , chunk , addToFront ) {
207
+ if ( state . flowing && state . length === 0 && ! state . sync ) {
208
+ stream . emit ( 'data' , chunk ) ;
209
+ stream . read ( 0 ) ;
210
+ } else {
211
+ // update the buffer info.
212
+ state . length += state . objectMode ? 1 : chunk . length ;
213
+ if ( addToFront )
214
+ state . buffer . unshift ( chunk ) ;
215
+ else
216
+ state . buffer . push ( chunk ) ;
217
+
218
+ if ( state . needReadable )
219
+ emitReadable ( stream ) ;
220
+ }
221
+ maybeReadMore ( stream , state ) ;
222
+ }
223
+
224
+ function chunkInvalid ( state , chunk ) {
225
+ var er ;
226
+ if ( ! ( chunk instanceof Buffer ) &&
227
+ typeof chunk !== 'string' &&
228
+ chunk !== undefined &&
229
+ ! state . objectMode ) {
230
+ er = new TypeError ( 'Invalid non-string/buffer chunk' ) ;
231
+ }
232
+ return er ;
233
+ }
234
+
219
235
220
236
// if it's past the high water mark, we can push in some more.
221
237
// Also, if we have no data yet, we can stand some
@@ -231,6 +247,10 @@ function needMoreData(state) {
231
247
state . length === 0 ) ;
232
248
}
233
249
250
+ Readable . prototype . isPaused = function ( ) {
251
+ return this . _readableState . flowing === false ;
252
+ } ;
253
+
234
254
// backwards compatibility.
235
255
Readable . prototype . setEncoding = function ( enc ) {
236
256
if ( ! StringDecoder )
@@ -402,19 +422,6 @@ Readable.prototype.read = function(n) {
402
422
return ret ;
403
423
} ;
404
424
405
- function chunkInvalid ( state , chunk ) {
406
- var er = null ;
407
- if ( ! ( chunk instanceof Buffer ) &&
408
- typeof chunk !== 'string' &&
409
- chunk !== null &&
410
- chunk !== undefined &&
411
- ! state . objectMode ) {
412
- er = new TypeError ( 'Invalid non-string/buffer chunk' ) ;
413
- }
414
- return er ;
415
- }
416
-
417
-
418
425
function onEofChunk ( stream , state ) {
419
426
if ( state . ended ) return ;
420
427
if ( state . decoder ) {
0 commit comments