Line data Source code
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/. */
6 :
7 : #include "nsVariant.h"
8 : #include "prprf.h"
9 : #include "prdtoa.h"
10 : #include <math.h>
11 : #include "nsCycleCollectionParticipant.h"
12 : #include "xpt_struct.h"
13 : #include "nsReadableUtils.h"
14 : #include "nsMemory.h"
15 : #include "nsString.h"
16 : #include "nsCRTGlue.h"
17 : #include "mozilla/IntegerPrintfMacros.h"
18 : #include "mozilla/Printf.h"
19 :
20 : /***************************************************************************/
21 : // Helpers for static convert functions...
22 :
23 : static nsresult
24 0 : String2Double(const char* aString, double* aResult)
25 : {
26 : char* next;
27 0 : double value = PR_strtod(aString, &next);
28 0 : if (next == aString) {
29 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
30 : }
31 0 : *aResult = value;
32 0 : return NS_OK;
33 : }
34 :
35 : static nsresult
36 0 : AString2Double(const nsAString& aString, double* aResult)
37 : {
38 0 : char* pChars = ToNewCString(aString);
39 0 : if (!pChars) {
40 0 : return NS_ERROR_OUT_OF_MEMORY;
41 : }
42 0 : nsresult rv = String2Double(pChars, aResult);
43 0 : free(pChars);
44 0 : return rv;
45 : }
46 :
47 : static nsresult
48 0 : AUTF8String2Double(const nsAUTF8String& aString, double* aResult)
49 : {
50 0 : return String2Double(PromiseFlatUTF8String(aString).get(), aResult);
51 : }
52 :
53 : static nsresult
54 0 : ACString2Double(const nsACString& aString, double* aResult)
55 : {
56 0 : return String2Double(PromiseFlatCString(aString).get(), aResult);
57 : }
58 :
59 : // Fills aOutData with double, uint32_t, or int32_t.
60 : // Returns NS_OK, an error code, or a non-NS_OK success code
61 : nsresult
62 11 : nsDiscriminatedUnion::ToManageableNumber(nsDiscriminatedUnion* aOutData) const
63 : {
64 : nsresult rv;
65 :
66 11 : switch (mType) {
67 : // This group results in a int32_t...
68 :
69 : #define CASE__NUMBER_INT32(type_, member_) \
70 : case nsIDataType::type_ : \
71 : aOutData->u.mInt32Value = u.member_ ; \
72 : aOutData->mType = nsIDataType::VTYPE_INT32; \
73 : return NS_OK;
74 :
75 0 : CASE__NUMBER_INT32(VTYPE_INT8, mInt8Value)
76 0 : CASE__NUMBER_INT32(VTYPE_INT16, mInt16Value)
77 9 : CASE__NUMBER_INT32(VTYPE_INT32, mInt32Value)
78 0 : CASE__NUMBER_INT32(VTYPE_UINT8, mUint8Value)
79 0 : CASE__NUMBER_INT32(VTYPE_UINT16, mUint16Value)
80 0 : CASE__NUMBER_INT32(VTYPE_BOOL, mBoolValue)
81 0 : CASE__NUMBER_INT32(VTYPE_CHAR, mCharValue)
82 0 : CASE__NUMBER_INT32(VTYPE_WCHAR, mWCharValue)
83 :
84 : #undef CASE__NUMBER_INT32
85 :
86 : // This group results in a uint32_t...
87 :
88 : case nsIDataType::VTYPE_UINT32:
89 0 : aOutData->u.mInt32Value = u.mUint32Value;
90 0 : aOutData->mType = nsIDataType::VTYPE_INT32;
91 0 : return NS_OK;
92 :
93 : // This group results in a double...
94 :
95 : case nsIDataType::VTYPE_INT64:
96 : case nsIDataType::VTYPE_UINT64:
97 : // XXX Need boundary checking here.
98 : // We may need to return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA
99 2 : aOutData->u.mDoubleValue = double(u.mInt64Value);
100 2 : aOutData->mType = nsIDataType::VTYPE_DOUBLE;
101 2 : return NS_OK;
102 : case nsIDataType::VTYPE_FLOAT:
103 0 : aOutData->u.mDoubleValue = u.mFloatValue;
104 0 : aOutData->mType = nsIDataType::VTYPE_DOUBLE;
105 0 : return NS_OK;
106 : case nsIDataType::VTYPE_DOUBLE:
107 0 : aOutData->u.mDoubleValue = u.mDoubleValue;
108 0 : aOutData->mType = nsIDataType::VTYPE_DOUBLE;
109 0 : return NS_OK;
110 : case nsIDataType::VTYPE_CHAR_STR:
111 : case nsIDataType::VTYPE_STRING_SIZE_IS:
112 0 : rv = String2Double(u.str.mStringValue, &aOutData->u.mDoubleValue);
113 0 : if (NS_FAILED(rv)) {
114 0 : return rv;
115 : }
116 0 : aOutData->mType = nsIDataType::VTYPE_DOUBLE;
117 0 : return NS_OK;
118 : case nsIDataType::VTYPE_DOMSTRING:
119 : case nsIDataType::VTYPE_ASTRING:
120 0 : rv = AString2Double(*u.mAStringValue, &aOutData->u.mDoubleValue);
121 0 : if (NS_FAILED(rv)) {
122 0 : return rv;
123 : }
124 0 : aOutData->mType = nsIDataType::VTYPE_DOUBLE;
125 0 : return NS_OK;
126 : case nsIDataType::VTYPE_UTF8STRING:
127 0 : rv = AUTF8String2Double(*u.mUTF8StringValue,
128 0 : &aOutData->u.mDoubleValue);
129 0 : if (NS_FAILED(rv)) {
130 0 : return rv;
131 : }
132 0 : aOutData->mType = nsIDataType::VTYPE_DOUBLE;
133 0 : return NS_OK;
134 : case nsIDataType::VTYPE_CSTRING:
135 0 : rv = ACString2Double(*u.mCStringValue,
136 0 : &aOutData->u.mDoubleValue);
137 0 : if (NS_FAILED(rv)) {
138 0 : return rv;
139 : }
140 0 : aOutData->mType = nsIDataType::VTYPE_DOUBLE;
141 0 : return NS_OK;
142 : case nsIDataType::VTYPE_WCHAR_STR:
143 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
144 0 : rv = AString2Double(nsDependentString(u.wstr.mWStringValue),
145 0 : &aOutData->u.mDoubleValue);
146 0 : if (NS_FAILED(rv)) {
147 0 : return rv;
148 : }
149 0 : aOutData->mType = nsIDataType::VTYPE_DOUBLE;
150 0 : return NS_OK;
151 :
152 : // This group fails...
153 :
154 : case nsIDataType::VTYPE_VOID:
155 : case nsIDataType::VTYPE_ID:
156 : case nsIDataType::VTYPE_INTERFACE:
157 : case nsIDataType::VTYPE_INTERFACE_IS:
158 : case nsIDataType::VTYPE_ARRAY:
159 : case nsIDataType::VTYPE_EMPTY_ARRAY:
160 : case nsIDataType::VTYPE_EMPTY:
161 : default:
162 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
163 : }
164 : }
165 :
166 : /***************************************************************************/
167 : // Array helpers...
168 :
169 : void
170 0 : nsDiscriminatedUnion::FreeArray()
171 : {
172 0 : NS_ASSERTION(mType == nsIDataType::VTYPE_ARRAY, "bad FreeArray call");
173 0 : NS_ASSERTION(u.array.mArrayValue, "bad array");
174 0 : NS_ASSERTION(u.array.mArrayCount, "bad array count");
175 :
176 : #define CASE__FREE_ARRAY_PTR(type_, ctype_) \
177 : case nsIDataType::type_ : \
178 : { \
179 : ctype_** p = (ctype_**) u.array.mArrayValue; \
180 : for (uint32_t i = u.array.mArrayCount; i > 0; p++, i--) \
181 : if (*p) \
182 : free((char*)*p); \
183 : break; \
184 : }
185 :
186 : #define CASE__FREE_ARRAY_IFACE(type_, ctype_) \
187 : case nsIDataType::type_ : \
188 : { \
189 : ctype_** p = (ctype_**) u.array.mArrayValue; \
190 : for (uint32_t i = u.array.mArrayCount; i > 0; p++, i--) \
191 : if (*p) \
192 : (*p)->Release(); \
193 : break; \
194 : }
195 :
196 0 : switch (u.array.mArrayType) {
197 : case nsIDataType::VTYPE_INT8:
198 : case nsIDataType::VTYPE_INT16:
199 : case nsIDataType::VTYPE_INT32:
200 : case nsIDataType::VTYPE_INT64:
201 : case nsIDataType::VTYPE_UINT8:
202 : case nsIDataType::VTYPE_UINT16:
203 : case nsIDataType::VTYPE_UINT32:
204 : case nsIDataType::VTYPE_UINT64:
205 : case nsIDataType::VTYPE_FLOAT:
206 : case nsIDataType::VTYPE_DOUBLE:
207 : case nsIDataType::VTYPE_BOOL:
208 : case nsIDataType::VTYPE_CHAR:
209 : case nsIDataType::VTYPE_WCHAR:
210 0 : break;
211 :
212 : // XXX We ASSUME that "array of nsID" means "array of pointers to nsID".
213 0 : CASE__FREE_ARRAY_PTR(VTYPE_ID, nsID)
214 0 : CASE__FREE_ARRAY_PTR(VTYPE_CHAR_STR, char)
215 0 : CASE__FREE_ARRAY_PTR(VTYPE_WCHAR_STR, char16_t)
216 0 : CASE__FREE_ARRAY_IFACE(VTYPE_INTERFACE, nsISupports)
217 0 : CASE__FREE_ARRAY_IFACE(VTYPE_INTERFACE_IS, nsISupports)
218 :
219 : // The rest are illegal.
220 : case nsIDataType::VTYPE_VOID:
221 : case nsIDataType::VTYPE_ASTRING:
222 : case nsIDataType::VTYPE_DOMSTRING:
223 : case nsIDataType::VTYPE_UTF8STRING:
224 : case nsIDataType::VTYPE_CSTRING:
225 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
226 : case nsIDataType::VTYPE_STRING_SIZE_IS:
227 : case nsIDataType::VTYPE_ARRAY:
228 : case nsIDataType::VTYPE_EMPTY_ARRAY:
229 : case nsIDataType::VTYPE_EMPTY:
230 : default:
231 0 : NS_ERROR("bad type in array!");
232 0 : break;
233 : }
234 :
235 : // Free the array memory.
236 0 : free((char*)u.array.mArrayValue);
237 :
238 : #undef CASE__FREE_ARRAY_PTR
239 : #undef CASE__FREE_ARRAY_IFACE
240 0 : }
241 :
242 : static nsresult
243 0 : CloneArray(uint16_t aInType, const nsIID* aInIID,
244 : uint32_t aInCount, void* aInValue,
245 : uint16_t* aOutType, nsIID* aOutIID,
246 : uint32_t* aOutCount, void** aOutValue)
247 : {
248 0 : NS_ASSERTION(aInCount, "bad param");
249 0 : NS_ASSERTION(aInValue, "bad param");
250 0 : NS_ASSERTION(aOutType, "bad param");
251 0 : NS_ASSERTION(aOutCount, "bad param");
252 0 : NS_ASSERTION(aOutValue, "bad param");
253 :
254 0 : uint32_t allocatedValueCount = 0;
255 0 : nsresult rv = NS_OK;
256 : uint32_t i;
257 :
258 : // First we figure out the size of the elements for the new u.array.
259 :
260 : size_t elementSize;
261 : size_t allocSize;
262 :
263 0 : switch (aInType) {
264 : case nsIDataType::VTYPE_INT8:
265 0 : elementSize = sizeof(int8_t);
266 0 : break;
267 : case nsIDataType::VTYPE_INT16:
268 0 : elementSize = sizeof(int16_t);
269 0 : break;
270 : case nsIDataType::VTYPE_INT32:
271 0 : elementSize = sizeof(int32_t);
272 0 : break;
273 : case nsIDataType::VTYPE_INT64:
274 0 : elementSize = sizeof(int64_t);
275 0 : break;
276 : case nsIDataType::VTYPE_UINT8:
277 0 : elementSize = sizeof(uint8_t);
278 0 : break;
279 : case nsIDataType::VTYPE_UINT16:
280 0 : elementSize = sizeof(uint16_t);
281 0 : break;
282 : case nsIDataType::VTYPE_UINT32:
283 0 : elementSize = sizeof(uint32_t);
284 0 : break;
285 : case nsIDataType::VTYPE_UINT64:
286 0 : elementSize = sizeof(uint64_t);
287 0 : break;
288 : case nsIDataType::VTYPE_FLOAT:
289 0 : elementSize = sizeof(float);
290 0 : break;
291 : case nsIDataType::VTYPE_DOUBLE:
292 0 : elementSize = sizeof(double);
293 0 : break;
294 : case nsIDataType::VTYPE_BOOL:
295 0 : elementSize = sizeof(bool);
296 0 : break;
297 : case nsIDataType::VTYPE_CHAR:
298 0 : elementSize = sizeof(char);
299 0 : break;
300 : case nsIDataType::VTYPE_WCHAR:
301 0 : elementSize = sizeof(char16_t);
302 0 : break;
303 :
304 : // XXX We ASSUME that "array of nsID" means "array of pointers to nsID".
305 : case nsIDataType::VTYPE_ID:
306 : case nsIDataType::VTYPE_CHAR_STR:
307 : case nsIDataType::VTYPE_WCHAR_STR:
308 : case nsIDataType::VTYPE_INTERFACE:
309 : case nsIDataType::VTYPE_INTERFACE_IS:
310 0 : elementSize = sizeof(void*);
311 0 : break;
312 :
313 : // The rest are illegal.
314 : case nsIDataType::VTYPE_ASTRING:
315 : case nsIDataType::VTYPE_DOMSTRING:
316 : case nsIDataType::VTYPE_UTF8STRING:
317 : case nsIDataType::VTYPE_CSTRING:
318 : case nsIDataType::VTYPE_STRING_SIZE_IS:
319 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
320 : case nsIDataType::VTYPE_VOID:
321 : case nsIDataType::VTYPE_ARRAY:
322 : case nsIDataType::VTYPE_EMPTY_ARRAY:
323 : case nsIDataType::VTYPE_EMPTY:
324 : default:
325 0 : NS_ERROR("bad type in array!");
326 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
327 : }
328 :
329 :
330 : // Alloc the u.array.
331 :
332 0 : allocSize = aInCount * elementSize;
333 0 : *aOutValue = moz_xmalloc(allocSize);
334 0 : if (!*aOutValue) {
335 0 : return NS_ERROR_OUT_OF_MEMORY;
336 : }
337 :
338 : // Clone the elements.
339 :
340 0 : switch (aInType) {
341 : case nsIDataType::VTYPE_INT8:
342 : case nsIDataType::VTYPE_INT16:
343 : case nsIDataType::VTYPE_INT32:
344 : case nsIDataType::VTYPE_INT64:
345 : case nsIDataType::VTYPE_UINT8:
346 : case nsIDataType::VTYPE_UINT16:
347 : case nsIDataType::VTYPE_UINT32:
348 : case nsIDataType::VTYPE_UINT64:
349 : case nsIDataType::VTYPE_FLOAT:
350 : case nsIDataType::VTYPE_DOUBLE:
351 : case nsIDataType::VTYPE_BOOL:
352 : case nsIDataType::VTYPE_CHAR:
353 : case nsIDataType::VTYPE_WCHAR:
354 0 : memcpy(*aOutValue, aInValue, allocSize);
355 0 : break;
356 :
357 : case nsIDataType::VTYPE_INTERFACE_IS:
358 0 : if (aOutIID) {
359 0 : *aOutIID = *aInIID;
360 : }
361 : MOZ_FALLTHROUGH;
362 :
363 : case nsIDataType::VTYPE_INTERFACE: {
364 0 : memcpy(*aOutValue, aInValue, allocSize);
365 :
366 0 : nsISupports** p = (nsISupports**)*aOutValue;
367 0 : for (i = aInCount; i > 0; ++p, --i)
368 0 : if (*p) {
369 0 : (*p)->AddRef();
370 : }
371 0 : break;
372 : }
373 :
374 : // XXX We ASSUME that "array of nsID" means "array of pointers to nsID".
375 : case nsIDataType::VTYPE_ID: {
376 0 : nsID** inp = (nsID**)aInValue;
377 0 : nsID** outp = (nsID**)*aOutValue;
378 0 : for (i = aInCount; i > 0; --i) {
379 0 : nsID* idp = *(inp++);
380 0 : if (idp) {
381 0 : if (!(*(outp++) = (nsID*)nsMemory::Clone((char*)idp, sizeof(nsID)))) {
382 0 : goto bad;
383 : }
384 : } else {
385 0 : *(outp++) = nullptr;
386 : }
387 0 : allocatedValueCount++;
388 : }
389 0 : break;
390 : }
391 :
392 : case nsIDataType::VTYPE_CHAR_STR: {
393 0 : char** inp = (char**)aInValue;
394 0 : char** outp = (char**)*aOutValue;
395 0 : for (i = aInCount; i > 0; i--) {
396 0 : char* str = *(inp++);
397 0 : if (str) {
398 0 : if (!(*(outp++) = (char*)nsMemory::Clone(
399 0 : str, (strlen(str) + 1) * sizeof(char)))) {
400 0 : goto bad;
401 : }
402 : } else {
403 0 : *(outp++) = nullptr;
404 : }
405 0 : allocatedValueCount++;
406 : }
407 0 : break;
408 : }
409 :
410 : case nsIDataType::VTYPE_WCHAR_STR: {
411 0 : char16_t** inp = (char16_t**)aInValue;
412 0 : char16_t** outp = (char16_t**)*aOutValue;
413 0 : for (i = aInCount; i > 0; i--) {
414 0 : char16_t* str = *(inp++);
415 0 : if (str) {
416 0 : if (!(*(outp++) = (char16_t*)nsMemory::Clone(
417 0 : str, (NS_strlen(str) + 1) * sizeof(char16_t)))) {
418 0 : goto bad;
419 : }
420 : } else {
421 0 : *(outp++) = nullptr;
422 : }
423 0 : allocatedValueCount++;
424 : }
425 0 : break;
426 : }
427 :
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:
439 : default:
440 0 : NS_ERROR("bad type in array!");
441 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
442 : }
443 :
444 0 : *aOutType = aInType;
445 0 : *aOutCount = aInCount;
446 0 : return NS_OK;
447 :
448 : bad:
449 0 : if (*aOutValue) {
450 0 : char** p = (char**)*aOutValue;
451 0 : for (i = allocatedValueCount; i > 0; ++p, --i)
452 0 : if (*p) {
453 0 : free(*p);
454 : }
455 0 : free((char*)*aOutValue);
456 0 : *aOutValue = nullptr;
457 : }
458 0 : return rv;
459 : }
460 :
461 : /***************************************************************************/
462 :
463 : #define TRIVIAL_DATA_CONVERTER(type_, member_, retval_) \
464 : if (mType == nsIDataType::type_) { \
465 : *retval_ = u.member_; \
466 : return NS_OK; \
467 : }
468 :
469 : #define NUMERIC_CONVERSION_METHOD_BEGIN(type_, Ctype_, name_) \
470 : nsresult \
471 : nsDiscriminatedUnion::ConvertTo##name_ (Ctype_* aResult) const \
472 : { \
473 : TRIVIAL_DATA_CONVERTER(type_, m##name_##Value, aResult) \
474 : nsDiscriminatedUnion tempData; \
475 : nsresult rv = ToManageableNumber(&tempData); \
476 : /* */ \
477 : /* NOTE: rv may indicate a success code that we want to preserve */ \
478 : /* For the final return. So all the return cases below should return */ \
479 : /* this rv when indicating success. */ \
480 : /* */ \
481 : if (NS_FAILED(rv)) \
482 : return rv; \
483 : switch(tempData.mType) \
484 : {
485 :
486 : #define CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(Ctype_) \
487 : case nsIDataType::VTYPE_INT32: \
488 : *aResult = ( Ctype_ ) tempData.u.mInt32Value; \
489 : return rv;
490 :
491 : #define CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(Ctype_, min_, max_) \
492 : case nsIDataType::VTYPE_INT32: \
493 : { \
494 : int32_t value = tempData.u.mInt32Value; \
495 : if (value < min_ || value > max_) \
496 : return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \
497 : *aResult = ( Ctype_ ) value; \
498 : return rv; \
499 : }
500 :
501 : #define CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(Ctype_) \
502 : case nsIDataType::VTYPE_UINT32: \
503 : *aResult = ( Ctype_ ) tempData.u.mUint32Value; \
504 : return rv;
505 :
506 : #define CASE__NUMERIC_CONVERSION_UINT32_MAX(Ctype_, max_) \
507 : case nsIDataType::VTYPE_UINT32: \
508 : { \
509 : uint32_t value = tempData.u.mUint32Value; \
510 : if (value > max_) \
511 : return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \
512 : *aResult = ( Ctype_ ) value; \
513 : return rv; \
514 : }
515 :
516 : #define CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(Ctype_) \
517 : case nsIDataType::VTYPE_DOUBLE: \
518 : *aResult = ( Ctype_ ) tempData.u.mDoubleValue; \
519 : return rv;
520 :
521 : #define CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX(Ctype_, min_, max_) \
522 : case nsIDataType::VTYPE_DOUBLE: \
523 : { \
524 : double value = tempData.u.mDoubleValue; \
525 : if (value < min_ || value > max_) \
526 : return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \
527 : *aResult = ( Ctype_ ) value; \
528 : return rv; \
529 : }
530 :
531 : #define CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(Ctype_, min_, max_) \
532 : case nsIDataType::VTYPE_DOUBLE: \
533 : { \
534 : double value = tempData.u.mDoubleValue; \
535 : if (value < min_ || value > max_) \
536 : return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \
537 : *aResult = ( Ctype_ ) value; \
538 : return (0.0 == fmod(value,1.0)) ? \
539 : rv : NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA; \
540 : }
541 :
542 : #define CASES__NUMERIC_CONVERSION_NORMAL(Ctype_, min_, max_) \
543 : CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(Ctype_, min_, max_) \
544 : CASE__NUMERIC_CONVERSION_UINT32_MAX(Ctype_, max_) \
545 : CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(Ctype_, min_, max_)
546 :
547 : #define NUMERIC_CONVERSION_METHOD_END \
548 : default: \
549 : NS_ERROR("bad type returned from ToManageableNumber"); \
550 : return NS_ERROR_CANNOT_CONVERT_DATA; \
551 : } \
552 : }
553 :
554 : #define NUMERIC_CONVERSION_METHOD_NORMAL(type_, Ctype_, name_, min_, max_) \
555 : NUMERIC_CONVERSION_METHOD_BEGIN(type_, Ctype_, name_) \
556 : CASES__NUMERIC_CONVERSION_NORMAL(Ctype_, min_, max_) \
557 : NUMERIC_CONVERSION_METHOD_END
558 :
559 : /***************************************************************************/
560 : // These expand into full public methods...
561 :
562 0 : NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_INT8, uint8_t, Int8, (-127 - 1), 127)
563 0 : NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_INT16, int16_t, Int16, (-32767 - 1), 32767)
564 :
565 1 : NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_INT32, int32_t, Int32)
566 0 : CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(int32_t)
567 0 : CASE__NUMERIC_CONVERSION_UINT32_MAX(int32_t, 2147483647)
568 0 : CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(int32_t, (-2147483647 - 1), 2147483647)
569 0 : NUMERIC_CONVERSION_METHOD_END
570 :
571 0 : NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_UINT8, uint8_t, Uint8, 0, 255)
572 0 : NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_UINT16, uint16_t, Uint16, 0, 65535)
573 :
574 0 : NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_UINT32, uint32_t, Uint32)
575 0 : CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(uint32_t, 0, 2147483647)
576 0 : CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(uint32_t)
577 0 : CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(uint32_t, 0, 4294967295U)
578 0 : NUMERIC_CONVERSION_METHOD_END
579 :
580 : // XXX toFloat convertions need to be fixed!
581 0 : NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_FLOAT, float, Float)
582 0 : CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(float)
583 0 : CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(float)
584 0 : CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(float)
585 0 : NUMERIC_CONVERSION_METHOD_END
586 :
587 20 : NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_DOUBLE, double, Double)
588 8 : CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(double)
589 0 : CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(double)
590 2 : CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(double)
591 0 : NUMERIC_CONVERSION_METHOD_END
592 :
593 : // XXX toChar convertions need to be fixed!
594 0 : NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_CHAR, char, Char)
595 0 : CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(char)
596 0 : CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(char)
597 0 : CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(char)
598 0 : NUMERIC_CONVERSION_METHOD_END
599 :
600 : // XXX toWChar convertions need to be fixed!
601 0 : NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_WCHAR, char16_t, WChar)
602 0 : CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(char16_t)
603 0 : CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(char16_t)
604 0 : CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(char16_t)
605 0 : NUMERIC_CONVERSION_METHOD_END
606 :
607 : #undef NUMERIC_CONVERSION_METHOD_BEGIN
608 : #undef CASE__NUMERIC_CONVERSION_INT32_JUST_CAST
609 : #undef CASE__NUMERIC_CONVERSION_INT32_MIN_MAX
610 : #undef CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST
611 : #undef CASE__NUMERIC_CONVERSION_UINT32_MIN_MAX
612 : #undef CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST
613 : #undef CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX
614 : #undef CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT
615 : #undef CASES__NUMERIC_CONVERSION_NORMAL
616 : #undef NUMERIC_CONVERSION_METHOD_END
617 : #undef NUMERIC_CONVERSION_METHOD_NORMAL
618 :
619 : /***************************************************************************/
620 :
621 : // Just leverage a numeric converter for bool (but restrict the values).
622 : // XXX Is this really what we want to do?
623 :
624 : nsresult
625 15 : nsDiscriminatedUnion::ConvertToBool(bool* aResult) const
626 : {
627 15 : TRIVIAL_DATA_CONVERTER(VTYPE_BOOL, mBoolValue, aResult)
628 :
629 : double val;
630 0 : nsresult rv = ConvertToDouble(&val);
631 0 : if (NS_FAILED(rv)) {
632 0 : return rv;
633 : }
634 0 : *aResult = 0.0 != val;
635 0 : return rv;
636 : }
637 :
638 : /***************************************************************************/
639 :
640 : nsresult
641 18 : nsDiscriminatedUnion::ConvertToInt64(int64_t* aResult) const
642 : {
643 18 : TRIVIAL_DATA_CONVERTER(VTYPE_INT64, mInt64Value, aResult)
644 1 : TRIVIAL_DATA_CONVERTER(VTYPE_UINT64, mUint64Value, aResult)
645 :
646 2 : nsDiscriminatedUnion tempData;
647 1 : nsresult rv = ToManageableNumber(&tempData);
648 1 : if (NS_FAILED(rv)) {
649 0 : return rv;
650 : }
651 1 : switch (tempData.mType) {
652 : case nsIDataType::VTYPE_INT32:
653 1 : *aResult = tempData.u.mInt32Value;
654 1 : return rv;
655 : case nsIDataType::VTYPE_UINT32:
656 0 : *aResult = tempData.u.mUint32Value;
657 0 : return rv;
658 : case nsIDataType::VTYPE_DOUBLE:
659 : // XXX should check for data loss here!
660 0 : *aResult = tempData.u.mDoubleValue;
661 0 : return rv;
662 : default:
663 0 : NS_ERROR("bad type returned from ToManageableNumber");
664 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
665 : }
666 : }
667 :
668 : nsresult
669 0 : nsDiscriminatedUnion::ConvertToUint64(uint64_t* aResult) const
670 : {
671 0 : return ConvertToInt64((int64_t*)aResult);
672 : }
673 :
674 : /***************************************************************************/
675 :
676 : bool
677 0 : nsDiscriminatedUnion::String2ID(nsID* aPid) const
678 : {
679 0 : nsAutoString tempString;
680 : nsAString* pString;
681 :
682 0 : switch (mType) {
683 : case nsIDataType::VTYPE_CHAR_STR:
684 : case nsIDataType::VTYPE_STRING_SIZE_IS:
685 0 : return aPid->Parse(u.str.mStringValue);
686 : case nsIDataType::VTYPE_CSTRING:
687 0 : return aPid->Parse(PromiseFlatCString(*u.mCStringValue).get());
688 : case nsIDataType::VTYPE_UTF8STRING:
689 0 : return aPid->Parse(PromiseFlatUTF8String(*u.mUTF8StringValue).get());
690 : case nsIDataType::VTYPE_ASTRING:
691 : case nsIDataType::VTYPE_DOMSTRING:
692 0 : pString = u.mAStringValue;
693 0 : break;
694 : case nsIDataType::VTYPE_WCHAR_STR:
695 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
696 0 : tempString.Assign(u.wstr.mWStringValue);
697 0 : pString = &tempString;
698 0 : break;
699 : default:
700 0 : NS_ERROR("bad type in call to String2ID");
701 0 : return false;
702 : }
703 :
704 0 : char* pChars = ToNewCString(*pString);
705 0 : if (!pChars) {
706 0 : return false;
707 : }
708 0 : bool result = aPid->Parse(pChars);
709 0 : free(pChars);
710 0 : return result;
711 : }
712 :
713 : nsresult
714 0 : nsDiscriminatedUnion::ConvertToID(nsID* aResult) const
715 : {
716 : nsID id;
717 :
718 0 : switch (mType) {
719 : case nsIDataType::VTYPE_ID:
720 0 : *aResult = u.mIDValue;
721 0 : return NS_OK;
722 : case nsIDataType::VTYPE_INTERFACE:
723 0 : *aResult = NS_GET_IID(nsISupports);
724 0 : return NS_OK;
725 : case nsIDataType::VTYPE_INTERFACE_IS:
726 0 : *aResult = u.iface.mInterfaceID;
727 0 : return NS_OK;
728 : case nsIDataType::VTYPE_ASTRING:
729 : case nsIDataType::VTYPE_DOMSTRING:
730 : case nsIDataType::VTYPE_UTF8STRING:
731 : case nsIDataType::VTYPE_CSTRING:
732 : case nsIDataType::VTYPE_CHAR_STR:
733 : case nsIDataType::VTYPE_WCHAR_STR:
734 : case nsIDataType::VTYPE_STRING_SIZE_IS:
735 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
736 0 : if (!String2ID(&id)) {
737 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
738 : }
739 0 : *aResult = id;
740 0 : return NS_OK;
741 : default:
742 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
743 : }
744 : }
745 :
746 : /***************************************************************************/
747 :
748 : nsresult
749 0 : nsDiscriminatedUnion::ToString(nsACString& aOutString) const
750 : {
751 0 : mozilla::SmprintfPointer pptr;
752 :
753 0 : switch (mType) {
754 : // all the stuff we don't handle...
755 : case nsIDataType::VTYPE_ASTRING:
756 : case nsIDataType::VTYPE_DOMSTRING:
757 : case nsIDataType::VTYPE_UTF8STRING:
758 : case nsIDataType::VTYPE_CSTRING:
759 : case nsIDataType::VTYPE_CHAR_STR:
760 : case nsIDataType::VTYPE_WCHAR_STR:
761 : case nsIDataType::VTYPE_STRING_SIZE_IS:
762 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
763 : case nsIDataType::VTYPE_WCHAR:
764 0 : NS_ERROR("ToString being called for a string type - screwy logic!");
765 : MOZ_FALLTHROUGH;
766 :
767 : // XXX We might want stringified versions of these... ???
768 :
769 : case nsIDataType::VTYPE_VOID:
770 : case nsIDataType::VTYPE_EMPTY:
771 0 : aOutString.SetIsVoid(true);
772 0 : return NS_OK;
773 :
774 : case nsIDataType::VTYPE_EMPTY_ARRAY:
775 : case nsIDataType::VTYPE_ARRAY:
776 : case nsIDataType::VTYPE_INTERFACE:
777 : case nsIDataType::VTYPE_INTERFACE_IS:
778 : default:
779 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
780 :
781 : // nsID has its own text formatter.
782 :
783 : case nsIDataType::VTYPE_ID: {
784 0 : char* ptr = u.mIDValue.ToString();
785 0 : if (!ptr) {
786 0 : return NS_ERROR_OUT_OF_MEMORY;
787 : }
788 0 : aOutString.Assign(ptr);
789 0 : free(ptr);
790 0 : return NS_OK;
791 : }
792 :
793 : // Can't use Smprintf for floats, since it's locale-dependent
794 : #define CASE__APPENDFLOAT_NUMBER(type_, member_) \
795 : case nsIDataType::type_ : \
796 : { \
797 : nsAutoCString str; \
798 : str.AppendFloat(u.member_); \
799 : aOutString.Assign(str); \
800 : return NS_OK; \
801 : }
802 :
803 0 : CASE__APPENDFLOAT_NUMBER(VTYPE_FLOAT, mFloatValue)
804 0 : CASE__APPENDFLOAT_NUMBER(VTYPE_DOUBLE, mDoubleValue)
805 :
806 : #undef CASE__APPENDFLOAT_NUMBER
807 :
808 : // the rest can be Smprintf'd and use common code.
809 :
810 : #define CASE__SMPRINTF_NUMBER(type_, format_, cast_, member_) \
811 : case nsIDataType::type_: \
812 : static_assert(sizeof(cast_) >= sizeof(u.member_), \
813 : "size of type should be at least as big as member"); \
814 : pptr = mozilla::Smprintf( format_ , (cast_) u.member_); \
815 : break;
816 :
817 0 : CASE__SMPRINTF_NUMBER(VTYPE_INT8, "%d", int, mInt8Value)
818 0 : CASE__SMPRINTF_NUMBER(VTYPE_INT16, "%d", int, mInt16Value)
819 0 : CASE__SMPRINTF_NUMBER(VTYPE_INT32, "%d", int, mInt32Value)
820 0 : CASE__SMPRINTF_NUMBER(VTYPE_INT64, "%" PRId64, int64_t, mInt64Value)
821 :
822 0 : CASE__SMPRINTF_NUMBER(VTYPE_UINT8, "%u", unsigned, mUint8Value)
823 0 : CASE__SMPRINTF_NUMBER(VTYPE_UINT16, "%u", unsigned, mUint16Value)
824 0 : CASE__SMPRINTF_NUMBER(VTYPE_UINT32, "%u", unsigned, mUint32Value)
825 0 : CASE__SMPRINTF_NUMBER(VTYPE_UINT64, "%" PRIu64, int64_t, mUint64Value)
826 :
827 : // XXX Would we rather print "true" / "false" ?
828 0 : CASE__SMPRINTF_NUMBER(VTYPE_BOOL, "%d", int, mBoolValue)
829 :
830 0 : CASE__SMPRINTF_NUMBER(VTYPE_CHAR, "%c", char, mCharValue)
831 :
832 : #undef CASE__SMPRINTF_NUMBER
833 : }
834 :
835 0 : if (!pptr) {
836 0 : return NS_ERROR_OUT_OF_MEMORY;
837 : }
838 0 : aOutString.Assign(pptr.get());
839 0 : return NS_OK;
840 : }
841 :
842 : nsresult
843 25 : nsDiscriminatedUnion::ConvertToAString(nsAString& aResult) const
844 : {
845 25 : switch (mType) {
846 : case nsIDataType::VTYPE_ASTRING:
847 : case nsIDataType::VTYPE_DOMSTRING:
848 23 : aResult.Assign(*u.mAStringValue);
849 23 : return NS_OK;
850 : case nsIDataType::VTYPE_CSTRING:
851 0 : CopyASCIItoUTF16(*u.mCStringValue, aResult);
852 0 : return NS_OK;
853 : case nsIDataType::VTYPE_UTF8STRING:
854 0 : CopyUTF8toUTF16(*u.mUTF8StringValue, aResult);
855 0 : return NS_OK;
856 : case nsIDataType::VTYPE_CHAR_STR:
857 0 : CopyASCIItoUTF16(u.str.mStringValue, aResult);
858 0 : return NS_OK;
859 : case nsIDataType::VTYPE_WCHAR_STR:
860 0 : aResult.Assign(u.wstr.mWStringValue);
861 0 : return NS_OK;
862 : case nsIDataType::VTYPE_STRING_SIZE_IS:
863 0 : CopyASCIItoUTF16(nsDependentCString(u.str.mStringValue,
864 0 : u.str.mStringLength),
865 0 : aResult);
866 0 : return NS_OK;
867 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
868 2 : aResult.Assign(u.wstr.mWStringValue, u.wstr.mWStringLength);
869 2 : return NS_OK;
870 : case nsIDataType::VTYPE_WCHAR:
871 0 : aResult.Assign(u.mWCharValue);
872 0 : return NS_OK;
873 : default: {
874 0 : nsAutoCString tempCString;
875 0 : nsresult rv = ToString(tempCString);
876 0 : if (NS_FAILED(rv)) {
877 0 : return rv;
878 : }
879 0 : CopyASCIItoUTF16(tempCString, aResult);
880 0 : return NS_OK;
881 : }
882 : }
883 : }
884 :
885 : nsresult
886 9 : nsDiscriminatedUnion::ConvertToACString(nsACString& aResult) const
887 : {
888 9 : switch (mType) {
889 : case nsIDataType::VTYPE_ASTRING:
890 : case nsIDataType::VTYPE_DOMSTRING:
891 0 : LossyCopyUTF16toASCII(*u.mAStringValue, aResult);
892 0 : return NS_OK;
893 : case nsIDataType::VTYPE_CSTRING:
894 9 : aResult.Assign(*u.mCStringValue);
895 9 : return NS_OK;
896 : case nsIDataType::VTYPE_UTF8STRING:
897 : // XXX This is an extra copy that should be avoided
898 : // once Jag lands support for UTF8String and associated
899 : // conversion methods.
900 0 : LossyCopyUTF16toASCII(NS_ConvertUTF8toUTF16(*u.mUTF8StringValue),
901 0 : aResult);
902 0 : return NS_OK;
903 : case nsIDataType::VTYPE_CHAR_STR:
904 0 : aResult.Assign(*u.str.mStringValue);
905 0 : return NS_OK;
906 : case nsIDataType::VTYPE_WCHAR_STR:
907 0 : LossyCopyUTF16toASCII(nsDependentString(u.wstr.mWStringValue),
908 0 : aResult);
909 0 : return NS_OK;
910 : case nsIDataType::VTYPE_STRING_SIZE_IS:
911 0 : aResult.Assign(u.str.mStringValue, u.str.mStringLength);
912 0 : return NS_OK;
913 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
914 0 : LossyCopyUTF16toASCII(nsDependentString(u.wstr.mWStringValue,
915 0 : u.wstr.mWStringLength),
916 0 : aResult);
917 0 : return NS_OK;
918 : case nsIDataType::VTYPE_WCHAR: {
919 0 : const char16_t* str = &u.mWCharValue;
920 0 : LossyCopyUTF16toASCII(Substring(str, 1), aResult);
921 0 : return NS_OK;
922 : }
923 : default:
924 0 : return ToString(aResult);
925 : }
926 : }
927 :
928 : nsresult
929 0 : nsDiscriminatedUnion::ConvertToAUTF8String(nsAUTF8String& aResult) const
930 : {
931 0 : switch (mType) {
932 : case nsIDataType::VTYPE_ASTRING:
933 : case nsIDataType::VTYPE_DOMSTRING:
934 0 : CopyUTF16toUTF8(*u.mAStringValue, aResult);
935 0 : return NS_OK;
936 : case nsIDataType::VTYPE_CSTRING:
937 : // XXX Extra copy, can be removed if we're sure CSTRING can
938 : // only contain ASCII.
939 0 : CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(*u.mCStringValue),
940 0 : aResult);
941 0 : return NS_OK;
942 : case nsIDataType::VTYPE_UTF8STRING:
943 0 : aResult.Assign(*u.mUTF8StringValue);
944 0 : return NS_OK;
945 : case nsIDataType::VTYPE_CHAR_STR:
946 : // XXX Extra copy, can be removed if we're sure CHAR_STR can
947 : // only contain ASCII.
948 0 : CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(u.str.mStringValue),
949 0 : aResult);
950 0 : return NS_OK;
951 : case nsIDataType::VTYPE_WCHAR_STR:
952 0 : CopyUTF16toUTF8(u.wstr.mWStringValue, aResult);
953 0 : return NS_OK;
954 : case nsIDataType::VTYPE_STRING_SIZE_IS:
955 : // XXX Extra copy, can be removed if we're sure CHAR_STR can
956 : // only contain ASCII.
957 0 : CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(
958 0 : nsDependentCString(u.str.mStringValue,
959 0 : u.str.mStringLength)), aResult);
960 0 : return NS_OK;
961 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
962 0 : CopyUTF16toUTF8(nsDependentString(u.wstr.mWStringValue,
963 0 : u.wstr.mWStringLength),
964 0 : aResult);
965 0 : return NS_OK;
966 : case nsIDataType::VTYPE_WCHAR: {
967 0 : const char16_t* str = &u.mWCharValue;
968 0 : CopyUTF16toUTF8(Substring(str, 1), aResult);
969 0 : return NS_OK;
970 : }
971 : default: {
972 0 : nsAutoCString tempCString;
973 0 : nsresult rv = ToString(tempCString);
974 0 : if (NS_FAILED(rv)) {
975 0 : return rv;
976 : }
977 : // XXX Extra copy, can be removed if we're sure tempCString can
978 : // only contain ASCII.
979 0 : CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(tempCString), aResult);
980 0 : return NS_OK;
981 : }
982 : }
983 : }
984 :
985 : nsresult
986 0 : nsDiscriminatedUnion::ConvertToString(char** aResult) const
987 : {
988 : uint32_t ignored;
989 0 : return ConvertToStringWithSize(&ignored, aResult);
990 : }
991 :
992 : nsresult
993 0 : nsDiscriminatedUnion::ConvertToWString(char16_t** aResult) const
994 : {
995 : uint32_t ignored;
996 0 : return ConvertToWStringWithSize(&ignored, aResult);
997 : }
998 :
999 : nsresult
1000 0 : nsDiscriminatedUnion::ConvertToStringWithSize(uint32_t* aSize, char** aStr) const
1001 : {
1002 0 : nsAutoString tempString;
1003 0 : nsAutoCString tempCString;
1004 : nsresult rv;
1005 :
1006 0 : switch (mType) {
1007 : case nsIDataType::VTYPE_ASTRING:
1008 : case nsIDataType::VTYPE_DOMSTRING:
1009 0 : *aSize = u.mAStringValue->Length();
1010 0 : *aStr = ToNewCString(*u.mAStringValue);
1011 0 : break;
1012 : case nsIDataType::VTYPE_CSTRING:
1013 0 : *aSize = u.mCStringValue->Length();
1014 0 : *aStr = ToNewCString(*u.mCStringValue);
1015 0 : break;
1016 : case nsIDataType::VTYPE_UTF8STRING: {
1017 : // XXX This is doing 1 extra copy. Need to fix this
1018 : // when Jag lands UTF8String
1019 : // we want:
1020 : // *aSize = *mUTF8StringValue->Length();
1021 : // *aStr = ToNewCString(*mUTF8StringValue);
1022 : // But this will have to do for now.
1023 0 : const NS_ConvertUTF8toUTF16 tempString16(*u.mUTF8StringValue);
1024 0 : *aSize = tempString16.Length();
1025 0 : *aStr = ToNewCString(tempString16);
1026 0 : break;
1027 : }
1028 : case nsIDataType::VTYPE_CHAR_STR: {
1029 0 : nsDependentCString cString(u.str.mStringValue);
1030 0 : *aSize = cString.Length();
1031 0 : *aStr = ToNewCString(cString);
1032 0 : break;
1033 : }
1034 : case nsIDataType::VTYPE_WCHAR_STR: {
1035 0 : nsDependentString string(u.wstr.mWStringValue);
1036 0 : *aSize = string.Length();
1037 0 : *aStr = ToNewCString(string);
1038 0 : break;
1039 : }
1040 : case nsIDataType::VTYPE_STRING_SIZE_IS: {
1041 0 : nsDependentCString cString(u.str.mStringValue,
1042 0 : u.str.mStringLength);
1043 0 : *aSize = cString.Length();
1044 0 : *aStr = ToNewCString(cString);
1045 0 : break;
1046 : }
1047 : case nsIDataType::VTYPE_WSTRING_SIZE_IS: {
1048 0 : nsDependentString string(u.wstr.mWStringValue,
1049 0 : u.wstr.mWStringLength);
1050 0 : *aSize = string.Length();
1051 0 : *aStr = ToNewCString(string);
1052 0 : break;
1053 : }
1054 : case nsIDataType::VTYPE_WCHAR:
1055 0 : tempString.Assign(u.mWCharValue);
1056 0 : *aSize = tempString.Length();
1057 0 : *aStr = ToNewCString(tempString);
1058 0 : break;
1059 : default:
1060 0 : rv = ToString(tempCString);
1061 0 : if (NS_FAILED(rv)) {
1062 0 : return rv;
1063 : }
1064 0 : *aSize = tempCString.Length();
1065 0 : *aStr = ToNewCString(tempCString);
1066 0 : break;
1067 : }
1068 :
1069 0 : return *aStr ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1070 : }
1071 : nsresult
1072 2 : nsDiscriminatedUnion::ConvertToWStringWithSize(uint32_t* aSize, char16_t** aStr) const
1073 : {
1074 4 : nsAutoString tempString;
1075 4 : nsAutoCString tempCString;
1076 : nsresult rv;
1077 :
1078 2 : switch (mType) {
1079 : case nsIDataType::VTYPE_ASTRING:
1080 : case nsIDataType::VTYPE_DOMSTRING:
1081 2 : *aSize = u.mAStringValue->Length();
1082 2 : *aStr = ToNewUnicode(*u.mAStringValue);
1083 2 : break;
1084 : case nsIDataType::VTYPE_CSTRING:
1085 0 : *aSize = u.mCStringValue->Length();
1086 0 : *aStr = ToNewUnicode(*u.mCStringValue);
1087 0 : break;
1088 : case nsIDataType::VTYPE_UTF8STRING: {
1089 0 : *aStr = UTF8ToNewUnicode(*u.mUTF8StringValue, aSize);
1090 0 : break;
1091 : }
1092 : case nsIDataType::VTYPE_CHAR_STR: {
1093 0 : nsDependentCString cString(u.str.mStringValue);
1094 0 : *aSize = cString.Length();
1095 0 : *aStr = ToNewUnicode(cString);
1096 0 : break;
1097 : }
1098 : case nsIDataType::VTYPE_WCHAR_STR: {
1099 0 : nsDependentString string(u.wstr.mWStringValue);
1100 0 : *aSize = string.Length();
1101 0 : *aStr = ToNewUnicode(string);
1102 0 : break;
1103 : }
1104 : case nsIDataType::VTYPE_STRING_SIZE_IS: {
1105 0 : nsDependentCString cString(u.str.mStringValue,
1106 0 : u.str.mStringLength);
1107 0 : *aSize = cString.Length();
1108 0 : *aStr = ToNewUnicode(cString);
1109 0 : break;
1110 : }
1111 : case nsIDataType::VTYPE_WSTRING_SIZE_IS: {
1112 0 : nsDependentString string(u.wstr.mWStringValue,
1113 0 : u.wstr.mWStringLength);
1114 0 : *aSize = string.Length();
1115 0 : *aStr = ToNewUnicode(string);
1116 0 : break;
1117 : }
1118 : case nsIDataType::VTYPE_WCHAR:
1119 0 : tempString.Assign(u.mWCharValue);
1120 0 : *aSize = tempString.Length();
1121 0 : *aStr = ToNewUnicode(tempString);
1122 0 : break;
1123 : default:
1124 0 : rv = ToString(tempCString);
1125 0 : if (NS_FAILED(rv)) {
1126 0 : return rv;
1127 : }
1128 0 : *aSize = tempCString.Length();
1129 0 : *aStr = ToNewUnicode(tempCString);
1130 0 : break;
1131 : }
1132 :
1133 2 : return *aStr ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1134 : }
1135 :
1136 : nsresult
1137 3 : nsDiscriminatedUnion::ConvertToISupports(nsISupports** aResult) const
1138 : {
1139 3 : switch (mType) {
1140 : case nsIDataType::VTYPE_INTERFACE:
1141 : case nsIDataType::VTYPE_INTERFACE_IS:
1142 3 : if (u.iface.mInterfaceValue) {
1143 2 : return u.iface.mInterfaceValue->
1144 2 : QueryInterface(NS_GET_IID(nsISupports), (void**)aResult);
1145 : } else {
1146 2 : *aResult = nullptr;
1147 2 : return NS_OK;
1148 : }
1149 : default:
1150 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
1151 : }
1152 : }
1153 :
1154 : nsresult
1155 0 : nsDiscriminatedUnion::ConvertToInterface(nsIID** aIID,
1156 : void** aInterface) const
1157 : {
1158 : const nsIID* piid;
1159 :
1160 0 : switch (mType) {
1161 : case nsIDataType::VTYPE_INTERFACE:
1162 0 : piid = &NS_GET_IID(nsISupports);
1163 0 : break;
1164 : case nsIDataType::VTYPE_INTERFACE_IS:
1165 0 : piid = &u.iface.mInterfaceID;
1166 0 : break;
1167 : default:
1168 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
1169 : }
1170 :
1171 0 : *aIID = (nsIID*)nsMemory::Clone(piid, sizeof(nsIID));
1172 0 : if (!*aIID) {
1173 0 : return NS_ERROR_OUT_OF_MEMORY;
1174 : }
1175 :
1176 0 : if (u.iface.mInterfaceValue) {
1177 0 : return u.iface.mInterfaceValue->QueryInterface(*piid, aInterface);
1178 : }
1179 :
1180 0 : *aInterface = nullptr;
1181 0 : return NS_OK;
1182 : }
1183 :
1184 : nsresult
1185 0 : nsDiscriminatedUnion::ConvertToArray(uint16_t* aType, nsIID* aIID,
1186 : uint32_t* aCount, void** aPtr) const
1187 : {
1188 : // XXX perhaps we'd like to add support for converting each of the various
1189 : // types into an array containing one element of that type. We can leverage
1190 : // CloneArray to do this if we want to support this.
1191 :
1192 0 : if (mType == nsIDataType::VTYPE_ARRAY) {
1193 0 : return CloneArray(u.array.mArrayType, &u.array.mArrayInterfaceID,
1194 0 : u.array.mArrayCount, u.array.mArrayValue,
1195 0 : aType, aIID, aCount, aPtr);
1196 : }
1197 0 : return NS_ERROR_CANNOT_CONVERT_DATA;
1198 : }
1199 :
1200 : /***************************************************************************/
1201 : // static setter functions...
1202 :
1203 : #define DATA_SETTER_PROLOGUE \
1204 : Cleanup()
1205 :
1206 : #define DATA_SETTER_EPILOGUE(type_) \
1207 : mType = nsIDataType::type_;
1208 :
1209 : #define DATA_SETTER(type_, member_, value_) \
1210 : DATA_SETTER_PROLOGUE; \
1211 : u.member_ = value_; \
1212 : DATA_SETTER_EPILOGUE(type_)
1213 :
1214 : #define DATA_SETTER_WITH_CAST(type_, member_, cast_, value_) \
1215 : DATA_SETTER_PROLOGUE; \
1216 : u.member_ = cast_ value_; \
1217 : DATA_SETTER_EPILOGUE(type_)
1218 :
1219 :
1220 : /********************************************/
1221 :
1222 : #define CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \
1223 : { \
1224 :
1225 : #define CASE__SET_FROM_VARIANT_VTYPE__GETTER(member_, name_) \
1226 : rv = aValue->GetAs##name_ (&(u.member_ ));
1227 :
1228 : #define CASE__SET_FROM_VARIANT_VTYPE__GETTER_CAST(cast_, member_, name_) \
1229 : rv = aValue->GetAs##name_ ( cast_ &(u.member_ ));
1230 :
1231 : #define CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_) \
1232 : if (NS_SUCCEEDED(rv)) { \
1233 : mType = nsIDataType::type_ ; \
1234 : } \
1235 : break; \
1236 : }
1237 :
1238 : #define CASE__SET_FROM_VARIANT_TYPE(type_, member_, name_) \
1239 : case nsIDataType::type_: \
1240 : CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \
1241 : CASE__SET_FROM_VARIANT_VTYPE__GETTER(member_, name_) \
1242 : CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_)
1243 :
1244 : #define CASE__SET_FROM_VARIANT_VTYPE_CAST(type_, cast_, member_, name_) \
1245 : case nsIDataType::type_ : \
1246 : CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \
1247 : CASE__SET_FROM_VARIANT_VTYPE__GETTER_CAST(cast_, member_, name_) \
1248 : CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_)
1249 :
1250 :
1251 : nsresult
1252 0 : nsDiscriminatedUnion::SetFromVariant(nsIVariant* aValue)
1253 : {
1254 : uint16_t type;
1255 : nsresult rv;
1256 :
1257 0 : Cleanup();
1258 :
1259 0 : rv = aValue->GetDataType(&type);
1260 0 : if (NS_FAILED(rv)) {
1261 0 : return rv;
1262 : }
1263 :
1264 0 : switch (type) {
1265 0 : CASE__SET_FROM_VARIANT_VTYPE_CAST(VTYPE_INT8, (uint8_t*), mInt8Value,
1266 : Int8)
1267 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_INT16, mInt16Value, Int16)
1268 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_INT32, mInt32Value, Int32)
1269 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT8, mUint8Value, Uint8)
1270 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT16, mUint16Value, Uint16)
1271 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT32, mUint32Value, Uint32)
1272 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_FLOAT, mFloatValue, Float)
1273 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_DOUBLE, mDoubleValue, Double)
1274 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_BOOL , mBoolValue, Bool)
1275 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_CHAR, mCharValue, Char)
1276 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_WCHAR, mWCharValue, WChar)
1277 0 : CASE__SET_FROM_VARIANT_TYPE(VTYPE_ID, mIDValue, ID)
1278 :
1279 : case nsIDataType::VTYPE_ASTRING:
1280 : case nsIDataType::VTYPE_DOMSTRING:
1281 : case nsIDataType::VTYPE_WCHAR_STR:
1282 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
1283 : CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_ASTRING);
1284 0 : u.mAStringValue = new nsString();
1285 0 : if (!u.mAStringValue) {
1286 0 : return NS_ERROR_OUT_OF_MEMORY;
1287 : }
1288 0 : rv = aValue->GetAsAString(*u.mAStringValue);
1289 0 : if (NS_FAILED(rv)) {
1290 0 : delete u.mAStringValue;
1291 : }
1292 0 : CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_ASTRING)
1293 :
1294 : case nsIDataType::VTYPE_CSTRING:
1295 : CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_CSTRING);
1296 0 : u.mCStringValue = new nsCString();
1297 0 : if (!u.mCStringValue) {
1298 0 : return NS_ERROR_OUT_OF_MEMORY;
1299 : }
1300 0 : rv = aValue->GetAsACString(*u.mCStringValue);
1301 0 : if (NS_FAILED(rv)) {
1302 0 : delete u.mCStringValue;
1303 : }
1304 0 : CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_CSTRING)
1305 :
1306 : case nsIDataType::VTYPE_UTF8STRING:
1307 : CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_UTF8STRING);
1308 0 : u.mUTF8StringValue = new nsUTF8String();
1309 0 : if (!u.mUTF8StringValue) {
1310 0 : return NS_ERROR_OUT_OF_MEMORY;
1311 : }
1312 0 : rv = aValue->GetAsAUTF8String(*u.mUTF8StringValue);
1313 0 : if (NS_FAILED(rv)) {
1314 0 : delete u.mUTF8StringValue;
1315 : }
1316 0 : CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_UTF8STRING)
1317 :
1318 : case nsIDataType::VTYPE_CHAR_STR:
1319 : case nsIDataType::VTYPE_STRING_SIZE_IS:
1320 : CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_STRING_SIZE_IS);
1321 0 : rv = aValue->GetAsStringWithSize(&u.str.mStringLength,
1322 0 : &u.str.mStringValue);
1323 0 : CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_STRING_SIZE_IS)
1324 :
1325 : case nsIDataType::VTYPE_INTERFACE:
1326 : case nsIDataType::VTYPE_INTERFACE_IS:
1327 : CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_INTERFACE_IS);
1328 : // XXX This iid handling is ugly!
1329 : nsIID* iid;
1330 0 : rv = aValue->GetAsInterface(&iid, (void**)&u.iface.mInterfaceValue);
1331 0 : if (NS_SUCCEEDED(rv)) {
1332 0 : u.iface.mInterfaceID = *iid;
1333 0 : free((char*)iid);
1334 : }
1335 0 : CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_INTERFACE_IS)
1336 :
1337 : case nsIDataType::VTYPE_ARRAY:
1338 : CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_ARRAY);
1339 0 : rv = aValue->GetAsArray(&u.array.mArrayType,
1340 : &u.array.mArrayInterfaceID,
1341 : &u.array.mArrayCount,
1342 0 : &u.array.mArrayValue);
1343 0 : CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_ARRAY)
1344 :
1345 : case nsIDataType::VTYPE_VOID:
1346 0 : SetToVoid();
1347 0 : rv = NS_OK;
1348 0 : break;
1349 : case nsIDataType::VTYPE_EMPTY_ARRAY:
1350 0 : SetToEmptyArray();
1351 0 : rv = NS_OK;
1352 0 : break;
1353 : case nsIDataType::VTYPE_EMPTY:
1354 0 : SetToEmpty();
1355 0 : rv = NS_OK;
1356 0 : break;
1357 : default:
1358 0 : NS_ERROR("bad type in variant!");
1359 0 : rv = NS_ERROR_FAILURE;
1360 0 : break;
1361 : }
1362 0 : return rv;
1363 : }
1364 :
1365 : void
1366 0 : nsDiscriminatedUnion::SetFromInt8(uint8_t aValue)
1367 : {
1368 0 : DATA_SETTER_WITH_CAST(VTYPE_INT8, mInt8Value, (uint8_t), aValue);
1369 0 : }
1370 : void
1371 0 : nsDiscriminatedUnion::SetFromInt16(int16_t aValue)
1372 : {
1373 0 : DATA_SETTER(VTYPE_INT16, mInt16Value, aValue);
1374 0 : }
1375 : void
1376 13 : nsDiscriminatedUnion::SetFromInt32(int32_t aValue)
1377 : {
1378 13 : DATA_SETTER(VTYPE_INT32, mInt32Value, aValue);
1379 13 : }
1380 : void
1381 17 : nsDiscriminatedUnion::SetFromInt64(int64_t aValue)
1382 : {
1383 17 : DATA_SETTER(VTYPE_INT64, mInt64Value, aValue);
1384 17 : }
1385 : void
1386 0 : nsDiscriminatedUnion::SetFromUint8(uint8_t aValue)
1387 : {
1388 0 : DATA_SETTER(VTYPE_UINT8, mUint8Value, aValue);
1389 0 : }
1390 : void
1391 0 : nsDiscriminatedUnion::SetFromUint16(uint16_t aValue)
1392 : {
1393 0 : DATA_SETTER(VTYPE_UINT16, mUint16Value, aValue);
1394 0 : }
1395 : void
1396 1 : nsDiscriminatedUnion::SetFromUint32(uint32_t aValue)
1397 : {
1398 1 : DATA_SETTER(VTYPE_UINT32, mUint32Value, aValue);
1399 1 : }
1400 : void
1401 1 : nsDiscriminatedUnion::SetFromUint64(uint64_t aValue)
1402 : {
1403 1 : DATA_SETTER(VTYPE_UINT64, mUint64Value, aValue);
1404 1 : }
1405 : void
1406 0 : nsDiscriminatedUnion::SetFromFloat(float aValue)
1407 : {
1408 0 : DATA_SETTER(VTYPE_FLOAT, mFloatValue, aValue);
1409 0 : }
1410 : void
1411 0 : nsDiscriminatedUnion::SetFromDouble(double aValue)
1412 : {
1413 0 : DATA_SETTER(VTYPE_DOUBLE, mDoubleValue, aValue);
1414 0 : }
1415 : void
1416 17 : nsDiscriminatedUnion::SetFromBool(bool aValue)
1417 : {
1418 17 : DATA_SETTER(VTYPE_BOOL, mBoolValue, aValue);
1419 17 : }
1420 : void
1421 0 : nsDiscriminatedUnion::SetFromChar(char aValue)
1422 : {
1423 0 : DATA_SETTER(VTYPE_CHAR, mCharValue, aValue);
1424 0 : }
1425 : void
1426 0 : nsDiscriminatedUnion::SetFromWChar(char16_t aValue)
1427 : {
1428 0 : DATA_SETTER(VTYPE_WCHAR, mWCharValue, aValue);
1429 0 : }
1430 : void
1431 0 : nsDiscriminatedUnion::SetFromID(const nsID& aValue)
1432 : {
1433 0 : DATA_SETTER(VTYPE_ID, mIDValue, aValue);
1434 0 : }
1435 : void
1436 25 : nsDiscriminatedUnion::SetFromAString(const nsAString& aValue)
1437 : {
1438 25 : DATA_SETTER_PROLOGUE;
1439 25 : u.mAStringValue = new nsString(aValue);
1440 25 : DATA_SETTER_EPILOGUE(VTYPE_ASTRING);
1441 25 : }
1442 :
1443 : void
1444 0 : nsDiscriminatedUnion::SetFromDOMString(const nsAString& aValue)
1445 : {
1446 0 : DATA_SETTER_PROLOGUE;
1447 0 : u.mAStringValue = new nsString(aValue);
1448 0 : DATA_SETTER_EPILOGUE(VTYPE_DOMSTRING);
1449 0 : }
1450 :
1451 : void
1452 5 : nsDiscriminatedUnion::SetFromACString(const nsACString& aValue)
1453 : {
1454 5 : DATA_SETTER_PROLOGUE;
1455 5 : u.mCStringValue = new nsCString(aValue);
1456 5 : DATA_SETTER_EPILOGUE(VTYPE_CSTRING);
1457 5 : }
1458 :
1459 : void
1460 0 : nsDiscriminatedUnion::SetFromAUTF8String(const nsAUTF8String& aValue)
1461 : {
1462 0 : DATA_SETTER_PROLOGUE;
1463 0 : u.mUTF8StringValue = new nsUTF8String(aValue);
1464 0 : DATA_SETTER_EPILOGUE(VTYPE_UTF8STRING);
1465 0 : }
1466 :
1467 : nsresult
1468 0 : nsDiscriminatedUnion::SetFromString(const char* aValue)
1469 : {
1470 0 : DATA_SETTER_PROLOGUE;
1471 0 : if (!aValue) {
1472 0 : return NS_ERROR_NULL_POINTER;
1473 : }
1474 0 : return SetFromStringWithSize(strlen(aValue), aValue);
1475 : }
1476 : nsresult
1477 0 : nsDiscriminatedUnion::SetFromWString(const char16_t* aValue)
1478 : {
1479 0 : DATA_SETTER_PROLOGUE;
1480 0 : if (!aValue) {
1481 0 : return NS_ERROR_NULL_POINTER;
1482 : }
1483 0 : return SetFromWStringWithSize(NS_strlen(aValue), aValue);
1484 : }
1485 : void
1486 8 : nsDiscriminatedUnion::SetFromISupports(nsISupports* aValue)
1487 : {
1488 8 : return SetFromInterface(NS_GET_IID(nsISupports), aValue);
1489 : }
1490 : void
1491 8 : nsDiscriminatedUnion::SetFromInterface(const nsIID& aIID, nsISupports* aValue)
1492 : {
1493 8 : DATA_SETTER_PROLOGUE;
1494 8 : NS_IF_ADDREF(aValue);
1495 8 : u.iface.mInterfaceValue = aValue;
1496 8 : u.iface.mInterfaceID = aIID;
1497 8 : DATA_SETTER_EPILOGUE(VTYPE_INTERFACE_IS);
1498 8 : }
1499 : nsresult
1500 0 : nsDiscriminatedUnion::SetFromArray(uint16_t aType, const nsIID* aIID,
1501 : uint32_t aCount, void* aValue)
1502 : {
1503 0 : DATA_SETTER_PROLOGUE;
1504 0 : if (!aValue || !aCount) {
1505 0 : return NS_ERROR_NULL_POINTER;
1506 : }
1507 :
1508 0 : nsresult rv = CloneArray(aType, aIID, aCount, aValue,
1509 : &u.array.mArrayType,
1510 : &u.array.mArrayInterfaceID,
1511 : &u.array.mArrayCount,
1512 0 : &u.array.mArrayValue);
1513 0 : if (NS_FAILED(rv)) {
1514 0 : return rv;
1515 : }
1516 0 : DATA_SETTER_EPILOGUE(VTYPE_ARRAY);
1517 0 : return NS_OK;
1518 : }
1519 : nsresult
1520 0 : nsDiscriminatedUnion::SetFromStringWithSize(uint32_t aSize,
1521 : const char* aValue)
1522 : {
1523 0 : DATA_SETTER_PROLOGUE;
1524 0 : if (!aValue) {
1525 0 : return NS_ERROR_NULL_POINTER;
1526 : }
1527 0 : if (!(u.str.mStringValue =
1528 0 : (char*)nsMemory::Clone(aValue, (aSize + 1) * sizeof(char)))) {
1529 0 : return NS_ERROR_OUT_OF_MEMORY;
1530 : }
1531 0 : u.str.mStringLength = aSize;
1532 0 : DATA_SETTER_EPILOGUE(VTYPE_STRING_SIZE_IS);
1533 0 : return NS_OK;
1534 : }
1535 : nsresult
1536 0 : nsDiscriminatedUnion::SetFromWStringWithSize(uint32_t aSize,
1537 : const char16_t* aValue)
1538 : {
1539 0 : DATA_SETTER_PROLOGUE;
1540 0 : if (!aValue) {
1541 0 : return NS_ERROR_NULL_POINTER;
1542 : }
1543 0 : if (!(u.wstr.mWStringValue =
1544 0 : (char16_t*)nsMemory::Clone(aValue, (aSize + 1) * sizeof(char16_t)))) {
1545 0 : return NS_ERROR_OUT_OF_MEMORY;
1546 : }
1547 0 : u.wstr.mWStringLength = aSize;
1548 0 : DATA_SETTER_EPILOGUE(VTYPE_WSTRING_SIZE_IS);
1549 0 : return NS_OK;
1550 : }
1551 : void
1552 2 : nsDiscriminatedUnion::AllocateWStringWithSize(uint32_t aSize)
1553 : {
1554 2 : DATA_SETTER_PROLOGUE;
1555 2 : u.wstr.mWStringValue = (char16_t*)moz_xmalloc((aSize + 1) * sizeof(char16_t));
1556 2 : u.wstr.mWStringValue[aSize] = '\0';
1557 2 : u.wstr.mWStringLength = aSize;
1558 2 : DATA_SETTER_EPILOGUE(VTYPE_WSTRING_SIZE_IS);
1559 2 : }
1560 : void
1561 0 : nsDiscriminatedUnion::SetToVoid()
1562 : {
1563 0 : DATA_SETTER_PROLOGUE;
1564 0 : DATA_SETTER_EPILOGUE(VTYPE_VOID);
1565 0 : }
1566 : void
1567 0 : nsDiscriminatedUnion::SetToEmpty()
1568 : {
1569 0 : DATA_SETTER_PROLOGUE;
1570 0 : DATA_SETTER_EPILOGUE(VTYPE_EMPTY);
1571 0 : }
1572 : void
1573 0 : nsDiscriminatedUnion::SetToEmptyArray()
1574 : {
1575 0 : DATA_SETTER_PROLOGUE;
1576 0 : DATA_SETTER_EPILOGUE(VTYPE_EMPTY_ARRAY);
1577 0 : }
1578 :
1579 : /***************************************************************************/
1580 :
1581 : void
1582 148 : nsDiscriminatedUnion::Cleanup()
1583 : {
1584 148 : switch (mType) {
1585 : case nsIDataType::VTYPE_INT8:
1586 : case nsIDataType::VTYPE_INT16:
1587 : case nsIDataType::VTYPE_INT32:
1588 : case nsIDataType::VTYPE_INT64:
1589 : case nsIDataType::VTYPE_UINT8:
1590 : case nsIDataType::VTYPE_UINT16:
1591 : case nsIDataType::VTYPE_UINT32:
1592 : case nsIDataType::VTYPE_UINT64:
1593 : case nsIDataType::VTYPE_FLOAT:
1594 : case nsIDataType::VTYPE_DOUBLE:
1595 : case nsIDataType::VTYPE_BOOL:
1596 : case nsIDataType::VTYPE_CHAR:
1597 : case nsIDataType::VTYPE_WCHAR:
1598 : case nsIDataType::VTYPE_VOID:
1599 : case nsIDataType::VTYPE_ID:
1600 30 : break;
1601 : case nsIDataType::VTYPE_ASTRING:
1602 : case nsIDataType::VTYPE_DOMSTRING:
1603 25 : delete u.mAStringValue;
1604 25 : break;
1605 : case nsIDataType::VTYPE_CSTRING:
1606 0 : delete u.mCStringValue;
1607 0 : break;
1608 : case nsIDataType::VTYPE_UTF8STRING:
1609 0 : delete u.mUTF8StringValue;
1610 0 : break;
1611 : case nsIDataType::VTYPE_CHAR_STR:
1612 : case nsIDataType::VTYPE_STRING_SIZE_IS:
1613 0 : free((char*)u.str.mStringValue);
1614 0 : break;
1615 : case nsIDataType::VTYPE_WCHAR_STR:
1616 : case nsIDataType::VTYPE_WSTRING_SIZE_IS:
1617 2 : free((char*)u.wstr.mWStringValue);
1618 2 : break;
1619 : case nsIDataType::VTYPE_INTERFACE:
1620 : case nsIDataType::VTYPE_INTERFACE_IS:
1621 0 : NS_IF_RELEASE(u.iface.mInterfaceValue);
1622 0 : break;
1623 : case nsIDataType::VTYPE_ARRAY:
1624 0 : FreeArray();
1625 0 : break;
1626 : case nsIDataType::VTYPE_EMPTY_ARRAY:
1627 : case nsIDataType::VTYPE_EMPTY:
1628 91 : break;
1629 : default:
1630 0 : NS_ERROR("bad type in variant!");
1631 0 : break;
1632 : }
1633 :
1634 148 : mType = nsIDataType::VTYPE_EMPTY;
1635 148 : }
1636 :
1637 : void
1638 0 : nsDiscriminatedUnion::Traverse(nsCycleCollectionTraversalCallback& aCb) const
1639 : {
1640 0 : switch (mType) {
1641 : case nsIDataType::VTYPE_INTERFACE:
1642 : case nsIDataType::VTYPE_INTERFACE_IS:
1643 0 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mData");
1644 0 : aCb.NoteXPCOMChild(u.iface.mInterfaceValue);
1645 0 : break;
1646 : case nsIDataType::VTYPE_ARRAY:
1647 0 : switch (u.array.mArrayType) {
1648 : case nsIDataType::VTYPE_INTERFACE:
1649 : case nsIDataType::VTYPE_INTERFACE_IS: {
1650 0 : nsISupports** p = (nsISupports**)u.array.mArrayValue;
1651 0 : for (uint32_t i = u.array.mArrayCount; i > 0; ++p, --i) {
1652 0 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mData[i]");
1653 0 : aCb.NoteXPCOMChild(*p);
1654 : }
1655 0 : break;
1656 : }
1657 : default:
1658 0 : break;
1659 : }
1660 0 : break;
1661 : default:
1662 0 : break;
1663 : }
1664 0 : }
1665 :
1666 : /***************************************************************************/
1667 : /***************************************************************************/
1668 : // members...
1669 :
1670 86 : nsVariantBase::nsVariantBase()
1671 86 : : mWritable(true)
1672 : {
1673 : #ifdef DEBUG
1674 : {
1675 : // Assert that the nsIDataType consts match the values #defined in
1676 : // xpt_struct.h. Bad things happen somewhere if they don't.
1677 : struct THE_TYPES
1678 : {
1679 : uint16_t a;
1680 : uint16_t b;
1681 : };
1682 : static const THE_TYPES array[] = {
1683 : {nsIDataType::VTYPE_INT8 , TD_INT8 },
1684 : {nsIDataType::VTYPE_INT16 , TD_INT16 },
1685 : {nsIDataType::VTYPE_INT32 , TD_INT32 },
1686 : {nsIDataType::VTYPE_INT64 , TD_INT64 },
1687 : {nsIDataType::VTYPE_UINT8 , TD_UINT8 },
1688 : {nsIDataType::VTYPE_UINT16 , TD_UINT16 },
1689 : {nsIDataType::VTYPE_UINT32 , TD_UINT32 },
1690 : {nsIDataType::VTYPE_UINT64 , TD_UINT64 },
1691 : {nsIDataType::VTYPE_FLOAT , TD_FLOAT },
1692 : {nsIDataType::VTYPE_DOUBLE , TD_DOUBLE },
1693 : {nsIDataType::VTYPE_BOOL , TD_BOOL },
1694 : {nsIDataType::VTYPE_CHAR , TD_CHAR },
1695 : {nsIDataType::VTYPE_WCHAR , TD_WCHAR },
1696 : {nsIDataType::VTYPE_VOID , TD_VOID },
1697 : {nsIDataType::VTYPE_ID , TD_PNSIID },
1698 : {nsIDataType::VTYPE_DOMSTRING , TD_DOMSTRING },
1699 : {nsIDataType::VTYPE_CHAR_STR , TD_PSTRING },
1700 : {nsIDataType::VTYPE_WCHAR_STR , TD_PWSTRING },
1701 : {nsIDataType::VTYPE_INTERFACE , TD_INTERFACE_TYPE },
1702 : {nsIDataType::VTYPE_INTERFACE_IS , TD_INTERFACE_IS_TYPE},
1703 : {nsIDataType::VTYPE_ARRAY , TD_ARRAY },
1704 : {nsIDataType::VTYPE_STRING_SIZE_IS , TD_PSTRING_SIZE_IS },
1705 : {nsIDataType::VTYPE_WSTRING_SIZE_IS , TD_PWSTRING_SIZE_IS },
1706 : {nsIDataType::VTYPE_UTF8STRING , TD_UTF8STRING },
1707 : {nsIDataType::VTYPE_CSTRING , TD_CSTRING },
1708 : {nsIDataType::VTYPE_ASTRING , TD_ASTRING }
1709 : };
1710 : static const int length = sizeof(array) / sizeof(array[0]);
1711 : static bool inited = false;
1712 86 : if (!inited) {
1713 54 : for (int i = 0; i < length; ++i) {
1714 52 : NS_ASSERTION(array[i].a == array[i].b, "bad const declaration");
1715 : }
1716 2 : inited = true;
1717 : }
1718 : }
1719 : #endif
1720 86 : }
1721 :
1722 : // For all the data getters we just forward to the static (and sharable)
1723 : // 'ConvertTo' functions.
1724 :
1725 : NS_IMETHODIMP
1726 77 : nsVariantBase::GetDataType(uint16_t* aDataType)
1727 : {
1728 77 : *aDataType = mData.GetType();
1729 77 : return NS_OK;
1730 : }
1731 :
1732 : NS_IMETHODIMP
1733 0 : nsVariantBase::GetAsInt8(uint8_t* aResult)
1734 : {
1735 0 : return mData.ConvertToInt8(aResult);
1736 : }
1737 :
1738 : NS_IMETHODIMP
1739 0 : nsVariantBase::GetAsInt16(int16_t* aResult)
1740 : {
1741 0 : return mData.ConvertToInt16(aResult);
1742 : }
1743 :
1744 : NS_IMETHODIMP
1745 1 : nsVariantBase::GetAsInt32(int32_t* aResult)
1746 : {
1747 1 : return mData.ConvertToInt32(aResult);
1748 : }
1749 :
1750 : NS_IMETHODIMP
1751 17 : nsVariantBase::GetAsInt64(int64_t* aResult)
1752 : {
1753 17 : return mData.ConvertToInt64(aResult);
1754 : }
1755 :
1756 : NS_IMETHODIMP
1757 0 : nsVariantBase::GetAsUint8(uint8_t* aResult)
1758 : {
1759 0 : return mData.ConvertToUint8(aResult);
1760 : }
1761 :
1762 : NS_IMETHODIMP
1763 0 : nsVariantBase::GetAsUint16(uint16_t* aResult)
1764 : {
1765 0 : return mData.ConvertToUint16(aResult);
1766 : }
1767 :
1768 : NS_IMETHODIMP
1769 0 : nsVariantBase::GetAsUint32(uint32_t* aResult)
1770 : {
1771 0 : return mData.ConvertToUint32(aResult);
1772 : }
1773 :
1774 : NS_IMETHODIMP
1775 0 : nsVariantBase::GetAsUint64(uint64_t* aResult)
1776 : {
1777 0 : return mData.ConvertToUint64(aResult);
1778 : }
1779 :
1780 : NS_IMETHODIMP
1781 0 : nsVariantBase::GetAsFloat(float* aResult)
1782 : {
1783 0 : return mData.ConvertToFloat(aResult);
1784 : }
1785 :
1786 : NS_IMETHODIMP
1787 10 : nsVariantBase::GetAsDouble(double* aResult)
1788 : {
1789 10 : return mData.ConvertToDouble(aResult);
1790 : }
1791 :
1792 : NS_IMETHODIMP
1793 15 : nsVariantBase::GetAsBool(bool* aResult)
1794 : {
1795 15 : return mData.ConvertToBool(aResult);
1796 : }
1797 :
1798 : NS_IMETHODIMP
1799 0 : nsVariantBase::GetAsChar(char* aResult)
1800 : {
1801 0 : return mData.ConvertToChar(aResult);
1802 : }
1803 :
1804 : NS_IMETHODIMP
1805 0 : nsVariantBase::GetAsWChar(char16_t* aResult)
1806 : {
1807 0 : return mData.ConvertToWChar(aResult);
1808 : }
1809 :
1810 : NS_IMETHODIMP_(nsresult)
1811 0 : nsVariantBase::GetAsID(nsID* aResult)
1812 : {
1813 0 : return mData.ConvertToID(aResult);
1814 : }
1815 :
1816 : NS_IMETHODIMP
1817 23 : nsVariantBase::GetAsAString(nsAString& aResult)
1818 : {
1819 23 : return mData.ConvertToAString(aResult);
1820 : }
1821 :
1822 : NS_IMETHODIMP
1823 0 : nsVariantBase::GetAsDOMString(nsAString& aResult)
1824 : {
1825 : // A DOMString maps to an AString internally, so we can re-use
1826 : // ConvertToAString here.
1827 0 : return mData.ConvertToAString(aResult);
1828 : }
1829 :
1830 : NS_IMETHODIMP
1831 9 : nsVariantBase::GetAsACString(nsACString& aResult)
1832 : {
1833 9 : return mData.ConvertToACString(aResult);
1834 : }
1835 :
1836 : NS_IMETHODIMP
1837 0 : nsVariantBase::GetAsAUTF8String(nsAUTF8String& aResult)
1838 : {
1839 0 : return mData.ConvertToAUTF8String(aResult);
1840 : }
1841 :
1842 : NS_IMETHODIMP
1843 0 : nsVariantBase::GetAsString(char** aResult)
1844 : {
1845 0 : return mData.ConvertToString(aResult);
1846 : }
1847 :
1848 : NS_IMETHODIMP
1849 0 : nsVariantBase::GetAsWString(char16_t** aResult)
1850 : {
1851 0 : return mData.ConvertToWString(aResult);
1852 : }
1853 :
1854 : NS_IMETHODIMP
1855 3 : nsVariantBase::GetAsISupports(nsISupports** aResult)
1856 : {
1857 3 : return mData.ConvertToISupports(aResult);
1858 : }
1859 :
1860 : NS_IMETHODIMP
1861 34 : nsVariantBase::GetAsJSVal(JS::MutableHandleValue)
1862 : {
1863 : // Can only get the jsval from an XPCVariant.
1864 34 : return NS_ERROR_CANNOT_CONVERT_DATA;
1865 : }
1866 :
1867 : NS_IMETHODIMP
1868 0 : nsVariantBase::GetAsInterface(nsIID** aIID, void** aInterface)
1869 : {
1870 0 : return mData.ConvertToInterface(aIID, aInterface);
1871 : }
1872 :
1873 : NS_IMETHODIMP_(nsresult)
1874 0 : nsVariantBase::GetAsArray(uint16_t* aType, nsIID* aIID,
1875 : uint32_t* aCount, void** aPtr)
1876 : {
1877 0 : return mData.ConvertToArray(aType, aIID, aCount, aPtr);
1878 : }
1879 :
1880 : NS_IMETHODIMP
1881 0 : nsVariantBase::GetAsStringWithSize(uint32_t* aSize, char** aStr)
1882 : {
1883 0 : return mData.ConvertToStringWithSize(aSize, aStr);
1884 : }
1885 :
1886 : NS_IMETHODIMP
1887 2 : nsVariantBase::GetAsWStringWithSize(uint32_t* aSize, char16_t** aStr)
1888 : {
1889 2 : return mData.ConvertToWStringWithSize(aSize, aStr);
1890 : }
1891 :
1892 : /***************************************************************************/
1893 :
1894 : NS_IMETHODIMP
1895 0 : nsVariantBase::GetWritable(bool* aWritable)
1896 : {
1897 0 : *aWritable = mWritable;
1898 0 : return NS_OK;
1899 : }
1900 : NS_IMETHODIMP
1901 0 : nsVariantBase::SetWritable(bool aWritable)
1902 : {
1903 0 : if (!mWritable && aWritable) {
1904 0 : return NS_ERROR_FAILURE;
1905 : }
1906 0 : mWritable = aWritable;
1907 0 : return NS_OK;
1908 : }
1909 :
1910 : /***************************************************************************/
1911 :
1912 : // For all the data setters we just forward to the static (and sharable)
1913 : // 'SetFrom' functions.
1914 :
1915 : NS_IMETHODIMP
1916 0 : nsVariantBase::SetAsInt8(uint8_t aValue)
1917 : {
1918 0 : if (!mWritable) {
1919 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
1920 : }
1921 0 : mData.SetFromInt8(aValue);
1922 0 : return NS_OK;
1923 : }
1924 :
1925 : NS_IMETHODIMP
1926 0 : nsVariantBase::SetAsInt16(int16_t aValue)
1927 : {
1928 0 : if (!mWritable) {
1929 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
1930 : }
1931 0 : mData.SetFromInt16(aValue);
1932 0 : return NS_OK;
1933 : }
1934 :
1935 : NS_IMETHODIMP
1936 12 : nsVariantBase::SetAsInt32(int32_t aValue)
1937 : {
1938 12 : if (!mWritable) {
1939 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
1940 : }
1941 12 : mData.SetFromInt32(aValue);
1942 12 : return NS_OK;
1943 : }
1944 :
1945 : NS_IMETHODIMP
1946 17 : nsVariantBase::SetAsInt64(int64_t aValue)
1947 : {
1948 17 : if (!mWritable) {
1949 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
1950 : }
1951 17 : mData.SetFromInt64(aValue);
1952 17 : return NS_OK;
1953 : }
1954 :
1955 : NS_IMETHODIMP
1956 0 : nsVariantBase::SetAsUint8(uint8_t aValue)
1957 : {
1958 0 : if (!mWritable) {
1959 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
1960 : }
1961 0 : mData.SetFromUint8(aValue);
1962 0 : return NS_OK;
1963 : }
1964 :
1965 : NS_IMETHODIMP
1966 0 : nsVariantBase::SetAsUint16(uint16_t aValue)
1967 : {
1968 0 : if (!mWritable) {
1969 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
1970 : }
1971 0 : mData.SetFromUint16(aValue);
1972 0 : return NS_OK;
1973 : }
1974 :
1975 : NS_IMETHODIMP
1976 1 : nsVariantBase::SetAsUint32(uint32_t aValue)
1977 : {
1978 1 : if (!mWritable) {
1979 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
1980 : }
1981 1 : mData.SetFromUint32(aValue);
1982 1 : return NS_OK;
1983 : }
1984 :
1985 : NS_IMETHODIMP
1986 1 : nsVariantBase::SetAsUint64(uint64_t aValue)
1987 : {
1988 1 : if (!mWritable) {
1989 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
1990 : }
1991 1 : mData.SetFromUint64(aValue);
1992 1 : return NS_OK;
1993 : }
1994 :
1995 : NS_IMETHODIMP
1996 0 : nsVariantBase::SetAsFloat(float aValue)
1997 : {
1998 0 : if (!mWritable) {
1999 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2000 : }
2001 0 : mData.SetFromFloat(aValue);
2002 0 : return NS_OK;
2003 : }
2004 :
2005 : NS_IMETHODIMP
2006 0 : nsVariantBase::SetAsDouble(double aValue)
2007 : {
2008 0 : if (!mWritable) {
2009 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2010 : }
2011 0 : mData.SetFromDouble(aValue);
2012 0 : return NS_OK;
2013 : }
2014 :
2015 : NS_IMETHODIMP
2016 17 : nsVariantBase::SetAsBool(bool aValue)
2017 : {
2018 17 : if (!mWritable) {
2019 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2020 : }
2021 17 : mData.SetFromBool(aValue);
2022 17 : return NS_OK;
2023 : }
2024 :
2025 : NS_IMETHODIMP
2026 0 : nsVariantBase::SetAsChar(char aValue)
2027 : {
2028 0 : if (!mWritable) {
2029 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2030 : }
2031 0 : mData.SetFromChar(aValue);
2032 0 : return NS_OK;
2033 : }
2034 :
2035 : NS_IMETHODIMP
2036 0 : nsVariantBase::SetAsWChar(char16_t aValue)
2037 : {
2038 0 : if (!mWritable) {
2039 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2040 : }
2041 0 : mData.SetFromWChar(aValue);
2042 0 : return NS_OK;
2043 : }
2044 :
2045 : NS_IMETHODIMP
2046 0 : nsVariantBase::SetAsID(const nsID& aValue)
2047 : {
2048 0 : if (!mWritable) {
2049 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2050 : }
2051 0 : mData.SetFromID(aValue);
2052 0 : return NS_OK;
2053 : }
2054 :
2055 : NS_IMETHODIMP
2056 25 : nsVariantBase::SetAsAString(const nsAString& aValue)
2057 : {
2058 25 : if (!mWritable) {
2059 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2060 : }
2061 25 : mData.SetFromAString(aValue);
2062 25 : return NS_OK;
2063 : }
2064 :
2065 : NS_IMETHODIMP
2066 0 : nsVariantBase::SetAsDOMString(const nsAString& aValue)
2067 : {
2068 0 : if (!mWritable) {
2069 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2070 : }
2071 :
2072 0 : mData.SetFromDOMString(aValue);
2073 0 : return NS_OK;
2074 : }
2075 :
2076 : NS_IMETHODIMP
2077 5 : nsVariantBase::SetAsACString(const nsACString& aValue)
2078 : {
2079 5 : if (!mWritable) {
2080 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2081 : }
2082 5 : mData.SetFromACString(aValue);
2083 5 : return NS_OK;
2084 : }
2085 :
2086 : NS_IMETHODIMP
2087 0 : nsVariantBase::SetAsAUTF8String(const nsAUTF8String& aValue)
2088 : {
2089 0 : if (!mWritable) {
2090 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2091 : }
2092 0 : mData.SetFromAUTF8String(aValue);
2093 0 : return NS_OK;
2094 : }
2095 :
2096 : NS_IMETHODIMP
2097 0 : nsVariantBase::SetAsString(const char* aValue)
2098 : {
2099 0 : if (!mWritable) {
2100 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2101 : }
2102 0 : return mData.SetFromString(aValue);
2103 : }
2104 :
2105 : NS_IMETHODIMP
2106 0 : nsVariantBase::SetAsWString(const char16_t* aValue)
2107 : {
2108 0 : if (!mWritable) {
2109 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2110 : }
2111 0 : return mData.SetFromWString(aValue);
2112 : }
2113 :
2114 : NS_IMETHODIMP
2115 8 : nsVariantBase::SetAsISupports(nsISupports* aValue)
2116 : {
2117 8 : if (!mWritable) {
2118 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2119 : }
2120 8 : mData.SetFromISupports(aValue);
2121 8 : return NS_OK;
2122 : }
2123 :
2124 : NS_IMETHODIMP
2125 0 : nsVariantBase::SetAsInterface(const nsIID& aIID, void* aInterface)
2126 : {
2127 0 : if (!mWritable) {
2128 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2129 : }
2130 0 : mData.SetFromInterface(aIID, (nsISupports*)aInterface);
2131 0 : return NS_OK;
2132 : }
2133 :
2134 : NS_IMETHODIMP
2135 0 : nsVariantBase::SetAsArray(uint16_t aType, const nsIID* aIID,
2136 : uint32_t aCount, void* aPtr)
2137 : {
2138 0 : if (!mWritable) {
2139 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2140 : }
2141 0 : return mData.SetFromArray(aType, aIID, aCount, aPtr);
2142 : }
2143 :
2144 : NS_IMETHODIMP
2145 0 : nsVariantBase::SetAsStringWithSize(uint32_t aSize, const char* aStr)
2146 : {
2147 0 : if (!mWritable) {
2148 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2149 : }
2150 0 : return mData.SetFromStringWithSize(aSize, aStr);
2151 : }
2152 :
2153 : NS_IMETHODIMP
2154 0 : nsVariantBase::SetAsWStringWithSize(uint32_t aSize, const char16_t* aStr)
2155 : {
2156 0 : if (!mWritable) {
2157 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2158 : }
2159 0 : return mData.SetFromWStringWithSize(aSize, aStr);
2160 : }
2161 :
2162 : NS_IMETHODIMP
2163 0 : nsVariantBase::SetAsVoid()
2164 : {
2165 0 : if (!mWritable) {
2166 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2167 : }
2168 0 : mData.SetToVoid();
2169 0 : return NS_OK;
2170 : }
2171 :
2172 : NS_IMETHODIMP
2173 0 : nsVariantBase::SetAsEmpty()
2174 : {
2175 0 : if (!mWritable) {
2176 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2177 : }
2178 0 : mData.SetToEmpty();
2179 0 : return NS_OK;
2180 : }
2181 :
2182 : NS_IMETHODIMP
2183 0 : nsVariantBase::SetAsEmptyArray()
2184 : {
2185 0 : if (!mWritable) {
2186 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2187 : }
2188 0 : mData.SetToEmptyArray();
2189 0 : return NS_OK;
2190 : }
2191 :
2192 : NS_IMETHODIMP
2193 0 : nsVariantBase::SetFromVariant(nsIVariant* aValue)
2194 : {
2195 0 : if (!mWritable) {
2196 0 : return NS_ERROR_OBJECT_IS_IMMUTABLE;
2197 : }
2198 0 : return mData.SetFromVariant(aValue);
2199 : }
2200 :
2201 : /* nsVariant implementation */
2202 :
2203 853 : NS_IMPL_ISUPPORTS(nsVariant, nsIVariant, nsIWritableVariant)
2204 :
2205 :
2206 : /* nsVariantCC implementation */
2207 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsVariantCC)
2208 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
2209 0 : NS_INTERFACE_MAP_ENTRY(nsIVariant)
2210 0 : NS_INTERFACE_MAP_ENTRY(nsIWritableVariant)
2211 0 : NS_INTERFACE_MAP_END
2212 :
2213 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsVariantCC)
2214 :
2215 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsVariantCC)
2216 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsVariantCC)
2217 :
2218 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsVariantCC)
2219 0 : tmp->mData.Traverse(cb);
2220 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
2221 :
2222 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsVariantCC)
2223 0 : tmp->mData.Cleanup();
2224 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|