jsval toval( const BSONElement& e ) { switch( e.type() ) { case EOO: case jstNULL: case Undefined: return JSVAL_NULL; case NumberDouble: case NumberInt: return toval( e.number() ); case Symbol: // TODO: should we make a special class for this case String: return toval( e.valuestr() ); case Bool: return e.boolean() ? JSVAL_TRUE : JSVAL_FALSE; case Object: { BSONObj embed = e.embeddedObject().getOwned(); return toval( &embed ); } case Array: { BSONObj embed = e.embeddedObject().getOwned(); if ( embed.isEmpty() ) { return OBJECT_TO_JSVAL( JS_NewArrayObject( _context , 0 , 0 ) ); } int n = embed.nFields(); JSObject * array = JS_NewArrayObject( _context , n , 0 ); assert( array ); jsval myarray = OBJECT_TO_JSVAL( array ); for ( int i=0; i<n; i++ ) { jsval v = toval( embed[i] ); assert( JS_SetElement( _context , array , i , &v ) ); } return myarray; } case jstOID: { OID oid = e.__oid(); JSObject * o = JS_NewObject( _context , &object_id_class , 0 , 0 ); setProperty( o , "str" , toval( oid.str().c_str() ) ); return OBJECT_TO_JSVAL( o ); } case RegEx: { const char * flags = e.regexFlags(); uintN flagNumber = 0; while ( *flags ) { switch ( *flags ) { case 'g': flagNumber |= JSREG_GLOB; break; case 'i': flagNumber |= JSREG_FOLD; break; case 'm': flagNumber |= JSREG_MULTILINE; break; //case 'y': flagNumber |= JSREG_STICKY; break; default: log() << "warning: unknown regex flag:" << *flags << endl; } flags++; } JSObject * r = JS_NewRegExpObject( _context , (char*)e.regex() , strlen( e.regex() ) , flagNumber ); assert( r ); return OBJECT_TO_JSVAL( r ); } case Code: { JSFunction * func = compileFunction( e.valuestr() ); return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) ); } case CodeWScope: { JSFunction * func = compileFunction( e.codeWScopeCode() ); BSONObj extraScope = e.codeWScopeObject(); if ( ! extraScope.isEmpty() ) { log() << "warning: CodeWScope doesn't transfer to db.eval" << endl; } return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) ); } case Date: return OBJECT_TO_JSVAL( js_NewDateObjectMsec( _context , (jsdouble) e.date().millis ) ); case MinKey: return OBJECT_TO_JSVAL( JS_NewObject( _context , &minkey_class , 0 , 0 ) ); case MaxKey: return OBJECT_TO_JSVAL( JS_NewObject( _context , &maxkey_class , 0 , 0 ) ); case Timestamp: { JSObject * o = JS_NewObject( _context , ×tamp_class , 0 , 0 ); setProperty( o , "t" , toval( (double)(e.timestampTime()) ) ); setProperty( o , "i" , toval( (double)(e.timestampInc()) ) ); return OBJECT_TO_JSVAL( o ); } case NumberLong: { boost::uint64_t val = (boost::uint64_t)e.numberLong(); JSObject * o = JS_NewObject( _context , &numberlong_class , 0 , 0 ); setProperty( o , "floatApprox" , toval( (double)(boost::int64_t)( val ) ) ); if ( (boost::int64_t)val != (boost::int64_t)(double)(boost::int64_t)( val ) ) { // using 2 doubles here instead of a single double because certain double // bit patterns represent undefined values and sm might trash them setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) ); setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) ); } return OBJECT_TO_JSVAL( o ); } case DBRef: { JSObject * o = JS_NewObject( _context , &dbpointer_class , 0 , 0 ); setProperty( o , "ns" , toval( e.dbrefNS() ) ); JSObject * oid = JS_NewObject( _context , &object_id_class , 0 , 0 ); setProperty( oid , "str" , toval( e.dbrefOID().str().c_str() ) ); setProperty( o , "id" , OBJECT_TO_JSVAL( oid ) ); return OBJECT_TO_JSVAL( o ); } case BinData: { JSObject * o = JS_NewObject( _context , &bindata_class , 0 , 0 ); int len; const char * data = e.binData( len ); assert( JS_SetPrivate( _context , o , new BinDataHolder( data ) ) ); setProperty( o , "len" , toval( len ) ); setProperty( o , "type" , toval( (int)e.binDataType() ) ); return OBJECT_TO_JSVAL( o ); } }
nsresult WebCL_convertVectorToJSArrayInVariant(JSContext *cx, nsTArray<cl_image_format> const& aVector, nsIVariant** aResultOut, WebCL_LibCLWrapper*) { D_METHOD_START; NS_ENSURE_ARG_POINTER (aResultOut); nsresult rv; if (!cx) { nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv); NS_ENSURE_SUCCESS (rv, rv); cx = stack->GetSafeJSContext (); NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE); } nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv); NS_ENSURE_SUCCESS (rv, rv); JS_BeginRequest (cx); JSBool ignored = JS_EnterLocalRootScope (cx); (void)ignored; // ignored is there to avoid gcc warnings.. JSObject* jsArr = JS_NewArrayObject (cx, aVector.Length (), NULL); if (!jsArr) { JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } size_t cnt = 0; for (nsTArray<cl_image_format>::index_type i = 0; i < aVector.Length(); ++i) { JSObject* jsObj = JS_NewObject (cx, NULL, NULL, NULL); if (jsObj) { js::Value propChannelOrder; propChannelOrder.setInt32 (aVector[i].image_channel_order); js::Value propChannelDataType; propChannelDataType.setInt32 (aVector[i].image_channel_data_type); JS_SetProperty(cx, jsObj, "channelOrder", &propChannelOrder); JS_SetProperty(cx, jsObj, "channelDataType", &propChannelDataType); JS_SetProperty(cx, jsObj, "image_channel_order", &propChannelOrder); JS_SetProperty(cx, jsObj, "image_channel_data_type", &propChannelDataType); js::Value objVal; objVal.setObjectOrNull (jsObj); JS_SetElement (cx, jsArr, cnt++, &objVal); } } JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); if (NS_FAILED (rv)) return rv; // Wrap the JSArray in an nsIVariant nsCOMPtr<nsIVariant> value; js::Value jsValue; jsValue.setObjectOrNull (jsArr); rv = xpc->JSValToVariant(cx, &jsValue, getter_AddRefs(value)); NS_ENSURE_SUCCESS (rv, rv); NS_ADDREF (*aResultOut = value); return NS_OK; }
nsresult WebCL_createVersionObject (JSContext *cx, nsIVariant** aResultOut) { D_METHOD_START; nsresult rv; if (!cx) { return NS_ERROR_INVALID_ARG; } nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv); NS_ENSURE_SUCCESS (rv, rv); JS_BeginRequest (cx); JSBool ignored = JS_EnterLocalRootScope (cx); (void)ignored; // ignored is there to avoid gcc warnings.. JSObject* jsArr = JS_NewArrayObject (cx, 4, NULL); if (!jsArr) { JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } js::Value val; val.setNumber ((double)WEBCL_VERSION_MAJOR); JS_SetElement (cx, jsArr, 0, &val); val.setNumber ((double)WEBCL_VERSION_MINOR); JS_SetElement (cx, jsArr, 1, &val); val.setNumber ((double)WEBCL_VERSION_RELEASE); JS_SetElement (cx, jsArr, 2, &val); // nsCString buildDate = WEBCL_BUILD_DATE; val = STRING_TO_JSVAL (JS_NewStringCopyZ (cx, WEBCL_BUILD_DATE)); JS_SetElement (cx, jsArr, 3, &val); JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); if (NS_FAILED (rv)) { return rv; } nsCOMPtr<nsIVariant> value; js::Value jsValue; jsValue.setObject (*jsArr); rv = xpc->JSValToVariant(cx, &jsValue, getter_AddRefs(value)); NS_ENSURE_SUCCESS (rv, rv); NS_ADDREF (*aResultOut = value); return NS_OK; /* nsTArray<int> version; version.SetCapacity (4); version.AppendElement (WEBCL_VERSION_MAJOR); version.AppendElement (WEBCL_VERSION_MINOR); version.AppendElement (WEBCL_VERSION_RELEASE); version.AppendElement (WEBCL_BUILD_DATE); return WebCL_convertVectorToJSArrayInVariant<int> (cx, version, types::INT_V, aResultOut, 0); */ }
nsresult WebCL_convertVectorToJSArrayInVariant_string(JSContext *cx, nsTArray<nsCString> const& aVector, int aType, nsIVariant** aResultOut, WebCL_LibCLWrapper*) { D_METHOD_START; NS_ENSURE_ARG_POINTER (aResultOut); nsresult rv; switch (aType) { case types::STRING_V: // Accept string vector types break; default: { D_LOG (LOG_LEVEL_ERROR, "Unsupported type %d, expected types::STRING_V", aType); return NS_ERROR_FAILURE; } } if (!cx) { nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv); NS_ENSURE_SUCCESS (rv, rv); cx = stack->GetSafeJSContext (); NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE); } nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv); NS_ENSURE_SUCCESS (rv, rv); JS_BeginRequest (cx); JSBool ignored = JS_EnterLocalRootScope (cx); (void)ignored; // ignored is there to avoid gcc warnings.. JSObject* jsArr = JS_NewArrayObject (cx, aVector.Length (), NULL); if (!jsArr) { JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } size_t cnt = 0; for (nsTArray<nsCString>::index_type i = 0; i < aVector.Length(); ++i) { jsval val = STRING_TO_JSVAL (JS_NewStringCopyZ (cx, aVector[i].get ())); JS_SetElement (cx, jsArr, cnt++, &val); } JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); // Wrap the JSArray in an nsIVariant nsCOMPtr<nsIVariant> value; js::Value jsValue; jsValue.setObjectOrNull (jsArr); rv = xpc->JSValToVariant(cx, &jsValue, getter_AddRefs(value)); NS_ENSURE_SUCCESS (rv, rv); NS_ADDREF (*aResultOut = value); return NS_OK; }
static JSBool rpmxar_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmxarClass, NULL); rpmxar xar = ptr; int ix = 0; _ENUMERATE_DEBUG_ENTRY(_debug < 0); switch (op) { case JSENUMERATE_INIT: case JSENUMERATE_INIT_ALL: if (idp) *idp = JSVAL_ZERO; *statep = INT_TO_JSVAL(ix); if (_debug) fprintf(stderr, "\tINIT xar %p\n", xar); break; case JSENUMERATE_NEXT: ix = JSVAL_TO_INT(*statep); if (!rpmxarNext(xar)) { const char * path = rpmxarPath(xar); struct stat * st = xmalloc(sizeof(*st)); JSObject * arr = JS_NewArrayObject(cx, 0, NULL); JSBool ok = JS_AddRoot(cx, &arr); JSObject * o; jsval v; v = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, path)); ok = JS_SetElement(cx, arr, 0, &v); if (!rpmxarStat(xar, st) && (o = JS_NewObject(cx, &rpmstClass, NULL, NULL)) != NULL && JS_SetPrivate(cx, o, (void *)st)) v = OBJECT_TO_JSVAL(o); else { st = _free(st); v = JSVAL_NULL; } ok = JS_SetElement(cx, arr, 1, &v); v = OBJECT_TO_JSVAL(arr); ok = JS_DefineElement(cx, obj, ix, v, NULL, NULL, JSPROP_ENUMERATE); (void) JS_RemoveRoot(cx, &arr); if (_debug) fprintf(stderr, "\tNEXT xar %p[%u] \"%s\"\n", xar, ix, path); path = _free(path); JS_ValueToId(cx, *statep, idp); *statep = INT_TO_JSVAL(ix+1); } else *idp = JSVAL_VOID; if (!JSID_IS_VOID(*idp)) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: ix = JSVAL_TO_INT(*statep); (void) JS_DefineProperty(cx, obj, "length", INT_TO_JSVAL(ix), NULL, NULL, JSPROP_ENUMERATE); if (_debug) fprintf(stderr, "\tFINI xar %p[%u]\n", xar, ix); *statep = JSVAL_NULL; break; } return JS_TRUE; }