Back to index

lightning-sunbird  0.9+nobinonly
xpctest_array.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 nsIXPCTestString for testing. */
00042 
00043 #include "xpctest_private.h"
00044 
00045 class xpcarraytest : public nsIXPCTestArray
00046 {
00047 public:
00048     NS_DECL_ISUPPORTS
00049     NS_DECL_NSIXPCTESTARRAY
00050 
00051     xpcarraytest();
00052     virtual ~xpcarraytest();
00053 private:
00054     nsIXPCTestArray* mReceiver;
00055 };
00056 
00057 xpcarraytest::xpcarraytest()
00058     : mReceiver(NULL)
00059 {
00060     NS_ADDREF_THIS();
00061 }
00062 
00063 xpcarraytest::~xpcarraytest()
00064 {
00065     NS_IF_RELEASE(mReceiver);
00066 }
00067 
00068 NS_IMPL_ISUPPORTS1(xpcarraytest, nsIXPCTestArray)
00069 
00070 NS_IMETHODIMP xpcarraytest::SetReceiver(nsIXPCTestArray* aReceiver)
00071 {
00072     NS_IF_ADDREF(aReceiver);
00073     NS_IF_RELEASE(mReceiver);
00074     mReceiver = aReceiver;
00075 
00076     // a test that forces a QI to some other arbitrary type.
00077     if(mReceiver)
00078     {
00079         nsCOMPtr<nsIEcho> echo = do_QueryInterface(mReceiver);
00080     }
00081 
00082     return NS_OK;
00083 }
00084 
00085 
00086 /* void PrintIntegerArray (in PRUint32 count, [array, size_is (count)] in PRInt32 valueArray); */
00087 NS_IMETHODIMP
00088 xpcarraytest::PrintIntegerArray(PRUint32 count, PRInt32 *valueArray)
00089 {
00090     if(mReceiver)
00091         return mReceiver->PrintIntegerArray(count, valueArray);
00092     if(valueArray && count)
00093     {
00094         for(PRUint32 i = 0; i < count; i++)
00095             printf("%d%s", valueArray[i], i == count -1 ? "\n" : ",");
00096     }
00097     else
00098         printf("empty array\n");
00099 
00100     return NS_OK;
00101 }
00102 
00103 /* void PrintStringArray (in PRUint32 count, [array, size_is (count)] in string valueArray); */
00104 NS_IMETHODIMP
00105 xpcarraytest::PrintStringArray(PRUint32 count, const char **valueArray)
00106 {
00107     if(mReceiver)
00108         return mReceiver->PrintStringArray(count, valueArray);
00109     if(valueArray && count)
00110     {
00111         for(PRUint32 i = 0; i < count; i++)
00112             printf("\"%s\"%s", valueArray[i], i == count -1 ? "\n" : ",");
00113     }
00114     else
00115         printf("empty array\n");
00116 
00117     return NS_OK;
00118 }
00119 
00120 /* void MultiplyEachItemInIntegerArray (in PRInt32 val, in PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
00121 NS_IMETHODIMP
00122 xpcarraytest::MultiplyEachItemInIntegerArray(PRInt32 val, PRUint32 count, PRInt32 **valueArray)
00123 {
00124     if(mReceiver)
00125         return mReceiver->MultiplyEachItemInIntegerArray(val, count, valueArray);
00126     PRInt32* a;
00127     if(valueArray && count && nsnull != (a = *valueArray))
00128     {
00129         for(PRUint32 i = 0; i < count; i++)
00130             a[i] *= val;
00131         return NS_OK;
00132     }
00133     return NS_ERROR_FAILURE;
00134 }        
00135 
00136 /* void MultiplyEachItemInIntegerArrayAndAppend (in PRInt32 val, inout PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
00137 NS_IMETHODIMP
00138 xpcarraytest::MultiplyEachItemInIntegerArrayAndAppend(PRInt32 val, PRUint32 *count, PRInt32 **valueArray)
00139 {
00140     if(mReceiver)
00141         return mReceiver->MultiplyEachItemInIntegerArrayAndAppend(val, count, valueArray);
00142     PRInt32* in;
00143     PRUint32 in_count;
00144     if(valueArray && count && 0 != (in_count = *count) && nsnull != (in = *valueArray))
00145     {
00146         PRInt32* out = 
00147             (PRInt32*) nsMemory::Alloc(in_count * 2 * sizeof(PRUint32));
00148 
00149         if(!out)
00150             return NS_ERROR_OUT_OF_MEMORY;
00151 
00152         for(PRUint32 i = 0; i < in_count; i++)
00153         {
00154             out[i*2]   = in[i];
00155             out[i*2+1] = in[i] * val;
00156         }
00157         nsMemory::Free(in);
00158         *valueArray = out;
00159         *count = in_count * 2;
00160         return NS_OK;
00161     }
00162     return NS_ERROR_FAILURE;
00163 }        
00164 
00165 /* void CallEchoMethodOnEachInArray (inout nsIIDPtr uuid, inout PRUint32 count, [array, size_is (count), iid_is (uuid)] inout nsQIResult result); */
00166 NS_IMETHODIMP
00167 xpcarraytest::CallEchoMethodOnEachInArray(nsIID * *uuid, PRUint32 *count, void * **result)
00168 {
00169     NS_ENSURE_ARG_POINTER(uuid);
00170     NS_ENSURE_ARG_POINTER(count);
00171     NS_ENSURE_ARG_POINTER(result);
00172 
00173     if(mReceiver)
00174         return mReceiver->CallEchoMethodOnEachInArray(uuid, count, result);
00175 
00176     // check that this is the expected type
00177     if(!(*uuid)->Equals(NS_GET_IID(nsIEcho)))
00178         return NS_ERROR_FAILURE;
00179 
00180     // call each and release
00181     nsIEcho** ifaceArray = (nsIEcho**) *result;
00182     for(PRUint32 i = 0; i < *count; i++)
00183     {
00184         ifaceArray[i]->SendOneString("print this from C++");
00185         NS_RELEASE(ifaceArray[i]);
00186     }
00187 
00188     // cleanup
00189     nsMemory::Free(*uuid);
00190     nsMemory::Free(*result);
00191 
00192     // set up to hand over array of 'this'
00193 
00194     *uuid = (nsIID*) nsMemory::Clone(&NS_GET_IID(nsIXPCTestArray), 
00195                                         sizeof(nsIID));
00196     NS_ENSURE_TRUE(*uuid, NS_ERROR_OUT_OF_MEMORY);
00197 
00198     nsISupports** outArray = (nsISupports**) 
00199             nsMemory::Alloc(2 * sizeof(nsISupports*));
00200     if (!outArray) {
00201       nsMemory::Free(*uuid);
00202       return NS_ERROR_OUT_OF_MEMORY;
00203     }
00204 
00205     outArray[0] = outArray[1] = this;    
00206     NS_ADDREF(this);
00207     NS_ADDREF(this);
00208     *result = (void**) outArray;
00209 
00210     *count = 2;
00211 
00212     return NS_OK;
00213 }        
00214 
00215 /* void CallEchoMethodOnEachInArray2 (inout PRUint32 count, [array, size_is (count)] inout nsIEcho result); */
00216 NS_IMETHODIMP
00217 xpcarraytest::CallEchoMethodOnEachInArray2(PRUint32 *count, nsIEcho ***result)
00218 {
00219     NS_ENSURE_ARG_POINTER(count);
00220     NS_ENSURE_ARG_POINTER(result);
00221 
00222     if(mReceiver)
00223         return mReceiver->CallEchoMethodOnEachInArray2(count, result);
00224 
00225     // call each and release
00226     nsIEcho** ifaceArray =  *result;
00227     for(PRUint32 i = 0; i < *count; i++)
00228     {
00229         ifaceArray[i]->SendOneString("print this from C++");
00230         NS_RELEASE(ifaceArray[i]);
00231     }
00232 
00233     // cleanup
00234     nsMemory::Free(*result);
00235 
00236     // setup return
00237     *count = 0;
00238     *result = nsnull;
00239     return NS_OK;
00240 }        
00241 
00242 
00243 
00244 /* void DoubleStringArray (inout PRUint32 count, [array, size_is (count)] inout string valueArray); */
00245 NS_IMETHODIMP
00246 xpcarraytest::DoubleStringArray(PRUint32 *count, char ***valueArray)
00247 {
00248     NS_ENSURE_ARG_POINTER(valueArray);
00249     if(mReceiver)
00250         return mReceiver->DoubleStringArray(count, valueArray);
00251     if(!count || !*count)
00252         return NS_OK;
00253 
00254     char** outArray = (char**) nsMemory::Alloc(*count * 2 * sizeof(char*));
00255     if(!outArray)
00256         return NS_ERROR_OUT_OF_MEMORY;
00257     
00258     char** p = *valueArray;
00259     for(PRUint32 i = 0; i < *count; i++)
00260     {
00261         int len = strlen(p[i]);
00262         outArray[i*2] = (char*)nsMemory::Alloc(((len * 2)+1) * sizeof(char));                        
00263         outArray[(i*2)+1] = (char*)nsMemory::Alloc(((len * 2)+1) * sizeof(char));                        
00264 
00265         for(int k = 0; k < len; k++)
00266         {
00267             outArray[i*2][k*2] = outArray[i*2][(k*2)+1] =
00268             outArray[(i*2)+1][k*2] = outArray[(i*2)+1][(k*2)+1] = p[i][k];
00269         }
00270         outArray[i*2][len*2] = outArray[(i*2)+1][len*2] = '\0';
00271         nsMemory::Free(p[i]);
00272     }
00273 
00274     nsMemory::Free(p);
00275     *valueArray = outArray; 
00276     *count = *count * 2;
00277     return NS_OK;
00278 }        
00279 
00280 /* void ReverseStringArray (in PRUint32 count, [array, size_is (count)] inout string valueArray); */
00281 NS_IMETHODIMP
00282 xpcarraytest::ReverseStringArray(PRUint32 count, char ***valueArray)
00283 {
00284     NS_ENSURE_ARG_POINTER(valueArray);
00285     if(mReceiver)
00286         return mReceiver->ReverseStringArray(count, valueArray);
00287     if(!count)
00288         return NS_OK;
00289 
00290     char** p = *valueArray;
00291     for(PRUint32 i = 0; i < count/2; i++)
00292     {
00293         char* temp = p[i];
00294         p[i] = p[count-1-i];
00295         p[count-1-i] = temp;
00296     }
00297     return NS_OK;
00298 }
00299 
00300 /* void PrintStringWithSize (in PRUint32 count, [size_is (count)] in string str); */
00301 NS_IMETHODIMP
00302 xpcarraytest::PrintStringWithSize(PRUint32 count, const char *str)
00303 {
00304     if(mReceiver)
00305         return mReceiver->PrintStringWithSize(count, str);
00306     printf("\"%s\" : %d\n", str, count);
00307     return NS_OK;
00308 }        
00309 
00310 /* void DoubleString (inout PRUint32 count, [size_is (count)] inout string str); */
00311 NS_IMETHODIMP
00312 xpcarraytest::DoubleString(PRUint32 *count, char **str)
00313 {
00314     NS_ENSURE_ARG_POINTER(str);
00315     if(mReceiver)
00316         return mReceiver->DoubleString(count, str);
00317     if(!count || !*count)
00318         return NS_OK;
00319 
00320     char* out = (char*) nsMemory::Alloc(((*count * 2)+1) * sizeof(char));                        
00321     if(!out)
00322         return NS_ERROR_OUT_OF_MEMORY;
00323 
00324     PRUint32 k;
00325     for(k = 0; k < *count; k++)
00326         out[k*2] = out[(k*2)+1] = (*str)[k];
00327     out[k*2] = '\0';
00328     nsMemory::Free(*str);
00329     *str = out; 
00330     *count = *count * 2;
00331     return NS_OK;
00332 }        
00333 
00334 /* void GetStrings (out PRUint32 count, [array, size_is (count), retval] out string str); */
00335 NS_IMETHODIMP 
00336 xpcarraytest::GetStrings(PRUint32 *count, char ***str)
00337 {
00338     const static char *strings[] = {"one", "two", "three", "four"};
00339     const static PRUint32 scount = sizeof(strings)/sizeof(strings[0]);
00340 
00341     if(mReceiver)
00342         return mReceiver->GetStrings(count, str);
00343 
00344     char** out = (char**) nsMemory::Alloc(scount * sizeof(char*));
00345     if(!out)
00346         return NS_ERROR_OUT_OF_MEMORY;
00347     for(PRUint32 i = 0; i < scount; ++i)
00348     {
00349         out[i] = (char*) nsMemory::Clone(strings[i], strlen(strings[i])+1);
00350         // failure unlikely, leakage foolishly tolerated in this test case
00351         if(!out[i])
00352             return NS_ERROR_OUT_OF_MEMORY;
00353     }
00354 
00355     *count = scount;
00356     *str = out;
00357     return NS_OK;
00358 }
00359 
00360 /***************************************************************************/
00361 
00362 // static
00363 NS_IMETHODIMP
00364 xpctest::ConstructArrayTest(nsISupports *aOuter, REFNSIID aIID, void **aResult)
00365 {
00366     nsresult rv;
00367     NS_ASSERTION(aOuter == nsnull, "no aggregation");
00368     xpcarraytest* obj = new xpcarraytest();
00369 
00370     if(obj)
00371     {
00372         rv = obj->QueryInterface(aIID, aResult);
00373         NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
00374         NS_RELEASE(obj);
00375     }
00376     else
00377     {
00378         *aResult = nsnull;
00379         rv = NS_ERROR_OUT_OF_MEMORY;
00380     }
00381 
00382     return rv;
00383 }
00384 /***************************************************************************/
00385 
00386 
00387 
00388