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.
		
		
		
		
		
			
		
			
				
					441 lines
				
				11 KiB
			
		
		
			
		
	
	
					441 lines
				
				11 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * node-compress-commons
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright (c) 2014 Chris Talkington, contributors.
							 | 
						||
| 
								 | 
							
								 * Licensed under the MIT license.
							 | 
						||
| 
								 | 
							
								 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var inherits = require('util').inherits;
							 | 
						||
| 
								 | 
							
								var crc32 = require('buffer-crc32');
							 | 
						||
| 
								 | 
							
								var {CRC32Stream} = require('crc32-stream');
							 | 
						||
| 
								 | 
							
								var {DeflateCRC32Stream} = require('crc32-stream');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var ArchiveOutputStream = require('../archive-output-stream');
							 | 
						||
| 
								 | 
							
								var ZipArchiveEntry = require('./zip-archive-entry');
							 | 
						||
| 
								 | 
							
								var GeneralPurposeBit = require('./general-purpose-bit');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var constants = require('./constants');
							 | 
						||
| 
								 | 
							
								var util = require('../../util');
							 | 
						||
| 
								 | 
							
								var zipUtil = require('./util');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var ZipArchiveOutputStream = module.exports = function(options) {
							 | 
						||
| 
								 | 
							
								  if (!(this instanceof ZipArchiveOutputStream)) {
							 | 
						||
| 
								 | 
							
								    return new ZipArchiveOutputStream(options);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  options = this.options = this._defaults(options);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ArchiveOutputStream.call(this, options);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._entry = null;
							 | 
						||
| 
								 | 
							
								  this._entries = [];
							 | 
						||
| 
								 | 
							
								  this._archive = {
							 | 
						||
| 
								 | 
							
								    centralLength: 0,
							 | 
						||
| 
								 | 
							
								    centralOffset: 0,
							 | 
						||
| 
								 | 
							
								    comment: '',
							 | 
						||
| 
								 | 
							
								    finish: false,
							 | 
						||
| 
								 | 
							
								    finished: false,
							 | 
						||
| 
								 | 
							
								    processing: false,
							 | 
						||
| 
								 | 
							
								    forceZip64: options.forceZip64,
							 | 
						||
| 
								 | 
							
								    forceLocalTime: options.forceLocalTime
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inherits(ZipArchiveOutputStream, ArchiveOutputStream);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._afterAppend = function(ae) {
							 | 
						||
| 
								 | 
							
								  this._entries.push(ae);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (ae.getGeneralPurposeBit().usesDataDescriptor()) {
							 | 
						||
| 
								 | 
							
								    this._writeDataDescriptor(ae);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._archive.processing = false;
							 | 
						||
| 
								 | 
							
								  this._entry = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this._archive.finish && !this._archive.finished) {
							 | 
						||
| 
								 | 
							
								    this._finish();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._appendBuffer = function(ae, source, callback) {
							 | 
						||
| 
								 | 
							
								  if (source.length === 0) {
							 | 
						||
| 
								 | 
							
								    ae.setMethod(constants.METHOD_STORED);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var method = ae.getMethod();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (method === constants.METHOD_STORED) {
							 | 
						||
| 
								 | 
							
								    ae.setSize(source.length);
							 | 
						||
| 
								 | 
							
								    ae.setCompressedSize(source.length);
							 | 
						||
| 
								 | 
							
								    ae.setCrc(crc32.unsigned(source));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._writeLocalFileHeader(ae);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (method === constants.METHOD_STORED) {
							 | 
						||
| 
								 | 
							
								    this.write(source);
							 | 
						||
| 
								 | 
							
								    this._afterAppend(ae);
							 | 
						||
| 
								 | 
							
								    callback(null, ae);
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  } else if (method === constants.METHOD_DEFLATED) {
							 | 
						||
| 
								 | 
							
								    this._smartStream(ae, callback).end(source);
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    callback(new Error('compression method ' + method + ' not implemented'));
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._appendStream = function(ae, source, callback) {
							 | 
						||
| 
								 | 
							
								  ae.getGeneralPurposeBit().useDataDescriptor(true);
							 | 
						||
| 
								 | 
							
								  ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._writeLocalFileHeader(ae);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var smart = this._smartStream(ae, callback);
							 | 
						||
| 
								 | 
							
								  source.once('error', function(err) {
							 | 
						||
| 
								 | 
							
								    smart.emit('error', err);
							 | 
						||
| 
								 | 
							
								    smart.end();
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								  source.pipe(smart);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._defaults = function(o) {
							 | 
						||
| 
								 | 
							
								  if (typeof o !== 'object') {
							 | 
						||
| 
								 | 
							
								    o = {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (typeof o.zlib !== 'object') {
							 | 
						||
| 
								 | 
							
								    o.zlib = {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (typeof o.zlib.level !== 'number') {
							 | 
						||
| 
								 | 
							
								    o.zlib.level = constants.ZLIB_BEST_SPEED;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  o.forceZip64 = !!o.forceZip64;
							 | 
						||
| 
								 | 
							
								  o.forceLocalTime = !!o.forceLocalTime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return o;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._finish = function() {
							 | 
						||
| 
								 | 
							
								  this._archive.centralOffset = this.offset;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._entries.forEach(function(ae) {
							 | 
						||
| 
								 | 
							
								    this._writeCentralFileHeader(ae);
							 | 
						||
| 
								 | 
							
								  }.bind(this));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._archive.centralLength = this.offset - this._archive.centralOffset;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this.isZip64()) {
							 | 
						||
| 
								 | 
							
								    this._writeCentralDirectoryZip64();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._writeCentralDirectoryEnd();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._archive.processing = false;
							 | 
						||
| 
								 | 
							
								  this._archive.finish = true;
							 | 
						||
| 
								 | 
							
								  this._archive.finished = true;
							 | 
						||
| 
								 | 
							
								  this.end();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._normalizeEntry = function(ae) {
							 | 
						||
| 
								 | 
							
								  if (ae.getMethod() === -1) {
							 | 
						||
| 
								 | 
							
								    ae.setMethod(constants.METHOD_DEFLATED);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (ae.getMethod() === constants.METHOD_DEFLATED) {
							 | 
						||
| 
								 | 
							
								    ae.getGeneralPurposeBit().useDataDescriptor(true);
							 | 
						||
| 
								 | 
							
								    ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (ae.getTime() === -1) {
							 | 
						||
| 
								 | 
							
								    ae.setTime(new Date(), this._archive.forceLocalTime);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ae._offsets = {
							 | 
						||
| 
								 | 
							
								    file: 0,
							 | 
						||
| 
								 | 
							
								    data: 0,
							 | 
						||
| 
								 | 
							
								    contents: 0,
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._smartStream = function(ae, callback) {
							 | 
						||
| 
								 | 
							
								  var deflate = ae.getMethod() === constants.METHOD_DEFLATED;
							 | 
						||
| 
								 | 
							
								  var process = deflate ? new DeflateCRC32Stream(this.options.zlib) : new CRC32Stream();
							 | 
						||
| 
								 | 
							
								  var error = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function handleStuff() {
							 | 
						||
| 
								 | 
							
								    var digest = process.digest().readUInt32BE(0);
							 | 
						||
| 
								 | 
							
								    ae.setCrc(digest);
							 | 
						||
| 
								 | 
							
								    ae.setSize(process.size());
							 | 
						||
| 
								 | 
							
								    ae.setCompressedSize(process.size(true));
							 | 
						||
| 
								 | 
							
								    this._afterAppend(ae);
							 | 
						||
| 
								 | 
							
								    callback(error, ae);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  process.once('end', handleStuff.bind(this));
							 | 
						||
| 
								 | 
							
								  process.once('error', function(err) {
							 | 
						||
| 
								 | 
							
								    error = err;
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  process.pipe(this, { end: false });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return process;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._writeCentralDirectoryEnd = function() {
							 | 
						||
| 
								 | 
							
								  var records = this._entries.length;
							 | 
						||
| 
								 | 
							
								  var size = this._archive.centralLength;
							 | 
						||
| 
								 | 
							
								  var offset = this._archive.centralOffset;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this.isZip64()) {
							 | 
						||
| 
								 | 
							
								    records = constants.ZIP64_MAGIC_SHORT;
							 | 
						||
| 
								 | 
							
								    size = constants.ZIP64_MAGIC;
							 | 
						||
| 
								 | 
							
								    offset = constants.ZIP64_MAGIC;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // signature
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(constants.SIG_EOCD));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // disk numbers
							 | 
						||
| 
								 | 
							
								  this.write(constants.SHORT_ZERO);
							 | 
						||
| 
								 | 
							
								  this.write(constants.SHORT_ZERO);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // number of entries
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(records));
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(records));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // length and location of CD
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(size));
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(offset));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // archive comment
							 | 
						||
| 
								 | 
							
								  var comment = this.getComment();
							 | 
						||
| 
								 | 
							
								  var commentLength = Buffer.byteLength(comment);
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(commentLength));
							 | 
						||
| 
								 | 
							
								  this.write(comment);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._writeCentralDirectoryZip64 = function() {
							 | 
						||
| 
								 | 
							
								  // signature
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(constants.SIG_ZIP64_EOCD));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // size of the ZIP64 EOCD record
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getEightBytes(44));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // version made by
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(constants.MIN_VERSION_ZIP64));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // version to extract
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(constants.MIN_VERSION_ZIP64));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // disk numbers
							 | 
						||
| 
								 | 
							
								  this.write(constants.LONG_ZERO);
							 | 
						||
| 
								 | 
							
								  this.write(constants.LONG_ZERO);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // number of entries
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getEightBytes(this._entries.length));
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getEightBytes(this._entries.length));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // length and location of CD
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getEightBytes(this._archive.centralLength));
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getEightBytes(this._archive.centralOffset));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // extensible data sector
							 | 
						||
| 
								 | 
							
								  // not implemented at this time
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // end of central directory locator
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(constants.SIG_ZIP64_EOCD_LOC));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // disk number holding the ZIP64 EOCD record
							 | 
						||
| 
								 | 
							
								  this.write(constants.LONG_ZERO);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // relative offset of the ZIP64 EOCD record
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getEightBytes(this._archive.centralOffset + this._archive.centralLength));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // total number of disks
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(1));
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._writeCentralFileHeader = function(ae) {
							 | 
						||
| 
								 | 
							
								  var gpb = ae.getGeneralPurposeBit();
							 | 
						||
| 
								 | 
							
								  var method = ae.getMethod();
							 | 
						||
| 
								 | 
							
								  var offsets = ae._offsets;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var size = ae.getSize();
							 | 
						||
| 
								 | 
							
								  var compressedSize = ae.getCompressedSize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (ae.isZip64() || offsets.file > constants.ZIP64_MAGIC) {
							 | 
						||
| 
								 | 
							
								    size = constants.ZIP64_MAGIC;
							 | 
						||
| 
								 | 
							
								    compressedSize = constants.ZIP64_MAGIC;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ae.setVersionNeededToExtract(constants.MIN_VERSION_ZIP64);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var extraBuf = Buffer.concat([
							 | 
						||
| 
								 | 
							
								      zipUtil.getShortBytes(constants.ZIP64_EXTRA_ID),
							 | 
						||
| 
								 | 
							
								      zipUtil.getShortBytes(24),
							 | 
						||
| 
								 | 
							
								      zipUtil.getEightBytes(ae.getSize()),
							 | 
						||
| 
								 | 
							
								      zipUtil.getEightBytes(ae.getCompressedSize()),
							 | 
						||
| 
								 | 
							
								      zipUtil.getEightBytes(offsets.file)
							 | 
						||
| 
								 | 
							
								    ], 28);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ae.setExtra(extraBuf);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // signature
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(constants.SIG_CFH));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // version made by
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes((ae.getPlatform() << 8) | constants.VERSION_MADEBY));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // version to extract and general bit flag
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
							 | 
						||
| 
								 | 
							
								  this.write(gpb.encode());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // compression method
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(method));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // datetime
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(ae.getTimeDos()));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // crc32 checksum
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(ae.getCrc()));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // sizes
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(compressedSize));
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(size));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var name = ae.getName();
							 | 
						||
| 
								 | 
							
								  var comment = ae.getComment();
							 | 
						||
| 
								 | 
							
								  var extra = ae.getCentralDirectoryExtra();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (gpb.usesUTF8ForNames()) {
							 | 
						||
| 
								 | 
							
								    name = Buffer.from(name);
							 | 
						||
| 
								 | 
							
								    comment = Buffer.from(comment);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // name length
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(name.length));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // extra length
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(extra.length));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // comments length
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(comment.length));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // disk number start
							 | 
						||
| 
								 | 
							
								  this.write(constants.SHORT_ZERO);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // internal attributes
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(ae.getInternalAttributes()));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // external attributes
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(ae.getExternalAttributes()));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // relative offset of LFH
							 | 
						||
| 
								 | 
							
								  if (offsets.file > constants.ZIP64_MAGIC) {
							 | 
						||
| 
								 | 
							
								    this.write(zipUtil.getLongBytes(constants.ZIP64_MAGIC));
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.write(zipUtil.getLongBytes(offsets.file));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // name
							 | 
						||
| 
								 | 
							
								  this.write(name);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // extra
							 | 
						||
| 
								 | 
							
								  this.write(extra);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // comment
							 | 
						||
| 
								 | 
							
								  this.write(comment);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._writeDataDescriptor = function(ae) {
							 | 
						||
| 
								 | 
							
								  // signature
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(constants.SIG_DD));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // crc32 checksum
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(ae.getCrc()));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // sizes
							 | 
						||
| 
								 | 
							
								  if (ae.isZip64()) {
							 | 
						||
| 
								 | 
							
								    this.write(zipUtil.getEightBytes(ae.getCompressedSize()));
							 | 
						||
| 
								 | 
							
								    this.write(zipUtil.getEightBytes(ae.getSize()));
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
							 | 
						||
| 
								 | 
							
								    this.write(zipUtil.getLongBytes(ae.getSize()));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype._writeLocalFileHeader = function(ae) {
							 | 
						||
| 
								 | 
							
								  var gpb = ae.getGeneralPurposeBit();
							 | 
						||
| 
								 | 
							
								  var method = ae.getMethod();
							 | 
						||
| 
								 | 
							
								  var name = ae.getName();
							 | 
						||
| 
								 | 
							
								  var extra = ae.getLocalFileDataExtra();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (ae.isZip64()) {
							 | 
						||
| 
								 | 
							
								    gpb.useDataDescriptor(true);
							 | 
						||
| 
								 | 
							
								    ae.setVersionNeededToExtract(constants.MIN_VERSION_ZIP64);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (gpb.usesUTF8ForNames()) {
							 | 
						||
| 
								 | 
							
								    name = Buffer.from(name);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ae._offsets.file = this.offset;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // signature
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(constants.SIG_LFH));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // version to extract and general bit flag
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
							 | 
						||
| 
								 | 
							
								  this.write(gpb.encode());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // compression method
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(method));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // datetime
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getLongBytes(ae.getTimeDos()));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ae._offsets.data = this.offset;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // crc32 checksum and sizes
							 | 
						||
| 
								 | 
							
								  if (gpb.usesDataDescriptor()) {
							 | 
						||
| 
								 | 
							
								    this.write(constants.LONG_ZERO);
							 | 
						||
| 
								 | 
							
								    this.write(constants.LONG_ZERO);
							 | 
						||
| 
								 | 
							
								    this.write(constants.LONG_ZERO);
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.write(zipUtil.getLongBytes(ae.getCrc()));
							 | 
						||
| 
								 | 
							
								    this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
							 | 
						||
| 
								 | 
							
								    this.write(zipUtil.getLongBytes(ae.getSize()));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // name length
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(name.length));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // extra length
							 | 
						||
| 
								 | 
							
								  this.write(zipUtil.getShortBytes(extra.length));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // name
							 | 
						||
| 
								 | 
							
								  this.write(name);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // extra
							 | 
						||
| 
								 | 
							
								  this.write(extra);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ae._offsets.contents = this.offset;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype.getComment = function(comment) {
							 | 
						||
| 
								 | 
							
								  return this._archive.comment !== null ? this._archive.comment : '';
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype.isZip64 = function() {
							 | 
						||
| 
								 | 
							
								  return this._archive.forceZip64 || this._entries.length > constants.ZIP64_MAGIC_SHORT || this._archive.centralLength > constants.ZIP64_MAGIC || this._archive.centralOffset > constants.ZIP64_MAGIC;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ZipArchiveOutputStream.prototype.setComment = function(comment) {
							 | 
						||
| 
								 | 
							
								  this._archive.comment = comment;
							 | 
						||
| 
								 | 
							
								};
							 |