From b1527d1cb4886beb5c97f8ac5ec968619d70ce4c Mon Sep 17 00:00:00 2001 From: "jband%netscape.com" Date: Tue, 15 Jan 2002 22:22:16 +0000 Subject: [PATCH] initial checkin of support for scriptable wrappers around interface info and for generic interface info sets that can be manually populated - NOT PART OF THE BUILD --- extensions/interfaceinfo/makefile.win | 37 + extensions/interfaceinfo/public/makefile.win | 31 + .../public/nsIGenericInterfaceInfoSet.idl | 90 ++ .../public/nsIScriptableInterfaceInfo.idl | 176 ++++ extensions/interfaceinfo/src/iixmodule.cpp | 68 ++ extensions/interfaceinfo/src/iixprivate.h | 177 ++++ extensions/interfaceinfo/src/makefile.win | 63 ++ .../src/nsGenericInterfaceInfoSet.cpp | 597 +++++++++++++ .../src/nsScriptableInterfaceInfo.cpp | 786 ++++++++++++++++++ .../interfaceinfo/tests/ifaceinfotest.js | 364 ++++++++ .../interfaceinfo/src/iixprivate.h | 177 ++++ .../src/nsGenericInterfaceInfoSet.cpp | 597 +++++++++++++ .../src/nsScriptableInterfaceInfo.cpp | 786 ++++++++++++++++++ .../interfaceinfo/tests/ifaceinfotest.js | 364 ++++++++ .../public/nsIGenericInterfaceInfoSet.idl | 90 ++ .../public/nsIScriptableInterfaceInfo.idl | 176 ++++ .../xmlextras/interfaceinfo/makefile.win | 37 + .../interfaceinfo/public/makefile.win | 31 + .../public/nsIGenericInterfaceInfoSet.idl | 90 ++ .../public/nsIScriptableInterfaceInfo.idl | 176 ++++ .../xmlextras/interfaceinfo/src/iixmodule.cpp | 68 ++ .../xmlextras/interfaceinfo/src/iixprivate.h | 177 ++++ .../xmlextras/interfaceinfo/src/makefile.win | 63 ++ .../src/nsGenericInterfaceInfoSet.cpp | 597 +++++++++++++ .../src/nsScriptableInterfaceInfo.cpp | 786 ++++++++++++++++++ .../interfaceinfo/tests/ifaceinfotest.js | 364 ++++++++ 26 files changed, 6968 insertions(+) create mode 100644 extensions/interfaceinfo/makefile.win create mode 100644 extensions/interfaceinfo/public/makefile.win create mode 100644 extensions/interfaceinfo/public/nsIGenericInterfaceInfoSet.idl create mode 100644 extensions/interfaceinfo/public/nsIScriptableInterfaceInfo.idl create mode 100644 extensions/interfaceinfo/src/iixmodule.cpp create mode 100644 extensions/interfaceinfo/src/iixprivate.h create mode 100644 extensions/interfaceinfo/src/makefile.win create mode 100644 extensions/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp create mode 100644 extensions/interfaceinfo/src/nsScriptableInterfaceInfo.cpp create mode 100644 extensions/interfaceinfo/tests/ifaceinfotest.js create mode 100644 extensions/webservices/interfaceinfo/src/iixprivate.h create mode 100644 extensions/webservices/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp create mode 100644 extensions/webservices/interfaceinfo/src/nsScriptableInterfaceInfo.cpp create mode 100644 extensions/webservices/interfaceinfo/tests/ifaceinfotest.js create mode 100644 extensions/webservices/public/nsIGenericInterfaceInfoSet.idl create mode 100644 extensions/webservices/public/nsIScriptableInterfaceInfo.idl create mode 100644 extensions/xmlextras/interfaceinfo/makefile.win create mode 100644 extensions/xmlextras/interfaceinfo/public/makefile.win create mode 100644 extensions/xmlextras/interfaceinfo/public/nsIGenericInterfaceInfoSet.idl create mode 100644 extensions/xmlextras/interfaceinfo/public/nsIScriptableInterfaceInfo.idl create mode 100644 extensions/xmlextras/interfaceinfo/src/iixmodule.cpp create mode 100644 extensions/xmlextras/interfaceinfo/src/iixprivate.h create mode 100644 extensions/xmlextras/interfaceinfo/src/makefile.win create mode 100644 extensions/xmlextras/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp create mode 100644 extensions/xmlextras/interfaceinfo/src/nsScriptableInterfaceInfo.cpp create mode 100644 extensions/xmlextras/interfaceinfo/tests/ifaceinfotest.js diff --git a/extensions/interfaceinfo/makefile.win b/extensions/interfaceinfo/makefile.win new file mode 100644 index 00000000000..61af210c6d4 --- /dev/null +++ b/extensions/interfaceinfo/makefile.win @@ -0,0 +1,37 @@ +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is Mozilla Communicator client code, released +# March 31, 1998. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU Public License (the "GPL"), in which case the +# provisions of the GPL are applicable instead of those above. +# If you wish to allow use of your version of this file only +# under the terms of the GPL and not to allow others to use your +# version of this file under the NPL, indicate your decision by +# deleting the provisions above and replace them with the notice +# and other provisions required by the GPL. If you do not delete +# the provisions above, a recipient may use your version of this +# file under either the NPL or the GPL. + +DEPTH=..\.. + +DIRS=public src + +include <$(DEPTH)\config\rules.mak> diff --git a/extensions/interfaceinfo/public/makefile.win b/extensions/interfaceinfo/public/makefile.win new file mode 100644 index 00000000000..4350049960b --- /dev/null +++ b/extensions/interfaceinfo/public/makefile.win @@ -0,0 +1,31 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): + +DEPTH=..\..\.. + +MODULE=iiextras + +XPIDLSRCS = \ + .\nsIGenericInterfaceInfoSet.idl \ + .\nsIScriptableInterfaceInfo.idl \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> diff --git a/extensions/interfaceinfo/public/nsIGenericInterfaceInfoSet.idl b/extensions/interfaceinfo/public/nsIGenericInterfaceInfoSet.idl new file mode 100644 index 00000000000..05520fe2933 --- /dev/null +++ b/extensions/interfaceinfo/public/nsIGenericInterfaceInfoSet.idl @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsIGenericInterfaceInfo/nsIGenericInterfaceInfoSet public declarations.*/ + + +#include "nsISupports.idl" +#include "nsIInterfaceInfo.idl" +#include "nsIInterfaceInfoManager.idl" + +[ptr] native nsXPTTypePtr(nsXPTType); + +/* this is NOT intended to be scriptable */ +[uuid(8344a200-18ed-4538-8d44-e50b5156b564)] +interface nsIGenericInterfaceInfo : nsIInterfaceInfo +{ + /** + * Caller might allocate one more than the actual param count in + * order to have a location for the result pointer used in the methodinfo. + */ + nsXPTParamInfoPtr allocateParamArray(in PRUint16 aCount); + + /** + * Used for arrays. + */ + nsXPTTypePtr allocateAdditionalType(out PRUint16 aIndex); + + /** + * All members except params* and result* copied + */ + + PRUint16 appendMethod(in nsXPTMethodInfoPtr aMethod); + + /** + * All members copied + */ + PRUint16 appendConst(in nsXPTConstantPtr aConst); +}; + +/* this is NOT intended to be scriptable */ +[uuid(8cc674ee-52ba-45fa-b897-bb88d35eaa91)] +interface nsIGenericInterfaceInfoSet : nsIInterfaceInfoManager +{ + PRUint16 createAndAppendInterface(in string aName, in nsIIDRef aIID, + in PRUint16 aParent, in PRUint8 aFlags, + out nsIGenericInterfaceInfo aInfo); + PRUint16 appendExternalInterface(in nsIInterfaceInfo aInfo); + PRUint16 indexOf(in nsIIDRef aIID); + nsIInterfaceInfo interfaceInfoAt(in PRUint16 aIndex); +}; + +%{C++ +// The contractID for the implementation built into iiextras +#define NS_GENERIC_INTERFACE_INFO_SET_CONTRACTID "@mozilla.org/genericInterfaceInfoSet;1" +%} + diff --git a/extensions/interfaceinfo/public/nsIScriptableInterfaceInfo.idl b/extensions/interfaceinfo/public/nsIScriptableInterfaceInfo.idl new file mode 100644 index 00000000000..1e799ee2dc4 --- /dev/null +++ b/extensions/interfaceinfo/public/nsIScriptableInterfaceInfo.idl @@ -0,0 +1,176 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 2001 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * John Bandhauer (original author) + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU Public License (the "GPL"), in which case the + * provisions of the GPL are applicable instead of those above. + * If you wish to allow use of your version of this file only + * under the terms of the GPL and not to allow others to use your + * version of this file under the NPL, indicate your decision by + * deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete + * the provisions above, a recipient may use your version of this + * file under either the NPL or the GPL. + */ + +/* Scriptable version of the information exposed by nsIInterfaceInfo */ + +#include "nsISupports.idl" +#include "nsIInterfaceInfo.idl" +#include "nsIVariant.idl" + +[scriptable, uuid(312e3b94-dc98-4ccc-b2fb-e3406f905cc6)] +interface nsIScriptableDataType : nsISupports +{ + readonly attribute PRBool isPointer; + readonly attribute PRBool isUniquePointer; + readonly attribute PRBool isReference; + readonly attribute PRBool isArithmetic; + readonly attribute PRBool isInterfacePointer; + readonly attribute PRBool isArray; + readonly attribute PRBool isDependent; + + /** + * This is one of the constants declared in nsIDataType + */ + readonly attribute PRUint16 dataType; +}; + +[scriptable, uuid(2309482b-4631-455f-833f-5e4e9ce38589)] +interface nsIScriptableParamInfo : nsISupports +{ + readonly attribute PRBool isIn; + readonly attribute PRBool isOut; + readonly attribute PRBool isRetval; + readonly attribute PRBool isShared; + readonly attribute PRBool isDipper; + + readonly attribute nsIScriptableDataType type; + + [noscript] void getParamInfo([shared, const, retval] out nsXPTParamInfoPtr aInfo); +}; + +[scriptable, uuid(0f6c5b09-88b0-43ca-b55c-578f24f3d810)] +interface nsIScriptableConstant : nsISupports +{ + readonly attribute string name; + readonly attribute nsIScriptableDataType type; + readonly attribute nsIVariant value; +}; + +[scriptable, uuid(9228afa2-187c-4feb-9228-5108e640ca33)] +interface nsIScriptableMethodInfo : nsISupports +{ + readonly attribute PRBool isGetter; + readonly attribute PRBool isSetter; + readonly attribute PRBool isNotXPCOM; + readonly attribute PRBool isConstructor; + readonly attribute PRBool isHidden; + + readonly attribute string name; + readonly attribute PRUint8 paramCount; + + nsIScriptableParamInfo getParam(in PRUint8 idx); + + readonly attribute nsIScriptableParamInfo result; +}; + +[scriptable, uuid(f902d5ba-2ef6-444e-8a17-52cb70715c10)] +interface nsIScriptableInterfaceInfo : nsISupports +{ + [noscript] attribute nsIInterfaceInfo info; + + void init(in nsIIDPtr aIID); + + readonly attribute string name; + + /** + * Setting interfaceID will set what interface info this object wraps. + */ + attribute nsIIDPtr interfaceID; + + /** + * True if this object has been sucessfully set to wrap an interface info. + */ + readonly attribute PRBool isValid; + + readonly attribute PRBool isScriptable; + + readonly attribute nsIScriptableInterfaceInfo parent; + + /** + * These include counts for parent (and all ancestors). + */ + readonly attribute PRUint16 methodCount; + readonly attribute PRUint16 constantCount; + + /** + * These include methods and constants for parent (and all ancestors). + */ + + nsIScriptableMethodInfo getMethodInfo(in PRUint16 index); + + nsIScriptableMethodInfo getMethodInfoForName(in string methodName, + out PRUint16 index); + + + nsIScriptableConstant getConstant(in PRUint16 index); + + /** + * Get the interface information or iid associated with a param of some + * method in this interface. + */ + + nsIScriptableInterfaceInfo getInfoForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param); + + nsIIDPtr getIIDForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param); + + + nsIScriptableDataType getTypeForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param, + in PRUint16 dimension); + + PRUint8 getSizeIsArgNumberForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param, + in PRUint16 dimension); + + PRUint8 getLengthIsArgNumberForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param, + in PRUint16 dimension); + + PRUint8 getInterfaceIsArgNumberForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param); + + PRBool isIID(in nsIIDPtr IID); + + readonly attribute PRBool isFunction; + + PRBool hasAncestor(in nsIIDPtr iid); +}; + +%{C++ +// The contractID for the implementation built in to xpconnect. +#define NS_SCRIPTABLE_INTERFACE_INFO_CONTRACTID "@mozilla.org/scriptableInterfaceInfo;1" +%} diff --git a/extensions/interfaceinfo/src/iixmodule.cpp b/extensions/interfaceinfo/src/iixmodule.cpp new file mode 100644 index 00000000000..3df703e103e --- /dev/null +++ b/extensions/interfaceinfo/src/iixmodule.cpp @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * John Bandhauer (original author) + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU Public License (the "GPL"), in which case the + * provisions of the GPL are applicable instead of those above. + * If you wish to allow use of your version of this file only + * under the terms of the GPL and not to allow others to use your + * version of this file under the NPL, indicate your decision by + * deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete + * the provisions above, a recipient may use your version of this + * file under either the NPL or the GPL. + */ + +/* Module level methods. */ + +#include "iixprivate.h" + +/* Module implementation for the interface info extras library. */ + +// {B404670D-1EB1-4af8-86E5-FB3E9C4ECC4B} +#define NS_GENERIC_INTERFACE_INFO_SET_CID \ +{ 0xb404670d, 0x1eb1, 0x4af8, \ + { 0x86, 0xe5, 0xfb, 0x3e, 0x9c, 0x4e, 0xcc, 0x4b } } + + +// {ED150A6A-4592-4e2c-82F8-70C8D65F74D2} +#define NS_SCRIPTABLE_INTERFACE_INFO_CID \ +{ 0xed150a6a, 0x4592, 0x4e2c, \ + { 0x82, 0xf8, 0x70, 0xc8, 0xd6, 0x5f, 0x74, 0xd2 } } + + +NS_GENERIC_FACTORY_CONSTRUCTOR(nsGenericInterfaceInfoSet) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableInterfaceInfo) + +static nsModuleComponentInfo components[] = { + {nsnull, + NS_GENERIC_INTERFACE_INFO_SET_CID, + NS_GENERIC_INTERFACE_INFO_SET_CONTRACTID, + nsGenericInterfaceInfoSetConstructor}, + {nsnull, + NS_SCRIPTABLE_INTERFACE_INFO_CID, + NS_SCRIPTABLE_INTERFACE_INFO_CONTRACTID, + nsScriptableInterfaceInfoConstructor} +}; + +NS_IMPL_NSGETMODULE(iiextras, components) diff --git a/extensions/interfaceinfo/src/iixprivate.h b/extensions/interfaceinfo/src/iixprivate.h new file mode 100644 index 00000000000..5b4e8472255 --- /dev/null +++ b/extensions/interfaceinfo/src/iixprivate.h @@ -0,0 +1,177 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe + * John Bandhauer + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Library-private header for Interface Info extras system. */ + +#ifndef iixprivate_h___ +#define iixprivate_h___ + +#include "nsCOMPtr.h" +#include "nsVoidArray.h" +#include "nsSupportsArray.h" +#include "nsString.h" +#include "nsReadableUtils.h" +#include "nsWeakReference.h" +#include "nsIGenericFactory.h" +#include "nsVariant.h" + +#include "nsIInterfaceInfo.h" +#include "nsIInterfaceInfoManager.h" +#include "xpt_struct.h" +#include "xptinfo.h" +#include "xptcall.h" + +#include "nsIGenericInterfaceInfoSet.h" +#include "nsIScriptableInterfaceInfo.h" + +/***************************************************************************/ + +class nsGenericInterfaceInfoSet : public nsIGenericInterfaceInfoSet, + public nsSupportsWeakReference +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERFACEINFOMANAGER + NS_DECL_NSIGENERICINTERFACEINFOSET + + nsGenericInterfaceInfoSet(); + virtual ~nsGenericInterfaceInfoSet(); + + XPTArena* GetArena() {return mArena;} + nsresult AllocateAdditionalType(PRUint16 *aIndex, nsXPTType * *_retval); + + const XPTTypeDescriptor* GetAdditionalTypeAt(PRUint16 aIndex) + { + NS_ASSERTION(aIndex < (PRUint16) mAdditionalTypes.Count(), "bad index"); + return (const XPTTypeDescriptor*) mAdditionalTypes.ElementAt(aIndex); + } + + nsIInterfaceInfo* InfoAtNoAddRef(PRUint16 aIndex) + { + NS_ASSERTION(aIndex < (PRUint16) mInterfaces.Count(), "bad index"); + return (nsIInterfaceInfo*) ClearOwnedFlag(mInterfaces.ElementAt(aIndex)); + } + +private: + nsresult IndexOfIID(const nsIID & aIID, PRUint16 *_retval); + nsresult IndexOfName(const char* aName, PRUint16 *_retval); + + void* SetOwnedFlag(void* p) {return (void*) ((long)p | 1);} + void* ClearOwnedFlag(void* p) {return (void*) ((long)p & ~(long)1);} + PRBool CheckOwnedFlag(void* p) {return (PRBool) ((long)p & (long)1);} + + +private: + nsVoidArray mInterfaces; + nsVoidArray mAdditionalTypes; + XPTArena* mArena; +}; + +/***************************************************************************/ + +class nsGenericInterfaceInfo : public nsIGenericInterfaceInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERFACEINFO + NS_DECL_NSIGENERICINTERFACEINFO + + nsGenericInterfaceInfo(); // not implemented + nsGenericInterfaceInfo(nsGenericInterfaceInfoSet* aSet, + const char *aName, + const nsIID & aIID, + nsIInterfaceInfo* mParent, + PRUint8 aFlags); + virtual ~nsGenericInterfaceInfo() {} + +private: + const XPTTypeDescriptor* GetPossiblyNestedType(const nsXPTParamInfo* param) + { + const XPTTypeDescriptor* td = ¶m->type; + while(XPT_TDP_TAG(td->prefix) == TD_ARRAY) + td = mSet->GetAdditionalTypeAt(td->type.additional_type); + return td; + } + + const XPTTypeDescriptor* GetTypeInArray(const nsXPTParamInfo* param, + PRUint16 dimension) + { + const XPTTypeDescriptor* td = ¶m->type; + for(PRUint16 i = 0; i < dimension; i++) + { + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_ARRAY, "bad dimension"); + td = mSet->GetAdditionalTypeAt(td->type.additional_type); + } + return td; + } + +private: + char* mName; + nsIID mIID; + nsVoidArray mMethods; + nsVoidArray mConstants; + nsGenericInterfaceInfoSet* mSet; + nsIInterfaceInfo* mParent; // weak reference (it must be held in set table) + PRUint16 mMethodBaseIndex; + PRUint16 mConstantBaseIndex; + PRUint8 mFlags; +}; + +/***************************************************************************/ + +class nsScriptableInterfaceInfo : public nsIScriptableInterfaceInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEINTERFACEINFO + + static nsresult Create(nsIInterfaceInfo* aInfo, + nsIScriptableInterfaceInfo** aResult); + + nsScriptableInterfaceInfo(); + nsScriptableInterfaceInfo(nsIInterfaceInfo* aInfo); + virtual ~nsScriptableInterfaceInfo(); + +private: + nsCOMPtr mInfo; +}; + +/***************************************************************************/ + +#endif /* iixprivate_h___ */ diff --git a/extensions/interfaceinfo/src/makefile.win b/extensions/interfaceinfo/src/makefile.win new file mode 100644 index 00000000000..7e78970d4dc --- /dev/null +++ b/extensions/interfaceinfo/src/makefile.win @@ -0,0 +1,63 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is Mozilla Communicator client code, released +# March 31, 1998. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# John Bandhauer +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU Public License (the "GPL"), in which case the +# provisions of the GPL are applicable instead of those above. +# If you wish to allow use of your version of this file only +# under the terms of the GPL and not to allow others to use your +# version of this file under the NPL, indicate your decision by +# deleting the provisions above and replace them with the notice +# and other provisions required by the GPL. If you do not delete +# the provisions above, a recipient may use your version of this +# file under either the NPL or the GPL. + +DEPTH=..\..\.. + +MODULE=iiextras +LIBRARY_NAME=$(MODULE) +MODULE_NAME=$(MODULE) + +REQUIRES = \ + xpcom \ + string \ + $(NULL) + +DEFINES=-DWIN32_LEAN_AND_MEAN + +OBJS= \ + .\$(OBJDIR)\nsGenericInterfaceInfoSet.obj \ + .\$(OBJDIR)\nsScriptableInterfaceInfo.obj \ + .\$(OBJDIR)\iixmodule.obj \ + $(NULL) + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +LLIBS= $(LIBNSPR) \ + $(DIST)\lib\xpcom.lib \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> diff --git a/extensions/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp b/extensions/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp new file mode 100644 index 00000000000..b9f8b46452d --- /dev/null +++ b/extensions/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp @@ -0,0 +1,597 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsGenericInterfaceInfo/nsGenericInterfaceInfoSet implementations.*/ + +#include "iixprivate.h" + + +/***************************************************************************/ +// implement nsGenericInterfaceInfoSet + +#define ARENA_BLOCK_SIZE (1024 * 1) + +NS_IMPL_THREADSAFE_ISUPPORTS3(nsGenericInterfaceInfoSet, + nsIInterfaceInfoManager, + nsIGenericInterfaceInfoSet, + nsISupportsWeakReference); + +nsGenericInterfaceInfoSet::nsGenericInterfaceInfoSet() +{ + NS_INIT_ISUPPORTS(); + mArena = XPT_NewArena(ARENA_BLOCK_SIZE, sizeof(double), + "nsGenericInterfaceInfoSet Arena"); +} + +nsGenericInterfaceInfoSet::~nsGenericInterfaceInfoSet() +{ + PRInt32 count = mInterfaces.Count(); + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i); + if(CheckOwnedFlag(info)) + delete (nsGenericInterfaceInfo*) ClearOwnedFlag(info); + else + NS_RELEASE(info); + } + + if(mArena) + XPT_DestroyArena(mArena); +} + +nsresult +nsGenericInterfaceInfoSet::AllocateAdditionalType(PRUint16 *aIndex, nsXPTType * *_retval) +{ + *_retval = (nsXPTType*) + XPT_MALLOC(GetArena(), sizeof(nsXPTType)); + if(!*_retval || !mAdditionalTypes.AppendElement(*_retval)) + return NS_ERROR_OUT_OF_MEMORY; + *aIndex = (PRUint16) mAdditionalTypes.Count()-1; + return NS_OK; +} + +nsresult +nsGenericInterfaceInfoSet::IndexOfIID(const nsIID & aIID, PRUint16 *_retval) +{ + PRInt32 count = mInterfaces.Count(); + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i); + const nsID* iid; + nsresult rv = info->GetIIDShared(&iid); + if(NS_FAILED(rv)) + return rv; + if(iid->Equals(aIID)) + { + *_retval = (PRUint16) i; + return NS_OK; + } + } + return NS_ERROR_NO_INTERFACE; +} + +nsresult +nsGenericInterfaceInfoSet::IndexOfName(const char* aName, PRUint16 *_retval) +{ + PRInt32 count = mInterfaces.Count(); + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i); + const char* name; + nsresult rv = info->GetNameShared(&name); + if(NS_FAILED(rv)) + return rv; + if(!strcmp(name, aName)) + { + *_retval = (PRUint16) i; + return NS_OK; + } + } + return NS_ERROR_NO_INTERFACE; +} + +/************************************************/ +// nsIGenericInterfaceInfoSet methods... + +/* PRUint16 createAndAppendInterface (in string aName, in nsIIDRef aIID, in PRUint16 aParent, in PRUint8 aFlags, out nsIGenericInterfaceInfo aInfo); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::CreateAndAppendInterface(const char *aName, const nsIID & aIID, PRUint16 aParent, PRUint8 aFlags, nsIGenericInterfaceInfo **aInfo, PRUint16 *_retval) +{ + nsGenericInterfaceInfo* info = + new nsGenericInterfaceInfo(this, aName, aIID, + (aParent == (PRUint16) -1) ? + nsnull : InfoAtNoAddRef(aParent), + aFlags); + if(!info || !mInterfaces.AppendElement(SetOwnedFlag(info))) + return NS_ERROR_OUT_OF_MEMORY; + + *_retval = (PRUint16) mInterfaces.Count()-1; + return CallQueryInterface(info, aInfo); +} + +/* PRUint16 appendExternalInterface (in nsIInterfaceInfo aInfo); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::AppendExternalInterface(nsIInterfaceInfo *aInfo, PRUint16 *_retval) +{ + if(!mInterfaces.AppendElement(aInfo)) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(aInfo); + *_retval = (PRUint16) mInterfaces.Count()-1; + return NS_OK; +} + +/* PRUint16 indexOf (in nsIIDRef aIID); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::IndexOf(const nsIID & aIID, PRUint16 *_retval) +{ + return IndexOfIID(aIID, _retval); +} + +/* nsIInterfaceInfo interfaceInfoAt (in PRUint16 aIndex); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::InterfaceInfoAt(PRUint16 aIndex, nsIInterfaceInfo **_retval) +{ + NS_ASSERTION(aIndex < (PRUint16)mInterfaces.Count(), "bad index"); + + *_retval = (nsIInterfaceInfo*) ClearOwnedFlag(mInterfaces.ElementAt(aIndex)); + NS_ADDREF(*_retval); + return NS_OK; +} + +/************************************************/ +// nsIInterfaceInfoManager methods... + +/* nsIInterfaceInfo getInfoForIID (in nsIIDPtr iid); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetInfoForIID(const nsIID * iid, nsIInterfaceInfo **_retval) +{ + PRUint16 index; + nsresult rv = IndexOfIID(*iid, &index); + if(NS_FAILED(rv)) + return rv; + return InterfaceInfoAt(index, _retval); +} + +/* nsIInterfaceInfo getInfoForName (in string name); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetInfoForName(const char *name, nsIInterfaceInfo **_retval) +{ + PRUint16 index; + nsresult rv = IndexOfName(name, &index); + if(NS_FAILED(rv)) + return rv; + return InterfaceInfoAt(index, _retval); +} + +/* nsIIDPtr getIIDForName (in string name); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetIIDForName(const char *name, nsIID * *_retval) +{ + PRUint16 index; + nsresult rv = IndexOfName(name, &index); + if(NS_FAILED(rv)) + return rv; + + return InfoAtNoAddRef(index)->GetIID(_retval); +} + +/* string getNameForIID (in nsIIDPtr iid); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetNameForIID(const nsIID * iid, char **_retval) +{ + PRUint16 index; + nsresult rv = IndexOfIID(*iid, &index); + if(NS_FAILED(rv)) + return rv; + + return InfoAtNoAddRef(index)->GetName(_retval); +} + +/* nsIEnumerator enumerateInterfaces (); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::EnumerateInterfaces(nsIEnumerator **_retval) +{ + return EnumerateInterfacesWhoseNamesStartWith(nsnull, _retval); +} + +/* void autoRegisterInterfaces (); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::AutoRegisterInterfaces() +{ + // NOP + return NS_OK; +} + +/* nsIEnumerator enumerateInterfacesWhoseNamesStartWith (in string prefix); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::EnumerateInterfacesWhoseNamesStartWith(const char *prefix, nsIEnumerator **_retval) +{ + int count = (PRUint16) mInterfaces.Count(); + int len = prefix ? PL_strlen(prefix) : 0; + const char* name; + + nsCOMPtr array; + NS_NewISupportsArray(getter_AddRefs(array)); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = InfoAtNoAddRef(i); + if(!prefix || + (NS_SUCCEEDED(info->GetNameShared(&name)) && + name == PL_strnstr(name, prefix, len))) + { + if(!array->AppendElement(info)) + return NS_ERROR_OUT_OF_MEMORY; + } + } + + return array->Enumerate(_retval); +} + +/***************************************************************************/ +/***************************************************************************/ +// implement nsGenericInterfaceInfo + +NS_IMPL_QUERY_INTERFACE2(nsGenericInterfaceInfo, + nsIInterfaceInfo, + nsIGenericInterfaceInfo); + +NS_IMETHODIMP_(nsrefcnt) +nsGenericInterfaceInfo::AddRef() +{ + return mSet->AddRef(); +} + +NS_IMETHODIMP_(nsrefcnt) +nsGenericInterfaceInfo::Release() +{ + return mSet->Release(); +} + +nsGenericInterfaceInfo::nsGenericInterfaceInfo(nsGenericInterfaceInfoSet* aSet, + const char *aName, + const nsIID & aIID, + nsIInterfaceInfo* aParent, + PRUint8 aFlags) + : mName(nsnull), + mIID(aIID), + mSet(aSet), + mParent(aParent), + mFlags(aFlags) +{ + if(mParent) + { + mParent->GetMethodCount(&mMethodBaseIndex); + mParent->GetConstantCount(&mConstantBaseIndex); + } + else + { + mMethodBaseIndex = mConstantBaseIndex = 0; + } +} + +/************************************************/ +// nsIGenericInterfaceInfo methods... + +/* nsXPTParamInfoPtr allocateParamArray (in PRUint16 aCount); */ +NS_IMETHODIMP +nsGenericInterfaceInfo::AllocateParamArray(PRUint16 aCount, nsXPTParamInfo * *_retval) +{ + *_retval = (nsXPTParamInfo*) + XPT_MALLOC(mSet->GetArena(), sizeof(nsXPTParamInfo) * aCount); + return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* nsXPTTypePtr allocateAdditionalType (out PRUint16 aIndex); */ +NS_IMETHODIMP +nsGenericInterfaceInfo::AllocateAdditionalType(PRUint16 *aIndex, nsXPTType * *_retval) +{ + return mSet->AllocateAdditionalType(aIndex, _retval); +} + +/* PRUint16 appendMethod (in nsXPTMethodInfoPtr aMethod); */ +NS_IMETHODIMP +nsGenericInterfaceInfo::AppendMethod(nsXPTMethodInfo * aMethod, PRUint16 *_retval) +{ + nsXPTMethodInfo* desc = (nsXPTMethodInfo*) + XPT_MALLOC(mSet->GetArena(), sizeof(nsXPTMethodInfo)); + if(!desc) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc, aMethod, sizeof(nsXPTMethodInfo)); + + int len = PL_strlen(aMethod->name); + desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1); + if(!desc->name) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc->name, aMethod->name, len); + + return mMethods.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* PRUint16 appendConst (in nsXPTConstantPtr aConst); */ +NS_IMETHODIMP nsGenericInterfaceInfo::AppendConst(nsXPTConstant * aConst, PRUint16 *_retval) + +{ + NS_ASSERTION(aConst->type.prefix.flags == TD_INT16 || + aConst->type.prefix.flags == TD_UINT16 || + aConst->type.prefix.flags == TD_INT32 || + aConst->type.prefix.flags == TD_UINT32, + "unsupported const type"); + + XPTConstDescriptor* desc = (XPTConstDescriptor*) + XPT_MALLOC(mSet->GetArena(), sizeof(XPTConstDescriptor)); + if(!desc) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc, aConst, sizeof(XPTConstDescriptor)); + + int len = PL_strlen(aConst->name); + desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1); + if(!desc->name) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc->name, aConst->name, len); + + return mConstants.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/************************************************/ +// nsIInterfaceInfo methods... + +/* readonly attribute string name; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetName(char * *aName) +{ + *aName = (char*) nsMemory::Clone(mName, PL_strlen(mName)+1); + return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsIIDPtr IID; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetIID(nsIID * *aIID) +{ + *aIID = (nsIID*) nsMemory::Clone(&mIID, sizeof(nsIID)); + return *aIID ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* PRBool isScriptable (); */ +NS_IMETHODIMP nsGenericInterfaceInfo::IsScriptable(PRBool *_retval) +{ + *_retval = XPT_ID_IS_SCRIPTABLE(mFlags) != 0; + return NS_OK; +} + +/* readonly attribute nsIInterfaceInfo parent; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetParent(nsIInterfaceInfo * *aParent) +{ + *aParent = mParent; + NS_IF_ADDREF(*aParent); + return NS_OK; +} + +/* readonly attribute PRUint16 methodCount; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetMethodCount(PRUint16 *aMethodCount) +{ + *aMethodCount = mMethodBaseIndex + (PRUint16) mMethods.Count(); + return NS_OK; +} + +/* readonly attribute PRUint16 constantCount; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetConstantCount(PRUint16 *aConstantCount) +{ + *aConstantCount = mConstantBaseIndex + (PRUint16) mConstants.Count(); + return NS_OK; +} + +/* void getMethodInfo (in PRUint16 index, [shared, retval] out nsXPTMethodInfoPtr info); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetMethodInfo(PRUint16 index, const nsXPTMethodInfo * *info) +{ + if(index < mMethodBaseIndex) + return mParent->GetMethodInfo(index, info); + *info = (const nsXPTMethodInfo *) mMethods.ElementAt(index-mMethodBaseIndex); + return NS_OK; +} + +/* void getMethodInfoForName (in string methodName, out PRUint16 index, [shared, retval] out nsXPTMethodInfoPtr info); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetMethodInfoForName(const char *methodName, PRUint16 *index, const nsXPTMethodInfo * *info) +{ + PRUint16 count = mMethodBaseIndex + (PRUint16) mMethods.Count(); + for(PRUint16 i = 0; i < count; i++) + { + const nsXPTMethodInfo* current; + nsresult rv = GetMethodInfo(i, ¤t); + if(NS_FAILED(rv)) + return rv; + + if(!PL_strcmp(methodName, current->GetName())) + { + *index = i; + *info = current; + return NS_OK; + } + } + *index = 0; + *info = 0; + return NS_ERROR_INVALID_ARG; +} + +/* void getConstant (in PRUint16 index, [shared, retval] out nsXPTConstantPtr constant); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetConstant(PRUint16 index, const nsXPTConstant * *constant) +{ + if(index < mConstantBaseIndex) + return mParent->GetConstant(index, constant); + *constant = (const nsXPTConstant *) mConstants.ElementAt(index-mConstantBaseIndex); + return NS_OK; +} + +/* nsIInterfaceInfo getInfoForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetInfoForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIInterfaceInfo **_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetInfoForParam(methodIndex, param, _retval); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE, "not an interface"); + + return mSet->InterfaceInfoAt(td->type.iface, _retval); +} + +/* nsIIDPtr getIIDForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetIIDForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID * *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetIIDForParam(methodIndex, param, _retval); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE, "not an interface"); + + return mSet->InfoAtNoAddRef(td->type.iface)->GetIID(_retval); +} + +/* nsXPTType getTypeForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetTypeForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, nsXPTType *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetTypeForParam(methodIndex, param, dimension, _retval); + + const XPTTypeDescriptor *td = + dimension ? GetTypeInArray(param, dimension) : ¶m->type; + + *_retval = nsXPTType(td->prefix); + return NS_OK; +} + +/* PRUint8 getSizeIsArgNumberForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetSizeIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetSizeIsArgNumberForParam(methodIndex, param, dimension, _retval); + + const XPTTypeDescriptor *td = + dimension ? GetTypeInArray(param, dimension) : ¶m->type; + + *_retval = td->argnum; + return NS_OK; +} + +/* PRUint8 getLengthIsArgNumberForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetLengthIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetLengthIsArgNumberForParam(methodIndex, param, dimension, _retval); + + const XPTTypeDescriptor *td = + dimension ? GetTypeInArray(param, dimension) : ¶m->type; + + *_retval = td->argnum2; + return NS_OK; +} + +/* PRUint8 getInterfaceIsArgNumberForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint8 *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetInterfaceIsArgNumberForParam(methodIndex, param, _retval); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE, "not an interface"); + + *_retval = td->argnum; + return NS_OK; +} + +/* PRBool isIID (in nsIIDPtr IID); */ +NS_IMETHODIMP nsGenericInterfaceInfo::IsIID(const nsIID * IID, PRBool *_retval) +{ + *_retval = mIID.Equals(*IID); + return NS_OK; +} + +/* void getNameShared ([shared, retval] out string name); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetNameShared(const char **name) +{ + *name = mName; + return NS_OK; +} + +/* void getIIDShared ([shared, retval] out nsIIDPtrShared iid); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetIIDShared(const nsIID * *iid) +{ + *iid = &mIID; + return NS_OK; +} + +/* PRBool isFunction (); */ +NS_IMETHODIMP nsGenericInterfaceInfo::IsFunction(PRBool *_retval) +{ + *_retval = XPT_ID_IS_FUNCTION(mFlags) != 0; + return NS_OK; +} + +/* PRBool hasAncestor (in nsIIDPtr iid); */ +NS_IMETHODIMP nsGenericInterfaceInfo::HasAncestor(const nsIID * iid, PRBool *_retval) +{ + *_retval = PR_FALSE; + + nsCOMPtr current = NS_STATIC_CAST(nsIInterfaceInfo*, this); + while(current) + { + PRBool same; + if(NS_SUCCEEDED(current->IsIID(iid, &same)) && same) + { + *_retval = PR_TRUE; + break; + } + nsCOMPtr temp(current); + temp->GetParent(getter_AddRefs(current)); + } + return NS_OK; +} + +/* [notxpcom] nsresult getIIDForParamNoAlloc (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, out nsIID iid); */ +NS_IMETHODIMP_(nsresult) nsGenericInterfaceInfo::GetIIDForParamNoAlloc(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID *iid) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetIIDForParamNoAlloc(methodIndex, param, iid); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE, "not an interface"); + + const nsIID* iidp; + return mSet->InfoAtNoAddRef(td->type.iface)->GetIIDShared(&iidp); + *iid = *iidp; + return NS_OK; +} diff --git a/extensions/interfaceinfo/src/nsScriptableInterfaceInfo.cpp b/extensions/interfaceinfo/src/nsScriptableInterfaceInfo.cpp new file mode 100644 index 00000000000..4deb9b5d8d5 --- /dev/null +++ b/extensions/interfaceinfo/src/nsScriptableInterfaceInfo.cpp @@ -0,0 +1,786 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * John Bandhauer + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* nsIScriptableInteraceInfo family implementations. */ + +#include "iixprivate.h" + +/***************************************************************************/ +static inline nsresult CloneString(const char* inStr, char** outStr) +{ + *outStr = (char*) nsMemory::Clone(inStr, strlen(inStr)+1); + return *outStr ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/***************************************************************************/ + +/* Header file */ +class nsScriptableDataType : public nsIScriptableDataType +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEDATATYPE + + static nsresult Create(const nsXPTType& aType, + nsIScriptableDataType** aResult); + + nsScriptableDataType(); // not implemented + + nsScriptableDataType(const nsXPTType& aType) + : mType(aType) {NS_INIT_ISUPPORTS();} + + virtual ~nsScriptableDataType() {} + +private: + nsXPTType mType; +}; + +// static +nsresult +nsScriptableDataType::Create(const nsXPTType& aType, + nsIScriptableDataType** aResult) +{ + nsScriptableDataType* obj = new nsScriptableDataType(aType); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableDataType*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableDataType, nsIScriptableDataType) + +/* readonly attribute PRBool isPointer; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsPointer(PRBool *aIsPointer) +{ + *aIsPointer = mType.IsPointer(); + return NS_OK; +} + +/* readonly attribute PRBool isUniquePointer; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsUniquePointer(PRBool *aIsUniquePointer) +{ + *aIsUniquePointer = mType.IsUniquePointer(); + return NS_OK; +} + +/* readonly attribute PRBool isReference; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsReference(PRBool *aIsReference) +{ + *aIsReference = mType.IsReference(); + return NS_OK; +} + +/* readonly attribute PRBool isArithmetic; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsArithmetic(PRBool *aIsArithmetic) +{ + *aIsArithmetic = mType.IsArithmetic(); + return NS_OK; +} + +/* readonly attribute PRBool isInterfacePointer; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsInterfacePointer(PRBool *aIsInterfacePointer) +{ + *aIsInterfacePointer = mType.IsInterfacePointer(); + return NS_OK; +} + +/* readonly attribute PRBool isArray; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsArray(PRBool *aIsArray) +{ + *aIsArray = mType.IsArray(); + return NS_OK; +} + +/* readonly attribute PRBool isDependent; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsDependent(PRBool *aIsDependent) +{ + *aIsDependent = mType.IsDependent(); + return NS_OK; +} + +/* readonly attribute PRUint16 dataType; */ +NS_IMETHODIMP +nsScriptableDataType::GetDataType(PRUint16 *aDataType) +{ + *aDataType = mType.TagPart(); + return NS_OK; +} + +/***************************************************************************/ + +class nsScriptableParamInfo : public nsIScriptableParamInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEPARAMINFO + + static nsresult Create(nsIInterfaceInfo* aInfo, + const nsXPTParamInfo& aParam, + nsIScriptableParamInfo** aResult); + + nsScriptableParamInfo(); // not implemented + nsScriptableParamInfo(nsIInterfaceInfo* aInfo, + const nsXPTParamInfo& aParam) + : mInfo(aInfo), mParam(aParam) {NS_INIT_ISUPPORTS();} + virtual ~nsScriptableParamInfo() {} + +private: + // Holding onto the interface info keeps the underlying param alive. + nsCOMPtr mInfo; + nsXPTParamInfo mParam; +}; + + +// static +nsresult +nsScriptableParamInfo::Create(nsIInterfaceInfo* aInfo, + const nsXPTParamInfo& aParam, + nsIScriptableParamInfo** aResult) +{ + nsScriptableParamInfo* obj = new nsScriptableParamInfo(aInfo, aParam); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableParamInfo*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableParamInfo, nsIScriptableParamInfo) + +/* readonly attribute PRBool isIn; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsIn(PRBool *aIsIn) +{ + *aIsIn = mParam.IsIn(); + return NS_OK; +} + +/* readonly attribute PRBool isOut; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsOut(PRBool *aIsOut) +{ + *aIsOut = mParam.IsOut(); + return NS_OK; +} + +/* readonly attribute PRBool isRetval; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsRetval(PRBool *aIsRetval) +{ + *aIsRetval = mParam.IsRetval(); + return NS_OK; +} + +/* readonly attribute PRBool isShared; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsShared(PRBool *aIsShared) +{ + *aIsShared = mParam.IsShared(); + return NS_OK; +} + +/* readonly attribute PRBool isDipper; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsDipper(PRBool *aIsDipper) +{ + *aIsDipper = mParam.IsDipper(); + return NS_OK; +} + +/* readonly attribute nsIScriptableDataType type; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetType(nsIScriptableDataType * *aType) +{ + return nsScriptableDataType::Create(mParam.GetType(), aType); +} + +/* [noscript] void getParamInfo ([shared, const, retval] out nsXPTParamInfoPtr aInfo); */ +NS_IMETHODIMP +nsScriptableParamInfo::GetParamInfo(const nsXPTParamInfo * *aInfo) +{ + *aInfo = &mParam; + return NS_OK; +} + +/***************************************************************************/ +class nsScriptableConstant : public nsIScriptableConstant +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLECONSTANT + + static nsresult Create(nsIInterfaceInfo* aInfo, + const nsXPTConstant& aConst, + nsIScriptableConstant** aResult); + + nsScriptableConstant(); // not implemented + nsScriptableConstant(nsIInterfaceInfo* aInfo, + const nsXPTConstant& aConst) + : mInfo(aInfo), mConst(aConst) {NS_INIT_ISUPPORTS();} + virtual ~nsScriptableConstant() {} +private: + // Holding onto the interface info keeps the underlying const alive. + nsCOMPtr mInfo; + nsXPTConstant mConst; +}; + +// static +nsresult +nsScriptableConstant::Create(nsIInterfaceInfo* aInfo, + const nsXPTConstant& aConst, + nsIScriptableConstant** aResult) +{ + nsScriptableConstant* obj = new nsScriptableConstant(aInfo, aConst); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableConstant*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableConstant, nsIScriptableConstant) + +/* readonly attribute string name; */ +NS_IMETHODIMP +nsScriptableConstant::GetName(char * *aName) +{ + return CloneString(mConst.GetName(), aName); +} + +/* readonly attribute nsIScriptableDataType type; */ +NS_IMETHODIMP +nsScriptableConstant::GetType(nsIScriptableDataType * *aType) +{ + return nsScriptableDataType::Create(mConst.GetType(), aType); +} + +/* readonly attribute nsIVariant value; */ +NS_IMETHODIMP +nsScriptableConstant::GetValue(nsIVariant * *aValue) +{ + nsVariant* variant = new nsVariant(); + if(!variant) + { + *aValue = nsnull; + return NS_ERROR_OUT_OF_MEMORY; + } + *aValue = NS_STATIC_CAST(nsIVariant*, variant); + NS_ADDREF(*aValue); + + const nsXPTCMiniVariant* varval = mConst.GetValue(); + nsresult rv; + + switch(mConst.GetType()) + { + case nsXPTType::T_I16: + rv = variant->SetAsInt16(varval->val.i16); + break; + case nsXPTType::T_I32: + rv = variant->SetAsInt32(varval->val.i32); + break; + case nsXPTType::T_U16: + rv = variant->SetAsUint16(varval->val.u16); + break; + case nsXPTType::T_U32: + rv = variant->SetAsUint32(varval->val.u32); + break; + default: + NS_ERROR("invalid const type"); + rv = NS_ERROR_UNEXPECTED; + break; + } + + if(NS_FAILED(rv)) + { + NS_RELEASE(*aValue); + return rv; + } + + return NS_OK; +} + +/***************************************************************************/ + +class nsScriptableMethodInfo : public nsIScriptableMethodInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEMETHODINFO + + static nsresult Create(nsIInterfaceInfo* aInfo, + const nsXPTMethodInfo& aMethod, + nsIScriptableMethodInfo** aResult); + + nsScriptableMethodInfo(); // not implemented + nsScriptableMethodInfo(nsIInterfaceInfo* aInfo, + const nsXPTMethodInfo& aMethod) + : mInfo(aInfo), mMethod(aMethod) {NS_INIT_ISUPPORTS();} + virtual ~nsScriptableMethodInfo() {} +private: + // Holding onto the interface info keeps the underlying method alive. + nsCOMPtr mInfo; + const nsXPTMethodInfo& mMethod; +}; + +// static +nsresult +nsScriptableMethodInfo::Create(nsIInterfaceInfo* aInfo, + const nsXPTMethodInfo& aMethod, + nsIScriptableMethodInfo** aResult) +{ + nsScriptableMethodInfo* obj = new nsScriptableMethodInfo(aInfo, aMethod); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableMethodInfo*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableMethodInfo, nsIScriptableMethodInfo) + +/* readonly attribute PRBool isGetter; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsGetter(PRBool *aIsGetter) +{ + *aIsGetter = mMethod.IsGetter(); + return NS_OK; +} + +/* readonly attribute PRBool isSetter; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsSetter(PRBool *aIsSetter) +{ + *aIsSetter = mMethod.IsSetter(); + return NS_OK; +} + +/* readonly attribute PRBool isNotXPCOM; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsNotXPCOM(PRBool *aIsNotXPCOM) +{ + *aIsNotXPCOM = mMethod.IsNotXPCOM(); + return NS_OK; +} + +/* readonly attribute PRBool isConstructor; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsConstructor(PRBool *aIsConstructor) +{ + *aIsConstructor = mMethod.IsConstructor(); + return NS_OK; +} + +/* readonly attribute PRBool isHidden; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsHidden(PRBool *aIsHidden) +{ + *aIsHidden = mMethod.IsHidden(); + return NS_OK; +} + +/* readonly attribute string name; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetName(char * *aName) +{ + return CloneString(mMethod.GetName(), aName); +} + +/* readonly attribute PRUint8 paramCount; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetParamCount(PRUint8 *aParamCount) +{ + *aParamCount = mMethod.GetParamCount(); + return NS_OK; +} + +/* nsIScriptableParamInfo getParam (in PRUint8 idx); */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetParam(PRUint8 idx, nsIScriptableParamInfo **_retval) +{ + if(idx >= mMethod.GetParamCount()) + return NS_ERROR_INVALID_ARG; + return nsScriptableParamInfo::Create(mInfo, mMethod.GetParam(idx), _retval); +} + +/* readonly attribute nsIScriptableParamInfo result; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetResult(nsIScriptableParamInfo * *aResult) +{ + return nsScriptableParamInfo::Create(mInfo, mMethod.GetResult(), aResult); +} + +/***************************************************************************/ + +// static +nsresult +nsScriptableInterfaceInfo::Create(nsIInterfaceInfo* aInfo, + nsIScriptableInterfaceInfo** aResult) +{ + nsScriptableInterfaceInfo* obj = new nsScriptableInterfaceInfo(aInfo); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableInterfaceInfo*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableInterfaceInfo, nsIScriptableInterfaceInfo) + +nsScriptableInterfaceInfo::nsScriptableInterfaceInfo() +{ + NS_INIT_ISUPPORTS(); +} + +nsScriptableInterfaceInfo::nsScriptableInterfaceInfo(nsIInterfaceInfo* aInfo) + : mInfo(aInfo) +{ + NS_INIT_ISUPPORTS(); +} + +nsScriptableInterfaceInfo::~nsScriptableInterfaceInfo() +{ + // empty; +} + +/* [noscript] attribute nsIInterfaceInfo info; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInfo(nsIInterfaceInfo * *aInfo) +{ + if(mInfo) + NS_ADDREF(*aInfo = mInfo); + else + *aInfo = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsScriptableInterfaceInfo::SetInfo(nsIInterfaceInfo * aInfo) +{ + mInfo = aInfo; + return NS_OK; +} + +/* void Init (in nsIIDPtr aIID); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::Init(const nsIID * aIID) +{ + return SetInterfaceID(aIID); +} + +/* readonly attribute string name; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetName(char * *aName) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetName(aName); +} + +/* attribute nsIIDPtr interfaceID; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInterfaceID(nsIID * *aInterfaceID) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetIID(aInterfaceID); +} + +NS_IMETHODIMP +nsScriptableInterfaceInfo::SetInterfaceID(const nsIID * aInterfaceID) +{ + nsCOMPtr iim = + dont_AddRef(XPTI_GetInterfaceInfoManager()); + if(!iim) + return NS_ERROR_UNEXPECTED; + mInfo = nsnull; + iim->GetInfoForIID(aInterfaceID, getter_AddRefs(mInfo)); + + // XXX we want to look at additional managers here if not found! + + return mInfo ? NS_OK : NS_ERROR_NO_INTERFACE; +} + +/* readonly attribute PRBool isValid; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIsValid(PRBool *aIsValid) +{ + *aIsValid = !!mInfo; + return NS_OK; +} + +/* readonly attribute PRBool isScriptable; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIsScriptable(PRBool *aIsScriptable) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->IsScriptable(aIsScriptable); +} + +/* readonly attribute nsIScriptableInterfaceInfo parent; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetParent(nsIScriptableInterfaceInfo * *aParent) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + nsCOMPtr parentInfo; + nsresult rv = mInfo->GetParent(getter_AddRefs(parentInfo)); + if(NS_FAILED(rv)) + return rv; + + if(parentInfo) + return Create(parentInfo, aParent); + + *aParent = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint16 methodCount; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetMethodCount(PRUint16 *aMethodCount) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetMethodCount(aMethodCount); +} + +/* readonly attribute PRUint16 constantCount; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetConstantCount(PRUint16 *aConstantCount) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetConstantCount(aConstantCount); +} + +/* nsIScriptableMethodInfo getMethodInfo (in PRUint16 index); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetMethodInfo(PRUint16 index, nsIScriptableMethodInfo **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTMethodInfo* methodInfo; + nsresult rv = mInfo->GetMethodInfo(index, &methodInfo); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableMethodInfo::Create(mInfo, *methodInfo, _retval); +} + +/* nsIScriptableMethodInfo getMethodInfoForName (in string methodName, out PRUint16 index); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetMethodInfoForName(const char *methodName, PRUint16 *index, nsIScriptableMethodInfo **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTMethodInfo* methodInfo; + nsresult rv = mInfo->GetMethodInfoForName(methodName, index, &methodInfo); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableMethodInfo::Create(mInfo, *methodInfo, _retval); +} + +/* nsIScriptableConstant getConstant (in PRUint16 index); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetConstant(PRUint16 index, nsIScriptableConstant **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTConstant* constant; + nsresult rv = mInfo->GetConstant(index, &constant); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableConstant::Create(mInfo, *constant, _retval); +} + +/* nsIScriptableInterfaceInfo getInfoForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInfoForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, nsIScriptableInterfaceInfo **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + nsCOMPtr info; + rv = mInfo->GetInfoForParam(methodIndex, paramInfo, getter_AddRefs(info)); + if(NS_FAILED(rv)) + return rv; + + if(info) + return Create(info, _retval); + + *_retval = nsnull; + return NS_OK; +} + +/* nsIIDPtr getIIDForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIIDForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, nsIID * *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetIIDForParam(methodIndex, paramInfo, _retval); +} + +/* nsIScriptableDataType getTypeForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param, in PRUint16 dimension); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetTypeForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint16 dimension, nsIScriptableDataType **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + nsXPTType type; + + rv = mInfo->GetTypeForParam(methodIndex, paramInfo, dimension, &type); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableDataType::Create(type, _retval); +} + +/* PRUint8 getSizeIsArgNumberForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param, in PRUint16 dimension); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetSizeIsArgNumberForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint16 dimension, PRUint8 *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetSizeIsArgNumberForParam(methodIndex, paramInfo, + dimension, _retval); +} + +/* PRUint8 getLengthIsArgNumberForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param, in PRUint16 dimension); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetLengthIsArgNumberForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint16 dimension, PRUint8 *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetLengthIsArgNumberForParam(methodIndex, paramInfo, + dimension, _retval); +} + +/* PRUint8 getInterfaceIsArgNumberForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint8 *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetInterfaceIsArgNumberForParam(methodIndex, paramInfo, + _retval); +} + +/* PRBool isIID (in nsIIDPtr IID); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::IsIID(const nsIID * IID, PRBool *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->IsIID(IID, _retval); +} + +/* readonly attribute PRBool isFunction; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIsFunction(PRBool *aIsFunction) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->IsFunction(aIsFunction); +} + +/* PRBool hasAncestor (in nsIIDPtr iid); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::HasAncestor(const nsIID * iid, PRBool *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->HasAncestor(iid, _retval); +} diff --git a/extensions/interfaceinfo/tests/ifaceinfotest.js b/extensions/interfaceinfo/tests/ifaceinfotest.js new file mode 100644 index 00000000000..f490462fd66 --- /dev/null +++ b/extensions/interfaceinfo/tests/ifaceinfotest.js @@ -0,0 +1,364 @@ +// test the nsIScriptableInterfaceInfo stuff... +// We ought to leverage this in SOAP code. + +const IInfo = new Components.Constructor("@mozilla.org/scriptableInterfaceInfo;1", + "nsIScriptableInterfaceInfo", + "init"); + +const nsIDataType = Components.interfaces.nsIDataType; +const nsISupports = Components.interfaces.nsISupports; + +const PARAM_NAME_PREFIX = "arg"; + +/** +* takes: {xxx} +* returns: uuid(xxx) +*/ +function formatID(str) +{ + return "uuid("+str.substring(1,str.length-1)+")"; +} + +function formatConstType(type) +{ + switch(type) + { + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + default: + return "!!!! bad const type !!!"; + } +} + +function formatTypeName(info, methodIndex, param, dimension) +{ + var type = param.type; + + switch(type.dataType) + { + case nsIDataType.VTYPE_INT8 : + return "PRInt8"; + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_INT64: + return "PRInt64"; + case nsIDataType.VTYPE_UINT8: + return "PRUint8"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + case nsIDataType.VTYPE_UINT64: + return "PRUint64"; + case nsIDataType.VTYPE_FLOAT: + return "float"; + case nsIDataType.VTYPE_DOUBLE: + return "double"; + case nsIDataType.VTYPE_BOOL: + return "PRBool"; + case nsIDataType.VTYPE_CHAR: + return "char"; + case nsIDataType.VTYPE_WCHAR: + return "PRUnichar"; + case nsIDataType.VTYPE_VOID: + if(type.isPointer) + return "voidPtr"; + return "void"; + case nsIDataType.VTYPE_ID: + // order matters here... + if(type.isReference) + return "nsIDRef"; + if(type.isPointer) + return "nsIDPtr"; + return "nsID"; + case nsIDataType.VTYPE_ASTRING: + return "aString"; + case nsIDataType.VTYPE_CHAR_STR: + return "string"; + case nsIDataType.VTYPE_WCHAR_STR: + return "wstring"; + case nsIDataType.VTYPE_INTERFACE: + return info.getInfoForParam(methodIndex, param).name; + case nsIDataType.VTYPE_INTERFACE_IS: + return "nsQIResult"; + case nsIDataType.VTYPE_ARRAY: + return formatTypeName(info, methodIndex, param, dimension+1); + case nsIDataType.VTYPE_STRING_SIZE_IS: + return "string"; + case nsIDataType.VTYPE_WSTRING_SIZE_IS: + return "wstring"; + default: + return "!!!! bad data type !!!"; + } +} + +function formatBracketForParam(info, methodIndex, param) +{ + var type = param.type; + var str = "["; + var found = 0; + var size_is_ArgNum; + var length_is_ArgNum; + + if(param.isRetval) + { + if(found++) + str += ", "; + str += "retval" + } + + if(param.isShared) + { + if(found++) + str += ", "; + str += "shared" + } + + if(type.isArray) + { + if(found++) + str += ", "; + str += "array" + } + + if(type.dataType == nsIDataType.VTYPE_INTERFACE_IS) + { + if(found++) + str += ", "; + str += "iid_is("+ + PARAM_NAME_PREFIX + + info.getInterfaceIsArgNumberForParam(methodIndex, param) + ")"; + } + + if(type.isArray || + type.dataType == nsIDataType.VTYPE_STRING_SIZE_IS || + type.dataType == nsIDataType.VTYPE_WSTRING_SIZE_IS) + { + if(found++) + str += ", "; + + size_is_ArgNum = + info.getSizeIsArgNumberForParam(methodIndex, param, 0); + + str += "size_is("+ PARAM_NAME_PREFIX + size_is_ArgNum + ")"; + + length_is_ArgNum = + info.getLengthIsArgNumberForParam(methodIndex, param, 0); + + if(length_is_ArgNum != size_is_ArgNum) + { + str += ", "; + str += "length_is("+ PARAM_NAME_PREFIX + length_is_ArgNum + ")"; + } + } + + if(!found) + return ""; + str += "] "; + return str +} + +function doInterface(iid) +{ + var i, k, t, m, m2, c, p, readonly, bracketed, paramCount, retvalTypeName; + + var info = new IInfo(iid); + var parent = info.parent; + + var constBaseIndex = parent ? parent.constantCount : 0; + var constTotalCount = info.constantCount; + var constLocalCount = constTotalCount - constBaseIndex; + + var methodBaseIndex = parent ? parent.methodCount : 0; + var methodTotalCount = info.methodCount; + var methodLocalCount = methodTotalCount - methodBaseIndex; + + + // maybe recurring to emit parent declarations is not a good idea... +// if(parent) +// doInterface(parent.interfaceID); + + print(); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// print("/*\n"); + + print("[" + (info.isScriptable ? "scriptable, " : "") + + formatID(info.interfaceID.number) + "]"); + + print("interface "+ info.name + (parent ? (" : "+parent.name) : "") + " {"); + + if(constLocalCount) + { + for(i = constBaseIndex; i < constTotalCount; i++) + { + c = info.getConstant(i); + print(" const " + formatConstType(c.type.dataType) + " " + + c.name + " = " + c.value + ";"); + } + } + + if(constLocalCount && methodLocalCount) + print(); + + if(methodLocalCount) + { + for(i = methodBaseIndex; i < methodTotalCount; i++) + { + m = info.getMethodInfo(i); + + if(m.isNotXPCOM) + bracketed = "[notxpcom] " + else if(m.isHidden) + bracketed = "[noscript] " + else + bracketed = ""; + + if(m.isGetter) + { + // Is an attribute + + // figure out if this is readonly + m2 = i+1 < methodTotalCount ? info.getMethodInfo(i+1) : null; + readonly = !m2 || m2.name != m.name; + + print(" " + bracketed + (readonly ? "readonly " : "") + + "attribute " + + formatTypeName(info, i, m.getParam(0), 0) + + " " + m.name + ";\n"); + + if(!readonly) + i++; // skip the next one, we have it covered. + + continue; + } + // else... + + paramCount = m.paramCount; + + // 'last' param is used to figure out retvalTypeName + + p = paramCount ? m.getParam(paramCount-1) : null; + + if(m.isNotXPCOM) + retvalTypeName = formatTypeName(info, i, m.result, 0); + else if(p && "[retval] " == formatBracketForParam(info, i, p)) + { + // Check for the exact string above because anything else + // indicates that there either is no expilict retval + // or there are additional braketed attributes (meaning that + // the retval must appear in the param list and not + // preceeding the method name). + retvalTypeName = formatTypeName(info, i, p, 0); + // no need to print it in the param list + paramCount-- ; + } + else + retvalTypeName = "void"; + + // print method name + + print(" " + bracketed + retvalTypeName + " " + m.name + "(" + + (paramCount ? "" : ");")); + + // print params + + for(k = 0; k < paramCount; k++) + { + p = m.getParam(k); + print(" "+ + formatBracketForParam(info, i, p) + + (p.isOut ? p.isIn ? "inout " : "out " : "in ") + + formatTypeName(info, i, p, 0) + " " + + PARAM_NAME_PREFIX+k + + (k+1 == paramCount ? ");\n" : ", ")); + } + } + } + + print("};\n"); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// print("\n*/\n"); +} + +function appendForwardDeclarations(list, info) +{ + list.push(info.name); + if(info.parent) + appendForwardDeclarations(list, info.parent); + + var i, k, m, p; + + for(i = 0; i < info.methodCount; i++) + { + m = info.getMethodInfo(i); + + for(k = 0; k < m.paramCount; k++) + { + p = m.getParam(k); + + if(p.type.dataType == nsIDataType.VTYPE_INTERFACE) + { + list.push(info.getInfoForParam(i, p).name); + } + } + } +} + +function doForwardDeclarations(iid) +{ + var i, cur, prev; + var list = []; + appendForwardDeclarations(list, new IInfo(iid)); + list.sort(); + + print("// forward declarations..."); + + for(i = 0; i < list.length; i++) + { + cur = list[i]; + if(cur != prev && cur != "nsISupports") + { + print("interface " + cur +";"); + prev = cur; + } + } + print(""); +} + +function info2IDL(iid) +{ + print(); + print('#include "nsISupports.idl"'); + print(); + + doForwardDeclarations(iid) + doInterface(iid); +} + +/***************************************************************************/ +/***************************************************************************/ +// test... + +print(); +print(); +//info2IDL(Components.interfaces.nsISupports); +print("//------------------------------------------------------------"); +info2IDL(Components.interfaces.nsIDataType); +print("//------------------------------------------------------------"); +info2IDL(Components.interfaces.nsIScriptableInterfaceInfo); +print("//------------------------------------------------------------"); +info2IDL(Components.interfaces.nsIVariant); +print(); +print(); diff --git a/extensions/webservices/interfaceinfo/src/iixprivate.h b/extensions/webservices/interfaceinfo/src/iixprivate.h new file mode 100644 index 00000000000..5b4e8472255 --- /dev/null +++ b/extensions/webservices/interfaceinfo/src/iixprivate.h @@ -0,0 +1,177 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe + * John Bandhauer + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Library-private header for Interface Info extras system. */ + +#ifndef iixprivate_h___ +#define iixprivate_h___ + +#include "nsCOMPtr.h" +#include "nsVoidArray.h" +#include "nsSupportsArray.h" +#include "nsString.h" +#include "nsReadableUtils.h" +#include "nsWeakReference.h" +#include "nsIGenericFactory.h" +#include "nsVariant.h" + +#include "nsIInterfaceInfo.h" +#include "nsIInterfaceInfoManager.h" +#include "xpt_struct.h" +#include "xptinfo.h" +#include "xptcall.h" + +#include "nsIGenericInterfaceInfoSet.h" +#include "nsIScriptableInterfaceInfo.h" + +/***************************************************************************/ + +class nsGenericInterfaceInfoSet : public nsIGenericInterfaceInfoSet, + public nsSupportsWeakReference +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERFACEINFOMANAGER + NS_DECL_NSIGENERICINTERFACEINFOSET + + nsGenericInterfaceInfoSet(); + virtual ~nsGenericInterfaceInfoSet(); + + XPTArena* GetArena() {return mArena;} + nsresult AllocateAdditionalType(PRUint16 *aIndex, nsXPTType * *_retval); + + const XPTTypeDescriptor* GetAdditionalTypeAt(PRUint16 aIndex) + { + NS_ASSERTION(aIndex < (PRUint16) mAdditionalTypes.Count(), "bad index"); + return (const XPTTypeDescriptor*) mAdditionalTypes.ElementAt(aIndex); + } + + nsIInterfaceInfo* InfoAtNoAddRef(PRUint16 aIndex) + { + NS_ASSERTION(aIndex < (PRUint16) mInterfaces.Count(), "bad index"); + return (nsIInterfaceInfo*) ClearOwnedFlag(mInterfaces.ElementAt(aIndex)); + } + +private: + nsresult IndexOfIID(const nsIID & aIID, PRUint16 *_retval); + nsresult IndexOfName(const char* aName, PRUint16 *_retval); + + void* SetOwnedFlag(void* p) {return (void*) ((long)p | 1);} + void* ClearOwnedFlag(void* p) {return (void*) ((long)p & ~(long)1);} + PRBool CheckOwnedFlag(void* p) {return (PRBool) ((long)p & (long)1);} + + +private: + nsVoidArray mInterfaces; + nsVoidArray mAdditionalTypes; + XPTArena* mArena; +}; + +/***************************************************************************/ + +class nsGenericInterfaceInfo : public nsIGenericInterfaceInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERFACEINFO + NS_DECL_NSIGENERICINTERFACEINFO + + nsGenericInterfaceInfo(); // not implemented + nsGenericInterfaceInfo(nsGenericInterfaceInfoSet* aSet, + const char *aName, + const nsIID & aIID, + nsIInterfaceInfo* mParent, + PRUint8 aFlags); + virtual ~nsGenericInterfaceInfo() {} + +private: + const XPTTypeDescriptor* GetPossiblyNestedType(const nsXPTParamInfo* param) + { + const XPTTypeDescriptor* td = ¶m->type; + while(XPT_TDP_TAG(td->prefix) == TD_ARRAY) + td = mSet->GetAdditionalTypeAt(td->type.additional_type); + return td; + } + + const XPTTypeDescriptor* GetTypeInArray(const nsXPTParamInfo* param, + PRUint16 dimension) + { + const XPTTypeDescriptor* td = ¶m->type; + for(PRUint16 i = 0; i < dimension; i++) + { + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_ARRAY, "bad dimension"); + td = mSet->GetAdditionalTypeAt(td->type.additional_type); + } + return td; + } + +private: + char* mName; + nsIID mIID; + nsVoidArray mMethods; + nsVoidArray mConstants; + nsGenericInterfaceInfoSet* mSet; + nsIInterfaceInfo* mParent; // weak reference (it must be held in set table) + PRUint16 mMethodBaseIndex; + PRUint16 mConstantBaseIndex; + PRUint8 mFlags; +}; + +/***************************************************************************/ + +class nsScriptableInterfaceInfo : public nsIScriptableInterfaceInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEINTERFACEINFO + + static nsresult Create(nsIInterfaceInfo* aInfo, + nsIScriptableInterfaceInfo** aResult); + + nsScriptableInterfaceInfo(); + nsScriptableInterfaceInfo(nsIInterfaceInfo* aInfo); + virtual ~nsScriptableInterfaceInfo(); + +private: + nsCOMPtr mInfo; +}; + +/***************************************************************************/ + +#endif /* iixprivate_h___ */ diff --git a/extensions/webservices/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp b/extensions/webservices/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp new file mode 100644 index 00000000000..b9f8b46452d --- /dev/null +++ b/extensions/webservices/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp @@ -0,0 +1,597 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsGenericInterfaceInfo/nsGenericInterfaceInfoSet implementations.*/ + +#include "iixprivate.h" + + +/***************************************************************************/ +// implement nsGenericInterfaceInfoSet + +#define ARENA_BLOCK_SIZE (1024 * 1) + +NS_IMPL_THREADSAFE_ISUPPORTS3(nsGenericInterfaceInfoSet, + nsIInterfaceInfoManager, + nsIGenericInterfaceInfoSet, + nsISupportsWeakReference); + +nsGenericInterfaceInfoSet::nsGenericInterfaceInfoSet() +{ + NS_INIT_ISUPPORTS(); + mArena = XPT_NewArena(ARENA_BLOCK_SIZE, sizeof(double), + "nsGenericInterfaceInfoSet Arena"); +} + +nsGenericInterfaceInfoSet::~nsGenericInterfaceInfoSet() +{ + PRInt32 count = mInterfaces.Count(); + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i); + if(CheckOwnedFlag(info)) + delete (nsGenericInterfaceInfo*) ClearOwnedFlag(info); + else + NS_RELEASE(info); + } + + if(mArena) + XPT_DestroyArena(mArena); +} + +nsresult +nsGenericInterfaceInfoSet::AllocateAdditionalType(PRUint16 *aIndex, nsXPTType * *_retval) +{ + *_retval = (nsXPTType*) + XPT_MALLOC(GetArena(), sizeof(nsXPTType)); + if(!*_retval || !mAdditionalTypes.AppendElement(*_retval)) + return NS_ERROR_OUT_OF_MEMORY; + *aIndex = (PRUint16) mAdditionalTypes.Count()-1; + return NS_OK; +} + +nsresult +nsGenericInterfaceInfoSet::IndexOfIID(const nsIID & aIID, PRUint16 *_retval) +{ + PRInt32 count = mInterfaces.Count(); + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i); + const nsID* iid; + nsresult rv = info->GetIIDShared(&iid); + if(NS_FAILED(rv)) + return rv; + if(iid->Equals(aIID)) + { + *_retval = (PRUint16) i; + return NS_OK; + } + } + return NS_ERROR_NO_INTERFACE; +} + +nsresult +nsGenericInterfaceInfoSet::IndexOfName(const char* aName, PRUint16 *_retval) +{ + PRInt32 count = mInterfaces.Count(); + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i); + const char* name; + nsresult rv = info->GetNameShared(&name); + if(NS_FAILED(rv)) + return rv; + if(!strcmp(name, aName)) + { + *_retval = (PRUint16) i; + return NS_OK; + } + } + return NS_ERROR_NO_INTERFACE; +} + +/************************************************/ +// nsIGenericInterfaceInfoSet methods... + +/* PRUint16 createAndAppendInterface (in string aName, in nsIIDRef aIID, in PRUint16 aParent, in PRUint8 aFlags, out nsIGenericInterfaceInfo aInfo); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::CreateAndAppendInterface(const char *aName, const nsIID & aIID, PRUint16 aParent, PRUint8 aFlags, nsIGenericInterfaceInfo **aInfo, PRUint16 *_retval) +{ + nsGenericInterfaceInfo* info = + new nsGenericInterfaceInfo(this, aName, aIID, + (aParent == (PRUint16) -1) ? + nsnull : InfoAtNoAddRef(aParent), + aFlags); + if(!info || !mInterfaces.AppendElement(SetOwnedFlag(info))) + return NS_ERROR_OUT_OF_MEMORY; + + *_retval = (PRUint16) mInterfaces.Count()-1; + return CallQueryInterface(info, aInfo); +} + +/* PRUint16 appendExternalInterface (in nsIInterfaceInfo aInfo); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::AppendExternalInterface(nsIInterfaceInfo *aInfo, PRUint16 *_retval) +{ + if(!mInterfaces.AppendElement(aInfo)) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(aInfo); + *_retval = (PRUint16) mInterfaces.Count()-1; + return NS_OK; +} + +/* PRUint16 indexOf (in nsIIDRef aIID); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::IndexOf(const nsIID & aIID, PRUint16 *_retval) +{ + return IndexOfIID(aIID, _retval); +} + +/* nsIInterfaceInfo interfaceInfoAt (in PRUint16 aIndex); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::InterfaceInfoAt(PRUint16 aIndex, nsIInterfaceInfo **_retval) +{ + NS_ASSERTION(aIndex < (PRUint16)mInterfaces.Count(), "bad index"); + + *_retval = (nsIInterfaceInfo*) ClearOwnedFlag(mInterfaces.ElementAt(aIndex)); + NS_ADDREF(*_retval); + return NS_OK; +} + +/************************************************/ +// nsIInterfaceInfoManager methods... + +/* nsIInterfaceInfo getInfoForIID (in nsIIDPtr iid); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetInfoForIID(const nsIID * iid, nsIInterfaceInfo **_retval) +{ + PRUint16 index; + nsresult rv = IndexOfIID(*iid, &index); + if(NS_FAILED(rv)) + return rv; + return InterfaceInfoAt(index, _retval); +} + +/* nsIInterfaceInfo getInfoForName (in string name); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetInfoForName(const char *name, nsIInterfaceInfo **_retval) +{ + PRUint16 index; + nsresult rv = IndexOfName(name, &index); + if(NS_FAILED(rv)) + return rv; + return InterfaceInfoAt(index, _retval); +} + +/* nsIIDPtr getIIDForName (in string name); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetIIDForName(const char *name, nsIID * *_retval) +{ + PRUint16 index; + nsresult rv = IndexOfName(name, &index); + if(NS_FAILED(rv)) + return rv; + + return InfoAtNoAddRef(index)->GetIID(_retval); +} + +/* string getNameForIID (in nsIIDPtr iid); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetNameForIID(const nsIID * iid, char **_retval) +{ + PRUint16 index; + nsresult rv = IndexOfIID(*iid, &index); + if(NS_FAILED(rv)) + return rv; + + return InfoAtNoAddRef(index)->GetName(_retval); +} + +/* nsIEnumerator enumerateInterfaces (); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::EnumerateInterfaces(nsIEnumerator **_retval) +{ + return EnumerateInterfacesWhoseNamesStartWith(nsnull, _retval); +} + +/* void autoRegisterInterfaces (); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::AutoRegisterInterfaces() +{ + // NOP + return NS_OK; +} + +/* nsIEnumerator enumerateInterfacesWhoseNamesStartWith (in string prefix); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::EnumerateInterfacesWhoseNamesStartWith(const char *prefix, nsIEnumerator **_retval) +{ + int count = (PRUint16) mInterfaces.Count(); + int len = prefix ? PL_strlen(prefix) : 0; + const char* name; + + nsCOMPtr array; + NS_NewISupportsArray(getter_AddRefs(array)); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = InfoAtNoAddRef(i); + if(!prefix || + (NS_SUCCEEDED(info->GetNameShared(&name)) && + name == PL_strnstr(name, prefix, len))) + { + if(!array->AppendElement(info)) + return NS_ERROR_OUT_OF_MEMORY; + } + } + + return array->Enumerate(_retval); +} + +/***************************************************************************/ +/***************************************************************************/ +// implement nsGenericInterfaceInfo + +NS_IMPL_QUERY_INTERFACE2(nsGenericInterfaceInfo, + nsIInterfaceInfo, + nsIGenericInterfaceInfo); + +NS_IMETHODIMP_(nsrefcnt) +nsGenericInterfaceInfo::AddRef() +{ + return mSet->AddRef(); +} + +NS_IMETHODIMP_(nsrefcnt) +nsGenericInterfaceInfo::Release() +{ + return mSet->Release(); +} + +nsGenericInterfaceInfo::nsGenericInterfaceInfo(nsGenericInterfaceInfoSet* aSet, + const char *aName, + const nsIID & aIID, + nsIInterfaceInfo* aParent, + PRUint8 aFlags) + : mName(nsnull), + mIID(aIID), + mSet(aSet), + mParent(aParent), + mFlags(aFlags) +{ + if(mParent) + { + mParent->GetMethodCount(&mMethodBaseIndex); + mParent->GetConstantCount(&mConstantBaseIndex); + } + else + { + mMethodBaseIndex = mConstantBaseIndex = 0; + } +} + +/************************************************/ +// nsIGenericInterfaceInfo methods... + +/* nsXPTParamInfoPtr allocateParamArray (in PRUint16 aCount); */ +NS_IMETHODIMP +nsGenericInterfaceInfo::AllocateParamArray(PRUint16 aCount, nsXPTParamInfo * *_retval) +{ + *_retval = (nsXPTParamInfo*) + XPT_MALLOC(mSet->GetArena(), sizeof(nsXPTParamInfo) * aCount); + return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* nsXPTTypePtr allocateAdditionalType (out PRUint16 aIndex); */ +NS_IMETHODIMP +nsGenericInterfaceInfo::AllocateAdditionalType(PRUint16 *aIndex, nsXPTType * *_retval) +{ + return mSet->AllocateAdditionalType(aIndex, _retval); +} + +/* PRUint16 appendMethod (in nsXPTMethodInfoPtr aMethod); */ +NS_IMETHODIMP +nsGenericInterfaceInfo::AppendMethod(nsXPTMethodInfo * aMethod, PRUint16 *_retval) +{ + nsXPTMethodInfo* desc = (nsXPTMethodInfo*) + XPT_MALLOC(mSet->GetArena(), sizeof(nsXPTMethodInfo)); + if(!desc) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc, aMethod, sizeof(nsXPTMethodInfo)); + + int len = PL_strlen(aMethod->name); + desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1); + if(!desc->name) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc->name, aMethod->name, len); + + return mMethods.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* PRUint16 appendConst (in nsXPTConstantPtr aConst); */ +NS_IMETHODIMP nsGenericInterfaceInfo::AppendConst(nsXPTConstant * aConst, PRUint16 *_retval) + +{ + NS_ASSERTION(aConst->type.prefix.flags == TD_INT16 || + aConst->type.prefix.flags == TD_UINT16 || + aConst->type.prefix.flags == TD_INT32 || + aConst->type.prefix.flags == TD_UINT32, + "unsupported const type"); + + XPTConstDescriptor* desc = (XPTConstDescriptor*) + XPT_MALLOC(mSet->GetArena(), sizeof(XPTConstDescriptor)); + if(!desc) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc, aConst, sizeof(XPTConstDescriptor)); + + int len = PL_strlen(aConst->name); + desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1); + if(!desc->name) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc->name, aConst->name, len); + + return mConstants.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/************************************************/ +// nsIInterfaceInfo methods... + +/* readonly attribute string name; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetName(char * *aName) +{ + *aName = (char*) nsMemory::Clone(mName, PL_strlen(mName)+1); + return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsIIDPtr IID; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetIID(nsIID * *aIID) +{ + *aIID = (nsIID*) nsMemory::Clone(&mIID, sizeof(nsIID)); + return *aIID ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* PRBool isScriptable (); */ +NS_IMETHODIMP nsGenericInterfaceInfo::IsScriptable(PRBool *_retval) +{ + *_retval = XPT_ID_IS_SCRIPTABLE(mFlags) != 0; + return NS_OK; +} + +/* readonly attribute nsIInterfaceInfo parent; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetParent(nsIInterfaceInfo * *aParent) +{ + *aParent = mParent; + NS_IF_ADDREF(*aParent); + return NS_OK; +} + +/* readonly attribute PRUint16 methodCount; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetMethodCount(PRUint16 *aMethodCount) +{ + *aMethodCount = mMethodBaseIndex + (PRUint16) mMethods.Count(); + return NS_OK; +} + +/* readonly attribute PRUint16 constantCount; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetConstantCount(PRUint16 *aConstantCount) +{ + *aConstantCount = mConstantBaseIndex + (PRUint16) mConstants.Count(); + return NS_OK; +} + +/* void getMethodInfo (in PRUint16 index, [shared, retval] out nsXPTMethodInfoPtr info); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetMethodInfo(PRUint16 index, const nsXPTMethodInfo * *info) +{ + if(index < mMethodBaseIndex) + return mParent->GetMethodInfo(index, info); + *info = (const nsXPTMethodInfo *) mMethods.ElementAt(index-mMethodBaseIndex); + return NS_OK; +} + +/* void getMethodInfoForName (in string methodName, out PRUint16 index, [shared, retval] out nsXPTMethodInfoPtr info); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetMethodInfoForName(const char *methodName, PRUint16 *index, const nsXPTMethodInfo * *info) +{ + PRUint16 count = mMethodBaseIndex + (PRUint16) mMethods.Count(); + for(PRUint16 i = 0; i < count; i++) + { + const nsXPTMethodInfo* current; + nsresult rv = GetMethodInfo(i, ¤t); + if(NS_FAILED(rv)) + return rv; + + if(!PL_strcmp(methodName, current->GetName())) + { + *index = i; + *info = current; + return NS_OK; + } + } + *index = 0; + *info = 0; + return NS_ERROR_INVALID_ARG; +} + +/* void getConstant (in PRUint16 index, [shared, retval] out nsXPTConstantPtr constant); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetConstant(PRUint16 index, const nsXPTConstant * *constant) +{ + if(index < mConstantBaseIndex) + return mParent->GetConstant(index, constant); + *constant = (const nsXPTConstant *) mConstants.ElementAt(index-mConstantBaseIndex); + return NS_OK; +} + +/* nsIInterfaceInfo getInfoForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetInfoForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIInterfaceInfo **_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetInfoForParam(methodIndex, param, _retval); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE, "not an interface"); + + return mSet->InterfaceInfoAt(td->type.iface, _retval); +} + +/* nsIIDPtr getIIDForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetIIDForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID * *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetIIDForParam(methodIndex, param, _retval); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE, "not an interface"); + + return mSet->InfoAtNoAddRef(td->type.iface)->GetIID(_retval); +} + +/* nsXPTType getTypeForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetTypeForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, nsXPTType *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetTypeForParam(methodIndex, param, dimension, _retval); + + const XPTTypeDescriptor *td = + dimension ? GetTypeInArray(param, dimension) : ¶m->type; + + *_retval = nsXPTType(td->prefix); + return NS_OK; +} + +/* PRUint8 getSizeIsArgNumberForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetSizeIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetSizeIsArgNumberForParam(methodIndex, param, dimension, _retval); + + const XPTTypeDescriptor *td = + dimension ? GetTypeInArray(param, dimension) : ¶m->type; + + *_retval = td->argnum; + return NS_OK; +} + +/* PRUint8 getLengthIsArgNumberForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetLengthIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetLengthIsArgNumberForParam(methodIndex, param, dimension, _retval); + + const XPTTypeDescriptor *td = + dimension ? GetTypeInArray(param, dimension) : ¶m->type; + + *_retval = td->argnum2; + return NS_OK; +} + +/* PRUint8 getInterfaceIsArgNumberForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint8 *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetInterfaceIsArgNumberForParam(methodIndex, param, _retval); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE, "not an interface"); + + *_retval = td->argnum; + return NS_OK; +} + +/* PRBool isIID (in nsIIDPtr IID); */ +NS_IMETHODIMP nsGenericInterfaceInfo::IsIID(const nsIID * IID, PRBool *_retval) +{ + *_retval = mIID.Equals(*IID); + return NS_OK; +} + +/* void getNameShared ([shared, retval] out string name); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetNameShared(const char **name) +{ + *name = mName; + return NS_OK; +} + +/* void getIIDShared ([shared, retval] out nsIIDPtrShared iid); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetIIDShared(const nsIID * *iid) +{ + *iid = &mIID; + return NS_OK; +} + +/* PRBool isFunction (); */ +NS_IMETHODIMP nsGenericInterfaceInfo::IsFunction(PRBool *_retval) +{ + *_retval = XPT_ID_IS_FUNCTION(mFlags) != 0; + return NS_OK; +} + +/* PRBool hasAncestor (in nsIIDPtr iid); */ +NS_IMETHODIMP nsGenericInterfaceInfo::HasAncestor(const nsIID * iid, PRBool *_retval) +{ + *_retval = PR_FALSE; + + nsCOMPtr current = NS_STATIC_CAST(nsIInterfaceInfo*, this); + while(current) + { + PRBool same; + if(NS_SUCCEEDED(current->IsIID(iid, &same)) && same) + { + *_retval = PR_TRUE; + break; + } + nsCOMPtr temp(current); + temp->GetParent(getter_AddRefs(current)); + } + return NS_OK; +} + +/* [notxpcom] nsresult getIIDForParamNoAlloc (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, out nsIID iid); */ +NS_IMETHODIMP_(nsresult) nsGenericInterfaceInfo::GetIIDForParamNoAlloc(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID *iid) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetIIDForParamNoAlloc(methodIndex, param, iid); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE, "not an interface"); + + const nsIID* iidp; + return mSet->InfoAtNoAddRef(td->type.iface)->GetIIDShared(&iidp); + *iid = *iidp; + return NS_OK; +} diff --git a/extensions/webservices/interfaceinfo/src/nsScriptableInterfaceInfo.cpp b/extensions/webservices/interfaceinfo/src/nsScriptableInterfaceInfo.cpp new file mode 100644 index 00000000000..4deb9b5d8d5 --- /dev/null +++ b/extensions/webservices/interfaceinfo/src/nsScriptableInterfaceInfo.cpp @@ -0,0 +1,786 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * John Bandhauer + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* nsIScriptableInteraceInfo family implementations. */ + +#include "iixprivate.h" + +/***************************************************************************/ +static inline nsresult CloneString(const char* inStr, char** outStr) +{ + *outStr = (char*) nsMemory::Clone(inStr, strlen(inStr)+1); + return *outStr ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/***************************************************************************/ + +/* Header file */ +class nsScriptableDataType : public nsIScriptableDataType +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEDATATYPE + + static nsresult Create(const nsXPTType& aType, + nsIScriptableDataType** aResult); + + nsScriptableDataType(); // not implemented + + nsScriptableDataType(const nsXPTType& aType) + : mType(aType) {NS_INIT_ISUPPORTS();} + + virtual ~nsScriptableDataType() {} + +private: + nsXPTType mType; +}; + +// static +nsresult +nsScriptableDataType::Create(const nsXPTType& aType, + nsIScriptableDataType** aResult) +{ + nsScriptableDataType* obj = new nsScriptableDataType(aType); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableDataType*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableDataType, nsIScriptableDataType) + +/* readonly attribute PRBool isPointer; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsPointer(PRBool *aIsPointer) +{ + *aIsPointer = mType.IsPointer(); + return NS_OK; +} + +/* readonly attribute PRBool isUniquePointer; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsUniquePointer(PRBool *aIsUniquePointer) +{ + *aIsUniquePointer = mType.IsUniquePointer(); + return NS_OK; +} + +/* readonly attribute PRBool isReference; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsReference(PRBool *aIsReference) +{ + *aIsReference = mType.IsReference(); + return NS_OK; +} + +/* readonly attribute PRBool isArithmetic; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsArithmetic(PRBool *aIsArithmetic) +{ + *aIsArithmetic = mType.IsArithmetic(); + return NS_OK; +} + +/* readonly attribute PRBool isInterfacePointer; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsInterfacePointer(PRBool *aIsInterfacePointer) +{ + *aIsInterfacePointer = mType.IsInterfacePointer(); + return NS_OK; +} + +/* readonly attribute PRBool isArray; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsArray(PRBool *aIsArray) +{ + *aIsArray = mType.IsArray(); + return NS_OK; +} + +/* readonly attribute PRBool isDependent; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsDependent(PRBool *aIsDependent) +{ + *aIsDependent = mType.IsDependent(); + return NS_OK; +} + +/* readonly attribute PRUint16 dataType; */ +NS_IMETHODIMP +nsScriptableDataType::GetDataType(PRUint16 *aDataType) +{ + *aDataType = mType.TagPart(); + return NS_OK; +} + +/***************************************************************************/ + +class nsScriptableParamInfo : public nsIScriptableParamInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEPARAMINFO + + static nsresult Create(nsIInterfaceInfo* aInfo, + const nsXPTParamInfo& aParam, + nsIScriptableParamInfo** aResult); + + nsScriptableParamInfo(); // not implemented + nsScriptableParamInfo(nsIInterfaceInfo* aInfo, + const nsXPTParamInfo& aParam) + : mInfo(aInfo), mParam(aParam) {NS_INIT_ISUPPORTS();} + virtual ~nsScriptableParamInfo() {} + +private: + // Holding onto the interface info keeps the underlying param alive. + nsCOMPtr mInfo; + nsXPTParamInfo mParam; +}; + + +// static +nsresult +nsScriptableParamInfo::Create(nsIInterfaceInfo* aInfo, + const nsXPTParamInfo& aParam, + nsIScriptableParamInfo** aResult) +{ + nsScriptableParamInfo* obj = new nsScriptableParamInfo(aInfo, aParam); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableParamInfo*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableParamInfo, nsIScriptableParamInfo) + +/* readonly attribute PRBool isIn; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsIn(PRBool *aIsIn) +{ + *aIsIn = mParam.IsIn(); + return NS_OK; +} + +/* readonly attribute PRBool isOut; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsOut(PRBool *aIsOut) +{ + *aIsOut = mParam.IsOut(); + return NS_OK; +} + +/* readonly attribute PRBool isRetval; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsRetval(PRBool *aIsRetval) +{ + *aIsRetval = mParam.IsRetval(); + return NS_OK; +} + +/* readonly attribute PRBool isShared; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsShared(PRBool *aIsShared) +{ + *aIsShared = mParam.IsShared(); + return NS_OK; +} + +/* readonly attribute PRBool isDipper; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsDipper(PRBool *aIsDipper) +{ + *aIsDipper = mParam.IsDipper(); + return NS_OK; +} + +/* readonly attribute nsIScriptableDataType type; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetType(nsIScriptableDataType * *aType) +{ + return nsScriptableDataType::Create(mParam.GetType(), aType); +} + +/* [noscript] void getParamInfo ([shared, const, retval] out nsXPTParamInfoPtr aInfo); */ +NS_IMETHODIMP +nsScriptableParamInfo::GetParamInfo(const nsXPTParamInfo * *aInfo) +{ + *aInfo = &mParam; + return NS_OK; +} + +/***************************************************************************/ +class nsScriptableConstant : public nsIScriptableConstant +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLECONSTANT + + static nsresult Create(nsIInterfaceInfo* aInfo, + const nsXPTConstant& aConst, + nsIScriptableConstant** aResult); + + nsScriptableConstant(); // not implemented + nsScriptableConstant(nsIInterfaceInfo* aInfo, + const nsXPTConstant& aConst) + : mInfo(aInfo), mConst(aConst) {NS_INIT_ISUPPORTS();} + virtual ~nsScriptableConstant() {} +private: + // Holding onto the interface info keeps the underlying const alive. + nsCOMPtr mInfo; + nsXPTConstant mConst; +}; + +// static +nsresult +nsScriptableConstant::Create(nsIInterfaceInfo* aInfo, + const nsXPTConstant& aConst, + nsIScriptableConstant** aResult) +{ + nsScriptableConstant* obj = new nsScriptableConstant(aInfo, aConst); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableConstant*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableConstant, nsIScriptableConstant) + +/* readonly attribute string name; */ +NS_IMETHODIMP +nsScriptableConstant::GetName(char * *aName) +{ + return CloneString(mConst.GetName(), aName); +} + +/* readonly attribute nsIScriptableDataType type; */ +NS_IMETHODIMP +nsScriptableConstant::GetType(nsIScriptableDataType * *aType) +{ + return nsScriptableDataType::Create(mConst.GetType(), aType); +} + +/* readonly attribute nsIVariant value; */ +NS_IMETHODIMP +nsScriptableConstant::GetValue(nsIVariant * *aValue) +{ + nsVariant* variant = new nsVariant(); + if(!variant) + { + *aValue = nsnull; + return NS_ERROR_OUT_OF_MEMORY; + } + *aValue = NS_STATIC_CAST(nsIVariant*, variant); + NS_ADDREF(*aValue); + + const nsXPTCMiniVariant* varval = mConst.GetValue(); + nsresult rv; + + switch(mConst.GetType()) + { + case nsXPTType::T_I16: + rv = variant->SetAsInt16(varval->val.i16); + break; + case nsXPTType::T_I32: + rv = variant->SetAsInt32(varval->val.i32); + break; + case nsXPTType::T_U16: + rv = variant->SetAsUint16(varval->val.u16); + break; + case nsXPTType::T_U32: + rv = variant->SetAsUint32(varval->val.u32); + break; + default: + NS_ERROR("invalid const type"); + rv = NS_ERROR_UNEXPECTED; + break; + } + + if(NS_FAILED(rv)) + { + NS_RELEASE(*aValue); + return rv; + } + + return NS_OK; +} + +/***************************************************************************/ + +class nsScriptableMethodInfo : public nsIScriptableMethodInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEMETHODINFO + + static nsresult Create(nsIInterfaceInfo* aInfo, + const nsXPTMethodInfo& aMethod, + nsIScriptableMethodInfo** aResult); + + nsScriptableMethodInfo(); // not implemented + nsScriptableMethodInfo(nsIInterfaceInfo* aInfo, + const nsXPTMethodInfo& aMethod) + : mInfo(aInfo), mMethod(aMethod) {NS_INIT_ISUPPORTS();} + virtual ~nsScriptableMethodInfo() {} +private: + // Holding onto the interface info keeps the underlying method alive. + nsCOMPtr mInfo; + const nsXPTMethodInfo& mMethod; +}; + +// static +nsresult +nsScriptableMethodInfo::Create(nsIInterfaceInfo* aInfo, + const nsXPTMethodInfo& aMethod, + nsIScriptableMethodInfo** aResult) +{ + nsScriptableMethodInfo* obj = new nsScriptableMethodInfo(aInfo, aMethod); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableMethodInfo*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableMethodInfo, nsIScriptableMethodInfo) + +/* readonly attribute PRBool isGetter; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsGetter(PRBool *aIsGetter) +{ + *aIsGetter = mMethod.IsGetter(); + return NS_OK; +} + +/* readonly attribute PRBool isSetter; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsSetter(PRBool *aIsSetter) +{ + *aIsSetter = mMethod.IsSetter(); + return NS_OK; +} + +/* readonly attribute PRBool isNotXPCOM; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsNotXPCOM(PRBool *aIsNotXPCOM) +{ + *aIsNotXPCOM = mMethod.IsNotXPCOM(); + return NS_OK; +} + +/* readonly attribute PRBool isConstructor; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsConstructor(PRBool *aIsConstructor) +{ + *aIsConstructor = mMethod.IsConstructor(); + return NS_OK; +} + +/* readonly attribute PRBool isHidden; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsHidden(PRBool *aIsHidden) +{ + *aIsHidden = mMethod.IsHidden(); + return NS_OK; +} + +/* readonly attribute string name; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetName(char * *aName) +{ + return CloneString(mMethod.GetName(), aName); +} + +/* readonly attribute PRUint8 paramCount; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetParamCount(PRUint8 *aParamCount) +{ + *aParamCount = mMethod.GetParamCount(); + return NS_OK; +} + +/* nsIScriptableParamInfo getParam (in PRUint8 idx); */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetParam(PRUint8 idx, nsIScriptableParamInfo **_retval) +{ + if(idx >= mMethod.GetParamCount()) + return NS_ERROR_INVALID_ARG; + return nsScriptableParamInfo::Create(mInfo, mMethod.GetParam(idx), _retval); +} + +/* readonly attribute nsIScriptableParamInfo result; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetResult(nsIScriptableParamInfo * *aResult) +{ + return nsScriptableParamInfo::Create(mInfo, mMethod.GetResult(), aResult); +} + +/***************************************************************************/ + +// static +nsresult +nsScriptableInterfaceInfo::Create(nsIInterfaceInfo* aInfo, + nsIScriptableInterfaceInfo** aResult) +{ + nsScriptableInterfaceInfo* obj = new nsScriptableInterfaceInfo(aInfo); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableInterfaceInfo*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableInterfaceInfo, nsIScriptableInterfaceInfo) + +nsScriptableInterfaceInfo::nsScriptableInterfaceInfo() +{ + NS_INIT_ISUPPORTS(); +} + +nsScriptableInterfaceInfo::nsScriptableInterfaceInfo(nsIInterfaceInfo* aInfo) + : mInfo(aInfo) +{ + NS_INIT_ISUPPORTS(); +} + +nsScriptableInterfaceInfo::~nsScriptableInterfaceInfo() +{ + // empty; +} + +/* [noscript] attribute nsIInterfaceInfo info; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInfo(nsIInterfaceInfo * *aInfo) +{ + if(mInfo) + NS_ADDREF(*aInfo = mInfo); + else + *aInfo = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsScriptableInterfaceInfo::SetInfo(nsIInterfaceInfo * aInfo) +{ + mInfo = aInfo; + return NS_OK; +} + +/* void Init (in nsIIDPtr aIID); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::Init(const nsIID * aIID) +{ + return SetInterfaceID(aIID); +} + +/* readonly attribute string name; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetName(char * *aName) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetName(aName); +} + +/* attribute nsIIDPtr interfaceID; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInterfaceID(nsIID * *aInterfaceID) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetIID(aInterfaceID); +} + +NS_IMETHODIMP +nsScriptableInterfaceInfo::SetInterfaceID(const nsIID * aInterfaceID) +{ + nsCOMPtr iim = + dont_AddRef(XPTI_GetInterfaceInfoManager()); + if(!iim) + return NS_ERROR_UNEXPECTED; + mInfo = nsnull; + iim->GetInfoForIID(aInterfaceID, getter_AddRefs(mInfo)); + + // XXX we want to look at additional managers here if not found! + + return mInfo ? NS_OK : NS_ERROR_NO_INTERFACE; +} + +/* readonly attribute PRBool isValid; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIsValid(PRBool *aIsValid) +{ + *aIsValid = !!mInfo; + return NS_OK; +} + +/* readonly attribute PRBool isScriptable; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIsScriptable(PRBool *aIsScriptable) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->IsScriptable(aIsScriptable); +} + +/* readonly attribute nsIScriptableInterfaceInfo parent; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetParent(nsIScriptableInterfaceInfo * *aParent) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + nsCOMPtr parentInfo; + nsresult rv = mInfo->GetParent(getter_AddRefs(parentInfo)); + if(NS_FAILED(rv)) + return rv; + + if(parentInfo) + return Create(parentInfo, aParent); + + *aParent = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint16 methodCount; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetMethodCount(PRUint16 *aMethodCount) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetMethodCount(aMethodCount); +} + +/* readonly attribute PRUint16 constantCount; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetConstantCount(PRUint16 *aConstantCount) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetConstantCount(aConstantCount); +} + +/* nsIScriptableMethodInfo getMethodInfo (in PRUint16 index); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetMethodInfo(PRUint16 index, nsIScriptableMethodInfo **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTMethodInfo* methodInfo; + nsresult rv = mInfo->GetMethodInfo(index, &methodInfo); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableMethodInfo::Create(mInfo, *methodInfo, _retval); +} + +/* nsIScriptableMethodInfo getMethodInfoForName (in string methodName, out PRUint16 index); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetMethodInfoForName(const char *methodName, PRUint16 *index, nsIScriptableMethodInfo **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTMethodInfo* methodInfo; + nsresult rv = mInfo->GetMethodInfoForName(methodName, index, &methodInfo); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableMethodInfo::Create(mInfo, *methodInfo, _retval); +} + +/* nsIScriptableConstant getConstant (in PRUint16 index); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetConstant(PRUint16 index, nsIScriptableConstant **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTConstant* constant; + nsresult rv = mInfo->GetConstant(index, &constant); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableConstant::Create(mInfo, *constant, _retval); +} + +/* nsIScriptableInterfaceInfo getInfoForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInfoForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, nsIScriptableInterfaceInfo **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + nsCOMPtr info; + rv = mInfo->GetInfoForParam(methodIndex, paramInfo, getter_AddRefs(info)); + if(NS_FAILED(rv)) + return rv; + + if(info) + return Create(info, _retval); + + *_retval = nsnull; + return NS_OK; +} + +/* nsIIDPtr getIIDForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIIDForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, nsIID * *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetIIDForParam(methodIndex, paramInfo, _retval); +} + +/* nsIScriptableDataType getTypeForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param, in PRUint16 dimension); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetTypeForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint16 dimension, nsIScriptableDataType **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + nsXPTType type; + + rv = mInfo->GetTypeForParam(methodIndex, paramInfo, dimension, &type); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableDataType::Create(type, _retval); +} + +/* PRUint8 getSizeIsArgNumberForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param, in PRUint16 dimension); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetSizeIsArgNumberForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint16 dimension, PRUint8 *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetSizeIsArgNumberForParam(methodIndex, paramInfo, + dimension, _retval); +} + +/* PRUint8 getLengthIsArgNumberForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param, in PRUint16 dimension); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetLengthIsArgNumberForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint16 dimension, PRUint8 *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetLengthIsArgNumberForParam(methodIndex, paramInfo, + dimension, _retval); +} + +/* PRUint8 getInterfaceIsArgNumberForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint8 *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetInterfaceIsArgNumberForParam(methodIndex, paramInfo, + _retval); +} + +/* PRBool isIID (in nsIIDPtr IID); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::IsIID(const nsIID * IID, PRBool *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->IsIID(IID, _retval); +} + +/* readonly attribute PRBool isFunction; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIsFunction(PRBool *aIsFunction) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->IsFunction(aIsFunction); +} + +/* PRBool hasAncestor (in nsIIDPtr iid); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::HasAncestor(const nsIID * iid, PRBool *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->HasAncestor(iid, _retval); +} diff --git a/extensions/webservices/interfaceinfo/tests/ifaceinfotest.js b/extensions/webservices/interfaceinfo/tests/ifaceinfotest.js new file mode 100644 index 00000000000..f490462fd66 --- /dev/null +++ b/extensions/webservices/interfaceinfo/tests/ifaceinfotest.js @@ -0,0 +1,364 @@ +// test the nsIScriptableInterfaceInfo stuff... +// We ought to leverage this in SOAP code. + +const IInfo = new Components.Constructor("@mozilla.org/scriptableInterfaceInfo;1", + "nsIScriptableInterfaceInfo", + "init"); + +const nsIDataType = Components.interfaces.nsIDataType; +const nsISupports = Components.interfaces.nsISupports; + +const PARAM_NAME_PREFIX = "arg"; + +/** +* takes: {xxx} +* returns: uuid(xxx) +*/ +function formatID(str) +{ + return "uuid("+str.substring(1,str.length-1)+")"; +} + +function formatConstType(type) +{ + switch(type) + { + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + default: + return "!!!! bad const type !!!"; + } +} + +function formatTypeName(info, methodIndex, param, dimension) +{ + var type = param.type; + + switch(type.dataType) + { + case nsIDataType.VTYPE_INT8 : + return "PRInt8"; + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_INT64: + return "PRInt64"; + case nsIDataType.VTYPE_UINT8: + return "PRUint8"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + case nsIDataType.VTYPE_UINT64: + return "PRUint64"; + case nsIDataType.VTYPE_FLOAT: + return "float"; + case nsIDataType.VTYPE_DOUBLE: + return "double"; + case nsIDataType.VTYPE_BOOL: + return "PRBool"; + case nsIDataType.VTYPE_CHAR: + return "char"; + case nsIDataType.VTYPE_WCHAR: + return "PRUnichar"; + case nsIDataType.VTYPE_VOID: + if(type.isPointer) + return "voidPtr"; + return "void"; + case nsIDataType.VTYPE_ID: + // order matters here... + if(type.isReference) + return "nsIDRef"; + if(type.isPointer) + return "nsIDPtr"; + return "nsID"; + case nsIDataType.VTYPE_ASTRING: + return "aString"; + case nsIDataType.VTYPE_CHAR_STR: + return "string"; + case nsIDataType.VTYPE_WCHAR_STR: + return "wstring"; + case nsIDataType.VTYPE_INTERFACE: + return info.getInfoForParam(methodIndex, param).name; + case nsIDataType.VTYPE_INTERFACE_IS: + return "nsQIResult"; + case nsIDataType.VTYPE_ARRAY: + return formatTypeName(info, methodIndex, param, dimension+1); + case nsIDataType.VTYPE_STRING_SIZE_IS: + return "string"; + case nsIDataType.VTYPE_WSTRING_SIZE_IS: + return "wstring"; + default: + return "!!!! bad data type !!!"; + } +} + +function formatBracketForParam(info, methodIndex, param) +{ + var type = param.type; + var str = "["; + var found = 0; + var size_is_ArgNum; + var length_is_ArgNum; + + if(param.isRetval) + { + if(found++) + str += ", "; + str += "retval" + } + + if(param.isShared) + { + if(found++) + str += ", "; + str += "shared" + } + + if(type.isArray) + { + if(found++) + str += ", "; + str += "array" + } + + if(type.dataType == nsIDataType.VTYPE_INTERFACE_IS) + { + if(found++) + str += ", "; + str += "iid_is("+ + PARAM_NAME_PREFIX + + info.getInterfaceIsArgNumberForParam(methodIndex, param) + ")"; + } + + if(type.isArray || + type.dataType == nsIDataType.VTYPE_STRING_SIZE_IS || + type.dataType == nsIDataType.VTYPE_WSTRING_SIZE_IS) + { + if(found++) + str += ", "; + + size_is_ArgNum = + info.getSizeIsArgNumberForParam(methodIndex, param, 0); + + str += "size_is("+ PARAM_NAME_PREFIX + size_is_ArgNum + ")"; + + length_is_ArgNum = + info.getLengthIsArgNumberForParam(methodIndex, param, 0); + + if(length_is_ArgNum != size_is_ArgNum) + { + str += ", "; + str += "length_is("+ PARAM_NAME_PREFIX + length_is_ArgNum + ")"; + } + } + + if(!found) + return ""; + str += "] "; + return str +} + +function doInterface(iid) +{ + var i, k, t, m, m2, c, p, readonly, bracketed, paramCount, retvalTypeName; + + var info = new IInfo(iid); + var parent = info.parent; + + var constBaseIndex = parent ? parent.constantCount : 0; + var constTotalCount = info.constantCount; + var constLocalCount = constTotalCount - constBaseIndex; + + var methodBaseIndex = parent ? parent.methodCount : 0; + var methodTotalCount = info.methodCount; + var methodLocalCount = methodTotalCount - methodBaseIndex; + + + // maybe recurring to emit parent declarations is not a good idea... +// if(parent) +// doInterface(parent.interfaceID); + + print(); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// print("/*\n"); + + print("[" + (info.isScriptable ? "scriptable, " : "") + + formatID(info.interfaceID.number) + "]"); + + print("interface "+ info.name + (parent ? (" : "+parent.name) : "") + " {"); + + if(constLocalCount) + { + for(i = constBaseIndex; i < constTotalCount; i++) + { + c = info.getConstant(i); + print(" const " + formatConstType(c.type.dataType) + " " + + c.name + " = " + c.value + ";"); + } + } + + if(constLocalCount && methodLocalCount) + print(); + + if(methodLocalCount) + { + for(i = methodBaseIndex; i < methodTotalCount; i++) + { + m = info.getMethodInfo(i); + + if(m.isNotXPCOM) + bracketed = "[notxpcom] " + else if(m.isHidden) + bracketed = "[noscript] " + else + bracketed = ""; + + if(m.isGetter) + { + // Is an attribute + + // figure out if this is readonly + m2 = i+1 < methodTotalCount ? info.getMethodInfo(i+1) : null; + readonly = !m2 || m2.name != m.name; + + print(" " + bracketed + (readonly ? "readonly " : "") + + "attribute " + + formatTypeName(info, i, m.getParam(0), 0) + + " " + m.name + ";\n"); + + if(!readonly) + i++; // skip the next one, we have it covered. + + continue; + } + // else... + + paramCount = m.paramCount; + + // 'last' param is used to figure out retvalTypeName + + p = paramCount ? m.getParam(paramCount-1) : null; + + if(m.isNotXPCOM) + retvalTypeName = formatTypeName(info, i, m.result, 0); + else if(p && "[retval] " == formatBracketForParam(info, i, p)) + { + // Check for the exact string above because anything else + // indicates that there either is no expilict retval + // or there are additional braketed attributes (meaning that + // the retval must appear in the param list and not + // preceeding the method name). + retvalTypeName = formatTypeName(info, i, p, 0); + // no need to print it in the param list + paramCount-- ; + } + else + retvalTypeName = "void"; + + // print method name + + print(" " + bracketed + retvalTypeName + " " + m.name + "(" + + (paramCount ? "" : ");")); + + // print params + + for(k = 0; k < paramCount; k++) + { + p = m.getParam(k); + print(" "+ + formatBracketForParam(info, i, p) + + (p.isOut ? p.isIn ? "inout " : "out " : "in ") + + formatTypeName(info, i, p, 0) + " " + + PARAM_NAME_PREFIX+k + + (k+1 == paramCount ? ");\n" : ", ")); + } + } + } + + print("};\n"); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// print("\n*/\n"); +} + +function appendForwardDeclarations(list, info) +{ + list.push(info.name); + if(info.parent) + appendForwardDeclarations(list, info.parent); + + var i, k, m, p; + + for(i = 0; i < info.methodCount; i++) + { + m = info.getMethodInfo(i); + + for(k = 0; k < m.paramCount; k++) + { + p = m.getParam(k); + + if(p.type.dataType == nsIDataType.VTYPE_INTERFACE) + { + list.push(info.getInfoForParam(i, p).name); + } + } + } +} + +function doForwardDeclarations(iid) +{ + var i, cur, prev; + var list = []; + appendForwardDeclarations(list, new IInfo(iid)); + list.sort(); + + print("// forward declarations..."); + + for(i = 0; i < list.length; i++) + { + cur = list[i]; + if(cur != prev && cur != "nsISupports") + { + print("interface " + cur +";"); + prev = cur; + } + } + print(""); +} + +function info2IDL(iid) +{ + print(); + print('#include "nsISupports.idl"'); + print(); + + doForwardDeclarations(iid) + doInterface(iid); +} + +/***************************************************************************/ +/***************************************************************************/ +// test... + +print(); +print(); +//info2IDL(Components.interfaces.nsISupports); +print("//------------------------------------------------------------"); +info2IDL(Components.interfaces.nsIDataType); +print("//------------------------------------------------------------"); +info2IDL(Components.interfaces.nsIScriptableInterfaceInfo); +print("//------------------------------------------------------------"); +info2IDL(Components.interfaces.nsIVariant); +print(); +print(); diff --git a/extensions/webservices/public/nsIGenericInterfaceInfoSet.idl b/extensions/webservices/public/nsIGenericInterfaceInfoSet.idl new file mode 100644 index 00000000000..05520fe2933 --- /dev/null +++ b/extensions/webservices/public/nsIGenericInterfaceInfoSet.idl @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsIGenericInterfaceInfo/nsIGenericInterfaceInfoSet public declarations.*/ + + +#include "nsISupports.idl" +#include "nsIInterfaceInfo.idl" +#include "nsIInterfaceInfoManager.idl" + +[ptr] native nsXPTTypePtr(nsXPTType); + +/* this is NOT intended to be scriptable */ +[uuid(8344a200-18ed-4538-8d44-e50b5156b564)] +interface nsIGenericInterfaceInfo : nsIInterfaceInfo +{ + /** + * Caller might allocate one more than the actual param count in + * order to have a location for the result pointer used in the methodinfo. + */ + nsXPTParamInfoPtr allocateParamArray(in PRUint16 aCount); + + /** + * Used for arrays. + */ + nsXPTTypePtr allocateAdditionalType(out PRUint16 aIndex); + + /** + * All members except params* and result* copied + */ + + PRUint16 appendMethod(in nsXPTMethodInfoPtr aMethod); + + /** + * All members copied + */ + PRUint16 appendConst(in nsXPTConstantPtr aConst); +}; + +/* this is NOT intended to be scriptable */ +[uuid(8cc674ee-52ba-45fa-b897-bb88d35eaa91)] +interface nsIGenericInterfaceInfoSet : nsIInterfaceInfoManager +{ + PRUint16 createAndAppendInterface(in string aName, in nsIIDRef aIID, + in PRUint16 aParent, in PRUint8 aFlags, + out nsIGenericInterfaceInfo aInfo); + PRUint16 appendExternalInterface(in nsIInterfaceInfo aInfo); + PRUint16 indexOf(in nsIIDRef aIID); + nsIInterfaceInfo interfaceInfoAt(in PRUint16 aIndex); +}; + +%{C++ +// The contractID for the implementation built into iiextras +#define NS_GENERIC_INTERFACE_INFO_SET_CONTRACTID "@mozilla.org/genericInterfaceInfoSet;1" +%} + diff --git a/extensions/webservices/public/nsIScriptableInterfaceInfo.idl b/extensions/webservices/public/nsIScriptableInterfaceInfo.idl new file mode 100644 index 00000000000..1e799ee2dc4 --- /dev/null +++ b/extensions/webservices/public/nsIScriptableInterfaceInfo.idl @@ -0,0 +1,176 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 2001 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * John Bandhauer (original author) + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU Public License (the "GPL"), in which case the + * provisions of the GPL are applicable instead of those above. + * If you wish to allow use of your version of this file only + * under the terms of the GPL and not to allow others to use your + * version of this file under the NPL, indicate your decision by + * deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete + * the provisions above, a recipient may use your version of this + * file under either the NPL or the GPL. + */ + +/* Scriptable version of the information exposed by nsIInterfaceInfo */ + +#include "nsISupports.idl" +#include "nsIInterfaceInfo.idl" +#include "nsIVariant.idl" + +[scriptable, uuid(312e3b94-dc98-4ccc-b2fb-e3406f905cc6)] +interface nsIScriptableDataType : nsISupports +{ + readonly attribute PRBool isPointer; + readonly attribute PRBool isUniquePointer; + readonly attribute PRBool isReference; + readonly attribute PRBool isArithmetic; + readonly attribute PRBool isInterfacePointer; + readonly attribute PRBool isArray; + readonly attribute PRBool isDependent; + + /** + * This is one of the constants declared in nsIDataType + */ + readonly attribute PRUint16 dataType; +}; + +[scriptable, uuid(2309482b-4631-455f-833f-5e4e9ce38589)] +interface nsIScriptableParamInfo : nsISupports +{ + readonly attribute PRBool isIn; + readonly attribute PRBool isOut; + readonly attribute PRBool isRetval; + readonly attribute PRBool isShared; + readonly attribute PRBool isDipper; + + readonly attribute nsIScriptableDataType type; + + [noscript] void getParamInfo([shared, const, retval] out nsXPTParamInfoPtr aInfo); +}; + +[scriptable, uuid(0f6c5b09-88b0-43ca-b55c-578f24f3d810)] +interface nsIScriptableConstant : nsISupports +{ + readonly attribute string name; + readonly attribute nsIScriptableDataType type; + readonly attribute nsIVariant value; +}; + +[scriptable, uuid(9228afa2-187c-4feb-9228-5108e640ca33)] +interface nsIScriptableMethodInfo : nsISupports +{ + readonly attribute PRBool isGetter; + readonly attribute PRBool isSetter; + readonly attribute PRBool isNotXPCOM; + readonly attribute PRBool isConstructor; + readonly attribute PRBool isHidden; + + readonly attribute string name; + readonly attribute PRUint8 paramCount; + + nsIScriptableParamInfo getParam(in PRUint8 idx); + + readonly attribute nsIScriptableParamInfo result; +}; + +[scriptable, uuid(f902d5ba-2ef6-444e-8a17-52cb70715c10)] +interface nsIScriptableInterfaceInfo : nsISupports +{ + [noscript] attribute nsIInterfaceInfo info; + + void init(in nsIIDPtr aIID); + + readonly attribute string name; + + /** + * Setting interfaceID will set what interface info this object wraps. + */ + attribute nsIIDPtr interfaceID; + + /** + * True if this object has been sucessfully set to wrap an interface info. + */ + readonly attribute PRBool isValid; + + readonly attribute PRBool isScriptable; + + readonly attribute nsIScriptableInterfaceInfo parent; + + /** + * These include counts for parent (and all ancestors). + */ + readonly attribute PRUint16 methodCount; + readonly attribute PRUint16 constantCount; + + /** + * These include methods and constants for parent (and all ancestors). + */ + + nsIScriptableMethodInfo getMethodInfo(in PRUint16 index); + + nsIScriptableMethodInfo getMethodInfoForName(in string methodName, + out PRUint16 index); + + + nsIScriptableConstant getConstant(in PRUint16 index); + + /** + * Get the interface information or iid associated with a param of some + * method in this interface. + */ + + nsIScriptableInterfaceInfo getInfoForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param); + + nsIIDPtr getIIDForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param); + + + nsIScriptableDataType getTypeForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param, + in PRUint16 dimension); + + PRUint8 getSizeIsArgNumberForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param, + in PRUint16 dimension); + + PRUint8 getLengthIsArgNumberForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param, + in PRUint16 dimension); + + PRUint8 getInterfaceIsArgNumberForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param); + + PRBool isIID(in nsIIDPtr IID); + + readonly attribute PRBool isFunction; + + PRBool hasAncestor(in nsIIDPtr iid); +}; + +%{C++ +// The contractID for the implementation built in to xpconnect. +#define NS_SCRIPTABLE_INTERFACE_INFO_CONTRACTID "@mozilla.org/scriptableInterfaceInfo;1" +%} diff --git a/extensions/xmlextras/interfaceinfo/makefile.win b/extensions/xmlextras/interfaceinfo/makefile.win new file mode 100644 index 00000000000..61af210c6d4 --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/makefile.win @@ -0,0 +1,37 @@ +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is Mozilla Communicator client code, released +# March 31, 1998. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU Public License (the "GPL"), in which case the +# provisions of the GPL are applicable instead of those above. +# If you wish to allow use of your version of this file only +# under the terms of the GPL and not to allow others to use your +# version of this file under the NPL, indicate your decision by +# deleting the provisions above and replace them with the notice +# and other provisions required by the GPL. If you do not delete +# the provisions above, a recipient may use your version of this +# file under either the NPL or the GPL. + +DEPTH=..\.. + +DIRS=public src + +include <$(DEPTH)\config\rules.mak> diff --git a/extensions/xmlextras/interfaceinfo/public/makefile.win b/extensions/xmlextras/interfaceinfo/public/makefile.win new file mode 100644 index 00000000000..4350049960b --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/public/makefile.win @@ -0,0 +1,31 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): + +DEPTH=..\..\.. + +MODULE=iiextras + +XPIDLSRCS = \ + .\nsIGenericInterfaceInfoSet.idl \ + .\nsIScriptableInterfaceInfo.idl \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> diff --git a/extensions/xmlextras/interfaceinfo/public/nsIGenericInterfaceInfoSet.idl b/extensions/xmlextras/interfaceinfo/public/nsIGenericInterfaceInfoSet.idl new file mode 100644 index 00000000000..05520fe2933 --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/public/nsIGenericInterfaceInfoSet.idl @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsIGenericInterfaceInfo/nsIGenericInterfaceInfoSet public declarations.*/ + + +#include "nsISupports.idl" +#include "nsIInterfaceInfo.idl" +#include "nsIInterfaceInfoManager.idl" + +[ptr] native nsXPTTypePtr(nsXPTType); + +/* this is NOT intended to be scriptable */ +[uuid(8344a200-18ed-4538-8d44-e50b5156b564)] +interface nsIGenericInterfaceInfo : nsIInterfaceInfo +{ + /** + * Caller might allocate one more than the actual param count in + * order to have a location for the result pointer used in the methodinfo. + */ + nsXPTParamInfoPtr allocateParamArray(in PRUint16 aCount); + + /** + * Used for arrays. + */ + nsXPTTypePtr allocateAdditionalType(out PRUint16 aIndex); + + /** + * All members except params* and result* copied + */ + + PRUint16 appendMethod(in nsXPTMethodInfoPtr aMethod); + + /** + * All members copied + */ + PRUint16 appendConst(in nsXPTConstantPtr aConst); +}; + +/* this is NOT intended to be scriptable */ +[uuid(8cc674ee-52ba-45fa-b897-bb88d35eaa91)] +interface nsIGenericInterfaceInfoSet : nsIInterfaceInfoManager +{ + PRUint16 createAndAppendInterface(in string aName, in nsIIDRef aIID, + in PRUint16 aParent, in PRUint8 aFlags, + out nsIGenericInterfaceInfo aInfo); + PRUint16 appendExternalInterface(in nsIInterfaceInfo aInfo); + PRUint16 indexOf(in nsIIDRef aIID); + nsIInterfaceInfo interfaceInfoAt(in PRUint16 aIndex); +}; + +%{C++ +// The contractID for the implementation built into iiextras +#define NS_GENERIC_INTERFACE_INFO_SET_CONTRACTID "@mozilla.org/genericInterfaceInfoSet;1" +%} + diff --git a/extensions/xmlextras/interfaceinfo/public/nsIScriptableInterfaceInfo.idl b/extensions/xmlextras/interfaceinfo/public/nsIScriptableInterfaceInfo.idl new file mode 100644 index 00000000000..1e799ee2dc4 --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/public/nsIScriptableInterfaceInfo.idl @@ -0,0 +1,176 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 2001 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * John Bandhauer (original author) + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU Public License (the "GPL"), in which case the + * provisions of the GPL are applicable instead of those above. + * If you wish to allow use of your version of this file only + * under the terms of the GPL and not to allow others to use your + * version of this file under the NPL, indicate your decision by + * deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete + * the provisions above, a recipient may use your version of this + * file under either the NPL or the GPL. + */ + +/* Scriptable version of the information exposed by nsIInterfaceInfo */ + +#include "nsISupports.idl" +#include "nsIInterfaceInfo.idl" +#include "nsIVariant.idl" + +[scriptable, uuid(312e3b94-dc98-4ccc-b2fb-e3406f905cc6)] +interface nsIScriptableDataType : nsISupports +{ + readonly attribute PRBool isPointer; + readonly attribute PRBool isUniquePointer; + readonly attribute PRBool isReference; + readonly attribute PRBool isArithmetic; + readonly attribute PRBool isInterfacePointer; + readonly attribute PRBool isArray; + readonly attribute PRBool isDependent; + + /** + * This is one of the constants declared in nsIDataType + */ + readonly attribute PRUint16 dataType; +}; + +[scriptable, uuid(2309482b-4631-455f-833f-5e4e9ce38589)] +interface nsIScriptableParamInfo : nsISupports +{ + readonly attribute PRBool isIn; + readonly attribute PRBool isOut; + readonly attribute PRBool isRetval; + readonly attribute PRBool isShared; + readonly attribute PRBool isDipper; + + readonly attribute nsIScriptableDataType type; + + [noscript] void getParamInfo([shared, const, retval] out nsXPTParamInfoPtr aInfo); +}; + +[scriptable, uuid(0f6c5b09-88b0-43ca-b55c-578f24f3d810)] +interface nsIScriptableConstant : nsISupports +{ + readonly attribute string name; + readonly attribute nsIScriptableDataType type; + readonly attribute nsIVariant value; +}; + +[scriptable, uuid(9228afa2-187c-4feb-9228-5108e640ca33)] +interface nsIScriptableMethodInfo : nsISupports +{ + readonly attribute PRBool isGetter; + readonly attribute PRBool isSetter; + readonly attribute PRBool isNotXPCOM; + readonly attribute PRBool isConstructor; + readonly attribute PRBool isHidden; + + readonly attribute string name; + readonly attribute PRUint8 paramCount; + + nsIScriptableParamInfo getParam(in PRUint8 idx); + + readonly attribute nsIScriptableParamInfo result; +}; + +[scriptable, uuid(f902d5ba-2ef6-444e-8a17-52cb70715c10)] +interface nsIScriptableInterfaceInfo : nsISupports +{ + [noscript] attribute nsIInterfaceInfo info; + + void init(in nsIIDPtr aIID); + + readonly attribute string name; + + /** + * Setting interfaceID will set what interface info this object wraps. + */ + attribute nsIIDPtr interfaceID; + + /** + * True if this object has been sucessfully set to wrap an interface info. + */ + readonly attribute PRBool isValid; + + readonly attribute PRBool isScriptable; + + readonly attribute nsIScriptableInterfaceInfo parent; + + /** + * These include counts for parent (and all ancestors). + */ + readonly attribute PRUint16 methodCount; + readonly attribute PRUint16 constantCount; + + /** + * These include methods and constants for parent (and all ancestors). + */ + + nsIScriptableMethodInfo getMethodInfo(in PRUint16 index); + + nsIScriptableMethodInfo getMethodInfoForName(in string methodName, + out PRUint16 index); + + + nsIScriptableConstant getConstant(in PRUint16 index); + + /** + * Get the interface information or iid associated with a param of some + * method in this interface. + */ + + nsIScriptableInterfaceInfo getInfoForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param); + + nsIIDPtr getIIDForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param); + + + nsIScriptableDataType getTypeForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param, + in PRUint16 dimension); + + PRUint8 getSizeIsArgNumberForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param, + in PRUint16 dimension); + + PRUint8 getLengthIsArgNumberForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param, + in PRUint16 dimension); + + PRUint8 getInterfaceIsArgNumberForParam(in PRUint16 methodIndex, + in nsIScriptableParamInfo param); + + PRBool isIID(in nsIIDPtr IID); + + readonly attribute PRBool isFunction; + + PRBool hasAncestor(in nsIIDPtr iid); +}; + +%{C++ +// The contractID for the implementation built in to xpconnect. +#define NS_SCRIPTABLE_INTERFACE_INFO_CONTRACTID "@mozilla.org/scriptableInterfaceInfo;1" +%} diff --git a/extensions/xmlextras/interfaceinfo/src/iixmodule.cpp b/extensions/xmlextras/interfaceinfo/src/iixmodule.cpp new file mode 100644 index 00000000000..3df703e103e --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/src/iixmodule.cpp @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * John Bandhauer (original author) + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU Public License (the "GPL"), in which case the + * provisions of the GPL are applicable instead of those above. + * If you wish to allow use of your version of this file only + * under the terms of the GPL and not to allow others to use your + * version of this file under the NPL, indicate your decision by + * deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete + * the provisions above, a recipient may use your version of this + * file under either the NPL or the GPL. + */ + +/* Module level methods. */ + +#include "iixprivate.h" + +/* Module implementation for the interface info extras library. */ + +// {B404670D-1EB1-4af8-86E5-FB3E9C4ECC4B} +#define NS_GENERIC_INTERFACE_INFO_SET_CID \ +{ 0xb404670d, 0x1eb1, 0x4af8, \ + { 0x86, 0xe5, 0xfb, 0x3e, 0x9c, 0x4e, 0xcc, 0x4b } } + + +// {ED150A6A-4592-4e2c-82F8-70C8D65F74D2} +#define NS_SCRIPTABLE_INTERFACE_INFO_CID \ +{ 0xed150a6a, 0x4592, 0x4e2c, \ + { 0x82, 0xf8, 0x70, 0xc8, 0xd6, 0x5f, 0x74, 0xd2 } } + + +NS_GENERIC_FACTORY_CONSTRUCTOR(nsGenericInterfaceInfoSet) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableInterfaceInfo) + +static nsModuleComponentInfo components[] = { + {nsnull, + NS_GENERIC_INTERFACE_INFO_SET_CID, + NS_GENERIC_INTERFACE_INFO_SET_CONTRACTID, + nsGenericInterfaceInfoSetConstructor}, + {nsnull, + NS_SCRIPTABLE_INTERFACE_INFO_CID, + NS_SCRIPTABLE_INTERFACE_INFO_CONTRACTID, + nsScriptableInterfaceInfoConstructor} +}; + +NS_IMPL_NSGETMODULE(iiextras, components) diff --git a/extensions/xmlextras/interfaceinfo/src/iixprivate.h b/extensions/xmlextras/interfaceinfo/src/iixprivate.h new file mode 100644 index 00000000000..5b4e8472255 --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/src/iixprivate.h @@ -0,0 +1,177 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe + * John Bandhauer + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Library-private header for Interface Info extras system. */ + +#ifndef iixprivate_h___ +#define iixprivate_h___ + +#include "nsCOMPtr.h" +#include "nsVoidArray.h" +#include "nsSupportsArray.h" +#include "nsString.h" +#include "nsReadableUtils.h" +#include "nsWeakReference.h" +#include "nsIGenericFactory.h" +#include "nsVariant.h" + +#include "nsIInterfaceInfo.h" +#include "nsIInterfaceInfoManager.h" +#include "xpt_struct.h" +#include "xptinfo.h" +#include "xptcall.h" + +#include "nsIGenericInterfaceInfoSet.h" +#include "nsIScriptableInterfaceInfo.h" + +/***************************************************************************/ + +class nsGenericInterfaceInfoSet : public nsIGenericInterfaceInfoSet, + public nsSupportsWeakReference +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERFACEINFOMANAGER + NS_DECL_NSIGENERICINTERFACEINFOSET + + nsGenericInterfaceInfoSet(); + virtual ~nsGenericInterfaceInfoSet(); + + XPTArena* GetArena() {return mArena;} + nsresult AllocateAdditionalType(PRUint16 *aIndex, nsXPTType * *_retval); + + const XPTTypeDescriptor* GetAdditionalTypeAt(PRUint16 aIndex) + { + NS_ASSERTION(aIndex < (PRUint16) mAdditionalTypes.Count(), "bad index"); + return (const XPTTypeDescriptor*) mAdditionalTypes.ElementAt(aIndex); + } + + nsIInterfaceInfo* InfoAtNoAddRef(PRUint16 aIndex) + { + NS_ASSERTION(aIndex < (PRUint16) mInterfaces.Count(), "bad index"); + return (nsIInterfaceInfo*) ClearOwnedFlag(mInterfaces.ElementAt(aIndex)); + } + +private: + nsresult IndexOfIID(const nsIID & aIID, PRUint16 *_retval); + nsresult IndexOfName(const char* aName, PRUint16 *_retval); + + void* SetOwnedFlag(void* p) {return (void*) ((long)p | 1);} + void* ClearOwnedFlag(void* p) {return (void*) ((long)p & ~(long)1);} + PRBool CheckOwnedFlag(void* p) {return (PRBool) ((long)p & (long)1);} + + +private: + nsVoidArray mInterfaces; + nsVoidArray mAdditionalTypes; + XPTArena* mArena; +}; + +/***************************************************************************/ + +class nsGenericInterfaceInfo : public nsIGenericInterfaceInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERFACEINFO + NS_DECL_NSIGENERICINTERFACEINFO + + nsGenericInterfaceInfo(); // not implemented + nsGenericInterfaceInfo(nsGenericInterfaceInfoSet* aSet, + const char *aName, + const nsIID & aIID, + nsIInterfaceInfo* mParent, + PRUint8 aFlags); + virtual ~nsGenericInterfaceInfo() {} + +private: + const XPTTypeDescriptor* GetPossiblyNestedType(const nsXPTParamInfo* param) + { + const XPTTypeDescriptor* td = ¶m->type; + while(XPT_TDP_TAG(td->prefix) == TD_ARRAY) + td = mSet->GetAdditionalTypeAt(td->type.additional_type); + return td; + } + + const XPTTypeDescriptor* GetTypeInArray(const nsXPTParamInfo* param, + PRUint16 dimension) + { + const XPTTypeDescriptor* td = ¶m->type; + for(PRUint16 i = 0; i < dimension; i++) + { + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_ARRAY, "bad dimension"); + td = mSet->GetAdditionalTypeAt(td->type.additional_type); + } + return td; + } + +private: + char* mName; + nsIID mIID; + nsVoidArray mMethods; + nsVoidArray mConstants; + nsGenericInterfaceInfoSet* mSet; + nsIInterfaceInfo* mParent; // weak reference (it must be held in set table) + PRUint16 mMethodBaseIndex; + PRUint16 mConstantBaseIndex; + PRUint8 mFlags; +}; + +/***************************************************************************/ + +class nsScriptableInterfaceInfo : public nsIScriptableInterfaceInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEINTERFACEINFO + + static nsresult Create(nsIInterfaceInfo* aInfo, + nsIScriptableInterfaceInfo** aResult); + + nsScriptableInterfaceInfo(); + nsScriptableInterfaceInfo(nsIInterfaceInfo* aInfo); + virtual ~nsScriptableInterfaceInfo(); + +private: + nsCOMPtr mInfo; +}; + +/***************************************************************************/ + +#endif /* iixprivate_h___ */ diff --git a/extensions/xmlextras/interfaceinfo/src/makefile.win b/extensions/xmlextras/interfaceinfo/src/makefile.win new file mode 100644 index 00000000000..7e78970d4dc --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/src/makefile.win @@ -0,0 +1,63 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is Mozilla Communicator client code, released +# March 31, 1998. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# John Bandhauer +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU Public License (the "GPL"), in which case the +# provisions of the GPL are applicable instead of those above. +# If you wish to allow use of your version of this file only +# under the terms of the GPL and not to allow others to use your +# version of this file under the NPL, indicate your decision by +# deleting the provisions above and replace them with the notice +# and other provisions required by the GPL. If you do not delete +# the provisions above, a recipient may use your version of this +# file under either the NPL or the GPL. + +DEPTH=..\..\.. + +MODULE=iiextras +LIBRARY_NAME=$(MODULE) +MODULE_NAME=$(MODULE) + +REQUIRES = \ + xpcom \ + string \ + $(NULL) + +DEFINES=-DWIN32_LEAN_AND_MEAN + +OBJS= \ + .\$(OBJDIR)\nsGenericInterfaceInfoSet.obj \ + .\$(OBJDIR)\nsScriptableInterfaceInfo.obj \ + .\$(OBJDIR)\iixmodule.obj \ + $(NULL) + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +LLIBS= $(LIBNSPR) \ + $(DIST)\lib\xpcom.lib \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> diff --git a/extensions/xmlextras/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp b/extensions/xmlextras/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp new file mode 100644 index 00000000000..b9f8b46452d --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/src/nsGenericInterfaceInfoSet.cpp @@ -0,0 +1,597 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsGenericInterfaceInfo/nsGenericInterfaceInfoSet implementations.*/ + +#include "iixprivate.h" + + +/***************************************************************************/ +// implement nsGenericInterfaceInfoSet + +#define ARENA_BLOCK_SIZE (1024 * 1) + +NS_IMPL_THREADSAFE_ISUPPORTS3(nsGenericInterfaceInfoSet, + nsIInterfaceInfoManager, + nsIGenericInterfaceInfoSet, + nsISupportsWeakReference); + +nsGenericInterfaceInfoSet::nsGenericInterfaceInfoSet() +{ + NS_INIT_ISUPPORTS(); + mArena = XPT_NewArena(ARENA_BLOCK_SIZE, sizeof(double), + "nsGenericInterfaceInfoSet Arena"); +} + +nsGenericInterfaceInfoSet::~nsGenericInterfaceInfoSet() +{ + PRInt32 count = mInterfaces.Count(); + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i); + if(CheckOwnedFlag(info)) + delete (nsGenericInterfaceInfo*) ClearOwnedFlag(info); + else + NS_RELEASE(info); + } + + if(mArena) + XPT_DestroyArena(mArena); +} + +nsresult +nsGenericInterfaceInfoSet::AllocateAdditionalType(PRUint16 *aIndex, nsXPTType * *_retval) +{ + *_retval = (nsXPTType*) + XPT_MALLOC(GetArena(), sizeof(nsXPTType)); + if(!*_retval || !mAdditionalTypes.AppendElement(*_retval)) + return NS_ERROR_OUT_OF_MEMORY; + *aIndex = (PRUint16) mAdditionalTypes.Count()-1; + return NS_OK; +} + +nsresult +nsGenericInterfaceInfoSet::IndexOfIID(const nsIID & aIID, PRUint16 *_retval) +{ + PRInt32 count = mInterfaces.Count(); + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i); + const nsID* iid; + nsresult rv = info->GetIIDShared(&iid); + if(NS_FAILED(rv)) + return rv; + if(iid->Equals(aIID)) + { + *_retval = (PRUint16) i; + return NS_OK; + } + } + return NS_ERROR_NO_INTERFACE; +} + +nsresult +nsGenericInterfaceInfoSet::IndexOfName(const char* aName, PRUint16 *_retval) +{ + PRInt32 count = mInterfaces.Count(); + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = (nsIInterfaceInfo*) mInterfaces.ElementAt(i); + const char* name; + nsresult rv = info->GetNameShared(&name); + if(NS_FAILED(rv)) + return rv; + if(!strcmp(name, aName)) + { + *_retval = (PRUint16) i; + return NS_OK; + } + } + return NS_ERROR_NO_INTERFACE; +} + +/************************************************/ +// nsIGenericInterfaceInfoSet methods... + +/* PRUint16 createAndAppendInterface (in string aName, in nsIIDRef aIID, in PRUint16 aParent, in PRUint8 aFlags, out nsIGenericInterfaceInfo aInfo); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::CreateAndAppendInterface(const char *aName, const nsIID & aIID, PRUint16 aParent, PRUint8 aFlags, nsIGenericInterfaceInfo **aInfo, PRUint16 *_retval) +{ + nsGenericInterfaceInfo* info = + new nsGenericInterfaceInfo(this, aName, aIID, + (aParent == (PRUint16) -1) ? + nsnull : InfoAtNoAddRef(aParent), + aFlags); + if(!info || !mInterfaces.AppendElement(SetOwnedFlag(info))) + return NS_ERROR_OUT_OF_MEMORY; + + *_retval = (PRUint16) mInterfaces.Count()-1; + return CallQueryInterface(info, aInfo); +} + +/* PRUint16 appendExternalInterface (in nsIInterfaceInfo aInfo); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::AppendExternalInterface(nsIInterfaceInfo *aInfo, PRUint16 *_retval) +{ + if(!mInterfaces.AppendElement(aInfo)) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(aInfo); + *_retval = (PRUint16) mInterfaces.Count()-1; + return NS_OK; +} + +/* PRUint16 indexOf (in nsIIDRef aIID); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::IndexOf(const nsIID & aIID, PRUint16 *_retval) +{ + return IndexOfIID(aIID, _retval); +} + +/* nsIInterfaceInfo interfaceInfoAt (in PRUint16 aIndex); */ +NS_IMETHODIMP +nsGenericInterfaceInfoSet::InterfaceInfoAt(PRUint16 aIndex, nsIInterfaceInfo **_retval) +{ + NS_ASSERTION(aIndex < (PRUint16)mInterfaces.Count(), "bad index"); + + *_retval = (nsIInterfaceInfo*) ClearOwnedFlag(mInterfaces.ElementAt(aIndex)); + NS_ADDREF(*_retval); + return NS_OK; +} + +/************************************************/ +// nsIInterfaceInfoManager methods... + +/* nsIInterfaceInfo getInfoForIID (in nsIIDPtr iid); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetInfoForIID(const nsIID * iid, nsIInterfaceInfo **_retval) +{ + PRUint16 index; + nsresult rv = IndexOfIID(*iid, &index); + if(NS_FAILED(rv)) + return rv; + return InterfaceInfoAt(index, _retval); +} + +/* nsIInterfaceInfo getInfoForName (in string name); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetInfoForName(const char *name, nsIInterfaceInfo **_retval) +{ + PRUint16 index; + nsresult rv = IndexOfName(name, &index); + if(NS_FAILED(rv)) + return rv; + return InterfaceInfoAt(index, _retval); +} + +/* nsIIDPtr getIIDForName (in string name); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetIIDForName(const char *name, nsIID * *_retval) +{ + PRUint16 index; + nsresult rv = IndexOfName(name, &index); + if(NS_FAILED(rv)) + return rv; + + return InfoAtNoAddRef(index)->GetIID(_retval); +} + +/* string getNameForIID (in nsIIDPtr iid); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::GetNameForIID(const nsIID * iid, char **_retval) +{ + PRUint16 index; + nsresult rv = IndexOfIID(*iid, &index); + if(NS_FAILED(rv)) + return rv; + + return InfoAtNoAddRef(index)->GetName(_retval); +} + +/* nsIEnumerator enumerateInterfaces (); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::EnumerateInterfaces(nsIEnumerator **_retval) +{ + return EnumerateInterfacesWhoseNamesStartWith(nsnull, _retval); +} + +/* void autoRegisterInterfaces (); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::AutoRegisterInterfaces() +{ + // NOP + return NS_OK; +} + +/* nsIEnumerator enumerateInterfacesWhoseNamesStartWith (in string prefix); */ +NS_IMETHODIMP nsGenericInterfaceInfoSet::EnumerateInterfacesWhoseNamesStartWith(const char *prefix, nsIEnumerator **_retval) +{ + int count = (PRUint16) mInterfaces.Count(); + int len = prefix ? PL_strlen(prefix) : 0; + const char* name; + + nsCOMPtr array; + NS_NewISupportsArray(getter_AddRefs(array)); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + for(PRInt32 i = 0; i < count; i++) + { + nsIInterfaceInfo* info = InfoAtNoAddRef(i); + if(!prefix || + (NS_SUCCEEDED(info->GetNameShared(&name)) && + name == PL_strnstr(name, prefix, len))) + { + if(!array->AppendElement(info)) + return NS_ERROR_OUT_OF_MEMORY; + } + } + + return array->Enumerate(_retval); +} + +/***************************************************************************/ +/***************************************************************************/ +// implement nsGenericInterfaceInfo + +NS_IMPL_QUERY_INTERFACE2(nsGenericInterfaceInfo, + nsIInterfaceInfo, + nsIGenericInterfaceInfo); + +NS_IMETHODIMP_(nsrefcnt) +nsGenericInterfaceInfo::AddRef() +{ + return mSet->AddRef(); +} + +NS_IMETHODIMP_(nsrefcnt) +nsGenericInterfaceInfo::Release() +{ + return mSet->Release(); +} + +nsGenericInterfaceInfo::nsGenericInterfaceInfo(nsGenericInterfaceInfoSet* aSet, + const char *aName, + const nsIID & aIID, + nsIInterfaceInfo* aParent, + PRUint8 aFlags) + : mName(nsnull), + mIID(aIID), + mSet(aSet), + mParent(aParent), + mFlags(aFlags) +{ + if(mParent) + { + mParent->GetMethodCount(&mMethodBaseIndex); + mParent->GetConstantCount(&mConstantBaseIndex); + } + else + { + mMethodBaseIndex = mConstantBaseIndex = 0; + } +} + +/************************************************/ +// nsIGenericInterfaceInfo methods... + +/* nsXPTParamInfoPtr allocateParamArray (in PRUint16 aCount); */ +NS_IMETHODIMP +nsGenericInterfaceInfo::AllocateParamArray(PRUint16 aCount, nsXPTParamInfo * *_retval) +{ + *_retval = (nsXPTParamInfo*) + XPT_MALLOC(mSet->GetArena(), sizeof(nsXPTParamInfo) * aCount); + return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* nsXPTTypePtr allocateAdditionalType (out PRUint16 aIndex); */ +NS_IMETHODIMP +nsGenericInterfaceInfo::AllocateAdditionalType(PRUint16 *aIndex, nsXPTType * *_retval) +{ + return mSet->AllocateAdditionalType(aIndex, _retval); +} + +/* PRUint16 appendMethod (in nsXPTMethodInfoPtr aMethod); */ +NS_IMETHODIMP +nsGenericInterfaceInfo::AppendMethod(nsXPTMethodInfo * aMethod, PRUint16 *_retval) +{ + nsXPTMethodInfo* desc = (nsXPTMethodInfo*) + XPT_MALLOC(mSet->GetArena(), sizeof(nsXPTMethodInfo)); + if(!desc) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc, aMethod, sizeof(nsXPTMethodInfo)); + + int len = PL_strlen(aMethod->name); + desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1); + if(!desc->name) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc->name, aMethod->name, len); + + return mMethods.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* PRUint16 appendConst (in nsXPTConstantPtr aConst); */ +NS_IMETHODIMP nsGenericInterfaceInfo::AppendConst(nsXPTConstant * aConst, PRUint16 *_retval) + +{ + NS_ASSERTION(aConst->type.prefix.flags == TD_INT16 || + aConst->type.prefix.flags == TD_UINT16 || + aConst->type.prefix.flags == TD_INT32 || + aConst->type.prefix.flags == TD_UINT32, + "unsupported const type"); + + XPTConstDescriptor* desc = (XPTConstDescriptor*) + XPT_MALLOC(mSet->GetArena(), sizeof(XPTConstDescriptor)); + if(!desc) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc, aConst, sizeof(XPTConstDescriptor)); + + int len = PL_strlen(aConst->name); + desc->name = (char*) XPT_MALLOC(mSet->GetArena(), len+1); + if(!desc->name) + return NS_ERROR_OUT_OF_MEMORY; + + memcpy(desc->name, aConst->name, len); + + return mConstants.AppendElement(desc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/************************************************/ +// nsIInterfaceInfo methods... + +/* readonly attribute string name; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetName(char * *aName) +{ + *aName = (char*) nsMemory::Clone(mName, PL_strlen(mName)+1); + return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsIIDPtr IID; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetIID(nsIID * *aIID) +{ + *aIID = (nsIID*) nsMemory::Clone(&mIID, sizeof(nsIID)); + return *aIID ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* PRBool isScriptable (); */ +NS_IMETHODIMP nsGenericInterfaceInfo::IsScriptable(PRBool *_retval) +{ + *_retval = XPT_ID_IS_SCRIPTABLE(mFlags) != 0; + return NS_OK; +} + +/* readonly attribute nsIInterfaceInfo parent; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetParent(nsIInterfaceInfo * *aParent) +{ + *aParent = mParent; + NS_IF_ADDREF(*aParent); + return NS_OK; +} + +/* readonly attribute PRUint16 methodCount; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetMethodCount(PRUint16 *aMethodCount) +{ + *aMethodCount = mMethodBaseIndex + (PRUint16) mMethods.Count(); + return NS_OK; +} + +/* readonly attribute PRUint16 constantCount; */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetConstantCount(PRUint16 *aConstantCount) +{ + *aConstantCount = mConstantBaseIndex + (PRUint16) mConstants.Count(); + return NS_OK; +} + +/* void getMethodInfo (in PRUint16 index, [shared, retval] out nsXPTMethodInfoPtr info); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetMethodInfo(PRUint16 index, const nsXPTMethodInfo * *info) +{ + if(index < mMethodBaseIndex) + return mParent->GetMethodInfo(index, info); + *info = (const nsXPTMethodInfo *) mMethods.ElementAt(index-mMethodBaseIndex); + return NS_OK; +} + +/* void getMethodInfoForName (in string methodName, out PRUint16 index, [shared, retval] out nsXPTMethodInfoPtr info); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetMethodInfoForName(const char *methodName, PRUint16 *index, const nsXPTMethodInfo * *info) +{ + PRUint16 count = mMethodBaseIndex + (PRUint16) mMethods.Count(); + for(PRUint16 i = 0; i < count; i++) + { + const nsXPTMethodInfo* current; + nsresult rv = GetMethodInfo(i, ¤t); + if(NS_FAILED(rv)) + return rv; + + if(!PL_strcmp(methodName, current->GetName())) + { + *index = i; + *info = current; + return NS_OK; + } + } + *index = 0; + *info = 0; + return NS_ERROR_INVALID_ARG; +} + +/* void getConstant (in PRUint16 index, [shared, retval] out nsXPTConstantPtr constant); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetConstant(PRUint16 index, const nsXPTConstant * *constant) +{ + if(index < mConstantBaseIndex) + return mParent->GetConstant(index, constant); + *constant = (const nsXPTConstant *) mConstants.ElementAt(index-mConstantBaseIndex); + return NS_OK; +} + +/* nsIInterfaceInfo getInfoForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetInfoForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIInterfaceInfo **_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetInfoForParam(methodIndex, param, _retval); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE, "not an interface"); + + return mSet->InterfaceInfoAt(td->type.iface, _retval); +} + +/* nsIIDPtr getIIDForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetIIDForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID * *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetIIDForParam(methodIndex, param, _retval); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE, "not an interface"); + + return mSet->InfoAtNoAddRef(td->type.iface)->GetIID(_retval); +} + +/* nsXPTType getTypeForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetTypeForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, nsXPTType *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetTypeForParam(methodIndex, param, dimension, _retval); + + const XPTTypeDescriptor *td = + dimension ? GetTypeInArray(param, dimension) : ¶m->type; + + *_retval = nsXPTType(td->prefix); + return NS_OK; +} + +/* PRUint8 getSizeIsArgNumberForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetSizeIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetSizeIsArgNumberForParam(methodIndex, param, dimension, _retval); + + const XPTTypeDescriptor *td = + dimension ? GetTypeInArray(param, dimension) : ¶m->type; + + *_retval = td->argnum; + return NS_OK; +} + +/* PRUint8 getLengthIsArgNumberForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, in PRUint16 dimension); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetLengthIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetLengthIsArgNumberForParam(methodIndex, param, dimension, _retval); + + const XPTTypeDescriptor *td = + dimension ? GetTypeInArray(param, dimension) : ¶m->type; + + *_retval = td->argnum2; + return NS_OK; +} + +/* PRUint8 getInterfaceIsArgNumberForParam (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint8 *_retval) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetInterfaceIsArgNumberForParam(methodIndex, param, _retval); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE, "not an interface"); + + *_retval = td->argnum; + return NS_OK; +} + +/* PRBool isIID (in nsIIDPtr IID); */ +NS_IMETHODIMP nsGenericInterfaceInfo::IsIID(const nsIID * IID, PRBool *_retval) +{ + *_retval = mIID.Equals(*IID); + return NS_OK; +} + +/* void getNameShared ([shared, retval] out string name); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetNameShared(const char **name) +{ + *name = mName; + return NS_OK; +} + +/* void getIIDShared ([shared, retval] out nsIIDPtrShared iid); */ +NS_IMETHODIMP nsGenericInterfaceInfo::GetIIDShared(const nsIID * *iid) +{ + *iid = &mIID; + return NS_OK; +} + +/* PRBool isFunction (); */ +NS_IMETHODIMP nsGenericInterfaceInfo::IsFunction(PRBool *_retval) +{ + *_retval = XPT_ID_IS_FUNCTION(mFlags) != 0; + return NS_OK; +} + +/* PRBool hasAncestor (in nsIIDPtr iid); */ +NS_IMETHODIMP nsGenericInterfaceInfo::HasAncestor(const nsIID * iid, PRBool *_retval) +{ + *_retval = PR_FALSE; + + nsCOMPtr current = NS_STATIC_CAST(nsIInterfaceInfo*, this); + while(current) + { + PRBool same; + if(NS_SUCCEEDED(current->IsIID(iid, &same)) && same) + { + *_retval = PR_TRUE; + break; + } + nsCOMPtr temp(current); + temp->GetParent(getter_AddRefs(current)); + } + return NS_OK; +} + +/* [notxpcom] nsresult getIIDForParamNoAlloc (in PRUint16 methodIndex, [const] in nsXPTParamInfoPtr param, out nsIID iid); */ +NS_IMETHODIMP_(nsresult) nsGenericInterfaceInfo::GetIIDForParamNoAlloc(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID *iid) +{ + if(methodIndex < mMethodBaseIndex) + return mParent->GetIIDForParamNoAlloc(methodIndex, param, iid); + + const XPTTypeDescriptor* td = GetPossiblyNestedType(param); + NS_ASSERTION(XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE, "not an interface"); + + const nsIID* iidp; + return mSet->InfoAtNoAddRef(td->type.iface)->GetIIDShared(&iidp); + *iid = *iidp; + return NS_OK; +} diff --git a/extensions/xmlextras/interfaceinfo/src/nsScriptableInterfaceInfo.cpp b/extensions/xmlextras/interfaceinfo/src/nsScriptableInterfaceInfo.cpp new file mode 100644 index 00000000000..4deb9b5d8d5 --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/src/nsScriptableInterfaceInfo.cpp @@ -0,0 +1,786 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * John Bandhauer + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* nsIScriptableInteraceInfo family implementations. */ + +#include "iixprivate.h" + +/***************************************************************************/ +static inline nsresult CloneString(const char* inStr, char** outStr) +{ + *outStr = (char*) nsMemory::Clone(inStr, strlen(inStr)+1); + return *outStr ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/***************************************************************************/ + +/* Header file */ +class nsScriptableDataType : public nsIScriptableDataType +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEDATATYPE + + static nsresult Create(const nsXPTType& aType, + nsIScriptableDataType** aResult); + + nsScriptableDataType(); // not implemented + + nsScriptableDataType(const nsXPTType& aType) + : mType(aType) {NS_INIT_ISUPPORTS();} + + virtual ~nsScriptableDataType() {} + +private: + nsXPTType mType; +}; + +// static +nsresult +nsScriptableDataType::Create(const nsXPTType& aType, + nsIScriptableDataType** aResult) +{ + nsScriptableDataType* obj = new nsScriptableDataType(aType); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableDataType*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableDataType, nsIScriptableDataType) + +/* readonly attribute PRBool isPointer; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsPointer(PRBool *aIsPointer) +{ + *aIsPointer = mType.IsPointer(); + return NS_OK; +} + +/* readonly attribute PRBool isUniquePointer; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsUniquePointer(PRBool *aIsUniquePointer) +{ + *aIsUniquePointer = mType.IsUniquePointer(); + return NS_OK; +} + +/* readonly attribute PRBool isReference; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsReference(PRBool *aIsReference) +{ + *aIsReference = mType.IsReference(); + return NS_OK; +} + +/* readonly attribute PRBool isArithmetic; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsArithmetic(PRBool *aIsArithmetic) +{ + *aIsArithmetic = mType.IsArithmetic(); + return NS_OK; +} + +/* readonly attribute PRBool isInterfacePointer; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsInterfacePointer(PRBool *aIsInterfacePointer) +{ + *aIsInterfacePointer = mType.IsInterfacePointer(); + return NS_OK; +} + +/* readonly attribute PRBool isArray; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsArray(PRBool *aIsArray) +{ + *aIsArray = mType.IsArray(); + return NS_OK; +} + +/* readonly attribute PRBool isDependent; */ +NS_IMETHODIMP +nsScriptableDataType::GetIsDependent(PRBool *aIsDependent) +{ + *aIsDependent = mType.IsDependent(); + return NS_OK; +} + +/* readonly attribute PRUint16 dataType; */ +NS_IMETHODIMP +nsScriptableDataType::GetDataType(PRUint16 *aDataType) +{ + *aDataType = mType.TagPart(); + return NS_OK; +} + +/***************************************************************************/ + +class nsScriptableParamInfo : public nsIScriptableParamInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEPARAMINFO + + static nsresult Create(nsIInterfaceInfo* aInfo, + const nsXPTParamInfo& aParam, + nsIScriptableParamInfo** aResult); + + nsScriptableParamInfo(); // not implemented + nsScriptableParamInfo(nsIInterfaceInfo* aInfo, + const nsXPTParamInfo& aParam) + : mInfo(aInfo), mParam(aParam) {NS_INIT_ISUPPORTS();} + virtual ~nsScriptableParamInfo() {} + +private: + // Holding onto the interface info keeps the underlying param alive. + nsCOMPtr mInfo; + nsXPTParamInfo mParam; +}; + + +// static +nsresult +nsScriptableParamInfo::Create(nsIInterfaceInfo* aInfo, + const nsXPTParamInfo& aParam, + nsIScriptableParamInfo** aResult) +{ + nsScriptableParamInfo* obj = new nsScriptableParamInfo(aInfo, aParam); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableParamInfo*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableParamInfo, nsIScriptableParamInfo) + +/* readonly attribute PRBool isIn; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsIn(PRBool *aIsIn) +{ + *aIsIn = mParam.IsIn(); + return NS_OK; +} + +/* readonly attribute PRBool isOut; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsOut(PRBool *aIsOut) +{ + *aIsOut = mParam.IsOut(); + return NS_OK; +} + +/* readonly attribute PRBool isRetval; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsRetval(PRBool *aIsRetval) +{ + *aIsRetval = mParam.IsRetval(); + return NS_OK; +} + +/* readonly attribute PRBool isShared; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsShared(PRBool *aIsShared) +{ + *aIsShared = mParam.IsShared(); + return NS_OK; +} + +/* readonly attribute PRBool isDipper; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetIsDipper(PRBool *aIsDipper) +{ + *aIsDipper = mParam.IsDipper(); + return NS_OK; +} + +/* readonly attribute nsIScriptableDataType type; */ +NS_IMETHODIMP +nsScriptableParamInfo::GetType(nsIScriptableDataType * *aType) +{ + return nsScriptableDataType::Create(mParam.GetType(), aType); +} + +/* [noscript] void getParamInfo ([shared, const, retval] out nsXPTParamInfoPtr aInfo); */ +NS_IMETHODIMP +nsScriptableParamInfo::GetParamInfo(const nsXPTParamInfo * *aInfo) +{ + *aInfo = &mParam; + return NS_OK; +} + +/***************************************************************************/ +class nsScriptableConstant : public nsIScriptableConstant +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLECONSTANT + + static nsresult Create(nsIInterfaceInfo* aInfo, + const nsXPTConstant& aConst, + nsIScriptableConstant** aResult); + + nsScriptableConstant(); // not implemented + nsScriptableConstant(nsIInterfaceInfo* aInfo, + const nsXPTConstant& aConst) + : mInfo(aInfo), mConst(aConst) {NS_INIT_ISUPPORTS();} + virtual ~nsScriptableConstant() {} +private: + // Holding onto the interface info keeps the underlying const alive. + nsCOMPtr mInfo; + nsXPTConstant mConst; +}; + +// static +nsresult +nsScriptableConstant::Create(nsIInterfaceInfo* aInfo, + const nsXPTConstant& aConst, + nsIScriptableConstant** aResult) +{ + nsScriptableConstant* obj = new nsScriptableConstant(aInfo, aConst); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableConstant*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableConstant, nsIScriptableConstant) + +/* readonly attribute string name; */ +NS_IMETHODIMP +nsScriptableConstant::GetName(char * *aName) +{ + return CloneString(mConst.GetName(), aName); +} + +/* readonly attribute nsIScriptableDataType type; */ +NS_IMETHODIMP +nsScriptableConstant::GetType(nsIScriptableDataType * *aType) +{ + return nsScriptableDataType::Create(mConst.GetType(), aType); +} + +/* readonly attribute nsIVariant value; */ +NS_IMETHODIMP +nsScriptableConstant::GetValue(nsIVariant * *aValue) +{ + nsVariant* variant = new nsVariant(); + if(!variant) + { + *aValue = nsnull; + return NS_ERROR_OUT_OF_MEMORY; + } + *aValue = NS_STATIC_CAST(nsIVariant*, variant); + NS_ADDREF(*aValue); + + const nsXPTCMiniVariant* varval = mConst.GetValue(); + nsresult rv; + + switch(mConst.GetType()) + { + case nsXPTType::T_I16: + rv = variant->SetAsInt16(varval->val.i16); + break; + case nsXPTType::T_I32: + rv = variant->SetAsInt32(varval->val.i32); + break; + case nsXPTType::T_U16: + rv = variant->SetAsUint16(varval->val.u16); + break; + case nsXPTType::T_U32: + rv = variant->SetAsUint32(varval->val.u32); + break; + default: + NS_ERROR("invalid const type"); + rv = NS_ERROR_UNEXPECTED; + break; + } + + if(NS_FAILED(rv)) + { + NS_RELEASE(*aValue); + return rv; + } + + return NS_OK; +} + +/***************************************************************************/ + +class nsScriptableMethodInfo : public nsIScriptableMethodInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISCRIPTABLEMETHODINFO + + static nsresult Create(nsIInterfaceInfo* aInfo, + const nsXPTMethodInfo& aMethod, + nsIScriptableMethodInfo** aResult); + + nsScriptableMethodInfo(); // not implemented + nsScriptableMethodInfo(nsIInterfaceInfo* aInfo, + const nsXPTMethodInfo& aMethod) + : mInfo(aInfo), mMethod(aMethod) {NS_INIT_ISUPPORTS();} + virtual ~nsScriptableMethodInfo() {} +private: + // Holding onto the interface info keeps the underlying method alive. + nsCOMPtr mInfo; + const nsXPTMethodInfo& mMethod; +}; + +// static +nsresult +nsScriptableMethodInfo::Create(nsIInterfaceInfo* aInfo, + const nsXPTMethodInfo& aMethod, + nsIScriptableMethodInfo** aResult) +{ + nsScriptableMethodInfo* obj = new nsScriptableMethodInfo(aInfo, aMethod); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableMethodInfo*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableMethodInfo, nsIScriptableMethodInfo) + +/* readonly attribute PRBool isGetter; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsGetter(PRBool *aIsGetter) +{ + *aIsGetter = mMethod.IsGetter(); + return NS_OK; +} + +/* readonly attribute PRBool isSetter; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsSetter(PRBool *aIsSetter) +{ + *aIsSetter = mMethod.IsSetter(); + return NS_OK; +} + +/* readonly attribute PRBool isNotXPCOM; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsNotXPCOM(PRBool *aIsNotXPCOM) +{ + *aIsNotXPCOM = mMethod.IsNotXPCOM(); + return NS_OK; +} + +/* readonly attribute PRBool isConstructor; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsConstructor(PRBool *aIsConstructor) +{ + *aIsConstructor = mMethod.IsConstructor(); + return NS_OK; +} + +/* readonly attribute PRBool isHidden; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetIsHidden(PRBool *aIsHidden) +{ + *aIsHidden = mMethod.IsHidden(); + return NS_OK; +} + +/* readonly attribute string name; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetName(char * *aName) +{ + return CloneString(mMethod.GetName(), aName); +} + +/* readonly attribute PRUint8 paramCount; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetParamCount(PRUint8 *aParamCount) +{ + *aParamCount = mMethod.GetParamCount(); + return NS_OK; +} + +/* nsIScriptableParamInfo getParam (in PRUint8 idx); */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetParam(PRUint8 idx, nsIScriptableParamInfo **_retval) +{ + if(idx >= mMethod.GetParamCount()) + return NS_ERROR_INVALID_ARG; + return nsScriptableParamInfo::Create(mInfo, mMethod.GetParam(idx), _retval); +} + +/* readonly attribute nsIScriptableParamInfo result; */ +NS_IMETHODIMP +nsScriptableMethodInfo::GetResult(nsIScriptableParamInfo * *aResult) +{ + return nsScriptableParamInfo::Create(mInfo, mMethod.GetResult(), aResult); +} + +/***************************************************************************/ + +// static +nsresult +nsScriptableInterfaceInfo::Create(nsIInterfaceInfo* aInfo, + nsIScriptableInterfaceInfo** aResult) +{ + nsScriptableInterfaceInfo* obj = new nsScriptableInterfaceInfo(aInfo); + if(!obj) + return NS_ERROR_OUT_OF_MEMORY; + *aResult = NS_STATIC_CAST(nsIScriptableInterfaceInfo*, obj); + NS_ADDREF(*aResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsScriptableInterfaceInfo, nsIScriptableInterfaceInfo) + +nsScriptableInterfaceInfo::nsScriptableInterfaceInfo() +{ + NS_INIT_ISUPPORTS(); +} + +nsScriptableInterfaceInfo::nsScriptableInterfaceInfo(nsIInterfaceInfo* aInfo) + : mInfo(aInfo) +{ + NS_INIT_ISUPPORTS(); +} + +nsScriptableInterfaceInfo::~nsScriptableInterfaceInfo() +{ + // empty; +} + +/* [noscript] attribute nsIInterfaceInfo info; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInfo(nsIInterfaceInfo * *aInfo) +{ + if(mInfo) + NS_ADDREF(*aInfo = mInfo); + else + *aInfo = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsScriptableInterfaceInfo::SetInfo(nsIInterfaceInfo * aInfo) +{ + mInfo = aInfo; + return NS_OK; +} + +/* void Init (in nsIIDPtr aIID); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::Init(const nsIID * aIID) +{ + return SetInterfaceID(aIID); +} + +/* readonly attribute string name; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetName(char * *aName) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetName(aName); +} + +/* attribute nsIIDPtr interfaceID; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInterfaceID(nsIID * *aInterfaceID) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetIID(aInterfaceID); +} + +NS_IMETHODIMP +nsScriptableInterfaceInfo::SetInterfaceID(const nsIID * aInterfaceID) +{ + nsCOMPtr iim = + dont_AddRef(XPTI_GetInterfaceInfoManager()); + if(!iim) + return NS_ERROR_UNEXPECTED; + mInfo = nsnull; + iim->GetInfoForIID(aInterfaceID, getter_AddRefs(mInfo)); + + // XXX we want to look at additional managers here if not found! + + return mInfo ? NS_OK : NS_ERROR_NO_INTERFACE; +} + +/* readonly attribute PRBool isValid; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIsValid(PRBool *aIsValid) +{ + *aIsValid = !!mInfo; + return NS_OK; +} + +/* readonly attribute PRBool isScriptable; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIsScriptable(PRBool *aIsScriptable) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->IsScriptable(aIsScriptable); +} + +/* readonly attribute nsIScriptableInterfaceInfo parent; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetParent(nsIScriptableInterfaceInfo * *aParent) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + nsCOMPtr parentInfo; + nsresult rv = mInfo->GetParent(getter_AddRefs(parentInfo)); + if(NS_FAILED(rv)) + return rv; + + if(parentInfo) + return Create(parentInfo, aParent); + + *aParent = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint16 methodCount; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetMethodCount(PRUint16 *aMethodCount) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetMethodCount(aMethodCount); +} + +/* readonly attribute PRUint16 constantCount; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetConstantCount(PRUint16 *aConstantCount) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->GetConstantCount(aConstantCount); +} + +/* nsIScriptableMethodInfo getMethodInfo (in PRUint16 index); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetMethodInfo(PRUint16 index, nsIScriptableMethodInfo **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTMethodInfo* methodInfo; + nsresult rv = mInfo->GetMethodInfo(index, &methodInfo); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableMethodInfo::Create(mInfo, *methodInfo, _retval); +} + +/* nsIScriptableMethodInfo getMethodInfoForName (in string methodName, out PRUint16 index); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetMethodInfoForName(const char *methodName, PRUint16 *index, nsIScriptableMethodInfo **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTMethodInfo* methodInfo; + nsresult rv = mInfo->GetMethodInfoForName(methodName, index, &methodInfo); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableMethodInfo::Create(mInfo, *methodInfo, _retval); +} + +/* nsIScriptableConstant getConstant (in PRUint16 index); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetConstant(PRUint16 index, nsIScriptableConstant **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTConstant* constant; + nsresult rv = mInfo->GetConstant(index, &constant); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableConstant::Create(mInfo, *constant, _retval); +} + +/* nsIScriptableInterfaceInfo getInfoForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInfoForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, nsIScriptableInterfaceInfo **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + nsCOMPtr info; + rv = mInfo->GetInfoForParam(methodIndex, paramInfo, getter_AddRefs(info)); + if(NS_FAILED(rv)) + return rv; + + if(info) + return Create(info, _retval); + + *_retval = nsnull; + return NS_OK; +} + +/* nsIIDPtr getIIDForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIIDForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, nsIID * *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetIIDForParam(methodIndex, paramInfo, _retval); +} + +/* nsIScriptableDataType getTypeForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param, in PRUint16 dimension); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetTypeForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint16 dimension, nsIScriptableDataType **_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + nsXPTType type; + + rv = mInfo->GetTypeForParam(methodIndex, paramInfo, dimension, &type); + if(NS_FAILED(rv)) + return rv; + + return nsScriptableDataType::Create(type, _retval); +} + +/* PRUint8 getSizeIsArgNumberForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param, in PRUint16 dimension); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetSizeIsArgNumberForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint16 dimension, PRUint8 *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetSizeIsArgNumberForParam(methodIndex, paramInfo, + dimension, _retval); +} + +/* PRUint8 getLengthIsArgNumberForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param, in PRUint16 dimension); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetLengthIsArgNumberForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint16 dimension, PRUint8 *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetLengthIsArgNumberForParam(methodIndex, paramInfo, + dimension, _retval); +} + +/* PRUint8 getInterfaceIsArgNumberForParam (in PRUint16 methodIndex, in nsIScriptableParamInfo param); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, nsIScriptableParamInfo *param, PRUint8 *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + const nsXPTParamInfo* paramInfo; + nsresult rv = param->GetParamInfo(¶mInfo); + if(NS_FAILED(rv)) + return rv; + + return mInfo->GetInterfaceIsArgNumberForParam(methodIndex, paramInfo, + _retval); +} + +/* PRBool isIID (in nsIIDPtr IID); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::IsIID(const nsIID * IID, PRBool *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->IsIID(IID, _retval); +} + +/* readonly attribute PRBool isFunction; */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::GetIsFunction(PRBool *aIsFunction) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->IsFunction(aIsFunction); +} + +/* PRBool hasAncestor (in nsIIDPtr iid); */ +NS_IMETHODIMP +nsScriptableInterfaceInfo::HasAncestor(const nsIID * iid, PRBool *_retval) +{ + if(!mInfo) + return NS_ERROR_NOT_INITIALIZED; + + return mInfo->HasAncestor(iid, _retval); +} diff --git a/extensions/xmlextras/interfaceinfo/tests/ifaceinfotest.js b/extensions/xmlextras/interfaceinfo/tests/ifaceinfotest.js new file mode 100644 index 00000000000..f490462fd66 --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/tests/ifaceinfotest.js @@ -0,0 +1,364 @@ +// test the nsIScriptableInterfaceInfo stuff... +// We ought to leverage this in SOAP code. + +const IInfo = new Components.Constructor("@mozilla.org/scriptableInterfaceInfo;1", + "nsIScriptableInterfaceInfo", + "init"); + +const nsIDataType = Components.interfaces.nsIDataType; +const nsISupports = Components.interfaces.nsISupports; + +const PARAM_NAME_PREFIX = "arg"; + +/** +* takes: {xxx} +* returns: uuid(xxx) +*/ +function formatID(str) +{ + return "uuid("+str.substring(1,str.length-1)+")"; +} + +function formatConstType(type) +{ + switch(type) + { + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + default: + return "!!!! bad const type !!!"; + } +} + +function formatTypeName(info, methodIndex, param, dimension) +{ + var type = param.type; + + switch(type.dataType) + { + case nsIDataType.VTYPE_INT8 : + return "PRInt8"; + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_INT64: + return "PRInt64"; + case nsIDataType.VTYPE_UINT8: + return "PRUint8"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + case nsIDataType.VTYPE_UINT64: + return "PRUint64"; + case nsIDataType.VTYPE_FLOAT: + return "float"; + case nsIDataType.VTYPE_DOUBLE: + return "double"; + case nsIDataType.VTYPE_BOOL: + return "PRBool"; + case nsIDataType.VTYPE_CHAR: + return "char"; + case nsIDataType.VTYPE_WCHAR: + return "PRUnichar"; + case nsIDataType.VTYPE_VOID: + if(type.isPointer) + return "voidPtr"; + return "void"; + case nsIDataType.VTYPE_ID: + // order matters here... + if(type.isReference) + return "nsIDRef"; + if(type.isPointer) + return "nsIDPtr"; + return "nsID"; + case nsIDataType.VTYPE_ASTRING: + return "aString"; + case nsIDataType.VTYPE_CHAR_STR: + return "string"; + case nsIDataType.VTYPE_WCHAR_STR: + return "wstring"; + case nsIDataType.VTYPE_INTERFACE: + return info.getInfoForParam(methodIndex, param).name; + case nsIDataType.VTYPE_INTERFACE_IS: + return "nsQIResult"; + case nsIDataType.VTYPE_ARRAY: + return formatTypeName(info, methodIndex, param, dimension+1); + case nsIDataType.VTYPE_STRING_SIZE_IS: + return "string"; + case nsIDataType.VTYPE_WSTRING_SIZE_IS: + return "wstring"; + default: + return "!!!! bad data type !!!"; + } +} + +function formatBracketForParam(info, methodIndex, param) +{ + var type = param.type; + var str = "["; + var found = 0; + var size_is_ArgNum; + var length_is_ArgNum; + + if(param.isRetval) + { + if(found++) + str += ", "; + str += "retval" + } + + if(param.isShared) + { + if(found++) + str += ", "; + str += "shared" + } + + if(type.isArray) + { + if(found++) + str += ", "; + str += "array" + } + + if(type.dataType == nsIDataType.VTYPE_INTERFACE_IS) + { + if(found++) + str += ", "; + str += "iid_is("+ + PARAM_NAME_PREFIX + + info.getInterfaceIsArgNumberForParam(methodIndex, param) + ")"; + } + + if(type.isArray || + type.dataType == nsIDataType.VTYPE_STRING_SIZE_IS || + type.dataType == nsIDataType.VTYPE_WSTRING_SIZE_IS) + { + if(found++) + str += ", "; + + size_is_ArgNum = + info.getSizeIsArgNumberForParam(methodIndex, param, 0); + + str += "size_is("+ PARAM_NAME_PREFIX + size_is_ArgNum + ")"; + + length_is_ArgNum = + info.getLengthIsArgNumberForParam(methodIndex, param, 0); + + if(length_is_ArgNum != size_is_ArgNum) + { + str += ", "; + str += "length_is("+ PARAM_NAME_PREFIX + length_is_ArgNum + ")"; + } + } + + if(!found) + return ""; + str += "] "; + return str +} + +function doInterface(iid) +{ + var i, k, t, m, m2, c, p, readonly, bracketed, paramCount, retvalTypeName; + + var info = new IInfo(iid); + var parent = info.parent; + + var constBaseIndex = parent ? parent.constantCount : 0; + var constTotalCount = info.constantCount; + var constLocalCount = constTotalCount - constBaseIndex; + + var methodBaseIndex = parent ? parent.methodCount : 0; + var methodTotalCount = info.methodCount; + var methodLocalCount = methodTotalCount - methodBaseIndex; + + + // maybe recurring to emit parent declarations is not a good idea... +// if(parent) +// doInterface(parent.interfaceID); + + print(); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// print("/*\n"); + + print("[" + (info.isScriptable ? "scriptable, " : "") + + formatID(info.interfaceID.number) + "]"); + + print("interface "+ info.name + (parent ? (" : "+parent.name) : "") + " {"); + + if(constLocalCount) + { + for(i = constBaseIndex; i < constTotalCount; i++) + { + c = info.getConstant(i); + print(" const " + formatConstType(c.type.dataType) + " " + + c.name + " = " + c.value + ";"); + } + } + + if(constLocalCount && methodLocalCount) + print(); + + if(methodLocalCount) + { + for(i = methodBaseIndex; i < methodTotalCount; i++) + { + m = info.getMethodInfo(i); + + if(m.isNotXPCOM) + bracketed = "[notxpcom] " + else if(m.isHidden) + bracketed = "[noscript] " + else + bracketed = ""; + + if(m.isGetter) + { + // Is an attribute + + // figure out if this is readonly + m2 = i+1 < methodTotalCount ? info.getMethodInfo(i+1) : null; + readonly = !m2 || m2.name != m.name; + + print(" " + bracketed + (readonly ? "readonly " : "") + + "attribute " + + formatTypeName(info, i, m.getParam(0), 0) + + " " + m.name + ";\n"); + + if(!readonly) + i++; // skip the next one, we have it covered. + + continue; + } + // else... + + paramCount = m.paramCount; + + // 'last' param is used to figure out retvalTypeName + + p = paramCount ? m.getParam(paramCount-1) : null; + + if(m.isNotXPCOM) + retvalTypeName = formatTypeName(info, i, m.result, 0); + else if(p && "[retval] " == formatBracketForParam(info, i, p)) + { + // Check for the exact string above because anything else + // indicates that there either is no expilict retval + // or there are additional braketed attributes (meaning that + // the retval must appear in the param list and not + // preceeding the method name). + retvalTypeName = formatTypeName(info, i, p, 0); + // no need to print it in the param list + paramCount-- ; + } + else + retvalTypeName = "void"; + + // print method name + + print(" " + bracketed + retvalTypeName + " " + m.name + "(" + + (paramCount ? "" : ");")); + + // print params + + for(k = 0; k < paramCount; k++) + { + p = m.getParam(k); + print(" "+ + formatBracketForParam(info, i, p) + + (p.isOut ? p.isIn ? "inout " : "out " : "in ") + + formatTypeName(info, i, p, 0) + " " + + PARAM_NAME_PREFIX+k + + (k+1 == paramCount ? ");\n" : ", ")); + } + } + } + + print("};\n"); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// print("\n*/\n"); +} + +function appendForwardDeclarations(list, info) +{ + list.push(info.name); + if(info.parent) + appendForwardDeclarations(list, info.parent); + + var i, k, m, p; + + for(i = 0; i < info.methodCount; i++) + { + m = info.getMethodInfo(i); + + for(k = 0; k < m.paramCount; k++) + { + p = m.getParam(k); + + if(p.type.dataType == nsIDataType.VTYPE_INTERFACE) + { + list.push(info.getInfoForParam(i, p).name); + } + } + } +} + +function doForwardDeclarations(iid) +{ + var i, cur, prev; + var list = []; + appendForwardDeclarations(list, new IInfo(iid)); + list.sort(); + + print("// forward declarations..."); + + for(i = 0; i < list.length; i++) + { + cur = list[i]; + if(cur != prev && cur != "nsISupports") + { + print("interface " + cur +";"); + prev = cur; + } + } + print(""); +} + +function info2IDL(iid) +{ + print(); + print('#include "nsISupports.idl"'); + print(); + + doForwardDeclarations(iid) + doInterface(iid); +} + +/***************************************************************************/ +/***************************************************************************/ +// test... + +print(); +print(); +//info2IDL(Components.interfaces.nsISupports); +print("//------------------------------------------------------------"); +info2IDL(Components.interfaces.nsIDataType); +print("//------------------------------------------------------------"); +info2IDL(Components.interfaces.nsIScriptableInterfaceInfo); +print("//------------------------------------------------------------"); +info2IDL(Components.interfaces.nsIVariant); +print(); +print();