3 var writeIEEE754 = require('./float_parser').writeIEEE754,
4 readIEEE754 = require('./float_parser').readIEEE754,
5 Map = require('./map'),
6 Long = require('./long'),
7 Double = require('./double'),
8 Timestamp = require('./timestamp'),
9 ObjectID = require('./objectid'),
10 BSONRegExp = require('./regexp'),
11 Symbol = require('./symbol'),
12 Int32 = require('./int_32'),
13 Code = require('./code'),
14 Decimal128 = require('./decimal128'),
15 MinKey = require('./min_key'),
16 MaxKey = require('./max_key'),
17 DBRef = require('./db_ref'),
18 Binary = require('./binary');
20 // Parts of the parser
21 var deserialize = require('./parser/deserializer'),
22 serializer = require('./parser/serializer'),
23 calculateObjectSize = require('./parser/calculate_size');
30 var MAXSIZE = (1024*1024*17);
31 // Max Document Buffer size
32 var buffer = new Buffer(MAXSIZE);
34 var BSON = function() {
38 * Serialize a Javascript object.
40 * @param {Object} object the Javascript object to serialize.
41 * @param {Boolean} [options.checkKeys] the serializer will check if keys are valid.
42 * @param {Boolean} [options.serializeFunctions=false] serialize the javascript functions **(default:false)**.
43 * @param {Boolean} [options.ignoreUndefined=true] ignore undefined fields **(default:true)**.
44 * @return {Buffer} returns the Buffer object containing the serialized object.
47 BSON.prototype.serialize = function serialize(object, options) {
48 options = options || {};
50 var checkKeys = typeof options.checkKeys == 'boolean'
51 ? options.checkKeys : false;
52 var serializeFunctions = typeof options.serializeFunctions == 'boolean'
53 ? options.serializeFunctions : false;
54 var ignoreUndefined = typeof options.ignoreUndefined == 'boolean'
55 ? options.ignoreUndefined : true;
57 // Attempt to serialize
58 var serializationIndex = serializer(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, []);
59 // Create the final buffer
60 var finishedBuffer = new Buffer(serializationIndex);
61 // Copy into the finished buffer
62 buffer.copy(finishedBuffer, 0, 0, finishedBuffer.length);
64 return finishedBuffer;
68 * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization.
70 * @param {Object} object the Javascript object to serialize.
71 * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object.
72 * @param {Boolean} [options.checkKeys] the serializer will check if keys are valid.
73 * @param {Boolean} [options.serializeFunctions=false] serialize the javascript functions **(default:false)**.
74 * @param {Boolean} [options.ignoreUndefined=true] ignore undefined fields **(default:true)**.
75 * @param {Number} [options.index] the index in the buffer where we wish to start serializing into.
76 * @return {Number} returns the index pointing to the last written byte in the buffer.
79 BSON.prototype.serializeWithBufferAndIndex = function(object, finalBuffer, options) {
80 options = options || {};
82 var checkKeys = typeof options.checkKeys == 'boolean'
83 ? options.checkKeys : false;
84 var serializeFunctions = typeof options.serializeFunctions == 'boolean'
85 ? options.serializeFunctions : false;
86 var ignoreUndefined = typeof options.ignoreUndefined == 'boolean'
87 ? options.ignoreUndefined : true;
88 var startIndex = typeof options.index == 'number'
91 // Attempt to serialize
92 var serializationIndex = serializer(buffer, object, checkKeys, startIndex || 0, 0, serializeFunctions, ignoreUndefined);
93 buffer.copy(finalBuffer, startIndex, 0, serializationIndex);
96 return serializationIndex - 1;
100 * Deserialize data as BSON.
102 * @param {Buffer} buffer the buffer containing the serialized set of BSON documents.
103 * @param {Object} [options.evalFunctions=false] evaluate functions in the BSON document scoped to the object deserialized.
104 * @param {Object} [options.cacheFunctions=false] cache evaluated functions for reuse.
105 * @param {Object} [options.cacheFunctionsCrc32=false] use a crc32 code for caching, otherwise use the string of the function.
106 * @param {Object} [options.promoteLongs=true] when deserializing a Long will fit it into a Number if it's smaller than 53 bits
107 * @param {Object} [options.promoteBuffers=false] when deserializing a Binary will return it as a node.js Buffer instance.
108 * @param {Object} [options.promoteValues=false] when deserializing will promote BSON values to their Node.js closest equivalent types.
109 * @param {Object} [options.fieldsAsRaw=null] allow to specify if there what fields we wish to return as unserialized raw buffer.
110 * @param {Object} [options.bsonRegExp=false] return BSON regular expressions as BSONRegExp instances.
111 * @return {Object} returns the deserialized Javascript Object.
114 BSON.prototype.deserialize = function(buffer, options) {
115 return deserialize(buffer, options);
119 * Calculate the bson size for a passed in Javascript object.
121 * @param {Object} object the Javascript object to calculate the BSON byte size for.
122 * @param {Boolean} [options.serializeFunctions=false] serialize the javascript functions **(default:false)**.
123 * @param {Boolean} [options.ignoreUndefined=true] ignore undefined fields **(default:true)**.
124 * @return {Number} returns the number of bytes the BSON object will take up.
127 BSON.prototype.calculateObjectSize = function(object, options) {
128 options = options || {};
130 var serializeFunctions = typeof options.serializeFunctions == 'boolean'
131 ? options.serializeFunctions : false;
132 var ignoreUndefined = typeof options.ignoreUndefined == 'boolean'
133 ? options.ignoreUndefined : true;
135 return calculateObjectSize(object, serializeFunctions, ignoreUndefined);
139 * Deserialize stream data as BSON documents.
141 * @param {Buffer} data the buffer containing the serialized set of BSON documents.
142 * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start.
143 * @param {Number} numberOfDocuments number of documents to deserialize.
144 * @param {Array} documents an array where to store the deserialized documents.
145 * @param {Number} docStartIndex the index in the documents array from where to start inserting documents.
146 * @param {Object} [options] additional options used for the deserialization.
147 * @param {Object} [options.evalFunctions=false] evaluate functions in the BSON document scoped to the object deserialized.
148 * @param {Object} [options.cacheFunctions=false] cache evaluated functions for reuse.
149 * @param {Object} [options.cacheFunctionsCrc32=false] use a crc32 code for caching, otherwise use the string of the function.
150 * @param {Object} [options.promoteLongs=true] when deserializing a Long will fit it into a Number if it's smaller than 53 bits
151 * @param {Object} [options.promoteBuffers=false] when deserializing a Binary will return it as a node.js Buffer instance.
152 * @param {Object} [options.promoteValues=false] when deserializing will promote BSON values to their Node.js closest equivalent types.
153 * @param {Object} [options.fieldsAsRaw=null] allow to specify if there what fields we wish to return as unserialized raw buffer.
154 * @param {Object} [options.bsonRegExp=false] return BSON regular expressions as BSONRegExp instances.
155 * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents.
158 BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) {
159 options = options != null ? options : {};
160 var index = startIndex;
161 // Loop over all documents
162 for(var i = 0; i < numberOfDocuments; i++) {
163 // Find size of the document
164 var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24;
165 // Update options with index
166 options['index'] = index;
167 // Parse the document at this point
168 documents[docStartIndex + i] = this.deserialize(data, options);
169 // Adjust index by the document size
170 index = index + size;
173 // Return object containing end index of parsing and list of documents
182 BSON.BSON_INT32_MAX = 0x7FFFFFFF;
183 BSON.BSON_INT32_MIN = -0x80000000;
185 BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1;
186 BSON.BSON_INT64_MIN = -Math.pow(2, 63);
188 // JS MAX PRECISE VALUES
189 BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double.
190 BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double.
192 // Internal long versions
193 var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double.
194 var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double.
199 * @classconstant BSON_DATA_NUMBER
201 BSON.BSON_DATA_NUMBER = 1;
205 * @classconstant BSON_DATA_STRING
207 BSON.BSON_DATA_STRING = 2;
211 * @classconstant BSON_DATA_OBJECT
213 BSON.BSON_DATA_OBJECT = 3;
217 * @classconstant BSON_DATA_ARRAY
219 BSON.BSON_DATA_ARRAY = 4;
223 * @classconstant BSON_DATA_BINARY
225 BSON.BSON_DATA_BINARY = 5;
229 * @classconstant BSON_DATA_OID
231 BSON.BSON_DATA_OID = 7;
235 * @classconstant BSON_DATA_BOOLEAN
237 BSON.BSON_DATA_BOOLEAN = 8;
241 * @classconstant BSON_DATA_DATE
243 BSON.BSON_DATA_DATE = 9;
247 * @classconstant BSON_DATA_NULL
249 BSON.BSON_DATA_NULL = 10;
253 * @classconstant BSON_DATA_REGEXP
255 BSON.BSON_DATA_REGEXP = 11;
259 * @classconstant BSON_DATA_CODE
261 BSON.BSON_DATA_CODE = 13;
265 * @classconstant BSON_DATA_SYMBOL
267 BSON.BSON_DATA_SYMBOL = 14;
269 * Code with Scope BSON Type
271 * @classconstant BSON_DATA_CODE_W_SCOPE
273 BSON.BSON_DATA_CODE_W_SCOPE = 15;
275 * 32 bit Integer BSON Type
277 * @classconstant BSON_DATA_INT
279 BSON.BSON_DATA_INT = 16;
281 * Timestamp BSON Type
283 * @classconstant BSON_DATA_TIMESTAMP
285 BSON.BSON_DATA_TIMESTAMP = 17;
289 * @classconstant BSON_DATA_LONG
291 BSON.BSON_DATA_LONG = 18;
295 * @classconstant BSON_DATA_MIN_KEY
297 BSON.BSON_DATA_MIN_KEY = 0xff;
301 * @classconstant BSON_DATA_MAX_KEY
303 BSON.BSON_DATA_MAX_KEY = 0x7f;
306 * Binary Default Type
308 * @classconstant BSON_BINARY_SUBTYPE_DEFAULT
310 BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0;
312 * Binary Function Type
314 * @classconstant BSON_BINARY_SUBTYPE_FUNCTION
316 BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1;
318 * Binary Byte Array Type
320 * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY
322 BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2;
326 * @classconstant BSON_BINARY_SUBTYPE_UUID
328 BSON.BSON_BINARY_SUBTYPE_UUID = 3;
332 * @classconstant BSON_BINARY_SUBTYPE_MD5
334 BSON.BSON_BINARY_SUBTYPE_MD5 = 4;
336 * Binary User Defined Type
338 * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED
340 BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128;
343 module.exports = BSON;
344 module.exports.Code = Code;
345 module.exports.Map = Map;
346 module.exports.Symbol = Symbol;
347 module.exports.BSON = BSON;
348 module.exports.DBRef = DBRef;
349 module.exports.Binary = Binary;
350 module.exports.ObjectID = ObjectID;
351 module.exports.Long = Long;
352 module.exports.Timestamp = Timestamp;
353 module.exports.Double = Double;
354 module.exports.Int32 = Int32;
355 module.exports.MinKey = MinKey;
356 module.exports.MaxKey = MaxKey;
357 module.exports.BSONRegExp = BSONRegExp;
358 module.exports.Decimal128 = Decimal128;