node_modules/readable-stream/lib/_stream_writable.js   F
last analyzed

Complexity

Total Complexity 137
Complexity/F 3.19

Size

Lines of Code 652
Function Count 43

Duplication

Duplicated Lines 8
Ratio 1.23 %

Importance

Changes 0
Metric Value
cc 5
eloc 343
nc 480
dl 8
loc 652
rs 2
c 0
b 0
f 0
wmc 137
mnd 3
bc 93
fnc 43
bpm 2.1627
cpm 3.186
noi 27

40 Functions

Rating   Name   Duplication   Size   Complexity  
A _stream_writable.js ➔ prefinish 0 12 4
B _stream_writable.js ➔ WritableState 1 110 8
A _stream_writable.js ➔ finishMaybe 0 11 3
A internalUtil.deprecate 0 3 1
A Writable.cork 0 5 1
A _stream_writable.js ➔ setDefaultEncoding 1 7 3
B _stream_writable.js ➔ onwrite 0 24 7
A _stream_writable.js ➔ onwriteError 0 23 2
A Writable._write 0 3 1
A _stream_writable.js ➔ _isUint8Array 0 3 1
C _stream_writable.js ➔ clearBuffer 1 60 11
A _stream_writable.js ➔ onwriteDrain 0 6 3
B Writable.uncork 0 9 7
A Object.defineProperty.set 0 11 2
A _stream_writable.js ➔ onCorkedFinish 0 15 3
B Writable.end 1 23 8
A _stream_writable.js ➔ afterWrite 0 6 2
A _stream_writable.js ➔ doWrite 0 8 2
A Object.defineProperty.value 0 6 3
A _stream_writable.js ➔ callFinal 0 11 1
A _stream_writable.js ➔ ??? 0 1 1
B _stream_writable.js ➔ validChunk 0 16 6
B _stream_writable.js ➔ writeOrBuffer 1 38 8
C Writable.write 1 25 10
A _stream_writable.js ➔ nop 0 1 1
A _stream_writable.js ➔ CorkedRequest 0 9 1
A _stream_writable.js ➔ WriteReq 0 6 1
A Object.defineProperty.get 0 6 2
A _stream_writable.js ➔ getBuffer 0 9 2
A _stream_writable.js ➔ realHasInstance 0 3 1
A _stream_writable.js ➔ needFinish 0 3 1
A 0 9 1
A _stream_writable.js ➔ writeAfterEnd 0 6 1
A Writable._destroy 0 4 1
A _stream_writable.js ➔ onwriteStateUpdate 0 6 1
A _stream_writable.js ➔ _uint8ArrayToBuffer 0 3 1
A _stream_writable.js ➔ decodeChunk 0 6 4
B _stream_writable.js ➔ Writable 1 31 8
A Writable.pipe 0 3 1
A _stream_writable.js ➔ endWritable 0 9 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like node_modules/readable-stream/lib/_stream_writable.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
// Copyright Joyent, Inc. and other Node contributors.
2
//
3
// Permission is hereby granted, free of charge, to any person obtaining a
4
// copy of this software and associated documentation files (the
5
// "Software"), to deal in the Software without restriction, including
6
// without limitation the rights to use, copy, modify, merge, publish,
7
// distribute, sublicense, and/or sell copies of the Software, and to permit
8
// persons to whom the Software is furnished to do so, subject to the
9
// following conditions:
10
//
11
// The above copyright notice and this permission notice shall be included
12
// in all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
// A bit simpler than readable streams.
23
// Implement an async ._write(chunk, encoding, cb), and it'll handle all
24
// the drain event emission and buffering.
25
26
'use strict';
27
28
/*<replacement>*/
29
30
var pna = require('process-nextick-args');
31
/*</replacement>*/
32
33
module.exports = Writable;
34
35
/* <replacement> */
36
function WriteReq(chunk, encoding, cb) {
37
  this.chunk = chunk;
38
  this.encoding = encoding;
39
  this.callback = cb;
40
  this.next = null;
41
}
42
43
// It seems a linked list but it is not
44
// there will be only 2 of these for each stream
45
function CorkedRequest(state) {
46
  var _this = this;
47
48
  this.next = null;
49
  this.entry = null;
50
  this.finish = function () {
51
    onCorkedFinish(_this, state);
52
  };
53
}
54
/* </replacement> */
55
56
/*<replacement>*/
57
var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick;
0 ignored issues
show
Bug introduced by
The variable setImmediate seems to be never declared. If this is a global, consider adding a /** global: setImmediate */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
58
/*</replacement>*/
59
60
/*<replacement>*/
61
var Duplex;
62
/*</replacement>*/
63
64
Writable.WritableState = WritableState;
65
66
/*<replacement>*/
67
var util = require('core-util-is');
68
util.inherits = require('inherits');
69
/*</replacement>*/
70
71
/*<replacement>*/
72
var internalUtil = {
73
  deprecate: require('util-deprecate')
74
};
75
/*</replacement>*/
76
77
/*<replacement>*/
78
var Stream = require('./internal/streams/stream');
79
/*</replacement>*/
80
81
/*<replacement>*/
82
83
var Buffer = require('safe-buffer').Buffer;
84
var OurUint8Array = global.Uint8Array || function () {};
85
function _uint8ArrayToBuffer(chunk) {
86
  return Buffer.from(chunk);
87
}
88
function _isUint8Array(obj) {
89
  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
90
}
91
92
/*</replacement>*/
93
94
var destroyImpl = require('./internal/streams/destroy');
95
96
util.inherits(Writable, Stream);
97
98
function nop() {}
99
100 View Code Duplication
function WritableState(options, stream) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
101
  Duplex = Duplex || require('./_stream_duplex');
