130 lines
3.3 KiB
JavaScript
Executable File
130 lines
3.3 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
var program = require('commander');
|
|
var Bunzip = require('../');
|
|
var fs = require('fs');
|
|
|
|
program
|
|
.version(Bunzip.version)
|
|
.usage('-d|-z [infile] [outfile]')
|
|
.option('-d, --decompress',
|
|
'Decompress stdin to stdout')
|
|
//.option('-z, --compress',
|
|
// 'Compress stdin to stdout')
|
|
.option('-b, --block <n>',
|
|
'Extract a single block, starting at <n> bits.', undefined)
|
|
.option('-m, --multistream',
|
|
'Read a multistream bzip2 file');
|
|
program.on('--help', function() {
|
|
console.log(' If <infile> is omitted, reads from stdin.');
|
|
console.log(' If <outfile> is omitted, writes to stdout.');
|
|
});
|
|
program.parse(process.argv);
|
|
|
|
if (!program.compress) { program.decompress = true; }
|
|
|
|
if (program.compress && program.block !== undefined) {
|
|
console.error('--block can only be used with decompression');
|
|
return 1;
|
|
}
|
|
|
|
if (program.decompress && program.compress) {
|
|
console.error('Must specify either -d or -z.');
|
|
return 1;
|
|
}
|
|
|
|
var makeInStream = function(in_fd) {
|
|
var stat = fs.fstatSync(in_fd);
|
|
var stream = {
|
|
buffer: new Buffer(4096),
|
|
filePos: null,
|
|
pos: 0,
|
|
end: 0,
|
|
_fillBuffer: function() {
|
|
this.end = fs.readSync(in_fd, this.buffer, 0, this.buffer.length,
|
|
this.filePos);
|
|
this.pos = 0;
|
|
if (this.filePos !== null && this.end > 0) {
|
|
this.filePos += this.end;
|
|
}
|
|
},
|
|
readByte: function() {
|
|
if (this.pos >= this.end) { this._fillBuffer(); }
|
|
if (this.pos < this.end) {
|
|
return this.buffer[this.pos++];
|
|
}
|
|
return -1;
|
|
},
|
|
read: function(buffer, bufOffset, length) {
|
|
if (this.pos >= this.end) { this._fillBuffer(); }
|
|
var bytesRead = 0;
|
|
while (bytesRead < length && this.pos < this.end) {
|
|
buffer[bufOffset++] = this.buffer[this.pos++];
|
|
bytesRead++;
|
|
}
|
|
return bytesRead;
|
|
},
|
|
seek: function(seek_pos) {
|
|
this.filePos = seek_pos;
|
|
this.pos = this.end = 0;
|
|
},
|
|
eof: function() {
|
|
if (this.pos >= this.end) { this._fillBuffer(); }
|
|
return !(this.pos < this.end);
|
|
}
|
|
};
|
|
if (stat.size) {
|
|
stream.size = stat.size;
|
|
}
|
|
return stream;
|
|
};
|
|
var makeOutStream = function(out_fd) {
|
|
return {
|
|
buffer: new Buffer(4096),
|
|
pos: 0,
|
|
flush: function() {
|
|
fs.writeSync(out_fd, this.buffer, 0, this.pos);
|
|
this.pos = 0;
|
|
},
|
|
writeByte: function(byte) {
|
|
if (this.pos >= this.buffer.length) { this.flush(); }
|
|
this.buffer[this.pos++] = byte;
|
|
}
|
|
};
|
|
};
|
|
|
|
var in_fd = 0, close_in = function(){};
|
|
var out_fd = 1, close_out = function(){};
|
|
if (program.args.length > 0) {
|
|
in_fd = fs.openSync(program.args.shift(), 'r');
|
|
close_in = function() { fs.closeSync(in_fd); };
|
|
}
|
|
if (program.args.length > 0) {
|
|
out_fd = fs.openSync(program.args.shift(), 'w');
|
|
close_out = function() { fs.closeSync(out_fd); };
|
|
}
|
|
|
|
var inStream = makeInStream(in_fd);
|
|
var outStream= makeOutStream(out_fd);
|
|
|
|
if (program.decompress) {
|
|
try {
|
|
if (program.block !== undefined) {
|
|
Bunzip.decodeBlock(inStream, +program.block, outStream);
|
|
} else {
|
|
Bunzip.decode(inStream, outStream, program.multistream);
|
|
}
|
|
outStream.flush();
|
|
} catch (e) {
|
|
if (e.code !== 'EPIPE') throw e;
|
|
}
|
|
close_in();
|
|
close_out();
|
|
return 0;
|
|
}
|
|
if (program.compress) {
|
|
console.error('Compression not yet implemented.');
|
|
return 1;
|
|
}
|
|
return 1;
|