LCOV - code coverage report
Current view: directory - xpcom/ds - nsVariant.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 834 248 29.7 %
Date: 2012-06-02 Functions: 127 61 48.0 %

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

Generated by: LCOV version 1.7