{“ast”:null,“code”:“// Copyright Joyent, Inc. and other Node contributors.n//n// Permission is hereby granted, free of charge, to any person obtaining an// copy of this software and associated documentation files (then// "Software"), to deal in the Software without restriction, includingn// without limitation the rights to use, copy, modify, merge, publish,n// distribute, sublicense, and/or sell copies of the Software, and to permitn// persons to whom the Software is furnished to do so, subject to then// following conditions:n//n// The above copyright notice and this permission notice shall be includedn// in all copies or substantial portions of the Software.n//n// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSn// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFn// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. INn// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT ORn// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THEn// USE OR OTHER DEALINGS IN THE SOFTWARE.n// a transform stream is a readable/writable stream where you don// something with the data. Sometimes it's called a "filter",n// but that's not a great name for it, since that implies a thing wheren// some bits pass through, and others are simply ignored. (That wouldn// be a valid example of a transform, of course.)n//n// While the output is causally related to the input, it's not an// necessarily symmetric or synchronous transformation. For example,n// a zlib stream might take multiple plain-text writes(), and thenn// emit a single compressed chunk some time in the future.n//n// Here's how this works:n//n// The Transform stream has all the aspects of the readable and writablen// stream classes. When you write(chunk), that calls _write(chunk,cb)n// internally, and returns false if there's a lot of pending writesn// buffered up. When you call read(), that calls _read(n) untiln// there's enough pending readable data buffered up.n//n// In a transform stream, the written data is placed in a buffer. Whenn// _read(n) is called, it transforms the queued up data, calling then// buffered _write cb's as it consumes chunks. If consuming a singlen// written chunk would result in multiple output chunks, then the firstn// outputted bit calls the readcb, and subsequent chunks just go inton// the read buffer, and will cause it to emit 'readable' if necessary.n//n// This way, back-pressure is actually determined by the reading side,n// since _read has to be called to start processing a new chunk. However,n// a pathological inflate type of transform can cause excessive bufferingn// here. For example, imagine a stream where every byte of input isn// interpreted as an integer from 0-255, and then results in that manyn// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result inn// 1kb of data being output. In this case, you could write a very smalln// amount of input, and end up with a very large amount of output. Inn// such a pathological inflating mechanism, there'd be no way to telln// the system to stop doing the transform. A single 4MB write couldn// cause the system to run out of memory.n//n// However, even in such a pathological case, only a single written chunkn// would be consumed, and then the rest would wait (un-transformed) untiln// the results of the previous transformed chunk were consumed.n'use strict';nnmodule.exports = Transform;nnvar Duplex = require('./_stream_duplex');n/*<replacement>*/nnnvar util = require('core-util-is');nnutil.inherits = require('inherits');n/*</replacement>*/nnutil.inherits(Transform, Duplex);nnfunction afterTransform(er, data) {n var ts = this._transformState;n ts.transforming = false;n var cb = ts.writecb;nn if (!cb) {n return this.emit('error', new Error('write callback called multiple times'));n }nn ts.writechunk = null;n ts.writecb = null;n if (data != null) // single equals check for both `null` and `undefined`n this.push(data);n cb(er);n var rs = this._readableState;n rs.reading = false;nn if (rs.needReadable || rs.length < rs.highWaterMark) {n this._read(rs.highWaterMark);n }n}nnfunction Transform(options) {n if (!(this instanceof Transform)) return new Transform(options);n Duplex.call(this, options);n this._transformState = {n afterTransform: afterTransform.bind(this),n needTransform: false,n transforming: false,n writecb: null,n writechunk: null,n writeencoding: nulln }; // start out asking for a readable event once data is transformed.nn this._readableState.needReadable = true; // we have implemented the _read method, and done the other thingsn // that Readable wants before the first _read call, so unset then // sync guard flag.nn this._readableState.sync = false;nn if (options) {n if (typeof options.transform === 'function') this._transform = options.transform;n if (typeof options.flush === 'function') this._flush = options.flush;n } // When the writable side finishes, then flush out anything remaining.nnn this.on('prefinish', prefinish);n}nnfunction prefinish() {n var _this = this;nn if (typeof this._flush === 'function') {n this._flush(function (er, data) {n done(_this, er, data);n });n } else {n done(this, null, null);n }n}nnTransform.prototype.push = function (chunk, encoding) {n this._transformState.needTransform = false;n return Duplex.prototype.push.call(this, chunk, encoding);n}; // This is the part where you do stuff!n// override this function in implementation classes.n// 'chunk' is an input chunk.n//n// Call `push(newChunk)` to pass along transformed outputn// to the readable side. You may call 'push' zero or more times.n//n// Call `cb(err)` when you are done with this chunk. If you passn// an error, then that'll put the hurt on the whole operation. If youn// never call cb(), then you'll never get another chunk.nnnTransform.prototype._transform = function (chunk, encoding, cb) {n throw new Error('_transform() is not implemented');n};nnTransform.prototype._write = function (chunk, encoding, cb) {n var ts = this._transformState;n ts.writecb = cb;n ts.writechunk = chunk;n ts.writeencoding = encoding;nn if (!ts.transforming) {n var rs = this._readableState;n if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);n }n}; // Doesn't matter what the args are here.n// _transform does all the work.n// That we got here means that the readable side wants more data.nnnTransform.prototype._read = function (n) {n var ts = this._transformState;nn if (ts.writechunk !== null && ts.writecb && !ts.transforming) {n ts.transforming = true;nn this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);n } else {n // mark that we need a transform, so that any data that comes inn // will get processed, now that we've asked for it.n ts.needTransform = true;n }n};nnTransform.prototype._destroy = function (err, cb) {n var _this2 = this;nn Duplex.prototype._destroy.call(this, err, function (err2) {n cb(err2);nn _this2.emit('close');n });n};nnfunction done(stream, er, data) {n if (er) return stream.emit('error', er);n if (data != null) // single equals check for both `null` and `undefined`n stream.push(data); // if there's nothing in the write buffer, then that meansn // that nothing more will ever be providednn if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0');n if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming');n return stream.push(null);n}”,“map”:null,“metadata”:{},“sourceType”:“module”}