@@ -108,6 +108,7 @@ const kWriteCb = 1 << 26;
108
108
const kExpectWriteCb = 1 << 27 ;
109
109
const kAfterWriteTickInfo = 1 << 28 ;
110
110
const kAfterWritePending = 1 << 29 ;
111
+ const kHasBuffer = 1 << 30 ;
111
112
112
113
// TODO(benjamingr) it is likely slower to do it this way than with free functions
113
114
function makeBitMapDescriptor ( bit ) {
@@ -337,19 +338,20 @@ function WritableState(options, stream, isDuplex) {
337
338
}
338
339
339
340
function resetBuffer ( state ) {
340
- state . buffered = [ ] ;
341
+ state . buffered = null ;
341
342
state . bufferedIndex = 0 ;
342
343
state . state |= kAllBuffers | kAllNoop ;
344
+ state . state &= ~ kHasBuffer ;
343
345
}
344
346
345
347
WritableState . prototype . getBuffer = function getBuffer ( ) {
346
- return ArrayPrototypeSlice ( this . buffered , this . bufferedIndex ) ;
348
+ return ( this . state & kHasBuffer ) === 0 ? [ ] : ArrayPrototypeSlice ( this . buffered , this . bufferedIndex ) ;
347
349
} ;
348
350
349
351
ObjectDefineProperty ( WritableState . prototype , 'bufferedRequestCount' , {
350
352
__proto__ : null ,
351
353
get ( ) {
352
- return this . buffered . length - this . bufferedIndex ;
354
+ return ( this . state & kHasBuffer ) === 0 ? 0 : this . buffered . length - this . bufferedIndex ;
353
355
} ,
354
356
} ) ;
355
357
@@ -522,6 +524,11 @@ function writeOrBuffer(stream, state, chunk, encoding, callback) {
522
524
}
523
525
524
526
if ( ( state . state & ( kWriting | kErrored | kCorked | kConstructed ) ) !== kConstructed ) {
527
+ if ( ( state . state & kHasBuffer ) === 0 ) {
528
+ state . state |= kHasBuffer ;
529
+ state . buffered = [ ] ;
530
+ }
531
+
525
532
state . buffered . push ( { chunk, encoding, callback } ) ;
526
533
if ( ( state . state & kAllBuffers ) !== 0 && encoding !== 'buffer' ) {
527
534
state . state &= ~ kAllBuffers ;
@@ -607,7 +614,7 @@ function onwrite(stream, er) {
607
614
onwriteError ( stream , state , er , cb ) ;
608
615
}
609
616
} else {
610
- if ( state . buffered . length > state . bufferedIndex ) {
617
+ if ( ( state . state & kHasBuffer ) !== 0 ) {
611
618
clearBuffer ( stream , state ) ;
612
619
}
613
620
@@ -677,11 +684,13 @@ function errorBuffer(state) {
677
684
return ;
678
685
}
679
686
680
- for ( let n = state . bufferedIndex ; n < state . buffered . length ; ++ n ) {
681
- const { chunk, callback } = state . buffered [ n ] ;
682
- const len = ( state . state & kObjectMode ) !== 0 ? 1 : chunk . length ;
683
- state . length -= len ;
684
- callback ( state . errored ?? new ERR_STREAM_DESTROYED ( 'write' ) ) ;
687
+ if ( ( state . state & kHasBuffer ) !== 0 ) {
688
+ for ( let n = state . bufferedIndex ; n < state . buffered . length ; ++ n ) {
689
+ const { chunk, callback } = state . buffered [ n ] ;
690
+ const len = ( state . state & kObjectMode ) !== 0 ? 1 : chunk . length ;
691
+ state . length -= len ;
692
+ callback ( state . errored ?? new ERR_STREAM_DESTROYED ( 'write' ) ) ;
693
+ }
685
694
}
686
695
687
696
@@ -692,8 +701,7 @@ function errorBuffer(state) {
692
701
693
702
// If there's something in the buffer waiting, then process it.
694
703
function clearBuffer ( stream , state ) {
695
- if ( ( state . state & ( kDestroyed | kBufferProcessing | kCorked ) ) !== 0 ||
696
- ( state . state & kConstructed ) === 0 ) {
704
+ if ( ( state . state & ( kDestroyed | kBufferProcessing | kCorked | kHasBuffer ) ) !== kHasBuffer ) {
697
705
return ;
698
706
}
699
707
@@ -828,10 +836,9 @@ function needFinish(state) {
828
836
kWriting |
829
837
kErrorEmitted |
830
838
kCloseEmitted |
831
- kErrored
832
- ) ) === ( kEnding | kConstructed ) &&
833
- state . length === 0 &&
834
- state . buffered . length === 0 ) ;
839
+ kErrored |
840
+ kHasBuffer
841
+ ) ) === ( kEnding | kConstructed ) && state . length === 0 ) ;
835
842
}
836
843
837
844
function callFinal ( stream , state ) {
@@ -1073,9 +1080,7 @@ Writable.prototype.destroy = function(err, cb) {
1073
1080
const state = this . _writableState ;
1074
1081
1075
1082
// Invoke pending callbacks.
1076
- if ( ( state . state & kDestroyed ) === 0 &&
1077
- ( state . bufferedIndex < state . buffered . length ||
1078
- ( state . state & kOnFinished ) !== 0 ) ) {
1083
+ if ( ( state . state & ( kHasBuffer | kOnFinished | kDestroyed ) ) !== kDestroyed ) {
1079
1084
process . nextTick ( errorBuffer , state ) ;
1080
1085
}
1081
1086
0 commit comments