35818a3c22cfdcf8f92ebe9a33765b267e89be54
[aai/esr-gui.git] /
1 "use strict"
2
3 var readIEEE754 = require('../float_parser').readIEEE754,
4         f = require('util').format,
5         Long = require('../long').Long,
6   Double = require('../double').Double,
7   Timestamp = require('../timestamp').Timestamp,
8   ObjectID = require('../objectid').ObjectID,
9   Symbol = require('../symbol').Symbol,
10   Code = require('../code').Code,
11   MinKey = require('../min_key').MinKey,
12   MaxKey = require('../max_key').MaxKey,
13         Decimal128 = require('../decimal128'),
14         Int32 = require('../int_32'),
15   DBRef = require('../db_ref').DBRef,
16   BSONRegExp = require('../regexp').BSONRegExp,
17   Binary = require('../binary').Binary;
18
19 var deserialize = function(buffer, options, isArray) {
20         options = options == null ? {} : options;
21         var index = options && options.index ? options.index : 0;
22         // Read the document size
23   var size = buffer[index] | buffer[index+1] << 8 | buffer[index+2] << 16 | buffer[index+3] << 24;
24
25         // Ensure buffer is valid size
26   if(size < 5 || buffer.length < size || (size + index) > buffer.length) {
27                 throw new Error("corrupt bson message");
28         }
29
30         // Illegal end value
31         if(buffer[index + size - 1] != 0) {
32                 throw new Error("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");
33         }
34
35         // Start deserializtion
36         return deserializeObject(buffer, index, options, isArray);
37 }
38
39 var deserializeObject = function(buffer, index, options, isArray) {
40         var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions'];
41   var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions'];
42   var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32'];
43         var fieldsAsRaw = options['fieldsAsRaw'] == null ? null : options['fieldsAsRaw'];
44
45         // Return raw bson buffer instead of parsing it
46         var raw = options['raw'] == null ? false : options['raw'];
47
48         // Return BSONRegExp objects instead of native regular expressions
49   var bsonRegExp = typeof options['bsonRegExp'] == 'boolean' ? options['bsonRegExp'] : false;
50
51         // Controls the promotion of values vs wrapper classes
52         var promoteBuffers = options['promoteBuffers'] == null ? false : options['promoteBuffers'];
53         var promoteLongs = options['promoteLongs'] == null ? true : options['promoteLongs'];
54         var promoteValues = options['promoteValues'] == null ? true : options['promoteValues'];
55
56         // Set the start index
57         var startIndex = index;
58
59   // Validate that we have at least 4 bytes of buffer
60   if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long");
61
62         // Read the document size
63   var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
64
65         // Ensure buffer is valid size
66   if(size < 5 || size > buffer.length) throw new Error("corrupt bson message");
67
68   // Create holding object
69   var object = isArray ? [] : {};
70         // Used for arrays to skip having to perform utf8 decoding
71         var arrayIndex = 0;
72
73   // While we have more left data left keep parsing
74   while(true) {
75     // Read the type
76     var elementType = buffer[index++];
77     // If we get a zero it's the last byte, exit
78     if(elementType == 0) {
79                         break;
80                 }
81
82                 // Get the start search index
83                 var i = index;
84                 // Locate the end of the c string
85                 while(buffer[i] !== 0x00 && i < buffer.length) {
86                         i++
87                 }
88
89                 // If are at the end of the buffer there is a problem with the document
90                 if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString")
91                 var name = isArray ? arrayIndex++ : buffer.toString('utf8', index, i);
92
93                 index = i + 1;
94
95                 if(elementType == BSON.BSON_DATA_STRING) {
96       var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
97                         if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson");
98       object[name] = buffer.toString('utf8', index, index + stringSize - 1);
99       index = index + stringSize;
100                 } else if(elementType == BSON.BSON_DATA_OID) {
101                         var oid = new Buffer(12);
102                         buffer.copy(oid, 0, index, index + 12);
103       object[name] = new ObjectID(oid);
104       index = index + 12;
105                 } else if(elementType == BSON.BSON_DATA_INT && promoteValues == false) {
106                         object[name] = new Int32(buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24);
107                 } else if(elementType == BSON.BSON_DATA_INT) {
108       object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
109                 } else if(elementType == BSON.BSON_DATA_NUMBER && promoteValues == false) {
110                         object[name] = new Double(buffer.readDoubleLE(index));
111                         index = index + 8;
112                 } else if(elementType == BSON.BSON_DATA_NUMBER) {
113                         object[name] = buffer.readDoubleLE(index);
114       index = index + 8;
115                 } else if(elementType == BSON.BSON_DATA_DATE) {
116       var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
117       var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
118       object[name] = new Date(new Long(lowBits, highBits).toNumber());
119                 } else if(elementType == BSON.BSON_DATA_BOOLEAN) {
120                         if(buffer[index] != 0 && buffer[index] != 1) throw new Error('illegal boolean type value');
121       object[name] = buffer[index++] == 1;
122                 } else if(elementType == BSON.BSON_DATA_OBJECT) {
123                         var _index = index;
124       var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24;
125                         if(objectSize <= 0 || objectSize > (buffer.length - index)) throw new Error("bad embedded document length in bson");
126
127                         // We have a raw value
128                         if(raw) {
129               object[name] = buffer.slice(index, index + objectSize);
130                         } else {
131               object[name] = deserializeObject(buffer, _index, options, false);
132                         }
133
134       index = index + objectSize;
135                 } else if(elementType == BSON.BSON_DATA_ARRAY) {
136                         var _index = index;
137       var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24;
138                         var arrayOptions = options;
139
140                         // Stop index
141                         var stopIndex = index + objectSize;
142
143                         // All elements of array to be returned as raw bson
144                         if(fieldsAsRaw && fieldsAsRaw[name]) {
145                                 arrayOptions = {};
146                                 for(var n in options) arrayOptions[n] = options[n];
147                                 arrayOptions['raw'] = true;
148                         }
149
150       object[name] = deserializeObject(buffer, _index, arrayOptions, true);
151       index = index + objectSize;
152
153                         if(buffer[index - 1] != 0) throw new Error('invalid array terminator byte');
154                         if(index != stopIndex) throw new Error('corrupted array bson');
155                 } else if(elementType == BSON.BSON_DATA_UNDEFINED) {
156       object[name] = undefined;
157                 } else if(elementType == BSON.BSON_DATA_NULL) {
158                         object[name] = null;
159                 } else if(elementType == BSON.BSON_DATA_LONG) {
160       // Unpack the low and high bits
161       var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
162       var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
163       var long = new Long(lowBits, highBits);
164       // Promote the long if possible
165       if(promoteLongs && promoteValues == true) {
166         object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long;
167       } else {
168         object[name] = long;
169       }
170                 } else if(elementType == BSON.BSON_DATA_DECIMAL128) {
171                         // Buffer to contain the decimal bytes
172                         var bytes = new Buffer(16);
173                         // Copy the next 16 bytes into the bytes buffer
174                         buffer.copy(bytes, 0, index, index + 16);
175                         // Update index
176                         index = index + 16;
177                         // Assign the new Decimal128 value
178                         var decimal128 = new Decimal128(bytes);
179                         // If we have an alternative mapper use that
180                         object[name] = decimal128.toObject ? decimal128.toObject() : decimal128;
181                 } else if(elementType == BSON.BSON_DATA_BINARY) {
182       var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
183                         var totalBinarySize = binarySize;
184       var subType = buffer[index++];
185
186                         // Did we have a negative binary size, throw
187                         if(binarySize < 0) throw new Error('Negative binary type element size found');
188
189                         // Is the length longer than the document
190                         if(binarySize > buffer.length) throw new Error('Binary type size larger than document size');
191
192                         // Decode as raw Buffer object if options specifies it
193       if(buffer['slice'] != null) {
194         // If we have subtype 2 skip the 4 bytes for the size
195         if(subType == Binary.SUBTYPE_BYTE_ARRAY) {
196           binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
197                                         if(binarySize < 0) throw new Error('Negative binary type element size found for subtype 0x02');
198                                         if(binarySize > (totalBinarySize - 4)) throw new Error('Binary type with subtype 0x02 contains to long binary size');
199                                         if(binarySize < (totalBinarySize - 4)) throw new Error('Binary type with subtype 0x02 contains to short binary size');
200         }
201
202         if(promoteBuffers && promoteValues) {
203           object[name] = buffer.slice(index, index + binarySize);
204         } else {
205           object[name] = new Binary(buffer.slice(index, index + binarySize), subType);
206         }
207       } else {
208         var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize);
209         // If we have subtype 2 skip the 4 bytes for the size
210         if(subType == Binary.SUBTYPE_BYTE_ARRAY) {
211           binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
212                                         if(binarySize < 0) throw new Error('Negative binary type element size found for subtype 0x02');
213                                         if(binarySize > (totalBinarySize - 4)) throw new Error('Binary type with subtype 0x02 contains to long binary size');
214                                         if(binarySize < (totalBinarySize - 4)) throw new Error('Binary type with subtype 0x02 contains to short binary size');
215         }
216
217         // Copy the data
218         for(var i = 0; i < binarySize; i++) {
219           _buffer[i] = buffer[index + i];
220         }
221
222         if(promoteBuffers && promoteValues) {
223           object[name] = _buffer;
224         } else {
225           object[name] = new Binary(_buffer, subType);
226         }
227       }
228
229       // Update the index
230       index = index + binarySize;
231                 } else if(elementType == BSON.BSON_DATA_REGEXP && bsonRegExp == false) {
232                         // Get the start search index
233                         var i = index;
234                         // Locate the end of the c string
235                         while(buffer[i] !== 0x00 && i < buffer.length) {
236                                 i++
237                         }
238                         // If are at the end of the buffer there is a problem with the document
239                         if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString")
240                         // Return the C string
241                         var source = buffer.toString('utf8', index, i);
242       // Create the regexp
243                         index = i + 1;
244
245                         // Get the start search index
246                         var i = index;
247                         // Locate the end of the c string
248                         while(buffer[i] !== 0x00 && i < buffer.length) {
249                                 i++
250                         }
251                         // If are at the end of the buffer there is a problem with the document
252                         if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString")
253                         // Return the C string
254                         var regExpOptions = buffer.toString('utf8', index, i);
255                         index = i + 1;
256
257       // For each option add the corresponding one for javascript
258       var optionsArray = new Array(regExpOptions.length);
259
260       // Parse options
261       for(var i = 0; i < regExpOptions.length; i++) {
262         switch(regExpOptions[i]) {
263           case 'm':
264             optionsArray[i] = 'm';
265             break;
266           case 's':
267             optionsArray[i] = 'g';
268             break;
269           case 'i':
270             optionsArray[i] = 'i';
271             break;
272         }
273       }
274
275       object[name] = new RegExp(source, optionsArray.join(''));
276     } else if(elementType == BSON.BSON_DATA_REGEXP && bsonRegExp == true) {
277                         // Get the start search index
278                         var i = index;
279                         // Locate the end of the c string
280                         while(buffer[i] !== 0x00 && i < buffer.length) {
281                                 i++
282                         }
283                         // If are at the end of the buffer there is a problem with the document
284                         if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString")
285                         // Return the C string
286                         var source = buffer.toString('utf8', index, i);
287       index = i + 1;
288
289                         // Get the start search index
290                         var i = index;
291                         // Locate the end of the c string
292                         while(buffer[i] !== 0x00 && i < buffer.length) {
293                                 i++
294                         }
295                         // If are at the end of the buffer there is a problem with the document
296                         if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString")
297                         // Return the C string
298                         var regExpOptions = buffer.toString('utf8', index, i);
299       index = i + 1;
300
301       // Set the object
302       object[name] = new BSONRegExp(source, regExpOptions);
303                 } else if(elementType == BSON.BSON_DATA_SYMBOL) {
304       var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
305                         if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson");
306       object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1));
307       index = index + stringSize;
308                 } else if(elementType == BSON.BSON_DATA_TIMESTAMP) {
309       var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
310       var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
311       object[name] = new Timestamp(lowBits, highBits);
312                 } else if(elementType == BSON.BSON_DATA_MIN_KEY) {
313       object[name] = new MinKey();
314                 } else if(elementType == BSON.BSON_DATA_MAX_KEY) {
315       object[name] = new MaxKey();
316                 } else if(elementType == BSON.BSON_DATA_CODE) {
317       var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
318                         if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson");
319       var functionString = buffer.toString('utf8', index, index + stringSize - 1);
320
321       // If we are evaluating the functions
322       if(evalFunctions) {
323         var value = null;
324         // If we have cache enabled let's look for the md5 of the function in the cache
325         if(cacheFunctions) {
326           var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString;
327           // Got to do this to avoid V8 deoptimizing the call due to finding eval
328           object[name] = isolateEvalWithHash(functionCache, hash, functionString, object);
329         } else {
330           object[name] = isolateEval(functionString);
331         }
332       } else {
333         object[name]  = new Code(functionString);
334       }
335
336       // Update parse index position
337       index = index + stringSize;
338                 } else if(elementType == BSON.BSON_DATA_CODE_W_SCOPE) {
339       var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
340
341                         // Element cannot be shorter than totalSize + stringSize + documentSize + terminator
342                         if(totalSize < (4 + 4 + 4 + 1)) {
343                                 throw new Error("code_w_scope total size shorter minimum expected length");
344                         }
345
346                         // Get the code string size
347       var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
348                         // Check if we have a valid string
349                         if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson");
350
351       // Javascript function
352       var functionString = buffer.toString('utf8', index, index + stringSize - 1);
353       // Update parse index position
354       index = index + stringSize;
355       // Parse the element
356                         var _index = index;
357       // Decode the size of the object document
358       var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24;
359       // Decode the scope object
360       var scopeObject = deserializeObject(buffer, _index, options, false);
361       // Adjust the index
362       index = index + objectSize;
363
364                         // Check if field length is to short
365                         if(totalSize < (4 + 4 + objectSize + stringSize)) {
366                                 throw new Error('code_w_scope total size is to short, truncating scope');
367                         }
368
369                         // Check if totalSize field is to long
370                         if(totalSize > (4 + 4 + objectSize + stringSize)) {
371                                 throw new Error('code_w_scope total size is to long, clips outer document');
372                         }
373
374       // If we are evaluating the functions
375       if(evalFunctions) {
376         // Contains the value we are going to set
377         var value = null;
378         // If we have cache enabled let's look for the md5 of the function in the cache
379         if(cacheFunctions) {
380           var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString;
381           // Got to do this to avoid V8 deoptimizing the call due to finding eval
382           object[name] = isolateEvalWithHash(functionCache, hash, functionString, object);
383         } else {
384           object[name] = isolateEval(functionString);
385         }
386
387         object[name].scope = scopeObject;
388       } else {
389         object[name]  = new Code(functionString, scopeObject);
390       }
391                 } else if(elementType == BSON.BSON_DATA_DBPOINTER) {
392                         // Get the code string size
393       var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24;
394                         // Check if we have a valid string
395                         if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson");
396                         // Namespace
397       var namespace = buffer.toString('utf8', index, index + stringSize - 1);
398                         // Update parse index position
399       index = index + stringSize;
400
401                         // Read the oid
402                         var oidBuffer = new Buffer(12);
403                         buffer.copy(oidBuffer, 0, index, index + 12);
404       var oid = new ObjectID(oidBuffer);
405
406                         // Update the index
407                         index = index + 12;
408
409                         // Split the namespace
410                         var parts = namespace.split('.');
411                         var db = parts.shift();
412                         var collection = parts.join('.');
413                         // Upgrade to DBRef type
414                         object[name] = new DBRef(collection, oid, db);
415     } else {
416                         throw new Error("Detected unknown BSON type " + elementType.toString(16) + " for fieldname \"" + name + "\", are you using the latest BSON parser");
417                 }
418   }
419
420         // Check if the deserialization was against a valid array/object
421         if(size != (index - startIndex)) {
422                 if(isArray) throw new Error('corrupt array bson');
423                 throw new Error('corrupt object bson');
424         }
425
426   // Check if we have a db ref object
427   if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']);
428   return object;
429 }
430
431 /**
432  * Ensure eval is isolated.
433  *
434  * @ignore
435  * @api private
436  */
437 var isolateEvalWithHash = function(functionCache, hash, functionString, object) {
438   // Contains the value we are going to set
439   var value = null;
440
441   // Check for cache hit, eval if missing and return cached function
442   if(functionCache[hash] == null) {
443     eval("value = " + functionString);
444     functionCache[hash] = value;
445   }
446   // Set the object
447   return functionCache[hash].bind(object);
448 }
449
450 /**
451  * Ensure eval is isolated.
452  *
453  * @ignore
454  * @api private
455  */
456 var isolateEval = function(functionString) {
457   // Contains the value we are going to set
458   var value = null;
459   // Eval the function
460   eval("value = " + functionString);
461   return value;
462 }
463
464 var BSON = {};
465
466 /**
467  * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5
468  *
469  * @ignore
470  * @api private
471  */
472 var functionCache = BSON.functionCache = {};
473
474 /**
475  * Number BSON Type
476  *
477  * @classconstant BSON_DATA_NUMBER
478  **/
479 BSON.BSON_DATA_NUMBER = 1;
480 /**
481  * String BSON Type
482  *
483  * @classconstant BSON_DATA_STRING
484  **/
485 BSON.BSON_DATA_STRING = 2;
486 /**
487  * Object BSON Type
488  *
489  * @classconstant BSON_DATA_OBJECT
490  **/
491 BSON.BSON_DATA_OBJECT = 3;
492 /**
493  * Array BSON Type
494  *
495  * @classconstant BSON_DATA_ARRAY
496  **/
497 BSON.BSON_DATA_ARRAY = 4;
498 /**
499  * Binary BSON Type
500  *
501  * @classconstant BSON_DATA_BINARY
502  **/
503 BSON.BSON_DATA_BINARY = 5;
504 /**
505  * Binary BSON Type
506  *
507  * @classconstant BSON_DATA_UNDEFINED
508  **/
509 BSON.BSON_DATA_UNDEFINED = 6;
510 /**
511  * ObjectID BSON Type
512  *
513  * @classconstant BSON_DATA_OID
514  **/
515 BSON.BSON_DATA_OID = 7;
516 /**
517  * Boolean BSON Type
518  *
519  * @classconstant BSON_DATA_BOOLEAN
520  **/
521 BSON.BSON_DATA_BOOLEAN = 8;
522 /**
523  * Date BSON Type
524  *
525  * @classconstant BSON_DATA_DATE
526  **/
527 BSON.BSON_DATA_DATE = 9;
528 /**
529  * null BSON Type
530  *
531  * @classconstant BSON_DATA_NULL
532  **/
533 BSON.BSON_DATA_NULL = 10;
534 /**
535  * RegExp BSON Type
536  *
537  * @classconstant BSON_DATA_REGEXP
538  **/
539 BSON.BSON_DATA_REGEXP = 11;
540 /**
541  * Code BSON Type
542  *
543  * @classconstant BSON_DATA_DBPOINTER
544  **/
545 BSON.BSON_DATA_DBPOINTER = 12;
546 /**
547  * Code BSON Type
548  *
549  * @classconstant BSON_DATA_CODE
550  **/
551 BSON.BSON_DATA_CODE = 13;
552 /**
553  * Symbol BSON Type
554  *
555  * @classconstant BSON_DATA_SYMBOL
556  **/
557 BSON.BSON_DATA_SYMBOL = 14;
558 /**
559  * Code with Scope BSON Type
560  *
561  * @classconstant BSON_DATA_CODE_W_SCOPE
562  **/
563 BSON.BSON_DATA_CODE_W_SCOPE = 15;
564 /**
565  * 32 bit Integer BSON Type
566  *
567  * @classconstant BSON_DATA_INT
568  **/
569 BSON.BSON_DATA_INT = 16;
570 /**
571  * Timestamp BSON Type
572  *
573  * @classconstant BSON_DATA_TIMESTAMP
574  **/
575 BSON.BSON_DATA_TIMESTAMP = 17;
576 /**
577  * Long BSON Type
578  *
579  * @classconstant BSON_DATA_LONG
580  **/
581 BSON.BSON_DATA_LONG = 18;
582 /**
583  * Long BSON Type
584  *
585  * @classconstant BSON_DATA_DECIMAL128
586  **/
587 BSON.BSON_DATA_DECIMAL128 = 19;
588 /**
589  * MinKey BSON Type
590  *
591  * @classconstant BSON_DATA_MIN_KEY
592  **/
593 BSON.BSON_DATA_MIN_KEY = 0xff;
594 /**
595  * MaxKey BSON Type
596  *
597  * @classconstant BSON_DATA_MAX_KEY
598  **/
599 BSON.BSON_DATA_MAX_KEY = 0x7f;
600
601 /**
602  * Binary Default Type
603  *
604  * @classconstant BSON_BINARY_SUBTYPE_DEFAULT
605  **/
606 BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0;
607 /**
608  * Binary Function Type
609  *
610  * @classconstant BSON_BINARY_SUBTYPE_FUNCTION
611  **/
612 BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1;
613 /**
614  * Binary Byte Array Type
615  *
616  * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY
617  **/
618 BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2;
619 /**
620  * Binary UUID Type
621  *
622  * @classconstant BSON_BINARY_SUBTYPE_UUID
623  **/
624 BSON.BSON_BINARY_SUBTYPE_UUID = 3;
625 /**
626  * Binary MD5 Type
627  *
628  * @classconstant BSON_BINARY_SUBTYPE_MD5
629  **/
630 BSON.BSON_BINARY_SUBTYPE_MD5 = 4;
631 /**
632  * Binary User Defined Type
633  *
634  * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED
635  **/
636 BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128;
637
638 // BSON MAX VALUES
639 BSON.BSON_INT32_MAX = 0x7FFFFFFF;
640 BSON.BSON_INT32_MIN = -0x80000000;
641
642 BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1;
643 BSON.BSON_INT64_MIN = -Math.pow(2, 63);
644
645 // JS MAX PRECISE VALUES
646 BSON.JS_INT_MAX = 0x20000000000000;  // Any integer up to 2^53 can be precisely represented by a double.
647 BSON.JS_INT_MIN = -0x20000000000000;  // Any integer down to -2^53 can be precisely represented by a double.
648
649 // Internal long versions
650 var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000);  // Any integer up to 2^53 can be precisely represented by a double.
651 var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000);  // Any integer down to -2^53 can be precisely represented by a double.
652
653 module.exports = deserialize