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.
		
		
		
		
		
			
		
			
				
					103 lines
				
				2.8 KiB
			
		
		
			
		
	
	
					103 lines
				
				2.8 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								var util = require('util')
							 | 
						||
| 
								 | 
							
								var Stream = require('stream')
							 | 
						||
| 
								 | 
							
								var StringDecoder = require('string_decoder').StringDecoder
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = StringStream
							 | 
						||
| 
								 | 
							
								module.exports.AlignedStringDecoder = AlignedStringDecoder
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function 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)
							 | 
						||
| 
								 | 
							
								}
							 |