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