@@ -105,21 +105,51 @@ function Readable(options) {
105
105
// similar to how Writable.write() returns true if you should
106
106
// write() some more.
107
107
Readable . prototype . push = function ( chunk ) {
108
- var rs = this . _readableState ;
109
- rs . onread ( null , chunk ) ;
110
-
111
- // if it's past the high water mark, we can push in some more.
112
- // Also, if we have no data yet, we can stand some
113
- // more bytes. This is to work around cases where hwm=0,
114
- // such as the repl. Also, if the push() triggered a
115
- // readable event, and the user called read(largeNumber) such that
116
- // needReadable was set, then we ought to push more, so that another
117
- // 'readable' event will be triggered.
118
- return rs . needReadable ||
119
- rs . length < rs . highWaterMark ||
120
- rs . length === 0 ;
108
+ var state = this . _readableState ;
109
+ return readableAddChunk ( this , state , chunk ) ;
121
110
} ;
122
111
112
+ function readableAddChunk ( stream , state , chunk ) {
113
+ state . reading = false ;
114
+
115
+ var er = chunkInvalid ( state , chunk ) ;
116
+ if ( er ) {
117
+ stream . emit ( 'error' , er ) ;
118
+ } else if ( chunk === null || chunk === undefined ) {
119
+ onreadEof ( stream , state ) ;
120
+ } else if ( state . objectMode || chunk && chunk . length > 0 ) {
121
+ if ( state . decoder )
122
+ chunk = state . decoder . write ( chunk ) ;
123
+
124
+ // update the buffer info.
125
+ state . length += state . objectMode ? 1 : chunk . length ;
126
+ state . buffer . push ( chunk ) ;
127
+
128
+ if ( state . needReadable )
129
+ emitReadable ( stream ) ;
130
+
131
+ maybeReadMore ( stream , state ) ;
132
+ }
133
+
134
+ return needMoreData ( state ) ;
135
+ }
136
+
137
+
138
+
139
+ // if it's past the high water mark, we can push in some more.
140
+ // Also, if we have no data yet, we can stand some
141
+ // more bytes. This is to work around cases where hwm=0,
142
+ // such as the repl. Also, if the push() triggered a
143
+ // readable event, and the user called read(largeNumber) such that
144
+ // needReadable was set, then we ought to push more, so that another
145
+ // 'readable' event will be triggered.
146
+ function needMoreData ( state ) {
147
+ return ! state . ended &&
148
+ ( state . needReadable ||
149
+ state . length < state . highWaterMark ||
150
+ state . length === 0 ) ;
151
+ }
152
+
123
153
// backwards compatibility.
124
154
Readable . prototype . setEncoding = function ( enc ) {
125
155
if ( ! StringDecoder )
@@ -263,15 +293,20 @@ Readable.prototype.read = function(n) {
263
293
return ret ;
264
294
} ;
265
295
296
+ // This is the function passed to _read(n,cb) as the callback.
297
+ // It should be called exactly once for every _read() call.
266
298
function onread ( stream , er , chunk ) {
267
299
var state = stream . _readableState ;
268
300
var sync = state . sync ;
269
301
270
- // If we get something that is not a buffer, string, null, or undefined,
271
- // and we're not in objectMode, then that's an error.
272
- // Otherwise stream chunks are all considered to be of length=1, and the
273
- // watermarks determine how many objects to keep in the buffer, rather than
274
- // how many bytes or characters.
302
+ if ( er )
303
+ stream . emit ( 'error' , er ) ;
304
+ else
305
+ stream . push ( chunk ) ;
306
+ }
307
+
308
+ function chunkInvalid ( state , chunk ) {
309
+ var er = null ;
275
310
if ( ! Buffer . isBuffer ( chunk ) &&
276
311
'string' !== typeof chunk &&
277
312
chunk !== null &&
@@ -280,68 +315,26 @@ function onread(stream, er, chunk) {
280
315
! er ) {
281
316
er = new TypeError ( 'Invalid non-string/buffer chunk' ) ;
282
317
}
318
+ return er ;
319
+ }
283
320
284
- state . reading = false ;
285
- if ( er )
286
- return stream . emit ( 'error' , er ) ;
287
321
288
- if ( chunk === null || chunk === undefined ) {
289
- // eof
290
- state . ended = true ;
291
- if ( state . decoder ) {
292
- chunk = state . decoder . end ( ) ;
293
- if ( chunk && chunk . length ) {
294
- state . buffer . push ( chunk ) ;
295
- state . length += state . objectMode ? 1 : chunk . length ;
296
- }
322
+ function onreadEof ( stream , state ) {
323
+ state . ended = true ;
324
+ if ( state . decoder ) {
325
+ var chunk = state . decoder . end ( ) ;
326
+ if ( chunk && chunk . length ) {
327
+ state . buffer . push ( chunk ) ;
328
+ state . length += state . objectMode ? 1 : chunk . length ;
297
329
}
298
-
299
- // if we've ended and we have some data left, then emit
300
- // 'readable' now to make sure it gets picked up.
301
- if ( state . length > 0 )
302
- emitReadable ( stream ) ;
303
- else
304
- endReadable ( stream ) ;
305
- return ;
306
- }
307
-
308
- // at this point, if we got a zero-length buffer or string,
309
- // and we're not in object-mode, then there's really no point
310
- // continuing. it means that there is nothing to read right
311
- // now, but as we have not received the EOF-signaling null,
312
- // we're not ended. we've already unset the reading flag,
313
- // so just get out of here.
314
- if ( ! state . objectMode &&
315
- ( chunk || typeof chunk === 'string' ) &&
316
- 0 === chunk . length )
317
- return ;
318
-
319
- if ( state . decoder )
320
- chunk = state . decoder . write ( chunk ) ;
321
-
322
- // update the buffer info.
323
- state . length += state . objectMode ? 1 : chunk . length ;
324
- state . buffer . push ( chunk ) ;
325
-
326
- // if we haven't gotten any data,
327
- // and we haven't ended, then don't bother telling the user
328
- // that it's time to read more data. Otherwise, emitting 'readable'
329
- // probably will trigger another stream.read(), which can trigger
330
- // another _read(n,cb) before this one returns!
331
- if ( state . length === 0 ) {
332
- state . reading = true ;
333
- stream . _read ( state . bufferSize , state . onread ) ;
334
- return ;
335
330
}
336
331
337
- if ( state . needReadable )
332
+ // if we've ended and we have some data left, then emit
333
+ // 'readable' now to make sure it gets picked up.
334
+ if ( state . length > 0 )
338
335
emitReadable ( stream ) ;
339
- else if ( state . sync )
340
- process . nextTick ( function ( ) {
341
- maybeReadMore ( stream , state ) ;
342
- } ) ;
343
336
else
344
- maybeReadMore ( stream , state ) ;
337
+ endReadable ( stream ) ;
345
338
}
346
339
347
340
// Don't emit readable right away in sync mode, because this can trigger
@@ -365,17 +358,26 @@ function emitReadable(stream) {
365
358
function emitReadable_ ( stream ) {
366
359
var state = stream . _readableState ;
367
360
stream . emit ( 'readable' ) ;
368
- maybeReadMore ( stream , state ) ;
369
361
}
370
362
363
+
364
+ // at this point, the user has presumably seen the 'readable' event,
365
+ // and called read() to consume some data. that may have triggered
366
+ // in turn another _read(n,cb) call, in which case reading = true if
367
+ // it's in progress.
368
+ // However, if we're not ended, or reading, and the length < hwm,
369
+ // then go ahead and try to read some more right now preemptively.
371
370
function maybeReadMore ( stream , state ) {
372
- // at this point, the user has presumably seen the 'readable' event,
373
- // and called read() to consume some data. that may have triggered
374
- // in turn another _read(n,cb) call, in which case reading = true if
375
- // it's in progress.
376
- // However, if we're not ended, or reading, and the length < hwm,
377
- // then go ahead and try to read some more right now preemptively.
378
- if ( ! state . reading && ! state . ending && ! state . ended &&
371
+ if ( state . sync )
372
+ process . nextTick ( function ( ) {
373
+ maybeReadMore_ ( stream , state ) ;
374
+ } ) ;
375
+ else
376
+ maybeReadMore_ ( stream , state ) ;
377
+ }
378
+
379
+ function maybeReadMore_ ( stream , state ) {
380
+ if ( ! state . reading && ! state . ended &&
379
381
state . length < state . highWaterMark ) {
380
382
stream . read ( 0 ) ;
381
383
}
0 commit comments