102
103
  options = options || {};
104
105
  // Duplex streams are both readable and writable, but share
106
  // the same options object.
107
  // However, some cases require setting options to different
108
  // values for the readable and the writable sides of the duplex stream.
109
  // These options can be provided separately as readableXXX and writableXXX.
110
  var isDuplex = stream instanceof Duplex;
111
112
  // object stream flag to indicate whether or not this stream
113
  // contains buffers or objects.
114
  this.objectMode = !!options.objectMode;
115
116
  if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
117
118
  // the point at which write() starts returning false
119
  // Note: 0 is a valid value, means that we always return false if
120
  // the entire buffer is not flushed immediately on write()
121
  var hwm = options.highWaterMark;
122
  var writableHwm = options.writableHighWaterMark;
123
  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
124
125
  if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
126
127
  // cast to ints.
128
  this.highWaterMark = Math.floor(this.highWaterMark);
129
130
  // if _final has been called
131
  this.finalCalled = false;
132
133
  // drain event flag.
134
  this.needDrain = false;
135
  // at the start of calling end()
136
  this.ending = false;
137
  // when end() has been called, and returned
138
  this.ended = false;
139
  // when 'finish' is emitted
140
  this.finished = false;
141
142
  // has it been destroyed
143
  this.destroyed = false;
144
145
  // should we decode strings into buffers before passing to _write?
146
  // this is here so that some node-core streams can optimize string
147
  // handling at a lower level.
148
  var noDecode = options.decodeStrings === false;
149
  this.decodeStrings = !noDecode;
150
151
  // Crypto is kind of old and crusty.  Historically, its default string
152
  // encoding is 'binary' so we have to make this configurable.
153
  // Everything else in the universe uses 'utf8', though.
154
  this.defaultEncoding = options.defaultEncoding || 'utf8';
155
156
  // not an actual buffer we keep track of, but a measurement
157
  // of how much we're waiting to get pushed to some underlying
158
  // socket or file.
159
  this.length = 0;
160
161
  // a flag to see when we're in the middle of a write.
162
  this.writing = false;
163
164
  // when true all writes will be buffered until .uncork() call
165
  this.corked = 0;
