6 #include <node_events.h>
7 #include <node_buffer.h>
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);
22 const double LN2 = 0.6931471805599453;
25 const int64_t BSON_INT64_MAX = (int64_t)9223372036854775807LL;
26 const int64_t BSON_INT64_MIN = (int64_t)(-1)*(9223372036854775807LL);
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);
36 const int32_t LONG_BUFFER_SIZE = 64;
38 #define max(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); _a > _b ? _a : _b; })
40 static Handle<Value> VException(const char *msg) {
42 return ThrowException(Exception::Error(String::New(msg)));
45 Persistent<FunctionTemplate> Long::constructor_template;
47 static Persistent<String> low_bits_symbol;
48 static Persistent<String> high_bits_symbol;
50 Long::Long(int32_t low_bits, int32_t high_bits) : ObjectWrap() {
51 this->low_bits = low_bits;
52 this->high_bits = high_bits;
57 Handle<Value> Long::New(const Arguments &args) {
60 // Ensure that we have an parameter
61 if(args.Length() == 1 && args[0]->IsNumber()) {
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
70 } else if(args.Length() == 2 && args[0]->IsNumber() && args[1]->IsNumber()) {
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
80 } else if(args.Length() == 2 && args[0]->IsString() && args[1]->IsString()) {
81 // Parse the strings into int32_t values
83 int32_t high_bits = 0;
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);
89 // Create an instance of long
90 Long *l = new Long(low_bits, high_bits);
91 // Wrap it in the object wrap
96 return VException("Argument passed in must be either a 64 bit number or two 32 bit numbers.");
100 void Long::Initialize(Handle<Object> target) {
101 // Grab the scope of the call from Node
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"));
110 low_bits_symbol = NODE_PSYMBOL("low_");
111 high_bits_symbol = NODE_PSYMBOL("high_");
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);
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);
130 NODE_SET_METHOD(constructor_template->GetFunction(), "fromNumber", FromNumber);
131 NODE_SET_METHOD(constructor_template->GetFunction(), "fromInt", FromInt);
133 // Add class to scope
134 target->Set(String::NewSymbol("Long"), constructor_template->GetFunction());
137 Handle<Value> Long::ToInt(const Arguments &args) {
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());
143 uint32_t low_bits = l->low_bits;
145 return Int32::New(low_bits);
148 Handle<Value> Long::ToNumber(const Arguments &args) {
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());
156 Handle<Value> Long::LowGetter(Local<String> property, const AccessorInfo& info) {
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);
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());
170 l->low_bits = value->Int32Value();
174 Handle<Value> Long::HighGetter(Local<String> property, const AccessorInfo& info) {
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);
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());
188 l->high_bits = value->Int32Value();
192 Handle<Value> Long::Inspect(const Arguments &args) {
193 return ToString(args);
196 Handle<Value> Long::GetLowBits(const Arguments &args) {
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);
207 Handle<Value> Long::GetHighBits(const Arguments &args) {
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);
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;
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;
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);
236 Handle<Value> Long::IsZero(const Arguments &args) {
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());
244 int32_t Long::toInt() {
245 return this->low_bits;
248 char *Long::toString(int32_t opt_radix, char *buffer) {
249 if (opt_radix == 10) {
251 sprintf(buffer,"%lld",toNumber());
254 sprintf(buffer,"%llu",toNumber());
257 else if (opt_radix == 16) {
258 sprintf(buffer,"%llx",toNumber());
261 throw "Unsupported radix";
267 Handle<Value> Long::ToString(const Arguments &args) {
270 Long *l = ObjectWrap::Unwrap<Long>(args.This());
272 char buffer[LONG_BUFFER_SIZE];
273 l->toString(10,buffer);
275 return String::New(buffer);
278 Handle<Value> Long::ToJSON(const Arguments &args) {
279 return ToString(args);
282 Long *Long::shiftRight(int32_t number_bits) {
284 if(number_bits == 0) {
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);
292 return Long::fromBits(high_bits >> (number_bits - 32), high_bits >= 0 ? 0 : -1);
297 Long *Long::shiftLeft(int32_t number_bits) {
299 if(number_bits == 0) {
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)));
307 return Long::fromBits(0, low_bits << (number_bits - 32));
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);
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);
326 Long *half_this = this->shiftRight(1);
327 Long *div_obj = half_this->div(other);
328 Long *approx = div_obj->shiftLeft(1);
332 // Check if we are done
333 if(approx->equals(LONG_ZERO)) {
334 return other->isNegative() ? Long::fromNumber(0) : Long::fromNumber(-1);
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);
348 } else if(other->equals(LONG_MIN_VALUE)) {
349 return new Long(0, 0);
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);
364 Long *neg = this->negate();
365 Long *neg_result = neg->div(other);
366 Long *result = neg_result->negate();
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();
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);
394 Long *Long::multiply(Long *other) {
395 if(this->isZero() || other->isZero()) {
396 return new Long(0, 0);
399 int64_t this_number = this->toNumber();
400 int64_t other_number = other->toNumber();
401 int64_t result = this_number * other_number;
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);
411 return (this->low_bits & 1) == 1;
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();
420 int64_t Long::toNumber() {
421 return (int64_t)(this->high_bits * BSON_INT32_ + this->getLowBitsUnsigned());
424 int64_t Long::getLowBitsUnsigned() {
425 return (this->low_bits >= 0) ? this->low_bits : BSON_INT32_ + this->low_bits;
428 int64_t Long::compare(Long *other) {
429 if(this->equals(other)) {
433 bool this_neg = this->isNegative();
434 bool other_neg = other->isNegative();
435 if(this_neg && !other_neg) {
438 if(!this_neg && other_neg) {
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()) {
453 Long *Long::negate() {
454 if(this->equals(LONG_MIN_VALUE)) {
455 return LONG_MIN_VALUE;
457 Long *not_obj = this->not_();
458 Long *add = not_obj->add(LONG_ONE);
465 return new Long(~this->low_bits, ~this->high_bits);
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);
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);
490 Handle<Value> Long::GreatherThan(const Arguments &args) {
493 if(args.Length() != 1 && !Long::HasInstance(args[0])) return VException("One argument of type Long required");
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());
498 Local<Object> obj = args[0]->ToObject();
499 Long *long_obj = Long::Unwrap<Long>(obj);
501 bool comparision_result = current_long_obj->greaterThan(long_obj);
502 return scope.Close(Boolean::New(comparision_result));
505 Handle<Value> Long::Equals(const Arguments &args) {
508 if(args.Length() != 1 && !Long::HasInstance(args[0])) return VException("One argument of type Long required");
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());
513 Local<Object> obj = args[0]->ToObject();
514 Long *long_obj = Long::Unwrap<Long>(obj);
516 bool comparision_result = (current_long_obj->compare(long_obj) == 0);
517 return scope.Close(Boolean::New(comparision_result));
520 bool Long::greaterThan(Long *other) {
521 return this->compare(other) > 0;
524 bool Long::greaterThanOrEqual(Long *other) {
525 return this->compare(other) >= 0;
528 Handle<Value> Long::FromInt(const Arguments &args) {
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);
541 Long *Long::fromInt(int64_t value) {
542 return new Long((value | 0), (value < 0 ? -1 : 0));
545 Long *Long::fromBits(int32_t low_bits, int32_t high_bits) {
546 return new Long(low_bits, high_bits);
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();
560 int64_t int_value = (int64_t)value;
561 return Long::fromBits((int_value % BSON_INT32_) | 0, (int_value / BSON_INT32_) | 0);
565 Handle<Value> Long::FromNumber(const Arguments &args) {
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);
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);