forked from zhurui/management
170 lines
3.7 KiB
JavaScript
170 lines
3.7 KiB
JavaScript
|
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 () {}
|