166
167
  // a flag to be able to tell if the onwrite cb is called immediately,
168
  // or on a later tick.  We set this to true at first, because any
169
  // actions that shouldn't happen until "later" should generally also
170
  // not happen before the first write call.
171
  this.sync = true;
172
173
  // a flag to know if we're processing previously buffered items, which
174
  // may call the _write() callback in the same tick, so that we don't
175
  // end up in an overlapped onwrite situation.
176
  this.bufferProcessing = false;
177
178
  // the callback that's passed to _write(chunk,cb)
179
  this.onwrite = function (er) {
180
    onwrite(stream, er);
181
  };
182
183
  // the callback that the user supplies to write(chunk,encoding,cb)
184
  this.writecb = null;
185
186
  // the amount that is being written when _write is called.
187
  this.writelen = 0;
188
189
  this.bufferedRequest = null;
190
  this.lastBufferedRequest = null;
191
192
  // number of pending user-supplied write callbacks
193
  // this must be 0 before 'finish' can be emitted
194
  this.pendingcb = 0;
195
196
  // emit prefinish if the only thing we're waiting for is _write cbs
197
  // This is relevant for synchronous Transform streams
198
  this.prefinished = false;
199
200
  // True if the error was already emitted and should not be thrown again
201
  this.errorEmitted = false;
202
203
  // count buffered requests
204
  this.bufferedRequestCount = 0;
205
206
  // allocate the first CorkedRequest, there is always
207
  // one allocated and free to use, and we maintain at most two
208
  this.corkedRequestsFree = new CorkedRequest(this);
209
}
210
211
WritableState.prototype.getBuffer = function getBuffer() {
212
  var current = this.bufferedRequest;
213
  var out = [];
214
  while (current) {
215
    out.push(current);
216
    current = current.next;
217
  }
218
  return out;
219
};
220
221
(function () {
222
  try {
223
    Object.defineProperty(WritableState.prototype, 'buffer', {
224
      get: internalUtil.deprecate(function () {
225
        return this.getBuffer();
226
      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
227
    });
228
  } catch (_) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
229
})();
230
231
// Test _writableState for inheritance to account for Duplex streams,
232
// whose prototype chain only points to Readable.
233
var realHasInstance;
234 View Code Duplication
if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
0 ignored issues
show
Bug introduced by
The variable Symbol seems to be never declared. If this is a global, consider adding a /** global: Symbol */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
235
  realHasInstance = Function.prototype[Symbol.hasInstance];
236
  Object.defineProperty(Writable, Symbol.hasInstance, {
237
    value: function (object) {
238
      if (realHasInstance.call(this, object)) return true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
239
      if (this !== Writable) return false;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
240
241
      return object && object._writableState instanceof WritableState;
242
    }
243
  });
244
} else {
245
  realHasInstance = function (object) {
246
    return object instanceof this;
247
  };
248
}
249
250 View Code Duplication
function Writable(options) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
251
  Duplex = Duplex || require('./_stream_duplex');
252
253
  // Writable ctor is applied to Duplexes, too.
254
  // `realHasInstance` is necessary because using plain `instanceof`
255
  // would return false, as no `_writableState` property is attached.
256
257
  // Trying to use the custom `instanceof` for Writable here will also break the
258
  // Node.js LazyTransform implementation, which has a non-trivial getter for
259
  // `_writableState` that would lead to infinite recursion.
260
  if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
261
    return new Writable(options);
262
  }
263
264
  this._writableState = new WritableState(options, this);
265
266
  // legacy.
267
  this.writable = true;
268
269
  if (options) {
270
    if (typeof options.write === 'function') this._write = options.write;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
271
272
    if (typeof options.writev === 'function') this._writev = options.writev;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
273
274
    if (typeof options.destroy === 'function') this._destroy = options.destroy;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
275
276
    if (typeof options.final === 'function') this._final = options.final;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
277
  }
278
279
  Stream.call(this);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
