LCOV - code coverage report
Current view: top level - xpcom/ds - nsVariant.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 158 952 16.6 %
Date: 2017-07-14 16:53:18 Functions: 42 133 31.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13