| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 | 
							- var BIT_16            = Math.pow(2, 16);
 
- var BIT_24            = Math.pow(2, 24);
 
- var BUFFER_ALLOC_SIZE = Math.pow(2, 8);
 
- // The maximum precision JS Numbers can hold precisely
 
- // Don't panic: Good enough to represent byte values up to 8192 TB
 
- var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53);
 
- var MAX_PACKET_LENGTH            = Math.pow(2, 24) - 1;
 
- var Buffer                       = require('safe-buffer').Buffer;
 
- module.exports = PacketWriter;
 
- function PacketWriter() {
 
-   this._buffer = null;
 
-   this._offset = 0;
 
- }
 
- PacketWriter.prototype.toBuffer = function toBuffer(parser) {
 
-   if (!this._buffer) {
 
-     this._buffer = Buffer.alloc(0);
 
-     this._offset = 0;
 
-   }
 
-   var buffer  = this._buffer;
 
-   var length  = this._offset;
 
-   var packets = Math.floor(length / MAX_PACKET_LENGTH) + 1;
 
-   this._buffer = Buffer.allocUnsafe(length + packets * 4);
 
-   this._offset = 0;
 
-   for (var packet = 0; packet < packets; packet++) {
 
-     var isLast = (packet + 1 === packets);
 
-     var packetLength = (isLast)
 
-       ? length % MAX_PACKET_LENGTH
 
-       : MAX_PACKET_LENGTH;
 
-     var packetNumber = parser.incrementPacketNumber();
 
-     this.writeUnsignedNumber(3, packetLength);
 
-     this.writeUnsignedNumber(1, packetNumber);
 
-     var start = packet * MAX_PACKET_LENGTH;
 
-     var end   = start + packetLength;
 
-     this.writeBuffer(buffer.slice(start, end));
 
-   }
 
-   return this._buffer;
 
- };
 
- PacketWriter.prototype.writeUnsignedNumber = function(bytes, value) {
 
-   this._allocate(bytes);
 
-   for (var i = 0; i < bytes; i++) {
 
-     this._buffer[this._offset++] = (value >> (i * 8)) & 0xff;
 
-   }
 
- };
 
- PacketWriter.prototype.writeFiller = function(bytes) {
 
-   this._allocate(bytes);
 
-   for (var i = 0; i < bytes; i++) {
 
-     this._buffer[this._offset++] = 0x00;
 
-   }
 
- };
 
- PacketWriter.prototype.writeNullTerminatedString = function(value, encoding) {
 
-   // Typecast undefined into '' and numbers into strings
 
-   value = value || '';
 
-   value = value + '';
 
-   var bytes = Buffer.byteLength(value, encoding || 'utf-8') + 1;
 
-   this._allocate(bytes);
 
-   this._buffer.write(value, this._offset, encoding);
 
-   this._buffer[this._offset + bytes - 1] = 0x00;
 
-   this._offset += bytes;
 
- };
 
- PacketWriter.prototype.writeString = function(value) {
 
-   // Typecast undefined into '' and numbers into strings
 
-   value = value || '';
 
-   value = value + '';
 
-   var bytes = Buffer.byteLength(value, 'utf-8');
 
-   this._allocate(bytes);
 
-   this._buffer.write(value, this._offset, 'utf-8');
 
-   this._offset += bytes;
 
- };
 
- PacketWriter.prototype.writeBuffer = function(value) {
 
-   var bytes = value.length;
 
-   this._allocate(bytes);
 
-   value.copy(this._buffer, this._offset);
 
-   this._offset += bytes;
 
- };
 
- PacketWriter.prototype.writeLengthCodedNumber = function(value) {
 
-   if (value === null) {
 
-     this._allocate(1);
 
-     this._buffer[this._offset++] = 251;
 
-     return;
 
-   }
 
-   if (value <= 250) {
 
-     this._allocate(1);
 
-     this._buffer[this._offset++] = value;
 
-     return;
 
-   }
 
-   if (value > IEEE_754_BINARY_64_PRECISION) {
 
-     throw new Error(
 
-       'writeLengthCodedNumber: JS precision range exceeded, your ' +
 
-       'number is > 53 bit: "' + value + '"'
 
-     );
 
-   }
 
-   if (value < BIT_16) {
 
-     this._allocate(3);
 
-     this._buffer[this._offset++] = 252;
 
-   } else if (value < BIT_24) {
 
-     this._allocate(4);
 
-     this._buffer[this._offset++] = 253;
 
-   } else {
 
-     this._allocate(9);
 
-     this._buffer[this._offset++] = 254;
 
-   }
 
-   // 16 Bit
 
-   this._buffer[this._offset++] = value & 0xff;
 
-   this._buffer[this._offset++] = (value >> 8) & 0xff;
 
-   if (value < BIT_16) {
 
-     return;
 
-   }
 
-   // 24 Bit
 
-   this._buffer[this._offset++] = (value >> 16) & 0xff;
 
-   if (value < BIT_24) {
 
-     return;
 
-   }
 
-   this._buffer[this._offset++] = (value >> 24) & 0xff;
 
-   // Hack: Get the most significant 32 bit (JS bitwise operators are 32 bit)
 
-   value = value.toString(2);
 
-   value = value.substr(0, value.length - 32);
 
-   value = parseInt(value, 2);
 
-   this._buffer[this._offset++] = value & 0xff;
 
-   this._buffer[this._offset++] = (value >> 8) & 0xff;
 
-   this._buffer[this._offset++] = (value >> 16) & 0xff;
 
-   // Set last byte to 0, as we can only support 53 bits in JS (see above)
 
-   this._buffer[this._offset++] = 0;
 
- };
 
- PacketWriter.prototype.writeLengthCodedBuffer = function(value) {
 
-   var bytes = value.length;
 
-   this.writeLengthCodedNumber(bytes);
 
-   this.writeBuffer(value);
 
- };
 
- PacketWriter.prototype.writeNullTerminatedBuffer = function(value) {
 
-   this.writeBuffer(value);
 
-   this.writeFiller(1); // 0x00 terminator
 
- };
 
- PacketWriter.prototype.writeLengthCodedString = function(value) {
 
-   if (value === null) {
 
-     this.writeLengthCodedNumber(null);
 
-     return;
 
-   }
 
-   value = (value === undefined)
 
-     ? ''
 
-     : String(value);
 
-   var bytes = Buffer.byteLength(value, 'utf-8');
 
-   this.writeLengthCodedNumber(bytes);
 
-   if (!bytes) {
 
-     return;
 
-   }
 
-   this._allocate(bytes);
 
-   this._buffer.write(value, this._offset, 'utf-8');
 
-   this._offset += bytes;
 
- };
 
- PacketWriter.prototype._allocate = function _allocate(bytes) {
 
-   if (!this._buffer) {
 
-     this._buffer = Buffer.alloc(Math.max(BUFFER_ALLOC_SIZE, bytes));
 
-     this._offset = 0;
 
-     return;
 
-   }
 
-   var bytesRemaining = this._buffer.length - this._offset;
 
-   if (bytesRemaining >= bytes) {
 
-     return;
 
-   }
 
-   var newSize   = this._buffer.length + Math.max(BUFFER_ALLOC_SIZE, bytes);
 
-   var oldBuffer = this._buffer;
 
-   this._buffer = Buffer.alloc(newSize);
 
-   oldBuffer.copy(this._buffer);
 
- };
 
 
  |