280
}
281
282
// Otherwise people can pipe Writable streams, which is just wrong.
283
Writable.prototype.pipe = function () {
284
  this.emit('error', new Error('Cannot pipe, not readable'));
285
};
286
287
function writeAfterEnd(stream, cb) {
288
  var er = new Error('write after end');
289
  // TODO: defer error events consistently everywhere, not just the cb
290
  stream.emit('error', er);
291
  pna.nextTick(cb, er);
292
}
293
294
// Checks that a user-supplied chunk is valid, especially for the particular
295
// mode the stream is in. Currently this means that `null` is never accepted
296
// and undefined/non-string values are only allowed in object mode.
297
function validChunk(stream, state, chunk, cb) {
298
  var valid = true;
299
  var er = false;
300
301
  if (chunk === null) {
302
    er = new TypeError('May not write null values to stream');
303
  } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
304
    er = new TypeError('Invalid non-string/buffer chunk');
305
  }
306
  if (er) {
307
    stream.emit('error', er);
308
    pna.nextTick(cb, er);
309
    valid = false;
310
  }
311
  return valid;
312
}
313
314 View Code Duplication
Writable.prototype.write = function (chunk, encoding, cb) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
315
  var state = this._writableState;
316
  var ret = false;
317
  var isBuf = !state.objectMode && _isUint8Array(chunk);
318
319
  if (isBuf && !Buffer.isBuffer(chunk)) {
320
    chunk = _uint8ArrayToBuffer(chunk);
321
  }
322
323
  if (typeof encoding === 'function') {
324
    cb = encoding;
325
    encoding = null;
326
  }
327
328
  if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
329
330
  if (typeof cb !== 'function') cb = nop;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
331
332
  if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
333
    state.pendingcb++;
334
    ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
335
  }
336
337
  return ret;
338
};
339
340
Writable.prototype.cork = function () {
341
  var state = this._writableState;
342
343
  state.corked++;
344
};
345
346
Writable.prototype.uncork = function () {
347
  var state = this._writableState;
348
349
  if (state.corked) {
350
    state.corked--;
351
352
    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
353
  }
354
};
355
356 View Code Duplication
Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
357
  // node::ParseEncoding() requires lower case.
358
  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
359
  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
360
  this._writableState.defaultEncoding = encoding;
361
  return this;
362
};
363
364
function decodeChunk(state, chunk, encoding) {
365
  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
366
    chunk = Buffer.from(chunk, encoding);
367
  }
368
  return chunk;
369
}
370
371
// if we're already writing something, then just put this
372
// in the queue, and wait our turn.  Otherwise, call _write
373
// If we return false, then we need a drain event, so set that flag.
374 View Code Duplication
function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
375
  if (!isBuf) {
376
    var newChunk = decodeChunk(state, chunk, encoding);
377
    if (chunk !== newChunk) {
378
      isBuf = true;
379
      encoding = 'buffer';
380
      chunk = newChunk;
381
    }
382
  }
383
  var len = state.objectMode ? 1 : chunk.length;
384
385
  state.length += len;
386
387
  var ret = state.length < state.highWaterMark;
388
  // we must ensure that previous needDrain will not be reset to false.
389
  if (!ret) state.needDrain = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
390
391
  if (state.writing || state.corked) {
392
    var last = state.lastBufferedRequest;
393
    state.lastBufferedRequest = {
394
      chunk: chunk,
395
      encoding: encoding,
396
      isBuf: isBuf,
397
      callback: cb,
398
      next: null
399
    };
400
    if (last) {
401
      last.next = state.lastBufferedRequest;
402
    } else {
403
      state.bufferedRequest = state.lastBufferedRequest;
404
    }
405
    state.bufferedRequestCount += 1;
406
  } else {
407
    doWrite(stream, state, false, len, chunk, encoding, cb);
408
  }
409
410
  return ret;
411
}
412
413
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
414
  state.writelen = len;
415
  state.writecb = cb;
416
  state.writing = true;
417
  state.sync = true;
418
  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
419
  state.sync = false;
