Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes
XPCVariant Class Reference

#include <xpcprivate.h>

Inheritance diagram for XPCVariant:
Inheritance graph
[legend]
Collaboration diagram for XPCVariant:
Collaboration graph
[legend]

List of all members.

Public Member Functions

jsval GetJSVal () const
 XPCVariant ()
PRUint8 getAsInt8 ()
PRInt16 getAsInt16 ()
PRInt32 getAsInt32 ()
PRInt64 getAsInt64 ()
PRUint8 getAsUint8 ()
PRUint16 getAsUint16 ()
PRUint32 getAsUint32 ()
PRUint64 getAsUint64 ()
float getAsFloat ()
double getAsDouble ()
PRBool getAsBool ()
char getAsChar ()
wchar getAsWChar ()
nsresult getAsID (out nsID retval)
AString getAsAString ()
DOMString getAsDOMString ()
ACString getAsACString ()
AUTF8String getAsAUTF8String ()
string getAsString ()
wstring getAsWString ()
nsISupports getAsISupports ()
void getAsInterface (out nsIIDPtr iid,[iid_is(iid), retval] out nsQIResult iface)
nsresult getAsArray (out PRUint16 type, out nsIID iid, out PRUint32 count, out voidPtr ptr)
void getAsStringWithSize (out PRUint32 size,[size_is(size), retval] out string str)
void getAsWStringWithSize (out PRUint32 size,[size_is(size), retval] out wstring str)

Static Public Member Functions

NS_DECL_ISUPPORTS static
NS_DECL_NSIVARIANT XPCVariant
newVariant (XPCCallContext &ccx, jsval aJSVal)
static JSBool VariantDataToJS (XPCCallContext &ccx, nsIVariant *variant, JSObject *scope, nsresult *pErr, jsval *pJSVal)
 Convert a variant into a jsval.

Public Attributes

readonly attribute PRUint16 dataType

Protected Member Functions

virtual ~XPCVariant ()
JSBool InitializeData (XPCCallContext &ccx)

Protected Attributes

nsDiscriminatedUnion mData
jsval mJSVal

Detailed Description

Definition at line 3524 of file xpcprivate.h.


Constructor & Destructor Documentation

Definition at line 47 of file xpcvariant.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

XPCVariant::~XPCVariant ( ) [protected, virtual]

Definition at line 53 of file xpcvariant.cpp.

Here is the call graph for this function:


Member Function Documentation

ACString nsIVariant::getAsACString ( ) [inherited]
nsresult nsIVariant::getAsArray ( out PRUint16  type,
out nsIID  iid,
out PRUint32  count,
out voidPtr  ptr 
) [inherited]
AString nsIVariant::getAsAString ( ) [inherited]
AUTF8String nsIVariant::getAsAUTF8String ( ) [inherited]
PRBool nsIVariant::getAsBool ( ) [inherited]
char nsIVariant::getAsChar ( ) [inherited]
DOMString nsIVariant::getAsDOMString ( ) [inherited]
double nsIVariant::getAsDouble ( ) [inherited]
float nsIVariant::getAsFloat ( ) [inherited]
nsresult nsIVariant::getAsID ( out nsID  retval) [inherited]
PRUint8 nsIVariant::getAsInt8 ( ) [inherited]
void nsIVariant::getAsInterface ( out nsIIDPtr  iid,
[iid_is(iid), retval] out nsQIResult  iface 
) [inherited]
nsISupports nsIVariant::getAsISupports ( ) [inherited]
void nsIVariant::getAsStringWithSize ( out PRUint32  size,
[size_is(size), retval] out string  str 
) [inherited]
wchar nsIVariant::getAsWChar ( ) [inherited]
wstring nsIVariant::getAsWString ( ) [inherited]
void nsIVariant::getAsWStringWithSize ( out PRUint32  size,
[size_is(size), retval] out wstring  str 
) [inherited]
jsval XPCVariant::GetJSVal ( ) const [inline]

Definition at line 3536 of file xpcprivate.h.

{return mJSVal;}

Definition at line 240 of file xpcvariant.cpp.

{
    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));
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPCVariant * XPCVariant::newVariant ( XPCCallContext ccx,
jsval  aJSVal 
) [static]

Definition at line 68 of file xpcvariant.cpp.

