Coverage Report

Created: 2018-09-25 14:53

/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