420
}
421
422
function onwriteError(stream, state, sync, er, cb) {
423
  --state.pendingcb;
424
425
  if (sync) {
426
    // defer the callback if we are being called synchronously
427
    // to avoid piling up things on the stack
428
    pna.nextTick(cb, er);
429
    // this can emit finish, and it will always happen
430
    // after error
431
    pna.nextTick(finishMaybe, stream, state);
432
    stream._writableState.errorEmitted = true;
433
    stream.emit('error', er);
434
  } else {
435
    // the caller expect this to happen before if
436
    // it is async
437
    cb(er);
438
    stream._writableState.errorEmitted = true;
439
    stream.emit('error', er);
440
    // this can emit finish, but finish must
441
    // always follow error
442
    finishMaybe(stream, state);
443
  }
444
}
445
446
function onwriteStateUpdate(state) {
447
  state.writing = false;
448
  state.writecb = null;
449
  state.length -= state.writelen;
450
  state.writelen = 0;
451
}
452
453
function onwrite(stream, er) {
454
  var state = stream._writableState;
455
  var sync = state.sync;
456
  var cb = state.writecb;
457
458
  onwriteStateUpdate(state);
459
460
  if (er) onwriteError(stream, state, sync, er, cb);else {
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
461
    // Check if we're actually ready to finish, but don't emit yet
462
    var finished = needFinish(state);
463
464
    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
465
      clearBuffer(stream, state);
466
    }
467
468
    if (sync) {
469
      /*<replacement>*/
470
      asyncWrite(afterWrite, stream, state, finished, cb);
471
      /*</replacement>*/
472
    } else {
473
      afterWrite(stream, state, finished, cb);
474
    }
475
  }
476
}
477
478
function afterWrite(stream, state, finished, cb) {
479
  if (!finished) onwriteDrain(stream, state);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
480
  state.pendingcb--;
481
  cb();
482
  finishMaybe(stream, state);
483
}
484
485
// Must force callback to be called on nextTick, so that we don't
486
// emit 'drain' before the write() consumer gets the 'false' return
487
// value, and has a chance to attach a 'drain' listener.
488
function onwriteDrain(stream, state) {
489
  if (state.length === 0 && state.needDrain) {
490
    state.needDrain = false;
491
    stream.emit('drain');
492
  }
493
}
494
495
// if there's something in the buffer waiting, then process it
496 View Code Duplication
function clearBuffer(stream, state) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
497
  state.bufferProcessing = true;
498
  var entry = state.bufferedRequest;
499
500
  if (stream._writev && entry && entry.next) {
501
    // Fast case, write everything using _writev()
502
    var l = state.bufferedRequestCount;
503
    var buffer = new Array(l);
504
    var holder = state.corkedRequestsFree;
505
    holder.entry = entry;
506
507
    var count = 0;
508
    var allBuffers = true;
509
    while (entry) {
510
      buffer[count] = entry;
511
      if (!entry.isBuf) allBuffers = false;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
512
      entry = entry.next;
513
      count += 1;
514
    }
515
    buffer.allBuffers = allBuffers;
516
517
    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
518
519
    // doWrite is almost always async, defer these to save a bit of time
520
    // as the hot path ends with doWrite
521
    state.pendingcb++;
522
    state.lastBufferedRequest = null;
523
    if (holder.next) {
524
      state.corkedRequestsFree = holder.next;
525
      holder.next = null;
526
    } else {
527
      state.corkedRequestsFree = new CorkedRequest(state);
528
    }
529
    state.bufferedRequestCount = 0;
530
  } else {
531
    // Slow case, write chunks one-by-one
532
    while (entry) {
533
      var chunk = entry.chunk;
534
      var encoding = entry.encoding;
535
      var cb = entry.callback;
536
      var len = state.objectMode ? 1 : chunk.length;
537
538
      doWrite(stream, state, false, len, chunk, encoding, cb);
539
      entry = entry.next;
540
      state.bufferedRequestCount--;
541
      // if we didn't call the onwrite immediately, then
542
      // it means that we need to wait until it does.
543
      // also, that means that the chunk and cb are currently
544
      // being processed, so move the buffer counter past them.
545
      if (state.writing) {
546
        break;
547
      }
548
    }
549
550
    if (entry === null) state.lastBufferedRequest = null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
551
  }
