summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/pacote/node_modules/tar-stream/extract.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/pacote/node_modules/tar-stream/extract.js')
-rw-r--r--deps/npm/node_modules/pacote/node_modules/tar-stream/extract.js246
1 files changed, 246 insertions, 0 deletions
diff --git a/deps/npm/node_modules/pacote/node_modules/tar-stream/extract.js b/deps/npm/node_modules/pacote/node_modules/tar-stream/extract.js
new file mode 100644
index 0000000000..8be2a472c6
--- /dev/null
+++ b/deps/npm/node_modules/pacote/node_modules/tar-stream/extract.js
@@ -0,0 +1,246 @@
+var util = require('util')
+var bl = require('bl')
+var xtend = require('xtend')
+var headers = require('./headers')
+
+var Writable = require('readable-stream').Writable
+var PassThrough = require('readable-stream').PassThrough
+
+var noop = function () {}
+
+var overflow = function (size) {
+ size &= 511
+ return size && 512 - size
+}
+
+var emptyStream = function (self, offset) {
+ var s = new Source(self, offset)
+ s.end()
+ return s
+}
+
+var mixinPax = function (header, pax) {
+ if (pax.path) header.name = pax.path
+ if (pax.linkpath) header.linkname = pax.linkpath
+ header.pax = pax
+ return header
+}
+
+var Source = function (self, offset) {
+ this._parent = self
+ this.offset = offset
+ PassThrough.call(this)
+}
+
+util.inherits(Source, PassThrough)
+
+Source.prototype.destroy = function (err) {
+ this._parent.destroy(err)
+}
+
+var Extract = function (opts) {
+ if (!(this instanceof Extract)) return new Extract(opts)
+ Writable.call(this, opts)
+
+ this._offset = 0
+ this._buffer = bl()
+ this._missing = 0
+ this._onparse = noop
+ this._header = null
+ this._stream = null
+ this._overflow = null
+ this._cb = null
+ this._locked = false
+ this._destroyed = false
+ this._pax = null
+ this._paxGlobal = null
+ this._gnuLongPath = null
+ this._gnuLongLinkPath = null
+
+ var self = this
+ var b = self._buffer
+
+ var oncontinue = function () {
+ self._continue()
+ }
+
+ var onunlock = function (err) {
+ self._locked = false
+ if (err) return self.destroy(err)
+ if (!self._stream) oncontinue()
+ }
+
+ var onstreamend = function () {
+ self._stream = null
+ var drain = overflow(self._header.size)
+ if (drain) self._parse(drain, ondrain)
+ else self._parse(512, onheader)
+ if (!self._locked) oncontinue()
+ }
+
+ var ondrain = function () {
+ self._buffer.consume(overflow(self._header.size))
+ self._parse(512, onheader)
+ oncontinue()
+ }
+
+ var onpaxglobalheader = function () {
+ var size = self._header.size
+ self._paxGlobal = headers.decodePax(b.slice(0, size))
+ b.consume(size)
+ onstreamend()
+ }
+
+ var onpaxheader = function () {
+ var size = self._header.size
+ self._pax = headers.decodePax(b.slice(0, size))
+ if (self._paxGlobal) self._pax = xtend(self._paxGlobal, self._pax)
+ b.consume(size)
+ onstreamend()
+ }
+
+ var ongnulongpath = function () {
+ var size = self._header.size
+ this._gnuLongPath = headers.decodeLongPath(b.slice(0, size))
+ b.consume(size)
+ onstreamend()
+ }
+
+ var ongnulonglinkpath = function () {
+ var size = self._header.size
+ this._gnuLongLinkPath = headers.decodeLongPath(b.slice(0, size))
+ b.consume(size)
+ onstreamend()
+ }
+
+ var onheader = function () {
+ var offset = self._offset
+ var header
+ try {
+ header = self._header = headers.decode(b.slice(0, 512))
+ } catch (err) {
+ self.emit('error', err)
+ }
+ b.consume(512)
+
+ if (!header) {
+ self._parse(512, onheader)
+ oncontinue()
+ return
+ }
+ if (header.type === 'gnu-long-path') {
+ self._parse(header.size, ongnulongpath)
+ oncontinue()
+ return
+ }
+ if (header.type === 'gnu-long-link-path') {
+ self._parse(header.size, ongnulonglinkpath)
+ oncontinue()
+ return
+ }
+ if (header.type === 'pax-global-header') {
+ self._parse(header.size, onpaxglobalheader)
+ oncontinue()
+ return
+ }
+ if (header.type === 'pax-header') {
+ self._parse(header.size, onpaxheader)
+ oncontinue()
+ return
+ }
+
+ if (self._gnuLongPath) {
+ header.name = self._gnuLongPath
+ self._gnuLongPath = null
+ }
+
+ if (self._gnuLongLinkPath) {
+ header.linkname = self._gnuLongLinkPath
+ self._gnuLongLinkPath = null
+ }
+
+ if (self._pax) {
+ self._header = header = mixinPax(header, self._pax)
+ self._pax = null
+ }
+
+ self._locked = true
+
+ if (!header.size || header.type === 'directory') {
+ self._parse(512, onheader)
+ self.emit('entry', header, emptyStream(self, offset), onunlock)
+ return
+ }
+
+ self._stream = new Source(self, offset)
+
+ self.emit('entry', header, self._stream, onunlock)
+ self._parse(header.size, onstreamend)
+ oncontinue()
+ }
+
+ this._parse(512, onheader)
+}
+
+util.inherits(Extract, Writable)
+
+Extract.prototype.destroy = function (err) {
+ if (this._destroyed) return
+ this._destroyed = true
+
+ if (err) this.emit('error', err)
+ this.emit('close')
+ if (this._stream) this._stream.emit('close')
+}
+
+Extract.prototype._parse = function (size, onparse) {
+ if (this._destroyed) return
+ this._offset += size
+ this._missing = size
+ this._onparse = onparse
+}
+
+Extract.prototype._continue = function () {
+ if (this._destroyed) return
+ var cb = this._cb
+ this._cb = noop
+ if (this._overflow) this._write(this._overflow, undefined, cb)
+ else cb()
+}
+
+Extract.prototype._write = function (data, enc, cb) {
+ if (this._destroyed) return
+
+ var s = this._stream
+ var b = this._buffer
+ var missing = this._missing
+
+ // we do not reach end-of-chunk now. just forward it
+
+ if (data.length < missing) {
+ this._missing -= data.length
+ this._overflow = null
+ if (s) return s.write(data, cb)
+ b.append(data)
+ return cb()
+ }
+
+ // end-of-chunk. the parser should call cb.
+
+ this._cb = cb
+ this._missing = 0
+
+ var overflow = null
+ if (data.length > missing) {
+ overflow = data.slice(missing)
+ data = data.slice(0, missing)
+ }
+
+ if (s) s.end(data)
+ else b.append(data)
+
+ this._overflow = overflow
+ this._onparse()
+}
+
+module.exports = Extract