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