{
    XPCVariant* variant = new XPCVariant();
    if(!variant)
        return nsnull;
    
    NS_ADDREF(variant);

    variant->mJSVal = aJSVal;

    if(JSVAL_IS_GCTHING(variant->mJSVal))
    {
        JSRuntime* rt;
        if(NS_FAILED(ccx.GetRuntime()->GetJSRuntimeService()->GetRuntime(&rt))||
           !JS_AddNamedRootRT(rt, &variant->mJSVal, "XPCVariant::mJSVal"))
        {
            NS_RELEASE(variant); // Also sets variant to nsnull.
        }
    }

    if(variant && !variant->InitializeData(ccx))
        NS_RELEASE(variant);     // Also sets variant to nsnull.

    return variant;
}

Here is the call graph for this function:

Here is the caller graph for this function:

JSBool XPCVariant::VariantDataToJS ( XPCCallContext ccx,
nsIVariant variant,
JSObject scope,
nsresult pErr,
jsval pJSVal 
) [static]

Convert a variant into a jsval.

Parameters:
ccxthe context for the whole procedure
variantthe variant to convert
scopethe default scope to put on the new JSObject's parent chain
pErr[out] relevant error code, if any.
pJSVal[out] the resulting jsval.

Definition at line 326 of file xpcvariant.cpp.

