ECode CInterfaceInfo::CreateIFList() { if (mIFList) { return NOERROR; } UInt32* indexList = (UInt32 *)alloca( mClsMod->mInterfaceCount * sizeof(UInt32)); if (indexList == NULL) { return E_OUT_OF_MEMORY; } Int32 i, j = 0; mIFCount = 0; UInt32 index = mIndex; InterfaceDirEntry* ifDir = NULL; while (index != 0) { indexList[mIFCount++] = index; ifDir = getInterfaceDirAddr(mBase, mClsMod->mInterfaceDirs, index); index = adjustInterfaceDescAddr(mBase, ifDir->mDesc)->mParentIndex; } indexList[mIFCount] = 0; mIFCount++; UInt32 beginNo = METHOD_START_NO; mIFList = new IFIndexEntry[mIFCount]; if (mIFList == NULL) { return E_OUT_OF_MEMORY; } for (i = mIFCount - 1, j = 0; i >= 0; i--, j++) { index = indexList[i]; mIFList[j].mIndex = index; mIFList[j].mBeginNo = beginNo; ifDir = getInterfaceDirAddr(mBase, mClsMod->mInterfaceDirs, index); mIFList[j].mName = adjustNameAddr(mBase, ifDir->mName); mIFList[j].mNameSpace = adjustNameAddr(mBase, ifDir->mNameSpace); mIFList[j].mDesc = adjustInterfaceDescAddr(mBase, ifDir->mDesc); beginNo += mIFList[j].mDesc->mMethodCount; } mMethodCount = 0; for (i = 0; i < (int)mIFCount; i++) { mMethodCount += mIFList[i].mDesc->mMethodCount; } return NOERROR; }
ELAPI _CObject_ReflectInterfaceInfo( /* [in] */ PInterface object, /* [out] */ IInterfaceInfo** interfaceInfo) { if (!object || !interfaceInfo) { return E_INVALID_ARGUMENT; } EIID iid; ECode ec = object->GetInterfaceID(object, &iid); if (FAILED(ec)) return E_INVALID_ARGUMENT; IObject* iObject = (IObject*)object->Probe(EIID_IObject); if (iObject == NULL) return E_NO_INTERFACE; ClassID clsid; ec = iObject->GetClassID(&clsid); if (FAILED(ec)) return E_INVALID_ARGUMENT; AutoPtr<IModuleInfo> obj; ec = _CReflector_AcquireModuleInfo(String(clsid.mUunm), (IModuleInfo**)&obj); if (FAILED(ec)) { return ec; } CModuleInfo* moduleInfo = (CModuleInfo*)obj.Get(); ClassDirEntry* classDir = NULL; ClassDescriptor* clsDesc = NULL; ClassInterface* cifDir = NULL; InterfaceDirEntry* ifDir = NULL; InterfaceDescriptor* ifDesc = NULL; UInt16 index = 0; Int32 base = moduleInfo->mClsModule->mBase; *interfaceInfo = NULL; for (Int32 i = 0; i < moduleInfo->mClsMod->mClassCount; i++) { classDir = getClassDirAddr(base, moduleInfo->mClsMod->mClassDirs, i); clsDesc = adjustClassDescAddr(base, classDir->mDesc); //find the class if (clsDesc->mClsid == clsid.mClsid) { for (Int32 j = 0; j < clsDesc->mInterfaceCount; j++) { cifDir = getCIFAddr(base, clsDesc->mInterfaces, j); index = cifDir->mIndex; ifDir = getInterfaceDirAddr(base, moduleInfo->mClsMod->mInterfaceDirs, index); ifDesc = adjustInterfaceDescAddr(base, ifDir->mDesc); //find the interface if (ifDesc->mIID == iid) { ec = g_objInfoList.AcquireInterfaceInfo( moduleInfo->mClsModule, index, (IInterface **)interfaceInfo); return ec; } } } } return E_DOES_NOT_EXIST; }
ECode CClassInfo::CreateObjInRgm( /* [in] */ PRegime rgm, /* [out] */ PInterface* object) { Int32 index = getCIFAddr(mBase, mDesc->ppInterfaces, 0)->mIndex; InterfaceDirEntry* ifDir = getInterfaceDirAddr(mBase, mClsMod->mInterfaceDirs, index); EIID iid = adjustInterfaceDescAddr(mBase, ifDir->mDesc)->iid; return _CObject_CreateInstance(mClsId, rgm, iid, object); }
CInterfaceInfo::CInterfaceInfo( /* [in] */ CClsModule* clsModule, /* [in] */ UInt32 index) { mClsModule = clsModule; mClsMod = mClsModule->mClsMod; mBase = mClsModule->mBase; mInterfaceDirEntry = getInterfaceDirAddr(mBase, mClsMod->mInterfaceDirs, index); mDesc = adjustInterfaceDescAddr(mBase, mInterfaceDirEntry->mDesc); mIndex = index; mIFList = NULL; }
ECode CObjInfoList::AcquireInterfaceInfo( /* [in] */ CClsModule* clsModule, /* [in] */ UInt32 index, /* [in, out] */ IInterface** object) { if (!clsModule || !object) { return E_INVALID_ARGUMENT; } LockHashTable(EntryType_Interface); if (*object) { UnlockHashTable(EntryType_Interface); return NOERROR; } InterfaceDirEntry* ifDir = getInterfaceDirAddr(clsModule->mBase, clsModule->mClsMod->mInterfaceDirs, index); EIID iid = adjustInterfaceDescAddr(clsModule->mBase, ifDir->mDesc)->mIID; IInterface** obj = mIFInfos.Get(&iid); if (!obj) { IInterface *interfaceObj = NULL; AutoPtr<CInterfaceInfo> ifInfoObj = new CInterfaceInfo(clsModule, index); if (ifInfoObj == NULL) { UnlockHashTable(EntryType_Interface); return E_OUT_OF_MEMORY; } ECode ec = ifInfoObj->Init(); if (FAILED(ec)) { UnlockHashTable(EntryType_Interface); return ec; } interfaceObj = (IInterface*)ifInfoObj.Get(); if (!mIFInfos.Put(&iid, (IInterface**)&interfaceObj)) { UnlockHashTable(EntryType_Interface); return E_OUT_OF_MEMORY; } *object = interfaceObj; (*object)->AddRef(); } else { *object = *obj; (*object)->AddRef(); } UnlockHashTable(EntryType_Interface); return NOERROR; }
ECode CClassInfo::CreateIFList() { if (mIFList) { return NOERROR; } UInt32* indexList = (UInt32 *)alloca(mClsMod->mInterfaceCount * sizeof(UInt32)); if (indexList == NULL) { return E_OUT_OF_MEMORY; } IFIndexEntry* allIFList = (IFIndexEntry *) alloca(mClsMod->mInterfaceCount * sizeof(IFIndexEntry)); if (allIFList == NULL) { return E_OUT_OF_MEMORY; } Int32 i, j, k, n = 0, iNo, listCount = 0; UInt32 index = 0, eventNum = 1, beginNo = METHOD_START_NO; Boolean isCallBack = FALSE; mIFCount = 0; mCBIFCount = 0; ClassInterface* cifDir = NULL; InterfaceDirEntry* ifDir = NULL; for (i = 0; i < mDesc->mInterfaceCount; i++) { cifDir = getCIFAddr(mBase, mDesc->ppInterfaces, i); if (cifDir->wAttribs & ClassInterfaceAttrib_callback) { isCallBack = TRUE; } else { isCallBack = FALSE; } index = cifDir->mIndex; iNo = 0; while (index != 0) { indexList[iNo++] = index; ifDir = getInterfaceDirAddr(mBase, mClsMod->mInterfaceDirs, index); index = adjustInterfaceDescAddr(mBase, ifDir->mDesc)->sParentIndex; } indexList[iNo] = 0; //Save the indexList to mIFList for (j = iNo; j >= 0; j--) { index = indexList[j]; if (listCount != 0) { //If the same inteface in list, continue for (k = 0; k < listCount; k++) { if (allIFList[k].mIndex == index) { beginNo = allIFList[k].mBeginNo + allIFList[k].mDesc->cMethods; if (!isCallBack) { if (!(allIFList[k].mAttribs & IFAttrib_normal)) { mIFCount++; allIFList[k].mAttribs |= IFAttrib_normal; } } else { if (!(allIFList[k].mAttribs & IFAttrib_callback)) { mCBIFCount++; allIFList[k].mAttribs |= IFAttrib_callback; } } break; } } if (k < listCount) { continue; } } allIFList[listCount].mIndex = index; allIFList[listCount].mBeginNo = beginNo; ifDir = getInterfaceDirAddr(mBase, mClsMod->mInterfaceDirs, index); allIFList[listCount].mName = adjustNameAddr(mBase, ifDir->mName); allIFList[listCount].mNameSpace = adjustNameAddr(mBase, ifDir->mNameSpace); allIFList[listCount].mDesc = adjustInterfaceDescAddr(mBase, ifDir->mDesc); if (!isCallBack) { mIFCount++; allIFList[listCount].mAttribs = IFAttrib_normal; } else { mCBIFCount++; allIFList[listCount].mAttribs = IFAttrib_callback; } beginNo += allIFList[listCount].mDesc->cMethods; listCount++; } } mIFList = new IFIndexEntry[mIFCount]; if (!mIFList) goto EExit; if (mCBIFCount) { mCBIFCount--; mCBIFList = new IFIndexEntry[mCBIFCount]; if (!mCBIFList) goto EExit; } mMethodCount = 0; mCBMethodCount = 0; j = 0; k = 0; for (i = 0; i < listCount; i++) { if (allIFList[i].mAttribs & IFAttrib_normal) { memcpy(&mIFList[j], &allIFList[i], sizeof(IFIndexEntry)); mMethodCount += allIFList[i].mDesc->cMethods; j++; } if (i && mCBIFCount && (allIFList[i].mAttribs & IFAttrib_callback)) { memcpy(&mCBIFList[k], &allIFList[i], sizeof(IFIndexEntry)); mCBMethodCount += allIFList[i].mDesc->cMethods; k++; } } //Set Callback Method Info mCBMethodDesc = new CBMethodDesc[mCBMethodCount]; if (!mCBMethodDesc) goto EExit; memset(mCBMethodDesc, 0, mCBMethodCount * sizeof(CBMethodDesc)); for (i = 0; i < k; i++) { for (j = 0; j < mCBIFList[i].mDesc->cMethods; j++) { mCBMethodDesc[n].mDesc = getMethodDescAddr(mBase, mCBIFList[i].mDesc->ppMethods, j); mCBMethodDesc[n].mIndex = MK_METHOD_INDEX(mCBIFList[i].mIndex, mCBIFList[i].mBeginNo + j); mCBMethodDesc[n].mEventNum = eventNum; eventNum++; n++; } eventNum += 2; } return NOERROR; EExit: mIFCount = 0; mCBIFCount = 0; mMethodCount = 0; mCBMethodCount = 0; if (mIFList) { delete [] mIFList; mIFList = NULL; } if (mCBIFList) { delete [] mCBIFList; mCBIFList = NULL; } if (mCBMethodDesc) { delete [] mCBMethodDesc; mCBMethodDesc = NULL; } return E_OUT_OF_MEMORY; }