Total Complexity | 134 |
Complexity/F | 33.5 |
Lines of Code | 653 |
Function Count | 4 |
Duplicated Lines | 410 |
Ratio | 62.79 % |
Changes | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like formio/node_modules/bson/lib/bson/parser/deserializer.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
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 | View Code Duplication | 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 | View Code Duplication | 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 |
||
654 |