blob: da117fcf22e1cd62c6ed77916d370f094e89dd6d [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001#!/usr/bin/env node
2
3var program = require('commander');
4var Bunzip = require('../');
5var fs = require('fs');
6
7program
8 .version(Bunzip.version)
9 .usage('-d|-z [infile] [outfile]')
10 .option('-d, --decompress',
11 'Decompress stdin to stdout')
12 //.option('-z, --compress',
13 // 'Compress stdin to stdout')
14 .option('-b, --block <n>',
15 'Extract a single block, starting at <n> bits.', undefined)
16 .option('-m, --multistream',
17 'Read a multistream bzip2 file');
18program.on('--help', function() {
19 console.log(' If <infile> is omitted, reads from stdin.');
20 console.log(' If <outfile> is omitted, writes to stdout.');
21});
22program.parse(process.argv);
23
24if (!program.compress) { program.decompress = true; }
25
26if (program.compress && program.block !== undefined) {
27 console.error('--block can only be used with decompression');
28 return 1;
29}
30
31if (program.decompress && program.compress) {
32 console.error('Must specify either -d or -z.');
33 return 1;
34}
35
36var makeInStream = function(in_fd) {
37 var stat = fs.fstatSync(in_fd);
38 var stream = {
39 buffer: new Buffer(4096),
40 filePos: null,
41 pos: 0,
42 end: 0,
43 _fillBuffer: function() {
44 this.end = fs.readSync(in_fd, this.buffer, 0, this.buffer.length,
45 this.filePos);
46 this.pos = 0;
47 if (this.filePos !== null && this.end > 0) {
48 this.filePos += this.end;
49 }
50 },
51 readByte: function() {
52 if (this.pos >= this.end) { this._fillBuffer(); }
53 if (this.pos < this.end) {
54 return this.buffer[this.pos++];
55 }
56 return -1;
57 },
58 read: function(buffer, bufOffset, length) {
59 if (this.pos >= this.end) { this._fillBuffer(); }
60 var bytesRead = 0;
61 while (bytesRead < length && this.pos < this.end) {
62 buffer[bufOffset++] = this.buffer[this.pos++];
63 bytesRead++;
64 }
65 return bytesRead;
66 },
67 seek: function(seek_pos) {
68 this.filePos = seek_pos;
69 this.pos = this.end = 0;
70 },
71 eof: function() {
72 if (this.pos >= this.end) { this._fillBuffer(); }
73 return !(this.pos < this.end);
74 }
75 };
76 if (stat.size) {
77 stream.size = stat.size;
78 }
79 return stream;
80};
81var makeOutStream = function(out_fd) {
82 return {
83 buffer: new Buffer(4096),
84 pos: 0,
85 flush: function() {
86 fs.writeSync(out_fd, this.buffer, 0, this.pos);
87 this.pos = 0;
88 },
89 writeByte: function(byte) {
90 if (this.pos >= this.buffer.length) { this.flush(); }
91 this.buffer[this.pos++] = byte;
92 }
93 };
94};
95
96var in_fd = 0, close_in = function(){};
97var out_fd = 1, close_out = function(){};
98if (program.args.length > 0) {
99 in_fd = fs.openSync(program.args.shift(), 'r');
100 close_in = function() { fs.closeSync(in_fd); };
101}
102if (program.args.length > 0) {
103 out_fd = fs.openSync(program.args.shift(), 'w');
104 close_out = function() { fs.closeSync(out_fd); };
105}
106
107var inStream = makeInStream(in_fd);
108var outStream= makeOutStream(out_fd);
109
110if (program.decompress) {
111 try {
112 if (program.block !== undefined) {
113 Bunzip.decodeBlock(inStream, +program.block, outStream);
114 } else {
115 Bunzip.decode(inStream, outStream, program.multistream);
116 }
117 outStream.flush();
118 } catch (e) {
119 if (e.code !== 'EPIPE') throw e;
120 }
121 close_in();
122 close_out();
123 return 0;
124}
125if (program.compress) {
126 console.error('Compression not yet implemented.');
127 return 1;
128}
129return 1;