{
    // Get the type early because we might need to spoof it below.
    PRUint16 type;
    if(NS_FAILED(variant->GetDataType(&type)))
        return JS_FALSE;

    nsCOMPtr<XPCVariant> xpcvariant = do_QueryInterface(variant);
    if(xpcvariant)
    {
        jsval realVal = xpcvariant->GetJSVal();
        if(JSVAL_IS_PRIMITIVE(realVal) || 
           type == nsIDataType::VTYPE_ARRAY ||
           type == nsIDataType::VTYPE_ID)
        {
            // Not a JSObject (or is a JSArray or is a JSObject representing 
            // an nsID),.
            // So, just pass through the underlying data.
            *pJSVal = realVal;
            return JS_TRUE;
        }

        // else, it's an object and we really need to double wrap it if we've 
        // already decided that its 'natural' type is as some sort of interface.
        
        // We just fall through to the code below and let it do what it does.
    }

    // The nsIVariant is not a XPCVariant (or we act like it isn't).
    // So we extract the data and do the Right Thing.
    
    // We ASSUME that the variant implementation can do these conversions...

    nsXPTCVariant xpctvar;
    nsID iid;
    nsAutoString astring;
    nsCAutoString cString;
    nsUTF8String utf8String;
    PRUint32 size;
    xpctvar.flags = 0;
    JSBool success;

    switch(type)
    {
        case nsIDataType::VTYPE_INT8:        
        case nsIDataType::VTYPE_INT16:        
        case nsIDataType::VTYPE_INT32:        
        case nsIDataType::VTYPE_INT64:        
        case nsIDataType::VTYPE_UINT8:        
        case nsIDataType::VTYPE_UINT16:        
        case nsIDataType::VTYPE_UINT32:        
        case nsIDataType::VTYPE_UINT64:        
        case nsIDataType::VTYPE_FLOAT:        
        case nsIDataType::VTYPE_DOUBLE:        
        {
            // Easy. Handle inline.
            if(NS_FAILED(variant->GetAsDouble(&xpctvar.val.d)))
                return JS_FALSE;
            return JS_NewNumberValue(ccx, xpctvar.val.d, pJSVal);
        }
        case nsIDataType::VTYPE_BOOL:        
        {
            // Easy. Handle inline.
            if(NS_FAILED(variant->GetAsBool(&xpctvar.val.b)))
                return JS_FALSE;
            *pJSVal = BOOLEAN_TO_JSVAL(xpctvar.val.b);
            return JS_TRUE;
        }
        case nsIDataType::VTYPE_CHAR: 
            if(NS_FAILED(variant->GetAsChar(&xpctvar.val.c)))
                return JS_FALSE;
            xpctvar.type = (uint8)TD_CHAR;
            break;
        case nsIDataType::VTYPE_WCHAR:        
            if(NS_FAILED(variant->GetAsWChar(&xpctvar.val.wc)))
                return JS_FALSE;
            xpctvar.type = (uint8)TD_WCHAR;
            break;
        case nsIDataType::VTYPE_ID:        
            if(NS_FAILED(variant->GetAsID(&iid)))
                return JS_FALSE;
            xpctvar.type = (uint8)(TD_PNSIID | XPT_TDP_POINTER);
            xpctvar.val.p = &iid;
            break;
        case nsIDataType::VTYPE_ASTRING:        
            if(NS_FAILED(variant->GetAsAString(astring)))
                return JS_FALSE;
            xpctvar.type = (uint8)(TD_ASTRING | XPT_TDP_POINTER);
            xpctvar.val.p = &astring;
            break;
        case nsIDataType::VTYPE_DOMSTRING:
            if(NS_FAILED(variant->GetAsAString(astring)))
                return JS_FALSE;
            xpctvar.type = (uint8)(TD_DOMSTRING | XPT_TDP_POINTER);
            xpctvar.val.p = &astring;
            break;
        case nsIDataType::VTYPE_CSTRING:            
            if(NS_FAILED(variant->GetAsACString(cString)))
                return JS_FALSE;
            xpctvar.type = (uint8)(TD_CSTRING | XPT_TDP_POINTER);
            xpctvar.val.p = &cString;
            break;
        case nsIDataType::VTYPE_UTF8STRING:            
            if(NS_FAILED(variant->GetAsAUTF8String(utf8String)))
                return JS_FALSE;
            xpctvar.type = (uint8)(TD_UTF8STRING | XPT_TDP_POINTER);
            xpctvar.val.p = &utf8String;
            break;       
        case nsIDataType::VTYPE_CHAR_STR:       
            if(NS_FAILED(variant->GetAsString((char**)&xpctvar.val.p)))
                return JS_FALSE;
            xpctvar.type = (uint8)(TD_PSTRING | XPT_TDP_POINTER);
            xpctvar.SetValIsAllocated();
            break;
        case nsIDataType::VTYPE_STRING_SIZE_IS:
            if(NS_FAILED(variant->GetAsStringWithSize(&size, 
                                                      (char**)&xpctvar.val.p)))
                return JS_FALSE;
            xpctvar.type = (uint8)(TD_PSTRING_SIZE_IS | XPT_TDP_POINTER);
            break;
        case nsIDataType::VTYPE_WCHAR_STR:        
            if(NS_FAILED(variant->GetAsWString((PRUnichar**)&xpctvar.val.p)))
                return JS_FALSE;
            xpctvar.type = (uint8)(TD_PWSTRING | XPT_TDP_POINTER);
            xpctvar.SetValIsAllocated();
            break;
        case nsIDataType::VTYPE_WSTRING_SIZE_IS:        
            if(NS_FAILED(variant->GetAsWStringWithSize(&size, 
                                                      (PRUnichar**)&xpctvar.val.p)))
                return JS_FALSE;
            xpctvar.type = (uint8)(TD_PWSTRING_SIZE_IS | XPT_TDP_POINTER);
            break;
        case nsIDataType::VTYPE_INTERFACE:        
        case nsIDataType::VTYPE_INTERFACE_IS:        
        {
            nsID* piid;
            if(NS_FAILED(variant->GetAsInterface(&piid, &xpctvar.val.p)))
                return JS_FALSE;

            iid = *piid;
            nsMemory::Free((char*)piid);

            xpctvar.type = (uint8)(TD_INTERFACE_IS_TYPE | XPT_TDP_POINTER);
            if(xpctvar.val.p)
                xpctvar.SetValIsInterface();
            break;
        }
        case nsIDataType::VTYPE_ARRAY:
        {
            nsDiscriminatedUnion du;
            nsVariant::Initialize(&du);
            nsresult rv;

            rv = variant->GetAsArray(&du.u.array.mArrayType,
                                     &du.u.array.mArrayInterfaceID,
                                     &du.u.array.mArrayCount,
                                     &du.u.array.mArrayValue);
            if(NS_FAILED(rv))
                return JS_FALSE;
        
            // must exit via VARIANT_DONE from here on...
            du.mType = nsIDataType::VTYPE_ARRAY;
            success = JS_FALSE;

            nsXPTType conversionType;
            PRUint16 elementType = du.u.array.mArrayType;
            const nsID* pid = nsnull;

            switch(elementType)
            {
                case nsIDataType::VTYPE_INT8:        
                case nsIDataType::VTYPE_INT16:        
                case nsIDataType::VTYPE_INT32:        
                case nsIDataType::VTYPE_INT64:        
                case nsIDataType::VTYPE_UINT8:        
                case nsIDataType::VTYPE_UINT16:        
                case nsIDataType::VTYPE_UINT32:        
                case nsIDataType::VTYPE_UINT64:        
                case nsIDataType::VTYPE_FLOAT:        
                case nsIDataType::VTYPE_DOUBLE:        
                case nsIDataType::VTYPE_BOOL:        
                case nsIDataType::VTYPE_CHAR:        
                case nsIDataType::VTYPE_WCHAR:        
                    conversionType = nsXPTType((uint8)elementType);
                    break;

                case nsIDataType::VTYPE_ID:        
                case nsIDataType::VTYPE_CHAR_STR:        
                case nsIDataType::VTYPE_WCHAR_STR:        
                    conversionType = nsXPTType((uint8)elementType | XPT_TDP_POINTER);
                    break;

                case nsIDataType::VTYPE_INTERFACE:        
                    pid = &NS_GET_IID(nsISupports);
                    conversionType = nsXPTType((uint8)elementType | XPT_TDP_POINTER);
                    break;

                case nsIDataType::VTYPE_INTERFACE_IS:        
                    pid = &du.u.array.mArrayInterfaceID;
                    conversionType = nsXPTType((uint8)elementType | XPT_TDP_POINTER);
                    break;

                // The rest are illegal.
                case nsIDataType::VTYPE_VOID:        
                case nsIDataType::VTYPE_ASTRING:        
                case nsIDataType::VTYPE_DOMSTRING:        
                case nsIDataType::VTYPE_CSTRING:        
                case nsIDataType::VTYPE_UTF8STRING:        
                case nsIDataType::VTYPE_WSTRING_SIZE_IS:        
                case nsIDataType::VTYPE_STRING_SIZE_IS:        
                case nsIDataType::VTYPE_ARRAY:
                case nsIDataType::VTYPE_EMPTY_ARRAY:
                case nsIDataType::VTYPE_EMPTY:
                default:
                    NS_ERROR("bad type in array!");
                    goto VARIANT_DONE;
            }

            success = 
                XPCConvert::NativeArray2JS(ccx, pJSVal, 
                                           (const void**)&du.u.array.mArrayValue,
                                           conversionType, pid,
                                           du.u.array.mArrayCount, 
                                           scope, pErr);

VARIANT_DONE:                                
            nsVariant::Cleanup(&du);
            return success;
        }        
        case nsIDataType::VTYPE_EMPTY_ARRAY: 
        {
            JSObject* array = JS_NewArrayObject(ccx, 0, nsnull);
            if(!array) 
                return JS_FALSE;
            *pJSVal = OBJECT_TO_JSVAL(array);
            return JS_TRUE;
        }
        case nsIDataType::VTYPE_VOID:        
        case nsIDataType::VTYPE_EMPTY:
            *pJSVal = JSVAL_VOID;
            return JS_TRUE;
        default:
            NS_ERROR("bad type in variant!");
            return JS_FALSE;
    }

    // If we are here then we need to convert the data in the xpctvar.
    
    if(xpctvar.type.TagPart() == TD_PSTRING_SIZE_IS ||
       xpctvar.type.TagPart() == TD_PWSTRING_SIZE_IS)
    {
        success = XPCConvert::NativeStringWithSize2JS(ccx, pJSVal,
                                                      (const void*)&xpctvar.val,
                                                      xpctvar.type,
                                                      size, pErr);
    }
    else
    {
        success = XPCConvert::NativeData2JS(ccx, pJSVal,
                                            (const void*)&xpctvar.val,
                                            xpctvar.type,
                                            &iid, scope, pErr);
    }

    if(xpctvar.IsValAllocated())
        nsMemory::Free((char*)xpctvar.val.p);
    else if(xpctvar.IsValInterface())
        ((nsISupports*)xpctvar.val.p)->Release();

    return success;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

readonly attribute PRUint16 nsIVariant::dataType [inherited]

Definition at line 92 of file nsIVariant.idl.

Definition at line 3561 of file xpcprivate.h.

Definition at line 3562 of file xpcprivate.h.


The documentation for this class was generated from the following files: