diff options
Diffstat (limited to 'node_modules/needle/lib/decoder.js')
| -rw-r--r-- | node_modules/needle/lib/decoder.js | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/node_modules/needle/lib/decoder.js b/node_modules/needle/lib/decoder.js new file mode 100644 index 0000000..d82bb5a --- /dev/null +++ b/node_modules/needle/lib/decoder.js @@ -0,0 +1,53 @@ +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 == 'iso-8859-1' && !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; +} |