1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/ds/nsVariant.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2119 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* The long avoided variant support for xpcom. */ 1.11 + 1.12 +#include "nsVariant.h" 1.13 +#include "prprf.h" 1.14 +#include "prdtoa.h" 1.15 +#include <math.h> 1.16 +#include "nsCycleCollectionParticipant.h" 1.17 +#include "xpt_struct.h" 1.18 +#include "nsReadableUtils.h" 1.19 +#include "nsMemory.h" 1.20 +#include "nsString.h" 1.21 +#include "nsCRTGlue.h" 1.22 + 1.23 +/***************************************************************************/ 1.24 +// Helpers for static convert functions... 1.25 + 1.26 +static nsresult String2Double(const char* aString, double* retval) 1.27 +{ 1.28 + char* next; 1.29 + double value = PR_strtod(aString, &next); 1.30 + if(next == aString) 1.31 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.32 + *retval = value; 1.33 + return NS_OK; 1.34 +} 1.35 + 1.36 +static nsresult AString2Double(const nsAString& aString, double* retval) 1.37 +{ 1.38 + char* pChars = ToNewCString(aString); 1.39 + if(!pChars) 1.40 + return NS_ERROR_OUT_OF_MEMORY; 1.41 + nsresult rv = String2Double(pChars, retval); 1.42 + nsMemory::Free(pChars); 1.43 + return rv; 1.44 +} 1.45 + 1.46 +static nsresult AUTF8String2Double(const nsAUTF8String& aString, double* retval) 1.47 +{ 1.48 + return String2Double(PromiseFlatUTF8String(aString).get(), retval); 1.49 +} 1.50 + 1.51 +static nsresult ACString2Double(const nsACString& aString, double* retval) 1.52 +{ 1.53 + return String2Double(PromiseFlatCString(aString).get(), retval); 1.54 +} 1.55 + 1.56 +// Fills outVariant with double, uint32_t, or int32_t. 1.57 +// Returns NS_OK, an error code, or a non-NS_OK success code 1.58 +static nsresult ToManageableNumber(const nsDiscriminatedUnion& inData, 1.59 + nsDiscriminatedUnion* outData) 1.60 +{ 1.61 + nsresult rv; 1.62 + 1.63 + switch(inData.mType) 1.64 + { 1.65 + // This group results in a int32_t... 1.66 + 1.67 +#define CASE__NUMBER_INT32(type_, member_) \ 1.68 + case nsIDataType :: type_ : \ 1.69 + outData->u.mInt32Value = inData.u. member_ ; \ 1.70 + outData->mType = nsIDataType::VTYPE_INT32; \ 1.71 + return NS_OK; 1.72 + 1.73 + CASE__NUMBER_INT32(VTYPE_INT8, mInt8Value) 1.74 + CASE__NUMBER_INT32(VTYPE_INT16, mInt16Value) 1.75 + CASE__NUMBER_INT32(VTYPE_INT32, mInt32Value) 1.76 + CASE__NUMBER_INT32(VTYPE_UINT8, mUint8Value) 1.77 + CASE__NUMBER_INT32(VTYPE_UINT16, mUint16Value) 1.78 + CASE__NUMBER_INT32(VTYPE_BOOL, mBoolValue) 1.79 + CASE__NUMBER_INT32(VTYPE_CHAR, mCharValue) 1.80 + CASE__NUMBER_INT32(VTYPE_WCHAR, mWCharValue) 1.81 + 1.82 +#undef CASE__NUMBER_INT32 1.83 + 1.84 + // This group results in a uint32_t... 1.85 + 1.86 + case nsIDataType::VTYPE_UINT32: 1.87 + outData->u.mInt32Value = inData.u.mUint32Value; 1.88 + outData->mType = nsIDataType::VTYPE_INT32; 1.89 + return NS_OK; 1.90 + 1.91 + // This group results in a double... 1.92 + 1.93 + case nsIDataType::VTYPE_INT64: 1.94 + case nsIDataType::VTYPE_UINT64: 1.95 + // XXX Need boundary checking here. 1.96 + // We may need to return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA 1.97 + outData->u.mDoubleValue = double(inData.u.mInt64Value); 1.98 + outData->mType = nsIDataType::VTYPE_DOUBLE; 1.99 + return NS_OK; 1.100 + case nsIDataType::VTYPE_FLOAT: 1.101 + outData->u.mDoubleValue = inData.u.mFloatValue; 1.102 + outData->mType = nsIDataType::VTYPE_DOUBLE; 1.103 + return NS_OK; 1.104 + case nsIDataType::VTYPE_DOUBLE: 1.105 + outData->u.mDoubleValue = inData.u.mDoubleValue; 1.106 + outData->mType = nsIDataType::VTYPE_DOUBLE; 1.107 + return NS_OK; 1.108 + case nsIDataType::VTYPE_CHAR_STR: 1.109 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.110 + rv = String2Double(inData.u.str.mStringValue, &outData->u.mDoubleValue); 1.111 + if(NS_FAILED(rv)) 1.112 + return rv; 1.113 + outData->mType = nsIDataType::VTYPE_DOUBLE; 1.114 + return NS_OK; 1.115 + case nsIDataType::VTYPE_DOMSTRING: 1.116 + case nsIDataType::VTYPE_ASTRING: 1.117 + rv = AString2Double(*inData.u.mAStringValue, &outData->u.mDoubleValue); 1.118 + if(NS_FAILED(rv)) 1.119 + return rv; 1.120 + outData->mType = nsIDataType::VTYPE_DOUBLE; 1.121 + return NS_OK; 1.122 + case nsIDataType::VTYPE_UTF8STRING: 1.123 + rv = AUTF8String2Double(*inData.u.mUTF8StringValue, 1.124 + &outData->u.mDoubleValue); 1.125 + if(NS_FAILED(rv)) 1.126 + return rv; 1.127 + outData->mType = nsIDataType::VTYPE_DOUBLE; 1.128 + return NS_OK; 1.129 + case nsIDataType::VTYPE_CSTRING: 1.130 + rv = ACString2Double(*inData.u.mCStringValue, 1.131 + &outData->u.mDoubleValue); 1.132 + if(NS_FAILED(rv)) 1.133 + return rv; 1.134 + outData->mType = nsIDataType::VTYPE_DOUBLE; 1.135 + return NS_OK; 1.136 + case nsIDataType::VTYPE_WCHAR_STR: 1.137 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.138 + rv = AString2Double(nsDependentString(inData.u.wstr.mWStringValue), 1.139 + &outData->u.mDoubleValue); 1.140 + if(NS_FAILED(rv)) 1.141 + return rv; 1.142 + outData->mType = nsIDataType::VTYPE_DOUBLE; 1.143 + return NS_OK; 1.144 + 1.145 + // This group fails... 1.146 + 1.147 + case nsIDataType::VTYPE_VOID: 1.148 + case nsIDataType::VTYPE_ID: 1.149 + case nsIDataType::VTYPE_INTERFACE: 1.150 + case nsIDataType::VTYPE_INTERFACE_IS: 1.151 + case nsIDataType::VTYPE_ARRAY: 1.152 + case nsIDataType::VTYPE_EMPTY_ARRAY: 1.153 + case nsIDataType::VTYPE_EMPTY: 1.154 + default: 1.155 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.156 + } 1.157 +} 1.158 + 1.159 +/***************************************************************************/ 1.160 +// Array helpers... 1.161 + 1.162 +static void FreeArray(nsDiscriminatedUnion* data) 1.163 +{ 1.164 + NS_ASSERTION(data->mType == nsIDataType::VTYPE_ARRAY, "bad FreeArray call"); 1.165 + NS_ASSERTION(data->u.array.mArrayValue, "bad array"); 1.166 + NS_ASSERTION(data->u.array.mArrayCount, "bad array count"); 1.167 + 1.168 +#define CASE__FREE_ARRAY_PTR(type_, ctype_) \ 1.169 + case nsIDataType:: type_ : \ 1.170 + { \ 1.171 + ctype_ ** p = (ctype_ **) data->u.array.mArrayValue; \ 1.172 + for(uint32_t i = data->u.array.mArrayCount; i > 0; p++, i--) \ 1.173 + if(*p) \ 1.174 + nsMemory::Free((char*)*p); \ 1.175 + break; \ 1.176 + } 1.177 + 1.178 +#define CASE__FREE_ARRAY_IFACE(type_, ctype_) \ 1.179 + case nsIDataType:: type_ : \ 1.180 + { \ 1.181 + ctype_ ** p = (ctype_ **) data->u.array.mArrayValue; \ 1.182 + for(uint32_t i = data->u.array.mArrayCount; i > 0; p++, i--) \ 1.183 + if(*p) \ 1.184 + (*p)->Release(); \ 1.185 + break; \ 1.186 + } 1.187 + 1.188 + switch(data->u.array.mArrayType) 1.189 + { 1.190 + case nsIDataType::VTYPE_INT8: 1.191 + case nsIDataType::VTYPE_INT16: 1.192 + case nsIDataType::VTYPE_INT32: 1.193 + case nsIDataType::VTYPE_INT64: 1.194 + case nsIDataType::VTYPE_UINT8: 1.195 + case nsIDataType::VTYPE_UINT16: 1.196 + case nsIDataType::VTYPE_UINT32: 1.197 + case nsIDataType::VTYPE_UINT64: 1.198 + case nsIDataType::VTYPE_FLOAT: 1.199 + case nsIDataType::VTYPE_DOUBLE: 1.200 + case nsIDataType::VTYPE_BOOL: 1.201 + case nsIDataType::VTYPE_CHAR: 1.202 + case nsIDataType::VTYPE_WCHAR: 1.203 + break; 1.204 + 1.205 + // XXX We ASSUME that "array of nsID" means "array of pointers to nsID". 1.206 + CASE__FREE_ARRAY_PTR(VTYPE_ID, nsID) 1.207 + CASE__FREE_ARRAY_PTR(VTYPE_CHAR_STR, char) 1.208 + CASE__FREE_ARRAY_PTR(VTYPE_WCHAR_STR, char16_t) 1.209 + CASE__FREE_ARRAY_IFACE(VTYPE_INTERFACE, nsISupports) 1.210 + CASE__FREE_ARRAY_IFACE(VTYPE_INTERFACE_IS, nsISupports) 1.211 + 1.212 + // The rest are illegal. 1.213 + case nsIDataType::VTYPE_VOID: 1.214 + case nsIDataType::VTYPE_ASTRING: 1.215 + case nsIDataType::VTYPE_DOMSTRING: 1.216 + case nsIDataType::VTYPE_UTF8STRING: 1.217 + case nsIDataType::VTYPE_CSTRING: 1.218 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.219 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.220 + case nsIDataType::VTYPE_ARRAY: 1.221 + case nsIDataType::VTYPE_EMPTY_ARRAY: 1.222 + case nsIDataType::VTYPE_EMPTY: 1.223 + default: 1.224 + NS_ERROR("bad type in array!"); 1.225 + break; 1.226 + } 1.227 + 1.228 + // Free the array memory. 1.229 + nsMemory::Free((char*)data->u.array.mArrayValue); 1.230 + 1.231 +#undef CASE__FREE_ARRAY_PTR 1.232 +#undef CASE__FREE_ARRAY_IFACE 1.233 +} 1.234 + 1.235 +static nsresult CloneArray(uint16_t inType, const nsIID* inIID, 1.236 + uint32_t inCount, void* inValue, 1.237 + uint16_t* outType, 1.238 + nsIID* outIID, 1.239 + uint32_t* outCount, 1.240 + void** outValue) 1.241 +{ 1.242 + NS_ASSERTION(inCount, "bad param"); 1.243 + NS_ASSERTION(inValue, "bad param"); 1.244 + NS_ASSERTION(outType, "bad param"); 1.245 + NS_ASSERTION(outCount, "bad param"); 1.246 + NS_ASSERTION(outValue, "bad param"); 1.247 + 1.248 + uint32_t allocatedValueCount = 0; 1.249 + nsresult rv = NS_OK; 1.250 + uint32_t i; 1.251 + 1.252 + // First we figure out the size of the elements for the new u.array. 1.253 + 1.254 + size_t elementSize; 1.255 + size_t allocSize; 1.256 + 1.257 + switch(inType) 1.258 + { 1.259 + case nsIDataType::VTYPE_INT8: 1.260 + elementSize = sizeof(int8_t); 1.261 + break; 1.262 + case nsIDataType::VTYPE_INT16: 1.263 + elementSize = sizeof(int16_t); 1.264 + break; 1.265 + case nsIDataType::VTYPE_INT32: 1.266 + elementSize = sizeof(int32_t); 1.267 + break; 1.268 + case nsIDataType::VTYPE_INT64: 1.269 + elementSize = sizeof(int64_t); 1.270 + break; 1.271 + case nsIDataType::VTYPE_UINT8: 1.272 + elementSize = sizeof(uint8_t); 1.273 + break; 1.274 + case nsIDataType::VTYPE_UINT16: 1.275 + elementSize = sizeof(uint16_t); 1.276 + break; 1.277 + case nsIDataType::VTYPE_UINT32: 1.278 + elementSize = sizeof(uint32_t); 1.279 + break; 1.280 + case nsIDataType::VTYPE_UINT64: 1.281 + elementSize = sizeof(uint64_t); 1.282 + break; 1.283 + case nsIDataType::VTYPE_FLOAT: 1.284 + elementSize = sizeof(float); 1.285 + break; 1.286 + case nsIDataType::VTYPE_DOUBLE: 1.287 + elementSize = sizeof(double); 1.288 + break; 1.289 + case nsIDataType::VTYPE_BOOL: 1.290 + elementSize = sizeof(bool); 1.291 + break; 1.292 + case nsIDataType::VTYPE_CHAR: 1.293 + elementSize = sizeof(char); 1.294 + break; 1.295 + case nsIDataType::VTYPE_WCHAR: 1.296 + elementSize = sizeof(char16_t); 1.297 + break; 1.298 + 1.299 + // XXX We ASSUME that "array of nsID" means "array of pointers to nsID". 1.300 + case nsIDataType::VTYPE_ID: 1.301 + case nsIDataType::VTYPE_CHAR_STR: 1.302 + case nsIDataType::VTYPE_WCHAR_STR: 1.303 + case nsIDataType::VTYPE_INTERFACE: 1.304 + case nsIDataType::VTYPE_INTERFACE_IS: 1.305 + elementSize = sizeof(void*); 1.306 + break; 1.307 + 1.308 + // The rest are illegal. 1.309 + case nsIDataType::VTYPE_ASTRING: 1.310 + case nsIDataType::VTYPE_DOMSTRING: 1.311 + case nsIDataType::VTYPE_UTF8STRING: 1.312 + case nsIDataType::VTYPE_CSTRING: 1.313 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.314 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.315 + case nsIDataType::VTYPE_VOID: 1.316 + case nsIDataType::VTYPE_ARRAY: 1.317 + case nsIDataType::VTYPE_EMPTY_ARRAY: 1.318 + case nsIDataType::VTYPE_EMPTY: 1.319 + default: 1.320 + NS_ERROR("bad type in array!"); 1.321 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.322 + } 1.323 + 1.324 + 1.325 + // Alloc the u.array. 1.326 + 1.327 + allocSize = inCount * elementSize; 1.328 + *outValue = nsMemory::Alloc(allocSize); 1.329 + if(!*outValue) 1.330 + return NS_ERROR_OUT_OF_MEMORY; 1.331 + 1.332 + // Clone the elements. 1.333 + 1.334 + switch(inType) 1.335 + { 1.336 + case nsIDataType::VTYPE_INT8: 1.337 + case nsIDataType::VTYPE_INT16: 1.338 + case nsIDataType::VTYPE_INT32: 1.339 + case nsIDataType::VTYPE_INT64: 1.340 + case nsIDataType::VTYPE_UINT8: 1.341 + case nsIDataType::VTYPE_UINT16: 1.342 + case nsIDataType::VTYPE_UINT32: 1.343 + case nsIDataType::VTYPE_UINT64: 1.344 + case nsIDataType::VTYPE_FLOAT: 1.345 + case nsIDataType::VTYPE_DOUBLE: 1.346 + case nsIDataType::VTYPE_BOOL: 1.347 + case nsIDataType::VTYPE_CHAR: 1.348 + case nsIDataType::VTYPE_WCHAR: 1.349 + memcpy(*outValue, inValue, allocSize); 1.350 + break; 1.351 + 1.352 + case nsIDataType::VTYPE_INTERFACE_IS: 1.353 + if(outIID) 1.354 + *outIID = *inIID; 1.355 + // fall through... 1.356 + case nsIDataType::VTYPE_INTERFACE: 1.357 + { 1.358 + memcpy(*outValue, inValue, allocSize); 1.359 + 1.360 + nsISupports** p = (nsISupports**) *outValue; 1.361 + for(i = inCount; i > 0; p++, i--) 1.362 + if(*p) 1.363 + (*p)->AddRef(); 1.364 + break; 1.365 + } 1.366 + 1.367 + // XXX We ASSUME that "array of nsID" means "array of pointers to nsID". 1.368 + case nsIDataType::VTYPE_ID: 1.369 + { 1.370 + nsID** inp = (nsID**) inValue; 1.371 + nsID** outp = (nsID**) *outValue; 1.372 + for(i = inCount; i > 0; i--) 1.373 + { 1.374 + nsID* idp = *(inp++); 1.375 + if(idp) 1.376 + { 1.377 + if(nullptr == (*(outp++) = (nsID*) 1.378 + nsMemory::Clone((char*)idp, sizeof(nsID)))) 1.379 + goto bad; 1.380 + } 1.381 + else 1.382 + *(outp++) = nullptr; 1.383 + allocatedValueCount++; 1.384 + } 1.385 + break; 1.386 + } 1.387 + 1.388 + case nsIDataType::VTYPE_CHAR_STR: 1.389 + { 1.390 + char** inp = (char**) inValue; 1.391 + char** outp = (char**) *outValue; 1.392 + for(i = inCount; i > 0; i--) 1.393 + { 1.394 + char* str = *(inp++); 1.395 + if(str) 1.396 + { 1.397 + if(nullptr == (*(outp++) = (char*) 1.398 + nsMemory::Clone(str, (strlen(str)+1)*sizeof(char)))) 1.399 + goto bad; 1.400 + } 1.401 + else 1.402 + *(outp++) = nullptr; 1.403 + allocatedValueCount++; 1.404 + } 1.405 + break; 1.406 + } 1.407 + 1.408 + case nsIDataType::VTYPE_WCHAR_STR: 1.409 + { 1.410 + char16_t** inp = (char16_t**) inValue; 1.411 + char16_t** outp = (char16_t**) *outValue; 1.412 + for(i = inCount; i > 0; i--) 1.413 + { 1.414 + char16_t* str = *(inp++); 1.415 + if(str) 1.416 + { 1.417 + if(nullptr == (*(outp++) = (char16_t*) 1.418 + nsMemory::Clone(str, 1.419 + (NS_strlen(str) + 1) * sizeof(char16_t)))) 1.420 + goto bad; 1.421 + } 1.422 + else 1.423 + *(outp++) = nullptr; 1.424 + allocatedValueCount++; 1.425 + } 1.426 + break; 1.427 + } 1.428 + 1.429 + // The rest are illegal. 1.430 + case nsIDataType::VTYPE_VOID: 1.431 + case nsIDataType::VTYPE_ARRAY: 1.432 + case nsIDataType::VTYPE_EMPTY_ARRAY: 1.433 + case nsIDataType::VTYPE_EMPTY: 1.434 + case nsIDataType::VTYPE_ASTRING: 1.435 + case nsIDataType::VTYPE_DOMSTRING: 1.436 + case nsIDataType::VTYPE_UTF8STRING: 1.437 + case nsIDataType::VTYPE_CSTRING: 1.438 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.439 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.440 + default: 1.441 + NS_ERROR("bad type in array!"); 1.442 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.443 + } 1.444 + 1.445 + *outType = inType; 1.446 + *outCount = inCount; 1.447 + return NS_OK; 1.448 + 1.449 +bad: 1.450 + if(*outValue) 1.451 + { 1.452 + char** p = (char**) *outValue; 1.453 + for(i = allocatedValueCount; i > 0; p++, i--) 1.454 + if(*p) 1.455 + nsMemory::Free(*p); 1.456 + nsMemory::Free((char*)*outValue); 1.457 + *outValue = nullptr; 1.458 + } 1.459 + return rv; 1.460 +} 1.461 + 1.462 +/***************************************************************************/ 1.463 + 1.464 +#define TRIVIAL_DATA_CONVERTER(type_, data_, member_, retval_) \ 1.465 + if(data_.mType == nsIDataType :: type_) { \ 1.466 + *retval_ = data_.u.member_; \ 1.467 + return NS_OK; \ 1.468 + } 1.469 + 1.470 +#define NUMERIC_CONVERSION_METHOD_BEGIN(type_, Ctype_, name_) \ 1.471 +/* static */ nsresult \ 1.472 +nsVariant::ConvertTo##name_ (const nsDiscriminatedUnion& data, \ 1.473 + Ctype_ *_retval) \ 1.474 +{ \ 1.475 + TRIVIAL_DATA_CONVERTER(type_, data, m##name_##Value, _retval) \ 1.476 + nsDiscriminatedUnion tempData; \ 1.477 + nsVariant::Initialize(&tempData); \ 1.478 + nsresult rv = ToManageableNumber(data, &tempData); \ 1.479 + /* */ \ 1.480 + /* NOTE: rv may indicate a success code that we want to preserve */ \ 1.481 + /* For the final return. So all the return cases below should return */ \ 1.482 + /* this rv when indicating success. */ \ 1.483 + /* */ \ 1.484 + if(NS_FAILED(rv)) \ 1.485 + return rv; \ 1.486 + switch(tempData.mType) \ 1.487 + { 1.488 + 1.489 +#define CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(Ctype_) \ 1.490 + case nsIDataType::VTYPE_INT32: \ 1.491 + *_retval = ( Ctype_ ) tempData.u.mInt32Value; \ 1.492 + return rv; 1.493 + 1.494 +#define CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(Ctype_, min_, max_) \ 1.495 + case nsIDataType::VTYPE_INT32: \ 1.496 + { \ 1.497 + int32_t value = tempData.u.mInt32Value; \ 1.498 + if(value < min_ || value > max_) \ 1.499 + return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \ 1.500 + *_retval = ( Ctype_ ) value; \ 1.501 + return rv; \ 1.502 + } 1.503 + 1.504 +#define CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(Ctype_) \ 1.505 + case nsIDataType::VTYPE_UINT32: \ 1.506 + *_retval = ( Ctype_ ) tempData.u.mUint32Value; \ 1.507 + return rv; 1.508 + 1.509 +#define CASE__NUMERIC_CONVERSION_UINT32_MAX(Ctype_, max_) \ 1.510 + case nsIDataType::VTYPE_UINT32: \ 1.511 + { \ 1.512 + uint32_t value = tempData.u.mUint32Value; \ 1.513 + if(value > max_) \ 1.514 + return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \ 1.515 + *_retval = ( Ctype_ ) value; \ 1.516 + return rv; \ 1.517 + } 1.518 + 1.519 +#define CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(Ctype_) \ 1.520 + case nsIDataType::VTYPE_DOUBLE: \ 1.521 + *_retval = ( Ctype_ ) tempData.u.mDoubleValue; \ 1.522 + return rv; 1.523 + 1.524 +#define CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX(Ctype_, min_, max_) \ 1.525 + case nsIDataType::VTYPE_DOUBLE: \ 1.526 + { \ 1.527 + double value = tempData.u.mDoubleValue; \ 1.528 + if(value < min_ || value > max_) \ 1.529 + return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \ 1.530 + *_retval = ( Ctype_ ) value; \ 1.531 + return rv; \ 1.532 + } 1.533 + 1.534 +#define CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(Ctype_, min_, max_) \ 1.535 + case nsIDataType::VTYPE_DOUBLE: \ 1.536 + { \ 1.537 + double value = tempData.u.mDoubleValue; \ 1.538 + if(value < min_ || value > max_) \ 1.539 + return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \ 1.540 + *_retval = ( Ctype_ ) value; \ 1.541 + return (0.0 == fmod(value,1.0)) ? \ 1.542 + rv : NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA; \ 1.543 + } 1.544 + 1.545 +#define CASES__NUMERIC_CONVERSION_NORMAL(Ctype_, min_, max_) \ 1.546 + CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(Ctype_, min_, max_) \ 1.547 + CASE__NUMERIC_CONVERSION_UINT32_MAX(Ctype_, max_) \ 1.548 + CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(Ctype_, min_, max_) 1.549 + 1.550 +#define NUMERIC_CONVERSION_METHOD_END \ 1.551 + default: \ 1.552 + NS_ERROR("bad type returned from ToManageableNumber"); \ 1.553 + return NS_ERROR_CANNOT_CONVERT_DATA; \ 1.554 + } \ 1.555 +} 1.556 + 1.557 +#define NUMERIC_CONVERSION_METHOD_NORMAL(type_, Ctype_, name_, min_, max_) \ 1.558 + NUMERIC_CONVERSION_METHOD_BEGIN(type_, Ctype_, name_) \ 1.559 + CASES__NUMERIC_CONVERSION_NORMAL(Ctype_, min_, max_) \ 1.560 + NUMERIC_CONVERSION_METHOD_END 1.561 + 1.562 +/***************************************************************************/ 1.563 +// These expand into full public methods... 1.564 + 1.565 +NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_INT8, uint8_t, Int8, (-127-1), 127) 1.566 +NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_INT16, int16_t, Int16, (-32767-1), 32767) 1.567 + 1.568 +NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_INT32, int32_t, Int32) 1.569 + CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(int32_t) 1.570 + CASE__NUMERIC_CONVERSION_UINT32_MAX(int32_t, 2147483647) 1.571 + CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(int32_t, (-2147483647-1), 2147483647) 1.572 +NUMERIC_CONVERSION_METHOD_END 1.573 + 1.574 +NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_UINT8, uint8_t, Uint8, 0, 255) 1.575 +NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_UINT16, uint16_t, Uint16, 0, 65535) 1.576 + 1.577 +NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_UINT32, uint32_t, Uint32) 1.578 + CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(uint32_t, 0, 2147483647) 1.579 + CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(uint32_t) 1.580 + CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(uint32_t, 0, 4294967295U) 1.581 +NUMERIC_CONVERSION_METHOD_END 1.582 + 1.583 +// XXX toFloat convertions need to be fixed! 1.584 +NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_FLOAT, float, Float) 1.585 + CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(float) 1.586 + CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(float) 1.587 + CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(float) 1.588 +NUMERIC_CONVERSION_METHOD_END 1.589 + 1.590 +NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_DOUBLE, double, Double) 1.591 + CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(double) 1.592 + CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(double) 1.593 + CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(double) 1.594 +NUMERIC_CONVERSION_METHOD_END 1.595 + 1.596 +// XXX toChar convertions need to be fixed! 1.597 +NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_CHAR, char, Char) 1.598 + CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(char) 1.599 + CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(char) 1.600 + CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(char) 1.601 +NUMERIC_CONVERSION_METHOD_END 1.602 + 1.603 +// XXX toWChar convertions need to be fixed! 1.604 +NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_WCHAR, char16_t, WChar) 1.605 + CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(char16_t) 1.606 + CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(char16_t) 1.607 + CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(char16_t) 1.608 +NUMERIC_CONVERSION_METHOD_END 1.609 + 1.610 +#undef NUMERIC_CONVERSION_METHOD_BEGIN 1.611 +#undef CASE__NUMERIC_CONVERSION_INT32_JUST_CAST 1.612 +#undef CASE__NUMERIC_CONVERSION_INT32_MIN_MAX 1.613 +#undef CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST 1.614 +#undef CASE__NUMERIC_CONVERSION_UINT32_MIN_MAX 1.615 +#undef CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST 1.616 +#undef CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX 1.617 +#undef CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT 1.618 +#undef CASES__NUMERIC_CONVERSION_NORMAL 1.619 +#undef NUMERIC_CONVERSION_METHOD_END 1.620 +#undef NUMERIC_CONVERSION_METHOD_NORMAL 1.621 + 1.622 +/***************************************************************************/ 1.623 + 1.624 +// Just leverage a numeric converter for bool (but restrict the values). 1.625 +// XXX Is this really what we want to do? 1.626 + 1.627 +/* static */ nsresult 1.628 +nsVariant::ConvertToBool(const nsDiscriminatedUnion& data, bool *_retval) 1.629 +{ 1.630 + TRIVIAL_DATA_CONVERTER(VTYPE_BOOL, data, mBoolValue, _retval) 1.631 + 1.632 + double val; 1.633 + nsresult rv = nsVariant::ConvertToDouble(data, &val); 1.634 + if(NS_FAILED(rv)) 1.635 + return rv; 1.636 + *_retval = 0.0 != val; 1.637 + return rv; 1.638 +} 1.639 + 1.640 +/***************************************************************************/ 1.641 + 1.642 +/* static */ nsresult 1.643 +nsVariant::ConvertToInt64(const nsDiscriminatedUnion& data, int64_t *_retval) 1.644 +{ 1.645 + TRIVIAL_DATA_CONVERTER(VTYPE_INT64, data, mInt64Value, _retval) 1.646 + TRIVIAL_DATA_CONVERTER(VTYPE_UINT64, data, mUint64Value, _retval) 1.647 + 1.648 + nsDiscriminatedUnion tempData; 1.649 + nsVariant::Initialize(&tempData); 1.650 + nsresult rv = ToManageableNumber(data, &tempData); 1.651 + if(NS_FAILED(rv)) 1.652 + return rv; 1.653 + switch(tempData.mType) 1.654 + { 1.655 + case nsIDataType::VTYPE_INT32: 1.656 + *_retval = tempData.u.mInt32Value; 1.657 + return rv; 1.658 + case nsIDataType::VTYPE_UINT32: 1.659 + *_retval = tempData.u.mUint32Value; 1.660 + return rv; 1.661 + case nsIDataType::VTYPE_DOUBLE: 1.662 + // XXX should check for data loss here! 1.663 + *_retval = tempData.u.mDoubleValue; 1.664 + return rv; 1.665 + default: 1.666 + NS_ERROR("bad type returned from ToManageableNumber"); 1.667 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.668 + } 1.669 +} 1.670 + 1.671 +/* static */ nsresult 1.672 +nsVariant::ConvertToUint64(const nsDiscriminatedUnion& data, uint64_t *_retval) 1.673 +{ 1.674 + return nsVariant::ConvertToInt64(data, (int64_t *)_retval); 1.675 +} 1.676 + 1.677 +/***************************************************************************/ 1.678 + 1.679 +static bool String2ID(const nsDiscriminatedUnion& data, nsID* pid) 1.680 +{ 1.681 + nsAutoString tempString; 1.682 + nsAString* pString; 1.683 + 1.684 + switch(data.mType) 1.685 + { 1.686 + case nsIDataType::VTYPE_CHAR_STR: 1.687 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.688 + return pid->Parse(data.u.str.mStringValue); 1.689 + case nsIDataType::VTYPE_CSTRING: 1.690 + return pid->Parse(PromiseFlatCString(*data.u.mCStringValue).get()); 1.691 + case nsIDataType::VTYPE_UTF8STRING: 1.692 + return pid->Parse(PromiseFlatUTF8String(*data.u.mUTF8StringValue).get()); 1.693 + case nsIDataType::VTYPE_ASTRING: 1.694 + case nsIDataType::VTYPE_DOMSTRING: 1.695 + pString = data.u.mAStringValue; 1.696 + break; 1.697 + case nsIDataType::VTYPE_WCHAR_STR: 1.698 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.699 + tempString.Assign(data.u.wstr.mWStringValue); 1.700 + pString = &tempString; 1.701 + break; 1.702 + default: 1.703 + NS_ERROR("bad type in call to String2ID"); 1.704 + return false; 1.705 + } 1.706 + 1.707 + char* pChars = ToNewCString(*pString); 1.708 + if(!pChars) 1.709 + return false; 1.710 + bool result = pid->Parse(pChars); 1.711 + nsMemory::Free(pChars); 1.712 + return result; 1.713 +} 1.714 + 1.715 +/* static */ nsresult 1.716 +nsVariant::ConvertToID(const nsDiscriminatedUnion& data, nsID * _retval) 1.717 +{ 1.718 + nsID id; 1.719 + 1.720 + switch(data.mType) 1.721 + { 1.722 + case nsIDataType::VTYPE_ID: 1.723 + *_retval = data.u.mIDValue; 1.724 + return NS_OK; 1.725 + case nsIDataType::VTYPE_INTERFACE: 1.726 + *_retval = NS_GET_IID(nsISupports); 1.727 + return NS_OK; 1.728 + case nsIDataType::VTYPE_INTERFACE_IS: 1.729 + *_retval = data.u.iface.mInterfaceID; 1.730 + return NS_OK; 1.731 + case nsIDataType::VTYPE_ASTRING: 1.732 + case nsIDataType::VTYPE_DOMSTRING: 1.733 + case nsIDataType::VTYPE_UTF8STRING: 1.734 + case nsIDataType::VTYPE_CSTRING: 1.735 + case nsIDataType::VTYPE_CHAR_STR: 1.736 + case nsIDataType::VTYPE_WCHAR_STR: 1.737 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.738 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.739 + if(!String2ID(data, &id)) 1.740 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.741 + *_retval = id; 1.742 + return NS_OK; 1.743 + default: 1.744 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.745 + } 1.746 +} 1.747 + 1.748 +/***************************************************************************/ 1.749 + 1.750 +static nsresult ToString(const nsDiscriminatedUnion& data, 1.751 + nsACString & outString) 1.752 +{ 1.753 + char* ptr; 1.754 + 1.755 + switch(data.mType) 1.756 + { 1.757 + // all the stuff we don't handle... 1.758 + case nsIDataType::VTYPE_ASTRING: 1.759 + case nsIDataType::VTYPE_DOMSTRING: 1.760 + case nsIDataType::VTYPE_UTF8STRING: 1.761 + case nsIDataType::VTYPE_CSTRING: 1.762 + case nsIDataType::VTYPE_CHAR_STR: 1.763 + case nsIDataType::VTYPE_WCHAR_STR: 1.764 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.765 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.766 + case nsIDataType::VTYPE_WCHAR: 1.767 + NS_ERROR("ToString being called for a string type - screwy logic!"); 1.768 + // fall through... 1.769 + 1.770 + // XXX We might want stringified versions of these... ??? 1.771 + 1.772 + case nsIDataType::VTYPE_VOID: 1.773 + case nsIDataType::VTYPE_EMPTY: 1.774 + outString.Truncate(); 1.775 + outString.SetIsVoid(true); 1.776 + return NS_OK; 1.777 + 1.778 + case nsIDataType::VTYPE_EMPTY_ARRAY: 1.779 + case nsIDataType::VTYPE_ARRAY: 1.780 + case nsIDataType::VTYPE_INTERFACE: 1.781 + case nsIDataType::VTYPE_INTERFACE_IS: 1.782 + default: 1.783 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.784 + 1.785 + // nsID has its own text formatter. 1.786 + 1.787 + case nsIDataType::VTYPE_ID: 1.788 + ptr = data.u.mIDValue.ToString(); 1.789 + if(!ptr) 1.790 + return NS_ERROR_OUT_OF_MEMORY; 1.791 + outString.Assign(ptr); 1.792 + nsMemory::Free(ptr); 1.793 + return NS_OK; 1.794 + 1.795 + // Can't use PR_smprintf for floats, since it's locale-dependent 1.796 +#define CASE__APPENDFLOAT_NUMBER(type_, member_) \ 1.797 + case nsIDataType :: type_ : \ 1.798 + { \ 1.799 + nsAutoCString str; \ 1.800 + str.AppendFloat(data.u. member_); \ 1.801 + outString.Assign(str); \ 1.802 + return NS_OK; \ 1.803 + } 1.804 + 1.805 + CASE__APPENDFLOAT_NUMBER(VTYPE_FLOAT, mFloatValue) 1.806 + CASE__APPENDFLOAT_NUMBER(VTYPE_DOUBLE, mDoubleValue) 1.807 + 1.808 +#undef CASE__APPENDFLOAT_NUMBER 1.809 + 1.810 + // the rest can be PR_smprintf'd and use common code. 1.811 + 1.812 +#define CASE__SMPRINTF_NUMBER(type_, format_, cast_, member_) \ 1.813 + case nsIDataType :: type_ : \ 1.814 + ptr = PR_smprintf( format_ , (cast_) data.u. member_ ); \ 1.815 + break; 1.816 + 1.817 + CASE__SMPRINTF_NUMBER(VTYPE_INT8, "%d", int, mInt8Value) 1.818 + CASE__SMPRINTF_NUMBER(VTYPE_INT16, "%d", int, mInt16Value) 1.819 + CASE__SMPRINTF_NUMBER(VTYPE_INT32, "%d", int, mInt32Value) 1.820 + CASE__SMPRINTF_NUMBER(VTYPE_INT64, "%lld", int64_t, mInt64Value) 1.821 + 1.822 + CASE__SMPRINTF_NUMBER(VTYPE_UINT8, "%u", unsigned, mUint8Value) 1.823 + CASE__SMPRINTF_NUMBER(VTYPE_UINT16, "%u", unsigned, mUint16Value) 1.824 + CASE__SMPRINTF_NUMBER(VTYPE_UINT32, "%u", unsigned, mUint32Value) 1.825 + CASE__SMPRINTF_NUMBER(VTYPE_UINT64, "%llu", int64_t, mUint64Value) 1.826 + 1.827 + // XXX Would we rather print "true" / "false" ? 1.828 + CASE__SMPRINTF_NUMBER(VTYPE_BOOL, "%d", int, mBoolValue) 1.829 + 1.830 + CASE__SMPRINTF_NUMBER(VTYPE_CHAR, "%c", char, mCharValue) 1.831 + 1.832 +#undef CASE__SMPRINTF_NUMBER 1.833 + } 1.834 + 1.835 + if(!ptr) 1.836 + return NS_ERROR_OUT_OF_MEMORY; 1.837 + outString.Assign(ptr); 1.838 + PR_smprintf_free(ptr); 1.839 + return NS_OK; 1.840 +} 1.841 + 1.842 +/* static */ nsresult 1.843 +nsVariant::ConvertToAString(const nsDiscriminatedUnion& data, 1.844 + nsAString & _retval) 1.845 +{ 1.846 + switch(data.mType) 1.847 + { 1.848 + case nsIDataType::VTYPE_ASTRING: 1.849 + case nsIDataType::VTYPE_DOMSTRING: 1.850 + _retval.Assign(*data.u.mAStringValue); 1.851 + return NS_OK; 1.852 + case nsIDataType::VTYPE_CSTRING: 1.853 + CopyASCIItoUTF16(*data.u.mCStringValue, _retval); 1.854 + return NS_OK; 1.855 + case nsIDataType::VTYPE_UTF8STRING: 1.856 + CopyUTF8toUTF16(*data.u.mUTF8StringValue, _retval); 1.857 + return NS_OK; 1.858 + case nsIDataType::VTYPE_CHAR_STR: 1.859 + CopyASCIItoUTF16(data.u.str.mStringValue, _retval); 1.860 + return NS_OK; 1.861 + case nsIDataType::VTYPE_WCHAR_STR: 1.862 + _retval.Assign(data.u.wstr.mWStringValue); 1.863 + return NS_OK; 1.864 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.865 + CopyASCIItoUTF16(nsDependentCString(data.u.str.mStringValue, 1.866 + data.u.str.mStringLength), 1.867 + _retval); 1.868 + return NS_OK; 1.869 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.870 + _retval.Assign(data.u.wstr.mWStringValue, data.u.wstr.mWStringLength); 1.871 + return NS_OK; 1.872 + case nsIDataType::VTYPE_WCHAR: 1.873 + _retval.Assign(data.u.mWCharValue); 1.874 + return NS_OK; 1.875 + default: 1.876 + { 1.877 + nsAutoCString tempCString; 1.878 + nsresult rv = ToString(data, tempCString); 1.879 + if(NS_FAILED(rv)) 1.880 + return rv; 1.881 + CopyASCIItoUTF16(tempCString, _retval); 1.882 + return NS_OK; 1.883 + } 1.884 + } 1.885 +} 1.886 + 1.887 +/* static */ nsresult 1.888 +nsVariant::ConvertToACString(const nsDiscriminatedUnion& data, 1.889 + nsACString & _retval) 1.890 +{ 1.891 + switch(data.mType) 1.892 + { 1.893 + case nsIDataType::VTYPE_ASTRING: 1.894 + case nsIDataType::VTYPE_DOMSTRING: 1.895 + LossyCopyUTF16toASCII(*data.u.mAStringValue, _retval); 1.896 + return NS_OK; 1.897 + case nsIDataType::VTYPE_CSTRING: 1.898 + _retval.Assign(*data.u.mCStringValue); 1.899 + return NS_OK; 1.900 + case nsIDataType::VTYPE_UTF8STRING: 1.901 + // XXX This is an extra copy that should be avoided 1.902 + // once Jag lands support for UTF8String and associated 1.903 + // conversion methods. 1.904 + LossyCopyUTF16toASCII(NS_ConvertUTF8toUTF16(*data.u.mUTF8StringValue), 1.905 + _retval); 1.906 + return NS_OK; 1.907 + case nsIDataType::VTYPE_CHAR_STR: 1.908 + _retval.Assign(*data.u.str.mStringValue); 1.909 + return NS_OK; 1.910 + case nsIDataType::VTYPE_WCHAR_STR: 1.911 + LossyCopyUTF16toASCII(nsDependentString(data.u.wstr.mWStringValue), 1.912 + _retval); 1.913 + return NS_OK; 1.914 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.915 + _retval.Assign(data.u.str.mStringValue, data.u.str.mStringLength); 1.916 + return NS_OK; 1.917 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.918 + LossyCopyUTF16toASCII(nsDependentString(data.u.wstr.mWStringValue, 1.919 + data.u.wstr.mWStringLength), _retval); 1.920 + return NS_OK; 1.921 + case nsIDataType::VTYPE_WCHAR: 1.922 + { 1.923 + const char16_t* str = &data.u.mWCharValue; 1.924 + LossyCopyUTF16toASCII(Substring(str, 1), _retval); 1.925 + return NS_OK; 1.926 + } 1.927 + default: 1.928 + return ToString(data, _retval); 1.929 + } 1.930 +} 1.931 + 1.932 +/* static */ nsresult 1.933 +nsVariant::ConvertToAUTF8String(const nsDiscriminatedUnion& data, 1.934 + nsAUTF8String & _retval) 1.935 +{ 1.936 + switch(data.mType) 1.937 + { 1.938 + case nsIDataType::VTYPE_ASTRING: 1.939 + case nsIDataType::VTYPE_DOMSTRING: 1.940 + CopyUTF16toUTF8(*data.u.mAStringValue, _retval); 1.941 + return NS_OK; 1.942 + case nsIDataType::VTYPE_CSTRING: 1.943 + // XXX Extra copy, can be removed if we're sure CSTRING can 1.944 + // only contain ASCII. 1.945 + CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(*data.u.mCStringValue), 1.946 + _retval); 1.947 + return NS_OK; 1.948 + case nsIDataType::VTYPE_UTF8STRING: 1.949 + _retval.Assign(*data.u.mUTF8StringValue); 1.950 + return NS_OK; 1.951 + case nsIDataType::VTYPE_CHAR_STR: 1.952 + // XXX Extra copy, can be removed if we're sure CHAR_STR can 1.953 + // only contain ASCII. 1.954 + CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(data.u.str.mStringValue), 1.955 + _retval); 1.956 + return NS_OK; 1.957 + case nsIDataType::VTYPE_WCHAR_STR: 1.958 + CopyUTF16toUTF8(data.u.wstr.mWStringValue, _retval); 1.959 + return NS_OK; 1.960 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.961 + // XXX Extra copy, can be removed if we're sure CHAR_STR can 1.962 + // only contain ASCII. 1.963 + CopyUTF16toUTF8(NS_ConvertASCIItoUTF16( 1.964 + nsDependentCString(data.u.str.mStringValue, 1.965 + data.u.str.mStringLength)), _retval); 1.966 + return NS_OK; 1.967 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.968 + CopyUTF16toUTF8(nsDependentString(data.u.wstr.mWStringValue, 1.969 + data.u.wstr.mWStringLength), 1.970 + _retval); 1.971 + return NS_OK; 1.972 + case nsIDataType::VTYPE_WCHAR: 1.973 + { 1.974 + const char16_t* str = &data.u.mWCharValue; 1.975 + CopyUTF16toUTF8(Substring(str, 1), _retval); 1.976 + return NS_OK; 1.977 + } 1.978 + default: 1.979 + { 1.980 + nsAutoCString tempCString; 1.981 + nsresult rv = ToString(data, tempCString); 1.982 + if(NS_FAILED(rv)) 1.983 + return rv; 1.984 + // XXX Extra copy, can be removed if we're sure tempCString can 1.985 + // only contain ASCII. 1.986 + CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(tempCString), _retval); 1.987 + return NS_OK; 1.988 + } 1.989 + } 1.990 +} 1.991 + 1.992 +/* static */ nsresult 1.993 +nsVariant::ConvertToString(const nsDiscriminatedUnion& data, char **_retval) 1.994 +{ 1.995 + uint32_t ignored; 1.996 + return nsVariant::ConvertToStringWithSize(data, &ignored, _retval); 1.997 +} 1.998 + 1.999 +/* static */ nsresult 1.1000 +nsVariant::ConvertToWString(const nsDiscriminatedUnion& data, char16_t **_retval) 1.1001 +{ 1.1002 + uint32_t ignored; 1.1003 + return nsVariant::ConvertToWStringWithSize(data, &ignored, _retval); 1.1004 +} 1.1005 + 1.1006 +/* static */ nsresult 1.1007 +nsVariant::ConvertToStringWithSize(const nsDiscriminatedUnion& data, 1.1008 + uint32_t *size, char **str) 1.1009 +{ 1.1010 + nsAutoString tempString; 1.1011 + nsAutoCString tempCString; 1.1012 + nsresult rv; 1.1013 + 1.1014 + switch(data.mType) 1.1015 + { 1.1016 + case nsIDataType::VTYPE_ASTRING: 1.1017 + case nsIDataType::VTYPE_DOMSTRING: 1.1018 + *size = data.u.mAStringValue->Length(); 1.1019 + *str = ToNewCString(*data.u.mAStringValue); 1.1020 + break; 1.1021 + case nsIDataType::VTYPE_CSTRING: 1.1022 + *size = data.u.mCStringValue->Length(); 1.1023 + *str = ToNewCString(*data.u.mCStringValue); 1.1024 + break; 1.1025 + case nsIDataType::VTYPE_UTF8STRING: 1.1026 + { 1.1027 + // XXX This is doing 1 extra copy. Need to fix this 1.1028 + // when Jag lands UTF8String 1.1029 + // we want: 1.1030 + // *size = *data.mUTF8StringValue->Length(); 1.1031 + // *str = ToNewCString(*data.mUTF8StringValue); 1.1032 + // But this will have to do for now. 1.1033 + NS_ConvertUTF8toUTF16 tempString(*data.u.mUTF8StringValue); 1.1034 + *size = tempString.Length(); 1.1035 + *str = ToNewCString(tempString); 1.1036 + break; 1.1037 + } 1.1038 + case nsIDataType::VTYPE_CHAR_STR: 1.1039 + { 1.1040 + nsDependentCString cString(data.u.str.mStringValue); 1.1041 + *size = cString.Length(); 1.1042 + *str = ToNewCString(cString); 1.1043 + break; 1.1044 + } 1.1045 + case nsIDataType::VTYPE_WCHAR_STR: 1.1046 + { 1.1047 + nsDependentString string(data.u.wstr.mWStringValue); 1.1048 + *size = string.Length(); 1.1049 + *str = ToNewCString(string); 1.1050 + break; 1.1051 + } 1.1052 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.1053 + { 1.1054 + nsDependentCString cString(data.u.str.mStringValue, 1.1055 + data.u.str.mStringLength); 1.1056 + *size = cString.Length(); 1.1057 + *str = ToNewCString(cString); 1.1058 + break; 1.1059 + } 1.1060 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.1061 + { 1.1062 + nsDependentString string(data.u.wstr.mWStringValue, 1.1063 + data.u.wstr.mWStringLength); 1.1064 + *size = string.Length(); 1.1065 + *str = ToNewCString(string); 1.1066 + break; 1.1067 + } 1.1068 + case nsIDataType::VTYPE_WCHAR: 1.1069 + tempString.Assign(data.u.mWCharValue); 1.1070 + *size = tempString.Length(); 1.1071 + *str = ToNewCString(tempString); 1.1072 + break; 1.1073 + default: 1.1074 + rv = ToString(data, tempCString); 1.1075 + if(NS_FAILED(rv)) 1.1076 + return rv; 1.1077 + *size = tempCString.Length(); 1.1078 + *str = ToNewCString(tempCString); 1.1079 + break; 1.1080 + } 1.1081 + 1.1082 + return *str ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.1083 +} 1.1084 +/* static */ nsresult 1.1085 +nsVariant::ConvertToWStringWithSize(const nsDiscriminatedUnion& data, 1.1086 + uint32_t *size, char16_t **str) 1.1087 +{ 1.1088 + nsAutoString tempString; 1.1089 + nsAutoCString tempCString; 1.1090 + nsresult rv; 1.1091 + 1.1092 + switch(data.mType) 1.1093 + { 1.1094 + case nsIDataType::VTYPE_ASTRING: 1.1095 + case nsIDataType::VTYPE_DOMSTRING: 1.1096 + *size = data.u.mAStringValue->Length(); 1.1097 + *str = ToNewUnicode(*data.u.mAStringValue); 1.1098 + break; 1.1099 + case nsIDataType::VTYPE_CSTRING: 1.1100 + *size = data.u.mCStringValue->Length(); 1.1101 + *str = ToNewUnicode(*data.u.mCStringValue); 1.1102 + break; 1.1103 + case nsIDataType::VTYPE_UTF8STRING: 1.1104 + { 1.1105 + *str = UTF8ToNewUnicode(*data.u.mUTF8StringValue, size); 1.1106 + break; 1.1107 + } 1.1108 + case nsIDataType::VTYPE_CHAR_STR: 1.1109 + { 1.1110 + nsDependentCString cString(data.u.str.mStringValue); 1.1111 + *size = cString.Length(); 1.1112 + *str = ToNewUnicode(cString); 1.1113 + break; 1.1114 + } 1.1115 + case nsIDataType::VTYPE_WCHAR_STR: 1.1116 + { 1.1117 + nsDependentString string(data.u.wstr.mWStringValue); 1.1118 + *size = string.Length(); 1.1119 + *str = ToNewUnicode(string); 1.1120 + break; 1.1121 + } 1.1122 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.1123 + { 1.1124 + nsDependentCString cString(data.u.str.mStringValue, 1.1125 + data.u.str.mStringLength); 1.1126 + *size = cString.Length(); 1.1127 + *str = ToNewUnicode(cString); 1.1128 + break; 1.1129 + } 1.1130 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.1131 + { 1.1132 + nsDependentString string(data.u.wstr.mWStringValue, 1.1133 + data.u.wstr.mWStringLength); 1.1134 + *size = string.Length(); 1.1135 + *str = ToNewUnicode(string); 1.1136 + break; 1.1137 + } 1.1138 + case nsIDataType::VTYPE_WCHAR: 1.1139 + tempString.Assign(data.u.mWCharValue); 1.1140 + *size = tempString.Length(); 1.1141 + *str = ToNewUnicode(tempString); 1.1142 + break; 1.1143 + default: 1.1144 + rv = ToString(data, tempCString); 1.1145 + if(NS_FAILED(rv)) 1.1146 + return rv; 1.1147 + *size = tempCString.Length(); 1.1148 + *str = ToNewUnicode(tempCString); 1.1149 + break; 1.1150 + } 1.1151 + 1.1152 + return *str ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.1153 +} 1.1154 + 1.1155 +/* static */ nsresult 1.1156 +nsVariant::ConvertToISupports(const nsDiscriminatedUnion& data, 1.1157 + nsISupports **_retval) 1.1158 +{ 1.1159 + switch(data.mType) 1.1160 + { 1.1161 + case nsIDataType::VTYPE_INTERFACE: 1.1162 + case nsIDataType::VTYPE_INTERFACE_IS: 1.1163 + if (data.u.iface.mInterfaceValue) { 1.1164 + return data.u.iface.mInterfaceValue-> 1.1165 + QueryInterface(NS_GET_IID(nsISupports), (void**)_retval); 1.1166 + } else { 1.1167 + *_retval = nullptr; 1.1168 + return NS_OK; 1.1169 + } 1.1170 + default: 1.1171 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.1172 + } 1.1173 +} 1.1174 + 1.1175 +/* static */ nsresult 1.1176 +nsVariant::ConvertToInterface(const nsDiscriminatedUnion& data, nsIID * *iid, 1.1177 + void * *iface) 1.1178 +{ 1.1179 + const nsIID* piid; 1.1180 + 1.1181 + switch(data.mType) 1.1182 + { 1.1183 + case nsIDataType::VTYPE_INTERFACE: 1.1184 + piid = &NS_GET_IID(nsISupports); 1.1185 + break; 1.1186 + case nsIDataType::VTYPE_INTERFACE_IS: 1.1187 + piid = &data.u.iface.mInterfaceID; 1.1188 + break; 1.1189 + default: 1.1190 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.1191 + } 1.1192 + 1.1193 + *iid = (nsIID*) nsMemory::Clone(piid, sizeof(nsIID)); 1.1194 + if(!*iid) 1.1195 + return NS_ERROR_OUT_OF_MEMORY; 1.1196 + 1.1197 + if (data.u.iface.mInterfaceValue) { 1.1198 + return data.u.iface.mInterfaceValue->QueryInterface(*piid, iface); 1.1199 + } 1.1200 + 1.1201 + *iface = nullptr; 1.1202 + return NS_OK; 1.1203 +} 1.1204 + 1.1205 +/* static */ nsresult 1.1206 +nsVariant::ConvertToArray(const nsDiscriminatedUnion& data, uint16_t *type, 1.1207 + nsIID* iid, uint32_t *count, void * *ptr) 1.1208 +{ 1.1209 + // XXX perhaps we'd like to add support for converting each of the various 1.1210 + // types into an array containing one element of that type. We can leverage 1.1211 + // CloneArray to do this if we want to support this. 1.1212 + 1.1213 + if(data.mType == nsIDataType::VTYPE_ARRAY) 1.1214 + return CloneArray(data.u.array.mArrayType, &data.u.array.mArrayInterfaceID, 1.1215 + data.u.array.mArrayCount, data.u.array.mArrayValue, 1.1216 + type, iid, count, ptr); 1.1217 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.1218 +} 1.1219 + 1.1220 +/***************************************************************************/ 1.1221 +// static setter functions... 1.1222 + 1.1223 +#define DATA_SETTER_PROLOGUE(data_) \ 1.1224 + nsVariant::Cleanup(data_); 1.1225 + 1.1226 +#define DATA_SETTER_EPILOGUE(data_, type_) \ 1.1227 + data_->mType = nsIDataType :: type_; \ 1.1228 + return NS_OK; 1.1229 + 1.1230 +#define DATA_SETTER(data_, type_, member_, value_) \ 1.1231 + DATA_SETTER_PROLOGUE(data_) \ 1.1232 + data_->u.member_ = value_; \ 1.1233 + DATA_SETTER_EPILOGUE(data_, type_) 1.1234 + 1.1235 +#define DATA_SETTER_WITH_CAST(data_, type_, member_, cast_, value_) \ 1.1236 + DATA_SETTER_PROLOGUE(data_) \ 1.1237 + data_->u.member_ = cast_ value_; \ 1.1238 + DATA_SETTER_EPILOGUE(data_, type_) 1.1239 + 1.1240 + 1.1241 +/********************************************/ 1.1242 + 1.1243 +#define CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \ 1.1244 + { \ 1.1245 + 1.1246 +#define CASE__SET_FROM_VARIANT_VTYPE__GETTER(member_, name_) \ 1.1247 + rv = aValue->GetAs##name_ (&(data->u. member_ )); 1.1248 + 1.1249 +#define CASE__SET_FROM_VARIANT_VTYPE__GETTER_CAST(cast_, member_, name_) \ 1.1250 + rv = aValue->GetAs##name_ ( cast_ &(data->u. member_ )); 1.1251 + 1.1252 +#define CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_) \ 1.1253 + if(NS_SUCCEEDED(rv)) \ 1.1254 + { \ 1.1255 + data->mType = nsIDataType :: type_ ; \ 1.1256 + } \ 1.1257 + break; \ 1.1258 + } 1.1259 + 1.1260 +#define CASE__SET_FROM_VARIANT_TYPE(type_, member_, name_) \ 1.1261 + case nsIDataType :: type_ : \ 1.1262 + CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \ 1.1263 + CASE__SET_FROM_VARIANT_VTYPE__GETTER(member_, name_) \ 1.1264 + CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_) 1.1265 + 1.1266 +#define CASE__SET_FROM_VARIANT_VTYPE_CAST(type_, cast_, member_, name_) \ 1.1267 + case nsIDataType :: type_ : \ 1.1268 + CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \ 1.1269 + CASE__SET_FROM_VARIANT_VTYPE__GETTER_CAST(cast_, member_, name_) \ 1.1270 + CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_) 1.1271 + 1.1272 + 1.1273 +/* static */ nsresult 1.1274 +nsVariant::SetFromVariant(nsDiscriminatedUnion* data, nsIVariant* aValue) 1.1275 +{ 1.1276 + uint16_t type; 1.1277 + nsresult rv; 1.1278 + 1.1279 + nsVariant::Cleanup(data); 1.1280 + 1.1281 + rv = aValue->GetDataType(&type); 1.1282 + if(NS_FAILED(rv)) 1.1283 + return rv; 1.1284 + 1.1285 + switch(type) 1.1286 + { 1.1287 + CASE__SET_FROM_VARIANT_VTYPE_CAST(VTYPE_INT8, (uint8_t*), mInt8Value, 1.1288 + Int8) 1.1289 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_INT16, mInt16Value, Int16) 1.1290 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_INT32, mInt32Value, Int32) 1.1291 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT8, mUint8Value, Uint8) 1.1292 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT16, mUint16Value, Uint16) 1.1293 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT32, mUint32Value, Uint32) 1.1294 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_FLOAT, mFloatValue, Float) 1.1295 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_DOUBLE, mDoubleValue, Double) 1.1296 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_BOOL , mBoolValue, Bool) 1.1297 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_CHAR, mCharValue, Char) 1.1298 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_WCHAR, mWCharValue, WChar) 1.1299 + CASE__SET_FROM_VARIANT_TYPE(VTYPE_ID, mIDValue, ID) 1.1300 + 1.1301 + case nsIDataType::VTYPE_ASTRING: 1.1302 + case nsIDataType::VTYPE_DOMSTRING: 1.1303 + case nsIDataType::VTYPE_WCHAR_STR: 1.1304 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.1305 + CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_ASTRING); 1.1306 + data->u.mAStringValue = new nsString(); 1.1307 + if(!data->u.mAStringValue) 1.1308 + return NS_ERROR_OUT_OF_MEMORY; 1.1309 + rv = aValue->GetAsAString(*data->u.mAStringValue); 1.1310 + if(NS_FAILED(rv)) 1.1311 + delete data->u.mAStringValue; 1.1312 + CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_ASTRING) 1.1313 + 1.1314 + case nsIDataType::VTYPE_CSTRING: 1.1315 + CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_CSTRING); 1.1316 + data->u.mCStringValue = new nsCString(); 1.1317 + if(!data->u.mCStringValue) 1.1318 + return NS_ERROR_OUT_OF_MEMORY; 1.1319 + rv = aValue->GetAsACString(*data->u.mCStringValue); 1.1320 + if(NS_FAILED(rv)) 1.1321 + delete data->u.mCStringValue; 1.1322 + CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_CSTRING) 1.1323 + 1.1324 + case nsIDataType::VTYPE_UTF8STRING: 1.1325 + CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_UTF8STRING); 1.1326 + data->u.mUTF8StringValue = new nsUTF8String(); 1.1327 + if(!data->u.mUTF8StringValue) 1.1328 + return NS_ERROR_OUT_OF_MEMORY; 1.1329 + rv = aValue->GetAsAUTF8String(*data->u.mUTF8StringValue); 1.1330 + if(NS_FAILED(rv)) 1.1331 + delete data->u.mUTF8StringValue; 1.1332 + CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_UTF8STRING) 1.1333 + 1.1334 + case nsIDataType::VTYPE_CHAR_STR: 1.1335 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.1336 + CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_STRING_SIZE_IS); 1.1337 + rv = aValue->GetAsStringWithSize(&data->u.str.mStringLength, 1.1338 + &data->u.str.mStringValue); 1.1339 + CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_STRING_SIZE_IS) 1.1340 + 1.1341 + case nsIDataType::VTYPE_INTERFACE: 1.1342 + case nsIDataType::VTYPE_INTERFACE_IS: 1.1343 + CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_INTERFACE_IS); 1.1344 + // XXX This iid handling is ugly! 1.1345 + nsIID* iid; 1.1346 + rv = aValue->GetAsInterface(&iid, (void**)&data->u.iface.mInterfaceValue); 1.1347 + if(NS_SUCCEEDED(rv)) 1.1348 + { 1.1349 + data->u.iface.mInterfaceID = *iid; 1.1350 + nsMemory::Free((char*)iid); 1.1351 + } 1.1352 + CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_INTERFACE_IS) 1.1353 + 1.1354 + case nsIDataType::VTYPE_ARRAY: 1.1355 + CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_ARRAY); 1.1356 + rv = aValue->GetAsArray(&data->u.array.mArrayType, 1.1357 + &data->u.array.mArrayInterfaceID, 1.1358 + &data->u.array.mArrayCount, 1.1359 + &data->u.array.mArrayValue); 1.1360 + CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_ARRAY) 1.1361 + 1.1362 + case nsIDataType::VTYPE_VOID: 1.1363 + rv = nsVariant::SetToVoid(data); 1.1364 + break; 1.1365 + case nsIDataType::VTYPE_EMPTY_ARRAY: 1.1366 + rv = nsVariant::SetToEmptyArray(data); 1.1367 + break; 1.1368 + case nsIDataType::VTYPE_EMPTY: 1.1369 + rv = nsVariant::SetToEmpty(data); 1.1370 + break; 1.1371 + default: 1.1372 + NS_ERROR("bad type in variant!"); 1.1373 + rv = NS_ERROR_FAILURE; 1.1374 + break; 1.1375 + } 1.1376 + return rv; 1.1377 +} 1.1378 + 1.1379 +/* static */ nsresult 1.1380 +nsVariant::SetFromInt8(nsDiscriminatedUnion* data, uint8_t aValue) 1.1381 +{ 1.1382 + DATA_SETTER_WITH_CAST(data, VTYPE_INT8, mInt8Value, (uint8_t), aValue) 1.1383 +} 1.1384 +/* static */ nsresult 1.1385 +nsVariant::SetFromInt16(nsDiscriminatedUnion* data, int16_t aValue) 1.1386 +{ 1.1387 + DATA_SETTER(data, VTYPE_INT16, mInt16Value, aValue) 1.1388 +} 1.1389 +/* static */ nsresult 1.1390 +nsVariant::SetFromInt32(nsDiscriminatedUnion* data, int32_t aValue) 1.1391 +{ 1.1392 + DATA_SETTER(data, VTYPE_INT32, mInt32Value, aValue) 1.1393 +} 1.1394 +/* static */ nsresult 1.1395 +nsVariant::SetFromInt64(nsDiscriminatedUnion* data, int64_t aValue) 1.1396 +{ 1.1397 + DATA_SETTER(data, VTYPE_INT64, mInt64Value, aValue) 1.1398 +} 1.1399 +/* static */ nsresult 1.1400 +nsVariant::SetFromUint8(nsDiscriminatedUnion* data, uint8_t aValue) 1.1401 +{ 1.1402 + DATA_SETTER(data, VTYPE_UINT8, mUint8Value, aValue) 1.1403 +} 1.1404 +/* static */ nsresult 1.1405 +nsVariant::SetFromUint16(nsDiscriminatedUnion* data, uint16_t aValue) 1.1406 +{ 1.1407 + DATA_SETTER(data, VTYPE_UINT16, mUint16Value, aValue) 1.1408 +} 1.1409 +/* static */ nsresult 1.1410 +nsVariant::SetFromUint32(nsDiscriminatedUnion* data, uint32_t aValue) 1.1411 +{ 1.1412 + DATA_SETTER(data, VTYPE_UINT32, mUint32Value, aValue) 1.1413 +} 1.1414 +/* static */ nsresult 1.1415 +nsVariant::SetFromUint64(nsDiscriminatedUnion* data, uint64_t aValue) 1.1416 +{ 1.1417 + DATA_SETTER(data, VTYPE_UINT64, mUint64Value, aValue) 1.1418 +} 1.1419 +/* static */ nsresult 1.1420 +nsVariant::SetFromFloat(nsDiscriminatedUnion* data, float aValue) 1.1421 +{ 1.1422 + DATA_SETTER(data, VTYPE_FLOAT, mFloatValue, aValue) 1.1423 +} 1.1424 +/* static */ nsresult 1.1425 +nsVariant::SetFromDouble(nsDiscriminatedUnion* data, double aValue) 1.1426 +{ 1.1427 + DATA_SETTER(data, VTYPE_DOUBLE, mDoubleValue, aValue) 1.1428 +} 1.1429 +/* static */ nsresult 1.1430 +nsVariant::SetFromBool(nsDiscriminatedUnion* data, bool aValue) 1.1431 +{ 1.1432 + DATA_SETTER(data, VTYPE_BOOL, mBoolValue, aValue) 1.1433 +} 1.1434 +/* static */ nsresult 1.1435 +nsVariant::SetFromChar(nsDiscriminatedUnion* data, char aValue) 1.1436 +{ 1.1437 + DATA_SETTER(data, VTYPE_CHAR, mCharValue, aValue) 1.1438 +} 1.1439 +/* static */ nsresult 1.1440 +nsVariant::SetFromWChar(nsDiscriminatedUnion* data, char16_t aValue) 1.1441 +{ 1.1442 + DATA_SETTER(data, VTYPE_WCHAR, mWCharValue, aValue) 1.1443 +} 1.1444 +/* static */ nsresult 1.1445 +nsVariant::SetFromID(nsDiscriminatedUnion* data, const nsID & aValue) 1.1446 +{ 1.1447 + DATA_SETTER(data, VTYPE_ID, mIDValue, aValue) 1.1448 +} 1.1449 +/* static */ nsresult 1.1450 +nsVariant::SetFromAString(nsDiscriminatedUnion* data, const nsAString & aValue) 1.1451 +{ 1.1452 + DATA_SETTER_PROLOGUE(data); 1.1453 + if(!(data->u.mAStringValue = new nsString(aValue))) 1.1454 + return NS_ERROR_OUT_OF_MEMORY; 1.1455 + DATA_SETTER_EPILOGUE(data, VTYPE_ASTRING); 1.1456 +} 1.1457 + 1.1458 +/* static */ nsresult 1.1459 +nsVariant::SetFromACString(nsDiscriminatedUnion* data, 1.1460 + const nsACString & aValue) 1.1461 +{ 1.1462 + DATA_SETTER_PROLOGUE(data); 1.1463 + if(!(data->u.mCStringValue = new nsCString(aValue))) 1.1464 + return NS_ERROR_OUT_OF_MEMORY; 1.1465 + DATA_SETTER_EPILOGUE(data, VTYPE_CSTRING); 1.1466 +} 1.1467 + 1.1468 +/* static */ nsresult 1.1469 +nsVariant::SetFromAUTF8String(nsDiscriminatedUnion* data, 1.1470 + const nsAUTF8String & aValue) 1.1471 +{ 1.1472 + DATA_SETTER_PROLOGUE(data); 1.1473 + if(!(data->u.mUTF8StringValue = new nsUTF8String(aValue))) 1.1474 + return NS_ERROR_OUT_OF_MEMORY; 1.1475 + DATA_SETTER_EPILOGUE(data, VTYPE_UTF8STRING); 1.1476 +} 1.1477 + 1.1478 +/* static */ nsresult 1.1479 +nsVariant::SetFromString(nsDiscriminatedUnion* data, const char *aValue) 1.1480 +{ 1.1481 + DATA_SETTER_PROLOGUE(data); 1.1482 + if(!aValue) 1.1483 + return NS_ERROR_NULL_POINTER; 1.1484 + return SetFromStringWithSize(data, strlen(aValue), aValue); 1.1485 +} 1.1486 +/* static */ nsresult 1.1487 +nsVariant::SetFromWString(nsDiscriminatedUnion* data, const char16_t *aValue) 1.1488 +{ 1.1489 + DATA_SETTER_PROLOGUE(data); 1.1490 + if(!aValue) 1.1491 + return NS_ERROR_NULL_POINTER; 1.1492 + return SetFromWStringWithSize(data, NS_strlen(aValue), aValue); 1.1493 +} 1.1494 +/* static */ nsresult 1.1495 +nsVariant::SetFromISupports(nsDiscriminatedUnion* data, nsISupports *aValue) 1.1496 +{ 1.1497 + return SetFromInterface(data, NS_GET_IID(nsISupports), aValue); 1.1498 +} 1.1499 +/* static */ nsresult 1.1500 +nsVariant::SetFromInterface(nsDiscriminatedUnion* data, const nsIID& iid, 1.1501 + nsISupports *aValue) 1.1502 +{ 1.1503 + DATA_SETTER_PROLOGUE(data); 1.1504 + NS_IF_ADDREF(aValue); 1.1505 + data->u.iface.mInterfaceValue = aValue; 1.1506 + data->u.iface.mInterfaceID = iid; 1.1507 + DATA_SETTER_EPILOGUE(data, VTYPE_INTERFACE_IS); 1.1508 +} 1.1509 +/* static */ nsresult 1.1510 +nsVariant::SetFromArray(nsDiscriminatedUnion* data, uint16_t type, 1.1511 + const nsIID* iid, uint32_t count, void * aValue) 1.1512 +{ 1.1513 + DATA_SETTER_PROLOGUE(data); 1.1514 + if(!aValue || !count) 1.1515 + return NS_ERROR_NULL_POINTER; 1.1516 + 1.1517 + nsresult rv = CloneArray(type, iid, count, aValue, 1.1518 + &data->u.array.mArrayType, 1.1519 + &data->u.array.mArrayInterfaceID, 1.1520 + &data->u.array.mArrayCount, 1.1521 + &data->u.array.mArrayValue); 1.1522 + if(NS_FAILED(rv)) 1.1523 + return rv; 1.1524 + DATA_SETTER_EPILOGUE(data, VTYPE_ARRAY); 1.1525 +} 1.1526 +/* static */ nsresult 1.1527 +nsVariant::SetFromStringWithSize(nsDiscriminatedUnion* data, uint32_t size, const char *aValue) 1.1528 +{ 1.1529 + DATA_SETTER_PROLOGUE(data); 1.1530 + if(!aValue) 1.1531 + return NS_ERROR_NULL_POINTER; 1.1532 + if(!(data->u.str.mStringValue = 1.1533 + (char*) nsMemory::Clone(aValue, (size+1)*sizeof(char)))) 1.1534 + return NS_ERROR_OUT_OF_MEMORY; 1.1535 + data->u.str.mStringLength = size; 1.1536 + DATA_SETTER_EPILOGUE(data, VTYPE_STRING_SIZE_IS); 1.1537 +} 1.1538 +/* static */ nsresult 1.1539 +nsVariant::SetFromWStringWithSize(nsDiscriminatedUnion* data, uint32_t size, const char16_t *aValue) 1.1540 +{ 1.1541 + DATA_SETTER_PROLOGUE(data); 1.1542 + if(!aValue) 1.1543 + return NS_ERROR_NULL_POINTER; 1.1544 + if(!(data->u.wstr.mWStringValue = 1.1545 + (char16_t*) nsMemory::Clone(aValue, (size+1)*sizeof(char16_t)))) 1.1546 + return NS_ERROR_OUT_OF_MEMORY; 1.1547 + data->u.wstr.mWStringLength = size; 1.1548 + DATA_SETTER_EPILOGUE(data, VTYPE_WSTRING_SIZE_IS); 1.1549 +} 1.1550 +/* static */ nsresult 1.1551 +nsVariant::SetToVoid(nsDiscriminatedUnion* data) 1.1552 +{ 1.1553 + DATA_SETTER_PROLOGUE(data); 1.1554 + DATA_SETTER_EPILOGUE(data, VTYPE_VOID); 1.1555 +} 1.1556 +/* static */ nsresult 1.1557 +nsVariant::SetToEmpty(nsDiscriminatedUnion* data) 1.1558 +{ 1.1559 + DATA_SETTER_PROLOGUE(data); 1.1560 + DATA_SETTER_EPILOGUE(data, VTYPE_EMPTY); 1.1561 +} 1.1562 +/* static */ nsresult 1.1563 +nsVariant::SetToEmptyArray(nsDiscriminatedUnion* data) 1.1564 +{ 1.1565 + DATA_SETTER_PROLOGUE(data); 1.1566 + DATA_SETTER_EPILOGUE(data, VTYPE_EMPTY_ARRAY); 1.1567 +} 1.1568 + 1.1569 +/***************************************************************************/ 1.1570 + 1.1571 +/* static */ nsresult 1.1572 +nsVariant::Initialize(nsDiscriminatedUnion* data) 1.1573 +{ 1.1574 + data->mType = nsIDataType::VTYPE_EMPTY; 1.1575 + return NS_OK; 1.1576 +} 1.1577 + 1.1578 +/* static */ nsresult 1.1579 +nsVariant::Cleanup(nsDiscriminatedUnion* data) 1.1580 +{ 1.1581 + switch(data->mType) 1.1582 + { 1.1583 + case nsIDataType::VTYPE_INT8: 1.1584 + case nsIDataType::VTYPE_INT16: 1.1585 + case nsIDataType::VTYPE_INT32: 1.1586 + case nsIDataType::VTYPE_INT64: 1.1587 + case nsIDataType::VTYPE_UINT8: 1.1588 + case nsIDataType::VTYPE_UINT16: 1.1589 + case nsIDataType::VTYPE_UINT32: 1.1590 + case nsIDataType::VTYPE_UINT64: 1.1591 + case nsIDataType::VTYPE_FLOAT: 1.1592 + case nsIDataType::VTYPE_DOUBLE: 1.1593 + case nsIDataType::VTYPE_BOOL: 1.1594 + case nsIDataType::VTYPE_CHAR: 1.1595 + case nsIDataType::VTYPE_WCHAR: 1.1596 + case nsIDataType::VTYPE_VOID: 1.1597 + case nsIDataType::VTYPE_ID: 1.1598 + break; 1.1599 + case nsIDataType::VTYPE_ASTRING: 1.1600 + case nsIDataType::VTYPE_DOMSTRING: 1.1601 + delete data->u.mAStringValue; 1.1602 + break; 1.1603 + case nsIDataType::VTYPE_CSTRING: 1.1604 + delete data->u.mCStringValue; 1.1605 + break; 1.1606 + case nsIDataType::VTYPE_UTF8STRING: 1.1607 + delete data->u.mUTF8StringValue; 1.1608 + break; 1.1609 + case nsIDataType::VTYPE_CHAR_STR: 1.1610 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.1611 + nsMemory::Free((char*)data->u.str.mStringValue); 1.1612 + break; 1.1613 + case nsIDataType::VTYPE_WCHAR_STR: 1.1614 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.1615 + nsMemory::Free((char*)data->u.wstr.mWStringValue); 1.1616 + break; 1.1617 + case nsIDataType::VTYPE_INTERFACE: 1.1618 + case nsIDataType::VTYPE_INTERFACE_IS: 1.1619 + NS_IF_RELEASE(data->u.iface.mInterfaceValue); 1.1620 + break; 1.1621 + case nsIDataType::VTYPE_ARRAY: 1.1622 + FreeArray(data); 1.1623 + break; 1.1624 + case nsIDataType::VTYPE_EMPTY_ARRAY: 1.1625 + case nsIDataType::VTYPE_EMPTY: 1.1626 + break; 1.1627 + default: 1.1628 + NS_ERROR("bad type in variant!"); 1.1629 + break; 1.1630 + } 1.1631 + 1.1632 + data->mType = nsIDataType::VTYPE_EMPTY; 1.1633 + return NS_OK; 1.1634 +} 1.1635 + 1.1636 +/* static */ void 1.1637 +nsVariant::Traverse(const nsDiscriminatedUnion& data, 1.1638 + nsCycleCollectionTraversalCallback &cb) 1.1639 +{ 1.1640 + switch(data.mType) 1.1641 + { 1.1642 + case nsIDataType::VTYPE_INTERFACE: 1.1643 + case nsIDataType::VTYPE_INTERFACE_IS: 1.1644 + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mData"); 1.1645 + cb.NoteXPCOMChild(data.u.iface.mInterfaceValue); 1.1646 + break; 1.1647 + case nsIDataType::VTYPE_ARRAY: 1.1648 + switch(data.u.array.mArrayType) { 1.1649 + case nsIDataType::VTYPE_INTERFACE: 1.1650 + case nsIDataType::VTYPE_INTERFACE_IS: 1.1651 + { 1.1652 + nsISupports** p = (nsISupports**) data.u.array.mArrayValue; 1.1653 + for(uint32_t i = data.u.array.mArrayCount; i > 0; p++, i--) { 1.1654 + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mData[i]"); 1.1655 + cb.NoteXPCOMChild(*p); 1.1656 + } 1.1657 + } 1.1658 + default: 1.1659 + break; 1.1660 + } 1.1661 + default: 1.1662 + break; 1.1663 + } 1.1664 +} 1.1665 + 1.1666 +/***************************************************************************/ 1.1667 +/***************************************************************************/ 1.1668 +// members... 1.1669 + 1.1670 +NS_IMPL_ISUPPORTS(nsVariant, nsIVariant, nsIWritableVariant) 1.1671 + 1.1672 +nsVariant::nsVariant() 1.1673 + : mWritable(true) 1.1674 +{ 1.1675 + nsVariant::Initialize(&mData); 1.1676 + 1.1677 +#ifdef DEBUG 1.1678 + { 1.1679 + // Assert that the nsIDataType consts match the values #defined in 1.1680 + // xpt_struct.h. Bad things happen somewhere if they don't. 1.1681 + struct THE_TYPES {uint16_t a; uint16_t b;}; 1.1682 + static const THE_TYPES array[] = { 1.1683 + {nsIDataType::VTYPE_INT8 , TD_INT8 }, 1.1684 + {nsIDataType::VTYPE_INT16 , TD_INT16 }, 1.1685 + {nsIDataType::VTYPE_INT32 , TD_INT32 }, 1.1686 + {nsIDataType::VTYPE_INT64 , TD_INT64 }, 1.1687 + {nsIDataType::VTYPE_UINT8 , TD_UINT8 }, 1.1688 + {nsIDataType::VTYPE_UINT16 , TD_UINT16 }, 1.1689 + {nsIDataType::VTYPE_UINT32 , TD_UINT32 }, 1.1690 + {nsIDataType::VTYPE_UINT64 , TD_UINT64 }, 1.1691 + {nsIDataType::VTYPE_FLOAT , TD_FLOAT }, 1.1692 + {nsIDataType::VTYPE_DOUBLE , TD_DOUBLE }, 1.1693 + {nsIDataType::VTYPE_BOOL , TD_BOOL }, 1.1694 + {nsIDataType::VTYPE_CHAR , TD_CHAR }, 1.1695 + {nsIDataType::VTYPE_WCHAR , TD_WCHAR }, 1.1696 + {nsIDataType::VTYPE_VOID , TD_VOID }, 1.1697 + {nsIDataType::VTYPE_ID , TD_PNSIID }, 1.1698 + {nsIDataType::VTYPE_DOMSTRING , TD_DOMSTRING }, 1.1699 + {nsIDataType::VTYPE_CHAR_STR , TD_PSTRING }, 1.1700 + {nsIDataType::VTYPE_WCHAR_STR , TD_PWSTRING }, 1.1701 + {nsIDataType::VTYPE_INTERFACE , TD_INTERFACE_TYPE }, 1.1702 + {nsIDataType::VTYPE_INTERFACE_IS , TD_INTERFACE_IS_TYPE}, 1.1703 + {nsIDataType::VTYPE_ARRAY , TD_ARRAY }, 1.1704 + {nsIDataType::VTYPE_STRING_SIZE_IS , TD_PSTRING_SIZE_IS }, 1.1705 + {nsIDataType::VTYPE_WSTRING_SIZE_IS , TD_PWSTRING_SIZE_IS }, 1.1706 + {nsIDataType::VTYPE_UTF8STRING , TD_UTF8STRING }, 1.1707 + {nsIDataType::VTYPE_CSTRING , TD_CSTRING }, 1.1708 + {nsIDataType::VTYPE_ASTRING , TD_ASTRING } 1.1709 + }; 1.1710 + static const int length = sizeof(array)/sizeof(array[0]); 1.1711 + static bool inited = false; 1.1712 + if(!inited) 1.1713 + { 1.1714 + for(int i = 0; i < length; i++) 1.1715 + NS_ASSERTION(array[i].a == array[i].b, "bad const declaration"); 1.1716 + inited = true; 1.1717 + } 1.1718 + } 1.1719 +#endif 1.1720 +} 1.1721 + 1.1722 +nsVariant::~nsVariant() 1.1723 +{ 1.1724 + nsVariant::Cleanup(&mData); 1.1725 +} 1.1726 + 1.1727 +// For all the data getters we just forward to the static (and sharable) 1.1728 +// 'ConvertTo' functions. 1.1729 + 1.1730 +/* readonly attribute uint16_t dataType; */ 1.1731 +NS_IMETHODIMP nsVariant::GetDataType(uint16_t *aDataType) 1.1732 +{ 1.1733 + *aDataType = mData.mType; 1.1734 + return NS_OK; 1.1735 +} 1.1736 + 1.1737 +/* uint8_t getAsInt8 (); */ 1.1738 +NS_IMETHODIMP nsVariant::GetAsInt8(uint8_t *_retval) 1.1739 +{ 1.1740 + return nsVariant::ConvertToInt8(mData, _retval); 1.1741 +} 1.1742 + 1.1743 +/* int16_t getAsInt16 (); */ 1.1744 +NS_IMETHODIMP nsVariant::GetAsInt16(int16_t *_retval) 1.1745 +{ 1.1746 + return nsVariant::ConvertToInt16(mData, _retval); 1.1747 +} 1.1748 + 1.1749 +/* int32_t getAsInt32 (); */ 1.1750 +NS_IMETHODIMP nsVariant::GetAsInt32(int32_t *_retval) 1.1751 +{ 1.1752 + return nsVariant::ConvertToInt32(mData, _retval); 1.1753 +} 1.1754 + 1.1755 +/* int64_t getAsInt64 (); */ 1.1756 +NS_IMETHODIMP nsVariant::GetAsInt64(int64_t *_retval) 1.1757 +{ 1.1758 + return nsVariant::ConvertToInt64(mData, _retval); 1.1759 +} 1.1760 + 1.1761 +/* uint8_t getAsUint8 (); */ 1.1762 +NS_IMETHODIMP nsVariant::GetAsUint8(uint8_t *_retval) 1.1763 +{ 1.1764 + return nsVariant::ConvertToUint8(mData, _retval); 1.1765 +} 1.1766 + 1.1767 +/* uint16_t getAsUint16 (); */ 1.1768 +NS_IMETHODIMP nsVariant::GetAsUint16(uint16_t *_retval) 1.1769 +{ 1.1770 + return nsVariant::ConvertToUint16(mData, _retval); 1.1771 +} 1.1772 + 1.1773 +/* uint32_t getAsUint32 (); */ 1.1774 +NS_IMETHODIMP nsVariant::GetAsUint32(uint32_t *_retval) 1.1775 +{ 1.1776 + return nsVariant::ConvertToUint32(mData, _retval); 1.1777 +} 1.1778 + 1.1779 +/* uint64_t getAsUint64 (); */ 1.1780 +NS_IMETHODIMP nsVariant::GetAsUint64(uint64_t *_retval) 1.1781 +{ 1.1782 + return nsVariant::ConvertToUint64(mData, _retval); 1.1783 +} 1.1784 + 1.1785 +/* float getAsFloat (); */ 1.1786 +NS_IMETHODIMP nsVariant::GetAsFloat(float *_retval) 1.1787 +{ 1.1788 + return nsVariant::ConvertToFloat(mData, _retval); 1.1789 +} 1.1790 + 1.1791 +/* double getAsDouble (); */ 1.1792 +NS_IMETHODIMP nsVariant::GetAsDouble(double *_retval) 1.1793 +{ 1.1794 + return nsVariant::ConvertToDouble(mData, _retval); 1.1795 +} 1.1796 + 1.1797 +/* bool getAsBool (); */ 1.1798 +NS_IMETHODIMP nsVariant::GetAsBool(bool *_retval) 1.1799 +{ 1.1800 + return nsVariant::ConvertToBool(mData, _retval); 1.1801 +} 1.1802 + 1.1803 +/* char getAsChar (); */ 1.1804 +NS_IMETHODIMP nsVariant::GetAsChar(char *_retval) 1.1805 +{ 1.1806 + return nsVariant::ConvertToChar(mData, _retval); 1.1807 +} 1.1808 + 1.1809 +/* wchar getAsWChar (); */ 1.1810 +NS_IMETHODIMP nsVariant::GetAsWChar(char16_t *_retval) 1.1811 +{ 1.1812 + return nsVariant::ConvertToWChar(mData, _retval); 1.1813 +} 1.1814 + 1.1815 +/* [notxpcom] nsresult getAsID (out nsID retval); */ 1.1816 +NS_IMETHODIMP_(nsresult) nsVariant::GetAsID(nsID *retval) 1.1817 +{ 1.1818 + return nsVariant::ConvertToID(mData, retval); 1.1819 +} 1.1820 + 1.1821 +/* AString getAsAString (); */ 1.1822 +NS_IMETHODIMP nsVariant::GetAsAString(nsAString & _retval) 1.1823 +{ 1.1824 + return nsVariant::ConvertToAString(mData, _retval); 1.1825 +} 1.1826 + 1.1827 +/* DOMString getAsDOMString (); */ 1.1828 +NS_IMETHODIMP nsVariant::GetAsDOMString(nsAString & _retval) 1.1829 +{ 1.1830 + // A DOMString maps to an AString internally, so we can re-use 1.1831 + // ConvertToAString here. 1.1832 + return nsVariant::ConvertToAString(mData, _retval); 1.1833 +} 1.1834 + 1.1835 +/* ACString getAsACString (); */ 1.1836 +NS_IMETHODIMP nsVariant::GetAsACString(nsACString & _retval) 1.1837 +{ 1.1838 + return nsVariant::ConvertToACString(mData, _retval); 1.1839 +} 1.1840 + 1.1841 +/* AUTF8String getAsAUTF8String (); */ 1.1842 +NS_IMETHODIMP nsVariant::GetAsAUTF8String(nsAUTF8String & _retval) 1.1843 +{ 1.1844 + return nsVariant::ConvertToAUTF8String(mData, _retval); 1.1845 +} 1.1846 + 1.1847 +/* string getAsString (); */ 1.1848 +NS_IMETHODIMP nsVariant::GetAsString(char **_retval) 1.1849 +{ 1.1850 + return nsVariant::ConvertToString(mData, _retval); 1.1851 +} 1.1852 + 1.1853 +/* wstring getAsWString (); */ 1.1854 +NS_IMETHODIMP nsVariant::GetAsWString(char16_t **_retval) 1.1855 +{ 1.1856 + return nsVariant::ConvertToWString(mData, _retval); 1.1857 +} 1.1858 + 1.1859 +/* nsISupports getAsISupports (); */ 1.1860 +NS_IMETHODIMP nsVariant::GetAsISupports(nsISupports **_retval) 1.1861 +{ 1.1862 + return nsVariant::ConvertToISupports(mData, _retval); 1.1863 +} 1.1864 + 1.1865 +/* jsval getAsJSVal() */ 1.1866 +NS_IMETHODIMP nsVariant::GetAsJSVal(JS::MutableHandleValue) 1.1867 +{ 1.1868 + // Can only get the jsval from an XPCVariant. 1.1869 + return NS_ERROR_CANNOT_CONVERT_DATA; 1.1870 +} 1.1871 + 1.1872 +/* void getAsInterface (out nsIIDPtr iid, [iid_is (iid), retval] out nsQIResult iface); */ 1.1873 +NS_IMETHODIMP nsVariant::GetAsInterface(nsIID * *iid, void * *iface) 1.1874 +{ 1.1875 + return nsVariant::ConvertToInterface(mData, iid, iface); 1.1876 +} 1.1877 + 1.1878 +/* [notxpcom] nsresult getAsArray (out uint16_t type, out nsIID iid, out uint32_t count, out voidPtr ptr); */ 1.1879 +NS_IMETHODIMP_(nsresult) nsVariant::GetAsArray(uint16_t *type, nsIID *iid, uint32_t *count, void * *ptr) 1.1880 +{ 1.1881 + return nsVariant::ConvertToArray(mData, type, iid, count, ptr); 1.1882 +} 1.1883 + 1.1884 +/* void getAsStringWithSize (out uint32_t size, [size_is (size), retval] out string str); */ 1.1885 +NS_IMETHODIMP nsVariant::GetAsStringWithSize(uint32_t *size, char **str) 1.1886 +{ 1.1887 + return nsVariant::ConvertToStringWithSize(mData, size, str); 1.1888 +} 1.1889 + 1.1890 +/* void getAsWStringWithSize (out uint32_t size, [size_is (size), retval] out wstring str); */ 1.1891 +NS_IMETHODIMP nsVariant::GetAsWStringWithSize(uint32_t *size, char16_t **str) 1.1892 +{ 1.1893 + return nsVariant::ConvertToWStringWithSize(mData, size, str); 1.1894 +} 1.1895 + 1.1896 +/***************************************************************************/ 1.1897 + 1.1898 +/* attribute bool writable; */ 1.1899 +NS_IMETHODIMP nsVariant::GetWritable(bool *aWritable) 1.1900 +{ 1.1901 + *aWritable = mWritable; 1.1902 + return NS_OK; 1.1903 +} 1.1904 +NS_IMETHODIMP nsVariant::SetWritable(bool aWritable) 1.1905 +{ 1.1906 + if(!mWritable && aWritable) 1.1907 + return NS_ERROR_FAILURE; 1.1908 + mWritable = aWritable; 1.1909 + return NS_OK; 1.1910 +} 1.1911 + 1.1912 +/***************************************************************************/ 1.1913 + 1.1914 +// For all the data setters we just forward to the static (and sharable) 1.1915 +// 'SetFrom' functions. 1.1916 + 1.1917 +/* void setAsInt8 (in uint8_t aValue); */ 1.1918 +NS_IMETHODIMP nsVariant::SetAsInt8(uint8_t aValue) 1.1919 +{ 1.1920 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1921 + return nsVariant::SetFromInt8(&mData, aValue); 1.1922 +} 1.1923 + 1.1924 +/* void setAsInt16 (in int16_t aValue); */ 1.1925 +NS_IMETHODIMP nsVariant::SetAsInt16(int16_t aValue) 1.1926 +{ 1.1927 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1928 + return nsVariant::SetFromInt16(&mData, aValue); 1.1929 +} 1.1930 + 1.1931 +/* void setAsInt32 (in int32_t aValue); */ 1.1932 +NS_IMETHODIMP nsVariant::SetAsInt32(int32_t aValue) 1.1933 +{ 1.1934 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1935 + return nsVariant::SetFromInt32(&mData, aValue); 1.1936 +} 1.1937 + 1.1938 +/* void setAsInt64 (in int64_t aValue); */ 1.1939 +NS_IMETHODIMP nsVariant::SetAsInt64(int64_t aValue) 1.1940 +{ 1.1941 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1942 + return nsVariant::SetFromInt64(&mData, aValue); 1.1943 +} 1.1944 + 1.1945 +/* void setAsUint8 (in uint8_t aValue); */ 1.1946 +NS_IMETHODIMP nsVariant::SetAsUint8(uint8_t aValue) 1.1947 +{ 1.1948 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1949 + return nsVariant::SetFromUint8(&mData, aValue); 1.1950 +} 1.1951 + 1.1952 +/* void setAsUint16 (in uint16_t aValue); */ 1.1953 +NS_IMETHODIMP nsVariant::SetAsUint16(uint16_t aValue) 1.1954 +{ 1.1955 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1956 + return nsVariant::SetFromUint16(&mData, aValue); 1.1957 +} 1.1958 + 1.1959 +/* void setAsUint32 (in uint32_t aValue); */ 1.1960 +NS_IMETHODIMP nsVariant::SetAsUint32(uint32_t aValue) 1.1961 +{ 1.1962 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1963 + return nsVariant::SetFromUint32(&mData, aValue); 1.1964 +} 1.1965 + 1.1966 +/* void setAsUint64 (in uint64_t aValue); */ 1.1967 +NS_IMETHODIMP nsVariant::SetAsUint64(uint64_t aValue) 1.1968 +{ 1.1969 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1970 + return nsVariant::SetFromUint64(&mData, aValue); 1.1971 +} 1.1972 + 1.1973 +/* void setAsFloat (in float aValue); */ 1.1974 +NS_IMETHODIMP nsVariant::SetAsFloat(float aValue) 1.1975 +{ 1.1976 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1977 + return nsVariant::SetFromFloat(&mData, aValue); 1.1978 +} 1.1979 + 1.1980 +/* void setAsDouble (in double aValue); */ 1.1981 +NS_IMETHODIMP nsVariant::SetAsDouble(double aValue) 1.1982 +{ 1.1983 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1984 + return nsVariant::SetFromDouble(&mData, aValue); 1.1985 +} 1.1986 + 1.1987 +/* void setAsBool (in bool aValue); */ 1.1988 +NS_IMETHODIMP nsVariant::SetAsBool(bool aValue) 1.1989 +{ 1.1990 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1991 + return nsVariant::SetFromBool(&mData, aValue); 1.1992 +} 1.1993 + 1.1994 +/* void setAsChar (in char aValue); */ 1.1995 +NS_IMETHODIMP nsVariant::SetAsChar(char aValue) 1.1996 +{ 1.1997 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.1998 + return nsVariant::SetFromChar(&mData, aValue); 1.1999 +} 1.2000 + 1.2001 +/* void setAsWChar (in wchar aValue); */ 1.2002 +NS_IMETHODIMP nsVariant::SetAsWChar(char16_t aValue) 1.2003 +{ 1.2004 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2005 + return nsVariant::SetFromWChar(&mData, aValue); 1.2006 +} 1.2007 + 1.2008 +/* void setAsID (in nsIDRef aValue); */ 1.2009 +NS_IMETHODIMP nsVariant::SetAsID(const nsID & aValue) 1.2010 +{ 1.2011 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2012 + return nsVariant::SetFromID(&mData, aValue); 1.2013 +} 1.2014 + 1.2015 +/* void setAsAString (in AString aValue); */ 1.2016 +NS_IMETHODIMP nsVariant::SetAsAString(const nsAString & aValue) 1.2017 +{ 1.2018 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2019 + return nsVariant::SetFromAString(&mData, aValue); 1.2020 +} 1.2021 + 1.2022 +/* void setAsDOMString (in DOMString aValue); */ 1.2023 +NS_IMETHODIMP nsVariant::SetAsDOMString(const nsAString & aValue) 1.2024 +{ 1.2025 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2026 + 1.2027 + DATA_SETTER_PROLOGUE((&mData)); 1.2028 + if(!(mData.u.mAStringValue = new nsString(aValue))) 1.2029 + return NS_ERROR_OUT_OF_MEMORY; 1.2030 + DATA_SETTER_EPILOGUE((&mData), VTYPE_DOMSTRING); 1.2031 +} 1.2032 + 1.2033 +/* void setAsACString (in ACString aValue); */ 1.2034 +NS_IMETHODIMP nsVariant::SetAsACString(const nsACString & aValue) 1.2035 +{ 1.2036 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2037 + return nsVariant::SetFromACString(&mData, aValue); 1.2038 +} 1.2039 + 1.2040 +/* void setAsAUTF8String (in AUTF8String aValue); */ 1.2041 +NS_IMETHODIMP nsVariant::SetAsAUTF8String(const nsAUTF8String & aValue) 1.2042 +{ 1.2043 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2044 + return nsVariant::SetFromAUTF8String(&mData, aValue); 1.2045 +} 1.2046 + 1.2047 +/* void setAsString (in string aValue); */ 1.2048 +NS_IMETHODIMP nsVariant::SetAsString(const char *aValue) 1.2049 +{ 1.2050 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2051 + return nsVariant::SetFromString(&mData, aValue); 1.2052 +} 1.2053 + 1.2054 +/* void setAsWString (in wstring aValue); */ 1.2055 +NS_IMETHODIMP nsVariant::SetAsWString(const char16_t *aValue) 1.2056 +{ 1.2057 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2058 + return nsVariant::SetFromWString(&mData, aValue); 1.2059 +} 1.2060 + 1.2061 +/* void setAsISupports (in nsISupports aValue); */ 1.2062 +NS_IMETHODIMP nsVariant::SetAsISupports(nsISupports *aValue) 1.2063 +{ 1.2064 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2065 + return nsVariant::SetFromISupports(&mData, aValue); 1.2066 +} 1.2067 + 1.2068 +/* void setAsInterface (in nsIIDRef iid, [iid_is (iid)] in nsQIResult iface); */ 1.2069 +NS_IMETHODIMP nsVariant::SetAsInterface(const nsIID & iid, void * iface) 1.2070 +{ 1.2071 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2072 + return nsVariant::SetFromInterface(&mData, iid, (nsISupports*)iface); 1.2073 +} 1.2074 + 1.2075 +/* [noscript] void setAsArray (in uint16_t type, in nsIIDPtr iid, in uint32_t count, in voidPtr ptr); */ 1.2076 +NS_IMETHODIMP nsVariant::SetAsArray(uint16_t type, const nsIID * iid, uint32_t count, void * ptr) 1.2077 +{ 1.2078 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2079 + return nsVariant::SetFromArray(&mData, type, iid, count, ptr); 1.2080 +} 1.2081 + 1.2082 +/* void setAsStringWithSize (in uint32_t size, [size_is (size)] in string str); */ 1.2083 +NS_IMETHODIMP nsVariant::SetAsStringWithSize(uint32_t size, const char *str) 1.2084 +{ 1.2085 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2086 + return nsVariant::SetFromStringWithSize(&mData, size, str); 1.2087 +} 1.2088 + 1.2089 +/* void setAsWStringWithSize (in uint32_t size, [size_is (size)] in wstring str); */ 1.2090 +NS_IMETHODIMP nsVariant::SetAsWStringWithSize(uint32_t size, const char16_t *str) 1.2091 +{ 1.2092 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2093 + return nsVariant::SetFromWStringWithSize(&mData, size, str); 1.2094 +} 1.2095 + 1.2096 +/* void setAsVoid (); */ 1.2097 +NS_IMETHODIMP nsVariant::SetAsVoid() 1.2098 +{ 1.2099 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2100 + return nsVariant::SetToVoid(&mData); 1.2101 +} 1.2102 + 1.2103 +/* void setAsEmpty (); */ 1.2104 +NS_IMETHODIMP nsVariant::SetAsEmpty() 1.2105 +{ 1.2106 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2107 + return nsVariant::SetToEmpty(&mData); 1.2108 +} 1.2109 + 1.2110 +/* void setAsEmptyArray (); */ 1.2111 +NS_IMETHODIMP nsVariant::SetAsEmptyArray() 1.2112 +{ 1.2113 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2114 + return nsVariant::SetToEmptyArray(&mData); 1.2115 +} 1.2116 + 1.2117 +/* void setFromVariant (in nsIVariant aValue); */ 1.2118 +NS_IMETHODIMP nsVariant::SetFromVariant(nsIVariant *aValue) 1.2119 +{ 1.2120 + if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; 1.2121 + return nsVariant::SetFromVariant(&mData, aValue); 1.2122 +}