forked from public/fvtt-cthulhu-eternal
108 lines
2.3 KiB
JavaScript
108 lines
2.3 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
/* eslint-disable new-cap */
|
||
|
|
||
|
var iconv = require('iconv-lite');
|
||
|
// TODO: Reaching into iconv-lite is fragile
|
||
|
var StripBOM = require('iconv-lite/lib/bom-handling').StripBOM;
|
||
|
var Transform = require('streamx').Transform;
|
||
|
|
||
|
var DEFAULT_ENCODING = require('./constants').DEFAULT_ENCODING;
|
||
|
|
||
|
function Codec(codec, encoding) {
|
||
|
this.codec = codec;
|
||
|
this.enc = codec.enc || encoding;
|
||
|
this.bomAware = codec.bomAware || false;
|
||
|
}
|
||
|
|
||
|
function getEncoder(codec) {
|
||
|
return new codec.encoder(null, codec);
|
||
|
}
|
||
|
|
||
|
Codec.prototype.encode = function (str) {
|
||
|
var encoder = getEncoder(this.codec);
|
||
|
var buf = encoder.write(str);
|
||
|
var end = encoder.end();
|
||
|
return end && end.length > 0 ? Buffer.concat(buf, end) : buf;
|
||
|
};
|
||
|
|
||
|
Codec.prototype.encodeStream = function () {
|
||
|
var encoder = getEncoder(this.codec);
|
||
|
return new Transform({
|
||
|
transform: function (str, cb) {
|
||
|
var buf = encoder.write(str);
|
||
|
if (buf && buf.length) {
|
||
|
this.push(buf);
|
||
|
}
|
||
|
cb();
|
||
|
},
|
||
|
flush: function (cb) {
|
||
|
var buf = encoder.end();
|
||
|
if (buf && buf.length) {
|
||
|
this.push(buf);
|
||
|
}
|
||
|
cb();
|
||
|
},
|
||
|
});
|
||
|
};
|
||
|
|
||
|
function getDecoder(codec) {
|
||
|
return new codec.decoder(null, codec);
|
||
|
}
|
||
|
|
||
|
Codec.prototype.decode = function (buf, options) {
|
||
|
var decoder = getDecoder(this.codec);
|
||
|
if (options && options.removeBOM) {
|
||
|
decoder = new StripBOM(decoder);
|
||
|
}
|
||
|
var str = decoder.write(buf);
|
||
|
var end = decoder.end();
|
||
|
return end ? str + end : str;
|
||
|
};
|
||
|
|
||
|
Codec.prototype.decodeStream = function (options) {
|
||
|
var decoder = getDecoder(this.codec);
|
||
|
if (options && options.removeBOM) {
|
||
|
decoder = new StripBOM(decoder);
|
||
|
}
|
||
|
return new Transform({
|
||
|
transform: function (buf, cb) {
|
||
|
var str = decoder.write(buf);
|
||
|
if (str && str.length) {
|
||
|
this.push(str);
|
||
|
}
|
||
|
cb();
|
||
|
},
|
||
|
flush: function (cb) {
|
||
|
var str = decoder.end();
|
||
|
if (str && str.length) {
|
||
|
this.push(str);
|
||
|
}
|
||
|
cb();
|
||
|
},
|
||
|
});
|
||
|
};
|
||
|
|
||
|
var cache = {};
|
||
|
|
||
|
function getCodec(encoding) {
|
||
|
var codec = cache[encoding];
|
||
|
if (!!codec || !encoding || Object.hasOwnProperty.call(cache, encoding)) {
|
||
|
return codec;
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
codec = new Codec(iconv.getCodec(encoding), encoding);
|
||
|
} catch (err) {
|
||
|
// Unsupported codec
|
||
|
}
|
||
|
|
||
|
cache[encoding] = codec;
|
||
|
return codec;
|
||
|
}
|
||
|
|
||
|
// Pre-load default encoding
|
||
|
getCodec(DEFAULT_ENCODING);
|
||
|
|
||
|
module.exports = getCodec;
|