diff options
Diffstat (limited to 'cppuhelper/source/tdmgr.cxx')
-rw-r--r-- | cppuhelper/source/tdmgr.cxx | 785 |
1 files changed, 785 insertions, 0 deletions
diff --git a/cppuhelper/source/tdmgr.cxx b/cppuhelper/source/tdmgr.cxx new file mode 100644 index 000000000000..7090adbe90d3 --- /dev/null +++ b/cppuhelper/source/tdmgr.cxx @@ -0,0 +1,785 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_cppuhelper.hxx" + +#include "sal/config.h" + +#include <vector> + +#include <sal/alloca.h> + +#include <osl/diagnose.h> +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> + +#include <uno/mapping.hxx> + +#include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/implbase1.hxx> +#include <typelib/typedescription.h> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/reflection/XTypeDescription.hpp> +#include <com/sun/star/reflection/XEnumTypeDescription.hpp> +#include <com/sun/star/reflection/XIndirectTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp> +#include <com/sun/star/reflection/XMethodParameter.hpp> +#include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceTypeDescription2.hpp> +#include <com/sun/star/reflection/XCompoundTypeDescription.hpp> +#include <com/sun/star/reflection/XStructTypeDescription.hpp> +#include <com/sun/star/reflection/XUnionTypeDescription.hpp> +#include "com/sun/star/uno/RuntimeException.hpp" + +#include "boost/scoped_array.hpp" + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::reflection; + + +namespace cppu +{ + +static typelib_TypeDescription * createCTD( + Reference< container::XHierarchicalNameAccess > const & access, + const Reference< XTypeDescription > & xType ); + +//================================================================================================== +inline static sal_Int64 coerceToInt64( const Any & rVal ) +{ + switch (rVal.getValueTypeClass()) + { + case TypeClass_CHAR: + return *(sal_Unicode *)rVal.getValue(); + case TypeClass_BOOLEAN: + return (*(sal_Bool *)rVal.getValue() ? 1 : 0); + case TypeClass_BYTE: + return *(sal_Int8 *)rVal.getValue(); + case TypeClass_SHORT: + return *(sal_Int16 *)rVal.getValue(); + case TypeClass_UNSIGNED_SHORT: + return *(sal_uInt16 *)rVal.getValue(); + case TypeClass_LONG: + return *(sal_Int32 *)rVal.getValue(); + case TypeClass_UNSIGNED_LONG: + return *(sal_uInt32 *)rVal.getValue(); + case TypeClass_HYPER: + return *(sal_Int64 *)rVal.getValue(); + case TypeClass_UNSIGNED_HYPER: + return *(sal_uInt64 *)rVal.getValue(); + case TypeClass_ENUM: + return *(int *)rVal.getValue(); + default: + OSL_ASSERT(false); + return 0; + } +} +//================================================================================================== +inline static typelib_TypeDescription * createCTD( + const Reference< XUnionTypeDescription > & xType ) +{ + typelib_TypeDescription * pRet = 0; + if (xType.is()) + { + OUString aTypeName( xType->getName() ); + + // discriminant type + Reference< XTypeDescription > xDiscrTD( xType->getDiscriminantType() ); + OUString aDiscrTypeName( xDiscrTD->getName() ); + typelib_TypeDescriptionReference * pDiscrTypeRef = 0; + typelib_typedescriptionreference_new( &pDiscrTypeRef, + (typelib_TypeClass)xDiscrTD->getTypeClass(), + aDiscrTypeName.pData ); + // default member type + Reference< XTypeDescription > xDefaultMemberTD( xType->getDefaultMemberType() ); + OUString aDefMemberTypeName( xDefaultMemberTD->getName() ); + typelib_TypeDescriptionReference * pDefMemberTypeRef = 0; + typelib_typedescriptionreference_new( &pDefMemberTypeRef, + (typelib_TypeClass)xDefaultMemberTD->getTypeClass(), + aDefMemberTypeName.pData ); + // init array + Sequence< Any > aDiscriminants( xType->getDiscriminants() ); + Sequence< Reference< XTypeDescription > > aMemberTypes( xType->getMemberTypes() ); + Sequence< OUString > aMemberNames( xType->getMemberNames() ); + sal_Int32 nMembers = aDiscriminants.getLength(); + OSL_ASSERT( nMembers == aMemberNames.getLength() && nMembers == aMemberTypes.getLength() ); + + const Any * pDiscriminants = aDiscriminants.getConstArray(); + const Reference< XTypeDescription > * pMemberTypes = aMemberTypes.getConstArray(); + const OUString * pMemberNames = aMemberNames.getConstArray(); + + typelib_Union_Init * pMembers = (typelib_Union_Init *)alloca( nMembers * sizeof(typelib_Union_Init) ); + + sal_Int32 nPos; + for ( nPos = nMembers; nPos--; ) + { + typelib_Union_Init & rEntry = pMembers[nPos]; + // member discriminant + rEntry.nDiscriminant = coerceToInt64( pDiscriminants[nPos] ); + // member type + OUString aMemberTypeName( pMemberTypes[nPos]->getName() ); + rEntry.pTypeRef = 0; + typelib_typedescriptionreference_new( &rEntry.pTypeRef, + (typelib_TypeClass)pMemberTypes[nPos]->getTypeClass(), + aMemberTypeName.pData ); + // member name + rEntry.pMemberName = pMemberNames[nPos].pData; + } + + typelib_typedescription_newUnion( &pRet, aTypeName.pData, + pDiscrTypeRef, + coerceToInt64( xType->getDefaultDiscriminant() ), + pDefMemberTypeRef, + nMembers, pMembers ); + + for ( nPos = nMembers; nPos--; ) + { + typelib_typedescriptionreference_release( pMembers[nPos].pTypeRef ); + } + + typelib_typedescriptionreference_release( pDiscrTypeRef ); + typelib_typedescriptionreference_release( pDefMemberTypeRef ); + } + return pRet; +} +//================================================================================================== +inline static typelib_TypeDescription * createCTD( + const Reference< XCompoundTypeDescription > & xType ) +{ + typelib_TypeDescription * pRet = 0; + if (xType.is()) + { + typelib_TypeDescription * pBaseType = createCTD( + Reference< XCompoundTypeDescription >::query( xType->getBaseType() ) ); + if (pBaseType) + typelib_typedescription_register( &pBaseType ); + + // construct member init array + const Sequence<Reference< XTypeDescription > > & rMemberTypes = xType->getMemberTypes(); + const Sequence< OUString > & rMemberNames = xType->getMemberNames(); + + const Reference< XTypeDescription > * pMemberTypes = rMemberTypes.getConstArray(); + const OUString * pMemberNames = rMemberNames.getConstArray(); + + sal_Int32 nMembers = rMemberTypes.getLength(); + OSL_ENSURE( nMembers == rMemberNames.getLength(), "### lens differ!" ); + + OUString aTypeName( xType->getName() ); + + typelib_CompoundMember_Init * pMemberInits = (typelib_CompoundMember_Init *)alloca( + sizeof(typelib_CompoundMember_Init) * nMembers ); + + sal_Int32 nPos; + for ( nPos = nMembers; nPos--; ) + { + typelib_CompoundMember_Init & rInit = pMemberInits[nPos]; + rInit.eTypeClass = (typelib_TypeClass)pMemberTypes[nPos]->getTypeClass(); + + OUString aMemberTypeName( pMemberTypes[nPos]->getName() ); + rtl_uString_acquire( rInit.pTypeName = aMemberTypeName.pData ); + + // string is held by rMemberNames + rInit.pMemberName = pMemberNames[nPos].pData; + } + + typelib_typedescription_new( + &pRet, + (typelib_TypeClass)xType->getTypeClass(), + aTypeName.pData, + (pBaseType ? pBaseType->pWeakRef : 0), + nMembers, pMemberInits ); + + // cleanup + for ( nPos = nMembers; nPos--; ) + { + rtl_uString_release( pMemberInits[nPos].pTypeName ); + } + if (pBaseType) + typelib_typedescription_release( pBaseType ); + } + return pRet; +} +//================================================================================================== +inline static typelib_TypeDescription * createCTD( + Reference< container::XHierarchicalNameAccess > const & access, + const Reference< XStructTypeDescription > & xType ) +{ + typelib_TypeDescription * pRet = 0; + if (xType.is() && xType->getTypeParameters().getLength() == 0) + { + typelib_TypeDescription * pBaseType = createCTD( + access, xType->getBaseType() ); + if (pBaseType) + typelib_typedescription_register( &pBaseType ); + + // construct member init array + const Sequence<Reference< XTypeDescription > > & rMemberTypes = xType->getMemberTypes(); + const Sequence< OUString > & rMemberNames = xType->getMemberNames(); + + const Reference< XTypeDescription > * pMemberTypes = rMemberTypes.getConstArray(); + const OUString * pMemberNames = rMemberNames.getConstArray(); + + sal_Int32 nMembers = rMemberTypes.getLength(); + OSL_ENSURE( nMembers == rMemberNames.getLength(), "### lens differ!" ); + + OUString aTypeName( xType->getName() ); + + typelib_StructMember_Init * pMemberInits = (typelib_StructMember_Init *)alloca( + sizeof(typelib_StructMember_Init) * nMembers ); + + Sequence< Reference< XTypeDescription > > templateMemberTypes; + sal_Int32 i = aTypeName.indexOf('<'); + if (i >= 0) { + Reference< XStructTypeDescription > templateDesc( + access->getByHierarchicalName(aTypeName.copy(0, i)), + UNO_QUERY_THROW); + OSL_ASSERT( + templateDesc->getTypeParameters().getLength() + == xType->getTypeArguments().getLength()); + templateMemberTypes = templateDesc->getMemberTypes(); + OSL_ASSERT(templateMemberTypes.getLength() == nMembers); + } + + sal_Int32 nPos; + for ( nPos = nMembers; nPos--; ) + { + typelib_StructMember_Init & rInit = pMemberInits[nPos]; + rInit.aBase.eTypeClass + = (typelib_TypeClass)pMemberTypes[nPos]->getTypeClass(); + + OUString aMemberTypeName( pMemberTypes[nPos]->getName() ); + rtl_uString_acquire( + rInit.aBase.pTypeName = aMemberTypeName.pData ); + + // string is held by rMemberNames + rInit.aBase.pMemberName = pMemberNames[nPos].pData; + + rInit.bParameterizedType = templateMemberTypes.getLength() != 0 + && (templateMemberTypes[nPos]->getTypeClass() + == TypeClass_UNKNOWN); + } + + typelib_typedescription_newStruct( + &pRet, + aTypeName.pData, + (pBaseType ? pBaseType->pWeakRef : 0), + nMembers, pMemberInits ); + + // cleanup + for ( nPos = nMembers; nPos--; ) + { + rtl_uString_release( pMemberInits[nPos].aBase.pTypeName ); + } + if (pBaseType) + typelib_typedescription_release( pBaseType ); + } + return pRet; +} +//================================================================================================== +inline static typelib_TypeDescription * createCTD( + const Reference< XInterfaceAttributeTypeDescription2 > & xAttribute ) +{ + typelib_TypeDescription * pRet = 0; + if (xAttribute.is()) + { + OUString aMemberName( xAttribute->getName() ); + Reference< XTypeDescription > xType( xAttribute->getType() ); + OUString aMemberTypeName( xType->getName() ); + std::vector< rtl_uString * > getExc; + Sequence< Reference< XCompoundTypeDescription > > getExcs( + xAttribute->getGetExceptions() ); + for (sal_Int32 i = 0; i != getExcs.getLength(); ++i) + { + OSL_ASSERT( getExcs[i].is() ); + getExc.push_back( getExcs[i]->getName().pData ); + } + std::vector< rtl_uString * > setExc; + Sequence< Reference< XCompoundTypeDescription > > setExcs( + xAttribute->getSetExceptions() ); + for (sal_Int32 i = 0; i != setExcs.getLength(); ++i) + { + OSL_ASSERT( setExcs[i].is() ); + setExc.push_back( setExcs[i]->getName().pData ); + } + typelib_typedescription_newExtendedInterfaceAttribute( + (typelib_InterfaceAttributeTypeDescription **)&pRet, + xAttribute->getPosition(), + aMemberName.pData, // name + (typelib_TypeClass)xType->getTypeClass(), + aMemberTypeName.pData, // type name + xAttribute->isReadOnly(), + getExc.size(), getExc.empty() ? 0 : &getExc[0], + setExc.size(), setExc.empty() ? 0 : &setExc[0] ); + } + return pRet; +} +//================================================================================================== +static typelib_TypeDescription * createCTD( + const Reference< XInterfaceMethodTypeDescription > & xMethod ) +{ + typelib_TypeDescription * pRet = 0; + if (xMethod.is()) + { + Reference< XTypeDescription > xReturnType( xMethod->getReturnType() ); + + // init all params + const Sequence<Reference< XMethodParameter > > & rParams = xMethod->getParameters(); + const Reference< XMethodParameter > * pParams = rParams.getConstArray(); + sal_Int32 nParams = rParams.getLength(); + + typelib_Parameter_Init * pParamInit = (typelib_Parameter_Init *)alloca( + sizeof(typelib_Parameter_Init) * nParams ); + + sal_Int32 nPos; + for ( nPos = nParams; nPos--; ) + { + const Reference< XMethodParameter > & xParam = pParams[nPos]; + const Reference< XTypeDescription > & xType = xParam->getType(); + typelib_Parameter_Init & rInit = pParamInit[xParam->getPosition()]; + + rInit.eTypeClass = (typelib_TypeClass)xType->getTypeClass(); + OUString aParamTypeName( xType->getName() ); + rtl_uString_acquire( rInit.pTypeName = aParamTypeName.pData ); + OUString aParamName( xParam->getName() ); + rtl_uString_acquire( rInit.pParamName = aParamName.pData ); + rInit.bIn = xParam->isIn(); + rInit.bOut = xParam->isOut(); + } + + // init all exception strings + const Sequence<Reference< XTypeDescription > > & rExceptions = xMethod->getExceptions(); + const Reference< XTypeDescription > * pExceptions = rExceptions.getConstArray(); + sal_Int32 nExceptions = rExceptions.getLength(); + rtl_uString ** ppExceptionNames = (rtl_uString **)alloca( + sizeof(rtl_uString *) * nExceptions ); + + for ( nPos = nExceptions; nPos--; ) + { + OUString aExceptionTypeName( pExceptions[nPos]->getName() ); + rtl_uString_acquire( ppExceptionNames[nPos] = aExceptionTypeName.pData ); + } + + OUString aTypeName( xMethod->getName() ); + OUString aReturnTypeName( xReturnType->getName() ); + + typelib_typedescription_newInterfaceMethod( + (typelib_InterfaceMethodTypeDescription **)&pRet, + xMethod->getPosition(), + xMethod->isOneway(), + aTypeName.pData, + (typelib_TypeClass)xReturnType->getTypeClass(), + aReturnTypeName.pData, + nParams, pParamInit, + nExceptions, ppExceptionNames ); + + for ( nPos = nParams; nPos--; ) + { + rtl_uString_release( pParamInit[nPos].pTypeName ); + rtl_uString_release( pParamInit[nPos].pParamName ); + } + for ( nPos = nExceptions; nPos--; ) + { + rtl_uString_release( ppExceptionNames[nPos] ); + } + } + return pRet; +} +//================================================================================================== +inline static typelib_TypeDescription * createCTD( + Reference< container::XHierarchicalNameAccess > const & access, + const Reference< XInterfaceTypeDescription2 > & xType ) +{ + typelib_TypeDescription * pRet = 0; + if (xType.is()) + { + Sequence< Reference< XTypeDescription > > aBases(xType->getBaseTypes()); + sal_Int32 nBases = aBases.getLength(); + // Exploit the fact that a typelib_TypeDescription for an interface type + // is also the typelib_TypeDescriptionReference for that type: + boost::scoped_array< typelib_TypeDescription * > aBaseTypes( + new typelib_TypeDescription *[nBases]); + {for (sal_Int32 i = 0; i < nBases; ++i) { + typelib_TypeDescription * p = createCTD(access, aBases[i]); + OSL_ASSERT( + !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(p->eTypeClass)); + typelib_typedescription_register(&p); + aBaseTypes[i] = p; + }} + typelib_TypeDescriptionReference ** pBaseTypeRefs + = reinterpret_cast< typelib_TypeDescriptionReference ** >( + aBaseTypes.get()); + + // construct all member refs + const Sequence<Reference< XInterfaceMemberTypeDescription > > & rMembers = xType->getMembers(); + sal_Int32 nMembers = rMembers.getLength(); + + typelib_TypeDescriptionReference ** ppMemberRefs = (typelib_TypeDescriptionReference **)alloca( + sizeof(typelib_TypeDescriptionReference *) * nMembers ); + + const Reference< XInterfaceMemberTypeDescription > * pMembers = rMembers.getConstArray(); + + OUString aTypeName( xType->getName() ); + + sal_Int32 nPos; + for ( nPos = nMembers; nPos--; ) + { + OUString aMemberTypeName( pMembers[nPos]->getName() ); + ppMemberRefs[nPos] = 0; + typelib_typedescriptionreference_new( + ppMemberRefs + nPos, + (typelib_TypeClass)pMembers[nPos]->getTypeClass(), + aMemberTypeName.pData ); + } + + Uik uik = xType->getUik(); + + typelib_typedescription_newMIInterface( + (typelib_InterfaceTypeDescription **)&pRet, + aTypeName.pData, + uik.m_Data1, uik.m_Data2, uik.m_Data3, uik.m_Data4, uik.m_Data5, + nBases, pBaseTypeRefs, + nMembers, ppMemberRefs ); + + // cleanup refs and base type + {for (int i = 0; i < nBases; ++i) { + typelib_typedescription_release(aBaseTypes[i]); + }} + + for ( nPos = nMembers; nPos--; ) + { + typelib_typedescriptionreference_release( ppMemberRefs[nPos] ); + } + } + return pRet; +} +//================================================================================================== +inline static typelib_TypeDescription * createCTD( const Reference< XEnumTypeDescription > & xType ) +{ + typelib_TypeDescription * pRet = 0; + if (xType.is()) + { + OUString aTypeName( xType->getName() ); + Sequence< OUString > aNames( xType->getEnumNames() ); + OSL_ASSERT( sizeof(OUString) == sizeof(rtl_uString *) ); // !!! + Sequence< sal_Int32 > aValues( xType->getEnumValues() ); + + typelib_typedescription_newEnum( + &pRet, aTypeName.pData, xType->getDefaultEnumValue(), + aNames.getLength(), + (rtl_uString **)aNames.getConstArray(), + const_cast< sal_Int32 * >( aValues.getConstArray() ) ); + } + return pRet; +} +//================================================================================================== +inline static typelib_TypeDescription * createCTD( + Reference< container::XHierarchicalNameAccess > const & access, + const Reference< XIndirectTypeDescription > & xType ) +{ + typelib_TypeDescription * pRet = 0; + if (xType.is()) + { + typelib_TypeDescription * pRefType = createCTD( + access, xType->getReferencedType() ); + typelib_typedescription_register( &pRefType ); + + OUString aTypeName( xType->getName() ); + + typelib_typedescription_new( + &pRet, + (typelib_TypeClass)xType->getTypeClass(), + aTypeName.pData, + pRefType->pWeakRef, + 0, 0 ); + + // cleanup + typelib_typedescription_release( pRefType ); + } + return pRet; +} + +//================================================================================================== +static typelib_TypeDescription * createCTD( + Reference< container::XHierarchicalNameAccess > const & access, + const Reference< XTypeDescription > & xType ) +{ + typelib_TypeDescription * pRet = 0; + + if (xType.is()) + { + switch (xType->getTypeClass()) + { + // built in types + case TypeClass_VOID: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("void") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_VOID, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_CHAR: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("char") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_CHAR, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_BOOLEAN: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("boolean") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_BOOLEAN, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_BYTE: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("byte") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_BYTE, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_SHORT: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("short") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_SHORT, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_UNSIGNED_SHORT: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("unsigned short") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_SHORT, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_LONG: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("long") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_LONG, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_UNSIGNED_LONG: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("unsigned long") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_LONG, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_HYPER: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("hyper") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_HYPER, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_UNSIGNED_HYPER: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("unsigned hyper") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_HYPER, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_FLOAT: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("float") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_FLOAT, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_DOUBLE: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("double") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_DOUBLE, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_STRING: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("string") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_STRING, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_TYPE: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("type") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_TYPE, aTypeName.pData, 0, 0, 0 ); + break; + } + case TypeClass_ANY: + { + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("any") ); + typelib_typedescription_new( &pRet, typelib_TypeClass_ANY, aTypeName.pData, 0, 0, 0 ); + break; + } + + case TypeClass_UNION: + pRet = createCTD( Reference< XUnionTypeDescription >::query( xType ) ); + break; + case TypeClass_EXCEPTION: + pRet = createCTD( Reference< XCompoundTypeDescription >::query( xType ) ); + break; + case TypeClass_STRUCT: + pRet = createCTD( + access, Reference< XStructTypeDescription >::query( xType ) ); + break; + case TypeClass_ENUM: + pRet = createCTD( Reference< XEnumTypeDescription >::query( xType ) ); + break; + case TypeClass_TYPEDEF: + { + Reference< XIndirectTypeDescription > xTypedef( xType, UNO_QUERY ); + if (xTypedef.is()) + pRet = createCTD( access, xTypedef->getReferencedType() ); + break; + } + case TypeClass_SEQUENCE: + pRet = createCTD( + access, Reference< XIndirectTypeDescription >::query( xType ) ); + break; + case TypeClass_INTERFACE: + pRet = createCTD( + access, + Reference< XInterfaceTypeDescription2 >::query( xType ) ); + break; + case TypeClass_INTERFACE_METHOD: + pRet = createCTD( Reference< XInterfaceMethodTypeDescription >::query( xType ) ); + break; + case TypeClass_INTERFACE_ATTRIBUTE: + pRet = createCTD( Reference< XInterfaceAttributeTypeDescription2 >::query( xType ) ); + break; + default: + break; + } + } + + return pRet; +} + + +//================================================================================================== +extern "C" +{ +static void SAL_CALL typelib_callback( + void * pContext, typelib_TypeDescription ** ppRet, rtl_uString * pTypeName ) +{ + OSL_ENSURE( pContext && ppRet && pTypeName, "### null ptr!" ); + if (ppRet) + { + if (*ppRet) + { + ::typelib_typedescription_release( *ppRet ); + *ppRet = 0; + } + if (pContext && pTypeName) + { + Reference< container::XHierarchicalNameAccess > access( + reinterpret_cast< container::XHierarchicalNameAccess * >( + pContext)); + try + { + OUString const & rTypeName = OUString::unacquired( &pTypeName ); + Reference< XTypeDescription > xTD; + if (access->getByHierarchicalName(rTypeName ) >>= xTD) + { + *ppRet = createCTD( access, xTD ); + } + } + catch (container::NoSuchElementException & exc) + { + (void) exc; // avoid warning about unused variable + OSL_TRACE( + "typelibrary type not available: %s", + OUStringToOString( + exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + catch (Exception & exc) + { + (void) exc; // avoid warning about unused variable + OSL_TRACE( + "%s", + OUStringToOString( + exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + } +} +} + +//================================================================================================== +class EventListenerImpl + : public WeakImplHelper1< lang::XEventListener > +{ + Reference< container::XHierarchicalNameAccess > m_xTDMgr; + +public: + inline EventListenerImpl( + Reference< container::XHierarchicalNameAccess > const & xTDMgr ) + SAL_THROW( () ) + : m_xTDMgr( xTDMgr ) + {} + + // XEventListener + virtual void SAL_CALL disposing( lang::EventObject const & rEvt ) + throw (RuntimeException); +}; +//__________________________________________________________________________________________________ +void EventListenerImpl::disposing( lang::EventObject const & rEvt ) + throw (RuntimeException) +{ + if (rEvt.Source != m_xTDMgr) { + OSL_ASSERT(false); + } + // deregister of c typelib callback + ::typelib_typedescription_revokeCallback( m_xTDMgr.get(), typelib_callback ); +} + +//================================================================================================== +sal_Bool SAL_CALL installTypeDescriptionManager( + Reference< container::XHierarchicalNameAccess > const & xTDMgr_c ) + SAL_THROW( () ) +{ + uno::Environment curr_env(Environment::getCurrent()); + uno::Environment target_env(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV)))); + + uno::Mapping curr2target(curr_env, target_env); + + + Reference<container::XHierarchicalNameAccess> xTDMgr( + reinterpret_cast<container::XHierarchicalNameAccess *>( + curr2target.mapInterface(xTDMgr_c.get(), ::getCppuType(&xTDMgr_c))), + SAL_NO_ACQUIRE); + + Reference< lang::XComponent > xComp( xTDMgr, UNO_QUERY ); + if (xComp.is()) + { + xComp->addEventListener( new EventListenerImpl( xTDMgr ) ); + // register c typelib callback + ::typelib_typedescription_registerCallback( xTDMgr.get(), typelib_callback ); + return sal_True; + } + return sal_False; +} + +} // end namespace cppu + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |