no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / js / xpconnect / src / XPCVariant.cpp
blob73e6279f1517f55f41836cf3d88848e24ef55915
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"
21 using namespace JS;
22 using namespace mozilla;
23 using namespace xpc;
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)
31 NS_INTERFACE_MAP_END
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
47 // an outer window.
48 JSObject* obj = js::ToWindowIfWindowProxy(&mJSVal.toObject());
49 mJSVal = JS::ObjectValue(*obj);
51 JSObject* unwrapped =
52 js::CheckedUnwrapDynamic(obj, cx, /* stopAtWindowProxy = */ false);
53 mReturnRawObject = !(unwrapped && IsWrappedNativeReflector(unwrapped));
54 } else {
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)
72 tmp->Cleanup();
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
79 // static
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)) {
84 return nullptr;
87 return variant.forget();
90 void XPCVariant::Cleanup() {
91 mData.Cleanup();
93 if (!GetJSValPreserveColor().isGCThing()) {
94 return;
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 {
102 private:
103 enum Type {
104 tNull = 0, // null value
105 tInt, // Integer
106 tDbl, // Double
107 tBool, // Boolean
108 tStr, // String
109 tID, // ID
110 tArr, // Array
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];
123 public:
124 static bool GetTypeForArray(JSContext* cx, HandleObject array,
125 uint32_t length, nsXPTType* resultType,
126 nsID* resultID);
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}};
146 // static
147 bool XPCArrayHomogenizer::GetTypeForArray(JSContext* cx, HandleObject array,
148 uint32_t length,
149 nsXPTType* resultType,
150 nsID* resultID) {
151 Type state = tUnk;
152 Type type;
154 RootedValue val(cx);
155 RootedObject jsobj(cx);
156 for (uint32_t i = 0; i < length; i++) {
157 if (!JS_GetElement(cx, array, i, &val)) {
158 return false;
161 if (val.isInt32()) {
162 type = tInt;
163 } else if (val.isDouble()) {
164 type = tDbl;
165 } else if (val.isBoolean()) {
166 type = tBool;
167 } else if (val.isUndefined() || val.isSymbol() || val.isBigInt()) {
168 state = tVar;
169 break;
170 } else if (val.isNull()) {
171 type = tNull;
172 } else if (val.isString()) {
173 type = tStr;
174 } else {
175 MOZ_RELEASE_ASSERT(val.isObject(), "invalid type of jsval!");
176 jsobj = &val.toObject();
178 bool isArray;
179 if (!JS::IsArrayObject(cx, jsobj, &isArray)) {
180 return false;
183 if (isArray) {
184 type = tArr;
185 } else if (xpc::JSValue2ID(cx, val)) {
186 type = tID;
187 } else {
188 type = tISup;
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!");
202 if (state == tVar) {
203 break;
207 switch (state) {
208 case tInt:
209 *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::INT32);
210 break;
211 case tDbl:
212 *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::DOUBLE);
213 break;
214 case tBool:
215 *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::BOOL);
216 break;
217 case tStr:
218 *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::PWSTRING);
219 break;
220 case tID:
221 *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::NSIDPTR);
222 break;
223 case tISup:
224 *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::INTERFACE_IS_TYPE);
225 *resultID = NS_GET_IID(nsISupports);
226 break;
227 case tNull:
228 // FALL THROUGH
229 case tVar:
230 *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::INTERFACE_IS_TYPE);
231 *resultID = NS_GET_IID(nsIVariant);
232 break;
233 case tArr:
234 // FALL THROUGH
235 case tUnk:
236 // FALL THROUGH
237 case tErr:
238 // FALL THROUGH
239 default:
240 NS_ERROR("bad state");
241 return false;
243 return true;
246 bool XPCVariant::InitializeData(JSContext* cx) {
247 js::AutoCheckRecursionLimit recursion(cx);
248 if (!recursion.check(cx)) {
249 return false;
252 RootedValue val(cx, GetJSVal());
254 if (val.isInt32()) {
255 mData.SetFromInt32(val.toInt32());
256 return true;
258 if (val.isDouble()) {
259 mData.SetFromDouble(val.toDouble());
260 return true;
262 if (val.isBoolean()) {
263 mData.SetFromBool(val.toBoolean());
264 return true;
266 // We can't represent symbol or BigInt on C++ side, so pretend it is void.
267 if (val.isUndefined() || val.isSymbol() || val.isBigInt()) {
268 mData.SetToVoid();
269 return true;
271 if (val.isNull()) {
272 mData.SetToEmpty();
273 return true;
275 if (val.isString()) {
276 RootedString str(cx, val.toString());
277 if (!str) {
278 return false;
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)) {
289 return false;
292 MOZ_ASSERT(mData.u.wstr.mWStringValue[length] == '\0');
293 return true;
295 if (Maybe<nsID> id = xpc::JSValue2ID(cx, val)) {
296 mData.SetFromID(id.ref());
297 return true;
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.
307 uint32_t len;
309 bool isArray;
310 if (!JS::IsArrayObject(cx, jsobj, &isArray) ||
311 (isArray && !JS::GetArrayLength(cx, jsobj, &len))) {
312 return false;
315 if (isArray) {
316 if (!len) {
317 // Zero length array
318 mData.SetToEmptyArray();
319 return true;
322 nsXPTType type;
323 nsID id;
325 if (!XPCArrayHomogenizer::GetTypeForArray(cx, jsobj, len, &type, &id)) {
326 return false;
329 if (!XPCConvert::JSData2Native(cx, &mData.u.array.mArrayValue, val, type,
330 &id, len, nullptr))
331 return false;
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();
341 return true;
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)))) {
351 return false;
354 mData.SetFromInterface(iid, wrapper);
355 return true;
358 NS_IMETHODIMP
359 XPCVariant::GetAsJSVal(MutableHandleValue result) {
360 result.set(GetJSVal());
361 return NS_OK;
364 // static
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)) {
378 return false;
380 pJSVal.set(realVal);
381 return true;
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,
388 "Weird variant");
390 if (!JS_WrapValue(cx, &realVal)) {
391 return false;
393 pJSVal.set(realVal);
394 return true;
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...
407 nsID iid;
409 switch (type) {
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: {
420 double d;
421 if (NS_FAILED(variant->GetAsDouble(&d))) {
422 return false;
424 pJSVal.set(JS_NumberValue(d));
425 return true;
427 case nsIDataType::VTYPE_BOOL: {
428 bool b;
429 if (NS_FAILED(variant->GetAsBool(&b))) {
430 return false;
432 pJSVal.setBoolean(b);
433 return true;
435 case nsIDataType::VTYPE_CHAR: {
436 char c;
437 if (NS_FAILED(variant->GetAsChar(&c))) {
438 return false;
440 return XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&c, {TD_CHAR},
441 &iid, 0, pErr);
443 case nsIDataType::VTYPE_WCHAR: {
444 char16_t wc;
445 if (NS_FAILED(variant->GetAsWChar(&wc))) {
446 return false;
448 return XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&wc, {TD_WCHAR},
449 &iid, 0, pErr);
451 case nsIDataType::VTYPE_ID: {
452 if (NS_FAILED(variant->GetAsID(&iid))) {
453 return false;
455 nsID* v = &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))) {
462 return false;
464 return XPCConvert::NativeData2JS(cx, pJSVal, &astring, {TD_ASTRING}, &iid,
465 0, pErr);
467 case nsIDataType::VTYPE_CSTRING: {
468 nsAutoCString cString;
469 if (NS_FAILED(variant->GetAsACString(cString))) {
470 return false;
472 return XPCConvert::NativeData2JS(cx, pJSVal, &cString, {TD_CSTRING}, &iid,
473 0, pErr);
475 case nsIDataType::VTYPE_UTF8STRING: {
476 nsUTF8String utf8String;
477 if (NS_FAILED(variant->GetAsAUTF8String(utf8String))) {
478 return false;
480 return XPCConvert::NativeData2JS(cx, pJSVal, &utf8String, {TD_UTF8STRING},
481 &iid, 0, pErr);
483 case nsIDataType::VTYPE_CHAR_STR: {
484 char* pc;
485 if (NS_FAILED(variant->GetAsString(&pc))) {
486 return false;
488 bool success = XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&pc,
489 {TD_PSTRING}, &iid, 0, pErr);
490 free(pc);
491 return success;
493 case nsIDataType::VTYPE_STRING_SIZE_IS: {
494 char* pc;
495 uint32_t size;
496 if (NS_FAILED(variant->GetAsStringWithSize(&size, &pc))) {
497 return false;
499 bool success = XPCConvert::NativeData2JS(
500 cx, pJSVal, (const void*)&pc, {TD_PSTRING_SIZE_IS}, &iid, size, pErr);
501 free(pc);
502 return success;
504 case nsIDataType::VTYPE_WCHAR_STR: {
505 char16_t* pwc;
506 if (NS_FAILED(variant->GetAsWString(&pwc))) {
507 return false;
509 bool success = XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&pwc,
510 {TD_PSTRING}, &iid, 0, pErr);
511 free(pwc);
512 return success;
514 case nsIDataType::VTYPE_WSTRING_SIZE_IS: {
515 char16_t* pwc;
516 uint32_t size;
517 if (NS_FAILED(variant->GetAsWStringWithSize(&size, &pwc))) {
518 return false;
520 bool success =
521 XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&pwc,
522 {TD_PWSTRING_SIZE_IS}, &iid, size, pErr);
523 free(pwc);
524 return success;
526 case nsIDataType::VTYPE_INTERFACE:
527 case nsIDataType::VTYPE_INTERFACE_IS: {
528 nsISupports* pi;
529 nsID* piid;
530 if (NS_FAILED(variant->GetAsInterface(&piid, (void**)&pi))) {
531 return false;
534 iid = *piid;
535 free((char*)piid);
537 bool success = XPCConvert::NativeData2JS(
538 cx, pJSVal, (const void*)&pi, {TD_INTERFACE_IS_TYPE}, &iid, 0, pErr);
539 if (pi) {
540 pi->Release();
542 return success;
544 case nsIDataType::VTYPE_ARRAY: {
545 nsDiscriminatedUnion du;
546 nsresult rv;
548 rv = variant->GetAsArray(
549 &du.u.array.mArrayType, &du.u.array.mArrayInterfaceID,
550 &du.u.array.mArrayCount, &du.u.array.mArrayValue);
551 if (NS_FAILED(rv)) {
552 return false;
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;
565 break;
566 case nsIDataType::VTYPE_INT16:
567 xptIndex = nsXPTType::Idx::INT16;
568 break;
569 case nsIDataType::VTYPE_INT32:
570 xptIndex = nsXPTType::Idx::INT32;
571 break;
572 case nsIDataType::VTYPE_INT64:
573 xptIndex = nsXPTType::Idx::INT64;
574 break;
575 case nsIDataType::VTYPE_UINT8:
576 xptIndex = nsXPTType::Idx::UINT8;
577 break;
578 case nsIDataType::VTYPE_UINT16:
579 xptIndex = nsXPTType::Idx::UINT16;
580 break;
581 case nsIDataType::VTYPE_UINT32:
582 xptIndex = nsXPTType::Idx::UINT32;
583 break;
584 case nsIDataType::VTYPE_UINT64:
585 xptIndex = nsXPTType::Idx::UINT64;
586 break;
587 case nsIDataType::VTYPE_FLOAT:
588 xptIndex = nsXPTType::Idx::FLOAT;
589 break;
590 case nsIDataType::VTYPE_DOUBLE:
591 xptIndex = nsXPTType::Idx::DOUBLE;
592 break;
593 case nsIDataType::VTYPE_BOOL:
594 xptIndex = nsXPTType::Idx::BOOL;
595 break;
596 case nsIDataType::VTYPE_CHAR:
597 xptIndex = nsXPTType::Idx::CHAR;
598 break;
599 case nsIDataType::VTYPE_WCHAR:
600 xptIndex = nsXPTType::Idx::WCHAR;
601 break;
602 case nsIDataType::VTYPE_ID:
603 xptIndex = nsXPTType::Idx::NSIDPTR;
604 break;
605 case nsIDataType::VTYPE_CHAR_STR:
606 xptIndex = nsXPTType::Idx::PSTRING;
607 break;
608 case nsIDataType::VTYPE_WCHAR_STR:
609 xptIndex = nsXPTType::Idx::PWSTRING;
610 break;
611 case nsIDataType::VTYPE_INTERFACE:
612 pid = &NS_GET_IID(nsISupports);
613 xptIndex = nsXPTType::Idx::INTERFACE_IS_TYPE;
614 break;
615 case nsIDataType::VTYPE_INTERFACE_IS:
616 pid = &du.u.array.mArrayInterfaceID;
617 xptIndex = nsXPTType::Idx::INTERFACE_IS_TYPE;
618 break;
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:
630 default:
631 NS_ERROR("bad type in array!");
632 return false;
635 bool success = XPCConvert::NativeData2JS(
636 cx, pJSVal, (const void*)&du.u.array.mArrayValue,
637 nsXPTType::MkArrayType(xptIndex), pid, du.u.array.mArrayCount, pErr);
639 return success;
641 case nsIDataType::VTYPE_EMPTY_ARRAY: {
642 JSObject* array = JS::NewArrayObject(cx, 0);
643 if (!array) {
644 return false;
646 pJSVal.setObject(*array);
647 return true;
649 case nsIDataType::VTYPE_VOID:
650 pJSVal.setUndefined();
651 return true;
652 case nsIDataType::VTYPE_EMPTY:
653 pJSVal.setNull();
654 return true;
655 default:
656 NS_ERROR("bad type in variant!");
657 return false;
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,
754 void** ptr) {
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);