summaryrefslogtreecommitdiff
path: root/scripting
diff options
context:
space:
mode:
authoragirbal <antoine@10gen.com>2011-07-03 18:47:14 -0700
committeragirbal <antoine@10gen.com>2011-07-03 18:47:14 -0700
commit5dcc4f9d49173b5e67909714f3bf39f918d2398a (patch)
tree7a412611a9b4d00cea2791aec7ec3dc6b646b35e /scripting
parent758a9c734164ecda21cdc5f96436fed88bdfd24f (diff)
downloadmongo-5dcc4f9d49173b5e67909714f3bf39f918d2398a.tar.gz
SERVER-854: NumberInt implemented in SM
Diffstat (limited to 'scripting')
-rw-r--r--scripting/engine_spidermonkey.cpp20
-rw-r--r--scripting/engine_spidermonkey.h1
-rw-r--r--scripting/sm_db.cpp73
3 files changed, 93 insertions, 1 deletions
diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp
index 9189153d12a..01aacbe49ca 100644
--- a/scripting/engine_spidermonkey.cpp
+++ b/scripting/engine_spidermonkey.cpp
@@ -242,6 +242,10 @@ namespace mongo {
return val;
}
+ int toNumberInt( JSObject *o ) {
+ return (boost::uint32_t)(boost::int32_t) getNumber( o, "floatApprox" );
+ }
+
double toNumber( jsval v ) {
double d;
uassert( 10214 , "not a number" , JS_ValueToNumber( _context , v , &d ) );
@@ -566,6 +570,19 @@ namespace mongo {
return OBJECT_TO_JSVAL( o );
}
+ void makeIntObj( int n, JSObject * o ) {
+ boost::uint32_t val = (boost::uint32_t)n;
+ CHECKNEWOBJECT(o,_context,"NumberInt1");
+ double floatApprox = (double)(boost::int32_t)val;
+ setProperty( o , "floatApprox" , toval( floatApprox ) );
+ }
+
+ jsval toval( int n ) {
+ JSObject * o = JS_NewObject( _context , &numberint_class , 0 , 0 );
+ makeIntObj( n, o );
+ return OBJECT_TO_JSVAL( o );
+ }
+
jsval toval( const BSONElement& e ) {
switch( e.type() ) {
@@ -574,8 +591,9 @@ namespace mongo {
case Undefined:
return JSVAL_NULL;
case NumberDouble:
- case NumberInt:
return toval( e.number() );
+ case NumberInt:
+ return toval( e.numberInt() );
case Symbol: // TODO: should we make a special class for this
case String:
return toval( e.valuestr() );
diff --git a/scripting/engine_spidermonkey.h b/scripting/engine_spidermonkey.h
index 3ee74953444..0554adbf836 100644
--- a/scripting/engine_spidermonkey.h
+++ b/scripting/engine_spidermonkey.h
@@ -95,6 +95,7 @@ namespace mongo {
extern JSClass bindata_class;
extern JSClass timestamp_class;
extern JSClass numberlong_class;
+ extern JSClass numberint_class;
extern JSClass minkey_class;
extern JSClass maxkey_class;
diff --git a/scripting/sm_db.cpp b/scripting/sm_db.cpp
index 189c81b454f..c2e4bd42984 100644
--- a/scripting/sm_db.cpp
+++ b/scripting/sm_db.cpp
@@ -938,6 +938,73 @@ zzz
{ 0 }
};
+ JSClass numberint_class = {
+ "NumberInt" , JSCLASS_HAS_PRIVATE ,
+ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+ JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub,
+ JSCLASS_NO_OPTIONAL_MEMBERS
+ };
+
+ JSBool numberint_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) {
+ smuassert( cx , "NumberInt needs 0 or 1 args" , argc == 0 || argc == 1 );
+
+ if ( ! JS_InstanceOf( cx , obj , &numberint_class , 0 ) ) {
+ obj = JS_NewObject( cx , &numberint_class , 0 , 0 );
+ CHECKNEWOBJECT( obj, cx, "numberint_constructor" );
+ *rval = OBJECT_TO_JSVAL( obj );
+ }
+
+ Convertor c( cx );
+ if ( argc == 0 ) {
+ c.setProperty( obj, "floatApprox", c.toval( 0.0 ) );
+ }
+ else if ( JSVAL_IS_NUMBER( argv[ 0 ] ) ) {
+ c.setProperty( obj, "floatApprox", argv[ 0 ] );
+ }
+ else {
+ string num = c.toString( argv[ 0 ] );
+ //PRINT(num);
+ const char *numStr = num.c_str();
+ int n;
+ try {
+ n = (int) parseLL( numStr );
+ //PRINT(n);
+ }
+ catch ( const AssertionException & ) {
+ smuassert( cx , "could not convert string to integer" , false );
+ }
+ c.makeIntObj( n, obj );
+ }
+
+ return JS_TRUE;
+ }
+
+ JSBool numberint_valueof(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
+ Convertor c(cx);
+ return *rval = c.toval( double( c.toNumberInt( obj ) ) );
+ }
+
+ JSBool numberint_tonumber(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
+ return numberint_valueof( cx, obj, argc, argv, rval );
+ }
+
+ JSBool numberint_tostring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
+ Convertor c(cx);
+ stringstream ss;
+ int val = c.toNumberInt( obj );
+ ss << "NumberInt(" << val << ")";
+
+ string ret = ss.str();
+ return *rval = c.toval( ret.c_str() );
+ }
+
+ JSFunctionSpec numberint_functions[] = {
+ { "valueOf" , numberint_valueof , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } ,
+ { "toNumber" , numberint_tonumber , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } ,
+ { "toString" , numberint_tostring , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } ,
+ { 0 }
+ };
+
JSClass minkey_class = {
"MinKey" , JSCLASS_HAS_PRIVATE ,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
@@ -1044,6 +1111,7 @@ zzz
assert( JS_InitClass( cx , global , 0 , &timestamp_class , timestamp_constructor , 0 , 0 , 0 , 0 , 0 ) );
assert( JS_InitClass( cx , global , 0 , &numberlong_class , numberlong_constructor , 0 , 0 , numberlong_functions , 0 , 0 ) );
+ assert( JS_InitClass( cx , global , 0 , &numberint_class , numberint_constructor , 0 , 0 , numberint_functions , 0 , 0 ) );
assert( JS_InitClass( cx , global , 0 , &minkey_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
assert( JS_InitClass( cx , global , 0 , &maxkey_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
@@ -1088,6 +1156,11 @@ zzz
return true;
}
+ if ( JS_InstanceOf( c->_context , o , &numberint_class , 0 ) ) {
+ b.append( name , c->toNumberInt( o ) );
+ return true;
+ }
+
if ( JS_InstanceOf( c->_context , o , &dbpointer_class , 0 ) ) {
b.appendDBRef( name , c->getString( o , "ns" ) , c->toOID( c->getProperty( o , "id" ) ) );
return true;