1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* nsIVariant implementation for xpconnect. */
9 #include "mozilla/Range.h"
11 #include "xpcprivate.h"
13 #include "jsfriendapi.h"
14 #include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
15 #include "js/friend/StackLimits.h" // js::AutoCheckRecursionLimit
16 #include "js/friend/WindowProxy.h" // js::ToWindowIfWindowProxy
17 #include "js/PropertyAndElement.h" // JS_GetElement
18 #include "js/Wrapper.h"
19 #include "mozilla/HoldDropJSObjects.h"
22 using namespace mozilla
;
25 NS_IMPL_CLASSINFO(XPCVariant
, nullptr, 0, XPCVARIANT_CID
)
26 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCVariant
)
27 NS_INTERFACE_MAP_ENTRY(XPCVariant
)
28 NS_INTERFACE_MAP_ENTRY(nsIVariant
)
29 NS_INTERFACE_MAP_ENTRY(nsISupports
)
30 NS_IMPL_QUERY_CLASSINFO(XPCVariant
)
32 NS_IMPL_CI_INTERFACE_GETTER(XPCVariant
, XPCVariant
, nsIVariant
)
34 NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCVariant
)
35 NS_IMPL_CYCLE_COLLECTING_RELEASE(XPCVariant
)
37 XPCVariant::XPCVariant(JSContext
* cx
, const Value
& aJSVal
) : mJSVal(aJSVal
) {
38 if (!mJSVal
.isPrimitive()) {
39 // XXXbholley - The innerization here was from bug 638026. Blake says
40 // the basic problem was that we were storing the C++ inner but the JS
41 // outer, which meant that, after navigation, the JS inner could be
42 // collected, which would cause us to try to recreate the JS inner at
43 // some later point after teardown, which would crash. This is shouldn't
44 // be a problem anymore because SetParentToWindow will do the right
45 // thing, but I'm saving the cleanup here for another day. Blake thinks
46 // that we should just not store the WN if we're creating a variant for
48 JSObject
* obj
= js::ToWindowIfWindowProxy(&mJSVal
.toObject());
49 mJSVal
= JS::ObjectValue(*obj
);
52 js::CheckedUnwrapDynamic(obj
, cx
, /* stopAtWindowProxy = */ false);
53 mReturnRawObject
= !(unwrapped
&& IsWrappedNativeReflector(unwrapped
));
55 mReturnRawObject
= false;
58 if (aJSVal
.isGCThing()) {
59 mozilla::HoldJSObjects(this);
63 XPCVariant::~XPCVariant() { Cleanup(); }
65 NS_IMPL_CYCLE_COLLECTION_CLASS(XPCVariant
)
67 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPCVariant
)
68 tmp
->mData
.Traverse(cb
);
69 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
71 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPCVariant
)
73 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
75 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(XPCVariant
)
76 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJSVal
)
77 NS_IMPL_CYCLE_COLLECTION_TRACE_END
80 already_AddRefed
<XPCVariant
> XPCVariant::newVariant(JSContext
* cx
,
81 const Value
& aJSVal
) {
82 RefPtr
<XPCVariant
> variant
= new XPCVariant(cx
, aJSVal
);
83 if (!variant
->InitializeData(cx
)) {
87 return variant
.forget();
90 void XPCVariant::Cleanup() {
93 if (!GetJSValPreserveColor().isGCThing()) {
96 mJSVal
= JS::NullValue();
97 mozilla::DropJSObjects(this);
100 // Helper class to give us a namespace for the table based code below.
101 class XPCArrayHomogenizer
{
104 tNull
= 0, // null value
111 tISup
, // nsISupports (really just a plain JSObject)
112 tUnk
, // Unknown. Used only for initial state.
114 tTypeCount
, // Just a count for table dimensioning.
116 tVar
, // nsVariant - last ditch if no other common type found.
117 tErr
// No valid state or type has this value.
120 // Table has tUnk as a state (column) but not as a type (row).
121 static const Type StateTable
[tTypeCount
][tTypeCount
- 1];
124 static bool GetTypeForArray(JSContext
* cx
, HandleObject array
,
125 uint32_t length
, nsXPTType
* resultType
,
129 // Current state is the column down the side.
130 // Current type is the row along the top.
131 // New state is in the box at the intersection.
133 const XPCArrayHomogenizer::Type
134 XPCArrayHomogenizer::StateTable
[tTypeCount
][tTypeCount
- 1] = {
135 /* tNull,tInt ,tDbl ,tBool,tStr ,tID ,tArr ,tISup */
136 /* tNull */ {tNull
, tVar
, tVar
, tVar
, tStr
, tID
, tVar
, tISup
},
137 /* tInt */ {tVar
, tInt
, tDbl
, tVar
, tVar
, tVar
, tVar
, tVar
},
138 /* tDbl */ {tVar
, tDbl
, tDbl
, tVar
, tVar
, tVar
, tVar
, tVar
},
139 /* tBool */ {tVar
, tVar
, tVar
, tBool
, tVar
, tVar
, tVar
, tVar
},
140 /* tStr */ {tStr
, tVar
, tVar
, tVar
, tStr
, tVar
, tVar
, tVar
},
141 /* tID */ {tID
, tVar
, tVar
, tVar
, tVar
, tID
, tVar
, tVar
},
142 /* tArr */ {tErr
, tErr
, tErr
, tErr
, tErr
, tErr
, tErr
, tErr
},
143 /* tISup */ {tISup
, tVar
, tVar
, tVar
, tVar
, tVar
, tVar
, tISup
},
144 /* tUnk */ {tNull
, tInt
, tDbl
, tBool
, tStr
, tID
, tVar
, tISup
}};
147 bool XPCArrayHomogenizer::GetTypeForArray(JSContext
* cx
, HandleObject array
,
149 nsXPTType
* resultType
,
155 RootedObject
jsobj(cx
);
156 for (uint32_t i
= 0; i
< length
; i
++) {
157 if (!JS_GetElement(cx
, array
, i
, &val
)) {
163 } else if (val
.isDouble()) {
165 } else if (val
.isBoolean()) {
167 } else if (val
.isUndefined() || val
.isSymbol() || val
.isBigInt()) {
170 } else if (val
.isNull()) {
172 } else if (val
.isString()) {
175 MOZ_RELEASE_ASSERT(val
.isObject(), "invalid type of jsval!");
176 jsobj
= &val
.toObject();
179 if (!JS::IsArrayObject(cx
, jsobj
, &isArray
)) {
185 } else if (xpc::JSValue2ID(cx
, val
)) {
192 MOZ_ASSERT(state
!= tErr
, "bad state table!");
193 MOZ_ASSERT(type
!= tErr
, "bad type!");
194 MOZ_ASSERT(type
!= tVar
, "bad type!");
195 MOZ_ASSERT(type
!= tUnk
, "bad type!");
197 state
= StateTable
[state
][type
];
199 MOZ_ASSERT(state
!= tErr
, "bad state table!");
200 MOZ_ASSERT(state
!= tUnk
, "bad state table!");
209 *resultType
= nsXPTType::MkArrayType(nsXPTType::Idx::INT32
);
212 *resultType
= nsXPTType::MkArrayType(nsXPTType::Idx::DOUBLE
);
215 *resultType
= nsXPTType::MkArrayType(nsXPTType::Idx::BOOL
);
218 *resultType
= nsXPTType::MkArrayType(nsXPTType::Idx::PWSTRING
);
221 *resultType
= nsXPTType::MkArrayType(nsXPTType::Idx::NSIDPTR
);
224 *resultType
= nsXPTType::MkArrayType(nsXPTType::Idx::INTERFACE_IS_TYPE
);
225 *resultID
= NS_GET_IID(nsISupports
);
230 *resultType
= nsXPTType::MkArrayType(nsXPTType::Idx::INTERFACE_IS_TYPE
);
231 *resultID
= NS_GET_IID(nsIVariant
);
240 NS_ERROR("bad state");
246 bool XPCVariant::InitializeData(JSContext
* cx
) {
247 js::AutoCheckRecursionLimit
recursion(cx
);
248 if (!recursion
.check(cx
)) {
252 RootedValue
val(cx
, GetJSVal());
255 mData
.SetFromInt32(val
.toInt32());
258 if (val
.isDouble()) {
259 mData
.SetFromDouble(val
.toDouble());
262 if (val
.isBoolean()) {
263 mData
.SetFromBool(val
.toBoolean());
266 // We can't represent symbol or BigInt on C++ side, so pretend it is void.
267 if (val
.isUndefined() || val
.isSymbol() || val
.isBigInt()) {
275 if (val
.isString()) {
276 RootedString
str(cx
, val
.toString());
281 MOZ_ASSERT(mData
.GetType() == nsIDataType::VTYPE_EMPTY
,
282 "Why do we already have data?");
284 size_t length
= JS_GetStringLength(str
);
285 mData
.AllocateWStringWithSize(length
);
287 mozilla::Range
<char16_t
> destChars(mData
.u
.wstr
.mWStringValue
, length
);
288 if (!JS_CopyStringChars(cx
, destChars
, str
)) {
292 MOZ_ASSERT(mData
.u
.wstr
.mWStringValue
[length
] == '\0');
295 if (Maybe
<nsID
> id
= xpc::JSValue2ID(cx
, val
)) {
296 mData
.SetFromID(id
.ref());
300 // leaving only JSObject...
301 MOZ_RELEASE_ASSERT(val
.isObject(), "invalid type of jsval!");
303 RootedObject
jsobj(cx
, &val
.toObject());
305 // Let's see if it is a js array object.
310 if (!JS::IsArrayObject(cx
, jsobj
, &isArray
) ||
311 (isArray
&& !JS::GetArrayLength(cx
, jsobj
, &len
))) {
318 mData
.SetToEmptyArray();
325 if (!XPCArrayHomogenizer::GetTypeForArray(cx
, jsobj
, len
, &type
, &id
)) {
329 if (!XPCConvert::JSData2Native(cx
, &mData
.u
.array
.mArrayValue
, val
, type
,
333 const nsXPTType
& elty
= type
.ArrayElementType();
334 mData
.mType
= nsIDataType::VTYPE_ARRAY
;
335 if (elty
.IsInterfacePointer()) {
336 mData
.u
.array
.mArrayInterfaceID
= id
;
338 mData
.u
.array
.mArrayCount
= len
;
339 mData
.u
.array
.mArrayType
= elty
.Tag();
344 // XXX This could be smarter and pick some more interesting iface.
346 nsIXPConnect
* xpc
= nsIXPConnect::XPConnect();
347 nsCOMPtr
<nsISupports
> wrapper
;
348 const nsIID
& iid
= NS_GET_IID(nsISupports
);
350 if (NS_FAILED(xpc
->WrapJS(cx
, jsobj
, iid
, getter_AddRefs(wrapper
)))) {
354 mData
.SetFromInterface(iid
, wrapper
);
359 XPCVariant::GetAsJSVal(MutableHandleValue result
) {
360 result
.set(GetJSVal());
365 bool XPCVariant::VariantDataToJS(JSContext
* cx
, nsIVariant
* variant
,
366 nsresult
* pErr
, MutableHandleValue pJSVal
) {
367 // Get the type early because we might need to spoof it below.
368 uint16_t type
= variant
->GetDataType();
370 RootedValue
realVal(cx
);
371 nsresult rv
= variant
->GetAsJSVal(&realVal
);
373 if (NS_SUCCEEDED(rv
) &&
374 (realVal
.isPrimitive() || type
== nsIDataType::VTYPE_ARRAY
||
375 type
== nsIDataType::VTYPE_EMPTY_ARRAY
||
376 type
== nsIDataType::VTYPE_ID
)) {
377 if (!JS_WrapValue(cx
, &realVal
)) {
384 nsCOMPtr
<XPCVariant
> xpcvariant
= do_QueryInterface(variant
);
385 if (xpcvariant
&& xpcvariant
->mReturnRawObject
) {
386 MOZ_ASSERT(type
== nsIDataType::VTYPE_INTERFACE
||
387 type
== nsIDataType::VTYPE_INTERFACE_IS
,
390 if (!JS_WrapValue(cx
, &realVal
)) {
397 // else, it's an object and we really need to double wrap it if we've
398 // already decided that its 'natural' type is as some sort of interface.
400 // We just fall through to the code below and let it do what it does.
402 // The nsIVariant is not a XPCVariant (or we act like it isn't).
403 // So we extract the data and do the Right Thing.
405 // We ASSUME that the variant implementation can do these conversions...
410 case nsIDataType::VTYPE_INT8
:
411 case nsIDataType::VTYPE_INT16
:
412 case nsIDataType::VTYPE_INT32
:
413 case nsIDataType::VTYPE_INT64
:
414 case nsIDataType::VTYPE_UINT8
:
415 case nsIDataType::VTYPE_UINT16
:
416 case nsIDataType::VTYPE_UINT32
:
417 case nsIDataType::VTYPE_UINT64
:
418 case nsIDataType::VTYPE_FLOAT
:
419 case nsIDataType::VTYPE_DOUBLE
: {
421 if (NS_FAILED(variant
->GetAsDouble(&d
))) {
424 pJSVal
.set(JS_NumberValue(d
));
427 case nsIDataType::VTYPE_BOOL
: {
429 if (NS_FAILED(variant
->GetAsBool(&b
))) {
432 pJSVal
.setBoolean(b
);
435 case nsIDataType::VTYPE_CHAR
: {
437 if (NS_FAILED(variant
->GetAsChar(&c
))) {
440 return XPCConvert::NativeData2JS(cx
, pJSVal
, (const void*)&c
, {TD_CHAR
},
443 case nsIDataType::VTYPE_WCHAR
: {
445 if (NS_FAILED(variant
->GetAsWChar(&wc
))) {
448 return XPCConvert::NativeData2JS(cx
, pJSVal
, (const void*)&wc
, {TD_WCHAR
},
451 case nsIDataType::VTYPE_ID
: {
452 if (NS_FAILED(variant
->GetAsID(&iid
))) {
456 return XPCConvert::NativeData2JS(cx
, pJSVal
, (const void*)&v
,
457 {TD_NSIDPTR
}, &iid
, 0, pErr
);
459 case nsIDataType::VTYPE_ASTRING
: {
460 nsAutoString astring
;
461 if (NS_FAILED(variant
->GetAsAString(astring
))) {
464 return XPCConvert::NativeData2JS(cx
, pJSVal
, &astring
, {TD_ASTRING
}, &iid
,
467 case nsIDataType::VTYPE_CSTRING
: {
468 nsAutoCString cString
;
469 if (NS_FAILED(variant
->GetAsACString(cString
))) {
472 return XPCConvert::NativeData2JS(cx
, pJSVal
, &cString
, {TD_CSTRING
}, &iid
,
475 case nsIDataType::VTYPE_UTF8STRING
: {
476 nsUTF8String utf8String
;
477 if (NS_FAILED(variant
->GetAsAUTF8String(utf8String
))) {
480 return XPCConvert::NativeData2JS(cx
, pJSVal
, &utf8String
, {TD_UTF8STRING
},
483 case nsIDataType::VTYPE_CHAR_STR
: {
485 if (NS_FAILED(variant
->GetAsString(&pc
))) {
488 bool success
= XPCConvert::NativeData2JS(cx
, pJSVal
, (const void*)&pc
,
489 {TD_PSTRING
}, &iid
, 0, pErr
);
493 case nsIDataType::VTYPE_STRING_SIZE_IS
: {
496 if (NS_FAILED(variant
->GetAsStringWithSize(&size
, &pc
))) {
499 bool success
= XPCConvert::NativeData2JS(
500 cx
, pJSVal
, (const void*)&pc
, {TD_PSTRING_SIZE_IS
}, &iid
, size
, pErr
);
504 case nsIDataType::VTYPE_WCHAR_STR
: {
506 if (NS_FAILED(variant
->GetAsWString(&pwc
))) {
509 bool success
= XPCConvert::NativeData2JS(cx
, pJSVal
, (const void*)&pwc
,
510 {TD_PSTRING
}, &iid
, 0, pErr
);
514 case nsIDataType::VTYPE_WSTRING_SIZE_IS
: {
517 if (NS_FAILED(variant
->GetAsWStringWithSize(&size
, &pwc
))) {
521 XPCConvert::NativeData2JS(cx
, pJSVal
, (const void*)&pwc
,
522 {TD_PWSTRING_SIZE_IS
}, &iid
, size
, pErr
);
526 case nsIDataType::VTYPE_INTERFACE
:
527 case nsIDataType::VTYPE_INTERFACE_IS
: {
530 if (NS_FAILED(variant
->GetAsInterface(&piid
, (void**)&pi
))) {
537 bool success
= XPCConvert::NativeData2JS(
538 cx
, pJSVal
, (const void*)&pi
, {TD_INTERFACE_IS_TYPE
}, &iid
, 0, pErr
);
544 case nsIDataType::VTYPE_ARRAY
: {
545 nsDiscriminatedUnion du
;
548 rv
= variant
->GetAsArray(
549 &du
.u
.array
.mArrayType
, &du
.u
.array
.mArrayInterfaceID
,
550 &du
.u
.array
.mArrayCount
, &du
.u
.array
.mArrayValue
);
555 // must exit via VARIANT_DONE from here on...
556 du
.mType
= nsIDataType::VTYPE_ARRAY
;
558 uint16_t elementType
= du
.u
.array
.mArrayType
;
559 const nsID
* pid
= nullptr;
561 nsXPTType::Idx xptIndex
;
562 switch (elementType
) {
563 case nsIDataType::VTYPE_INT8
:
564 xptIndex
= nsXPTType::Idx::INT8
;
566 case nsIDataType::VTYPE_INT16
:
567 xptIndex
= nsXPTType::Idx::INT16
;
569 case nsIDataType::VTYPE_INT32
:
570 xptIndex
= nsXPTType::Idx::INT32
;
572 case nsIDataType::VTYPE_INT64
:
573 xptIndex
= nsXPTType::Idx::INT64
;
575 case nsIDataType::VTYPE_UINT8
:
576 xptIndex
= nsXPTType::Idx::UINT8
;
578 case nsIDataType::VTYPE_UINT16
:
579 xptIndex
= nsXPTType::Idx::UINT16
;
581 case nsIDataType::VTYPE_UINT32
:
582 xptIndex
= nsXPTType::Idx::UINT32
;
584 case nsIDataType::VTYPE_UINT64
:
585 xptIndex
= nsXPTType::Idx::UINT64
;
587 case nsIDataType::VTYPE_FLOAT
:
588 xptIndex
= nsXPTType::Idx::FLOAT
;
590 case nsIDataType::VTYPE_DOUBLE
:
591 xptIndex
= nsXPTType::Idx::DOUBLE
;
593 case nsIDataType::VTYPE_BOOL
:
594 xptIndex
= nsXPTType::Idx::BOOL
;
596 case nsIDataType::VTYPE_CHAR
:
597 xptIndex
= nsXPTType::Idx::CHAR
;
599 case nsIDataType::VTYPE_WCHAR
:
600 xptIndex
= nsXPTType::Idx::WCHAR
;
602 case nsIDataType::VTYPE_ID
:
603 xptIndex
= nsXPTType::Idx::NSIDPTR
;
605 case nsIDataType::VTYPE_CHAR_STR
:
606 xptIndex
= nsXPTType::Idx::PSTRING
;
608 case nsIDataType::VTYPE_WCHAR_STR
:
609 xptIndex
= nsXPTType::Idx::PWSTRING
;
611 case nsIDataType::VTYPE_INTERFACE
:
612 pid
= &NS_GET_IID(nsISupports
);
613 xptIndex
= nsXPTType::Idx::INTERFACE_IS_TYPE
;
615 case nsIDataType::VTYPE_INTERFACE_IS
:
616 pid
= &du
.u
.array
.mArrayInterfaceID
;
617 xptIndex
= nsXPTType::Idx::INTERFACE_IS_TYPE
;
620 // The rest are illegal.
621 case nsIDataType::VTYPE_VOID
:
622 case nsIDataType::VTYPE_ASTRING
:
623 case nsIDataType::VTYPE_CSTRING
:
624 case nsIDataType::VTYPE_UTF8STRING
:
625 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
626 case nsIDataType::VTYPE_STRING_SIZE_IS
:
627 case nsIDataType::VTYPE_ARRAY
:
628 case nsIDataType::VTYPE_EMPTY_ARRAY
:
629 case nsIDataType::VTYPE_EMPTY
:
631 NS_ERROR("bad type in array!");
635 bool success
= XPCConvert::NativeData2JS(
636 cx
, pJSVal
, (const void*)&du
.u
.array
.mArrayValue
,
637 nsXPTType::MkArrayType(xptIndex
), pid
, du
.u
.array
.mArrayCount
, pErr
);
641 case nsIDataType::VTYPE_EMPTY_ARRAY
: {
642 JSObject
* array
= JS::NewArrayObject(cx
, 0);
646 pJSVal
.setObject(*array
);
649 case nsIDataType::VTYPE_VOID
:
650 pJSVal
.setUndefined();
652 case nsIDataType::VTYPE_EMPTY
:
656 NS_ERROR("bad type in variant!");
661 /***************************************************************************/
662 /***************************************************************************/
663 // XXX These default implementations need to be improved to allow for
664 // some more interesting conversions.
666 uint16_t XPCVariant::GetDataType() { return mData
.GetType(); }
668 NS_IMETHODIMP
XPCVariant::GetAsInt8(uint8_t* _retval
) {
669 return mData
.ConvertToInt8(_retval
);
672 NS_IMETHODIMP
XPCVariant::GetAsInt16(int16_t* _retval
) {
673 return mData
.ConvertToInt16(_retval
);
676 NS_IMETHODIMP
XPCVariant::GetAsInt32(int32_t* _retval
) {
677 return mData
.ConvertToInt32(_retval
);
680 NS_IMETHODIMP
XPCVariant::GetAsInt64(int64_t* _retval
) {
681 return mData
.ConvertToInt64(_retval
);
684 NS_IMETHODIMP
XPCVariant::GetAsUint8(uint8_t* _retval
) {
685 return mData
.ConvertToUint8(_retval
);
688 NS_IMETHODIMP
XPCVariant::GetAsUint16(uint16_t* _retval
) {
689 return mData
.ConvertToUint16(_retval
);
692 NS_IMETHODIMP
XPCVariant::GetAsUint32(uint32_t* _retval
) {
693 return mData
.ConvertToUint32(_retval
);
696 NS_IMETHODIMP
XPCVariant::GetAsUint64(uint64_t* _retval
) {
697 return mData
.ConvertToUint64(_retval
);
700 NS_IMETHODIMP
XPCVariant::GetAsFloat(float* _retval
) {
701 return mData
.ConvertToFloat(_retval
);
704 NS_IMETHODIMP
XPCVariant::GetAsDouble(double* _retval
) {
705 return mData
.ConvertToDouble(_retval
);
708 NS_IMETHODIMP
XPCVariant::GetAsBool(bool* _retval
) {
709 return mData
.ConvertToBool(_retval
);
712 NS_IMETHODIMP
XPCVariant::GetAsChar(char* _retval
) {
713 return mData
.ConvertToChar(_retval
);
716 NS_IMETHODIMP
XPCVariant::GetAsWChar(char16_t
* _retval
) {
717 return mData
.ConvertToWChar(_retval
);
720 NS_IMETHODIMP_(nsresult
) XPCVariant::GetAsID(nsID
* retval
) {
721 return mData
.ConvertToID(retval
);
724 NS_IMETHODIMP
XPCVariant::GetAsAString(nsAString
& _retval
) {
725 return mData
.ConvertToAString(_retval
);
728 NS_IMETHODIMP
XPCVariant::GetAsACString(nsACString
& _retval
) {
729 return mData
.ConvertToACString(_retval
);
732 NS_IMETHODIMP
XPCVariant::GetAsAUTF8String(nsAUTF8String
& _retval
) {
733 return mData
.ConvertToAUTF8String(_retval
);
736 NS_IMETHODIMP
XPCVariant::GetAsString(char** _retval
) {
737 return mData
.ConvertToString(_retval
);
740 NS_IMETHODIMP
XPCVariant::GetAsWString(char16_t
** _retval
) {
741 return mData
.ConvertToWString(_retval
);
744 NS_IMETHODIMP
XPCVariant::GetAsISupports(nsISupports
** _retval
) {
745 return mData
.ConvertToISupports(_retval
);
748 NS_IMETHODIMP
XPCVariant::GetAsInterface(nsIID
** iid
, void** iface
) {
749 return mData
.ConvertToInterface(iid
, iface
);
752 NS_IMETHODIMP_(nsresult
)
753 XPCVariant::GetAsArray(uint16_t* type
, nsIID
* iid
, uint32_t* count
,
755 return mData
.ConvertToArray(type
, iid
, count
, ptr
);
758 NS_IMETHODIMP
XPCVariant::GetAsStringWithSize(uint32_t* size
, char** str
) {
759 return mData
.ConvertToStringWithSize(size
, str
);
762 NS_IMETHODIMP
XPCVariant::GetAsWStringWithSize(uint32_t* size
, char16_t
** str
) {
763 return mData
.ConvertToWStringWithSize(size
, str
);