var Stream = require('stream').Stream, utillib = require('util'), mimelib = require("mimelib"), encodinglib = require("encoding"), crypto = require("crypto"); module.exports.Base64Stream = Base64Stream; module.exports.QPStream = QPStream; module.exports.BinaryStream = BinaryStream; function Base64Stream(){ Stream.call(this); this.writable = true; this.checksum = crypto.createHash("md5"); this.length = 0; this.current = ""; } utillib.inherits(Base64Stream, Stream); Base64Stream.prototype.write = function(data){ this.handleInput(data); return true; }; Base64Stream.prototype.end = function(data){ this.handleInput(data); this.emit("end"); return { length: this.length, checksum: this.checksum.digest("hex") }; }; Base64Stream.prototype.handleInput = function(data){ if(!data || !data.length){ return; } data = (data || "").toString("utf-8"); var remainder = 0; this.current += data.replace(/[^\w\+\/=]/g,''); var buffer = new Buffer(this.current.substr(0, this.current.length - this.current.length % 4),"base64"); if(buffer.length){ this.length += buffer.length; this.checksum.update(buffer); this.emit("data", buffer); } this.current = (remainder=this.current.length % 4)?this.current.substr(- remainder):""; }; function QPStream(charset){ Stream.call(this); this.writable = true; this.checksum = crypto.createHash("md5"); this.length = 0; this.charset = charset || "UTF-8"; this.current = undefined; } utillib.inherits(QPStream, Stream); QPStream.prototype.write = function(data){ this.handleInput(data); return true; }; QPStream.prototype.end = function(data){ this.handleInput(data); this.flush(); this.emit("end"); return { length: this.length, checksum: this.checksum.digest("hex") }; }; QPStream.prototype.handleInput = function(data){ if(!data || !data.length){ return; } data = (data || "").toString("utf-8"); if(data.match(/^\r\n/)){ data = data.substr(2); } if(typeof this.current !="string"){ this.current = data; }else{ this.current += "\r\n" + data; } }; QPStream.prototype.flush = function(){ var buffer = mimelib.decodeQuotedPrintable(this.current, false, this.charset); if(this.charset.toLowerCase() == "binary"){ // do nothing }else if(this.charset.toLowerCase() != "utf-8"){ buffer = encodinglib.convert(buffer, "utf-8", this.charset); }else{ buffer = new Buffer(buffer, "utf-8"); } this.length += buffer.length; this.checksum.update(buffer); this.emit("data", buffer); }; function BinaryStream(charset){ Stream.call(this); this.writable = true; this.checksum = crypto.createHash("md5"); this.length = 0; this.charset = charset || "UTF-8"; this.current = ""; } utillib.inherits(BinaryStream, Stream); BinaryStream.prototype.write = function(data){ if(data && data.length){ this.length += data.length; this.checksum.update(data); this.emit("data", data); } return true; }; BinaryStream.prototype.end = function(data){ if(data && data.length){ this.emit("data", data); } this.emit("end"); return { length: this.length, checksum: this.checksum.digest("hex") }; };