Back to index

lightning-sunbird  0.9+nobinonly
nsGenericInterfaceInfoSet.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /* The nsGenericInterfaceInfo/nsGenericInterfaceInfoSet implementations.*/
00039 
00040 #include "iixprivate.h"
00041 
00042 
00043 /***************************************************************************/
00044 // implement nsGenericInterfaceInfoSet
00045 
00046 #define ARENA_BLOCK_SIZE (1024 * 1)
00047 
00048 NS_IMPL_THREADSAFE_ISUPPORTS3(nsGenericInterfaceInfoSet,
00049                               nsIInterfaceInfoManager,
00050                               nsIGenericInterfaceInfoSet,
00051                               nsISupportsWeakReference)
00052 
00053 nsGenericInterfaceInfoSet::nsGenericInterfaceInfoSet()
00054 {
00055     mArena = XPT_NewArena(ARENA_BLOCK_SIZE, sizeof(double),
00056                           "nsGenericInterfaceInfoSet Arena");
00057 }
00058 
00059 nsGenericInterfaceInfoSet::~nsGenericInterfaceInfoSet()
00060 {
00061     PRInt32 count = mInterfaces.Count();
00062 
00063     for(PRInt32 i = 0; i < count; i++)
00064     {
00065         nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i);
00066         if(CheckOwnedFlag(info))
00067             delete (nsGenericInterfaceInfo*) ClearOwnedFlag(info);
00068         else
00069             NS_RELEASE(info);
00070     }
00071 
00072     if(mArena)
00073         XPT_DestroyArena(mArena);
00074 }
00075 
00076 nsresult
00077 nsGenericInterfaceInfoSet::IndexOfIID(const nsIID & aIID, PRUint16 *_retval)
00078 {
00079     PRInt32 count = mInterfaces.Count();
00080 
00081     for(PRInt32 i = 0; i < count; i++)
00082     {
00083         nsIInterfaceInfo* info = (nsIInterfaceInfo*)
00084             ClearOwnedFlag(mInterfaces.ElementAt(i));
00085         const nsID* iid;
00086         nsresult rv = info->GetIIDShared(&iid);
00087         if(NS_FAILED(rv))
00088             return rv;
00089         if(iid->Equals(aIID))
00090         {
00091             *_retval = (PRUint16) i;
00092             return NS_OK;
00093         }
00094     }
00095     return NS_ERROR_NO_INTERFACE;
00096 }
00097 
00098 nsresult
00099 nsGenericInterfaceInfoSet::IndexOfName(const char* aName, PRUint16 *_retval)
00100 {
00101     PRInt32 count = mInterfaces.Count();
00102 
00103     for(PRInt32 i = 0; i < count; i++)
00104     {
00105         nsIInterfaceInfo* info = (nsIInterfaceInfo*)
00106             ClearOwnedFlag(mInterfaces.ElementAt(i));
00107         const char* name;
00108         nsresult rv = info->GetNameShared(&name);
00109         if(NS_FAILED(rv))
00110             return rv;
00111         if(!strcmp(name, aName))
00112         {
00113             *_retval = (PRUint16) i;
00114             return NS_OK;
00115         }
00116     }
00117     return NS_ERROR_NO_INTERFACE;
00118 }
00119 
00120 /************************************************/
00121 // nsIGenericInterfaceInfoSet methods...
00122 
00123 /* XPTParamDescriptorPtr allocateParamArray (in PRUint16 aCount); */
00124 NS_IMETHODIMP
00125 nsGenericInterfaceInfoSet::AllocateParamArray(PRUint16 aCount,
00126                                               XPTParamDescriptor * *_retval)
00127 {
00128     *_retval = (XPTParamDescriptor*)
00129         XPT_MALLOC(GetArena(), sizeof(XPTParamDescriptor) * aCount);
00130     return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00131 }
00132 
00133 /* XPTTypeDescriptorPtr allocateAdditionalType (out PRUint16 aIndex); */
00134 NS_IMETHODIMP
00135 nsGenericInterfaceInfoSet::AllocateAdditionalType(PRUint16 *aIndex,
00136                                                   XPTTypeDescriptor * *_retval)
00137 {
00138     *_retval = (XPTTypeDescriptor*)
00139         XPT_MALLOC(GetArena(), sizeof(XPTTypeDescriptor));
00140     if(!*_retval || !mAdditionalTypes.AppendElement(*_retval))
00141         return NS_ERROR_OUT_OF_MEMORY;
00142     *aIndex = (PRUint16) mAdditionalTypes.Count()-1;
00143     return NS_OK;
00144 }
00145 
00146 /* PRUint16 createAndAppendInterface (in string aName, in nsIIDRef
00147    aIID, in PRUint16 aParent, in PRUint8 aFlags, out
00148    nsIGenericInterfaceInfo aInfo); */
00149 NS_IMETHODIMP
00150 nsGenericInterfaceInfoSet::CreateAndAppendInterface(const char *aName,
00151                                                     const nsIID & aIID,
00152                                                     PRUint16 aParent,
00153                                                     PRUint8 aFlags,
00154                                                     nsIGenericInterfaceInfo **aInfo,
00155                                                     PRUint16 *_retval)
00156 {
00157     nsGenericInterfaceInfo* info =
00158         new nsGenericInterfaceInfo(this, aName, aIID,
00159                                    (aParent == (PRUint16) -1) ?
00160                                         nsnull : InfoAtNoAddRef(aParent),
00161                                    aFlags);
00162     if(!info || !mInterfaces.AppendElement(SetOwnedFlag(info)))
00163         return NS_ERROR_OUT_OF_MEMORY;
00164 
00165     *_retval = (PRUint16) mInterfaces.Count()-1;
00166     return CallQueryInterface(info, aInfo);
00167 }
00168 
00169 /* PRUint16 appendExternalInterface (in nsIInterfaceInfo aInfo); */
00170 NS_IMETHODIMP
00171 nsGenericInterfaceInfoSet::AppendExternalInterface(nsIInterfaceInfo *aInfo,
00172                                                    PRUint16 *_retval)
00173 {
00174     if(!mInterfaces.AppendElement(aInfo))
00175         return NS_ERROR_OUT_OF_MEMORY;
00176 
00177     NS_ADDREF(aInfo);
00178     *_retval = (PRUint16) mInterfaces.Count()-1;
00179     return NS_OK;
00180 }
00181 
00182 /* PRUint16 indexOf (in nsIIDRef aIID); */
00183 NS_IMETHODIMP
00184 nsGenericInterfaceInfoSet::IndexOf(const nsIID & aIID, PRUint16 *_retval)
00185 {
00186     return IndexOfIID(aIID, _retval);
00187 }
00188 
00189 /* PRUint16 indexOfByName (in string aName); */
00190 NS_IMETHODIMP nsGenericInterfaceInfoSet::IndexOfByName(const char *aName,
00191                                                        PRUint16 *_retval)
00192 {
00193     return IndexOfName(aName, _retval);
00194 }
00195 
00196 /* nsIInterfaceInfo interfaceInfoAt (in PRUint16 aIndex); */
00197 NS_IMETHODIMP
00198 nsGenericInterfaceInfoSet::InterfaceInfoAt(PRUint16 aIndex,
00199                                            nsIInterfaceInfo **_retval)
00200 {
00201     NS_ASSERTION(aIndex < (PRUint16)mInterfaces.Count(), "bad index");
00202 
00203     *_retval = (nsIInterfaceInfo*)
00204         ClearOwnedFlag(mInterfaces.ElementAt(aIndex));
00205     NS_ADDREF(*_retval);
00206     return NS_OK;
00207 }
00208 
00209 /************************************************/
00210 // nsIInterfaceInfoManager methods...
00211 
00212 /* nsIInterfaceInfo getInfoForIID (in nsIIDPtr iid); */
00213 NS_IMETHODIMP
00214 nsGenericInterfaceInfoSet::GetInfoForIID(const nsIID * iid,
00215                                          nsIInterfaceInfo **_retval)
00216 {
00217     PRUint16 index;
00218     nsresult rv = IndexOfIID(*iid, &index);
00219     if(NS_FAILED(rv))
00220         return rv;
00221     return InterfaceInfoAt(index, _retval);
00222 }
00223 
00224 /* nsIInterfaceInfo getInfoForName (in string name); */
00225 NS_IMETHODIMP
00226 nsGenericInterfaceInfoSet::GetInfoForName(const char *name,
00227                                           nsIInterfaceInfo **_retval)
00228 {
00229     PRUint16 index;
00230     nsresult rv = IndexOfName(name, &index);
00231     if(NS_FAILED(rv))
00232         return rv;
00233     return InterfaceInfoAt(index, _retval);
00234 }
00235 
00236 /* nsIIDPtr getIIDForName (in string name); */
00237 NS_IMETHODIMP
00238 nsGenericInterfaceInfoSet::GetIIDForName(const char *name, nsIID **_retval)
00239 {
00240     PRUint16 index;
00241     nsresult rv = IndexOfName(name, &index);
00242     if(NS_FAILED(rv))
00243         return rv;
00244 
00245     nsIInterfaceInfo* info = InfoAtNoAddRef(index);
00246     if(!info)
00247         return NS_ERROR_FAILURE;
00248 
00249     return info->GetInterfaceIID(_retval);
00250 }
00251 
00252 /* string getNameForIID (in nsIIDPtr iid); */
00253 NS_IMETHODIMP
00254 nsGenericInterfaceInfoSet::GetNameForIID(const nsIID * iid, char **_retval)
00255 {
00256     PRUint16 index;
00257     nsresult rv = IndexOfIID(*iid, &index);
00258     if(NS_FAILED(rv))
00259         return rv;
00260 
00261     nsIInterfaceInfo* info = InfoAtNoAddRef(index);
00262     if(!info)
00263         return NS_ERROR_FAILURE;
00264 
00265     return info->GetName(_retval);
00266 }
00267 
00268 /* nsIEnumerator enumerateInterfaces (); */
00269 NS_IMETHODIMP
00270 nsGenericInterfaceInfoSet::EnumerateInterfaces(nsIEnumerator **_retval)
00271 {
00272     return EnumerateInterfacesWhoseNamesStartWith(nsnull, _retval);
00273 }
00274 
00275 /* void autoRegisterInterfaces (); */
00276 NS_IMETHODIMP
00277 nsGenericInterfaceInfoSet::AutoRegisterInterfaces()
00278 {
00279     // NOP
00280     return NS_OK;
00281 }
00282 
00283 /* nsIEnumerator enumerateInterfacesWhoseNamesStartWith (in string prefix); */
00284 NS_IMETHODIMP
00285 nsGenericInterfaceInfoSet::EnumerateInterfacesWhoseNamesStartWith(const char *prefix,
00286                                                                   nsIEnumerator **_retval)
00287 {
00288     int count = (int) mInterfaces.Count();
00289     int len = prefix ? PL_strlen(prefix) : 0;
00290     const char* name;
00291 
00292     nsCOMPtr<nsISupportsArray> array;
00293     NS_NewISupportsArray(getter_AddRefs(array));
00294     if(!array)
00295         return NS_ERROR_OUT_OF_MEMORY;
00296 
00297     for(PRInt32 i = 0; i < count; i++)
00298     {
00299         nsIInterfaceInfo* info = InfoAtNoAddRef(i);
00300         if(!info)
00301             continue;
00302         if(!prefix ||
00303            (NS_SUCCEEDED(info->GetNameShared(&name)) &&
00304             name == PL_strnstr(name, prefix, len)))
00305         {
00306             if(!array->AppendElement(info))
00307                 return NS_ERROR_OUT_OF_MEMORY;
00308         }
00309     }
00310 
00311     return array->Enumerate(_retval);
00312 }
00313 
00314 /***************************************************************************/
00315 /***************************************************************************/
00316 // implement nsGenericInterfaceInfo
00317 
00318 NS_IMPL_QUERY_INTERFACE2(nsGenericInterfaceInfo,
00319                          nsIInterfaceInfo,
00320                          nsIGenericInterfaceInfo)
00321 
00322 NS_IMETHODIMP_(nsrefcnt)
00323 nsGenericInterfaceInfo::AddRef()
00324 {
00325     return mSet->AddRef();
00326 }
00327 
00328 NS_IMETHODIMP_(nsrefcnt)
00329 nsGenericInterfaceInfo::Release()
00330 {
00331     return mSet->Release();
00332 }
00333 
00334 nsGenericInterfaceInfo::nsGenericInterfaceInfo(nsGenericInterfaceInfoSet* aSet,
00335                                                const char *aName,
00336                                                const nsIID & aIID,
00337                                                nsIInterfaceInfo* aParent,
00338                                                PRUint8 aFlags)
00339     : mName(nsnull),
00340       mIID(aIID),
00341       mSet(aSet),
00342       mParent(aParent),
00343       mFlags(aFlags)
00344 {
00345     if(mParent)
00346     {
00347         mParent->GetMethodCount(&mMethodBaseIndex);
00348         mParent->GetConstantCount(&mConstantBaseIndex);
00349     }
00350     else
00351     {
00352         mMethodBaseIndex = mConstantBaseIndex = 0;
00353     }
00354 
00355     int len = PL_strlen(aName);
00356     mName = (char*) XPT_MALLOC(mSet->GetArena(), len+1);
00357     if(mName)
00358         memcpy(mName, aName, len);
00359 }
00360 
00361 /************************************************/
00362 // nsIGenericInterfaceInfo methods...
00363 
00364 /* PRUint16 appendMethod (in XPTMethodDescriptorPtr aMethod); */
00365 NS_IMETHODIMP
00366 nsGenericInterfaceInfo::AppendMethod(XPTMethodDescriptor * aMethod,
00367                                      PRUint16 *_retval)
00368 {
00369     XPTMethodDescriptor* desc = (XPTMethodDescriptor*)
00370         XPT_MALLOC(mSet->GetArena(), sizeof(XPTMethodDescriptor));
00371     if(!desc)
00372         return NS_ERROR_OUT_OF_MEMORY;
00373 
00374     memcpy(desc, aMethod, sizeof(XPTMethodDescriptor));
00375 
00376     int len = PL_strlen(aMethod->name);
00377     desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1);
00378     if(!desc->name)
00379         return NS_ERROR_OUT_OF_MEMORY;
00380 
00381     // XPT_MALLOC returns zeroed out memory, no need to copy the
00382     // terminating null character.
00383     memcpy(desc->name, aMethod->name, len);
00384 
00385     return mMethods.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00386 }
00387 
00388 /* PRUint16 appendConst (in XPTConstDescriptorPtr aConst); */
00389 NS_IMETHODIMP
00390 nsGenericInterfaceInfo::AppendConst(XPTConstDescriptor * aConst,
00391                                     PRUint16 *_retval)
00392 {
00393     NS_ASSERTION(aConst->type.prefix.flags == TD_INT16  ||
00394                  aConst->type.prefix.flags == TD_UINT16 ||
00395                  aConst->type.prefix.flags == TD_INT32  ||
00396                  aConst->type.prefix.flags == TD_UINT32,
00397                  "unsupported const type");
00398 
00399     XPTConstDescriptor* desc = (XPTConstDescriptor*)
00400         XPT_MALLOC(mSet->GetArena(), sizeof(XPTConstDescriptor));
00401     if(!desc)
00402         return NS_ERROR_OUT_OF_MEMORY;
00403 
00404     memcpy(desc, aConst, sizeof(XPTConstDescriptor));
00405 
00406     int len = PL_strlen(aConst->name);
00407     desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1);
00408     if(!desc->name)
00409         return NS_ERROR_OUT_OF_MEMORY;
00410 
00411     // XPT_MALLOC returns zeroed out memory, no need to copy the
00412     // terminating null character.
00413     memcpy(desc->name, aConst->name, len);
00414 
00415     return mConstants.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00416 }
00417 
00418 /************************************************/
00419 // nsIInterfaceInfo methods...
00420 
00421 /* readonly attribute string name; */
00422 NS_IMETHODIMP
00423 nsGenericInterfaceInfo::GetName(char * *aName)
00424 {
00425     *aName = (char*) nsMemory::Clone(mName, PL_strlen(mName)+1);
00426     return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00427 }
00428 
00429 /* readonly attribute nsIIDPtr InterfaceIID; */
00430 NS_IMETHODIMP
00431 nsGenericInterfaceInfo::GetInterfaceIID(nsIID * *aIID)
00432 {
00433     *aIID = (nsIID*) nsMemory::Clone(&mIID, sizeof(nsIID));
00434     return *aIID ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00435 }
00436 
00437 /* PRBool isScriptable (); */
00438 NS_IMETHODIMP
00439 nsGenericInterfaceInfo::IsScriptable(PRBool *_retval)
00440 {
00441     *_retval = XPT_ID_IS_SCRIPTABLE(mFlags) != 0;
00442     return NS_OK;
00443 }
00444 
00445 /* readonly attribute nsIInterfaceInfo parent; */
00446 NS_IMETHODIMP
00447 nsGenericInterfaceInfo::GetParent(nsIInterfaceInfo * *aParent)
00448 {
00449     *aParent = mParent;
00450     NS_IF_ADDREF(*aParent);
00451     return NS_OK;
00452 }
00453 
00454 /* readonly attribute PRUint16 methodCount; */
00455 NS_IMETHODIMP
00456 nsGenericInterfaceInfo::GetMethodCount(PRUint16 *aMethodCount)
00457 {
00458     *aMethodCount = mMethodBaseIndex + (PRUint16) mMethods.Count();
00459     return NS_OK;
00460 }
00461 
00462 /* readonly attribute PRUint16 constantCount; */
00463 NS_IMETHODIMP
00464 nsGenericInterfaceInfo::GetConstantCount(PRUint16 *aConstantCount)
00465 {
00466     *aConstantCount = mConstantBaseIndex + (PRUint16) mConstants.Count();
00467     return NS_OK;
00468 }
00469 
00470 /* void getMethodInfo (in PRUint16 index, [shared, retval] out
00471    nsXPTMethodInfoPtr info); */
00472 NS_IMETHODIMP
00473 nsGenericInterfaceInfo::GetMethodInfo(PRUint16 index,
00474                                       const nsXPTMethodInfo * *info)
00475 {
00476     if(index < mMethodBaseIndex)
00477         return mParent->GetMethodInfo(index, info);
00478     *info = (const nsXPTMethodInfo *) mMethods.ElementAt(index-mMethodBaseIndex);
00479     return NS_OK;
00480 }
00481 
00482 /* void getMethodInfoForName (in string methodName, out PRUint16
00483    index, [shared, retval] out nsXPTMethodInfoPtr info); */
00484 NS_IMETHODIMP
00485 nsGenericInterfaceInfo::GetMethodInfoForName(const char *methodName,
00486                                              PRUint16 *index,
00487                                              const nsXPTMethodInfo * *info)
00488 {
00489     PRUint16 count = mMethodBaseIndex + (PRUint16) mMethods.Count();
00490     for(PRUint16 i = 0; i < count; i++)
00491     {
00492         const nsXPTMethodInfo* current;
00493         nsresult rv = GetMethodInfo(i, &current);
00494         if(NS_FAILED(rv))
00495             return rv;
00496 
00497         if(!PL_strcmp(methodName, current->GetName()))
00498         {
00499             *index = i;
00500             *info = current;
00501             return NS_OK;
00502         }
00503     }
00504     *index = 0;
00505     *info = 0;
00506     return NS_ERROR_INVALID_ARG;
00507 }
00508 
00509 /* void getConstant (in PRUint16 index, [shared, retval] out
00510    nsXPTConstantPtr constant); */
00511 NS_IMETHODIMP
00512 nsGenericInterfaceInfo::GetConstant(PRUint16 index,
00513                                     const nsXPTConstant * *constant)
00514 {
00515     if(index < mConstantBaseIndex)
00516         return mParent->GetConstant(index, constant);
00517     *constant = (const nsXPTConstant *)
00518         mConstants.ElementAt(index-mConstantBaseIndex);
00519     return NS_OK;
00520 }
00521 
00522 /* nsIInterfaceInfo getInfoForParam (in PRUint16 methodIndex, [const]
00523    in nsXPTParamInfoPtr param); */
00524 NS_IMETHODIMP
00525 nsGenericInterfaceInfo::GetInfoForParam(PRUint16 methodIndex,
00526                                         const nsXPTParamInfo * param,
00527                                         nsIInterfaceInfo **_retval)
00528 {
00529     if(methodIndex < mMethodBaseIndex)
00530         return mParent->GetInfoForParam(methodIndex, param, _retval);
00531 
00532     const XPTTypeDescriptor* td = GetPossiblyNestedType(param);
00533     NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE,
00534                  "not an interface");
00535 
00536     return mSet->InterfaceInfoAt(td->type.iface, _retval);
00537 }
00538 
00539 /* nsIIDPtr getIIDForParam (in PRUint16 methodIndex, [const] in
00540    nsXPTParamInfoPtr param); */
00541 NS_IMETHODIMP
00542 nsGenericInterfaceInfo::GetIIDForParam(PRUint16 methodIndex,
00543                                        const nsXPTParamInfo * param,
00544                                        nsIID * *_retval)
00545 {
00546     if(methodIndex < mMethodBaseIndex)
00547         return mParent->GetIIDForParam(methodIndex, param, _retval);
00548 
00549     const XPTTypeDescriptor* td = GetPossiblyNestedType(param);
00550     NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE,
00551                  "not an interface");
00552 
00553     nsIInterfaceInfo* info = mSet->InfoAtNoAddRef(td->type.iface);
00554     if(!info)
00555         return NS_ERROR_FAILURE;
00556 
00557     return info->GetInterfaceIID(_retval);
00558 }
00559 
00560 /* nsXPTType getTypeForParam (in PRUint16 methodIndex, [const] in
00561    nsXPTParamInfoPtr param, in PRUint16 dimension); */
00562 NS_IMETHODIMP
00563 nsGenericInterfaceInfo::GetTypeForParam(PRUint16 methodIndex,
00564                                         const nsXPTParamInfo * param,
00565                                         PRUint16 dimension, nsXPTType *_retval)
00566 {
00567     if(methodIndex < mMethodBaseIndex)
00568         return mParent->GetTypeForParam(methodIndex, param, dimension,
00569                                         _retval);
00570 
00571     const XPTTypeDescriptor *td =
00572         dimension ? GetTypeInArray(param, dimension) : &param->type;
00573 
00574     *_retval = nsXPTType(td->prefix);
00575     return NS_OK;
00576 }
00577 
00578 /* PRUint8 getSizeIsArgNumberForParam (in PRUint16 methodIndex,
00579    [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */
00580 NS_IMETHODIMP
00581 nsGenericInterfaceInfo::GetSizeIsArgNumberForParam(PRUint16 methodIndex,
00582                                                    const nsXPTParamInfo *param,
00583                                                    PRUint16 dimension,
00584                                                    PRUint8 *_retval)
00585 {
00586     if(methodIndex < mMethodBaseIndex)
00587         return mParent->GetSizeIsArgNumberForParam(methodIndex, param,
00588                                                    dimension, _retval);
00589 
00590     const XPTTypeDescriptor *td =
00591         dimension ? GetTypeInArray(param, dimension) : &param->type;
00592 
00593     *_retval = td->argnum;
00594     return NS_OK;
00595 }
00596 
00597 /* PRUint8 getLengthIsArgNumberForParam (in PRUint16 methodIndex,
00598    [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */
00599 NS_IMETHODIMP
00600 nsGenericInterfaceInfo::GetLengthIsArgNumberForParam(PRUint16 methodIndex,
00601                                                      const nsXPTParamInfo *param,
00602                                                      PRUint16 dimension,
00603                                                      PRUint8 *_retval)
00604 {
00605     if(methodIndex < mMethodBaseIndex)
00606         return mParent->GetLengthIsArgNumberForParam(methodIndex, param,
00607                                                      dimension, _retval);
00608 
00609     const XPTTypeDescriptor *td =
00610         dimension ? GetTypeInArray(param, dimension) : &param->type;
00611 
00612     *_retval = td->argnum2;
00613     return NS_OK;
00614 }
00615 
00616 /* PRUint8 getInterfaceIsArgNumberForParam (in PRUint16 methodIndex,
00617    [const] in nsXPTParamInfoPtr param); */
00618 NS_IMETHODIMP
00619 nsGenericInterfaceInfo::GetInterfaceIsArgNumberForParam(PRUint16 methodIndex,
00620                                                         const nsXPTParamInfo *param,
00621                                                         PRUint8 *_retval)
00622 {
00623     if(methodIndex < mMethodBaseIndex)
00624         return mParent->GetInterfaceIsArgNumberForParam(methodIndex, param,
00625                                                         _retval);
00626 
00627     const XPTTypeDescriptor* td = GetPossiblyNestedType(param);
00628     NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE,
00629                  "not an interface");
00630 
00631     *_retval = td->argnum;
00632     return NS_OK;
00633 }
00634 
00635 /* PRBool isIID (in nsIIDPtr IID); */
00636 NS_IMETHODIMP
00637 nsGenericInterfaceInfo::IsIID(const nsIID * IID, PRBool *_retval)
00638 {
00639     *_retval = mIID.Equals(*IID);
00640     return NS_OK;
00641 }
00642 
00643 /* void getNameShared ([shared, retval] out string name); */
00644 NS_IMETHODIMP
00645 nsGenericInterfaceInfo::GetNameShared(const char **name)
00646 {
00647     *name = mName;
00648     return NS_OK;
00649 }
00650 
00651 /* void getIIDShared ([shared, retval] out nsIIDPtrShared iid); */
00652 NS_IMETHODIMP
00653 nsGenericInterfaceInfo::GetIIDShared(const nsIID * *iid)
00654 {
00655     *iid = &mIID;
00656     return NS_OK;
00657 }
00658 
00659 /* PRBool isFunction (); */
00660 NS_IMETHODIMP
00661 nsGenericInterfaceInfo::IsFunction(PRBool *_retval)
00662 {
00663     *_retval = XPT_ID_IS_FUNCTION(mFlags) != 0;
00664     return NS_OK;
00665 }
00666 
00667 /* PRBool hasAncestor (in nsIIDPtr iid); */
00668 NS_IMETHODIMP
00669 nsGenericInterfaceInfo::HasAncestor(const nsIID * iid, PRBool *_retval)
00670 {
00671     *_retval = PR_FALSE;
00672 
00673     nsCOMPtr<nsIInterfaceInfo> current =
00674         NS_STATIC_CAST(nsIInterfaceInfo*, this);
00675     while(current)
00676     {
00677         PRBool same;
00678         if(NS_SUCCEEDED(current->IsIID(iid, &same)) && same)
00679         {
00680             *_retval = PR_TRUE;
00681             break;
00682         }
00683         nsCOMPtr<nsIInterfaceInfo> temp(current);
00684         temp->GetParent(getter_AddRefs(current));
00685     }
00686     return NS_OK;
00687 }
00688 
00689 /* [notxpcom] nsresult getIIDForParamNoAlloc (in PRUint16 methodIndex,
00690    [const] in nsXPTParamInfoPtr param, out nsIID iid); */
00691 NS_IMETHODIMP_(nsresult)
00692 nsGenericInterfaceInfo::GetIIDForParamNoAlloc(PRUint16 methodIndex,
00693                                               const nsXPTParamInfo * param,
00694                                               nsIID *iid)
00695 {
00696     if(methodIndex < mMethodBaseIndex)
00697         return mParent->GetIIDForParamNoAlloc(methodIndex, param, iid);
00698 
00699     const XPTTypeDescriptor* td = GetPossiblyNestedType(param);
00700     NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE,
00701                  "not an interface");
00702 
00703     nsIInterfaceInfo* info = mSet->InfoAtNoAddRef(td->type.iface);
00704     if(!info)
00705         return NS_ERROR_FAILURE;
00706 
00707     const nsIID* iidp;
00708     nsresult rv = info->GetIIDShared(&iidp);
00709     if(NS_FAILED(rv))
00710         return rv;
00711 
00712     *iid = *iidp;
00713     return NS_OK;
00714 }