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