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.

130 lines
3.3 KiB

6 years ago
#!/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;