1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is mozilla.org code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 2002
20
* the Initial Developer. All Rights Reserved.
24
* Alternatively, the contents of this file may be used under the terms of
25
* either the GNU General Public License Version 2 or later (the "GPL"), or
26
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
* in which case the provisions of the GPL or the LGPL are applicable instead
28
* of those above. If you wish to allow use of your version of this file only
29
* under the terms of either the GPL or the LGPL, and not to allow others to
30
* use your version of this file under the terms of the NPL, indicate your
31
* decision by deleting the provisions above and replace them with the notice
32
* and other provisions required by the GPL or the LGPL. If you do not delete
33
* the provisions above, a recipient may use your version of this file under
34
* the terms of any one of the NPL, the GPL or the LGPL.
36
* ***** END LICENSE BLOCK ***** */
38
/* The nsGenericInterfaceInfo/nsGenericInterfaceInfoSet implementations.*/
40
#include "iixprivate.h"
43
/***************************************************************************/
44
// implement nsGenericInterfaceInfoSet
46
#define ARENA_BLOCK_SIZE (1024 * 1)
48
NS_IMPL_THREADSAFE_ISUPPORTS3(nsGenericInterfaceInfoSet,
49
nsIInterfaceInfoManager,
50
nsIGenericInterfaceInfoSet,
51
nsISupportsWeakReference)
53
nsGenericInterfaceInfoSet::nsGenericInterfaceInfoSet()
55
mArena = XPT_NewArena(ARENA_BLOCK_SIZE, sizeof(double),
56
"nsGenericInterfaceInfoSet Arena");
59
nsGenericInterfaceInfoSet::~nsGenericInterfaceInfoSet()
61
PRInt32 count = mInterfaces.Count();
63
for(PRInt32 i = 0; i < count; i++)
65
nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i);
66
if(CheckOwnedFlag(info))
67
delete (nsGenericInterfaceInfo*) ClearOwnedFlag(info);
73
XPT_DestroyArena(mArena);
77
nsGenericInterfaceInfoSet::IndexOfIID(const nsIID & aIID, PRUint16 *_retval)
79
PRInt32 count = mInterfaces.Count();
81
for(PRInt32 i = 0; i < count; i++)
83
nsIInterfaceInfo* info = (nsIInterfaceInfo*)
84
ClearOwnedFlag(mInterfaces.ElementAt(i));
86
nsresult rv = info->GetIIDShared(&iid);
91
*_retval = (PRUint16) i;
95
return NS_ERROR_NO_INTERFACE;
99
nsGenericInterfaceInfoSet::IndexOfName(const char* aName, PRUint16 *_retval)
101
PRInt32 count = mInterfaces.Count();
103
for(PRInt32 i = 0; i < count; i++)
105
nsIInterfaceInfo* info = (nsIInterfaceInfo*)
106
ClearOwnedFlag(mInterfaces.ElementAt(i));
108
nsresult rv = info->GetNameShared(&name);
111
if(!strcmp(name, aName))
113
*_retval = (PRUint16) i;
117
return NS_ERROR_NO_INTERFACE;
120
/************************************************/
121
// nsIGenericInterfaceInfoSet methods...
123
/* XPTParamDescriptorPtr allocateParamArray (in PRUint16 aCount); */
125
nsGenericInterfaceInfoSet::AllocateParamArray(PRUint16 aCount,
126
XPTParamDescriptor * *_retval)
128
*_retval = (XPTParamDescriptor*)
129
XPT_MALLOC(GetArena(), sizeof(XPTParamDescriptor) * aCount);
130
return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
133
/* XPTTypeDescriptorPtr allocateAdditionalType (out PRUint16 aIndex); */
135
nsGenericInterfaceInfoSet::AllocateAdditionalType(PRUint16 *aIndex,
136
XPTTypeDescriptor * *_retval)
138
*_retval = (XPTTypeDescriptor*)
139
XPT_MALLOC(GetArena(), sizeof(XPTTypeDescriptor));
140
if(!*_retval || !mAdditionalTypes.AppendElement(*_retval))
141
return NS_ERROR_OUT_OF_MEMORY;
142
*aIndex = (PRUint16) mAdditionalTypes.Count()-1;
146
/* PRUint16 createAndAppendInterface (in string aName, in nsIIDRef
147
aIID, in PRUint16 aParent, in PRUint8 aFlags, out
148
nsIGenericInterfaceInfo aInfo); */
150
nsGenericInterfaceInfoSet::CreateAndAppendInterface(const char *aName,
154
nsIGenericInterfaceInfo **aInfo,
157
nsGenericInterfaceInfo* info =
158
new nsGenericInterfaceInfo(this, aName, aIID,
159
(aParent == (PRUint16) -1) ?
160
nsnull : InfoAtNoAddRef(aParent),
162
if(!info || !mInterfaces.AppendElement(SetOwnedFlag(info)))
163
return NS_ERROR_OUT_OF_MEMORY;
165
*_retval = (PRUint16) mInterfaces.Count()-1;
166
return CallQueryInterface(info, aInfo);
169
/* PRUint16 appendExternalInterface (in nsIInterfaceInfo aInfo); */
171
nsGenericInterfaceInfoSet::AppendExternalInterface(nsIInterfaceInfo *aInfo,
174
if(!mInterfaces.AppendElement(aInfo))
175
return NS_ERROR_OUT_OF_MEMORY;
178
*_retval = (PRUint16) mInterfaces.Count()-1;
182
/* PRUint16 indexOf (in nsIIDRef aIID); */
184
nsGenericInterfaceInfoSet::IndexOf(const nsIID & aIID, PRUint16 *_retval)
186
return IndexOfIID(aIID, _retval);
189
/* PRUint16 indexOfByName (in string aName); */
190
NS_IMETHODIMP nsGenericInterfaceInfoSet::IndexOfByName(const char *aName,
193
return IndexOfName(aName, _retval);
196
/* nsIInterfaceInfo interfaceInfoAt (in PRUint16 aIndex); */
198
nsGenericInterfaceInfoSet::InterfaceInfoAt(PRUint16 aIndex,
199
nsIInterfaceInfo **_retval)
201
NS_ASSERTION(aIndex < (PRUint16)mInterfaces.Count(), "bad index");
203
*_retval = (nsIInterfaceInfo*)
204
ClearOwnedFlag(mInterfaces.ElementAt(aIndex));
209
/************************************************/
210
// nsIInterfaceInfoManager methods...
212
/* nsIInterfaceInfo getInfoForIID (in nsIIDPtr iid); */
214
nsGenericInterfaceInfoSet::GetInfoForIID(const nsIID * iid,
215
nsIInterfaceInfo **_retval)
218
nsresult rv = IndexOfIID(*iid, &index);
221
return InterfaceInfoAt(index, _retval);
224
/* nsIInterfaceInfo getInfoForName (in string name); */
226
nsGenericInterfaceInfoSet::GetInfoForName(const char *name,
227
nsIInterfaceInfo **_retval)
230
nsresult rv = IndexOfName(name, &index);
233
return InterfaceInfoAt(index, _retval);
236
/* nsIIDPtr getIIDForName (in string name); */
238
nsGenericInterfaceInfoSet::GetIIDForName(const char *name, nsIID **_retval)
241
nsresult rv = IndexOfName(name, &index);
245
nsIInterfaceInfo* info = InfoAtNoAddRef(index);
247
return NS_ERROR_FAILURE;
249
return info->GetInterfaceIID(_retval);
252
/* string getNameForIID (in nsIIDPtr iid); */
254
nsGenericInterfaceInfoSet::GetNameForIID(const nsIID * iid, char **_retval)
257
nsresult rv = IndexOfIID(*iid, &index);
261
nsIInterfaceInfo* info = InfoAtNoAddRef(index);
263
return NS_ERROR_FAILURE;
265
return info->GetName(_retval);
268
/* nsIEnumerator enumerateInterfaces (); */
270
nsGenericInterfaceInfoSet::EnumerateInterfaces(nsIEnumerator **_retval)
272
return EnumerateInterfacesWhoseNamesStartWith(nsnull, _retval);
275
/* void autoRegisterInterfaces (); */
277
nsGenericInterfaceInfoSet::AutoRegisterInterfaces()
283
/* nsIEnumerator enumerateInterfacesWhoseNamesStartWith (in string prefix); */
285
nsGenericInterfaceInfoSet::EnumerateInterfacesWhoseNamesStartWith(const char *prefix,
286
nsIEnumerator **_retval)
288
int count = (int) mInterfaces.Count();
289
int len = prefix ? PL_strlen(prefix) : 0;
292
nsCOMPtr<nsISupportsArray> array;
293
NS_NewISupportsArray(getter_AddRefs(array));
295
return NS_ERROR_OUT_OF_MEMORY;
297
for(PRInt32 i = 0; i < count; i++)
299
nsIInterfaceInfo* info = InfoAtNoAddRef(i);
303
(NS_SUCCEEDED(info->GetNameShared(&name)) &&
304
name == PL_strnstr(name, prefix, len)))
306
if(!array->AppendElement(info))
307
return NS_ERROR_OUT_OF_MEMORY;
311
return array->Enumerate(_retval);
314
/***************************************************************************/
315
/***************************************************************************/
316
// implement nsGenericInterfaceInfo
318
NS_IMPL_QUERY_INTERFACE2(nsGenericInterfaceInfo,
320
nsIGenericInterfaceInfo)
322
NS_IMETHODIMP_(nsrefcnt)
323
nsGenericInterfaceInfo::AddRef()
325
return mSet->AddRef();
328
NS_IMETHODIMP_(nsrefcnt)
329
nsGenericInterfaceInfo::Release()
331
return mSet->Release();
334
nsGenericInterfaceInfo::nsGenericInterfaceInfo(nsGenericInterfaceInfoSet* aSet,
337
nsIInterfaceInfo* aParent,
347
mParent->GetMethodCount(&mMethodBaseIndex);
348
mParent->GetConstantCount(&mConstantBaseIndex);
352
mMethodBaseIndex = mConstantBaseIndex = 0;
355
int len = PL_strlen(aName);
356
mName = (char*) XPT_MALLOC(mSet->GetArena(), len+1);
358
memcpy(mName, aName, len);
361
/************************************************/
362
// nsIGenericInterfaceInfo methods...
364
/* PRUint16 appendMethod (in XPTMethodDescriptorPtr aMethod); */
366
nsGenericInterfaceInfo::AppendMethod(XPTMethodDescriptor * aMethod,
369
XPTMethodDescriptor* desc = (XPTMethodDescriptor*)
370
XPT_MALLOC(mSet->GetArena(), sizeof(XPTMethodDescriptor));
372
return NS_ERROR_OUT_OF_MEMORY;
374
memcpy(desc, aMethod, sizeof(XPTMethodDescriptor));
376
int len = PL_strlen(aMethod->name);
377
desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1);
379
return NS_ERROR_OUT_OF_MEMORY;
381
// XPT_MALLOC returns zeroed out memory, no need to copy the
382
// terminating null character.
383
memcpy(desc->name, aMethod->name, len);
385
return mMethods.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
388
/* PRUint16 appendConst (in XPTConstDescriptorPtr aConst); */
390
nsGenericInterfaceInfo::AppendConst(XPTConstDescriptor * aConst,
393
NS_ASSERTION(aConst->type.prefix.flags == TD_INT16 ||
394
aConst->type.prefix.flags == TD_UINT16 ||
395
aConst->type.prefix.flags == TD_INT32 ||
396
aConst->type.prefix.flags == TD_UINT32,
397
"unsupported const type");
399
XPTConstDescriptor* desc = (XPTConstDescriptor*)
400
XPT_MALLOC(mSet->GetArena(), sizeof(XPTConstDescriptor));
402
return NS_ERROR_OUT_OF_MEMORY;
404
memcpy(desc, aConst, sizeof(XPTConstDescriptor));
406
int len = PL_strlen(aConst->name);
407
desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1);
409
return NS_ERROR_OUT_OF_MEMORY;
411
// XPT_MALLOC returns zeroed out memory, no need to copy the
412
// terminating null character.
413
memcpy(desc->name, aConst->name, len);
415
return mConstants.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
418
/************************************************/
419
// nsIInterfaceInfo methods...
421
/* readonly attribute string name; */
423
nsGenericInterfaceInfo::GetName(char * *aName)
425
*aName = (char*) nsMemory::Clone(mName, PL_strlen(mName)+1);
426
return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
429
/* readonly attribute nsIIDPtr InterfaceIID; */
431
nsGenericInterfaceInfo::GetInterfaceIID(nsIID * *aIID)
433
*aIID = (nsIID*) nsMemory::Clone(&mIID, sizeof(nsIID));
434
return *aIID ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
437
/* PRBool isScriptable (); */
439
nsGenericInterfaceInfo::IsScriptable(PRBool *_retval)
441
*_retval = XPT_ID_IS_SCRIPTABLE(mFlags) != 0;
445
/* readonly attribute nsIInterfaceInfo parent; */
447
nsGenericInterfaceInfo::GetParent(nsIInterfaceInfo * *aParent)
450
NS_IF_ADDREF(*aParent);
454
/* readonly attribute PRUint16 methodCount; */
456
nsGenericInterfaceInfo::GetMethodCount(PRUint16 *aMethodCount)
458
*aMethodCount = mMethodBaseIndex + (PRUint16) mMethods.Count();
462
/* readonly attribute PRUint16 constantCount; */
464
nsGenericInterfaceInfo::GetConstantCount(PRUint16 *aConstantCount)
466
*aConstantCount = mConstantBaseIndex + (PRUint16) mConstants.Count();
470
/* void getMethodInfo (in PRUint16 index, [shared, retval] out
471
nsXPTMethodInfoPtr info); */
473
nsGenericInterfaceInfo::GetMethodInfo(PRUint16 index,
474
const nsXPTMethodInfo * *info)
476
if(index < mMethodBaseIndex)
477
return mParent->GetMethodInfo(index, info);
478
*info = (const nsXPTMethodInfo *) mMethods.ElementAt(index-mMethodBaseIndex);
482
/* void getMethodInfoForName (in string methodName, out PRUint16
483
index, [shared, retval] out nsXPTMethodInfoPtr info); */
485
nsGenericInterfaceInfo::GetMethodInfoForName(const char *methodName,
487
const nsXPTMethodInfo * *info)
489
PRUint16 count = mMethodBaseIndex + (PRUint16) mMethods.Count();
490
for(PRUint16 i = 0; i < count; i++)
492
const nsXPTMethodInfo* current;
493
nsresult rv = GetMethodInfo(i, ¤t);
497
if(!PL_strcmp(methodName, current->GetName()))
506
return NS_ERROR_INVALID_ARG;
509
/* void getConstant (in PRUint16 index, [shared, retval] out
510
nsXPTConstantPtr constant); */
512
nsGenericInterfaceInfo::GetConstant(PRUint16 index,
513
const nsXPTConstant * *constant)
515
if(index < mConstantBaseIndex)
516
return mParent->GetConstant(index, constant);
517
*constant = (const nsXPTConstant *)
518
mConstants.ElementAt(index-mConstantBaseIndex);
522
/* nsIInterfaceInfo getInfoForParam (in PRUint16 methodIndex, [const]
523
in nsXPTParamInfoPtr param); */
525
nsGenericInterfaceInfo::GetInfoForParam(PRUint16 methodIndex,
526
const nsXPTParamInfo * param,
527
nsIInterfaceInfo **_retval)
529
if(methodIndex < mMethodBaseIndex)
530
return mParent->GetInfoForParam(methodIndex, param, _retval);
532
const XPTTypeDescriptor* td = GetPossiblyNestedType(param);
533
NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE,
536
return mSet->InterfaceInfoAt(td->type.iface, _retval);
539
/* nsIIDPtr getIIDForParam (in PRUint16 methodIndex, [const] in
540
nsXPTParamInfoPtr param); */
542
nsGenericInterfaceInfo::GetIIDForParam(PRUint16 methodIndex,
543
const nsXPTParamInfo * param,
546
if(methodIndex < mMethodBaseIndex)
547
return mParent->GetIIDForParam(methodIndex, param, _retval);
549
const XPTTypeDescriptor* td = GetPossiblyNestedType(param);
550
NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE,
553
nsIInterfaceInfo* info = mSet->InfoAtNoAddRef(td->type.iface);
555
return NS_ERROR_FAILURE;
557
return info->GetInterfaceIID(_retval);
560
/* nsXPTType getTypeForParam (in PRUint16 methodIndex, [const] in
561
nsXPTParamInfoPtr param, in PRUint16 dimension); */
563
nsGenericInterfaceInfo::GetTypeForParam(PRUint16 methodIndex,
564
const nsXPTParamInfo * param,
565
PRUint16 dimension, nsXPTType *_retval)
567
if(methodIndex < mMethodBaseIndex)
568
return mParent->GetTypeForParam(methodIndex, param, dimension,
571
const XPTTypeDescriptor *td =
572
dimension ? GetTypeInArray(param, dimension) : ¶m->type;
574
*_retval = nsXPTType(td->prefix);
578
/* PRUint8 getSizeIsArgNumberForParam (in PRUint16 methodIndex,
579
[const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */
581
nsGenericInterfaceInfo::GetSizeIsArgNumberForParam(PRUint16 methodIndex,
582
const nsXPTParamInfo *param,
586
if(methodIndex < mMethodBaseIndex)
587
return mParent->GetSizeIsArgNumberForParam(methodIndex, param,
590
const XPTTypeDescriptor *td =
591
dimension ? GetTypeInArray(param, dimension) : ¶m->type;
593
*_retval = td->argnum;
597
/* PRUint8 getLengthIsArgNumberForParam (in PRUint16 methodIndex,
598
[const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */
600
nsGenericInterfaceInfo::GetLengthIsArgNumberForParam(PRUint16 methodIndex,
601
const nsXPTParamInfo *param,
605
if(methodIndex < mMethodBaseIndex)
606
return mParent->GetLengthIsArgNumberForParam(methodIndex, param,
609
const XPTTypeDescriptor *td =
610
dimension ? GetTypeInArray(param, dimension) : ¶m->type;
612
*_retval = td->argnum2;
616
/* PRUint8 getInterfaceIsArgNumberForParam (in PRUint16 methodIndex,
617
[const] in nsXPTParamInfoPtr param); */
619
nsGenericInterfaceInfo::GetInterfaceIsArgNumberForParam(PRUint16 methodIndex,
620
const nsXPTParamInfo *param,
623
if(methodIndex < mMethodBaseIndex)
624
return mParent->GetInterfaceIsArgNumberForParam(methodIndex, param,
627
const XPTTypeDescriptor* td = GetPossiblyNestedType(param);
628
NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE,
631
*_retval = td->argnum;
635
/* PRBool isIID (in nsIIDPtr IID); */
637
nsGenericInterfaceInfo::IsIID(const nsIID * IID, PRBool *_retval)
639
*_retval = mIID.Equals(*IID);
643
/* void getNameShared ([shared, retval] out string name); */
645
nsGenericInterfaceInfo::GetNameShared(const char **name)
651
/* void getIIDShared ([shared, retval] out nsIIDPtrShared iid); */
653
nsGenericInterfaceInfo::GetIIDShared(const nsIID * *iid)
659
/* PRBool isFunction (); */
661
nsGenericInterfaceInfo::IsFunction(PRBool *_retval)
663
*_retval = XPT_ID_IS_FUNCTION(mFlags) != 0;
667
/* PRBool hasAncestor (in nsIIDPtr iid); */
669
nsGenericInterfaceInfo::HasAncestor(const nsIID * iid, PRBool *_retval)
673
nsCOMPtr<nsIInterfaceInfo> current =
674
NS_STATIC_CAST(nsIInterfaceInfo*, this);
678
if(NS_SUCCEEDED(current->IsIID(iid, &same)) && same)
683
nsCOMPtr<nsIInterfaceInfo> temp(current);
684
temp->GetParent(getter_AddRefs(current));
689
/* [notxpcom] nsresult getIIDForParamNoAlloc (in PRUint16 methodIndex,
690
[const] in nsXPTParamInfoPtr param, out nsIID iid); */
691
NS_IMETHODIMP_(nsresult)
692
nsGenericInterfaceInfo::GetIIDForParamNoAlloc(PRUint16 methodIndex,
693
const nsXPTParamInfo * param,
696
if(methodIndex < mMethodBaseIndex)
697
return mParent->GetIIDForParamNoAlloc(methodIndex, param, iid);
699
const XPTTypeDescriptor* td = GetPossiblyNestedType(param);
700
NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE,
703
nsIInterfaceInfo* info = mSet->InfoAtNoAddRef(td->type.iface);
705
return NS_ERROR_FAILURE;
708
nsresult rv = info->GetIIDShared(&iidp);