UNPKG

fast-extract

Version:

Extract contents from various archive types (tar, tar.bz2, tar.gz, tar.xz, tgz, zip)

1,320 lines (1,292 loc) 109 kB
/* COMPATIBILITY POLYFILLS */ var major = +process.versions.node.split(".")[0]; var Buffer = require('safe-buffer').Buffer; var BufferComparePolyfill = require("./buffer-compare.cjs"); var BufferCompare = major > 4 ? function (source) { return source.compare.apply(source, Array.prototype.slice.call(arguments, 1)); } : function (_source) { return BufferComparePolyfill.apply(null, Array.prototype.slice.call(arguments)); } var MathTrunc = Math.trunc || function (val) { return val < 0 ? Math.ceil(val) : Math.floor(val); }; /* COMPATIBILITY POLYFILLS */ var require$$0 = require('stream'); var require$$2 = require('events'); var require$$0$1 = require('buffer'); var require$$1 = require('util'); var require$$11 = require('string_decoder'); var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs(x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var pumpify = { exports: {} }; var once = { exports: {} }; var wrappy_1; var hasRequiredWrappy; function requireWrappy() { if (hasRequiredWrappy) return wrappy_1; hasRequiredWrappy = 1; // Returns a wrapper function that returns a wrapped callback // The wrapper function should do some stuff, and return a // presumably different callback function. // This makes sure that own properties are retained, so that // decorations and such are not lost along the way. wrappy_1 = wrappy; function wrappy(fn, cb) { if (fn && cb) return wrappy(fn)(cb); if (typeof fn !== 'function') throw new TypeError('need wrapper function'); Object.keys(fn).forEach(function(k) { wrapper[k] = fn[k]; }); return wrapper; function wrapper() { var args = new Array(arguments.length); for(var i = 0; i < args.length; i++){ args[i] = arguments[i]; } var ret = fn.apply(this, args); var _$cb = args[args.length - 1]; if (typeof ret === 'function' && ret !== _$cb) { Object.keys(_$cb).forEach(function(k) { ret[k] = _$cb[k]; }); } return ret; } } return wrappy_1; } var hasRequiredOnce; function requireOnce() { if (hasRequiredOnce) return once.exports; hasRequiredOnce = 1; var wrappy = requireWrappy(); once.exports = wrappy(once$1); once.exports.strict = wrappy(onceStrict); once$1.proto = once$1(function() { Object.defineProperty(Function.prototype, 'once', { value: function value() { return once$1(this); }, configurable: true }); Object.defineProperty(Function.prototype, 'onceStrict', { value: function value() { return onceStrict(this); }, configurable: true }); }); function once$1(fn) { var f = function f1() { if (f.called) return f.value; f.called = true; return f.value = fn.apply(this, arguments); }; f.called = false; return f; } function onceStrict(fn) { var f = function f1() { if (f.called) throw new Error(f.onceError); f.called = true; return f.value = fn.apply(this, arguments); }; var name = fn.name || 'Function wrapped with `once`'; f.onceError = name + " shouldn't be called more than once"; f.called = false; return f; } return once.exports; } var endOfStream; var hasRequiredEndOfStream; function requireEndOfStream() { if (hasRequiredEndOfStream) return endOfStream; hasRequiredEndOfStream = 1; var once = requireOnce(); var noop = function noop() {}; var qnt = commonjsGlobal.Bare ? queueMicrotask : process.nextTick.bind(process); var isRequest = function isRequest(stream) { return stream.setHeader && typeof stream.abort === 'function'; }; var isChildProcess = function isChildProcess(stream) { return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3; }; var eos = function eos1(stream, opts, callback) { if (typeof opts === 'function') return eos(stream, null, opts); if (!opts) opts = {}; callback = once(callback || noop); var ws = stream._writableState; var rs = stream._readableState; var readable = opts.readable || opts.readable !== false && stream.readable; var writable = opts.writable || opts.writable !== false && stream.writable; var cancelled = false; var onlegacyfinish = function onlegacyfinish() { if (!stream.writable) onfinish(); }; var onfinish = function onfinish() { writable = false; if (!readable) callback.call(stream); }; var onend = function onend() { readable = false; if (!writable) callback.call(stream); }; var onexit = function onexit(exitCode) { callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); }; var onerror = function onerror(err) { callback.call(stream, err); }; var onclose = function onclose() { qnt(onclosenexttick); }; var onclosenexttick = function onclosenexttick() { if (cancelled) return; if (readable && !(rs && rs.ended && !rs.destroyed)) return callback.call(stream, new Error('premature close')); if (writable && !(ws && ws.ended && !ws.destroyed)) return callback.call(stream, new Error('premature close')); }; var onrequest = function onrequest() { stream.req.on('finish', onfinish); }; if (isRequest(stream)) { stream.on('complete', onfinish); stream.on('abort', onclose); if (stream.req) onrequest(); else stream.on('request', onrequest); } else if (writable && !ws) { stream.on('end', onlegacyfinish); stream.on('close', onlegacyfinish); } if (isChildProcess(stream)) stream.on('exit', onexit); stream.on('end', onend); stream.on('finish', onfinish); if (opts.error !== false) stream.on('error', onerror); stream.on('close', onclose); return function() { cancelled = true; stream.removeListener('complete', onfinish); stream.removeListener('abort', onclose); stream.removeListener('request', onrequest); if (stream.req) stream.req.removeListener('finish', onfinish); stream.removeListener('end', onlegacyfinish); stream.removeListener('close', onlegacyfinish); stream.removeListener('finish', onfinish); stream.removeListener('exit', onexit); stream.removeListener('end', onend); stream.removeListener('error', onerror); stream.removeListener('close', onclose); }; }; endOfStream = eos; return endOfStream; } function _instanceof$9(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } var pump_1; var hasRequiredPump; function requirePump() { if (hasRequiredPump) return pump_1; hasRequiredPump = 1; var once = requireOnce(); var eos = requireEndOfStream(); var fs; try { fs = require('fs'); // we only need fs to get the ReadStream and WriteStream prototypes } catch (e) {} var noop = function noop() {}; var ancient = typeof process === 'undefined' ? false : /^v?\.0/.test(process.version); var isFn = function isFn(fn) { return typeof fn === 'function'; }; var isFS = function isFS(stream) { if (!ancient) return false // newer node version do not need to care about fs is a special way ; if (!fs) return false // browser ; return (_instanceof$9(stream, fs.ReadStream || noop) || _instanceof$9(stream, fs.WriteStream || noop)) && isFn(stream.close); }; var isRequest = function isRequest(stream) { return stream.setHeader && isFn(stream.abort); }; var destroyer = function destroyer(stream, reading, writing, callback) { callback = once(callback); var closed = false; stream.on('close', function() { closed = true; }); eos(stream, { readable: reading, writable: writing }, function(err) { if (err) return callback(err); closed = true; callback(); }); var destroyed = false; return function(err) { if (closed) return; if (destroyed) return; destroyed = true; if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks ; if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want ; if (isFn(stream.destroy)) return stream.destroy(); callback(err || new Error('stream was destroyed')); }; }; var call = function call(fn) { fn(); }; var pipe = function pipe(from, to) { return from.pipe(to); }; var pump = function pump() { var streams = Array.prototype.slice.call(arguments); var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop; if (Array.isArray(streams[0])) streams = streams[0]; if (streams.length < 2) throw new Error('pump requires two streams per minimum'); var error; var destroys = streams.map(function(stream, i) { var reading = i < streams.length - 1; var writing = i > 0; return destroyer(stream, reading, writing, function(err) { if (!error) error = err; if (err) destroys.forEach(call); if (reading) return; destroys.forEach(call); callback(error); }); }); return streams.reduce(pipe); }; pump_1 = pump; return pump_1; } var inherits = { exports: {} }; var inherits_browser = { exports: {} }; var hasRequiredInherits_browser; function requireInherits_browser() { if (hasRequiredInherits_browser) return inherits_browser.exports; hasRequiredInherits_browser = 1; if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module inherits_browser.exports = function inherits(ctor, superCtor) { if (superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); } }; } else { // old school shim for old browsers inherits_browser.exports = function inherits(ctor, superCtor) { if (superCtor) { ctor.super_ = superCtor; var TempCtor = function TempCtor() {}; TempCtor.prototype = superCtor.prototype; ctor.prototype = new TempCtor(); ctor.prototype.constructor = ctor; } }; } return inherits_browser.exports; } var hasRequiredInherits; function requireInherits() { if (hasRequiredInherits) return inherits.exports; hasRequiredInherits = 1; try { var util = require('util'); /* istanbul ignore next */ if (typeof util.inherits !== 'function') throw ''; inherits.exports = util.inherits; } catch (e) { /* istanbul ignore next */ inherits.exports = requireInherits_browser(); } return inherits.exports; } var readable = { exports: {} }; var processNextickArgs = { exports: {} }; var hasRequiredProcessNextickArgs; function requireProcessNextickArgs() { if (hasRequiredProcessNextickArgs) return processNextickArgs.exports; hasRequiredProcessNextickArgs = 1; if (typeof process === 'undefined' || !process.version || process.version.indexOf('v0.') === 0 || process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { processNextickArgs.exports = { nextTick: nextTick }; } else { processNextickArgs.exports = process; } function nextTick(fn, arg1, arg2, arg3) { if (typeof fn !== 'function') { throw new TypeError('"callback" argument must be a function'); } var len = arguments.length; var args, i; switch(len){ case 0: case 1: return process.nextTick(fn); case 2: return process.nextTick(function afterTickOne() { fn.call(null, arg1); }); case 3: return process.nextTick(function afterTickTwo() { fn.call(null, arg1, arg2); }); case 4: return process.nextTick(function afterTickThree() { fn.call(null, arg1, arg2, arg3); }); default: args = new Array(len - 1); i = 0; while(i < args.length){ args[i++] = arguments[i]; } return process.nextTick(function afterTick() { fn.apply(null, args); }); } } return processNextickArgs.exports; } var isarray; var hasRequiredIsarray; function requireIsarray() { if (hasRequiredIsarray) return isarray; hasRequiredIsarray = 1; var toString = {}.toString; isarray = Array.isArray || function(arr) { return toString.call(arr) == '[object Array]'; }; return isarray; } var stream; var hasRequiredStream; function requireStream() { if (hasRequiredStream) return stream; hasRequiredStream = 1; stream = require$$0; return stream; } var safeBuffer = { exports: {} }; var hasRequiredSafeBuffer; function requireSafeBuffer() { if (hasRequiredSafeBuffer) return safeBuffer.exports; hasRequiredSafeBuffer = 1; (function(module, exports) { var buffer = require$$0$1; var Buffer = buffer.Buffer; // alternative to using Object.keys for old browsers function copyProps(src, dst) { for(var key in src){ dst[key] = src[key]; } } if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { module.exports = buffer; } else { // Copy properties from require('buffer') copyProps(buffer, exports); exports.Buffer = SafeBuffer; } function SafeBuffer(arg, encodingOrOffset, length) { return Buffer(arg, encodingOrOffset, length); } // Copy static methods from Buffer copyProps(Buffer, SafeBuffer); SafeBuffer.from = function(arg, encodingOrOffset, length) { if (typeof arg === 'number') { throw new TypeError('Argument must not be a number'); } return Buffer(arg, encodingOrOffset, length); }; SafeBuffer.alloc = function(size, fill, encoding) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number'); } var buf = Buffer(size); if (fill !== undefined) { if (typeof encoding === 'string') { buf.fill(fill, encoding); } else { buf.fill(fill); } } else { buf.fill(0); } return buf; }; SafeBuffer.allocUnsafe = function(size) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number'); } return Buffer(size); }; SafeBuffer.allocUnsafeSlow = function(size) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number'); } return buffer.SlowBuffer(size); }; })(safeBuffer, safeBuffer.exports); return safeBuffer.exports; } var util = {}; function _instanceof$8(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } function _type_of(obj) { "@swc/helpers - typeof"; return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } var hasRequiredUtil; function requireUtil() { if (hasRequiredUtil) return util; hasRequiredUtil = 1; // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // NOTE: These type checking functions intentionally don't use `instanceof` // because it is fragile and can be easily faked with `Object.create()`. function isArray(arg) { if (Array.isArray) { return Array.isArray(arg); } return objectToString(arg) === '[object Array]'; } util.isArray = isArray; function isBoolean(arg) { return typeof arg === 'boolean'; } util.isBoolean = isBoolean; function isNull(arg) { return arg === null; } util.isNull = isNull; function isNullOrUndefined(arg) { return arg == null; } util.isNullOrUndefined = isNullOrUndefined; function isNumber(arg) { return typeof arg === 'number'; } util.isNumber = isNumber; function isString(arg) { return typeof arg === 'string'; } util.isString = isString; function isSymbol(arg) { return (typeof arg === "undefined" ? "undefined" : _type_of(arg)) === 'symbol'; } util.isSymbol = isSymbol; function isUndefined(arg) { return arg === void 0; } util.isUndefined = isUndefined; function isRegExp(re) { return objectToString(re) === '[object RegExp]'; } util.isRegExp = isRegExp; function isObject(arg) { return (typeof arg === "undefined" ? "undefined" : _type_of(arg)) === 'object' && arg !== null; } util.isObject = isObject; function isDate(d) { return objectToString(d) === '[object Date]'; } util.isDate = isDate; function isError(e) { return objectToString(e) === '[object Error]' || _instanceof$8(e, Error); } util.isError = isError; function isFunction(arg) { return typeof arg === 'function'; } util.isFunction = isFunction; function isPrimitive(arg) { return arg === null || typeof arg === 'boolean' || typeof arg === 'number' || typeof arg === 'string' || (typeof arg === "undefined" ? "undefined" : _type_of(arg)) === 'symbol' || // ES6 symbol typeof arg === 'undefined'; } util.isPrimitive = isPrimitive; util.isBuffer = require$$0$1.Buffer.isBuffer; function objectToString(o) { return Object.prototype.toString.call(o); } return util; } var BufferList = { exports: {} }; function _instanceof$7(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } var hasRequiredBufferList; function requireBufferList() { if (hasRequiredBufferList) return BufferList.exports; hasRequiredBufferList = 1; (function(module) { function _classCallCheck(instance, Constructor) { if (!_instanceof$7(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Buffer = requireSafeBuffer().Buffer; var util = require$$1; function copyBuffer(src, target, offset) { src.copy(target, offset); } module.exports = function() { function BufferList() { _classCallCheck(this, BufferList); this.head = null; this.tail = null; this.length = 0; } BufferList.prototype.push = function push(v) { var entry = { data: v, next: null }; if (this.length > 0) this.tail.next = entry; else this.head = entry; this.tail = entry; ++this.length; }; BufferList.prototype.unshift = function unshift(v) { var entry = { data: v, next: this.head }; if (this.length === 0) this.tail = entry; this.head = entry; ++this.length; }; BufferList.prototype.shift = function shift() { if (this.length === 0) return; var ret = this.head.data; if (this.length === 1) this.head = this.tail = null; else this.head = this.head.next; --this.length; return ret; }; BufferList.prototype.clear = function clear() { this.head = this.tail = null; this.length = 0; }; BufferList.prototype.join = function join(s) { if (this.length === 0) return ''; var p = this.head; var ret = '' + p.data; while(p = p.next){ ret += s + p.data; } return ret; }; BufferList.prototype.concat = function concat(n) { if (this.length === 0) return Buffer.alloc(0); var ret = Buffer.allocUnsafe(n >>> 0); var p = this.head; var i = 0; while(p){ copyBuffer(p.data, ret, i); i += p.data.length; p = p.next; } return ret; }; return BufferList; }(); if (util && util.inspect && util.inspect.custom) { module.exports.prototype[util.inspect.custom] = function() { var obj = util.inspect({ length: this.length }); return this.constructor.name + ' ' + obj; }; } })(BufferList); return BufferList.exports; } var destroy_1; var hasRequiredDestroy; function requireDestroy() { if (hasRequiredDestroy) return destroy_1; hasRequiredDestroy = 1; /*<replacement>*/ var pna = requireProcessNextickArgs(); /*</replacement>*/ // undocumented cb() API, needed for core, not for public API function destroy(err, cb) { var _this = this; var readableDestroyed = this._readableState && this._readableState.destroyed; var writableDestroyed = this._writableState && this._writableState.destroyed; if (readableDestroyed || writableDestroyed) { if (cb) { cb(err); } else if (err) { if (!this._writableState) { pna.nextTick(emitErrorNT, this, err); } else if (!this._writableState.errorEmitted) { this._writableState.errorEmitted = true; pna.nextTick(emitErrorNT, this, err); } } return this; } // we set destroyed to true before firing error callbacks in order // to make it re-entrance safe in case destroy() is called within callbacks if (this._readableState) { this._readableState.destroyed = true; } // if this is a duplex stream mark the writable part as destroyed as well if (this._writableState) { this._writableState.destroyed = true; } this._destroy(err || null, function(err) { if (!cb && err) { if (!_this._writableState) { pna.nextTick(emitErrorNT, _this, err); } else if (!_this._writableState.errorEmitted) { _this._writableState.errorEmitted = true; pna.nextTick(emitErrorNT, _this, err); } } else if (cb) { cb(err); } }); return this; } function undestroy() { if (this._readableState) { this._readableState.destroyed = false; this._readableState.reading = false; this._readableState.ended = false; this._readableState.endEmitted = false; } if (this._writableState) { this._writableState.destroyed = false; this._writableState.ended = false; this._writableState.ending = false; this._writableState.finalCalled = false; this._writableState.prefinished = false; this._writableState.finished = false; this._writableState.errorEmitted = false; } } function emitErrorNT(self, err) { self.emit('error', err); } destroy_1 = { destroy: destroy, undestroy: undestroy }; return destroy_1; } var node; var hasRequiredNode; function requireNode() { if (hasRequiredNode) return node; hasRequiredNode = 1; /** * For Node.js, simply re-export the core `util.deprecate` function. */ node = require$$1.deprecate; return node; } function _instanceof$6(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } var _stream_writable; var hasRequired_stream_writable; function require_stream_writable() { if (hasRequired_stream_writable) return _stream_writable; hasRequired_stream_writable = 1; /*<replacement>*/ var pna = requireProcessNextickArgs(); /*</replacement>*/ _stream_writable = Writable; // It seems a linked list but it is not // there will be only 2 of these for each stream function CorkedRequest(state) { var _this = this; this.next = null; this.entry = null; this.finish = function() { onCorkedFinish(_this, state); }; } /* </replacement> */ /*<replacement>*/ var asyncWrite = !process.browser && [ 'v0.10', 'v0.9.' ].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick; /*</replacement>*/ /*<replacement>*/ var Duplex; /*</replacement>*/ Writable.WritableState = WritableState; /*<replacement>*/ var util = Object.create(requireUtil()); util.inherits = requireInherits(); /*</replacement>*/ /*<replacement>*/ var internalUtil = { deprecate: requireNode() }; /*</replacement>*/ /*<replacement>*/ var Stream = requireStream(); /*</replacement>*/ /*<replacement>*/ var Buffer = requireSafeBuffer().Buffer; var OurUint8Array = (typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function() {}; function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } function _isUint8Array(obj) { return Buffer.isBuffer(obj) || _instanceof$6(obj, OurUint8Array); } /*</replacement>*/ var destroyImpl = requireDestroy(); util.inherits(Writable, Stream); function nop() {} function WritableState(options, stream) { Duplex = Duplex || require_stream_duplex(); options = options || {}; // Duplex streams are both readable and writable, but share // the same options object. // However, some cases require setting options to different // values for the readable and the writable sides of the duplex stream. // These options can be provided separately as readableXXX and writableXXX. var isDuplex = _instanceof$6(stream, Duplex); // object stream flag to indicate whether or not this stream // contains buffers or objects. this.objectMode = !!options.objectMode; if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false // Note: 0 is a valid value, means that we always return false if // the entire buffer is not flushed immediately on write() var hwm = options.highWaterMark; var writableHwm = options.writableHighWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; if (hwm || hwm === 0) this.highWaterMark = hwm; else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm; else this.highWaterMark = defaultHwm; // cast to ints. this.highWaterMark = Math.floor(this.highWaterMark); // if _final has been called this.finalCalled = false; // drain event flag. this.needDrain = false; // at the start of calling end() this.ending = false; // when end() has been called, and returned this.ended = false; // when 'finish' is emitted this.finished = false; // has it been destroyed this.destroyed = false; // should we decode strings into buffers before passing to _write? // this is here so that some node-core streams can optimize string // handling at a lower level. var noDecode = options.decodeStrings === false; this.decodeStrings = !noDecode; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; // not an actual buffer we keep track of, but a measurement // of how much we're waiting to get pushed to some underlying // socket or file. this.length = 0; // a flag to see when we're in the middle of a write. this.writing = false; // when true all writes will be buffered until .uncork() call this.corked = 0; // a flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. this.sync = true; // a flag to know if we're processing previously buffered items, which // may call the _write() callback in the same tick, so that we don't // end up in an overlapped onwrite situation. this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb) this.onwrite = function(er) { onwrite(stream, er); }; // the callback that the user supplies to write(chunk,encoding,cb) this.writecb = null; // the amount that is being written when _write is called. this.writelen = 0; this.bufferedRequest = null; this.lastBufferedRequest = null; // number of pending user-supplied write callbacks // this must be 0 before 'finish' can be emitted this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs // This is relevant for synchronous Transform streams this.prefinished = false; // True if the error was already emitted and should not be thrown again this.errorEmitted = false; // count buffered requests this.bufferedRequestCount = 0; // allocate the first CorkedRequest, there is always // one allocated and free to use, and we maintain at most two this.corkedRequestsFree = new CorkedRequest(this); } WritableState.prototype.getBuffer = function getBuffer() { var current = this.bufferedRequest; var out = []; while(current){ out.push(current); current = current.next; } return out; }; (function() { try { Object.defineProperty(WritableState.prototype, 'buffer', { get: internalUtil.deprecate(function() { return this.getBuffer(); }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') }); } catch (_) {} })(); // Test _writableState for inheritance to account for Duplex streams, // whose prototype chain only points to Readable. var realHasInstance; if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { realHasInstance = Function.prototype[Symbol.hasInstance]; Object.defineProperty(Writable, Symbol.hasInstance, { value: function value(object) { if (realHasInstance.call(this, object)) return true; if (this !== Writable) return false; return object && _instanceof$6(object._writableState, WritableState); } }); } else { realHasInstance = function realHasInstance(object) { return _instanceof$6(object, this); }; } function Writable(options) { Duplex = Duplex || require_stream_duplex(); // Writable ctor is applied to Duplexes, too. // `realHasInstance` is necessary because using plain `instanceof` // would return false, as no `_writableState` property is attached. // Trying to use the custom `instanceof` for Writable here will also break the // Node.js LazyTransform implementation, which has a non-trivial getter for // `_writableState` that would lead to infinite recursion. if (!realHasInstance.call(Writable, this) && !_instanceof$6(this, Duplex)) { return new Writable(options); } this._writableState = new WritableState(options, this); // legacy. this.writable = true; if (options) { if (typeof options.write === 'function') this._write = options.write; if (typeof options.writev === 'function') this._writev = options.writev; if (typeof options.destroy === 'function') this._destroy = options.destroy; if (typeof options.final === 'function') this._final = options.final; } Stream.call(this); } // Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function() { this.emit('error', new Error('Cannot pipe, not readable')); }; function writeAfterEnd(stream, cb) { var er = new Error('write after end'); // TODO: defer error events consistently everywhere, not just the cb stream.emit('error', er); pna.nextTick(cb, er); } // Checks that a user-supplied chunk is valid, especially for the particular // mode the stream is in. Currently this means that `null` is never accepted // and undefined/non-string values are only allowed in object mode. function validChunk(stream, state, chunk, cb) { var valid = true; var er = false; if (chunk === null) { er = new TypeError('May not write null values to stream'); } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { er = new TypeError('Invalid non-string/buffer chunk'); } if (er) { stream.emit('error', er); pna.nextTick(cb, er); valid = false; } return valid; } Writable.prototype.write = function(chunk, encoding, cb) { var state = this._writableState; var ret = false; var isBuf = !state.objectMode && _isUint8Array(chunk); if (isBuf && !Buffer.isBuffer(chunk)) { chunk = _uint8ArrayToBuffer(chunk); } if (typeof encoding === 'function') { cb = encoding; encoding = null; } if (isBuf) encoding = 'buffer'; else if (!encoding) encoding = state.defaultEncoding; if (typeof cb !== 'function') cb = nop; if (state.ended) writeAfterEnd(this, cb); else if (isBuf || validChunk(this, state, chunk, cb)) { state.pendingcb++; ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); } return ret; }; Writable.prototype.cork = function() { var state = this._writableState; state.corked++; }; Writable.prototype.uncork = function() { var state = this._writableState; if (state.corked) { state.corked--; if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); } }; Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { // node::ParseEncoding() requires lower case. if (typeof encoding === 'string') encoding = encoding.toLowerCase(); 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); this._writableState.defaultEncoding = encoding; return this; }; function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { chunk = Buffer.from(chunk, encoding); } return chunk; } Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._writableState.highWaterMark; } }); // if we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { if (!isBuf) { var newChunk = decodeChunk(state, chunk, encoding); if (chunk !== newChunk) { isBuf = true; encoding = 'buffer'; chunk = newChunk; } } var len = state.objectMode ? 1 : chunk.length; state.length += len; var ret = state.length < state.highWaterMark; // we must ensure that previous needDrain will not be reset to false. if (!ret) state.needDrain = true; if (state.writing || state.corked) { var last = state.lastBufferedRequest; state.lastBufferedRequest = { chunk: chunk, encoding: encoding, isBuf: isBuf, callback: cb, next: null }; if (last) { last.next = state.lastBufferedRequest; } else { state.bufferedRequest = state.lastBufferedRequest; } state.bufferedRequestCount += 1; } else { doWrite(stream, state, false, len, chunk, encoding, cb); } return ret; } function doWrite(stream, state, writev, len, chunk, encoding, cb) { state.writelen = len; state.writecb = cb; state.writing = true; state.sync = true; if (writev) stream._writev(chunk, state.onwrite); else stream._write(chunk, encoding, state.onwrite); state.sync = false; } function onwriteError(stream, state, sync, er, cb) { --state.pendingcb; if (sync) { // defer the callback if we are being called synchronously // to avoid piling up things on the stack pna.nextTick(cb, er); // this can emit finish, and it will always happen // after error pna.nextTick(finishMaybe, stream, state); stream._writableState.errorEmitted = true; stream.emit('error', er); } else { // the caller expect this to happen before if // it is async cb(er); stream._writableState.errorEmitted = true; stream.emit('error', er); // this can emit finish, but finish must // always follow error finishMaybe(stream, state); } } function onwriteStateUpdate(state) { state.writing = false; state.writecb = null; state.length -= state.writelen; state.writelen = 0; } function onwrite(stream, er) { var state = stream._writableState; var sync = state.sync; var cb = state.writecb; onwriteStateUpdate(state); if (er) onwriteError(stream, state, sync, er, cb); else { // Check if we're actually ready to finish, but don't emit yet var finished = needFinish(state); if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { clearBuffer(stream, state); } if (sync) { /*<replacement>*/ asyncWrite(afterWrite, stream, state, finished, cb); /*</replacement>*/ } else { afterWrite(stream, state, finished, cb); } } } function afterWrite(stream, state, finished, cb) { if (!finished) onwriteDrain(stream, state); state.pendingcb--; cb(); finishMaybe(stream, state); } // Must force callback to be called on nextTick, so that we don't // emit 'drain' before the write() consumer gets the 'false' return // value, and has a chance to attach a 'drain' listener. function onwriteDrain(stream, state) { if (state.length === 0 && state.needDrain) { state.needDrain = false; stream.emit('drain'); } } // if there's something in the buffer waiting, then process it function clearBuffer(stream, state) { state.bufferProcessing = true; var entry = state.bufferedRequest; if (stream._writev && entry && entry.next) { // Fast case, write everything using _writev() var l = state.bufferedRequestCount; var buffer = new Array(l); var holder = state.corkedRequestsFree; holder.entry = entry; var count = 0; var allBuffers = true; while(entry){ buffer[count] = entry; if (!entry.isBuf) allBuffers = false; entry = entry.next; count += 1; } buffer.allBuffers = allBuffers; doWrite(stream, state, true, state.length, buffer, '', holder.finish); // doWrite is almost always async, defer these to save a bit of time // as the hot path ends with doWrite state.pendingcb++; state.lastBufferedRequest = null; if (holder.next) { state.corkedRequestsFree = holder.next; holder.next = null; } else { state.corkedRequestsFree = new CorkedRequest(state); } state.bufferedRequestCount = 0; } else { // Slow case, write chunks one-by-one while(entry){ var chunk = entry.chunk; var encoding = entry.encoding; var cb = entry.callback; var len = state.objectMode ? 1 : chunk.length; doWrite(stream, state, false, len, chunk, encoding, cb); entry = entry.next; state.bufferedRequestCount--; // if we didn't call the onwrite immediately, then // it means that we need to wait until it does. // also, that means that the chunk and cb are currently // being processed, so move the buffer counter past them. if (state.writing) { break; } } if (entry === null) state.lastBufferedRequest = null; } state.bufferedRequest = entry; state.bufferProcessing = false; } Writable.prototype._write = function(chunk, encoding, cb) { cb(new Error('_write() is not implemented')); }; Writable.prototype._writev = null; Writable.prototype.end = function(chunk, encoding, cb) { var state = this._writableState; if (typeof chunk === 'function') { cb = chunk; chunk = null; encoding = null; } else if (typeof encoding === 'function') { cb = encoding; encoding = null; } if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); // .end() fully uncorks if (state.corked) { state.corked = 1; this.uncork(); } // ignore unnecessary end() calls. if (!state.ending) endWritable(this, state, cb); }; function needFinish(state) { return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; } function callFinal(stream, state) { stream._final(function(err) { state.pendingcb--; if (err) { stream.emit('error', err); } state.prefinished = true; stream.emit('prefinish'); finishMaybe(stream, state); }); } function prefinish(stream, state) { if (!state.prefinished && !state.finalCalled) { if (typeof stream._final === 'function') { state.pendingcb++; state.finalCalled = true; pna.nextTick(callFinal, stream, state); } else { state.prefinished = true; stream.emit('prefinish'); } } } function finishMaybe(stream, state) { var need = needFinish(state); if (need) { prefinish(stream, state); if (state.pendingcb === 0) { state.finished = true; stream.emit('finish'); } } return need; } function endWritable(stream, state, cb) { state.ending = true; finishMaybe(stream, state); if (cb) { if (state.finished) pna.nextTick(cb); else stream.once('finish', cb); } state.ended = true; stream.writable = false; } function onCorkedFinish(corkReq, state, err) { var entry = corkReq.entry; corkReq.entry = null; while(entry){ var cb = entry.callback; state.pendingcb--; cb(err); entry = entry.next; } // reuse the free corkReq. state.corkedRequestsFree.next = corkReq; } Object.defineProperty(Writable.prototype, 'destroyed', { get: function get() { if (this._writableState === undefined) { return false; } return this._writableState.destroyed; }, set: function set(value) { // we ignore the value if the stream // has not been initialized yet if (!this._writableState) { return; } // backward compatibility, the user is explicitly // managing destroyed this._writableState.destroyed = value; } }); Writable.prototype.destroy = destroyImpl.destroy; Writable.prototype._undestroy = destroyImpl.undestroy; Writable.prototype._destro