]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/node_modules/sha/node_modules/readable-stream/lib/_stream_writable.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / node_modules / sha / node_modules / readable-stream / lib / _stream_writable.js
1 // A bit simpler than readable streams.
2 // Implement an async ._write(chunk, cb), and it'll handle all
3 // the drain event emission and buffering.
4
5 'use strict';
6
7 module.exports = Writable;
8
9 /*<replacement>*/
10 var processNextTick = require('process-nextick-args');
11 /*</replacement>*/
12
13
14 /*<replacement>*/
15 var Buffer = require('buffer').Buffer;
16 /*</replacement>*/
17
18 Writable.WritableState = WritableState;
19
20
21 /*<replacement>*/
22 var util = require('core-util-is');
23 util.inherits = require('inherits');
24 /*</replacement>*/
25
26
27
28 /*<replacement>*/
29 var Stream;
30 (function (){try{
31   Stream = require('st' + 'ream');
32 }catch(_){}finally{
33   if (!Stream)
34     Stream = require('events').EventEmitter;
35 }}())
36 /*</replacement>*/
37
38 var Buffer = require('buffer').Buffer;
39
40 util.inherits(Writable, Stream);
41
42 function nop() {}
43
44 function WriteReq(chunk, encoding, cb) {
45   this.chunk = chunk;
46   this.encoding = encoding;
47   this.callback = cb;
48   this.next = null;
49 }
50
51 function WritableState(options, stream) {
52   var Duplex = require('./_stream_duplex');
53
54   options = options || {};
55
56   // object stream flag to indicate whether or not this stream
57   // contains buffers or objects.
58   this.objectMode = !!options.objectMode;
59
60   if (stream instanceof Duplex)
61     this.objectMode = this.objectMode || !!options.writableObjectMode;
62
63   // the point at which write() starts returning false
64   // Note: 0 is a valid value, means that we always return false if
65   // the entire buffer is not flushed immediately on write()
66   var hwm = options.highWaterMark;
67   var defaultHwm = this.objectMode ? 16 : 16 * 1024;
68   this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
69
70   // cast to ints.
71   this.highWaterMark = ~~this.highWaterMark;
72
73   this.needDrain = false;
74   // at the start of calling end()
75   this.ending = false;
76   // when end() has been called, and returned
77   this.ended = false;
78   // when 'finish' is emitted
79   this.finished = false;
80
81   // should we decode strings into buffers before passing to _write?
82   // this is here so that some node-core streams can optimize string
83   // handling at a lower level.
84   var noDecode = options.decodeStrings === false;
85   this.decodeStrings = !noDecode;
86
87   // Crypto is kind of old and crusty.  Historically, its default string
88   // encoding is 'binary' so we have to make this configurable.
89   // Everything else in the universe uses 'utf8', though.
90   this.defaultEncoding = options.defaultEncoding || 'utf8';
91
92   // not an actual buffer we keep track of, but a measurement
93   // of how much we're waiting to get pushed to some underlying
94   // socket or file.
95   this.length = 0;
96
97   // a flag to see when we're in the middle of a write.
98   this.writing = false;
99
100   // when true all writes will be buffered until .uncork() call
101   this.corked = 0;
102
103   // a flag to be able to tell if the onwrite cb is called immediately,
104   // or on a later tick.  We set this to true at first, because any
105   // actions that shouldn't happen until "later" should generally also
106   // not happen before the first write call.
107   this.sync = true;
108
109   // a flag to know if we're processing previously buffered items, which
110   // may call the _write() callback in the same tick, so that we don't
111   // end up in an overlapped onwrite situation.
112   this.bufferProcessing = false;
113
114   // the callback that's passed to _write(chunk,cb)
115   this.onwrite = function(er) {
116     onwrite(stream, er);
117   };
118
119   // the callback that the user supplies to write(chunk,encoding,cb)
120   this.writecb = null;
121
122   // the amount that is being written when _write is called.
123   this.writelen = 0;
124
125   this.bufferedRequest = null;
126   this.lastBufferedRequest = null;
127
128   // number of pending user-supplied write callbacks
129   // this must be 0 before 'finish' can be emitted
130   this.pendingcb = 0;
131
132   // emit prefinish if the only thing we're waiting for is _write cbs
133   // This is relevant for synchronous Transform streams
134   this.prefinished = false;
135
136   // True if the error was already emitted and should not be thrown again
137   this.errorEmitted = false;
138 }
139
140 WritableState.prototype.getBuffer = function writableStateGetBuffer() {
141   var current = this.bufferedRequest;
142   var out = [];
143   while (current) {
144     out.push(current);
145     current = current.next;
146   }
147   return out;
148 };
149
150 (function (){try {
151 Object.defineProperty(WritableState.prototype, 'buffer', {
152   get: require('util-deprecate')(function() {
153     return this.getBuffer();
154   }, '_writableState.buffer is deprecated. Use ' +
155       '_writableState.getBuffer() instead.')
156 });
157 }catch(_){}}());
158
159
160 function Writable(options) {
161   var Duplex = require('./_stream_duplex');
162
163   // Writable ctor is applied to Duplexes, though they're not
164   // instanceof Writable, they're instanceof Readable.
165   if (!(this instanceof Writable) && !(this instanceof Duplex))
166     return new Writable(options);
167
168   this._writableState = new WritableState(options, this);
169
170   // legacy.
171   this.writable = true;
172
173   if (options) {
174     if (typeof options.write === 'function')
175       this._write = options.write;
176
177     if (typeof options.writev === 'function')
178       this._writev = options.writev;
179   }
180
181   Stream.call(this);
182 }
183
184 // Otherwise people can pipe Writable streams, which is just wrong.
185 Writable.prototype.pipe = function() {
186   this.emit('error', new Error('Cannot pipe. Not readable.'));
187 };
188
189
190 function writeAfterEnd(stream, cb) {
191   var er = new Error('write after end');
192   // TODO: defer error events consistently everywhere, not just the cb
193   stream.emit('error', er);
194   processNextTick(cb, er);
195 }
196
197 // If we get something that is not a buffer, string, null, or undefined,
198 // and we're not in objectMode, then that's an error.
199 // Otherwise stream chunks are all considered to be of length=1, and the
200 // watermarks determine how many objects to keep in the buffer, rather than
201 // how many bytes or characters.
202 function validChunk(stream, state, chunk, cb) {
203   var valid = true;
204
205   if (!(Buffer.isBuffer(chunk)) &&
206       typeof chunk !== 'string' &&
207       chunk !== null &&
208       chunk !== undefined &&
209       !state.objectMode) {
210     var er = new TypeError('Invalid non-string/buffer chunk');
211     stream.emit('error', er);
212     processNextTick(cb, er);
213     valid = false;
214   }
215   return valid;
216 }
217
218 Writable.prototype.write = function(chunk, encoding, cb) {
219   var state = this._writableState;
220   var ret = false;
221
222   if (typeof encoding === 'function') {
223     cb = encoding;
224     encoding = null;
225   }
226
227   if (Buffer.isBuffer(chunk))
228     encoding = 'buffer';
229   else if (!encoding)
230     encoding = state.defaultEncoding;
231
232   if (typeof cb !== 'function')
233     cb = nop;
234
235   if (state.ended)
236     writeAfterEnd(this, cb);
237   else if (validChunk(this, state, chunk, cb)) {
238     state.pendingcb++;
239     ret = writeOrBuffer(this, state, chunk, encoding, cb);
240   }
241
242   return ret;
243 };
244
245 Writable.prototype.cork = function() {
246   var state = this._writableState;
247
248   state.corked++;
249 };
250
251 Writable.prototype.uncork = function() {
252   var state = this._writableState;
253
254   if (state.corked) {
255     state.corked--;
256
257     if (!state.writing &&
258         !state.corked &&
259         !state.finished &&
260         !state.bufferProcessing &&
261         state.bufferedRequest)
262       clearBuffer(this, state);
263   }
264 };
265
266 Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
267   // node::ParseEncoding() requires lower case.
268   if (typeof encoding === 'string')
269     encoding = encoding.toLowerCase();
270   if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64',
271 'ucs2', 'ucs-2','utf16le', 'utf-16le', 'raw']
272 .indexOf((encoding + '').toLowerCase()) > -1))
273     throw new TypeError('Unknown encoding: ' + encoding);
274   this._writableState.defaultEncoding = encoding;
275 };
276
277 function decodeChunk(state, chunk, encoding) {
278   if (!state.objectMode &&
279       state.decodeStrings !== false &&
280       typeof chunk === 'string') {
281     chunk = new Buffer(chunk, encoding);
282   }
283   return chunk;
284 }
285
286 // if we're already writing something, then just put this
287 // in the queue, and wait our turn.  Otherwise, call _write
288 // If we return false, then we need a drain event, so set that flag.
289 function writeOrBuffer(stream, state, chunk, encoding, cb) {
290   chunk = decodeChunk(state, chunk, encoding);
291
292   if (Buffer.isBuffer(chunk))
293     encoding = 'buffer';
294   var len = state.objectMode ? 1 : chunk.length;
295
296   state.length += len;
297
298   var ret = state.length < state.highWaterMark;
299   // we must ensure that previous needDrain will not be reset to false.
300   if (!ret)
301     state.needDrain = true;
302
303   if (state.writing || state.corked) {
304     var last = state.lastBufferedRequest;
305     state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
306     if (last) {
307       last.next = state.lastBufferedRequest;
308     } else {
309       state.bufferedRequest = state.lastBufferedRequest;
310     }
311   } else {
312     doWrite(stream, state, false, len, chunk, encoding, cb);
313   }
314
315   return ret;
316 }
317
318 function doWrite(stream, state, writev, len, chunk, encoding, cb) {
319   state.writelen = len;
320   state.writecb = cb;
321   state.writing = true;
322   state.sync = true;
323   if (writev)
324     stream._writev(chunk, state.onwrite);
325   else
326     stream._write(chunk, encoding, state.onwrite);
327   state.sync = false;
328 }
329
330 function onwriteError(stream, state, sync, er, cb) {
331   --state.pendingcb;
332   if (sync)
333     processNextTick(cb, er);
334   else
335     cb(er);
336
337   stream._writableState.errorEmitted = true;
338   stream.emit('error', er);
339 }
340
341 function onwriteStateUpdate(state) {
342   state.writing = false;
343   state.writecb = null;
344   state.length -= state.writelen;
345   state.writelen = 0;
346 }
347
348 function onwrite(stream, er) {
349   var state = stream._writableState;
350   var sync = state.sync;
351   var cb = state.writecb;
352
353   onwriteStateUpdate(state);
354
355   if (er)
356     onwriteError(stream, state, sync, er, cb);
357   else {
358     // Check if we're actually ready to finish, but don't emit yet
359     var finished = needFinish(state);
360
361     if (!finished &&
362         !state.corked &&
363         !state.bufferProcessing &&
364         state.bufferedRequest) {
365       clearBuffer(stream, state);
366     }
367
368     if (sync) {
369       processNextTick(afterWrite, stream, state, finished, cb);
370     } else {
371       afterWrite(stream, state, finished, cb);
372     }
373   }
374 }
375
376 function afterWrite(stream, state, finished, cb) {
377   if (!finished)
378     onwriteDrain(stream, state);
379   state.pendingcb--;
380   cb();
381   finishMaybe(stream, state);
382 }
383
384 // Must force callback to be called on nextTick, so that we don't
385 // emit 'drain' before the write() consumer gets the 'false' return
386 // value, and has a chance to attach a 'drain' listener.
387 function onwriteDrain(stream, state) {
388   if (state.length === 0 && state.needDrain) {
389     state.needDrain = false;
390     stream.emit('drain');
391   }
392 }
393
394
395 // if there's something in the buffer waiting, then process it
396 function clearBuffer(stream, state) {
397   state.bufferProcessing = true;
398   var entry = state.bufferedRequest;
399
400   if (stream._writev && entry && entry.next) {
401     // Fast case, write everything using _writev()
402     var buffer = [];
403     var cbs = [];
404     while (entry) {
405       cbs.push(entry.callback);
406       buffer.push(entry);
407       entry = entry.next;
408     }
409
410     // count the one we are adding, as well.
411     // TODO(isaacs) clean this up
412     state.pendingcb++;
413     state.lastBufferedRequest = null;
414     doWrite(stream, state, true, state.length, buffer, '', function(err) {
415       for (var i = 0; i < cbs.length; i++) {
416         state.pendingcb--;
417         cbs[i](err);
418       }
419     });
420
421     // Clear buffer
422   } else {
423     // Slow case, write chunks one-by-one
424     while (entry) {
425       var chunk = entry.chunk;
426       var encoding = entry.encoding;
427       var cb = entry.callback;
428       var len = state.objectMode ? 1 : chunk.length;
429
430       doWrite(stream, state, false, len, chunk, encoding, cb);
431       entry = entry.next;
432       // if we didn't call the onwrite immediately, then
433       // it means that we need to wait until it does.
434       // also, that means that the chunk and cb are currently
435       // being processed, so move the buffer counter past them.
436       if (state.writing) {
437         break;
438       }
439     }
440
441     if (entry === null)
442       state.lastBufferedRequest = null;
443   }
444   state.bufferedRequest = entry;
445   state.bufferProcessing = false;
446 }
447
448 Writable.prototype._write = function(chunk, encoding, cb) {
449   cb(new Error('not implemented'));
450 };
451
452 Writable.prototype._writev = null;
453
454 Writable.prototype.end = function(chunk, encoding, cb) {
455   var state = this._writableState;
456
457   if (typeof chunk === 'function') {
458     cb = chunk;
459     chunk = null;
460     encoding = null;
461   } else if (typeof encoding === 'function') {
462     cb = encoding;
463     encoding = null;
464   }
465
466   if (chunk !== null && chunk !== undefined)
467     this.write(chunk, encoding);
468
469   // .end() fully uncorks
470   if (state.corked) {
471     state.corked = 1;
472     this.uncork();
473   }
474
475   // ignore unnecessary end() calls.
476   if (!state.ending && !state.finished)
477     endWritable(this, state, cb);
478 };
479
480
481 function needFinish(state) {
482   return (state.ending &&
483           state.length === 0 &&
484           state.bufferedRequest === null &&
485           !state.finished &&
486           !state.writing);
487 }
488
489 function prefinish(stream, state) {
490   if (!state.prefinished) {
491     state.prefinished = true;
492     stream.emit('prefinish');
493   }
494 }
495
496 function finishMaybe(stream, state) {
497   var need = needFinish(state);
498   if (need) {
499     if (state.pendingcb === 0) {
500       prefinish(stream, state);
501       state.finished = true;
502       stream.emit('finish');
503     } else {
504       prefinish(stream, state);
505     }
506   }
507   return need;
508 }
509
510 function endWritable(stream, state, cb) {
511   state.ending = true;
512   finishMaybe(stream, state);
513   if (cb) {
514     if (state.finished)
515       processNextTick(cb);
516     else
517       stream.once('finish', cb);
518   }
519   state.ended = true;
520 }