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} checkKeys the serializer will check if keys are valid.
42 * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**.
43 * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**.
44 * @return {Buffer} returns the Buffer object containing the serialized object.
47 BSON.prototype.serialize = function serialize(object, checkKeys, asBuffer, serializeFunctions, index, ignoreUndefined) {
48 // Attempt to serialize
49 var serializationIndex = serializer(buffer, object, checkKeys, index || 0, 0, serializeFunctions, ignoreUndefined, []);
50 // Create the final buffer
51 var finishedBuffer = new Buffer(serializationIndex);
52 // Copy into the finished buffer
53 buffer.copy(finishedBuffer, 0, 0, finishedBuffer.length);
55 return finishedBuffer;
59 * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization.
61 * @param {Object} object the Javascript object to serialize.
62 * @param {Boolean} checkKeys the serializer will check if keys are valid.
63 * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object.
64 * @param {Number} index the index in the buffer where we wish to start serializing into.
65 * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**.
66 * @return {Number} returns the index pointing to the last written byte in the buffer.
69 BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, finalBuffer, startIndex, serializeFunctions, ignoreUndefined) {
70 // Attempt to serialize
71 var serializationIndex = serializer(buffer, object, checkKeys, startIndex || 0, 0, serializeFunctions, ignoreUndefined);
72 buffer.copy(finalBuffer, startIndex, 0, serializationIndex);
74 return serializationIndex - 1;
78 * Deserialize data as BSON.
81 * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized.
82 * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse.
83 * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function.
84 * - **promoteLongs** {Boolean, default:true}, when deserializing a Long will fit it into a Number if it's smaller than 53 bits
86 * @param {Buffer} buffer the buffer containing the serialized set of BSON documents.
87 * @param {Object} [options] additional options used for the deserialization.
88 * @param {Boolean} [isArray] ignore used for recursive parsing.
89 * @return {Object} returns the deserialized Javascript Object.
92 BSON.prototype.deserialize = function(data, options) {
93 return deserialize(data, options);
97 * Calculate the bson size for a passed in Javascript object.
99 * @param {Object} object the Javascript object to calculate the BSON byte size for.
100 * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**.
101 * @return {Number} returns the number of bytes the BSON object will take up.
104 BSON.prototype.calculateObjectSize = function(object, serializeFunctions, ignoreUndefined) {
105 return calculateObjectSize(object, serializeFunctions, ignoreUndefined);
109 * Deserialize stream data as BSON documents.
112 * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized.
113 * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse.
114 * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function.
115 * - **promoteLongs** {Boolean, default:true}, when deserializing a Long will fit it into a Number if it's smaller than 53 bits
117 * @param {Buffer} data the buffer containing the serialized set of BSON documents.
118 * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start.
119 * @param {Number} numberOfDocuments number of documents to deserialize.
120 * @param {Array} documents an array where to store the deserialized documents.
121 * @param {Number} docStartIndex the index in the documents array from where to start inserting documents.
122 * @param {Object} [options] additional options used for the deserialization.
123 * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents.
126 BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) {
127 // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents");
128 options = options != null ? options : {};
129 var index = startIndex;
130 // Loop over all documents
131 for(var i = 0; i < numberOfDocuments; i++) {
132 // Find size of the document
133 var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24;
134 // Update options with index
135 options['index'] = index;
136 // Parse the document at this point
137 documents[docStartIndex + i] = this.deserialize(data, options);
138 // Adjust index by the document size
139 index = index + size;
142 // Return object containing end index of parsing and list of documents
151 BSON.BSON_INT32_MAX = 0x7FFFFFFF;
152 BSON.BSON_INT32_MIN = -0x80000000;
154 BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1;
155 BSON.BSON_INT64_MIN = -Math.pow(2, 63);
157 // JS MAX PRECISE VALUES
158 BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double.
159 BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double.
161 // Internal long versions
162 var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double.
163 var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double.
168 * @classconstant BSON_DATA_NUMBER
170 BSON.BSON_DATA_NUMBER = 1;
174 * @classconstant BSON_DATA_STRING
176 BSON.BSON_DATA_STRING = 2;
180 * @classconstant BSON_DATA_OBJECT
182 BSON.BSON_DATA_OBJECT = 3;
186 * @classconstant BSON_DATA_ARRAY
188 BSON.BSON_DATA_ARRAY = 4;
192 * @classconstant BSON_DATA_BINARY
194 BSON.BSON_DATA_BINARY = 5;
198 * @classconstant BSON_DATA_OID
200 BSON.BSON_DATA_OID = 7;
204 * @classconstant BSON_DATA_BOOLEAN
206 BSON.BSON_DATA_BOOLEAN = 8;
210 * @classconstant BSON_DATA_DATE
212 BSON.BSON_DATA_DATE = 9;
216 * @classconstant BSON_DATA_NULL
218 BSON.BSON_DATA_NULL = 10;
222 * @classconstant BSON_DATA_REGEXP
224 BSON.BSON_DATA_REGEXP = 11;
228 * @classconstant BSON_DATA_CODE
230 BSON.BSON_DATA_CODE = 13;
234 * @classconstant BSON_DATA_SYMBOL
236 BSON.BSON_DATA_SYMBOL = 14;
238 * Code with Scope BSON Type
240 * @classconstant BSON_DATA_CODE_W_SCOPE
242 BSON.BSON_DATA_CODE_W_SCOPE = 15;
244 * 32 bit Integer BSON Type
246 * @classconstant BSON_DATA_INT
248 BSON.BSON_DATA_INT = 16;
250 * Timestamp BSON Type
252 * @classconstant BSON_DATA_TIMESTAMP
254 BSON.BSON_DATA_TIMESTAMP = 17;
258 * @classconstant BSON_DATA_LONG
260 BSON.BSON_DATA_LONG = 18;
264 * @classconstant BSON_DATA_MIN_KEY
266 BSON.BSON_DATA_MIN_KEY = 0xff;
270 * @classconstant BSON_DATA_MAX_KEY
272 BSON.BSON_DATA_MAX_KEY = 0x7f;
275 * Binary Default Type
277 * @classconstant BSON_BINARY_SUBTYPE_DEFAULT
279 BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0;
281 * Binary Function Type
283 * @classconstant BSON_BINARY_SUBTYPE_FUNCTION
285 BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1;
287 * Binary Byte Array Type
289 * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY
291 BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2;
295 * @classconstant BSON_BINARY_SUBTYPE_UUID
297 BSON.BSON_BINARY_SUBTYPE_UUID = 3;
301 * @classconstant BSON_BINARY_SUBTYPE_MD5
303 BSON.BSON_BINARY_SUBTYPE_MD5 = 4;
305 * Binary User Defined Type
307 * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED
309 BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128;
312 module.exports = BSON;
313 module.exports.Code = Code;
314 module.exports.Map = Map;
315 module.exports.Symbol = Symbol;
316 module.exports.BSON = BSON;
317 module.exports.DBRef = DBRef;
318 module.exports.Binary = Binary;
319 module.exports.ObjectID = ObjectID;
320 module.exports.Long = Long;
321 module.exports.Timestamp = Timestamp;
322 module.exports.Double = Double;
323 module.exports.Int32 = Int32;
324 module.exports.MinKey = MinKey;
325 module.exports.MaxKey = MaxKey;
326 module.exports.BSONRegExp = BSONRegExp;
327 module.exports.Decimal128 = Decimal128;