xpcom/ds/nsVariant.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial