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.
		
		
		
		
			
				
					170 lines
				
				3.7 KiB
			
		
		
			
		
	
	
					170 lines
				
				3.7 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								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 () {}
							 |