static const nsID*
GetIIDArg(PRUint32 argc, const JS::Value& val, JSContext* cx)
{
    const nsID* iid;

    // If an IID was passed in then use it
    if (argc) {
        JSObject* iidobj;
        if (JSVAL_IS_PRIMITIVE(val) ||
            !(iidobj = JSVAL_TO_OBJECT(val)) ||
            !(iid = xpc_JSObjectToID(cx, iidobj))) {
            return nsnull;
        }
    } else
        iid = &NS_GET_IID(nsISupports);

    return iid;
}
Beispiel #2
0
JSBool XPCVariant::InitializeData(XPCCallContext& ccx)
{
    if(JSVAL_IS_INT(mJSVal))
        return NS_SUCCEEDED(nsVariant::SetFromInt32(&mData, 
                                                   JSVAL_TO_INT(mJSVal)));
    if(JSVAL_IS_DOUBLE(mJSVal))
        return NS_SUCCEEDED(nsVariant::SetFromDouble(&mData, 
                                                     *JSVAL_TO_DOUBLE(mJSVal)));
    if(JSVAL_IS_BOOLEAN(mJSVal))
        return NS_SUCCEEDED(nsVariant::SetFromBool(&mData, 
                                                   JSVAL_TO_BOOLEAN(mJSVal)));
    if(JSVAL_IS_VOID(mJSVal))
        return NS_SUCCEEDED(nsVariant::SetToEmpty(&mData));
    if(JSVAL_IS_NULL(mJSVal))
        return NS_SUCCEEDED(nsVariant::SetToEmpty(&mData));
    if(JSVAL_IS_STRING(mJSVal))
    {
        return NS_SUCCEEDED(nsVariant::SetFromWStringWithSize(&mData, 
                    (PRUint32)JS_GetStringLength(JSVAL_TO_STRING(mJSVal)),
                    (PRUnichar*)JS_GetStringChars(JSVAL_TO_STRING(mJSVal))));
    }

    // leaving only JSObject...
    NS_ASSERTION(JSVAL_IS_OBJECT(mJSVal), "invalid type of jsval!");
    
    JSObject* jsobj = JSVAL_TO_OBJECT(mJSVal);

    // Let's see if it is a xpcJSID.

    // XXX It might be nice to have a non-allocing version of xpc_JSObjectToID.
    nsID* id = xpc_JSObjectToID(ccx, jsobj);
    if(id)
    {
        JSBool success = NS_SUCCEEDED(nsVariant::SetFromID(&mData, *id));
        nsMemory::Free((char*)id);
        return success;
    }
    
    // Let's see if it is a js array object.

    jsuint len;

    if(JS_IsArrayObject(ccx, jsobj) && JS_GetArrayLength(ccx, jsobj, &len))
    {
        if(!len) 
        {
            // Zero length array
            nsVariant::SetToEmptyArray(&mData);
            return JS_TRUE;
        }
        
        nsXPTType type;
        nsID id;

        if(!XPCArrayHomogenizer::GetTypeForArray(ccx, jsobj, len, &type, &id))
            return JS_FALSE; 

        if(!XPCConvert::JSArray2Native(ccx, &mData.u.array.mArrayValue, 
                                       mJSVal, len, len,
                                       type, type.IsPointer(),
                                       &id, nsnull))
            return JS_FALSE;

        mData.mType = nsIDataType::VTYPE_ARRAY;
        if(type.IsInterfacePointer())
            mData.u.array.mArrayInterfaceID = id;
        mData.u.array.mArrayCount = len;
        mData.u.array.mArrayType = type.TagPart();
        
        return JS_TRUE;
    }    

    // XXX This could be smarter and pick some more interesting iface.

    nsXPConnect*  xpc;
    nsCOMPtr<nsISupports> wrapper;
    const nsIID& iid = NS_GET_IID(nsISupports);

    return nsnull != (xpc = nsXPConnect::GetXPConnect()) &&
           NS_SUCCEEDED(xpc->WrapJS(ccx, jsobj,
                        iid, getter_AddRefs(wrapper))) &&
           NS_SUCCEEDED(nsVariant::SetFromInterface(&mData, iid, wrapper));
}