| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | var util = require('util')var Stream = require('stream')var StringDecoder = require('string_decoder').StringDecodermodule.exports = StringStreammodule.exports.AlignedStringDecoder = AlignedStringDecoderfunction StringStream(from, to) {  if (!(this instanceof StringStream)) return new StringStream(from, to)  Stream.call(this)  if (from == null) from = 'utf8'  this.readable = this.writable = true  this.paused = false  this.toEncoding = (to == null ? from : to)  this.fromEncoding = (to == null ? '' : from)  this.decoder = new AlignedStringDecoder(this.toEncoding)}util.inherits(StringStream, Stream)StringStream.prototype.write = function(data) {  if (!this.writable) {    var err = new Error('stream not writable')    err.code = 'EPIPE'    this.emit('error', err)    return false  }  if (this.fromEncoding) {    if (Buffer.isBuffer(data) || typeof data === 'number') data = data.toString()    data = new Buffer(data, this.fromEncoding)  }  var string = this.decoder.write(data)  if (string.length) this.emit('data', string)  return !this.paused}StringStream.prototype.flush = function() {  if (this.decoder.flush) {    var string = this.decoder.flush()    if (string.length) this.emit('data', string)  }}StringStream.prototype.end = function() {  if (!this.writable && !this.readable) return  this.flush()  this.emit('end')  this.writable = this.readable = false  this.destroy()}StringStream.prototype.destroy = function() {  this.decoder = null  this.writable = this.readable = false  this.emit('close')}StringStream.prototype.pause = function() {  this.paused = true}StringStream.prototype.resume = function () {  if (this.paused) this.emit('drain')  this.paused = false}function AlignedStringDecoder(encoding) {  StringDecoder.call(this, encoding)  switch (this.encoding) {    case 'base64':      this.write = alignedWrite      this.alignedBuffer = new Buffer(3)      this.alignedBytes = 0      break  }}util.inherits(AlignedStringDecoder, StringDecoder)AlignedStringDecoder.prototype.flush = function() {  if (!this.alignedBuffer || !this.alignedBytes) return ''  var leftover = this.alignedBuffer.toString(this.encoding, 0, this.alignedBytes)  this.alignedBytes = 0  return leftover}function alignedWrite(buffer) {  var rem = (this.alignedBytes + buffer.length) % this.alignedBuffer.length  if (!rem && !this.alignedBytes) return buffer.toString(this.encoding)  var returnBuffer = new Buffer(this.alignedBytes + buffer.length - rem)  this.alignedBuffer.copy(returnBuffer, 0, 0, this.alignedBytes)  buffer.copy(returnBuffer, this.alignedBytes, 0, buffer.length - rem)  buffer.copy(this.alignedBuffer, 0, buffer.length - rem, buffer.length)  this.alignedBytes = rem  return returnBuffer.toString(this.encoding)}
 |