deserializer.js 24 KB

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