~ubuntu-branches/ubuntu/gutsy/virtualbox-ose/gutsy

« back to all changes in this revision

Viewing changes to src/libs/xpcom18a4/xpcom/ds/nsVariant.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-09-08 16:44:58 UTC
  • Revision ID: james.westby@ubuntu.com-20070908164458-wao29470vqtr8ksy
Tags: upstream-1.5.0-dfsg2
ImportĀ upstreamĀ versionĀ 1.5.0-dfsg2

Show diffs side-by-side

added added

removed removed

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