You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
3.7 KiB
169 lines
3.7 KiB
module.exports = EntryWriter |
|
|
|
var tar = require("../tar.js") |
|
, TarHeader = require("./header.js") |
|
, Entry = require("./entry.js") |
|
, inherits = require("inherits") |
|
, BlockStream = require("block-stream") |
|
, ExtendedHeaderWriter |
|
, Stream = require("stream").Stream |
|
, EOF = {} |
|
|
|
inherits(EntryWriter, Stream) |
|
|
|
function EntryWriter (props) { |
|
var me = this |
|
|
|
if (!(me instanceof EntryWriter)) { |
|
return new EntryWriter(props) |
|
} |
|
|
|
Stream.apply(this) |
|
|
|
me.writable = true |
|
me.readable = true |
|
|
|
me._stream = new BlockStream(512) |
|
|
|
me._stream.on("data", function (c) { |
|
me.emit("data", c) |
|
}) |
|
|
|
me._stream.on("drain", function () { |
|
me.emit("drain") |
|
}) |
|
|
|
me._stream.on("end", function () { |
|
me.emit("end") |
|
me.emit("close") |
|
}) |
|
|
|
me.props = props |
|
if (props.type === "Directory") { |
|
props.size = 0 |
|
} |
|
props.ustar = "ustar\0" |
|
props.ustarver = "00" |
|
me.path = props.path |
|
|
|
me._buffer = [] |
|
me._didHeader = false |
|
me._meta = false |
|
|
|
me.on("pipe", function () { |
|
me._process() |
|
}) |
|
} |
|
|
|
EntryWriter.prototype.write = function (c) { |
|
// console.error(".. ew write") |
|
if (this._ended) return this.emit("error", new Error("write after end")) |
|
this._buffer.push(c) |
|
this._process() |
|
this._needDrain = this._buffer.length > 0 |
|
return !this._needDrain |
|
} |
|
|
|
EntryWriter.prototype.end = function (c) { |
|
// console.error(".. ew end") |
|
if (c) this._buffer.push(c) |
|
this._buffer.push(EOF) |
|
this._ended = true |
|
this._process() |
|
this._needDrain = this._buffer.length > 0 |
|
} |
|
|
|
EntryWriter.prototype.pause = function () { |
|
// console.error(".. ew pause") |
|
this._paused = true |
|
this.emit("pause") |
|
} |
|
|
|
EntryWriter.prototype.resume = function () { |
|
// console.error(".. ew resume") |
|
this._paused = false |
|
this.emit("resume") |
|
this._process() |
|
} |
|
|
|
EntryWriter.prototype.add = function (entry) { |
|
// console.error(".. ew add") |
|
if (!this.parent) return this.emit("error", new Error("no parent")) |
|
|
|
// make sure that the _header and such is emitted, and clear out |
|
// the _currentEntry link on the parent. |
|
if (!this._ended) this.end() |
|
|
|
return this.parent.add(entry) |
|
} |
|
|
|
EntryWriter.prototype._header = function () { |
|
// console.error(".. ew header") |
|
if (this._didHeader) return |
|
this._didHeader = true |
|
|
|
var headerBlock = TarHeader.encode(this.props) |
|
|
|
if (this.props.needExtended && !this._meta) { |
|
var me = this |
|
|
|
ExtendedHeaderWriter = ExtendedHeaderWriter || |
|
require("./extended-header-writer.js") |
|
|
|
ExtendedHeaderWriter(this.props) |
|
.on("data", function (c) { |
|
me.emit("data", c) |
|
}) |
|
.on("error", function (er) { |
|
me.emit("error", er) |
|
}) |
|
.end() |
|
} |
|
|
|
// console.error(".. .. ew headerBlock emitting") |
|
this.emit("data", headerBlock) |
|
this.emit("header") |
|
} |
|
|
|
EntryWriter.prototype._process = function () { |
|
// console.error(".. .. ew process") |
|
if (!this._didHeader && !this._meta) { |
|
this._header() |
|
} |
|
|
|
if (this._paused || this._processing) { |
|
// console.error(".. .. .. paused=%j, processing=%j", this._paused, this._processing) |
|
return |
|
} |
|
|
|
this._processing = true |
|
|
|
var buf = this._buffer |
|
for (var i = 0; i < buf.length; i ++) { |
|
// console.error(".. .. .. i=%d", i) |
|
|
|
var c = buf[i] |
|
|
|
if (c === EOF) this._stream.end() |
|
else this._stream.write(c) |
|
|
|
if (this._paused) { |
|
// console.error(".. .. .. paused mid-emission") |
|
this._processing = false |
|
if (i < buf.length) { |
|
this._needDrain = true |
|
this._buffer = buf.slice(i + 1) |
|
} |
|
return |
|
} |
|
} |
|
|
|
// console.error(".. .. .. emitted") |
|
this._buffer.length = 0 |
|
this._processing = false |
|
|
|
// console.error(".. .. .. emitting drain") |
|
this.emit("drain") |
|
} |
|
|
|
EntryWriter.prototype.destroy = function () {}
|
|
|