From e1bfe84a47eb07946cb65530a1aaca7d1db76cde Mon Sep 17 00:00:00 2001 From: "bjorn%netscape.com" Date: Wed, 11 Nov 1998 23:46:21 +0000 Subject: [PATCH] New support for typeinformation and typelibraries. nsISupports.h has an additional definition NS_DECL_ISUPPORTS_EXPORTED, which exports the threesome. This is not yet part of the build. It will be picked up by support code in mozilla/js/src/xpcom. --- xpcom/public/nsISupports.h | 10 ++ xpcom/public/nsITypeInfo.h | 67 ++++++++ xpcom/public/nsITypeLib.h | 34 ++++ xpcom/public/nsTypeInfo.h | 73 +++++++++ xpcom/public/nsTypeInfoDefs.h | 160 +++++++++++++++++++ xpcom/public/nsTypeLib.h | 34 ++++ xpcom/src/nsTypeInfo.cpp | 214 ++++++++++++++++++++++++++ xpcom/src/nsTypeLib.cpp | 93 +++++++++++ xpcom/tests/typeinfo/main.cpp | 125 +++++++++++++++ xpcom/tests/typeinfo/test.cpp | 34 ++++ xpcom/tests/typeinfo/test.h | 25 +++ xpcom/tests/typeinfo/testTypeInfo.cpp | 124 +++++++++++++++ xpcom/tests/typeinfo/testTypeInfo.h | 28 ++++ xpcom/tests/typeinfo/testTypeLib.cpp | 45 ++++++ xpcom/tests/typeinfo/testTypeLib.h | 16 ++ 15 files changed, 1082 insertions(+) create mode 100644 xpcom/public/nsITypeInfo.h create mode 100644 xpcom/public/nsITypeLib.h create mode 100644 xpcom/public/nsTypeInfo.h create mode 100644 xpcom/public/nsTypeInfoDefs.h create mode 100644 xpcom/public/nsTypeLib.h create mode 100644 xpcom/src/nsTypeInfo.cpp create mode 100644 xpcom/src/nsTypeLib.cpp create mode 100644 xpcom/tests/typeinfo/main.cpp create mode 100644 xpcom/tests/typeinfo/test.cpp create mode 100644 xpcom/tests/typeinfo/test.h create mode 100644 xpcom/tests/typeinfo/testTypeInfo.cpp create mode 100644 xpcom/tests/typeinfo/testTypeInfo.h create mode 100644 xpcom/tests/typeinfo/testTypeLib.cpp create mode 100644 xpcom/tests/typeinfo/testTypeLib.h diff --git a/xpcom/public/nsISupports.h b/xpcom/public/nsISupports.h index 42d553224ed4..d5ba9ce8946a 100644 --- a/xpcom/public/nsISupports.h +++ b/xpcom/public/nsISupports.h @@ -132,6 +132,16 @@ protected: \ nsrefcnt mRefCnt; \ public: +#define NS_DECL_ISUPPORTS_EXPORTED \ +public: \ + NS_EXPORT NS_IMETHOD QueryInterface(REFNSIID aIID, \ + void** aInstancePtr); \ + NS_EXPORT NS_IMETHOD_(nsrefcnt) AddRef(void); \ + NS_EXPORT NS_IMETHOD_(nsrefcnt) Release(void); \ +protected: \ + nsrefcnt mRefCnt; \ +public: + /** * Initialize the reference count variable. Add this to each and every * constructor you implement. diff --git a/xpcom/public/nsITypeInfo.h b/xpcom/public/nsITypeInfo.h new file mode 100644 index 000000000000..c9ea30476a99 --- /dev/null +++ b/xpcom/public/nsITypeInfo.h @@ -0,0 +1,67 @@ +#ifndef _NSTYPEINFO_ +#define _NSTYPEINFO_ +#include "nsISupports.h" +#include "nsTypeInfoDefs.h" + +// {969dac50-75a5-11d2-abad-00805f6177ce} +#define NS_TYPEINFO_IID \ +{ 0x969dac50, 0x75a5, 0x11d2, \ + { 0xab, 0xad, 0x00, 0x80, 0x5f, 0x61, 0x77, 0xce } } + +class nsITypeInfo : public nsISupports +{ +public: + NS_IMETHOD GetTypeAttr( + nsTYPEATTR **ppTypeAttr) = 0; + + NS_IMETHOD GetFuncDesc( + PRUint32 index, + nsFUNCDESC **ppFuncDesc) = 0; + + NS_IMETHOD GetVarDesc( + PRUint32 index, + nsVARDESC **ppVarDesc) = 0; + + NS_IMETHOD GetNames( + nsDISPID memid, + nsSTR *rgBstrNames, + PRUint32 cMaxNames, + PRUint32 *pcNames) = 0; + + NS_IMETHOD GetIDOfName( + nsSTR name, + nsDISPID *pMemId) = 0; + + NS_IMETHOD Invoke( + void *pvInstance, + nsDISPID memid, + nsDISPATCHKIND dispKind, + nsDISPPARAMS *pDispParams, + nsVARIANT *pVarResult, + nsEXCEP *pExcepInfo, + PRInt32 *puArgErr) = 0; + + NS_IMETHOD AddressOfMember( + nsDISPID memid, + nsINVOKEKIND invKind, + void **ppv) = 0; + + NS_IMETHOD CreateInstance( + nsISupports *delegate, + REFNSIID riid, + void **ppvObj) = 0; + + NS_IMETHOD GetContainingTypeLib( + nsITypeLib **ppTLib, + PRUint32 *pIndex) = 0; + + NS_IMETHOD_(void) ReleaseTypeAttr( + nsTYPEATTR *pTypeAttr) = 0; + + NS_IMETHOD_(void) ReleaseFuncDesc( + nsFUNCDESC *pFuncDesc) = 0; + + NS_IMETHOD_(void) ReleaseVarDesc( + nsVARDESC *pVarDesc) = 0; +}; +#endif // _NSTYPEINFO_ diff --git a/xpcom/public/nsITypeLib.h b/xpcom/public/nsITypeLib.h new file mode 100644 index 000000000000..3dd4f7c3db7c --- /dev/null +++ b/xpcom/public/nsITypeLib.h @@ -0,0 +1,34 @@ +#ifndef _NSTYPELIB_ +#define _NSTYPELIB_ +#include "nsISupports.h" +#include "nsTypeInfoDefs.h" + +// {4f50cda0-75a5-11d2-abad-00805f6177ce} +#define NS_TYPELIB_IID \ +{ 0x4f50cda0, 0x75a5, 0x11d2, \ + { 0xab, 0xad, 0x00, 0x80, 0x5f, 0x61, 0x77, 0xce } } + +class nsITypeLib : public nsISupports +{ +public: + NS_IMETHOD GetTypeInfoCount(PRInt32 *count) = 0; + + NS_IMETHOD GetTypeInfo( + PRUint32 index, + nsITypeInfo **ppTInfo) = 0; + + NS_IMETHOD GetTypeInfoType( + PRUint32 index, + nsTYPEKIND *pTKind) = 0; + + NS_IMETHOD GetTypeInfoOfGuid( + REFNSIID guid, + nsITypeInfo **ppTinfo) = 0; + + NS_IMETHOD GetLibAttr( + nsTLIBATTR **ppTLibAttr) = 0; + + NS_IMETHOD_(void) ReleaseLibAttr( + nsTLIBATTR *pTLibAttr) = 0; +}; +#endif // _NSTYPELIB_ diff --git a/xpcom/public/nsTypeInfo.h b/xpcom/public/nsTypeInfo.h new file mode 100644 index 000000000000..83303186fddc --- /dev/null +++ b/xpcom/public/nsTypeInfo.h @@ -0,0 +1,73 @@ +#ifndef __nstypeinfo__ +#define __nstypeinfo__ + +#include "nsITypeLib.h" +#include "nsITypeInfo.h" + +class nsTypeInfo : public nsITypeInfo { +protected: + nsITypeLib* lib; + nsTYPEATTR tattr; + nsVARTYPE **paramdesc; + nsFUNCDESC *fdesc; + nsSTR *fnames; + nsVARDESC *vdesc; + nsSTR *vnames; + NS_DECL_ISUPPORTS_EXPORTED +public: + + NS_EXPORT NS_IMETHODIMP GetTypeAttr( + nsTYPEATTR **ppTypeAttr); + + NS_EXPORT NS_IMETHODIMP GetFuncDesc( + PRUint32 index, + nsFUNCDESC **ppFuncDesc); + + NS_EXPORT NS_IMETHODIMP GetVarDesc( + PRUint32 index, + nsVARDESC **ppVarDesc); + + NS_EXPORT NS_IMETHODIMP GetNames( + nsDISPID memid, + nsSTR *rgBstrNames, + PRUint32 cMaxNames, + PRUint32 *pcNames); + + NS_EXPORT NS_IMETHODIMP GetIDOfName( + nsSTR name, + nsDISPID *pMemId); + + NS_EXPORT NS_IMETHODIMP InvokeCheck( + nsDISPID memid, + nsDISPATCHKIND dispKind, + nsDISPPARAMS *pDispParams, + PRInt32 *puArgErr); + + NS_EXPORT NS_IMETHODIMP AddressOfMember( + nsDISPID memid, + nsINVOKEKIND invKind, + void **ppv); + + NS_EXPORT NS_IMETHODIMP CheckInstance( + nsISupports *nsi, + REFNSIID riid, + void **ppvObj); + + NS_EXPORT NS_IMETHODIMP GetContainingTypeLib( + nsITypeLib **ppTLib, + PRUint32 *pIndex); + + NS_EXPORT NS_IMETHODIMP_(void) ReleaseTypeAttr( + nsTYPEATTR *pTypeAttr); + + NS_EXPORT NS_IMETHODIMP_(void) ReleaseFuncDesc( + nsFUNCDESC *pFuncDesc); + + NS_EXPORT NS_IMETHODIMP_(void) ReleaseVarDesc( + nsVARDESC *pVarDesc); + + NS_EXPORT nsTypeInfo(nsITypeLib *l, PRUint32 nfuns, PRUint32 nvars); + NS_EXPORT ~nsTypeInfo(); +}; + +#endif diff --git a/xpcom/public/nsTypeInfoDefs.h b/xpcom/public/nsTypeInfoDefs.h new file mode 100644 index 000000000000..24ddc41f6ad6 --- /dev/null +++ b/xpcom/public/nsTypeInfoDefs.h @@ -0,0 +1,160 @@ +#ifndef __typeinfo__ +#define __typeinfo__ + +#include "prtypes.h" +#include + +typedef wchar_t wchar; +typedef wchar* nsSTR; +typedef PRUint16 nsDISPID; +typedef PRUint32 nsHREFTYPE; + +enum nsTIERROR { + NS_TYPE_MISMATCH = 100, + NS_NOSUCH_FUN = 101, + NS_NOSUCH_VAR = 102, + NS_NOSUCH_NAME = 103, + NS_DISPATCH_MISMATCH = 104, + NS_NOSUCH_INDEX = 105, + NS_NOSUCH_ID = 106, + NS_ARGUMENT_MISMATCH = 107, +}; + +enum nsSYSKIND { + SYS_WIN32, + SYS_MAC, + SYS_UNIX +}; + +struct nsTLIBATTR { + nsIID guid; + PRUint16 lcid; + nsSYSKIND syskind; + PRInt32 wMajorVerNum; + PRInt32 wMinorVerNum; + PRInt32 wLibFlags; +}; + +enum nsTYPEKIND { + TKIND_INTERFACE, + TKIND_COCLASS +}; + +typedef PRUint16 nsVARTYPE; + +enum nsVARENUM { + VT_EMPTY = 0, // Not specified. + VT_NULL = 1, // Null. + VT_I2 = 2, // 2-byte signed int. + VT_I4 = 3, // 4-byte signed int. + VT_R4 = 4, // 4-byte real. + VT_R8 = 5, // 8-byte real. + VT_ERROR = 6, // status code (scode). + VT_BOOL = 7, // Boolean; + VT_SUPPORT = 8, // nsISupports *. + VT_C1 = 9, // Unsigned char. + VT_C2 = 10, // Unicode char. + VT_STR = 11, // C string. + VT_WSTR = 12, // Unicode string. + VT_VOID = 13, // void *. + // By reference, a pointer to the data is passed. + // Added as extra bit. + VT_BYREF = (int) 0x4000 +}; + +struct nsVARIANT { + nsVARTYPE kind; + union { + unsigned char cVal; + wchar wVal; + char *strVal; + nsSTR wstrVal; + PRInt16 iVal; + PRInt32 lVal; + float fltVal; + double dblVal; + PRBool boolVal; + PRUint16 scode; + nsISupports * suppVal; + void * voidVal; + unsigned char * pcVal; + wchar * pwVal; + nsSTR * pstrVal; + PRInt16 * piVal; + PRInt32 * plVal; + float * pfltVal; + double * pdblVal; + PRBool * pboolVal; + PRUint16 * pscode; + nsISupports ** psuppVal; + void ** pvoidVal; + } u; +}; + +struct nsDISPPARAMS { + nsVARIANT *argv; // Array of arguments. + PRUint32 argc; // Number of arguments. +}; + +struct nsEXCEP { + PRUint16 scode; // An error code describing the error. + nsSTR description; // Textual description of the error. +}; + +struct nsTYPEATTR { + nsIID guid; // The GUID of the type information. + PRUint16 lcid; // Locale of member names and doc + // strings + PRInt32 cbSizeInstance;// The size of an instance of + // this type. + nsTYPEKIND typekind; // The kind of type this information + // describes. + PRUint16 cFuncs; // Number of functions. + PRUint16 cVars; // Number of variables/data members. + PRInt16 cImplTypes; // Number of implemented interfaces. + PRInt16 wTypeFlags; + PRInt16 wMajorVerNum; // Major version number. + PRInt16 wMinorVerNum; // Minor version number. +}; + +enum nsINVOKEKIND { + INVOKE_FUNC=0, + INVOKE_PROPERTYGET=1, + INVOKE_PROPERTYPUT=2 +}; + +enum nsDISPATCHKIND { + DISPATCH_FUNC=0, + DISPATCH_PROPERTYGET=1, + DISPATCH_PROPERTYPUT=2 +}; + +enum nsFUNCKIND { + FUNC_VIRTUAL, + FUNC_STATIC +}; + +struct nsFUNCDESC { + nsDISPID dispid; // Function dispatch ID. + nsVARTYPE *paramDesc; /* tags for parameters */ + nsFUNCKIND funckind; // Specifies whether the function is virtual or static + nsINVOKEKIND invkind; // Invocation kind. Indicates if this is a // property function, and if so, what kind. + PRUint32 cParams; // Count of total number of parameters. + nsVARTYPE retDesc; // Contains the return type of the function. +}; + +enum nsVARKIND { + VAR_INSTANCE, + VAR_STATIC +}; + +struct nsVARDESC { + nsDISPID dispid; + nsVARTYPE varType; + nsVARKIND varkind; +}; + +class nsITypeInfo; +class nsITypeLib; + +#endif diff --git a/xpcom/public/nsTypeLib.h b/xpcom/public/nsTypeLib.h new file mode 100644 index 000000000000..b7ab27eb4089 --- /dev/null +++ b/xpcom/public/nsTypeLib.h @@ -0,0 +1,34 @@ +#include "nsITypeLib.h" +#include "nsITypeInfo.h" + +class nsTypeLib : public nsITypeLib { +protected: + nsITypeInfo **ti; + nsTYPEKIND *kind; + nsTLIBATTR libattr; + PRUint32 ti_count; + NS_DECL_ISUPPORTS_EXPORTED +public: + NS_EXPORT NS_IMETHODIMP GetTypeInfoCount(PRInt32 *count); + + NS_EXPORT NS_IMETHODIMP GetTypeInfo( + PRUint32 index, + nsITypeInfo **ppTInfo); + + NS_EXPORT NS_IMETHODIMP GetTypeInfoType( + PRUint32 index, + nsTYPEKIND *pTKind); + + NS_EXPORT NS_IMETHODIMP GetTypeInfoOfGuid( + REFNSIID guid, + nsITypeInfo **ppTinfo); + + NS_EXPORT NS_IMETHODIMP GetLibAttr( + nsTLIBATTR **ppTLibAttr); + + NS_EXPORT NS_IMETHODIMP_(void) ReleaseLibAttr( + nsTLIBATTR *pTLibAttr); + + NS_EXPORT nsTypeLib(PRUint32 count); + NS_EXPORT ~nsTypeLib(); +}; diff --git a/xpcom/src/nsTypeInfo.cpp b/xpcom/src/nsTypeInfo.cpp new file mode 100644 index 000000000000..01058b05bb97 --- /dev/null +++ b/xpcom/src/nsTypeInfo.cpp @@ -0,0 +1,214 @@ +#include "nsTypeInfo.h" + +NS_DEFINE_IID(typeInfoIID, NS_TYPEINFO_IID); +NS_DEFINE_IID(nsSupportsIID, NS_ISUPPORTS_IID); + +NS_IMPL_ADDREF(nsTypeInfo); +NS_IMPL_RELEASE(nsTypeInfo); + +nsresult nsTypeInfo::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + *aInstancePtr = NULL; + if (aIID.Equals(typeInfoIID)) { + *aInstancePtr = (void*)(nsITypeInfo*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(nsSupportsIID)) { + *aInstancePtr = (void*) ((nsISupports*)this); + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +nsTypeInfo::nsTypeInfo(nsITypeLib* l, PRUint32 nfuns, PRUint32 nvars) +{ + NS_INIT_REFCNT(); + lib = l; + lib->AddRef(); + fnames = new nsSTR[nfuns]; + fdesc = new nsFUNCDESC[nfuns]; + paramdesc = new nsVARTYPE*[nfuns]; + vnames = new nsSTR[nvars]; + vdesc = new nsVARDESC[nvars]; +} + +nsTypeInfo::~nsTypeInfo() +{ + if (lib) + lib->Release(); + delete vdesc; + delete vnames; + delete paramdesc; + delete fdesc; + delete fnames; +} + +nsresult nsTypeInfo::GetTypeAttr( + nsTYPEATTR **ppTypeAttr) +{ + *ppTypeAttr = &tattr; + return NS_OK; +} + +nsresult nsTypeInfo::GetFuncDesc( + PRUint32 index, + nsFUNCDESC **ppFuncDesc) +{ + if (index >= tattr.cFuncs) + return NS_NOSUCH_INDEX; + *ppFuncDesc = &fdesc[index]; + return NS_OK; +} + +nsresult nsTypeInfo::GetVarDesc( + PRUint32 index, + nsVARDESC **ppVarDesc) +{ + if (index >= tattr.cFuncs) + return NS_NOSUCH_INDEX; + *ppVarDesc = &vdesc[index]; + return NS_OK; +} + +nsresult nsTypeInfo::GetNames( + nsDISPID memid, + nsSTR *rgBstrNames, + PRUint32 cMaxNames, + PRUint32 *pcNames) +{ + PRUint32 i; + if (memid < tattr.cFuncs) { + for (i=0; i (tattr.cFuncs + tattr.cVars)) + return NS_NOSUCH_INDEX; + switch (dispKind) { + case DISPATCH_FUNC: + if (pDispParams->argc != fdesc[memid].cParams) + return NS_ARGUMENT_MISMATCH; + for (i=0; iargc; i++) + if (pDispParams->argv[i].kind != fdesc[memid].paramDesc[i]) { + *puArgErr = i; + return NS_TYPE_MISMATCH; + } + return NS_OK; + case DISPATCH_PROPERTYGET: + if (pDispParams->argc != 1) + return NS_ARGUMENT_MISMATCH; + if ((pDispParams->argv[0].kind & VT_BYREF) == 0) { + *puArgErr = 0; + return NS_TYPE_MISMATCH; + } + if ((pDispParams->argv[0].kind & ~VT_BYREF) != vdesc[memid-tattr.cFuncs].varType) { + *puArgErr = 0; + return NS_TYPE_MISMATCH; + } + return NS_OK; + case DISPATCH_PROPERTYPUT: + if (pDispParams->argc != 1) + return NS_ARGUMENT_MISMATCH; + if (pDispParams->argv[0].kind == vdesc[memid-tattr.cFuncs].varType) { + *puArgErr = 0; + return NS_TYPE_MISMATCH; + } + return NS_OK; + default: + return NS_DISPATCH_MISMATCH; + } +} + +nsresult nsTypeInfo::AddressOfMember( + nsDISPID memid, + nsINVOKEKIND invKind, + void **ppv) +{ + return NS_COMFALSE; // no static members +} + +nsresult nsTypeInfo::CheckInstance( + nsISupports *nsi, + REFNSIID riid, + void **ppvObj) +{ + if (nsi == NULL) { + return NS_COMFALSE; + } + nsresult res = nsi->QueryInterface(riid, ppvObj); + if (NS_FAILED(res)) { + *ppvObj = NULL; + delete nsi; + } + return res; +} + +nsresult nsTypeInfo::GetContainingTypeLib( + nsITypeLib **ppTLib, + PRUint32 *pIndex) +{ + *ppTLib = lib; + pIndex = 0; + return NS_OK; +} + +void nsTypeInfo::ReleaseTypeAttr(nsTYPEATTR *pTypeAttr) +{ + +} + +void nsTypeInfo::ReleaseFuncDesc(nsFUNCDESC *pFuncDesc) +{ + +} + +void nsTypeInfo::ReleaseVarDesc(nsVARDESC *pVarDesc) +{ + +} diff --git a/xpcom/src/nsTypeLib.cpp b/xpcom/src/nsTypeLib.cpp new file mode 100644 index 000000000000..f7c3f7580390 --- /dev/null +++ b/xpcom/src/nsTypeLib.cpp @@ -0,0 +1,93 @@ +#include "nsTypeLib.h" +#include "nsTypeInfo.h" + +NS_DEFINE_IID(typeLibIID, NS_TYPELIB_IID); +NS_DEFINE_IID(typeInfIID, NS_TYPEINFO_IID); +NS_DEFINE_IID(nsSupportsIID, NS_ISUPPORTS_IID); + +NS_IMPL_ADDREF(nsTypeLib); +NS_IMPL_RELEASE(nsTypeLib); + +nsresult nsTypeLib::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + *aInstancePtr = NULL; + if (aIID.Equals(typeLibIID)) { + *aInstancePtr = (void*)(nsITypeLib*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(nsSupportsIID)) { + *aInstancePtr = (void*) ((nsISupports*)this); + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +nsTypeLib::nsTypeLib(PRUint32 count) : ti_count(count) +{ + NS_INIT_REFCNT(); + ti = new nsITypeInfo*[ti_count]; + kind = new nsTYPEKIND[ti_count]; + for (PRUint32 i=0; iRelease(); + else // class + delete ti[i]; + } + delete kind; + delete ti; +} + +nsresult nsTypeLib::GetTypeInfoCount(PRInt32 *_count) +{ + *_count = ti_count; + return NS_OK; +} + +nsresult nsTypeLib::GetTypeInfo(PRUint32 index, nsITypeInfo **ppTInfo) +{ + if (index >= ti_count) + return NS_NOSUCH_INDEX; + *ppTInfo = ti[index]; + ti[index]->AddRef(); + return NS_OK; +} + +nsresult nsTypeLib::GetTypeInfoType(PRUint32 index, nsTYPEKIND *pTKind) +{ + if (index >= ti_count) + return NS_NOSUCH_INDEX; + *pTKind = kind[index]; + return NS_OK; +} + +nsresult nsTypeLib::GetTypeInfoOfGuid(REFNSIID guid, nsITypeInfo **ppTinfo) +{ + for (PRUint32 i=0; iQueryInterface(guid,(void**)ppTinfo) == NS_OK) + return NS_OK; + *ppTinfo = NULL; + return NS_NOSUCH_ID; +} + +nsresult nsTypeLib::GetLibAttr(nsTLIBATTR **ppTLibAttr) +{ + *ppTLibAttr = &libattr; + return NS_OK; +} + +void nsTypeLib::ReleaseLibAttr(nsTLIBATTR *pTLibAttr) +{ + +} diff --git a/xpcom/tests/typeinfo/main.cpp b/xpcom/tests/typeinfo/main.cpp new file mode 100644 index 000000000000..10f53be77c43 --- /dev/null +++ b/xpcom/tests/typeinfo/main.cpp @@ -0,0 +1,125 @@ +#include "testTypeLib.h" +#include "testTypeInfo.h" +#include "test.h" +#include + +/* + * main for testing typeinfo and typelibs. + */ + +int main(int argc, char *argv[]) +{ + nsIID myLib = MY_TYPELIB_IID; + nsIID myTypeInf = MY_TYPEINFO_IID; + nsIID myTest = MY_TEST_IID; + nsITypeLib* lib1; + nsITypeInfo* info1; + void *inst; + nsresult nr; + nsSTR nfoo = L"foo"; + nsSTR nx = L"x"; + nsDISPID id; + nsDISPPARAMS params; + nsVARIANT args[2]; + nsVARIANT res; + nsEXCEP excep; + PRInt32 argerr = -1; + + nr = GetTypeLib(myLib, &lib1); + if (nr != NS_OK) + return -1; + nr = lib1->GetTypeInfoOfGuid(myTypeInf, &info1); + if (nr != NS_OK) { + lib1->Release(); + return -1; + } + nr = info1->CreateInstance(NULL,myTest,&inst); + if (nr != NS_OK) { + lib1->Release(); + return -1; + } + nr = info1->GetIDOfName(nfoo,&id); + if (nr != NS_OK) { + lib1->Release(); + return -1; + } + args[0].kind = VT_I4; + args[0].u.lVal = 42; + args[1].kind = VT_WSTR; + args[1].u.wstrVal = L"Kaviar"; + params.argv = (nsVARIANT*)&args; + params.argc = 2; + excep.scode = 0; // 0=no error + nr = info1->Invoke(inst, id, DISPATCH_FUNC, ¶ms, &res, &excep, &argerr); + if (nr != NS_OK) { + info1->Release(); + lib1->Release(); + return -1; + } + if ((res.kind & VT_BYREF) != 0) { + printf("By reference:\n"); + res.u.dblVal = *(double*)res.u.voidVal; + res.kind &= ~VT_BYREF; + } + switch (res.kind) { + case VT_EMPTY: + printf("no result!\n"); + break; + case VT_NULL: + printf("NULL result!\n"); + break; + case VT_I2: + printf("short result: %d!\n", res.u.iVal); + break; + case VT_I4: + printf("long result: %d!\n", res.u.lVal); + break; + case VT_R4: + printf("float result: %e!\n", res.u.fltVal); + break; + case VT_R8: + printf("double result: %e!\n", res.u.dblVal); + break; + case VT_ERROR: + printf("error result: %d!\n", res.u.scode); + break; + case VT_BOOL: + printf("boolean result: %d!\n", res.u.boolVal); + break; + case VT_SUPPORT: + printf("ISupports result: %x!\n", res.u.suppVal); + break; + case VT_STR: + printf("string result: %s!\n", res.u.strVal); + break; + case VT_WSTR: + printf("string result: %ws!\n", res.u.wstrVal); + break; + case VT_VOID: + printf("void * result: %x!\n", res.u.voidVal); + break; + case VT_C1: + printf("character result: %d!\n", res.u.cVal); + break; + case VT_C2: + printf("character result: %d!\n", res.u.wVal); + break; + default: + printf("HUH!?\n"); + } + PRInt32 x; + args[0].kind = VT_I4 | VT_BYREF; + args[0].u.plVal = &x; + params.argv = (nsVARIANT*)&args; + params.argc = 1; + nr = info1->GetIDOfName(nx,&id); + if (nr != NS_OK) { + lib1->Release(); + return -1; + } + nr = info1->Invoke(inst, id, DISPATCH_PROPERTYGET, ¶ms, &res, &excep, &argerr); + printf("x was set to: %d\n",x); + info1->Release(); + lib1->Release(); + return 0; +} diff --git a/xpcom/tests/typeinfo/test.cpp b/xpcom/tests/typeinfo/test.cpp new file mode 100644 index 000000000000..e545751e07a3 --- /dev/null +++ b/xpcom/tests/typeinfo/test.cpp @@ -0,0 +1,34 @@ +#include "test.h" +#include + +NS_DEFINE_IID(testIID, MY_TEST_IID); + +NS_IMPL_ISUPPORTS(testC, testIID); + +testC::testC() : msg(L"TEST:"), x(99) +{ + NS_INIT_REFCNT(); +} + +nsresult testC::foo(PRInt32 i, nsSTR s) +{ + printf("%ws %ws %d %ws\n", msg, s, i, s); + return NS_OK; +} + +nsresult testC::get_x(PRInt32 *_x) +{ + *_x = x; + return NS_OK; +} + +nsresult testC::set_x(PRInt32 _x) +{ + x = _x; + return NS_OK; +} + +testI* CreateTestI() +{ + return new testC(); +} diff --git a/xpcom/tests/typeinfo/test.h b/xpcom/tests/typeinfo/test.h new file mode 100644 index 000000000000..9766fc2302da --- /dev/null +++ b/xpcom/tests/typeinfo/test.h @@ -0,0 +1,25 @@ +#include "nsITypeInfo.h" + +// {3959EF90-77FC-11d2-ABAD-00805F6177CE} +#define MY_TEST_IID { 0x3959ef90, 0x77fc, 0x11d2, { 0xab, 0xad, 0x0, 0x80, 0x5f, 0x61, 0x77, 0xce } } + +class testI : public nsISupports { +public: + NS_IMETHOD foo(PRInt32 i, nsSTR s) = 0; + NS_IMETHOD get_x(PRInt32 *_x) = 0; + NS_IMETHOD set_x(PRInt32 i) = 0; +}; + +class testC : public testI { + nsSTR msg; + PRInt32 x; + NS_DECL_ISUPPORTS +public: + NS_EXPORT NS_IMETHODIMP foo(PRInt32 i, nsSTR s); + NS_EXPORT NS_IMETHODIMP get_x(PRInt32 *_x); + NS_EXPORT NS_IMETHODIMP set_x(PRInt32 i); + NS_EXPORT testC(); +}; + + +extern "C" NS_EXPORT testI* CreateTestI(); diff --git a/xpcom/tests/typeinfo/testTypeInfo.cpp b/xpcom/tests/typeinfo/testTypeInfo.cpp new file mode 100644 index 000000000000..1f194a937dd3 --- /dev/null +++ b/xpcom/tests/typeinfo/testTypeInfo.cpp @@ -0,0 +1,124 @@ +#include "testTypeInfo.h" +#include "test.h" + +// this file will be generated by the IDL compiler + +NS_DEFINE_IID(myTypeInfoIID, MY_TYPEINFO_IID); + +nsresult testTypeInfo::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (nsTypeInfo::QueryInterface(aIID, aInstancePtr) == NS_OK) + return NS_OK; + if (aIID.Equals(myTypeInfoIID)) { + *aInstancePtr = (void*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +testTypeInfo::testTypeInfo(nsITypeLib* l) : nsTypeInfo(l,1,1) +{ + tattr.guid = myTypeInfoIID; + tattr.lcid = -1; // niu + tattr.cbSizeInstance = sizeof(testI); + tattr.typekind = TKIND_INTERFACE; + tattr.cFuncs = 1; // foo + tattr.cVars = 1; // x + tattr.cImplTypes = 1; + tattr.wTypeFlags = -1; // niu + tattr.wMajorVerNum = 1; + tattr.wMinorVerNum = -1; // niu + fnames[0] = L"foo"; + fdesc[0].dispid = 0; // foo + paramdesc[0] = new nsVARTYPE[2]; + paramdesc[0][0] = VT_I4; + paramdesc[0][1] = VT_WSTR; + fdesc[0].paramDesc = paramdesc[0]; + fdesc[0].invkind = INVOKE_FUNC; + fdesc[0].cParams = 2; + fdesc[0].retDesc = VT_I4; + fdesc[0].dispid = 0; + vnames[0] = L"x"; + vdesc[0].varType = VT_I4; + vdesc[0].dispid = tattr.cFuncs; // next is 1+ and so on. +} + +testTypeInfo::~testTypeInfo() +{ + delete paramdesc[0]; +} + +nsresult testTypeInfo::Invoke( + void *pvInstance, + nsDISPID memid, + nsDISPATCHKIND dispKind, + nsDISPPARAMS *pDispParams, + nsVARIANT *pVarResult, + nsEXCEP *pExcepInfo, + PRInt32 *puArgErr) +{ + PRInt32 res; + testI* ti = (testI*)pvInstance; + PRInt32 v, *vp; + nsresult nr; + + if ((nr = InvokeCheck(memid, dispKind, pDispParams, puArgErr)) != NS_OK) + return nr; + switch (dispKind) { + case DISPATCH_FUNC: + nsSTR s; + switch (memid) { + case 0: // foo + v = pDispParams->argv[0].u.lVal; + s = pDispParams->argv[1].u.wstrVal; + res = ti->foo(v,s); // ignore exception for now + if (pVarResult != NULL) { + pVarResult->kind = fdesc[0].retDesc; + pVarResult->u.lVal = res; + } + return NS_OK; + default: + return NS_NOSUCH_INDEX; + } + case DISPATCH_PROPERTYGET: + switch (memid-tattr.cVars) { + case 0: // x + vp = pDispParams->argv[0].u.plVal; + res = ti->get_x(vp); + if (pVarResult != NULL) { + pVarResult->kind = fdesc[0].retDesc; + pVarResult->u.lVal = res; + } + return NS_OK; + default: + return NS_NOSUCH_INDEX; + } + case DISPATCH_PROPERTYPUT: + switch (memid-tattr.cVars) { + case 0: // x + v = pDispParams->argv[0].u.lVal; + res = ti->set_x(v); + if (pVarResult != NULL) { + pVarResult->kind = fdesc[0].retDesc; + pVarResult->u.lVal = res; + } + return NS_OK; + default: + return NS_NOSUCH_INDEX; + } + default: + return NS_DISPATCH_MISMATCH; + } +} + +nsresult testTypeInfo::CreateInstance( + nsISupports *delegate, + REFNSIID riid, + void **ppvObj) +{ + if (delegate != NULL) { + return NS_ERROR_NO_AGGREGATION; + } + return CheckInstance(CreateTestI(),riid,ppvObj); +} diff --git a/xpcom/tests/typeinfo/testTypeInfo.h b/xpcom/tests/typeinfo/testTypeInfo.h new file mode 100644 index 000000000000..79e66600c2b1 --- /dev/null +++ b/xpcom/tests/typeinfo/testTypeInfo.h @@ -0,0 +1,28 @@ +#include "nsTypeInfo.h" + +// this file will be generated by the IDL compiler + +// {5F274240-7770-11d2-ABAD-00805F6177CE} +#define MY_TYPEINFO_IID { 0x5f274240, 0x7770, 0x11d2, { 0xab, 0xad, 0x0, 0x80, 0x5f, 0x61, 0x77, 0xce } } + +class testTypeInfo : public nsTypeInfo { +public: + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); + + NS_IMETHODIMP Invoke( + void *pvInstance, + nsDISPID memid, + nsDISPATCHKIND dispKind, + nsDISPPARAMS *pDispParams, + nsVARIANT *pVarResult, + nsEXCEP *pExcepInfo, + PRInt32 *puArgErr); + + NS_IMETHODIMP CreateInstance( + nsISupports *delegate, + REFNSIID riid, + void **ppvObj); + + testTypeInfo(nsITypeLib *l); + ~testTypeInfo(); +}; diff --git a/xpcom/tests/typeinfo/testTypeLib.cpp b/xpcom/tests/typeinfo/testTypeLib.cpp new file mode 100644 index 000000000000..112eab6ba57a --- /dev/null +++ b/xpcom/tests/typeinfo/testTypeLib.cpp @@ -0,0 +1,45 @@ +#include "testTypeLib.h" +#include "testTypeInfo.h" + +// this file will be generated by the IDL compiler + +NS_DEFINE_IID(myLibIID, MY_TYPELIB_IID); +NS_DEFINE_IID(typeLibIID, NS_TYPELIB_IID); +NS_DEFINE_IID(typeInfIID, NS_TYPEINFO_IID); + +nsresult testTypeLib::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (nsTypeLib::QueryInterface(aIID, aInstancePtr) == NS_OK) + return NS_OK; + if (aIID.Equals(myLibIID)) { + *aInstancePtr = (void*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +testTypeLib::testTypeLib() : nsTypeLib(1) +{ + testTypeInfo* tst = new testTypeInfo(this); + if (tst->QueryInterface(typeInfIID,(void**)&ti[0]) != NS_OK) + ti[0] = NULL; + else + kind[0] = TKIND_INTERFACE; + libattr.guid = myLibIID; + libattr.lcid = -1; // niu (not in use) + libattr.syskind = SYS_WIN32; + libattr.wMajorVerNum = 1; + libattr.wMinorVerNum = -1; // niu + libattr.wLibFlags = -1; // niu +} + +// this should be kept elsewhere +testTypeLib* testTypeLib::tlib = NULL; + +nsresult GetTypeLib(REFNSIID libid, nsITypeLib** lib) +{ + if (testTypeLib::tlib == NULL) + testTypeLib::tlib = new testTypeLib(); + return testTypeLib::tlib->QueryInterface(typeLibIID, (void**)lib); +} diff --git a/xpcom/tests/typeinfo/testTypeLib.h b/xpcom/tests/typeinfo/testTypeLib.h new file mode 100644 index 000000000000..482afdaecdc8 --- /dev/null +++ b/xpcom/tests/typeinfo/testTypeLib.h @@ -0,0 +1,16 @@ +#include "nsTypeLib.h" + +// this file will be generated by the IDL compiler + +// {12061210-7769-11d2-ABAD-00805F6177CE} +#define MY_TYPELIB_IID { 0x12061210, 0x7769, 0x11d2, { 0xab, 0xad, 0x0, 0x80, 0x5f, 0x61, 0x77, 0xce } } + +class testTypeLib : public nsTypeLib { +public: + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); + static testTypeLib* tlib; + testTypeLib(); +}; + +extern "C" NS_EXPORT nsresult GetTypeLib(REFNSIID libid, nsITypeLib** lib); +