diff options
Diffstat (limited to 'stoc/source/corereflection')
-rw-r--r-- | stoc/source/corereflection/base.hxx | 453 | ||||
-rw-r--r-- | stoc/source/corereflection/corefl.xml | 44 | ||||
-rw-r--r-- | stoc/source/corereflection/crarray.cxx | 232 | ||||
-rw-r--r-- | stoc/source/corereflection/crbase.cxx | 291 | ||||
-rw-r--r-- | stoc/source/corereflection/crcomp.cxx | 405 | ||||
-rw-r--r-- | stoc/source/corereflection/crefl.cxx | 514 | ||||
-rw-r--r-- | stoc/source/corereflection/crenum.cxx | 247 | ||||
-rw-r--r-- | stoc/source/corereflection/criface.cxx | 993 | ||||
-rw-r--r-- | stoc/source/corereflection/lrucache.hxx | 244 | ||||
-rw-r--r-- | stoc/source/corereflection/makefile.mk | 82 | ||||
-rw-r--r-- | stoc/source/corereflection/reflection.component | 35 |
11 files changed, 3540 insertions, 0 deletions
diff --git a/stoc/source/corereflection/base.hxx b/stoc/source/corereflection/base.hxx new file mode 100644 index 000000000000..2ef60da60d0b --- /dev/null +++ b/stoc/source/corereflection/base.hxx @@ -0,0 +1,453 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +// #define TEST_LIST_CLASSES +// #define TRACE(x) OSL_TRACE(x) +#define TRACE(x) + +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#include <uno/mapping.hxx> +#include <uno/dispatcher.h> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/component.hxx> +#include <cppuhelper/typeprovider.hxx> + +#include "lrucache.hxx" + +#ifdef TEST_LIST_CLASSES +#include <list> +#include <algorithm> +#endif +#include <hash_map> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> + +#include <com/sun/star/reflection/XIdlClass.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +#include <com/sun/star/reflection/XIdlField.hpp> +#include <com/sun/star/reflection/XIdlField2.hpp> +#include <com/sun/star/reflection/XIdlMethod.hpp> + +using namespace std; +using namespace osl; +using namespace rtl; +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::reflection; +using namespace com::sun::star::container; + + +namespace stoc_corefl +{ + +#ifdef TEST_LIST_CLASSES +typedef list< OUString > ClassNameList; +extern ClassNameList g_aClassNames; +#endif + +//-------------------------------------------------------------------------------------------------- +Mutex & getMutexAccess(); + +//-------------------------------------------------------------------------------------------------- +inline bool td_equals( typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType ) +{ + return (pTD->pWeakRef == pType || + (pTD->pTypeName->length == pType->pTypeName->length && + rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0)); +} +//-------------------------------------------------------------------------------------------------- +inline typelib_TypeDescription * getTypeByName( const OUString & rName ) +{ + typelib_TypeDescription * pTypeDescr = 0; + typelib_typedescription_getByName( &pTypeDescr, rName.pData ); + if (! pTypeDescr->bComplete) + typelib_typedescription_complete( &pTypeDescr ); + return pTypeDescr; +} + +typedef std::hash_map< OUString, WeakReference< XIdlField >, + FctHashOUString, equal_to< OUString > > OUString2Field; +typedef std::hash_map< OUString, WeakReference< XIdlMethod >, + FctHashOUString, equal_to< OUString > > OUString2Method; + +//================================================================================================== +class IdlReflectionServiceImpl + : public OComponentHelper + , public XIdlReflection + , public XHierarchicalNameAccess + , public XServiceInfo +{ + Mutex _aComponentMutex; + Reference< XMultiServiceFactory > _xMgr; + Reference< XHierarchicalNameAccess > _xTDMgr; + + // caching + LRU_CacheAnyByOUString _aElements; + + Mapping _aCpp2Uno; + Mapping _aUno2Cpp; + + inline Reference< XIdlClass > constructClass( typelib_TypeDescription * pTypeDescr ); +public: + Reference< XHierarchicalNameAccess > getTDMgr() const + { return _xTDMgr; } + Reference< XMultiServiceFactory > getSMgr() const + { return _xMgr; } + + const Mapping & getCpp2Uno() throw(::com::sun::star::uno::RuntimeException); + const Mapping & getUno2Cpp() throw(::com::sun::star::uno::RuntimeException); + uno_Interface * mapToUno( const Any & rObj, typelib_InterfaceTypeDescription * pTo ) throw(::com::sun::star::uno::RuntimeException); + + // ctor/ dtor + IdlReflectionServiceImpl( const Reference< XComponentContext > & xContext ); + virtual ~IdlReflectionServiceImpl(); + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // some XComponent part from OComponentHelper + virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlReflection + virtual Reference< XIdlClass > SAL_CALL forName( const OUString & rTypeName ) throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlClass > SAL_CALL getType( const Any & rObj ) throw(::com::sun::star::uno::RuntimeException); + + // XHierarchicalNameAccess + virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + + Reference< XIdlClass > forType( typelib_TypeDescription * pTypeDescr ) throw(::com::sun::star::uno::RuntimeException); + Reference< XIdlClass > forType( typelib_TypeDescriptionReference * pRef ) throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class IdlClassImpl + : public WeakImplHelper1< XIdlClass > +{ + IdlReflectionServiceImpl * _pReflection; + + OUString _aName; + TypeClass _eTypeClass; + + typelib_TypeDescription * _pTypeDescr; + +public: + typelib_TypeDescription * getTypeDescr() const + { return _pTypeDescr; } + IdlReflectionServiceImpl * getReflection() const + { return _pReflection; } + Reference< XMultiServiceFactory > getSMgr() const + { return _pReflection->getSMgr(); } + Reference< XHierarchicalNameAccess > getTDMgr() const + { return getReflection()->getTDMgr(); } + + // Ctor + IdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ); + virtual ~IdlClassImpl(); + + // XIdlClassImpl default implementation + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL equals( const Reference< XIdlClass >& xType ) throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException); + + // def impl ???? + virtual Sequence< Reference< XIdlClass > > SAL_CALL getClasses() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlClass > SAL_CALL getClass( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getInterfaces() throw(::com::sun::star::uno::RuntimeException); + + // structs, interfaces + virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException); + // structs + virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException); + // interfaces + virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlMethod > SAL_CALL getMethod( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods() throw(::com::sun::star::uno::RuntimeException); + // array + virtual Reference< XIdlClass > SAL_CALL getComponentType() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlArray > SAL_CALL getArray() throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class InterfaceIdlClassImpl + : public IdlClassImpl +{ + typedef pair< OUString, typelib_TypeDescription * > MemberInit; + + Sequence< Reference< XIdlClass > > _xSuperClasses; + + MemberInit * _pSortedMemberInit; // first methods, then attributes + OUString2Field _aName2Field; + OUString2Method _aName2Method; + sal_Int32 _nMethods; + sal_Int32 _nAttributes; + + void initMembers(); + +public: + typelib_InterfaceTypeDescription * getTypeDescr() const + { return (typelib_InterfaceTypeDescription *)IdlClassImpl::getTypeDescr(); } + + // ctor/ dtor + InterfaceIdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr ) + , _pSortedMemberInit( 0 ) + , _nMethods( 0 ) + , _nAttributes( 0 ) + {} + virtual ~InterfaceIdlClassImpl(); + + // IdlClassImpl modifications + virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException); + virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlMethod > SAL_CALL getMethod( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class CompoundIdlClassImpl + : public IdlClassImpl +{ + Reference< XIdlClass > _xSuperClass; + + Sequence< Reference< XIdlField > > * _pFields; + OUString2Field _aName2Field; + +public: + typelib_CompoundTypeDescription * getTypeDescr() const + { return (typelib_CompoundTypeDescription *)IdlClassImpl::getTypeDescr(); } + + // ctor/ dtor + CompoundIdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr ) + , _pFields( 0 ) + {} + virtual ~CompoundIdlClassImpl(); + + // IdlClassImpl modifications + virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class ArrayIdlClassImpl + : public IdlClassImpl + , public XIdlArray +{ +public: + typelib_IndirectTypeDescription * getTypeDescr() const + { return (typelib_IndirectTypeDescription *)IdlClassImpl::getTypeDescr(); } + + // ctor + ArrayIdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr ) + {} + + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // IdlClassImpl modifications + virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlClass > SAL_CALL getComponentType() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlArray > SAL_CALL getArray() throw(::com::sun::star::uno::RuntimeException); + + // XIdlArray + virtual void SAL_CALL realloc( Any & rArray, sal_Int32 nLen ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getLen( const Any & rArray ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL get( const Any & rArray, sal_Int32 nIndex ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL set( Any & rArray, sal_Int32 nIndex, const Any & rNewValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class EnumIdlClassImpl + : public IdlClassImpl +{ + Sequence< Reference< XIdlField > > * _pFields; + OUString2Field _aName2Field; + +public: + typelib_EnumTypeDescription * getTypeDescr() const + { return (typelib_EnumTypeDescription *)IdlClassImpl::getTypeDescr(); } + + // ctor/ dtor + EnumIdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr ) + , _pFields( 0 ) + {} + virtual ~EnumIdlClassImpl(); + + // IdlClassImpl modifications + virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class IdlMemberImpl + : public WeakImplHelper1< XIdlMember > +{ + IdlReflectionServiceImpl * _pReflection; + OUString _aName; + + typelib_TypeDescription * _pTypeDescr; + typelib_TypeDescription * _pDeclTypeDescr; + +protected: + Reference< XIdlClass > _xDeclClass; + +public: + IdlReflectionServiceImpl * getReflection() const + { return _pReflection; } + Reference< XMultiServiceFactory > getSMgr() const + { return _pReflection->getSMgr(); } + typelib_TypeDescription * getTypeDescr() const + { return _pTypeDescr; } + typelib_TypeDescription * getDeclTypeDescr() const + { return _pDeclTypeDescr; } + + // ctor/ dtor + IdlMemberImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr ); + virtual ~IdlMemberImpl(); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); +}; + +//-------------------------------------------------------------------------------------------------- +// coerces to type descr pTo else queries for it: the interface pointer is returned via rDest +// ## type to XidlClass coercion possible +inline sal_Bool extract( + const Any & rObj, typelib_InterfaceTypeDescription * pTo, + Reference< XInterface > & rDest, + IdlReflectionServiceImpl * pRefl ) +{ + rDest.clear(); + if (0 != pTo) + { + if (! rObj.hasValue()) + return sal_True; + if (rObj.getValueTypeClass() == TypeClass_INTERFACE) + { + return ::uno_type_assignData( + &rDest, ((typelib_TypeDescription *)pTo)->pWeakRef, + const_cast< void * >( rObj.getValue() ), rObj.getValueTypeRef(), + reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface), + reinterpret_cast< uno_AcquireFunc >(cpp_acquire), + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + } + else if (rObj.getValueTypeClass() == TypeClass_TYPE) + { + rDest = pRefl->forType( reinterpret_cast< const Type * >( rObj.getValue() )->getTypeLibType() ); + return rDest.is(); + } + } + return sal_False; +} +//-------------------------------------------------------------------------------------------------- +inline sal_Bool coerce_assign( + void * pDest, typelib_TypeDescription * pTD, const Any & rSource, + IdlReflectionServiceImpl * pRefl ) +{ + if (pTD->eTypeClass == typelib_TypeClass_INTERFACE) + { + Reference< XInterface > xVal; + if (extract( rSource, (typelib_InterfaceTypeDescription *)pTD, xVal, pRefl )) + { + if (*(XInterface **)pDest) + (*(XInterface **)pDest)->release(); + *(XInterface **)pDest = xVal.get(); + if (*(XInterface **)pDest) + (*(XInterface **)pDest)->acquire(); + return sal_True; + } + return sal_False; + } + else if (pTD->eTypeClass == typelib_TypeClass_ANY) + { + return uno_assignData( + pDest, pTD, + (void *)&rSource, pTD, + reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface), + reinterpret_cast< uno_AcquireFunc >(cpp_acquire), + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + } + else + { + return uno_type_assignData( + pDest, pTD->pWeakRef, + (void *)rSource.getValue(), rSource.getValueTypeRef(), + reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface), + reinterpret_cast< uno_AcquireFunc >(cpp_acquire), + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + } +} + +} + + diff --git a/stoc/source/corereflection/corefl.xml b/stoc/source/corereflection/corefl.xml new file mode 100644 index 000000000000..5dba80b6abff --- /dev/null +++ b/stoc/source/corereflection/corefl.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> corereflection.uno </module-name> + <component-description> + <author> Daniel Boelzle </author> + <name> com.sun.star.comp.stoc.CoreReflection </name> + <description> +This service is the implementation of XIdlClassProvider. +The service provides reflection and access to all uno types +(interfaces, structs, enums, ...). +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> C++ </language> + <status value="final"/> + <supported-service> com.sun.star.reflection.CoreReflection </supported-service> + <service-dependency> ... </service-dependency> + <type>com.sun.star.lang.DisposedException</type> + <type> com.sun.star.reflection.XTypeDescription </type> + <type> com.sun.star.reflection.XIdlReflection </type> + <type> com.sun.star.reflection.XIdlClass </type> + <type> com.sun.star.reflection.XIdlField2 </type> + <type> com.sun.star.container.XHierarchicalNameAccess </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XSingleComponentFactory </type> + <type> com.sun.star.lang.XMultiComponentFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.WrappedTargetRuntimeException </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.uno.XComponentContext </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.TypeClass </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency> + <runtime-module-dependency> cppu3 </runtime-module-dependency> + <runtime-module-dependency> sal3 </runtime-module-dependency> +</module-description> diff --git a/stoc/source/corereflection/crarray.cxx b/stoc/source/corereflection/crarray.cxx new file mode 100644 index 000000000000..1546b2389fbb --- /dev/null +++ b/stoc/source/corereflection/crarray.cxx @@ -0,0 +1,232 @@ +/************************************************************************* + * + * 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_stoc.hxx" +#include <typelib/typedescription.h> +#include <uno/data.h> + +#include "base.hxx" + + +namespace stoc_corefl +{ + +// XInterface +//__________________________________________________________________________________________________ +Any ArrayIdlClassImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlArray * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlClassImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void ArrayIdlClassImpl::acquire() throw() +{ + IdlClassImpl::acquire(); +} +//__________________________________________________________________________________________________ +void ArrayIdlClassImpl::release() throw() +{ + IdlClassImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > ArrayIdlClassImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlArray > *)0 ), + IdlClassImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > ArrayIdlClassImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlArray +//__________________________________________________________________________________________________ +void ArrayIdlClassImpl::realloc( Any & rArray, sal_Int32 nLen ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + TypeClass eTC = rArray.getValueTypeClass(); + if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + if (nLen < 0) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal length given!") ), + (XWeak *)(OWeakObject *)this, 1 ); + } + + uno_Sequence ** ppSeq = (uno_Sequence **)rArray.getValue(); + uno_sequence_realloc( ppSeq, (typelib_TypeDescription *)getTypeDescr(), + nLen, + reinterpret_cast< uno_AcquireFunc >(cpp_acquire), + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + rArray.pData = ppSeq; +} +//__________________________________________________________________________________________________ +sal_Int32 ArrayIdlClassImpl::getLen( const Any & rArray ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + TypeClass eTC = rArray.getValueTypeClass(); + if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + + return (*(uno_Sequence **)rArray.getValue())->nElements; +} +//__________________________________________________________________________________________________ +Any ArrayIdlClassImpl::get( const Any & rArray, sal_Int32 nIndex ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) +{ + TypeClass eTC = rArray.getValueTypeClass(); + if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + + uno_Sequence * pSeq = *(uno_Sequence **)rArray.getValue(); + if (pSeq->nElements <= nIndex) + { + throw ArrayIndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal index given!") ), + (XWeak *)(OWeakObject *)this ); + } + + Any aRet; + typelib_TypeDescription * pElemTypeDescr = 0; + TYPELIB_DANGER_GET( &pElemTypeDescr, getTypeDescr()->pType ); + uno_any_destruct( &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + uno_any_construct( &aRet, &pSeq->elements[nIndex * pElemTypeDescr->nSize], + pElemTypeDescr, + reinterpret_cast< uno_AcquireFunc >(cpp_acquire) ); + TYPELIB_DANGER_RELEASE( pElemTypeDescr ); + return aRet; +} + +//__________________________________________________________________________________________________ +void ArrayIdlClassImpl::set( Any & rArray, sal_Int32 nIndex, const Any & rNewValue ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) +{ + TypeClass eTC = rArray.getValueTypeClass(); + if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + + uno_Sequence * pSeq = *(uno_Sequence **)rArray.getValue(); + if (pSeq->nElements <= nIndex) + { + throw ArrayIndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal index given!") ), + (XWeak *)(OWeakObject *)this ); + } + + uno_Sequence ** ppSeq = (uno_Sequence **)rArray.getValue(); + uno_sequence_reference2One( + ppSeq, (typelib_TypeDescription *)getTypeDescr(), + reinterpret_cast< uno_AcquireFunc >(cpp_acquire), + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + rArray.pData = ppSeq; + pSeq = *ppSeq; + + typelib_TypeDescription * pElemTypeDescr = 0; + TYPELIB_DANGER_GET( &pElemTypeDescr, getTypeDescr()->pType ); + + if (! coerce_assign( &pSeq->elements[nIndex * pElemTypeDescr->nSize], + pElemTypeDescr, rNewValue, getReflection() )) + { + TYPELIB_DANGER_RELEASE( pElemTypeDescr ); + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("sequence element is not assignable by given value!") ), + (XWeak *)(OWeakObject *)this, 2 ); + } + TYPELIB_DANGER_RELEASE( pElemTypeDescr ); +} + +// ArrayIdlClassImpl +//__________________________________________________________________________________________________ +sal_Bool ArrayIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + return (xType.is() && + (equals( xType ) || + (xType->getTypeClass() == getTypeClass() && // must be sequence|array + getComponentType()->isAssignableFrom( xType->getComponentType() )))); +} +//__________________________________________________________________________________________________ +Reference< XIdlClass > ArrayIdlClassImpl::getComponentType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getReflection()->forType( getTypeDescr()->pType ); +} +//__________________________________________________________________________________________________ +Reference< XIdlArray > ArrayIdlClassImpl::getArray() + throw(::com::sun::star::uno::RuntimeException) +{ + return this; +} + +} + + diff --git a/stoc/source/corereflection/crbase.cxx b/stoc/source/corereflection/crbase.cxx new file mode 100644 index 000000000000..93d6aa4f2d24 --- /dev/null +++ b/stoc/source/corereflection/crbase.cxx @@ -0,0 +1,291 @@ +/************************************************************************* + * + * 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_stoc.hxx" +#include <cppuhelper/queryinterface.hxx> +#include <uno/any2.h> + +#include "base.hxx" + +namespace stoc_corefl +{ + +#ifdef TEST_LIST_CLASSES +ClassNameList g_aClassNames; +#endif + +//-------------------------------------------------------------------------------------------------- +Mutex & getMutexAccess() +{ + static Mutex * s_pMutex = 0; + if (! s_pMutex) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pMutex) + { + static Mutex s_aMutex; + s_pMutex = &s_aMutex; + } + } + return *s_pMutex; +} + +//__________________________________________________________________________________________________ +IdlClassImpl::IdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : _pReflection( pReflection ) + , _aName( rName ) + , _eTypeClass( (TypeClass)eTypeClass ) + , _pTypeDescr( pTypeDescr ) +{ + if (_pReflection) + _pReflection->acquire(); + if (_pTypeDescr) + { + typelib_typedescription_acquire( _pTypeDescr ); + if (! _pTypeDescr->bComplete) + typelib_typedescription_complete( &_pTypeDescr ); + } + +#ifdef TEST_LIST_CLASSES + ClassNameList::const_iterator iFind( find( g_aClassNames.begin(), g_aClassNames.end(), _aName ) ); + OSL_ENSURE( iFind == g_aClassNames.end(), "### idl class already exists!" ); + g_aClassNames.push_front( _aName ); +#endif +} +//__________________________________________________________________________________________________ +IdlClassImpl::~IdlClassImpl() +{ + if (_pTypeDescr) + typelib_typedescription_release( _pTypeDescr ); + if (_pReflection) + _pReflection->release(); + +#ifdef TEST_LIST_CLASSES + ClassNameList::iterator iFind( find( g_aClassNames.begin(), g_aClassNames.end(), _aName ) ); + OSL_ENSURE( iFind != g_aClassNames.end(), "### idl class does not exist!" ); + g_aClassNames.erase( iFind ); +#endif +} + +// XIdlClassImpl default implementation +//__________________________________________________________________________________________________ +TypeClass IdlClassImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return _eTypeClass; +} +//__________________________________________________________________________________________________ +OUString IdlClassImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} +//__________________________________________________________________________________________________ +sal_Bool IdlClassImpl::equals( const Reference< XIdlClass >& xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + return (xType.is() && + (xType->getTypeClass() == _eTypeClass) && (xType->getName() == _aName)); +} + +static sal_Bool s_aAssignableFromTab[11][11] = +{ + /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */ +/* TypeClass_CHAR */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_BOOLEAN */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_BYTE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_UNSIGNED_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, +/* TypeClass_UNSIGNED_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, +/* TypeClass_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, +/* TypeClass_UNSIGNED_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, +/* TypeClass_FLOAT */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, +/* TypeClass_DOUBLE */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 } +}; +//__________________________________________________________________________________________________ +sal_Bool IdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + TypeClass eAssign = getTypeClass(); + if (equals( xType ) || eAssign == TypeClass_ANY) // default shot + { + return sal_True; + } + else + { + TypeClass eFrom = xType->getTypeClass(); + if (eAssign > TypeClass_VOID && eAssign < TypeClass_STRING && + eFrom > TypeClass_VOID && eFrom < TypeClass_STRING) + { + return s_aAssignableFromTab[eAssign-1][eFrom-1]; + } + } + return sal_False; +} +//__________________________________________________________________________________________________ +void IdlClassImpl::createObject( Any & rObj ) + throw(::com::sun::star::uno::RuntimeException) +{ + rObj.clear(); + uno_any_destruct( &rObj, reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + uno_any_construct( &rObj, 0, getTypeDescr(), 0 ); +} + +// what TODO ???? +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlClassImpl::getClasses() + throw(::com::sun::star::uno::RuntimeException) +{ + OSL_ENSURE( sal_False, "### unexpected use!" ); + return Sequence< Reference< XIdlClass > >(); +} +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlClassImpl::getClass( const OUString & ) + throw(::com::sun::star::uno::RuntimeException) +{ + OSL_ENSURE( sal_False, "### unexpected use!" ); + return Reference< XIdlClass >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlClassImpl::getInterfaces() + throw(::com::sun::star::uno::RuntimeException) +{ +// OSL_ENSURE( sal_False, "### unexpected use!" ); + return Sequence< Reference< XIdlClass > >(); +} + +// structs, interfaces +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlClassImpl::getSuperclasses() throw(::com::sun::star::uno::RuntimeException) +{ + return Sequence< Reference< XIdlClass > >(); +} +// structs +//__________________________________________________________________________________________________ +Reference< XIdlField > IdlClassImpl::getField( const OUString & ) + throw(::com::sun::star::uno::RuntimeException) +{ + return Reference< XIdlField >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlField > > IdlClassImpl::getFields() + throw(::com::sun::star::uno::RuntimeException) +{ + return Sequence< Reference< XIdlField > >(); +} +// interfaces +//__________________________________________________________________________________________________ +Uik IdlClassImpl::getUik() + throw(::com::sun::star::uno::RuntimeException) +{ + return Uik(); +} +//__________________________________________________________________________________________________ +Reference< XIdlMethod > IdlClassImpl::getMethod( const OUString & ) + throw(::com::sun::star::uno::RuntimeException) +{ + return Reference< XIdlMethod >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlMethod > > IdlClassImpl::getMethods() + throw(::com::sun::star::uno::RuntimeException) +{ + return Sequence< Reference< XIdlMethod > >(); +} +// array +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlClassImpl::getComponentType() + throw(::com::sun::star::uno::RuntimeException) +{ + return Reference< XIdlClass >(); +} +//__________________________________________________________________________________________________ +Reference< XIdlArray > IdlClassImpl::getArray() + throw(::com::sun::star::uno::RuntimeException) +{ + return Reference< XIdlArray >(); +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +IdlMemberImpl::IdlMemberImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, + typelib_TypeDescription * pDeclTypeDescr ) + : _pReflection( pReflection ) + , _aName( rName ) + , _pTypeDescr( pTypeDescr ) + , _pDeclTypeDescr( pDeclTypeDescr ) +{ + _pReflection->acquire(); + typelib_typedescription_acquire( _pTypeDescr ); + if (! _pTypeDescr->bComplete) + typelib_typedescription_complete( &_pTypeDescr ); + typelib_typedescription_acquire( _pDeclTypeDescr ); + if (! _pDeclTypeDescr->bComplete) + typelib_typedescription_complete( &_pDeclTypeDescr ); +} +//__________________________________________________________________________________________________ +IdlMemberImpl::~IdlMemberImpl() +{ + typelib_typedescription_release( _pDeclTypeDescr ); + typelib_typedescription_release( _pTypeDescr ); + _pReflection->release(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlMemberImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xDeclClass.is()) + { + Reference< XIdlClass > xDeclClass( getReflection()->forType( getDeclTypeDescr() ) ); + MutexGuard aGuard( getMutexAccess() ); + if (! _xDeclClass.is()) + _xDeclClass = xDeclClass; + } + return _xDeclClass; +} +//__________________________________________________________________________________________________ +OUString IdlMemberImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} + +} + + diff --git a/stoc/source/corereflection/crcomp.cxx b/stoc/source/corereflection/crcomp.cxx new file mode 100644 index 000000000000..db3c2741322f --- /dev/null +++ b/stoc/source/corereflection/crcomp.cxx @@ -0,0 +1,405 @@ +/************************************************************************* + * + * 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_stoc.hxx" +#include <rtl/strbuf.hxx> + +#include <com/sun/star/reflection/XIdlField.hpp> +#include <com/sun/star/reflection/XIdlField2.hpp> +#include "com/sun/star/uno/TypeClass.hpp" + +#include "base.hxx" + + +namespace stoc_corefl +{ + +//================================================================================================== +class IdlCompFieldImpl + : public IdlMemberImpl + , public XIdlField + , public XIdlField2 +{ + sal_Int32 _nOffset; + +public: + IdlCompFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr, + sal_Int32 nOffset ) + : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr ) + , _nOffset( nOffset ) + {} + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + // XIdlField + virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); + virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException); + // XIdlField2: getType, getAccessMode and get are equal to XIdlField + virtual void SAL_CALL set( Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException); +}; + +// XInterface +//__________________________________________________________________________________________________ +Any IdlCompFieldImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, + static_cast< XIdlField * >( this ), + static_cast< XIdlField2 * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlCompFieldImpl::acquire() throw() +{ + IdlMemberImpl::acquire(); +} +//__________________________________________________________________________________________________ +void IdlCompFieldImpl::release() throw() +{ + IdlMemberImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlCompFieldImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlField2 > *)0 ), + ::getCppuType( (const Reference< XIdlField > *)0 ), + IdlMemberImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlCompFieldImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlCompFieldImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xDeclClass.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _xDeclClass.is()) + { + typelib_CompoundTypeDescription * pTD = + (typelib_CompoundTypeDescription *)getDeclTypeDescr(); + while (pTD) + { + typelib_TypeDescriptionReference ** ppTypeRefs = pTD->ppTypeRefs; + for ( sal_Int32 nPos = pTD->nMembers; nPos--; ) + { + if (td_equals( (typelib_TypeDescription *)getTypeDescr(), ppTypeRefs[nPos] )) + { + _xDeclClass = getReflection()->forType( (typelib_TypeDescription *)pTD ); + return _xDeclClass; + } + } + pTD = pTD->pBaseTypeDescription; + } + } + } + return _xDeclClass; +} +//__________________________________________________________________________________________________ +OUString IdlCompFieldImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getName(); +} + +// XIdlField +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlCompFieldImpl::getType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getReflection()->forType( getTypeDescr() ); +} +//__________________________________________________________________________________________________ +FieldAccessMode IdlCompFieldImpl::getAccessMode() + throw(::com::sun::star::uno::RuntimeException) +{ + return FieldAccessMode_READWRITE; +} +//__________________________________________________________________________________________________ +Any IdlCompFieldImpl::get( const Any & rObj ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT || + rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION) + { + typelib_TypeDescription * pObjTD = 0; + TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() ); + + typelib_TypeDescription * pTD = pObjTD; + typelib_TypeDescription * pDeclTD = getDeclTypeDescr(); + while (pTD && !typelib_typedescription_equals( pTD, pDeclTD )) + pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription; + + OSL_ENSURE( pTD, "### illegal object type!" ); + if (pTD) + { + TYPELIB_DANGER_RELEASE( pObjTD ); + Any aRet; + uno_any_destruct( + &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + uno_any_construct( + &aRet, (char *)rObj.getValue() + _nOffset, getTypeDescr(), + reinterpret_cast< uno_AcquireFunc >(cpp_acquire) ); + return aRet; + } + TYPELIB_DANGER_RELEASE( pObjTD ); + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); +} +//__________________________________________________________________________________________________ +void IdlCompFieldImpl::set( const Any & rObj, const Any & rValue ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) +{ + if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT || + rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION) + { + typelib_TypeDescription * pObjTD = 0; + TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() ); + + typelib_TypeDescription * pTD = pObjTD; + typelib_TypeDescription * pDeclTD = getDeclTypeDescr(); + while (pTD && !typelib_typedescription_equals( pTD, pDeclTD )) + pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription; + + OSL_ENSURE( pTD, "### illegal object type!" ); + if (pTD) + { + TYPELIB_DANGER_RELEASE( pObjTD ); + if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() )) + { + return; + } + else + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ), + (XWeak *)(OWeakObject *)this, 1 ); + } + } + TYPELIB_DANGER_RELEASE( pObjTD ); + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); +} + +//__________________________________________________________________________________________________ +void IdlCompFieldImpl::set( Any & rObj, const Any & rValue ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) +{ + if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT || + rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION) + { + typelib_TypeDescription * pObjTD = 0; + TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() ); + + typelib_TypeDescription * pTD = pObjTD; + typelib_TypeDescription * pDeclTD = getDeclTypeDescr(); + while (pTD && !typelib_typedescription_equals( pTD, pDeclTD )) + pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription; + + OSL_ENSURE( pTD, "### illegal object type!" ); + if (pTD) + { + TYPELIB_DANGER_RELEASE( pObjTD ); + if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() )) + { + return; + } + else + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ), + (XWeak *)(OWeakObject *)this, 1 ); + } + } + TYPELIB_DANGER_RELEASE( pObjTD ); + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); +} + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +CompoundIdlClassImpl::~CompoundIdlClassImpl() +{ + delete _pFields; +} + +//__________________________________________________________________________________________________ +sal_Bool CompoundIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + if (xType.is()) + { + TypeClass eTC = xType->getTypeClass(); + if (eTC == TypeClass_STRUCT || eTC == TypeClass_EXCEPTION) + { + if (equals( xType )) + return sal_True; + else + { + const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses(); + if (rSeq.getLength()) + { + OSL_ENSURE( rSeq.getLength() == 1, "### unexpected len of super classes!" ); + return isAssignableFrom( rSeq[0] ); + } + } + } + } + return sal_False; +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > CompoundIdlClassImpl::getSuperclasses() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xSuperClass.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _xSuperClass.is()) + { + typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr()->pBaseTypeDescription; + if (pCompTypeDescr) + _xSuperClass = getReflection()->forType( (typelib_TypeDescription *)pCompTypeDescr ); + } + } + if (_xSuperClass.is()) + return Sequence< Reference< XIdlClass > >( &_xSuperClass, 1 ); + else + return Sequence< Reference< XIdlClass > >(); +} +//__________________________________________________________________________________________________ +Reference< XIdlField > CompoundIdlClassImpl::getField( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pFields) + getFields(); // init fields + + const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) ); + if (iFind != _aName2Field.end()) + return Reference< XIdlField >( (*iFind).second ); + else + return Reference< XIdlField >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlField > > CompoundIdlClassImpl::getFields() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pFields) + { + sal_Int32 nAll = 0; + typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr(); + for ( ; pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription ) + nAll += pCompTypeDescr->nMembers; + + Sequence< Reference< XIdlField > > * pFields = + new Sequence< Reference< XIdlField > >( nAll ); + Reference< XIdlField > * pSeq = pFields->getArray(); + + for ( pCompTypeDescr = getTypeDescr(); pCompTypeDescr; + pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription ) + { + typelib_TypeDescriptionReference ** ppTypeRefs = pCompTypeDescr->ppTypeRefs; + rtl_uString ** ppNames = pCompTypeDescr->ppMemberNames; + sal_Int32 * pMemberOffsets = pCompTypeDescr->pMemberOffsets; + + for ( sal_Int32 nPos = pCompTypeDescr->nMembers; nPos--; ) + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ppTypeRefs[nPos] ); + OSL_ENSURE( pTD, "### cannot get field in struct!" ); + if (pTD) + { + OUString aName( ppNames[nPos] ); + _aName2Field[aName] = pSeq[--nAll] = new IdlCompFieldImpl( + getReflection(), aName, pTD, IdlClassImpl::getTypeDescr(), pMemberOffsets[nPos] ); + TYPELIB_DANGER_RELEASE( pTD ); + } + } + } + + _pFields = pFields; + } + return *_pFields; +} + +} + + diff --git a/stoc/source/corereflection/crefl.cxx b/stoc/source/corereflection/crefl.cxx new file mode 100644 index 000000000000..d3ebed762bac --- /dev/null +++ b/stoc/source/corereflection/crefl.cxx @@ -0,0 +1,514 @@ +/************************************************************************* + * + * 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_stoc.hxx" +#include <cppuhelper/queryinterface.hxx> +#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_ +#include <cppuhelper/implementationentry.hxx> +#endif + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/reflection/XTypeDescription.hpp> +#include "com/sun/star/uno/RuntimeException.hpp" + +using namespace com::sun::star; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace cppu; +using namespace osl; +using namespace rtl; + +#include "base.hxx" + + +namespace stoc_corefl +{ + +static const sal_Int32 CACHE_SIZE = 256; + +#define SERVICENAME "com.sun.star.reflection.CoreReflection" +#define IMPLNAME "com.sun.star.comp.stoc.CoreReflection" + +// can be static, as every client of the core reflection keeps a reference to the +// core reflection, so refcounting can be done here. +static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; + +static Sequence< OUString > core_getSupportedServiceNames() +{ + static Sequence < OUString > *pNames = 0; + if( ! pNames ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( !pNames ) + { + static Sequence< OUString > seqNames(1); + seqNames.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ); + pNames = &seqNames; + } + } + return *pNames; +} + +static OUString core_getImplementationName() +{ + static OUString *pImplName = 0; + if( ! pImplName ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pImplName ) + { + static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ); + pImplName = &implName; + } + } + return *pImplName; +} +//__________________________________________________________________________________________________ +IdlReflectionServiceImpl::IdlReflectionServiceImpl( + const Reference< XComponentContext > & xContext ) + : OComponentHelper( _aComponentMutex ) + , _xMgr( xContext->getServiceManager(), UNO_QUERY ) + , _aElements( CACHE_SIZE ) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + xContext->getValueByName( OUString( RTL_CONSTASCII_USTRINGPARAM( + "/singletons/com.sun.star.reflection.theTypeDescriptionManager") ) ) >>= _xTDMgr; + OSL_ENSURE( _xTDMgr.is(), "### cannot get singleton \"TypeDescriptionManager\" from context!" ); +} +//__________________________________________________________________________________________________ +IdlReflectionServiceImpl::~IdlReflectionServiceImpl() +{ + TRACE( "> IdlReflectionServiceImpl dtor <\n" ); + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +// XInterface +//__________________________________________________________________________________________________ +Any IdlReflectionServiceImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( + rType, + static_cast< XIdlReflection * >( this ), + static_cast< XHierarchicalNameAccess * >( this ), + static_cast< XServiceInfo * >( this ) ) ); + + return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlReflectionServiceImpl::acquire() throw() +{ + OComponentHelper::acquire(); +} +//__________________________________________________________________________________________________ +void IdlReflectionServiceImpl::release() throw() +{ + OComponentHelper::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlReflectionServiceImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( _aComponentMutex ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlReflection > *)0 ), + ::getCppuType( (const Reference< XHierarchicalNameAccess > *)0 ), + ::getCppuType( (const Reference< XServiceInfo > *)0 ), + OComponentHelper::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlReflectionServiceImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( _aComponentMutex ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XComponent +//__________________________________________________________________________________________________ +void IdlReflectionServiceImpl::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + TRACE( "> disposing corereflection... <" ); + OComponentHelper::dispose(); + + MutexGuard aGuard( _aComponentMutex ); + _aElements.clear(); +#ifdef TEST_LIST_CLASSES + OSL_ENSURE( g_aClassNames.size() == 0, "### idl classes still alive!" ); + ClassNameList::const_iterator iPos( g_aClassNames.begin() ); + while (iPos != g_aClassNames.end()) + { + OUString aName( *iPos ); + ++iPos; + } +#endif +} + +// XServiceInfo +//__________________________________________________________________________________________________ +OUString IdlReflectionServiceImpl::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return core_getImplementationName(); +} +//__________________________________________________________________________________________________ +sal_Bool IdlReflectionServiceImpl::supportsService( const OUString & rServiceName ) + throw(::com::sun::star::uno::RuntimeException) +{ + const Sequence< OUString > & rSNL = getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + { + if (pArray[nPos] == rServiceName) + return sal_True; + } + return sal_False; +} +//__________________________________________________________________________________________________ +Sequence< OUString > IdlReflectionServiceImpl::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + return core_getSupportedServiceNames(); +} + +// XIdlReflection +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlReflectionServiceImpl::getType( const Any & rObj ) + throw(::com::sun::star::uno::RuntimeException) +{ + return (rObj.hasValue() ? forType( rObj.getValueTypeRef() ) : Reference< XIdlClass >()); +} + +//__________________________________________________________________________________________________ +inline Reference< XIdlClass > IdlReflectionServiceImpl::constructClass( + typelib_TypeDescription * pTypeDescr ) +{ + OSL_ENSURE( pTypeDescr->eTypeClass != typelib_TypeClass_TYPEDEF, "### unexpected typedef!" ); + + switch (pTypeDescr->eTypeClass) + { + case typelib_TypeClass_VOID: + case typelib_TypeClass_CHAR: + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + case typelib_TypeClass_FLOAT: + case typelib_TypeClass_DOUBLE: + case typelib_TypeClass_STRING: + case typelib_TypeClass_ANY: + return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case TypeClass_ENUM: + return new EnumIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_UNION: + case typelib_TypeClass_EXCEPTION: + return new CompoundIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case typelib_TypeClass_ARRAY: + case typelib_TypeClass_SEQUENCE: + return new ArrayIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case typelib_TypeClass_INTERFACE: + return new InterfaceIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case typelib_TypeClass_TYPE: + return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + default: +#if OSL_DEBUG_LEVEL > 1 + OSL_TRACE( "### corereflection type unsupported: " ); + OString aName( OUStringToOString( pTypeDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( aName.getStr() ); + OSL_TRACE( "\n" ); +#endif + return Reference< XIdlClass >(); + } +} +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlReflectionServiceImpl::forName( const OUString & rTypeName ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XIdlClass > xRet; + Any aAny( _aElements.getValue( rTypeName ) ); + + if (aAny.hasValue()) + { + if (aAny.getValueTypeClass() == TypeClass_INTERFACE) + xRet = *(const Reference< XIdlClass > *)aAny.getValue(); + } + else + { + // try to get _type_ by name + typelib_TypeDescription * pTD = 0; + typelib_typedescription_getByName( &pTD, rTypeName.pData ); + if (pTD) + { + if ((xRet = constructClass( pTD )).is()) + _aElements.setValue( rTypeName, makeAny( xRet ) ); // update + typelib_typedescription_release( pTD ); + } + } + + return xRet; +} + +// XHierarchicalNameAccess +//__________________________________________________________________________________________________ +Any IdlReflectionServiceImpl::getByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException) +{ + Any aRet( _aElements.getValue( rName ) ); + if (! aRet.hasValue()) + { + // first look for constants exclusivly! + aRet = _xTDMgr->getByHierarchicalName( rName ); + if (aRet.getValueTypeClass() == TypeClass_INTERFACE) // if no constant, + // i.e. XTypeDescription for a type + { + // type retrieved from tdmgr + OSL_ASSERT( (*(Reference< XInterface > *)aRet.getValue())->queryInterface( + ::getCppuType( (const Reference< XTypeDescription > *)0 ) ).hasValue() ); + + // if you are interested in a type then CALL forName()!!! + // this way is NOT recommended for types, because this method looks for constants first + + // if td manager found some type, it will be in the cache (hopefully.. we just got it) + // so the second retrieving via c typelib callback chain should succeed... + + // try to get _type_ by name + typelib_TypeDescription * pTD = 0; + typelib_typedescription_getByName( &pTD, rName.pData ); + + aRet.clear(); // kick XTypeDescription interface + + if (pTD) + { + Reference< XIdlClass > xIdlClass( constructClass( pTD ) ); + aRet.setValue( &xIdlClass, ::getCppuType( (const Reference< XIdlClass > *)0 ) ); + typelib_typedescription_release( pTD ); + } + } + // else is constant + + // update + if (aRet.hasValue()) + _aElements.setValue( rName, aRet ); + else + { + throw NoSuchElementException( rName, Reference< XInterface >() ); + } + } + return aRet; +} +//__________________________________________________________________________________________________ +sal_Bool IdlReflectionServiceImpl::hasByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + try + { + return getByHierarchicalName( rName ).hasValue(); + } + catch (NoSuchElementException &) + { + } + return sal_False; +} + +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescription * pTypeDescr ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XIdlClass > xRet; + OUString aName( pTypeDescr->pTypeName ); + Any aAny( _aElements.getValue( aName ) ); + + if (aAny.hasValue()) + { + if (aAny.getValueTypeClass() == TypeClass_INTERFACE) + xRet = *(const Reference< XIdlClass > *)aAny.getValue(); + } + else + { + if (pTypeDescr && (xRet = constructClass( pTypeDescr )).is()) + _aElements.setValue( aName, makeAny( xRet ) ); // update + } + + return xRet; +} +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference * pRef ) + throw(::com::sun::star::uno::RuntimeException) +{ + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, pRef ); + if (pTD) + { + Reference< XIdlClass > xRet = forType( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + return xRet; + } + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("IdlReflectionServiceImpl::forType() failed!") ), + (XWeak *)(OWeakObject *)this ); +} + +//__________________________________________________________________________________________________ +const Mapping & IdlReflectionServiceImpl::getCpp2Uno() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _aCpp2Uno.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _aCpp2Uno.is()) + { + _aCpp2Uno = Mapping( + OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ), + OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ) ); + OSL_ENSURE( _aCpp2Uno.is(), "### cannot get c++ to uno mapping!" ); + if (! _aCpp2Uno.is()) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get c++ to uno mapping!") ), + (XWeak *)(OWeakObject *)this ); + } + } + } + return _aCpp2Uno; +} +//__________________________________________________________________________________________________ +const Mapping & IdlReflectionServiceImpl::getUno2Cpp() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _aUno2Cpp.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _aUno2Cpp.is()) + { + _aUno2Cpp = Mapping( + OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ), + OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ) ); + OSL_ENSURE( _aUno2Cpp.is(), "### cannot get uno to c++ mapping!" ); + if (! _aUno2Cpp.is()) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get uno to c++ mapping!") ), + (XWeak *)(OWeakObject *)this ); + } + } + } + return _aUno2Cpp; +} +//__________________________________________________________________________________________________ +uno_Interface * IdlReflectionServiceImpl::mapToUno( + const Any & rObj, typelib_InterfaceTypeDescription * pTo ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XInterface > xObj; + if (extract( rObj, pTo, xObj, this )) + return (uno_Interface *)getCpp2Uno().mapInterface( xObj.get(), pTo ); + + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), + (XWeak *)(OWeakObject *)this ); +} + +//================================================================================================== +Reference< XInterface > SAL_CALL IdlReflectionServiceImpl_create( + const Reference< XComponentContext > & xContext ) + throw(::com::sun::star::uno::Exception) +{ + return Reference< XInterface >( (XWeak *)(OWeakObject *)new IdlReflectionServiceImpl( xContext ) ); +} + +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + +using namespace stoc_corefl; + +static struct ImplementationEntry g_entries[] = +{ + { + IdlReflectionServiceImpl_create, core_getImplementationName, + core_getSupportedServiceNames, createSingleComponentFactory, + &g_moduleCount.modCnt , 0 + }, + { 0, 0, 0, 0, 0, 0 } +}; + +extern "C" +{ +sal_Bool SAL_CALL component_canUnload( TimeValue *pTime ) +{ + return g_moduleCount.canUnload( &g_moduleCount , pTime ); +} + +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries ); +} +} diff --git a/stoc/source/corereflection/crenum.cxx b/stoc/source/corereflection/crenum.cxx new file mode 100644 index 000000000000..174e177080fe --- /dev/null +++ b/stoc/source/corereflection/crenum.cxx @@ -0,0 +1,247 @@ +/************************************************************************* + * + * 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_stoc.hxx" + +#include "base.hxx" + +namespace stoc_corefl +{ + +//================================================================================================== +class IdlEnumFieldImpl + : public IdlMemberImpl + , public XIdlField + , public XIdlField2 +{ + sal_Int32 _nValue; + +public: + IdlEnumFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, sal_Int32 nValue ) + : IdlMemberImpl( pReflection, rName, pTypeDescr, pTypeDescr ) + , _nValue( nValue ) + {} + virtual ~IdlEnumFieldImpl(); + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + // XIdlField + virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); + virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException); + // XIdlField2: getType, getAccessMode and get are equal to XIdlField + virtual void SAL_CALL set( Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException); +}; +//__________________________________________________________________________________________________ +IdlEnumFieldImpl::~IdlEnumFieldImpl() +{ +} + +// XInterface +//__________________________________________________________________________________________________ +Any IdlEnumFieldImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, + static_cast< XIdlField * >( this ), + static_cast< XIdlField2 * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlEnumFieldImpl::acquire() throw() +{ + IdlMemberImpl::acquire(); +} +//__________________________________________________________________________________________________ +void IdlEnumFieldImpl::release() throw() +{ + IdlMemberImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlEnumFieldImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlField2 > *)0 ), + ::getCppuType( (const Reference< XIdlField > *)0 ), + IdlMemberImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlEnumFieldImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlEnumFieldImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getDeclaringClass(); +} +//__________________________________________________________________________________________________ +OUString IdlEnumFieldImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getName(); +} + +// XIdlField +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlEnumFieldImpl::getType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getDeclaringClass(); +} +//__________________________________________________________________________________________________ +FieldAccessMode IdlEnumFieldImpl::getAccessMode() + throw(::com::sun::star::uno::RuntimeException) +{ + return FieldAccessMode_READONLY; +} +//__________________________________________________________________________________________________ +Any IdlEnumFieldImpl::get( const Any & ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + return Any( &_nValue, getTypeDescr() ); +} +//__________________________________________________________________________________________________ +void IdlEnumFieldImpl::set( const Any &, const Any & ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) +{ + throw IllegalAccessException( + OUString( RTL_CONSTASCII_USTRINGPARAM("enum field is constant!") ), + (XWeak *)(OWeakObject *)this ); +} +//__________________________________________________________________________________________________ +void IdlEnumFieldImpl::set( Any &, const Any & ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) +{ + throw IllegalAccessException( + OUString( RTL_CONSTASCII_USTRINGPARAM("enum field is constant!") ), + (XWeak *)(OWeakObject *)this ); +} + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +EnumIdlClassImpl::~EnumIdlClassImpl() +{ + delete _pFields; +} + +// IdlClassImpl modifications +//__________________________________________________________________________________________________ +Reference< XIdlField > EnumIdlClassImpl::getField( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pFields) + getFields(); // init members + + const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) ); + if (iFind != _aName2Field.end()) + return (*iFind).second; + else + return Reference< XIdlField >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlField > > EnumIdlClassImpl::getFields() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pFields) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _pFields) + { + sal_Int32 nFields = getTypeDescr()->nEnumValues; + Sequence< Reference< XIdlField > > * pFields = + new Sequence< Reference< XIdlField > >( nFields ); + Reference< XIdlField > * pSeq = pFields->getArray(); + + while (nFields--) + { + OUString aName( getTypeDescr()->ppEnumNames[nFields] ); + _aName2Field[aName] = pSeq[nFields] = new IdlEnumFieldImpl( + getReflection(), aName, IdlClassImpl::getTypeDescr(), getTypeDescr()->pEnumValues[nFields] ); + } + + _pFields = pFields; + } + } + return *_pFields; +} +//__________________________________________________________________________________________________ +void EnumIdlClassImpl::createObject( Any & rObj ) + throw(::com::sun::star::uno::RuntimeException) +{ + sal_Int32 eVal = + ((typelib_EnumTypeDescription *)IdlClassImpl::getTypeDescr())->nDefaultEnumValue; + rObj.setValue( &eVal, IdlClassImpl::getTypeDescr() ); +} + +} + + diff --git a/stoc/source/corereflection/criface.cxx b/stoc/source/corereflection/criface.cxx new file mode 100644 index 000000000000..95d9990257f5 --- /dev/null +++ b/stoc/source/corereflection/criface.cxx @@ -0,0 +1,993 @@ +/************************************************************************* + * + * 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_stoc.hxx" + +#include <sal/config.h> +#ifdef SAL_UNX +#include <sal/alloca.h> +#endif +#if !(defined(MACOSX) || defined(FREEBSD)) +#include <malloc.h> +#endif +#include <rtl/alloc.h> +#include <typelib/typedescription.hxx> +#include <uno/data.h> + +#include "base.hxx" + +#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "cppuhelper/exc_hlp.hxx" + +namespace stoc_corefl +{ + +//================================================================================================== +class IdlAttributeFieldImpl + : public IdlMemberImpl + , public XIdlField + , public XIdlField2 +{ +public: + typelib_InterfaceAttributeTypeDescription * getAttributeTypeDescr() + { return (typelib_InterfaceAttributeTypeDescription *)getTypeDescr(); } + + IdlAttributeFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr ) + : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr ) + {} + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + // XIdlField + virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); + virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException); + // XIdlField2: getType, getAccessMode and get are equal to XIdlField + virtual void SAL_CALL set( Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException); + +private: + void checkException( + uno_Any * exception, Reference< XInterface > const & context); +}; + +// XInterface +//__________________________________________________________________________________________________ +Any IdlAttributeFieldImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, + static_cast< XIdlField * >( this ), + static_cast< XIdlField2 * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlAttributeFieldImpl::acquire() throw() +{ + IdlMemberImpl::acquire(); +} +//__________________________________________________________________________________________________ +void IdlAttributeFieldImpl::release() throw() +{ + IdlMemberImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlAttributeFieldImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlField2 > *)0 ), + ::getCppuType( (const Reference< XIdlField > *)0 ), + IdlMemberImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlAttributeFieldImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlAttributeFieldImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xDeclClass.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _xDeclClass.is()) + { + rtl::OUString aName(getAttributeTypeDescr()->aBase.aBase.pTypeName); + sal_Int32 i = aName.indexOf(':'); + OSL_ASSERT(i >= 0); + _xDeclClass = getReflection()->forName(aName.copy(0, i)); + } + } + return _xDeclClass; +} +//__________________________________________________________________________________________________ +OUString IdlAttributeFieldImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getName(); +} + +// XIdlField +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlAttributeFieldImpl::getType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getReflection()->forType( + getAttributeTypeDescr()->pAttributeTypeRef ); +} +//__________________________________________________________________________________________________ +FieldAccessMode IdlAttributeFieldImpl::getAccessMode() + throw(::com::sun::star::uno::RuntimeException) +{ + return (((typelib_InterfaceAttributeTypeDescription *)getAttributeTypeDescr())->bReadOnly + ? FieldAccessMode_READONLY : FieldAccessMode_READWRITE); +} +//__________________________________________________________________________________________________ +Any IdlAttributeFieldImpl::get( const Any & rObj ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + uno_Interface * pUnoI = getReflection()->mapToUno( + rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() ); + OSL_ENSURE( pUnoI, "### illegal destination object given!" ); + if (pUnoI) + { + TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef ); + typelib_TypeDescription * pTD = aTD.get(); + + uno_Any aExc; + uno_Any * pExc = &aExc; + void * pReturn = alloca( pTD->nSize ); + + (*pUnoI->pDispatcher)( pUnoI, getTypeDescr(), pReturn, 0, &pExc ); + (*pUnoI->release)( pUnoI ); + + checkException( + pExc, + *static_cast< Reference< XInterface > const * >(rObj.getValue())); + Any aRet; + uno_any_destruct( + &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + uno_any_constructAndConvert( &aRet, pReturn, pTD, getReflection()->getUno2Cpp().get() ); + uno_destructData( pReturn, pTD, 0 ); + return aRet; + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); +} +//__________________________________________________________________________________________________ +void IdlAttributeFieldImpl::set( Any & rObj, const Any & rValue ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) +{ + if (getAttributeTypeDescr()->bReadOnly) + { + throw IllegalAccessException( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot set readonly attribute!") ), + (XWeak *)(OWeakObject *)this ); + } + + uno_Interface * pUnoI = getReflection()->mapToUno( + rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() ); + OSL_ENSURE( pUnoI, "### illegal destination object given!" ); + if (pUnoI) + { + TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef ); + typelib_TypeDescription * pTD = aTD.get(); + + // construct uno value to be set + void * pArgs[1]; + void * pArg = pArgs[0] = alloca( pTD->nSize ); + + sal_Bool bAssign; + if (pTD->eTypeClass == typelib_TypeClass_ANY) + { + uno_copyAndConvertData( pArg, SAL_CONST_CAST( Any *, &rValue ), + pTD, getReflection()->getCpp2Uno().get() ); + bAssign = sal_True; + } + else if (typelib_typedescriptionreference_equals( rValue.getValueTypeRef(), pTD->pWeakRef )) + { + uno_copyAndConvertData( pArg, SAL_CONST_CAST( void *, rValue.getValue() ), + pTD, getReflection()->getCpp2Uno().get() ); + bAssign = sal_True; + } + else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE) + { + Reference< XInterface > xObj; + bAssign = extract( + rValue, (typelib_InterfaceTypeDescription *)pTD, xObj, + getReflection() ); + if (bAssign) + { + *(void **)pArg = getReflection()->getCpp2Uno().mapInterface( + xObj.get(), (typelib_InterfaceTypeDescription *)pTD ); + } + } + else + { + typelib_TypeDescription * pValueTD = 0; + TYPELIB_DANGER_GET( &pValueTD, rValue.getValueTypeRef() ); + // construct temp uno val to do proper assignment: todo opt + void * pTemp = alloca( pValueTD->nSize ); + uno_copyAndConvertData( + pTemp, (void *)rValue.getValue(), pValueTD, getReflection()->getCpp2Uno().get() ); + uno_constructData( + pArg, pTD ); + // assignment does simple conversion + bAssign = uno_assignData( + pArg, pTD, pTemp, pValueTD, 0, 0, 0 ); + uno_destructData( + pTemp, pValueTD, 0 ); + TYPELIB_DANGER_RELEASE( pValueTD ); + } + + if (bAssign) + { + uno_Any aExc; + uno_Any * pExc = &aExc; + (*pUnoI->pDispatcher)( pUnoI, getTypeDescr(), 0, pArgs, &pExc ); + (*pUnoI->release)( pUnoI ); + + uno_destructData( pArg, pTD, 0 ); + checkException( + pExc, + *static_cast< Reference< XInterface > const * >( + rObj.getValue())); + return; + } + (*pUnoI->release)( pUnoI ); + + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ), + *(const Reference< XInterface > *)rObj.getValue(), 1 ); + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); +} +//__________________________________________________________________________________________________ +void IdlAttributeFieldImpl::set( const Any & rObj, const Any & rValue ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) +{ + IdlAttributeFieldImpl::set( const_cast< Any & >( rObj ), rValue ); +} + +void IdlAttributeFieldImpl::checkException( + uno_Any * exception, Reference< XInterface > const & context) +{ + if (exception != 0) { + Any e; + uno_any_destruct(&e, reinterpret_cast< uno_ReleaseFunc >(cpp_release)); + uno_type_any_constructAndConvert( + &e, exception->pData, exception->pType, + getReflection()->getUno2Cpp().get()); + uno_any_destruct(exception, 0); + if (e.isExtractableTo( + getCppuType(static_cast< RuntimeException const * >(0)))) + { + cppu::throwException(e); + } else { + throw WrappedTargetRuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "non-RuntimeException occured when accessing an" + " interface type attribute")), + context, e); + } + } +} + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//================================================================================================== +class IdlInterfaceMethodImpl + : public IdlMemberImpl + , public XIdlMethod +{ + Sequence< Reference< XIdlClass > > * _pExceptionTypes; + Sequence< Reference< XIdlClass > > * _pParamTypes; + Sequence< ParamInfo > * _pParamInfos; + +public: + typelib_InterfaceMethodTypeDescription * getMethodTypeDescr() + { return (typelib_InterfaceMethodTypeDescription *)getTypeDescr(); } + + IdlInterfaceMethodImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr ) + : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr ) + , _pExceptionTypes( 0 ) + , _pParamTypes( 0 ) + , _pParamInfos( 0 ) + {} + virtual ~IdlInterfaceMethodImpl(); + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + // XIdlMethod + virtual Reference< XIdlClass > SAL_CALL getReturnType() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getParameterTypes() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< ParamInfo > SAL_CALL getParameterInfos() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getExceptionTypes() throw(::com::sun::star::uno::RuntimeException); + virtual MethodMode SAL_CALL getMode() throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL invoke( const Any & rObj, Sequence< Any > & rArgs ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException); +}; +//__________________________________________________________________________________________________ +IdlInterfaceMethodImpl::~IdlInterfaceMethodImpl() +{ + delete _pParamInfos; + delete _pParamTypes; + delete _pExceptionTypes; +} + +// XInterface +//__________________________________________________________________________________________________ +Any IdlInterfaceMethodImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlMethod * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlInterfaceMethodImpl::acquire() throw() +{ + IdlMemberImpl::acquire(); +} +//__________________________________________________________________________________________________ +void IdlInterfaceMethodImpl::release() throw() +{ + IdlMemberImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlInterfaceMethodImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlMethod > *)0 ), + IdlMemberImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlInterfaceMethodImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlInterfaceMethodImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xDeclClass.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _xDeclClass.is()) + { + rtl::OUString aName(getMethodTypeDescr()->aBase.aBase.pTypeName); + sal_Int32 i = aName.indexOf(':'); + OSL_ASSERT(i >= 0); + _xDeclClass = getReflection()->forName(aName.copy(0, i)); + } + } + return _xDeclClass; +} +//__________________________________________________________________________________________________ +OUString IdlInterfaceMethodImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getName(); +} + +// XIdlMethod +//__________________________________________________________________________________________________ +Reference< XIdlClass > SAL_CALL IdlInterfaceMethodImpl::getReturnType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getReflection()->forType( getMethodTypeDescr()->pReturnTypeRef ); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getExceptionTypes() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pExceptionTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _pExceptionTypes) + { + sal_Int32 nExc = getMethodTypeDescr()->nExceptions; + Sequence< Reference< XIdlClass > > * pTempExceptionTypes = + new Sequence< Reference< XIdlClass > >( nExc ); + Reference< XIdlClass > * pExceptionTypes = pTempExceptionTypes->getArray(); + + typelib_TypeDescriptionReference ** ppExc = + getMethodTypeDescr()->ppExceptions; + IdlReflectionServiceImpl * pRefl = getReflection(); + + while (nExc--) + pExceptionTypes[nExc] = pRefl->forType( ppExc[nExc] ); + + _pExceptionTypes = pTempExceptionTypes; + } + } + return *_pExceptionTypes; +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getParameterTypes() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pParamTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _pParamTypes) + { + sal_Int32 nParams = getMethodTypeDescr()->nParams; + Sequence< Reference< XIdlClass > > * pTempParamTypes = + new Sequence< Reference< XIdlClass > >( nParams ); + Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray(); + + typelib_MethodParameter * pTypelibParams = + getMethodTypeDescr()->pParams; + IdlReflectionServiceImpl * pRefl = getReflection(); + + while (nParams--) + pParamTypes[nParams] = pRefl->forType( pTypelibParams[nParams].pTypeRef ); + + _pParamTypes = pTempParamTypes; + } + } + return *_pParamTypes; +} +//__________________________________________________________________________________________________ +Sequence< ParamInfo > IdlInterfaceMethodImpl::getParameterInfos() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pParamInfos) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _pParamInfos) + { + sal_Int32 nParams = getMethodTypeDescr()->nParams; + Sequence< ParamInfo > * pTempParamInfos = new Sequence< ParamInfo >( nParams ); + ParamInfo * pParamInfos = pTempParamInfos->getArray(); + + typelib_MethodParameter * pTypelibParams = + getMethodTypeDescr()->pParams; + + if (_pParamTypes) // use param types + { + const Reference< XIdlClass > * pParamTypes = _pParamTypes->getConstArray(); + + while (nParams--) + { + const typelib_MethodParameter & rParam = pTypelibParams[nParams]; + ParamInfo & rInfo = pParamInfos[nParams]; + rInfo.aName = rParam.pName; + if (rParam.bIn) + rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN); + else + rInfo.aMode = ParamMode_OUT; + rInfo.aType = pParamTypes[nParams]; + } + } + else // make also param types sequence if not already initialized + { + Sequence< Reference< XIdlClass > > * pTempParamTypes = + new Sequence< Reference< XIdlClass > >( nParams ); + Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray(); + + IdlReflectionServiceImpl * pRefl = getReflection(); + + while (nParams--) + { + const typelib_MethodParameter & rParam = pTypelibParams[nParams]; + ParamInfo & rInfo = pParamInfos[nParams]; + rInfo.aName = rParam.pName; + if (rParam.bIn) + rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN); + else + rInfo.aMode = ParamMode_OUT; + rInfo.aType = pParamTypes[nParams] = pRefl->forType( rParam.pTypeRef ); + } + + _pParamTypes = pTempParamTypes; + } + + _pParamInfos = pTempParamInfos; + } + } + return *_pParamInfos; +} +//__________________________________________________________________________________________________ +MethodMode SAL_CALL IdlInterfaceMethodImpl::getMode() + throw(::com::sun::star::uno::RuntimeException) +{ + return + getMethodTypeDescr()->bOneWay ? MethodMode_ONEWAY : MethodMode_TWOWAY; +} +//__________________________________________________________________________________________________ +Any SAL_CALL IdlInterfaceMethodImpl::invoke( const Any & rObj, Sequence< Any > & rArgs ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::reflection::InvocationTargetException, + ::com::sun::star::uno::RuntimeException) +{ + if (rObj.getValueTypeClass() == TypeClass_INTERFACE) + { + // acquire()/ release() + if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer, + "com.sun.star.uno.XInterface::acquire" ) == 0) + { + (*(const Reference< XInterface > *)rObj.getValue())->acquire(); + return Any(); + } + else if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer, + "com.sun.star.uno.XInterface::release" ) == 0) + { + (*(const Reference< XInterface > *)rObj.getValue())->release(); + return Any(); + } + } + + uno_Interface * pUnoI = getReflection()->mapToUno( + rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() ); + OSL_ENSURE( pUnoI, "### illegal destination object given!" ); + if (pUnoI) + { + sal_Int32 nParams = getMethodTypeDescr()->nParams; + if (rArgs.getLength() != nParams) + { + (*pUnoI->release)( pUnoI ); + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("arguments len differ!") ), + *(const Reference< XInterface > *)rObj.getValue(), 1 ); + } + + Any * pCppArgs = rArgs.getArray(); + typelib_MethodParameter * pParams = getMethodTypeDescr()->pParams; + typelib_TypeDescription * pReturnType = 0; + TYPELIB_DANGER_GET( + &pReturnType, getMethodTypeDescr()->pReturnTypeRef ); + + void * pUnoReturn = alloca( pReturnType->nSize ); + void ** ppUnoArgs = (void **)alloca( sizeof(void *) * nParams *2 ); + typelib_TypeDescription ** ppParamTypes = (typelib_TypeDescription **)(ppUnoArgs + nParams); + + // convert arguments + for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) + { + ppParamTypes[nPos] = 0; + TYPELIB_DANGER_GET( ppParamTypes + nPos, pParams[nPos].pTypeRef ); + typelib_TypeDescription * pTD = ppParamTypes[nPos]; + + ppUnoArgs[nPos] = alloca( pTD->nSize ); + if (pParams[nPos].bIn) + { + sal_Bool bAssign; + if (typelib_typedescriptionreference_equals( + pCppArgs[nPos].getValueTypeRef(), pTD->pWeakRef )) + { + uno_type_copyAndConvertData( + ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(), + pCppArgs[nPos].getValueTypeRef(), getReflection()->getCpp2Uno().get() ); + bAssign = sal_True; + } + else if (pTD->eTypeClass == typelib_TypeClass_ANY) + { + uno_type_any_constructAndConvert( + (uno_Any *)ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(), + pCppArgs[nPos].getValueTypeRef(), getReflection()->getCpp2Uno().get() ); + bAssign = sal_True; + } + else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE) + { + Reference< XInterface > xDest; + bAssign = extract( + pCppArgs[nPos], (typelib_InterfaceTypeDescription *)pTD, + xDest, getReflection() ); + if (bAssign) + { + *(void **)ppUnoArgs[nPos] = getReflection()->getCpp2Uno().mapInterface( + xDest.get(), (typelib_InterfaceTypeDescription *)pTD ); + } + } + else + { + typelib_TypeDescription * pValueTD = 0; + TYPELIB_DANGER_GET( &pValueTD, pCppArgs[nPos].getValueTypeRef() ); + // construct temp uno val to do proper assignment: todo opt + void * pTemp = alloca( pValueTD->nSize ); + uno_copyAndConvertData( + pTemp, (void *)pCppArgs[nPos].getValue(), pValueTD, + getReflection()->getCpp2Uno().get() ); + uno_constructData( + ppUnoArgs[nPos], pTD ); + // assignment does simple conversion + bAssign = uno_assignData( + ppUnoArgs[nPos], pTD, pTemp, pValueTD, 0, 0, 0 ); + uno_destructData( + pTemp, pValueTD, 0 ); + TYPELIB_DANGER_RELEASE( pValueTD ); + } + + if (! bAssign) + { + IllegalArgumentException aExc( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot coerce argument type during corereflection call!") ), + *(const Reference< XInterface > *)rObj.getValue(), (sal_Int16)nPos ); + + // cleanup + while (nPos--) + { + if (pParams[nPos].bIn) + uno_destructData( ppUnoArgs[nPos], ppParamTypes[nPos], 0 ); + TYPELIB_DANGER_RELEASE( ppParamTypes[nPos] ); + } + TYPELIB_DANGER_RELEASE( pReturnType ); + (*pUnoI->release)( pUnoI ); + + throw aExc; + } + } + } + + uno_Any aUnoExc; + uno_Any * pUnoExc = &aUnoExc; + + (*pUnoI->pDispatcher)( + pUnoI, getTypeDescr(), pUnoReturn, ppUnoArgs, &pUnoExc ); + (*pUnoI->release)( pUnoI ); + + Any aRet; + if (pUnoExc) + { + // cleanup + while (nParams--) + { + if (pParams[nParams].bIn) + uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 ); + TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] ); + } + TYPELIB_DANGER_RELEASE( pReturnType ); + + InvocationTargetException aExc; + aExc.Context = *(const Reference< XInterface > *)rObj.getValue(); + aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("exception occured during invocation!") ); + uno_any_destruct( + &aExc.TargetException, + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + uno_type_copyAndConvertData( + &aExc.TargetException, pUnoExc, ::getCppuType( (const Any *)0 ).getTypeLibType(), + getReflection()->getUno2Cpp().get() ); + uno_any_destruct( pUnoExc, 0 ); + throw aExc; + } + else + { + // reconvert arguments and cleanup + while (nParams--) + { + if (pParams[nParams].bOut) // write back + { + uno_any_destruct( + &pCppArgs[nParams], + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + uno_any_constructAndConvert( + &pCppArgs[nParams], ppUnoArgs[nParams], ppParamTypes[nParams], + getReflection()->getUno2Cpp().get() ); + } + uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 ); + TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] ); + } + uno_any_destruct( + &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + uno_any_constructAndConvert( + &aRet, pUnoReturn, pReturnType, + getReflection()->getUno2Cpp().get() ); + uno_destructData( pUnoReturn, pReturnType, 0 ); + TYPELIB_DANGER_RELEASE( pReturnType ); + } + return aRet; + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +InterfaceIdlClassImpl::~InterfaceIdlClassImpl() +{ + for ( sal_Int32 nPos = _nMethods + _nAttributes; nPos--; ) + typelib_typedescription_release( _pSortedMemberInit[nPos].second ); + + delete [] _pSortedMemberInit; +} + +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > InterfaceIdlClassImpl::getSuperclasses() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard(getMutexAccess()); + if (_xSuperClasses.getLength() == 0) { + typelib_InterfaceTypeDescription * pType = getTypeDescr(); + _xSuperClasses.realloc(pType->nBaseTypes); + for (sal_Int32 i = 0; i < pType->nBaseTypes; ++i) { + _xSuperClasses[i] = getReflection()->forType( + &pType->ppBaseTypes[i]->aBase); + OSL_ASSERT(_xSuperClasses[i].is()); + } + } + return Sequence< Reference< XIdlClass > >(_xSuperClasses); +} +//__________________________________________________________________________________________________ +void InterfaceIdlClassImpl::initMembers() +{ + sal_Int32 nAll = getTypeDescr()->nAllMembers; + MemberInit * pSortedMemberInit = new MemberInit[nAll]; + typelib_TypeDescriptionReference ** ppAllMembers = getTypeDescr()->ppAllMembers; + + for ( sal_Int32 nPos = 0; nPos < nAll; ++nPos ) + { + sal_Int32 nIndex; + if (ppAllMembers[nPos]->eTypeClass == typelib_TypeClass_INTERFACE_METHOD) + { + // methods to front + nIndex = _nMethods; + ++_nMethods; + } + else + { + ++_nAttributes; + nIndex = (nAll - _nAttributes); + // attributes at the back + } + + typelib_TypeDescription * pTD = 0; + typelib_typedescriptionreference_getDescription( &pTD, ppAllMembers[nPos] ); + OSL_ENSURE( pTD, "### cannot get type description!" ); + pSortedMemberInit[nIndex].first = ((typelib_InterfaceMemberTypeDescription *)pTD)->pMemberName; + pSortedMemberInit[nIndex].second = pTD; + } + + _pSortedMemberInit = pSortedMemberInit; +} +//__________________________________________________________________________________________________ +sal_Bool InterfaceIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + if (xType.is() && xType->getTypeClass() == TypeClass_INTERFACE) + { + if (equals( xType )) + return sal_True; + else + { + const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses(); + for (sal_Int32 i = 0; i < rSeq.getLength(); ++i) { + if (isAssignableFrom(rSeq[i])) { + return true; + } + } + } + } + return sal_False; +} +//__________________________________________________________________________________________________ +Uik InterfaceIdlClassImpl::getUik() + throw(::com::sun::star::uno::RuntimeException) +{ + return Uik(0, 0, 0, 0, 0); + // Uiks are deprecated and this function must not be called +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlMethod > > InterfaceIdlClassImpl::getMethods() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pSortedMemberInit) + initMembers(); + + // create methods sequence + Sequence< Reference< XIdlMethod > > aRet( _nMethods ); + Reference< XIdlMethod > * pRet = aRet.getArray(); + for ( sal_Int32 nPos = _nMethods; nPos--; ) + { + + /*_aName2Method[_pSortedMemberInit[nPos].first] = */pRet[nPos] = new IdlInterfaceMethodImpl( + getReflection(), _pSortedMemberInit[nPos].first, + _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() ); + } + return aRet; +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlField > > InterfaceIdlClassImpl::getFields() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pSortedMemberInit) + initMembers(); + + // create fields sequence + Sequence< Reference< XIdlField > > aRet( _nAttributes ); + Reference< XIdlField > * pRet = aRet.getArray(); + for ( sal_Int32 nPos = _nAttributes; nPos--; ) + { + /*_aName2Field[_pSortedMemberInit[_nMethods+nPos].first] = */pRet[_nAttributes-nPos-1] = + new IdlAttributeFieldImpl( + getReflection(), _pSortedMemberInit[_nMethods+nPos].first, + _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() ); + } + return aRet; +} +//__________________________________________________________________________________________________ +Reference< XIdlMethod > InterfaceIdlClassImpl::getMethod( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pSortedMemberInit) + initMembers(); + + Reference< XIdlMethod > xRet; + + // try weak map + const OUString2Method::const_iterator iFind( _aName2Method.find( rName ) ); + if (iFind != _aName2Method.end()) + xRet = (*iFind).second; // harden ref + + if (! xRet.is()) + { + for ( sal_Int32 nPos = _nMethods; nPos--; ) + { + if (_pSortedMemberInit[nPos].first == rName) + { + _aName2Method[rName] = xRet = new IdlInterfaceMethodImpl( + getReflection(), rName, + _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() ); + break; + } + } + } + return xRet; +} +//__________________________________________________________________________________________________ +Reference< XIdlField > InterfaceIdlClassImpl::getField( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pSortedMemberInit) + initMembers(); + + Reference< XIdlField > xRet; + + // try weak map + const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) ); + if (iFind != _aName2Field.end()) + xRet = (*iFind).second; // harden ref + + if (! xRet.is()) + { + for ( sal_Int32 nPos = _nAttributes; nPos--; ) + { + if (_pSortedMemberInit[_nMethods+nPos].first == rName) + { + _aName2Field[rName] = xRet = new IdlAttributeFieldImpl( + getReflection(), rName, + _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() ); + break; + } + } + } + return xRet; +} +//__________________________________________________________________________________________________ +void InterfaceIdlClassImpl::createObject( Any & rObj ) + throw(::com::sun::star::uno::RuntimeException) +{ + // interfaces cannot be constructed + rObj.clear(); +} + +} + + diff --git a/stoc/source/corereflection/lrucache.hxx b/stoc/source/corereflection/lrucache.hxx new file mode 100644 index 000000000000..98c5faf4586d --- /dev/null +++ b/stoc/source/corereflection/lrucache.hxx @@ -0,0 +1,244 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _LRU_CACHE_HXX_ +#define _LRU_CACHE_HXX_ + +// __CACHE_DIAGNOSE forces cache size to 4 and works only for OUString keys +// #define __CACHE_DIAGNOSE 1 + +#include <osl/mutex.hxx> +#include "rtl/ustring.hxx" + +#include <hash_map> + +/** Implementation of a least recently used (lru) cache. + <br> + @author Daniel Boelzle +*/ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +class LRU_Cache +{ + struct CacheEntry + { + t_Key aKey; + t_Val aVal; + CacheEntry * pPred; + CacheEntry * pSucc; + }; + typedef ::std::hash_map< t_Key, CacheEntry *, t_KeyHash, t_KeyEqual > t_Key2Element; + + mutable ::osl::Mutex _aCacheMutex; + sal_Int32 _nCachedElements; + t_Key2Element _aKey2Element; + + CacheEntry * _pBlock; + mutable CacheEntry * _pHead; + mutable CacheEntry * _pTail; + inline void toFront( CacheEntry * pEntry ) const; + +public: + /** Constructor: + <br> + @param nCachedElements number of elements to be cached; default param set to 128 + */ + inline LRU_Cache( sal_Int32 nCachedElements = 128 ); + /** Destructor: releases all cached elements and keys. + <br> + */ + inline ~LRU_Cache(); + + /** Retrieves a value from the cache. Returns default constructed value, + if none was found. + <br> + @param rKey a key + @return value + */ + inline t_Val getValue( const t_Key & rKey ) const; + /** Sets a value to be cached for given key. + <br> + @param rKey a key + @param rValue a value + */ + inline void setValue( const t_Key & rKey, const t_Val & rValue ); + /** Tests whether a value is cached for given key. + <br> + @param rKey a key + @return true, if value is cached + */ + inline sal_Bool hasValue( const t_Key & rKey ) const; + /** Clears the cache, thus releasing all cached elements and keys. + <br> + */ + inline void clear(); +}; +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::LRU_Cache( sal_Int32 nCachedElements ) +#ifdef __CACHE_DIAGNOSE + : _nCachedElements( 4 ) +#else + : _nCachedElements( nCachedElements ) +#endif + , _pBlock( 0 ) +{ + if (_nCachedElements > 0) + { + _pBlock = new CacheEntry[_nCachedElements]; + _pHead = _pBlock; + _pTail = _pBlock + _nCachedElements -1; + for ( sal_Int32 nPos = _nCachedElements; nPos--; ) + { + _pBlock[nPos].pPred = _pBlock + nPos -1; + _pBlock[nPos].pSucc = _pBlock + nPos +1; + } + } +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::~LRU_Cache() +{ + delete [] _pBlock; +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::toFront( CacheEntry * pEntry ) const +{ + if (pEntry != _pHead) + { + // cut out element + if (pEntry == _pTail) + { + _pTail = pEntry->pPred; + } + else + { + pEntry->pSucc->pPred = pEntry->pPred; + pEntry->pPred->pSucc = pEntry->pSucc; + } + // push to front + _pHead->pPred = pEntry; + pEntry->pSucc = _pHead; + _pHead = pEntry; + } +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline sal_Bool LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::hasValue( const t_Key & rKey ) const +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + const typename t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) ); + return (iFind != _aKey2Element.end()); +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline t_Val LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::getValue( const t_Key & rKey ) const +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + const typename t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) ); + if (iFind != _aKey2Element.end()) + { + CacheEntry * pEntry = (*iFind).second; + toFront( pEntry ); +#ifdef __CACHE_DIAGNOSE + OSL_TRACE( "> retrieved element \"" ); + OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_TRACE( "\" from cache <\n" ); +#endif + return pEntry->aVal; + } + return t_Val(); +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::setValue( + const t_Key & rKey, const t_Val & rValue ) +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + if (_nCachedElements > 0) + { + const typename t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) ); + + CacheEntry * pEntry; + if (iFind == _aKey2Element.end()) + { + pEntry = _pTail; // erase last element +#ifdef __CACHE_DIAGNOSE + if (pEntry->aKey.getLength()) + { + OSL_TRACE( "> kicking element \"" ); + OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_TRACE( "\" from cache <\n" ); + } +#endif + _aKey2Element.erase( pEntry->aKey ); + _aKey2Element[ pEntry->aKey = rKey ] = pEntry; + } + else + { + pEntry = (*iFind).second; +#ifdef __CACHE_DIAGNOSE + OSL_TRACE( "> replacing element \"" ); + OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_TRACE( "\" in cache <\n" ); +#endif + } + pEntry->aVal = rValue; + toFront( pEntry ); + } +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::clear() +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + _aKey2Element.clear(); + for ( sal_Int32 nPos = _nCachedElements; nPos--; ) + { + _pBlock[nPos].aKey = t_Key(); + _pBlock[nPos].aVal = t_Val(); + } + _nCachedElements = 0; +#ifdef __CACHE_DIAGNOSE + OSL_TRACE( "> cleared cache <\n" ); +#endif +} + +//================================================================================================== +struct FctHashOUString : public ::std::unary_function< const ::rtl::OUString &, size_t > +{ + size_t operator()( const ::rtl::OUString & rKey ) const + { return rKey.hashCode(); } +}; + +/** Template instance for OUString keys, Any values.<br> +*/ +typedef LRU_Cache< ::rtl::OUString, ::com::sun::star::uno::Any, + FctHashOUString, ::std::equal_to< ::rtl::OUString > > + LRU_CacheAnyByOUString; + + +#endif diff --git a/stoc/source/corereflection/makefile.mk b/stoc/source/corereflection/makefile.mk new file mode 100644 index 000000000000..7156f6d63cc4 --- /dev/null +++ b/stoc/source/corereflection/makefile.mk @@ -0,0 +1,82 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET = reflection.uno +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST = corefl + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +DLLPRE = + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +SLOFILES= \ + $(SLO)$/crefl.obj \ + $(SLO)$/crbase.obj \ + $(SLO)$/crarray.obj \ + $(SLO)$/crcomp.obj \ + $(SLO)$/criface.obj \ + $(SLO)$/crenum.obj + +# internal compiler error with Forte 6 update 1 (x86) +# to be reconsidered after compiler upgrade +.IF "$(OS)$(CPU)"=="SOLARISI" +NOOPTFILES += $(SLO)$/criface.obj +.ENDIF + +SHL1TARGET= $(TARGET) +SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +SHL1RPATH= URELIB + +DEF1NAME= $(SHL1TARGET) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +ALLTAR : $(MISC)/reflection.component + +$(MISC)/reflection.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + reflection.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt reflection.component diff --git a/stoc/source/corereflection/reflection.component b/stoc/source/corereflection/reflection.component new file mode 100644 index 000000000000..00772a448367 --- /dev/null +++ b/stoc/source/corereflection/reflection.component @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* 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. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.stoc.CoreReflection"> + <service name="com.sun.star.reflection.CoreReflection"/> + <singleton name="com.sun.star.reflection.theCoreReflection"/> + </implementation> +</component> |