Inital Commit
[oweals/finalsclub.git] / node_modules / mongodb / external-libs / bson / long.cc
1 #include <assert.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <v8.h>
5 #include <node.h>
6 #include <node_events.h>
7 #include <node_buffer.h>
8 #include <cstring>
9 #include <cmath>
10 #include <cstdlib>
11 #include <iostream>
12 #include <limits>
13
14 #include "local.h"
15 #include "long.h"
16
17 // BSON MAX VALUES
18 const int32_t BSON_INT32_MAX = (int32_t)2147483648L;
19 const int32_t BSON_INT32_MIN = (int32_t)(-1) * 2147483648L;
20 const int64_t BSON_INT32_ = pow(2, 32);
21
22 const double LN2 = 0.6931471805599453;
23
24 // Max Values
25 const int64_t BSON_INT64_MAX = (int64_t)9223372036854775807LL;
26 const int64_t BSON_INT64_MIN = (int64_t)(-1)*(9223372036854775807LL);
27
28 // Constant objects used in calculations
29 Long* LONG_MIN_VALUE = Long::fromBits(0, 0x80000000 | 0);
30 Long* LONG_MAX_VALUE = Long::fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0);
31 Long* LONG_ZERO = Long::fromInt(0);
32 Long* LONG_ONE = Long::fromInt(1);
33 Long* LONG_NEG_ONE = Long::fromInt(-1);
34
35
36 const int32_t LONG_BUFFER_SIZE = 64;
37
38 #define max(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); _a > _b ? _a : _b; })
39
40 static Handle<Value> VException(const char *msg) {
41     HandleScope scope;
42     return ThrowException(Exception::Error(String::New(msg)));
43   };
44
45 Persistent<FunctionTemplate> Long::constructor_template;
46
47 static Persistent<String> low_bits_symbol;
48 static Persistent<String> high_bits_symbol;
49
50 Long::Long(int32_t low_bits, int32_t high_bits) : ObjectWrap() {
51   this->low_bits = low_bits;
52   this->high_bits = high_bits;
53 }
54
55 Long::~Long() {}
56
57 Handle<Value> Long::New(const Arguments &args) {
58   HandleScope scope;
59
60   // Ensure that we have an parameter
61   if(args.Length() == 1 && args[0]->IsNumber()) {
62     // Unpack the value
63     double value = args[0]->NumberValue();
64     // Create an instance of long
65     Long *l = Long::fromNumber(value);
66     // Wrap it in the object wrap
67     l->Wrap(args.This());
68     // Return the context
69     return args.This();
70   } else if(args.Length() == 2 && args[0]->IsNumber() && args[1]->IsNumber()) {
71     // Unpack the value
72     int32_t low_bits = args[0]->Int32Value();
73     int32_t high_bits = args[1]->Int32Value();
74     // Create an instance of long
75     Long *l = new Long(low_bits, high_bits);
76     // Wrap it in the object wrap
77     l->Wrap(args.This());
78     // Return the context
79     return args.This();    
80   } else if(args.Length() == 2 && args[0]->IsString() && args[1]->IsString()) {
81     // Parse the strings into int32_t values
82     int32_t low_bits = 0;
83     int32_t high_bits = 0;
84     
85     // Let's write the strings to the bits
86     DecodeWrite((char*)&low_bits, 4, args[0]->ToString(), BINARY);
87     DecodeWrite((char*)&high_bits, 4, args[1]->ToString(), BINARY);
88
89     // Create an instance of long
90     Long *l = new Long(low_bits, high_bits);
91     // Wrap it in the object wrap
92     l->Wrap(args.This());
93     // Return the context
94     return args.This();        
95   } else {
96     return VException("Argument passed in must be either a 64 bit number or two 32 bit numbers.");
97   }
98 }
99
100 void Long::Initialize(Handle<Object> target) {
101   // Grab the scope of the call from Node
102   HandleScope scope;
103   // Define a new function template
104   Local<FunctionTemplate> t = FunctionTemplate::New(New);
105   constructor_template = Persistent<FunctionTemplate>::New(t);
106   constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
107   constructor_template->SetClassName(String::NewSymbol("Long"));
108   
109   // Propertry symbols
110   low_bits_symbol = NODE_PSYMBOL("low_");
111   high_bits_symbol = NODE_PSYMBOL("high_");  
112   
113   // Instance methods
114   NODE_SET_PROTOTYPE_METHOD(constructor_template, "toString", ToString);
115   NODE_SET_PROTOTYPE_METHOD(constructor_template, "isZero", IsZero);
116   NODE_SET_PROTOTYPE_METHOD(constructor_template, "getLowBits", GetLowBits);
117   NODE_SET_PROTOTYPE_METHOD(constructor_template, "getHighBits", GetHighBits);
118   NODE_SET_PROTOTYPE_METHOD(constructor_template, "inspect", Inspect);  
119   NODE_SET_PROTOTYPE_METHOD(constructor_template, "greaterThan", GreatherThan);  
120   NODE_SET_PROTOTYPE_METHOD(constructor_template, "toInt", ToInt);  
121   NODE_SET_PROTOTYPE_METHOD(constructor_template, "toNumber", ToNumber);  
122   NODE_SET_PROTOTYPE_METHOD(constructor_template, "toJSON", ToJSON);
123   NODE_SET_PROTOTYPE_METHOD(constructor_template, "equals", Equals);
124
125   // Getters for correct serialization of the object  
126   constructor_template->InstanceTemplate()->SetAccessor(low_bits_symbol, LowGetter, LowSetter);
127   constructor_template->InstanceTemplate()->SetAccessor(high_bits_symbol, HighGetter, HighSetter);
128   
129   // Class methods
130   NODE_SET_METHOD(constructor_template->GetFunction(), "fromNumber", FromNumber);
131   NODE_SET_METHOD(constructor_template->GetFunction(), "fromInt", FromInt);
132   
133   // Add class to scope
134   target->Set(String::NewSymbol("Long"), constructor_template->GetFunction());
135 }
136
137 Handle<Value> Long::ToInt(const Arguments &args) {
138   HandleScope scope;
139   
140   // Let's unpack the Long instance that contains the number in low_bits and high_bits form
141   Long *l = ObjectWrap::Unwrap<Long>(args.This());
142   // Get lower bits
143   uint32_t low_bits = l->low_bits;
144   // Return the value
145   return Int32::New(low_bits);
146 }
147
148 Handle<Value> Long::ToNumber(const Arguments &args) {
149   HandleScope scope;  
150   // Let's unpack the Long instance that contains the number in low_bits and high_bits form
151   Long *l = ObjectWrap::Unwrap<Long>(args.This());
152   return Number::New(l->toNumber());
153 }
154
155
156 Handle<Value> Long::LowGetter(Local<String> property, const AccessorInfo& info) {
157   HandleScope scope;
158   
159   // Unpack the long object
160   Long *l = ObjectWrap::Unwrap<Long>(info.Holder());
161   // Return the low bits
162   return Integer::New(l->low_bits);
163 }
164
165 void Long::LowSetter(Local<String> property, Local<Value> value, const AccessorInfo& info) {
166   if(value->IsNumber()) {
167     // Unpack the long object
168     Long *l = ObjectWrap::Unwrap<Long>(info.Holder());
169     // Set the low bits
170     l->low_bits = value->Int32Value();    
171   }
172 }
173
174 Handle<Value> Long::HighGetter(Local<String> property, const AccessorInfo& info) {
175   HandleScope scope;
176
177   // Unpack the long object
178   Long *l = ObjectWrap::Unwrap<Long>(info.Holder());
179   // Return the low bits
180   return Integer::New(l->high_bits);
181 }
182
183 void Long::HighSetter(Local<String> property, Local<Value> value, const AccessorInfo& info) {
184   if(value->IsNumber()) {
185     // Unpack the long object
186     Long *l = ObjectWrap::Unwrap<Long>(info.Holder());
187     // Set the low bits
188     l->high_bits = value->Int32Value();  
189   }
190 }
191
192 Handle<Value> Long::Inspect(const Arguments &args) {
193   return ToString(args);
194 }
195
196 Handle<Value> Long::GetLowBits(const Arguments &args) {
197   HandleScope scope;
198
199   // Let's unpack the Long instance that contains the number in low_bits and high_bits form
200   Long *l = ObjectWrap::Unwrap<Long>(args.This());
201   // Let's fetch the low bits
202   int32_t low_bits = l->low_bits;
203   // Package the result in a V8 Integer object and return
204   return Integer::New(low_bits);  
205 }
206
207 Handle<Value> Long::GetHighBits(const Arguments &args) {
208   HandleScope scope;
209
210   // Let's unpack the Long instance that contains the number in low_bits and high_bits form
211   Long *l = ObjectWrap::Unwrap<Long>(args.This());
212   // Let's fetch the low bits
213   int32_t high_bits = l->high_bits;
214   // Package the result in a V8 Integer object and return
215   return Integer::New(high_bits);    
216 }
217
218 bool Long::isZero() {
219   int32_t low_bits = this->low_bits;
220   int32_t high_bits = this->high_bits;
221   return low_bits == 0 && high_bits == 0;
222 }
223
224 bool Long::isNegative() {
225   int32_t low_bits = this->low_bits;
226   int32_t high_bits = this->high_bits;
227   return high_bits < 0;
228 }
229
230 bool Long::equals(Long *l) {
231   int32_t low_bits = this->low_bits;
232   int32_t high_bits = this->high_bits;  
233   return (high_bits == l->high_bits) && (low_bits == l->low_bits);
234 }
235
236 Handle<Value> Long::IsZero(const Arguments &args) {
237   HandleScope scope;      
238     
239   // Let's unpack the Long instance that contains the number in low_bits and high_bits form
240   Long *l = ObjectWrap::Unwrap<Long>(args.This());
241   return Boolean::New(l->isZero());
242 }
243
244 int32_t Long::toInt() {
245   return this->low_bits;
246 }
247
248 char *Long::toString(int32_t opt_radix, char *buffer) {
249         if (opt_radix == 10) {
250           if (isNegative()) {
251       sprintf(buffer,"%lld",toNumber());
252           }
253           else {
254       sprintf(buffer,"%llu",toNumber());
255           }
256         }
257         else if (opt_radix == 16) {
258       sprintf(buffer,"%llx",toNumber());          
259         }
260         else {
261     throw "Unsupported radix";
262         }
263         
264   return buffer;
265 }
266
267 Handle<Value> Long::ToString(const Arguments &args) {
268   HandleScope scope;
269
270   Long *l = ObjectWrap::Unwrap<Long>(args.This());
271   
272   char buffer[LONG_BUFFER_SIZE];
273   l->toString(10,buffer);
274
275   return String::New(buffer);
276 }
277
278 Handle<Value> Long::ToJSON(const Arguments &args) {
279   return ToString(args);
280 }
281
282 Long *Long::shiftRight(int32_t number_bits) {
283   number_bits &= 63;
284   if(number_bits == 0) {
285     return this;
286   } else {
287     int32_t high_bits = this->high_bits;
288     if(number_bits < 32) {
289       int32_t low_bits = this->low_bits;
290       return Long::fromBits((low_bits >> number_bits) | (high_bits << (32 - number_bits)), high_bits >> number_bits);
291     } else {
292       return Long::fromBits(high_bits >> (number_bits - 32), high_bits >= 0 ? 0 : -1);
293     }
294   }
295 }
296
297 Long *Long::shiftLeft(int32_t number_bits) {
298   number_bits &= 63;
299   if(number_bits == 0) {
300     return this;
301   } else {
302     int32_t low_bits = this->low_bits;
303     if(number_bits < 32) {
304       int32_t high_bits = this->high_bits;
305       return Long::fromBits(low_bits << number_bits, (high_bits << number_bits) | (low_bits >> (32 - number_bits)));
306     } else {
307       return Long::fromBits(0, low_bits << (number_bits - 32));
308     }
309   }  
310 }
311
312 Long *Long::div(Long *other) {
313   // If we are about to do a divide by zero throw an exception
314   if(other->isZero()) {
315     throw "division by zero";
316   } else if(this->isZero()) {
317     return new Long(0, 0);
318   }
319     
320   if(this->equals(LONG_MIN_VALUE)) {    
321     if(other->equals(LONG_ONE) || other->equals(LONG_NEG_ONE)) {
322       return Long::fromBits(0, 0x80000000 | 0);
323     } else if(other->equals(LONG_MIN_VALUE)) {
324       return Long::fromNumber(1);
325     } else {
326       Long *half_this = this->shiftRight(1);
327       Long *div_obj = half_this->div(other);
328       Long *approx = div_obj->shiftLeft(1);
329       // Free memory
330       delete div_obj;
331       delete half_this;
332       // Check if we are done
333       if(approx->equals(LONG_ZERO)) {
334         return other->isNegative() ? Long::fromNumber(0) : Long::fromNumber(-1);
335       } else {
336         Long *mul = other->multiply(approx);
337         Long *rem = this->subtract(mul);
338         Long *rem_div = rem->div(other);
339         Long *result = approx->add(rem_div);
340         // Free memory
341         delete mul;
342         delete rem;
343         delete rem_div;
344         // Return result
345         return result;
346       }
347     }    
348   } else if(other->equals(LONG_MIN_VALUE)) {
349     return new Long(0, 0);
350   }
351   
352   // If the value is negative
353   if(this->isNegative()) {    
354     if(other->isNegative()) {
355       Long *neg = this->negate();
356       Long *other_neg = other->negate();
357       Long *result = neg->div(other_neg);
358       // Free memory
359       delete neg;
360       delete other_neg;
361       // Return result 
362       return result;
363     } else {
364       Long *neg = this->negate();
365       Long *neg_result = neg->div(other);
366       Long *result = neg_result->negate();
367       // Free memory
368       delete neg;
369       delete neg_result;
370       // Return result
371       return result;
372     }
373   } else if(other->isNegative()) {
374     Long *other_neg = other->negate();
375     Long *div_result = this->div(other_neg);
376     Long *result = div_result->negate();
377     // Free memory
378     delete other_neg;
379     delete div_result;
380     // Return the result
381     return result;
382   }  
383   
384   int64_t this_number = this->toNumber();
385   int64_t other_number = other->toNumber();
386   int64_t result = this_number / other_number;
387   // Split into the 32 bit valu
388   int32_t low32, high32;
389   high32 = (uint64_t)result >> 32;
390   low32 = (int32_t)result;
391   return Long::fromBits(low32, high32);
392 }
393
394 Long *Long::multiply(Long *other) {
395   if(this->isZero() || other->isZero()) {
396     return new Long(0, 0);    
397   }
398   
399   int64_t this_number = this->toNumber();
400   int64_t other_number = other->toNumber();
401   int64_t result = this_number * other_number;
402   
403   // Split into the 32 bit valu
404   int32_t low32, high32;
405   high32 = (uint64_t)result >> 32;
406   low32 = (int32_t)result;
407   return Long::fromBits(low32, high32);
408 }
409
410 bool Long::isOdd() {
411   return (this->low_bits & 1) == 1;
412 }
413
414 // /** @return {number} The closest floating-point representation to this value. */
415 // exports.Long.prototype.toNumber = function() {
416 //   return this.high_ * exports.Long.TWO_PWR_32_DBL_ +
417 //          this.getLowBitsUnsigned();
418 // };
419
420 int64_t Long::toNumber() {
421   return (int64_t)(this->high_bits * BSON_INT32_ + this->getLowBitsUnsigned());
422 }
423
424 int64_t Long::getLowBitsUnsigned() {
425   return (this->low_bits >= 0) ? this->low_bits : BSON_INT32_ + this->low_bits;
426 }
427
428 int64_t Long::compare(Long *other) {
429   if(this->equals(other)) {
430     return 0;
431   }
432   
433   bool this_neg = this->isNegative();
434   bool other_neg = other->isNegative();
435   if(this_neg && !other_neg) {
436     return -1;
437   }
438   if(!this_neg && other_neg) {
439     return 1;
440   }
441   
442   Long *return_value = this->subtract(other);  
443   // At this point, the signs are the same, so subtraction will not overflow
444   if(return_value->isNegative()) {
445     delete return_value;
446     return -1;
447   } else {
448     delete return_value;
449     return 1;
450   }
451 }
452
453 Long *Long::negate() {
454   if(this->equals(LONG_MIN_VALUE)) {
455     return LONG_MIN_VALUE;
456   } else {
457     Long *not_obj = this->not_();
458     Long *add = not_obj->add(LONG_ONE);
459     delete not_obj;
460     return add;
461   }
462 }
463
464 Long *Long::not_() {
465   return new Long(~this->low_bits, ~this->high_bits);
466 }
467
468 Long *Long::add(Long *other) {
469   int64_t this_number = this->toNumber();
470   int64_t other_number = other->toNumber();
471   int64_t result = this_number + other_number;  
472   // Split into the 32 bit valu
473   int32_t low32, high32;
474   high32 = (uint64_t)result >> 32;
475   low32 = (int32_t)result;
476   return Long::fromBits(low32, high32);
477 }
478
479 Long *Long::subtract(Long *other) {
480   int64_t this_number = this->toNumber();
481   int64_t other_number = other->toNumber();
482   int64_t result = this_number - other_number;
483   // Split into the 32 bit valu
484   int32_t low32, high32;
485   high32 = (uint64_t)result >> 32;
486   low32 = (int32_t)result;
487   return Long::fromBits(low32, high32);
488 }
489
490 Handle<Value> Long::GreatherThan(const Arguments &args) {
491   HandleScope scope;
492   
493   if(args.Length() != 1 && !Long::HasInstance(args[0])) return VException("One argument of type Long required");
494   
495   // Let's unpack the Long instance that contains the number in low_bits and high_bits form
496   Long *current_long_obj = ObjectWrap::Unwrap<Long>(args.This());  
497   // Unpack Long
498   Local<Object> obj = args[0]->ToObject();
499   Long *long_obj = Long::Unwrap<Long>(obj);
500   // Compare the longs
501   bool comparision_result = current_long_obj->greaterThan(long_obj);
502   return scope.Close(Boolean::New(comparision_result));
503 }
504
505 Handle<Value> Long::Equals(const Arguments &args) {
506   HandleScope scope;
507   
508   if(args.Length() != 1 && !Long::HasInstance(args[0])) return VException("One argument of type Long required");
509   
510   // Let's unpack the Long instance that contains the number in low_bits and high_bits form
511   Long *current_long_obj = ObjectWrap::Unwrap<Long>(args.This());  
512   // Unpack Long
513   Local<Object> obj = args[0]->ToObject();
514   Long *long_obj = Long::Unwrap<Long>(obj);
515   // Compare the longs
516   bool comparision_result = (current_long_obj->compare(long_obj) == 0);
517   return scope.Close(Boolean::New(comparision_result));
518 }
519
520 bool Long::greaterThan(Long *other) {
521   return this->compare(other) > 0;  
522 }
523
524 bool Long::greaterThanOrEqual(Long *other) {
525   return this->compare(other) >= 0;
526 }
527
528 Handle<Value> Long::FromInt(const Arguments &args) {
529   HandleScope scope;
530   
531   // Validate the arguments
532   if(args.Length() != 1 && !args[0]->IsNumber()) return VException("One argument of type number required");
533   // Unwrap Number variable
534   Local<Number> number = args[0]->ToNumber();
535   // Instantiate Long object and return
536   Local<Value> argv[] = {number};
537   Local<Object> long_obj = constructor_template->GetFunction()->NewInstance(1, argv);
538   return scope.Close(long_obj);  
539 }
540
541 Long *Long::fromInt(int64_t value) {
542   return new Long((value | 0), (value < 0 ? -1 : 0));
543 }
544
545 Long *Long::fromBits(int32_t low_bits, int32_t high_bits) {
546   return new Long(low_bits, high_bits);
547 }
548
549 Long *Long::fromNumber(double value) {
550   // Ensure we have a valid ranged number
551   if(std::isinf(value) || std::isnan(value)) {
552     return Long::fromBits(0, 0);
553   } else if(value <= BSON_INT64_MIN) {
554     return Long::fromBits(0, 0x80000000 | 0);
555   } else if(value >= BSON_INT64_MAX) {
556     return Long::fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0);
557   } else if(value < 0) {
558     return Long::fromNumber(-value)->negate();
559   } else {
560     int64_t int_value = (int64_t)value;
561     return Long::fromBits((int_value % BSON_INT32_) | 0, (int_value / BSON_INT32_) | 0);
562   }  
563 }
564
565 Handle<Value> Long::FromNumber(const Arguments &args) {
566   HandleScope scope;
567   
568   // Ensure that we have an parameter
569   if(args.Length() != 1) return VException("One argument required - number.");
570   if(!args[0]->IsNumber()) return VException("Arguments passed in must be numbers.");  
571   // Unpack the variable as a 64 bit integer
572   int64_t value = args[0]->IntegerValue();
573   double double_value = args[0]->NumberValue();
574   // Ensure we have a valid ranged number
575   if(std::isinf(double_value) || std::isnan(double_value)) {
576     Local<Value> argv[] = {Integer::New(0), Integer::New(0)};
577     Local<Object> long_obj = constructor_template->GetFunction()->NewInstance(2, argv);
578     return scope.Close(long_obj);
579   } else if(double_value <= BSON_INT64_MIN) {
580     Local<Value> argv[] = {Integer::New(0), Integer::New(0x80000000 | 0)};
581     Local<Object> long_obj = constructor_template->GetFunction()->NewInstance(2, argv);    
582     return scope.Close(long_obj);    
583   } else if(double_value >= BSON_INT64_MAX) {
584     Local<Value> argv[] = {Integer::New(0xFFFFFFFF | 0), Integer::New(0x7FFFFFFF | 0)};
585     Local<Object> long_obj = constructor_template->GetFunction()->NewInstance(2, argv);    
586     return scope.Close(long_obj);        
587   } else if(double_value < 0) {
588     Local<Value> argv[] = {Number::New(double_value)};
589     Local<Object> long_obj = constructor_template->GetFunction()->NewInstance(1, argv);    
590     return scope.Close(long_obj);    
591   } else {
592     Local<Value> argv[] = {Integer::New((value % BSON_INT32_) | 0), Integer::New((value / BSON_INT32_) | 0)};
593     Local<Object> long_obj = constructor_template->GetFunction()->NewInstance(2, argv);    
594     return scope.Close(long_obj);    
595   }
596 }