b98887eaaaa0b52badcd13c2cadcf2221f5a3b9f
[aai/esr-gui.git] /
1 "use strict"
2
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');
19
20 // Parts of the parser
21 var deserialize = require('./parser/deserializer'),
22         serializer = require('./parser/serializer'),
23         calculateObjectSize = require('./parser/calculate_size');
24
25 /**
26  * @ignore
27  * @api private
28  */
29 // Max Size
30 var MAXSIZE = (1024*1024*17);
31 // Max Document Buffer size
32 var buffer = new Buffer(MAXSIZE);
33
34 var BSON = function() {
35 }
36
37 /**
38  * Serialize a Javascript object.
39  *
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.
45  * @api public
46  */
47 BSON.prototype.serialize = function serialize(object, options) {
48         options = options || {};
49         // Unpack the 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;
56
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);
63         // Return the buffer
64         return finishedBuffer;
65 }
66
67 /**
68  * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization.
69  *
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.
77  * @api public
78  */
79 BSON.prototype.serializeWithBufferAndIndex = function(object, finalBuffer, options) {
80         options = options || {};
81         // Unpack the 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'
89                 ? options.index : 0;
90
91         // Attempt to serialize
92         var serializationIndex = serializer(buffer, object, checkKeys, startIndex || 0, 0, serializeFunctions, ignoreUndefined);
93         buffer.copy(finalBuffer, startIndex, 0, serializationIndex);
94
95         // Return the index
96         return serializationIndex - 1;
97 }
98
99 /**
100  * Deserialize data as BSON.
101  *
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.
112  * @api public
113  */
114 BSON.prototype.deserialize = function(buffer, options) {
115   return deserialize(buffer, options);
116 }
117
118 /**
119  * Calculate the bson size for a passed in Javascript object.
120  *
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.
125  * @api public
126  */
127 BSON.prototype.calculateObjectSize = function(object, options) {
128         options = options || {};
129
130         var serializeFunctions = typeof options.serializeFunctions == 'boolean'
131                 ? options.serializeFunctions : false;
132         var ignoreUndefined = typeof options.ignoreUndefined == 'boolean'
133                 ? options.ignoreUndefined : true;
134
135   return calculateObjectSize(object, serializeFunctions, ignoreUndefined);
136 }
137
138 /**
139  * Deserialize stream data as BSON documents.
140  *
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.
156  * @api public
157  */
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;
171   }
172
173   // Return object containing end index of parsing and list of documents
174   return index;
175 }
176
177 /**
178  * @ignore
179  * @api private
180  */
181 // BSON MAX VALUES
182 BSON.BSON_INT32_MAX = 0x7FFFFFFF;
183 BSON.BSON_INT32_MIN = -0x80000000;
184
185 BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1;
186 BSON.BSON_INT64_MIN = -Math.pow(2, 63);
187
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.
191
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.
195
196 /**
197  * Number BSON Type
198  *
199  * @classconstant BSON_DATA_NUMBER
200  **/
201 BSON.BSON_DATA_NUMBER = 1;
202 /**
203  * String BSON Type
204  *
205  * @classconstant BSON_DATA_STRING
206  **/
207 BSON.BSON_DATA_STRING = 2;
208 /**
209  * Object BSON Type
210  *
211  * @classconstant BSON_DATA_OBJECT
212  **/
213 BSON.BSON_DATA_OBJECT = 3;
214 /**
215  * Array BSON Type
216  *
217  * @classconstant BSON_DATA_ARRAY
218  **/
219 BSON.BSON_DATA_ARRAY = 4;
220 /**
221  * Binary BSON Type
222  *
223  * @classconstant BSON_DATA_BINARY
224  **/
225 BSON.BSON_DATA_BINARY = 5;
226 /**
227  * ObjectID BSON Type
228  *
229  * @classconstant BSON_DATA_OID
230  **/
231 BSON.BSON_DATA_OID = 7;
232 /**
233  * Boolean BSON Type
234  *
235  * @classconstant BSON_DATA_BOOLEAN
236  **/
237 BSON.BSON_DATA_BOOLEAN = 8;
238 /**
239  * Date BSON Type
240  *
241  * @classconstant BSON_DATA_DATE
242  **/
243 BSON.BSON_DATA_DATE = 9;
244 /**
245  * null BSON Type
246  *
247  * @classconstant BSON_DATA_NULL
248  **/
249 BSON.BSON_DATA_NULL = 10;
250 /**
251  * RegExp BSON Type
252  *
253  * @classconstant BSON_DATA_REGEXP
254  **/
255 BSON.BSON_DATA_REGEXP = 11;
256 /**
257  * Code BSON Type
258  *
259  * @classconstant BSON_DATA_CODE
260  **/
261 BSON.BSON_DATA_CODE = 13;
262 /**
263  * Symbol BSON Type
264  *
265  * @classconstant BSON_DATA_SYMBOL
266  **/
267 BSON.BSON_DATA_SYMBOL = 14;
268 /**
269  * Code with Scope BSON Type
270  *
271  * @classconstant BSON_DATA_CODE_W_SCOPE
272  **/
273 BSON.BSON_DATA_CODE_W_SCOPE = 15;
274 /**
275  * 32 bit Integer BSON Type
276  *
277  * @classconstant BSON_DATA_INT
278  **/
279 BSON.BSON_DATA_INT = 16;
280 /**
281  * Timestamp BSON Type
282  *
283  * @classconstant BSON_DATA_TIMESTAMP
284  **/
285 BSON.BSON_DATA_TIMESTAMP = 17;
286 /**
287  * Long BSON Type
288  *
289  * @classconstant BSON_DATA_LONG
290  **/
291 BSON.BSON_DATA_LONG = 18;
292 /**
293  * MinKey BSON Type
294  *
295  * @classconstant BSON_DATA_MIN_KEY
296  **/
297 BSON.BSON_DATA_MIN_KEY = 0xff;
298 /**
299  * MaxKey BSON Type
300  *
301  * @classconstant BSON_DATA_MAX_KEY
302  **/
303 BSON.BSON_DATA_MAX_KEY = 0x7f;
304
305 /**
306  * Binary Default Type
307  *
308  * @classconstant BSON_BINARY_SUBTYPE_DEFAULT
309  **/
310 BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0;
311 /**
312  * Binary Function Type
313  *
314  * @classconstant BSON_BINARY_SUBTYPE_FUNCTION
315  **/
316 BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1;
317 /**
318  * Binary Byte Array Type
319  *
320  * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY
321  **/
322 BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2;
323 /**
324  * Binary UUID Type
325  *
326  * @classconstant BSON_BINARY_SUBTYPE_UUID
327  **/
328 BSON.BSON_BINARY_SUBTYPE_UUID = 3;
329 /**
330  * Binary MD5 Type
331  *
332  * @classconstant BSON_BINARY_SUBTYPE_MD5
333  **/
334 BSON.BSON_BINARY_SUBTYPE_MD5 = 4;
335 /**
336  * Binary User Defined Type
337  *
338  * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED
339  **/
340 BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128;
341
342 // Return BSON
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;