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.
parttimejob/node_modules/needle/lib/decoder.js

63 lines
1.6 KiB

4 weeks 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) {
// try to get charset from chunk, but just once
if (!this.parsed_chunk && (this.charset == 'utf-8' || this.charset == 'utf8')) {
this.parsed_chunk = true;
var matches = regex.exec(chunk.toString());
if (matches) {
var found = matches[1].toLowerCase().replace('utf8', 'utf-8'); // canonicalize;
// set charset, but only if iconv can handle it
if (iconv.encodingExists(found)) this.charset = found;
}
}
// if charset is already utf-8 or given encoding isn't supported, just pass through
if (this.charset == 'utf-8' || !iconv.encodingExists(this.charset)) {
this.push(chunk);
return done();
}
// initialize stream decoder if not present
var self = this;
if (!this.decoder) {
this.decoder = iconv.decodeStream(this.charset);
this.decoder.on('data', function(decoded_chunk) {
self.push(decoded_chunk);
});
};
this.decoder.write(chunk);
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;
}