tar-js/lib/tar.js

111 lines
2.5 KiB
JavaScript

/*
* tar-js
* MIT (c) 2011 T. Jameson Little
*/
(function () {
"use strict";
var header = require("./header"),
utils = require("./utils"),
recordSize = 512,
blockSize;
function Tar(recordsPerBlock) {
this.written = 0;
blockSize = (recordsPerBlock || 20) * recordSize;
this.out = utils.clean(blockSize);
}
Tar.prototype.append = function (filepath, input, opts, callback) {
var data,
checksum,
mode,
mtime,
uid,
gid,
headerArr;
if (typeof input === 'string') {
input = utils.stringToUint8(input);
} else if (input.constructor !== Uint8Array.prototype.constructor) {
throw 'Invalid input type. You gave me: ' + input.constructor.toString().match(/function\s*([$A-Za-z_][0-9A-Za-z_]*)\s*\(/)[1];
}
if (typeof opts === 'function') {
callback = opts;
opts = {};
}
opts = opts || {};
mode = opts.mode || parseInt('777', 8) & 0xfff;
mtime = opts.mtime || Math.floor(+new Date() / 1000);
uid = opts.uid || 0;
gid = opts.gid || 0;
data = {
fileName: filepath,
fileMode: utils.pad(mode, 7),
uid: utils.pad(uid, 7),
gid: utils.pad(gid, 7),
fileSize: utils.pad(input.length, 11),
mtime: utils.pad(mtime, 11),
checksum: ' ',
type: '0', // just a file
ustar: 'ustar ',
owner: opts.owner || '',
group: opts.group || ''
};
// calculate the checksum
checksum = 0;
Object.keys(data).forEach(function (key) {
var i, value = data[key], length;
for (i = 0, length = value.length; i < length; i += 1) {
checksum += value.charCodeAt(i);
}
});
data.checksum = utils.pad(checksum, 6) + "\u0000 ";
headerArr = header.format(data);
var i, offset, length;
this.out.set(headerArr, this.written);
this.written += headerArr.length;
// If there is not enough space in this.out, we need to expand it to
// fit the new input.
if (this.written + input.length > this.out.length) {
this.out = utils.extend(this.out, this.written, input.length, blockSize);
}
this.out.set(input, this.written);
// to the nearest multiple of recordSize
this.written += input.length + (recordSize - (input.length % recordSize || recordSize));
// make sure there's at least 2 empty records worth of extra space
if (this.out.length - this.written < recordSize * 2) {
this.out = utils.extend(this.out, this.written, recordSize * 2, blockSize);
}
if (typeof callback === 'function') {
callback(this.out);
}
return this.out;
};
Tar.prototype.clear = function () {
this.written = 0;
this.out = utils.clean(blockSize);
};
module.exports = Tar;
}());