Back to index

lightning-sunbird  0.9+nobinonly
xpctest_variant.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla Communicator client code, released
00017  * March 31, 1998.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1998
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   John Bandhauer <jband@netscape.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 /* implement nsITestVariant for testing. */
00042 
00043 #include "xpctest_private.h"
00044 #include "nsString.h"
00045 
00046 class nsTestVariant : public nsITestVariant
00047 {
00048 public:
00049   NS_DECL_ISUPPORTS
00050   NS_DECL_NSITESTVARIANT
00051 
00052   nsTestVariant();
00053   virtual ~nsTestVariant();
00054 };
00055 
00056 NS_IMPL_ISUPPORTS1(nsTestVariant, nsITestVariant)
00057 
00058 nsTestVariant::nsTestVariant()
00059 {
00060 }
00061 
00062 nsTestVariant::~nsTestVariant()
00063 {
00064 }
00065 
00066 /* nsIVariant passThruVariant (in nsIVariant value); */
00067 NS_IMETHODIMP nsTestVariant::PassThruVariant(nsIVariant *value, nsIVariant **_retval)
00068 {
00069     *_retval = value;
00070     NS_IF_ADDREF(*_retval);
00071     return NS_OK;
00072 }
00073 
00074 /* PRUint16 returnVariantType (in nsIVariant value); */
00075 NS_IMETHODIMP nsTestVariant::ReturnVariantType(nsIVariant *value, PRUint16 *_retval)
00076 {
00077     return value->GetDataType(_retval);
00078 }
00079 
00080 #define MEMBER_COPY(type_)                                                    \
00081     rv = inVar->GetAs##type_(&du.u.m##type_##Value);                          \
00082     if(NS_FAILED(rv)) return rv;                                              \
00083     rv = outVar->SetAs##type_(du.u.m##type_##Value);                          \
00084     NS_ENSURE_SUCCESS(rv,rv);
00085 
00086 #define MEMBER_COPY_CAST(type_, cast_)                                        \
00087     rv = inVar->GetAs##type_( (cast_*) &du.u.m##type_##Value);                \
00088     if(NS_FAILED(rv)) return rv;                                              \
00089     rv = outVar->SetAs##type_( (cast_) du.u.m##type_##Value);                 \
00090     NS_ENSURE_SUCCESS(rv,rv);
00091 
00092 static nsresult ConvertAndCopyVariant(nsIVariant *inVar, PRUint16 type, nsIVariant **_retval)
00093 {
00094     nsresult rv;
00095     
00096     nsCOMPtr<nsIWritableVariant> outVar;
00097     outVar = do_CreateInstance("@mozilla.org/variant;1");
00098     if(!outVar)
00099         return NS_ERROR_FAILURE;
00100 
00101     PRUint16 inVarType;
00102     rv = inVar->GetDataType(&inVarType);
00103     if(NS_FAILED(rv))
00104         return rv;
00105 
00106     nsDiscriminatedUnion du;
00107     nsVariant::Initialize(&du);
00108 
00109     switch(type)
00110     {
00111     case nsIDataType::VTYPE_INT8:
00112         MEMBER_COPY_CAST(Int8, PRUint8)
00113         break;
00114     case nsIDataType::VTYPE_INT16:
00115         MEMBER_COPY(Int16)
00116         break;
00117     case nsIDataType::VTYPE_INT32:        
00118         MEMBER_COPY(Int32)
00119         break;
00120     case nsIDataType::VTYPE_INT64:        
00121         MEMBER_COPY(Int64)
00122         break;
00123     case nsIDataType::VTYPE_UINT8:        
00124         MEMBER_COPY(Uint8)
00125         break;
00126     case nsIDataType::VTYPE_UINT16:        
00127         MEMBER_COPY(Uint16)
00128         break;
00129     case nsIDataType::VTYPE_UINT32:        
00130         MEMBER_COPY(Uint32)
00131         break;
00132     case nsIDataType::VTYPE_UINT64:        
00133         MEMBER_COPY(Uint64)
00134         break;
00135     case nsIDataType::VTYPE_FLOAT:        
00136         MEMBER_COPY(Float)
00137         break;
00138     case nsIDataType::VTYPE_DOUBLE:        
00139         MEMBER_COPY(Double)
00140         break;
00141     case nsIDataType::VTYPE_BOOL:        
00142         MEMBER_COPY(Bool)
00143         break;
00144     case nsIDataType::VTYPE_CHAR:        
00145         MEMBER_COPY(Char)
00146         break;
00147     case nsIDataType::VTYPE_WCHAR:        
00148         MEMBER_COPY(WChar)
00149         break;
00150     case nsIDataType::VTYPE_VOID:        
00151         if(inVarType != nsIDataType::VTYPE_VOID)
00152             return NS_ERROR_CANNOT_CONVERT_DATA;
00153         rv = outVar->SetAsVoid();
00154         NS_ENSURE_SUCCESS(rv,rv);
00155         break;
00156     case nsIDataType::VTYPE_ID:        
00157         MEMBER_COPY(ID)
00158         break;
00159     case nsIDataType::VTYPE_ASTRING:        
00160     case nsIDataType::VTYPE_DOMSTRING:
00161     {
00162         nsAutoString str;
00163         rv = inVar->GetAsAString(str);
00164         if(NS_FAILED(rv)) return rv;
00165         rv = outVar->SetAsAString(str);
00166         NS_ENSURE_SUCCESS(rv,rv);
00167         break;
00168     }
00169     case nsIDataType::VTYPE_UTF8STRING:
00170     {
00171         nsUTF8String str;
00172         rv = inVar->GetAsAUTF8String(str);
00173         if(NS_FAILED(rv)) return rv;
00174         rv = outVar->SetAsAUTF8String(str);
00175         NS_ENSURE_SUCCESS(rv,rv);
00176         break;
00177     }
00178     case nsIDataType::VTYPE_CSTRING:
00179     {
00180         nsCAutoString str;
00181         rv = inVar->GetAsACString(str);
00182         if(NS_FAILED(rv)) return rv;
00183         rv = outVar->SetAsACString(str);
00184         NS_ENSURE_SUCCESS(rv,rv);
00185         break;
00186     }    
00187     case nsIDataType::VTYPE_CHAR_STR:        
00188     {
00189         char* str;
00190         rv = inVar->GetAsString(&str);
00191         if(NS_FAILED(rv)) return rv;
00192         rv = outVar->SetAsString(str);
00193         if(str) nsMemory::Free(str);
00194         NS_ENSURE_SUCCESS(rv,rv);
00195         break;
00196     }
00197     case nsIDataType::VTYPE_STRING_SIZE_IS:        
00198     {
00199         char* str;
00200         PRUint32 size;
00201         rv = inVar->GetAsStringWithSize(&size, &str);
00202         if(NS_FAILED(rv)) return rv;
00203         rv = outVar->SetAsStringWithSize(size, str);
00204         if(str) nsMemory::Free(str);
00205         NS_ENSURE_SUCCESS(rv,rv);
00206         break;
00207     }
00208     case nsIDataType::VTYPE_WCHAR_STR:        
00209     {
00210         PRUnichar* str;
00211         rv = inVar->GetAsWString(&str);
00212         if(NS_FAILED(rv)) return rv;
00213         rv = outVar->SetAsWString(str);
00214         if(str) nsMemory::Free((char*)str);
00215         NS_ENSURE_SUCCESS(rv,rv);
00216         break;
00217     }
00218     case nsIDataType::VTYPE_WSTRING_SIZE_IS:        
00219     {
00220         PRUnichar* str;
00221         PRUint32 size;
00222         rv = inVar->GetAsWStringWithSize(&size, &str);
00223         if(NS_FAILED(rv)) return rv;
00224         rv = outVar->SetAsWStringWithSize(size, str);
00225         if(str) nsMemory::Free((char*)str);
00226         NS_ENSURE_SUCCESS(rv,rv);
00227         break;
00228     }
00229     case nsIDataType::VTYPE_INTERFACE:        
00230     {
00231         nsISupports* ptr;
00232         rv = inVar->GetAsISupports(&ptr);
00233         if(NS_FAILED(rv)) return rv;
00234         rv = outVar->SetAsISupports(ptr);
00235         NS_IF_RELEASE(ptr);
00236         NS_ENSURE_SUCCESS(rv,rv);
00237         break;
00238     }
00239     case nsIDataType::VTYPE_INTERFACE_IS:        
00240     {
00241         nsISupports* ptr;
00242         nsIID* iid;
00243         rv = inVar->GetAsInterface(&iid, (void**)&ptr);
00244         if(NS_FAILED(rv)) return rv;
00245         rv = outVar->SetAsInterface(*iid, ptr);
00246         NS_IF_RELEASE(ptr);
00247         if(iid) nsMemory::Free((char*)iid);
00248         NS_ENSURE_SUCCESS(rv,rv);
00249         break;
00250     }
00251         break;
00252     case nsIDataType::VTYPE_ARRAY:
00253         rv = inVar->GetAsArray(&du.u.array.mArrayType,
00254                                &du.u.array.mArrayInterfaceID,
00255                                &du.u.array.mArrayCount,
00256                                &du.u.array.mArrayValue);
00257         if(NS_FAILED(rv)) return rv;
00258         du.mType = type;
00259         rv = outVar->SetAsArray(du.u.array.mArrayType,
00260                                 &du.u.array.mArrayInterfaceID,
00261                                 du.u.array.mArrayCount,
00262                                 du.u.array.mArrayValue);
00263         NS_ENSURE_SUCCESS(rv,rv);
00264         break;
00265     case nsIDataType::VTYPE_EMPTY_ARRAY:
00266         if(inVarType != nsIDataType::VTYPE_EMPTY_ARRAY)
00267             return NS_ERROR_CANNOT_CONVERT_DATA;
00268         rv = outVar->SetAsEmptyArray();
00269         NS_ENSURE_SUCCESS(rv,rv);
00270         break;        
00271     case nsIDataType::VTYPE_EMPTY:
00272         if(inVarType != nsIDataType::VTYPE_EMPTY)
00273             return NS_ERROR_CANNOT_CONVERT_DATA;
00274         rv = outVar->SetAsEmpty();
00275         NS_ENSURE_SUCCESS(rv,rv);
00276         break;
00277     default:
00278         NS_ERROR("bad type in variant!");
00279         break;
00280     }
00281 
00282     nsVariant::Cleanup(&du);
00283     *_retval = outVar;
00284     NS_IF_ADDREF(*_retval);
00285     return NS_OK;
00286 }        
00287 
00288 
00289 /* nsIVariant copyVariant (in nsIVariant value); */
00290 NS_IMETHODIMP nsTestVariant::CopyVariant(nsIVariant *value, nsIVariant **_retval)
00291 {
00292     PRUint16 type;
00293     if(NS_FAILED(value->GetDataType(&type)))
00294         return NS_ERROR_FAILURE;
00295     return ConvertAndCopyVariant(value, type, _retval);
00296 }
00297 
00298 /* nsIVariant copyVariantAsType (in nsIVariant value, in PRUint16 type); */
00299 NS_IMETHODIMP nsTestVariant::CopyVariantAsType(nsIVariant *value, PRUint16 type, nsIVariant **_retval)
00300 {
00301     return ConvertAndCopyVariant(value, type, _retval);
00302 }
00303 
00304 /* nsIVariant copyVariantAsTypeTwice (in nsIVariant value, in PRUint16 type1, in PRUint16 type2); */
00305 NS_IMETHODIMP nsTestVariant::CopyVariantAsTypeTwice(nsIVariant *value, PRUint16 type1, PRUint16 type2, nsIVariant **_retval)
00306 {
00307     nsCOMPtr<nsIVariant> temp;
00308     nsresult rv = ConvertAndCopyVariant(value, type1, getter_AddRefs(temp));
00309     if(NS_FAILED(rv))
00310         return rv;
00311     return ConvertAndCopyVariant(temp, type2, _retval);
00312 }
00313 
00314 /* nsIVariant getNamedProperty (in nsISupports aBag, in AString aName); */
00315 NS_IMETHODIMP nsTestVariant::GetNamedProperty(nsISupports *aObj, const nsAString & aName, nsIVariant **_retval)
00316 {
00317     nsresult rv;
00318     nsCOMPtr<nsIPropertyBag> bag = do_QueryInterface(aObj, &rv);
00319     if(!bag)
00320         return rv;
00321     return bag->GetProperty(aName, _retval);
00322 }
00323 
00324 /* nsISimpleEnumerator getEnumerator (in nsISupports aBag); */
00325 NS_IMETHODIMP nsTestVariant::GetEnumerator(nsISupports *aObj, nsISimpleEnumerator **_retval)
00326 {
00327     nsresult rv;
00328     nsCOMPtr<nsIPropertyBag> bag = do_QueryInterface(aObj, &rv);
00329     if(!bag)
00330         return rv;
00331     return bag->GetEnumerator(_retval);
00332 }
00333 
00334 /***************************************************************************/
00335 
00336 // static
00337 NS_IMETHODIMP
00338 xpctest::ConstructXPCTestVariant(nsISupports *aOuter, REFNSIID aIID, void **aResult)
00339 {
00340     nsresult rv;
00341     NS_ASSERTION(aOuter == nsnull, "no aggregation");
00342     nsTestVariant* obj = new nsTestVariant();
00343 
00344     if(!obj)
00345     {
00346         *aResult = nsnull;
00347         rv = NS_ERROR_OUT_OF_MEMORY;
00348     }
00349 
00350     NS_ADDREF(obj);
00351     rv = obj->QueryInterface(aIID, aResult);
00352     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
00353     NS_RELEASE(obj);
00354     return rv;
00355 }