michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* The long avoided variant support for xpcom. */ michael@0: michael@0: #include "nsVariant.h" michael@0: #include "prprf.h" michael@0: #include "prdtoa.h" michael@0: #include michael@0: #include "nsCycleCollectionParticipant.h" michael@0: #include "xpt_struct.h" michael@0: #include "nsReadableUtils.h" michael@0: #include "nsMemory.h" michael@0: #include "nsString.h" michael@0: #include "nsCRTGlue.h" michael@0: michael@0: /***************************************************************************/ michael@0: // Helpers for static convert functions... michael@0: michael@0: static nsresult String2Double(const char* aString, double* retval) michael@0: { michael@0: char* next; michael@0: double value = PR_strtod(aString, &next); michael@0: if(next == aString) michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: *retval = value; michael@0: return NS_OK; michael@0: } michael@0: michael@0: static nsresult AString2Double(const nsAString& aString, double* retval) michael@0: { michael@0: char* pChars = ToNewCString(aString); michael@0: if(!pChars) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: nsresult rv = String2Double(pChars, retval); michael@0: nsMemory::Free(pChars); michael@0: return rv; michael@0: } michael@0: michael@0: static nsresult AUTF8String2Double(const nsAUTF8String& aString, double* retval) michael@0: { michael@0: return String2Double(PromiseFlatUTF8String(aString).get(), retval); michael@0: } michael@0: michael@0: static nsresult ACString2Double(const nsACString& aString, double* retval) michael@0: { michael@0: return String2Double(PromiseFlatCString(aString).get(), retval); michael@0: } michael@0: michael@0: // Fills outVariant with double, uint32_t, or int32_t. michael@0: // Returns NS_OK, an error code, or a non-NS_OK success code michael@0: static nsresult ToManageableNumber(const nsDiscriminatedUnion& inData, michael@0: nsDiscriminatedUnion* outData) michael@0: { michael@0: nsresult rv; michael@0: michael@0: switch(inData.mType) michael@0: { michael@0: // This group results in a int32_t... michael@0: michael@0: #define CASE__NUMBER_INT32(type_, member_) \ michael@0: case nsIDataType :: type_ : \ michael@0: outData->u.mInt32Value = inData.u. member_ ; \ michael@0: outData->mType = nsIDataType::VTYPE_INT32; \ michael@0: return NS_OK; michael@0: michael@0: CASE__NUMBER_INT32(VTYPE_INT8, mInt8Value) michael@0: CASE__NUMBER_INT32(VTYPE_INT16, mInt16Value) michael@0: CASE__NUMBER_INT32(VTYPE_INT32, mInt32Value) michael@0: CASE__NUMBER_INT32(VTYPE_UINT8, mUint8Value) michael@0: CASE__NUMBER_INT32(VTYPE_UINT16, mUint16Value) michael@0: CASE__NUMBER_INT32(VTYPE_BOOL, mBoolValue) michael@0: CASE__NUMBER_INT32(VTYPE_CHAR, mCharValue) michael@0: CASE__NUMBER_INT32(VTYPE_WCHAR, mWCharValue) michael@0: michael@0: #undef CASE__NUMBER_INT32 michael@0: michael@0: // This group results in a uint32_t... michael@0: michael@0: case nsIDataType::VTYPE_UINT32: michael@0: outData->u.mInt32Value = inData.u.mUint32Value; michael@0: outData->mType = nsIDataType::VTYPE_INT32; michael@0: return NS_OK; michael@0: michael@0: // This group results in a double... michael@0: michael@0: case nsIDataType::VTYPE_INT64: michael@0: case nsIDataType::VTYPE_UINT64: michael@0: // XXX Need boundary checking here. michael@0: // We may need to return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA michael@0: outData->u.mDoubleValue = double(inData.u.mInt64Value); michael@0: outData->mType = nsIDataType::VTYPE_DOUBLE; michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_FLOAT: michael@0: outData->u.mDoubleValue = inData.u.mFloatValue; michael@0: outData->mType = nsIDataType::VTYPE_DOUBLE; michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_DOUBLE: michael@0: outData->u.mDoubleValue = inData.u.mDoubleValue; michael@0: outData->mType = nsIDataType::VTYPE_DOUBLE; michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: rv = String2Double(inData.u.str.mStringValue, &outData->u.mDoubleValue); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: outData->mType = nsIDataType::VTYPE_DOUBLE; michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: rv = AString2Double(*inData.u.mAStringValue, &outData->u.mDoubleValue); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: outData->mType = nsIDataType::VTYPE_DOUBLE; michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: rv = AUTF8String2Double(*inData.u.mUTF8StringValue, michael@0: &outData->u.mDoubleValue); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: outData->mType = nsIDataType::VTYPE_DOUBLE; michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: rv = ACString2Double(*inData.u.mCStringValue, michael@0: &outData->u.mDoubleValue); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: outData->mType = nsIDataType::VTYPE_DOUBLE; michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: rv = AString2Double(nsDependentString(inData.u.wstr.mWStringValue), michael@0: &outData->u.mDoubleValue); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: outData->mType = nsIDataType::VTYPE_DOUBLE; michael@0: return NS_OK; michael@0: michael@0: // This group fails... michael@0: michael@0: case nsIDataType::VTYPE_VOID: michael@0: case nsIDataType::VTYPE_ID: michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: case nsIDataType::VTYPE_ARRAY: michael@0: case nsIDataType::VTYPE_EMPTY_ARRAY: michael@0: case nsIDataType::VTYPE_EMPTY: michael@0: default: michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: } michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: // Array helpers... michael@0: michael@0: static void FreeArray(nsDiscriminatedUnion* data) michael@0: { michael@0: NS_ASSERTION(data->mType == nsIDataType::VTYPE_ARRAY, "bad FreeArray call"); michael@0: NS_ASSERTION(data->u.array.mArrayValue, "bad array"); michael@0: NS_ASSERTION(data->u.array.mArrayCount, "bad array count"); michael@0: michael@0: #define CASE__FREE_ARRAY_PTR(type_, ctype_) \ michael@0: case nsIDataType:: type_ : \ michael@0: { \ michael@0: ctype_ ** p = (ctype_ **) data->u.array.mArrayValue; \ michael@0: for(uint32_t i = data->u.array.mArrayCount; i > 0; p++, i--) \ michael@0: if(*p) \ michael@0: nsMemory::Free((char*)*p); \ michael@0: break; \ michael@0: } michael@0: michael@0: #define CASE__FREE_ARRAY_IFACE(type_, ctype_) \ michael@0: case nsIDataType:: type_ : \ michael@0: { \ michael@0: ctype_ ** p = (ctype_ **) data->u.array.mArrayValue; \ michael@0: for(uint32_t i = data->u.array.mArrayCount; i > 0; p++, i--) \ michael@0: if(*p) \ michael@0: (*p)->Release(); \ michael@0: break; \ michael@0: } michael@0: michael@0: switch(data->u.array.mArrayType) michael@0: { michael@0: case nsIDataType::VTYPE_INT8: michael@0: case nsIDataType::VTYPE_INT16: michael@0: case nsIDataType::VTYPE_INT32: michael@0: case nsIDataType::VTYPE_INT64: michael@0: case nsIDataType::VTYPE_UINT8: michael@0: case nsIDataType::VTYPE_UINT16: michael@0: case nsIDataType::VTYPE_UINT32: michael@0: case nsIDataType::VTYPE_UINT64: michael@0: case nsIDataType::VTYPE_FLOAT: michael@0: case nsIDataType::VTYPE_DOUBLE: michael@0: case nsIDataType::VTYPE_BOOL: michael@0: case nsIDataType::VTYPE_CHAR: michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: break; michael@0: michael@0: // XXX We ASSUME that "array of nsID" means "array of pointers to nsID". michael@0: CASE__FREE_ARRAY_PTR(VTYPE_ID, nsID) michael@0: CASE__FREE_ARRAY_PTR(VTYPE_CHAR_STR, char) michael@0: CASE__FREE_ARRAY_PTR(VTYPE_WCHAR_STR, char16_t) michael@0: CASE__FREE_ARRAY_IFACE(VTYPE_INTERFACE, nsISupports) michael@0: CASE__FREE_ARRAY_IFACE(VTYPE_INTERFACE_IS, nsISupports) michael@0: michael@0: // The rest are illegal. michael@0: case nsIDataType::VTYPE_VOID: michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: case nsIDataType::VTYPE_ARRAY: michael@0: case nsIDataType::VTYPE_EMPTY_ARRAY: michael@0: case nsIDataType::VTYPE_EMPTY: michael@0: default: michael@0: NS_ERROR("bad type in array!"); michael@0: break; michael@0: } michael@0: michael@0: // Free the array memory. michael@0: nsMemory::Free((char*)data->u.array.mArrayValue); michael@0: michael@0: #undef CASE__FREE_ARRAY_PTR michael@0: #undef CASE__FREE_ARRAY_IFACE michael@0: } michael@0: michael@0: static nsresult CloneArray(uint16_t inType, const nsIID* inIID, michael@0: uint32_t inCount, void* inValue, michael@0: uint16_t* outType, michael@0: nsIID* outIID, michael@0: uint32_t* outCount, michael@0: void** outValue) michael@0: { michael@0: NS_ASSERTION(inCount, "bad param"); michael@0: NS_ASSERTION(inValue, "bad param"); michael@0: NS_ASSERTION(outType, "bad param"); michael@0: NS_ASSERTION(outCount, "bad param"); michael@0: NS_ASSERTION(outValue, "bad param"); michael@0: michael@0: uint32_t allocatedValueCount = 0; michael@0: nsresult rv = NS_OK; michael@0: uint32_t i; michael@0: michael@0: // First we figure out the size of the elements for the new u.array. michael@0: michael@0: size_t elementSize; michael@0: size_t allocSize; michael@0: michael@0: switch(inType) michael@0: { michael@0: case nsIDataType::VTYPE_INT8: michael@0: elementSize = sizeof(int8_t); michael@0: break; michael@0: case nsIDataType::VTYPE_INT16: michael@0: elementSize = sizeof(int16_t); michael@0: break; michael@0: case nsIDataType::VTYPE_INT32: michael@0: elementSize = sizeof(int32_t); michael@0: break; michael@0: case nsIDataType::VTYPE_INT64: michael@0: elementSize = sizeof(int64_t); michael@0: break; michael@0: case nsIDataType::VTYPE_UINT8: michael@0: elementSize = sizeof(uint8_t); michael@0: break; michael@0: case nsIDataType::VTYPE_UINT16: michael@0: elementSize = sizeof(uint16_t); michael@0: break; michael@0: case nsIDataType::VTYPE_UINT32: michael@0: elementSize = sizeof(uint32_t); michael@0: break; michael@0: case nsIDataType::VTYPE_UINT64: michael@0: elementSize = sizeof(uint64_t); michael@0: break; michael@0: case nsIDataType::VTYPE_FLOAT: michael@0: elementSize = sizeof(float); michael@0: break; michael@0: case nsIDataType::VTYPE_DOUBLE: michael@0: elementSize = sizeof(double); michael@0: break; michael@0: case nsIDataType::VTYPE_BOOL: michael@0: elementSize = sizeof(bool); michael@0: break; michael@0: case nsIDataType::VTYPE_CHAR: michael@0: elementSize = sizeof(char); michael@0: break; michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: elementSize = sizeof(char16_t); michael@0: break; michael@0: michael@0: // XXX We ASSUME that "array of nsID" means "array of pointers to nsID". michael@0: case nsIDataType::VTYPE_ID: michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: elementSize = sizeof(void*); michael@0: break; michael@0: michael@0: // The rest are illegal. michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: case nsIDataType::VTYPE_VOID: michael@0: case nsIDataType::VTYPE_ARRAY: michael@0: case nsIDataType::VTYPE_EMPTY_ARRAY: michael@0: case nsIDataType::VTYPE_EMPTY: michael@0: default: michael@0: NS_ERROR("bad type in array!"); michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: } michael@0: michael@0: michael@0: // Alloc the u.array. michael@0: michael@0: allocSize = inCount * elementSize; michael@0: *outValue = nsMemory::Alloc(allocSize); michael@0: if(!*outValue) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: michael@0: // Clone the elements. michael@0: michael@0: switch(inType) michael@0: { michael@0: case nsIDataType::VTYPE_INT8: michael@0: case nsIDataType::VTYPE_INT16: michael@0: case nsIDataType::VTYPE_INT32: michael@0: case nsIDataType::VTYPE_INT64: michael@0: case nsIDataType::VTYPE_UINT8: michael@0: case nsIDataType::VTYPE_UINT16: michael@0: case nsIDataType::VTYPE_UINT32: michael@0: case nsIDataType::VTYPE_UINT64: michael@0: case nsIDataType::VTYPE_FLOAT: michael@0: case nsIDataType::VTYPE_DOUBLE: michael@0: case nsIDataType::VTYPE_BOOL: michael@0: case nsIDataType::VTYPE_CHAR: michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: memcpy(*outValue, inValue, allocSize); michael@0: break; michael@0: michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: if(outIID) michael@0: *outIID = *inIID; michael@0: // fall through... michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: { michael@0: memcpy(*outValue, inValue, allocSize); michael@0: michael@0: nsISupports** p = (nsISupports**) *outValue; michael@0: for(i = inCount; i > 0; p++, i--) michael@0: if(*p) michael@0: (*p)->AddRef(); michael@0: break; michael@0: } michael@0: michael@0: // XXX We ASSUME that "array of nsID" means "array of pointers to nsID". michael@0: case nsIDataType::VTYPE_ID: michael@0: { michael@0: nsID** inp = (nsID**) inValue; michael@0: nsID** outp = (nsID**) *outValue; michael@0: for(i = inCount; i > 0; i--) michael@0: { michael@0: nsID* idp = *(inp++); michael@0: if(idp) michael@0: { michael@0: if(nullptr == (*(outp++) = (nsID*) michael@0: nsMemory::Clone((char*)idp, sizeof(nsID)))) michael@0: goto bad; michael@0: } michael@0: else michael@0: *(outp++) = nullptr; michael@0: allocatedValueCount++; michael@0: } michael@0: break; michael@0: } michael@0: michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: { michael@0: char** inp = (char**) inValue; michael@0: char** outp = (char**) *outValue; michael@0: for(i = inCount; i > 0; i--) michael@0: { michael@0: char* str = *(inp++); michael@0: if(str) michael@0: { michael@0: if(nullptr == (*(outp++) = (char*) michael@0: nsMemory::Clone(str, (strlen(str)+1)*sizeof(char)))) michael@0: goto bad; michael@0: } michael@0: else michael@0: *(outp++) = nullptr; michael@0: allocatedValueCount++; michael@0: } michael@0: break; michael@0: } michael@0: michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: { michael@0: char16_t** inp = (char16_t**) inValue; michael@0: char16_t** outp = (char16_t**) *outValue; michael@0: for(i = inCount; i > 0; i--) michael@0: { michael@0: char16_t* str = *(inp++); michael@0: if(str) michael@0: { michael@0: if(nullptr == (*(outp++) = (char16_t*) michael@0: nsMemory::Clone(str, michael@0: (NS_strlen(str) + 1) * sizeof(char16_t)))) michael@0: goto bad; michael@0: } michael@0: else michael@0: *(outp++) = nullptr; michael@0: allocatedValueCount++; michael@0: } michael@0: break; michael@0: } michael@0: michael@0: // The rest are illegal. michael@0: case nsIDataType::VTYPE_VOID: michael@0: case nsIDataType::VTYPE_ARRAY: michael@0: case nsIDataType::VTYPE_EMPTY_ARRAY: michael@0: case nsIDataType::VTYPE_EMPTY: michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: default: michael@0: NS_ERROR("bad type in array!"); michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: } michael@0: michael@0: *outType = inType; michael@0: *outCount = inCount; michael@0: return NS_OK; michael@0: michael@0: bad: michael@0: if(*outValue) michael@0: { michael@0: char** p = (char**) *outValue; michael@0: for(i = allocatedValueCount; i > 0; p++, i--) michael@0: if(*p) michael@0: nsMemory::Free(*p); michael@0: nsMemory::Free((char*)*outValue); michael@0: *outValue = nullptr; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: #define TRIVIAL_DATA_CONVERTER(type_, data_, member_, retval_) \ michael@0: if(data_.mType == nsIDataType :: type_) { \ michael@0: *retval_ = data_.u.member_; \ michael@0: return NS_OK; \ michael@0: } michael@0: michael@0: #define NUMERIC_CONVERSION_METHOD_BEGIN(type_, Ctype_, name_) \ michael@0: /* static */ nsresult \ michael@0: nsVariant::ConvertTo##name_ (const nsDiscriminatedUnion& data, \ michael@0: Ctype_ *_retval) \ michael@0: { \ michael@0: TRIVIAL_DATA_CONVERTER(type_, data, m##name_##Value, _retval) \ michael@0: nsDiscriminatedUnion tempData; \ michael@0: nsVariant::Initialize(&tempData); \ michael@0: nsresult rv = ToManageableNumber(data, &tempData); \ michael@0: /* */ \ michael@0: /* NOTE: rv may indicate a success code that we want to preserve */ \ michael@0: /* For the final return. So all the return cases below should return */ \ michael@0: /* this rv when indicating success. */ \ michael@0: /* */ \ michael@0: if(NS_FAILED(rv)) \ michael@0: return rv; \ michael@0: switch(tempData.mType) \ michael@0: { michael@0: michael@0: #define CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(Ctype_) \ michael@0: case nsIDataType::VTYPE_INT32: \ michael@0: *_retval = ( Ctype_ ) tempData.u.mInt32Value; \ michael@0: return rv; michael@0: michael@0: #define CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(Ctype_, min_, max_) \ michael@0: case nsIDataType::VTYPE_INT32: \ michael@0: { \ michael@0: int32_t value = tempData.u.mInt32Value; \ michael@0: if(value < min_ || value > max_) \ michael@0: return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \ michael@0: *_retval = ( Ctype_ ) value; \ michael@0: return rv; \ michael@0: } michael@0: michael@0: #define CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(Ctype_) \ michael@0: case nsIDataType::VTYPE_UINT32: \ michael@0: *_retval = ( Ctype_ ) tempData.u.mUint32Value; \ michael@0: return rv; michael@0: michael@0: #define CASE__NUMERIC_CONVERSION_UINT32_MAX(Ctype_, max_) \ michael@0: case nsIDataType::VTYPE_UINT32: \ michael@0: { \ michael@0: uint32_t value = tempData.u.mUint32Value; \ michael@0: if(value > max_) \ michael@0: return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \ michael@0: *_retval = ( Ctype_ ) value; \ michael@0: return rv; \ michael@0: } michael@0: michael@0: #define CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(Ctype_) \ michael@0: case nsIDataType::VTYPE_DOUBLE: \ michael@0: *_retval = ( Ctype_ ) tempData.u.mDoubleValue; \ michael@0: return rv; michael@0: michael@0: #define CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX(Ctype_, min_, max_) \ michael@0: case nsIDataType::VTYPE_DOUBLE: \ michael@0: { \ michael@0: double value = tempData.u.mDoubleValue; \ michael@0: if(value < min_ || value > max_) \ michael@0: return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \ michael@0: *_retval = ( Ctype_ ) value; \ michael@0: return rv; \ michael@0: } michael@0: michael@0: #define CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(Ctype_, min_, max_) \ michael@0: case nsIDataType::VTYPE_DOUBLE: \ michael@0: { \ michael@0: double value = tempData.u.mDoubleValue; \ michael@0: if(value < min_ || value > max_) \ michael@0: return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; \ michael@0: *_retval = ( Ctype_ ) value; \ michael@0: return (0.0 == fmod(value,1.0)) ? \ michael@0: rv : NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA; \ michael@0: } michael@0: michael@0: #define CASES__NUMERIC_CONVERSION_NORMAL(Ctype_, min_, max_) \ michael@0: CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(Ctype_, min_, max_) \ michael@0: CASE__NUMERIC_CONVERSION_UINT32_MAX(Ctype_, max_) \ michael@0: CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(Ctype_, min_, max_) michael@0: michael@0: #define NUMERIC_CONVERSION_METHOD_END \ michael@0: default: \ michael@0: NS_ERROR("bad type returned from ToManageableNumber"); \ michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; \ michael@0: } \ michael@0: } michael@0: michael@0: #define NUMERIC_CONVERSION_METHOD_NORMAL(type_, Ctype_, name_, min_, max_) \ michael@0: NUMERIC_CONVERSION_METHOD_BEGIN(type_, Ctype_, name_) \ michael@0: CASES__NUMERIC_CONVERSION_NORMAL(Ctype_, min_, max_) \ michael@0: NUMERIC_CONVERSION_METHOD_END michael@0: michael@0: /***************************************************************************/ michael@0: // These expand into full public methods... michael@0: michael@0: NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_INT8, uint8_t, Int8, (-127-1), 127) michael@0: NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_INT16, int16_t, Int16, (-32767-1), 32767) michael@0: michael@0: NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_INT32, int32_t, Int32) michael@0: CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(int32_t) michael@0: CASE__NUMERIC_CONVERSION_UINT32_MAX(int32_t, 2147483647) michael@0: CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(int32_t, (-2147483647-1), 2147483647) michael@0: NUMERIC_CONVERSION_METHOD_END michael@0: michael@0: NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_UINT8, uint8_t, Uint8, 0, 255) michael@0: NUMERIC_CONVERSION_METHOD_NORMAL(VTYPE_UINT16, uint16_t, Uint16, 0, 65535) michael@0: michael@0: NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_UINT32, uint32_t, Uint32) michael@0: CASE__NUMERIC_CONVERSION_INT32_MIN_MAX(uint32_t, 0, 2147483647) michael@0: CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(uint32_t) michael@0: CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT(uint32_t, 0, 4294967295U) michael@0: NUMERIC_CONVERSION_METHOD_END michael@0: michael@0: // XXX toFloat convertions need to be fixed! michael@0: NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_FLOAT, float, Float) michael@0: CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(float) michael@0: CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(float) michael@0: CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(float) michael@0: NUMERIC_CONVERSION_METHOD_END michael@0: michael@0: NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_DOUBLE, double, Double) michael@0: CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(double) michael@0: CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(double) michael@0: CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(double) michael@0: NUMERIC_CONVERSION_METHOD_END michael@0: michael@0: // XXX toChar convertions need to be fixed! michael@0: NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_CHAR, char, Char) michael@0: CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(char) michael@0: CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(char) michael@0: CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(char) michael@0: NUMERIC_CONVERSION_METHOD_END michael@0: michael@0: // XXX toWChar convertions need to be fixed! michael@0: NUMERIC_CONVERSION_METHOD_BEGIN(VTYPE_WCHAR, char16_t, WChar) michael@0: CASE__NUMERIC_CONVERSION_INT32_JUST_CAST(char16_t) michael@0: CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST(char16_t) michael@0: CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST(char16_t) michael@0: NUMERIC_CONVERSION_METHOD_END michael@0: michael@0: #undef NUMERIC_CONVERSION_METHOD_BEGIN michael@0: #undef CASE__NUMERIC_CONVERSION_INT32_JUST_CAST michael@0: #undef CASE__NUMERIC_CONVERSION_INT32_MIN_MAX michael@0: #undef CASE__NUMERIC_CONVERSION_UINT32_JUST_CAST michael@0: #undef CASE__NUMERIC_CONVERSION_UINT32_MIN_MAX michael@0: #undef CASE__NUMERIC_CONVERSION_DOUBLE_JUST_CAST michael@0: #undef CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX michael@0: #undef CASE__NUMERIC_CONVERSION_DOUBLE_MIN_MAX_INT michael@0: #undef CASES__NUMERIC_CONVERSION_NORMAL michael@0: #undef NUMERIC_CONVERSION_METHOD_END michael@0: #undef NUMERIC_CONVERSION_METHOD_NORMAL michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: // Just leverage a numeric converter for bool (but restrict the values). michael@0: // XXX Is this really what we want to do? michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToBool(const nsDiscriminatedUnion& data, bool *_retval) michael@0: { michael@0: TRIVIAL_DATA_CONVERTER(VTYPE_BOOL, data, mBoolValue, _retval) michael@0: michael@0: double val; michael@0: nsresult rv = nsVariant::ConvertToDouble(data, &val); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: *_retval = 0.0 != val; michael@0: return rv; michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToInt64(const nsDiscriminatedUnion& data, int64_t *_retval) michael@0: { michael@0: TRIVIAL_DATA_CONVERTER(VTYPE_INT64, data, mInt64Value, _retval) michael@0: TRIVIAL_DATA_CONVERTER(VTYPE_UINT64, data, mUint64Value, _retval) michael@0: michael@0: nsDiscriminatedUnion tempData; michael@0: nsVariant::Initialize(&tempData); michael@0: nsresult rv = ToManageableNumber(data, &tempData); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: switch(tempData.mType) michael@0: { michael@0: case nsIDataType::VTYPE_INT32: michael@0: *_retval = tempData.u.mInt32Value; michael@0: return rv; michael@0: case nsIDataType::VTYPE_UINT32: michael@0: *_retval = tempData.u.mUint32Value; michael@0: return rv; michael@0: case nsIDataType::VTYPE_DOUBLE: michael@0: // XXX should check for data loss here! michael@0: *_retval = tempData.u.mDoubleValue; michael@0: return rv; michael@0: default: michael@0: NS_ERROR("bad type returned from ToManageableNumber"); michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: } michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToUint64(const nsDiscriminatedUnion& data, uint64_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToInt64(data, (int64_t *)_retval); michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: static bool String2ID(const nsDiscriminatedUnion& data, nsID* pid) michael@0: { michael@0: nsAutoString tempString; michael@0: nsAString* pString; michael@0: michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: return pid->Parse(data.u.str.mStringValue); michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: return pid->Parse(PromiseFlatCString(*data.u.mCStringValue).get()); michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: return pid->Parse(PromiseFlatUTF8String(*data.u.mUTF8StringValue).get()); michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: pString = data.u.mAStringValue; michael@0: break; michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: tempString.Assign(data.u.wstr.mWStringValue); michael@0: pString = &tempString; michael@0: break; michael@0: default: michael@0: NS_ERROR("bad type in call to String2ID"); michael@0: return false; michael@0: } michael@0: michael@0: char* pChars = ToNewCString(*pString); michael@0: if(!pChars) michael@0: return false; michael@0: bool result = pid->Parse(pChars); michael@0: nsMemory::Free(pChars); michael@0: return result; michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToID(const nsDiscriminatedUnion& data, nsID * _retval) michael@0: { michael@0: nsID id; michael@0: michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_ID: michael@0: *_retval = data.u.mIDValue; michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: *_retval = NS_GET_IID(nsISupports); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: *_retval = data.u.iface.mInterfaceID; michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: if(!String2ID(data, &id)) michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: *_retval = id; michael@0: return NS_OK; michael@0: default: michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: } michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: static nsresult ToString(const nsDiscriminatedUnion& data, michael@0: nsACString & outString) michael@0: { michael@0: char* ptr; michael@0: michael@0: switch(data.mType) michael@0: { michael@0: // all the stuff we don't handle... michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: NS_ERROR("ToString being called for a string type - screwy logic!"); michael@0: // fall through... michael@0: michael@0: // XXX We might want stringified versions of these... ??? michael@0: michael@0: case nsIDataType::VTYPE_VOID: michael@0: case nsIDataType::VTYPE_EMPTY: michael@0: outString.Truncate(); michael@0: outString.SetIsVoid(true); michael@0: return NS_OK; michael@0: michael@0: case nsIDataType::VTYPE_EMPTY_ARRAY: michael@0: case nsIDataType::VTYPE_ARRAY: michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: default: michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: michael@0: // nsID has its own text formatter. michael@0: michael@0: case nsIDataType::VTYPE_ID: michael@0: ptr = data.u.mIDValue.ToString(); michael@0: if(!ptr) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: outString.Assign(ptr); michael@0: nsMemory::Free(ptr); michael@0: return NS_OK; michael@0: michael@0: // Can't use PR_smprintf for floats, since it's locale-dependent michael@0: #define CASE__APPENDFLOAT_NUMBER(type_, member_) \ michael@0: case nsIDataType :: type_ : \ michael@0: { \ michael@0: nsAutoCString str; \ michael@0: str.AppendFloat(data.u. member_); \ michael@0: outString.Assign(str); \ michael@0: return NS_OK; \ michael@0: } michael@0: michael@0: CASE__APPENDFLOAT_NUMBER(VTYPE_FLOAT, mFloatValue) michael@0: CASE__APPENDFLOAT_NUMBER(VTYPE_DOUBLE, mDoubleValue) michael@0: michael@0: #undef CASE__APPENDFLOAT_NUMBER michael@0: michael@0: // the rest can be PR_smprintf'd and use common code. michael@0: michael@0: #define CASE__SMPRINTF_NUMBER(type_, format_, cast_, member_) \ michael@0: case nsIDataType :: type_ : \ michael@0: ptr = PR_smprintf( format_ , (cast_) data.u. member_ ); \ michael@0: break; michael@0: michael@0: CASE__SMPRINTF_NUMBER(VTYPE_INT8, "%d", int, mInt8Value) michael@0: CASE__SMPRINTF_NUMBER(VTYPE_INT16, "%d", int, mInt16Value) michael@0: CASE__SMPRINTF_NUMBER(VTYPE_INT32, "%d", int, mInt32Value) michael@0: CASE__SMPRINTF_NUMBER(VTYPE_INT64, "%lld", int64_t, mInt64Value) michael@0: michael@0: CASE__SMPRINTF_NUMBER(VTYPE_UINT8, "%u", unsigned, mUint8Value) michael@0: CASE__SMPRINTF_NUMBER(VTYPE_UINT16, "%u", unsigned, mUint16Value) michael@0: CASE__SMPRINTF_NUMBER(VTYPE_UINT32, "%u", unsigned, mUint32Value) michael@0: CASE__SMPRINTF_NUMBER(VTYPE_UINT64, "%llu", int64_t, mUint64Value) michael@0: michael@0: // XXX Would we rather print "true" / "false" ? michael@0: CASE__SMPRINTF_NUMBER(VTYPE_BOOL, "%d", int, mBoolValue) michael@0: michael@0: CASE__SMPRINTF_NUMBER(VTYPE_CHAR, "%c", char, mCharValue) michael@0: michael@0: #undef CASE__SMPRINTF_NUMBER michael@0: } michael@0: michael@0: if(!ptr) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: outString.Assign(ptr); michael@0: PR_smprintf_free(ptr); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToAString(const nsDiscriminatedUnion& data, michael@0: nsAString & _retval) michael@0: { michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: _retval.Assign(*data.u.mAStringValue); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: CopyASCIItoUTF16(*data.u.mCStringValue, _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: CopyUTF8toUTF16(*data.u.mUTF8StringValue, _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: CopyASCIItoUTF16(data.u.str.mStringValue, _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: _retval.Assign(data.u.wstr.mWStringValue); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: CopyASCIItoUTF16(nsDependentCString(data.u.str.mStringValue, michael@0: data.u.str.mStringLength), michael@0: _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: _retval.Assign(data.u.wstr.mWStringValue, data.u.wstr.mWStringLength); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: _retval.Assign(data.u.mWCharValue); michael@0: return NS_OK; michael@0: default: michael@0: { michael@0: nsAutoCString tempCString; michael@0: nsresult rv = ToString(data, tempCString); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: CopyASCIItoUTF16(tempCString, _retval); michael@0: return NS_OK; michael@0: } michael@0: } michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToACString(const nsDiscriminatedUnion& data, michael@0: nsACString & _retval) michael@0: { michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: LossyCopyUTF16toASCII(*data.u.mAStringValue, _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: _retval.Assign(*data.u.mCStringValue); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: // XXX This is an extra copy that should be avoided michael@0: // once Jag lands support for UTF8String and associated michael@0: // conversion methods. michael@0: LossyCopyUTF16toASCII(NS_ConvertUTF8toUTF16(*data.u.mUTF8StringValue), michael@0: _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: _retval.Assign(*data.u.str.mStringValue); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: LossyCopyUTF16toASCII(nsDependentString(data.u.wstr.mWStringValue), michael@0: _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: _retval.Assign(data.u.str.mStringValue, data.u.str.mStringLength); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: LossyCopyUTF16toASCII(nsDependentString(data.u.wstr.mWStringValue, michael@0: data.u.wstr.mWStringLength), _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: { michael@0: const char16_t* str = &data.u.mWCharValue; michael@0: LossyCopyUTF16toASCII(Substring(str, 1), _retval); michael@0: return NS_OK; michael@0: } michael@0: default: michael@0: return ToString(data, _retval); michael@0: } michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToAUTF8String(const nsDiscriminatedUnion& data, michael@0: nsAUTF8String & _retval) michael@0: { michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: CopyUTF16toUTF8(*data.u.mAStringValue, _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: // XXX Extra copy, can be removed if we're sure CSTRING can michael@0: // only contain ASCII. michael@0: CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(*data.u.mCStringValue), michael@0: _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: _retval.Assign(*data.u.mUTF8StringValue); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: // XXX Extra copy, can be removed if we're sure CHAR_STR can michael@0: // only contain ASCII. michael@0: CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(data.u.str.mStringValue), michael@0: _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: CopyUTF16toUTF8(data.u.wstr.mWStringValue, _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: // XXX Extra copy, can be removed if we're sure CHAR_STR can michael@0: // only contain ASCII. michael@0: CopyUTF16toUTF8(NS_ConvertASCIItoUTF16( michael@0: nsDependentCString(data.u.str.mStringValue, michael@0: data.u.str.mStringLength)), _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: CopyUTF16toUTF8(nsDependentString(data.u.wstr.mWStringValue, michael@0: data.u.wstr.mWStringLength), michael@0: _retval); michael@0: return NS_OK; michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: { michael@0: const char16_t* str = &data.u.mWCharValue; michael@0: CopyUTF16toUTF8(Substring(str, 1), _retval); michael@0: return NS_OK; michael@0: } michael@0: default: michael@0: { michael@0: nsAutoCString tempCString; michael@0: nsresult rv = ToString(data, tempCString); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: // XXX Extra copy, can be removed if we're sure tempCString can michael@0: // only contain ASCII. michael@0: CopyUTF16toUTF8(NS_ConvertASCIItoUTF16(tempCString), _retval); michael@0: return NS_OK; michael@0: } michael@0: } michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToString(const nsDiscriminatedUnion& data, char **_retval) michael@0: { michael@0: uint32_t ignored; michael@0: return nsVariant::ConvertToStringWithSize(data, &ignored, _retval); michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToWString(const nsDiscriminatedUnion& data, char16_t **_retval) michael@0: { michael@0: uint32_t ignored; michael@0: return nsVariant::ConvertToWStringWithSize(data, &ignored, _retval); michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToStringWithSize(const nsDiscriminatedUnion& data, michael@0: uint32_t *size, char **str) michael@0: { michael@0: nsAutoString tempString; michael@0: nsAutoCString tempCString; michael@0: nsresult rv; michael@0: michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: *size = data.u.mAStringValue->Length(); michael@0: *str = ToNewCString(*data.u.mAStringValue); michael@0: break; michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: *size = data.u.mCStringValue->Length(); michael@0: *str = ToNewCString(*data.u.mCStringValue); michael@0: break; michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: { michael@0: // XXX This is doing 1 extra copy. Need to fix this michael@0: // when Jag lands UTF8String michael@0: // we want: michael@0: // *size = *data.mUTF8StringValue->Length(); michael@0: // *str = ToNewCString(*data.mUTF8StringValue); michael@0: // But this will have to do for now. michael@0: NS_ConvertUTF8toUTF16 tempString(*data.u.mUTF8StringValue); michael@0: *size = tempString.Length(); michael@0: *str = ToNewCString(tempString); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: { michael@0: nsDependentCString cString(data.u.str.mStringValue); michael@0: *size = cString.Length(); michael@0: *str = ToNewCString(cString); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: { michael@0: nsDependentString string(data.u.wstr.mWStringValue); michael@0: *size = string.Length(); michael@0: *str = ToNewCString(string); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: { michael@0: nsDependentCString cString(data.u.str.mStringValue, michael@0: data.u.str.mStringLength); michael@0: *size = cString.Length(); michael@0: *str = ToNewCString(cString); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: { michael@0: nsDependentString string(data.u.wstr.mWStringValue, michael@0: data.u.wstr.mWStringLength); michael@0: *size = string.Length(); michael@0: *str = ToNewCString(string); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: tempString.Assign(data.u.mWCharValue); michael@0: *size = tempString.Length(); michael@0: *str = ToNewCString(tempString); michael@0: break; michael@0: default: michael@0: rv = ToString(data, tempCString); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: *size = tempCString.Length(); michael@0: *str = ToNewCString(tempCString); michael@0: break; michael@0: } michael@0: michael@0: return *str ? NS_OK : NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToWStringWithSize(const nsDiscriminatedUnion& data, michael@0: uint32_t *size, char16_t **str) michael@0: { michael@0: nsAutoString tempString; michael@0: nsAutoCString tempCString; michael@0: nsresult rv; michael@0: michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: *size = data.u.mAStringValue->Length(); michael@0: *str = ToNewUnicode(*data.u.mAStringValue); michael@0: break; michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: *size = data.u.mCStringValue->Length(); michael@0: *str = ToNewUnicode(*data.u.mCStringValue); michael@0: break; michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: { michael@0: *str = UTF8ToNewUnicode(*data.u.mUTF8StringValue, size); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: { michael@0: nsDependentCString cString(data.u.str.mStringValue); michael@0: *size = cString.Length(); michael@0: *str = ToNewUnicode(cString); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: { michael@0: nsDependentString string(data.u.wstr.mWStringValue); michael@0: *size = string.Length(); michael@0: *str = ToNewUnicode(string); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: { michael@0: nsDependentCString cString(data.u.str.mStringValue, michael@0: data.u.str.mStringLength); michael@0: *size = cString.Length(); michael@0: *str = ToNewUnicode(cString); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: { michael@0: nsDependentString string(data.u.wstr.mWStringValue, michael@0: data.u.wstr.mWStringLength); michael@0: *size = string.Length(); michael@0: *str = ToNewUnicode(string); michael@0: break; michael@0: } michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: tempString.Assign(data.u.mWCharValue); michael@0: *size = tempString.Length(); michael@0: *str = ToNewUnicode(tempString); michael@0: break; michael@0: default: michael@0: rv = ToString(data, tempCString); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: *size = tempCString.Length(); michael@0: *str = ToNewUnicode(tempCString); michael@0: break; michael@0: } michael@0: michael@0: return *str ? NS_OK : NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToISupports(const nsDiscriminatedUnion& data, michael@0: nsISupports **_retval) michael@0: { michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: if (data.u.iface.mInterfaceValue) { michael@0: return data.u.iface.mInterfaceValue-> michael@0: QueryInterface(NS_GET_IID(nsISupports), (void**)_retval); michael@0: } else { michael@0: *_retval = nullptr; michael@0: return NS_OK; michael@0: } michael@0: default: michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: } michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToInterface(const nsDiscriminatedUnion& data, nsIID * *iid, michael@0: void * *iface) michael@0: { michael@0: const nsIID* piid; michael@0: michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: piid = &NS_GET_IID(nsISupports); michael@0: break; michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: piid = &data.u.iface.mInterfaceID; michael@0: break; michael@0: default: michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: } michael@0: michael@0: *iid = (nsIID*) nsMemory::Clone(piid, sizeof(nsIID)); michael@0: if(!*iid) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: michael@0: if (data.u.iface.mInterfaceValue) { michael@0: return data.u.iface.mInterfaceValue->QueryInterface(*piid, iface); michael@0: } michael@0: michael@0: *iface = nullptr; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::ConvertToArray(const nsDiscriminatedUnion& data, uint16_t *type, michael@0: nsIID* iid, uint32_t *count, void * *ptr) michael@0: { michael@0: // XXX perhaps we'd like to add support for converting each of the various michael@0: // types into an array containing one element of that type. We can leverage michael@0: // CloneArray to do this if we want to support this. michael@0: michael@0: if(data.mType == nsIDataType::VTYPE_ARRAY) michael@0: return CloneArray(data.u.array.mArrayType, &data.u.array.mArrayInterfaceID, michael@0: data.u.array.mArrayCount, data.u.array.mArrayValue, michael@0: type, iid, count, ptr); michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: // static setter functions... michael@0: michael@0: #define DATA_SETTER_PROLOGUE(data_) \ michael@0: nsVariant::Cleanup(data_); michael@0: michael@0: #define DATA_SETTER_EPILOGUE(data_, type_) \ michael@0: data_->mType = nsIDataType :: type_; \ michael@0: return NS_OK; michael@0: michael@0: #define DATA_SETTER(data_, type_, member_, value_) \ michael@0: DATA_SETTER_PROLOGUE(data_) \ michael@0: data_->u.member_ = value_; \ michael@0: DATA_SETTER_EPILOGUE(data_, type_) michael@0: michael@0: #define DATA_SETTER_WITH_CAST(data_, type_, member_, cast_, value_) \ michael@0: DATA_SETTER_PROLOGUE(data_) \ michael@0: data_->u.member_ = cast_ value_; \ michael@0: DATA_SETTER_EPILOGUE(data_, type_) michael@0: michael@0: michael@0: /********************************************/ michael@0: michael@0: #define CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \ michael@0: { \ michael@0: michael@0: #define CASE__SET_FROM_VARIANT_VTYPE__GETTER(member_, name_) \ michael@0: rv = aValue->GetAs##name_ (&(data->u. member_ )); michael@0: michael@0: #define CASE__SET_FROM_VARIANT_VTYPE__GETTER_CAST(cast_, member_, name_) \ michael@0: rv = aValue->GetAs##name_ ( cast_ &(data->u. member_ )); michael@0: michael@0: #define CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_) \ michael@0: if(NS_SUCCEEDED(rv)) \ michael@0: { \ michael@0: data->mType = nsIDataType :: type_ ; \ michael@0: } \ michael@0: break; \ michael@0: } michael@0: michael@0: #define CASE__SET_FROM_VARIANT_TYPE(type_, member_, name_) \ michael@0: case nsIDataType :: type_ : \ michael@0: CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \ michael@0: CASE__SET_FROM_VARIANT_VTYPE__GETTER(member_, name_) \ michael@0: CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_) michael@0: michael@0: #define CASE__SET_FROM_VARIANT_VTYPE_CAST(type_, cast_, member_, name_) \ michael@0: case nsIDataType :: type_ : \ michael@0: CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(type_) \ michael@0: CASE__SET_FROM_VARIANT_VTYPE__GETTER_CAST(cast_, member_, name_) \ michael@0: CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(type_) michael@0: michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::SetFromVariant(nsDiscriminatedUnion* data, nsIVariant* aValue) michael@0: { michael@0: uint16_t type; michael@0: nsresult rv; michael@0: michael@0: nsVariant::Cleanup(data); michael@0: michael@0: rv = aValue->GetDataType(&type); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: switch(type) michael@0: { michael@0: CASE__SET_FROM_VARIANT_VTYPE_CAST(VTYPE_INT8, (uint8_t*), mInt8Value, michael@0: Int8) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_INT16, mInt16Value, Int16) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_INT32, mInt32Value, Int32) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT8, mUint8Value, Uint8) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT16, mUint16Value, Uint16) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_UINT32, mUint32Value, Uint32) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_FLOAT, mFloatValue, Float) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_DOUBLE, mDoubleValue, Double) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_BOOL , mBoolValue, Bool) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_CHAR, mCharValue, Char) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_WCHAR, mWCharValue, WChar) michael@0: CASE__SET_FROM_VARIANT_TYPE(VTYPE_ID, mIDValue, ID) michael@0: michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_ASTRING); michael@0: data->u.mAStringValue = new nsString(); michael@0: if(!data->u.mAStringValue) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: rv = aValue->GetAsAString(*data->u.mAStringValue); michael@0: if(NS_FAILED(rv)) michael@0: delete data->u.mAStringValue; michael@0: CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_ASTRING) michael@0: michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_CSTRING); michael@0: data->u.mCStringValue = new nsCString(); michael@0: if(!data->u.mCStringValue) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: rv = aValue->GetAsACString(*data->u.mCStringValue); michael@0: if(NS_FAILED(rv)) michael@0: delete data->u.mCStringValue; michael@0: CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_CSTRING) michael@0: michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_UTF8STRING); michael@0: data->u.mUTF8StringValue = new nsUTF8String(); michael@0: if(!data->u.mUTF8StringValue) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: rv = aValue->GetAsAUTF8String(*data->u.mUTF8StringValue); michael@0: if(NS_FAILED(rv)) michael@0: delete data->u.mUTF8StringValue; michael@0: CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_UTF8STRING) michael@0: michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_STRING_SIZE_IS); michael@0: rv = aValue->GetAsStringWithSize(&data->u.str.mStringLength, michael@0: &data->u.str.mStringValue); michael@0: CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_STRING_SIZE_IS) michael@0: michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_INTERFACE_IS); michael@0: // XXX This iid handling is ugly! michael@0: nsIID* iid; michael@0: rv = aValue->GetAsInterface(&iid, (void**)&data->u.iface.mInterfaceValue); michael@0: if(NS_SUCCEEDED(rv)) michael@0: { michael@0: data->u.iface.mInterfaceID = *iid; michael@0: nsMemory::Free((char*)iid); michael@0: } michael@0: CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_INTERFACE_IS) michael@0: michael@0: case nsIDataType::VTYPE_ARRAY: michael@0: CASE__SET_FROM_VARIANT_VTYPE_PROLOGUE(VTYPE_ARRAY); michael@0: rv = aValue->GetAsArray(&data->u.array.mArrayType, michael@0: &data->u.array.mArrayInterfaceID, michael@0: &data->u.array.mArrayCount, michael@0: &data->u.array.mArrayValue); michael@0: CASE__SET_FROM_VARIANT_VTYPE_EPILOGUE(VTYPE_ARRAY) michael@0: michael@0: case nsIDataType::VTYPE_VOID: michael@0: rv = nsVariant::SetToVoid(data); michael@0: break; michael@0: case nsIDataType::VTYPE_EMPTY_ARRAY: michael@0: rv = nsVariant::SetToEmptyArray(data); michael@0: break; michael@0: case nsIDataType::VTYPE_EMPTY: michael@0: rv = nsVariant::SetToEmpty(data); michael@0: break; michael@0: default: michael@0: NS_ERROR("bad type in variant!"); michael@0: rv = NS_ERROR_FAILURE; michael@0: break; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::SetFromInt8(nsDiscriminatedUnion* data, uint8_t aValue) michael@0: { michael@0: DATA_SETTER_WITH_CAST(data, VTYPE_INT8, mInt8Value, (uint8_t), aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromInt16(nsDiscriminatedUnion* data, int16_t aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_INT16, mInt16Value, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromInt32(nsDiscriminatedUnion* data, int32_t aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_INT32, mInt32Value, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromInt64(nsDiscriminatedUnion* data, int64_t aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_INT64, mInt64Value, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromUint8(nsDiscriminatedUnion* data, uint8_t aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_UINT8, mUint8Value, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromUint16(nsDiscriminatedUnion* data, uint16_t aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_UINT16, mUint16Value, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromUint32(nsDiscriminatedUnion* data, uint32_t aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_UINT32, mUint32Value, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromUint64(nsDiscriminatedUnion* data, uint64_t aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_UINT64, mUint64Value, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromFloat(nsDiscriminatedUnion* data, float aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_FLOAT, mFloatValue, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromDouble(nsDiscriminatedUnion* data, double aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_DOUBLE, mDoubleValue, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromBool(nsDiscriminatedUnion* data, bool aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_BOOL, mBoolValue, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromChar(nsDiscriminatedUnion* data, char aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_CHAR, mCharValue, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromWChar(nsDiscriminatedUnion* data, char16_t aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_WCHAR, mWCharValue, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromID(nsDiscriminatedUnion* data, const nsID & aValue) michael@0: { michael@0: DATA_SETTER(data, VTYPE_ID, mIDValue, aValue) michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromAString(nsDiscriminatedUnion* data, const nsAString & aValue) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: if(!(data->u.mAStringValue = new nsString(aValue))) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_ASTRING); michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::SetFromACString(nsDiscriminatedUnion* data, michael@0: const nsACString & aValue) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: if(!(data->u.mCStringValue = new nsCString(aValue))) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_CSTRING); michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::SetFromAUTF8String(nsDiscriminatedUnion* data, michael@0: const nsAUTF8String & aValue) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: if(!(data->u.mUTF8StringValue = new nsUTF8String(aValue))) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_UTF8STRING); michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::SetFromString(nsDiscriminatedUnion* data, const char *aValue) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: if(!aValue) michael@0: return NS_ERROR_NULL_POINTER; michael@0: return SetFromStringWithSize(data, strlen(aValue), aValue); michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromWString(nsDiscriminatedUnion* data, const char16_t *aValue) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: if(!aValue) michael@0: return NS_ERROR_NULL_POINTER; michael@0: return SetFromWStringWithSize(data, NS_strlen(aValue), aValue); michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromISupports(nsDiscriminatedUnion* data, nsISupports *aValue) michael@0: { michael@0: return SetFromInterface(data, NS_GET_IID(nsISupports), aValue); michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromInterface(nsDiscriminatedUnion* data, const nsIID& iid, michael@0: nsISupports *aValue) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: NS_IF_ADDREF(aValue); michael@0: data->u.iface.mInterfaceValue = aValue; michael@0: data->u.iface.mInterfaceID = iid; michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_INTERFACE_IS); michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromArray(nsDiscriminatedUnion* data, uint16_t type, michael@0: const nsIID* iid, uint32_t count, void * aValue) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: if(!aValue || !count) michael@0: return NS_ERROR_NULL_POINTER; michael@0: michael@0: nsresult rv = CloneArray(type, iid, count, aValue, michael@0: &data->u.array.mArrayType, michael@0: &data->u.array.mArrayInterfaceID, michael@0: &data->u.array.mArrayCount, michael@0: &data->u.array.mArrayValue); michael@0: if(NS_FAILED(rv)) michael@0: return rv; michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_ARRAY); michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromStringWithSize(nsDiscriminatedUnion* data, uint32_t size, const char *aValue) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: if(!aValue) michael@0: return NS_ERROR_NULL_POINTER; michael@0: if(!(data->u.str.mStringValue = michael@0: (char*) nsMemory::Clone(aValue, (size+1)*sizeof(char)))) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: data->u.str.mStringLength = size; michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_STRING_SIZE_IS); michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetFromWStringWithSize(nsDiscriminatedUnion* data, uint32_t size, const char16_t *aValue) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: if(!aValue) michael@0: return NS_ERROR_NULL_POINTER; michael@0: if(!(data->u.wstr.mWStringValue = michael@0: (char16_t*) nsMemory::Clone(aValue, (size+1)*sizeof(char16_t)))) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: data->u.wstr.mWStringLength = size; michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_WSTRING_SIZE_IS); michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetToVoid(nsDiscriminatedUnion* data) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_VOID); michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetToEmpty(nsDiscriminatedUnion* data) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_EMPTY); michael@0: } michael@0: /* static */ nsresult michael@0: nsVariant::SetToEmptyArray(nsDiscriminatedUnion* data) michael@0: { michael@0: DATA_SETTER_PROLOGUE(data); michael@0: DATA_SETTER_EPILOGUE(data, VTYPE_EMPTY_ARRAY); michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::Initialize(nsDiscriminatedUnion* data) michael@0: { michael@0: data->mType = nsIDataType::VTYPE_EMPTY; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: nsVariant::Cleanup(nsDiscriminatedUnion* data) michael@0: { michael@0: switch(data->mType) michael@0: { michael@0: case nsIDataType::VTYPE_INT8: michael@0: case nsIDataType::VTYPE_INT16: michael@0: case nsIDataType::VTYPE_INT32: michael@0: case nsIDataType::VTYPE_INT64: michael@0: case nsIDataType::VTYPE_UINT8: michael@0: case nsIDataType::VTYPE_UINT16: michael@0: case nsIDataType::VTYPE_UINT32: michael@0: case nsIDataType::VTYPE_UINT64: michael@0: case nsIDataType::VTYPE_FLOAT: michael@0: case nsIDataType::VTYPE_DOUBLE: michael@0: case nsIDataType::VTYPE_BOOL: michael@0: case nsIDataType::VTYPE_CHAR: michael@0: case nsIDataType::VTYPE_WCHAR: michael@0: case nsIDataType::VTYPE_VOID: michael@0: case nsIDataType::VTYPE_ID: michael@0: break; michael@0: case nsIDataType::VTYPE_ASTRING: michael@0: case nsIDataType::VTYPE_DOMSTRING: michael@0: delete data->u.mAStringValue; michael@0: break; michael@0: case nsIDataType::VTYPE_CSTRING: michael@0: delete data->u.mCStringValue; michael@0: break; michael@0: case nsIDataType::VTYPE_UTF8STRING: michael@0: delete data->u.mUTF8StringValue; michael@0: break; michael@0: case nsIDataType::VTYPE_CHAR_STR: michael@0: case nsIDataType::VTYPE_STRING_SIZE_IS: michael@0: nsMemory::Free((char*)data->u.str.mStringValue); michael@0: break; michael@0: case nsIDataType::VTYPE_WCHAR_STR: michael@0: case nsIDataType::VTYPE_WSTRING_SIZE_IS: michael@0: nsMemory::Free((char*)data->u.wstr.mWStringValue); michael@0: break; michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: NS_IF_RELEASE(data->u.iface.mInterfaceValue); michael@0: break; michael@0: case nsIDataType::VTYPE_ARRAY: michael@0: FreeArray(data); michael@0: break; michael@0: case nsIDataType::VTYPE_EMPTY_ARRAY: michael@0: case nsIDataType::VTYPE_EMPTY: michael@0: break; michael@0: default: michael@0: NS_ERROR("bad type in variant!"); michael@0: break; michael@0: } michael@0: michael@0: data->mType = nsIDataType::VTYPE_EMPTY; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* static */ void michael@0: nsVariant::Traverse(const nsDiscriminatedUnion& data, michael@0: nsCycleCollectionTraversalCallback &cb) michael@0: { michael@0: switch(data.mType) michael@0: { michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mData"); michael@0: cb.NoteXPCOMChild(data.u.iface.mInterfaceValue); michael@0: break; michael@0: case nsIDataType::VTYPE_ARRAY: michael@0: switch(data.u.array.mArrayType) { michael@0: case nsIDataType::VTYPE_INTERFACE: michael@0: case nsIDataType::VTYPE_INTERFACE_IS: michael@0: { michael@0: nsISupports** p = (nsISupports**) data.u.array.mArrayValue; michael@0: for(uint32_t i = data.u.array.mArrayCount; i > 0; p++, i--) { michael@0: NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mData[i]"); michael@0: cb.NoteXPCOMChild(*p); michael@0: } michael@0: } michael@0: default: michael@0: break; michael@0: } michael@0: default: michael@0: break; michael@0: } michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: /***************************************************************************/ michael@0: // members... michael@0: michael@0: NS_IMPL_ISUPPORTS(nsVariant, nsIVariant, nsIWritableVariant) michael@0: michael@0: nsVariant::nsVariant() michael@0: : mWritable(true) michael@0: { michael@0: nsVariant::Initialize(&mData); michael@0: michael@0: #ifdef DEBUG michael@0: { michael@0: // Assert that the nsIDataType consts match the values #defined in michael@0: // xpt_struct.h. Bad things happen somewhere if they don't. michael@0: struct THE_TYPES {uint16_t a; uint16_t b;}; michael@0: static const THE_TYPES array[] = { michael@0: {nsIDataType::VTYPE_INT8 , TD_INT8 }, michael@0: {nsIDataType::VTYPE_INT16 , TD_INT16 }, michael@0: {nsIDataType::VTYPE_INT32 , TD_INT32 }, michael@0: {nsIDataType::VTYPE_INT64 , TD_INT64 }, michael@0: {nsIDataType::VTYPE_UINT8 , TD_UINT8 }, michael@0: {nsIDataType::VTYPE_UINT16 , TD_UINT16 }, michael@0: {nsIDataType::VTYPE_UINT32 , TD_UINT32 }, michael@0: {nsIDataType::VTYPE_UINT64 , TD_UINT64 }, michael@0: {nsIDataType::VTYPE_FLOAT , TD_FLOAT }, michael@0: {nsIDataType::VTYPE_DOUBLE , TD_DOUBLE }, michael@0: {nsIDataType::VTYPE_BOOL , TD_BOOL }, michael@0: {nsIDataType::VTYPE_CHAR , TD_CHAR }, michael@0: {nsIDataType::VTYPE_WCHAR , TD_WCHAR }, michael@0: {nsIDataType::VTYPE_VOID , TD_VOID }, michael@0: {nsIDataType::VTYPE_ID , TD_PNSIID }, michael@0: {nsIDataType::VTYPE_DOMSTRING , TD_DOMSTRING }, michael@0: {nsIDataType::VTYPE_CHAR_STR , TD_PSTRING }, michael@0: {nsIDataType::VTYPE_WCHAR_STR , TD_PWSTRING }, michael@0: {nsIDataType::VTYPE_INTERFACE , TD_INTERFACE_TYPE }, michael@0: {nsIDataType::VTYPE_INTERFACE_IS , TD_INTERFACE_IS_TYPE}, michael@0: {nsIDataType::VTYPE_ARRAY , TD_ARRAY }, michael@0: {nsIDataType::VTYPE_STRING_SIZE_IS , TD_PSTRING_SIZE_IS }, michael@0: {nsIDataType::VTYPE_WSTRING_SIZE_IS , TD_PWSTRING_SIZE_IS }, michael@0: {nsIDataType::VTYPE_UTF8STRING , TD_UTF8STRING }, michael@0: {nsIDataType::VTYPE_CSTRING , TD_CSTRING }, michael@0: {nsIDataType::VTYPE_ASTRING , TD_ASTRING } michael@0: }; michael@0: static const int length = sizeof(array)/sizeof(array[0]); michael@0: static bool inited = false; michael@0: if(!inited) michael@0: { michael@0: for(int i = 0; i < length; i++) michael@0: NS_ASSERTION(array[i].a == array[i].b, "bad const declaration"); michael@0: inited = true; michael@0: } michael@0: } michael@0: #endif michael@0: } michael@0: michael@0: nsVariant::~nsVariant() michael@0: { michael@0: nsVariant::Cleanup(&mData); michael@0: } michael@0: michael@0: // For all the data getters we just forward to the static (and sharable) michael@0: // 'ConvertTo' functions. michael@0: michael@0: /* readonly attribute uint16_t dataType; */ michael@0: NS_IMETHODIMP nsVariant::GetDataType(uint16_t *aDataType) michael@0: { michael@0: *aDataType = mData.mType; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* uint8_t getAsInt8 (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsInt8(uint8_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToInt8(mData, _retval); michael@0: } michael@0: michael@0: /* int16_t getAsInt16 (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsInt16(int16_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToInt16(mData, _retval); michael@0: } michael@0: michael@0: /* int32_t getAsInt32 (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsInt32(int32_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToInt32(mData, _retval); michael@0: } michael@0: michael@0: /* int64_t getAsInt64 (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsInt64(int64_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToInt64(mData, _retval); michael@0: } michael@0: michael@0: /* uint8_t getAsUint8 (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsUint8(uint8_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToUint8(mData, _retval); michael@0: } michael@0: michael@0: /* uint16_t getAsUint16 (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsUint16(uint16_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToUint16(mData, _retval); michael@0: } michael@0: michael@0: /* uint32_t getAsUint32 (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsUint32(uint32_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToUint32(mData, _retval); michael@0: } michael@0: michael@0: /* uint64_t getAsUint64 (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsUint64(uint64_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToUint64(mData, _retval); michael@0: } michael@0: michael@0: /* float getAsFloat (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsFloat(float *_retval) michael@0: { michael@0: return nsVariant::ConvertToFloat(mData, _retval); michael@0: } michael@0: michael@0: /* double getAsDouble (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsDouble(double *_retval) michael@0: { michael@0: return nsVariant::ConvertToDouble(mData, _retval); michael@0: } michael@0: michael@0: /* bool getAsBool (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsBool(bool *_retval) michael@0: { michael@0: return nsVariant::ConvertToBool(mData, _retval); michael@0: } michael@0: michael@0: /* char getAsChar (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsChar(char *_retval) michael@0: { michael@0: return nsVariant::ConvertToChar(mData, _retval); michael@0: } michael@0: michael@0: /* wchar getAsWChar (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsWChar(char16_t *_retval) michael@0: { michael@0: return nsVariant::ConvertToWChar(mData, _retval); michael@0: } michael@0: michael@0: /* [notxpcom] nsresult getAsID (out nsID retval); */ michael@0: NS_IMETHODIMP_(nsresult) nsVariant::GetAsID(nsID *retval) michael@0: { michael@0: return nsVariant::ConvertToID(mData, retval); michael@0: } michael@0: michael@0: /* AString getAsAString (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsAString(nsAString & _retval) michael@0: { michael@0: return nsVariant::ConvertToAString(mData, _retval); michael@0: } michael@0: michael@0: /* DOMString getAsDOMString (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsDOMString(nsAString & _retval) michael@0: { michael@0: // A DOMString maps to an AString internally, so we can re-use michael@0: // ConvertToAString here. michael@0: return nsVariant::ConvertToAString(mData, _retval); michael@0: } michael@0: michael@0: /* ACString getAsACString (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsACString(nsACString & _retval) michael@0: { michael@0: return nsVariant::ConvertToACString(mData, _retval); michael@0: } michael@0: michael@0: /* AUTF8String getAsAUTF8String (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsAUTF8String(nsAUTF8String & _retval) michael@0: { michael@0: return nsVariant::ConvertToAUTF8String(mData, _retval); michael@0: } michael@0: michael@0: /* string getAsString (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsString(char **_retval) michael@0: { michael@0: return nsVariant::ConvertToString(mData, _retval); michael@0: } michael@0: michael@0: /* wstring getAsWString (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsWString(char16_t **_retval) michael@0: { michael@0: return nsVariant::ConvertToWString(mData, _retval); michael@0: } michael@0: michael@0: /* nsISupports getAsISupports (); */ michael@0: NS_IMETHODIMP nsVariant::GetAsISupports(nsISupports **_retval) michael@0: { michael@0: return nsVariant::ConvertToISupports(mData, _retval); michael@0: } michael@0: michael@0: /* jsval getAsJSVal() */ michael@0: NS_IMETHODIMP nsVariant::GetAsJSVal(JS::MutableHandleValue) michael@0: { michael@0: // Can only get the jsval from an XPCVariant. michael@0: return NS_ERROR_CANNOT_CONVERT_DATA; michael@0: } michael@0: michael@0: /* void getAsInterface (out nsIIDPtr iid, [iid_is (iid), retval] out nsQIResult iface); */ michael@0: NS_IMETHODIMP nsVariant::GetAsInterface(nsIID * *iid, void * *iface) michael@0: { michael@0: return nsVariant::ConvertToInterface(mData, iid, iface); michael@0: } michael@0: michael@0: /* [notxpcom] nsresult getAsArray (out uint16_t type, out nsIID iid, out uint32_t count, out voidPtr ptr); */ michael@0: NS_IMETHODIMP_(nsresult) nsVariant::GetAsArray(uint16_t *type, nsIID *iid, uint32_t *count, void * *ptr) michael@0: { michael@0: return nsVariant::ConvertToArray(mData, type, iid, count, ptr); michael@0: } michael@0: michael@0: /* void getAsStringWithSize (out uint32_t size, [size_is (size), retval] out string str); */ michael@0: NS_IMETHODIMP nsVariant::GetAsStringWithSize(uint32_t *size, char **str) michael@0: { michael@0: return nsVariant::ConvertToStringWithSize(mData, size, str); michael@0: } michael@0: michael@0: /* void getAsWStringWithSize (out uint32_t size, [size_is (size), retval] out wstring str); */ michael@0: NS_IMETHODIMP nsVariant::GetAsWStringWithSize(uint32_t *size, char16_t **str) michael@0: { michael@0: return nsVariant::ConvertToWStringWithSize(mData, size, str); michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: /* attribute bool writable; */ michael@0: NS_IMETHODIMP nsVariant::GetWritable(bool *aWritable) michael@0: { michael@0: *aWritable = mWritable; michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP nsVariant::SetWritable(bool aWritable) michael@0: { michael@0: if(!mWritable && aWritable) michael@0: return NS_ERROR_FAILURE; michael@0: mWritable = aWritable; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: // For all the data setters we just forward to the static (and sharable) michael@0: // 'SetFrom' functions. michael@0: michael@0: /* void setAsInt8 (in uint8_t aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsInt8(uint8_t aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromInt8(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsInt16 (in int16_t aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsInt16(int16_t aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromInt16(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsInt32 (in int32_t aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsInt32(int32_t aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromInt32(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsInt64 (in int64_t aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsInt64(int64_t aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromInt64(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsUint8 (in uint8_t aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsUint8(uint8_t aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromUint8(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsUint16 (in uint16_t aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsUint16(uint16_t aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromUint16(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsUint32 (in uint32_t aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsUint32(uint32_t aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromUint32(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsUint64 (in uint64_t aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsUint64(uint64_t aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromUint64(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsFloat (in float aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsFloat(float aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromFloat(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsDouble (in double aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsDouble(double aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromDouble(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsBool (in bool aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsBool(bool aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromBool(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsChar (in char aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsChar(char aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromChar(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsWChar (in wchar aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsWChar(char16_t aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromWChar(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsID (in nsIDRef aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsID(const nsID & aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromID(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsAString (in AString aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsAString(const nsAString & aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromAString(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsDOMString (in DOMString aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsDOMString(const nsAString & aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: michael@0: DATA_SETTER_PROLOGUE((&mData)); michael@0: if(!(mData.u.mAStringValue = new nsString(aValue))) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: DATA_SETTER_EPILOGUE((&mData), VTYPE_DOMSTRING); michael@0: } michael@0: michael@0: /* void setAsACString (in ACString aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsACString(const nsACString & aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromACString(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsAUTF8String (in AUTF8String aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsAUTF8String(const nsAUTF8String & aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromAUTF8String(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsString (in string aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsString(const char *aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromString(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsWString (in wstring aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsWString(const char16_t *aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromWString(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsISupports (in nsISupports aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetAsISupports(nsISupports *aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromISupports(&mData, aValue); michael@0: } michael@0: michael@0: /* void setAsInterface (in nsIIDRef iid, [iid_is (iid)] in nsQIResult iface); */ michael@0: NS_IMETHODIMP nsVariant::SetAsInterface(const nsIID & iid, void * iface) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromInterface(&mData, iid, (nsISupports*)iface); michael@0: } michael@0: michael@0: /* [noscript] void setAsArray (in uint16_t type, in nsIIDPtr iid, in uint32_t count, in voidPtr ptr); */ michael@0: NS_IMETHODIMP nsVariant::SetAsArray(uint16_t type, const nsIID * iid, uint32_t count, void * ptr) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromArray(&mData, type, iid, count, ptr); michael@0: } michael@0: michael@0: /* void setAsStringWithSize (in uint32_t size, [size_is (size)] in string str); */ michael@0: NS_IMETHODIMP nsVariant::SetAsStringWithSize(uint32_t size, const char *str) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromStringWithSize(&mData, size, str); michael@0: } michael@0: michael@0: /* void setAsWStringWithSize (in uint32_t size, [size_is (size)] in wstring str); */ michael@0: NS_IMETHODIMP nsVariant::SetAsWStringWithSize(uint32_t size, const char16_t *str) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromWStringWithSize(&mData, size, str); michael@0: } michael@0: michael@0: /* void setAsVoid (); */ michael@0: NS_IMETHODIMP nsVariant::SetAsVoid() michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetToVoid(&mData); michael@0: } michael@0: michael@0: /* void setAsEmpty (); */ michael@0: NS_IMETHODIMP nsVariant::SetAsEmpty() michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetToEmpty(&mData); michael@0: } michael@0: michael@0: /* void setAsEmptyArray (); */ michael@0: NS_IMETHODIMP nsVariant::SetAsEmptyArray() michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetToEmptyArray(&mData); michael@0: } michael@0: michael@0: /* void setFromVariant (in nsIVariant aValue); */ michael@0: NS_IMETHODIMP nsVariant::SetFromVariant(nsIVariant *aValue) michael@0: { michael@0: if(!mWritable) return NS_ERROR_OBJECT_IS_IMMUTABLE; michael@0: return nsVariant::SetFromVariant(&mData, aValue); michael@0: }