blob: d3f597868d9a138e12a335b5067d788aa9a4deed [file] [log] [blame]
'use strict';
exports.compress = compress;
exports.decompress = decompress;
exports.compressSync = compressSync;
exports.decompressSync = decompressSync;
exports.compressStream = compressStream;
exports.decompressStream = decompressStream;
const iltorb = require('./build/bindings/iltorb.node');
const Transform = require('stream').Transform;
class TransformStreamEncode extends Transform {
constructor(params, sync) {
super(params);
this.sync = sync || false;
this.encoding = false;
this.corked = false;
this.flushing = false;
this.encoder = new iltorb.StreamEncode(params || {});
}
_transform(chunk, encoding, next) {
this.encoding = true;
this.encoder.transform(chunk, (err, output) => {
this.encoding = false;
if (err) {
return next(err);
}
this._push(output);
next();
if (this.flushing) {
this.flush(true);
}
}, !this.sync);
}
_flush(done) {
this.encoder.flush(true, (err, output) => {
if (err) {
return done(err);
}
this._push(output);
done();
}, !this.sync);
}
_push(output) {
if (output) {
for (let i = 0; i < output.length; i++) {
this.push(output[i]);
}
}
}
flush(force) {
if (this.flushing && !force) {
return;
}
if (!this.corked) {
this.cork();
}
this.corked = true;
this.flushing = true;
if (this.encoding) {
return;
}
this.encoder.flush(false, (err, output) => {
if (err) {
this.emit('error', err);
} else {
this._push(output);
}
this.corked = false;
this.flushing = false;
this.uncork();
}, true);
}
}
class TransformStreamDecode extends Transform {
constructor(params, sync) {
super(params);
this.sync = sync || false;
this.decoder = new iltorb.StreamDecode(params || {});
}
_transform(chunk, encoding, next) {
this.decoder.transform(chunk, (err, output) => {
if (err) {
return next(err);
}
this._push(output);
next();
}, !this.sync);
}
_flush(done) {
this.decoder.flush((err, output) => {
if (err) {
return done(err);
}
this._push(output);
done();
}, !this.sync);
}
_push(output) {
if (output) {
for (let i = 0; i < output.length; i++) {
this.push(output[i]);
}
}
}
}
function compress(input, params, cb) {
if (arguments.length === 2) {
cb = params;
params = {};
}
if (!Buffer.isBuffer(input)) {
process.nextTick(cb, new Error('Brotli input is not a buffer.'));
return;
}
if (typeof cb !== 'function') {
process.nextTick(cb, new Error('Second argument is not a function.'));
return;
}
if (typeof params !== 'object') {
params = {};
}
params.size_hint = input.length;
const stream = new TransformStreamEncode(params);
const chunks = [];
let length = 0;
stream.on('error', cb);
stream.on('data', function(c) {
chunks.push(c);
length += c.length;
});
stream.on('end', function() {
cb(null, Buffer.concat(chunks, length));
});
stream.end(input);
}
function decompress(input, params, cb) {
if (arguments.length === 2) {
cb = params;
params = {};
}
if (!Buffer.isBuffer(input)) {
process.nextTick(cb, new Error('Brotli input is not a buffer.'));
return;
}
if (typeof cb !== 'function') {
process.nextTick(cb, new Error('Second argument is not a function.'));
return;
}
const stream = new TransformStreamDecode(params);
const chunks = [];
let length = 0;
stream.on('error', cb);
stream.on('data', function(c) {
chunks.push(c);
length += c.length;
});
stream.on('end', function() {
cb(null, Buffer.concat(chunks, length));
});
stream.end(input);
}
function compressSync(input, params) {
if (!Buffer.isBuffer(input)) {
throw new Error('Brotli input is not a buffer.');
}
if (typeof params !== 'object') {
params = {};
}
params.size_hint = input.length;
const stream = new TransformStreamEncode(params, true);
const chunks = [];
let length = 0;
stream.on('error', function(e) {
throw e;
});
stream.on('data', function(c) {
chunks.push(c);
length += c.length;
});
stream.end(input);
return Buffer.concat(chunks, length);
}
function decompressSync(input, params) {
if (!Buffer.isBuffer(input)) {
throw new Error('Brotli input is not a buffer.');
}
const stream = new TransformStreamDecode(params, true);
const chunks = [];
let length = 0;
stream.on('error', function(e) {
throw e;
});
stream.on('data', function(c) {
chunks.push(c);
length += c.length;
});
stream.end(input);
return Buffer.concat(chunks, length);
}
function compressStream(params) {
return new TransformStreamEncode(params);
}
function decompressStream(params) {
return new TransformStreamDecode(params);
}