552
553
  state.bufferedRequest = entry;
554
  state.bufferProcessing = false;
555
}
556
557
Writable.prototype._write = function (chunk, encoding, cb) {
558
  cb(new Error('_write() is not implemented'));
559
};
560
561
Writable.prototype._writev = null;
562
563 View Code Duplication
Writable.prototype.end = function (chunk, encoding, cb) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
564
  var state = this._writableState;
565
566
  if (typeof chunk === 'function') {
567
    cb = chunk;
568
    chunk = null;
569
    encoding = null;
570
  } else if (typeof encoding === 'function') {
571
    cb = encoding;
572
    encoding = null;
573
  }
574
575
  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
576
577
  // .end() fully uncorks
578
  if (state.corked) {
579
    state.corked = 1;
580
    this.uncork();
581
  }
582
583
  // ignore unnecessary end() calls.
584
  if (!state.ending && !state.finished) endWritable(this, state, cb);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
585
};
586
587
function needFinish(state) {
588
  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
589
}
590
function callFinal(stream, state) {
591
  stream._final(function (err) {
592
    state.pendingcb--;
593
    if (err) {
594
      stream.emit('error', err);
595
    }
596
    state.prefinished = true;
597
    stream.emit('prefinish');
598
    finishMaybe(stream, state);
599
  });
600
}
601
function prefinish(stream, state) {
602
  if (!state.prefinished && !state.finalCalled) {
603
    if (typeof stream._final === 'function') {
604
      state.pendingcb++;
605
      state.finalCalled = true;
606
      pna.nextTick(callFinal, stream, state);
607
    } else {
608
      state.prefinished = true;
609
      stream.emit('prefinish');
610
    }
611
  }
612
}
613
614
function finishMaybe(stream, state) {
615
  var need = needFinish(state);
616
  if (need) {
617
    prefinish(stream, state);
618
    if (state.pendingcb === 0) {
619
      state.finished = true;
620
      stream.emit('finish');
621
    }
622
  }
623
  return need;
624
}
625
626
function endWritable(stream, state, cb) {
627
  state.ending = true;
628
  finishMaybe(stream, state);
629
  if (cb) {
630
    if (state.finished) pna.nextTick(cb);else stream.once('finish', cb);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
631
  }
632
  state.ended = true;
633
  stream.writable = false;
634
}
635
636
function onCorkedFinish(corkReq, state, err) {
637
  var entry = corkReq.entry;
638
  corkReq.entry = null;
639
  while (entry) {
640
    var cb = entry.callback;
641
    state.pendingcb--;
642
    cb(err);
643
    entry = entry.next;
644
  }
645
  if (state.corkedRequestsFree) {
646
    state.corkedRequestsFree.next = corkReq;
647
  } else {
648
    state.corkedRequestsFree = corkReq;
649
  }
650
}
651
652
Object.defineProperty(Writable.prototype, 'destroyed', {
653
  get: function () {
654
    if (this._writableState === undefined) {
655
      return false;
656
    }
657
    return this._writableState.destroyed;
658
  },
659
  set: function (value) {
660
    // we ignore the value if the stream
661
    // has not been initialized yet
662
    if (!this._writableState) {
663
      return;
664
    }
665
666
    // backward compatibility, the user is explicitly
667
    // managing destroyed
668
    this._writableState.destroyed = value;
669
  }
670
});
671
672
Writable.prototype.destroy = destroyImpl.destroy;
673
Writable.prototype._undestroy = destroyImpl.undestroy;
674
Writable.prototype._destroy = function (err, cb) {
675
  this.end();
676
  cb(err);
677
};