UNPKG

sadira

Version:

Web framework

1,534 lines (1,348 loc) 157 kB
var bson = (function(){ var pkgmap = {}, global = {}, nativeRequire = typeof require != 'undefined' && require, lib, ties, main, async; function exports(){ return main(); }; exports.main = exports; exports.module = module; exports.packages = pkgmap; exports.pkg = pkg; exports.require = function require(uri){ return pkgmap.main.index.require(uri); }; ties = {}; aliases = {}; return exports; function join() { return normalize(Array.prototype.join.call(arguments, "/")); }; function normalize(path) { var ret = [], parts = path.split('/'), cur, prev; var i = 0, l = parts.length-1; for (; i <= l; i++) { cur = parts[i]; if (cur === "." && prev !== undefined) continue; if (cur === ".." && ret.length && prev !== ".." && prev !== "." && prev !== undefined) { ret.pop(); prev = ret.slice(-1)[0]; } else { if (prev === ".") ret.pop(); ret.push(cur); prev = cur; } } return ret.join("/"); }; function dirname(path) { return path && path.substr(0, path.lastIndexOf("/")) || "."; }; function findModule(workingModule, uri){ var moduleId = join(dirname(workingModule.id), /\.\/$/.test(uri) ? (uri + 'index') : uri ).replace(/\.js$/, ''), moduleIndexId = join(moduleId, 'index'), pkg = workingModule.pkg, module; var i = pkg.modules.length, id; while(i-->0){ id = pkg.modules[i].id; if(id==moduleId || id == moduleIndexId){ module = pkg.modules[i]; break; } } return module; } function newRequire(callingModule){ function require(uri){ var module, pkg; if(/^\./.test(uri)){ module = findModule(callingModule, uri); } else if ( ties && ties.hasOwnProperty( uri ) ) { return ties[uri]; } else if ( aliases && aliases.hasOwnProperty( uri ) ) { return require(aliases[uri]); } else { pkg = pkgmap[uri]; if(!pkg && nativeRequire){ try { pkg = nativeRequire(uri); } catch (nativeRequireError) {} if(pkg) return pkg; } if(!pkg){ throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); } module = pkg.index; } if(!module){ throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); } module.parent = callingModule; return module.call(); }; return require; } function module(parent, id, wrapper){ var mod = { pkg: parent, id: id, wrapper: wrapper }, cached = false; mod.exports = {}; mod.require = newRequire(mod); mod.call = function(){ if(cached) { return mod.exports; } cached = true; global.require = mod.require; mod.wrapper(mod, mod.exports, global, global.require); return mod.exports; }; if(parent.mainModuleId == mod.id){ parent.index = mod; parent.parents.length === 0 && ( main = mod.call ); } parent.modules.push(mod); } function pkg(/* [ parentId ...], wrapper */){ var wrapper = arguments[ arguments.length - 1 ], parents = Array.prototype.slice.call(arguments, 0, arguments.length - 1), ctx = wrapper(parents); pkgmap[ctx.name] = ctx; arguments.length == 1 && ( pkgmap.main = ctx ); return function(modules){ var id; for(id in modules){ module(ctx, id, modules[id]); } }; } }(this)); bson.pkg(function(parents){ return { 'name' : 'bson', 'mainModuleId' : 'bson', 'modules' : [], 'parents' : parents }; })({ 'binary': function(module, exports, global, require, undefined){ /** * Module dependencies. */ if(typeof window === 'undefined') { var Buffer = require('buffer').Buffer; // TODO just use global Buffer } // Binary default subtype var BSON_BINARY_SUBTYPE_DEFAULT = 0; /** * @ignore * @api private */ var writeStringToArray = function(data) { // Create a buffer var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); // Write the content to the buffer for(var i = 0; i < data.length; i++) { buffer[i] = data.charCodeAt(i); } // Write the string to the buffer return buffer; } /** * Convert Array ot Uint8Array to Binary String * * @ignore * @api private */ var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { var result = ""; for(var i = startIndex; i < endIndex; i++) { result = result + String.fromCharCode(byteArray[i]); } return result; }; /** * A class representation of the BSON Binary type. * * Sub types * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. * * @class Represents the Binary BSON type. * @param {Buffer} buffer a buffer object containing the binary data. * @param {Number} [subType] the option binary type. * @return {Grid} */ function Binary(buffer, subType) { if(!(this instanceof Binary)) return new Binary(buffer, subType); this._bsontype = 'Binary'; if(buffer instanceof Number) { this.sub_type = buffer; this.position = 0; } else { this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; this.position = 0; } if(buffer != null && !(buffer instanceof Number)) { // Only accept Buffer, Uint8Array or Arrays if(typeof buffer == 'string') { // Different ways of writing the length of the string for the different types if(typeof Buffer != 'undefined') { this.buffer = new Buffer(buffer); } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { this.buffer = writeStringToArray(buffer); } else { throw new Error("only String, Buffer, Uint8Array or Array accepted"); } } else { this.buffer = buffer; } this.position = buffer.length; } else { if(typeof Buffer != 'undefined') { this.buffer = new Buffer(Binary.BUFFER_SIZE); } else if(typeof Uint8Array != 'undefined'){ this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); } else { this.buffer = new Array(Binary.BUFFER_SIZE); } // Set position to start of buffer this.position = 0; } }; /** * Updates this binary with byte_value. * * @param {Character} byte_value a single byte we wish to write. * @api public */ Binary.prototype.put = function put(byte_value) { // If it's a string and a has more than one character throw an error if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); // Decode the byte value once var decoded_byte = null; if(typeof byte_value == 'string') { decoded_byte = byte_value.charCodeAt(0); } else if(byte_value['length'] != null) { decoded_byte = byte_value[0]; } else { decoded_byte = byte_value; } if(this.buffer.length > this.position) { this.buffer[this.position++] = decoded_byte; } else { if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { // Create additional overflow buffer var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); // Combine the two buffers together this.buffer.copy(buffer, 0, 0, this.buffer.length); this.buffer = buffer; this.buffer[this.position++] = decoded_byte; } else { var buffer = null; // Create a new buffer (typed or normal array) if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); } else { buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); } // We need to copy all the content to the new array for(var i = 0; i < this.buffer.length; i++) { buffer[i] = this.buffer[i]; } // Reassign the buffer this.buffer = buffer; // Write the byte this.buffer[this.position++] = decoded_byte; } } }; /** * Writes a buffer or string to the binary. * * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. * @param {Number} offset specify the binary of where to write the content. * @api public */ Binary.prototype.write = function write(string, offset) { offset = typeof offset == 'number' ? offset : this.position; // If the buffer is to small let's extend the buffer if(this.buffer.length < offset + string.length) { var buffer = null; // If we are in node.js if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { buffer = new Buffer(this.buffer.length + string.length); this.buffer.copy(buffer, 0, 0, this.buffer.length); } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { // Create a new buffer buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) // Copy the content for(var i = 0; i < this.position; i++) { buffer[i] = this.buffer[i]; } } // Assign the new buffer this.buffer = buffer; } if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { string.copy(this.buffer, offset, 0, string.length); this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; // offset = string.length } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { this.buffer.write(string, 'binary', offset); this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; // offset = string.length; } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { for(var i = 0; i < string.length; i++) { this.buffer[offset++] = string[i]; } this.position = offset > this.position ? offset : this.position; } else if(typeof string == 'string') { for(var i = 0; i < string.length; i++) { this.buffer[offset++] = string.charCodeAt(i); } this.position = offset > this.position ? offset : this.position; } }; /** * Reads **length** bytes starting at **position**. * * @param {Number} position read from the given position in the Binary. * @param {Number} length the number of bytes to read. * @return {Buffer} * @api public */ Binary.prototype.read = function read(position, length) { length = length && length > 0 ? length : this.position; // Let's return the data based on the type we have if(this.buffer['slice']) { return this.buffer.slice(position, position + length); } else { // Create a buffer to keep the result var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); for(var i = 0; i < length; i++) { buffer[i] = this.buffer[position++]; } } // Return the buffer return buffer; }; /** * Returns the value of this binary as a string. * * @return {String} * @api public */ Binary.prototype.value = function value(asRaw) { asRaw = asRaw == null ? false : asRaw; // If it's a node.js buffer object if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); } else { if(asRaw) { // we support the slice command use it if(this.buffer['slice'] != null) { return this.buffer.slice(0, this.position); } else { // Create a new buffer to copy content to var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); // Copy content for(var i = 0; i < this.position; i++) { newBuffer[i] = this.buffer[i]; } // Return the buffer return newBuffer; } } else { return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); } } }; /** * Length. * * @return {Number} the length of the binary. * @api public */ Binary.prototype.length = function length() { return this.position; }; /** * @ignore * @api private */ Binary.prototype.toJSON = function() { return this.buffer != null ? this.buffer.toString('base64') : ''; } /** * @ignore * @api private */ Binary.prototype.toString = function(format) { return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; } Binary.BUFFER_SIZE = 256; /** * Default BSON type * * @classconstant SUBTYPE_DEFAULT **/ Binary.SUBTYPE_DEFAULT = 0; /** * Function BSON type * * @classconstant SUBTYPE_DEFAULT **/ Binary.SUBTYPE_FUNCTION = 1; /** * Byte Array BSON type * * @classconstant SUBTYPE_DEFAULT **/ Binary.SUBTYPE_BYTE_ARRAY = 2; /** * OLD UUID BSON type * * @classconstant SUBTYPE_DEFAULT **/ Binary.SUBTYPE_UUID_OLD = 3; /** * UUID BSON type * * @classconstant SUBTYPE_DEFAULT **/ Binary.SUBTYPE_UUID = 4; /** * MD5 BSON type * * @classconstant SUBTYPE_DEFAULT **/ Binary.SUBTYPE_MD5 = 5; /** * User BSON type * * @classconstant SUBTYPE_DEFAULT **/ Binary.SUBTYPE_USER_DEFINED = 128; /** * Expose. */ exports.Binary = Binary; }, 'binary_parser': function(module, exports, global, require, undefined){ /** * Binary Parser. * Jonas Raoni Soares Silva * http://jsfromhell.com/classes/binary-parser [v1.0] */ var chr = String.fromCharCode; var maxBits = []; for (var i = 0; i < 64; i++) { maxBits[i] = Math.pow(2, i); } function BinaryParser (bigEndian, allowExceptions) { if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); this.bigEndian = bigEndian; this.allowExceptions = allowExceptions; }; BinaryParser.warn = function warn (msg) { if (this.allowExceptions) { throw new Error(msg); } return 1; }; BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { var b = new this.Buffer(this.bigEndian, data); b.checkBuffer(precisionBits + exponentBits + 1); var bias = maxBits[exponentBits - 1] - 1 , signal = b.readBits(precisionBits + exponentBits, 1) , exponent = b.readBits(precisionBits, exponentBits) , significand = 0 , divisor = 2 , curByte = b.buffer.length + (-precisionBits >> 3) - 1; do { for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); } while (precisionBits -= startBit); return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); }; BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { var b = new this.Buffer(this.bigEndian || forceBigEndian, data) , x = b.readBits(0, bits) , max = maxBits[bits]; //max = Math.pow( 2, bits ); return signed && x >= max / 2 ? x - max : x; }; BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { var bias = maxBits[exponentBits - 1] - 1 , minExp = -bias + 1 , maxExp = bias , minUnnormExp = minExp - precisionBits , n = parseFloat(data) , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 , exp = 0 , len = 2 * bias + 1 + precisionBits + 3 , bin = new Array(len) , signal = (n = status !== 0 ? 0 : n) < 0 , intPart = Math.floor(n = Math.abs(n)) , floatPart = n - intPart , lastBit , rounded , result , i , j; for (i = len; i; bin[--i] = 0); for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); for (i = -1; ++i < len && !bin[i];); if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { if (!(rounded = bin[lastBit])) { for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); } for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); } for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { ++i; } else if (exp < minExp) { exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); i = bias + 1 - (exp = minExp - 1); } if (intPart || status !== 0) { this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); exp = maxExp + 1; i = bias + 2; if (status == -Infinity) { signal = 1; } else if (isNaN(status)) { bin[i] = 1; } } for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { n += (1 << j) * result.charAt(--i); if (j == 7) { r[r.length] = String.fromCharCode(n); n = 0; } } r[r.length] = n ? String.fromCharCode(n) : ""; return (this.bigEndian ? r.reverse() : r).join(""); }; BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { var max = maxBits[bits]; if (data >= max || data < -(max / 2)) { this.warn("encodeInt::overflow"); data = 0; } if (data < 0) { data += max; } for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); }; BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; // Factor out the encode so it can be shared by add_header and push_int32 BinaryParser.encode_int32 = function encode_int32 (number, asArray) { var a, b, c, d, unsigned; unsigned = (number < 0) ? (number + 0x100000000) : number; a = Math.floor(unsigned / 0xffffff); unsigned &= 0xffffff; b = Math.floor(unsigned / 0xffff); unsigned &= 0xffff; c = Math.floor(unsigned / 0xff); unsigned &= 0xff; d = Math.floor(unsigned); return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); }; BinaryParser.encode_int64 = function encode_int64 (number) { var a, b, c, d, e, f, g, h, unsigned; unsigned = (number < 0) ? (number + 0x10000000000000000) : number; a = Math.floor(unsigned / 0xffffffffffffff); unsigned &= 0xffffffffffffff; b = Math.floor(unsigned / 0xffffffffffff); unsigned &= 0xffffffffffff; c = Math.floor(unsigned / 0xffffffffff); unsigned &= 0xffffffffff; d = Math.floor(unsigned / 0xffffffff); unsigned &= 0xffffffff; e = Math.floor(unsigned / 0xffffff); unsigned &= 0xffffff; f = Math.floor(unsigned / 0xffff); unsigned &= 0xffff; g = Math.floor(unsigned / 0xff); unsigned &= 0xff; h = Math.floor(unsigned); return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); }; /** * UTF8 methods */ // Take a raw binary string and return a utf8 string BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { var len = binaryStr.length , decoded = '' , i = 0 , c = 0 , c1 = 0 , c2 = 0 , c3; while (i < len) { c = binaryStr.charCodeAt(i); if (c < 128) { decoded += String.fromCharCode(c); i++; } else if ((c > 191) && (c < 224)) { c2 = binaryStr.charCodeAt(i+1); decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = binaryStr.charCodeAt(i+1); c3 = binaryStr.charCodeAt(i+2); decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return decoded; }; // Encode a cstring BinaryParser.encode_cstring = function encode_cstring (s) { return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); }; // Take a utf8 string and return a binary string BinaryParser.encode_utf8 = function encode_utf8 (s) { var a = "" , c; for (var n = 0, len = s.length; n < len; n++) { c = s.charCodeAt(n); if (c < 128) { a += String.fromCharCode(c); } else if ((c > 127) && (c < 2048)) { a += String.fromCharCode((c>>6) | 192) ; a += String.fromCharCode((c&63) | 128); } else { a += String.fromCharCode((c>>12) | 224); a += String.fromCharCode(((c>>6) & 63) | 128); a += String.fromCharCode((c&63) | 128); } } return a; }; BinaryParser.hprint = function hprint (s) { var number; for (var i = 0, len = s.length; i < len; i++) { if (s.charCodeAt(i) < 32) { number = s.charCodeAt(i) <= 15 ? "0" + s.charCodeAt(i).toString(16) : s.charCodeAt(i).toString(16); process.stdout.write(number + " ") } else { number = s.charCodeAt(i) <= 15 ? "0" + s.charCodeAt(i).toString(16) : s.charCodeAt(i).toString(16); process.stdout.write(number + " ") } } process.stdout.write("\n\n"); }; BinaryParser.ilprint = function hprint (s) { var number; for (var i = 0, len = s.length; i < len; i++) { if (s.charCodeAt(i) < 32) { number = s.charCodeAt(i) <= 15 ? "0" + s.charCodeAt(i).toString(10) : s.charCodeAt(i).toString(10); require('util').debug(number+' : '); } else { number = s.charCodeAt(i) <= 15 ? "0" + s.charCodeAt(i).toString(10) : s.charCodeAt(i).toString(10); require('util').debug(number+' : '+ s.charAt(i)); } } }; BinaryParser.hlprint = function hprint (s) { var number; for (var i = 0, len = s.length; i < len; i++) { if (s.charCodeAt(i) < 32) { number = s.charCodeAt(i) <= 15 ? "0" + s.charCodeAt(i).toString(16) : s.charCodeAt(i).toString(16); require('util').debug(number+' : '); } else { number = s.charCodeAt(i) <= 15 ? "0" + s.charCodeAt(i).toString(16) : s.charCodeAt(i).toString(16); require('util').debug(number+' : '+ s.charAt(i)); } } }; /** * BinaryParser buffer constructor. */ function BinaryParserBuffer (bigEndian, buffer) { this.bigEndian = bigEndian || 0; this.buffer = []; this.setBuffer(buffer); }; BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { var l, i, b; if (data) { i = l = data.length; b = this.buffer = new Array(l); for (; i; b[l - i] = data.charCodeAt(--i)); this.bigEndian && b.reverse(); } }; BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { return this.buffer.length >= -(-neededBits >> 3); }; BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { if (!this.hasNeededBits(neededBits)) { throw new Error("checkBuffer::missing bytes"); } }; BinaryParserBuffer.prototype.readBits = function readBits (start, length) { //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) function shl (a, b) { for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); return a; } if (start < 0 || length <= 0) { return 0; } this.checkBuffer(start + length); var offsetLeft , offsetRight = start % 8 , curByte = this.buffer.length - ( start >> 3 ) - 1 , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) , diff = curByte - lastByte , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); return sum; }; /** * Expose. */ BinaryParser.Buffer = BinaryParserBuffer; exports.BinaryParser = BinaryParser; }, 'bson': function(module, exports, global, require, undefined){ var Long = require('./long').Long , Double = require('./double').Double , Timestamp = require('./timestamp').Timestamp , ObjectID = require('./objectid').ObjectID , Symbol = require('./symbol').Symbol , Code = require('./code').Code , MinKey = require('./min_key').MinKey , MaxKey = require('./max_key').MaxKey , DBRef = require('./db_ref').DBRef , Binary = require('./binary').Binary , BinaryParser = require('./binary_parser').BinaryParser , writeIEEE754 = require('./float_parser').writeIEEE754 , readIEEE754 = require('./float_parser').readIEEE754 // To ensure that 0.4 of node works correctly var isDate = function isDate(d) { return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; } /** * Create a new BSON instance * * @class Represents the BSON Parser * @return {BSON} instance of BSON Parser. */ function BSON () {}; /** * @ignore * @api private */ // BSON MAX VALUES BSON.BSON_INT32_MAX = 0x7FFFFFFF; BSON.BSON_INT32_MIN = -0x80000000; BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; BSON.BSON_INT64_MIN = -Math.pow(2, 63); // JS MAX PRECISE VALUES BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. // Internal long versions var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. /** * Number BSON Type * * @classconstant BSON_DATA_NUMBER **/ BSON.BSON_DATA_NUMBER = 1; /** * String BSON Type * * @classconstant BSON_DATA_STRING **/ BSON.BSON_DATA_STRING = 2; /** * Object BSON Type * * @classconstant BSON_DATA_OBJECT **/ BSON.BSON_DATA_OBJECT = 3; /** * Array BSON Type * * @classconstant BSON_DATA_ARRAY **/ BSON.BSON_DATA_ARRAY = 4; /** * Binary BSON Type * * @classconstant BSON_DATA_BINARY **/ BSON.BSON_DATA_BINARY = 5; /** * ObjectID BSON Type * * @classconstant BSON_DATA_OID **/ BSON.BSON_DATA_OID = 7; /** * Boolean BSON Type * * @classconstant BSON_DATA_BOOLEAN **/ BSON.BSON_DATA_BOOLEAN = 8; /** * Date BSON Type * * @classconstant BSON_DATA_DATE **/ BSON.BSON_DATA_DATE = 9; /** * null BSON Type * * @classconstant BSON_DATA_NULL **/ BSON.BSON_DATA_NULL = 10; /** * RegExp BSON Type * * @classconstant BSON_DATA_REGEXP **/ BSON.BSON_DATA_REGEXP = 11; /** * Code BSON Type * * @classconstant BSON_DATA_CODE **/ BSON.BSON_DATA_CODE = 13; /** * Symbol BSON Type * * @classconstant BSON_DATA_SYMBOL **/ BSON.BSON_DATA_SYMBOL = 14; /** * Code with Scope BSON Type * * @classconstant BSON_DATA_CODE_W_SCOPE **/ BSON.BSON_DATA_CODE_W_SCOPE = 15; /** * 32 bit Integer BSON Type * * @classconstant BSON_DATA_INT **/ BSON.BSON_DATA_INT = 16; /** * Timestamp BSON Type * * @classconstant BSON_DATA_TIMESTAMP **/ BSON.BSON_DATA_TIMESTAMP = 17; /** * Long BSON Type * * @classconstant BSON_DATA_LONG **/ BSON.BSON_DATA_LONG = 18; /** * MinKey BSON Type * * @classconstant BSON_DATA_MIN_KEY **/ BSON.BSON_DATA_MIN_KEY = 0xff; /** * MaxKey BSON Type * * @classconstant BSON_DATA_MAX_KEY **/ BSON.BSON_DATA_MAX_KEY = 0x7f; /** * Binary Default Type * * @classconstant BSON_BINARY_SUBTYPE_DEFAULT **/ BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; /** * Binary Function Type * * @classconstant BSON_BINARY_SUBTYPE_FUNCTION **/ BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; /** * Binary Byte Array Type * * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY **/ BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; /** * Binary UUID Type * * @classconstant BSON_BINARY_SUBTYPE_UUID **/ BSON.BSON_BINARY_SUBTYPE_UUID = 3; /** * Binary MD5 Type * * @classconstant BSON_BINARY_SUBTYPE_MD5 **/ BSON.BSON_BINARY_SUBTYPE_MD5 = 4; /** * Binary User Defined Type * * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED **/ BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; /** * Calculate the bson size for a passed in Javascript object. * * @param {Object} object the Javascript object to calculate the BSON byte size for. * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. * @return {Number} returns the number of bytes the BSON object will take up. * @api public */ BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { var totalLength = (4 + 1); if(Array.isArray(object)) { for(var i = 0; i < object.length; i++) { totalLength += calculateElement(i.toString(), object[i], serializeFunctions) } } else { // If we have toBSON defined, override the current object if(object.toBSON) { object = object.toBSON(); } // Calculate size for(var key in object) { totalLength += calculateElement(key, object[key], serializeFunctions) } } return totalLength; } /** * @ignore * @api private */ function calculateElement(name, value, serializeFunctions) { var isBuffer = typeof Buffer !== 'undefined'; switch(typeof value) { case 'string': return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; case 'number': if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); } else { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); } } else { // 64 bit return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); } case 'undefined': return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); case 'boolean': return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); case 'object': if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); } else if(value instanceof Date || isDate(value)) { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); } else if(value instanceof Code || value['_bsontype'] == 'Code') { // Calculate size depending on the availability of a scope if(value.scope != null && Object.keys(value.scope).length > 0) { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); } else { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; } } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { // Check what kind of subtype we have if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); } else { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); } } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { // Set up correct object for serialization var ordered_values = { '$ref': value.namespace , '$id' : value.oid }; // Add db reference if it exists if(null != value.db) { ordered_values['$db'] = value.db; } return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 } else { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; } case 'function': // WTF for 0.4.X where typeof /someregexp/ === 'function' if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 } else { if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); } else if(serializeFunctions) { return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; } } } return 0; } /** * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. * * @param {Object} object the Javascript object to serialize. * @param {Boolean} checkKeys the serializer will check if keys are valid. * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. * @param {Number} index the index in the buffer where we wish to start serializing into. * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. * @return {Number} returns the new write index in the Buffer. * @api public */ BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { // Default setting false serializeFunctions = serializeFunctions == null ? false : serializeFunctions; // Write end information (length of the object) var size = buffer.length; // Write the size of the object buffer[index++] = size & 0xff; buffer[index++] = (size >> 8) & 0xff; buffer[index++] = (size >> 16) & 0xff; buffer[index++] = (size >> 24) & 0xff; return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; } /** * @ignore * @api private */ var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { // Process the object if(Array.isArray(object)) { for(var i = 0; i < object.length; i++) { index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); } } else { // If we have toBSON defined, override the current object if(object.toBSON) { object = object.toBSON(); } // Serialize the object for(var key in object) { // Check the key and throw error if it's illegal if (key != '$db' && key != '$ref' && key != '$id') { // dollars and dots ok BSON.checkKey(key, !checkKeys); } // Pack the element index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); } } // Write zero buffer[index++] = 0; return index; } var stringToBytes = function(str) { var ch, st, re = []; for (var i = 0; i < str.length; i++ ) { ch = str.charCodeAt(i); // get char st = []; // set up "stack" do { st.push( ch & 0xFF ); // push byte to stack ch = ch >> 8; // shift value down by 1 byte } while ( ch ); // add stack contents to result // done because chars have "wrong" endianness re = re.concat( st.reverse() ); } // return an array of bytes return re; } var numberOfBytes = function(str) { var ch, st, re = 0; for (var i = 0; i < str.length; i++ ) { ch = str.charCodeAt(i); // get char st = []; // set up "stack" do { st.push( ch & 0xFF ); // push byte to stack ch = ch >> 8; // shift value down by 1 byte } while ( ch ); // add stack contents to result // done because chars have "wrong" endianness re = re + st.length; } // return an array of bytes return re; } /** * @ignore * @api private */ var writeToTypedArray = function(buffer, string, index) { var bytes = stringToBytes(string); for(var i = 0; i < bytes.length; i++) { buffer[index + i] = bytes[i]; } return bytes.length; } /** * @ignore * @api private */ var supportsBuffer = typeof Buffer != 'undefined'; /** * @ignore * @api private */ var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { var startIndex = index; switch(typeof value) { case 'string': // Encode String type buffer[index++] = BSON.BSON_DATA_STRING; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; // Calculate size var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; // Write the size of the string to buffer buffer[index + 3] = (size >> 24) & 0xff; buffer[index + 2] = (size >> 16) & 0xff; buffer[index + 1] = (size >> 8) & 0xff; buffer[index] = size & 0xff; // Ajust the index index = index + 4; // Write the string supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); // Update index index = index + size - 1; // Write zero buffer[index++] = 0; // Return index return index; case 'number': // We have an integer value if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { // If the value fits in 32 bits encode as int, if it fits in a double // encode it as a double, otherwise long if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // Set int type 32 bits or less buffer[index++] = BSON.BSON_DATA_INT; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; // Write the int value buffer[index++] = value & 0xff; buffer[index++] = (value >> 8) & 0xff; buffer[index++] = (value >> 16) & 0xff; buffer[index++] = (value >> 24) & 0xff; } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { // Encode as double buffer[index++] = BSON.BSON_DATA_NUMBER; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; // Write float writeIEEE754(buffer, value, index, 'little', 52, 8); // Ajust index index = index + 8; } else { // Set long type buffer[index++] = BSON.BSON_DATA_LONG; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; var longVal = Long.fromNumber(value); var lowBits = longVal.getLowBits(); var highBits = longVal.getHighBits(); // Encode low bits buffer[index++] = lowBits & 0xff; buffer[index++] = (lowBits >> 8) & 0xff; buffer[index++] = (lowBits >> 16) & 0xff; buffer[index++] = (lowBits >> 24) & 0xff; // Encode high bits buffer[index++] = highBits & 0xff; buffer[index++] = (highBits >> 8) & 0xff; buffer[index++] = (highBits >> 16) & 0xff; buffer[index++] = (highBits >> 24) & 0xff; } } else { // Encode as double buffer[index++] = BSON.BSON_DATA_NUMBER; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; // Write float writeIEEE754(buffer, value, index, 'little', 52, 8); // Ajust index index = index + 8; } return index; case 'undefined': // Set long type buffer[index++] = BSON.BSON_DATA_NULL; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; return index; case 'boolean': // Write the type buffer[index++] = BSON.BSON_DATA_BOOLEAN; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; // Encode the boolean value buffer[index++] = value ? 1 : 0; return index; case 'object': if(value === null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { // Write the type of either min or max key if(value === null) { buffer[index++] = BSON.BSON_DATA_NULL; } else if(value instanceof MinKey) { buffer[index++] = BSON.BSON_DATA_MIN_KEY; } else { buffer[index++] = BSON.BSON_DATA_MAX_KEY; } // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; return index; } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { // Write the type buffer[index++] = BSON.BSON_DATA_OID; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; // Write objectid supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); // Ajust index index = index + 12; return index; } else if(value instanceof Date || isDate(value)) { // Write the type buffer[index++] = BSON.BSON_DATA_DATE; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; // Write the date var dateInMilis = Long.fromNumber(value.getTime()); var lowBits = dateInMilis.getLowBits(); var highBits = dateInMilis.getHighBits(); // Encode low bits buffer[index++] = lowBits & 0xff; buffer[index++] = (lowBits >> 8) & 0xff; buffer[index++] = (lowBits >> 16) & 0xff; buffer[index++] = (lowBits >> 24) & 0xff; // Encode high bits buffer[index++] = highBits & 0xff; buffer[index++] = (highBits >> 8) & 0xff; buffer[index++] = (highBits >> 16) & 0xff; buffer[index++] = (highBits >> 24) & 0xff; return index; } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { // Write the type buffer[index++] = BSON.BSON_DATA_BINARY; // Number of written bytes var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; // Get size of the buffer (current write point) var size = value.length; // Write the size of the string to buffer buffer[index++] = size & 0xff; buffer[index++] = (size >> 8) & 0xff; buffer[index++] = (size >> 16) & 0xff; buffer[index++] = (size >> 24) & 0xff; // Write the default subtype buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; // Copy the content form the binary field to the buffer value.copy(buffer, index, 0, size); // Adjust the index index = index + size; return index; } else if(value instanceof Long || value instanceof Timestamp ||