1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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 /* The long avoided variant support for xpcom. */
13 #include "nsCycleCollectionParticipant.h"
14 #include "xpt_struct.h"
15 #include "nsReadableUtils.h"
18 #include "nsCRTGlue.h"
20 /***************************************************************************/
21 // Helpers for static convert functions...
24 String2Double(const char* aString
, double* aResult
)
27 double value
= PR_strtod(aString
, &next
);
28 if (next
== aString
) {
29 return NS_ERROR_CANNOT_CONVERT_DATA
;
36 AString2Double(const nsAString
& aString
, double* aResult
)
38 char* pChars
= ToNewCString(aString
);
40 return NS_ERROR_OUT_OF_MEMORY
;
42 nsresult rv
= String2Double(pChars
, aResult
);
43 nsMemory::Free(pChars
);
48 AUTF8String2Double(const nsAUTF8String
& aString
, double* aResult
)
50 return String2Double(PromiseFlatUTF8String(aString
).get(), aResult
);
54 ACString2Double(const nsACString
& aString
, double* aResult
)
56 return String2Double(PromiseFlatCString(aString
).get(), aResult
);
59 // Fills outVariant with double, uint32_t, or int32_t.
60 // Returns NS_OK, an error code, or a non-NS_OK success code
62 ToManageableNumber(const nsDiscriminatedUnion
& aInData
,
63 nsDiscriminatedUnion
* aOutData
)
67 switch (aInData
.mType
) {
68 // This group results in a int32_t...
70 #define CASE__NUMBER_INT32(type_, member_) \
71 case nsIDataType :: type_ : \
72 aOutData->u.mInt32Value = aInData.u. member_ ; \
73 aOutData->mType = nsIDataType::VTYPE_INT32; \
76 CASE__NUMBER_INT32(VTYPE_INT8
, mInt8Value
)
77 CASE__NUMBER_INT32(VTYPE_INT16
, mInt16Value
)
78 CASE__NUMBER_INT32(VTYPE_INT32
, mInt32Value
)
79 CASE__NUMBER_INT32(VTYPE_UINT8
, mUint8Value
)
80 CASE__NUMBER_INT32(VTYPE_UINT16
, mUint16Value
)
81 CASE__NUMBER_INT32(VTYPE_BOOL
, mBoolValue
)
82 CASE__NUMBER_INT32(VTYPE_CHAR
, mCharValue
)
83 CASE__NUMBER_INT32(VTYPE_WCHAR
, mWCharValue
)
85 #undef CASE__NUMBER_INT32
87 // This group results in a uint32_t...
89 case nsIDataType::VTYPE_UINT32
:
90 aOutData
->u
.mInt32Value
= aInData
.u
.mUint32Value
;
91 aOutData
->mType
= nsIDataType::VTYPE_INT32
;
94 // This group results in a double...
96 case nsIDataType::VTYPE_INT64
:
97 case nsIDataType::VTYPE_UINT64
:
98 // XXX Need boundary checking here.
99 // We may need to return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA
100 aOutData
->u
.mDoubleValue
= double(aInData
.u
.mInt64Value
);
101 aOutData
->mType
= nsIDataType::VTYPE_DOUBLE
;
103 case nsIDataType::VTYPE_FLOAT
:
104 aOutData
->u
.mDoubleValue
= aInData
.u
.mFloatValue
;
105 aOutData
->mType
= nsIDataType::VTYPE_DOUBLE
;
107 case nsIDataType::VTYPE_DOUBLE
:
108 aOutData
->u
.mDoubleValue
= aInData
.u
.mDoubleValue
;
109 aOutData
->mType
= nsIDataType::VTYPE_DOUBLE
;
111 case nsIDataType::VTYPE_CHAR_STR
:
112 case nsIDataType::VTYPE_STRING_SIZE_IS
:
113 rv
= String2Double(aInData
.u
.str
.mStringValue
, &aOutData
->u
.mDoubleValue
);
117 aOutData
->mType
= nsIDataType::VTYPE_DOUBLE
;
119 case nsIDataType::VTYPE_DOMSTRING
:
120 case nsIDataType::VTYPE_ASTRING
:
121 rv
= AString2Double(*aInData
.u
.mAStringValue
, &aOutData
->u
.mDoubleValue
);
125 aOutData
->mType
= nsIDataType::VTYPE_DOUBLE
;
127 case nsIDataType::VTYPE_UTF8STRING
:
128 rv
= AUTF8String2Double(*aInData
.u
.mUTF8StringValue
,
129 &aOutData
->u
.mDoubleValue
);
133 aOutData
->mType
= nsIDataType::VTYPE_DOUBLE
;
135 case nsIDataType::VTYPE_CSTRING
:
136 rv
= ACString2Double(*aInData
.u
.mCStringValue
,
137 &aOutData
->u
.mDoubleValue
);
141 aOutData
->mType
= nsIDataType::VTYPE_DOUBLE
;
143 case nsIDataType::VTYPE_WCHAR_STR
:
144 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
145 rv
= AString2Double(nsDependentString(aInData
.u
.wstr
.mWStringValue
),
146 &aOutData
->u
.mDoubleValue
);
150 aOutData
->mType
= nsIDataType::VTYPE_DOUBLE
;
153 // This group fails...
155 case nsIDataType::VTYPE_VOID
:
156 case nsIDataType::VTYPE_ID
:
157 case nsIDataType::VTYPE_INTERFACE
:
158 case nsIDataType::VTYPE_INTERFACE_IS
:
159 case nsIDataType::VTYPE_ARRAY
:
160 case nsIDataType::VTYPE_EMPTY_ARRAY
:
161 case nsIDataType::VTYPE_EMPTY
:
163 return NS_ERROR_CANNOT_CONVERT_DATA
;
167 /***************************************************************************/
171 FreeArray(nsDiscriminatedUnion
* aData
)
173 NS_ASSERTION(aData
->mType
== nsIDataType::VTYPE_ARRAY
, "bad FreeArray call");
174 NS_ASSERTION(aData
->u
.array
.mArrayValue
, "bad array");
175 NS_ASSERTION(aData
->u
.array
.mArrayCount
, "bad array count");
177 #define CASE__FREE_ARRAY_PTR(type_, ctype_) \
178 case nsIDataType:: type_ : \
180 ctype_ ** p = (ctype_ **) aData->u.array.mArrayValue; \
181 for(uint32_t i = aData->u.array.mArrayCount; i > 0; p++, i--) \
183 nsMemory::Free((char*)*p); \
187 #define CASE__FREE_ARRAY_IFACE(type_, ctype_) \
188 case nsIDataType:: type_ : \
190 ctype_ ** p = (ctype_ **) aData->u.array.mArrayValue; \
191 for(uint32_t i = aData->u.array.mArrayCount; i > 0; p++, i--) \
197 switch (aData
->u
.array
.mArrayType
) {
198 case nsIDataType::VTYPE_INT8
:
199 case nsIDataType::VTYPE_INT16
:
200 case nsIDataType::VTYPE_INT32
:
201 case nsIDataType::VTYPE_INT64
:
202 case nsIDataType::VTYPE_UINT8
:
203 case nsIDataType::VTYPE_UINT16
:
204 case nsIDataType::VTYPE_UINT32
:
205 case nsIDataType::VTYPE_UINT64
:
206 case nsIDataType::VTYPE_FLOAT
:
207 case nsIDataType::VTYPE_DOUBLE
:
208 case nsIDataType::VTYPE_BOOL
:
209 case nsIDataType::VTYPE_CHAR
:
210 case nsIDataType::VTYPE_WCHAR
:
213 // XXX We ASSUME that "array of nsID" means "array of pointers to nsID".
214 CASE__FREE_ARRAY_PTR(VTYPE_ID
, nsID
)
215 CASE__FREE_ARRAY_PTR(VTYPE_CHAR_STR
, char)
216 CASE__FREE_ARRAY_PTR(VTYPE_WCHAR_STR
, char16_t
)
217 CASE__FREE_ARRAY_IFACE(VTYPE_INTERFACE
, nsISupports
)
218 CASE__FREE_ARRAY_IFACE(VTYPE_INTERFACE_IS
, nsISupports
)
220 // The rest are illegal.
221 case nsIDataType::VTYPE_VOID
:
222 case nsIDataType::VTYPE_ASTRING
:
223 case nsIDataType::VTYPE_DOMSTRING
:
224 case nsIDataType::VTYPE_UTF8STRING
:
225 case nsIDataType::VTYPE_CSTRING
:
226 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
227 case nsIDataType::VTYPE_STRING_SIZE_IS
:
228 case nsIDataType::VTYPE_ARRAY
:
229 case nsIDataType::VTYPE_EMPTY_ARRAY
:
230 case nsIDataType::VTYPE_EMPTY
:
232 NS_ERROR("bad type in array!");
236 // Free the array memory.
237 nsMemory::Free((char*)aData
->u
.array
.mArrayValue
);
239 #undef CASE__FREE_ARRAY_PTR
240 #undef CASE__FREE_ARRAY_IFACE
244 CloneArray(uint16_t aInType
, const nsIID
* aInIID
,
245 uint32_t aInCount
, void* aInValue
,
246 uint16_t* aOutType
, nsIID
* aOutIID
,
247 uint32_t* aOutCount
, void** aOutValue
)
249 NS_ASSERTION(aInCount
, "bad param");
250 NS_ASSERTION(aInValue
, "bad param");
251 NS_ASSERTION(aOutType
, "bad param");
252 NS_ASSERTION(aOutCount
, "bad param");
253 NS_ASSERTION(aOutValue
, "bad param");
255 uint32_t allocatedValueCount
= 0;
259 // First we figure out the size of the elements for the new u.array.
265 case nsIDataType::VTYPE_INT8
:
266 elementSize
= sizeof(int8_t);
268 case nsIDataType::VTYPE_INT16
:
269 elementSize
= sizeof(int16_t);
271 case nsIDataType::VTYPE_INT32
:
272 elementSize
= sizeof(int32_t);
274 case nsIDataType::VTYPE_INT64
:
275 elementSize
= sizeof(int64_t);
277 case nsIDataType::VTYPE_UINT8
:
278 elementSize
= sizeof(uint8_t);
280 case nsIDataType::VTYPE_UINT16
:
281 elementSize
= sizeof(uint16_t);
283 case nsIDataType::VTYPE_UINT32
:
284 elementSize
= sizeof(uint32_t);
286 case nsIDataType::VTYPE_UINT64
:
287 elementSize
= sizeof(uint64_t);
289 case nsIDataType::VTYPE_FLOAT
:
290 elementSize
= sizeof(float);
292 case nsIDataType::VTYPE_DOUBLE
:
293 elementSize
= sizeof(double);
295 case nsIDataType::VTYPE_BOOL
:
296 elementSize
= sizeof(bool);
298 case nsIDataType::VTYPE_CHAR
:
299 elementSize
= sizeof(char);
301 case nsIDataType::VTYPE_WCHAR
:
302 elementSize
= sizeof(char16_t
);
305 // XXX We ASSUME that "array of nsID" means "array of pointers to nsID".
306 case nsIDataType::VTYPE_ID
:
307 case nsIDataType::VTYPE_CHAR_STR
:
308 case nsIDataType::VTYPE_WCHAR_STR
:
309 case nsIDataType::VTYPE_INTERFACE
:
310 case nsIDataType::VTYPE_INTERFACE_IS
:
311 elementSize
= sizeof(void*);
314 // The rest are illegal.
315 case nsIDataType::VTYPE_ASTRING
:
316 case nsIDataType::VTYPE_DOMSTRING
:
317 case nsIDataType::VTYPE_UTF8STRING
:
318 case nsIDataType::VTYPE_CSTRING
:
319 case nsIDataType::VTYPE_STRING_SIZE_IS
:
320 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
321 case nsIDataType::VTYPE_VOID
:
322 case nsIDataType::VTYPE_ARRAY
:
323 case nsIDataType::VTYPE_EMPTY_ARRAY
:
324 case nsIDataType::VTYPE_EMPTY
:
326 NS_ERROR("bad type in array!");
327 return NS_ERROR_CANNOT_CONVERT_DATA
;
331 // Alloc the u.array.
333 allocSize
= aInCount
* elementSize
;
334 *aOutValue
= nsMemory::Alloc(allocSize
);
336 return NS_ERROR_OUT_OF_MEMORY
;
339 // Clone the elements.
342 case nsIDataType::VTYPE_INT8
:
343 case nsIDataType::VTYPE_INT16
:
344 case nsIDataType::VTYPE_INT32
:
345 case nsIDataType::VTYPE_INT64
:
346 case nsIDataType::VTYPE_UINT8
:
347 case nsIDataType::VTYPE_UINT16
:
348 case nsIDataType::VTYPE_UINT32
:
349 case nsIDataType::VTYPE_UINT64
:
350 case nsIDataType::VTYPE_FLOAT
:
351 case nsIDataType::VTYPE_DOUBLE
:
352 case nsIDataType::VTYPE_BOOL
:
353 case nsIDataType::VTYPE_CHAR
:
354 case nsIDataType::VTYPE_WCHAR
:
355 memcpy(*aOutValue
, aInValue
, allocSize
);
358 case nsIDataType::VTYPE_INTERFACE_IS
:
363 case nsIDataType::VTYPE_INTERFACE
: {
364 memcpy(*aOutValue
, aInValue
, allocSize
);
366 nsISupports
** p
= (nsISupports
**)*aOutValue
;
367 for (i
= aInCount
; i
> 0; ++p
, --i
)
374 // XXX We ASSUME that "array of nsID" means "array of pointers to nsID".
375 case nsIDataType::VTYPE_ID
: {
376 nsID
** inp
= (nsID
**)aInValue
;
377 nsID
** outp
= (nsID
**)*aOutValue
;
378 for (i
= aInCount
; i
> 0; --i
) {
379 nsID
* idp
= *(inp
++);
381 if (!(*(outp
++) = (nsID
*)nsMemory::Clone((char*)idp
, sizeof(nsID
)))) {
387 allocatedValueCount
++;
392 case nsIDataType::VTYPE_CHAR_STR
: {
393 char** inp
= (char**)aInValue
;
394 char** outp
= (char**)*aOutValue
;
395 for (i
= aInCount
; i
> 0; i
--) {
396 char* str
= *(inp
++);
398 if (!(*(outp
++) = (char*)nsMemory::Clone(
399 str
, (strlen(str
) + 1) * sizeof(char)))) {
405 allocatedValueCount
++;
410 case nsIDataType::VTYPE_WCHAR_STR
: {
411 char16_t
** inp
= (char16_t
**)aInValue
;
412 char16_t
** outp
= (char16_t
**)*aOutValue
;
413 for (i
= aInCount
; i
> 0; i
--) {
414 char16_t
* str
= *(inp
++);
416 if (!(*(outp
++) = (char16_t
*)nsMemory::Clone(
417 str
, (NS_strlen(str
) + 1) * sizeof(char16_t
)))) {
423 allocatedValueCount
++;
428 // The rest are illegal.
429 case nsIDataType::VTYPE_VOID
:
430 case nsIDataType::VTYPE_ARRAY
:
431 case nsIDataType::VTYPE_EMPTY_ARRAY
:
432 case nsIDataType::VTYPE_EMPTY
:
433 case nsIDataType::VTYPE_ASTRING
:
434 case nsIDataType::VTYPE_DOMSTRING
:
435 case nsIDataType::VTYPE_UTF8STRING
:
436 case nsIDataType::VTYPE_CSTRING
:
437 case nsIDataType::VTYPE_STRING_SIZE_IS
:
438 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
440 NS_ERROR("bad type in array!");
441 return NS_ERROR_CANNOT_CONVERT_DATA
;
445 *aOutCount
= aInCount
;
450 char** p
= (char**)*aOutValue
;
451 for (i
= allocatedValueCount
; i
> 0; ++p
, --i
)
455 nsMemory::Free((char*)*aOutValue
);
456 *aOutValue
= nullptr;
461 /***************************************************************************/
463 #define TRIVIAL_DATA_CONVERTER(type_, data_, member_, retval_) \
464 if(data_.mType == nsIDataType :: type_) { \
465 *retval_ = data_.u.member_; \
469 #define NUMERIC_CONVERSION_METHOD_BEGIN(type_, Ctype_, name_) \
470 /* static */ nsresult \
471 nsVariant::ConvertTo##name_ (const nsDiscriminatedUnion& data, \
474 TRIVIAL_DATA_CONVERTER(type_, data, m##name_##Value, _retval) \
475 nsDiscriminatedUnion tempData; \
476 nsVariant::Initialize(&tempData); \
477 nsresult rv = ToManageableNumber(data, &tempData); \
479 /* NOTE: rv may indicate a success code that we want to preserve */ \
480 /* For the final return. So all the return cases below should return */ \
481 /* this rv when indicating success. */ \
485 switch(tempData.mType) \
488 #define CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(Ctype_) \
489 case nsIDataType::VTYPE_INT32: \
490 *_retval = ( Ctype_ ) tempData.u.mInt32Value; \
493 #define CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(Ctype_, min_, max_) \
494 case nsIDataType::VTYPE_INT32: \
496 int32_t value = tempData.u.mInt32Value; \
497 if(value < min_ || value > max_) \
498 return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \
499 *_retval = ( Ctype_ ) value; \
503 #define CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(Ctype_) \
504 case nsIDataType::VTYPE_UINT32: \
505 *_retval = ( Ctype_ ) tempData.u.mUint32Value; \
508 #define CASE__NUMERIC_CONVERSION_UINT32_MAX(Ctype_, max_) \
509 case nsIDataType::VTYPE_UINT32: \
511 uint32_t value = tempData.u.mUint32Value; \
513 return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \
514 *_retval = ( Ctype_ ) value; \
518 #define CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(Ctype_) \
519 case nsIDataType::VTYPE_DOUBLE: \
520 *_retval = ( Ctype_ ) tempData.u.mDoubleValue; \
523 #define CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX(Ctype_, min_, max_) \
524 case nsIDataType::VTYPE_DOUBLE: \
526 double value = tempData.u.mDoubleValue; \
527 if(value < min_ || value > max_) \
528 return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \
529 *_retval = ( Ctype_ ) value; \
533 #define CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(Ctype_, min_, max_) \
534 case nsIDataType::VTYPE_DOUBLE: \
536 double value = tempData.u.mDoubleValue; \
537 if(value < min_ || value > max_) \
538 return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \
539 *_retval = ( Ctype_ ) value; \
540 return (0.0 == fmod(value,1.0)) ? \
541 rv : NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA; \
544 #define CASES__NUMERIC_CONVERSION_NORMAL(Ctype_, min_, max_) \
545 CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(Ctype_, min_, max_) \
546 CASE__NUMERIC_CONVERSION_UINT32_MAX(Ctype_, max_) \
547 CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(Ctype_, min_, max_)
549 #define NUMERIC_CONVERSION_METHOD_END \
551 NS_ERROR("bad type returned from ToManageableNumber"); \
552 return NS_ERROR_CANNOT_CONVERT_DATA; \
556 #define NUMERIC_CONVERSION_METHOD_NORMAL(type_, Ctype_, name_, min_, max_) \
557 NUMERIC_CONVERSION_METHOD_BEGIN(type_, Ctype_, name_) \
558 CASES__NUMERIC_CONVERSION_NORMAL(Ctype_, min_, max_) \
559 NUMERIC_CONVERSION_METHOD_END
561 /***************************************************************************/
562 // These expand into full public methods...
564 NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_INT8
, uint8_t, Int8
, (-127 - 1), 127)
565 NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_INT16
, int16_t, Int16
, (-32767 - 1), 32767)
567 NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_INT32
, int32_t, Int32
)
568 CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(int32_t)
569 CASE__NUMERIC_CONVERSION_UINT32_MAX(int32_t, 2147483647)
570 CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(int32_t, (-2147483647 - 1), 2147483647)
571 NUMERIC_CONVERSION_METHOD_END
573 NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_UINT8
, uint8_t, Uint8
, 0, 255)
574 NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_UINT16
, uint16_t, Uint16
, 0, 65535)
576 NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_UINT32
, uint32_t, Uint32
)
577 CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(uint32_t, 0, 2147483647)
578 CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(uint32_t)
579 CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(uint32_t, 0, 4294967295U)
580 NUMERIC_CONVERSION_METHOD_END
582 // XXX toFloat convertions need to be fixed!
583 NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_FLOAT
, float, Float
)
584 CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(float)
585 CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(float)
586 CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(float)
587 NUMERIC_CONVERSION_METHOD_END
589 NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_DOUBLE
, double, Double
)
590 CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(double)
591 CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(double)
592 CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(double)
593 NUMERIC_CONVERSION_METHOD_END
595 // XXX toChar convertions need to be fixed!
596 NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_CHAR
, char, Char
)
597 CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(char)
598 CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(char)
599 CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(char)
600 NUMERIC_CONVERSION_METHOD_END
602 // XXX toWChar convertions need to be fixed!
603 NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_WCHAR
, char16_t
, WChar
)
604 CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(char16_t
)
605 CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(char16_t
)
606 CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(char16_t
)
607 NUMERIC_CONVERSION_METHOD_END
609 #undef NUMERIC_CONVERSION_METHOD_BEGIN
610 #undef CASE__NUMERIC_CONVERSION_INT32_JUST_CAST
611 #undef CASE__NUMERIC_CONVERSION_INT32_MIN_MAX
612 #undef CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST
613 #undef CASE__NUMERIC_CONVERSION_UINT32_MIN_MAX
614 #undef CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST
615 #undef CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX
616 #undef CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT
617 #undef CASES__NUMERIC_CONVERSION_NORMAL
618 #undef NUMERIC_CONVERSION_METHOD_END
619 #undef NUMERIC_CONVERSION_METHOD_NORMAL
621 /***************************************************************************/
623 // Just leverage a numeric converter for bool (but restrict the values).
624 // XXX Is this really what we want to do?
626 /* static */ nsresult
627 nsVariant::ConvertToBool(const nsDiscriminatedUnion
& aData
, bool* aResult
)
629 TRIVIAL_DATA_CONVERTER(VTYPE_BOOL
, aData
, mBoolValue
, aResult
)
632 nsresult rv
= nsVariant::ConvertToDouble(aData
, &val
);
636 *aResult
= 0.0 != val
;
640 /***************************************************************************/
642 /* static */ nsresult
643 nsVariant::ConvertToInt64(const nsDiscriminatedUnion
& aData
, int64_t* aResult
)
645 TRIVIAL_DATA_CONVERTER(VTYPE_INT64
, aData
, mInt64Value
, aResult
)
646 TRIVIAL_DATA_CONVERTER(VTYPE_UINT64
, aData
, mUint64Value
, aResult
)
648 nsDiscriminatedUnion tempData
;
649 nsVariant::Initialize(&tempData
);
650 nsresult rv
= ToManageableNumber(aData
, &tempData
);
654 switch (tempData
.mType
) {
655 case nsIDataType::VTYPE_INT32
:
656 *aResult
= tempData
.u
.mInt32Value
;
658 case nsIDataType::VTYPE_UINT32
:
659 *aResult
= tempData
.u
.mUint32Value
;
661 case nsIDataType::VTYPE_DOUBLE
:
662 // XXX should check for data loss here!
663 *aResult
= tempData
.u
.mDoubleValue
;
666 NS_ERROR("bad type returned from ToManageableNumber");
667 return NS_ERROR_CANNOT_CONVERT_DATA
;
671 /* static */ nsresult
672 nsVariant::ConvertToUint64(const nsDiscriminatedUnion
& aData
,
675 return nsVariant::ConvertToInt64(aData
, (int64_t*)aResult
);
678 /***************************************************************************/
681 String2ID(const nsDiscriminatedUnion
& aData
, nsID
* aPid
)
683 nsAutoString tempString
;
686 switch (aData
.mType
) {
687 case nsIDataType::VTYPE_CHAR_STR
:
688 case nsIDataType::VTYPE_STRING_SIZE_IS
:
689 return aPid
->Parse(aData
.u
.str
.mStringValue
);
690 case nsIDataType::VTYPE_CSTRING
:
691 return aPid
->Parse(PromiseFlatCString(*aData
.u
.mCStringValue
).get());
692 case nsIDataType::VTYPE_UTF8STRING
:
693 return aPid
->Parse(PromiseFlatUTF8String(*aData
.u
.mUTF8StringValue
).get());
694 case nsIDataType::VTYPE_ASTRING
:
695 case nsIDataType::VTYPE_DOMSTRING
:
696 pString
= aData
.u
.mAStringValue
;
698 case nsIDataType::VTYPE_WCHAR_STR
:
699 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
700 tempString
.Assign(aData
.u
.wstr
.mWStringValue
);
701 pString
= &tempString
;
704 NS_ERROR("bad type in call to String2ID");
708 char* pChars
= ToNewCString(*pString
);
712 bool result
= aPid
->Parse(pChars
);
713 nsMemory::Free(pChars
);
717 /* static */ nsresult
718 nsVariant::ConvertToID(const nsDiscriminatedUnion
& aData
, nsID
* aResult
)
722 switch (aData
.mType
) {
723 case nsIDataType::VTYPE_ID
:
724 *aResult
= aData
.u
.mIDValue
;
726 case nsIDataType::VTYPE_INTERFACE
:
727 *aResult
= NS_GET_IID(nsISupports
);
729 case nsIDataType::VTYPE_INTERFACE_IS
:
730 *aResult
= aData
.u
.iface
.mInterfaceID
;
732 case nsIDataType::VTYPE_ASTRING
:
733 case nsIDataType::VTYPE_DOMSTRING
:
734 case nsIDataType::VTYPE_UTF8STRING
:
735 case nsIDataType::VTYPE_CSTRING
:
736 case nsIDataType::VTYPE_CHAR_STR
:
737 case nsIDataType::VTYPE_WCHAR_STR
:
738 case nsIDataType::VTYPE_STRING_SIZE_IS
:
739 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
740 if (!String2ID(aData
, &id
)) {
741 return NS_ERROR_CANNOT_CONVERT_DATA
;
746 return NS_ERROR_CANNOT_CONVERT_DATA
;
750 /***************************************************************************/
753 ToString(const nsDiscriminatedUnion
& aData
, nsACString
& aOutString
)
757 switch (aData
.mType
) {
758 // all the stuff we don't handle...
759 case nsIDataType::VTYPE_ASTRING
:
760 case nsIDataType::VTYPE_DOMSTRING
:
761 case nsIDataType::VTYPE_UTF8STRING
:
762 case nsIDataType::VTYPE_CSTRING
:
763 case nsIDataType::VTYPE_CHAR_STR
:
764 case nsIDataType::VTYPE_WCHAR_STR
:
765 case nsIDataType::VTYPE_STRING_SIZE_IS
:
766 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
767 case nsIDataType::VTYPE_WCHAR
:
768 NS_ERROR("ToString being called for a string type - screwy logic!");
771 // XXX We might want stringified versions of these... ???
773 case nsIDataType::VTYPE_VOID
:
774 case nsIDataType::VTYPE_EMPTY
:
775 aOutString
.Truncate();
776 aOutString
.SetIsVoid(true);
779 case nsIDataType::VTYPE_EMPTY_ARRAY
:
780 case nsIDataType::VTYPE_ARRAY
:
781 case nsIDataType::VTYPE_INTERFACE
:
782 case nsIDataType::VTYPE_INTERFACE_IS
:
784 return NS_ERROR_CANNOT_CONVERT_DATA
;
786 // nsID has its own text formatter.
788 case nsIDataType::VTYPE_ID
:
789 ptr
= aData
.u
.mIDValue
.ToString();
791 return NS_ERROR_OUT_OF_MEMORY
;
793 aOutString
.Assign(ptr
);
797 // Can't use PR_smprintf for floats, since it's locale-dependent
798 #define CASE__APPENDFLOAT_NUMBER(type_, member_) \
799 case nsIDataType :: type_ : \
802 str.AppendFloat(aData.u. member_); \
803 aOutString.Assign(str); \
807 CASE__APPENDFLOAT_NUMBER(VTYPE_FLOAT
, mFloatValue
)
808 CASE__APPENDFLOAT_NUMBER(VTYPE_DOUBLE
, mDoubleValue
)
810 #undef CASE__APPENDFLOAT_NUMBER
812 // the rest can be PR_smprintf'd and use common code.
814 #define CASE__SMPRINTF_NUMBER(type_, format_, cast_, member_) \
815 case nsIDataType :: type_ : \
816 ptr = PR_smprintf( format_ , (cast_) aData.u. member_ ); \
819 CASE__SMPRINTF_NUMBER(VTYPE_INT8
, "%d", int, mInt8Value
)
820 CASE__SMPRINTF_NUMBER(VTYPE_INT16
, "%d", int, mInt16Value
)
821 CASE__SMPRINTF_NUMBER(VTYPE_INT32
, "%d", int, mInt32Value
)
822 CASE__SMPRINTF_NUMBER(VTYPE_INT64
, "%lld", int64_t, mInt64Value
)
824 CASE__SMPRINTF_NUMBER(VTYPE_UINT8
, "%u", unsigned, mUint8Value
)
825 CASE__SMPRINTF_NUMBER(VTYPE_UINT16
, "%u", unsigned, mUint16Value
)
826 CASE__SMPRINTF_NUMBER(VTYPE_UINT32
, "%u", unsigned, mUint32Value
)
827 CASE__SMPRINTF_NUMBER(VTYPE_UINT64
, "%llu", int64_t, mUint64Value
)
829 // XXX Would we rather print "true" / "false" ?
830 CASE__SMPRINTF_NUMBER(VTYPE_BOOL
, "%d", int, mBoolValue
)
832 CASE__SMPRINTF_NUMBER(VTYPE_CHAR
, "%c", char, mCharValue
)
834 #undef CASE__SMPRINTF_NUMBER
838 return NS_ERROR_OUT_OF_MEMORY
;
840 aOutString
.Assign(ptr
);
841 PR_smprintf_free(ptr
);
845 /* static */ nsresult
846 nsVariant::ConvertToAString(const nsDiscriminatedUnion
& aData
,
849 switch (aData
.mType
) {
850 case nsIDataType::VTYPE_ASTRING
:
851 case nsIDataType::VTYPE_DOMSTRING
:
852 aResult
.Assign(*aData
.u
.mAStringValue
);
854 case nsIDataType::VTYPE_CSTRING
:
855 CopyASCIItoUTF16(*aData
.u
.mCStringValue
, aResult
);
857 case nsIDataType::VTYPE_UTF8STRING
:
858 CopyUTF8toUTF16(*aData
.u
.mUTF8StringValue
, aResult
);
860 case nsIDataType::VTYPE_CHAR_STR
:
861 CopyASCIItoUTF16(aData
.u
.str
.mStringValue
, aResult
);
863 case nsIDataType::VTYPE_WCHAR_STR
:
864 aResult
.Assign(aData
.u
.wstr
.mWStringValue
);
866 case nsIDataType::VTYPE_STRING_SIZE_IS
:
867 CopyASCIItoUTF16(nsDependentCString(aData
.u
.str
.mStringValue
,
868 aData
.u
.str
.mStringLength
),
871 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
872 aResult
.Assign(aData
.u
.wstr
.mWStringValue
, aData
.u
.wstr
.mWStringLength
);
874 case nsIDataType::VTYPE_WCHAR
:
875 aResult
.Assign(aData
.u
.mWCharValue
);
878 nsAutoCString tempCString
;
879 nsresult rv
= ToString(aData
, tempCString
);
883 CopyASCIItoUTF16(tempCString
, aResult
);
889 /* static */ nsresult
890 nsVariant::ConvertToACString(const nsDiscriminatedUnion
& aData
,
893 switch (aData
.mType
) {
894 case nsIDataType::VTYPE_ASTRING
:
895 case nsIDataType::VTYPE_DOMSTRING
:
896 LossyCopyUTF16toASCII(*aData
.u
.mAStringValue
, aResult
);
898 case nsIDataType::VTYPE_CSTRING
:
899 aResult
.Assign(*aData
.u
.mCStringValue
);
901 case nsIDataType::VTYPE_UTF8STRING
:
902 // XXX This is an extra copy that should be avoided
903 // once Jag lands support for UTF8String and associated
904 // conversion methods.
905 LossyCopyUTF16toASCII(NS_ConvertUTF8toUTF16(*aData
.u
.mUTF8StringValue
),
908 case nsIDataType::VTYPE_CHAR_STR
:
909 aResult
.Assign(*aData
.u
.str
.mStringValue
);
911 case nsIDataType::VTYPE_WCHAR_STR
:
912 LossyCopyUTF16toASCII(nsDependentString(aData
.u
.wstr
.mWStringValue
),
915 case nsIDataType::VTYPE_STRING_SIZE_IS
:
916 aResult
.Assign(aData
.u
.str
.mStringValue
, aData
.u
.str
.mStringLength
);
918 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
919 LossyCopyUTF16toASCII(nsDependentString(aData
.u
.wstr
.mWStringValue
,
920 aData
.u
.wstr
.mWStringLength
),
923 case nsIDataType::VTYPE_WCHAR
: {
924 const char16_t
* str
= &aData
.u
.mWCharValue
;
925 LossyCopyUTF16toASCII(Substring(str
, 1), aResult
);
929 return ToString(aData
, aResult
);
933 /* static */ nsresult
934 nsVariant::ConvertToAUTF8String(const nsDiscriminatedUnion
& aData
,
935 nsAUTF8String
& aResult
)
937 switch (aData
.mType
) {
938 case nsIDataType::VTYPE_ASTRING
:
939 case nsIDataType::VTYPE_DOMSTRING
:
940 CopyUTF16toUTF8(*aData
.u
.mAStringValue
, aResult
);
942 case nsIDataType::VTYPE_CSTRING
:
943 // XXX Extra copy, can be removed if we're sure CSTRING can
944 // only contain ASCII.
945 CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(*aData
.u
.mCStringValue
),
948 case nsIDataType::VTYPE_UTF8STRING
:
949 aResult
.Assign(*aData
.u
.mUTF8StringValue
);
951 case nsIDataType::VTYPE_CHAR_STR
:
952 // XXX Extra copy, can be removed if we're sure CHAR_STR can
953 // only contain ASCII.
954 CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(aData
.u
.str
.mStringValue
),
957 case nsIDataType::VTYPE_WCHAR_STR
:
958 CopyUTF16toUTF8(aData
.u
.wstr
.mWStringValue
, aResult
);
960 case nsIDataType::VTYPE_STRING_SIZE_IS
:
961 // XXX Extra copy, can be removed if we're sure CHAR_STR can
962 // only contain ASCII.
963 CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(
964 nsDependentCString(aData
.u
.str
.mStringValue
,
965 aData
.u
.str
.mStringLength
)), aResult
);
967 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
968 CopyUTF16toUTF8(nsDependentString(aData
.u
.wstr
.mWStringValue
,
969 aData
.u
.wstr
.mWStringLength
),
972 case nsIDataType::VTYPE_WCHAR
: {
973 const char16_t
* str
= &aData
.u
.mWCharValue
;
974 CopyUTF16toUTF8(Substring(str
, 1), aResult
);
978 nsAutoCString tempCString
;
979 nsresult rv
= ToString(aData
, tempCString
);
983 // XXX Extra copy, can be removed if we're sure tempCString can
984 // only contain ASCII.
985 CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(tempCString
), aResult
);
991 /* static */ nsresult
992 nsVariant::ConvertToString(const nsDiscriminatedUnion
& aData
, char** aResult
)
995 return nsVariant::ConvertToStringWithSize(aData
, &ignored
, aResult
);
998 /* static */ nsresult
999 nsVariant::ConvertToWString(const nsDiscriminatedUnion
& aData
,
1003 return nsVariant::ConvertToWStringWithSize(aData
, &ignored
, aResult
);
1006 /* static */ nsresult
1007 nsVariant::ConvertToStringWithSize(const nsDiscriminatedUnion
& aData
,
1008 uint32_t* aSize
, char** aStr
)
1010 nsAutoString tempString
;
1011 nsAutoCString tempCString
;
1014 switch (aData
.mType
) {
1015 case nsIDataType::VTYPE_ASTRING
:
1016 case nsIDataType::VTYPE_DOMSTRING
:
1017 *aSize
= aData
.u
.mAStringValue
->Length();
1018 *aStr
= ToNewCString(*aData
.u
.mAStringValue
);
1020 case nsIDataType::VTYPE_CSTRING
:
1021 *aSize
= aData
.u
.mCStringValue
->Length();
1022 *aStr
= ToNewCString(*aData
.u
.mCStringValue
);
1024 case nsIDataType::VTYPE_UTF8STRING
: {
1025 // XXX This is doing 1 extra copy. Need to fix this
1026 // when Jag lands UTF8String
1028 // *aSize = *aData.mUTF8StringValue->Length();
1029 // *aStr = ToNewCString(*aData.mUTF8StringValue);
1030 // But this will have to do for now.
1031 NS_ConvertUTF8toUTF16
tempString(*aData
.u
.mUTF8StringValue
);
1032 *aSize
= tempString
.Length();
1033 *aStr
= ToNewCString(tempString
);
1036 case nsIDataType::VTYPE_CHAR_STR
: {
1037 nsDependentCString
cString(aData
.u
.str
.mStringValue
);
1038 *aSize
= cString
.Length();
1039 *aStr
= ToNewCString(cString
);
1042 case nsIDataType::VTYPE_WCHAR_STR
: {
1043 nsDependentString
string(aData
.u
.wstr
.mWStringValue
);
1044 *aSize
= string
.Length();
1045 *aStr
= ToNewCString(string
);
1048 case nsIDataType::VTYPE_STRING_SIZE_IS
: {
1049 nsDependentCString
cString(aData
.u
.str
.mStringValue
,
1050 aData
.u
.str
.mStringLength
);
1051 *aSize
= cString
.Length();
1052 *aStr
= ToNewCString(cString
);
1055 case nsIDataType::VTYPE_WSTRING_SIZE_IS
: {
1056 nsDependentString
string(aData
.u
.wstr
.mWStringValue
,
1057 aData
.u
.wstr
.mWStringLength
);
1058 *aSize
= string
.Length();
1059 *aStr
= ToNewCString(string
);
1062 case nsIDataType::VTYPE_WCHAR
:
1063 tempString
.Assign(aData
.u
.mWCharValue
);
1064 *aSize
= tempString
.Length();
1065 *aStr
= ToNewCString(tempString
);
1068 rv
= ToString(aData
, tempCString
);
1069 if (NS_FAILED(rv
)) {
1072 *aSize
= tempCString
.Length();
1073 *aStr
= ToNewCString(tempCString
);
1077 return *aStr
? NS_OK
: NS_ERROR_OUT_OF_MEMORY
;
1079 /* static */ nsresult
1080 nsVariant::ConvertToWStringWithSize(const nsDiscriminatedUnion
& aData
,
1081 uint32_t* aSize
, char16_t
** aStr
)
1083 nsAutoString tempString
;
1084 nsAutoCString tempCString
;
1087 switch (aData
.mType
) {
1088 case nsIDataType::VTYPE_ASTRING
:
1089 case nsIDataType::VTYPE_DOMSTRING
:
1090 *aSize
= aData
.u
.mAStringValue
->Length();
1091 *aStr
= ToNewUnicode(*aData
.u
.mAStringValue
);
1093 case nsIDataType::VTYPE_CSTRING
:
1094 *aSize
= aData
.u
.mCStringValue
->Length();
1095 *aStr
= ToNewUnicode(*aData
.u
.mCStringValue
);
1097 case nsIDataType::VTYPE_UTF8STRING
: {
1098 *aStr
= UTF8ToNewUnicode(*aData
.u
.mUTF8StringValue
, aSize
);
1101 case nsIDataType::VTYPE_CHAR_STR
: {
1102 nsDependentCString
cString(aData
.u
.str
.mStringValue
);
1103 *aSize
= cString
.Length();
1104 *aStr
= ToNewUnicode(cString
);
1107 case nsIDataType::VTYPE_WCHAR_STR
: {
1108 nsDependentString
string(aData
.u
.wstr
.mWStringValue
);
1109 *aSize
= string
.Length();
1110 *aStr
= ToNewUnicode(string
);
1113 case nsIDataType::VTYPE_STRING_SIZE_IS
: {
1114 nsDependentCString
cString(aData
.u
.str
.mStringValue
,
1115 aData
.u
.str
.mStringLength
);
1116 *aSize
= cString
.Length();
1117 *aStr
= ToNewUnicode(cString
);
1120 case nsIDataType::VTYPE_WSTRING_SIZE_IS
: {
1121 nsDependentString
string(aData
.u
.wstr
.mWStringValue
,
1122 aData
.u
.wstr
.mWStringLength
);
1123 *aSize
= string
.Length();
1124 *aStr
= ToNewUnicode(string
);
1127 case nsIDataType::VTYPE_WCHAR
:
1128 tempString
.Assign(aData
.u
.mWCharValue
);
1129 *aSize
= tempString
.Length();
1130 *aStr
= ToNewUnicode(tempString
);
1133 rv
= ToString(aData
, tempCString
);
1134 if (NS_FAILED(rv
)) {
1137 *aSize
= tempCString
.Length();
1138 *aStr
= ToNewUnicode(tempCString
);
1142 return *aStr
? NS_OK
: NS_ERROR_OUT_OF_MEMORY
;
1145 /* static */ nsresult
1146 nsVariant::ConvertToISupports(const nsDiscriminatedUnion
& aData
,
1147 nsISupports
** aResult
)
1149 switch (aData
.mType
) {
1150 case nsIDataType::VTYPE_INTERFACE
:
1151 case nsIDataType::VTYPE_INTERFACE_IS
:
1152 if (aData
.u
.iface
.mInterfaceValue
) {
1153 return aData
.u
.iface
.mInterfaceValue
->
1154 QueryInterface(NS_GET_IID(nsISupports
), (void**)aResult
);
1160 return NS_ERROR_CANNOT_CONVERT_DATA
;
1164 /* static */ nsresult
1165 nsVariant::ConvertToInterface(const nsDiscriminatedUnion
& aData
, nsIID
** aIID
,
1170 switch (aData
.mType
) {
1171 case nsIDataType::VTYPE_INTERFACE
:
1172 piid
= &NS_GET_IID(nsISupports
);
1174 case nsIDataType::VTYPE_INTERFACE_IS
:
1175 piid
= &aData
.u
.iface
.mInterfaceID
;
1178 return NS_ERROR_CANNOT_CONVERT_DATA
;
1181 *aIID
= (nsIID
*)nsMemory::Clone(piid
, sizeof(nsIID
));
1183 return NS_ERROR_OUT_OF_MEMORY
;
1186 if (aData
.u
.iface
.mInterfaceValue
) {
1187 return aData
.u
.iface
.mInterfaceValue
->QueryInterface(*piid
,
1191 *aInterface
= nullptr;
1195 /* static */ nsresult
1196 nsVariant::ConvertToArray(const nsDiscriminatedUnion
& aData
, uint16_t* aType
,
1197 nsIID
* aIID
, uint32_t* aCount
, void** aPtr
)
1199 // XXX perhaps we'd like to add support for converting each of the various
1200 // types into an array containing one element of that type. We can leverage
1201 // CloneArray to do this if we want to support this.
1203 if (aData
.mType
== nsIDataType::VTYPE_ARRAY
) {
1204 return CloneArray(aData
.u
.array
.mArrayType
, &aData
.u
.array
.mArrayInterfaceID
,
1205 aData
.u
.array
.mArrayCount
, aData
.u
.array
.mArrayValue
,
1206 aType
, aIID
, aCount
, aPtr
);
1208 return NS_ERROR_CANNOT_CONVERT_DATA
;
1211 /***************************************************************************/
1212 // static setter functions...
1214 #define DATA_SETTER_PROLOGUE(data_) \
1215 nsVariant::Cleanup(data_);
1217 #define DATA_SETTER_EPILOGUE(data_, type_) \
1218 data_->mType = nsIDataType :: type_; \
1221 #define DATA_SETTER(data_, type_, member_, value_) \
1222 DATA_SETTER_PROLOGUE(data_) \
1223 data_->u.member_ = value_; \
1224 DATA_SETTER_EPILOGUE(data_, type_)
1226 #define DATA_SETTER_WITH_CAST(data_, type_, member_, cast_, value_) \
1227 DATA_SETTER_PROLOGUE(data_) \
1228 data_->u.member_ = cast_ value_; \
1229 DATA_SETTER_EPILOGUE(data_, type_)
1232 /********************************************/
1234 #define CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \
1237 #define CASE__SET_FROM_VARIANT_VTYPE__GETTER(member_, name_) \
1238 rv = aValue->GetAs##name_ (&(aData->u. member_ ));
1240 #define CASE__SET_FROM_VARIANT_VTYPE__GETTER_CAST(cast_, member_, name_) \
1241 rv = aValue->GetAs##name_ ( cast_ &(aData->u. member_ ));
1243 #define CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_) \
1244 if(NS_SUCCEEDED(rv)) \
1246 aData->mType = nsIDataType :: type_ ; \
1251 #define CASE__SET_FROM_VARIANT_TYPE(type_, member_, name_) \
1252 case nsIDataType :: type_ : \
1253 CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \
1254 CASE__SET_FROM_VARIANT_VTYPE__GETTER(member_, name_) \
1255 CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_)
1257 #define CASE__SET_FROM_VARIANT_VTYPE_CAST(type_, cast_, member_, name_) \
1258 case nsIDataType :: type_ : \
1259 CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \
1260 CASE__SET_FROM_VARIANT_VTYPE__GETTER_CAST(cast_, member_, name_) \
1261 CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_)
1264 /* static */ nsresult
1265 nsVariant::SetFromVariant(nsDiscriminatedUnion
* aData
, nsIVariant
* aValue
)
1270 nsVariant::Cleanup(aData
);
1272 rv
= aValue
->GetDataType(&type
);
1273 if (NS_FAILED(rv
)) {
1278 CASE__SET_FROM_VARIANT_VTYPE_CAST(VTYPE_INT8
, (uint8_t*), mInt8Value
,
1280 CASE__SET_FROM_VARIANT_TYPE(VTYPE_INT16
, mInt16Value
, Int16
)
1281 CASE__SET_FROM_VARIANT_TYPE(VTYPE_INT32
, mInt32Value
, Int32
)
1282 CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT8
, mUint8Value
, Uint8
)
1283 CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT16
, mUint16Value
, Uint16
)
1284 CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT32
, mUint32Value
, Uint32
)
1285 CASE__SET_FROM_VARIANT_TYPE(VTYPE_FLOAT
, mFloatValue
, Float
)
1286 CASE__SET_FROM_VARIANT_TYPE(VTYPE_DOUBLE
, mDoubleValue
, Double
)
1287 CASE__SET_FROM_VARIANT_TYPE(VTYPE_BOOL
, mBoolValue
, Bool
)
1288 CASE__SET_FROM_VARIANT_TYPE(VTYPE_CHAR
, mCharValue
, Char
)
1289 CASE__SET_FROM_VARIANT_TYPE(VTYPE_WCHAR
, mWCharValue
, WChar
)
1290 CASE__SET_FROM_VARIANT_TYPE(VTYPE_ID
, mIDValue
, ID
)
1292 case nsIDataType::VTYPE_ASTRING
:
1293 case nsIDataType::VTYPE_DOMSTRING
:
1294 case nsIDataType::VTYPE_WCHAR_STR
:
1295 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
1296 CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_ASTRING
);
1297 aData
->u
.mAStringValue
= new nsString();
1298 if (!aData
->u
.mAStringValue
) {
1299 return NS_ERROR_OUT_OF_MEMORY
;
1301 rv
= aValue
->GetAsAString(*aData
->u
.mAStringValue
);
1302 if (NS_FAILED(rv
)) {
1303 delete aData
->u
.mAStringValue
;
1305 CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_ASTRING
)
1307 case nsIDataType::VTYPE_CSTRING
:
1308 CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_CSTRING
);
1309 aData
->u
.mCStringValue
= new nsCString();
1310 if (!aData
->u
.mCStringValue
) {
1311 return NS_ERROR_OUT_OF_MEMORY
;
1313 rv
= aValue
->GetAsACString(*aData
->u
.mCStringValue
);
1314 if (NS_FAILED(rv
)) {
1315 delete aData
->u
.mCStringValue
;
1317 CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_CSTRING
)
1319 case nsIDataType::VTYPE_UTF8STRING
:
1320 CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_UTF8STRING
);
1321 aData
->u
.mUTF8StringValue
= new nsUTF8String();
1322 if (!aData
->u
.mUTF8StringValue
) {
1323 return NS_ERROR_OUT_OF_MEMORY
;
1325 rv
= aValue
->GetAsAUTF8String(*aData
->u
.mUTF8StringValue
);
1326 if (NS_FAILED(rv
)) {
1327 delete aData
->u
.mUTF8StringValue
;
1329 CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_UTF8STRING
)
1331 case nsIDataType::VTYPE_CHAR_STR
:
1332 case nsIDataType::VTYPE_STRING_SIZE_IS
:
1333 CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_STRING_SIZE_IS
);
1334 rv
= aValue
->GetAsStringWithSize(&aData
->u
.str
.mStringLength
,
1335 &aData
->u
.str
.mStringValue
);
1336 CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_STRING_SIZE_IS
)
1338 case nsIDataType::VTYPE_INTERFACE
:
1339 case nsIDataType::VTYPE_INTERFACE_IS
:
1340 CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_INTERFACE_IS
);
1341 // XXX This iid handling is ugly!
1343 rv
= aValue
->GetAsInterface(&iid
, (void**)&aData
->u
.iface
.mInterfaceValue
);
1344 if (NS_SUCCEEDED(rv
)) {
1345 aData
->u
.iface
.mInterfaceID
= *iid
;
1346 nsMemory::Free((char*)iid
);
1348 CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_INTERFACE_IS
)
1350 case nsIDataType::VTYPE_ARRAY
:
1351 CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_ARRAY
);
1352 rv
= aValue
->GetAsArray(&aData
->u
.array
.mArrayType
,
1353 &aData
->u
.array
.mArrayInterfaceID
,
1354 &aData
->u
.array
.mArrayCount
,
1355 &aData
->u
.array
.mArrayValue
);
1356 CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_ARRAY
)
1358 case nsIDataType::VTYPE_VOID
:
1359 rv
= nsVariant::SetToVoid(aData
);
1361 case nsIDataType::VTYPE_EMPTY_ARRAY
:
1362 rv
= nsVariant::SetToEmptyArray(aData
);
1364 case nsIDataType::VTYPE_EMPTY
:
1365 rv
= nsVariant::SetToEmpty(aData
);
1368 NS_ERROR("bad type in variant!");
1369 rv
= NS_ERROR_FAILURE
;
1375 /* static */ nsresult
1376 nsVariant::SetFromInt8(nsDiscriminatedUnion
* aData
, uint8_t aValue
)
1378 DATA_SETTER_WITH_CAST(aData
, VTYPE_INT8
, mInt8Value
, (uint8_t), aValue
)
1380 /* static */ nsresult
1381 nsVariant::SetFromInt16(nsDiscriminatedUnion
* aData
, int16_t aValue
)
1383 DATA_SETTER(aData
, VTYPE_INT16
, mInt16Value
, aValue
)
1385 /* static */ nsresult
1386 nsVariant::SetFromInt32(nsDiscriminatedUnion
* aData
, int32_t aValue
)
1388 DATA_SETTER(aData
, VTYPE_INT32
, mInt32Value
, aValue
)
1390 /* static */ nsresult
1391 nsVariant::SetFromInt64(nsDiscriminatedUnion
* aData
, int64_t aValue
)
1393 DATA_SETTER(aData
, VTYPE_INT64
, mInt64Value
, aValue
)
1395 /* static */ nsresult
1396 nsVariant::SetFromUint8(nsDiscriminatedUnion
* aData
, uint8_t aValue
)
1398 DATA_SETTER(aData
, VTYPE_UINT8
, mUint8Value
, aValue
)
1400 /* static */ nsresult
1401 nsVariant::SetFromUint16(nsDiscriminatedUnion
* aData
, uint16_t aValue
)
1403 DATA_SETTER(aData
, VTYPE_UINT16
, mUint16Value
, aValue
)
1405 /* static */ nsresult
1406 nsVariant::SetFromUint32(nsDiscriminatedUnion
* aData
, uint32_t aValue
)
1408 DATA_SETTER(aData
, VTYPE_UINT32
, mUint32Value
, aValue
)
1410 /* static */ nsresult
1411 nsVariant::SetFromUint64(nsDiscriminatedUnion
* aData
, uint64_t aValue
)
1413 DATA_SETTER(aData
, VTYPE_UINT64
, mUint64Value
, aValue
)
1415 /* static */ nsresult
1416 nsVariant::SetFromFloat(nsDiscriminatedUnion
* aData
, float aValue
)
1418 DATA_SETTER(aData
, VTYPE_FLOAT
, mFloatValue
, aValue
)
1420 /* static */ nsresult
1421 nsVariant::SetFromDouble(nsDiscriminatedUnion
* aData
, double aValue
)
1423 DATA_SETTER(aData
, VTYPE_DOUBLE
, mDoubleValue
, aValue
)
1425 /* static */ nsresult
1426 nsVariant::SetFromBool(nsDiscriminatedUnion
* aData
, bool aValue
)
1428 DATA_SETTER(aData
, VTYPE_BOOL
, mBoolValue
, aValue
)
1430 /* static */ nsresult
1431 nsVariant::SetFromChar(nsDiscriminatedUnion
* aData
, char aValue
)
1433 DATA_SETTER(aData
, VTYPE_CHAR
, mCharValue
, aValue
)
1435 /* static */ nsresult
1436 nsVariant::SetFromWChar(nsDiscriminatedUnion
* aData
, char16_t aValue
)
1438 DATA_SETTER(aData
, VTYPE_WCHAR
, mWCharValue
, aValue
)
1440 /* static */ nsresult
1441 nsVariant::SetFromID(nsDiscriminatedUnion
* aData
, const nsID
& aValue
)
1443 DATA_SETTER(aData
, VTYPE_ID
, mIDValue
, aValue
)
1445 /* static */ nsresult
1446 nsVariant::SetFromAString(nsDiscriminatedUnion
* aData
, const nsAString
& aValue
)
1448 DATA_SETTER_PROLOGUE(aData
);
1449 if (!(aData
->u
.mAStringValue
= new nsString(aValue
))) {
1450 return NS_ERROR_OUT_OF_MEMORY
;
1452 DATA_SETTER_EPILOGUE(aData
, VTYPE_ASTRING
);
1455 /* static */ nsresult
1456 nsVariant::SetFromACString(nsDiscriminatedUnion
* aData
,
1457 const nsACString
& aValue
)
1459 DATA_SETTER_PROLOGUE(aData
);
1460 if (!(aData
->u
.mCStringValue
= new nsCString(aValue
))) {
1461 return NS_ERROR_OUT_OF_MEMORY
;
1463 DATA_SETTER_EPILOGUE(aData
, VTYPE_CSTRING
);
1466 /* static */ nsresult
1467 nsVariant::SetFromAUTF8String(nsDiscriminatedUnion
* aData
,
1468 const nsAUTF8String
& aValue
)
1470 DATA_SETTER_PROLOGUE(aData
);
1471 if (!(aData
->u
.mUTF8StringValue
= new nsUTF8String(aValue
))) {
1472 return NS_ERROR_OUT_OF_MEMORY
;
1474 DATA_SETTER_EPILOGUE(aData
, VTYPE_UTF8STRING
);
1477 /* static */ nsresult
1478 nsVariant::SetFromString(nsDiscriminatedUnion
* aData
, const char* aValue
)
1480 DATA_SETTER_PROLOGUE(aData
);
1482 return NS_ERROR_NULL_POINTER
;
1484 return SetFromStringWithSize(aData
, strlen(aValue
), aValue
);
1486 /* static */ nsresult
1487 nsVariant::SetFromWString(nsDiscriminatedUnion
* aData
, const char16_t
* aValue
)
1489 DATA_SETTER_PROLOGUE(aData
);
1491 return NS_ERROR_NULL_POINTER
;
1493 return SetFromWStringWithSize(aData
, NS_strlen(aValue
), aValue
);
1495 /* static */ nsresult
1496 nsVariant::SetFromISupports(nsDiscriminatedUnion
* aData
, nsISupports
* aValue
)
1498 return SetFromInterface(aData
, NS_GET_IID(nsISupports
), aValue
);
1500 /* static */ nsresult
1501 nsVariant::SetFromInterface(nsDiscriminatedUnion
* aData
, const nsIID
& aIID
,
1502 nsISupports
* aValue
)
1504 DATA_SETTER_PROLOGUE(aData
);
1505 NS_IF_ADDREF(aValue
);
1506 aData
->u
.iface
.mInterfaceValue
= aValue
;
1507 aData
->u
.iface
.mInterfaceID
= aIID
;
1508 DATA_SETTER_EPILOGUE(aData
, VTYPE_INTERFACE_IS
);
1510 /* static */ nsresult
1511 nsVariant::SetFromArray(nsDiscriminatedUnion
* aData
, uint16_t aType
,
1512 const nsIID
* aIID
, uint32_t aCount
, void* aValue
)
1514 DATA_SETTER_PROLOGUE(aData
);
1515 if (!aValue
|| !aCount
) {
1516 return NS_ERROR_NULL_POINTER
;
1519 nsresult rv
= CloneArray(aType
, aIID
, aCount
, aValue
,
1520 &aData
->u
.array
.mArrayType
,
1521 &aData
->u
.array
.mArrayInterfaceID
,
1522 &aData
->u
.array
.mArrayCount
,
1523 &aData
->u
.array
.mArrayValue
);
1524 if (NS_FAILED(rv
)) {
1527 DATA_SETTER_EPILOGUE(aData
, VTYPE_ARRAY
);
1529 /* static */ nsresult
1530 nsVariant::SetFromStringWithSize(nsDiscriminatedUnion
* aData
, uint32_t aSize
,
1533 DATA_SETTER_PROLOGUE(aData
);
1535 return NS_ERROR_NULL_POINTER
;
1537 if (!(aData
->u
.str
.mStringValue
=
1538 (char*)nsMemory::Clone(aValue
, (aSize
+ 1) * sizeof(char)))) {
1539 return NS_ERROR_OUT_OF_MEMORY
;
1541 aData
->u
.str
.mStringLength
= aSize
;
1542 DATA_SETTER_EPILOGUE(aData
, VTYPE_STRING_SIZE_IS
);
1544 /* static */ nsresult
1545 nsVariant::SetFromWStringWithSize(nsDiscriminatedUnion
* aData
, uint32_t aSize
,
1546 const char16_t
* aValue
)
1548 DATA_SETTER_PROLOGUE(aData
);
1550 return NS_ERROR_NULL_POINTER
;
1552 if (!(aData
->u
.wstr
.mWStringValue
=
1553 (char16_t
*)nsMemory::Clone(aValue
, (aSize
+ 1) * sizeof(char16_t
)))) {
1554 return NS_ERROR_OUT_OF_MEMORY
;
1556 aData
->u
.wstr
.mWStringLength
= aSize
;
1557 DATA_SETTER_EPILOGUE(aData
, VTYPE_WSTRING_SIZE_IS
);
1559 /* static */ nsresult
1560 nsVariant::AllocateWStringWithSize(nsDiscriminatedUnion
* aData
, uint32_t aSize
)
1562 DATA_SETTER_PROLOGUE(aData
);
1563 if (!(aData
->u
.wstr
.mWStringValue
=
1564 (char16_t
*)NS_Alloc((aSize
+ 1) * sizeof(char16_t
)))) {
1565 return NS_ERROR_OUT_OF_MEMORY
;
1567 aData
->u
.wstr
.mWStringValue
[aSize
] = '\0';
1568 aData
->u
.wstr
.mWStringLength
= aSize
;
1569 DATA_SETTER_EPILOGUE(aData
, VTYPE_WSTRING_SIZE_IS
);
1571 /* static */ nsresult
1572 nsVariant::SetToVoid(nsDiscriminatedUnion
* aData
)
1574 DATA_SETTER_PROLOGUE(aData
);
1575 DATA_SETTER_EPILOGUE(aData
, VTYPE_VOID
);
1577 /* static */ nsresult
1578 nsVariant::SetToEmpty(nsDiscriminatedUnion
* aData
)
1580 DATA_SETTER_PROLOGUE(aData
);
1581 DATA_SETTER_EPILOGUE(aData
, VTYPE_EMPTY
);
1583 /* static */ nsresult
1584 nsVariant::SetToEmptyArray(nsDiscriminatedUnion
* aData
)
1586 DATA_SETTER_PROLOGUE(aData
);
1587 DATA_SETTER_EPILOGUE(aData
, VTYPE_EMPTY_ARRAY
);
1590 /***************************************************************************/
1592 /* static */ nsresult
1593 nsVariant::Initialize(nsDiscriminatedUnion
* aData
)
1595 aData
->mType
= nsIDataType::VTYPE_EMPTY
;
1599 /* static */ nsresult
1600 nsVariant::Cleanup(nsDiscriminatedUnion
* aData
)
1602 switch (aData
->mType
) {
1603 case nsIDataType::VTYPE_INT8
:
1604 case nsIDataType::VTYPE_INT16
:
1605 case nsIDataType::VTYPE_INT32
:
1606 case nsIDataType::VTYPE_INT64
:
1607 case nsIDataType::VTYPE_UINT8
:
1608 case nsIDataType::VTYPE_UINT16
:
1609 case nsIDataType::VTYPE_UINT32
:
1610 case nsIDataType::VTYPE_UINT64
:
1611 case nsIDataType::VTYPE_FLOAT
:
1612 case nsIDataType::VTYPE_DOUBLE
:
1613 case nsIDataType::VTYPE_BOOL
:
1614 case nsIDataType::VTYPE_CHAR
:
1615 case nsIDataType::VTYPE_WCHAR
:
1616 case nsIDataType::VTYPE_VOID
:
1617 case nsIDataType::VTYPE_ID
:
1619 case nsIDataType::VTYPE_ASTRING
:
1620 case nsIDataType::VTYPE_DOMSTRING
:
1621 delete aData
->u
.mAStringValue
;
1623 case nsIDataType::VTYPE_CSTRING
:
1624 delete aData
->u
.mCStringValue
;
1626 case nsIDataType::VTYPE_UTF8STRING
:
1627 delete aData
->u
.mUTF8StringValue
;
1629 case nsIDataType::VTYPE_CHAR_STR
:
1630 case nsIDataType::VTYPE_STRING_SIZE_IS
:
1631 nsMemory::Free((char*)aData
->u
.str
.mStringValue
);
1633 case nsIDataType::VTYPE_WCHAR_STR
:
1634 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
1635 nsMemory::Free((char*)aData
->u
.wstr
.mWStringValue
);
1637 case nsIDataType::VTYPE_INTERFACE
:
1638 case nsIDataType::VTYPE_INTERFACE_IS
:
1639 NS_IF_RELEASE(aData
->u
.iface
.mInterfaceValue
);
1641 case nsIDataType::VTYPE_ARRAY
:
1644 case nsIDataType::VTYPE_EMPTY_ARRAY
:
1645 case nsIDataType::VTYPE_EMPTY
:
1648 NS_ERROR("bad type in variant!");
1652 aData
->mType
= nsIDataType::VTYPE_EMPTY
;
1657 nsVariant::Traverse(const nsDiscriminatedUnion
& aData
,
1658 nsCycleCollectionTraversalCallback
& aCb
)
1660 switch (aData
.mType
) {
1661 case nsIDataType::VTYPE_INTERFACE
:
1662 case nsIDataType::VTYPE_INTERFACE_IS
:
1663 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb
, "mData");
1664 aCb
.NoteXPCOMChild(aData
.u
.iface
.mInterfaceValue
);
1666 case nsIDataType::VTYPE_ARRAY
:
1667 switch (aData
.u
.array
.mArrayType
) {
1668 case nsIDataType::VTYPE_INTERFACE
:
1669 case nsIDataType::VTYPE_INTERFACE_IS
: {
1670 nsISupports
** p
= (nsISupports
**)aData
.u
.array
.mArrayValue
;
1671 for (uint32_t i
= aData
.u
.array
.mArrayCount
; i
> 0; ++p
, --i
) {
1672 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb
, "mData[i]");
1673 aCb
.NoteXPCOMChild(*p
);
1684 /***************************************************************************/
1685 /***************************************************************************/
1688 NS_IMPL_ISUPPORTS(nsVariant
, nsIVariant
, nsIWritableVariant
)
1690 nsVariant::nsVariant()
1693 nsVariant::Initialize(&mData
);
1697 // Assert that the nsIDataType consts match the values #defined in
1698 // xpt_struct.h. Bad things happen somewhere if they don't.
1704 static const THE_TYPES array
[] = {
1705 {nsIDataType::VTYPE_INT8
, TD_INT8
},
1706 {nsIDataType::VTYPE_INT16
, TD_INT16
},
1707 {nsIDataType::VTYPE_INT32
, TD_INT32
},
1708 {nsIDataType::VTYPE_INT64
, TD_INT64
},
1709 {nsIDataType::VTYPE_UINT8
, TD_UINT8
},
1710 {nsIDataType::VTYPE_UINT16
, TD_UINT16
},
1711 {nsIDataType::VTYPE_UINT32
, TD_UINT32
},
1712 {nsIDataType::VTYPE_UINT64
, TD_UINT64
},
1713 {nsIDataType::VTYPE_FLOAT
, TD_FLOAT
},
1714 {nsIDataType::VTYPE_DOUBLE
, TD_DOUBLE
},
1715 {nsIDataType::VTYPE_BOOL
, TD_BOOL
},
1716 {nsIDataType::VTYPE_CHAR
, TD_CHAR
},
1717 {nsIDataType::VTYPE_WCHAR
, TD_WCHAR
},
1718 {nsIDataType::VTYPE_VOID
, TD_VOID
},
1719 {nsIDataType::VTYPE_ID
, TD_PNSIID
},
1720 {nsIDataType::VTYPE_DOMSTRING
, TD_DOMSTRING
},
1721 {nsIDataType::VTYPE_CHAR_STR
, TD_PSTRING
},
1722 {nsIDataType::VTYPE_WCHAR_STR
, TD_PWSTRING
},
1723 {nsIDataType::VTYPE_INTERFACE
, TD_INTERFACE_TYPE
},
1724 {nsIDataType::VTYPE_INTERFACE_IS
, TD_INTERFACE_IS_TYPE
},
1725 {nsIDataType::VTYPE_ARRAY
, TD_ARRAY
},
1726 {nsIDataType::VTYPE_STRING_SIZE_IS
, TD_PSTRING_SIZE_IS
},
1727 {nsIDataType::VTYPE_WSTRING_SIZE_IS
, TD_PWSTRING_SIZE_IS
},
1728 {nsIDataType::VTYPE_UTF8STRING
, TD_UTF8STRING
},
1729 {nsIDataType::VTYPE_CSTRING
, TD_CSTRING
},
1730 {nsIDataType::VTYPE_ASTRING
, TD_ASTRING
}
1732 static const int length
= sizeof(array
) / sizeof(array
[0]);
1733 static bool inited
= false;
1735 for (int i
= 0; i
< length
; ++i
) {
1736 NS_ASSERTION(array
[i
].a
== array
[i
].b
, "bad const declaration");
1744 nsVariant::~nsVariant()
1746 nsVariant::Cleanup(&mData
);
1749 // For all the data getters we just forward to the static (and sharable)
1750 // 'ConvertTo' functions.
1752 /* readonly attribute uint16_t dataType; */
1754 nsVariant::GetDataType(uint16_t* aDataType
)
1756 *aDataType
= mData
.mType
;
1760 /* uint8_t getAsInt8 (); */
1762 nsVariant::GetAsInt8(uint8_t* aResult
)
1764 return nsVariant::ConvertToInt8(mData
, aResult
);
1767 /* int16_t getAsInt16 (); */
1769 nsVariant::GetAsInt16(int16_t* aResult
)
1771 return nsVariant::ConvertToInt16(mData
, aResult
);
1774 /* int32_t getAsInt32 (); */
1776 nsVariant::GetAsInt32(int32_t* aResult
)
1778 return nsVariant::ConvertToInt32(mData
, aResult
);
1781 /* int64_t getAsInt64 (); */
1783 nsVariant::GetAsInt64(int64_t* aResult
)
1785 return nsVariant::ConvertToInt64(mData
, aResult
);
1788 /* uint8_t getAsUint8 (); */
1790 nsVariant::GetAsUint8(uint8_t* aResult
)
1792 return nsVariant::ConvertToUint8(mData
, aResult
);
1795 /* uint16_t getAsUint16 (); */
1797 nsVariant::GetAsUint16(uint16_t* aResult
)
1799 return nsVariant::ConvertToUint16(mData
, aResult
);
1802 /* uint32_t getAsUint32 (); */
1804 nsVariant::GetAsUint32(uint32_t* aResult
)
1806 return nsVariant::ConvertToUint32(mData
, aResult
);
1809 /* uint64_t getAsUint64 (); */
1811 nsVariant::GetAsUint64(uint64_t* aResult
)
1813 return nsVariant::ConvertToUint64(mData
, aResult
);
1816 /* float getAsFloat (); */
1818 nsVariant::GetAsFloat(float* aResult
)
1820 return nsVariant::ConvertToFloat(mData
, aResult
);
1823 /* double getAsDouble (); */
1825 nsVariant::GetAsDouble(double* aResult
)
1827 return nsVariant::ConvertToDouble(mData
, aResult
);
1830 /* bool getAsBool (); */
1832 nsVariant::GetAsBool(bool* aResult
)
1834 return nsVariant::ConvertToBool(mData
, aResult
);
1837 /* char getAsChar (); */
1839 nsVariant::GetAsChar(char* aResult
)
1841 return nsVariant::ConvertToChar(mData
, aResult
);
1844 /* wchar getAsWChar (); */
1846 nsVariant::GetAsWChar(char16_t
* aResult
)
1848 return nsVariant::ConvertToWChar(mData
, aResult
);
1851 /* [notxpcom] nsresult getAsID (out nsID retval); */
1852 NS_IMETHODIMP_(nsresult
)
1853 nsVariant::GetAsID(nsID
* aResult
)
1855 return nsVariant::ConvertToID(mData
, aResult
);
1858 /* AString getAsAString (); */
1860 nsVariant::GetAsAString(nsAString
& aResult
)
1862 return nsVariant::ConvertToAString(mData
, aResult
);
1865 /* DOMString getAsDOMString (); */
1867 nsVariant::GetAsDOMString(nsAString
& aResult
)
1869 // A DOMString maps to an AString internally, so we can re-use
1870 // ConvertToAString here.
1871 return nsVariant::ConvertToAString(mData
, aResult
);
1874 /* ACString getAsACString (); */
1876 nsVariant::GetAsACString(nsACString
& aResult
)
1878 return nsVariant::ConvertToACString(mData
, aResult
);
1881 /* AUTF8String getAsAUTF8String (); */
1883 nsVariant::GetAsAUTF8String(nsAUTF8String
& aResult
)
1885 return nsVariant::ConvertToAUTF8String(mData
, aResult
);
1888 /* string getAsString (); */
1890 nsVariant::GetAsString(char** aResult
)
1892 return nsVariant::ConvertToString(mData
, aResult
);
1895 /* wstring getAsWString (); */
1897 nsVariant::GetAsWString(char16_t
** aResult
)
1899 return nsVariant::ConvertToWString(mData
, aResult
);
1902 /* nsISupports getAsISupports (); */
1904 nsVariant::GetAsISupports(nsISupports
** aResult
)
1906 return nsVariant::ConvertToISupports(mData
, aResult
);
1909 /* jsval getAsJSVal() */
1911 nsVariant::GetAsJSVal(JS::MutableHandleValue
)
1913 // Can only get the jsval from an XPCVariant.
1914 return NS_ERROR_CANNOT_CONVERT_DATA
;
1917 /* void getAsInterface (out nsIIDPtr iid, [iid_is (iid), retval] out nsQIResult iface); */
1919 nsVariant::GetAsInterface(nsIID
** aIID
, void** aInterface
)
1921 return nsVariant::ConvertToInterface(mData
, aIID
, aInterface
);
1924 /* [notxpcom] nsresult getAsArray (out uint16_t type, out nsIID iid, out uint32_t count, out voidPtr ptr); */
1925 NS_IMETHODIMP_(nsresult
)
1926 nsVariant::GetAsArray(uint16_t* aType
, nsIID
* aIID
,
1927 uint32_t* aCount
, void** aPtr
)
1929 return nsVariant::ConvertToArray(mData
, aType
, aIID
, aCount
, aPtr
);
1932 /* void getAsStringWithSize (out uint32_t size, [size_is (size), retval] out string str); */
1934 nsVariant::GetAsStringWithSize(uint32_t* aSize
, char** aStr
)
1936 return nsVariant::ConvertToStringWithSize(mData
, aSize
, aStr
);
1939 /* void getAsWStringWithSize (out uint32_t size, [size_is (size), retval] out wstring str); */
1941 nsVariant::GetAsWStringWithSize(uint32_t* aSize
, char16_t
** aStr
)
1943 return nsVariant::ConvertToWStringWithSize(mData
, aSize
, aStr
);
1946 /***************************************************************************/
1948 /* attribute bool writable; */
1950 nsVariant::GetWritable(bool* aWritable
)
1952 *aWritable
= mWritable
;
1956 nsVariant::SetWritable(bool aWritable
)
1958 if (!mWritable
&& aWritable
) {
1959 return NS_ERROR_FAILURE
;
1961 mWritable
= aWritable
;
1965 /***************************************************************************/
1967 // For all the data setters we just forward to the static (and sharable)
1968 // 'SetFrom' functions.
1970 /* void setAsInt8 (in uint8_t aValue); */
1972 nsVariant::SetAsInt8(uint8_t aValue
)
1975 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
1977 return nsVariant::SetFromInt8(&mData
, aValue
);
1980 /* void setAsInt16 (in int16_t aValue); */
1982 nsVariant::SetAsInt16(int16_t aValue
)
1985 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
1987 return nsVariant::SetFromInt16(&mData
, aValue
);
1990 /* void setAsInt32 (in int32_t aValue); */
1992 nsVariant::SetAsInt32(int32_t aValue
)
1995 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
1997 return nsVariant::SetFromInt32(&mData
, aValue
);
2000 /* void setAsInt64 (in int64_t aValue); */
2002 nsVariant::SetAsInt64(int64_t aValue
)
2005 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2007 return nsVariant::SetFromInt64(&mData
, aValue
);
2010 /* void setAsUint8 (in uint8_t aValue); */
2012 nsVariant::SetAsUint8(uint8_t aValue
)
2015 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2017 return nsVariant::SetFromUint8(&mData
, aValue
);
2020 /* void setAsUint16 (in uint16_t aValue); */
2022 nsVariant::SetAsUint16(uint16_t aValue
)
2025 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2027 return nsVariant::SetFromUint16(&mData
, aValue
);
2030 /* void setAsUint32 (in uint32_t aValue); */
2032 nsVariant::SetAsUint32(uint32_t aValue
)
2035 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2037 return nsVariant::SetFromUint32(&mData
, aValue
);
2040 /* void setAsUint64 (in uint64_t aValue); */
2042 nsVariant::SetAsUint64(uint64_t aValue
)
2045 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2047 return nsVariant::SetFromUint64(&mData
, aValue
);
2050 /* void setAsFloat (in float aValue); */
2052 nsVariant::SetAsFloat(float aValue
)
2055 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2057 return nsVariant::SetFromFloat(&mData
, aValue
);
2060 /* void setAsDouble (in double aValue); */
2062 nsVariant::SetAsDouble(double aValue
)
2065 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2067 return nsVariant::SetFromDouble(&mData
, aValue
);
2070 /* void setAsBool (in bool aValue); */
2072 nsVariant::SetAsBool(bool aValue
)
2075 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2077 return nsVariant::SetFromBool(&mData
, aValue
);
2080 /* void setAsChar (in char aValue); */
2082 nsVariant::SetAsChar(char aValue
)
2085 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2087 return nsVariant::SetFromChar(&mData
, aValue
);
2090 /* void setAsWChar (in wchar aValue); */
2092 nsVariant::SetAsWChar(char16_t aValue
)
2095 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2097 return nsVariant::SetFromWChar(&mData
, aValue
);
2100 /* void setAsID (in nsIDRef aValue); */
2102 nsVariant::SetAsID(const nsID
& aValue
)
2105 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2107 return nsVariant::SetFromID(&mData
, aValue
);
2110 /* void setAsAString (in AString aValue); */
2112 nsVariant::SetAsAString(const nsAString
& aValue
)
2115 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2117 return nsVariant::SetFromAString(&mData
, aValue
);
2120 /* void setAsDOMString (in DOMString aValue); */
2122 nsVariant::SetAsDOMString(const nsAString
& aValue
)
2125 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2128 DATA_SETTER_PROLOGUE((&mData
));
2129 if (!(mData
.u
.mAStringValue
= new nsString(aValue
))) {
2130 return NS_ERROR_OUT_OF_MEMORY
;
2132 DATA_SETTER_EPILOGUE((&mData
), VTYPE_DOMSTRING
);
2135 /* void setAsACString (in ACString aValue); */
2137 nsVariant::SetAsACString(const nsACString
& aValue
)
2140 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2142 return nsVariant::SetFromACString(&mData
, aValue
);
2145 /* void setAsAUTF8String (in AUTF8String aValue); */
2147 nsVariant::SetAsAUTF8String(const nsAUTF8String
& aValue
)
2150 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2152 return nsVariant::SetFromAUTF8String(&mData
, aValue
);
2155 /* void setAsString (in string aValue); */
2157 nsVariant::SetAsString(const char* aValue
)
2160 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2162 return nsVariant::SetFromString(&mData
, aValue
);
2165 /* void setAsWString (in wstring aValue); */
2167 nsVariant::SetAsWString(const char16_t
* aValue
)
2170 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2172 return nsVariant::SetFromWString(&mData
, aValue
);
2175 /* void setAsISupports (in nsISupports aValue); */
2177 nsVariant::SetAsISupports(nsISupports
* aValue
)
2180 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2182 return nsVariant::SetFromISupports(&mData
, aValue
);
2185 /* void setAsInterface (in nsIIDRef iid, [iid_is (iid)] in nsQIResult iface); */
2187 nsVariant::SetAsInterface(const nsIID
& aIID
, void* aInterface
)
2190 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2192 return nsVariant::SetFromInterface(&mData
, aIID
, (nsISupports
*)aInterface
);
2195 /* [noscript] void setAsArray (in uint16_t type, in nsIIDPtr iid, in uint32_t count, in voidPtr ptr); */
2197 nsVariant::SetAsArray(uint16_t aType
, const nsIID
* aIID
,
2198 uint32_t aCount
, void* aPtr
)
2201 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2203 return nsVariant::SetFromArray(&mData
, aType
, aIID
, aCount
, aPtr
);
2206 /* void setAsStringWithSize (in uint32_t size, [size_is (size)] in string str); */
2208 nsVariant::SetAsStringWithSize(uint32_t aSize
, const char* aStr
)
2211 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2213 return nsVariant::SetFromStringWithSize(&mData
, aSize
, aStr
);
2216 /* void setAsWStringWithSize (in uint32_t size, [size_is (size)] in wstring str); */
2218 nsVariant::SetAsWStringWithSize(uint32_t aSize
, const char16_t
* aStr
)
2221 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2223 return nsVariant::SetFromWStringWithSize(&mData
, aSize
, aStr
);
2226 /* void setAsVoid (); */
2228 nsVariant::SetAsVoid()
2231 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2233 return nsVariant::SetToVoid(&mData
);
2236 /* void setAsEmpty (); */
2238 nsVariant::SetAsEmpty()
2241 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2243 return nsVariant::SetToEmpty(&mData
);
2246 /* void setAsEmptyArray (); */
2248 nsVariant::SetAsEmptyArray()
2251 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2253 return nsVariant::SetToEmptyArray(&mData
);
2256 /* void setFromVariant (in nsIVariant aValue); */
2258 nsVariant::SetFromVariant(nsIVariant
* aValue
)
2261 return NS_ERROR_OBJECT_IS_IMMUTABLE
;
2263 return nsVariant::SetFromVariant(&mData
, aValue
);