diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2004-02-03 11:17:30 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2004-02-03 11:17:30 +0000 |
commit | 24a7d9d62cba4364d07e931c23c725015a71d07e (patch) | |
tree | eaca412307913afa78787fb8a2fe2c24e6da2089 /cppu | |
parent | 11108cb7cb509c1fe17ab99ba20e861409270bf9 (diff) |
INTEGRATION: CWS sb10 (1.19.16); FILE MERGED
2004/01/21 09:29:36 sb 1.19.16.4: #114000# Take care of absolutely incomplete interface type descriptions, where even nMembers and nAllMembers is not yet set.
2004/01/19 09:26:42 sb 1.19.16.3: #114000# Added missing calls to typelib_typedescription_complete.
2004/01/13 14:15:41 sb 1.19.16.2: RESYNC: (1.19-1.20); FILE MERGED
2003/12/10 08:52:19 sb 1.19.16.1: #114000# Adapted to multiple-inheritance interface types.
Diffstat (limited to 'cppu')
-rw-r--r-- | cppu/source/typelib/typelib.cxx | 636 |
1 files changed, 473 insertions, 163 deletions
diff --git a/cppu/source/typelib/typelib.cxx b/cppu/source/typelib/typelib.cxx index 112b7a951..6a3a98c8d 100644 --- a/cppu/source/typelib/typelib.cxx +++ b/cppu/source/typelib/typelib.cxx @@ -2,9 +2,9 @@ * * $RCSfile: typelib.cxx,v $ * - * $Revision: 1.20 $ + * $Revision: 1.21 $ * - * last change: $Author: vg $ $Date: 2003-12-17 20:23:56 $ + * last change: $Author: hr $ $Date: 2004-02-03 12:17:29 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -61,6 +61,8 @@ #include <hash_map> #include <list> +#include <set> +#include <vector> #include <stdarg.h> #include <stdlib.h> @@ -541,6 +543,108 @@ static inline void typelib_typedescription_initTables( } } +namespace { + +// In some situations (notably typelib_typedescription_newInterfaceMethod and +// typelib_typedescription_newInterfaceAttribute), only the members nMembers, +// ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type +// description are necessary, but not the additional +// pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and +// pMapFunctionIndexToMemberIndex (which are computed by +// typelib_typedescription_initTables). Furthermore, in those situations, it +// might be illegal to compute those tables, as the creation of the interface +// member type descriptions would recursively require a complete interface type +// description. The parameter initTables controls whether or not to call +// typelib_typedescription_initTables in those situations. +bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) { + if (! (*ppTypeDescr)->bComplete) + { + OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass || + typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass || + typelib_TypeClass_UNION == (*ppTypeDescr)->eTypeClass || + typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass || + typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) && + !reallyWeak( (*ppTypeDescr)->eTypeClass ) ); + + if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass && + ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers) + { + if (initTables) { + typelib_typedescription_initTables( *ppTypeDescr ); + } + return true; + } + + typelib_TypeDescription * pTD = 0; + // on demand access of complete td + aInit.callChain( &pTD, (*ppTypeDescr)->pTypeName ); + if (pTD) + { + if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass) + { + typelib_typedescriptionreference_getDescription( + &pTD, ((typelib_IndirectTypeDescription *)pTD)->pType ); + OSL_ASSERT( pTD ); + if (! pTD) + return false; + } + + OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass ); + // typedescription found + // set to on demand + pTD->bOnDemand = sal_True; + + if (pTD->eTypeClass == typelib_TypeClass_INTERFACE + && !pTD->bComplete && initTables) + { + // mandatory info from callback chain + OSL_ASSERT( ((typelib_InterfaceTypeDescription *)pTD)->ppAllMembers ); + // complete except of tables init + typelib_typedescription_initTables( pTD ); + pTD->bComplete = sal_True; + } + + // The type description is hold by the reference until + // on demand is activated. + ::typelib_typedescription_register( &pTD ); // replaces incomplete one + OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one + + // insert into the chache + MutexGuard aGuard( aInit.getMutex() ); + if( !aInit.pCache ) + aInit.pCache = new TypeDescriptionList_Impl; + if( (sal_Int32)aInit.pCache->size() >= nCacheSize ) + { + typelib_typedescription_release( aInit.pCache->front() ); + aInit.pCache->pop_front(); + } + // descriptions in the cache must be acquired! + typelib_typedescription_acquire( pTD ); + aInit.pCache->push_back( pTD ); + + OSL_ASSERT( + pTD->bComplete + || (pTD->eTypeClass == typelib_TypeClass_INTERFACE + && !initTables)); + + ::typelib_typedescription_release( *ppTypeDescr ); + *ppTypeDescr = pTD; + } + else + { +#if OSL_DEBUG_LEVEL > 1 + OString aStr( + OUStringToOString( (*ppTypeDescr)->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "\n### type cannot be completed: %s", aStr.getStr() ); +#endif + return false; + } + } + return true; +} + +} + //------------------------------------------------------------------------ extern "C" void SAL_CALL typelib_typedescription_newEmpty( typelib_TypeDescription ** ppRet, @@ -647,6 +751,8 @@ extern "C" void SAL_CALL typelib_typedescription_newEmpty( pTmp->nMapFunctionIndexToMemberIndex = 0; pTmp->pMapFunctionIndexToMemberIndex = 0; pTmp->pMapMemberIndexToFunctionIndex= 0; + pTmp->nBaseTypes = 0; + pTmp->ppBaseTypes = 0; } break; @@ -663,6 +769,9 @@ extern "C" void SAL_CALL typelib_typedescription_newEmpty( pTmp->pParams = 0; pTmp->nExceptions = 0; pTmp->ppExceptions = 0; + pTmp->pInterface = 0; + pTmp->pBaseRef = 0; + pTmp->nIndex = 0; } break; @@ -675,6 +784,9 @@ extern "C" void SAL_CALL typelib_typedescription_newEmpty( #endif pTmp->aBase.pMemberName = 0; pTmp->pAttributeTypeRef = 0; + pTmp->pInterface = 0; + pTmp->pBaseRef = 0; + pTmp->nIndex = 0; } break; @@ -912,16 +1024,108 @@ extern "C" void SAL_CALL typelib_typedescription_newInterface( typelib_TypeDescriptionReference ** ppMembers ) SAL_THROW_EXTERN_C() { + typelib_typedescription_newMIInterface( + ppRet, pTypeName, nUik1, nUik2, nUik3, nUik4, nUik5, + pBaseInterface == 0 ? 0 : 1, &pBaseInterface, nMembers, ppMembers); +} + +//------------------------------------------------------------------------ + +namespace { + +class BaseList { +public: + struct Entry { + sal_Int32 memberOffset; + sal_Int32 directBaseIndex; + sal_Int32 directBaseMemberOffset; + typelib_InterfaceTypeDescription const * base; + }; + + typedef std::vector< Entry > List; + + BaseList(typelib_InterfaceTypeDescription const * desc); + + List const & getList() const { return list; } + + sal_Int32 getBaseMembers() const { return members; } + +private: + typedef std::set< rtl::OUString > Set; + + void calculate( + sal_Int32 directBaseIndex, Set & directBaseSet, + sal_Int32 * directBaseMembers, + typelib_InterfaceTypeDescription const * desc); + + Set set; + List list; + sal_Int32 members; +}; + +BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) { + members = 0; + for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) { + Set directBaseSet; + sal_Int32 directBaseMembers = 0; + calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]); + } +} + +void BaseList::calculate( + sal_Int32 directBaseIndex, Set & directBaseSet, + sal_Int32 * directBaseMembers, + typelib_InterfaceTypeDescription const * desc) +{ + for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) { + calculate( + directBaseIndex, directBaseSet, directBaseMembers, + desc->ppBaseTypes[i]); + } + if (set.insert(desc->aBase.pTypeName).second) { + Entry e; + e.memberOffset = members; + e.directBaseIndex = directBaseIndex; + e.directBaseMemberOffset = *directBaseMembers; + e.base = desc; + list.push_back(e); + OSL_ASSERT(desc->ppAllMembers != 0); + members += desc->nMembers; + } + if (directBaseSet.insert(desc->aBase.pTypeName).second) { + OSL_ASSERT(desc->ppAllMembers != 0); + *directBaseMembers += desc->nMembers; + } +} + +} + +extern "C" void SAL_CALL typelib_typedescription_newMIInterface( + typelib_InterfaceTypeDescription ** ppRet, + rtl_uString * pTypeName, + sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5, + sal_Int32 nBaseInterfaces, + typelib_TypeDescriptionReference ** ppBaseInterfaces, + sal_Int32 nMembers, + typelib_TypeDescriptionReference ** ppMembers ) + SAL_THROW_EXTERN_C() +{ typelib_InterfaceTypeDescription * pITD = 0; typelib_typedescription_newEmpty( (typelib_TypeDescription **)&pITD, typelib_TypeClass_INTERFACE, pTypeName ); - if( pBaseInterface ) - { - // set the base interface, may be 0 - ::typelib_typedescriptionreference_getDescription( - (typelib_TypeDescription **)&pITD->pBaseTypeDescription, pBaseInterface ); - OSL_ASSERT( pITD->pBaseTypeDescription ); + pITD->nBaseTypes = nBaseInterfaces; + pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces]; + for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) { + pITD->ppBaseTypes[i] = 0; + typelib_typedescriptionreference_getDescription( + reinterpret_cast< typelib_TypeDescription ** >( + &pITD->ppBaseTypes[i]), + ppBaseInterfaces[i]); + OSL_ASSERT(pITD->ppBaseTypes[i] != 0); + } + if (nBaseInterfaces > 0) { + pITD->pBaseTypeDescription = pITD->ppBaseTypes[0]; } // set the pITD->aUik.m_Data1 = nUik1; @@ -930,34 +1134,54 @@ extern "C" void SAL_CALL typelib_typedescription_newInterface( pITD->aUik.m_Data4 = nUik4; pITD->aUik.m_Data5 = nUik5; - sal_Int32 nSuperMembers = pITD->pBaseTypeDescription ? pITD->pBaseTypeDescription->nAllMembers : 0; - pITD->nAllMembers = nMembers + nSuperMembers; + BaseList aBaseList(pITD); + pITD->nAllMembers = nMembers + aBaseList.getBaseMembers(); pITD->nMembers = nMembers; if( pITD->nAllMembers ) { // at minimum one member exist, allocate the memory pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ]; - // the superclass references must not acquired - if( nSuperMembers ) + sal_Int32 n = 0; + + BaseList::List const & rList = aBaseList.getList(); + {for (BaseList::List::const_iterator i(rList.begin()); i != rList.end(); + ++i) { - rtl_moveMemory( pITD->ppAllMembers, pITD->pBaseTypeDescription->ppAllMembers, - nSuperMembers * sizeof( void * ) ); - } + typelib_InterfaceTypeDescription const * pBase = i->base; + typelib_InterfaceTypeDescription const * pDirectBase + = pITD->ppBaseTypes[i->directBaseIndex]; + OSL_ASSERT(pBase->ppAllMembers != 0); + for (sal_Int32 j = 0; j < pBase->nMembers; ++j) { + typelib_TypeDescriptionReference const * pDirectBaseMember + = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j]; + rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName); + aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(":@")); + aBuf.append(i->directBaseIndex); + aBuf.append(static_cast< sal_Unicode >(',')); + aBuf.append(i->memberOffset + j); + aBuf.append(static_cast< sal_Unicode >(':')); + aBuf.append(pITD->aBase.pTypeName); + rtl::OUString aName(aBuf.makeStringAndClear()); + typelib_TypeDescriptionReference * pDerivedMember = 0; + typelib_typedescriptionreference_new( + &pDerivedMember, pDirectBaseMember->eTypeClass, + aName.pData); + pITD->ppAllMembers[n++] = pDerivedMember; + } + }} if( nMembers ) { - pITD->ppMembers = pITD->ppAllMembers + nSuperMembers; + pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers(); } - sal_Int32 n = 0; // add own members - for( sal_Int32 i = nSuperMembers; i < pITD->nAllMembers; i++ ) + {for( sal_Int32 i = 0; i < nMembers; i++ ) { - typelib_typedescriptionreference_acquire( ppMembers[n] ); - pITD->ppAllMembers[i] = ppMembers[n]; - ++n; - } + typelib_typedescriptionreference_acquire( ppMembers[i] ); + pITD->ppAllMembers[n++] = ppMembers[i]; + }} } typelib_TypeDescription * pTmp = (typelib_TypeDescription *)pITD; @@ -986,25 +1210,37 @@ extern "C" void SAL_CALL typelib_typedescription_newInterfaceMethod( rtl_uString ** ppExceptionNames ) SAL_THROW_EXTERN_C() { - typelib_typedescription_newEmpty( - (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName ); - typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet; - + if (*ppRet != 0) { + typelib_typedescription_release(&(*ppRet)->aBase.aBase); + *ppRet = 0; + } sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength( - pTypeName->buffer, pTypeName->length, ':' ); - - if( nOffset == -1 ) - { - // not found - rtl_uString_acquire( (*ppRet)->aBase.pMemberName = pTypeName ); + pTypeName->buffer, pTypeName->length, ':'); + if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') { + OSL_ENSURE(false, "Bad interface method type name"); + return; } - else + rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1); + typelib_InterfaceTypeDescription * pInterface = 0; + typelib_typedescription_getByName( + reinterpret_cast< typelib_TypeDescription ** >(&pInterface), + aInterfaceTypeName.pData); + if (pInterface == 0 + || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE + || !complete( + reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false)) { - rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName, - pTypeName->buffer + nOffset +1, - pTypeName->length - nOffset -1 ); + OSL_ENSURE(false, "No interface corresponding to interface method"); + return; } + typelib_typedescription_newEmpty( + (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName ); + typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet; + + rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName, + pTypeName->buffer + nOffset +1, + pTypeName->length - nOffset -1 ); (*ppRet)->aBase.nPosition = nAbsolutePosition; (*ppRet)->bOneWay = bOneWay; typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName ); @@ -1038,6 +1274,13 @@ extern "C" void SAL_CALL typelib_typedescription_newInterfaceMethod( (*ppRet)->ppExceptions + i, typelib_TypeClass_EXCEPTION, ppExceptionNames[i] ); } } + (*ppRet)->pInterface = pInterface; + (*ppRet)->pBaseRef = 0; + OSL_ASSERT( + (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers) + && nAbsolutePosition < pInterface->nAllMembers); + (*ppRet)->nIndex = nAbsolutePosition + - (pInterface->nAllMembers - pInterface->nMembers); if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) ) pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp; } @@ -1053,29 +1296,47 @@ extern "C" void SAL_CALL typelib_typedescription_newInterfaceAttribute( sal_Bool bReadOnly ) SAL_THROW_EXTERN_C() { - typelib_typedescription_newEmpty( - (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName ); - typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet; - + if (*ppRet != 0) { + typelib_typedescription_release(&(*ppRet)->aBase.aBase); + *ppRet = 0; + } sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength( - pTypeName->buffer, pTypeName->length, ':' ); - - if( nOffset == -1 ) - { - // not found - rtl_uString_acquire( (*ppRet)->aBase.pMemberName = pTypeName ); + pTypeName->buffer, pTypeName->length, ':'); + if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') { + OSL_ENSURE(false, "Bad interface attribute type name"); + return; } - else + rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1); + typelib_InterfaceTypeDescription * pInterface = 0; + typelib_typedescription_getByName( + reinterpret_cast< typelib_TypeDescription ** >(&pInterface), + aInterfaceTypeName.pData); + if (pInterface == 0 + || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE + || !complete( + reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false)) { - rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName, - pTypeName->buffer + nOffset +1, - pTypeName->length - nOffset -1 ); + OSL_ENSURE(false, "No interface corresponding to interface attribute"); + return; } + typelib_typedescription_newEmpty( + (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName ); + typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet; + + rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName, + pTypeName->buffer + nOffset +1, + pTypeName->length - nOffset -1 ); (*ppRet)->aBase.nPosition = nAbsolutePosition; typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName ); (*ppRet)->bReadOnly = bReadOnly; - + (*ppRet)->pInterface = pInterface; + (*ppRet)->pBaseRef = 0; + OSL_ASSERT( + (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers) + && nAbsolutePosition < pInterface->nAllMembers); + (*ppRet)->nIndex = nAbsolutePosition + - (pInterface->nAllMembers - pInterface->nMembers); if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) ) pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp; } @@ -1156,18 +1417,19 @@ static inline void typelib_typedescription_destructExtendedMembers( case typelib_TypeClass_INTERFACE: { typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription*)pTD; - // The members in this array are not allocated - sal_Int32 nSuperMembers = pITD->pBaseTypeDescription ? pITD->pBaseTypeDescription->nAllMembers : 0; - // release only the descriptions of this class and not the one of the superclass - for( sal_Int32 i = nSuperMembers; i < pITD->nAllMembers; i++ ) + {for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ ) { typelib_typedescriptionreference_release( pITD->ppAllMembers[i] ); - } + }} delete [] pITD->ppAllMembers; delete [] pITD->pMapMemberIndexToFunctionIndex; delete [] pITD->pMapFunctionIndexToMemberIndex; - if (pITD->pBaseTypeDescription) - typelib_typedescription_release( (typelib_TypeDescription *)pITD->pBaseTypeDescription ); + {for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) { + typelib_typedescription_release( + reinterpret_cast< typelib_TypeDescription * >( + pITD->ppBaseTypes[i])); + }} + delete[] pITD->ppBaseTypes; break; } case typelib_TypeClass_INTERFACE_METHOD: @@ -1188,6 +1450,10 @@ static inline void typelib_typedescription_destructExtendedMembers( } delete [] pIMTD->ppExceptions; rtl_uString_release( pIMTD->aBase.pMemberName ); + typelib_typedescription_release(&pIMTD->pInterface->aBase); + if (pIMTD->pBaseRef != 0) { + typelib_typedescriptionreference_release(pIMTD->pBaseRef); + } } break; case typelib_TypeClass_INTERFACE_ATTRIBUTE: @@ -1197,6 +1463,10 @@ static inline void typelib_typedescription_destructExtendedMembers( typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef ); if( pIATD->aBase.pMemberName ) rtl_uString_release( pIATD->aBase.pMemberName ); + typelib_typedescription_release(&pIATD->pInterface->aBase); + if (pIATD->pBaseRef != 0) { + typelib_typedescriptionreference_release(pIATD->pBaseRef); + } } break; case typelib_TypeClass_ENUM: @@ -1590,6 +1860,96 @@ extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize( } //------------------------------------------------------------------------ + +namespace { + +bool createDerivedInterfaceMemberDescription( + typelib_TypeDescription ** result, rtl::OUString const & name, + typelib_TypeDescriptionReference * baseRef, + typelib_TypeDescription const * base, typelib_TypeDescription * interface, + sal_Int32 index, sal_Int32 position) +{ + if (baseRef != 0 && base != 0 && interface != 0) { + switch (base->eTypeClass) { + case typelib_TypeClass_INTERFACE_METHOD: + { + typelib_typedescription_newEmpty( + result, typelib_TypeClass_INTERFACE_METHOD, name.pData); + typelib_InterfaceMethodTypeDescription const * baseMethod + = reinterpret_cast< + typelib_InterfaceMethodTypeDescription const * >(base); + typelib_InterfaceMethodTypeDescription * newMethod + = reinterpret_cast< + typelib_InterfaceMethodTypeDescription * >(*result); + newMethod->aBase.nPosition = position; + rtl_uString_acquire( + newMethod->aBase.pMemberName + = baseMethod->aBase.pMemberName); + typelib_typedescriptionreference_acquire( + newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef); + newMethod->nParams = baseMethod->nParams; + newMethod->pParams = new typelib_MethodParameter[ + newMethod->nParams]; + {for (sal_Int32 i = 0; i < newMethod->nParams; ++i) { + rtl_uString_acquire( + newMethod->pParams[i].pName + = baseMethod->pParams[i].pName); + typelib_typedescriptionreference_acquire( + newMethod->pParams[i].pTypeRef + = baseMethod->pParams[i].pTypeRef); + newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn; + newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut; + }} + newMethod->nExceptions = baseMethod->nExceptions; + newMethod->ppExceptions + = new typelib_TypeDescriptionReference *[ + newMethod->nExceptions]; + {for (sal_Int32 i = 0; i < newMethod->nExceptions; ++i) { + typelib_typedescriptionreference_acquire( + newMethod->ppExceptions[i] + = baseMethod->ppExceptions[i]); + }} + newMethod->bOneWay = baseMethod->bOneWay; + newMethod->pInterface + = reinterpret_cast< typelib_InterfaceTypeDescription * >( + interface); + newMethod->pBaseRef = baseRef; + newMethod->nIndex = index; + return true; + } + + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + typelib_typedescription_newEmpty( + result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData); + typelib_InterfaceAttributeTypeDescription const * baseAttribute + = reinterpret_cast< + typelib_InterfaceAttributeTypeDescription const * >(base); + typelib_InterfaceAttributeTypeDescription * newAttribute + = reinterpret_cast< + typelib_InterfaceAttributeTypeDescription * >(*result); + newAttribute->aBase.nPosition = position; + rtl_uString_acquire( + newAttribute->aBase.pMemberName + = baseAttribute->aBase.pMemberName); + newAttribute->bReadOnly = baseAttribute->bReadOnly; + typelib_typedescriptionreference_acquire( + newAttribute->pAttributeTypeRef + = baseAttribute->pAttributeTypeRef); + newAttribute->pInterface + = reinterpret_cast< typelib_InterfaceTypeDescription * >( + interface); + newAttribute->pBaseRef = baseRef; + newAttribute->nIndex = index; + return true; + } + } + } + return false; +} + +} + extern "C" void SAL_CALL typelib_typedescription_getByName( typelib_TypeDescription ** ppRet, rtl_uString * pName ) SAL_THROW_EXTERN_C() @@ -1699,6 +2059,48 @@ extern "C" void SAL_CALL typelib_typedescription_getByName( } if (0 == *ppRet) { + // Check for derived interface member type: + sal_Int32 i1 = name.lastIndexOf( + rtl::OUString::createFromAscii(":@")); + if (i1 >= 0) { + sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@"); + sal_Int32 i3 = name.indexOf(',', i2); + if (i3 >= 0) { + sal_Int32 i4 = name.indexOf(':', i3); + if (i4 >= 0) { + typelib_TypeDescriptionReference * pBaseRef = 0; + typelib_TypeDescription * pBase = 0; + typelib_TypeDescription * pInterface = 0; + typelib_typedescriptionreference_getByName( + &pBaseRef, name.copy(0, i1).pData); + if (pBaseRef != 0) { + typelib_typedescriptionreference_getDescription( + &pBase, pBaseRef); + } + typelib_typedescription_getByName( + &pInterface, name.copy(i4 + 1).pData); + if (!createDerivedInterfaceMemberDescription( + ppRet, name, pBaseRef, pBase, pInterface, + name.copy(i2, i3 - i2).toInt32(), + name.copy(i3 + 1, i4 - i3 - 1).toInt32())) + { + if (pInterface != 0) { + typelib_typedescription_release(pInterface); + } + if (pBase != 0) { + typelib_typedescription_release(pBase); + } + if (pBaseRef != 0) { + typelib_typedescriptionreference_release( + pBaseRef); + } + } + } + } + } + } + if (0 == *ppRet) + { // on demand access aInit.callChain( ppRet, pName ); } @@ -2079,14 +2481,19 @@ extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom( { typelib_TypeDescription * pFromDescr = 0; TYPELIB_DANGER_GET( &pFromDescr, pFrom ); - if ( !((typelib_InterfaceTypeDescription *)pFromDescr)->pBaseTypeDescription ) - { - TYPELIB_DANGER_RELEASE( pFromDescr ); - return sal_False; + typelib_InterfaceTypeDescription * pFromIfc + = reinterpret_cast< + typelib_InterfaceTypeDescription * >(pFromDescr); + bool bRet = false; + for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) { + if (typelib_typedescriptionreference_isAssignableFrom( + pAssignable, + pFromIfc->ppBaseTypes[i]->aBase.pWeakRef)) + { + bRet = true; + break; + } } - sal_Bool bRet = typelib_typedescriptionreference_isAssignableFrom( - pAssignable, - ((typelib_TypeDescription *)((typelib_InterfaceTypeDescription *)pFromDescr)->pBaseTypeDescription)->pWeakRef ); TYPELIB_DANGER_RELEASE( pFromDescr ); return bRet; } @@ -2115,102 +2522,5 @@ extern "C" sal_Bool SAL_CALL typelib_typedescription_complete( typelib_TypeDescription ** ppTypeDescr ) SAL_THROW_EXTERN_C() { - if (! (*ppTypeDescr)->bComplete) - { - OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass || - typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass || - typelib_TypeClass_UNION == (*ppTypeDescr)->eTypeClass || - typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass || - typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) && - !reallyWeak( (*ppTypeDescr)->eTypeClass ) ); - - if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass && - ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers) - { - typelib_typedescription_initTables( *ppTypeDescr ); - return sal_True; - } - // obsolete -// else -// { -// MutexGuard aGuard( aInit.getMutex() ); -// typelib_TypeDescriptionReference * pRef = 0; -// ::typelib_typedescriptionreference_getByName( &pRef, (*ppTypeDescr)->pTypeName ); -// if (pRef) -// { -// if (pRef->pType && pRef->pType->pWeakRef && pRef->pType->bComplete) -// { -// // found registered and complete td -// ::typelib_typedescription_release( *ppTypeDescr ); -// *ppTypeDescr = pRef->pType; -// return sal_True; -// } -// ::typelib_typedescriptionreference_release( pRef ); -// } -// } - - typelib_TypeDescription * pTD = 0; - // on demand access of complete td - aInit.callChain( &pTD, (*ppTypeDescr)->pTypeName ); - if (pTD) - { - if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass) - { - typelib_typedescriptionreference_getDescription( - &pTD, ((typelib_IndirectTypeDescription *)pTD)->pType ); - OSL_ASSERT( pTD ); - if (! pTD) - return sal_False; - } - - OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass ); - // typedescription found - // set to on demand - pTD->bOnDemand = sal_True; - - if (typelib_TypeClass_INTERFACE == pTD->eTypeClass && !pTD->bComplete) - { - // mandatory info from callback chain - OSL_ASSERT( ((typelib_InterfaceTypeDescription *)pTD)->ppAllMembers ); - // complete except of tables init - typelib_typedescription_initTables( pTD ); - pTD->bComplete = sal_True; - } - - // The type description is hold by the reference until - // on demand is activated. - ::typelib_typedescription_register( &pTD ); // replaces incomplete one - OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one - - // insert into the chache - MutexGuard aGuard( aInit.getMutex() ); - if( !aInit.pCache ) - aInit.pCache = new TypeDescriptionList_Impl; - if( (sal_Int32)aInit.pCache->size() >= nCacheSize ) - { - typelib_typedescription_release( aInit.pCache->front() ); - aInit.pCache->pop_front(); - } - // descriptions in the cache must be acquired! - typelib_typedescription_acquire( pTD ); - aInit.pCache->push_back( pTD ); - - OSL_ASSERT( pTD->bComplete ); - - ::typelib_typedescription_release( *ppTypeDescr ); - *ppTypeDescr = pTD; - } - else - { -#if OSL_DEBUG_LEVEL > 1 - OString aStr( - OUStringToOString( (*ppTypeDescr)->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); - OSL_TRACE( "\n### type cannot be completed: %s", aStr.getStr() ); -#endif - return sal_False; - } - } - return sal_True; + return complete(ppTypeDescr, true); } - - |