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.
54 lines
1.2 KiB
54 lines
1.2 KiB
1 month ago
|
var iconv,
|
||
|
inherits = require('util').inherits,
|
||
|
stream = require('stream');
|
||
|
|
||
|
var regex = /(?:charset|encoding)\s*=\s*['"]? *([\w\-]+)/i;
|
||
|
|
||
|
inherits(StreamDecoder, stream.Transform);
|
||
|
|
||
|
function StreamDecoder(charset) {
|
||
|
if (!(this instanceof StreamDecoder))
|
||
|
return new StreamDecoder(charset);
|
||
|
|
||
|
stream.Transform.call(this, charset);
|
||
|
this.charset = charset;
|
||
|
this.parsed_chunk = false;
|
||
|
}
|
||
|
|
||
|
StreamDecoder.prototype._transform = function(chunk, encoding, done) {
|
||
|
var res, found;
|
||
|
|
||
|
// try get charset from chunk, just once
|
||
|
if (this.charset == 'utf8' && !this.parsed_chunk) {
|
||
|
this.parsed_chunk = true;
|
||
|
|
||
|
var matches = regex.exec(chunk.toString());
|
||
|
if (matches) {
|
||
|
found = matches[1].toLowerCase();
|
||
|
this.charset = found == 'utf-8' ? 'utf8' : found;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
res = iconv.decode(chunk, this.charset);
|
||
|
} catch(e) { // something went wrong, just return original chunk
|
||
|
res = chunk;
|
||
|
}
|
||
|
|
||
|
this.push(res);
|
||
|
done();
|
||
|
}
|
||
|
|
||
|
module.exports = function(charset) {
|
||
|
try {
|
||
|
if (!iconv) iconv = require('iconv-lite');
|
||
|
} catch(e) {
|
||
|
/* iconv not found */
|
||
|
}
|
||
|
|
||
|
if (iconv)
|
||
|
return new StreamDecoder(charset);
|
||
|
else
|
||
|
return new stream.PassThrough;
|
||
|
}
|