Back to index

lightning-sunbird  0.9+nobinonly
nsXTFInterfaceAggregator.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Mozilla XTF project.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Alex Fritze.
00019  * Portions created by the Initial Developer are Copyright (C) 2004
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Alex Fritze <alex@croczilla.com> (original author)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsCOMPtr.h"
00040 #include "xptcall.h"
00041 #include "nsIInterfaceInfo.h"
00042 #include "nsIInterfaceInfoManager.h"
00043 #ifdef DEBUG
00044 #include <stdio.h>
00045 #endif
00046 
00048 // nsXTFInterfaceAggregator class
00049 
00050 class nsXTFInterfaceAggregator : public nsXPTCStubBase
00051 {
00052 protected:
00053   friend nsresult
00054   NS_NewXTFInterfaceAggregator(const nsIID& iid,
00055                                nsISupports* inner,
00056                                nsISupports* outer,
00057                                void** result);
00058 
00059   nsXTFInterfaceAggregator(const nsIID& iid,
00060                            nsISupports* inner,
00061                            nsISupports* outer);
00062   ~nsXTFInterfaceAggregator();
00063   
00064 public:
00065   // nsISupports interface
00066   NS_DECL_ISUPPORTS
00067   
00068   // nsXPTCStubBase
00069   NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info);
00070 
00071   NS_IMETHOD CallMethod(PRUint16 methodIndex,
00072                         const nsXPTMethodInfo* info,
00073                         nsXPTCMiniVariant* params);
00074 
00075 private:
00076   nsISupports *mInner;
00077   nsISupports *mOuter;
00078   nsIID mIID;
00079 };
00080 
00081 //----------------------------------------------------------------------
00082 // implementation:
00083 
00084 nsXTFInterfaceAggregator::nsXTFInterfaceAggregator(const nsIID& iid,
00085                                                    nsISupports* inner,
00086                                                    nsISupports* outer)
00087     : mInner(inner), mOuter(outer), mIID(iid)
00088 {
00089 #ifdef DEBUG
00090 //  printf("nsXTFInterfaceAggregator CTOR\n");
00091 #endif
00092   mInner->AddRef();
00093   mOuter->AddRef();
00094 }
00095 
00096 nsXTFInterfaceAggregator::~nsXTFInterfaceAggregator()
00097 {
00098 #ifdef DEBUG
00099 //  printf("nsXTFInterfaceAggregator DTOR\n");
00100 #endif
00101   mInner->Release();
00102   mOuter->Release();
00103 }
00104 
00105 nsresult
00106 NS_NewXTFInterfaceAggregator(const nsIID& iid,
00107                              nsISupports* inner,
00108                              nsISupports* outer,
00109                              void** aResult){
00110   NS_PRECONDITION(aResult != nsnull, "null ptr");
00111   if (!aResult)
00112     return NS_ERROR_NULL_POINTER;
00113 
00114   nsXTFInterfaceAggregator* result = new nsXTFInterfaceAggregator(iid,inner,outer);
00115   if (!result)
00116     return NS_ERROR_OUT_OF_MEMORY;
00117 
00118   NS_ADDREF(result);
00119   *aResult = result;
00120   return NS_OK;
00121 }
00122 
00123 //----------------------------------------------------------------------
00124 // nsISupports implementation
00125 
00126 NS_IMPL_ADDREF(nsXTFInterfaceAggregator)
00127 NS_IMPL_RELEASE(nsXTFInterfaceAggregator)
00128 
00129 NS_IMETHODIMP
00130 nsXTFInterfaceAggregator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
00131 {
00132   if(aIID.Equals(mIID)) {
00133     *aInstancePtr = NS_STATIC_CAST(nsXPTCStubBase*, this);
00134     NS_ADDREF_THIS();
00135     return NS_OK;
00136   }
00137   else return mOuter->QueryInterface(aIID, aInstancePtr);
00138 }
00139 
00140 //----------------------------------------------------------------------
00141 // nsXPTCStubBase implementation
00142 
00143 NS_IMETHODIMP
00144 nsXTFInterfaceAggregator::GetInterfaceInfo(nsIInterfaceInfo** info)
00145 {
00146   nsCOMPtr<nsIInterfaceInfoManager> iim = XPTI_GetInterfaceInfoManager();
00147   NS_ASSERTION(iim, "could not get interface info manager");
00148   return iim->GetInfoForIID( &mIID, info);
00149 }
00150 
00151 NS_IMETHODIMP
00152 nsXTFInterfaceAggregator::CallMethod(PRUint16 methodIndex,
00153                                      const nsXPTMethodInfo* info,
00154                                      nsXPTCMiniVariant* params)
00155 {
00156   if (methodIndex < 3) {
00157     NS_ERROR("huh? indirect nsISupports method call unexpected on nsXTFInterfaceAggregator.");
00158     return NS_ERROR_FAILURE;
00159   }
00160 
00161   // prepare args:
00162   int paramCount = info->GetParamCount();
00163   nsXPTCVariant* fullPars = paramCount ? new nsXPTCVariant[paramCount] : nsnull;
00164 
00165   for (int i=0; i<paramCount; ++i) {
00166     const nsXPTParamInfo& paramInfo = info->GetParam(i);
00167     PRUint8 flags = paramInfo.IsOut() ? nsXPTCVariant::PTR_IS_DATA : 0;
00168     fullPars[i].Init(params[i], paramInfo.GetType(), flags);
00169   }
00170   
00171   // make the call:
00172   nsresult rv = XPTC_InvokeByIndex(mInner,
00173                                    methodIndex,
00174                                    paramCount,
00175                                    fullPars);
00176   if (fullPars)
00177     delete []fullPars;
00178   return rv;
00179 }