diff options
Diffstat (limited to 'cppu')
112 files changed, 28830 insertions, 0 deletions
diff --git a/cppu/inc/com/sun/star/uno/Any.h b/cppu/inc/com/sun/star/uno/Any.h new file mode 100644 index 000000000000..c9e8aed205e1 --- /dev/null +++ b/cppu/inc/com/sun/star/uno/Any.h @@ -0,0 +1,383 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_ANY_H_ +#define _COM_SUN_STAR_UNO_ANY_H_ + +#include <uno/any2.h> +#include <typelib/typedescription.h> +#include <com/sun/star/uno/Type.h> +#include "cppu/unotype.hxx" +#include <rtl/alloc.h> + + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +/** C++ class representing an IDL any. + This class is used to transport any type defined in IDL. The class inherits from the + binary C representation of uno_Any. + You can insert a value by either using the <<= operators or the template function makeAny(). + No any can hold an any. You can extract values from an any by using the >>= operators which + return true if the any contains an assignable value (no data loss), e.g. the any contains a + short and you >>= it into a long variable. +*/ +class Any : public uno_Any +{ +public: + // these are here to force memory de/allocation to sal lib. + /** @internal */ + inline static void * SAL_CALL operator new ( size_t nSize ) SAL_THROW( () ) + { return ::rtl_allocateMemory( nSize ); } + /** @internal */ + inline static void SAL_CALL operator delete ( void * pMem ) SAL_THROW( () ) + { ::rtl_freeMemory( pMem ); } + /** @internal */ + inline static void * SAL_CALL operator new ( size_t, void * pMem ) SAL_THROW( () ) + { return pMem; } + /** @internal */ + inline static void SAL_CALL operator delete ( void *, void * ) SAL_THROW( () ) + {} + + /** Default constructor: Any holds no value; its type is void. + */ + inline Any() SAL_THROW( () ); + + /** Templated ctor. Sets a copy of the given value. + + @param value value of the Any + */ + template <typename T> + explicit inline Any( T const & value ); + /// Ctor support for C++ bool. + explicit inline Any( bool value ); + + /** Copy constructor: Sets value of the given any. + + @param rAny another any + */ + inline Any( const Any & rAny ) SAL_THROW( () ); + + /** Constructor: Sets a copy of the given data. + + @param pData_ value + @param rType type of value + */ + inline Any( const void * pData_, const Type & rType ) SAL_THROW( () ); + + /** Constructor: Sets a copy of the given data. + + @param pData_ value + @param pTypeDescr type of value + */ + inline Any( const void * pData_, typelib_TypeDescription * pTypeDescr ) SAL_THROW( () ); + + /** Constructor: Sets a copy of the given data. + + @param pData_ value + @param pType type of value + */ + inline Any( const void * pData_, typelib_TypeDescriptionReference * pType ) SAL_THROW( () ); + + /** Destructor: Destructs any content and frees memory. + */ + inline ~Any() SAL_THROW( () ); + + /** Assignment operator: Sets the value of the given any. + + @param rAny another any (right side) + @return this any + */ + inline Any & SAL_CALL operator = ( const Any & rAny ) SAL_THROW( () ); + + /** Gets the type of the set value. + + @return a Type object of the set value + */ + inline const Type & SAL_CALL getValueType() const SAL_THROW( () ) + { return * reinterpret_cast< const Type * >( &pType ); } + /** Gets the type of the set value. + + @return the UNacquired type description reference of the set value + */ + inline typelib_TypeDescriptionReference * SAL_CALL getValueTypeRef() const SAL_THROW( () ) + { return pType; } + + /** Gets the type description of the set value. Provides ownership of the type description! + Call an explicit typelib_typedescription_release() to release afterwards. + + @param a pointer to type description pointer + */ + inline void SAL_CALL getValueTypeDescription( typelib_TypeDescription ** ppTypeDescr ) const SAL_THROW( () ) + { ::typelib_typedescriptionreference_getDescription( ppTypeDescr, pType ); } + + /** Gets the type class of the set value. + + @return the type class of the set value + */ + inline TypeClass SAL_CALL getValueTypeClass() const SAL_THROW( () ) + { return (TypeClass)pType->eTypeClass; } + + /** Gets the type name of the set value. + + @return the type name of the set value + */ + inline ::rtl::OUString SAL_CALL getValueTypeName() const SAL_THROW( () ); + + /** Tests if any contains a value. + + @return true if any has a value, false otherwise + */ + inline sal_Bool SAL_CALL hasValue() const SAL_THROW( () ) + { return (typelib_TypeClass_VOID != pType->eTypeClass); } + + /** Gets a pointer to the set value. + + @return a pointer to the set value + */ + inline const void * SAL_CALL getValue() const SAL_THROW( () ) + { return pData; } + +#if ! defined(EXCEPTIONS_OFF) + /** Provides a value of specified type, so you can easily write e.g. + <pre> + sal_Int32 myVal = myAny.get<sal_Int32>(); + </pre> + Widening conversion without data loss is taken into account. + Throws a + <type scope="com::sun::star::uno">RuntimeException</type> + if the specified type cannot be provided. + + @return value of specified type + @exception <type scope="com::sun::star::uno">RuntimeException</type> + in case the specified type cannot be provided + */ + template <typename T> + inline T get() const; +#endif // ! defined(EXCEPTIONS_OFF) + + /** Sets a value. If the any already contains a value, that value will be destructed + and its memory freed. + + @param pData_ pointer to value + @param rType type of value + */ + inline void SAL_CALL setValue( const void * pData_, const Type & rType ) SAL_THROW( () ); + /** Sets a value. If the any already contains a value, that value will be destructed + and its memory freed. + + @param pData_ pointer to value + @param pType type of value + */ + inline void SAL_CALL setValue( const void * pData_, typelib_TypeDescriptionReference * pType ) SAL_THROW( () ); + /** Sets a value. If the any already contains a value, that value will be destructed + and its memory freed. + + @param pData_ pointer to value + @param pTypeDescr type description of value + */ + inline void SAL_CALL setValue( const void * pData_, typelib_TypeDescription * pTypeDescr ) SAL_THROW( () ); + + /** Clears this any. If the any already contains a value, that value will be destructed + and its memory freed. After this has been called, the any does not contain a value. + */ + inline void SAL_CALL clear() SAL_THROW( () ); + + /** Tests whether this any is extractable to a value of given type. + Widening conversion without data loss is taken into account. + + @param rType destination type + @return true if this any is extractable to value of given type (e.g. using >>= operator) + */ + inline sal_Bool SAL_CALL isExtractableTo( const Type & rType ) const SAL_THROW( () ); + + /** Tests whether this any can provide a value of specified type. + Widening conversion without data loss is taken into account. + + @return true if this any can provide a value of specified type + (e.g. using >>= operator) + */ + template <typename T> + inline bool has() const; + + /** Equality operator: compares two anys. + The values need not be of equal type, e.g. a short integer is compared to a long integer. + + @param rAny another any (right side) + @return true if both any contains equal values + */ + inline sal_Bool SAL_CALL operator == ( const Any & rAny ) const SAL_THROW( () ); + /** Unequality operator: compares two anys. + The values need not be of equal type, e.g. a short integer is compared to a long integer. + + @param rAny another any (right side) + @return true if both any contains unequal values + */ + inline sal_Bool SAL_CALL operator != ( const Any & rAny ) const SAL_THROW( () ); + +private: + // not impl: forbid use with ambiguous type (sal_Unicode, sal_uInt16) + explicit Any( sal_uInt16 ); +#if defined(_MSC_VER) + // Omitting the following private declarations leads to an internal compiler + // error on MSVC (version 1310). + // not impl: forbid use with ambiguous type (sal_Unicode, sal_uInt16) +#if ! defined(EXCEPTIONS_OFF) + template <> + sal_uInt16 get<sal_uInt16>() const; +#endif // ! defined(EXCEPTIONS_OFF) + template <> + bool has<sal_uInt16>() const; +#endif // defined(_MSC_VER) +}; + +/** Template function to generically construct an any from a C++ value. + + @tplparam C value type + @param value a value + @return an any +*/ +template< class C > +inline Any SAL_CALL makeAny( const C & value ) SAL_THROW( () ); + +// additionally specialized for C++ bool +template<> +inline Any SAL_CALL makeAny( bool const & value ) SAL_THROW( () ); + +class BaseReference; +class Type; + +/** Template binary <<= operator to set the value of an any. + + @tplparam C value type + @param rAny destination any (left side) + @param value source value (right side) +*/ +template< class C > +inline void SAL_CALL operator <<= ( Any & rAny, const C & value ) SAL_THROW( () ); + +// additionally for C++ bool: +inline void SAL_CALL operator <<= ( Any & rAny, bool const & value ) + SAL_THROW( () ); + +/** Template binary >>= operator to assign a value from an any. + If the any does not contain a value that can be assigned without data loss, then this + operation will fail returning false. + + @tplparam C value type + @param rAny source any (left side) + @param value destination value (right side) + @return true if assignment was possible without data loss +*/ +template< class C > +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, C & value ) SAL_THROW( () ); + +/** Template equality operator: compares set value of left side any to right side value. + The values need not be of equal type, e.g. a short integer is compared to a long integer. + This operator can be implemented as template member function, if all supported compilers + can cope with template member functions. + + @tplparam C value type + @param rAny another any (left side) + @param value a value (right side) + @return true if values are equal, false otherwise +*/ +template< class C > +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const C & value ) SAL_THROW( () ); +/** Template unequality operator: compares set value of left side any to right side value. + The values need not be of equal type, e.g. a short integer is compared to a long integer. + This operator can be implemented as template member function, if all supported compilers + can cope with template member functions. + + @tplparam C value type + @param rAny another any (left side) + @param value a value (right side) + @return true if values are unequal, false otherwise +*/ +template< class C > +inline sal_Bool SAL_CALL operator != ( const Any & rAny, const C & value ) SAL_THROW( () ); + +// additional specialized >>= and == operators +// bool +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_Bool & value ) SAL_THROW( () ); +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const sal_Bool & value ) SAL_THROW( () ); +template<> +inline sal_Bool SAL_CALL operator >>= ( Any const & rAny, bool & value ) + SAL_THROW( () ); +template<> +inline sal_Bool SAL_CALL operator == ( Any const & rAny, bool const & value ) + SAL_THROW( () ); +// byte +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_Int8 & value ) SAL_THROW( () ); +// short +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_Int16 & value ) SAL_THROW( () ); +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt16 & value ) SAL_THROW( () ); +// long +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_Int32 & value ) SAL_THROW( () ); +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt32 & value ) SAL_THROW( () ); +// hyper +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_Int64 & value ) SAL_THROW( () ); +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt64 & value ) SAL_THROW( () ); +// float +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, float & value ) SAL_THROW( () ); +// double +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, double & value ) SAL_THROW( () ); +// string +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, ::rtl::OUString & value ) SAL_THROW( () ); +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const ::rtl::OUString & value ) SAL_THROW( () ); +// type +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, Type & value ) SAL_THROW( () ); +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const Type & value ) SAL_THROW( () ); +// any +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, Any & value ) SAL_THROW( () ); +// interface +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const BaseReference & value ) SAL_THROW( () ); + +} +} +} +} + +/** Gets the meta type of IDL type any. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type any +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const ::com::sun::star::uno::Any * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::com::sun::star::uno::Any >::get(); +} + +#endif diff --git a/cppu/inc/com/sun/star/uno/Any.hxx b/cppu/inc/com/sun/star/uno/Any.hxx new file mode 100644 index 000000000000..44508556698c --- /dev/null +++ b/cppu/inc/com/sun/star/uno/Any.hxx @@ -0,0 +1,589 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_ANY_HXX_ +#define _COM_SUN_STAR_UNO_ANY_HXX_ + +#include <com/sun/star/uno/Any.h> +#include <uno/data.h> +#include <com/sun/star/uno/Type.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/uno/genfunc.hxx> +#include "cppu/unotype.hxx" + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +//__________________________________________________________________________________________________ +inline Any::Any() SAL_THROW( () ) +{ + ::uno_any_construct( this, 0, 0, (uno_AcquireFunc)cpp_acquire ); +} + +//______________________________________________________________________________ +template <typename T> +inline Any::Any( T const & value ) +{ + ::uno_type_any_construct( + this, const_cast<T *>(&value), + ::cppu::getTypeFavourUnsigned(&value).getTypeLibType(), + (uno_AcquireFunc) cpp_acquire ); +} +//______________________________________________________________________________ +inline Any::Any( bool value ) +{ + sal_Bool b = value; + ::uno_type_any_construct( + this, &b, ::getCppuBooleanType().getTypeLibType(), + (uno_AcquireFunc) cpp_acquire ); +} + +//__________________________________________________________________________________________________ +inline Any::Any( const Any & rAny ) SAL_THROW( () ) +{ + ::uno_type_any_construct( this, rAny.pData, rAny.pType, (uno_AcquireFunc)cpp_acquire ); +} +//__________________________________________________________________________________________________ +inline Any::Any( const void * pData_, const Type & rType ) SAL_THROW( () ) +{ + ::uno_type_any_construct( + this, const_cast< void * >( pData_ ), rType.getTypeLibType(), + (uno_AcquireFunc)cpp_acquire ); +} +//__________________________________________________________________________________________________ +inline Any::Any( const void * pData_, typelib_TypeDescription * pTypeDescr ) SAL_THROW( () ) +{ + ::uno_any_construct( + this, const_cast< void * >( pData_ ), pTypeDescr, (uno_AcquireFunc)cpp_acquire ); +} +//__________________________________________________________________________________________________ +inline Any::Any( const void * pData_, typelib_TypeDescriptionReference * pType_ ) SAL_THROW( () ) +{ + ::uno_type_any_construct( + this, const_cast< void * >( pData_ ), pType_, (uno_AcquireFunc)cpp_acquire ); +} +//__________________________________________________________________________________________________ +inline Any::~Any() SAL_THROW( () ) +{ + ::uno_any_destruct( + this, (uno_ReleaseFunc)cpp_release ); +} +//__________________________________________________________________________________________________ +inline Any & Any::operator = ( const Any & rAny ) SAL_THROW( () ) +{ + if (this != &rAny) + { + ::uno_type_any_assign( + this, rAny.pData, rAny.pType, + (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); + } + return *this; +} +//__________________________________________________________________________________________________ +inline ::rtl::OUString Any::getValueTypeName() const SAL_THROW( () ) +{ + return ::rtl::OUString( pType->pTypeName ); +} +//__________________________________________________________________________________________________ +inline void Any::setValue( const void * pData_, const Type & rType ) SAL_THROW( () ) +{ + ::uno_type_any_assign( + this, const_cast< void * >( pData_ ), rType.getTypeLibType(), + (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); +} +//__________________________________________________________________________________________________ +inline void Any::setValue( const void * pData_, typelib_TypeDescriptionReference * pType_ ) SAL_THROW( () ) +{ + ::uno_type_any_assign( + this, const_cast< void * >( pData_ ), pType_, + (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); +} +//__________________________________________________________________________________________________ +inline void Any::setValue( const void * pData_, typelib_TypeDescription * pTypeDescr ) SAL_THROW( () ) +{ + ::uno_any_assign( + this, const_cast< void * >( pData_ ), pTypeDescr, + (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); +} +//__________________________________________________________________________________________________ +inline void Any::clear() SAL_THROW( () ) +{ + ::uno_any_clear( + this, (uno_ReleaseFunc)cpp_release ); +} +//__________________________________________________________________________________________________ +inline sal_Bool Any::isExtractableTo( const Type & rType ) const SAL_THROW( () ) +{ + return ::uno_type_isAssignableFromData( + rType.getTypeLibType(), pData, pType, + (uno_QueryInterfaceFunc)cpp_queryInterface, (uno_ReleaseFunc)cpp_release ); +} + +//______________________________________________________________________________ +template <typename T> +inline bool Any::has() const +{ + Type const & rType = ::cppu::getTypeFavourUnsigned(static_cast< T * >(0)); + return ::uno_type_isAssignableFromData( + rType.getTypeLibType(), pData, pType, + (uno_QueryInterfaceFunc) cpp_queryInterface, + (uno_ReleaseFunc) cpp_release ); +} +#if ! defined(__SUNPRO_CC) +// not impl: forbid use with ambiguous type (sal_Unicode, sal_uInt16) +template <> +bool Any::has<sal_uInt16>() const; +#endif // ! defined(__SUNPRO_CC) + +//__________________________________________________________________________________________________ +inline sal_Bool Any::operator == ( const Any & rAny ) const SAL_THROW( () ) +{ + return ::uno_type_equalData( + pData, pType, rAny.pData, rAny.pType, + (uno_QueryInterfaceFunc)cpp_queryInterface, (uno_ReleaseFunc)cpp_release ); +} +//__________________________________________________________________________________________________ +inline sal_Bool Any::operator != ( const Any & rAny ) const SAL_THROW( () ) +{ + return (! ::uno_type_equalData( + pData, pType, rAny.pData, rAny.pType, + (uno_QueryInterfaceFunc)cpp_queryInterface, (uno_ReleaseFunc)cpp_release )); +} + +//__________________________________________________________________________________________________ +template< class C > +inline Any SAL_CALL makeAny( const C & value ) SAL_THROW( () ) +{ + return Any( &value, ::cppu::getTypeFavourUnsigned(&value) ); +} + +// additionally specialized for C++ bool +//______________________________________________________________________________ +template<> +inline Any SAL_CALL makeAny( bool const & value ) SAL_THROW( () ) +{ + const sal_Bool b = value; + return Any( &b, ::getCppuBooleanType() ); +} + +//__________________________________________________________________________________________________ +template< class C > +inline void SAL_CALL operator <<= ( Any & rAny, const C & value ) SAL_THROW( () ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned(&value); + ::uno_type_any_assign( + &rAny, const_cast< C * >( &value ), rType.getTypeLibType(), + (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); +} + +// additionally for C++ bool: +//______________________________________________________________________________ +inline void SAL_CALL operator <<= ( Any & rAny, bool const & value ) + SAL_THROW( () ) +{ + sal_Bool b = value; + ::uno_type_any_assign( + &rAny, &b, ::getCppuBooleanType().getTypeLibType(), + (uno_AcquireFunc) cpp_acquire, (uno_ReleaseFunc) cpp_release ); +} + +//__________________________________________________________________________________________________ +template< class C > +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, C & value ) SAL_THROW( () ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned(&value); + return ::uno_type_assignData( + &value, rType.getTypeLibType(), + rAny.pData, rAny.pType, + (uno_QueryInterfaceFunc)cpp_queryInterface, + (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); +} + +// bool +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const ::com::sun::star::uno::Any & rAny, sal_Bool & value ) SAL_THROW( () ) +{ + if (typelib_TypeClass_BOOLEAN == rAny.pType->eTypeClass) + { + value = (* reinterpret_cast< const sal_Bool * >( &rAny.pReserved ) != sal_False); + return sal_True; + } + return sal_False; +} +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const sal_Bool & value ) SAL_THROW( () ) +{ + return (typelib_TypeClass_BOOLEAN == rAny.pType->eTypeClass && + (value != sal_False) == (* reinterpret_cast< const sal_Bool * >( &rAny.pReserved ) != sal_False)); +} + +//______________________________________________________________________________ +template<> +inline sal_Bool SAL_CALL operator >>= ( Any const & rAny, bool & value ) + SAL_THROW( () ) +{ + if (rAny.pType->eTypeClass == typelib_TypeClass_BOOLEAN) + { + value = *reinterpret_cast< sal_Bool const * >( + &rAny.pReserved ) != sal_False; + return true; + } + return false; +} + +//______________________________________________________________________________ +template<> +inline sal_Bool SAL_CALL operator == ( Any const & rAny, bool const & value ) + SAL_THROW( () ) +{ + return (rAny.pType->eTypeClass == typelib_TypeClass_BOOLEAN && + (value == + (*reinterpret_cast< sal_Bool const * >( &rAny.pReserved ) + != sal_False))); +} + +// byte +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const ::com::sun::star::uno::Any & rAny, sal_Int8 & value ) SAL_THROW( () ) +{ + if (typelib_TypeClass_BYTE == rAny.pType->eTypeClass) + { + value = * reinterpret_cast< const sal_Int8 * >( &rAny.pReserved ); + return sal_True; + } + return sal_False; +} +// short +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_Int16 & value ) SAL_THROW( () ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * reinterpret_cast< const sal_Int8 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + value = * reinterpret_cast< const sal_Int16 * >( &rAny.pReserved ); + return sal_True; + default: + return sal_False; + } +} +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt16 & value ) SAL_THROW( () ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * reinterpret_cast< const sal_Int8 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + value = * reinterpret_cast< const sal_uInt16 * >( &rAny.pReserved ); + return sal_True; + default: + return sal_False; + } +} +// long +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_Int32 & value ) SAL_THROW( () ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * reinterpret_cast< const sal_Int8 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_SHORT: + value = * reinterpret_cast< const sal_Int16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * reinterpret_cast< const sal_uInt16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + value = * reinterpret_cast< const sal_Int32 * >( &rAny.pReserved ); + return sal_True; + default: + return sal_False; + } +} +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt32 & value ) SAL_THROW( () ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * reinterpret_cast< const sal_Int8 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_SHORT: + value = * reinterpret_cast< const sal_Int16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * reinterpret_cast< const sal_uInt16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + value = * reinterpret_cast< const sal_uInt32 * >( &rAny.pReserved ); + return sal_True; + default: + return sal_False; + } +} +// hyper +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_Int64 & value ) SAL_THROW( () ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * reinterpret_cast< const sal_Int8 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_SHORT: + value = * reinterpret_cast< const sal_Int16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * reinterpret_cast< const sal_uInt16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_LONG: + value = * reinterpret_cast< const sal_Int32 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_UNSIGNED_LONG: + value = * reinterpret_cast< const sal_uInt32 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + value = * reinterpret_cast< const sal_Int64 * >( + (sizeof(void *) >= sizeof(sal_Int64)) ? (void *)&rAny.pReserved : rAny.pData ); + return sal_True; + + default: + return sal_False; + } +} +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt64 & value ) SAL_THROW( () ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * reinterpret_cast< const sal_Int8 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_SHORT: + value = * reinterpret_cast< const sal_Int16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * reinterpret_cast< const sal_uInt16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_LONG: + value = * reinterpret_cast< const sal_Int32 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_UNSIGNED_LONG: + value = * reinterpret_cast< const sal_uInt32 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + value = * reinterpret_cast< const sal_uInt64 * >( + (sizeof(void *) >= sizeof(sal_uInt64)) ? (void *)&rAny.pReserved : rAny.pData ); + return sal_True; + + default: + return sal_False; + } +} +// float +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, float & value ) SAL_THROW( () ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * reinterpret_cast< const sal_Int8 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_SHORT: + value = * reinterpret_cast< const sal_Int16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * reinterpret_cast< const sal_uInt16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_FLOAT: + value = * reinterpret_cast< const float * >( + (sizeof(void *) >= sizeof(float)) ? (void *)&rAny.pReserved : rAny.pData ); + return sal_True; + + default: + return sal_False; + } +} +// double +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, double & value ) SAL_THROW( () ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * reinterpret_cast< const sal_Int8 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_SHORT: + value = * reinterpret_cast< const sal_Int16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * reinterpret_cast< const sal_uInt16 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_LONG: + value = * reinterpret_cast< const sal_Int32 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_UNSIGNED_LONG: + value = * reinterpret_cast< const sal_uInt32 * >( &rAny.pReserved ); + return sal_True; + case typelib_TypeClass_FLOAT: + value = * reinterpret_cast< const float * >( + (sizeof(void *) >= sizeof(float)) ? (void *)&rAny.pReserved : rAny.pData ); + return sal_True; + case typelib_TypeClass_DOUBLE: + value = * reinterpret_cast< const double * >( + (sizeof(void *) >= sizeof(double)) ? (void *)&rAny.pReserved : rAny.pData ); + return sal_True; + + default: + return sal_False; + } +} +// string +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, ::rtl::OUString & value ) SAL_THROW( () ) +{ + if (typelib_TypeClass_STRING == rAny.pType->eTypeClass) + { + value = * reinterpret_cast< const ::rtl::OUString * >( &rAny.pReserved ); + return sal_True; + } + return sal_False; +} +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const ::rtl::OUString & value ) SAL_THROW( () ) +{ + return (typelib_TypeClass_STRING == rAny.pType->eTypeClass && + value.equals( * reinterpret_cast< const ::rtl::OUString * >( &rAny.pReserved ) )); +} +// type +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, Type & value ) SAL_THROW( () ) +{ + if (typelib_TypeClass_TYPE == rAny.pType->eTypeClass) + { + value = * reinterpret_cast< const Type * >( &rAny.pReserved ); + return sal_True; + } + return sal_False; +} +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const Type & value ) SAL_THROW( () ) +{ + return (typelib_TypeClass_TYPE == rAny.pType->eTypeClass && + value.equals( * reinterpret_cast< const Type * >( &rAny.pReserved ) )); +} +// any +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, Any & value ) SAL_THROW( () ) +{ + if (&rAny != &value) + { + ::uno_type_any_assign( + &value, rAny.pData, rAny.pType, + (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); + } + return sal_True; +} +// interface +//__________________________________________________________________________________________________ +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const BaseReference & value ) SAL_THROW( () ) +{ + if (typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass) + { + return reinterpret_cast< const BaseReference * >( &rAny.pReserved )->operator == ( value ); + } + return sal_False; +} + +// operator to compare to an any. +//__________________________________________________________________________________________________ +template< class C > +inline sal_Bool SAL_CALL operator == ( const Any & rAny, const C & value ) SAL_THROW( () ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned(&value); + return ::uno_type_equalData( + rAny.pData, rAny.pType, + const_cast< C * >( &value ), rType.getTypeLibType(), + (uno_QueryInterfaceFunc)cpp_queryInterface, (uno_ReleaseFunc)cpp_release ); +} +// operator to compare to an any. may use specialized operators ==. +//__________________________________________________________________________________________________ +template< class C > +inline sal_Bool SAL_CALL operator != ( const Any & rAny, const C & value ) SAL_THROW( () ) +{ + return (! operator == ( rAny, value )); +} + +#if ! defined(EXCEPTIONS_OFF) +extern "C" rtl_uString * SAL_CALL cppu_Any_extraction_failure_msg( + uno_Any const * pAny, typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C(); + +//______________________________________________________________________________ +template <typename T> +T Any::get() const +{ + T value = T(); + if (! (*this >>= value)) { + throw RuntimeException( + ::rtl::OUString( + cppu_Any_extraction_failure_msg( + this, + ::cppu::getTypeFavourUnsigned(&value).getTypeLibType() ), + SAL_NO_ACQUIRE ), + Reference<XInterface>() ); + } + return value; +} +// not impl: forbid use with ambiguous type (sal_Unicode, sal_uInt16) +template <> +sal_uInt16 Any::get<sal_uInt16>() const; +#endif // ! defined(EXCEPTIONS_OFF) + +} +} +} +} + +#endif diff --git a/cppu/inc/com/sun/star/uno/Reference.h b/cppu/inc/com/sun/star/uno/Reference.h new file mode 100644 index 000000000000..f792556dcb57 --- /dev/null +++ b/cppu/inc/com/sun/star/uno/Reference.h @@ -0,0 +1,533 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_REFERENCE_H_ +#define _COM_SUN_STAR_UNO_REFERENCE_H_ + +#include <rtl/alloc.h> + + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +class RuntimeException; +class XInterface; +class Type; +class Any; + +/** Enum defining UNO_REF_NO_ACQUIRE for setting reference without acquiring a given interface. + Deprecated, please use SAL_NO_ACQUIRE. + @deprecated +*/ +enum UnoReference_NoAcquire +{ + /** This enum value can be used for creating a reference granting a given interface, + i.e. transferring ownership to it. + */ + UNO_REF_NO_ACQUIRE +}; + +/** This base class serves as a base class for all template reference classes and + has been introduced due to compiler problems with templated operators ==, =!. +*/ +class BaseReference +{ +protected: + /** the interface pointer + */ + XInterface * _pInterface; + + /** Queries given interface for type rType. + + @param pInterface interface pointer + @param rType interface type + @return interface of demanded type (may be null) + */ + inline static XInterface * SAL_CALL iquery( XInterface * pInterface, const Type & rType ) + SAL_THROW( (RuntimeException) ); +#ifndef EXCEPTIONS_OFF + /** Queries given interface for type rType. + Throws a RuntimeException if the demanded interface cannot be queried. + + @param pInterface interface pointer + @param rType interface type + @return interface of demanded type + */ + inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface, const Type & rType ) + SAL_THROW( (RuntimeException) ); +#endif + +public: + /** Gets interface pointer. This call does not acquire the interface. + + @return UNacquired interface pointer + */ + inline XInterface * SAL_CALL get() const SAL_THROW( () ) + { return _pInterface; } + + /** Checks if reference is null. + + @return true if reference acquires an interface, i.e. true if it is not null + */ + inline sal_Bool SAL_CALL is() const SAL_THROW( () ) + { return (0 != _pInterface); } + + /** Equality operator: compares two interfaces + Checks if both references are null or refer to the same object. + + @param rRef another interface + @return true if both references are null or refer to the same object, false otherwise + */ + inline sal_Bool SAL_CALL operator == ( XInterface * pInterface ) const SAL_THROW( () ); + /** Unequality operator: compares two interfaces + Checks if both references are null or refer to the same object. + + @param rRef another interface + @return false if both references are null or refer to the same object, true otherwise + */ + inline sal_Bool SAL_CALL operator != ( XInterface * pInterface ) const SAL_THROW( () ); + + /** Equality operator: compares two interfaces + Checks if both references are null or refer to the same object. + + @param rRef another reference + @return true if both references are null or refer to the same object, false otherwise + */ + inline sal_Bool SAL_CALL operator == ( const BaseReference & rRef ) const SAL_THROW( () ); + /** Unequality operator: compares two interfaces + Checks if both references are null or refer to the same object. + + @param rRef another reference + @return false if both references are null or refer to the same object, true otherwise + */ + inline sal_Bool SAL_CALL operator != ( const BaseReference & rRef ) const SAL_THROW( () ); + + /** Needed by some STL containers. + + @param rRef another reference + @return true, if this reference is less than rRef + */ + inline sal_Bool SAL_CALL operator < ( const BaseReference & rRef ) const SAL_THROW( () ); +}; + +/** Enum defining UNO_QUERY and UNO_REF_QUERY for implicit interface query. +*/ +enum UnoReference_Query +{ + /** This enum value can be used for implicit interface query. + */ + UNO_QUERY, + /** This enum value can be used for implicit interface query. + */ + UNO_REF_QUERY +}; +#ifndef EXCEPTIONS_OFF +/** Enum defining UNO_QUERY_THROW and UNO_REF_QUERY_THROW for implicit interface query. + If the demanded interface is unavailable, then a RuntimeException is thrown. +*/ +enum UnoReference_QueryThrow +{ + /** This enum value can be used for implicit interface query. + */ + UNO_QUERY_THROW, + /** This enum value can be used for implicit interface query. + */ + UNO_REF_QUERY_THROW +}; +/** Enum defining UNO_SET_THROW for throwing if attempts are made to assign a <NULL/> + interface + + @since UDK 3.2.8 +*/ +enum UnoReference_SetThrow +{ + UNO_SET_THROW +}; +#endif + +/** Template reference class for interface type derived from BaseReference. + A special constructor given the UNO_QUERY or UNO_REF_QUERY identifier queries interfaces + for reference type. +*/ +template< class interface_type > +class Reference : public BaseReference +{ + /** Queries given interface for type interface_type. + + @param pInterface interface pointer + @return interface of demanded type (may be null) + */ + inline static XInterface * SAL_CALL iquery( XInterface * pInterface ) + SAL_THROW( (RuntimeException) ); +#ifndef EXCEPTIONS_OFF + /** Queries given interface for type interface_type. + Throws a RuntimeException if the demanded interface cannot be queried. + + @param pInterface interface pointer + @return interface of demanded type + */ + inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface ) + SAL_THROW( (RuntimeException) ); + /** Returns the given interface if it is not <NULL/>, throws a RuntimeException otherwise. + + @param pInterface interface pointer + @return pInterface + */ + inline static interface_type * SAL_CALL iset_throw( interface_type * pInterface ) + SAL_THROW( (RuntimeException) ); +#endif + + /** Cast from an "interface pointer" (e.g., BaseReference::_pInterface) to a + pointer to this interface_type. + + To work around ambiguities in the case of multiple-inheritance interface + types (which inherit XInterface more than once), use reinterpret_cast + (resp. a sequence of two static_casts, to avoid warnings about + reinterpret_cast used between related classes) to switch from a pointer + to XInterface to a pointer to this derived interface_type. In + principle, this is not guaranteed to work. In practice, it seems to + work on all supported platforms. + */ + static inline interface_type * castFromXInterface(XInterface * p) { + return static_cast< interface_type * >(static_cast< void * >(p)); + } + + /** Cast from a pointer to this interface_type to an "interface pointer" + (e.g., BaseReference::_pInterface). + + To work around ambiguities in the case of multiple-inheritance interface + types (which inherit XInterface more than once), use reinterpret_cast + (resp. a sequence of two static_casts, to avoid warnings about + reinterpret_cast used between related classes) to switch from a pointer + to this derived interface_type to a pointer to XInterface. In + principle, this is not guaranteed to work. In practice, it seems to + work on all supported platforms. + */ + static inline XInterface * castToXInterface(interface_type * p) { + return static_cast< XInterface * >(static_cast< void * >(p)); + } + +public: + // these are here to force memory de/allocation to sal lib. + /** @internal */ + inline static void * SAL_CALL operator new ( size_t nSize ) SAL_THROW( () ) + { return ::rtl_allocateMemory( nSize ); } + /** @internal */ + inline static void SAL_CALL operator delete ( void * pMem ) SAL_THROW( () ) + { ::rtl_freeMemory( pMem ); } + /** @internal */ + inline static void * SAL_CALL operator new ( size_t, void * pMem ) SAL_THROW( () ) + { return pMem; } + /** @internal */ + inline static void SAL_CALL operator delete ( void *, void * ) SAL_THROW( () ) + {} + + /** Destructor: Releases interface if set. + */ + inline ~Reference() SAL_THROW( () ); + + /** Default Constructor: Sets null reference. + */ + inline Reference() SAL_THROW( () ); + + /** Copy constructor: Copies interface reference. + + @param rRef another reference + */ + inline Reference( const Reference< interface_type > & rRef ) SAL_THROW( () ); + /** Constructor: Sets given interface pointer. + + @param pInterface an interface pointer + */ + inline Reference( interface_type * pInterface ) SAL_THROW( () ); + + /** Constructor: Sets given interface pointer without acquiring it. + + @param pInterface another reference + @param dummy SAL_NO_ACQUIRE to force obvious distinction to other constructors + */ + inline Reference( interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () ); + /** Constructor: Sets given interface pointer without acquiring it. + Deprecated, please use SAL_NO_ACQUIRE version. + + @deprecated + @param pInterface another reference + @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to other constructors + */ + inline Reference( interface_type * pInterface, UnoReference_NoAcquire ) SAL_THROW( () ); + + /** Constructor: Queries given interface for reference interface type (interface_type). + + @param rRef another reference + @param dummy UNO_QUERY or UNO_REF_QUERY to force obvious distinction to other constructors + */ + inline Reference( const BaseReference & rRef, UnoReference_Query ) SAL_THROW( (RuntimeException) ); + /** Constructor: Queries given interface for reference interface type (interface_type). + + @param pInterface an interface pointer + @param dummy UNO_QUERY to force obvious distinction to other constructors + */ + inline Reference( XInterface * pInterface, UnoReference_Query ) SAL_THROW( (RuntimeException) ); + /** Constructor: Queries given any for reference interface type (interface_type). + + @param rAny an any + @param dummy UNO_QUERY to force obvious distinction to other constructors + */ + inline Reference( const Any & rAny, UnoReference_Query ) SAL_THROW( (RuntimeException) ); +#ifndef EXCEPTIONS_OFF + /** Constructor: Queries given interface for reference interface type (interface_type). + Throws a RuntimeException if the demanded interface cannot be queried. + + @param rRef another reference + @param dummy UNO_QUERY_THROW or UNO_REF_QUERY_THROW to force obvious distinction + to other constructors + */ + inline Reference( const BaseReference & rRef, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ); + /** Constructor: Queries given interface for reference interface type (interface_type). + Throws a RuntimeException if the demanded interface cannot be queried. + + @param pInterface an interface pointer + @param dummy UNO_QUERY_THROW or UNO_REF_QUERY_THROW to force obvious distinction + to other constructors + */ + inline Reference( XInterface * pInterface, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ); + /** Constructor: Queries given any for reference interface type (interface_type). + Throws a RuntimeException if the demanded interface cannot be queried. + + @param rAny an any + @param dummy UNO_QUERY_THROW or UNO_REF_QUERY_THROW to force obvious distinction + to other constructors + */ + inline Reference( const Any & rAny, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ); + /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException + if the source interface is <NULL/>. + + @param rRef another interface reference of the same type + @param dummy UNO_SET_THROW to distinguish from default copy constructor + + @since UDK 3.2.8 + */ + inline Reference( const Reference< interface_type > & rRef, UnoReference_SetThrow ) SAL_THROW( (RuntimeException) ); + /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException + if the source interface is <NULL/>. + + @param pInterface an interface pointer + @param dummy UNO_SET_THROW to distinguish from default assignment constructor + + @since UDK 3.2.8 + */ + inline Reference( interface_type * pInterface, UnoReference_SetThrow ) SAL_THROW( (RuntimeException) ); +#endif + + /** Cast operator to Reference< XInterface >: Reference objects are binary compatible and + any interface must be derived from com.sun.star.uno.XInterface. + This a useful direct cast possibility. + */ + inline SAL_CALL operator const Reference< XInterface > & () const SAL_THROW( () ) + { return * reinterpret_cast< const Reference< XInterface > * >( this ); } + + /** Dereference operator: Used to call interface methods. + + @return UNacquired interface pointer + */ + inline interface_type * SAL_CALL operator -> () const SAL_THROW( () ) + { return castFromXInterface(_pInterface); } + + /** Gets interface pointer. This call does not acquire the interface. + + @return UNacquired interface pointer + */ + inline interface_type * SAL_CALL get() const SAL_THROW( () ) + { return castFromXInterface(_pInterface); } + + /** Clears reference, i.e. releases interface. Reference is null after clear() call. + */ + inline void SAL_CALL clear() SAL_THROW( () ); + + /** Sets the given interface. An interface already set will be released. + + @param rRef another reference + @return true, if non-null interface was set + */ + inline sal_Bool SAL_CALL set( const Reference< interface_type > & rRef ) SAL_THROW( () ); + /** Sets the given interface. An interface already set will be released. + + @param pInterface another interface + @return true, if non-null interface was set + */ + inline sal_Bool SAL_CALL set( interface_type * pInterface ) SAL_THROW( () ); + + /** Sets interface pointer without acquiring it. An interface already set will be released. + + @param pInterface an interface pointer + @param dummy SAL_NO_ACQUIRE to force obvious distinction to set methods + @return true, if non-null interface was set + */ + inline sal_Bool SAL_CALL set( interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () ); + /** Sets interface pointer without acquiring it. An interface already set will be released. + Deprecated, please use SAL_NO_ACQUIRE version. + + @deprecated + @param pInterface an interface pointer + @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to set methods + @return true, if non-null interface was set + */ + inline sal_Bool SAL_CALL set( interface_type * pInterface, UnoReference_NoAcquire ) SAL_THROW( () ); + + /** Queries given interface for reference interface type (interface_type) and sets it. + An interface already set will be released. + + @param pInterface an interface pointer + @param dummy UNO_QUERY or UNO_REF_QUERY to force obvious distinction to set methods + @return true, if non-null interface was set + */ + inline sal_Bool SAL_CALL set( XInterface * pInterface, UnoReference_Query ) SAL_THROW( (RuntimeException) ); + /** Queries given interface for reference interface type (interface_type) and sets it. + An interface already set will be released. + + @param rRef another reference + @param dummy UNO_QUERY or UNO_REF_QUERY to force obvious distinction to set methods + @return true, if non-null interface was set + */ + inline sal_Bool SAL_CALL set( const BaseReference & rRef, UnoReference_Query ) SAL_THROW( (RuntimeException) ); + + /** Queries given any for reference interface type (interface_type) + and sets it. An interface already set will be released. + + @param rAny + an Any containing an interface + @param dummy + UNO_QUERY or UNO_REF_QUERY to force obvious distinction + to set methods + @return + true, if non-null interface was set + */ + inline bool set( Any const & rAny, UnoReference_Query ); + +#ifndef EXCEPTIONS_OFF + /** Queries given interface for reference interface type (interface_type) and sets it. + An interface already set will be released. + Throws a RuntimeException if the demanded interface cannot be set. + + @param pInterface an interface pointer + @param dummy UNO_QUERY_THROW or UNO_REF_QUERY_THROW to force obvious distinction + to set methods + */ + inline void SAL_CALL set( XInterface * pInterface, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ); + /** Queries given interface for reference interface type (interface_type) and sets it. + An interface already set will be released. + Throws a RuntimeException if the demanded interface cannot be set. + + @param rRef another reference + @param dummy UNO_QUERY_THROW or UNO_REF_QUERY_THROW to force obvious distinction + to set methods + */ + inline void SAL_CALL set( const BaseReference & rRef, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ); + + /** Queries given any for reference interface type (interface_type) and + sets it. An interface already set will be released. + Throws a RuntimeException if the demanded interface cannot be set. + + @param rAny + an Any containing an interface + @param dummy + UNO_QUERY_THROW or UNO_REF_QUERY_THROW to force obvious + distinction to set methods + */ + inline void set( Any const & rAny, UnoReference_QueryThrow ); + /** sets the given interface + An interface already set will be released. + Throws a RuntimeException if the source interface is <NULL/>. + + @param pInterface an interface pointer + @param dummy UNO_SET_THROW to force obvious distinction to other set methods + + @since UDK 3.2.8 + */ + inline void SAL_CALL set( interface_type * pInterface, UnoReference_SetThrow ) SAL_THROW( (RuntimeException) ); + /** sets the given interface + An interface already set will be released. + Throws a RuntimeException if the source interface is <NULL/>. + + @param rRef an interface reference + @param dummy UNO_SET_THROW to force obvious distinction to other set methods + + @since UDK 3.2.8 + */ + inline void SAL_CALL set( const Reference< interface_type > & rRef, UnoReference_SetThrow ) SAL_THROW( (RuntimeException) ); + +#endif + + /** Assignment operator: Acquires given interface pointer and sets reference. + An interface already set will be released. + + @param pInterface an interface pointer + @return this reference + */ + inline Reference< interface_type > & SAL_CALL operator = ( interface_type * pInterface ) SAL_THROW( () ); + /** Assignment operator: Acquires given interface reference and sets reference. + An interface already set will be released. + + @param rRef an interface reference + @return this reference + */ + inline Reference< interface_type > & SAL_CALL operator = ( const Reference< interface_type > & rRef ) SAL_THROW( () ); + + /** Queries given interface reference for type interface_type. + + @param rRef interface reference + @return interface reference of demanded type (may be null) + */ + inline static Reference< interface_type > SAL_CALL query( const BaseReference & rRef ) SAL_THROW( (RuntimeException) ); + /** Queries given interface for type interface_type. + + @param pInterface interface pointer + @return interface reference of demanded type (may be null) + */ + inline static Reference< interface_type > SAL_CALL query( XInterface * pInterface ) SAL_THROW( (RuntimeException) ); +}; + +/** @internal + Enables boost::mem_fn and boost::bind to recognize Reference. +*/ +template <typename T> +inline T * get_pointer( Reference<T> const& r ) +{ + return r.get(); +} + +} +} +} +} + +#endif diff --git a/cppu/inc/com/sun/star/uno/Reference.hxx b/cppu/inc/com/sun/star/uno/Reference.hxx new file mode 100644 index 000000000000..4223cc277c37 --- /dev/null +++ b/cppu/inc/com/sun/star/uno/Reference.hxx @@ -0,0 +1,431 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#define _COM_SUN_STAR_UNO_REFERENCE_HXX_ + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/RuntimeException.hpp> +#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HDL_ +#include <com/sun/star/uno/XInterface.hdl> +#endif +#include <com/sun/star/uno/genfunc.hxx> + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +//__________________________________________________________________________________________________ +inline XInterface * BaseReference::iquery( + XInterface * pInterface, const Type & rType ) + SAL_THROW( (RuntimeException) ) +{ + if (pInterface) + { + Any aRet( pInterface->queryInterface( rType ) ); + if (typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass) + { + XInterface * pRet = static_cast< XInterface * >( aRet.pReserved ); + aRet.pReserved = 0; + return pRet; + } + } + return 0; +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline XInterface * Reference< interface_type >::iquery( + XInterface * pInterface ) SAL_THROW( (RuntimeException) ) +{ + return BaseReference::iquery(pInterface, interface_type::static_type()); +} +#ifndef EXCEPTIONS_OFF +extern "C" rtl_uString * SAL_CALL cppu_unsatisfied_iquery_msg( + typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C(); +extern "C" rtl_uString * SAL_CALL cppu_unsatisfied_iset_msg( + typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C(); +//__________________________________________________________________________________________________ +inline XInterface * BaseReference::iquery_throw( + XInterface * pInterface, const Type & rType ) + SAL_THROW( (RuntimeException) ) +{ + XInterface * pQueried = iquery( pInterface, rType ); + if (pQueried) + return pQueried; + throw RuntimeException( + ::rtl::OUString( cppu_unsatisfied_iquery_msg( rType.getTypeLibType() ), SAL_NO_ACQUIRE ), + Reference< XInterface >( pInterface ) ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline XInterface * Reference< interface_type >::iquery_throw( + XInterface * pInterface ) SAL_THROW( (RuntimeException) ) +{ + return BaseReference::iquery_throw( + pInterface, interface_type::static_type()); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline interface_type * Reference< interface_type >::iset_throw( + interface_type * pInterface ) SAL_THROW( (RuntimeException) ) +{ + if (pInterface) + { + pInterface->acquire(); + return pInterface; + } + throw RuntimeException( + ::rtl::OUString( cppu_unsatisfied_iset_msg( interface_type::static_type().getTypeLibType() ), SAL_NO_ACQUIRE ), + NULL ); +} +#endif + +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::~Reference() SAL_THROW( () ) +{ + if (_pInterface) + _pInterface->release(); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference() SAL_THROW( () ) +{ + _pInterface = 0; +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef ) SAL_THROW( () ) +{ + _pInterface = rRef._pInterface; + if (_pInterface) + _pInterface->acquire(); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( interface_type * pInterface ) SAL_THROW( () ) +{ + _pInterface = castToXInterface(pInterface); + if (_pInterface) + _pInterface->acquire(); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () ) +{ + _pInterface = castToXInterface(pInterface); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( interface_type * pInterface, UnoReference_NoAcquire ) SAL_THROW( () ) +{ + _pInterface = castToXInterface(pInterface); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_Query ) SAL_THROW( (RuntimeException) ) +{ + _pInterface = iquery( rRef.get() ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_Query ) SAL_THROW( (RuntimeException) ) +{ + _pInterface = iquery( pInterface ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_Query ) SAL_THROW( (RuntimeException) ) +{ + _pInterface = (typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass + ? iquery( static_cast< XInterface * >( rAny.pReserved ) ) : 0); +} +#ifndef EXCEPTIONS_OFF +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ) +{ + _pInterface = iquery_throw( rRef.get() ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ) +{ + _pInterface = iquery_throw( pInterface ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ) +{ + _pInterface = iquery_throw( typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass + ? static_cast< XInterface * >( rAny.pReserved ) : 0 ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef, UnoReference_SetThrow ) SAL_THROW( (RuntimeException) ) +{ + _pInterface = iset_throw( rRef.get() ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type >::Reference( interface_type * pInterface, UnoReference_SetThrow ) SAL_THROW( (RuntimeException) ) +{ + _pInterface = iset_throw( pInterface ); +} +#endif + +//__________________________________________________________________________________________________ +template< class interface_type > +inline void Reference< interface_type >::clear() SAL_THROW( () ) +{ + if (_pInterface) + { + XInterface * const pOld = _pInterface; + _pInterface = 0; + pOld->release(); + } +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline sal_Bool Reference< interface_type >::set( + interface_type * pInterface ) SAL_THROW( () ) +{ + if (pInterface) + castToXInterface(pInterface)->acquire(); + XInterface * const pOld = _pInterface; + _pInterface = castToXInterface(pInterface); + if (pOld) + pOld->release(); + return (0 != pInterface); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline sal_Bool Reference< interface_type >::set( + interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () ) +{ + XInterface * const pOld = _pInterface; + _pInterface = castToXInterface(pInterface); + if (pOld) + pOld->release(); + return (0 != pInterface); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline sal_Bool Reference< interface_type >::set( + interface_type * pInterface, UnoReference_NoAcquire ) SAL_THROW( () ) +{ + return set( pInterface, SAL_NO_ACQUIRE ); +} + +//__________________________________________________________________________________________________ +template< class interface_type > +inline sal_Bool Reference< interface_type >::set( + const Reference< interface_type > & rRef ) SAL_THROW( () ) +{ + return set( castFromXInterface( rRef._pInterface ) ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline sal_Bool Reference< interface_type >::set( + XInterface * pInterface, UnoReference_Query ) SAL_THROW( (RuntimeException) ) +{ + return set( castFromXInterface(iquery( pInterface )), SAL_NO_ACQUIRE ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline sal_Bool Reference< interface_type >::set( + const BaseReference & rRef, UnoReference_Query ) SAL_THROW( (RuntimeException) ) +{ + return set( castFromXInterface(iquery( rRef.get() )), SAL_NO_ACQUIRE ); +} + +//______________________________________________________________________________ +template< class interface_type > +inline bool Reference< interface_type >::set( + Any const & rAny, UnoReference_Query ) +{ + return set( + castFromXInterface( + iquery( + rAny.pType->eTypeClass == typelib_TypeClass_INTERFACE + ? static_cast< XInterface * >( rAny.pReserved ) : 0 )), + SAL_NO_ACQUIRE ); +} + +#ifndef EXCEPTIONS_OFF +//__________________________________________________________________________________________________ +template< class interface_type > +inline void Reference< interface_type >::set( + XInterface * pInterface, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ) +{ + set( castFromXInterface(iquery_throw( pInterface )), SAL_NO_ACQUIRE ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline void Reference< interface_type >::set( + const BaseReference & rRef, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) ) +{ + set( castFromXInterface(iquery_throw( rRef.get() )), SAL_NO_ACQUIRE ); +} + +//______________________________________________________________________________ +template< class interface_type > +inline void Reference< interface_type >::set( + Any const & rAny, UnoReference_QueryThrow ) +{ + set( castFromXInterface( + iquery_throw( + rAny.pType->eTypeClass == typelib_TypeClass_INTERFACE + ? static_cast< XInterface * >( rAny.pReserved ) : 0 )), + SAL_NO_ACQUIRE ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline void Reference< interface_type >::set( + interface_type * pInterface, UnoReference_SetThrow ) SAL_THROW( (RuntimeException) ) +{ + set( iset_throw( pInterface ), SAL_NO_ACQUIRE ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline void Reference< interface_type >::set( + const Reference< interface_type > & rRef, UnoReference_SetThrow ) SAL_THROW( (RuntimeException) ) +{ + set( rRef.get(), UNO_SET_THROW ); +} + +#endif + +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type > & Reference< interface_type >::operator = ( + interface_type * pInterface ) SAL_THROW( () ) +{ + set( pInterface ); + return *this; +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type > & Reference< interface_type >::operator = ( + const Reference< interface_type > & rRef ) SAL_THROW( () ) +{ + set( castFromXInterface( rRef._pInterface ) ); + return *this; +} + +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type > Reference< interface_type >::query( + const BaseReference & rRef ) SAL_THROW( (RuntimeException) ) +{ + return Reference< interface_type >( + castFromXInterface(iquery( rRef.get() )), SAL_NO_ACQUIRE ); +} +//__________________________________________________________________________________________________ +template< class interface_type > +inline Reference< interface_type > Reference< interface_type >::query( + XInterface * pInterface ) SAL_THROW( (RuntimeException) ) +{ + return Reference< interface_type >( + castFromXInterface(iquery( pInterface )), SAL_NO_ACQUIRE ); +} + +//################################################################################################## + +//__________________________________________________________________________________________________ +inline sal_Bool BaseReference::operator == ( XInterface * pInterface ) const SAL_THROW( () ) +{ + if (_pInterface == pInterface) + return sal_True; +#ifndef EXCEPTIONS_OFF + try + { +#endif + // only the query to XInterface must return the same pointer if they belong to same objects + Reference< XInterface > x1( _pInterface, UNO_QUERY ); + Reference< XInterface > x2( pInterface, UNO_QUERY ); + return (x1._pInterface == x2._pInterface); +#ifndef EXCEPTIONS_OFF + } + catch (RuntimeException &) + { + return sal_False; + } +#endif +} + +//______________________________________________________________________________ +inline sal_Bool BaseReference::operator < ( + const BaseReference & rRef ) const SAL_THROW( () ) +{ + if (_pInterface == rRef._pInterface) + return sal_False; +#if ! defined EXCEPTIONS_OFF + try + { +#endif + // only the query to XInterface must return the same pointer: + Reference< XInterface > x1( _pInterface, UNO_QUERY ); + Reference< XInterface > x2( rRef, UNO_QUERY ); + return (x1._pInterface < x2._pInterface); +#if ! defined EXCEPTIONS_OFF + } + catch (RuntimeException &) + { + return sal_False; + } +#endif +} + +//__________________________________________________________________________________________________ +inline sal_Bool BaseReference::operator != ( XInterface * pInterface ) const SAL_THROW( () ) +{ + return (! operator == ( pInterface )); +} +//__________________________________________________________________________________________________ +inline sal_Bool BaseReference::operator == ( const BaseReference & rRef ) const SAL_THROW( () ) +{ + return operator == ( rRef._pInterface ); +} +//__________________________________________________________________________________________________ +inline sal_Bool BaseReference::operator != ( const BaseReference & rRef ) const SAL_THROW( () ) +{ + return (! operator == ( rRef._pInterface )); +} + +} +} +} +} + +#endif diff --git a/cppu/inc/com/sun/star/uno/Sequence.h b/cppu/inc/com/sun/star/uno/Sequence.h new file mode 100644 index 000000000000..71bb42c7413b --- /dev/null +++ b/cppu/inc/com/sun/star/uno/Sequence.h @@ -0,0 +1,288 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_SEQUENCE_H_ +#define _COM_SUN_STAR_UNO_SEQUENCE_H_ + +#include "typelib/typedescription.h" +#include "uno/sequence2.h" +#include "com/sun/star/uno/Type.h" +#include "rtl/alloc.h" + +#if ! defined EXCEPTIONS_OFF +#include <new> +#endif + + +namespace rtl +{ +class ByteSequence; +} + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +/** Template C++ class representing an IDL sequence. Template argument is the + sequence element type. C++ Sequences are reference counted and shared, + so the sequence keeps a handle to its data. To keep value semantics, + copies are only generated if the sequence is to be modified (new handle). + + @tplparam E element type of sequence +*/ +template< class E > +class Sequence +{ + /** sequence handle + @internal + */ + uno_Sequence * _pSequence; + +public: + // these are here to force memory de/allocation to sal lib. + /** @internal */ + inline static void * SAL_CALL operator new ( size_t nSize ) + SAL_THROW( () ) + { return ::rtl_allocateMemory( nSize ); } + /** @internal */ + inline static void SAL_CALL operator delete ( void * pMem ) + SAL_THROW( () ) + { ::rtl_freeMemory( pMem ); } + /** @internal */ + inline static void * SAL_CALL operator new ( size_t, void * pMem ) + SAL_THROW( () ) + { return pMem; } + /** @internal */ + inline static void SAL_CALL operator delete ( void *, void * ) + SAL_THROW( () ) + {} + + /** Static pointer to typelib type of sequence. + Don't use directly, call getCppuType(). + @internal + */ + static typelib_TypeDescriptionReference * s_pType; + + /** typedefs the element type of the sequence + */ + typedef E ElementType; + + /** Default constructor: Creates an empty sequence. + */ + inline Sequence() SAL_THROW( () ); + + /** Copy constructor: Creates a copy of given sequence. + + @param rSeq another sequence of same type + */ + inline Sequence( const Sequence< E > & rSeq ) SAL_THROW( () ); + + /** Constructor: Takes over ownership of given sequence. + + @param pSequence a sequence + @param dummy SAL_NO_ACQUIRE to force obvious distinction to other + constructors + */ + inline Sequence( uno_Sequence * pSequence, __sal_NoAcquire ) + SAL_THROW( () ); + + /** Constructor: Creates a copy of given elements. + + @param pElement an array of elements + @param len length of array + */ + inline Sequence( const E * pElements, sal_Int32 len ); + + /** Constructor: Creates a default constructed sequence of given length. + + @param len initial sequence length + */ + inline explicit Sequence( sal_Int32 len ); + + /** Destructor: Releases sequence handle. Last handle will destruct + elements and free memory. + */ + inline ~Sequence() SAL_THROW( () ); + + /** Assignment operator: Acquires given sequence handle and releases + previously set handle. + + @param rSeq another sequence of same type + @return this sequence + */ + inline Sequence< E > & SAL_CALL operator = ( const Sequence< E > & rSeq ) + SAL_THROW( () ); + + /** Gets length of the sequence. + + @return length of sequence + */ + inline sal_Int32 SAL_CALL getLength() const SAL_THROW( () ) + { return _pSequence->nElements; } + + /** Tests whether the sequence has elements, i.e. elements count is + greater than zero. + + @return true, if elements count is greater than zero + */ + inline sal_Bool SAL_CALL hasElements() const SAL_THROW( () ) + { return (_pSequence->nElements > 0); } + + /** Gets a pointer to elements array for reading. + If the sequence has a length of 0, then the returned pointer is + undefined. + + @return pointer to elements array + */ + inline const E * SAL_CALL getConstArray() const SAL_THROW( () ) + { return reinterpret_cast< const E * >( _pSequence->elements ); } + + /** Gets a pointer to elements array for reading and writing. + In general if the sequence has a handle acquired by other sequences + (reference count > 1), then a new sequence is created copy constructing + all elements to keep value semantics! + If the sequence has a length of 0, then the returned pointer is + undefined. + + @return pointer to elements array + */ + inline E * SAL_CALL getArray(); + + /** Non-const index operator: Obtains a reference to element indexed at + given position. + The implementation does not check for array bounds! + In general if the sequence has a handle acquired by other sequences + (reference count > 1), then a new sequence is created copy constructing + all elements to keep value semantics! + + @param nIndex index + @return non-const C++ reference to element + */ + inline E & SAL_CALL operator [] ( sal_Int32 nIndex ); + + /** Const index operator: Obtains a reference to element indexed at + given position. The implementation does not check for array bounds! + + @param nIndex index + @return const C++ reference to element + */ + inline const E & SAL_CALL operator [] ( sal_Int32 nIndex ) const + SAL_THROW( () ); + + /** Equality operator: Compares two sequences. + + @param rSeq another sequence of same type (right side) + @return true if both sequences are equal, false otherwise + */ + inline sal_Bool SAL_CALL operator == ( const Sequence< E > & rSeq ) const + SAL_THROW( () ); + + /** Unequality operator: Compares two sequences. + + @param rSeq another sequence of same type (right side) + @return false if both sequences are equal, true otherwise + */ + inline sal_Bool SAL_CALL operator != ( const Sequence< E > & rSeq ) const + SAL_THROW( () ); + + /** Reallocates sequence to new length. + If the new length is smaller than the former, then upper elements will + be destructed (and their memory freed). If the new length is greater + than the former, then upper (new) elements are default constructed. + If the sequence has a handle acquired by other sequences + (reference count > 1), then the remaining elements are copy constructed + to a new sequence handle to keep value semantics! + + @param nSize new size of sequence + */ + inline void SAL_CALL realloc( sal_Int32 nSize ); + + /** Provides UNacquired sequence handle. + + @return UNacquired sequence handle + */ + inline uno_Sequence * SAL_CALL get() const SAL_THROW( () ) + { return _pSequence; } +}; + +/** Creates a UNO byte sequence from a SAL byte sequence. + + @param rByteSequence a byte sequence + @return a UNO byte sequence +*/ +inline ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL toUnoSequence( + const ::rtl::ByteSequence & rByteSequence ) SAL_THROW( () ); + +} +} +} +} + +/** Gets the meta type of IDL sequence. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @tplparam E element type of sequence + @param dummy typed pointer for function signature + @return type of IDL sequence +*/ +template< class E > +inline const ::com::sun::star::uno::Type & +SAL_CALL getCppuType( const ::com::sun::star::uno::Sequence< E > * ) + SAL_THROW( () ); + +/** Gets the meta type of IDL sequence. + This function has been introduced, because one cannot get the (templated) + cppu type out of C++ array types. Array types have special + getCppuArrayTypeN() functions. + + @attention + the given element type must be the same as the template argument type! + @tplparam E element type of sequence + @param rElementType element type of sequence + @return type of IDL sequence +*/ +template< class E > +inline const ::com::sun::star::uno::Type & +SAL_CALL getCppuSequenceType( const ::com::sun::star::uno::Type & rElementType ) + SAL_THROW( () ); + +/** Gets the meta type of IDL sequence< char >. + This function has been introduced due to ambiguities with unsigned short. + + @param dummy typed pointer for function signature + @return type of IDL sequence< char > +*/ +inline const ::com::sun::star::uno::Type & +SAL_CALL getCharSequenceCppuType() SAL_THROW( () ); + +#endif diff --git a/cppu/inc/com/sun/star/uno/Sequence.hxx b/cppu/inc/com/sun/star/uno/Sequence.hxx new file mode 100644 index 000000000000..bca6a1c44211 --- /dev/null +++ b/cppu/inc/com/sun/star/uno/Sequence.hxx @@ -0,0 +1,307 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_SEQUENCE_HXX_ +#define _COM_SUN_STAR_UNO_SEQUENCE_HXX_ + +#include "osl/diagnose.h" +#include "osl/interlck.h" +#include "com/sun/star/uno/Sequence.h" +#include "typelib/typedescription.h" +#include "uno/data.h" +#include "com/sun/star/uno/genfunc.hxx" +#include "cppu/unotype.hxx" + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +//______________________________________________________________________________ +template< class E > +typelib_TypeDescriptionReference * Sequence< E >::s_pType = 0; + +//______________________________________________________________________________ +template< class E > +inline Sequence< E >::Sequence() SAL_THROW( () ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + ::uno_type_sequence_construct( + &_pSequence, rType.getTypeLibType(), + 0, 0, (uno_AcquireFunc)cpp_acquire ); + // no bad_alloc, because empty sequence is statically allocated in cppu +} + +//______________________________________________________________________________ +template< class E > +inline Sequence< E >::Sequence( const Sequence< E > & rSeq ) SAL_THROW( () ) +{ + ::osl_incrementInterlockedCount( &rSeq._pSequence->nRefCount ); + _pSequence = rSeq._pSequence; +} + +//______________________________________________________________________________ +template< class E > +inline Sequence< E >::Sequence( + uno_Sequence * pSequence, __sal_NoAcquire ) SAL_THROW( () ) + : _pSequence( pSequence ) +{ +} + +//______________________________________________________________________________ +template< class E > +inline Sequence< E >::Sequence( const E * pElements, sal_Int32 len ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); +#if ! defined EXCEPTIONS_OFF + sal_Bool success = +#endif + ::uno_type_sequence_construct( + &_pSequence, rType.getTypeLibType(), + const_cast< E * >( pElements ), len, (uno_AcquireFunc)cpp_acquire ); +#if ! defined EXCEPTIONS_OFF + if (! success) + throw ::std::bad_alloc(); +#endif +} + +//______________________________________________________________________________ +template< class E > +inline Sequence< E >::Sequence( sal_Int32 len ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); +#if ! defined EXCEPTIONS_OFF + sal_Bool success = +#endif + ::uno_type_sequence_construct( + &_pSequence, rType.getTypeLibType(), + 0, len, (uno_AcquireFunc)cpp_acquire ); +#if ! defined EXCEPTIONS_OFF + if (! success) + throw ::std::bad_alloc(); +#endif +} + +//______________________________________________________________________________ +template< class E > +inline Sequence< E >::~Sequence() SAL_THROW( () ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + ::uno_type_destructData( + this, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release ); +} + +//______________________________________________________________________________ +template< class E > +inline Sequence< E > & Sequence< E >::operator = ( const Sequence< E > & rSeq ) SAL_THROW( () ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + ::uno_type_sequence_assign( + &_pSequence, rSeq._pSequence, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release ); + return *this; +} + +//______________________________________________________________________________ +template< class E > +inline sal_Bool Sequence< E >::operator == ( const Sequence< E > & rSeq ) const + SAL_THROW( () ) +{ + if (_pSequence == rSeq._pSequence) + return sal_True; + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + return ::uno_type_equalData( + const_cast< Sequence< E > * >( this ), rType.getTypeLibType(), + const_cast< Sequence< E > * >( &rSeq ), rType.getTypeLibType(), + (uno_QueryInterfaceFunc)cpp_queryInterface, + (uno_ReleaseFunc)cpp_release ); +} + +//______________________________________________________________________________ +template< class E > +inline sal_Bool Sequence< E >::operator != ( const Sequence< E > & rSeq ) const + SAL_THROW( () ) +{ + return (! operator == ( rSeq )); +} + +//______________________________________________________________________________ +template< class E > +inline E * Sequence< E >::getArray() +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); +#if ! defined EXCEPTIONS_OFF + sal_Bool success = +#endif + ::uno_type_sequence_reference2One( + &_pSequence, rType.getTypeLibType(), + (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); +#if ! defined EXCEPTIONS_OFF + if (! success) + throw ::std::bad_alloc(); +#endif + return reinterpret_cast< E * >( _pSequence->elements ); +} + +//______________________________________________________________________________ +template< class E > +inline E & Sequence< E >::operator [] ( sal_Int32 nIndex ) +{ + OSL_ENSURE( + nIndex >= 0 && nIndex < getLength(), + "### illegal index of sequence!" ); + return getArray()[ nIndex ]; +} + +//______________________________________________________________________________ +template< class E > +inline const E & Sequence< E >::operator [] ( sal_Int32 nIndex ) const + SAL_THROW( () ) +{ + OSL_ENSURE( + nIndex >= 0 && nIndex < getLength(), + "### illegal index of sequence!" ); + return reinterpret_cast< const E * >( _pSequence->elements )[ nIndex ]; +} + +//______________________________________________________________________________ +template< class E > +inline void Sequence< E >::realloc( sal_Int32 nSize ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); +#if !defined EXCEPTIONS_OFF + sal_Bool success = +#endif + ::uno_type_sequence_realloc( + &_pSequence, rType.getTypeLibType(), nSize, + (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); +#if !defined EXCEPTIONS_OFF + if (!success) + throw ::std::bad_alloc(); +#endif +} + +//------------------------------------------------------------------------------ +inline ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL toUnoSequence( + const ::rtl::ByteSequence & rByteSequence ) SAL_THROW( () ) +{ + return ::com::sun::star::uno::Sequence< sal_Int8 >( + * reinterpret_cast< const ::com::sun::star::uno::Sequence< sal_Int8 > * >( &rByteSequence ) ); +} + +} +} +} +} + +namespace cppu { + +template< typename T > inline ::com::sun::star::uno::Type const & +getTypeFavourUnsigned(::com::sun::star::uno::Sequence< T > const *) { + if (::com::sun::star::uno::Sequence< T >::s_pType == 0) { + ::typelib_static_sequence_type_init( + &::com::sun::star::uno::Sequence< T >::s_pType, + (::cppu::getTypeFavourUnsigned( + static_cast< + typename ::com::sun::star::uno::Sequence< T >::ElementType * >( + 0)). + getTypeLibType())); + } + return detail::getTypeFromTypeDescriptionReference( + &::com::sun::star::uno::Sequence< T >::s_pType); +} + +template< typename T > inline ::com::sun::star::uno::Type const & +getTypeFavourChar(::com::sun::star::uno::Sequence< T > const *) { + //TODO On certain platforms with weak memory models, the following code can + // result in some threads observing that td points to garbage: + static typelib_TypeDescriptionReference * td = 0; + if (td == 0) { + ::typelib_static_sequence_type_init( + &td, + (::cppu::getTypeFavourChar( + static_cast< + typename ::com::sun::star::uno::Sequence< T >::ElementType * >( + 0)). + getTypeLibType())); + } + return detail::getTypeFromTypeDescriptionReference(&td); +} + +} + +// generic sequence template +template< class E > +inline const ::com::sun::star::uno::Type & +SAL_CALL getCppuType( const ::com::sun::star::uno::Sequence< E > * ) + SAL_THROW( () ) +{ + return ::cppu::getTypeFavourUnsigned( + static_cast< ::com::sun::star::uno::Sequence< E > * >(0)); +} + +// generic sequence template for given element type (e.g. C++ arrays) +template< class E > +inline const ::com::sun::star::uno::Type & +SAL_CALL getCppuSequenceType( const ::com::sun::star::uno::Type & rElementType ) + SAL_THROW( () ) +{ + if (! ::com::sun::star::uno::Sequence< E >::s_pType) + { + ::typelib_static_sequence_type_init( + & ::com::sun::star::uno::Sequence< E >::s_pType, + rElementType.getTypeLibType() ); + } + return * reinterpret_cast< const ::com::sun::star::uno::Type * >( + & ::com::sun::star::uno::Sequence< E >::s_pType ); +} + +#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) +static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0; +#endif + +// char sequence +inline const ::com::sun::star::uno::Type & +SAL_CALL getCharSequenceCppuType() SAL_THROW( () ) +{ +#if !( defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) + static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0; +#endif + if (! s_pType_com_sun_star_uno_Sequence_Char) + { + const ::com::sun::star::uno::Type & rElementType = ::getCharCppuType(); + ::typelib_static_sequence_type_init( + & s_pType_com_sun_star_uno_Sequence_Char, + rElementType.getTypeLibType() ); + } + return * reinterpret_cast< const ::com::sun::star::uno::Type * >( + & s_pType_com_sun_star_uno_Sequence_Char ); +} + +#endif diff --git a/cppu/inc/com/sun/star/uno/Type.h b/cppu/inc/com/sun/star/uno/Type.h new file mode 100644 index 000000000000..61829c2c790d --- /dev/null +++ b/cppu/inc/com/sun/star/uno/Type.h @@ -0,0 +1,458 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_TYPE_H_ +#define _COM_SUN_STAR_UNO_TYPE_H_ + +#include <typelib/typedescription.h> +#ifndef _COM_SUN_STAR_UNO_TYPECLASS_HDL_ +#include <com/sun/star/uno/TypeClass.hdl> +#endif +#include <cppu/macros.hxx> +#include <rtl/ustring.hxx> +#include <rtl/alloc.h> + + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +/** Enum defining UNO_TYPE_NO_ACQUIRE for type description reference transfer. +*/ +enum UnoType_NoAcquire +{ + /** This enum value can be used for creating a Type object granting a given type description + reference, i.e. transferring ownership to it. + */ + UNO_TYPE_NO_ACQUIRE +}; + +/** C++ class representing an IDL meta type. This class is used to represent a a type, + i.e. a type name and its type class. + Internally the type holds a C type description reference of the runtime. + You can obtain a full type description of a type by calling member function getDescription(). + + @see typelib_TypeDescriptionReference +*/ +class Type +{ + /** the C typelib reference pointer + @internal + */ + typelib_TypeDescriptionReference * _pType; + +public: + // these are here to force memory de/allocation to sal lib. + /** @internal */ + inline static void * SAL_CALL operator new ( size_t nSize ) SAL_THROW( () ) + { return ::rtl_allocateMemory( nSize ); } + /** @internal */ + inline static void SAL_CALL operator delete ( void * pMem ) SAL_THROW( () ) + { ::rtl_freeMemory( pMem ); } + /** @internal */ + inline static void * SAL_CALL operator new ( size_t, void * pMem ) SAL_THROW( () ) + { return pMem; } + /** @internal */ + inline static void SAL_CALL operator delete ( void *, void * ) SAL_THROW( () ) + {} + + /** Default Constructor: Type is set to void. + */ + inline Type() SAL_THROW( () ); + + /** Constructor: Type is constructed by given name and type class. + + @param eTypeClass type class of type + @param rTypeName name of type + */ + inline Type( TypeClass eTypeClass, const ::rtl::OUString & rTypeName ) SAL_THROW( () ); + + /** Constructor: Type is constructed by given name and type class. + + @param eTypeClass type class of type + @param pTypeName name of type + */ + inline Type( TypeClass eTypeClass, const sal_Char * pTypeName ) SAL_THROW( () ); + + /** Constructor: Type is (copy) constructed by given C type description reference. + + @param pType C type description reference + */ + inline Type( typelib_TypeDescriptionReference * pType ) SAL_THROW( () ); + + /** Constructor: Type is (copy) constructed by given C type description reference + without acquiring it. + + @param pType C type description reference + @param dummy UNO_TYPE_NO_ACQUIRE to force obvious distinction to other constructors + */ + inline Type( typelib_TypeDescriptionReference * pType, UnoType_NoAcquire ) SAL_THROW( () ); + /** Constructor: Type is (copy) constructed by given C type description reference + without acquiring it. + + @param pType C type description reference + @param dummy SAL_NO_ACQUIRE to force obvious distinction to other constructors + */ + inline Type( typelib_TypeDescriptionReference * pType, __sal_NoAcquire ) SAL_THROW( () ); + + /** Copy constructor: Type is copy constructed by given type. + + @param rType another type + */ + inline Type( const Type & rType ) SAL_THROW( () ); + + /** Destructor: Releases acquired C type description reference. + */ + inline ~Type() SAL_THROW( () ) + { ::typelib_typedescriptionreference_release( _pType ); } + + /** Assignment operator: Acquires right side type and releases previously set type. + + @param rType another type (right side) + @return this type + */ + inline Type & SAL_CALL operator = ( const Type & rType ) SAL_THROW( () ); + + /** Gets the type class of set type. + + @return type class of set type + */ + inline TypeClass SAL_CALL getTypeClass() const SAL_THROW( () ) + { return (TypeClass)_pType->eTypeClass; } + + /** Gets the name of the set type. + + @return name of the set type + */ + inline ::rtl::OUString SAL_CALL getTypeName() const SAL_THROW( () ); + + /** Obtains a full type description of set type. + + @param ppDescr [inout] type description + */ + inline void SAL_CALL getDescription( typelib_TypeDescription ** ppDescr ) const SAL_THROW( () ) + { ::typelib_typedescriptionreference_getDescription( ppDescr, _pType ); } + + /** Gets the C typelib type description reference pointer. Does not acquire the reference! + + @return UNacquired type description reference + */ + inline typelib_TypeDescriptionReference * SAL_CALL getTypeLibType() const SAL_THROW( () ) + { return _pType; } + + /** Tests if values of this reflected type can be assigned by values of given type. + This includes widening conversion (e.g., long assignable from short), as long as there + is no data loss. + + @param rType another type + @return true if values of this type can be assigned from values of given type, + false otherwise + */ + inline sal_Bool SAL_CALL isAssignableFrom( const Type & rType ) const SAL_THROW( () ) + { return ::typelib_typedescriptionreference_isAssignableFrom( _pType, rType._pType ); } + + /** Compares two types. + + @param rType another type + @return true if both types refer the same type, false otherwise + */ + inline sal_Bool SAL_CALL equals( const Type & rType ) const SAL_THROW( () ) + { return ::typelib_typedescriptionreference_equals( _pType, rType._pType ); } + /** Equality operator: Compares two types. + + @param rType another type + @return true if both types refer the same type, false otherwise + */ + inline sal_Bool SAL_CALL operator == ( const Type & rType ) const SAL_THROW( () ) + { return ::typelib_typedescriptionreference_equals( _pType, rType._pType ); } + /** Unequality operator: Compares two types. + + @param rType another type + @return false if both types refer the same type, true otherwise + */ + inline sal_Bool SAL_CALL operator != ( const Type & rType ) const SAL_THROW( () ) + { return (! ::typelib_typedescriptionreference_equals( _pType, rType._pType )); } +}; + +/** Helper class to specify a type pointer for idl arrays. +*/ +template< class T > +class Array +{ +public: + static typelib_TypeDescriptionReference * s_pType; +}; + +} +} +} +} + +/** Gets the meta type of IDL type "type". + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type "type" +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const ::com::sun::star::uno::Type * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type void. + @return type of IDL type void +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuVoidType() SAL_THROW( () ); +/** Gets the meta type of IDL type void. + + @return type of IDL type void +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getVoidCppuType() SAL_THROW( () ); + +/** Gets the meta type of IDL type boolean. + + @return type of IDL type boolean +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuBooleanType() SAL_THROW( () ); +/** Gets the meta type of IDL type boolean. + + @return type of IDL type boolean +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getBooleanCppuType() SAL_THROW( () ); +/** Gets the meta type of IDL type boolean. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type boolean +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Bool * ) SAL_THROW( () ); +/** Gets the meta type of IDL type boolean. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type boolean +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( + bool const * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type char. + + @return type of IDL type char +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCharCppuType() SAL_THROW( () ); +/** Gets the meta type of IDL type char. + + @return type of IDL type char +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuCharType() SAL_THROW( () ); + +/** Gets the meta type of IDL type byte. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type byte +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int8 * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type string. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type string +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const ::rtl::OUString * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type short. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type short +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int16 * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type unsigned short. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type unsigned short +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_uInt16 * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type long. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type long +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int32 * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type unsigned long. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type unsigned long +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_uInt32 * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type hyper. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type hyper +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int64 * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type unsigned hyper. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type unsigned hyper +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_uInt64 * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type float. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type float +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const float * ) SAL_THROW( () ); + +/** Gets the meta type of IDL type double. + + There are cases (involving templates) where uses of getCppuType are known to + not compile. Use cppu::UnoType or cppu::getTypeFavourUnsigned instead. + + @param dummy typed pointer for function signature + @return type of IDL type double +*/ +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const double * ) SAL_THROW( () ); + +/** Array template function to get meta type for one-dimensional arrays. + + @param pT array pointer + @return type of array +*/ +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType1( T * pT ) SAL_THROW( () ); +/** Array template function to get meta type for two-dimensional arrays. + + @param pT array pointer + @return type of array +*/ +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType2( T * pT ) SAL_THROW( () ); +/** Array template function to get meta type for three-dimensional arrays. + + @param pT array pointer + @return type of array +*/ +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType3( T * pT ) SAL_THROW( () ); +/** Array template function to get meta type for four-dimensional arrays. + + @param pT array pointer + @return type of array +*/ +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType4( T * pT ) SAL_THROW( () ); +/** Array template function to get meta type for five-dimensional arrays. + + @param pT array pointer + @return type of array +*/ +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType5( T * pT ) SAL_THROW( () ); +/** Array template function to get meta type for six-dimensional arrays. + + @param pT array pointer + @return type of array +*/ +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType6( T * pT ) SAL_THROW( () ); + +/** Gets the meta type of an IDL type. + + The difference between this function template (with a type parameter) and + the overloaded getCppuType function with a single (dummy) parameter of a + specific type is that this function template may not work for the UNO type + "unsigned short" (sal_uInt16 in C++), while the overloaded one-parameter + function may not work for the UNO type "char" (sal_Unicode in C++, which may + have the same underlying C++ type as sal_uInt16 on certain platforms). + + @return type of the given IDL type + + @deprecated + Use cppu::UnoType instead (or the internal-only cppu::getTypeFavourChar). + Also note that getCppuType< com::sun::star::uno::Sequence< sal_Unicode > >() + does not work as expected. + + @since UDK 3.2.0 +*/ +template< typename T > inline const ::com::sun::star::uno::Type & SAL_CALL +getCppuType() SAL_THROW(()); + +/** Gets the meta type of IDL type char. + + @return type of IDL type char + + @deprecated + Use cppu::UnoType instead (or the internal-only cppu::getTypeFavourChar). + Also note that getCppuType< com::sun::star::uno::Sequence< sal_Unicode > >() + does not work as expected. + + @since UDK 3.2.0 +*/ +template<> inline const ::com::sun::star::uno::Type & SAL_CALL +getCppuType< sal_Unicode >() SAL_THROW(()); + +#endif diff --git a/cppu/inc/com/sun/star/uno/Type.hxx b/cppu/inc/com/sun/star/uno/Type.hxx new file mode 100644 index 000000000000..33eba298e188 --- /dev/null +++ b/cppu/inc/com/sun/star/uno/Type.hxx @@ -0,0 +1,327 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_TYPE_HXX_ +#define _COM_SUN_STAR_UNO_TYPE_HXX_ + +#include <osl/mutex.hxx> +#include <com/sun/star/uno/Type.h> +#include "cppu/unotype.hxx" + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +//__________________________________________________________________________________________________ +inline Type::Type() SAL_THROW( () ) +{ + _pType = reinterpret_cast< const ::com::sun::star::uno::Type * >( + ::typelib_static_type_getByTypeClass( typelib_TypeClass_VOID ) )->getTypeLibType(); + ::typelib_typedescriptionreference_acquire( _pType ); +} +//__________________________________________________________________________________________________ +inline Type::Type( TypeClass eTypeClass, const ::rtl::OUString & rTypeName ) SAL_THROW( () ) + : _pType( 0 ) +{ + ::typelib_typedescriptionreference_new( &_pType, (typelib_TypeClass)eTypeClass, rTypeName.pData ); +} +//__________________________________________________________________________________________________ +inline Type::Type( TypeClass eTypeClass, const sal_Char * pTypeName ) SAL_THROW( () ) + : _pType( 0 ) +{ + ::typelib_typedescriptionreference_newByAsciiName( &_pType, (typelib_TypeClass)eTypeClass, pTypeName ); +} +//__________________________________________________________________________________________________ +inline Type::Type( typelib_TypeDescriptionReference * pType ) SAL_THROW( () ) + : _pType( pType ) +{ + ::typelib_typedescriptionreference_acquire( _pType ); +} +//__________________________________________________________________________________________________ +inline Type::Type( typelib_TypeDescriptionReference * pType, UnoType_NoAcquire ) SAL_THROW( () ) + : _pType( pType ) +{ +} +//__________________________________________________________________________________________________ +inline Type::Type( typelib_TypeDescriptionReference * pType, __sal_NoAcquire ) SAL_THROW( () ) + : _pType( pType ) +{ +} +//__________________________________________________________________________________________________ +inline Type::Type( const Type & rType ) SAL_THROW( () ) + : _pType( rType._pType ) +{ + ::typelib_typedescriptionreference_acquire( _pType ); +} +//__________________________________________________________________________________________________ +inline ::rtl::OUString Type::getTypeName() const SAL_THROW( () ) +{ + return ::rtl::OUString( _pType->pTypeName ); +} +//__________________________________________________________________________________________________ +inline Type & Type::operator = ( const Type & rType ) SAL_THROW( () ) +{ + ::typelib_typedescriptionreference_assign( &_pType, rType._pType ); + return *this; +} + +//__________________________________________________________________________________________________ +template< class T > +typelib_TypeDescriptionReference * Array< T >::s_pType = 0; + +} +} +} +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const ::com::sun::star::uno::Type * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::com::sun::star::uno::Type >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuVoidType() SAL_THROW( () ) +{ + return ::cppu::UnoType< ::cppu::UnoVoidType >::get(); +} +inline const ::com::sun::star::uno::Type & SAL_CALL getVoidCppuType() SAL_THROW( () ) +{ + return ::cppu::UnoType< ::cppu::UnoVoidType >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuBooleanType() SAL_THROW( () ) +{ + return ::cppu::UnoType< bool >::get(); +} +inline const ::com::sun::star::uno::Type & SAL_CALL getBooleanCppuType() SAL_THROW( () ) +{ + return ::cppu::UnoType< bool >::get(); +} +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Bool * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< bool >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( + bool const * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< bool >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCharCppuType() SAL_THROW( () ) +{ + return ::cppu::UnoType< ::cppu::UnoCharType >::get(); +} +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuCharType() SAL_THROW( () ) +{ + return ::cppu::UnoType< ::cppu::UnoCharType >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int8 * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::sal_Int8 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const ::rtl::OUString * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::rtl::OUString >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int16 * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::sal_Int16 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_uInt16 * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int32 * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::sal_Int32 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_uInt32 * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::sal_uInt32 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int64 * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::sal_Int64 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_uInt64 * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< ::sal_uInt64 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const float * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< float >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const double * ) SAL_THROW( () ) +{ + return ::cppu::UnoType< double >::get(); +} + +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType1( T * pT ) SAL_THROW( () ) +{ + if (! ::com::sun::star::uno::Array< T >::s_pType) + { + const ::com::sun::star::uno::Type & rElementType = + ::cppu::getTypeFavourUnsigned( *pT ); + sal_Int32 size = sizeof( **pT ); + sal_Int32 dim1 = sizeof( *pT ) / size; + ::typelib_static_array_type_init( + & ::com::sun::star::uno::Array< T >::s_pType, rElementType.getTypeLibType(), + 1, dim1 ); + } + return * reinterpret_cast< const ::com::sun::star::uno::Type * >( + & ::com::sun::star::uno::Array< T >::s_pType ); +} + +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType2( T * pT ) SAL_THROW( () ) +{ + if (! ::com::sun::star::uno::Array< T >::s_pType) + { + const ::com::sun::star::uno::Type & rElementType = + ::cppu::getTypeFavourUnsigned( **pT ); + sal_Int32 size = sizeof( ***pT ); + sal_Int32 dim2 = sizeof( **pT ) / size; + sal_Int32 dim1 = sizeof( *pT ) / dim2 / size; + ::typelib_static_array_type_init( + & ::com::sun::star::uno::Array< T >::s_pType, rElementType.getTypeLibType(), + 2, dim1, dim2 ); + } + return * reinterpret_cast< const ::com::sun::star::uno::Type * >( + & ::com::sun::star::uno::Array< T >::s_pType ); +} + +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType3( T * pT ) SAL_THROW( () ) +{ + if (! ::com::sun::star::uno::Array< T >::s_pType) + { + const ::com::sun::star::uno::Type & rElementType = + ::cppu::getTypeFavourUnsigned( ***pT ); + sal_Int32 size = sizeof( ****pT ); + sal_Int32 dim3 = sizeof( ***pT ) / size; + sal_Int32 dim2 = sizeof( **pT ) / dim3 / size; + sal_Int32 dim1 = sizeof( *pT ) / (dim2 * dim3)/ size; + ::typelib_static_array_type_init( + & ::com::sun::star::uno::Array< T >::s_pType, rElementType.getTypeLibType(), + 3, dim1, dim2, dim3 ); + } + return * reinterpret_cast< const ::com::sun::star::uno::Type * >( + & ::com::sun::star::uno::Array< T >::s_pType ); +} + +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType4( T * pT ) SAL_THROW( () ) +{ + if (! ::com::sun::star::uno::Array< T >::s_pType) + { + const ::com::sun::star::uno::Type & rElementType = + ::cppu::getTypeFavourUnsigned( ****pT ); + sal_Int32 size = sizeof( *****pT ); + sal_Int32 dim4 = sizeof( ****pT ) / size; + sal_Int32 dim3 = sizeof( ***pT ) / dim4 / size; + sal_Int32 dim2 = sizeof( **pT ) / (dim3 * dim4) / size; + sal_Int32 dim1 = sizeof( *pT ) / (dim2 * dim3 * dim4) / size; + ::typelib_static_array_type_init( + & ::com::sun::star::uno::Array< T >::s_pType, rElementType.getTypeLibType(), + 4, dim1, dim2, dim3, dim4 ); + } + return * reinterpret_cast< const ::com::sun::star::uno::Type * >( + & ::com::sun::star::uno::Array< T >::s_pType ); +} + +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType5( T * pT ) SAL_THROW( () ) +{ + if (! ::com::sun::star::uno::Array< T >::s_pType) + { + const ::com::sun::star::uno::Type & rElementType = + ::cppu::getTypeFavourUnsigned( *****pT ); + sal_Int32 size = sizeof( ******pT ); + sal_Int32 dim5 = sizeof( *****pT ) / size; + sal_Int32 dim4 = sizeof( ****pT ) / dim5 / size; + sal_Int32 dim3 = sizeof( ***pT ) / (dim4 * dim5) / size; + sal_Int32 dim2 = sizeof( **pT ) / (dim3 * dim4 * dim5) / size; + sal_Int32 dim1 = sizeof( *pT ) / (dim2 * dim3 * dim4 * dim5) / size; + ::typelib_static_array_type_init( + & ::com::sun::star::uno::Array< T >::s_pType, rElementType.getTypeLibType(), + 5, dim1, dim2, dim3, dim4, dim5 ); + } + return * reinterpret_cast< const ::com::sun::star::uno::Type * >( + & ::com::sun::star::uno::Array< T >::s_pType ); +} + +template< class T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuArrayType6( T * pT ) SAL_THROW( () ) +{ + if (! ::com::sun::star::uno::Array< T >::s_pType) + { + const ::com::sun::star::uno::Type & rElementType = + ::cppu::getTypeFavourUnsigned( ******pT ); + sal_Int32 size = sizeof( *******pT ); + sal_Int32 dim6 = sizeof( ******pT ) / size; + sal_Int32 dim5 = sizeof( *****pT ) / dim6 / size; + sal_Int32 dim4 = sizeof( ****pT ) / (dim5 * dim6) / size; + sal_Int32 dim3 = sizeof( ***pT ) / (dim4 * dim5 * dim6) / size; + sal_Int32 dim2 = sizeof( **pT ) / (dim3 * dim4 * dim5 * dim6) / size; + sal_Int32 dim1 = sizeof( *pT ) / (dim2 * dim3 * dim4 * dim5 * dim6) / size; + ::typelib_static_array_type_init( + & ::com::sun::star::uno::Array< T >::s_pType, rElementType.getTypeLibType(), + 6, dim1, dim2, dim3, dim4, dim5, dim6 ); + } + return * reinterpret_cast< const ::com::sun::star::uno::Type * >( + & ::com::sun::star::uno::Array< T >::s_pType ); +} + +template< typename T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType() SAL_THROW(()) +{ + return ::cppu::UnoType< T >::get(); +} + +template<> +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType< sal_Unicode >() + SAL_THROW(()) +{ + return ::cppu::UnoType< ::cppu::UnoCharType >::get(); +} + +#endif diff --git a/cppu/inc/com/sun/star/uno/genfunc.h b/cppu/inc/com/sun/star/uno/genfunc.h new file mode 100644 index 000000000000..41fdebf47a31 --- /dev/null +++ b/cppu/inc/com/sun/star/uno/genfunc.h @@ -0,0 +1,69 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_GENFUNC_H_ +#define _COM_SUN_STAR_UNO_GENFUNC_H_ + +#include "sal/types.h" + +typedef struct _typelib_TypeDescriptionReference typelib_TypeDescriptionReference; + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +/** Function to acquire a C++ interface. + + @param pCppI C++ interface pointer +*/ +inline void SAL_CALL cpp_acquire( void * pCppI ) + SAL_THROW( () ); +/** Function to release a C++ interface. + + @param pCppI C++ interface pointer +*/ +inline void SAL_CALL cpp_release( void * pCppI ) + SAL_THROW( () ); +/** Function to query for a C++ interface. + + @param pCppI C++ interface pointer + @param pType demanded interface type + @return acquired C++ interface pointer or null +*/ +inline void * SAL_CALL cpp_queryInterface( void * pCppI, typelib_TypeDescriptionReference * pType ) + SAL_THROW( () ); + +} +} +} +} + +#endif diff --git a/cppu/inc/com/sun/star/uno/genfunc.hxx b/cppu/inc/com/sun/star/uno/genfunc.hxx new file mode 100644 index 000000000000..b2299a35cd3d --- /dev/null +++ b/cppu/inc/com/sun/star/uno/genfunc.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * 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 _COM_SUN_STAR_UNO_GENFUNC_HXX_ +#define _COM_SUN_STAR_UNO_GENFUNC_HXX_ + +#include <com/sun/star/uno/genfunc.h> +#include <com/sun/star/uno/Any.hxx> + + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +//================================================================================================== +inline void SAL_CALL cpp_acquire( void * pCppI ) + SAL_THROW( () ) +{ + reinterpret_cast< XInterface * >( pCppI )->acquire(); +} +//================================================================================================== +inline void SAL_CALL cpp_release( void * pCppI ) + SAL_THROW( () ) +{ + reinterpret_cast< XInterface * >( pCppI )->release(); +} +//================================================================================================== +inline void * SAL_CALL cpp_queryInterface( void * pCppI, typelib_TypeDescriptionReference * pType ) + SAL_THROW( () ) +{ + if (pCppI) + { +#ifndef EXCEPTIONS_OFF + try + { +#endif + Any aRet( reinterpret_cast< XInterface * >( pCppI )->queryInterface( + * reinterpret_cast< const Type * >( &pType ) ) ); + if (typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass) + { + XInterface * pRet = reinterpret_cast< XInterface * >( aRet.pReserved ); + aRet.pReserved = 0; + return pRet; + } +#ifndef EXCEPTIONS_OFF + } + catch (RuntimeException &) + { + } +#endif + } + return 0; +} + +} +} +} +} + +#endif diff --git a/cppu/inc/cppu/Enterable.hxx b/cppu/inc/cppu/Enterable.hxx new file mode 100644 index 000000000000..c8bbfb49d382 --- /dev/null +++ b/cppu/inc/cppu/Enterable.hxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * 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 INCLUDED_cppu_Enterable_hxx +#define INCLUDED_cppu_Enterable_hxx + +#include "uno/Enterable.h" +#include "rtl/ustring.hxx" + +namespace cppu +{ +/** C++ wrapper for binary C Enterable + (http://wiki.services.openoffice.org/wiki/Uno/Cpp/Spec/Environment_Stack) + + @see uno_Enterable + @since UDK 3.2.7 +*/ +class Enterable : public uno_Enterable +{ +public: + /* These methods need to be implemented in a derived class. + */ + virtual void v_enter (void) = 0; + virtual void v_leave (void) = 0; + virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam) = 0; + virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam) = 0; + virtual int v_isValid (rtl::OUString * pReason) = 0; + + virtual ~Enterable() {}; + +public: + inline explicit Enterable(void); + + inline void enter(void) {m_enter(this);}; + inline void leave(void) {m_leave(this);}; + + inline void callInto_v(uno_EnvCallee * pCallee, va_list * pParam) {m_callInto_v(this, pCallee, pParam);}; + inline void callOut_v (uno_EnvCallee * pCallee, va_list * pParam) {m_callOut_v (this, pCallee, pParam);}; + + inline void callInto(uno_EnvCallee * pCallee, ...); + inline void callOut (uno_EnvCallee * pCallee, ...); + + inline int isValid (rtl::OUString * pReason) {return m_isValid(this, (rtl_uString **)pReason);} + +private: + Enterable(Enterable const &); + Enterable & operator = (Enterable const &); +}; + +extern "C" inline void Enterable_call_enter (void * context) { ((Enterable *)context)->v_enter(); }; +extern "C" inline void Enterable_call_leave (void * context) { ((Enterable *)context)->v_leave(); }; +extern "C" inline void Enterable_call_callInto_v(void * context, uno_EnvCallee * pCallee, va_list * pParam) + { ((Enterable *)context)->v_callInto_v(pCallee, pParam); }; +extern "C" inline void Enterable_call_callOut_v (void * context, uno_EnvCallee * pCallee, va_list * pParam) + { ((Enterable *)context)->v_callOut_v(pCallee, pParam); }; +extern "C" inline int Enterable_call_isValid (void * context, rtl_uString ** pReason) + {return ((Enterable *)context)->v_isValid((rtl::OUString *)pReason);} + + +Enterable::Enterable(void) +{ + m_enter = Enterable_call_enter; + m_leave = Enterable_call_leave; + m_callInto_v = Enterable_call_callInto_v; + m_callOut_v = Enterable_call_callOut_v; + m_isValid = Enterable_call_isValid; +} + +void Enterable::callInto(uno_EnvCallee * pCallee, ...) +{ + va_list param; + + va_start(param, pCallee); + callInto_v(pCallee, ¶m); + va_end(param); +} + +void Enterable::callOut(uno_EnvCallee * pCallee, ...) +{ + va_list param; + + va_start(param, pCallee); + callOut_v(pCallee, ¶m); + va_end(param); +} + +} + + +#endif diff --git a/cppu/inc/cppu/EnvDcp.hxx b/cppu/inc/cppu/EnvDcp.hxx new file mode 100644 index 000000000000..c4e394b98460 --- /dev/null +++ b/cppu/inc/cppu/EnvDcp.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * 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 INCLUDED_cppu_EnvDcp_hxx +#define INCLUDED_cppu_EnvDcp_hxx + +#include "rtl/ustring.hxx" +#include "uno/EnvDcp.h" + + +namespace cppu +{ +namespace EnvDcp +{ +/** Get the OBI type part of an environment descriptor. + (http://wiki.services.openoffice.org/wiki/Uno/Cpp/Spec/Environment_Descriptor) + + @param rEnvDcp the Environment Descriptor + @return the OBI type + @since UDK 3.2.7 +*/ +inline rtl::OUString getTypeName(rtl::OUString const & rEnvDcp) +{ + rtl::OUString typeName; + + uno_EnvDcp_getTypeName(rEnvDcp.pData, &typeName.pData); + + return typeName; +} + +/** Get the purpose part of an environment descriptor. + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Environment_Descriptor) + + @param rEnvDcp the Environment Descriptor + @return the purpose + @since UDK 3.2.7 +*/ +inline rtl::OUString getPurpose(rtl::OUString const & rEnvDcp) +{ + rtl::OUString purpose; + + uno_EnvDcp_getPurpose(rEnvDcp.pData, &purpose.pData); + + return purpose; +} + +} +} + + +#endif diff --git a/cppu/inc/cppu/EnvGuards.hxx b/cppu/inc/cppu/EnvGuards.hxx new file mode 100644 index 000000000000..c7408f01cfd1 --- /dev/null +++ b/cppu/inc/cppu/EnvGuards.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * 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 INCLUDED_cppu_EnvGuards_hxx +#define INCLUDED_cppu_EnvGuards_hxx + +#include "uno/environment.hxx" +#include "uno/mapping.hxx" + + +namespace cssuno = com::sun::star::uno; + + +namespace cppu +{ + /** Environment Guard + The provided Environment becomes entered in the constructor and left + in the destructor. + (http://wiki.services.openoffice.org/wiki/Uno/Cpp/Spec/Environment_Guard) + + @since UDK 3.2.7 + */ + class EnvGuard + { + cssuno::Environment m_env; + + public: + explicit EnvGuard(cssuno::Environment const & env) + { + if (env.is()) + { + m_env = cssuno::Environment::getCurrent(); + env.enter(); + } + } + + ~EnvGuard() + { + m_env.enter(); + } + + /** Checks if the associated environment is non empty. + + @return 0 == empty, 1 == non empty + */ + sal_Bool SAL_CALL is() const SAL_THROW( () ) + { + return m_env.is(); + } + + /** Leaves the associated environment and clears + the reference. + */ + void clear() + { + if (m_env.is()) + { + m_env.enter(); + m_env.clear(); + } + } + }; + + /** Environment Anti-Guard + Any entered Environment becomes left in the constructor and re-entered + in the destructor. + (http://wiki.services.openoffice.org/wiki/Uno/Cpp/Spec/Environment_AntiGuard) + + @since UDK 3.2.7 + */ + class AntiEnvGuard + { + cssuno::Environment m_env; + + public: + explicit AntiEnvGuard() + : m_env(cssuno::Environment::getCurrent()) + { + uno_Environment_enter(NULL); + } + + ~AntiEnvGuard() + { + m_env.enter(); + } + }; +} + +#endif diff --git a/cppu/inc/cppu/FreeReference.hxx b/cppu/inc/cppu/FreeReference.hxx new file mode 100644 index 000000000000..e2d60775c0b3 --- /dev/null +++ b/cppu/inc/cppu/FreeReference.hxx @@ -0,0 +1,166 @@ +/************************************************************************* + * + * 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 INCLUDED_cppu_FreeReference_hxx +#define INCLUDED_cppu_FreeReference_hxx + +#include "uno/environment.hxx" +#include "cppu/Map.hxx" +#include "com/sun/star/uno/Reference.h" + + +namespace cssuno = com::sun::star::uno; + + +namespace cppu +{ + /** Freely (environment independent) usable Reference. + (http://wiki.services.openoffice.org/wiki/Uno/Cpp/Spec/FreeReference) + + @since UDK 3.2.7 + */ + template< class T > + class FreeReference + { + cssuno::Environment m_env; + T * m_pObject; + + public: + FreeReference() : m_pObject(NULL) {} + + FreeReference(T * pObject, __sal_NoAcquire) + : m_env(cssuno::Environment::getCurrent()), + m_pObject(pObject) + { + } + + FreeReference(T * pObject) + : m_env(cssuno::Environment::getCurrent()), + m_pObject(pObject) + { + if (m_pObject) + m_env.get()->pExtEnv->acquireInterface(m_env.get()->pExtEnv, m_pObject); + } + + explicit FreeReference(cssuno::Reference<T> const & xRef) + : m_env(cssuno::Environment::getCurrent()), + m_pObject(xRef.get()) + { + if (m_pObject) + m_env.get()->pExtEnv->acquireInterface(m_env.get()->pExtEnv, m_pObject); + } + + FreeReference(FreeReference<T> const & rOther) + : m_env (rOther.m_env), + m_pObject(rOther.m_pObject) + { + if (m_pObject) + m_env.get()->pExtEnv->acquireInterface(m_env.get()->pExtEnv, m_pObject); + } + + + ~FreeReference() + { + clear(); + } + + cssuno::Environment getEnv() const throw (cssuno::RuntimeException) + { + return m_env; + } + + cssuno::Reference<T> get() const throw (cssuno::RuntimeException) + { + return cssuno::Reference<T>(cppu::mapIn(m_pObject, m_env), SAL_NO_ACQUIRE); + } + + operator cssuno::Reference<T> () const throw (cssuno::RuntimeException) + { + return get(); + } + + cssuno::Reference<T> operator -> () const throw (cssuno::RuntimeException) + { + return get(); + } + + bool is() const throw (cssuno::RuntimeException) + { + return m_pObject != NULL; + } + + void clear() + { + if (m_pObject) + { + + m_env.get()->pExtEnv->releaseInterface(m_env.get()->pExtEnv, m_pObject); + m_pObject = NULL; + m_env.clear(); + } + } + + FreeReference<T> & operator = (FreeReference<T> const & rOther) + { + clear(); + + m_pObject = rOther.m_pObject; + if (m_pObject) + { + m_env = rOther.m_env; + m_env.get()->pExtEnv->acquireInterface(m_env.get()->pExtEnv, m_pObject); + } + + return *this; + } + + void set(cssuno::Reference<T> const & xRef) + { + clear(); + + m_pObject = xRef.get(); + if (m_pObject) + { + m_env = cssuno::Environment::getCurrent(); + + m_env.get()->pExtEnv->acquireInterface(m_env.get()->pExtEnv, m_pObject); + } + } + + bool operator == (FreeReference const & rOther) const + { + return get() == rOther.get(); + } + + bool operator != (FreeReference const & rOther) const + { + return !operator==(rOther); + } + }; +} + +#endif diff --git a/cppu/inc/cppu/Map.hxx b/cppu/inc/cppu/Map.hxx new file mode 100644 index 000000000000..455bee6e5fbd --- /dev/null +++ b/cppu/inc/cppu/Map.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * 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 INCLUDED_cppu_Map_hxx +#define INCLUDED_cppu_Map_hxx + +#include <uno/mapping.hxx> + + +namespace cssu = com::sun::star::uno; + +namespace cppu +{ + /** Helpers for mapping objects relative to the current environment. + (http://wiki.services.openoffice.org/wiki/Uno/Cpp/Spec/Map_Helpers) + */ + + /** Maps an object from the current to an outer Environment, returns mapped object. + + @param pT the object to be mapped + @param outerEnv the target environment + @return the mapped object + @since UDK 3.2.7 + */ + template<class T> inline T * mapOut(T * pT, cssu::Environment const & outerEnv) + { + cssu::Mapping curr2outer(cssu::Environment::getCurrent(), outerEnv); + + return reinterpret_cast<T *>(curr2outer.mapInterface(pT, getCppuType((cssu::Reference<T> *)NULL))); + } + + + /** Maps an object from an outer Environment to the current, returns mapped object. + + @param pT the object to be mapped + @param outerEnv the source environment + @return the mapped object + @since UDK 3.2.7 + */ + template<class T> inline T * mapIn(T * pT, cssu::Environment const & outerEnv) + { + cssu::Mapping outer2curr(outerEnv, cssu::Environment::getCurrent()); + + return reinterpret_cast<T *>(outer2curr.mapInterface(pT, getCppuType((cssu::Reference<T> *)NULL))); + } + + + /** Maps an any from the current to an outer Environment, fills passed any. + + @param any the any to be mapped + @param res the target any + @param outerEnv the target environment + @since UDK 3.2.7 + */ + // Problem: any gets assigned to something, acquire/releases may be called in wrong env. + inline void mapOutAny(cssu::Any const & any, cssu::Any * res, cssu::Environment const & outerEnv) + { + cssu::Mapping curr2outer(cssu::Environment::getCurrent(), outerEnv); + + uno_any_destruct(res, (uno_ReleaseFunc)cssu::cpp_release); + uno_type_any_constructAndConvert( + res, + const_cast<void *>(any.getValue()), + any.getValueTypeRef(), + curr2outer.get()); + } + + + /** Maps an any from an outer Environment to the current, fills passed any. + + @param any the any to be mapped + @param res the target any + @param outerEnv the source environment + @since UDK 3.2.7 + */ + inline void mapInAny(cssu::Any const & any, cssu::Any * res, cssu::Environment const & outerEnv) + { + cssu::Mapping outer2curr(outerEnv, cssu::Environment::getCurrent()); + + uno_any_destruct(res, (uno_ReleaseFunc)cssu::cpp_release); + uno_type_any_constructAndConvert( + res, + const_cast<void *>(any.getValue()), + any.getValueTypeRef(), + outer2curr.get()); + } +} + +#endif diff --git a/cppu/inc/cppu/Shield.hxx b/cppu/inc/cppu/Shield.hxx new file mode 100644 index 000000000000..46cdaeacea06 --- /dev/null +++ b/cppu/inc/cppu/Shield.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * 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 INCLUDED_cppu_Shield_hxx +#define INCLUDED_cppu_Shield_hxx + +#include <cppu/Map.hxx> + + +namespace cssu = com::sun::star::uno; + +namespace cppu +{ + /** Helpers for mapping objects relative to the thread-safe and current environments. + (http://wiki.services.openoffice.org/wiki/Uno/Cpp/Spec/Shield_Helpers) + */ + + + /** Maps an object from the current to the thread-safe Environment, returns mapped object. + + @param pT the object to be mapped + @return the mapped object + @since UDK 3.2.7 + */ + template<class T> inline T * shield(T * pT) + { + return mapOut(pT, cssu::Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))))); + } + + /** Maps an object from the thread-safe Environment to the current one, returns mapped object. + + @param pT the object to be mapped + @return the mapped object + @since UDK 3.2.7 + */ + template<class T> inline T * unshield(T * pT) + { + return mapIn(pT, cssu::Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))))); + } + + + /** Maps an any from the current to the thread-safe Environment, fills the passed any. + + @param any the any to be mapped + @param the target any + @since UDK 3.2.7 + */ + inline void shieldAny(cssu::Any const & any, cssu::Any * res) + { + mapOutAny(any, res, cssu::Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))))); + } + + + /** Maps an any from the thread-safe Environment to the current one, fills the passed any. + + @param any the any to be mapped + @param the target any + @since UDK 3.2.7 + */ + inline void unshieldAny(cssu::Any const & any, cssu::Any * res) + { + mapInAny(any, res, cssu::Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))))); + } +} + +#endif diff --git a/cppu/inc/cppu/helper/purpenv/Environment.hxx b/cppu/inc/cppu/helper/purpenv/Environment.hxx new file mode 100644 index 000000000000..ba56c22e53cf --- /dev/null +++ b/cppu/inc/cppu/helper/purpenv/Environment.hxx @@ -0,0 +1,46 @@ +/************************************************************************* + * + * 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 INCLUDED_cppu_helper_purpenv_Environment_hxx +#define INCLUDED_cppu_helper_purpenv_Environment_hxx + +#include "uno/environment.h" +#include "cppu/Enterable.hxx" + + +namespace cppu { namespace helper { namespace purpenv { + +/** C++ helper for implementing Purpose Environments. + (http://wiki.services.openoffice.org/wiki/Uno/Cpp/Spec/Purpose_Bridge_Implementation_Helper) + + @since UDK 3.2.7 +*/ +void Environment_initWithEnterable(uno_Environment * pEnvironment, cppu::Enterable * pEnterable); + +}}} + +#endif diff --git a/cppu/inc/cppu/helper/purpenv/Mapping.hxx b/cppu/inc/cppu/helper/purpenv/Mapping.hxx new file mode 100644 index 000000000000..c20309e7a180 --- /dev/null +++ b/cppu/inc/cppu/helper/purpenv/Mapping.hxx @@ -0,0 +1,68 @@ +/************************************************************************* + * + * 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 INCLUDED_cppu_helper_purpenv_Mapping_hxx +#define INCLUDED_cppu_helper_purpenv_Mapping_hxx + +#include "com/sun/star/uno/Any.h" + +#include "uno/environment.h" +#include "uno/mapping.h" + + +namespace cppu { namespace helper { namespace purpenv { + +/** C++ helper for implementing Purpose Environments. + (http://wiki.services.openoffice.org/wiki/Uno/Cpp/Spec/Purpose_Bridge_Implementation_Helper) + + @since UDK 3.2.7 +*/ + +typedef void ProbeFun( + bool pre, + void * pThis, + void * pContext, + typelib_TypeDescriptionReference * pReturnTypeRef, + typelib_MethodParameter * pParams, + sal_Int32 nParams, + typelib_TypeDescription const * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ); + + + +void createMapping(uno_Mapping ** ppMapping, + uno_Environment * pFrom, + uno_Environment * pTo, + ProbeFun * probeFun = NULL, + void * pContext = NULL + ); + +}}} + +#endif diff --git a/cppu/inc/cppu/macros.hxx b/cppu/inc/cppu/macros.hxx new file mode 100644 index 000000000000..fd64d1c767df --- /dev/null +++ b/cppu/inc/cppu/macros.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * 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 _CPPU_MACROS_HXX_ +#define _CPPU_MACROS_HXX_ + +#include <sal/types.h> +#include <uno/lbnames.h> + +/** Namespace name for compiler/ platform, e.g. gcc3, msci */ +#define CPPU_CURRENT_NAMESPACE CPPU_ENV + +/** Patching the GCC 3 incomatible alignment change for Linux. + + This macro is appended by cppumaker to every first member of a struct, if + the struct inherits from a base struct and the first member is neither + double nor sal_[u]Int64. (The double/sal_[u]Int64 restriction is due to a + bug in GCC prior to version 3.3, which would cause __alignof__ of such a + struct to become 8 instead of 4 if CPPU_GCC3_ALIGN were added to its first + member.) + + @internal +*/ +#if defined(__GNUC__) && (__GNUC__ >= 3) +#define CPPU_GCC3_ALIGN( base_struct ) __attribute__ ((aligned (__alignof__ (base_struct)))) +#else +#define CPPU_GCC3_ALIGN( base_struct ) +#endif + +/** + Exporting the symbols necessary for exception handling on GCC. + + These macros are used in the headers generated by cppumaker for UNO exception + types, to ensure that exception handling does not fail on GCC. + + @internal +*/ +#define CPPU_GCC_DLLPUBLIC_EXPORT SAL_EXCEPTION_DLLPUBLIC_EXPORT +#define CPPU_GCC_DLLPRIVATE SAL_EXCEPTION_DLLPRIVATE + +#endif // _CPPU_MACROS_HXX_ + diff --git a/cppu/inc/cppu/unotype.hxx b/cppu/inc/cppu/unotype.hxx new file mode 100644 index 000000000000..bef23d3cf38d --- /dev/null +++ b/cppu/inc/cppu/unotype.hxx @@ -0,0 +1,377 @@ +/************************************************************************* + * + * 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 INCLUDED_CPPU_UNOTYPE_HXX +#define INCLUDED_CPPU_UNOTYPE_HXX + +#include "sal/config.h" +#include "com/sun/star/uno/Type.h" +#include "sal/types.h" +#include "typelib/typeclass.h" +#include "typelib/typedescription.h" + +namespace com { namespace sun { namespace star { namespace uno { + class Any; + class Exception; + template< typename > class Reference; + template< typename > class Sequence; + class XInterface; +} } } } +namespace rtl { class OUString; } + +namespace cppu { + +template< typename > class UnoType; + +/** + A unique C++ type representing the UNO type VOID in cppu::UnoType. + + This type is declared but not defined. Its only use is as a template + argument to cppu::UnoType. + + @since UDK 3.2.2 +*/ +struct UnoVoidType; + +/** + A unique C++ type representing the UNO type UNSIGNED SHORT in cppu::UnoType. + + The UNO types UNSIGNED SHORT and CHAR map to the same C++ type, so this C++ + type is needed to unambiguously specify UNO types in cppu::UnoType. + + This type is declared but not defined. Its only use is as a template + argument to cppu::UnoType. + + @since UDK 3.2.2 +*/ +struct UnoUnsignedShortType; + +/** + A unique C++ type representing the UNO type UNSIGNED SHORT in cppu::UnoType. + + The UNO types UNSIGNED SHORT and CHAR map to the same C++ type, so this C++ + type is needed to unambiguously specify UNO types in cppu::UnoType. + + This type is declared but not defined. Its only use is as a template + argument to cppu::UnoType. + + @since UDK 3.2.2 +*/ +struct UnoCharType; + +/** + A unique C++ type template representing the UNO sequence types in + cppu::UnoType. + + The UNO types UNSIGNED SHORT and CHAR map to the same C++ type, so this C++ + type is needed to unambiguously specify UNO types in cppu::UnoType. + + This type is declared but not defined. Its only use is as a template + argument to cppu::UnoType. + + @since UDK 3.2.2 +*/ +template< typename > struct UnoSequenceType; + +namespace detail { + +inline ::com::sun::star::uno::Type const & getTypeFromTypeDescriptionReference( + ::typelib_TypeDescriptionReference * const * tdr) +{ + return *reinterpret_cast< ::com::sun::star::uno::Type const * >(tdr); +} + +inline ::com::sun::star::uno::Type const & +getTypeFromTypeClass(::typelib_TypeClass tc) { + return getTypeFromTypeDescriptionReference( + ::typelib_static_type_getByTypeClass(tc)); +} + +} + +} + +// For _MSC_VER 1310, define cppu_detail_getUnoType in the global namespace, to +// avoid spurious compiler errors in code that calls cppu_detail_getUnoType: +#if !defined _MSC_VER || _MSC_VER > 1310 +namespace cppu { namespace detail { +#endif + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::cppu::UnoVoidType const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_VOID); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(bool const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_BOOLEAN); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::sal_Bool const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_BOOLEAN); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::sal_Int8 const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_BYTE); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::sal_Int16 const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_SHORT); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::cppu::UnoUnsignedShortType const *) { + return ::cppu::detail::getTypeFromTypeClass( + ::typelib_TypeClass_UNSIGNED_SHORT); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::sal_Int32 const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_LONG); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::sal_uInt32 const *) { + return ::cppu::detail::getTypeFromTypeClass( + ::typelib_TypeClass_UNSIGNED_LONG); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::sal_Int64 const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_HYPER); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::sal_uInt64 const *) { + return ::cppu::detail::getTypeFromTypeClass( + ::typelib_TypeClass_UNSIGNED_HYPER); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(float const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_FLOAT); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(double const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_DOUBLE); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::cppu::UnoCharType const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_CHAR); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::rtl::OUString const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_STRING); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::com::sun::star::uno::Type const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_TYPE); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::com::sun::star::uno::Any const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_ANY); +} + +template< typename T > inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::cppu::UnoSequenceType< T > const *) { + //TODO: depending on memory model, the following might not work reliably + static typelib_TypeDescriptionReference * p = 0; + if (p == 0) { + ::typelib_static_sequence_type_init( + &p, ::cppu::UnoType< T >::get().getTypeLibType()); + } + return ::cppu::detail::getTypeFromTypeDescriptionReference(&p); +} + +template< typename T > inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::com::sun::star::uno::Sequence< T > const *) { + return cppu_detail_getUnoType( + static_cast< ::cppu::UnoSequenceType< T > * >(0)); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::com::sun::star::uno::Exception const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_EXCEPTION); +} + +inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::com::sun::star::uno::XInterface const *) { + return ::cppu::detail::getTypeFromTypeClass(::typelib_TypeClass_INTERFACE); +} + +template< typename T > inline ::com::sun::star::uno::Type const & +cppu_detail_getUnoType(::com::sun::star::uno::Reference< T > const *) { + return ::cppu::UnoType< T >::get(); +} + +#if !defined _MSC_VER || _MSC_VER > 1310 +} } +#endif + +namespace cppu { + +/** + Get the com::sun::star::uno::Type instance representing a certain UNO type. + + For each C++ type representing a UNO type, the corresponding instantiation of + this template has a public static member function get(). (The template is + specialized for C++ templates representing polymorphic struct type templates + of UNO. In those cases, it does not work to instantiate UnoType with a C++ + type that is derived from a C++ type that represents a UNO type, but does not + itself represent a UNO type. In all other cases, UnoType even works for such + C++ types that are unambiguously derived from one C++ type that represents a + UNO type.) In addition to those C++ types that are mappings of UNO types + (except for sal_uInt16 and sal_Unicode, see below), the following C++ types + are appropriate as template arguments: cppu::UnoVoidType, bool, + cppu::UnoUnsignedShortType, cppu::UnoCharType, cppu::UnoSequenceType with any + appropriate template argument (the latter three to unambiguously specify UNO + types, as the UNO types UNSIGNED SHORT and CHAR map to the same C++ type), + and com::sun::star::uno::Reference with any appropriate template argument. + + @since UDK 3.2.2 +*/ +template< typename T > class UnoType { +public: + static inline ::com::sun::star::uno::Type const & get() { + using namespace ::cppu::detail; + return cppu_detail_getUnoType(static_cast< T * >(0)); + } + +private: + UnoType(UnoType &); // not defined + ~UnoType(); // not defined + void operator =(UnoType &); // not defined +}; + +/** + A working replacement for getCppuType (see there). + + There are three overloads of this function that together form the replacement + of getCppuType. The replacement has exactly the same semantics as + getCppuType, in that it returns correct results for the UNO type UNSIGNED + SHORT but not for the UNO type CHAR. + + @since UDK 3.2.2 +*/ +template< typename T > inline ::com::sun::star::uno::Type const & +getTypeFavourUnsigned(T const *) { + return ::cppu::UnoType< T >::get(); +} + +/** + A working replacement for getCppuType (see there). + + There are three overloads of this function that together form the replacement + of getCppuType. The replacement has exactly the same semantics as + getCppuType, in that it returns correct results for the UNO type UNSIGNED + SHORT but not for the UNO type CHAR. + + @since UDK 3.2.2 +*/ +inline ::com::sun::star::uno::Type const & +getTypeFavourUnsigned(::sal_uInt16 const *) { + return ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get(); +} + +/** + A working replacement for getCppuType (see there). + + There are three overloads of this function that together form the replacement + of getCppuType. The replacement has exactly the same semantics as + getCppuType, in that it returns correct results for the UNO type UNSIGNED + SHORT but not for the UNO type CHAR. + + @since UDK 3.2.2 +*/ +template< typename T > inline ::com::sun::star::uno::Type const & +getTypeFavourUnsigned(::com::sun::star::uno::Sequence< T > const *); + // defined in com/sun/star/uno/Sequence.hxx + +/** + A working replacement for getCppuType (see there). + + There are three overloads of this function that together form the replacement + of the getCppuType template. The replacement has exactly the same semantics + as the getCppuType template, in that it returns correct results for the UNO + type CHAR but not for the UNO type UNSIGNED SHORT. Additionally, it also + returns the intended results for sequence types. + + @internal + + @since UDK 3.2.3 +*/ +template< typename T > inline ::com::sun::star::uno::Type const & +getTypeFavourChar(T const *) { + return ::cppu::UnoType< T >::get(); +} + +/** + A working replacement for getCppuType (see there). + + There are three overloads of this function that together form the replacement + of the getCppuType template. The replacement has exactly the same semantics + as the getCppuType template, in that it returns correct results for the UNO + type CHAR but not for the UNO type UNSIGNED SHORT. Additionally, it also + returns the intended results for sequence types. + + @internal + + @since UDK 3.2.3 +*/ +inline ::com::sun::star::uno::Type const & +getTypeFavourChar(::sal_Unicode const *) { + return ::cppu::UnoType< ::cppu::UnoCharType >::get(); +} + +/** + A working replacement for getCppuType (see there). + + There are three overloads of this function that together form the replacement + of the getCppuType template. The replacement has exactly the same semantics + as the getCppuType template, in that it returns correct results for the UNO + type CHAR but not for the UNO type UNSIGNED SHORT. Additionally, it also + returns the intended results for sequence types. + + @internal + + @since UDK 3.2.3 +*/ +template< typename T > inline ::com::sun::star::uno::Type const & +getTypeFavourChar(::com::sun::star::uno::Sequence< T > const *); + // defined in com/sun/star/uno/Sequence.hxx + +} + +#endif diff --git a/cppu/inc/makefile.mk b/cppu/inc/makefile.mk new file mode 100644 index 000000000000..47a2532efc68 --- /dev/null +++ b/cppu/inc/makefile.mk @@ -0,0 +1,48 @@ +#************************************************************************* +# +# 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=cppu +TARGET=inc + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +.IF "$(ENABLE_PCH)"!="" +ALLTAR : \ + $(SLO)$/precompiled.pch \ + $(SLO)$/precompiled_ex.pch + +.ENDIF # "$(ENABLE_PCH)"!="" + diff --git a/cppu/inc/pch/precompiled_cppu.cxx b/cppu/inc/pch/precompiled_cppu.cxx new file mode 100644 index 000000000000..5148aa6b5439 --- /dev/null +++ b/cppu/inc/pch/precompiled_cppu.cxx @@ -0,0 +1,29 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_cppu.hxx" + diff --git a/cppu/inc/pch/precompiled_cppu.hxx b/cppu/inc/pch/precompiled_cppu.hxx new file mode 100644 index 000000000000..38ea1cc9fbf7 --- /dev/null +++ b/cppu/inc/pch/precompiled_cppu.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * 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): Generated on 2006-09-01 17:49:37.030339 + +#ifdef PRECOMPILED_HEADERS +#endif + diff --git a/cppu/inc/typelib/typeclass.h b/cppu/inc/typelib/typeclass.h new file mode 100644 index 000000000000..da0ea9f37093 --- /dev/null +++ b/cppu/inc/typelib/typeclass.h @@ -0,0 +1,104 @@ +/************************************************************************* + * + * 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 _TYPELIB_TYPECLASS_H_ +#define _TYPELIB_TYPECLASS_H_ + +#include <sal/types.h> + +/** This type class enum is binary compatible with the IDL enum com.sun.star.uno.TypeClass. +*/ +typedef enum _typelib_TypeClass +{ + /** type class of void */ + typelib_TypeClass_VOID = 0, + /** type class of char */ + typelib_TypeClass_CHAR = 1, + /** type class of boolean */ + typelib_TypeClass_BOOLEAN = 2, + /** type class of byte */ + typelib_TypeClass_BYTE = 3, + /** type class of short */ + typelib_TypeClass_SHORT = 4, + /** type class of unsigned short */ + typelib_TypeClass_UNSIGNED_SHORT = 5, + /** type class of long */ + typelib_TypeClass_LONG = 6, + /** type class of unsigned long */ + typelib_TypeClass_UNSIGNED_LONG = 7, + /** type class of hyper */ + typelib_TypeClass_HYPER = 8, + /** type class of unsigned hyper */ + typelib_TypeClass_UNSIGNED_HYPER = 9, + /** type class of float */ + typelib_TypeClass_FLOAT = 10, + /** type class of double */ + typelib_TypeClass_DOUBLE = 11, + /** type class of string */ + typelib_TypeClass_STRING = 12, + /** type class of type */ + typelib_TypeClass_TYPE = 13, + /** type class of any */ + typelib_TypeClass_ANY = 14, + /** type class of enum */ + typelib_TypeClass_ENUM = 15, + /** type class of typedef */ + typelib_TypeClass_TYPEDEF = 16, + /** type class of struct */ + typelib_TypeClass_STRUCT = 17, + /** type class of union (not implemented) */ + typelib_TypeClass_UNION = 18, + /** type class of exception */ + typelib_TypeClass_EXCEPTION = 19, + /** type class of sequence */ + typelib_TypeClass_SEQUENCE = 20, + /** type class of array (not implemented) */ + typelib_TypeClass_ARRAY = 21, + /** type class of interface */ + typelib_TypeClass_INTERFACE = 22, + /** type class of service (not implemented) */ + typelib_TypeClass_SERVICE = 23, + /** type class of module (not implemented) */ + typelib_TypeClass_MODULE = 24, + /** type class of interface method */ + typelib_TypeClass_INTERFACE_METHOD = 25, + /** type class of interface attribute */ + typelib_TypeClass_INTERFACE_ATTRIBUTE = 26, + /** type class of unknown type */ + typelib_TypeClass_UNKNOWN = 27, + /** type class of properties */ + typelib_TypeClass_PROPERTY = 28, + /** type class of constants */ + typelib_TypeClass_CONSTANT = 29, + /** type class of constants groups */ + typelib_TypeClass_CONSTANTS = 30, + /** type class of singletons */ + typelib_TypeClass_SINGLETON = 31, + /** fixing enum size */ + typelib_TypeClass_MAKE_FIXED_SIZE = SAL_MAX_ENUM +} typelib_TypeClass; + +#endif diff --git a/cppu/inc/typelib/typedescription.h b/cppu/inc/typelib/typedescription.h new file mode 100644 index 000000000000..cf42acac96b1 --- /dev/null +++ b/cppu/inc/typelib/typedescription.h @@ -0,0 +1,1160 @@ +/************************************************************************* + * + * 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 _TYPELIB_TYPEDESCRIPTION_H_ +#define _TYPELIB_TYPEDESCRIPTION_H_ + +#include <sal/types.h> +#include <typelib/uik.h> +#include <typelib/typeclass.h> +#include <rtl/ustring.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct _typelib_TypeDescription; + +#if defined( SAL_W32) +#pragma pack(push, 8) +#elif defined(SAL_OS2) +#pragma pack(push, 8) +#endif + +/** Holds a weak reference to a type description. +*/ +typedef struct _typelib_TypeDescriptionReference +{ + /** reference count of type; don't ever modify this by yourself, use + typelib_typedescriptionreference_acquire() and typelib_typedescriptionreference_release() + */ + sal_Int32 nRefCount; + /** number of static references of type, because of the fact that some types are needed + until program termination and are commonly held static. + */ + sal_Int32 nStaticRefCount; + /** type class of type + */ + typelib_TypeClass eTypeClass; + /** fully qualified name of type + */ + rtl_uString * pTypeName; + /** pointer to full typedescription; this value is only valid if the type is never swapped out + */ + struct _typelib_TypeDescription * pType; + /** pointer to optimize the runtime; not for public use + */ + void * pUniqueIdentifier; + /** reserved for future use; 0 if not used + */ + void * pReserved; +} typelib_TypeDescriptionReference; + +/** Full type description of a type. Memory layout of this struct is identical to the + typelib_TypeDescriptionReference for the first six members. + So a typedescription can be used as type reference. +*/ +typedef struct _typelib_TypeDescription +{ + /** reference count; don't ever modify this by yourself, use + typelib_typedescription_acquire() and typelib_typedescription_release() + */ + sal_Int32 nRefCount; + /** number of static references of type, because of the fact that some types are needed + until program termination and are commonly held static. + */ + sal_Int32 nStaticRefCount; + /** type class of type + */ + typelib_TypeClass eTypeClass; + /** fully qualified name of type + */ + rtl_uString * pTypeName; + /** pointer to self to distinguish reference from description; for internal use only + */ + struct _typelib_TypeDescription * pSelf; + /** pointer to optimize the runtime; not for public use + */ + void * pUniqueIdentifier; + /** reserved for future use; 0 if not used + */ + void * pReserved; + + /** flag to determine whether the description is complete: + compound and union types lack of member names, enums lack of member types and names, + interfaces lack of members and table init. + Call typelib_typedescription_complete() if false. + */ + sal_Bool bComplete; + /** size of type + */ + sal_Int32 nSize; + /** alignment of type + */ + sal_Int32 nAlignment; + /** pointer to weak reference + */ + typelib_TypeDescriptionReference * pWeakRef; + /** determines, if type can be unloaded (and it is possible to reloaded it) + */ + sal_Bool bOnDemand; +} typelib_TypeDescription; + +/** Type description for exception types. +*/ +typedef struct _typelib_CompoundTypeDescription +{ + /** inherits all members of typelib_TypeDescription + */ + typelib_TypeDescription aBase; + + /** pointer to base type description, else 0 + */ + struct _typelib_CompoundTypeDescription * pBaseTypeDescription; + + /** number of members + */ + sal_Int32 nMembers; + /** byte offsets of each member including the size the base type + */ + sal_Int32 * pMemberOffsets; + /** members of the struct or exception + */ + typelib_TypeDescriptionReference ** ppTypeRefs; + /** member names of the struct or exception + */ + rtl_uString ** ppMemberNames; +} typelib_CompoundTypeDescription; + +/** + Type description for struct types. + + This is only used to represent plain struct types and instantiated + polymorphic struct types; there is no representation of polymorphic struct + type templates at this level. + + @since UDK 3.2.0 + */ +typedef struct _typelib_StructTypeDescription +{ + /** + Derived from typelib_CompoundTypeDescription. + */ + typelib_CompoundTypeDescription aBase; + + /** + Flags for direct members, specifying whether they are of parameterized + type (true) or explict type (false). + + For a plain struct type, this is a null pointer. + */ + sal_Bool * pParameterizedTypes; +} typelib_StructTypeDescription; + +/** Type description of a union. The type class of this description is typelib_TypeClass_UNION. +*/ +typedef struct _typelib_UnionTypeDescription +{ + /** inherits all members of typelib_TypeDescription + */ + typelib_TypeDescription aBase; + + /** type of the discriminant + */ + typelib_TypeDescriptionReference * pDiscriminantTypeRef; + + /** union default descriminant + */ + sal_Int64 nDefaultDiscriminant; + /** union default member type (may be 0) + */ + typelib_TypeDescriptionReference * pDefaultTypeRef; + /** number of union member types + */ + sal_Int32 nMembers; + /** union member discriminant values (same order as idl declaration) + */ + sal_Int64 * pDiscriminants; + /** union member value types (same order as idl declaration) + */ + typelib_TypeDescriptionReference ** ppTypeRefs; + /** union member value names (same order as idl declaration) + */ + rtl_uString ** ppMemberNames; + /** union value offset for data access + */ + sal_Int32 nValueOffset; +} typelib_UnionTypeDescription; + +/** Type description of an array or sequence. +*/ +typedef struct _typelib_IndirectTypeDescription +{ + /** inherits all members of typelib_TypeDescription + */ + typelib_TypeDescription aBase; + + /** array, sequence: pointer to element type + */ + typelib_TypeDescriptionReference * pType; +} typelib_IndirectTypeDescription; + +/** Type description of an array. +*/ +typedef struct _typelib_ArrayTypeDescription +{ + /** inherits all members of typelib_IndirectTypeDescription + */ + typelib_IndirectTypeDescription aBase; + + /** number of dimensions + */ + sal_Int32 nDimensions; + /** number of total array elements + */ + sal_Int32 nTotalElements; + /** array of dimensions + */ + sal_Int32 * pDimensions; +} typelib_ArrayTypeDescription; + +/** Type description of an enum. The type class of this description is typelib_TypeClass_ENUM. +*/ +typedef struct _typelib_EnumTypeDescription +{ + /** inherits all members of typelib_TypeDescription + */ + typelib_TypeDescription aBase; + + /** first value of the enum + */ + sal_Int32 nDefaultEnumValue; + /** number of enum values + */ + sal_Int32 nEnumValues; + /** names of enum values + */ + rtl_uString ** ppEnumNames; + /** values of enum (corresponding to names in similar order) + */ + sal_Int32 * pEnumValues; +} typelib_EnumTypeDescription; + +/** Description of an interface method parameter. +*/ +typedef struct _typelib_MethodParameter +{ + /** name of parameter + */ + rtl_uString * pName; + /** type of parameter + */ + typelib_TypeDescriptionReference * pTypeRef; + /** true: the call type of this parameter is [in] or [inout] + false: the call type of this parameter is [out] + */ + sal_Bool bIn; + /** true: the call type of this parameter is [out] or [inout] + false: the call type of this parameter is [in] + */ + sal_Bool bOut; +} typelib_MethodParameter; + +/** Common base type description of typelib_InterfaceMethodTypeDescription and + typelib_InterfaceAttributeTypeDescription. +*/ +typedef struct _typelib_InterfaceMemberTypeDescription +{ + /** inherits all members of typelib_TypeDescription + */ + typelib_TypeDescription aBase; + + /** position of member in the interface including the number of members of + any base interfaces + */ + sal_Int32 nPosition; + /** name of member + */ + rtl_uString * pMemberName; +} typelib_InterfaceMemberTypeDescription; + +/** Type description of an interface method. The type class of this description is + typelib_TypeClass_INTERFACE_METHOD. The size and the alignment are 0. +*/ +typedef struct _typelib_InterfaceMethodTypeDescription +{ + /** inherits all members of typelib_InterfaceMemberTypeDescription + */ + typelib_InterfaceMemberTypeDescription aBase; + + /** type of the return value + */ + typelib_TypeDescriptionReference * pReturnTypeRef; + /** number of parameters + */ + sal_Int32 nParams; + /** array of parameters + */ + typelib_MethodParameter * pParams; + /** number of exceptions + */ + sal_Int32 nExceptions; + /** array of exception types + */ + typelib_TypeDescriptionReference ** ppExceptions; + /** determines whether method is declared oneway + */ + sal_Bool bOneWay; + + /** the interface description this method is a member of + + @since #i21150# + */ + struct _typelib_InterfaceTypeDescription * pInterface; + /** the inherited direct base method (null for a method that is not + inherited) + + @since UDK 3.2.0 + */ + typelib_TypeDescriptionReference * pBaseRef; + /** if pBaseRef is null, the member position of this method within + pInterface, not counting members inherited from bases; if pBaseRef is + not null, the index of the direct base within pInterface from which this + method is inherited + + @since UDK 3.2.0 + */ + sal_Int32 nIndex; +} typelib_InterfaceMethodTypeDescription; + +/** The description of an interface attribute. The type class of this description is + typelib_TypeClass_INTERFACE_ATTRIBUTE. The size and the alignment are 0. +*/ +typedef struct _typelib_InterfaceAttributeTypeDescription +{ + /** inherits all members of typelib_InterfaceMemberTypeDescription + */ + typelib_InterfaceMemberTypeDescription aBase; + + /** determines whether attribute is read only + */ + sal_Bool bReadOnly; + /** type of the attribute + */ + typelib_TypeDescriptionReference * pAttributeTypeRef; + + /** the interface description this attribute is a member of + + @since #i21150# + */ + struct _typelib_InterfaceTypeDescription * pInterface; + /** the inherited direct base attribute (null for an attribute that is not + inherited) + + @since UDK 3.2.0 + */ + typelib_TypeDescriptionReference * pBaseRef; + /** if pBaseRef is null, the member position of this attribute within + pInterface, not counting members inherited from bases; if pBaseRef is + not null, the index of the direct base within pInterface from which this + attribute is inherited + + @since UDK 3.2.0 + */ + sal_Int32 nIndex; + /** number of getter exceptions + + @since UDK 3.2.0 + */ + sal_Int32 nGetExceptions; + /** array of getter exception types + + @since UDK 3.2.0 + */ + typelib_TypeDescriptionReference ** ppGetExceptions; + /** number of setter exceptions + + @since UDK 3.2.0 + */ + sal_Int32 nSetExceptions; + /** array of setter exception types + + @since UDK 3.2.0 + */ + typelib_TypeDescriptionReference ** ppSetExceptions; +} typelib_InterfaceAttributeTypeDescription; + +/// @HTML +/** Type description of an interface. + + <p>Not all members are always initialized (not yet initialized members being + null); there are three levels:</p> + <ul> + <li>Minimally, only <code>aBase</code>, + <code>pBaseTypeDescription</code>, <code>aUik</code>, + <code>nBaseTypes</code>, and <code>ppBaseTypes</code> are initialized; + <code>aBase.bComplete</code> is false. This only happens when an + interface type description is created with + <code>typelib_static_mi_interface_type_init</code> or + <code>typelib_static_interface_type_init</code>.</li> + + <li>At the next level, <code>nMembers</code>, <code>ppMembers</code>, + <code>nAllMembers</code>, <code>ppAllMembers</code> are also + initialized; <code>aBase.bComplete</code> is still false. This happens + when an interface type description is created with + <code>typelib_typedescription_newMIInterface</cocde> or + <code>typelib_typedescription_newInterface</code>.</li> + + <li>At the final level, <code>pMapMemberIndexToFunctionIndex</code>, + <code>nMapFunctionIndexToMemberIndex</code>, and + <code>pMapFunctionIndexToMemberIndex</code> are also initialized; + <code>aBase.bComplete</code> is true. This happens after a call to + <code>typelib_typedescription_complete</code>.</li> + </ul> +*/ +typedef struct _typelib_InterfaceTypeDescription +/// @NOHTML +{ + /** inherits all members of typelib_TypeDescription + */ + typelib_TypeDescription aBase; + + /** pointer to base type description, else 0 + + @deprecated + use nBaseTypes and ppBaseTypes instead + */ + struct _typelib_InterfaceTypeDescription * pBaseTypeDescription; + /** unique identifier of interface + */ + typelib_Uik aUik; + /** number of members + */ + sal_Int32 nMembers; + /** array of members; references attributes or methods + */ + typelib_TypeDescriptionReference ** ppMembers; + /** number of members including members of base interface + */ + sal_Int32 nAllMembers; + /** array of members including members of base interface; references attributes or methods + */ + typelib_TypeDescriptionReference ** ppAllMembers; + /** array mapping index of the member description to an index doubling for read-write + attributes (called function index); size of array is nAllMembers + */ + sal_Int32 * pMapMemberIndexToFunctionIndex; + /** number of members plus number of read-write attributes + */ + sal_Int32 nMapFunctionIndexToMemberIndex; + /** array mapping function index to member index; size of arry is nMapFunctionIndexToMemberIndex + */ + sal_Int32 * pMapFunctionIndexToMemberIndex; + /** number of base types + + @since UDK 3.2.0 + */ + sal_Int32 nBaseTypes; + /** array of base type descriptions + + @since UDK 3.2.0 + */ + struct _typelib_InterfaceTypeDescription ** ppBaseTypes; +} typelib_InterfaceTypeDescription; + +/** Init struct of compound members for typelib_typedescription_new(). +*/ +typedef struct _typelib_CompoundMember_Init +{ + /** type class of compound member + */ + typelib_TypeClass eTypeClass; + /** name of type of compound member + + For a member of an instantiated polymorphic struct type that is of + parameterized type, this will be a null pointer. + */ + rtl_uString * pTypeName; + /** name of compound member + */ + rtl_uString * pMemberName; +} typelib_CompoundMember_Init; + +/** + Init struct of members for typelib_typedescription_newStruct(). + + @since UDK 3.2.0 + */ +typedef struct _typelib_StructMember_Init +{ + /** + Derived from typelib_CompoundMember_Init; + */ + typelib_CompoundMember_Init aBase; + + /** + Flag specifying whether the member is of parameterized type (true) or + explict type (false). + */ + sal_Bool bParameterizedType; +} typelib_StructMember_Init; + +/** Init struct of interface methods for typelib_typedescription_new(). +*/ +typedef struct _typelib_Parameter_Init +{ + /** type class of parameter + */ + typelib_TypeClass eTypeClass; + /** name of parameter + */ + rtl_uString * pTypeName; + /** name of parameter + */ + rtl_uString * pParamName; + /** true, if parameter is [in] or [inout] + */ + sal_Bool bIn; + /** true, if parameter is [out] or [inout] + */ + sal_Bool bOut; +} typelib_Parameter_Init; + +/** Init struct of union types for typelib_typedescription_newUnion(). +*/ +typedef struct _typelib_Union_Init +{ + /** union member discriminant + */ + sal_Int64 nDiscriminant; + /** union member name + */ + rtl_uString * pMemberName; + /** union member type + */ + typelib_TypeDescriptionReference* pTypeRef; +} typelib_Union_Init; + +#if defined( SAL_W32) || defined(SAL_OS2) +#pragma pack(pop) +#endif + + +/** Creates a union type description. All discriminants are handled as int64 values. + The pDiscriminantTypeRef must be of type byte, short, ..., up to hyper. + + @param ppRet inout union type description + @param pTypeName name of union type + @param pDiscriminantTypeRef discriminant type + @param nDefaultDiscriminant default discriminant + @param pDefaultTypeRef default value type of union + @param nMembers number of union members + @param pMembers init members +*/ +void SAL_CALL typelib_typedescription_newUnion( + typelib_TypeDescription ** ppRet, + rtl_uString * pTypeName, + typelib_TypeDescriptionReference * pDiscriminantTypeRef, + sal_Int64 nDefaultDiscriminant, + typelib_TypeDescriptionReference * pDefaultTypeRef, + sal_Int32 nMembers, + typelib_Union_Init * pMembers ) + SAL_THROW_EXTERN_C(); + +/** Creates an enum type description. + + @param ppRet inout enum type description + @param pTypeName name of enum + @param nDefaultEnumValue default enum value + @param nEnumValues number of enum values + @param ppEnumNames names of enum values + @param pEnumValues enum values +*/ +void SAL_CALL typelib_typedescription_newEnum( + typelib_TypeDescription ** ppRet, + rtl_uString * pTypeName, + sal_Int32 nDefaultValue, + sal_Int32 nEnumValues, + rtl_uString ** ppEnumNames, + sal_Int32 * pEnumValues ) + SAL_THROW_EXTERN_C(); + +/** Creates an array type description. + + @param ppRet inout enum type description + @param pElementTypeRef element type + @param nDimensions number of dimensions + @param pDimensions dimensions +*/ +void SAL_CALL typelib_typedescription_newArray( + typelib_TypeDescription ** ppRet, + typelib_TypeDescriptionReference * pElementTypeRef, + sal_Int32 nDimensions, + sal_Int32 * pDimensions ) + SAL_THROW_EXTERN_C (); + +/** Creates a new type description. + + Since this function can only be used to create type descriptions for plain + struct types, not for instantiated polymorphic struct types, the function + typelib_typedescription_newStruct should be used instead for all struct + types. + + @param ppRet inout type description + @param eTypeClass type class + @param pTypeName name of type + @param pType sequence, array: element type; + struct, Exception: base type; + @param nMembers number of members if struct, exception + @param pMember array of members if struct, exception +*/ +void SAL_CALL typelib_typedescription_new( + typelib_TypeDescription ** ppRet, + typelib_TypeClass eTypeClass, + rtl_uString * pTypeName, + typelib_TypeDescriptionReference * pType, + sal_Int32 nMembers, + typelib_CompoundMember_Init * pMembers ) + SAL_THROW_EXTERN_C(); + +/** Creates a new struct type description. + + @param ppRet inout type description + @param pTypeName name of type + @param pType base type; + @param nMembers number of members + @param pMember array of members + + @since UDK 3.2.0 +*/ +void SAL_CALL typelib_typedescription_newStruct( + typelib_TypeDescription ** ppRet, + rtl_uString * pTypeName, + typelib_TypeDescriptionReference * pType, + sal_Int32 nMembers, + typelib_StructMember_Init * pMembers ) + SAL_THROW_EXTERN_C(); + +/** Creates an interface type description. + + @param ppRet inout interface type description + @param pTypeName the fully qualified name of the interface. + @param nUik1 uik part + @param nUik2 uik part + @param nUik3 uik part + @param nUik4 uik part + @param nUik5 uik part + @param pBaseInterface base interface type, else 0 + @param nMembers number of members + @param ppMembers members; attributes or methods + + @deprecated + use typelib_typedescription_newMIInterface instead +*/ +void SAL_CALL typelib_typedescription_newInterface( + typelib_InterfaceTypeDescription ** ppRet, + rtl_uString * pTypeName, + sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5, + typelib_TypeDescriptionReference * pBaseInterface, + sal_Int32 nMembers, + typelib_TypeDescriptionReference ** ppMembers ) + SAL_THROW_EXTERN_C(); + +/** Creates a multiple-inheritance interface type description. + + @param ppRet inout interface type description + @param pTypeName the fully qualified name of the interface. + @param nUik1 uik part + @param nUik2 uik part + @param nUik3 uik part + @param nUik4 uik part + @param nUik5 uik part + @param nBaseInterfaces number of base interface types + @param ppBaseInterface base interface types + @param nMembers number of members + @param ppMembers members; attributes or methods + + @since UDK 3.2.0 +*/ +void SAL_CALL typelib_typedescription_newMIInterface( + typelib_InterfaceTypeDescription ** ppRet, + rtl_uString * pTypeName, + sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5, + sal_Int32 nBaseInterfaces, + typelib_TypeDescriptionReference ** ppBaseInterfaces, + sal_Int32 nMembers, + typelib_TypeDescriptionReference ** ppMembers ) + SAL_THROW_EXTERN_C(); + +/** Creates an interface method type description. + + @param ppRet inout method type description + @param nAbsolutePosition position of member including all members of base interfaces + @param bOneWay determines whether method is declared oneway + @param pTypeName fully qualified name of method including interface name + @param eReturnTypeClass type class of return type + @param pReturnTypeName type name of the return type + @param nParams number of parameters + @param pParams parameter types + @param nExceptions number of exceptions + @param ppExceptionNames type names of exceptions +*/ +void SAL_CALL typelib_typedescription_newInterfaceMethod( + typelib_InterfaceMethodTypeDescription ** ppRet, + sal_Int32 nAbsolutePosition, + sal_Bool bOneWay, + rtl_uString * pMethodName, + typelib_TypeClass eReturnTypeClass, + rtl_uString * pReturnTypeName, + sal_Int32 nParams, + typelib_Parameter_Init * pParams, + sal_Int32 nExceptions, + rtl_uString ** ppExceptionNames ) + SAL_THROW_EXTERN_C(); + +/** Creates an interface attribute type description. + + @param ppRet inout attribute type description + @param nAbsolutePosition position of this attribute including all members of base interfaces + @param pAttributeName fully qualified name of attribute including interface + name + @param eAttributeTypeClass type class of attribute type + @param pAttributeTypeName type name of attribute type + @param bReadOnly determines whether attribute is read-only + + @deprecated + use typelib_typedescription_newExtendedInterfaceAttribute instead +*/ +void SAL_CALL typelib_typedescription_newInterfaceAttribute( + typelib_InterfaceAttributeTypeDescription ** ppRet, + sal_Int32 nAbsolutePosition, + rtl_uString * pAttributeName, + typelib_TypeClass eAttributeTypeClass, + rtl_uString * pAttributeTypeName, + sal_Bool bReadOnly ) + SAL_THROW_EXTERN_C(); + +/** Creates an extended interface attribute type description. + + @param ppRet inout attribute type description + @param nAbsolutePosition position of this attribute including all members of + base interfaces + @param pAttributeName fully qualified name of attribute including interface + name + @param eAttributeTypeClass type class of attribute type + @param pAttributeTypeName type name of attribute type + @param bReadOnly determines whether attribute is read-only + @param nGetExceptions number of getter exceptions + @param ppGetExceptionNames type names of getter exceptions + @param nSetExceptions number of setter exceptions + @param ppSetExceptionNames type names of setter exceptions + + @since UDK 3.2.0 +*/ +void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute( + typelib_InterfaceAttributeTypeDescription ** ppRet, + sal_Int32 nAbsolutePosition, + rtl_uString * pAttributeName, + typelib_TypeClass eAttributeTypeClass, + rtl_uString * pAttributeTypeName, + sal_Bool bReadOnly, + sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames, + sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames ) + SAL_THROW_EXTERN_C(); + +/** Increments reference count of given type description. + + @param pDesc type description +*/ +void SAL_CALL typelib_typedescription_acquire( + typelib_TypeDescription * pDesc ) + SAL_THROW_EXTERN_C(); + +/** Decrements reference count of given type. If reference count reaches 0, the trype description + is deleted. + + @param pDesc type description +*/ +void SAL_CALL typelib_typedescription_release( + typelib_TypeDescription * pDesc ) + SAL_THROW_EXTERN_C(); + +/** Registers a type description and creates a type description reference. Type descriptions + will be registered automatically if they are provided via the callback chain. + + @param ppNewDescription inout description to be registered; +*/ +void SAL_CALL typelib_typedescription_register( + typelib_TypeDescription ** ppNewDescription ) + SAL_THROW_EXTERN_C(); + +/** Tests whether two types descriptions are equal, i.e. type class and names are equal. + + @param p1 a type description + @param p2 another type description + @return true, if type descriptions are equal +*/ +sal_Bool SAL_CALL typelib_typedescription_equals( + const typelib_TypeDescription * p1, const typelib_TypeDescription * p2 ) + SAL_THROW_EXTERN_C(); + +/** Retrieves a type description via its fully qualified name. + + @param ppRet inout type description; *ppRet is 0, if type description was not found + @param pName name demanded type description +*/ +void SAL_CALL typelib_typedescription_getByName( + typelib_TypeDescription ** ppRet, rtl_uString * pName ) + SAL_THROW_EXTERN_C(); + +/** Sets size of type description cache. + + @param nNewSize new size of cache +*/ +void SAL_CALL typelib_setCacheSize( + sal_Int32 nNewSize ) + SAL_THROW_EXTERN_C(); + +/** Function pointer declaration of callback function get additional descriptions. Callbacks + must provide complete type descriptions (see typelib_typedescription_complete())! + + @param pContext callback context + @param ppRet inout type description + @param pTypeName name of demanded type description +*/ +typedef void (SAL_CALL * typelib_typedescription_Callback)( + void * pContext, typelib_TypeDescription ** ppRet, rtl_uString * pTypeName ); + +/** Registers callback function providing additional type descriptions. + + @param pContext callback context + @param pCallback callback function +*/ +void SAL_CALL typelib_typedescription_registerCallback( + void * pContext, typelib_typedescription_Callback pCallback ) + SAL_THROW_EXTERN_C(); + +/** Revokes a previously registered callback function. + + @param pContext callback context + @param pCallback registered callback function +*/ +void SAL_CALL typelib_typedescription_revokeCallback( + void * pContext, typelib_typedescription_Callback pCallback ) + SAL_THROW_EXTERN_C(); + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +/** Returns true, if the type description reference may lose the type description. Otherwise + pType is a valid pointer and cannot be discarded through the lifetime of this reference. + Remark: If the pWeakObj of the type is set too, you can avoid the call of + ...getDescription(...) and use the description directly. pWeakObj == 0 means, that the + description is not initialized. + @internal +*/ +#define TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass ) \ + ((eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || \ + (eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE) + +/** Gets a description from the reference. The description may not be locked by this call. + You must use the TYPELIB_DANGER_RELEASE macro to release the description fetched with + this macro. + @internal +*/ +#define TYPELIB_DANGER_GET( ppDescription, pTypeRef ) \ +{ \ + typelib_TypeDescriptionReference * pMacroTypeRef = (pTypeRef); \ + typelib_TypeDescription ** ppMacroTypeDescr = (ppDescription); \ + if (TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pMacroTypeRef->eTypeClass )) \ + { \ + typelib_typedescriptionreference_getDescription( ppMacroTypeDescr, pMacroTypeRef ); \ + } \ + else if (!pMacroTypeRef->pType || !pMacroTypeRef->pType->pWeakRef) \ + { \ + typelib_typedescriptionreference_getDescription( ppMacroTypeDescr, pMacroTypeRef ); \ + if (*ppMacroTypeDescr) \ + typelib_typedescription_release( *ppMacroTypeDescr ); \ + } \ + else \ + { \ + *ppMacroTypeDescr = pMacroTypeRef->pType; \ + } \ +} + +/** Releases the description previouse fetched by TYPELIB_DANGER_GET. + @internal +*/ +#define TYPELIB_DANGER_RELEASE( pDescription ) \ +{ \ + if (TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (pDescription)->eTypeClass )) \ + typelib_typedescription_release( pDescription ); \ +} + +/** Creates a type description reference. This is a weak reference not holding the description. + If the description is already registered, the previous one is returned. + + @param ppTDR inout type description reference + @param eTypeClass type class of type + @param pTypeName name of type +*/ +void SAL_CALL typelib_typedescriptionreference_new( + typelib_TypeDescriptionReference ** ppTDR, + typelib_TypeClass eTypeClass, + rtl_uString * pTypeName ) + SAL_THROW_EXTERN_C(); + +/** Creates a type description reference. This is a weak reference not holding the description. + If the description is already registered, the previous one is returned. + + @param ppTDR inout type description reference + @param eTypeClass type class of type + @param pTypeName ascii name of type +*/ +void SAL_CALL typelib_typedescriptionreference_newByAsciiName( + typelib_TypeDescriptionReference ** ppTDR, + typelib_TypeClass eTypeClass, + const sal_Char * pTypeName ) + SAL_THROW_EXTERN_C(); + +/** Increments reference count of type description reference. + + @param pRef type description reference +*/ +void SAL_CALL typelib_typedescriptionreference_acquire( + typelib_TypeDescriptionReference * pRef ) + SAL_THROW_EXTERN_C(); + +/** Increments reference count of type description reference. If the reference count reaches 0, + then the reference is deleted. + + @param pRef type description reference +*/ +void SAL_CALL typelib_typedescriptionreference_release( + typelib_TypeDescriptionReference * pRef ) + SAL_THROW_EXTERN_C(); + +/** Retrieves the type description for a given reference. If it is not possible to resolve the + reference, null is returned. + + @param ppRet inout type description +*/ +void SAL_CALL typelib_typedescriptionreference_getDescription( + typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef ) + SAL_THROW_EXTERN_C(); + +/** Tests whether two types description references are equal, i.e. type class and names are equal. + + @param p1 a type description reference + @param p2 another type description reference + @return true, if type description references are equal +*/ +sal_Bool SAL_CALL typelib_typedescriptionreference_equals( + const typelib_TypeDescriptionReference * p1, const typelib_TypeDescriptionReference * p2 ) + SAL_THROW_EXTERN_C(); + +/** Assigns a type. + + @param ppDest destination type + @param pSource source type +*/ +void SAL_CALL typelib_typedescriptionreference_assign( + typelib_TypeDescriptionReference ** ppDest, + typelib_TypeDescriptionReference * pSource ) + SAL_THROW_EXTERN_C(); + +/** Tests if values of type pAssignable can be assigned by values of type pFrom. This includes + widening conversion (e.g., long assignable from short), as long as there is no data loss. + + @param pAssignable type description of value to be assigned + @param pFrom type description of value +*/ +sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom( + typelib_TypeDescription * pAssignable, + typelib_TypeDescription * pFrom ) + SAL_THROW_EXTERN_C(); + +/** Tests if values of type pAssignable can be assigned by values of type pFrom. This includes + widening conversion (e.g., long assignable from short), as long as there is no data loss. + + @param pAssignable type of value to be assigned + @param pFrom type of value +*/ +sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom( + typelib_TypeDescriptionReference * pAssignable, + typelib_TypeDescriptionReference * pFrom ) + SAL_THROW_EXTERN_C(); + +/** Gets static type reference of standard types by type class. + ADDITIONAL OPT: provides Type com.sun.star.uno.Exception for typelib_TypeClass_EXCEPTION + and com.sun.star.uno.XInterface for typelib_TypeClass_INTERFACE. + + Thread synchronizes on typelib mutex. + + @param eTypeClass type class of basic type + @return pointer to type reference pointer +*/ +typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass( + typelib_TypeClass eTypeClass ) + SAL_THROW_EXTERN_C(); + +/** Inits static type reference. Thread synchronizes on typelib init mutex. + + @param ppRef pointer to type reference pointer + @param eTypeClass type class of type + @param pTypeName ascii name of type +*/ +void SAL_CALL typelib_static_type_init( + typelib_TypeDescriptionReference ** ppRef, + typelib_TypeClass eTypeClass, const sal_Char * pTypeName ) + SAL_THROW_EXTERN_C(); + +/** Inits static sequence type reference. Thread synchronizes on typelib init mutex. + + @param ppRef pointer to type reference pointer + @param pElementType element type of sequence +*/ +void SAL_CALL typelib_static_sequence_type_init( + typelib_TypeDescriptionReference ** ppRef, + typelib_TypeDescriptionReference * pElementType ) + SAL_THROW_EXTERN_C (); + +/** Inits static array type reference. Thread synchronizes on typelib init mutex. + + @param ppRef pointer to type reference pointer + @param pElementType element type of sequence + @param nDimensions number of dimensions + @param ... additional sal_Int32 parameter for each dimension +*/ +void SAL_CALL typelib_static_array_type_init( + typelib_TypeDescriptionReference ** ppRef, + typelib_TypeDescriptionReference * pElementType, + sal_Int32 nDimensions, ... ) + SAL_THROW_EXTERN_C (); + +/** Inits incomplete static compound type reference. Thread synchronizes on typelib init mutex. + + Since this function can only be used to create type descriptions for plain + struct types, not for instantiated polymorphic struct types, the function + typelib_static_struct_type_init should be used instead for all struct types. + + @param ppRef pointer to type reference pointer + @param eTypeClass typelib_TypeClass_STRUCT or typelib_TypeClass_EXCEPTION + @param pTypeName name of type + @param pBaseType base type + @param nMembers number of members + @param ppMembers member types +*/ +void SAL_CALL typelib_static_compound_type_init( + typelib_TypeDescriptionReference ** ppRef, + typelib_TypeClass eTypeClass, const sal_Char * pTypeName, + typelib_TypeDescriptionReference * pBaseType, + sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers ) + SAL_THROW_EXTERN_C(); + +/** Inits incomplete static struct type reference. + + Thread synchronizes on typelib init mutex. + + @param ppRef pointer to type reference pointer + @param pTypeName name of type + @param pBaseType base type + @param nMembers number of members + @param ppMembers member types + @param pParameterizedTypes flags for direct members, specifying whether they + are of parameterized type (true) or explict type (false); must be null + for a plain struct type + + @since UDK 3.2.0 +*/ +void SAL_CALL typelib_static_struct_type_init( + typelib_TypeDescriptionReference ** ppRef, const sal_Char * pTypeName, + typelib_TypeDescriptionReference * pBaseType, + sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers, + sal_Bool const * pParameterizedTypes ) + SAL_THROW_EXTERN_C(); + +/** Inits incomplete static interface type reference. Thread synchronizes on typelib init mutex. + + @param ppRef pointer to type reference pointer + @param pTypeName name of interface + @param pBaseType base type +*/ +void SAL_CALL typelib_static_interface_type_init( + typelib_TypeDescriptionReference ** ppRef, + const sal_Char * pTypeName, + typelib_TypeDescriptionReference * pBaseType ) + SAL_THROW_EXTERN_C(); + +/** Inits incomplete static multiple-inheritance interface type reference. + Thread synchronizes on typelib init mutex. + + @param ppRef pointer to type reference pointer + @param pTypeName name of interface + @param nBaseTypes number of base types + @param ppBaseTypes base types + + @since UDK 3.2.0 +*/ +void SAL_CALL typelib_static_mi_interface_type_init( + typelib_TypeDescriptionReference ** ppRef, + const sal_Char * pTypeName, + sal_Int32 nBaseTypes, + typelib_TypeDescriptionReference ** ppBaseTypes ) + SAL_THROW_EXTERN_C(); + +/** Inits incomplete static enum type reference. Thread synchronizes on typelib init mutex. + + @param ppRef pointer to type reference pointer + @param pTypeName name of enum + @param nDefaultEnumValue default enum value +*/ +void SAL_CALL typelib_static_enum_type_init( + typelib_TypeDescriptionReference ** ppRef, + const sal_Char * pTypeName, + sal_Int32 nDefaultValue ) + SAL_THROW_EXTERN_C(); + +/** Completes a typedescription to be used for, e.g., marshalling values. COMPOUND, UNION, + INTERFACE and ENUM type descriptions may be partly initialized (see typelib_static_...(), + typelib_TypeDescription::bComplete). For interface type descriptions, this will also + init index tables. + + @param ppTypeDescr [inout] type description to be completed (may be exchanged!) + @return true, if type description is complete +*/ +sal_Bool SAL_CALL typelib_typedescription_complete( + typelib_TypeDescription ** ppTypeDescr ) + SAL_THROW_EXTERN_C(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cppu/inc/typelib/typedescription.hxx b/cppu/inc/typelib/typedescription.hxx new file mode 100644 index 000000000000..61a6531d3529 --- /dev/null +++ b/cppu/inc/typelib/typedescription.hxx @@ -0,0 +1,226 @@ +/************************************************************************* + * + * 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 _TYPELIB_TYPEDESCRIPTION_HXX_ +#define _TYPELIB_TYPEDESCRIPTION_HXX_ + +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/Type.h> +#ifndef _TYPELIB_TYPEDESCRIPTION_H +#include <typelib/typedescription.h> +#endif + + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +/** C++ wrapper for typelib_TypeDescription. + Constructors by name, type, type description reference will get the full type description. + + @see typelib_TypeDescription +*/ +class TypeDescription +{ + /** C typelib type description + */ + mutable typelib_TypeDescription * _pTypeDescr; + +public: + // these are here to force memory de/allocation to sal lib. + /** @internal */ + inline static void * SAL_CALL operator new ( size_t nSize ) SAL_THROW( () ) + { return ::rtl_allocateMemory( nSize ); } + /** @internal */ + inline static void SAL_CALL operator delete ( void * pMem ) SAL_THROW( () ) + { ::rtl_freeMemory( pMem ); } + /** @internal */ + inline static void * SAL_CALL operator new ( size_t, void * pMem ) SAL_THROW( () ) + { return pMem; } + /** @internal */ + inline static void SAL_CALL operator delete ( void *, void * ) SAL_THROW( () ) + {} + + /** Constructor: + + @param pTypeDescr a type description + */ + inline TypeDescription( typelib_TypeDescription * pTypeDescr = 0 ) SAL_THROW( () ); + /** Constructor: + + @param pTypeDescrRef a type description reference + */ + inline TypeDescription( typelib_TypeDescriptionReference * pTypeDescrRef ) SAL_THROW( () ); + /** Constructor: + + @param rType a type + */ + inline TypeDescription( const ::com::sun::star::uno::Type & rType ) SAL_THROW( () ); + /** Copy constructor: + + @param rDescr another TypeDescription + */ + inline TypeDescription( const TypeDescription & rDescr ) SAL_THROW( () ); + /** Constructor: + + @param pTypeName a type name + */ + inline TypeDescription( rtl_uString * pTypeName ) SAL_THROW( () ); + /** Constructor: + + @param rTypeName a type name + */ + inline TypeDescription( const ::rtl::OUString & rTypeName ) SAL_THROW( () ); + /** Destructor: releases type description + */ + inline ~TypeDescription() SAL_THROW( () ); + + /** Assignment operator: acquires given type description and releases a set one. + + @param pTypeDescr another type description + @return this TypeDescription + */ + inline TypeDescription & SAL_CALL operator = ( typelib_TypeDescription * pTypeDescr ) SAL_THROW( () ); + /** Assignment operator: acquires given type description and releases a set one. + + @param rTypeDescr another type description + @return this TypeDescription + */ + inline TypeDescription & SAL_CALL operator =( const TypeDescription & rTypeDescr ) SAL_THROW( () ) + { return this->operator =( rTypeDescr.get() ); } + + /** Tests whether two type descriptions are equal. + + @param pTypeDescr another type description + @return true, if both type descriptions are equal, false otherwise + */ + inline sal_Bool SAL_CALL equals( const typelib_TypeDescription * pTypeDescr ) const SAL_THROW( () ); + /** Tests whether two type descriptions are equal. + + @param rTypeDescr another type description + @return true, if both type descriptions are equal, false otherwise + */ + inline sal_Bool SAL_CALL equals( const TypeDescription & rTypeDescr ) const SAL_THROW( () ) + { return equals( rTypeDescr._pTypeDescr ); } + + /** Makes stored type description complete. + */ + inline void SAL_CALL makeComplete() const SAL_THROW( () ); + + /** Gets the UNacquired type description pointer. + + @return stored pointer of type description + */ + inline typelib_TypeDescription * SAL_CALL get() const SAL_THROW( () ) + { return _pTypeDescr; } + /** Tests if a type description is set. + + @return true, if a type description is set, false otherwise + */ + inline sal_Bool SAL_CALL is() const SAL_THROW( () ) + { return (_pTypeDescr != 0); } +}; +//__________________________________________________________________________________________________ +inline TypeDescription::TypeDescription( typelib_TypeDescription * pTypeDescr ) SAL_THROW( () ) + : _pTypeDescr( pTypeDescr ) +{ + if (_pTypeDescr) + typelib_typedescription_acquire( _pTypeDescr ); +} +//__________________________________________________________________________________________________ +inline TypeDescription::TypeDescription( typelib_TypeDescriptionReference * pTypeDescrRef ) SAL_THROW( () ) + : _pTypeDescr( 0 ) +{ + if (pTypeDescrRef) + typelib_typedescriptionreference_getDescription( &_pTypeDescr, pTypeDescrRef ); +} +//__________________________________________________________________________________________________ +inline TypeDescription::TypeDescription( const ::com::sun::star::uno::Type & rType ) SAL_THROW( () ) + : _pTypeDescr( 0 ) +{ + if (rType.getTypeLibType()) + typelib_typedescriptionreference_getDescription( &_pTypeDescr, rType.getTypeLibType() ); +} +//__________________________________________________________________________________________________ +inline TypeDescription::TypeDescription( const TypeDescription & rTypeDescr ) SAL_THROW( () ) + : _pTypeDescr( rTypeDescr._pTypeDescr ) +{ + if (_pTypeDescr) + typelib_typedescription_acquire( _pTypeDescr ); +} +//__________________________________________________________________________________________________ +inline TypeDescription::TypeDescription( rtl_uString * pTypeName ) SAL_THROW( () ) + : _pTypeDescr( 0 ) +{ + typelib_typedescription_getByName( &_pTypeDescr , pTypeName ); +} +//__________________________________________________________________________________________________ +inline TypeDescription::TypeDescription( const ::rtl::OUString & rTypeName ) SAL_THROW( () ) + : _pTypeDescr( 0 ) +{ + typelib_typedescription_getByName( &_pTypeDescr , rTypeName.pData ); +} +//__________________________________________________________________________________________________ +inline TypeDescription::~TypeDescription() SAL_THROW( () ) +{ + if (_pTypeDescr) + typelib_typedescription_release( _pTypeDescr ); +} +//__________________________________________________________________________________________________ +inline TypeDescription & TypeDescription::operator = ( typelib_TypeDescription * pTypeDescr ) SAL_THROW( () ) +{ + if (pTypeDescr) + typelib_typedescription_acquire( pTypeDescr ); + if (_pTypeDescr) + typelib_typedescription_release( _pTypeDescr ); + _pTypeDescr = pTypeDescr; + return *this; +} +//__________________________________________________________________________________________________ +inline sal_Bool TypeDescription::equals( const typelib_TypeDescription * pTypeDescr ) const SAL_THROW( () ) +{ + return (_pTypeDescr && pTypeDescr && + typelib_typedescription_equals( _pTypeDescr, pTypeDescr )); +} +//__________________________________________________________________________________________________ +inline void TypeDescription::makeComplete() const SAL_THROW( () ) +{ + if (_pTypeDescr && !_pTypeDescr->bComplete) + ::typelib_typedescription_complete( &_pTypeDescr ); +} + +} +} +} +} + +#endif diff --git a/cppu/inc/typelib/uik.h b/cppu/inc/typelib/uik.h new file mode 100644 index 000000000000..06eead24f8bb --- /dev/null +++ b/cppu/inc/typelib/uik.h @@ -0,0 +1,53 @@ +/************************************************************************* + * + * 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 _TYPELIB_UIK_H_ +#define _TYPELIB_UIK_H_ + +#include <sal/types.h> + +#if defined( SAL_W32) +#pragma pack(push, 8) +#elif defined(SAL_OS2) +#pragma pack(push, 8) +#endif + +/** Binary typelib uik struct. Internally not used anymore. +*/ +typedef struct _typelib_Uik +{ + sal_uInt32 m_Data1; + sal_uInt16 m_Data2; + sal_uInt16 m_Data3; + sal_uInt32 m_Data4; + sal_uInt32 m_Data5; +} typelib_Uik; + +#if defined( SAL_W32) || defined(SAL_OS2) +# pragma pack(pop) +#endif + +#endif diff --git a/cppu/inc/uno/Enterable.h b/cppu/inc/uno/Enterable.h new file mode 100644 index 000000000000..d92013ec1404 --- /dev/null +++ b/cppu/inc/uno/Enterable.h @@ -0,0 +1,112 @@ +/************************************************************************* + * + * 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 INCLUDED_uno_Enterable_h +#define INCLUDED_uno_Enterable_h + +#include "uno/environment.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** Generic function type declaration for entering an Environment. + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Environment_Stack) + + @param context + @since UDK 3.2.7 +*/ +typedef void uno_Enterable_enter (void * context); + + +/** Generic function type declaration for levaing an Environment. + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Environment_Stack) + + @param context + @since UDK 3.2.7 +*/ +typedef void uno_Enterable_leave (void * context); + + +/** Generic function type declaration for calling into an Environment. + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Environment_Stack) + + @param context + @param pCallee the function to be called + @param pParam the parameter pointer to be passed to the function + @since UDK 3.2.7 +*/ +typedef void uno_Enterable_callInto_v(void * context, uno_EnvCallee * pCallee, va_list * pParam); + + +/** Generic function type declaration for calling out of an Environment. + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Environment_Stack) + + @param context + @param pCallee the function to be called + @param pParam the parameter pointer to be passed to the function + @since UDK 3.2.7 +*/ +typedef void uno_Enterable_callOut_v (void * context, uno_EnvCallee * pCallee, va_list * pParam); + + +/** Generic function type declaration for checking if calling on managed object is + valid. + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Environment_Stack) + + @param context + @param ppReason the reason, in case calling is not valid + @return 0 == calling is not valid, 1 == calling is valid + @since UDK 3.2.7 +*/ +typedef int uno_Enterable_isValid_v (void * context, rtl_uString ** ppReason); + + +/** A struct pReserved needs to point to, if implementing a purpose environment. + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Environment_Stack) + + @since UDK 3.2.7 +*/ +typedef struct +{ + uno_Enterable_enter * m_enter; + uno_Enterable_leave * m_leave; + uno_Enterable_callInto_v * m_callInto_v; + uno_Enterable_callOut_v * m_callOut_v; + uno_Enterable_isValid_v * m_isValid; +} +uno_Enterable; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cppu/inc/uno/EnvDcp.h b/cppu/inc/uno/EnvDcp.h new file mode 100644 index 000000000000..17d65bc57d9c --- /dev/null +++ b/cppu/inc/uno/EnvDcp.h @@ -0,0 +1,63 @@ +/************************************************************************* + * + * 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 INCLUDED_uno_EnvDcp_h +#define INCLUDED_uno_EnvDcp_h + +#include "rtl/ustring.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** Get the OBI type part of an environment descriptor. + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Environment_Descriptor) + + @param pEnvDcp the Environment Descriptor + @param ppEnvTypeName the OBI type + @since UDK 3.2.7 +*/ +void uno_EnvDcp_getTypeName(rtl_uString const * pEnvDcp, rtl_uString ** ppEnvTypeName); + + +/** Get the purpose part of an environment descriptor. + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Environment_Descriptor) + + @param pEnvDcp the Environment Descriptor + @param ppEnvPurpose the purpose + @since UDK 3.2.7 +*/ +void uno_EnvDcp_getPurpose (rtl_uString const * pEnvDcp, rtl_uString ** ppEnvPurpose); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/cppu/inc/uno/any2.h b/cppu/inc/uno/any2.h new file mode 100644 index 000000000000..72af895115b3 --- /dev/null +++ b/cppu/inc/uno/any2.h @@ -0,0 +1,178 @@ +/************************************************************************* + * + * 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 _UNO_ANY2_H_ +#define _UNO_ANY2_H_ + +#include <sal/types.h> +#include <uno/data.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined( SAL_W32) +#pragma pack(push, 8) +#elif defined(SAL_OS2) +#pragma pack(push, 8) +#endif + +struct _typelib_TypeDescriptionReference; +struct _typelib_TypeDescription; +struct _uno_Mapping; + +/** This is the binary specification of an UNO any. +*/ +typedef struct _uno_Any +{ + /** type of value + */ + struct _typelib_TypeDescriptionReference * pType; + /** pointer to value; this may point to pReserved and thus the uno_Any is not anytime + mem-copyable! You may have to correct the pData pointer to pReserved. Otherwise you need + not, because the data is stored in heap space. + */ + void * pData; + /** reserved space for storing value + */ + void * pReserved; +} uno_Any; + +#if defined( SAL_W32) || defined(SAL_OS2) +#pragma pack(pop) +#endif + +/** Assign an any with a given value. Interfaces are acquired or released by the given callback + functions. + + @param pDest pointer memory of destination any + @param pSource pointer to source value; defaults (0) to default constructed value + @param pTypeDescr type description of value; defaults (0) to void + @param acquire function called each time an interface needs to be acquired; + defaults (0) to uno + @param release function called each time an interface needs to be released; + defaults (0) to uno +*/ +void SAL_CALL uno_any_assign( + uno_Any * pDest, void * pSource, + struct _typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); +/** Assign an any with a given value. Interfaces are acquired or released by the given callback + functions. + + @param pDest pointer memory of destination any + @param pSource pointer to source value; defaults (0) to default constructed value + @param pTypeDescr type description of value; defaults (0) to void + @param acquire function called each time an interface needs to be acquired; + defaults (0) to uno + @param release function called each time an interface needs to be released; + defaults (0) to uno +*/ +void SAL_CALL uno_type_any_assign( + uno_Any * pDest, void * pSource, + struct _typelib_TypeDescriptionReference * pType, + uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +/** Constructs an any with a given value. Interfaces are acquired by the given callback function. + + @param pDest pointer memory of destination any + @param pSource pointer to source value; defaults (0) to default constructed value + @param pTypeDescr type description of value; defaults (0) to void + @param acquire function called each time an interface needs to be acquired; + defaults (0) to uno +*/ +void SAL_CALL uno_any_construct( + uno_Any * pDest, void * pSource, + struct _typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C(); +/** Constructs an any with a given value. Interfaces are acquired by the given callback function. + + @param pDest pointer memory of destination any + @param pSource pointer to source value; defaults (0) to default constructed value + @param pType type of value; defaults (0) to void + @param acquire function called each time an interface needs to be acquired; + defaults (0) to uno +*/ +void SAL_CALL uno_type_any_construct( + uno_Any * pDest, void * pSource, + struct _typelib_TypeDescriptionReference * pType, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C(); + +/** Constructs an any with a given value and converts/ maps interfaces. + + @param pDest pointer memory of destination any + @param pSource pointer to source value; defaults (0) to default constructed value + @param pTypeDescr type description of value; defaults (0) to void + @param mapping mapping to convert/ map interfaces +*/ +void SAL_CALL uno_any_constructAndConvert( + uno_Any * pDest, void * pSource, + struct _typelib_TypeDescription * pTypeDescr, + struct _uno_Mapping * mapping ) + SAL_THROW_EXTERN_C(); +/** Constructs an any with a given value and converts/ maps interfaces. + + @param pDest pointer memory of destination any + @param pSource pointer to source value; defaults (0) to default constructed value + @param pType type of value; defaults (0) to void + @param mapping mapping to convert/ map interfaces +*/ +void SAL_CALL uno_type_any_constructAndConvert( + uno_Any * pDest, void * pSource, + struct _typelib_TypeDescriptionReference * pType, + struct _uno_Mapping * mapping ) + SAL_THROW_EXTERN_C(); + +/** Destructs an any. + + @param pValue pointer to any + @param release function called each time an interface needs to be released; + defaults (0) to uno +*/ +void SAL_CALL uno_any_destruct( + uno_Any * pValue, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +/** Sets value to void. + + @param pValue pointer to any + @param release function called each time an interface needs to be released; + defaults (0) to uno +*/ +void SAL_CALL uno_any_clear( + uno_Any * pValue, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cppu/inc/uno/cuno.h b/cppu/inc/uno/cuno.h new file mode 100644 index 000000000000..dfe5edea7144 --- /dev/null +++ b/cppu/inc/uno/cuno.h @@ -0,0 +1,50 @@ +/************************************************************************* + * + * 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 _UNO_CUNO_H_ +#define _UNO_CUNO_H_ + +#include <sal/types.h> + +#define CUNO_ERROR_NONE 0 +#define CUNO_ERROR_CALL_FAILED (1 << 31) +#define CUNO_ERROR_EXCEPTION (1 | CUNO_ERROR_CALL_FAILED) + +/** macro to call on a C interface + + @param interface_pointer interface pointer +*/ +#define CUNO_CALL( interface_pointer ) (*interface_pointer) +/** macro to test if an exception was signalled. + + @param return_code return code of call +*/ +#define CUNO_EXCEPTION_OCCURED( return_code ) (0 != ((return_code) & CUNO_ERROR_EXCEPTION)) + +typedef sal_Int32 cuno_ErrorCode; + +#endif + diff --git a/cppu/inc/uno/current_context.h b/cppu/inc/uno/current_context.h new file mode 100644 index 000000000000..64edd60a4811 --- /dev/null +++ b/cppu/inc/uno/current_context.h @@ -0,0 +1,68 @@ +/************************************************************************* + * + * 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 _UNO_CURRENT_CONTEXT_H_ +#define _UNO_CURRENT_CONTEXT_H_ + +#include <rtl/ustring.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** Gets the current task's context. + @attention + Don't spread the returned interface around to other threads. Every thread has its own + current context. + + @param ppCurrentContext inout param current context of type com.sun.star.uno.XCurrentContext + @param pEnvDcp descriptor of returned interface's environment + @param pEnvContext context of returned interface's environment (commonly 0) + @return true, if context ref was transferred (even if null ref) +*/ +sal_Bool SAL_CALL uno_getCurrentContext( + void ** ppCurrentContext, + rtl_uString * pEnvDcp, void * pEnvContext ) + SAL_THROW_EXTERN_C(); + +/** Sets the current task's context. + + @param pCurrentContext in param current context of type com.sun.star.uno.XCurrentContext + @param pEnvDcp descriptor of interface's environment + @param pEnvContext context of interface's environment (commonly 0) + @return true, if context ref was transferred (even if null ref) +*/ +sal_Bool SAL_CALL uno_setCurrentContext( + void * pCurrentContext, + rtl_uString * pEnvDcp, void * pEnvContext ) + SAL_THROW_EXTERN_C(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cppu/inc/uno/current_context.hxx b/cppu/inc/uno/current_context.hxx new file mode 100644 index 000000000000..6cce6bc347a2 --- /dev/null +++ b/cppu/inc/uno/current_context.hxx @@ -0,0 +1,127 @@ +/************************************************************************* + * + * 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 _UNO_CURRENT_CONTEXT_HXX_ +#define _UNO_CURRENT_CONTEXT_HXX_ + +#include <uno/current_context.h> + +#include <com/sun/star/uno/XCurrentContext.hpp> + + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +/** Getting the current context. + @attention + Don't spread the returned interface around to other threads. Every thread has its own + current context. + + @return current context or null ref, if none is set +*/ +inline Reference< XCurrentContext > SAL_CALL getCurrentContext() + SAL_THROW( () ) +{ + Reference< XCurrentContext > xRet; + ::rtl::OUString aEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); + ::uno_getCurrentContext( (void **)&xRet, aEnvTypeName.pData, 0 ); + return xRet; +} +/** Setting the current context. + + @param xContext current context to be set + @return true, if context has been successfully set +*/ +inline bool SAL_CALL setCurrentContext( + Reference< XCurrentContext > const & xContext ) + SAL_THROW( () ) +{ + ::rtl::OUString aEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); + return (::uno_setCurrentContext( xContext.get(), aEnvTypeName.pData, 0 ) != sal_False); +} + +/** Objects of this class are used for applying a current context until they are destructed, i.e. + the ctor of this class saves the previous and sets the given context while the dtor restores + the previous one upon destruction. +*/ +class ContextLayer +{ + /** this C++ environment type name. + @internal + */ + ::rtl::OUString m_aEnvTypeName; + /** previous context + @internal + */ + Reference< XCurrentContext > m_xPreviousContext; + +public: + /** Constructor: Saves the previous context and sets the new (given) one. + + @param xNewContext new context to be set + */ + inline ContextLayer( + Reference< XCurrentContext > const & xNewContext = Reference< XCurrentContext >() ) + SAL_THROW( () ); + /** Destructor: restores the previous context. + */ + inline ~ContextLayer() SAL_THROW( () ); + + /** Gets the previously set context. + + @return the previously set context + */ + inline Reference< XCurrentContext > SAL_CALL getPreviousContext() const + SAL_THROW( () ) + { return m_xPreviousContext; } +}; +//__________________________________________________________________________________________________ +inline ContextLayer::ContextLayer( Reference< XCurrentContext > const & xNewContext ) + SAL_THROW( () ) + : m_aEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ) +{ + ::uno_getCurrentContext( (void **)&m_xPreviousContext, m_aEnvTypeName.pData, 0 ); + ::uno_setCurrentContext( xNewContext.get(), m_aEnvTypeName.pData, 0 ); +} +//__________________________________________________________________________________________________ +inline ContextLayer::~ContextLayer() + SAL_THROW( () ) +{ + ::uno_setCurrentContext( m_xPreviousContext.get(), m_aEnvTypeName.pData, 0 ); +} + +} +} +} +} + +#endif diff --git a/cppu/inc/uno/data.h b/cppu/inc/uno/data.h new file mode 100644 index 000000000000..31c3d57f3544 --- /dev/null +++ b/cppu/inc/uno/data.h @@ -0,0 +1,257 @@ +/************************************************************************* + * + * 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 _UNO_DATA_H_ +#define _UNO_DATA_H_ + +#include <sal/types.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct _typelib_TypeDescriptionReference; +struct _typelib_TypeDescription; +struct _typelib_InterfaceTypeDescription; +struct _uno_Mapping; + +/** Generic function pointer declaration to query for an interface. + + @param pInterface interface + @param pTypedemanded interface type + @return interface pointer +*/ +typedef void * (SAL_CALL * uno_QueryInterfaceFunc)( + void * pInterface, struct _typelib_TypeDescriptionReference * pType ); +/** Generic function pointer declaration to acquire an interface. + + @param pInterface interface to be acquired +*/ +typedef void (SAL_CALL * uno_AcquireFunc)( + void * pInterface ); +/** Generic function pointer declaration to release an interface. + + @param pInterface interface to be release +*/ +typedef void (SAL_CALL * uno_ReleaseFunc)( + void * pInterface ); + +/** Tests if two values are equal. May compare different types (e.g., short to long). + + @param pVal1 pointer to a value + @param pVal1TypeDescr type description of pVal1 + @param pVal2 pointer to another value + @param pVal2TypeDescr type description of pVal2 + @param queryInterface function called each time two interfaces are tested whether they belong + to the same object; defaults (0) to uno + @param release function to release queried interfaces; defaults (0) to uno + @return true if values are equal +*/ +sal_Bool SAL_CALL uno_equalData( + void * pVal1, struct _typelib_TypeDescription * pVal1TypeDescr, + void * pVal2, struct _typelib_TypeDescription * pVal2TypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); +/** Tests if two values are equal. May compare different types (e.g., short to long). + + @param pVal1 pointer to a value + @param pVal1Type type of pVal1 + @param pVal2 pointer to another value + @param pVal2Type type of pVal2 + @param queryInterface function called each time two interfaces are tested whether they belong + to the same object; defaults (0) to uno + @param release function to release queried interfaces; defaults (0) to uno + @return true if values are equal +*/ +sal_Bool SAL_CALL uno_type_equalData( + void * pVal1, struct _typelib_TypeDescriptionReference * pVal1Type, + void * pVal2, struct _typelib_TypeDescriptionReference * pVal2Type, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +/** Copy construct memory with given value. The size of the destination value must be larger + or equal to the size of the source value. + + @param pDest pointer to destination value memory + @param pSource pointer to source value + @param pTypeDescr type description of source + @param acquire function called each time an interface needs to be acquired; + defaults (0) to uno +*/ +void SAL_CALL uno_copyData( + void * pDest, void * pSource, + struct _typelib_TypeDescription * pTypeDescr, uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C(); +/** Copy construct memory with given value. The size of the destination value must be larger + or equal to the size of the source value. + + @param pDest pointer to destination value memory + @param pSource pointer to source value + @param pType type of source + @param acquire function called each time an interface needs to be acquired; + defaults (0) to uno +*/ +void SAL_CALL uno_type_copyData( + void * pDest, void * pSource, + struct _typelib_TypeDescriptionReference * pType, uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C(); + +/** Copy construct memory with given value. The size of the destination value must be larger + or equal to the size of the source value. Interfaces are converted/ mapped by mapping parameter. + + @param pDest pointer to destination value memory + @param pSource pointer to source value + @param pTypeDescr type description of source + @param mapping mapping to convert/ map interfaces +*/ +void SAL_CALL uno_copyAndConvertData( + void * pDest, void * pSource, + struct _typelib_TypeDescription * pTypeDescr, struct _uno_Mapping * mapping ) + SAL_THROW_EXTERN_C(); +/** Copy construct memory with given value. The size of the destination value must be larger + or equal to the size of the source value. Interfaces are converted/ mapped by mapping parameter. + + @param pDest pointer to destination value memory + @param pSource pointer to source value + @param pType type of source + @param mapping mapping to convert/ map interfaces +*/ +void SAL_CALL uno_type_copyAndConvertData( + void * pDest, void * pSource, + struct _typelib_TypeDescriptionReference * pType, struct _uno_Mapping * mapping ) + SAL_THROW_EXTERN_C(); + +/** Destructs a given value; does NOT free its memory! + + @param pValue value to be destructed + @param pTypeDescr type description of value + @param release function called each time an interface pointer needs to be released; + defaults (0) to uno +*/ +void SAL_CALL uno_destructData( + void * pValue, struct _typelib_TypeDescription * pTypeDescr, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); +/** Destructs a given value; does NOT free its memory! + + @param pValue value to be destructed + @param pType type of value + @param release function called each time an interface pointer needs to be released; + defaults (0) to uno +*/ +void SAL_CALL uno_type_destructData( + void * pValue, struct _typelib_TypeDescriptionReference * pType, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +/** Default constructs a value. All simple types are set to 0, enums are set to their default value. + + @param pMem pointer to memory of value to be constructed + @param pTypeDescr type description of value to be constructed +*/ +void SAL_CALL uno_constructData( + void * pMem, struct _typelib_TypeDescription * pTypeDescr ) + SAL_THROW_EXTERN_C(); +/** Default constructs a value. All simple types are set to 0, enums are set to their default value. + + @param pMem pointer to memory of value to be constructed + @param pType type of value to be constructed +*/ +void SAL_CALL uno_type_constructData( + void * pMem, struct _typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C(); + +/** Assigns a destination value with a source value. + Widening conversion WITHOUT data loss is allowed (e.g., assigning a long with a short). + Querying for demanded interface type is allowed. + Assignment from any value to a value of type Any and vice versa is allowed. + + @param pDest pointer to destination value + @param pDestTypeDescr type description of destination value + @param pSource pointer to source value; if 0, then destination value will be assigned + to default value + @param pSourceTypeDescr type destination of source value + @param queryInterface function called each time an interface needs to be queried; + defaults (0) to uno + @param acquire function called each time an interface needs to be acquired; + defaults (0) to uno + @param release function called each time an interface needs to be released; + defaults (0) to uno + @return true if destination has been successfully assigned +*/ +sal_Bool SAL_CALL uno_assignData( + void * pDest, struct _typelib_TypeDescription * pDestTypeDescr, + void * pSource, struct _typelib_TypeDescription * pSourceTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); +/** Assigns a destination value with a source value. + Widening conversion WITHOUT data loss is allowed (e.g., assigning a long with a short). + Querying for demanded interface type is allowed. + Assignment from any value to a value of type Any and vice versa is allowed. + + @param pDest pointer to destination value + @param pDestType type of destination value + @param pSource pointer to source value; if 0, then destination value will be assigned + to default value + @param pSourceType type of source value + @param queryInterface function called each time an interface needs to be queried; + defaults (0) to uno + @param acquire function called each time an interface needs to be acquired; + defaults (0) to uno + @param release function called each time an interface needs to be released; + defaults (0) to uno + @return true if destination has been successfully assigned +*/ +sal_Bool SAL_CALL uno_type_assignData( + void * pDest, struct _typelib_TypeDescriptionReference * pDestType, + void * pSource, struct _typelib_TypeDescriptionReference * pSourceType, + uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +/** Tests whether a value of given type is assignable from given value. + Widening conversion WITHOUT data loss is allowed (e.g., assigning a long with a short). + Querying for demanded interface type is allowed. + Assignment from any value to a value of type Any and vice versa is allowed. + + @param pAssignable type + @param pFrom pointer to value + @param pFromType type of value + @param queryInterface function called each time an interface needs to be queried; + defaults (0) to uno + @param release function called each time an interface needs to be released; + defaults (0) to uno + @return true if value is destination has been successfully assigned +*/ +sal_Bool SAL_CALL uno_type_isAssignableFromData( + struct _typelib_TypeDescriptionReference * pAssignable, + void * pFrom, struct _typelib_TypeDescriptionReference * pFromType, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cppu/inc/uno/dispatcher.h b/cppu/inc/uno/dispatcher.h new file mode 100644 index 000000000000..55475868fd24 --- /dev/null +++ b/cppu/inc/uno/dispatcher.h @@ -0,0 +1,97 @@ +/************************************************************************* + * + * 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 _UNO_DISPATCHER_H_ +#define _UNO_DISPATCHER_H_ + +#include <sal/types.h> +#include <rtl/ustring.h> +#include <uno/any2.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct _typelib_TypeDescription; +struct _uno_Interface; + +/** Function pointer declaration for the binary C uno dispatch function. Any pure out or return + value will be constructed by the callee, iff no exception is signalled. + If an exception is signalled, the any *ppException is properly constructed by the callee, + otherwise the pointer *ppException is set to 0. + An attribute get call is indicated by a non-null return pointer. + + @param pUnoI uno interface the call is performed on + @param pMemberType member type description of a method or attribute + @param pReturn pointer to return value memory; + pointer may be undefined if void method, null if attribute set call. + @param pArgs an array of pointers to arguments values. + (remark: the value of an interface reference stores a + uno_interface *, so you get it by *(uno_Interface **)pArgs[n]) + @param ppException pointer to pointer to unconstructed any to signal an exception. +*/ +typedef void (SAL_CALL * uno_DispatchMethod)( + struct _uno_Interface * pUnoI, + const struct _typelib_TypeDescription * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ); + +#if defined( SAL_W32) +#pragma pack(push, 8) +#elif defined(SAL_OS2) +#pragma pack(push, 8) +#endif + +/** The binary C uno interface description. +*/ +typedef struct _uno_Interface +{ + /** Acquires uno interface. + + @param pInterface uno interface + */ + void (SAL_CALL * acquire)( struct _uno_Interface * pInterface ); + /** Releases uno interface. + + @param pInterface uno interface + */ + void (SAL_CALL * release)( struct _uno_Interface * pInterface ); + /** dispatch function + */ + uno_DispatchMethod pDispatcher; +} uno_Interface; + +#if defined( SAL_W32) || defined(SAL_OS2) +#pragma pack(pop) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cppu/inc/uno/dispatcher.hxx b/cppu/inc/uno/dispatcher.hxx new file mode 100644 index 000000000000..a4a845fc738f --- /dev/null +++ b/cppu/inc/uno/dispatcher.hxx @@ -0,0 +1,175 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#if ! defined INCLUDED_UNO_DISPATCHER_HXX +#define INCLUDED_UNO_DISPATCHER_HXX + +#include "uno/dispatcher.h" + + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +/** C++ holder reference for binary C uno_Interface. Not for public use, may be + subject to changes. + + @see uno_Interface + @internal + not for public use! +*/ +class UnoInterfaceReference +{ +public: + uno_Interface * m_pUnoI; + + inline bool is() const + { return m_pUnoI != 0; } + + inline ~UnoInterfaceReference(); + inline UnoInterfaceReference(); + inline UnoInterfaceReference( uno_Interface * pUnoI, __sal_NoAcquire ); + inline UnoInterfaceReference( uno_Interface * pUnoI ); + inline UnoInterfaceReference( UnoInterfaceReference const & ref ); + + inline uno_Interface * get() const + { return m_pUnoI; } + + inline UnoInterfaceReference & set( + uno_Interface * pUnoI ); + inline UnoInterfaceReference & set( + uno_Interface * pUnoI, __sal_NoAcquire ); + inline void clear(); + + inline UnoInterfaceReference & operator = ( + UnoInterfaceReference const & ref ) + { return set( ref.m_pUnoI ); } + inline UnoInterfaceReference & operator = ( + uno_Interface * pUnoI ) + { return set( pUnoI ); } + + inline void dispatch( + struct _typelib_TypeDescription const * pMemberType, + void * pReturn, void * pArgs [], uno_Any ** ppException ) const; + +private: + inline bool operator == ( UnoInterfaceReference const & ); // not impl + inline bool operator != ( UnoInterfaceReference const & ); // not impl + inline bool operator == ( uno_Interface * ); // not impl + inline bool operator != ( uno_Interface * ); // not impl +}; + +//______________________________________________________________________________ +inline UnoInterfaceReference::~UnoInterfaceReference() +{ + if (m_pUnoI != 0) + (*m_pUnoI->release)( m_pUnoI ); +} + +//______________________________________________________________________________ +inline UnoInterfaceReference::UnoInterfaceReference() + : m_pUnoI( 0 ) +{ +} + +//______________________________________________________________________________ +inline UnoInterfaceReference::UnoInterfaceReference( + uno_Interface * pUnoI, __sal_NoAcquire ) + : m_pUnoI( pUnoI ) +{ +} + +//______________________________________________________________________________ +inline UnoInterfaceReference::UnoInterfaceReference( uno_Interface * pUnoI ) + : m_pUnoI( pUnoI ) +{ + if (m_pUnoI != 0) + (*m_pUnoI->acquire)( m_pUnoI ); +} + +//______________________________________________________________________________ +inline UnoInterfaceReference::UnoInterfaceReference( + UnoInterfaceReference const & ref ) + : m_pUnoI( ref.m_pUnoI ) +{ + if (m_pUnoI != 0) + (*m_pUnoI->acquire)( m_pUnoI ); +} + +//______________________________________________________________________________ +inline UnoInterfaceReference & UnoInterfaceReference::set( + uno_Interface * pUnoI ) +{ + if (pUnoI != 0) + (*pUnoI->acquire)( pUnoI ); + if (m_pUnoI != 0) + (*m_pUnoI->release)( m_pUnoI ); + m_pUnoI = pUnoI; + return *this; +} + +//______________________________________________________________________________ +inline UnoInterfaceReference & UnoInterfaceReference::set( + uno_Interface * pUnoI, __sal_NoAcquire ) +{ + if (m_pUnoI != 0) + (*m_pUnoI->release)( m_pUnoI ); + m_pUnoI = pUnoI; + return *this; +} + +//______________________________________________________________________________ +inline void UnoInterfaceReference::clear() +{ + if (m_pUnoI != 0) + { + (*m_pUnoI->release)( m_pUnoI ); + m_pUnoI = 0; + } +} + +//______________________________________________________________________________ +inline void UnoInterfaceReference::dispatch( + struct _typelib_TypeDescription const * pMemberType, + void * pReturn, void * pArgs [], uno_Any ** ppException ) const +{ + (*m_pUnoI->pDispatcher)( + m_pUnoI, pMemberType, pReturn, pArgs, ppException ); +} + +} +} +} +} + +#endif + diff --git a/cppu/inc/uno/environment.h b/cppu/inc/uno/environment.h new file mode 100644 index 000000000000..f959aa2571f4 --- /dev/null +++ b/cppu/inc/uno/environment.h @@ -0,0 +1,385 @@ +/************************************************************************* + * + * 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 _UNO_ENVIRONMENT_H_ +#define _UNO_ENVIRONMENT_H_ + +#include <sal/types.h> +#include <rtl/ustring.h> + +#include <stdarg.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct _uno_ExtEnvironment; +struct _typelib_InterfaceTypeDescription; + +#if defined( SAL_W32) +#pragma pack(push, 8) +#elif defined(SAL_OS2) +#pragma pack(push, 8) +#endif + +/** The binary specification of an UNO environment. +*/ +typedef struct _uno_Environment +{ + /** reserved for future use (0 if not used) + */ + void * pReserved; + + /** type name of environment + */ + rtl_uString * pTypeName; + + /** free context pointer to be used for specific classes of environments (e.g., a jvm pointer) + */ + void * pContext; + + /** pointer to extended environment (interface registration functionality), if supported + */ + struct _uno_ExtEnvironment * pExtEnv; + + /** Acquires this environment. + + @param pEnv this environment + */ + void (SAL_CALL * acquire)( struct _uno_Environment * pEnv ); + + /** Releases this environment; last release of environment will revoke the environment from + runtime. + + @param pEnv this environment + */ + void (SAL_CALL * release)( struct _uno_Environment * pEnv ); + + /** Acquires this environment weakly. You can only harden a weakly held environment if it + is still acquired hard (acquire()). + + @param pEnv this environment + */ + void (SAL_CALL * acquireWeak)( struct _uno_Environment * pEnv ); + + /** Releases this environment weakly in correspondence to acquireWeak(). + + @param pEnv this environment + */ + void (SAL_CALL * releaseWeak)( struct _uno_Environment * pEnv ); + + /** Makes hard reference out of weak referenced environment. You can only harden a weakly + held environment if it is still acquired hard (acquire()). + + @param ppHardEnv inout hard referenced environment (has to be released via release()) + @param pEnv environment (may be weak referenced) + */ + void (SAL_CALL * harden)( + struct _uno_Environment ** ppHardEnv, + struct _uno_Environment * pEnv ); + + /** Call this function to EXPLICITLY dispose this environment (e.g., release all + interfaces). You may want to call this function before shutting down due to a runtime error. + + @param pEnv this environment + */ + void (SAL_CALL * dispose)( struct _uno_Environment * pEnv ); + + /* ===== the following part will be late initialized by a matching bridge ===== * + * ===== and is NOT for public use. ===== */ + + /** CALLBACK function pointer: Disposing callback function pointer that can be set to get + signalled before the environment is destroyed. + + @param pEnv environment that is being disposed + */ + void (SAL_CALL * environmentDisposing)( struct _uno_Environment * pEnv ); +} uno_Environment; + +/** Generic function pointer declaration to free a proxy object if it is not needed by the + environment anymore. + Any proxy object must register itself on first acquire() call and revoke itself on last + release() call. This can happen several times because the environment caches proxy objects + until the environment explicitly frees the proxy object calling this function. + + @param pEnv environment + @param pProxy proxy pointer +*/ +typedef void (SAL_CALL * uno_freeProxyFunc)( struct _uno_ExtEnvironment * pEnv, void * pProxy ); + +/** Generic function pointer declaration to allocate memory. Used with getRegisteredInterfaces(). + + @param nBytes amount of memory in bytes + @return pointer to allocated memory +*/ +typedef void * (SAL_CALL * uno_memAlloc)( sal_Size nBytes ); + +/** The binary specification of an UNO environment supporting interface registration. +*/ +typedef struct _uno_ExtEnvironment +{ + /** inherits all members of an uno_Environment + */ + uno_Environment aBase; + + /** Registers an interface of this environment. + + @param pEnv this environment + @param ppInterface inout parameter of interface to be registered + @param pOId object id of interface + @param pTypeDescr type description of interface + */ + void (SAL_CALL * registerInterface)( + struct _uno_ExtEnvironment * pEnv, + void ** ppInterface, + rtl_uString * pOId, + struct _typelib_InterfaceTypeDescription * pTypeDescr ); + + /** Registers a proxy interface of this environment that can be reanimated and is freed + explicitly by this environment. + + @param pEnv this environment + @param ppInterface inout parameter of interface to be registered + @param freeProxy function to free proxy object + @param pOId object id of interface + @param pTypeDescr type description of interface + */ + void (SAL_CALL * registerProxyInterface)( + struct _uno_ExtEnvironment * pEnv, + void ** ppProxy, + uno_freeProxyFunc freeProxy, + rtl_uString * pOId, + struct _typelib_InterfaceTypeDescription * pTypeDescr ); + + /** Revokes an interface from this environment. You have to revoke any interface that has + been registered via this method. + + @param pEnv this environment + @param pInterface interface to be revoked + */ + void (SAL_CALL * revokeInterface)( + struct _uno_ExtEnvironment * pEnv, + void * pInterface ); + + /** Provides the object id of a given interface. + + @param ppOut inout oid + @param pInterface interface of object + */ + void (SAL_CALL * getObjectIdentifier)( + struct _uno_ExtEnvironment * pEnv, + rtl_uString ** ppOId, + void * pInterface ); + + /** Retrieves an interface identified by its object id and type from this environment. + Interfaces are retrieved in the same order as they are registered. + + @param pEnv this environment + @param ppInterface inout parameter for the registered interface; (0) if none was found + @param pOId object id of interface to be retrieved + @param pTypeDescr type description of interface to be retrieved + */ + void (SAL_CALL * getRegisteredInterface)( + struct _uno_ExtEnvironment * pEnv, + void ** ppInterface, + rtl_uString * pOId, + struct _typelib_InterfaceTypeDescription * pTypeDescr ); + + /** Returns all currently registered interfaces of this environment. The memory block + allocated might be slightly larger than (*pnLen * sizeof(void *)). + + @param pEnv this environment + @param pppInterfaces out param; pointer to array of interface pointers + @param pnLen out param; length of array + @param memAlloc function for allocating memory that is passed back + */ + void (SAL_CALL * getRegisteredInterfaces)( + struct _uno_ExtEnvironment * pEnv, + void *** pppInterfaces, + sal_Int32 * pnLen, + uno_memAlloc memAlloc ); + + /* ===== the following part will be late initialized by a matching bridge ===== */ + + /** Computes an object id of the given interface; is called by the environment implementation. + + @param pEnv corresponding environment + @param ppOId out param: computed id + @param pInterface an interface + */ + void (SAL_CALL * computeObjectIdentifier)( + struct _uno_ExtEnvironment * pEnv, + rtl_uString ** ppOId, void * pInterface ); + + /** Function to acquire an interface. + + @param pEnv corresponding environment + @param pInterface an interface + */ + void (SAL_CALL * acquireInterface)( + struct _uno_ExtEnvironment * pEnv, + void * pInterface ); + + /** Function to release an interface. + + @param pEnv corresponding environment + @param pInterface an interface + */ + void (SAL_CALL * releaseInterface)( + struct _uno_ExtEnvironment * pEnv, + void * pInterface ); + +} uno_ExtEnvironment; + +#if defined( SAL_W32) || defined(SAL_OS2) +#pragma pack(pop) +#endif + +/** Function exported by some bridge library providing acquireInterface(), releaseInterface(); + may set a disposing callback. + + @param pEnv environment to be initialized +*/ +typedef void (SAL_CALL * uno_initEnvironmentFunc)( uno_Environment * pEnv ); +#define UNO_INIT_ENVIRONMENT "uno_initEnvironment" + +/** Gets a specific environment. If the specified environment does not exist, then a default one + is created and registered. The environment revokes itself on last release() call. + + @param ppEnv inout parameter of environment; given environment will be released + @param pEnvDcp descriptor of environment + @param pContext some context pointer (e.g., to distinguish java vm; set 0 if not needed) +*/ +void SAL_CALL uno_getEnvironment( + uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext ) + SAL_THROW_EXTERN_C(); + +/** Gets all specified environments. Caller has to release returned environments and free allocated + memory. + + @param pppEnvs out param; pointer to array of environments + @param pnLen out param; length of array + @param memAlloc function for allocating memory that is passed back + @param pEnvDcp descriptor of environments; 0 defaults to all +*/ +void SAL_CALL uno_getRegisteredEnvironments( + uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc, + rtl_uString * pEnvDcp ) + SAL_THROW_EXTERN_C(); + +/** Creates an environment. The new environment is anonymous (NOT publicly registered/ accessible). + + @param ppEnv out parameter of environment; given environment will be released + @param pEnvDcp descriptor of environment + @param pContext context pointer (e.g., to distinguish java vm); set 0 if not needed +*/ +void SAL_CALL uno_createEnvironment( + uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext ) + SAL_THROW_EXTERN_C(); + +/** Dumps out environment information, i.e. registered interfaces. + + @param stream output stream (FILE *) + @param pEnv environment to be dumped + @param pFilter if not null, filters output +*/ +void SAL_CALL uno_dumpEnvironment( + void * stream, uno_Environment * pEnv, const sal_Char * pFilter ) + SAL_THROW_EXTERN_C(); +/** Dumps out environment information, i.e. registered interfaces. + + @param stream output stream (FILE *) + @param pEnvDcp descritpro of environment to be dumped + @param pFilter if not null, filters output +*/ +void SAL_CALL uno_dumpEnvironmentByName( + void * stream, rtl_uString * pEnvDcp, const sal_Char * pFilter ) + SAL_THROW_EXTERN_C(); + + + +/** Returns the current Environment. + In case no Environment has explicitly been entered, a purpose free + default environment gets returned (e.g. the "uno" or "gcc3" Environment). + + @param ppEnv inout parameter; a given environment will be released + @param pTypeName the optional type of the environment, falls back to "uno" + @since UDK 3.2.7 +*/ +void SAL_CALL uno_getCurrentEnvironment(uno_Environment ** ppEnv, rtl_uString * pTypeName) + SAL_THROW_EXTERN_C(); + +/** Typedef for variable argument function. + */ +typedef void SAL_CALL uno_EnvCallee(va_list * pParam); + +/** Invoke the passed function in the given environment. + + @param pEnv the target environment + @param pCallee the function to call + @param pParam the parameter pointer passed to the function + @since UDK 3.2.7 + */ +void SAL_CALL uno_Environment_invoke_v(uno_Environment * pEnv, uno_EnvCallee * pCallee, va_list * pParam) + SAL_THROW_EXTERN_C(); + +/** Invoke the passed function in the given environment. + + @param pEnv the target environment + @param pCallee the function to call + @param ... the parameters passed to the function + @since UDK 3.2.7 +*/ +void SAL_CALL uno_Environment_invoke (uno_Environment * pEnv, uno_EnvCallee * pCallee, ...) + SAL_THROW_EXTERN_C(); + +/** Enter an environment explicitly. + + @param pEnv the environment to enter; NULL leaves all environments + @since UDK 3.2.7 +*/ +void SAL_CALL uno_Environment_enter(uno_Environment * pEnv) + SAL_THROW_EXTERN_C(); + +/** Check if a particular environment is currently valid, so + that objects of that environment might be called. + + @param pEnv the environment + @param rtl_uString ** pReason the reason, if it is not valid + @return 1 == valid, 0 == invalid + @since UDK 3.2.7 +*/ +int SAL_CALL uno_Environment_isValid(uno_Environment * pEnv, rtl_uString ** pReason) + SAL_THROW_EXTERN_C(); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cppu/inc/uno/environment.hxx b/cppu/inc/uno/environment.hxx new file mode 100644 index 000000000000..c204b0a2dfa0 --- /dev/null +++ b/cppu/inc/uno/environment.hxx @@ -0,0 +1,278 @@ +/************************************************************************* + * + * 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 _UNO_ENVIRONMENT_HXX_ +#define _UNO_ENVIRONMENT_HXX_ + +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> +#include <uno/environment.h> + +#include "uno/lbnames.h" + +/** */ //for docpp +namespace com +{ +/** */ //for docpp +namespace sun +{ +/** */ //for docpp +namespace star +{ +/** */ //for docpp +namespace uno +{ + +/** C++ wrapper for binary C uno_Environment. + + @see uno_Environment +*/ +class Environment +{ + /** binary C uno_Environment + */ + uno_Environment * _pEnv; + +public: + /** Returns the current Environment. + + @param env_type the optional type of the Environment, falls back to "uno" in case being empty, + respectively to current C++ Environment. + @since UDK 3.2.7 + */ + inline static Environment getCurrent(rtl::OUString const & typeName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV)))) SAL_THROW( () ); + + // these are here to force memory de/allocation to sal lib. + /** @internal */ + inline static void * SAL_CALL operator new ( size_t nSize ) SAL_THROW( () ) + { return ::rtl_allocateMemory( nSize ); } + /** @internal */ + inline static void SAL_CALL operator delete ( void * pMem ) SAL_THROW( () ) + { ::rtl_freeMemory( pMem ); } + /** @internal */ + inline static void * SAL_CALL operator new ( size_t, void * pMem ) SAL_THROW( () ) + { return pMem; } + /** @internal */ + inline static void SAL_CALL operator delete ( void *, void * ) SAL_THROW( () ) + {} + + /** Constructor: acquires given environment + + @param pEnv environment + */ + inline Environment( uno_Environment * pEnv = 0 ) SAL_THROW( () ); + + /** Gets a specific environment. If the specified environment does not exist, then a default one + is created and registered. + + @param envDcp descriptor of the environment + @param pContext context pointer + */ + inline explicit Environment( rtl::OUString const & envDcp, void * pContext = NULL ) SAL_THROW( () ); + + + /** Copy constructor: acquires given environment + + @param rEnv another environment + */ + inline Environment( const Environment & rEnv ) SAL_THROW( () ); + + /** Destructor: releases a set environment. + */ + inline ~Environment() SAL_THROW( () ); + + /** Sets a given environment, i.e. acquires given one and releases a set one. + + @param pEnv another environment + @return this environment + */ + inline Environment & SAL_CALL operator = ( uno_Environment * pEnv ) SAL_THROW( () ); + /** Sets a given environment, i.e. acquires given one and releases a set one. + + @param rEnv another environment + @return this environment + */ + inline Environment & SAL_CALL operator = ( const Environment & rEnv ) SAL_THROW( () ) + { return operator = ( rEnv._pEnv ); } + + /** Provides UNacquired pointer to the set C environment. + + @return UNacquired pointer to the C environment struct + */ + inline uno_Environment * SAL_CALL get() const SAL_THROW( () ) + { return _pEnv; } + + /** Gets type name of set environment. + + @return type name of set environment + */ + inline ::rtl::OUString SAL_CALL getTypeName() const SAL_THROW( () ) + { return _pEnv->pTypeName; } + + /** Gets free context pointer of set environment. + + @return free context pointer of set environment + */ + inline void * SAL_CALL getContext() const SAL_THROW( () ) + { return _pEnv->pContext; } + + /** Tests if a environment is set. + + @return true, if a environment is set, false otherwise + */ + inline sal_Bool SAL_CALL is() const SAL_THROW( () ) + { return (_pEnv != 0); } + + /** Releases a set environment. + */ + inline void SAL_CALL clear() SAL_THROW( () ); + + /** Invoke the passed function in this environment. + + @param pCallee the function to call + @param pParam the parameter pointer to be passed to the function + @since UDK 3.2.7 + */ + inline void SAL_CALL invoke_v(uno_EnvCallee * pCallee, va_list * pParam) const SAL_THROW( () ); + + /** Invoke the passed function in this environment. + + @param pCallee the function to call + @param ... the parameters to be passed to the function + @since UDK 3.2.7 + */ + inline void SAL_CALL invoke(uno_EnvCallee * pCallee, ...) const SAL_THROW( () ); + + /** Enter this environment explicitly. + + @since UDK 3.2.7 + */ + inline void SAL_CALL enter() const SAL_THROW( () ); + + /** Checks, if it is valid to currently call objects + belonging to this environment. + + @since UDK 3.2.7 + */ + inline int SAL_CALL isValid(rtl::OUString * pReason) const SAL_THROW( () ); +}; +//__________________________________________________________________________________________________ +inline Environment::Environment( uno_Environment * pEnv ) SAL_THROW( () ) + : _pEnv( pEnv ) +{ + if (_pEnv) + (*_pEnv->acquire)( _pEnv ); +} +//__________________________________________________________________________________________________ +inline Environment::Environment( rtl::OUString const & rEnvDcp, void * pContext ) SAL_THROW( () ) + : _pEnv(NULL) +{ + uno_getEnvironment(&_pEnv, rEnvDcp.pData, pContext); +} +//__________________________________________________________________________________________________ +inline Environment::Environment( const Environment & rEnv ) SAL_THROW( () ) + : _pEnv( rEnv._pEnv ) +{ + if (_pEnv) + (*_pEnv->acquire)( _pEnv ); +} +//__________________________________________________________________________________________________ +inline Environment::~Environment() SAL_THROW( () ) +{ + if (_pEnv) + (*_pEnv->release)( _pEnv ); +} +//__________________________________________________________________________________________________ +inline void Environment::clear() SAL_THROW( () ) +{ + if (_pEnv) + { + (*_pEnv->release)( _pEnv ); + _pEnv = 0; + } +} +//__________________________________________________________________________________________________ +inline Environment & Environment::operator = ( uno_Environment * pEnv ) SAL_THROW( () ) +{ + if (pEnv != _pEnv) + { + if (pEnv) + (*pEnv->acquire)( pEnv ); + if (_pEnv) + (*_pEnv->release)( _pEnv ); + _pEnv = pEnv; + } + return *this; +} +//__________________________________________________________________________________________________ +inline void SAL_CALL Environment::invoke_v(uno_EnvCallee * pCallee, va_list * pParam) const SAL_THROW( () ) +{ + if (_pEnv) + uno_Environment_invoke_v(_pEnv, pCallee, pParam); +} +//__________________________________________________________________________________________________ +inline void SAL_CALL Environment::invoke(uno_EnvCallee * pCallee, ...) const SAL_THROW( () ) +{ + if (_pEnv) + { + va_list param; + + va_start(param, pCallee); + uno_Environment_invoke_v(_pEnv, pCallee, ¶m); + va_end(param); + } + +} +//__________________________________________________________________________________________________ +inline void SAL_CALL Environment::enter() const SAL_THROW( () ) +{ + uno_Environment_enter(_pEnv); +} +//__________________________________________________________________________________________________ +inline int SAL_CALL Environment::isValid(rtl::OUString * pReason) const SAL_THROW( () ) +{ + return uno_Environment_isValid(_pEnv, (rtl_uString **)pReason); +} +//__________________________________________________________________________________________________ +inline Environment Environment::getCurrent(rtl::OUString const & typeName) SAL_THROW( () ) +{ + Environment environment; + + uno_Environment * pEnv = NULL; + uno_getCurrentEnvironment(&pEnv, typeName.pData); + environment = pEnv; + if (pEnv) + pEnv->release(pEnv); + + return environment; +} + +} +} +} +} + +#endif diff --git a/cppu/inc/uno/lbnames.h b/cppu/inc/uno/lbnames.h new file mode 100644 index 000000000000..4bca6a8a9dd5 --- /dev/null +++ b/cppu/inc/uno/lbnames.h @@ -0,0 +1,58 @@ +/************************************************************************* + * + * 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 _UNO_LBNAMES_H_ +#define _UNO_LBNAMES_H_ + +#ifdef __cplusplus + +#ifdef CPPU_ENV + +#define CPPU_STRINGIFY_EX( x ) #x +#define CPPU_STRINGIFY( x ) CPPU_STRINGIFY_EX( x ) + +/** Name for C++ compiler/ platform, e.g. "gcc3", "msci" */ +#define CPPU_CURRENT_LANGUAGE_BINDING_NAME CPPU_STRINGIFY( CPPU_ENV ) + +#else + +#error "No supported C++ compiler environment." +provoking error here, because PP ignores #error + +#endif /* CPPU_ENV */ + +#endif /* __cplusplus */ + +/** Environment type name for binary C UNO. */ +#define UNO_LB_UNO "uno" +/** Environment type name for ANSI C compilers. */ +#define UNO_LB_C "c" +/** Environment type name for Java 1.3.1 compatible virtual machine. */ +#define UNO_LB_JAVA "java" +/** Environment type name for CLI (Common Language Infrastructure). */ +#define UNO_LB_CLI "cli" + +#endif diff --git a/cppu/inc/uno/mapping.h b/cppu/inc/uno/mapping.h new file mode 100644 index 000000000000..3254d3c7c47d --- /dev/null +++ b/cppu/inc/uno/mapping.h @@ -0,0 +1,203 @@ +/************************************************************************* + * + * 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 _UNO_MAPPING_H_ +#define _UNO_MAPPING_H_ + +#include <sal/types.h> +#include <rtl/ustring.h> + + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct _typelib_InterfaceTypeDescription; +struct _uno_Mapping; +struct _uno_Environment; + +/** + Function pointer declaration to acquire a UNO mapping. +*/ +typedef void (SAL_CALL * uno_AcquireMappingFunc)(struct _uno_Mapping *); + +/** + Function pointer declaration to release a UNO mapping. +*/ +typedef void (SAL_CALL * uno_ReleaseMappingFunc)(struct _uno_Mapping *); + +/** Function pointer declaration to map an interface from one environment to another. + + @param pMapping mapping + @param ppOut [inout] destination interface; existing interfaces are released + @param pInterface source interface + @param pInterfaceTypeDescr type description of the interface +*/ +typedef void (SAL_CALL * uno_MapInterfaceFunc)( + struct _uno_Mapping * pMapping, + void ** ppOut, void * pInterface, + struct _typelib_InterfaceTypeDescription * pInterfaceTypeDescr ); + + +#if defined( SAL_W32) +#pragma pack(push, 8) +#elif defined(SAL_OS2) +#pragma pack(push, 8) +#endif + +/** This is the binary specification of a mapping. +*/ +typedef struct _uno_Mapping +{ + /** Acquires mapping + */ + uno_AcquireMappingFunc acquire; + + /** Releases mapping. The last release may unload bridges. + */ + uno_ReleaseMappingFunc release; + + /** mapping function + */ + uno_MapInterfaceFunc mapInterface; +} uno_Mapping; + +#if defined( SAL_W32) || defined(SAL_OS2) +#pragma pack(pop) +#endif + +/** Gets an interface mapping from one environment to another. + + @param ppMapping [inout] mapping; existing mapping will be released + @param pFrom source environment + @param pTo destination environment + (interfaces resulting in mapInterface() call can be used + in this language environment) + @param pAddPurpose additional purpose of mapping (e.g., protocolling); defaults to 0 (none) +*/ +void SAL_CALL uno_getMapping( + struct _uno_Mapping ** ppMapping, + struct _uno_Environment * pFrom, + struct _uno_Environment * pTo, + rtl_uString * pAddPurpose ) + SAL_THROW_EXTERN_C(); + +/** Callback function pointer declaration to get a mapping. + + @param ppMapping inout mapping + @param pFrom source environment + @param pTo destination environment + @param pAddPurpose additional purpose +*/ +typedef void (SAL_CALL * uno_getMappingFunc)( + struct _uno_Mapping ** ppMapping, + struct _uno_Environment * pFrom, + struct _uno_Environment * pTo, + rtl_uString * pAddPurpose ); + +/** Registers a callback being called each time a mapping is demanded. + + @param pCallback callback function +*/ +void SAL_CALL uno_registerMappingCallback( + uno_getMappingFunc pCallback ) + SAL_THROW_EXTERN_C(); + +/** Revokes a mapping callback registration. + + @param pCallback callback function +*/ +void SAL_CALL uno_revokeMappingCallback( + uno_getMappingFunc pCallback ) + SAL_THROW_EXTERN_C(); + +/** Function pointer declaration to free a mapping. + + @param pMapping mapping to be freed +*/ +typedef void (SAL_CALL * uno_freeMappingFunc)( struct _uno_Mapping * pMapping ); + +/** Registers a mapping. A mapping registers itself on first acquire and revokes itself on last + release. The given freeMapping function is called by the runtime to cleanup any resources. + + @param ppMapping inout mapping to be registered + @param freeMapping called by runtime to delete mapping + @param pFrom source environment + @param pTo destination environment + @param pAddPurpose additional purpose string; defaults to 0 +*/ +void SAL_CALL uno_registerMapping( + struct _uno_Mapping ** ppMapping, uno_freeMappingFunc freeMapping, + struct _uno_Environment * pFrom, struct _uno_Environment * pTo, rtl_uString * pAddPurpose ) + SAL_THROW_EXTERN_C(); + +/** Revokes a mapping. A mapping registers itself on first acquire and revokes itself on last + release. + + @param pMapping mapping to be revoked +*/ +void SAL_CALL uno_revokeMapping( + struct _uno_Mapping * pMapping ) + SAL_THROW_EXTERN_C(); + +/** Gets an interface mapping from one language environment to another by corresponding environment + type names. + + @param ppMapping [inout] mapping; existing mapping will be released + @param pFrom source environment type name + @param pTo destination environment type name + (interfaces resulting in mapInterface() call can be used + in this language environment) + @param pAddPurpose additional purpose of mapping (e.g., protocolling); defaults to 0 (none) +*/ +void SAL_CALL uno_getMappingByName( + struct _uno_Mapping ** ppMapping, + rtl_uString * pFrom, + rtl_uString * pTo, + rtl_uString * pAddPurpose ) + SAL_THROW_EXTERN_C(); + +/* symbol exported by each language binding library */ +#define UNO_EXT_GETMAPPING "uno_ext_getMapping" + +/** Function pointer declaration to get a mapping from a loaded bridge. Bridges export a function + called uno_ext_getMapping() of this signature. + + @param ppMapping [inout] mapping; existing mapping will be released + @pFrom source environment + @pTo destination environment +*/ +typedef void (SAL_CALL * uno_ext_getMappingFunc)( + struct _uno_Mapping ** ppMapping, + struct _uno_Environment * pFrom, + struct _uno_Environment * pTo ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cppu/inc/uno/mapping.hxx b/cppu/inc/uno/mapping.hxx new file mode 100644 index 000000000000..2bd669133670 --- /dev/null +++ b/cppu/inc/uno/mapping.hxx @@ -0,0 +1,354 @@ +/************************************************************************* + * + * 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 _UNO_MAPPING_HXX_ +#define _UNO_MAPPING_HXX_ + +#include <cppu/macros.hxx> +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> +#include <uno/mapping.h> +#include <com/sun/star/uno/Type.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include "cppu/unotype.hxx" +#include "uno/environment.hxx" + +typedef struct _typelib_TypeDescription typelib_TypeDescription; +typedef struct _typelib_InterfaceTypeDescription typelib_InterfaceTypeDescription; +typedef struct _uno_Interface uno_Interface; + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +/** C++ wrapper for C uno_Mapping. + + @see uno_Mapping +*/ +class Mapping +{ + uno_Mapping * _pMapping; + +public: + // these are here to force memory de/allocation to sal lib. + /** @internal */ + inline static void * SAL_CALL operator new ( size_t nSize ) SAL_THROW( () ) + { return ::rtl_allocateMemory( nSize ); } + /** @internal */ + inline static void SAL_CALL operator delete ( void * pMem ) SAL_THROW( () ) + { ::rtl_freeMemory( pMem ); } + /** @internal */ + inline static void * SAL_CALL operator new ( size_t, void * pMem ) SAL_THROW( () ) + { return pMem; } + /** @internal */ + inline static void SAL_CALL operator delete ( void *, void * ) SAL_THROW( () ) + {} + + /** Holds a mapping from the specified source to the specified destination by environment + type names. + + @param rFrom type name of source environment + @param rTo type name of destination environment + @param rAddPurpose additional purpose + */ + inline Mapping( + const ::rtl::OUString & rFrom, const ::rtl::OUString & rTo, + const ::rtl::OUString & rAddPurpose = ::rtl::OUString() ) + SAL_THROW( () ); + + /** Holds a mapping from the specified source to the specified destination. + + @param pFrom source environment + @param pTo destination environment + @param rAddPurpose additional purpose + */ + inline Mapping( + uno_Environment * pFrom, uno_Environment * pTo, + const ::rtl::OUString & rAddPurpose = ::rtl::OUString() ) + SAL_THROW( () ); + + /** Holds a mapping from the specified source to the specified destination + environment. + + @param from source environment + @param to destination environment + @param rAddPurpose additional purpose + */ + inline Mapping(const Environment & rFrom, const Environment & rTo, + const ::rtl::OUString & rAddPurpose = ::rtl::OUString() ) + SAL_THROW( () ); + + /** Constructor. + + @param pMapping another mapping + */ + inline Mapping( uno_Mapping * pMapping = 0 ) SAL_THROW( () ); + + /** Copy constructor. + + @param rMapping another mapping + */ + inline Mapping( const Mapping & rMapping ) SAL_THROW( () ); + + /** Destructor. + */ + inline ~Mapping() SAL_THROW( () ); + + /** Sets a given mapping. + + @param pMapping another mapping + @return this mapping + */ + inline Mapping & SAL_CALL operator = ( uno_Mapping * pMapping ) SAL_THROW( () ); + /** Sets a given mapping. + + @param rMapping another mapping + @return this mapping + */ + inline Mapping & SAL_CALL operator = ( const Mapping & rMapping ) SAL_THROW( () ) + { return operator = ( rMapping._pMapping ); } + + /** Provides a pointer to the C mapping. The returned mapping is NOT acquired! + + @return UNacquired C mapping + */ + inline uno_Mapping * SAL_CALL get() const SAL_THROW( () ) + { return _pMapping; } + + /** Tests if a mapping is set. + + @return true if a mapping is set + */ + inline sal_Bool SAL_CALL is() const SAL_THROW( () ) + { return (_pMapping != 0); } + + /** Releases a set mapping. + */ + inline void SAL_CALL clear() SAL_THROW( () ); + + /** Maps an interface from one environment to another. + + @param pInterface source interface + @param pTypeDescr type description of interface + @return mapped interface + */ + inline void * SAL_CALL mapInterface( void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr ) const SAL_THROW( () ); + /** Maps an interface from one environment to another. + + @param pInterface source interface + @param pTypeDescr type description of interface + @return mapped interface + */ + inline void * SAL_CALL mapInterface( void * pInterface, typelib_TypeDescription * pTypeDescr ) const SAL_THROW( () ) + { return mapInterface( pInterface, (typelib_InterfaceTypeDescription *)pTypeDescr ); } + + /** Maps an interface from one environment to another. + + @param pInterface source interface + @param rType type of interface + @return mapped interface + */ + inline void * SAL_CALL mapInterface( + void * pInterface, const ::com::sun::star::uno::Type & rType ) const SAL_THROW( () ); + + /** Maps an interface from one environment to another. + + @param ppOut inout mapped interface + @param pInterface source interface + @param pTypeDescr type description of interface + */ + inline void SAL_CALL mapInterface( void ** ppOut, void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr ) const SAL_THROW( () ) + { (*_pMapping->mapInterface)( _pMapping, ppOut, pInterface, pTypeDescr ); } + /** Maps an interface from one environment to another. + + @param ppOut inout mapped interface + @param pInterface source interface + @param pTypeDescr type description of interface + */ + inline void SAL_CALL mapInterface( void ** ppOut, void * pInterface, typelib_TypeDescription * pTypeDescr ) const SAL_THROW( () ) + { (*_pMapping->mapInterface)( _pMapping, ppOut, pInterface, (typelib_InterfaceTypeDescription *)pTypeDescr ); } + + /** Maps an interface from one environment to another. + + @param ppOut inout mapped interface + @param pInterface source interface + @param rType type of interface to be mapped + */ + inline void SAL_CALL mapInterface( void ** ppOut, void * pInterface, const ::com::sun::star::uno::Type & rType ) const SAL_THROW( () ); +}; +//__________________________________________________________________________________________________ +inline Mapping::Mapping( + const ::rtl::OUString & rFrom, const ::rtl::OUString & rTo, const ::rtl::OUString & rAddPurpose ) + SAL_THROW( () ) + : _pMapping( 0 ) +{ + uno_getMappingByName( &_pMapping, rFrom.pData, rTo.pData, rAddPurpose.pData ); +} +//__________________________________________________________________________________________________ +inline Mapping::Mapping( + uno_Environment * pFrom, uno_Environment * pTo, const ::rtl::OUString & rAddPurpose ) + SAL_THROW( () ) + : _pMapping( 0 ) +{ + uno_getMapping( &_pMapping, pFrom, pTo, rAddPurpose.pData ); +} +//__________________________________________________________________________________________________ +inline Mapping::Mapping( + const Environment & rFrom, const Environment & rTo, const ::rtl::OUString & rAddPurpose ) + SAL_THROW( () ) + : _pMapping(0) +{ + uno_getMapping( &_pMapping, rFrom.get(), rTo.get(), rAddPurpose.pData ); +} +//__________________________________________________________________________________________________ +inline Mapping::Mapping( uno_Mapping * pMapping ) SAL_THROW( () ) + : _pMapping( pMapping ) +{ + if (_pMapping) + (*_pMapping->acquire)( _pMapping ); +} +//__________________________________________________________________________________________________ +inline Mapping::Mapping( const Mapping & rMapping ) SAL_THROW( () ) + : _pMapping( rMapping._pMapping ) +{ + if (_pMapping) + (*_pMapping->acquire)( _pMapping ); +} +//__________________________________________________________________________________________________ +inline Mapping::~Mapping() SAL_THROW( () ) +{ + if (_pMapping) + (*_pMapping->release)( _pMapping ); +} +//__________________________________________________________________________________________________ +inline void Mapping::clear() SAL_THROW( () ) +{ + if (_pMapping) + { + (*_pMapping->release)( _pMapping ); + _pMapping = 0; + } +} +//__________________________________________________________________________________________________ +inline Mapping & Mapping::operator = ( uno_Mapping * pMapping ) SAL_THROW( () ) +{ + if (pMapping) + (*pMapping->acquire)( pMapping ); + if (_pMapping) + (*_pMapping->release)( _pMapping ); + _pMapping = pMapping; + return *this; +} +//__________________________________________________________________________________________________ +inline void Mapping::mapInterface( + void ** ppOut, void * pInterface, const ::com::sun::star::uno::Type & rType ) const + SAL_THROW( () ) +{ + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, rType.getTypeLibType() ); + if (pTD) + { + (*_pMapping->mapInterface)( _pMapping, ppOut, pInterface, (typelib_InterfaceTypeDescription *)pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + } +} +//__________________________________________________________________________________________________ +inline void * Mapping::mapInterface( + void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr ) const + SAL_THROW( () ) +{ + void * pOut = 0; + (*_pMapping->mapInterface)( _pMapping, &pOut, pInterface, pTypeDescr ); + return pOut; +} +//__________________________________________________________________________________________________ +inline void * Mapping::mapInterface( + void * pInterface, const ::com::sun::star::uno::Type & rType ) const + SAL_THROW( () ) +{ + void * pOut = 0; + mapInterface( &pOut, pInterface, rType ); + return pOut; +} + +/** Deprecated. This function DOES NOT WORK with Purpose Environments + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Purpose Environments) + + Maps an binary C UNO interface to be used in the currently used compiler environment. + + @tplparam C interface type + @param ppRet inout returned interface pointer + @param pUnoI binary C UNO interface + @return true if successful, false otherwise + + @deprecated +*/ +template< class C > +inline sal_Bool mapToCpp( Reference< C > * ppRet, uno_Interface * pUnoI ) SAL_THROW( () ) +{ + Mapping aMapping( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ) ); + OSL_ASSERT( aMapping.is() ); + aMapping.mapInterface( + (void **)ppRet, pUnoI, ::cppu::getTypeFavourUnsigned( ppRet ) ); + return (0 != *ppRet); +} +/** Deprecated. This function DOES NOT WORK with Purpose Environments + (http://wiki.services.openoffice.org/wiki/Uno/Binary/Spec/Purpose Environments) + + Maps an UNO interface of the currently used compiler environment to binary C UNO. + + @tplparam C interface type + @param ppRet inout returned interface pointer + @param x interface reference + @return true if successful, false otherwise + + @deprecated +*/ +template< class C > +inline sal_Bool mapToUno( uno_Interface ** ppRet, const Reference< C > & x ) SAL_THROW( () ) +{ + Mapping aMapping( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ) ); + OSL_ASSERT( aMapping.is() ); + aMapping.mapInterface( + (void **)ppRet, x.get(), ::cppu::getTypeFavourUnsigned( &x ) ); + return (0 != *ppRet); +} + +} +} +} +} + +#endif diff --git a/cppu/inc/uno/sequence2.h b/cppu/inc/uno/sequence2.h new file mode 100644 index 000000000000..f8db769f9359 --- /dev/null +++ b/cppu/inc/uno/sequence2.h @@ -0,0 +1,187 @@ +/************************************************************************* + * + * 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 _UNO_SEQUENCE2_H_ +#define _UNO_SEQUENCE2_H_ + +#include <sal/types.h> +#include <uno/data.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct _typelib_TypeDescriptionReference; +struct _typelib_TypeDescription; +typedef sal_Sequence uno_Sequence; + +/** Assigns a sequence. + + @param ppDest destinstaion sequence + @param pSource source sequence + @param pTypeDescr type description of the sequence and NOT of an element + @param release function called each time an interface needs to + be released; defaults (0) to uno +*/ +void SAL_CALL uno_sequence_assign( + uno_Sequence ** ppDest, + uno_Sequence * pSource, + struct _typelib_TypeDescription * pTypeDescr, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); +/** Assigns a sequence. + + @param ppDest destinstaion sequence + @param pSource source sequence + @param pType type of the sequence and NOT of an element + @param release function called each time an interface needs to + be released; defaults (0) to uno +*/ +void SAL_CALL uno_type_sequence_assign( + uno_Sequence ** ppDest, + uno_Sequence * pSource, + struct _typelib_TypeDescriptionReference * pType, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +/** Constructs a new sequence with given elements. + + @param ppSequence out parameter sequence; + 0 if memory allocation has failed + @param pTypeDescr type description of the sequence and NOT of an + element + @param pElements if 0, then all elements are default constructed + @param len number of elements + @param acquire function called each time an interface needs to + be acquired; defaults (0) to uno + @return false, if memoray allocation has failed +*/ +sal_Bool SAL_CALL uno_sequence_construct( + uno_Sequence ** ppSequence, + struct _typelib_TypeDescription * pTypeDescr, + void * pElements, sal_Int32 len, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C(); +/** Constructs a new sequence with given elements. + + @param ppSequence out parameter sequence; + 0 if memory allocation has failed + @param pType type of the sequence and NOT of an element + @param pElements if 0, then all elements are default constructed + @param len number of elements + @param acquire function called each time an interface needs to + be acquired; defaults (0) to uno + @return false, if memoray allocation has failed +*/ +sal_Bool SAL_CALL uno_type_sequence_construct( + uno_Sequence ** ppSequence, + struct _typelib_TypeDescriptionReference * pType, + void * pElements, sal_Int32 len, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C(); + +/** Assures that the reference count of the given sequence is one. + Otherwise a new copy of the sequence is created with a reference count + of one. + + @param ppSequence inout sequence + @param pTypeDescr type description of sequence + @param acquire function called each time an interface needs to + be acquired; defaults (0) to uno + @param release function called each time an interface needs to + be released; defaults (0) to uno + @return false, if memoray allocation has failed +*/ +sal_Bool SAL_CALL uno_sequence_reference2One( + uno_Sequence ** ppSequence, + struct _typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); +/** Assures that the reference count of the given sequence is one. + Otherwise a new copy of the sequence is created with a reference count + of one. + + @param ppSequence inout sequence + @param pType type of sequence + @param acquire function called each time an interface needs to + be acquired; defaults (0) to uno + @param release function called each time an interface needs to + be released; defaults (0) to uno + @return false, if memoray allocation has failed +*/ +sal_Bool SAL_CALL uno_type_sequence_reference2One( + uno_Sequence ** ppSequence, + struct _typelib_TypeDescriptionReference * pType, + uno_AcquireFunc acquire, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +/** Reallocates length of a sequence. This truncates a sequence or enlarges + it default constructing appended elements. + + @param ppSequence inout sequence + @param pTypeDescr type description of sequence + @param nSize new size of sequence + @param acquire function called each time an interface needs to + be acquired; defaults (0) to uno + @param release function called each time an interface needs to + be released; defaults (0) to uno + @return false, if memoray allocation has failed +*/ +sal_Bool SAL_CALL uno_sequence_realloc( + uno_Sequence ** ppSequence, + struct _typelib_TypeDescription * pTypeDescr, + sal_Int32 nSize, + uno_AcquireFunc acquire, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); +/** Reallocates length of a sequence. This truncates a sequence or enlarges + it default constructing appended elements. + + @param ppSequence inout sequence + @param pType type of sequence + @param nSize new size of sequence + @param acquire function called each time an interface needs to + be acquired; defaults (0) to uno + @param release function called each time an interface needs to + be released; defaults (0) to uno + @return false, if memoray allocation has failed +*/ +sal_Bool SAL_CALL uno_type_sequence_realloc( + uno_Sequence ** ppSequence, + struct _typelib_TypeDescriptionReference * pType, + sal_Int32 nSize, + uno_AcquireFunc acquire, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cppu/inc/uno/threadpool.h b/cppu/inc/uno/threadpool.h new file mode 100644 index 000000000000..4938258a7ab9 --- /dev/null +++ b/cppu/inc/uno/threadpool.h @@ -0,0 +1,189 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include <sal/types.h> +#include <rtl/byteseq.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/*** + * Thread identifier administration. + ***/ +/** + Establishs an association between the current thread and the given thread identifier. + There can be only one association at a time. The association must be broken by + uno_releaseIdFromCurrentThread(). + This method is in general called by a bridge, that wants to bind a remote threadId + to a new thread. + + @param pThreadId a byte sequence, that contains the identifier of the current thread. + @return true, when the identifier was registered. + false, when the thread has already an identifier. The identifier was not + altered. ( This is in general a bug ). + + @see uno_releaseIdFromCurrentThread() + */ +sal_Bool SAL_CALL uno_bindIdToCurrentThread( sal_Sequence *pThreadId ) + SAL_THROW_EXTERN_C(); + + +/** + Get the identifier of the current thread. + If no id has been bound for the thread before, a new one is generated and bound + to the thread. + For each call to uno_getIdOfCurrentThread(), a call to uno_releaseIdFromCurrentThread() + must be done. + + @param ppThreadId [out] Contains the (acquired) ThreadId. + @see uno_releaseIdFromCurrentThread() + */ +void SAL_CALL uno_getIdOfCurrentThread( sal_Sequence **ppThreadId ) + SAL_THROW_EXTERN_C(); + + +/** + If the internal refcount drops to zero, the association betwen threadId and + thread is broken. + */ +void SAL_CALL uno_releaseIdFromCurrentThread() + SAL_THROW_EXTERN_C(); + + +struct _uno_ThreadPool; +typedef struct _uno_ThreadPool * uno_ThreadPool; + +/** + Creates a threadpool handle. Typically each remote bridge instances creates one + handle. + */ +uno_ThreadPool SAL_CALL +uno_threadpool_create() SAL_THROW_EXTERN_C(); + + +/** + Makes the current thread known to the threadpool. This function must be + called, BEFORE uno_threadpool_enter() is called and BEFORE a job for this + thread is put into the threadpool (avoid a race between this thread and + an incoming request/reply). + For every call to uno_threadpool_attach, a corrosponding call to + uno_threadpool_detach must be done. + + @param hPool The bridge threadpool handle previously created by uno_threadpool_create. + +*/ +void SAL_CALL +uno_threadpool_attach( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C(); + +/** + This method is called to wait for a reply of a previously sent request. This is a + blocking method. uno_threadpool_attach() must have been called before. + + @param hPool the handle that was previously created by uno_threadpool_create(). + @param ppJob [out] the pointer, that was given by uno_threadpool_putJob + 0, when uno_threadpool_dispose() was the reason to fall off from threadpool. + @see uno_threadpool_dispose() + **/ +void SAL_CALL +uno_threadpool_enter( uno_ThreadPool hPool , void **ppJob ) + SAL_THROW_EXTERN_C(); + +/** + Detaches the current thread from the threadpool. Must be called for + every call to uno_threadpool_attach. +*/ +void SAL_CALL +uno_threadpool_detach( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C(); + +/** + Puts a job into the pool. A job may eiter be a request or a reply + (replies have a 0 in the doRequest parameter). This function is non-blocking. + + A request may either be synchronous or asynchronous. + If the request is synchronous, it is first looked up, + if there exists a handle with the given + identifier. If this is the case, the thread is woken up and the doRequest + function is called with the given pJob. If no handle exists, + a new thread is created and the given threadId is bound to the new thread. + + If the request is asynchronous, it is put into the queue of asynchronous + requests for the current threadid. The requests are always executed in a new + thread, even if the thread with the given id is waiting in the pool. No id is bound + to the newly created thread. The responsibilty is left to the bridge ( if it + wishes to bind a name). + + If pJob is a reply, there MUST be a thread with the given threadId waiting + for this reply. + + @param pThreadId The Id of the thread, that initialized this request. (In general a + remote threadid). + @param pJob The argument, that doRequest will get or that will be returned by + uno_threadpool_enter(). + @param doRequest The function, that shall be called to execute the request. + 0 if pJob is a reply. + @param bIsOneway True, if the request is asynchrons. False, if it is synchronous. + Set to sal_False, if pJob is a reply. + */ +void SAL_CALL +uno_threadpool_putJob( + uno_ThreadPool hPool, + sal_Sequence *pThreadId, + void *pJob, + void ( SAL_CALL * doRequest ) ( void *pThreadSpecificData ), + sal_Bool bIsOneway ) SAL_THROW_EXTERN_C(); + +/** + All threads, that are waiting on the hPool handle, are forced out of the pool. + The threads waiting with uno_threadpool_enter() will return with *ppJob == 0 + + Later calls to uno_threadpool_enter() using the hPool handle will also + return immeadiatly with *ppJob == 0. + + @param hPool The handle to be disposed. + In case, hPool is 0, this function joins on all threads created + by the threadpool administration. This may e.g. used to ensure, that + no threads are inside the cppu library anymore, in case it needs to get + unloaded. + + This function is called i.e. by a bridge, that is forced to dispose itself. + */ +void SAL_CALL +uno_threadpool_dispose( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C(); + + +/** Releases the previously with uno_threadpool_create() created handle. + The handle thus becomes invalid. It is an error to use the handle after + uno_threadpool_destroy(). + @see uno_threadpool_create() + */ +void SAL_CALL +uno_threadpool_destroy( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C(); + +#ifdef __cplusplus +} +#endif diff --git a/cppu/prj/build.lst b/cppu/prj/build.lst new file mode 100644 index 000000000000..a22ca9ec8b66 --- /dev/null +++ b/cppu/prj/build.lst @@ -0,0 +1,12 @@ +cu cppu : sal salhelper offuh BOOST:boost NULL +cu cppu usr1 - all cu_mkout NULL +cu cppu\inc nmake - all cu_inc NULL +cu cppu\source\uno nmake - all cu_uno cu_inc NULL +cu cppu\source\threadpool nmake - all cu_thpool cu_inc NULL +cu cppu\source\typelib nmake - all cu_typelib cu_inc NULL +cu cppu\source\cppu nmake - all cu_cppu cu_inc NULL +cu cppu\source\helper\purpenv nmake - all cu_helper_purpenv cu_inc NULL +cu cppu\source\UnsafeBridge nmake - all cu_UnsafeBridge cu_inc NULL +cu cppu\source\AffineBridge nmake - all cu_AffineBridge cu_inc NULL +cu cppu\source\LogBridge nmake - all cu_LogBridge cu_inc NULL +cu cppu\util nmake - all cu_util cu_thpool cu_typelib cu_cppu cu_uno cu_helper_purpenv cu_UnsafeBridge cu_AffineBridge cu_LogBridge NULL diff --git a/cppu/prj/d.lst b/cppu/prj/d.lst new file mode 100644 index 000000000000..411a51cf2518 --- /dev/null +++ b/cppu/prj/d.lst @@ -0,0 +1,74 @@ +mkdir: %_DEST%\inc%_EXT%\cppu +mkdir: %_DEST%\inc%_EXT%\cppu\helper\purpenv +mkdir: %_DEST%\inc%_EXT%\com +mkdir: %_DEST%\inc%_EXT%\com\sun +mkdir: %_DEST%\inc%_EXT%\com\sun\star +mkdir: %_DEST%\inc%_EXT%\com\sun\star\uno +mkdir: %_DEST%\inc%_EXT%\typelib +mkdir: %_DEST%\inc%_EXT%\uno + +..\inc\cppu\macros.hxx %_DEST%\inc%_EXT%\cppu\macros.hxx +..\inc\cppu\unotype.hxx %_DEST%\inc%_EXT%\cppu\unotype.hxx + +..\inc\com\sun\star\uno\Reference.h %_DEST%\inc%_EXT%\com\sun\star\uno\Reference.h +..\inc\com\sun\star\uno\Reference.hxx %_DEST%\inc%_EXT%\com\sun\star\uno\Reference.hxx +..\inc\com\sun\star\uno\Type.h %_DEST%\inc%_EXT%\com\sun\star\uno\Type.h +..\inc\com\sun\star\uno\Type.hxx %_DEST%\inc%_EXT%\com\sun\star\uno\Type.hxx +..\inc\com\sun\star\uno\Any.h %_DEST%\inc%_EXT%\com\sun\star\uno\Any.h +..\inc\com\sun\star\uno\Any.hxx %_DEST%\inc%_EXT%\com\sun\star\uno\Any.hxx +..\inc\com\sun\star\uno\Sequence.h %_DEST%\inc%_EXT%\com\sun\star\uno\Sequence.h +..\inc\com\sun\star\uno\Sequence.hxx %_DEST%\inc%_EXT%\com\sun\star\uno\Sequence.hxx +..\inc\com\sun\star\uno\genfunc.h %_DEST%\inc%_EXT%\com\sun\star\uno\genfunc.h +..\inc\com\sun\star\uno\genfunc.hxx %_DEST%\inc%_EXT%\com\sun\star\uno\genfunc.hxx + +..\inc\typelib\typeclass.h %_DEST%\inc%_EXT%\typelib\typeclass.h +..\inc\typelib\typedescription.h %_DEST%\inc%_EXT%\typelib\typedescription.h +..\inc\typelib\typedescription.hxx %_DEST%\inc%_EXT%\typelib\typedescription.hxx +..\inc\typelib\uik.h %_DEST%\inc%_EXT%\typelib\uik.h + +..\inc\uno\dispatcher.h %_DEST%\inc%_EXT%\uno\dispatcher.h +..\inc\uno\dispatcher.hxx %_DEST%\inc%_EXT%\uno\dispatcher.hxx +..\inc\uno\any2.h %_DEST%\inc%_EXT%\uno\any2.h +..\inc\uno\sequence2.h %_DEST%\inc%_EXT%\uno\sequence2.h +..\inc\uno\data.h %_DEST%\inc%_EXT%\uno\data.h +..\inc\uno\lbnames.h %_DEST%\inc%_EXT%\uno\lbnames.h +..\inc\uno\environment.h %_DEST%\inc%_EXT%\uno\environment.h +..\inc\uno\environment.hxx %_DEST%\inc%_EXT%\uno\environment.hxx +..\inc\uno\mapping.h %_DEST%\inc%_EXT%\uno\mapping.h +..\inc\uno\mapping.hxx %_DEST%\inc%_EXT%\uno\mapping.hxx +..\inc\uno\threadpool.h %_DEST%\inc%_EXT%\uno\threadpool.h +..\inc\uno\current_context.h %_DEST%\inc%_EXT%\uno\current_context.h +..\inc\uno\current_context.hxx %_DEST%\inc%_EXT%\uno\current_context.hxx +..\inc\uno\cuno.h %_DEST%\inc%_EXT%\uno\cuno.h +..\inc\uno\EnvDcp.h %_DEST%\inc%_EXT%\uno\EnvDcp.h +..\inc\uno\Enterable.h %_DEST%\inc%_EXT%\uno\Enterable.h + +..\inc\cppu\EnvDcp.hxx %_DEST%\inc%_EXT%\cppu\EnvDcp.hxx +..\inc\cppu\Enterable.hxx %_DEST%\inc%_EXT%\cppu\Enterable.hxx +..\inc\cppu\EnvGuards.hxx %_DEST%\inc%_EXT%\cppu\EnvGuards.hxx +..\inc\cppu\FreeReference.hxx %_DEST%\inc%_EXT%\cppu\FreeReference.hxx +..\inc\cppu\Map.hxx %_DEST%\inc%_EXT%\cppu\Map.hxx +..\inc\cppu\Shield.hxx %_DEST%\inc%_EXT%\cppu\Shield.hxx + +..\inc\cppu\helper\purpenv\Environment.hxx %_DEST%\inc%_EXT%\cppu\helper\purpenv\Environment.hxx +..\inc\cppu\helper\purpenv\Mapping.hxx %_DEST%\inc%_EXT%\cppu\helper\purpenv\Mapping.hxx + +..\%__SRC%\lib\icppu.lib %_DEST%\lib%_EXT%\icppu.lib +..\%__SRC%\bin\cppu* %_DEST%\bin%_EXT%\* +..\%__SRC%\lib\libuno_cppu.*.* %_DEST%\lib%_EXT%\* + +..\%__SRC%\lib\ipurpenvhelper* %_DEST%\lib%_EXT%\* +..\%__SRC%\bin\purpe*.dll %_DEST%\bin%_EXT%\* +..\%__SRC%\lib\libuno_purpenvhelper*.*.* %_DEST%\lib%_EXT%\* + +..\%__SRC%\bin\unsafe_u*.dll %_DEST%\bin%_EXT%\* +..\%__SRC%\lib\libunsafe_uno_uno.* %_DEST%\lib%_EXT%\* + +..\%__SRC%\bin\affine_u*.dll %_DEST%\bin%_EXT%\* +..\%__SRC%\lib\libaffine_uno_uno.* %_DEST%\lib%_EXT%\* + +..\%__SRC%\bin\log_u*.dll %_DEST%\bin%_EXT%\* +..\%__SRC%\lib\liblog_uno_uno.* %_DEST%\lib%_EXT%\* + +linklib: libuno_cppu.*.* +linklib: libuno_purpenvhelper*.*.* diff --git a/cppu/qa/makefile.mk b/cppu/qa/makefile.mk new file mode 100644 index 000000000000..b40d3512e575 --- /dev/null +++ b/cppu/qa/makefile.mk @@ -0,0 +1,96 @@ +#************************************************************************* +# +# 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 := cppu +TARGET := qa + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk + +CFLAGSCXX += $(CPPUNIT_CFLAGS) + +DLLPRE = # no leading "lib" on .so files + +INCPRE += $(MISC)$/$(TARGET)$/inc + +SHL1TARGET = $(TARGET)_any +SHL1OBJS = $(SLO)$/test_any.obj +SHL1STDLIBS = $(CPPULIB) $(CPPUNITLIB) $(TESTSHL2LIB) $(SALLIB) +SHL1VERSIONMAP = version.map +SHL1IMPLIB = i$(SHL1TARGET) +DEF1NAME = $(SHL1TARGET) + +SHL2TARGET = $(TARGET)_unotype +SHL2OBJS = $(SLO)$/test_unotype.obj +SHL2STDLIBS = $(CPPULIB) $(CPPUNITLIB) $(TESTSHL2LIB) $(SALLIB) +SHL2VERSIONMAP = version.map +SHL2IMPLIB = i$(SHL2TARGET) +DEF2NAME = $(SHL2TARGET) + +SHL3TARGET = $(TARGET)_reference +SHL3OBJS = $(SLO)$/test_reference.obj +SHL3STDLIBS = $(CPPULIB) $(CPPUNITLIB) $(TESTSHL2LIB) $(SALLIB) +SHL3VERSIONMAP = version.map +SHL3IMPLIB = i$(SHL3TARGET) +DEF3NAME = $(SHL3TARGET) + +SHL4TARGET = $(TARGET)_recursion +SHL4OBJS = $(SLO)$/test_recursion.obj +SHL4STDLIBS = $(CPPULIB) $(CPPUNITLIB) $(TESTSHL2LIB) $(SALLIB) +SHL4VERSIONMAP = version.map +SHL4IMPLIB = i$(SHL4TARGET) +DEF4NAME = $(SHL4TARGET) + +SLOFILES = $(SHL1OBJS) $(SHL2OBJS) $(SHL3OBJS) $(SHL4OBJS) + +.INCLUDE: target.mk + +ALLTAR: test + +$(SHL1OBJS): $(MISC)$/$(TARGET).cppumaker.flag + +$(MISC)$/$(TARGET).cppumaker.flag: $(MISC)$/$(TARGET).rdb + - $(MKDIRHIER) $(MISC)$/$(TARGET)$/inc + $(CPPUMAKER) -O$(MISC)$/$(TARGET)$/inc -BUCR -C $< \ + $(SOLARBINDIR)$/udkapi.rdb + $(TOUCH) $@ + +$(MISC)$/$(TARGET).rdb: $(MISC)$/$(TARGET)$/types.urd + - rm $@ + $(REGMERGE) $@ /UCR $< + +$(MISC)$/$(TARGET)$/types.urd: types.idl + - $(MKDIR) $(MISC)$/$(TARGET) + $(IDLC) -O$(MISC)$/$(TARGET) -I$(SOLARIDLDIR) -cid -we $< + +test .PHONY: $(SHL1TARGETN) $(SHL2TARGETN) $(SHL3TARGETN) $(SHL4TARGETN) + $(TESTSHL2) $(SHL1TARGETN) + $(TESTSHL2) $(SHL2TARGETN) + $(TESTSHL2) $(SHL3TARGETN) + $(TESTSHL2) $(SHL4TARGETN) diff --git a/cppu/qa/test_any.cxx b/cppu/qa/test_any.cxx new file mode 100644 index 000000000000..1ab601b04c46 --- /dev/null +++ b/cppu/qa/test_any.cxx @@ -0,0 +1,2330 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "sal/config.h" + +#include <stdlib.h> // wntmsci10 does not like <cstdlib> + +#include "Enum1.hpp" +#include "Enum2.hpp" +#include "Exception1.hpp" +#include "Exception2.hpp" +#include "Exception2a.hpp" +#include "Exception2b.hpp" +#include "Interface1.hpp" +#include "Interface2.hpp" +#include "Interface2a.hpp" +#include "Interface2b.hpp" +#include "Interface3.hpp" +#include "Poly.hpp" +#include "Struct1.hpp" +#include "Struct2.hpp" +#include "Struct2a.hpp" +#include "Struct2b.hpp" +#include "boost/type_traits/is_same.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include "com/sun/star/uno/Type.hxx" +#include "com/sun/star/uno/XInterface.hpp" +#include "testshl/simpleheader.hxx" +#include "osl/diagnose.h" +#include "osl/interlck.h" +#include "rtl/string.h" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +namespace { + +namespace css = com::sun::star; + +class Base { +public: + Base(): m_count(0) {} + + void acquire() { + if (osl_incrementInterlockedCount(&m_count) == SAL_MAX_INT32) { + abort(); + } + } + + void release() { + if (osl_decrementInterlockedCount(&m_count) == 0) { + delete this; + } + } + +protected: + virtual ~Base() {} + +private: + Base(Base &); // not declared + void operator =(Base &); // not declared + + oslInterlockedCount m_count; +}; + +class Impl1: public Interface1, private Base { +public: + virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const & type) + throw (css::uno::RuntimeException) + { + if (type + == getCppuType< css::uno::Reference< css::uno::XInterface > >()) + { + css::uno::Reference< css::uno::XInterface > ref( + static_cast< css::uno::XInterface * >(this)); + return css::uno::Any(&ref, type); + } else if (type == getCppuType< css::uno::Reference< Interface1 > >()) { + css::uno::Reference< Interface1 > ref(this); + return css::uno::Any(&ref, type); + } else { + return css::uno::Any(); + } + } + + virtual void SAL_CALL acquire() throw () { + Base::acquire(); + } + + virtual void SAL_CALL release() throw () { + Base::release(); + } +}; + +class Impl2: public Interface2a, public Interface3, private Base { +public: + virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const & type) + throw (css::uno::RuntimeException) + { + if (type + == getCppuType< css::uno::Reference< css::uno::XInterface > >()) + { + css::uno::Reference< css::uno::XInterface > ref( + static_cast< css::uno::XInterface * >( + static_cast< Interface2a * >(this))); + return css::uno::Any(&ref, type); + } else if (type == getCppuType< css::uno::Reference< Interface2 > >()) { + css::uno::Reference< Interface2 > ref(this); + return css::uno::Any(&ref, type); + } else if (type == getCppuType< css::uno::Reference< Interface2a > >()) + { + css::uno::Reference< Interface2a > ref(this); + return css::uno::Any(&ref, type); + } else if (type == getCppuType< css::uno::Reference< Interface3 > >()) { + css::uno::Reference< Interface3 > ref(this); + return css::uno::Any(&ref, type); + } else { + return css::uno::Any(); + } + } + + virtual void SAL_CALL acquire() throw () { + Base::acquire(); + } + + virtual void SAL_CALL release() throw () { + Base::release(); + } +}; + +class Impl2b: public Interface2b, private Base { +public: + virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const & type) + throw (css::uno::RuntimeException) + { + if (type + == getCppuType< css::uno::Reference< css::uno::XInterface > >()) + { + css::uno::Reference< css::uno::XInterface > ref( + static_cast< css::uno::XInterface * >( + static_cast< Interface2a * >(this))); + return css::uno::Any(&ref, type); + } else if (type == getCppuType< css::uno::Reference< Interface2 > >()) { + css::uno::Reference< Interface2 > ref(this); + return css::uno::Any(&ref, type); + } else if (type == getCppuType< css::uno::Reference< Interface2a > >()) + { + css::uno::Reference< Interface2a > ref(this); + return css::uno::Any(&ref, type); + } else if (type == getCppuType< css::uno::Reference< Interface2b > >()) + { + css::uno::Reference< Interface2b > ref(this); + return css::uno::Any(&ref, type); + } else { + return css::uno::Any(); + } + } + + virtual void SAL_CALL acquire() throw () { + Base::acquire(); + } + + virtual void SAL_CALL release() throw () { + Base::release(); + } +}; + +class Test: public CppUnit::TestFixture { +public: + void testVoid(); + + void testBoolean(); + + void testByte(); + + void testShort(); + + void testUnsignedShort(); + + void testLong(); + + void testUnsignedLong(); + + void testHyper(); + + void testUnsignedHyper(); + + void testFloat(); + + void testDouble(); + + void testChar(); + + void testString(); + + void testType(); + + void testSequence(); + + void testEnum(); + + void testStruct(); + + void testPoly(); + + void testException(); + + void testInterface(); + + void testNull(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testVoid); + CPPUNIT_TEST(testBoolean); + CPPUNIT_TEST(testByte); + CPPUNIT_TEST(testShort); + CPPUNIT_TEST(testUnsignedShort); + CPPUNIT_TEST(testLong); + CPPUNIT_TEST(testUnsignedLong); + CPPUNIT_TEST(testHyper); + CPPUNIT_TEST(testUnsignedHyper); + CPPUNIT_TEST(testFloat); + CPPUNIT_TEST(testDouble); + CPPUNIT_TEST(testChar); + CPPUNIT_TEST(testString); + CPPUNIT_TEST(testType); + CPPUNIT_TEST(testSequence); + CPPUNIT_TEST(testEnum); + CPPUNIT_TEST(testStruct); + CPPUNIT_TEST(testPoly); + CPPUNIT_TEST(testException); + CPPUNIT_TEST(testInterface); + CPPUNIT_TEST(testNull); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::testVoid() { + css::uno::Any a; + CPPUNIT_ASSERT(a.getValueType() == getVoidCppuType()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testBoolean() { + css::uno::Any a(false); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< sal_Bool >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", (a >>= b) && !b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", (a >>= b) && !b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + if (boost::is_same< sal_uInt8, sal_Bool >::value) { + CPPUNIT_ASSERT_MESSAGE("@sal_uInt8", (a >>= b) && b == 0); + } else { + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testByte() { + css::uno::Any a(static_cast< sal_Int8 >(1)); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< sal_Int8 >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", (a >>= b) && b == 1); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", (a >>= b) && b == 1); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", (a >>= b) && b == 1); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", (a >>= b) && b == 1); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", (a >>= b) && b == 1); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", (a >>= b) && b == 1); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", (a >>= b) && b == 1); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", (a >>= b) && b == 1); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", (a >>= b) && b == 1); + } + { + sal_Unicode b = '2'; + if (boost::is_same< sal_Unicode, sal_uInt16 >::value) { + CPPUNIT_ASSERT_MESSAGE("@sal_Unicode", (a >>= b) && b == 1); + } else { + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testShort() { + css::uno::Any a(static_cast< sal_Int16 >(1)); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< sal_Int16 >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", (a >>= b) && b == 1); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", (a >>= b) && b == 1); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", (a >>= b) && b == 1); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", (a >>= b) && b == 1); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", (a >>= b) && b == 1); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", (a >>= b) && b == 1); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", (a >>= b) && b == 1); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", (a >>= b) && b == 1); + } + { + sal_Unicode b = '2'; + if (boost::is_same< sal_Unicode, sal_uInt16 >::value) { + CPPUNIT_ASSERT_MESSAGE("@sal_Unicode", (a >>= b) && b == 1); + } else { + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testUnsignedShort() { + sal_uInt16 n = 1; + css::uno::Any a(&n, getCppuType(static_cast< sal_uInt16 const * >(0))); + CPPUNIT_ASSERT( + a.getValueType() == getCppuType(static_cast< sal_uInt16 const * >(0))); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", (a >>= b) && b == 1); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", (a >>= b) && b == 1); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", (a >>= b) && b == 1); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", (a >>= b) && b == 1); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", (a >>= b) && b == 1); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", (a >>= b) && b == 1); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", (a >>= b) && b == 1); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", (a >>= b) && b == 1); + } + { + sal_Unicode b = '2'; + if (boost::is_same< sal_Unicode, sal_uInt16 >::value) { + CPPUNIT_ASSERT_MESSAGE("@sal_Unicode", (a >>= b) && b == 1); + } else { + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testLong() { + css::uno::Any a(static_cast< sal_Int32 >(1)); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< sal_Int32 >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", (a >>= b) && b == 1); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", (a >>= b) && b == 1); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", (a >>= b) && b == 1); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", (a >>= b) && b == 1); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", (a >>= b) && b == 1); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testUnsignedLong() { + css::uno::Any a(static_cast< sal_uInt32 >(1)); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< sal_uInt32 >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", (a >>= b) && b == 1); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", (a >>= b) && b == 1); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", (a >>= b) && b == 1); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", (a >>= b) && b == 1); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", (a >>= b) && b == 1); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testHyper() { + css::uno::Any a(static_cast< sal_Int64 >(1)); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< sal_Int64 >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", (a >>= b) && b == 1); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", (a >>= b) && b == 1); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testUnsignedHyper() { + css::uno::Any a(static_cast< sal_uInt64 >(1)); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< sal_uInt64 >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", (a >>= b) && b == 1); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", (a >>= b) && b == 1); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testFloat() { + css::uno::Any a(1.f); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< float >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", (a >>= b) && b == 1); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", (a >>= b) && b == 1); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testDouble() { + css::uno::Any a(1.); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< double >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", (a >>= b) && b == 1); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testChar() { + sal_Unicode c = '1'; + css::uno::Any a(&c, getCppuType< sal_Unicode >()); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< sal_Unicode >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + if (boost::is_same< sal_Unicode, sal_uInt16 >::value) { + CPPUNIT_ASSERT_MESSAGE("@sal_Unicode", !(a >>= b) && b == '2'); + } else { + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", (a >>= b) && b == '1'); + } + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testString() { + css::uno::Any a(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("1"))); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< rtl::OUString >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + (a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("1"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testType() { + css::uno::Any a(getCppuType< sal_Int32 >()); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< css::uno::Type >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", (a >>= b) && b == getCppuType< sal_Int32 >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testSequence() { + sal_Int32 n = 1; + css::uno::Any a(css::uno::Sequence< sal_Int32 >(&n, 1)); + CPPUNIT_ASSERT( + a.getValueType() == getCppuType< css::uno::Sequence< sal_Int32 > >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + css::uno::Sequence< sal_Int32 > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<sal_Int32>", + (a >>= b) && b.getLength() == 1 && b[0] == 1); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testEnum() { + css::uno::Any a(Enum2_M1); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< Enum2 >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Enum2 b = Enum2_M2; + CPPUNIT_ASSERT_MESSAGE("Enum2", (a >>= b) && b == Enum2_M1); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testStruct() { + css::uno::Any a(Struct2a(1, 3)); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< Struct2a >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Struct2 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct2", (a >>= b) && b.member == 1); + } + { + Struct2a b(2, 2); + CPPUNIT_ASSERT_MESSAGE( + "Struct2a", (a >>= b) && b.member == 1 && b.member2 == 3); + } + { + Struct2b b(2, 2, 2); + CPPUNIT_ASSERT_MESSAGE("Struct2b", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testPoly() { + css::uno::Any a; + a <<= Poly< css::uno::Sequence< ::sal_Unicode > >(); + CPPUNIT_ASSERT_MESSAGE( + "type name", + a.getValueType().getTypeName().equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("Poly<[]char>"))); + CPPUNIT_ASSERT_MESSAGE( + "constructor", + a == css::uno::Any(Poly< css::uno::Sequence< ::sal_Unicode > >())); +} + +void Test::testException() { + css::uno::Any a( + Exception2a( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 1, + 3)); + CPPUNIT_ASSERT(a.getValueType() == getCppuType< Exception2a >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + Exception2 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception2", (a >>= b) && b.member == 1); + } + { + Exception2a b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2, + 2); + CPPUNIT_ASSERT_MESSAGE( + "Exception2a", (a >>= b) && b.member == 1 && b.member2 == 3); + } + { + Exception2b b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2, + 2); + CPPUNIT_ASSERT_MESSAGE("Exception2b", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } +} + +void Test::testInterface() { + css::uno::Reference< Interface2a > i2(new Impl2); + css::uno::Any a(i2); + CPPUNIT_ASSERT( + a.getValueType() + == getCppuType< css::uno::Reference< Interface2a > >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > i(new Impl1); + css::uno::Reference< Interface1 > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface1", !(a >>= b) && b == i); + } + { + css::uno::Reference< Interface2 > b(new Impl2); + CPPUNIT_ASSERT_MESSAGE("Interface2", (a >>= b) && b == i2); + } + { + css::uno::Reference< Interface2a > b(new Impl2); + CPPUNIT_ASSERT_MESSAGE("Interface2a", (a >>= b) && b == i2); + } + { + css::uno::Reference< Interface2b > i(new Impl2b); + css::uno::Reference< Interface2b > b(i); + CPPUNIT_ASSERT_MESSAGE("Interface2b", !(a >>= b) && b == i); + } + { + css::uno::Reference< Interface3 > b(new Impl2); + CPPUNIT_ASSERT_MESSAGE("Interface3", (a >>= b) && b == i2); + } +} + +void Test::testNull() { + css::uno::Any a = css::uno::Any(css::uno::Reference< Interface2a >()); + CPPUNIT_ASSERT( + a.getValueType() + == getCppuType< css::uno::Reference< Interface2a > >()); + { + bool b = true; + CPPUNIT_ASSERT_MESSAGE("bool", !(a >>= b) && b); + } + { + sal_Bool b = true; + CPPUNIT_ASSERT_MESSAGE("sal_Bool", !(a >>= b) && b); + } + { + sal_Int8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int8", !(a >>= b) && b == 2); + } + { + sal_uInt8 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt8", !(a >>= b) && b == 2); + } + { + sal_Int16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int16", !(a >>= b) && b == 2); + } + { + sal_uInt16 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt16", !(a >>= b) && b == 2); + } + { + sal_Int32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int32", !(a >>= b) && b == 2); + } + { + sal_uInt32 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt32", !(a >>= b) && b == 2); + } + { + sal_Int64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_Int64", !(a >>= b) && b == 2); + } + { + sal_uInt64 b = 2; + CPPUNIT_ASSERT_MESSAGE("sal_uInt64", !(a >>= b) && b == 2); + } + { + float b = 2; + CPPUNIT_ASSERT_MESSAGE("float", !(a >>= b) && b == 2); + } + { + double b = 2; + CPPUNIT_ASSERT_MESSAGE("double", !(a >>= b) && b == 2); + } + { + sal_Unicode b = '2'; + CPPUNIT_ASSERT_MESSAGE("sal_Unicode", !(a >>= b) && b == '2'); + } + { + rtl::OUString b(RTL_CONSTASCII_USTRINGPARAM("2")); + CPPUNIT_ASSERT_MESSAGE( + "rtl::OUString", + !(a >>= b) && b.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("2"))); + } + { + css::uno::Type b(getCppuType< rtl::OUString >()); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Type", + !(a >>= b) && b == getCppuType< rtl::OUString >()); + } + { + css::uno::Any b(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2"))); + CPPUNIT_ASSERT_MESSAGE("css::uno::Any", (a >>= b) && b == a); + } + { + css::uno::Sequence< rtl::OUString > b(2); + CPPUNIT_ASSERT_MESSAGE( + "css::uno::Sequence<rtl::OUString>", + !(a >>= b) && b.getLength() == 2); + } + { + Enum1 b = Enum1_M2; + CPPUNIT_ASSERT_MESSAGE("Enum1", !(a >>= b) && b == Enum1_M2); + } + { + Struct1 b(2); + CPPUNIT_ASSERT_MESSAGE("Struct1", !(a >>= b) && b.member == 2); + } + { + Exception1 b( + rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), 2); + CPPUNIT_ASSERT_MESSAGE("Exception1", !(a >>= b) && b.member == 2); + } + { + css::uno::Reference< Interface1 > b(new Impl1); + CPPUNIT_ASSERT_MESSAGE( + "Interface1", (a >>= b) && !b.is()); + } + { + css::uno::Reference< Interface2 > b(new Impl2); + CPPUNIT_ASSERT_MESSAGE( + "Interface2", (a >>= b) && !b.is()); + } + { + css::uno::Reference< Interface2a > b(new Impl2); + CPPUNIT_ASSERT_MESSAGE("Interface2a", (a >>= b) && !b.is()); + } + { + css::uno::Reference< Interface2b > b(new Impl2b); + CPPUNIT_ASSERT_MESSAGE( + "Interface2b", (a >>= b) && !b.is()); + } + { + css::uno::Reference< Interface3 > b(new Impl2); + CPPUNIT_ASSERT_MESSAGE( + "Interface3", (a >>= b) && !b.is()); + } +} + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test, "alltests"); + +} + +NOADDITIONAL; diff --git a/cppu/qa/test_recursion.cxx b/cppu/qa/test_recursion.cxx new file mode 100644 index 000000000000..c0bab3e30b95 --- /dev/null +++ b/cppu/qa/test_recursion.cxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_cppu.hxx" +#include "sal/config.h" + +#include "testshl/simpleheader.hxx" +#include "sal/types.h" + +#include "Rec.hpp" + +namespace +{ + +class Test: public CppUnit::TestFixture { + +public: + void testRecursion(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testRecursion); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::testRecursion() { + CPPUNIT_ASSERT_EQUAL(static_cast< sal_Int32 >(0), Rec().x.getLength()); +} + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test, "tests"); + +} + +NOADDITIONAL; diff --git a/cppu/qa/test_reference.cxx b/cppu/qa/test_reference.cxx new file mode 100644 index 000000000000..88a24d8e361d --- /dev/null +++ b/cppu/qa/test_reference.cxx @@ -0,0 +1,156 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "sal/config.h" + +#include "Interface1.hpp" + +#include "testshl/simpleheader.hxx" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +namespace +{ + +using ::com::sun::star::uno::Type; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::UNO_SET_THROW; + +class Foo: public Interface1 +{ +public: + Foo() + :m_refCount(0) + { + } + + virtual Any SAL_CALL queryInterface(const Type & _type) + throw (RuntimeException) + { + Any aInterface; + if (_type == getCppuType< Reference< XInterface > >()) + { + Reference< XInterface > ref( static_cast< XInterface * >( this ) ); + aInterface.setValue( &ref, _type ); + } + else if (_type == getCppuType< Reference< Interface1 > >()) + { + Reference< Interface1 > ref( this ); + aInterface.setValue( &ref, _type ); + } + + return Any(); + } + + virtual void SAL_CALL acquire() throw () + { + osl_incrementInterlockedCount( &m_refCount ); + } + + virtual void SAL_CALL release() throw () + { + if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) + delete this; + } + +protected: + virtual ~Foo() + { + } + +private: + Foo(Foo &); // not declared + Foo& operator =(const Foo&); // not declared + +private: + oslInterlockedCount m_refCount; +}; + +class Test: public ::CppUnit::TestFixture +{ + +public: + void testUnoSetThrow(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testUnoSetThrow); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::testUnoSetThrow() +{ + Reference< Interface1 > xNull; + Reference< Interface1 > xFoo( new Foo ); + + // ctor taking Reference< interface_type > + bool bCaughtException = false; + try { Reference< Interface1 > x( xNull, UNO_SET_THROW ); (void)x; } catch( const RuntimeException& ) { bCaughtException = true; } + CPPUNIT_ASSERT_EQUAL( true, bCaughtException ); + + bCaughtException = false; + try { Reference< Interface1 > x( xFoo, UNO_SET_THROW ); (void)x; } catch( const RuntimeException& ) { bCaughtException = true; } + CPPUNIT_ASSERT_EQUAL( false, bCaughtException ); + + // ctor taking interface_type* + bCaughtException = false; + try { Reference< Interface1 > x( xNull.get(), UNO_SET_THROW ); (void)x; } catch( const RuntimeException& ) { bCaughtException = true; } + CPPUNIT_ASSERT_EQUAL( true, bCaughtException ); + + bCaughtException = false; + try { Reference< Interface1 > x( xFoo.get(), UNO_SET_THROW ); (void)x; } catch( const RuntimeException& ) { bCaughtException = true; } + CPPUNIT_ASSERT_EQUAL( false, bCaughtException ); + + Reference< Interface1 > x; + // "set" taking Reference< interface_type > + bCaughtException = false; + try { x.set( xNull, UNO_SET_THROW ); } catch( const RuntimeException& ) { bCaughtException = true; } + CPPUNIT_ASSERT_EQUAL( true, bCaughtException ); + + bCaughtException = false; + try { x.set( xFoo, UNO_SET_THROW ); } catch( const RuntimeException& ) { bCaughtException = true; } + CPPUNIT_ASSERT_EQUAL( false, bCaughtException ); + + // "set" taking interface_type* + bCaughtException = false; + try { x.set( xNull.get(), UNO_SET_THROW ); } catch( const RuntimeException& ) { bCaughtException = true; } + CPPUNIT_ASSERT_EQUAL( true, bCaughtException ); + + bCaughtException = false; + try { x.set( xFoo.get(), UNO_SET_THROW ); } catch( const RuntimeException& ) { bCaughtException = true; } + CPPUNIT_ASSERT_EQUAL( false, bCaughtException ); +} + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test, "alltests"); + +} // namespace + +NOADDITIONAL; diff --git a/cppu/qa/test_unotype.cxx b/cppu/qa/test_unotype.cxx new file mode 100644 index 000000000000..eda5be571e7b --- /dev/null +++ b/cppu/qa/test_unotype.cxx @@ -0,0 +1,812 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "sal/config.h" + +#include <typeinfo> + +#include "com/sun/star/beans/Optional.hpp" +#include "com/sun/star/beans/PropertyChangeEvent.hpp" +#include "com/sun/star/lang/EventObject.hpp" +#include "com/sun/star/uno/Exception.hpp" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include "com/sun/star/uno/Type.hxx" +#include "com/sun/star/uno/TypeClass.hpp" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/uno/XInterface.hpp" +#include "cppu/unotype.hxx" +#include "testshl/simpleheader.hxx" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +namespace com { namespace sun { namespace star { namespace uno { + class Any; +} } } } + +namespace { + +namespace css = com::sun::star; + +struct DerivedStruct1: css::lang::EventObject {}; + +struct DerivedStruct2: css::beans::PropertyChangeEvent {}; + +struct DerivedException1: css::uno::Exception {}; + +struct DerivedException2: css::uno::RuntimeException {}; + +struct DerivedInterface1: css::uno::XInterface {}; + +struct DerivedInterface2: css::uno::XComponentContext {}; + +class Test: public ::CppUnit::TestFixture { +public: + void testUnoType(); + + void testGetTypeFavourUnsigned(); + + void testGetTypeFavourChar(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testUnoType); + CPPUNIT_TEST(testGetTypeFavourUnsigned); + CPPUNIT_TEST(testGetTypeFavourChar); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::testUnoType() { + css::uno::Type t; + t = ::cppu::UnoType< ::cppu::UnoVoidType >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_VOID, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")), t.getTypeName()); + t = ::cppu::UnoType< bool >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_BOOLEAN, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("boolean")), + t.getTypeName()); + CPPUNIT_ASSERT(::cppu::UnoType< ::sal_Bool >::get() == t); + t = ::cppu::UnoType< ::sal_Int8 >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_BYTE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("byte")), t.getTypeName()); + t = ::cppu::UnoType< ::sal_Int16 >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_SHORT, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("short")), t.getTypeName()); + t = ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_UNSIGNED_SHORT, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unsigned short")), + t.getTypeName()); + t = ::cppu::UnoType< ::sal_Int32 >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_LONG, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("long")), t.getTypeName()); + t = ::cppu::UnoType< ::sal_uInt32 >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_UNSIGNED_LONG, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unsigned long")), + t.getTypeName()); + t = ::cppu::UnoType< ::sal_Int64 >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_HYPER, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hyper")), t.getTypeName()); + t = ::cppu::UnoType< ::sal_uInt64 >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_UNSIGNED_HYPER, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unsigned hyper")), + t.getTypeName()); + t = ::cppu::UnoType< float >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_FLOAT, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("float")), t.getTypeName()); + t = ::cppu::UnoType< double >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_DOUBLE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("double")), + t.getTypeName()); + t = ::cppu::UnoType< ::cppu::UnoCharType >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_CHAR, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("char")), t.getTypeName()); + t = ::cppu::UnoType< ::rtl::OUString >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_STRING, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("string")), + t.getTypeName()); + t = ::cppu::UnoType< css::uno::Type >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_TYPE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("type")), t.getTypeName()); + t = ::cppu::UnoType< css::uno::Any >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_ANY, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("any")), t.getTypeName()); + t = ::cppu::UnoType< ::cppu::UnoSequenceType< ::sal_Int8 > >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_SEQUENCE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[]byte")), + t.getTypeName()); + CPPUNIT_ASSERT( + ::cppu::UnoType< css::uno::Sequence< ::sal_Int8 > >::get() == t); + t = ::cppu::UnoType< + ::cppu::UnoSequenceType< ::cppu::UnoUnsignedShortType > >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_SEQUENCE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[]unsigned short")), + t.getTypeName()); + t = ::cppu::UnoType< + ::cppu::UnoSequenceType< ::cppu::UnoCharType > >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_SEQUENCE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[]char")), + t.getTypeName()); + t = ::cppu::UnoType< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::sal_Int8 > > >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_SEQUENCE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[][]byte")), + t.getTypeName()); + CPPUNIT_ASSERT( + ::cppu::UnoType< + css::uno::Sequence< css::uno::Sequence< ::sal_Int8 > > >::get() == t); + t = ::cppu::UnoType< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoUnsignedShortType > > >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_SEQUENCE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[][]unsigned short")), + t.getTypeName()); + t = ::cppu::UnoType< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoCharType > > >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_SEQUENCE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[][]char")), + t.getTypeName()); + t = ::cppu::UnoType< css::uno::TypeClass >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_ENUM, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.TypeClass")), + t.getTypeName()); + t = ::cppu::UnoType< css::lang::EventObject >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_STRUCT, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.EventObject")), + t.getTypeName()); + CPPUNIT_ASSERT(::cppu::UnoType< DerivedStruct1 >::get() == t); + t = ::cppu::UnoType< css::beans::PropertyChangeEvent >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_STRUCT, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.beans.PropertyChangeEvent")), + t.getTypeName()); +#if !(defined __SUNPRO_CC && __SUNPRO_CC <= 0x550) // erroneous ambiguity stated + CPPUNIT_ASSERT(::cppu::UnoType< DerivedStruct2 >::get() == t); +#endif + t = ::cppu::UnoType< css::beans::Optional< ::sal_Int8 > >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_STRUCT, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.Optional<byte>")), + t.getTypeName()); + t = ::cppu::UnoType< css::uno::Exception >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_EXCEPTION, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception")), + t.getTypeName()); + CPPUNIT_ASSERT(::cppu::UnoType< DerivedException1 >::get() == t); + t = ::cppu::UnoType< css::uno::RuntimeException >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_EXCEPTION, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException")), + t.getTypeName()); +#if !(defined __SUNPRO_CC && __SUNPRO_CC <= 0x550) // erroneous ambiguity stated + CPPUNIT_ASSERT(::cppu::UnoType< DerivedException2 >::get() == t); +#endif + t = ::cppu::UnoType< css::uno::XInterface >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_INTERFACE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface")), + t.getTypeName()); + CPPUNIT_ASSERT( + ::cppu::UnoType< css::uno::Reference< css::uno::XInterface > >::get() == + t); + CPPUNIT_ASSERT(::cppu::UnoType< DerivedInterface1 >::get() == t); + CPPUNIT_ASSERT( + ::cppu::UnoType< css::uno::Reference< DerivedInterface1 > >::get() == + t); + t = ::cppu::UnoType< css::uno::XComponentContext >::get(); + CPPUNIT_ASSERT_EQUAL(css::uno::TypeClass_INTERFACE, t.getTypeClass()); + CPPUNIT_ASSERT_EQUAL( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XComponentContext")), + t.getTypeName()); + CPPUNIT_ASSERT( + ::cppu::UnoType< + css::uno::Reference< css::uno::XComponentContext > >::get() == t); +#if !(defined __SUNPRO_CC && __SUNPRO_CC <= 0x550) // erroneous ambiguity stated + CPPUNIT_ASSERT(::cppu::UnoType< DerivedInterface2 >::get() == t); + CPPUNIT_ASSERT( + ::cppu::UnoType< css::uno::Reference< DerivedInterface2 > >::get() == + t); +#endif +} + +void Test::testGetTypeFavourUnsigned() { + CPPUNIT_ASSERT(typeid(::sal_Unicode) == typeid(::sal_uInt16)); + CPPUNIT_ASSERT( + ::getCppuType(static_cast< ::sal_Unicode * >(0)) == + ::getCppuType(static_cast< ::sal_uInt16 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< ::cppu::UnoVoidType * >(0)) == + ::cppu::UnoType< ::cppu::UnoVoidType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< bool * >(0)) == + ::cppu::UnoType< bool >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< bool * >(0)) == + ::getCppuType(static_cast< bool * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Bool * >(0)) == + ::cppu::UnoType< bool >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Bool * >(0)) == + ::getCppuType(static_cast< ::sal_Bool * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Int8 * >(0)) == + ::cppu::UnoType< ::sal_Int8 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Int8 * >(0)) == + ::getCppuType(static_cast< ::sal_Int8 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Int16 * >(0)) == + ::cppu::UnoType< ::sal_Int16 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Int16 * >(0)) == + ::getCppuType(static_cast< ::sal_Int16 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< ::cppu::UnoUnsignedShortType * >(0)) == + ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_uInt16 * >(0)) == + ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_uInt16 * >(0)) == + ::getCppuType(static_cast< ::sal_uInt16 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Int32 * >(0)) == + ::cppu::UnoType< ::sal_Int32 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Int32 * >(0)) == + ::getCppuType(static_cast< ::sal_Int32 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_uInt32 * >(0)) == + ::cppu::UnoType< ::sal_uInt32 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_uInt32 * >(0)) == + ::getCppuType(static_cast< ::sal_uInt32 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Int64 * >(0)) == + ::cppu::UnoType< ::sal_Int64 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Int64 * >(0)) == + ::getCppuType(static_cast< ::sal_Int64 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_uInt64 * >(0)) == + ::cppu::UnoType< ::sal_uInt64 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_uInt64 * >(0)) == + ::getCppuType(static_cast< ::sal_uInt64 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< float * >(0)) == + ::cppu::UnoType< float >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< float * >(0)) == + ::getCppuType(static_cast< float * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< double * >(0)) == + ::cppu::UnoType< double >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< double * >(0)) == + ::getCppuType(static_cast< double * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< ::cppu::UnoCharType * >(0)) == + ::cppu::UnoType< ::cppu::UnoCharType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Unicode * >(0)) == + ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::sal_Unicode * >(0)) == + ::getCppuType(static_cast< ::sal_Unicode * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::rtl::OUString * >(0)) == + ::cppu::UnoType< ::rtl::OUString >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< ::rtl::OUString * >(0)) == + ::getCppuType(static_cast< ::rtl::OUString * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< css::uno::Type * >(0)) == + ::cppu::UnoType< css::uno::Type >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< css::uno::Type * >(0)) == + ::getCppuType(static_cast< css::uno::Type * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< css::uno::Any * >(0)) == + ::cppu::UnoType< css::uno::Any >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< css::uno::Any * >(0)) == + ::getCppuType(static_cast< css::uno::Any * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< + ::cppu::UnoSequenceType< ::cppu::UnoUnsignedShortType > * >(0)) == + ::cppu::UnoType< + ::cppu::UnoSequenceType< ::cppu::UnoUnsignedShortType > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Sequence< ::sal_uInt16 > * >(0)) == + ::cppu::UnoType< + ::cppu::UnoSequenceType< ::cppu::UnoUnsignedShortType > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Sequence< ::sal_uInt16 > * >(0)) == + ::getCppuType(static_cast< css::uno::Sequence< ::sal_uInt16 > * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoUnsignedShortType > > * >(0)) == + ::cppu::UnoType< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoUnsignedShortType > > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Sequence< css::uno::Sequence< + ::sal_uInt16 > > * >(0)) == + ::cppu::UnoType< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoUnsignedShortType > > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Sequence< css::uno::Sequence< + ::sal_uInt16 > > * >(0)) == + ::getCppuType( + static_cast< css::uno::Sequence< css::uno::Sequence< + ::sal_uInt16 > > * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Sequence< ::sal_Unicode > * >(0)) == + ::cppu::UnoType< + ::cppu::UnoSequenceType< ::cppu::UnoUnsignedShortType > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Sequence< ::sal_Unicode > * >(0)) == + ::getCppuType(static_cast< css::uno::Sequence< ::sal_Unicode > * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Sequence< css::uno::Sequence< + ::sal_Unicode > > * >(0)) == + ::cppu::UnoType< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoUnsignedShortType > > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Sequence< css::uno::Sequence< + ::sal_Unicode > > * >(0)) == + ::getCppuType( + static_cast< css::uno::Sequence< css::uno::Sequence< + ::sal_Unicode > > * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::TypeClass * >(0)) == + ::cppu::UnoType< css::uno::TypeClass >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::TypeClass * >(0)) == + ::getCppuType(static_cast< css::uno::TypeClass * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::lang::EventObject * >(0)) == + ::cppu::UnoType< css::lang::EventObject >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::lang::EventObject * >(0)) == + ::getCppuType(static_cast< css::lang::EventObject * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedStruct1 * >(0)) == + ::cppu::UnoType< css::lang::EventObject >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedStruct1 * >(0)) == + ::getCppuType(static_cast< DerivedStruct1 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::beans::PropertyChangeEvent * >(0)) == + ::cppu::UnoType< css::beans::PropertyChangeEvent >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::beans::PropertyChangeEvent * >(0)) == + ::getCppuType(static_cast< css::beans::PropertyChangeEvent * >(0))); +#if !(defined __SUNPRO_CC && __SUNPRO_CC <= 0x550) // erroneous ambiguity stated + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedStruct2 * >(0)) == + ::cppu::UnoType< css::beans::PropertyChangeEvent >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedStruct2 * >(0)) == + ::getCppuType(static_cast< DerivedStruct2 * >(0))); +#endif + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::beans::Optional< ::sal_Int8 > * >(0)) == + ::cppu::UnoType< css::beans::Optional< ::sal_Int8 > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::beans::Optional< ::sal_Int8 > * >(0)) == + ::getCppuType(static_cast< css::beans::Optional< ::sal_Int8 > * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Exception * >(0)) == + ::cppu::UnoType< css::uno::Exception >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Exception * >(0)) == + ::getCppuType(static_cast< css::uno::Exception * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedException1 * >(0)) == + ::cppu::UnoType< css::uno::Exception >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedException1 * >(0)) == + ::getCppuType(static_cast< DerivedException1 * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::RuntimeException * >(0)) == + ::cppu::UnoType< css::uno::RuntimeException >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::RuntimeException * >(0)) == + ::getCppuType(static_cast< css::uno::RuntimeException * >(0))); +#if !(defined __SUNPRO_CC && __SUNPRO_CC <= 0x550) // erroneous ambiguity stated + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedException2 * >(0)) == + ::cppu::UnoType< css::uno::RuntimeException >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedException2 * >(0)) == + ::getCppuType(static_cast< DerivedException2 * >(0))); +#endif + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::XInterface * >(0)) == + ::cppu::UnoType< css::uno::XInterface >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Reference< css::uno::XInterface > * >(0)) == + ::cppu::UnoType< css::uno::XInterface >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Reference< css::uno::XInterface > * >(0)) == + ::getCppuType( + static_cast< css::uno::Reference< css::uno::XInterface > * >(0))); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedInterface1 * >(0)) == + ::cppu::UnoType< css::uno::XInterface >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Reference< DerivedInterface1 > * >(0)) == + ::cppu::UnoType< css::uno::XInterface >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::XComponentContext * >(0)) == + ::cppu::UnoType< css::uno::XComponentContext >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< + css::uno::Reference< css::uno::XComponentContext > * >(0)) == + ::cppu::UnoType< css::uno::XComponentContext >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< + css::uno::Reference< css::uno::XComponentContext > * >(0)) == + ::getCppuType( + static_cast< + css::uno::Reference< css::uno::XComponentContext > * >(0))); +#if !(defined __SUNPRO_CC && __SUNPRO_CC <= 0x550) // erroneous ambiguity stated + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned(static_cast< DerivedInterface2 * >(0)) == + ::cppu::UnoType< css::uno::XComponentContext >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourUnsigned( + static_cast< css::uno::Reference< DerivedInterface2 > * >(0)) == + ::cppu::UnoType< css::uno::XComponentContext >::get()); +#endif +} + +void Test::testGetTypeFavourChar() { + CPPUNIT_ASSERT(typeid(::sal_Unicode) == typeid(::sal_uInt16)); + CPPUNIT_ASSERT( + ::getCppuType< ::sal_Unicode >() == ::getCppuType< ::sal_uInt16 >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::cppu::UnoVoidType * >(0)) == + ::cppu::UnoType< ::cppu::UnoVoidType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< bool * >(0)) == + ::cppu::UnoType< bool >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< bool * >(0)) == + ::getCppuType< bool >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Bool * >(0)) == + ::cppu::UnoType< bool >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Bool * >(0)) == + ::getCppuType< ::sal_Bool >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Int8 * >(0)) == + ::cppu::UnoType< ::sal_Int8 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Int8 * >(0)) == + ::getCppuType< ::sal_Int8 >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Int16 * >(0)) == + ::cppu::UnoType< ::sal_Int16 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Int16 * >(0)) == + ::getCppuType< ::sal_Int16 >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< ::cppu::UnoUnsignedShortType * >(0)) == + ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_uInt16 * >(0)) == + ::cppu::UnoType< ::cppu::UnoCharType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Int32 * >(0)) == + ::cppu::UnoType< ::sal_Int32 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Int32 * >(0)) == + ::getCppuType< ::sal_Int32 >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_uInt32 * >(0)) == + ::cppu::UnoType< ::sal_uInt32 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_uInt32 * >(0)) == + ::getCppuType< ::sal_uInt32 >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Int64 * >(0)) == + ::cppu::UnoType< ::sal_Int64 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Int64 * >(0)) == + ::getCppuType< ::sal_Int64 >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_uInt64 * >(0)) == + ::cppu::UnoType< ::sal_uInt64 >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_uInt64 * >(0)) == + ::getCppuType< ::sal_uInt64 >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< float * >(0)) == + ::cppu::UnoType< float >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< float * >(0)) == + ::getCppuType< float >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< double * >(0)) == + ::cppu::UnoType< double >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< double * >(0)) == + ::getCppuType< double >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::cppu::UnoCharType * >(0)) == + ::cppu::UnoType< ::cppu::UnoCharType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Unicode * >(0)) == + ::cppu::UnoType< ::cppu::UnoCharType >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::sal_Unicode * >(0)) == + ::getCppuType< ::sal_Unicode >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::rtl::OUString * >(0)) == + ::cppu::UnoType< ::rtl::OUString >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< ::rtl::OUString * >(0)) == + ::getCppuType< ::rtl::OUString >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< css::uno::Type * >(0)) == + ::cppu::UnoType< css::uno::Type >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< css::uno::Type * >(0)) == + ::getCppuType< css::uno::Type >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< css::uno::Any * >(0)) == + ::cppu::UnoType< css::uno::Any >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< css::uno::Any * >(0)) == + ::getCppuType< css::uno::Any >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< + ::cppu::UnoSequenceType< ::cppu::UnoUnsignedShortType > * >(0)) == + ::cppu::UnoType< + ::cppu::UnoSequenceType< ::cppu::UnoUnsignedShortType > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::Sequence< ::sal_uInt16 > * >(0)) == + ::cppu::UnoType< + ::cppu::UnoSequenceType< ::cppu::UnoCharType > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoUnsignedShortType > > * >(0)) == + ::cppu::UnoType< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoUnsignedShortType > > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::Sequence< css::uno::Sequence< + ::sal_uInt16 > > * >(0)) == + ::cppu::UnoType< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoCharType > > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::Sequence< ::sal_Unicode > * >(0)) == + ::cppu::UnoType< + ::cppu::UnoSequenceType< ::cppu::UnoCharType > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::Sequence< css::uno::Sequence< + ::sal_Unicode > > * >(0)) == + ::cppu::UnoType< ::cppu::UnoSequenceType< ::cppu::UnoSequenceType< + ::cppu::UnoCharType > > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< css::uno::TypeClass * >(0)) == + ::cppu::UnoType< css::uno::TypeClass >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< css::uno::TypeClass * >(0)) == + ::getCppuType< css::uno::TypeClass >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::lang::EventObject * >(0)) == + ::cppu::UnoType< css::lang::EventObject >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::lang::EventObject * >(0)) == + ::getCppuType< css::lang::EventObject >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedStruct1 * >(0)) == + ::cppu::UnoType< css::lang::EventObject >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedStruct1 * >(0)) == + ::getCppuType< DerivedStruct1 >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::beans::PropertyChangeEvent * >(0)) == + ::cppu::UnoType< css::beans::PropertyChangeEvent >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::beans::PropertyChangeEvent * >(0)) == + ::getCppuType< css::beans::PropertyChangeEvent >()); +#if !(defined __SUNPRO_CC && __SUNPRO_CC <= 0x550) // erroneous ambiguity stated + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedStruct2 * >(0)) == + ::cppu::UnoType< css::beans::PropertyChangeEvent >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedStruct2 * >(0)) == + ::getCppuType< DerivedStruct2 >()); +#endif + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::beans::Optional< ::sal_Int8 > * >(0)) == + ::cppu::UnoType< css::beans::Optional< ::sal_Int8 > >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::beans::Optional< ::sal_Int8 > * >(0)) == + ::getCppuType< css::beans::Optional< ::sal_Int8 > >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< css::uno::Exception * >(0)) == + ::cppu::UnoType< css::uno::Exception >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< css::uno::Exception * >(0)) == + ::getCppuType< css::uno::Exception >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedException1 * >(0)) == + ::cppu::UnoType< css::uno::Exception >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedException1 * >(0)) == + ::getCppuType< DerivedException1 >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::RuntimeException * >(0)) == + ::cppu::UnoType< css::uno::RuntimeException >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::RuntimeException * >(0)) == + ::getCppuType< css::uno::RuntimeException >()); +#if !(defined __SUNPRO_CC && __SUNPRO_CC <= 0x550) // erroneous ambiguity stated + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedException2 * >(0)) == + ::cppu::UnoType< css::uno::RuntimeException >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedException2 * >(0)) == + ::getCppuType< DerivedException2 >()); +#endif + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::XInterface * >(0)) == + ::cppu::UnoType< css::uno::XInterface >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::Reference< css::uno::XInterface > * >(0)) == + ::cppu::UnoType< css::uno::XInterface >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::Reference< css::uno::XInterface > * >(0)) == + ::getCppuType< css::uno::Reference< css::uno::XInterface > >()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedInterface1 * >(0)) == + ::cppu::UnoType< css::uno::XInterface >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::Reference< DerivedInterface1 > * >(0)) == + ::cppu::UnoType< css::uno::XInterface >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::XComponentContext * >(0)) == + ::cppu::UnoType< css::uno::XComponentContext >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< + css::uno::Reference< css::uno::XComponentContext > * >(0)) == + ::cppu::UnoType< css::uno::XComponentContext >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< + css::uno::Reference< css::uno::XComponentContext > * >(0)) == + ::getCppuType< css::uno::Reference< css::uno::XComponentContext > >()); +#if !(defined __SUNPRO_CC && __SUNPRO_CC <= 0x550) // erroneous ambiguity stated + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar(static_cast< DerivedInterface2 * >(0)) == + ::cppu::UnoType< css::uno::XComponentContext >::get()); + CPPUNIT_ASSERT( + ::cppu::getTypeFavourChar( + static_cast< css::uno::Reference< DerivedInterface2 > * >(0)) == + ::cppu::UnoType< css::uno::XComponentContext >::get()); +#endif +} + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test, "alltests"); + +} + +NOADDITIONAL; diff --git a/cppu/qa/types.idl b/cppu/qa/types.idl new file mode 100644 index 000000000000..0ec106ec91b2 --- /dev/null +++ b/cppu/qa/types.idl @@ -0,0 +1,63 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "com/sun/star/uno/Exception.idl" +#include "com/sun/star/uno/XInterface.idl" + +enum Enum1 { M0, M1, M2 }; + +enum Enum2 { M0, M1, M2 }; + +struct Struct1 { long member; }; + +struct Struct2 { long member; }; + +struct Struct2a: Struct2 { long member2; }; + +struct Struct2b: Struct2a { long member3; }; + +struct Poly< T > { long member; }; + +struct Rec { sequence< Rec > x; }; + +exception Exception1: com::sun::star::uno::Exception { long member; }; + +exception Exception2: com::sun::star::uno::Exception { long member; }; + +exception Exception2a: Exception2 { long member2; }; + +exception Exception2b: Exception2a {}; + +interface Interface1 {}; + +interface Interface2 {}; + +interface Interface2a: Interface2 {}; + +interface Interface2b: Interface2a {}; + +interface Interface3 {}; diff --git a/cppu/qa/version.map b/cppu/qa/version.map new file mode 100644 index 000000000000..7321bbca16ad --- /dev/null +++ b/cppu/qa/version.map @@ -0,0 +1,34 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +UDK_3_0_0 { + global: + registerAllTestFunction; + + local: + *; +}; diff --git a/cppu/source/AffineBridge/AffineBridge.cxx b/cppu/source/AffineBridge/AffineBridge.cxx new file mode 100644 index 000000000000..59f8213274a6 --- /dev/null +++ b/cppu/source/AffineBridge/AffineBridge.cxx @@ -0,0 +1,364 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "osl/thread.hxx" +#include "osl/conditn.hxx" +#include "osl/mutex.hxx" + +#include "cppu/helper/purpenv/Environment.hxx" +#include "cppu/helper/purpenv/Mapping.hxx" + + +#ifdef debug +# define LOG_LIFECYCLE_AffineBridge +#endif + +#ifdef LOG_LIFECYCLE_AffineBridge +# include <iostream> +# define LOG_LIFECYCLE_AffineBridge_emit(x) x + +#else +# define LOG_LIFECYCLE_AffineBridge_emit(x) + +#endif + +class InnerThread; +class OuterThread; + +class SAL_DLLPRIVATE AffineBridge : public cppu::Enterable +{ +public: + enum Msg + { + CB_DONE, + CB_FPOINTER + }; + + Msg m_message; + uno_EnvCallee * m_pCallee; + va_list * m_pParam; + + osl::Mutex m_innerMutex; + oslThreadIdentifier m_innerThreadId; + InnerThread * m_pInnerThread; + osl::Condition m_innerCondition; + sal_Int32 m_enterCount; + + osl::Mutex m_outerMutex; + oslThreadIdentifier m_outerThreadId; + osl::Condition m_outerCondition; + OuterThread * m_pOuterThread; + + explicit AffineBridge(void); + virtual ~AffineBridge(void); + + virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam); + virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam); + + virtual void v_enter(void); + virtual void v_leave(void); + + virtual int v_isValid(rtl::OUString * pReason); + + void innerDispatch(void); + void outerDispatch(int loop); +}; + +class SAL_DLLPRIVATE InnerThread : public osl::Thread +{ + virtual void SAL_CALL run(void); + + AffineBridge * m_pAffineBridge; + +public: + InnerThread(AffineBridge * threadEnvironment) + : m_pAffineBridge(threadEnvironment) + { + create(); + } +}; + +void InnerThread::run(void) +{ + m_pAffineBridge->enter(); + m_pAffineBridge->innerDispatch(); + m_pAffineBridge->leave(); +} + +class SAL_DLLPRIVATE OuterThread : public osl::Thread +{ + virtual void SAL_CALL run(void); + + AffineBridge * m_pAffineBridge; + +public: + OuterThread(AffineBridge * threadEnvironment); +}; + +OuterThread::OuterThread(AffineBridge * threadEnvironment) + : m_pAffineBridge(threadEnvironment) +{ + create(); +} + +void OuterThread::run(void) +{ + osl::MutexGuard guard(m_pAffineBridge->m_outerMutex); + + m_pAffineBridge->m_outerThreadId = getIdentifier(); + m_pAffineBridge->outerDispatch(0); + m_pAffineBridge->m_outerThreadId = 0; + + m_pAffineBridge->m_pOuterThread = NULL; + m_pAffineBridge = NULL; +} + + +AffineBridge::AffineBridge(void) + : m_innerThreadId(0), + m_pInnerThread (NULL), + m_enterCount (0), + m_outerThreadId(0), + m_pOuterThread (NULL) +{ + LOG_LIFECYCLE_AffineBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "AffineBridge::AffineBridge(uno_Environment * pEnv)", this)); +} + +AffineBridge::~AffineBridge(void) +{ + LOG_LIFECYCLE_AffineBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "AffineBridge::~AffineBridge(void)", this)); + + if (m_pInnerThread && osl_getThreadIdentifier(NULL) != m_innerThreadId) + { + m_message = CB_DONE; + m_innerCondition.set(); + + m_pInnerThread->join(); + } + + delete m_pInnerThread; + + if (m_pOuterThread) + { + m_pOuterThread->join(); + delete m_pOuterThread; + } +} + + +void AffineBridge::outerDispatch(int loop) +{ + OSL_ASSERT(m_outerThreadId == osl_getThreadIdentifier(NULL)); + OSL_ASSERT(m_innerThreadId != m_outerThreadId); + + Msg mm; + + do + { + // FIXME: created outer thread must not wait + // in case of no message + // note: no message can happen in case newly created + // outer thread acquire outerMutex after a real outer + // thread enters outerDispatch! + m_outerCondition.wait(); + m_outerCondition.reset(); + + mm = m_message; + + switch(mm) + { + case CB_DONE: + break; + + case CB_FPOINTER: + { + m_pCallee(m_pParam); + + m_message = CB_DONE; + m_innerCondition.set(); + break; + } + default: + abort(); + } + } + while(mm != CB_DONE && loop); +} + +void AffineBridge::innerDispatch(void) +{ + OSL_ASSERT(m_innerThreadId == osl_getThreadIdentifier(NULL)); + OSL_ASSERT(m_innerThreadId != m_outerThreadId); + + Msg mm; + + do + { + m_innerCondition.wait(); + m_innerCondition.reset(); + + mm = m_message; + + switch(mm) + { + case CB_DONE: + break; + + case CB_FPOINTER: + { + m_pCallee(m_pParam); + + m_message = CB_DONE; + m_outerCondition.set(); + break; + } + default: + abort(); + } + } + while(mm != CB_DONE); +} + +void AffineBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam) +{ + osl::MutexGuard guard(m_outerMutex); // only one thread at a time can call into + + if (m_innerThreadId == 0) // no inner thread yet + { + m_pInnerThread = new InnerThread(this); + m_pInnerThread->resume(); + } + + bool resetId = false; + if (!m_outerThreadId) + { + m_outerThreadId = osl_getThreadIdentifier(NULL); + resetId = true; + } + + m_message = CB_FPOINTER; + m_pCallee = pCallee; + m_pParam = pParam; + m_innerCondition.set(); + + outerDispatch(1); + + if (resetId) + m_outerThreadId = 0; +} + +void AffineBridge::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam) +{ + OSL_ASSERT(m_innerThreadId); + + osl::MutexGuard guard(m_innerMutex); + + if (m_outerThreadId == 0) // no outer thread yet + { + osl::MutexGuard guard_m_outerMutex(m_outerMutex); + + if (m_outerThreadId == 0) + { + if (m_pOuterThread) + { + m_pOuterThread->join(); + delete m_pOuterThread; + } + + m_pOuterThread = new OuterThread(this); + } + } + + m_message = CB_FPOINTER; + m_pCallee = pCallee; + m_pParam = pParam; + m_outerCondition.set(); + + innerDispatch(); +} + +void AffineBridge::v_enter(void) +{ + m_innerMutex.acquire(); + + if (!m_enterCount) + m_innerThreadId = osl_getThreadIdentifier(NULL); + + OSL_ASSERT(m_innerThreadId == osl_getThreadIdentifier(NULL)); + + ++ m_enterCount; +} + +void AffineBridge::v_leave(void) +{ + OSL_ASSERT(m_innerThreadId == osl_getThreadIdentifier(NULL)); + + -- m_enterCount; + if (!m_enterCount) + m_innerThreadId = 0; + + m_innerMutex.release(); +} + +int AffineBridge::v_isValid(rtl::OUString * pReason) +{ + int result = 1; + + result = m_enterCount > 0; + if (!result) + *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not entered")); + + else + { + result = m_innerThreadId == osl_getThreadIdentifier(NULL); + + if (!result) + *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong thread")); + } + + if (result) + *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OK")); + + return result; +} + +extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_initEnvironment(uno_Environment * pEnv) + SAL_THROW_EXTERN_C() +{ + cppu::helper::purpenv::Environment_initWithEnterable(pEnv, new AffineBridge()); +} + +extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_ext_getMapping(uno_Mapping ** ppMapping, + uno_Environment * pFrom, + uno_Environment * pTo ) +{ + cppu::helper::purpenv::createMapping(ppMapping, pFrom, pTo); +} + diff --git a/cppu/source/AffineBridge/makefile.mk b/cppu/source/AffineBridge/makefile.mk new file mode 100644 index 000000000000..c25062c15194 --- /dev/null +++ b/cppu/source/AffineBridge/makefile.mk @@ -0,0 +1,44 @@ +#************************************************************************* +# +# 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 := cppu +TARGET := AffineBridge + +ENABLE_EXCEPTIONS := TRUE +NO_BSYMBOLIC := TRUE +USE_DEFFILE := FALSE + + +.INCLUDE: settings.mk + + +SLOFILES := $(SLO)$/AffineBridge.obj + + +.INCLUDE: target.mk + diff --git a/cppu/source/LogBridge/LogBridge.cxx b/cppu/source/LogBridge/LogBridge.cxx new file mode 100755 index 000000000000..b57cd405c82b --- /dev/null +++ b/cppu/source/LogBridge/LogBridge.cxx @@ -0,0 +1,277 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "osl/mutex.hxx" +#include "osl/thread.h" +#include "uno/dispatcher.h" +#include "typelib/typedescription.hxx" +#include "cppu/helper/purpenv/Environment.hxx" +#include "cppu/helper/purpenv/Mapping.hxx" +#include "cppu/EnvDcp.hxx" +#include "rtl/logfile.hxx" +#include "uno/environment.hxx" +#include <com/sun/star/uno/Type.hxx> +#include <hash_map> +#include <memory> + +namespace +{ +class LogBridge : public cppu::Enterable +{ + osl::Mutex m_mutex; + sal_Int32 m_count; + oslThreadIdentifier m_threadId; + + virtual ~LogBridge(void); + +public: + explicit LogBridge(void); + + virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam); + virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam); + + virtual void v_enter(void); + virtual void v_leave(void); + + virtual int v_isValid(rtl::OUString * pReason); +}; + +LogBridge::LogBridge(void) + : m_count (0) + ,m_threadId(0) +{ +} + +LogBridge::~LogBridge(void) +{ + OSL_ASSERT(m_count >= 0); +} + +void LogBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam) +{ + enter(); + pCallee(pParam); + leave(); +} + +void LogBridge::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam) +{ + OSL_ASSERT(m_count > 0); + + -- m_count; + pCallee(pParam); + ++ m_count; + + if (!m_threadId) + m_threadId = osl_getThreadIdentifier(NULL); +} + +void LogBridge::v_enter(void) +{ + m_mutex.acquire(); + + OSL_ASSERT(m_count >= 0); + + if (m_count == 0) + m_threadId = osl_getThreadIdentifier(NULL); + + ++ m_count; +} + +void LogBridge::v_leave(void) +{ + OSL_ASSERT(m_count > 0); + + -- m_count; + if (!m_count) + m_threadId = 0; + + + m_mutex.release(); +} + +int LogBridge::v_isValid(rtl::OUString * pReason) +{ + int result = 1; + + result = m_count > 0; + if (!result) + *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not entered")); + + else + { + result = m_threadId == osl_getThreadIdentifier(NULL); + + if (!result) + *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong thread")); + } + + if (result) + *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OK")); + + return result; +} + + void traceValue(typelib_TypeDescriptionReference* _pTypeRef,void* pArg) + { + switch(_pTypeRef->eTypeClass) + { + case typelib_TypeClass_STRING: + { + const ::rtl::OString sValue( ::rtl::OUStringToOString(*static_cast< ::rtl::OUString*>(pArg),osl_getThreadTextEncoding())); + rtl_logfile_trace( "%s", sValue.getStr()); + } + break; + case typelib_TypeClass_BOOLEAN: + rtl_logfile_trace( "%d", *static_cast<sal_Bool*>(pArg)); + break; + case typelib_TypeClass_BYTE: + rtl_logfile_trace( "%d", *static_cast<sal_Int8*>(pArg)); + break; + case typelib_TypeClass_CHAR: + rtl_logfile_trace( "%c", *static_cast<sal_Char*>(pArg)); + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + rtl_logfile_trace( "%d", *static_cast<sal_Int16*>(pArg)); + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_ENUM: + rtl_logfile_trace( "%d", *static_cast<sal_Int32*>(pArg)); + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + rtl_logfile_trace( "%d", *static_cast<sal_Int64*>(pArg)); + break; + case typelib_TypeClass_FLOAT: + rtl_logfile_trace( "%f", *static_cast<float*>(pArg)); + break; + case typelib_TypeClass_DOUBLE: + rtl_logfile_trace( "%f", *static_cast<double*>(pArg)); + break; + case typelib_TypeClass_TYPE: + { + const ::rtl::OString sValue( ::rtl::OUStringToOString(((com::sun::star::uno::Type*)pArg)->getTypeName(),osl_getThreadTextEncoding())); + rtl_logfile_trace( "%s", sValue.getStr()); + } + break; + case typelib_TypeClass_ANY: + if ( static_cast<uno_Any*>(pArg)->pData ) + traceValue(static_cast<uno_Any*>(pArg)->pType,static_cast<uno_Any*>(pArg)->pData); + else + rtl_logfile_trace( "void"); + break; + case typelib_TypeClass_EXCEPTION: + rtl_logfile_trace( "exception"); + break; + case typelib_TypeClass_INTERFACE: + { + const ::rtl::OString sValue( ::rtl::OUStringToOString(_pTypeRef->pTypeName,osl_getThreadTextEncoding())); + rtl_logfile_trace( "%s 0x%p", sValue.getStr(),pArg); + } + break; + case typelib_TypeClass_VOID: + rtl_logfile_trace( "void"); + break; + default: + rtl_logfile_trace( "0x%p", pArg); + break; + } // switch(pParams[i].pTypeRef->eTypeClass) + } +} + +void LogProbe( + bool pre, + void * /*pThis*/, + void * /*pContext*/, + typelib_TypeDescriptionReference * pReturnTypeRef, + typelib_MethodParameter * pParams, + sal_Int32 nParams, + typelib_TypeDescription const * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ) +{ + static ::std::auto_ptr< ::rtl::Logfile> pLogger; + ::rtl::OString sTemp; + if ( pMemberType && pMemberType->pTypeName ) + sTemp = ::rtl::OUStringToOString(pMemberType->pTypeName,RTL_TEXTENCODING_ASCII_US); + if ( pre ) + { + rtl_logfile_longTrace( "{ LogBridge () %s", sTemp.getStr() ); + if ( nParams ) + { + rtl_logfile_trace( "\n| : ( LogBridge "); + for(sal_Int32 i = 0;i < nParams;++i) + { + if ( i > 0 ) + rtl_logfile_trace( ","); + traceValue(pParams[i].pTypeRef,pArgs[i]); + + } + rtl_logfile_trace( ")"); + } // if ( nParams ) + rtl_logfile_trace( "\n"); + } + else if ( !pre ) + { + rtl_logfile_longTrace( "} LogBridge () %s",sTemp.getStr()); + if ( ppException && *ppException ) + { + rtl_logfile_trace( " excption occured : "); + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, (*ppException)->pType ); + const ::rtl::OString sValue( ::rtl::OUStringToOString(pElementTypeDescr->pTypeName,osl_getThreadTextEncoding())); + rtl_logfile_trace( "%s", sValue.getStr()); + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + } + else if ( pReturnTypeRef ) + { + rtl_logfile_trace( " return : "); + traceValue(pReturnTypeRef,pReturn); + } // if ( pReturn && pReturnTypeRef ) + + rtl_logfile_trace( "\n"); + } +} + +extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_initEnvironment(uno_Environment * pEnv) + SAL_THROW_EXTERN_C() +{ + cppu::helper::purpenv::Environment_initWithEnterable(pEnv, new LogBridge()); +} + +extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_ext_getMapping(uno_Mapping ** ppMapping, + uno_Environment * pFrom, + uno_Environment * pTo ) +{ + cppu::helper::purpenv::createMapping(ppMapping, pFrom, pTo,LogProbe); +} diff --git a/cppu/source/LogBridge/makefile.mk b/cppu/source/LogBridge/makefile.mk new file mode 100755 index 000000000000..2759c3ddfcb3 --- /dev/null +++ b/cppu/source/LogBridge/makefile.mk @@ -0,0 +1,44 @@ +#************************************************************************* +# +# 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 := cppu +TARGET := LogBridge + +ENABLE_EXCEPTIONS := TRUE +NO_BSYMBOLIC := TRUE +USE_DEFFILE := FALSE + + +.INCLUDE: settings.mk + + +SLOFILES := $(SLO)$/LogBridge.obj + + +.INCLUDE: target.mk + diff --git a/cppu/source/UnsafeBridge/UnsafeBridge.cxx b/cppu/source/UnsafeBridge/UnsafeBridge.cxx new file mode 100644 index 000000000000..5a531de47182 --- /dev/null +++ b/cppu/source/UnsafeBridge/UnsafeBridge.cxx @@ -0,0 +1,163 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "osl/mutex.hxx" +#include "osl/thread.h" + +#include "cppu/helper/purpenv/Environment.hxx" +#include "cppu/helper/purpenv/Mapping.hxx" + + +#ifdef debug +# define LOG_LIFECYCLE_UnsafeBridge +#endif + +#ifdef LOG_LIFECYCLE_UnsafeBridge +# include <iostream> +# define LOG_LIFECYCLE_UnsafeBridge_emit(x) x + +#else +# define LOG_LIFECYCLE_UnsafeBridge_emit(x) + +#endif + + +class SAL_DLLPRIVATE UnsafeBridge : public cppu::Enterable +{ + osl::Mutex m_mutex; + sal_Int32 m_count; + oslThreadIdentifier m_threadId; + + virtual ~UnsafeBridge(void); + +public: + explicit UnsafeBridge(void); + + virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam); + virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam); + + virtual void v_enter(void); + virtual void v_leave(void); + + virtual int v_isValid(rtl::OUString * pReason); +}; + +UnsafeBridge::UnsafeBridge(void) + : m_count (0), + m_threadId(0) +{ + LOG_LIFECYCLE_UnsafeBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "UnsafeBridge::UnsafeBridge(uno_Environment * pEnv)", this)); +} + +UnsafeBridge::~UnsafeBridge(void) +{ + LOG_LIFECYCLE_UnsafeBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "UnsafeBridge::~UnsafeBridge(void)", this)); + + OSL_ASSERT(m_count >= 0); +} + +void UnsafeBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam) +{ + enter(); + pCallee(pParam); + leave(); +} + +void UnsafeBridge::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam) +{ + OSL_ASSERT(m_count > 0); + + -- m_count; + pCallee(pParam); + ++ m_count; + + if (!m_threadId) + m_threadId = osl_getThreadIdentifier(NULL); +} + +void UnsafeBridge::v_enter(void) +{ + m_mutex.acquire(); + + OSL_ASSERT(m_count >= 0); + + if (m_count == 0) + m_threadId = osl_getThreadIdentifier(NULL); + + ++ m_count; +} + +void UnsafeBridge::v_leave(void) +{ + OSL_ASSERT(m_count > 0); + + -- m_count; + if (!m_count) + m_threadId = 0; + + + m_mutex.release(); +} + +int UnsafeBridge::v_isValid(rtl::OUString * pReason) +{ + int result = 1; + + result = m_count > 0; + if (!result) + *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not entered")); + + else + { + result = m_threadId == osl_getThreadIdentifier(NULL); + + if (!result) + *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong thread")); + } + + if (result) + *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OK")); + + return result; +} + +extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_initEnvironment(uno_Environment * pEnv) + SAL_THROW_EXTERN_C() +{ + cppu::helper::purpenv::Environment_initWithEnterable(pEnv, new UnsafeBridge()); +} + +extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_ext_getMapping(uno_Mapping ** ppMapping, + uno_Environment * pFrom, + uno_Environment * pTo ) +{ + cppu::helper::purpenv::createMapping(ppMapping, pFrom, pTo); +} + diff --git a/cppu/source/UnsafeBridge/makefile.mk b/cppu/source/UnsafeBridge/makefile.mk new file mode 100644 index 000000000000..0c1c4a988c83 --- /dev/null +++ b/cppu/source/UnsafeBridge/makefile.mk @@ -0,0 +1,44 @@ +#************************************************************************* +# +# 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 := cppu +TARGET := UnsafeBridge + +ENABLE_EXCEPTIONS := TRUE +NO_BSYMBOLIC := TRUE +USE_DEFFILE := FALSE + + +.INCLUDE: settings.mk + + +SLOFILES := $(SLO)$/UnsafeBridge.obj + + +.INCLUDE: target.mk + diff --git a/cppu/source/cppu/cppu_opt.cxx b/cppu/source/cppu/cppu_opt.cxx new file mode 100644 index 000000000000..a4640fd6f945 --- /dev/null +++ b/cppu/source/cppu/cppu_opt.cxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "typelib/typedescription.h" +#include "uno/any2.h" +#include "rtl/ustrbuf.hxx" + + +using namespace ::rtl; + +//################################################################################################## +extern "C" rtl_uString * SAL_CALL cppu_unsatisfied_iquery_msg( + typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C() +{ + OUStringBuffer buf( 64 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unsatisfied query for interface of type ") ); + buf.append( OUString::unacquired( &pType->pTypeName ) ); + buf.append( (sal_Unicode) '!' ); + OUString ret( buf.makeStringAndClear() ); + rtl_uString_acquire( ret.pData ); + return ret.pData; +} + +//################################################################################################## +extern "C" rtl_uString * SAL_CALL cppu_unsatisfied_iset_msg( + typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C() +{ + OUStringBuffer buf( 64 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("invalid attempt to assign an empty interface of type ") ); + buf.append( OUString::unacquired( &pType->pTypeName ) ); + buf.append( (sal_Unicode) '!' ); + OUString ret( buf.makeStringAndClear() ); + rtl_uString_acquire( ret.pData ); + return ret.pData; +} + +//############################################################################## +extern "C" rtl_uString * SAL_CALL cppu_Any_extraction_failure_msg( + uno_Any * pAny, typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C() +{ + OUStringBuffer buf; + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( + "Cannot extract an Any(") ); + buf.append( OUString::unacquired(&pAny->pType->pTypeName) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(") to ") ); + buf.append( OUString::unacquired(&pType->pTypeName) ); + buf.append( static_cast<sal_Unicode>('!') ); + const OUString ret( buf.makeStringAndClear() ); + rtl_uString_acquire( ret.pData ); + return ret.pData; +} diff --git a/cppu/source/cppu/makefile.mk b/cppu/source/cppu/makefile.mk new file mode 100644 index 000000000000..5a42ec3113c2 --- /dev/null +++ b/cppu/source/cppu/makefile.mk @@ -0,0 +1,45 @@ +#************************************************************************* +# +# 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=cppu +TARGET=cppu_cppu + +# --- Settings ----------------------------------------------------- + +.INCLUDE : ..$/..$/util$/makefile.pmk +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/cppu_opt.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : ..$/..$/util$/target.pmk +.INCLUDE : target.mk diff --git a/cppu/source/helper/purpenv/Proxy.hxx b/cppu/source/helper/purpenv/Proxy.hxx new file mode 100644 index 000000000000..570d7291b177 --- /dev/null +++ b/cppu/source/helper/purpenv/Proxy.hxx @@ -0,0 +1,89 @@ +/************************************************************************* + * + * 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 INCLUDED_Proxy_hxx +#define INCLUDED_Proxy_hxx + +#include "osl/interlck.h" + +#include "uno/environment.hxx" +#include "uno/mapping.hxx" +#include "uno/dispatcher.h" + +#include "cppu/helper/purpenv/Mapping.hxx" + + +namespace cssu = com::sun::star::uno; + + +class SAL_DLLPRIVATE Proxy : public uno_Interface +{ + oslInterlockedCount m_nRef; + + cssu::Environment m_from; + cssu::Environment m_to; + + cssu::Mapping m_from_to; + cssu::Mapping m_to_from; + + // mapping information + uno_Interface * m_pUnoI; // wrapped interface + typelib_InterfaceTypeDescription * m_pTypeDescr; + rtl::OUString m_aOId; + + cppu::helper::purpenv::ProbeFun * m_probeFun; + void * m_pProbeContext; + +public: + explicit Proxy(cssu::Mapping const & to_from, + uno_Environment * pTo, + uno_Environment * pFrom, + uno_Interface * pUnoI, + typelib_InterfaceTypeDescription * pTypeDescr, + rtl::OUString const & rOId, + cppu::helper::purpenv::ProbeFun * probeFun, + void * pProbeContext) + SAL_THROW( () ); + ~Proxy(void); + + void acquire(void); + void release(void); + + void dispatch( + typelib_TypeDescriptionReference * pReturnTypeRef, + typelib_MethodParameter * pParams, + sal_Int32 nParams, + typelib_TypeDescription const * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ); + +}; + +extern "C" SAL_DLLPRIVATE void SAL_CALL Proxy_free(uno_ExtEnvironment * pEnv, void * pProxy) SAL_THROW_EXTERN_C(); + +#endif diff --git a/cppu/source/helper/purpenv/export.mk b/cppu/source/helper/purpenv/export.mk new file mode 100644 index 000000000000..7e5e9d04d1d2 --- /dev/null +++ b/cppu/source/helper/purpenv/export.mk @@ -0,0 +1,19 @@ + +.IF "$(GUI)"=="UNX" || "$(GUI)"=="MAC" +NAMEpurpenv_helper := uno_purpenvhelper$(COMID) + +purpenv_helper_LIB := -l$(NAMEpurpenv_helper) + +.ELIF "$(GUI)"=="OS2" +NAMEpurpenv_helper := purpeh$(UDK_MAJOR) +purpenv_helper_LIB := i$(NAMEpurpenv_helper) + +.ELSE +NAMEpurpenv_helper := purpenvhelper$(UDK_MAJOR)$(COMID) +.IF "$(COM)"=="GCC" +purpenv_helper_LIB := -l$(NAMEpurpenv_helper) +.ELSE +purpenv_helper_LIB := $(LIBPRE) i$(NAMEpurpenv_helper).lib +.ENDIF + +.ENDIF diff --git a/cppu/source/helper/purpenv/helper_purpenv_Environment.cxx b/cppu/source/helper/purpenv/helper_purpenv_Environment.cxx new file mode 100644 index 000000000000..0fbed6739951 --- /dev/null +++ b/cppu/source/helper/purpenv/helper_purpenv_Environment.cxx @@ -0,0 +1,537 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "cppu/helper/purpenv/Environment.hxx" + +#include "osl/diagnose.h" +#include "uno/lbnames.h" + +#include "typelib/typedescription.h" +#include "osl/interlck.h" + +#ifdef debug +# define LOG_LIFECYCLE_cppu_helper_purpenv_Base +#endif + +#ifdef LOG_LIFECYCLE_cppu_helper_purpenv_Base +# include <iostream> +# define LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(x) x + +#else +# define LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(x) + +#endif + + +extern "C" { +typedef void SAL_CALL EnvFun_P (uno_Environment *); +typedef void SAL_CALL EnvFun_PP_P(uno_Environment ** ppHardEnv, uno_Environment *); +typedef void SAL_CALL ExtEnv_registerProxyInterface (uno_ExtEnvironment *, + void ** ppProxy, + uno_freeProxyFunc freeProxy, + rtl_uString * pOId, + typelib_InterfaceTypeDescription * pTypeDescr); +typedef void SAL_CALL ExtEnv_revokeInterface (uno_ExtEnvironment *, + void * pInterface); +typedef void SAL_CALL ExtEnv_getObjectIdentifier (uno_ExtEnvironment *, + rtl_uString **, + void *); +typedef void SAL_CALL ExtEnv_getRegisteredInterface (uno_ExtEnvironment *, + void **, + rtl_uString *, + typelib_InterfaceTypeDescription *); +typedef void SAL_CALL ExtEnv_getRegisteredInterfaces(uno_ExtEnvironment *, + void *** pppInterfaces, + sal_Int32 * pnLen, + uno_memAlloc memAlloc); +typedef void SAL_CALL ExtEnv_computeObjectIdentifier(uno_ExtEnvironment *, + rtl_uString ** ppOId, + void * pInterface); +typedef void SAL_CALL ExtEnv_acquireInterface (uno_ExtEnvironment *, + void * pInterface); +typedef void SAL_CALL ExtEnv_releaseInterface (uno_ExtEnvironment *, + void * pInterface); +} + +class Base : public cppu::Enterable +{ +public: + explicit Base(uno_Environment * pEnv, cppu::Enterable * pEnterable); + + void acquireWeak(void); + void releaseWeak(void); + void harden (uno_Environment ** ppHardEnv); + void acquire (void); + void release (void); + + void registerProxyInterface (void ** ppProxy, + uno_freeProxyFunc freeProxy, + rtl::OUString const & oid, + typelib_InterfaceTypeDescription * pTypeDescr); + void revokeInterface (void * pInterface); + void getObjectIdentifier (void * pInterface, + rtl::OUString * pOid); + void getRegisteredInterface (void **, + rtl::OUString const & oid, + typelib_InterfaceTypeDescription *); + void getRegisteredInterfaces(void ***, + sal_Int32 * pnLen, + uno_memAlloc memAlloc); + void computeObjectIdentifier(void * pInterface, + rtl::OUString * pOid); + void acquireInterface (void * pInterface); + void releaseInterface (void * pInterface); + + virtual void v_enter (void); + virtual void v_leave (void); + virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam); + virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam); + virtual int v_isValid (rtl::OUString * pReason); + +protected: + oslInterlockedCount m_nRef; + uno_Environment * m_pEnv; + cppu::Enterable * m_pEnterable; + + EnvFun_P * m_env_acquire; + EnvFun_P * m_env_release; + EnvFun_PP_P * m_env_harden; + EnvFun_P * m_env_acquireWeak; + EnvFun_P * m_env_releaseWeak; + + ExtEnv_registerProxyInterface * m_env_registerProxyInterface; + ExtEnv_revokeInterface * m_env_revokeInterface; + ExtEnv_getObjectIdentifier * m_env_getObjectIdentifier; + ExtEnv_getRegisteredInterface * m_env_getRegisteredInterface; + ExtEnv_getRegisteredInterfaces * m_env_getRegisteredInterfaces; + ExtEnv_computeObjectIdentifier * m_env_computeObjectIdentifier; + ExtEnv_acquireInterface * m_env_acquireInterface; + ExtEnv_releaseInterface * m_env_releaseInterface; + + virtual ~Base(); +}; + +extern "C" { +static void SAL_CALL s_acquire(uno_Environment * pEnv) //SAL_THROW_EXTERN_C() +{ + Base * pBase = static_cast<Base *>(pEnv->pReserved); + pBase->acquire(); +} + +static void SAL_CALL s_release(uno_Environment * pEnv) SAL_THROW_EXTERN_C() +{ + Base * pBase = static_cast<Base *>(pEnv->pReserved); + pBase->release(); +} + +static void SAL_CALL s_harden(uno_Environment ** ppHardEnv, uno_Environment * pEnv) SAL_THROW_EXTERN_C() +{ + Base * pBase = static_cast<Base *>(pEnv->pReserved); + pBase->harden(ppHardEnv); +} + +static void SAL_CALL s_acquireWeak(uno_Environment * pEnv) SAL_THROW_EXTERN_C() +{ + Base * pBase = static_cast<Base *>(pEnv->pReserved); + pBase->acquireWeak(); +} + +static void SAL_CALL s_releaseWeak(uno_Environment * pEnv) SAL_THROW_EXTERN_C() +{ + Base * pBase = static_cast<Base *>(pEnv->pReserved); + pBase->releaseWeak(); +} + + +static void SAL_CALL s_registerProxyInterface(uno_ExtEnvironment * pExtEnv, + void ** ppProxy, + uno_freeProxyFunc freeProxy, + rtl_uString * pOId, + typelib_InterfaceTypeDescription * pTypeDescr) +{ + Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); + pBase->registerProxyInterface(ppProxy, freeProxy, pOId, pTypeDescr); +} + +static void SAL_CALL s_revokeInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) +{ + Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); + pBase->revokeInterface(pInterface); +} + +static void SAL_CALL s_getObjectIdentifier(uno_ExtEnvironment * pExtEnv, + rtl_uString ** ppOId, + void * pInterface) +{ + Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); + pBase->getObjectIdentifier(pInterface, reinterpret_cast<rtl::OUString *>(ppOId)); +} + +static void SAL_CALL s_getRegisteredInterface(uno_ExtEnvironment * pExtEnv, + void ** ppInterface, + rtl_uString * pOId, + typelib_InterfaceTypeDescription * pTypeDescr) +{ + Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); + pBase->getRegisteredInterface(ppInterface, pOId, pTypeDescr); +} + +static void SAL_CALL s_getRegisteredInterfaces(uno_ExtEnvironment * pExtEnv, + void *** pppInterface, + sal_Int32 * pnLen, + uno_memAlloc memAlloc) +{ + Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); + pBase->getRegisteredInterfaces(pppInterface, pnLen, memAlloc); +} + +static void SAL_CALL s_computeObjectIdentifier(uno_ExtEnvironment * pExtEnv, + rtl_uString ** ppOId, + void * pInterface) +{ + Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); + pBase->computeObjectIdentifier(pInterface, reinterpret_cast<rtl::OUString *>(ppOId)); +} + +static void SAL_CALL s_acquireInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) { + Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); + pBase->acquireInterface(pInterface); +} + +static void SAL_CALL s_releaseInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) { + Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); + pBase->releaseInterface(pInterface); +} + +} + +Base::Base(uno_Environment * pEnv, cppu::Enterable * pEnterable) + :m_nRef(1), + m_pEnv(pEnv), + m_pEnterable (pEnterable), + m_env_acquire (pEnv->acquire), + m_env_release (pEnv->release), + m_env_harden (pEnv->harden), + m_env_acquireWeak(pEnv->acquireWeak), + m_env_releaseWeak(pEnv->releaseWeak), + m_env_registerProxyInterface (pEnv->pExtEnv->registerProxyInterface), + m_env_revokeInterface (pEnv->pExtEnv->revokeInterface), + m_env_getObjectIdentifier (pEnv->pExtEnv->getObjectIdentifier), + m_env_getRegisteredInterface (pEnv->pExtEnv->getRegisteredInterface), + m_env_getRegisteredInterfaces(pEnv->pExtEnv->getRegisteredInterfaces), + m_env_computeObjectIdentifier(pEnv->pExtEnv->computeObjectIdentifier), + m_env_acquireInterface (pEnv->pExtEnv->acquireInterface), + m_env_releaseInterface (pEnv->pExtEnv->releaseInterface) +{ + LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(fprintf(stderr, "LIFE: %s -> %p\n", "cppu::helper::purpenv::Base::Base(uno_Environment * pEnv)", this)); + OSL_ENSURE( + rtl_ustr_ascii_compare_WithLength(pEnv->pTypeName->buffer, rtl_str_getLength(UNO_LB_UNO), UNO_LB_UNO) + == 0, + "### wrong environment type!"); + + pEnv->acquire = s_acquire; + pEnv->release = s_release; + pEnv->harden = s_harden; + pEnv->acquireWeak = s_acquireWeak; + pEnv->releaseWeak = s_releaseWeak; + + pEnv->pExtEnv->registerProxyInterface = s_registerProxyInterface; + pEnv->pExtEnv->revokeInterface = s_revokeInterface; + pEnv->pExtEnv->getObjectIdentifier = s_getObjectIdentifier; + pEnv->pExtEnv->getRegisteredInterface = s_getRegisteredInterface; + pEnv->pExtEnv->getRegisteredInterfaces = s_getRegisteredInterfaces; + pEnv->pExtEnv->computeObjectIdentifier = s_computeObjectIdentifier; + pEnv->pExtEnv->acquireInterface = s_acquireInterface; + pEnv->pExtEnv->releaseInterface = s_releaseInterface; + + pEnv->pReserved = this; +} + +Base::~Base() +{ + LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(fprintf(stderr, "LIFE: %s -> %p\n", "cppu::helper::purpenv::Base::~Base()", this)); + + m_pEnv->acquire = m_env_acquire; + m_pEnv->release = m_env_release; + m_pEnv->harden = m_env_harden; + m_pEnv->acquireWeak = m_env_acquireWeak; + m_pEnv->releaseWeak = m_env_releaseWeak; + + m_pEnv->pReserved = NULL; + + delete m_pEnterable; + m_pEnv->release(m_pEnv); +} + +void Base::acquire(void) +{ + m_env_acquire(m_pEnv); + + osl_incrementInterlockedCount(&m_nRef); +} + +void Base::release(void) +{ + if (osl_decrementInterlockedCount(&m_nRef) == 0) + delete this; + + else + m_env_release(m_pEnv); +} + +void Base::harden(uno_Environment ** ppHardEnv) +{ + m_env_harden(ppHardEnv, m_pEnv); + osl_incrementInterlockedCount(&m_nRef); +} + +void Base::acquireWeak(void) +{ + m_env_acquireWeak(m_pEnv); +} + +void Base::releaseWeak(void) +{ + m_env_releaseWeak(m_pEnv); +} + + +extern "C" { static void s_registerProxyInterface_v(va_list * pParam) +{ + uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); + void ** ppProxy = va_arg(*pParam, void **); + uno_freeProxyFunc freeProxy = va_arg(*pParam, uno_freeProxyFunc); + rtl_uString * pOId = va_arg(*pParam, rtl_uString *); + typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *); + ExtEnv_registerProxyInterface * pRegisterProxyInterface + = va_arg(*pParam, ExtEnv_registerProxyInterface *); + + pRegisterProxyInterface(pExtEnv, ppProxy, freeProxy, pOId, pTypeDescr); +}} + +void Base::registerProxyInterface(void ** ppProxy, + uno_freeProxyFunc freeProxy, + rtl::OUString const & oid, + typelib_InterfaceTypeDescription * pTypeDescr) +{ + uno_Environment_invoke(m_pEnv, + s_registerProxyInterface_v, + m_pEnv->pExtEnv, + ppProxy, + freeProxy, + oid.pData, + pTypeDescr, + m_env_registerProxyInterface); +} + + +extern "C" { static void s_revokeInterface_v(va_list * pParam) +{ + uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); + void * pInterface = va_arg(*pParam, void *); + ExtEnv_revokeInterface * pRevokeInterface = va_arg(*pParam, ExtEnv_revokeInterface *); + + pRevokeInterface(pExtEnv, pInterface); +}} + +void Base::revokeInterface(void * pInterface) +{ + uno_Environment_invoke(m_pEnv, + s_revokeInterface_v, + m_pEnv->pExtEnv, + pInterface, + m_env_revokeInterface); +} + + +extern "C" { static void s_getObjectIdentifier_v(va_list * pParam) +{ + uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); + void * pInterface = va_arg(*pParam, void *); + rtl::OUString * pOId = va_arg(*pParam, rtl::OUString *); + ExtEnv_getObjectIdentifier * pGetObjectIdentifier + = va_arg(*pParam, ExtEnv_getObjectIdentifier *); + + pGetObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface); +}} + +void Base::getObjectIdentifier(void * pInterface, rtl::OUString * pOid) +{ + uno_Environment_invoke(m_pEnv, + s_getObjectIdentifier_v, + m_pEnv->pExtEnv, + pInterface, + pOid, + m_env_getObjectIdentifier); +} + + +extern "C" { static void s_getRegisteredInterface_v(va_list * pParam) +{ + uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); + void ** ppInterface = va_arg(*pParam, void **); + rtl_uString * pOId = va_arg(*pParam, rtl_uString *); + typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *); + ExtEnv_getRegisteredInterface * pGetRegisteredInterface + = va_arg(*pParam, ExtEnv_getRegisteredInterface *); + + pGetRegisteredInterface(pExtEnv, ppInterface, pOId, pTypeDescr); +}} + +void Base::getRegisteredInterface(void ** ppInterface, + rtl::OUString const & oid, + typelib_InterfaceTypeDescription * pTypeDescr) +{ + uno_Environment_invoke(m_pEnv, + s_getRegisteredInterface_v, + m_pEnv->pExtEnv, + ppInterface, + oid.pData, + pTypeDescr, + m_env_getRegisteredInterface); +} + + +extern "C" { static void s_getRegisteredInterfaces_v(va_list * pParam) +{ + uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); + void *** pppInterface = va_arg(*pParam, void ***); + sal_Int32 * pnLen = va_arg(*pParam, sal_Int32 *); + uno_memAlloc memAlloc = va_arg(*pParam, uno_memAlloc); + ExtEnv_getRegisteredInterfaces * pGetRegisteredInterfaces + = va_arg(*pParam, ExtEnv_getRegisteredInterfaces *); + + pGetRegisteredInterfaces(pExtEnv, pppInterface, pnLen, memAlloc); +}} + +void Base::getRegisteredInterfaces(void *** pppInterface, + sal_Int32 * pnLen, + uno_memAlloc memAlloc) +{ + uno_Environment_invoke(m_pEnv, + s_getRegisteredInterfaces_v, + m_pEnv->pExtEnv, + pppInterface, + pnLen, + memAlloc, + m_env_getRegisteredInterfaces); +} + + +extern "C" { static void s_computeObjectIdentifier_v(va_list * pParam) +{ + uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); + void * pInterface = va_arg(*pParam, void *); + rtl::OUString * pOId = va_arg(*pParam, rtl::OUString *); + ExtEnv_computeObjectIdentifier * pComputeObjectIdentifier + = va_arg(*pParam, ExtEnv_computeObjectIdentifier *); + + pComputeObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface); +}} + +void Base::computeObjectIdentifier(void * pInterface, rtl::OUString * pOid) +{ + uno_Environment_invoke(m_pEnv, + s_computeObjectIdentifier_v, + m_pEnv->pExtEnv, + pInterface, + pOid, + m_env_computeObjectIdentifier); +} + + +extern "C" { static void s_acquireInterface_v(va_list * pParam) +{ + uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); + void * pInterface = va_arg(*pParam, void *); + ExtEnv_acquireInterface * pAcquireInterface + = va_arg(*pParam, ExtEnv_acquireInterface *); + + pAcquireInterface(pExtEnv, pInterface); +}} + +void Base::acquireInterface(void * pInterface) +{ + uno_Environment_invoke(m_pEnv, s_acquireInterface_v, m_pEnv->pExtEnv, pInterface, m_env_acquireInterface); +} + + +extern "C" { static void s_releaseInterface_v(va_list * pParam) +{ + uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); + void * pInterface = va_arg(*pParam, void *); + ExtEnv_releaseInterface * pReleaseInterface + = va_arg(*pParam, ExtEnv_releaseInterface *); + + pReleaseInterface(pExtEnv, pInterface); +}} + +void Base::releaseInterface(void * pInterface) +{ + uno_Environment_invoke(m_pEnv, + s_releaseInterface_v, + m_pEnv->pExtEnv, + pInterface, + m_env_releaseInterface); +} + +void Base::v_enter(void) +{ + m_pEnterable->enter(); +} + +void Base::v_leave(void) +{ + m_pEnterable->leave(); +} + +void Base::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam) +{ + m_pEnterable->callInto_v(pCallee, pParam); +} + +void Base::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam) +{ + m_pEnterable->callOut_v(pCallee, pParam); +} + +int Base::v_isValid(rtl::OUString * pReason) +{ + return m_pEnterable->isValid(pReason); +} + +namespace cppu { namespace helper { namespace purpenv { + +void Environment_initWithEnterable(uno_Environment * pEnvironment, cppu::Enterable * pEnterable) +{ + new Base(pEnvironment, pEnterable); +} + +}}} diff --git a/cppu/source/helper/purpenv/helper_purpenv_Mapping.cxx b/cppu/source/helper/purpenv/helper_purpenv_Mapping.cxx new file mode 100644 index 000000000000..0b4b3c9e0786 --- /dev/null +++ b/cppu/source/helper/purpenv/helper_purpenv_Mapping.cxx @@ -0,0 +1,233 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "cppu/helper/purpenv/Mapping.hxx" + +#include "Proxy.hxx" + +#include "osl/interlck.h" +#include "uno/environment.hxx" +#include "uno/dispatcher.h" +#include "typelib/typedescription.h" + + +#ifdef debug +# define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping +#endif + +#ifdef LOG_LIFECYCLE_cppu_helper_purpenv_Mapping +# include <iostream> +# define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x) x + +#else +# define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x) + +#endif + + +using namespace com::sun::star; + + +class Mapping : public uno_Mapping +{ + uno::Environment m_from; + uno::Environment m_to; + + oslInterlockedCount m_nCount; + + cppu::helper::purpenv::ProbeFun * m_probeFun; + void * m_pContext; + +public: + explicit Mapping(uno_Environment * pFrom, + uno_Environment * pTo, + cppu::helper::purpenv::ProbeFun * probeFun, + void * pProbeContext); + virtual ~Mapping(void); + + void mapInterface( + uno_Interface ** ppOut, + uno_Interface * pUnoI, + typelib_InterfaceTypeDescription * pTypeDescr); + + void acquire(void); + void release(void); +}; + +static void SAL_CALL s_mapInterface( + uno_Mapping * puno_Mapping, + uno_Interface ** ppOut, + uno_Interface * pUnoI, + typelib_InterfaceTypeDescription * pTypeDescr ) + SAL_THROW_EXTERN_C() +{ + Mapping * pMapping = static_cast<Mapping *>(puno_Mapping); + pMapping->mapInterface(ppOut, pUnoI, pTypeDescr); +} + +extern "C" { +static void SAL_CALL s_acquire(uno_Mapping * puno_Mapping) + SAL_THROW_EXTERN_C() +{ + Mapping * pMapping = static_cast<Mapping *>(puno_Mapping); + pMapping->acquire(); +} + +static void SAL_CALL s_release(uno_Mapping * puno_Mapping) + SAL_THROW_EXTERN_C() +{ + Mapping * pMapping = static_cast<Mapping * >(puno_Mapping); + pMapping->release(); +} + + +static void s_getIdentifier_v(va_list * pParam) +{ + uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *); + rtl_uString ** ppOid = va_arg(*pParam, rtl_uString **); + uno_Interface * pUnoI = va_arg(*pParam, uno_Interface *); + + pEnv->getObjectIdentifier(pEnv, ppOid, pUnoI); +} + +static void SAL_CALL s_free(uno_Mapping * puno_Mapping) + SAL_THROW_EXTERN_C() +{ + Mapping * pMapping = static_cast<Mapping *>(puno_Mapping); + delete pMapping; +} +} + +Mapping::Mapping(uno_Environment * pFrom, + uno_Environment * pTo, + cppu::helper::purpenv::ProbeFun * probeFun, + void * pProbeContext +) SAL_THROW( () ) + : m_from (pFrom), + m_to (pTo), + m_nCount (1), + m_probeFun(probeFun), + m_pContext(pProbeContext) +{ + LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::Mapping(uno_Environment * pFrom, uno_Environment * pTo) SAL_THROW( () )", this)); + + uno_Mapping::acquire = s_acquire; + uno_Mapping::release = s_release; + uno_Mapping::mapInterface = (uno_MapInterfaceFunc)s_mapInterface; +} + +Mapping::~Mapping(void) +{ + LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::~Mapping(void)", this)); +} + + +void Mapping::mapInterface( + uno_Interface ** ppOut, + uno_Interface * pUnoI, + typelib_InterfaceTypeDescription * pTypeDescr) +{ + OSL_ASSERT(ppOut && pTypeDescr); + if (*ppOut) + { + (*ppOut)->release(*ppOut); + *ppOut = 0; + } + + if (!pUnoI) + return; + + // get object id of uno interface to be wrapped + // need to enter environment because of potential "queryInterface" call + rtl_uString * pOId = 0; + uno_Environment_invoke(m_from.get(), s_getIdentifier_v, m_from.get(), &pOId, pUnoI); + OSL_ASSERT(pOId); + + // try to get any known interface from target environment + m_to.get()->pExtEnv->getRegisteredInterface(m_to.get()->pExtEnv, (void **)ppOut, pOId, pTypeDescr); + + if (!*ppOut) // not yet there, register new proxy interface + { + // try to publish a new proxy (ref count initially 1) + uno_Interface * pProxy = new Proxy(this, + m_from.get(), + m_to.get(), + pUnoI, + pTypeDescr, + pOId, + m_probeFun, + m_pContext); + + // proxy may be exchanged during registration + m_to.get()->pExtEnv->registerProxyInterface(m_to.get()->pExtEnv, + (void **)&pProxy, + Proxy_free, + pOId, + pTypeDescr); + + *ppOut = pProxy; + } + + rtl_uString_release(pOId); +} + + +void Mapping::acquire() SAL_THROW(()) +{ + if (osl_incrementInterlockedCount(&m_nCount) == 1) + { + uno_Mapping * pMapping = this; + + ::uno_registerMapping(&pMapping, s_free, m_from.get(), m_to.get(), NULL); + } +} + +void Mapping::release() SAL_THROW(()) +{ + if (osl_decrementInterlockedCount(&m_nCount) == 0) + ::uno_revokeMapping(this); +} + + +namespace cppu { namespace helper { namespace purpenv { + +void createMapping(uno_Mapping ** ppMapping, + uno_Environment * pFrom, + uno_Environment * pTo, + ProbeFun * probeFun, + void * pContext + ) +{ + *ppMapping = new Mapping(pFrom, pTo, probeFun, pContext); + + ::uno_registerMapping(ppMapping, s_free, pFrom, pTo, NULL); +} + +}}} diff --git a/cppu/source/helper/purpenv/helper_purpenv_Proxy.cxx b/cppu/source/helper/purpenv/helper_purpenv_Proxy.cxx new file mode 100644 index 000000000000..344203e38762 --- /dev/null +++ b/cppu/source/helper/purpenv/helper_purpenv_Proxy.cxx @@ -0,0 +1,530 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "Proxy.hxx" + +#include "sal/alloca.h" +#include "uno/dispatcher.h" +#include "typelib/typedescription.hxx" +#include "cppu/EnvDcp.hxx" + + +//#define LOG_LIFECYCLE_Proxy +#ifdef LOG_LIFECYCLE_Proxy +# include <iostream> +# define LOG_LIFECYCLE_Proxy_emit(x) x + +#else +# define LOG_LIFECYCLE_Proxy_emit(x) + +#endif + + +using namespace com::sun::star; + + +static bool relatesToInterface(typelib_TypeDescription * pTypeDescr) + SAL_THROW( () ) +{ + switch (pTypeDescr->eTypeClass) + { +// case typelib_TypeClass_TYPEDEF: + case typelib_TypeClass_SEQUENCE: + { + switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass) + { + case typelib_TypeClass_INTERFACE: + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + return true; + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType ); + bool bRel = relatesToInterface( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + return bRel; + } + default: + ; + } + return false; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + // ...optimized... to avoid getDescription() calls! + typelib_CompoundTypeDescription * pComp = (typelib_CompoundTypeDescription *)pTypeDescr; + typelib_TypeDescriptionReference ** pTypes = pComp->ppTypeRefs; + for ( sal_Int32 nPos = pComp->nMembers; nPos--; ) + { + switch (pTypes[nPos]->eTypeClass) + { + case typelib_TypeClass_INTERFACE: + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + return true; +// case typelib_TypeClass_TYPEDEF: + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, pTypes[nPos] ); + bool bRel = relatesToInterface( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + if (bRel) + return true; + } + default: + ; + } + } + if (pComp->pBaseTypeDescription) + return relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription ); + break; + } + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + case typelib_TypeClass_INTERFACE: + return true; + + default: + ; + } + return false; +} + +extern "C" { static void SAL_CALL s_Proxy_dispatch( + uno_Interface * pUnoI, + typelib_TypeDescription const * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException) + SAL_THROW_EXTERN_C() +{ + Proxy * pThis = static_cast<Proxy *>(pUnoI); + + typelib_MethodParameter param; + sal_Int32 nParams = 0; + typelib_MethodParameter * pParams = 0; + typelib_TypeDescriptionReference * pReturnTypeRef = 0; + // sal_Int32 nOutParams = 0; + + switch (pMemberType->eTypeClass) + { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + if (pReturn) + { + pReturnTypeRef = + ((typelib_InterfaceAttributeTypeDescription *) + pMemberType)->pAttributeTypeRef; + nParams = 0; + pParams = NULL; + } + else + { + param.pTypeRef = ((typelib_InterfaceAttributeTypeDescription *) + pMemberType)->pAttributeTypeRef; + param.bIn = sal_True; + param.bOut = sal_False; + nParams = 1; + pParams = ¶m; + } + break; + case typelib_TypeClass_INTERFACE_METHOD: + { + typelib_InterfaceMethodTypeDescription * method_td = + (typelib_InterfaceMethodTypeDescription *) pMemberType; + pReturnTypeRef = method_td->pReturnTypeRef; + nParams = method_td->nParams; + pParams = method_td->pParams; + break; + } + default: + OSL_ENSURE( sal_False, "### illegal member typeclass!" ); + abort(); + } + + pThis->dispatch( pReturnTypeRef, + pParams, + nParams, + pMemberType, + pReturn, + pArgs, + ppException ); +}} + +extern "C" void SAL_CALL Proxy_free(uno_ExtEnvironment * /*pEnv*/, void * pProxy) SAL_THROW_EXTERN_C() +{ + Proxy * pThis = static_cast<Proxy * >(reinterpret_cast<uno_Interface *>(pProxy)); + delete pThis; +} + +extern "C" { +static void SAL_CALL s_Proxy_acquire(uno_Interface * pUnoI) SAL_THROW_EXTERN_C() +{ + Proxy * pProxy = static_cast<Proxy *>(pUnoI); + pProxy->acquire(); +} + +static void SAL_CALL s_Proxy_release(uno_Interface * pUnoI) SAL_THROW_EXTERN_C() +{ + Proxy * pProxy = static_cast<Proxy *>(pUnoI); + pProxy->release(); +} + +static void s_acquireAndRegister_v(va_list * pParam) +{ + uno_Interface * pUnoI = va_arg(*pParam, uno_Interface *); + rtl_uString * pOid = va_arg(*pParam, rtl_uString *); + typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *); + uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *); + + pUnoI->acquire(pUnoI); + pEnv->registerInterface(pEnv, reinterpret_cast<void **>(&pUnoI), pOid, pTypeDescr); +} +} + +Proxy::Proxy(uno::Mapping const & to_from, + uno_Environment * pTo, + uno_Environment * pFrom, + uno_Interface * pUnoI, + typelib_InterfaceTypeDescription * pTypeDescr, + rtl::OUString const & rOId, + cppu::helper::purpenv::ProbeFun * probeFun, + void * pProbeContext +) + SAL_THROW(()) + : m_nRef (1), + m_from (pFrom), + m_to (pTo), + m_from_to (pFrom, pTo), + m_to_from (to_from), + m_pUnoI (pUnoI), + m_pTypeDescr (pTypeDescr), + m_aOId (rOId), + m_probeFun (probeFun), + m_pProbeContext(pProbeContext) +{ + LOG_LIFECYCLE_Proxy_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Proxy::Proxy(<>)", this)); + + typelib_typedescription_acquire((typelib_TypeDescription *)m_pTypeDescr); + if (!((typelib_TypeDescription *)m_pTypeDescr)->bComplete) + typelib_typedescription_complete((typelib_TypeDescription **)&m_pTypeDescr); + + OSL_ENSURE(((typelib_TypeDescription *)m_pTypeDescr)->bComplete, "### type is incomplete!"); + + uno_Environment_invoke(m_to.get(), s_acquireAndRegister_v, m_pUnoI, rOId.pData, pTypeDescr, m_to.get()); + + // uno_Interface + uno_Interface::acquire = s_Proxy_acquire; + uno_Interface::release = s_Proxy_release; + uno_Interface::pDispatcher = s_Proxy_dispatch; +} + +extern "C" { static void s_releaseAndRevoke_v(va_list * pParam) +{ + uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *); + uno_Interface * pUnoI = va_arg(*pParam, uno_Interface *); + + pEnv->revokeInterface(pEnv, reinterpret_cast<void *>(pUnoI)); + pUnoI->release(pUnoI); +}} + +Proxy::~Proxy() +{ + LOG_LIFECYCLE_Proxy_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Proxy::~Proxy()", this)); + + uno_Environment_invoke(m_to.get(), s_releaseAndRevoke_v, m_to.get(), m_pUnoI); + + typelib_typedescription_release((typelib_TypeDescription *)m_pTypeDescr); +} + +static uno::TypeDescription getAcquireMethod(void) +{ + typelib_TypeDescriptionReference * type_XInterface = + * typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE); + + typelib_TypeDescription * pTXInterfaceDescr = 0; + TYPELIB_DANGER_GET (&pTXInterfaceDescr, type_XInterface); + uno::TypeDescription acquire( + reinterpret_cast< typelib_InterfaceTypeDescription * >( + pTXInterfaceDescr)->ppAllMembers[1]); + TYPELIB_DANGER_RELEASE(pTXInterfaceDescr); + + return acquire; +} + +static uno::TypeDescription getReleaseMethod(void) +{ + typelib_TypeDescriptionReference * type_XInterface = + * typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE); + + typelib_TypeDescription * pTXInterfaceDescr = 0; + TYPELIB_DANGER_GET (&pTXInterfaceDescr, type_XInterface); + uno::TypeDescription release( + reinterpret_cast< typelib_InterfaceTypeDescription * >( + pTXInterfaceDescr)->ppAllMembers[2]); + TYPELIB_DANGER_RELEASE(pTXInterfaceDescr); + + return release; +} + +static uno::TypeDescription s_acquireMethod(getAcquireMethod()); +static uno::TypeDescription s_releaseMethod(getReleaseMethod()); + +void Proxy::acquire(void) +{ + if (m_probeFun) + m_probeFun(true, + this, + m_pProbeContext, + *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID), + NULL, + 0, + s_acquireMethod.get(), + NULL, + NULL, + NULL); + + if (osl_incrementInterlockedCount(&m_nRef) == 1) + { + // rebirth of proxy zombie + void * pThis = this; + m_from.get()->pExtEnv->registerProxyInterface(m_from.get()->pExtEnv, + &pThis, + Proxy_free, + m_aOId.pData, + m_pTypeDescr); + OSL_ASSERT(pThis == this); + } + + if (m_probeFun) + m_probeFun(false, + this, + m_pProbeContext, + *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID), + NULL, + 0, + s_acquireMethod.get(), + NULL, + NULL, + NULL); + +} + +void Proxy::release(void) +{ + cppu::helper::purpenv::ProbeFun * probeFun = m_probeFun; + void * pProbeContext = m_pProbeContext; + + if (m_probeFun) + m_probeFun(true, + this, + m_pProbeContext, + *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID), + NULL, + 0, + s_releaseMethod.get(), + NULL, + NULL, + NULL); + + if (osl_decrementInterlockedCount(&m_nRef) == 0) + m_from.get()->pExtEnv->revokeInterface(m_from.get()->pExtEnv, this); + + if (probeFun) + probeFun(false, + this, + pProbeContext, + *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID), + NULL, + 0, + s_releaseMethod.get(), + NULL, + NULL, + NULL); + +} + + +extern "C" { +static void s_type_destructData_v(va_list * pParam) +{ + void * ret = va_arg(*pParam, void *); + typelib_TypeDescriptionReference * pReturnTypeRef = va_arg(*pParam, typelib_TypeDescriptionReference *); + + uno_type_destructData(ret, pReturnTypeRef, 0); +} + +static void s_dispatcher_v(va_list * pParam) +{ + uno_Interface * pUnoI = va_arg(*pParam, uno_Interface *); + typelib_TypeDescription const * pMemberType = va_arg(*pParam, typelib_TypeDescription const *); + void * pReturn = va_arg(*pParam, void *); + void ** pArgs = va_arg(*pParam, void **); + uno_Any ** ppException = va_arg(*pParam, uno_Any **); + + pUnoI->pDispatcher(pUnoI, pMemberType, pReturn, pArgs, ppException); +} +} + +void Proxy::dispatch(typelib_TypeDescriptionReference * pReturnTypeRef, + typelib_MethodParameter * pParams, + sal_Int32 nParams, + typelib_TypeDescription const * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException) +{ + if (m_probeFun) + m_probeFun(true, + this, + m_pProbeContext, + pReturnTypeRef, + pParams, + nParams, + pMemberType, + pReturn, + pArgs, + ppException); + + void ** args = (void **) alloca( sizeof (void *) * nParams ); + + typelib_TypeDescription * return_td = 0; + void * ret = pReturn; + if (pReturnTypeRef) + { + TYPELIB_DANGER_GET(&return_td, pReturnTypeRef); + + if (relatesToInterface(return_td)) + ret = alloca(return_td->nSize); + + TYPELIB_DANGER_RELEASE(return_td); + } + + for (sal_Int32 nPos = 0; nPos < nParams; ++ nPos) + { + typelib_MethodParameter const & param = pParams[nPos]; + typelib_TypeDescription * td = 0; + TYPELIB_DANGER_GET( &td, param.pTypeRef ); + if (relatesToInterface(td)) + { + args[nPos] = alloca(td->nSize); + if (param.bIn) + { + uno_copyAndConvertData(args[nPos], pArgs[nPos], td, m_from_to.get()); + } + } + else + { + args[nPos] = pArgs[nPos]; + } + TYPELIB_DANGER_RELEASE( td ); + } + + uno_Any exc_data; + uno_Any * exc = &exc_data; + + // do the UNO call... + uno_Environment_invoke(m_to.get(), s_dispatcher_v, m_pUnoI, pMemberType, ret, args, &exc); + + if (exc == 0) + { + for (sal_Int32 nPos = 0; nPos < nParams; ++ nPos) + { + if (args[nPos] != pArgs[nPos]) + { + typelib_MethodParameter const & param = pParams[nPos]; + if (param.bOut) + { + if (param.bIn) // is inout + { + uno_type_destructData(pArgs[nPos], param.pTypeRef, 0); + } + uno_type_copyAndConvertData(pArgs[ nPos ], + args[ nPos ], + param.pTypeRef, + m_to_from.get()); + } + uno_Environment_invoke(m_to.get(), s_type_destructData_v, args[nPos], param.pTypeRef, 0); + } + } + if (ret != pReturn) + { + uno_type_copyAndConvertData(pReturn, + ret, + pReturnTypeRef, + m_to_from.get()); + + uno_Environment_invoke(m_to.get(), s_type_destructData_v, ret, pReturnTypeRef, 0); + } + + *ppException = 0; + } + else // exception occured + { + for (sal_Int32 nPos = 0; nPos < nParams; ++ nPos) + { + if (args[nPos] != pArgs[nPos]) + { + typelib_MethodParameter const & param = pParams[nPos]; + if (param.bIn) + { + uno_Environment_invoke(m_to.get(), s_type_destructData_v, args[nPos], param.pTypeRef, 0); + } + } + } + + uno_type_any_constructAndConvert(*ppException, + exc->pData, + exc->pType, + m_to_from.get()); + + // FIXME: need to destruct in m_to + uno_any_destruct(exc, 0); + } + + if (m_probeFun) + m_probeFun(false, + this, + m_pProbeContext, + pReturnTypeRef, + pParams, + nParams, + pMemberType, + pReturn, + pArgs, + ppException); +} + diff --git a/cppu/source/helper/purpenv/makefile.mk b/cppu/source/helper/purpenv/makefile.mk new file mode 100644 index 000000000000..0517a95579cc --- /dev/null +++ b/cppu/source/helper/purpenv/makefile.mk @@ -0,0 +1,46 @@ +#************************************************************************* +# +# 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 := cppu +TARGET := helper_purpenv + + +ENABLE_EXCEPTIONS := TRUE +NO_BSYMBOLIC := TRUE +USE_DEFFILE := TRUE + + +.INCLUDE : settings.mk + +SLOFILES := \ + $(SLO)$/helper_purpenv_Environment.obj \ + $(SLO)$/helper_purpenv_Mapping.obj \ + $(SLO)$/helper_purpenv_Proxy.obj + + +.INCLUDE : target.mk diff --git a/cppu/source/threadpool/current.cxx b/cppu/source/threadpool/current.cxx new file mode 100644 index 000000000000..23bd52ca1917 --- /dev/null +++ b/cppu/source/threadpool/current.cxx @@ -0,0 +1,297 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "rtl/uuid.h" +#include "osl/thread.h" +#include "osl/mutex.hxx" + +#include "uno/environment.hxx" +#include "uno/mapping.hxx" +#include "uno/lbnames.h" +#include "typelib/typedescription.h" + +#include "current.hxx" + + +using namespace ::osl; +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star::uno; + +namespace cppu +{ + +//-------------------------------------------------------------------------------------------------- +class SAL_NO_VTABLE XInterface +{ +public: + virtual void SAL_CALL slot_queryInterface() = 0; + virtual void SAL_CALL acquire() throw () = 0; + virtual void SAL_CALL release() throw () = 0; +}; +//-------------------------------------------------------------------------------------------------- +static typelib_InterfaceTypeDescription * get_type_XCurrentContext() +{ + static typelib_InterfaceTypeDescription * s_type_XCurrentContext = 0; + if (0 == s_type_XCurrentContext) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (0 == s_type_XCurrentContext) + { + OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XCurrentContext") ); + typelib_InterfaceTypeDescription * pTD = 0; + typelib_TypeDescriptionReference * pMembers[1] = { 0 }; + OUString sMethodName0( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XCurrentContext::getValueByName") ); + typelib_typedescriptionreference_new( + &pMembers[0], + typelib_TypeClass_INTERFACE_METHOD, + sMethodName0.pData ); + typelib_typedescription_newInterface( + &pTD, + sTypeName.pData, 0x00000000, 0x0000, 0x0000, 0x00000000, 0x00000000, + * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ), + 1, + pMembers ); + + typelib_typedescription_register( (typelib_TypeDescription**)&pTD ); + typelib_typedescriptionreference_release( pMembers[0] ); + + typelib_InterfaceMethodTypeDescription * pMethod = 0; + typelib_Parameter_Init aParameters[1]; + OUString sParamName0( RTL_CONSTASCII_USTRINGPARAM("Name") ); + OUString sParamType0( RTL_CONSTASCII_USTRINGPARAM("string") ); + aParameters[0].pParamName = sParamName0.pData; + aParameters[0].eTypeClass = typelib_TypeClass_STRING; + aParameters[0].pTypeName = sParamType0.pData; + aParameters[0].bIn = sal_True; + aParameters[0].bOut = sal_False; + rtl_uString * pExceptions[1]; + OUString sExceptionName0( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") ); + pExceptions[0] = sExceptionName0.pData; + OUString sReturnType0( RTL_CONSTASCII_USTRINGPARAM("any") ); + typelib_typedescription_newInterfaceMethod( + &pMethod, + 3, sal_False, + sMethodName0.pData, + typelib_TypeClass_ANY, sReturnType0.pData, + 1, aParameters, 1, pExceptions ); + typelib_typedescription_register( (typelib_TypeDescription**)&pMethod ); + typelib_typedescription_release( (typelib_TypeDescription*)pMethod ); + // another static ref: + ++reinterpret_cast< typelib_TypeDescription * >( pTD )-> + nStaticRefCount; + s_type_XCurrentContext = pTD; + } + } + return s_type_XCurrentContext; +} + +//################################################################################################## + +//================================================================================================== +class ThreadKey +{ + sal_Bool _bInit; + oslThreadKey _hThreadKey; + oslThreadKeyCallbackFunction _pCallback; + +public: + inline oslThreadKey getThreadKey() SAL_THROW( () ); + + inline ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW( () ); + inline ~ThreadKey() SAL_THROW( () ); +}; +//__________________________________________________________________________________________________ +inline ThreadKey::ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW( () ) + : _bInit( sal_False ) + , _pCallback( pCallback ) +{ +} +//__________________________________________________________________________________________________ +inline ThreadKey::~ThreadKey() SAL_THROW( () ) +{ + if (_bInit) + { + ::osl_destroyThreadKey( _hThreadKey ); + } +} +//__________________________________________________________________________________________________ +inline oslThreadKey ThreadKey::getThreadKey() SAL_THROW( () ) +{ + if (! _bInit) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! _bInit) + { + _hThreadKey = ::osl_createThreadKey( _pCallback ); + _bInit = sal_True; + } + } + return _hThreadKey; +} + +//================================================================================================== +extern "C" void SAL_CALL delete_IdContainer( void * p ) +{ + if (p) + { + IdContainer * pId = reinterpret_cast< IdContainer * >( p ); + if (pId->pCurrentContext) + { + (*pId->pCurrentContextEnv->releaseInterface)( + pId->pCurrentContextEnv, pId->pCurrentContext ); + (*((uno_Environment *)pId->pCurrentContextEnv)->release)( + (uno_Environment *)pId->pCurrentContextEnv ); + } + if (pId->bInit) + { + ::rtl_byte_sequence_release( pId->pLocalThreadId ); + ::rtl_byte_sequence_release( pId->pCurrentId ); + } + delete pId; + } +} +//================================================================================================== +IdContainer * getIdContainer() SAL_THROW( () ) +{ + static ThreadKey s_key( delete_IdContainer ); + oslThreadKey aKey = s_key.getThreadKey(); + + IdContainer * pId = reinterpret_cast< IdContainer * >( ::osl_getThreadKeyData( aKey ) ); + if (! pId) + { + pId = new IdContainer(); + pId->pCurrentContext = 0; + pId->pCurrentContextEnv = 0; + pId->bInit = sal_False; + ::osl_setThreadKeyData( aKey, pId ); + } + return pId; +} + +} + +//################################################################################################## +extern "C" sal_Bool SAL_CALL uno_setCurrentContext( + void * pCurrentContext, + rtl_uString * pEnvTypeName, void * pEnvContext ) + SAL_THROW_EXTERN_C() +{ + IdContainer * pId = getIdContainer(); + OSL_ASSERT( pId ); + + // free old one + if (pId->pCurrentContext) + { + (*pId->pCurrentContextEnv->releaseInterface)( + pId->pCurrentContextEnv, pId->pCurrentContext ); + (*((uno_Environment *)pId->pCurrentContextEnv)->release)( + (uno_Environment *)pId->pCurrentContextEnv ); + pId->pCurrentContextEnv = 0; + + pId->pCurrentContext = 0; + } + + if (pCurrentContext) + { + uno_Environment * pEnv = 0; + ::uno_getEnvironment( &pEnv, pEnvTypeName, pEnvContext ); + OSL_ASSERT( pEnv && pEnv->pExtEnv ); + if (pEnv) + { + if (pEnv->pExtEnv) + { + pId->pCurrentContextEnv = pEnv->pExtEnv; + (*pId->pCurrentContextEnv->acquireInterface)( + pId->pCurrentContextEnv, pCurrentContext ); + pId->pCurrentContext = pCurrentContext; + } + else + { + (*pEnv->release)( pEnv ); + return sal_False; + } + } + else + { + return sal_False; + } + } + return sal_True; +} +//################################################################################################## +extern "C" sal_Bool SAL_CALL uno_getCurrentContext( + void ** ppCurrentContext, rtl_uString * pEnvTypeName, void * pEnvContext ) + SAL_THROW_EXTERN_C() +{ + IdContainer * pId = getIdContainer(); + OSL_ASSERT( pId ); + + Environment target_env; + + // release inout parameter + if (*ppCurrentContext) + { + target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext); + OSL_ASSERT( target_env.is() ); + if (! target_env.is()) + return sal_False; + uno_ExtEnvironment * pEnv = target_env.get()->pExtEnv; + OSL_ASSERT( 0 != pEnv ); + if (0 == pEnv) + return sal_False; + (*pEnv->releaseInterface)( pEnv, *ppCurrentContext ); + + *ppCurrentContext = 0; + } + + // case: null-ref + if (0 == pId->pCurrentContext) + return sal_True; + + if (! target_env.is()) + { + target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext); + OSL_ASSERT( target_env.is() ); + if (! target_env.is()) + return sal_False; + } + + Mapping mapping((uno_Environment *) pId->pCurrentContextEnv, target_env.get()); + OSL_ASSERT( mapping.is() ); + if (! mapping.is()) + return sal_False; + + mapping.mapInterface(ppCurrentContext, pId->pCurrentContext, ::cppu::get_type_XCurrentContext() ); + + return sal_True; +} diff --git a/cppu/source/threadpool/current.hxx b/cppu/source/threadpool/current.hxx new file mode 100644 index 000000000000..fbe0531cf178 --- /dev/null +++ b/cppu/source/threadpool/current.hxx @@ -0,0 +1,48 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "rtl/byteseq.h" + +typedef struct _uno_ExtEnvironment uno_ExtEnvironment; + +namespace cppu +{ +struct CurrentContext; + +struct IdContainer +{ + void * pCurrentContext; + uno_ExtEnvironment * pCurrentContextEnv; + // + sal_Bool bInit; + sal_Sequence * pLocalThreadId; + sal_Int32 nRefCountOfCurrentId; + sal_Sequence * pCurrentId; +}; + +IdContainer * getIdContainer() SAL_THROW( () ); +} diff --git a/cppu/source/threadpool/jobqueue.cxx b/cppu/source/threadpool/jobqueue.cxx new file mode 100644 index 000000000000..333a350c0b23 --- /dev/null +++ b/cppu/source/threadpool/jobqueue.cxx @@ -0,0 +1,196 @@ +/************************************************************************* + * + * 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_cppu.hxx" +#include "jobqueue.hxx" +#include "threadpool.hxx" + +#include <osl/diagnose.h> + +using namespace ::osl; + +namespace cppu_threadpool { + + JobQueue::JobQueue() : + m_nToDo( 0 ), + m_bSuspended( sal_False ), + m_cndWait( osl_createCondition() ) + { + osl_resetCondition( m_cndWait ); + m_DisposedCallerAdmin = DisposedCallerAdmin::getInstance(); + } + + JobQueue::~JobQueue() + { + osl_destroyCondition( m_cndWait ); + } + + + void JobQueue::add( void *pThreadSpecificData, RequestFun * doRequest ) + { + MutexGuard guard( m_mutex ); + Job job = { pThreadSpecificData , doRequest }; + m_lstJob.push_back( job ); + if( ! m_bSuspended ) + { + osl_setCondition( m_cndWait ); + } + m_nToDo ++; + } + + void *JobQueue::enter( sal_Int64 nDisposeId , sal_Bool bReturnWhenNoJob ) + { + void *pReturn = 0; + { + // synchronize with the dispose calls + MutexGuard guard( m_mutex ); + if( m_DisposedCallerAdmin->isDisposed( nDisposeId ) ) + { + return 0; + } + m_lstCallstack.push_front( nDisposeId ); + } + + + while( sal_True ) + { + if( bReturnWhenNoJob ) + { + MutexGuard guard( m_mutex ); + if( m_lstJob.empty() ) + { + break; + } + } + + osl_waitCondition( m_cndWait , 0 ); + + struct Job job={0,0}; + { + // synchronize with add and dispose calls + MutexGuard guard( m_mutex ); + + if( 0 == m_lstCallstack.front() ) + { + // disposed ! + if( m_lstJob.empty() ) + { + osl_resetCondition( m_cndWait ); + } + break; + } + + OSL_ASSERT( ! m_lstJob.empty() ); + if( ! m_lstJob.empty() ) + { + job = m_lstJob.front(); + m_lstJob.pop_front(); + } + if( m_lstJob.empty() ) + { + osl_resetCondition( m_cndWait ); + } + } + + if( job.doRequest ) + { + job.doRequest( job.pThreadSpecificData ); + m_nToDo --; + } + else + { + m_nToDo --; + pReturn = job.pThreadSpecificData; + break; + } + } + + { + // synchronize with the dispose calls + MutexGuard guard( m_mutex ); + m_lstCallstack.pop_front(); + } + + return pReturn; + } + + void JobQueue::dispose( sal_Int64 nDisposeId ) + { + MutexGuard guard( m_mutex ); + for( CallStackList::iterator ii = m_lstCallstack.begin() ; + ii != m_lstCallstack.end() ; + ++ii ) + { + if( (*ii) == nDisposeId ) + { + (*ii) = 0; + } + } + + if( !m_lstCallstack.empty() && ! m_lstCallstack.front() ) + { + // The thread is waiting for a disposed pCallerId, let it go + osl_setCondition( m_cndWait ); + } + } + + void JobQueue::suspend() + { + MutexGuard guard( m_mutex ); + m_bSuspended = sal_True; + } + + void JobQueue::resume() + { + MutexGuard guard( m_mutex ); + m_bSuspended = sal_False; + if( ! m_lstJob.empty() ) + { + osl_setCondition( m_cndWait ); + } + } + + sal_Bool JobQueue::isEmpty() + { + MutexGuard guard( m_mutex ); + return m_lstJob.empty(); + } + + sal_Bool JobQueue::isCallstackEmpty() + { + MutexGuard guard( m_mutex ); + return m_lstCallstack.empty(); + } + + sal_Bool JobQueue::isBusy() + { + return m_nToDo > 0; + } + + +} diff --git a/cppu/source/threadpool/jobqueue.hxx b/cppu/source/threadpool/jobqueue.hxx new file mode 100644 index 000000000000..78202573403e --- /dev/null +++ b/cppu/source/threadpool/jobqueue.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * 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 _CPPU_THREADPOOL_JOBQUEUE_HXX_ +#define _CPPU_THREADPOOL_JOBQUEUE_HXX_ + +#include <list> +#include <sal/types.h> + +#include <osl/conditn.h> +#include <osl/mutex.hxx> + +#include <boost/shared_ptr.hpp> + +namespace cppu_threadpool +{ + extern "C" typedef void (SAL_CALL RequestFun)(void *); + + struct Job + { + void *pThreadSpecificData; + RequestFun * doRequest; + }; + + typedef ::std::list < struct Job > JobList; + + typedef ::std::list < sal_Int64 > CallStackList; + + class DisposedCallerAdmin; + typedef boost::shared_ptr<DisposedCallerAdmin> DisposedCallerAdminHolder; + + class JobQueue + { + public: + JobQueue(); + ~JobQueue(); + + void add( void *pThreadSpecificData, RequestFun * doRequest ); + + void *enter( sal_Int64 nDisposeId , sal_Bool bReturnWhenNoJob = sal_False ); + void dispose( sal_Int64 nDisposeId ); + + void suspend(); + void resume(); + + sal_Bool isEmpty(); + sal_Bool isCallstackEmpty(); + sal_Bool isBusy(); + + private: + ::osl::Mutex m_mutex; + JobList m_lstJob; + CallStackList m_lstCallstack; + sal_Int32 m_nToDo; + sal_Bool m_bSuspended; + oslCondition m_cndWait; + DisposedCallerAdminHolder m_DisposedCallerAdmin; + }; +} + +#endif diff --git a/cppu/source/threadpool/makefile.mk b/cppu/source/threadpool/makefile.mk new file mode 100644 index 000000000000..ea5e146b9cf6 --- /dev/null +++ b/cppu/source/threadpool/makefile.mk @@ -0,0 +1,49 @@ +#************************************************************************* +# +# 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=cppu +TARGET=cppu_threadpool + +# --- Settings ----------------------------------------------------- + +.INCLUDE : ..$/..$/util$/makefile.pmk +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES=\ + $(SLO)$/threadpool.obj\ + $(SLO)$/jobqueue.obj\ + $(SLO)$/thread.obj\ + $(SLO)$/threadident.obj\ + $(SLO)$/current.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : ..$/..$/util$/target.pmk +.INCLUDE : target.mk diff --git a/cppu/source/threadpool/thread.cxx b/cppu/source/threadpool/thread.cxx new file mode 100644 index 000000000000..00c91500d1e5 --- /dev/null +++ b/cppu/source/threadpool/thread.cxx @@ -0,0 +1,219 @@ +/************************************************************************* + * + * 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_cppu.hxx" +#include <stdio.h> +#include <osl/diagnose.h> +#include <uno/threadpool.h> + +#include <rtl/instance.hxx> + +#include "thread.hxx" +#include "jobqueue.hxx" +#include "threadpool.hxx" + + +using namespace osl; +extern "C" { + +void SAL_CALL cppu_requestThreadWorker( void *pVoid ) +{ + ::cppu_threadpool::ORequestThread *pThread = ( ::cppu_threadpool::ORequestThread * ) pVoid; + + pThread->run(); + pThread->onTerminated(); +} + +} + +namespace cppu_threadpool { + +// ---------------------------------------------------------------------------------- + ThreadAdmin::~ThreadAdmin() + { +#if OSL_DEBUG_LEVEL > 1 + if( m_lst.size() ) + { + fprintf( stderr, "%lu Threads left\n" , static_cast<unsigned long>(m_lst.size()) ); + } +#endif + } + + void ThreadAdmin::add( ORequestThread *p ) + { + MutexGuard aGuard( m_mutex ); + m_lst.push_back( p ); + } + + void ThreadAdmin::remove( ORequestThread * p ) + { + MutexGuard aGuard( m_mutex ); + ::std::list< ORequestThread * >::iterator ii = ::std::find( m_lst.begin(), m_lst.end(), p ); + OSL_ASSERT( ii != m_lst.end() ); + m_lst.erase( ii ); + } + + void ThreadAdmin::join() + { + ORequestThread *pCurrent; + do + { + pCurrent = 0; + { + MutexGuard aGuard( m_mutex ); + if( ! m_lst.empty() ) + { + pCurrent = m_lst.front(); + pCurrent->setDeleteSelf( sal_False ); + } + } + if ( pCurrent ) + { + pCurrent->join(); + delete pCurrent; + } + } while( pCurrent ); + } + + struct theThreadAdmin : public rtl::StaticWithInit< ThreadAdminHolder, theThreadAdmin > + { + ThreadAdminHolder operator () () { + ThreadAdminHolder aRet(new ThreadAdmin()); + return aRet; + } + }; + + ThreadAdminHolder& ThreadAdmin::getInstance() + { + return theThreadAdmin::get(); + } + +// ---------------------------------------------------------------------------------- + ORequestThread::ORequestThread( JobQueue *pQueue, + const ByteSequence &aThreadId, + sal_Bool bAsynchron ) + : m_thread( 0 ) + , m_aThreadAdmin( ThreadAdmin::getInstance() ) + , m_pQueue( pQueue ) + , m_aThreadId( aThreadId ) + , m_bAsynchron( bAsynchron ) + , m_bDeleteSelf( sal_True ) + { + m_aThreadAdmin->add( this ); + } + + + ORequestThread::~ORequestThread() + { + if (m_thread != 0) + { + osl_destroyThread(m_thread); + } + } + + + void ORequestThread::setTask( JobQueue *pQueue, + const ByteSequence &aThreadId, + sal_Bool bAsynchron ) + { + m_pQueue = pQueue; + m_aThreadId = aThreadId; + m_bAsynchron = bAsynchron; + } + + sal_Bool ORequestThread::create() + { + OSL_ASSERT(m_thread == 0); // only one running thread per instance + + m_thread = osl_createSuspendedThread( cppu_requestThreadWorker, (void*)this); + if ( m_thread ) + { + osl_resumeThread( m_thread ); + } + + return m_thread != 0; + } + + void ORequestThread::join() + { + osl_joinWithThread( m_thread ); + } + + void ORequestThread::onTerminated() + { + m_aThreadAdmin->remove( this ); + if( m_bDeleteSelf ) + { + delete this; + } + } + + void ORequestThread::run() + { + ThreadPoolHolder theThreadPool = cppu_threadpool::ThreadPool::getInstance(); + + while ( m_pQueue ) + { + if( ! m_bAsynchron ) + { + if ( !uno_bindIdToCurrentThread( m_aThreadId.getHandle() ) ) + { + OSL_ASSERT( false ); + } + } + + while( ! m_pQueue->isEmpty() ) + { + // Note : Oneways should not get a disposable disposeid, + // It does not make sense to dispose a call in this state. + // That's way we put it an disposeid, that can't be used otherwise. + m_pQueue->enter( + sal::static_int_cast< sal_Int64 >( + reinterpret_cast< sal_IntPtr >(this)), + sal_True ); + + if( m_pQueue->isEmpty() ) + { + theThreadPool->revokeQueue( m_aThreadId , m_bAsynchron ); + // Note : revokeQueue might have failed because m_pQueue.isEmpty() + // may be false (race). + } + } + + delete m_pQueue; + m_pQueue = 0; + + if( ! m_bAsynchron ) + { + uno_releaseIdFromCurrentThread(); + } + + theThreadPool->waitInPool( this ); + } + } +} diff --git a/cppu/source/threadpool/thread.hxx b/cppu/source/threadpool/thread.hxx new file mode 100644 index 000000000000..2f7791daf7e5 --- /dev/null +++ b/cppu/source/threadpool/thread.hxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * 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 _CPPU_THREADPOOL_THREAD_HXX +#define _CPPU_THREADPOOL_THREAD_HXX + +#include <list> +#include <sal/types.h> + +#include <osl/thread.h> + +#include "jobqueue.hxx" + +namespace cppu_threadpool { + + class JobQueue; + class ThreadAdmin; + typedef boost::shared_ptr<ThreadAdmin> ThreadAdminHolder; + + //----------------------------------------- + // private thread class for the threadpool + // independent from vos + //----------------------------------------- + class ORequestThread + { + public: + ORequestThread( JobQueue * , + const ::rtl::ByteSequence &aThreadId, + sal_Bool bAsynchron ); + ~ORequestThread(); + + void setTask( JobQueue * , const ::rtl::ByteSequence & aThreadId , sal_Bool bAsynchron ); + + sal_Bool create(); + void join(); + void onTerminated(); + void run(); + inline void setDeleteSelf( sal_Bool b ) + { m_bDeleteSelf = b; } + + private: + oslThread m_thread; + ThreadAdminHolder m_aThreadAdmin; + JobQueue *m_pQueue; + ::rtl::ByteSequence m_aThreadId; + sal_Bool m_bAsynchron; + sal_Bool m_bDeleteSelf; + }; + + class ThreadAdmin + { + public: + ~ThreadAdmin (); + static ThreadAdminHolder &getInstance(); + void add( ORequestThread * ); + void remove( ORequestThread * ); + void join(); + + private: + ::osl::Mutex m_mutex; + ::std::list< ORequestThread * > m_lst; + }; + +} // end cppu_threadpool + + +#endif + diff --git a/cppu/source/threadpool/threadident.cxx b/cppu/source/threadpool/threadident.cxx new file mode 100644 index 000000000000..0fb6c1196185 --- /dev/null +++ b/cppu/source/threadpool/threadident.cxx @@ -0,0 +1,135 @@ +/************************************************************************* + * + * 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_cppu.hxx" +#include <stdio.h> + +#include <list> + +#include <osl/mutex.hxx> +#include <osl/thread.h> +#include <osl/diagnose.h> + +#include <rtl/process.h> +#include <rtl/byteseq.hxx> + +#include <uno/threadpool.h> + +#include "current.hxx" + + +using namespace ::std; +using namespace ::osl; +using namespace ::rtl; +using namespace ::cppu; + + +static inline void createLocalId( sal_Sequence **ppThreadId ) +{ + rtl_byte_sequence_constructNoDefault( ppThreadId , 4 + 16 ); + *((sal_Int32*) ((*ppThreadId)->elements)) = osl_getThreadIdentifier(0); + + rtl_getGlobalProcessId( (sal_uInt8 * ) &( (*ppThreadId)->elements[4]) ); +} + + +extern "C" void SAL_CALL +uno_getIdOfCurrentThread( sal_Sequence **ppThreadId ) + SAL_THROW_EXTERN_C() +{ + IdContainer * p = getIdContainer(); + if( ! p->bInit ) + { + // first time, that the thread enters the bridge + createLocalId( ppThreadId ); + + // TODO + // note : this is a leak ! + p->pLocalThreadId = *ppThreadId; + p->pCurrentId = *ppThreadId; + p->nRefCountOfCurrentId = 1; + rtl_byte_sequence_acquire( p->pLocalThreadId ); + rtl_byte_sequence_acquire( p->pCurrentId ); + p->bInit = sal_True; + } + else + { + p->nRefCountOfCurrentId ++; + if( *ppThreadId ) + { + rtl_byte_sequence_release( *ppThreadId ); + } + *ppThreadId = p->pCurrentId; + rtl_byte_sequence_acquire( *ppThreadId ); + } +} + + +extern "C" void SAL_CALL uno_releaseIdFromCurrentThread() + SAL_THROW_EXTERN_C() +{ + IdContainer *p = getIdContainer(); + OSL_ASSERT( p ); + OSL_ASSERT( p->nRefCountOfCurrentId ); + + p->nRefCountOfCurrentId --; + if( ! p->nRefCountOfCurrentId && (p->pLocalThreadId != p->pCurrentId) ) + { + rtl_byte_sequence_assign( &(p->pCurrentId) , p->pLocalThreadId ); + } +} + +extern "C" sal_Bool SAL_CALL uno_bindIdToCurrentThread( sal_Sequence *pThreadId ) + SAL_THROW_EXTERN_C() +{ + IdContainer *p = getIdContainer(); + if( ! p->bInit ) + { + p->pLocalThreadId = 0; + createLocalId( &(p->pLocalThreadId) ); + p->nRefCountOfCurrentId = 1; + p->pCurrentId = pThreadId; + rtl_byte_sequence_acquire( p->pCurrentId ); + p->bInit = sal_True; + } + else + { + OSL_ASSERT( 0 == p->nRefCountOfCurrentId ); + if( 0 == p->nRefCountOfCurrentId ) + { + rtl_byte_sequence_assign(&( p->pCurrentId ), pThreadId ); + p->nRefCountOfCurrentId ++; + } + else + { + return sal_False; + } + + } + return sal_True; +} diff --git a/cppu/source/threadpool/threadpool.cxx b/cppu/source/threadpool/threadpool.cxx new file mode 100644 index 000000000000..b7df159a80b9 --- /dev/null +++ b/cppu/source/threadpool/threadpool.cxx @@ -0,0 +1,506 @@ +/************************************************************************* + * + * 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_cppu.hxx" +#include <hash_set> +#include <stdio.h> + +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#include <osl/thread.h> +#include <rtl/instance.hxx> + +#include <uno/threadpool.h> + +#include "threadpool.hxx" +#include "thread.hxx" + +using namespace ::std; +using namespace ::osl; + +namespace cppu_threadpool +{ + struct theDisposedCallerAdmin : + public rtl::StaticWithInit< DisposedCallerAdminHolder, theDisposedCallerAdmin > + { + DisposedCallerAdminHolder operator () () { + return DisposedCallerAdminHolder(new DisposedCallerAdmin()); + } + }; + + DisposedCallerAdminHolder DisposedCallerAdmin::getInstance() + { + return theDisposedCallerAdmin::get(); + } + + DisposedCallerAdmin::~DisposedCallerAdmin() + { +#if OSL_DEBUG_LEVEL > 1 + if( !m_lst.empty() ) + { + printf( "DisposedCallerList : %lu left\n" , static_cast<unsigned long>(m_lst.size( ))); + } +#endif + } + + void DisposedCallerAdmin::dispose( sal_Int64 nDisposeId ) + { + MutexGuard guard( m_mutex ); + m_lst.push_back( nDisposeId ); + } + + void DisposedCallerAdmin::stopDisposing( sal_Int64 nDisposeId ) + { + MutexGuard guard( m_mutex ); + for( DisposedCallerList::iterator ii = m_lst.begin() ; + ii != m_lst.end() ; + ++ ii ) + { + if( (*ii) == nDisposeId ) + { + m_lst.erase( ii ); + break; + } + } + } + + sal_Bool DisposedCallerAdmin::isDisposed( sal_Int64 nDisposeId ) + { + MutexGuard guard( m_mutex ); + for( DisposedCallerList::iterator ii = m_lst.begin() ; + ii != m_lst.end() ; + ++ ii ) + { + if( (*ii) == nDisposeId ) + { + return sal_True; + } + } + return sal_False; + } + + + //------------------------------------------------------------------------------- + + struct theThreadPool : + public rtl::StaticWithInit< ThreadPoolHolder, theThreadPool > + { + ThreadPoolHolder operator () () { + ThreadPoolHolder aRet(new ThreadPool()); + return aRet; + } + }; + + ThreadPool::ThreadPool() + { + m_DisposedCallerAdmin = DisposedCallerAdmin::getInstance(); + } + + ThreadPool::~ThreadPool() + { +#if OSL_DEBUG_LEVEL > 1 + if( m_mapQueue.size() ) + { + printf( "ThreadIdHashMap : %lu left\n" , static_cast<unsigned long>(m_mapQueue.size()) ); + } +#endif + } + ThreadPoolHolder ThreadPool::getInstance() + { + return theThreadPool::get(); + } + + + void ThreadPool::dispose( sal_Int64 nDisposeId ) + { + if( nDisposeId ) + { + m_DisposedCallerAdmin->dispose( nDisposeId ); + + MutexGuard guard( m_mutex ); + for( ThreadIdHashMap::iterator ii = m_mapQueue.begin() ; + ii != m_mapQueue.end(); + ++ii) + { + if( (*ii).second.first ) + { + (*ii).second.first->dispose( nDisposeId ); + } + if( (*ii).second.second ) + { + (*ii).second.second->dispose( nDisposeId ); + } + } + } + else + { + { + MutexGuard guard( m_mutexWaitingThreadList ); + for( WaitingThreadList::iterator ii = m_lstThreads.begin() ; + ii != m_lstThreads.end() ; + ++ ii ) + { + // wake the threads up + osl_setCondition( (*ii)->condition ); + } + } + ThreadAdmin::getInstance()->join(); + } + } + + void ThreadPool::stopDisposing( sal_Int64 nDisposeId ) + { + m_DisposedCallerAdmin->stopDisposing( nDisposeId ); + } + + /****************** + * This methods lets the thread wait a certain amount of time. If within this timespan + * a new request comes in, this thread is reused. This is done only to improve performance, + * it is not required for threadpool functionality. + ******************/ + void ThreadPool::waitInPool( ORequestThread * pThread ) + { + struct WaitingThread waitingThread; + waitingThread.condition = osl_createCondition(); + waitingThread.thread = pThread; + { + MutexGuard guard( m_mutexWaitingThreadList ); + m_lstThreads.push_front( &waitingThread ); + } + + // let the thread wait 2 seconds + TimeValue time = { 2 , 0 }; + osl_waitCondition( waitingThread.condition , &time ); + + { + MutexGuard guard ( m_mutexWaitingThreadList ); + if( waitingThread.thread ) + { + // thread wasn't reused, remove it from the list + WaitingThreadList::iterator ii = find( + m_lstThreads.begin(), m_lstThreads.end(), &waitingThread ); + OSL_ASSERT( ii != m_lstThreads.end() ); + m_lstThreads.erase( ii ); + } + } + + osl_destroyCondition( waitingThread.condition ); + } + + void ThreadPool::createThread( JobQueue *pQueue , + const ByteSequence &aThreadId, + sal_Bool bAsynchron ) + { + sal_Bool bCreate = sal_True; + { + // Can a thread be reused ? + MutexGuard guard( m_mutexWaitingThreadList ); + if( ! m_lstThreads.empty() ) + { + // inform the thread and let it go + struct WaitingThread *pWaitingThread = m_lstThreads.back(); + pWaitingThread->thread->setTask( pQueue , aThreadId , bAsynchron ); + pWaitingThread->thread = 0; + + // remove from list + m_lstThreads.pop_back(); + + // let the thread go + osl_setCondition( pWaitingThread->condition ); + bCreate = sal_False; + } + } + + if( bCreate ) + { + ORequestThread *pThread = + new ORequestThread( pQueue , aThreadId, bAsynchron); + // deletes itself ! + pThread->create(); + } + } + + sal_Bool ThreadPool::revokeQueue( const ByteSequence &aThreadId, sal_Bool bAsynchron ) + { + MutexGuard guard( m_mutex ); + + ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId ); + OSL_ASSERT( ii != m_mapQueue.end() ); + + if( bAsynchron ) + { + if( ! (*ii).second.second->isEmpty() ) + { + // another thread has put something into the queue + return sal_False; + } + + (*ii).second.second = 0; + if( (*ii).second.first ) + { + // all oneway request have been processed, now + // synchronus requests may go on + (*ii).second.first->resume(); + } + } + else + { + if( ! (*ii).second.first->isEmpty() ) + { + // another thread has put something into the queue + return sal_False; + } + (*ii).second.first = 0; + } + + if( 0 == (*ii).second.first && 0 == (*ii).second.second ) + { + m_mapQueue.erase( ii ); + } + + return sal_True; + } + + + void ThreadPool::addJob( + const ByteSequence &aThreadId , + sal_Bool bAsynchron, + void *pThreadSpecificData, + RequestFun * doRequest ) + { + sal_Bool bCreateThread = sal_False; + JobQueue *pQueue = 0; + { + MutexGuard guard( m_mutex ); + + ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId ); + + if( ii == m_mapQueue.end() ) + { + m_mapQueue[ aThreadId ] = pair < JobQueue * , JobQueue * > ( 0 , 0 ); + ii = m_mapQueue.find( aThreadId ); + OSL_ASSERT( ii != m_mapQueue.end() ); + } + + if( bAsynchron ) + { + if( ! (*ii).second.second ) + { + (*ii).second.second = new JobQueue(); + bCreateThread = sal_True; + } + pQueue = (*ii).second.second; + } + else + { + if( ! (*ii).second.first ) + { + (*ii).second.first = new JobQueue(); + bCreateThread = sal_True; + } + pQueue = (*ii).second.first; + + if( (*ii).second.second && ( (*ii).second.second->isBusy() ) ) + { + pQueue->suspend(); + } + } + pQueue->add( pThreadSpecificData , doRequest ); + } + + if( bCreateThread ) + { + createThread( pQueue , aThreadId , bAsynchron); + } + } + + void ThreadPool::prepare( const ByteSequence &aThreadId ) + { + MutexGuard guard( m_mutex ); + + ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId ); + + if( ii == m_mapQueue.end() ) + { + JobQueue *p = new JobQueue(); + m_mapQueue[ aThreadId ] = pair< JobQueue * , JobQueue * > ( p , 0 ); + } + else if( 0 == (*ii).second.first ) + { + (*ii).second.first = new JobQueue(); + } + } + + void * ThreadPool::enter( const ByteSequence & aThreadId , sal_Int64 nDisposeId ) + { + JobQueue *pQueue = 0; + { + MutexGuard guard( m_mutex ); + + ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId ); + + OSL_ASSERT( ii != m_mapQueue.end() ); + pQueue = (*ii).second.first; + } + + OSL_ASSERT( pQueue ); + void *pReturn = pQueue->enter( nDisposeId ); + + if( pQueue->isCallstackEmpty() ) + { + if( revokeQueue( aThreadId , sal_False) ) + { + // remove queue + delete pQueue; + } + } + return pReturn; + } +} + + +using namespace cppu_threadpool; + +struct uno_ThreadPool_Equal +{ + sal_Bool operator () ( const uno_ThreadPool &a , const uno_ThreadPool &b ) const + { + return a == b; + } +}; + +struct uno_ThreadPool_Hash +{ + sal_Size operator () ( const uno_ThreadPool &a ) const + { + return (sal_Size) a; + } +}; + + + +typedef ::std::hash_map< uno_ThreadPool, ThreadPoolHolder, uno_ThreadPool_Hash, uno_ThreadPool_Equal > ThreadpoolHashSet; + +static ThreadpoolHashSet *g_pThreadpoolHashSet; + +struct _uno_ThreadPool +{ + sal_Int32 dummy; +}; + +extern "C" uno_ThreadPool SAL_CALL +uno_threadpool_create() SAL_THROW_EXTERN_C() +{ + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! g_pThreadpoolHashSet ) + { + g_pThreadpoolHashSet = new ThreadpoolHashSet(); + } + + // Just ensure that the handle is unique in the process (via heap) + uno_ThreadPool h = new struct _uno_ThreadPool; + g_pThreadpoolHashSet->insert( ThreadpoolHashSet::value_type(h, ThreadPool::getInstance()) ); + return h; +} + +extern "C" void SAL_CALL +uno_threadpool_attach( uno_ThreadPool ) SAL_THROW_EXTERN_C() +{ + sal_Sequence *pThreadId = 0; + uno_getIdOfCurrentThread( &pThreadId ); + ThreadPool::getInstance()->prepare( pThreadId ); + rtl_byte_sequence_release( pThreadId ); + uno_releaseIdFromCurrentThread(); +} + +extern "C" void SAL_CALL +uno_threadpool_enter( uno_ThreadPool hPool , void **ppJob ) + SAL_THROW_EXTERN_C() +{ + sal_Sequence *pThreadId = 0; + uno_getIdOfCurrentThread( &pThreadId ); + *ppJob = + ThreadPool::getInstance()->enter( + pThreadId, + sal::static_int_cast< sal_Int64 >( + reinterpret_cast< sal_IntPtr >(hPool)) ); + rtl_byte_sequence_release( pThreadId ); + uno_releaseIdFromCurrentThread(); +} + +extern "C" void SAL_CALL +uno_threadpool_detach( uno_ThreadPool ) SAL_THROW_EXTERN_C() +{ + // we might do here some tiding up in case a thread called attach but never detach +} + +extern "C" void SAL_CALL +uno_threadpool_putJob( + uno_ThreadPool, + sal_Sequence *pThreadId, + void *pJob, + void ( SAL_CALL * doRequest ) ( void *pThreadSpecificData ), + sal_Bool bIsOneway ) SAL_THROW_EXTERN_C() +{ + ThreadPool::getInstance()->addJob( pThreadId, bIsOneway, pJob ,doRequest ); +} + +extern "C" void SAL_CALL +uno_threadpool_dispose( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C() +{ + ThreadPool::getInstance()->dispose( + sal::static_int_cast< sal_Int64 >( + reinterpret_cast< sal_IntPtr >(hPool)) ); +} + +extern "C" void SAL_CALL +uno_threadpool_destroy( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C() +{ + ThreadPool::getInstance()->stopDisposing( + sal::static_int_cast< sal_Int64 >( + reinterpret_cast< sal_IntPtr >(hPool)) ); + + if( hPool ) + { + // special treatment for 0 ! + OSL_ASSERT( g_pThreadpoolHashSet ); + + MutexGuard guard( Mutex::getGlobalMutex() ); + + ThreadpoolHashSet::iterator ii = g_pThreadpoolHashSet->find( hPool ); + OSL_ASSERT( ii != g_pThreadpoolHashSet->end() ); + g_pThreadpoolHashSet->erase( ii ); + delete hPool; + + if( g_pThreadpoolHashSet->empty() ) + { + delete g_pThreadpoolHashSet; + g_pThreadpoolHashSet = 0; + } + } +} diff --git a/cppu/source/threadpool/threadpool.hxx b/cppu/source/threadpool/threadpool.hxx new file mode 100644 index 000000000000..e1c9a127fa55 --- /dev/null +++ b/cppu/source/threadpool/threadpool.hxx @@ -0,0 +1,140 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#include <hash_map> + +#include <osl/conditn.h> + +#include <rtl/byteseq.hxx> + +#include <boost/shared_ptr.hpp> + +#include "jobqueue.hxx" + + +using namespace ::rtl; +namespace cppu_threadpool { + class ORequestThread; + + struct EqualThreadId + { + sal_Int32 operator () ( const ::rtl::ByteSequence &a , const ::rtl::ByteSequence &b ) const + { + return a == b; + } + }; + + struct HashThreadId + { + sal_Int32 operator () ( const ::rtl::ByteSequence &a ) const + { + if( a.getLength() >= 4 ) + { + return *(sal_Int32 *)a.getConstArray(); + } + return 0; + } + }; + + typedef ::std::hash_map + < + ByteSequence, // ThreadID + ::std::pair < JobQueue * , JobQueue * >, + HashThreadId, + EqualThreadId + > ThreadIdHashMap; + + typedef ::std::list < sal_Int64 > DisposedCallerList; + + + struct WaitingThread + { + oslCondition condition; + ORequestThread *thread; + }; + + typedef ::std::list < struct ::cppu_threadpool::WaitingThread * > WaitingThreadList; + + class DisposedCallerAdmin; + typedef boost::shared_ptr<DisposedCallerAdmin> DisposedCallerAdminHolder; + + class DisposedCallerAdmin + { + public: + ~DisposedCallerAdmin(); + + static DisposedCallerAdminHolder getInstance(); + + void dispose( sal_Int64 nDisposeId ); + void stopDisposing( sal_Int64 nDisposeId ); + sal_Bool isDisposed( sal_Int64 nDisposeId ); + + private: + ::osl::Mutex m_mutex; + DisposedCallerList m_lst; + }; + + class ThreadPool; + typedef boost::shared_ptr<ThreadPool> ThreadPoolHolder; + + class ThreadPool + { + public: + ThreadPool(); + ~ThreadPool(); + static ThreadPoolHolder getInstance(); + + void dispose( sal_Int64 nDisposeId ); + void stopDisposing( sal_Int64 nDisposeId ); + + void addJob( const ByteSequence &aThreadId, + sal_Bool bAsynchron, + void *pThreadSpecificData, + RequestFun * doRequest ); + + void prepare( const ByteSequence &aThreadId ); + void * enter( const ByteSequence &aThreadId, sal_Int64 nDisposeId ); + + /******** + * @return true, if queue could be succesfully revoked. + ********/ + sal_Bool revokeQueue( const ByteSequence & aThreadId , sal_Bool bAsynchron ); + + void waitInPool( ORequestThread *pThread ); + private: + void createThread( JobQueue *pQueue, const ByteSequence &aThreadId, sal_Bool bAsynchron); + + + ThreadIdHashMap m_mapQueue; + ::osl::Mutex m_mutex; + + ::osl::Mutex m_mutexWaitingThreadList; + WaitingThreadList m_lstThreads; + + DisposedCallerAdminHolder m_DisposedCallerAdmin; + }; + +} // end namespace cppu_threadpool diff --git a/cppu/source/typelib/makefile.mk b/cppu/source/typelib/makefile.mk new file mode 100644 index 000000000000..5a09459fed54 --- /dev/null +++ b/cppu/source/typelib/makefile.mk @@ -0,0 +1,45 @@ +#************************************************************************* +# +# 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=cppu +TARGET=cppu_typelib + +# --- Settings ----------------------------------------------------- + +.INCLUDE : ..$/..$/util$/makefile.pmk +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/typelib.obj \ + $(SLO)$/static_types.obj + +.INCLUDE : ..$/..$/util$/target.pmk +.INCLUDE : target.mk + diff --git a/cppu/source/typelib/static_types.cxx b/cppu/source/typelib/static_types.cxx new file mode 100644 index 000000000000..605bc5aadbdc --- /dev/null +++ b/cppu/source/typelib/static_types.cxx @@ -0,0 +1,649 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include <stdarg.h> +#include <algorithm> + +#include <osl/mutex.hxx> +#include <osl/interlck.h> +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/memory.h> +#include <rtl/instance.hxx> + +#include <typelib/typedescription.h> + + +using namespace osl; +using namespace rtl; + +extern "C" +{ + +//------------------------------------------------------------------------ +sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize( + const typelib_TypeDescription * pTypeDescription, + sal_Int32 nOffset, + sal_Int32 & rMaxIntegralTypeSize ) + SAL_THROW_EXTERN_C(); +//------------------------------------------------------------------------ +void SAL_CALL typelib_typedescription_newEmpty( + typelib_TypeDescription ** ppRet, + typelib_TypeClass eTypeClass, + rtl_uString * pTypeName ) + SAL_THROW_EXTERN_C(); +//----------------------------------------------------------------------------- +void SAL_CALL typelib_typedescriptionreference_getByName( + typelib_TypeDescriptionReference ** ppRet, + rtl_uString * pName ) + SAL_THROW_EXTERN_C(); + +#ifdef SAL_W32 +#pragma pack(push, 8) +#elif defined(SAL_OS2) +#pragma pack(8) +#endif + +/** + * The double member determin the alignment. + * Under Os2 and MS-Windows the Alignment is min( 8, sizeof( type ) ). + * The aligment of a strukture is min( 8, sizeof( max basic type ) ), the greatest basic type + * determine the aligment. + */ +struct AlignSize_Impl +{ + sal_Int16 nInt16; + double dDouble; +}; + +#ifdef SAL_W32 +#pragma pack(pop) +#elif defined(SAL_OS2) +#pragma pack() +#endif + +// the value of the maximal alignment +static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16); + +static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment ) + SAL_THROW( () ) +{ + if( nRequestedAlignment > nMaxAlignment ) + nRequestedAlignment = nMaxAlignment; + return nRequestedAlignment; +} + +/** + * Calculate the new size of the struktur. + */ +static inline sal_Int32 newAlignedSize( + sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment ) + SAL_THROW( () ) +{ + NeededAlignment = adjustAlignment( NeededAlignment ); + return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize; +} + +//-------------------------------------------------------------------------------------------------- + +namespace +{ + struct typelib_StaticInitMutex : public rtl::Static< Mutex, typelib_StaticInitMutex > {}; +} + +// !for NOT REALLY WEAK TYPES only! +static inline typelib_TypeDescriptionReference * igetTypeByName( rtl_uString * pTypeName ) + SAL_THROW( () ) +{ + typelib_TypeDescriptionReference * pRef = 0; + ::typelib_typedescriptionreference_getByName( &pRef, pTypeName ); + if (pRef && pRef->pType && pRef->pType->pWeakRef) // found initialized td + { + return pRef; + } + else + { + return 0; + } +} + +extern "C" +{ +//################################################################################################## +typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass( + typelib_TypeClass eTypeClass ) + SAL_THROW_EXTERN_C() +{ + static typelib_TypeDescriptionReference * s_aTypes[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 }; + + if (! s_aTypes[eTypeClass]) + { + MutexGuard aGuard( typelib_StaticInitMutex::get() ); + if (! s_aTypes[eTypeClass]) + { + static const char * s_aTypeNames[] = { + "void", "char", "boolean", "byte", + "short", "unsigned short", "long", "unsigned long", + "hyper", "unsigned hyper", "float", "double", + "string", "type", "any" }; + + switch (eTypeClass) + { + case typelib_TypeClass_EXCEPTION: + case typelib_TypeClass_INTERFACE: + { + // type + if (! s_aTypes[typelib_TypeClass_TYPE]) + { + OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("type") ); + ::typelib_typedescriptionreference_new( + &s_aTypes[typelib_TypeClass_TYPE], typelib_TypeClass_TYPE, sTypeName.pData ); + // another static ref: + ++s_aTypes[typelib_TypeClass_TYPE]->nStaticRefCount; + } + // any + if (! s_aTypes[typelib_TypeClass_ANY]) + { + OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("any") ); + ::typelib_typedescriptionreference_new( + &s_aTypes[typelib_TypeClass_ANY], typelib_TypeClass_ANY, sTypeName.pData ); + // another static ref: + ++s_aTypes[typelib_TypeClass_ANY]->nStaticRefCount; + } + // string + if (! s_aTypes[typelib_TypeClass_STRING]) + { + OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("string") ); + ::typelib_typedescriptionreference_new( + &s_aTypes[typelib_TypeClass_STRING], typelib_TypeClass_STRING, sTypeName.pData ); + // another static ref: + ++s_aTypes[typelib_TypeClass_STRING]->nStaticRefCount; + } + // XInterface + if (! s_aTypes[typelib_TypeClass_INTERFACE]) + { + OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface") ); + + typelib_InterfaceTypeDescription * pTD = 0; + + typelib_TypeDescriptionReference * pMembers[3] = { 0,0,0 }; + OUString sMethodName0( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::queryInterface") ); + ::typelib_typedescriptionreference_new( + &pMembers[0], typelib_TypeClass_INTERFACE_METHOD, sMethodName0.pData ); + OUString sMethodName1( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::acquire") ); + ::typelib_typedescriptionreference_new( + &pMembers[1], typelib_TypeClass_INTERFACE_METHOD, sMethodName1.pData ); + OUString sMethodName2( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::release") ); + ::typelib_typedescriptionreference_new( + &pMembers[2], typelib_TypeClass_INTERFACE_METHOD, sMethodName2.pData ); + + ::typelib_typedescription_newInterface( + &pTD, sTypeName.pData, 0xe227a391, 0x33d6, 0x11d1, 0xaabe00a0, 0x249d5590, + 0, 3, pMembers ); + + ::typelib_typedescription_register( (typelib_TypeDescription **)&pTD ); + ::typelib_typedescriptionreference_acquire( + s_aTypes[typelib_TypeClass_INTERFACE] = ((typelib_TypeDescription *)pTD)->pWeakRef ); + // another static ref: + ++s_aTypes[typelib_TypeClass_INTERFACE]->nStaticRefCount; + ::typelib_typedescription_release( (typelib_TypeDescription*)pTD ); + + ::typelib_typedescriptionreference_release( pMembers[0] ); + ::typelib_typedescriptionreference_release( pMembers[1] ); + ::typelib_typedescriptionreference_release( pMembers[2] ); + // Exception + OSL_ASSERT( ! s_aTypes[typelib_TypeClass_EXCEPTION] ); + { + typelib_TypeDescription * pTD1 = 0; + OUString sTypeName1( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception") ); + + typelib_CompoundMember_Init aMembers[2]; + OUString sMemberType0( RTL_CONSTASCII_USTRINGPARAM("string") ); + OUString sMemberName0( RTL_CONSTASCII_USTRINGPARAM("Message") ); + aMembers[0].eTypeClass = typelib_TypeClass_STRING; + aMembers[0].pTypeName = sMemberType0.pData; + aMembers[0].pMemberName = sMemberName0.pData; + OUString sMemberType1( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface") ); + OUString sMemberName1( RTL_CONSTASCII_USTRINGPARAM("Context") ); + aMembers[1].eTypeClass = typelib_TypeClass_INTERFACE; + aMembers[1].pTypeName = sMemberType1.pData; + aMembers[1].pMemberName = sMemberName1.pData; + + ::typelib_typedescription_new( + &pTD1, typelib_TypeClass_EXCEPTION, sTypeName1.pData, 0, 2, aMembers ); + typelib_typedescription_register( &pTD1 ); + typelib_typedescriptionreference_acquire( + s_aTypes[typelib_TypeClass_EXCEPTION] = pTD1->pWeakRef ); + // another static ref: + ++s_aTypes[typelib_TypeClass_EXCEPTION]->nStaticRefCount; + // RuntimeException + OUString sTypeName2( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") ); + ::typelib_typedescription_new( + &pTD1, typelib_TypeClass_EXCEPTION, sTypeName2.pData, s_aTypes[typelib_TypeClass_EXCEPTION], 0, 0 ); + ::typelib_typedescription_register( &pTD1 ); + ::typelib_typedescription_release( pTD1 ); + } + // XInterface members + typelib_InterfaceMethodTypeDescription * pMethod = 0; + typelib_Parameter_Init aParameters[1]; + OUString sParamName0( RTL_CONSTASCII_USTRINGPARAM("aType") ); + OUString sParamType0( RTL_CONSTASCII_USTRINGPARAM("type") ); + aParameters[0].pParamName = sParamName0.pData; + aParameters[0].eTypeClass = typelib_TypeClass_TYPE; + aParameters[0].pTypeName = sParamType0.pData; + aParameters[0].bIn = sal_True; + aParameters[0].bOut = sal_False; + rtl_uString * pExceptions[1]; + OUString sExceptionName0( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") ); + pExceptions[0] = sExceptionName0.pData; + OUString sReturnType0( RTL_CONSTASCII_USTRINGPARAM("any") ); + typelib_typedescription_newInterfaceMethod( + &pMethod, 0, sal_False, sMethodName0.pData, + typelib_TypeClass_ANY, sReturnType0.pData, + 1, aParameters, 1, pExceptions ); + ::typelib_typedescription_register( (typelib_TypeDescription**)&pMethod ); + + OUString sReturnType1( RTL_CONSTASCII_USTRINGPARAM("void") ); + ::typelib_typedescription_newInterfaceMethod( + &pMethod, 1, sal_True, sMethodName1.pData, + typelib_TypeClass_VOID, sReturnType1.pData, 0, 0, 0, 0 ); + ::typelib_typedescription_register( (typelib_TypeDescription**)&pMethod ); + + ::typelib_typedescription_newInterfaceMethod( + &pMethod, 2, sal_True, sMethodName2.pData, + typelib_TypeClass_VOID, sReturnType1.pData, + 0, 0, 0, 0 ); + ::typelib_typedescription_register( (typelib_TypeDescription**)&pMethod ); + ::typelib_typedescription_release( (typelib_TypeDescription*)pMethod ); + } + break; + } + default: + { + OUString aTypeName( OUString::createFromAscii( s_aTypeNames[eTypeClass] ) ); + ::typelib_typedescriptionreference_new( &s_aTypes[eTypeClass], eTypeClass, aTypeName.pData ); + // another static ref: + ++s_aTypes[eTypeClass]->nStaticRefCount; + } + } + } + } + return &s_aTypes[eTypeClass]; +} + +//################################################################################################## +void SAL_CALL typelib_static_type_init( + typelib_TypeDescriptionReference ** ppRef, + typelib_TypeClass eTypeClass, const sal_Char * pTypeName ) + SAL_THROW_EXTERN_C() +{ + if (! *ppRef) + { + MutexGuard aGuard( typelib_StaticInitMutex::get() ); + if (! *ppRef) + { + OUString aTypeName( OUString::createFromAscii( pTypeName ) ); + ::typelib_typedescriptionreference_new( ppRef, eTypeClass, aTypeName.pData ); + + // another static ref: + ++((*ppRef)->nStaticRefCount); + } + } +} + +//################################################################################################## +void SAL_CALL typelib_static_sequence_type_init( + typelib_TypeDescriptionReference ** ppRef, + typelib_TypeDescriptionReference * pElementType ) + SAL_THROW_EXTERN_C() +{ + if (! *ppRef) + { + MutexGuard aGuard( typelib_StaticInitMutex::get() ); + if (! *ppRef) + { + OUStringBuffer aBuf( 32 ); + aBuf.appendAscii( "[]" ); + aBuf.append( pElementType->pTypeName ); + OUString aTypeName( aBuf.makeStringAndClear() ); + + OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_SEQUENCE) ); + *ppRef = igetTypeByName( aTypeName.pData ); + if (!*ppRef) + { + typelib_TypeDescription * pReg = 0; + ::typelib_typedescription_new( + &pReg, typelib_TypeClass_SEQUENCE, + aTypeName.pData, pElementType, 0, 0 ); + + ::typelib_typedescription_register( &pReg ); + *ppRef = (typelib_TypeDescriptionReference *)pReg; + OSL_ASSERT( *ppRef == pReg->pWeakRef ); + } + // another static ref: + ++((*ppRef)->nStaticRefCount); + } + } +} + +//################################################################################################## +namespace { + +void init( + typelib_TypeDescriptionReference ** ppRef, + typelib_TypeClass eTypeClass, const sal_Char * pTypeName, + typelib_TypeDescriptionReference * pBaseType, + sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers, + sal_Bool const * pParameterizedTypes) +{ + OSL_ENSURE( typelib_TypeClass_STRUCT == eTypeClass || + typelib_TypeClass_EXCEPTION == eTypeClass, "### unexpected type class!" ); + + if (! *ppRef) + { + MutexGuard aGuard( typelib_StaticInitMutex::get() ); + if (! *ppRef) + { + OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(eTypeClass) ); + OUString aTypeName( OUString::createFromAscii( pTypeName ) ); + *ppRef = igetTypeByName( aTypeName.pData ); + if (!*ppRef) + { + typelib_CompoundTypeDescription * pComp = 0; + ::typelib_typedescription_newEmpty( + (typelib_TypeDescription **)&pComp, eTypeClass, aTypeName.pData ); + + sal_Int32 nOffset = 0; + if (pBaseType) + { + ::typelib_typedescriptionreference_getDescription( + (typelib_TypeDescription **)&pComp->pBaseTypeDescription, pBaseType ); + OSL_ASSERT( pComp->pBaseTypeDescription ); + nOffset = ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nSize; + OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nSize, "### unexpected offset!" ); + } + + if (nMembers) + { + pComp->nMembers = nMembers; + pComp->pMemberOffsets = new sal_Int32[ nMembers ]; + pComp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ]; + if (pParameterizedTypes != 0) { + reinterpret_cast< typelib_StructTypeDescription * >( + pComp)->pParameterizedTypes + = new sal_Bool[nMembers]; + } + for ( sal_Int32 i = 0 ; i < nMembers; ++i ) + { + ::typelib_typedescriptionreference_acquire( + pComp->ppTypeRefs[i] = ppMembers[i] ); + // write offset + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, pComp->ppTypeRefs[i] ); + OSL_ENSURE( pTD->nSize, "### void member?" ); + nOffset = newAlignedSize( nOffset, pTD->nSize, pTD->nAlignment ); + pComp->pMemberOffsets[i] = nOffset - pTD->nSize; + TYPELIB_DANGER_RELEASE( pTD ); + + if (pParameterizedTypes != 0) { + reinterpret_cast< typelib_StructTypeDescription * >( + pComp)->pParameterizedTypes[i] + = pParameterizedTypes[i]; + } + } + } + + typelib_TypeDescription * pReg = (typelib_TypeDescription *)pComp; + pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg; + // sizeof( void ) not allowed + pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment ); + pReg->nAlignment = adjustAlignment( pReg->nAlignment ); + pReg->bComplete = sal_False; + + ::typelib_typedescription_register( &pReg ); + *ppRef = (typelib_TypeDescriptionReference *)pReg; + OSL_ASSERT( *ppRef == pReg->pWeakRef ); + } + // another static ref: + ++((*ppRef)->nStaticRefCount); + } + } +} + +} + +void SAL_CALL typelib_static_compound_type_init( + typelib_TypeDescriptionReference ** ppRef, + typelib_TypeClass eTypeClass, const sal_Char * pTypeName, + typelib_TypeDescriptionReference * pBaseType, + sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers ) + SAL_THROW_EXTERN_C() +{ + init(ppRef, eTypeClass, pTypeName, pBaseType, nMembers, ppMembers, 0); +} + +void SAL_CALL typelib_static_struct_type_init( + typelib_TypeDescriptionReference ** ppRef, const sal_Char * pTypeName, + typelib_TypeDescriptionReference * pBaseType, + sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers, + sal_Bool const * pParameterizedTypes ) + SAL_THROW_EXTERN_C() +{ + init( + ppRef, typelib_TypeClass_STRUCT, pTypeName, pBaseType, nMembers, + ppMembers, pParameterizedTypes); +} + +//################################################################################################## +void SAL_CALL typelib_static_interface_type_init( + typelib_TypeDescriptionReference ** ppRef, + const sal_Char * pTypeName, + typelib_TypeDescriptionReference * pBaseType ) + SAL_THROW_EXTERN_C() +{ + typelib_static_mi_interface_type_init( + ppRef, pTypeName, pBaseType == 0 ? 0 : 1, &pBaseType); +} + +//################################################################################################## +void SAL_CALL typelib_static_mi_interface_type_init( + typelib_TypeDescriptionReference ** ppRef, + const sal_Char * pTypeName, + sal_Int32 nBaseTypes, + typelib_TypeDescriptionReference ** ppBaseTypes ) + SAL_THROW_EXTERN_C() +{ + if (! *ppRef) + { + MutexGuard aGuard( typelib_StaticInitMutex::get() ); + if (! *ppRef) + { + OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_INTERFACE) ); + OUString aTypeName( OUString::createFromAscii( pTypeName ) ); + *ppRef = igetTypeByName( aTypeName.pData ); + if (!*ppRef) + { + typelib_InterfaceTypeDescription * pIface = 0; + ::typelib_typedescription_newEmpty( + (typelib_TypeDescription **)&pIface, typelib_TypeClass_INTERFACE, aTypeName.pData ); + + pIface->nBaseTypes = std::max< sal_Int32 >(nBaseTypes, 1); + pIface->ppBaseTypes = new typelib_InterfaceTypeDescription *[ + pIface->nBaseTypes]; + if (nBaseTypes > 0) + { + for (sal_Int32 i = 0; i < nBaseTypes; ++i) { + pIface->ppBaseTypes[i] = 0; + ::typelib_typedescriptionreference_getDescription( + (typelib_TypeDescription **)&pIface->ppBaseTypes[i], ppBaseTypes[i] ); + OSL_ASSERT( pIface->ppBaseTypes[i] ); + } + } + else + { + pIface->ppBaseTypes[0] = 0; + ::typelib_typedescriptionreference_getDescription( + (typelib_TypeDescription **)&pIface->ppBaseTypes[0], + * ::typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ) ); + OSL_ASSERT( pIface->ppBaseTypes[0] ); + } + pIface->pBaseTypeDescription = pIface->ppBaseTypes[0]; + typelib_typedescription_acquire( + &pIface->pBaseTypeDescription->aBase); + + typelib_TypeDescription * pReg = (typelib_TypeDescription *)pIface; + pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg; + // sizeof( void ) not allowed + pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment ); + + pReg->nAlignment = adjustAlignment( pReg->nAlignment ); + pReg->bComplete = sal_False; + + ::typelib_typedescription_register( &pReg ); + *ppRef = (typelib_TypeDescriptionReference *)pReg; + OSL_ASSERT( *ppRef == pReg->pWeakRef ); + } + // another static ref: + ++((*ppRef)->nStaticRefCount); + } + } +} + +//################################################################################################## +void SAL_CALL typelib_static_enum_type_init( + typelib_TypeDescriptionReference ** ppRef, + const sal_Char * pTypeName, + sal_Int32 nDefaultValue ) + SAL_THROW_EXTERN_C() +{ + if (! *ppRef) + { + MutexGuard aGuard( typelib_StaticInitMutex::get() ); + if (! *ppRef) + { + OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM) ); + OUString aTypeName( OUString::createFromAscii( pTypeName ) ); + *ppRef = igetTypeByName( aTypeName.pData ); + if (!*ppRef) + { + typelib_TypeDescription * pReg = 0; + ::typelib_typedescription_newEmpty( + &pReg, typelib_TypeClass_ENUM, aTypeName.pData ); + typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pReg; + + pEnum->nDefaultEnumValue = nDefaultValue; + + pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg; + // sizeof( void ) not allowed + pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment ); + pReg->nAlignment = ::adjustAlignment( pReg->nAlignment ); + pReg->bComplete = sal_False; + + ::typelib_typedescription_register( &pReg ); + *ppRef = (typelib_TypeDescriptionReference *)pReg; + OSL_ASSERT( *ppRef == pReg->pWeakRef ); + } + // another static ref: + ++(*(sal_Int32 *)&(*ppRef)->pReserved); + } + } +} + +//################################################################################################## +void SAL_CALL typelib_static_array_type_init( + typelib_TypeDescriptionReference ** ppRef, + typelib_TypeDescriptionReference * pElementTypeRef, + sal_Int32 nDimensions, ... ) + SAL_THROW_EXTERN_C() +{ + if (! *ppRef) + { + MutexGuard aGuard( typelib_StaticInitMutex::get() ); + if (! *ppRef) + { + OUStringBuffer aBuf( 32 ); + aBuf.append( pElementTypeRef->pTypeName ); + + va_list dimArgs; + va_start( dimArgs, nDimensions ); + sal_Int32 dim = 0; + sal_Int32 nElements = 1; + sal_Int32* pDimensions = new sal_Int32[nDimensions]; + for (sal_Int32 i=0; i < nDimensions; i++) + { + dim = va_arg( dimArgs, int); + pDimensions[i] = dim; + aBuf.appendAscii("["); + aBuf.append(dim); + aBuf.appendAscii("]"); + nElements *= dim; + } + va_end( dimArgs ); + OUString aTypeName( aBuf.makeStringAndClear() ); + + OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ARRAY) ); + *ppRef = igetTypeByName( aTypeName.pData ); + if (!*ppRef) + { + typelib_TypeDescription * pReg = 0; + ::typelib_typedescription_newEmpty( + &pReg, typelib_TypeClass_ARRAY, aTypeName.pData ); + typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)pReg; + + pArray->nDimensions = nDimensions; + pArray->nTotalElements = nElements; + pArray->pDimensions = pDimensions; + + typelib_typedescriptionreference_acquire(pElementTypeRef); + ((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef; + + pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg; + // sizeof( void ) not allowed + pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment ); + pReg->nAlignment = ::adjustAlignment( pReg->nAlignment ); + pReg->bComplete = sal_True; + + ::typelib_typedescription_register( &pReg ); + *ppRef = (typelib_TypeDescriptionReference *)pReg; + OSL_ASSERT( *ppRef == pReg->pWeakRef ); + } else + delete [] pDimensions; + // another static ref: + ++((*ppRef)->nStaticRefCount); + } + } +} + +} // extern "C" + +} diff --git a/cppu/source/typelib/typelib.cxx b/cppu/source/typelib/typelib.cxx new file mode 100644 index 000000000000..aa0d18589a89 --- /dev/null +++ b/cppu/source/typelib/typelib.cxx @@ -0,0 +1,2660 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include <hash_map> +#include <list> +#include <set> +#include <vector> + +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <sal/alloca.h> +#include <new> +#include <osl/interlck.h> +#include <osl/mutex.hxx> +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/alloc.h> +#include <rtl/instance.hxx> +#include <osl/diagnose.h> +#include <typelib/typedescription.h> +#include <uno/any2.h> + +using namespace rtl; +using namespace std; +using namespace osl; + + +//------------------------------------------------------------------------ +//------------------------------------------------------------------------ +#ifdef SAL_W32 +#pragma pack(push, 8) +#elif defined(SAL_OS2) +#pragma pack(8) +#endif + +/** + * The double member determin the alignment. + * Under Os2 and MS-Windows the Alignment is min( 8, sizeof( type ) ). + * The aligment of a strukture is min( 8, sizeof( max basic type ) ), the greatest basic type + * determine the aligment. + */ +struct AlignSize_Impl +{ + sal_Int16 nInt16; + double dDouble; +}; + +#ifdef SAL_W32 +#pragma pack(pop) +#elif defined(SAL_OS2) +#pragma pack() +#endif + +// the value of the maximal alignment +static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16); + +static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment ) + SAL_THROW( () ) +{ + if( nRequestedAlignment > nMaxAlignment ) + nRequestedAlignment = nMaxAlignment; + return nRequestedAlignment; +} + +/** + * Calculate the new size of the struktur. + */ +static inline sal_Int32 newAlignedSize( + sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment ) + SAL_THROW( () ) +{ + NeededAlignment = adjustAlignment( NeededAlignment ); + return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize; +} + +static inline sal_Bool reallyWeak( typelib_TypeClass eTypeClass ) + SAL_THROW( () ) +{ + return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass ); +} + +static inline sal_Int32 getDescriptionSize( typelib_TypeClass eTypeClass ) + SAL_THROW( () ) +{ + OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass ); + + sal_Int32 nSize; + // The reference is the description + // if the description is empty, than it must be filled with + // the new description + switch( eTypeClass ) + { + case typelib_TypeClass_ARRAY: + nSize = (sal_Int32)sizeof( typelib_ArrayTypeDescription ); + break; + + case typelib_TypeClass_SEQUENCE: + nSize = (sal_Int32)sizeof( typelib_IndirectTypeDescription ); + break; + + case typelib_TypeClass_UNION: + nSize = (sal_Int32)sizeof( typelib_UnionTypeDescription ); + break; + + case typelib_TypeClass_STRUCT: + nSize = (sal_Int32)sizeof( typelib_StructTypeDescription ); + break; + + case typelib_TypeClass_EXCEPTION: + nSize = (sal_Int32)sizeof( typelib_CompoundTypeDescription ); + break; + + case typelib_TypeClass_ENUM: + nSize = (sal_Int32)sizeof( typelib_EnumTypeDescription ); + break; + + case typelib_TypeClass_INTERFACE: + nSize = (sal_Int32)sizeof( typelib_InterfaceTypeDescription ); + break; + + case typelib_TypeClass_INTERFACE_METHOD: + nSize = (sal_Int32)sizeof( typelib_InterfaceMethodTypeDescription ); + break; + + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + nSize = (sal_Int32)sizeof( typelib_InterfaceAttributeTypeDescription ); + break; + + default: + nSize = (sal_Int32)sizeof( typelib_TypeDescription ); + } + return nSize; +} + + +//----------------------------------------------------------------------------- +extern "C" void SAL_CALL typelib_typedescriptionreference_getByName( + typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName ) + SAL_THROW_EXTERN_C(); + +//----------------------------------------------------------------------------- +struct equalStr_Impl +{ + sal_Bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const SAL_THROW( () ) + { return 0 == rtl_ustr_compare( s1, s2 ); } +}; + +//----------------------------------------------------------------------------- +struct hashStr_Impl +{ + size_t operator()(const sal_Unicode * const & s) const SAL_THROW( () ) + { return rtl_ustr_hashCode( s ); } +}; + + +//----------------------------------------------------------------------------- +// Heavy hack, the const sal_Unicode * is hold by the typedescription reference +typedef hash_map< const sal_Unicode *, typelib_TypeDescriptionReference *, + hashStr_Impl, equalStr_Impl > WeakMap_Impl; + +typedef pair< void *, typelib_typedescription_Callback > CallbackEntry; +typedef list< CallbackEntry > CallbackSet_Impl; +typedef list< typelib_TypeDescription * > TypeDescriptionList_Impl; + +// # of cached elements +static sal_Int32 nCacheSize = 256; + +//----------------------------------------------------------------------------- +/** + * All members must set initial to 0 and no constructor is needed. So it + * doesn't care, when this class is static initialized.<BR> + */ +struct TypeDescriptor_Init_Impl +{ + //sal_Bool bDesctructorCalled; + // all type description references + WeakMap_Impl * pWeakMap; + // all type description callbacks + CallbackSet_Impl * pCallbacks; + // A cache to hold descriptions + TypeDescriptionList_Impl * pCache; + // The mutex to guard all type library accesses + Mutex * pMutex; + + inline Mutex & getMutex() SAL_THROW( () ); + + inline void callChain( typelib_TypeDescription ** ppRet, rtl_uString * pName ) SAL_THROW( () ); + +#if OSL_DEBUG_LEVEL > 1 + // only for debugging + sal_Int32 nTypeDescriptionCount; + sal_Int32 nCompoundTypeDescriptionCount; + sal_Int32 nUnionTypeDescriptionCount; + sal_Int32 nIndirectTypeDescriptionCount; + sal_Int32 nArrayTypeDescriptionCount; + sal_Int32 nEnumTypeDescriptionCount; + sal_Int32 nInterfaceMethodTypeDescriptionCount; + sal_Int32 nInterfaceAttributeTypeDescriptionCount; + sal_Int32 nInterfaceTypeDescriptionCount; + sal_Int32 nTypeDescriptionReferenceCount; +#endif + ~TypeDescriptor_Init_Impl() SAL_THROW( () ); +}; +//__________________________________________________________________________________________________ +inline Mutex & TypeDescriptor_Init_Impl::getMutex() SAL_THROW( () ) +{ + if( !pMutex ) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if( !pMutex ) + pMutex = new Mutex(); + } + return * pMutex; +} +//__________________________________________________________________________________________________ +inline void TypeDescriptor_Init_Impl::callChain( + typelib_TypeDescription ** ppRet, rtl_uString * pName ) + SAL_THROW( () ) +{ + if (pCallbacks) + { + CallbackSet_Impl::const_iterator aIt = pCallbacks->begin(); + while( aIt != pCallbacks->end() ) + { + const CallbackEntry & rEntry = *aIt; + (*rEntry.second)( rEntry.first, ppRet, pName ); + if( *ppRet ) + return; + ++aIt; + } + } + if (*ppRet) + { + typelib_typedescription_release( *ppRet ); + *ppRet = 0; + } +} + +//__________________________________________________________________________________________________ +TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW( () ) +{ + if( pCache ) + { + TypeDescriptionList_Impl::const_iterator aIt = pCache->begin(); + while( aIt != pCache->end() ) + { + typelib_typedescription_release( (*aIt) ); + aIt++; + } + delete pCache; + pCache = 0; + } + + if( pWeakMap ) + { + sal_Int32 nSize = pWeakMap->size(); + typelib_TypeDescriptionReference ** ppTDR = new typelib_TypeDescriptionReference *[ nSize ]; + // save al weak references + WeakMap_Impl::const_iterator aIt = pWeakMap->begin(); + sal_Int32 i = 0; + while( aIt != pWeakMap->end() ) + { + typelib_typedescriptionreference_acquire( ppTDR[i++] = (*aIt).second ); + ++aIt; + } + + for( i = 0; i < nSize; i++ ) + { + typelib_TypeDescriptionReference * pTDR = ppTDR[i]; + OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount ); + pTDR->nRefCount -= pTDR->nStaticRefCount; + + if( pTDR->pType && !pTDR->pType->bOnDemand ) + { + pTDR->pType->bOnDemand = sal_True; + typelib_typedescription_release( pTDR->pType ); + } + typelib_typedescriptionreference_release( pTDR ); + } + + delete [] ppTDR; + +#if OSL_DEBUG_LEVEL > 1 + aIt = pWeakMap->begin(); + while( aIt != pWeakMap->end() ) + { + typelib_TypeDescriptionReference * pTDR = (*aIt).second; + if (pTDR) + { + OString aTypeName( OUStringToOString( pTDR->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( + "### remaining type: %s; ref count = %d", aTypeName.getStr(), pTDR->nRefCount ); + } + else + { + OSL_TRACE( "### remaining null type entry!?" ); + } + ++aIt; + } +#endif + + delete pWeakMap; + pWeakMap = 0; + } +#if OSL_DEBUG_LEVEL > 1 + OSL_ASSERT( nTypeDescriptionCount == 0 ); + OSL_ASSERT( nCompoundTypeDescriptionCount == 0 ); + OSL_ASSERT( nUnionTypeDescriptionCount == 0 ); + OSL_ASSERT( nIndirectTypeDescriptionCount == 0 ); + OSL_ASSERT( nArrayTypeDescriptionCount == 0 ); + OSL_ASSERT( nEnumTypeDescriptionCount == 0 ); + OSL_ASSERT( nInterfaceMethodTypeDescriptionCount == 0 ); + OSL_ASSERT( nInterfaceAttributeTypeDescriptionCount == 0 ); + OSL_ASSERT( nInterfaceTypeDescriptionCount == 0 ); + OSL_ASSERT( nTypeDescriptionReferenceCount == 0 ); + + OSL_ASSERT( !pCallbacks || pCallbacks->empty() ); +#endif + delete pCallbacks; + pCallbacks = 0; + + if( pMutex ) + { + delete pMutex; + pMutex = 0; + } +}; + +namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; } + +//------------------------------------------------------------------------ +//------------------------------------------------------------------------ +//------------------------------------------------------------------------ +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_registerCallback( + void * pContext, typelib_typedescription_Callback pCallback ) + SAL_THROW_EXTERN_C() +{ + // todo mt safe: guard is no solution, can not acquire while calling callback! + TypeDescriptor_Init_Impl &rInit = Init::get(); +// OslGuard aGuard( rInit.getMutex() ); + if( !rInit.pCallbacks ) + rInit.pCallbacks = new CallbackSet_Impl; + rInit.pCallbacks->push_back( CallbackEntry( pContext, pCallback ) ); +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_revokeCallback( + void * pContext, typelib_typedescription_Callback pCallback ) + SAL_THROW_EXTERN_C() +{ + TypeDescriptor_Init_Impl &rInit = Init::get(); + if( rInit.pCallbacks ) + { + // todo mt safe: guard is no solution, can not acquire while calling callback! +// OslGuard aGuard( rInit.getMutex() ); + CallbackEntry aEntry( pContext, pCallback ); + CallbackSet_Impl::iterator iPos( rInit.pCallbacks->begin() ); + while (!(iPos == rInit.pCallbacks->end())) + { + if (*iPos == aEntry) + { + rInit.pCallbacks->erase( iPos ); + iPos = rInit.pCallbacks->begin(); + } + else + { + ++iPos; + } + } + } +} + + +//------------------------------------------------------------------------ +//------------------------------------------------------------------------ +//------------------------------------------------------------------------ +extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize( + const typelib_TypeDescription * pTypeDescription, + sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize ) + SAL_THROW_EXTERN_C(); + +//------------------------------------------------------------------------ +static inline void typelib_typedescription_initTables( + typelib_TypeDescription * pTD ) + SAL_THROW( () ) +{ + typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription *)pTD; + + sal_Bool * pReadWriteAttributes = (sal_Bool *)alloca( pITD->nAllMembers ); + for ( sal_Int32 i = pITD->nAllMembers; i--; ) + { + pReadWriteAttributes[i] = sal_False; + if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass ) + { + typelib_TypeDescription * pM = 0; + TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] ); + OSL_ASSERT( pM ); + if (pM) + { + pReadWriteAttributes[i] = !((typelib_InterfaceAttributeTypeDescription *)pM)->bReadOnly; + TYPELIB_DANGER_RELEASE( pM ); + } +#if OSL_DEBUG_LEVEL > 1 + else + { + OString aStr( OUStringToOString( pITD->ppAllMembers[i]->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "\n### cannot get attribute type description: %s", aStr.getStr() ); + } +#endif + } + } + + MutexGuard aGuard( Init::get().getMutex() ); + if( !pTD->bComplete ) + { + // create the index table from member to function table + pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ]; + sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes + sal_Int32 i; + for( i = 0; i < pITD->nAllMembers; i++ ) + { + // index to the get method of the attribute + pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset; + // extra offset if it is a read/write attribute? + if( pReadWriteAttributes[i] ) + { + // a read/write attribute + nAdditionalOffset++; + } + } + + // create the index table from function to member table + pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ]; + nAdditionalOffset = 0; // +1 for read/write attributes + for( i = 0; i < pITD->nAllMembers; i++ ) + { + // index to the get method of the attribute + pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i; + // extra offset if it is a read/write attribute? + if( pReadWriteAttributes[i] ) + { + // a read/write attribute + pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i; + } + } + // must be the last action after all initialization is done + pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset; + pTD->bComplete = sal_True; + } +} + +namespace { + +// In some situations (notably typelib_typedescription_newInterfaceMethod and +// typelib_typedescription_newInterfaceAttribute), only the members nMembers, +// ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type +// description are necessary, but not the additional +// pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and +// pMapFunctionIndexToMemberIndex (which are computed by +// typelib_typedescription_initTables). Furthermore, in those situations, it +// might be illegal to compute those tables, as the creation of the interface +// member type descriptions would recursively require a complete interface type +// description. The parameter initTables controls whether or not to call +// typelib_typedescription_initTables in those situations. +bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) { + if (! (*ppTypeDescr)->bComplete) + { + OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass || + typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass || + typelib_TypeClass_UNION == (*ppTypeDescr)->eTypeClass || + typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass || + typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) && + !reallyWeak( (*ppTypeDescr)->eTypeClass ) ); + + if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass && + ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers) + { + if (initTables) { + typelib_typedescription_initTables( *ppTypeDescr ); + } + return true; + } + + typelib_TypeDescription * pTD = 0; + // on demand access of complete td + TypeDescriptor_Init_Impl &rInit = Init::get(); + rInit.callChain( &pTD, (*ppTypeDescr)->pTypeName ); + if (pTD) + { + if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass) + { + typelib_typedescriptionreference_getDescription( + &pTD, ((typelib_IndirectTypeDescription *)pTD)->pType ); + OSL_ASSERT( pTD ); + if (! pTD) + return false; + } + + OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass ); + // typedescription found + // set to on demand + pTD->bOnDemand = sal_True; + + if (pTD->eTypeClass == typelib_TypeClass_INTERFACE + && !pTD->bComplete && initTables) + { + // mandatory info from callback chain + OSL_ASSERT( ((typelib_InterfaceTypeDescription *)pTD)->ppAllMembers ); + // complete except of tables init + typelib_typedescription_initTables( pTD ); + pTD->bComplete = sal_True; + } + + // The type description is hold by the reference until + // on demand is activated. + ::typelib_typedescription_register( &pTD ); // replaces incomplete one + OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one + + // insert into the chache + MutexGuard aGuard( rInit.getMutex() ); + if( !rInit.pCache ) + rInit.pCache = new TypeDescriptionList_Impl; + if( (sal_Int32)rInit.pCache->size() >= nCacheSize ) + { + typelib_typedescription_release( rInit.pCache->front() ); + rInit.pCache->pop_front(); + } + // descriptions in the cache must be acquired! + typelib_typedescription_acquire( pTD ); + rInit.pCache->push_back( pTD ); + + OSL_ASSERT( + pTD->bComplete + || (pTD->eTypeClass == typelib_TypeClass_INTERFACE + && !initTables)); + + ::typelib_typedescription_release( *ppTypeDescr ); + *ppTypeDescr = pTD; + } + else + { +#if OSL_DEBUG_LEVEL > 1 + OString aStr( + OUStringToOString( (*ppTypeDescr)->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "\n### type cannot be completed: %s", aStr.getStr() ); +#endif + return false; + } + } + return true; +} + +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_newEmpty( + typelib_TypeDescription ** ppRet, + typelib_TypeClass eTypeClass, rtl_uString * pTypeName ) + SAL_THROW_EXTERN_C() +{ + if( *ppRet ) + { + typelib_typedescription_release( *ppRet ); + *ppRet = 0; + } + + OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass ); + + typelib_TypeDescription * pRet; + switch( eTypeClass ) + { + case typelib_TypeClass_ARRAY: + { + typelib_ArrayTypeDescription * pTmp = new typelib_ArrayTypeDescription(); + typelib_IndirectTypeDescription * pIndirect = (typelib_IndirectTypeDescription *)pTmp; + pRet = (typelib_TypeDescription *)pTmp; +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( + &Init::get().nArrayTypeDescriptionCount ); +#endif + pIndirect->pType = 0; + pTmp->nDimensions = 0; + pTmp->nTotalElements = 0; + pTmp->pDimensions = 0; + } + break; + + case typelib_TypeClass_SEQUENCE: + { + typelib_IndirectTypeDescription * pTmp = new typelib_IndirectTypeDescription(); + pRet = (typelib_TypeDescription *)pTmp; +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( + &Init::get().nIndirectTypeDescriptionCount ); +#endif + pTmp->pType = 0; + } + break; + + case typelib_TypeClass_UNION: + { + typelib_UnionTypeDescription * pTmp; + pTmp = new typelib_UnionTypeDescription(); + pRet = (typelib_TypeDescription *)pTmp; +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( + &Init::get().nUnionTypeDescriptionCount ); +#endif + pTmp->nMembers = 0; + pTmp->pDiscriminantTypeRef = 0; + pTmp->pDiscriminants = 0; + pTmp->ppTypeRefs = 0; + pTmp->ppMemberNames = 0; + pTmp->pDefaultTypeRef = 0; + } + break; + + case typelib_TypeClass_STRUCT: + { + // FEATURE_EMPTYCLASS + typelib_StructTypeDescription * pTmp; + pTmp = new typelib_StructTypeDescription(); + pRet = (typelib_TypeDescription *)pTmp; +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( + &Init::get().nCompoundTypeDescriptionCount ); +#endif + pTmp->aBase.pBaseTypeDescription = 0; + pTmp->aBase.nMembers = 0; + pTmp->aBase.pMemberOffsets = 0; + pTmp->aBase.ppTypeRefs = 0; + pTmp->aBase.ppMemberNames = 0; + pTmp->pParameterizedTypes = 0; + } + break; + + case typelib_TypeClass_EXCEPTION: + { + // FEATURE_EMPTYCLASS + typelib_CompoundTypeDescription * pTmp; + pTmp = new typelib_CompoundTypeDescription(); + pRet = (typelib_TypeDescription *)pTmp; +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( + &Init::get().nCompoundTypeDescriptionCount ); +#endif + pTmp->pBaseTypeDescription = 0; + pTmp->nMembers = 0; + pTmp->pMemberOffsets = 0; + pTmp->ppTypeRefs = 0; + pTmp->ppMemberNames = 0; + } + break; + + case typelib_TypeClass_ENUM: + { + typelib_EnumTypeDescription * pTmp = new typelib_EnumTypeDescription(); + pRet = (typelib_TypeDescription *)pTmp; +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( + &Init::get().nEnumTypeDescriptionCount ); +#endif + pTmp->nDefaultEnumValue = 0; + pTmp->nEnumValues = 0; + pTmp->ppEnumNames = 0; + pTmp->pEnumValues = 0; + } + break; + + case typelib_TypeClass_INTERFACE: + { + typelib_InterfaceTypeDescription * pTmp = new typelib_InterfaceTypeDescription(); + pRet = (typelib_TypeDescription *)pTmp; +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( + &Init::get().nInterfaceTypeDescriptionCount ); +#endif + pTmp->pBaseTypeDescription = 0; + pTmp->nMembers = 0; + pTmp->ppMembers = 0; + pTmp->nAllMembers = 0; + pTmp->ppAllMembers = 0; + pTmp->nMapFunctionIndexToMemberIndex = 0; + pTmp->pMapFunctionIndexToMemberIndex = 0; + pTmp->pMapMemberIndexToFunctionIndex= 0; + pTmp->nBaseTypes = 0; + pTmp->ppBaseTypes = 0; + } + break; + + case typelib_TypeClass_INTERFACE_METHOD: + { + typelib_InterfaceMethodTypeDescription * pTmp = new typelib_InterfaceMethodTypeDescription(); + pRet = (typelib_TypeDescription *)pTmp; +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( + &Init::get().nInterfaceMethodTypeDescriptionCount ); +#endif + pTmp->aBase.pMemberName = 0; + pTmp->pReturnTypeRef = 0; + pTmp->nParams = 0; + pTmp->pParams = 0; + pTmp->nExceptions = 0; + pTmp->ppExceptions = 0; + pTmp->pInterface = 0; + pTmp->pBaseRef = 0; + pTmp->nIndex = 0; + } + break; + + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + typelib_InterfaceAttributeTypeDescription * pTmp = new typelib_InterfaceAttributeTypeDescription(); + pRet = (typelib_TypeDescription *)pTmp; +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( + &Init::get().nInterfaceAttributeTypeDescriptionCount ); +#endif + pTmp->aBase.pMemberName = 0; + pTmp->pAttributeTypeRef = 0; + pTmp->pInterface = 0; + pTmp->pBaseRef = 0; + pTmp->nIndex = 0; + pTmp->nGetExceptions = 0; + pTmp->ppGetExceptions = 0; + pTmp->nSetExceptions = 0; + pTmp->ppSetExceptions = 0; + } + break; + + default: + { + pRet = new typelib_TypeDescription(); +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( &Init::get().nTypeDescriptionCount ); +#endif + } + } + + pRet->nRefCount = 1; // reference count is initially 1 + pRet->nStaticRefCount = 0; + pRet->eTypeClass = eTypeClass; + pRet->pTypeName = 0; + pRet->pUniqueIdentifier = 0; + pRet->pReserved = 0; + rtl_uString_acquire( pRet->pTypeName = pTypeName ); + pRet->pSelf = pRet; + pRet->bComplete = sal_True; + pRet->nSize = 0; + pRet->nAlignment = 0; + pRet->pWeakRef = 0; + pRet->bOnDemand = sal_False; + *ppRet = pRet; +} + +//------------------------------------------------------------------------ +namespace { + +void newTypeDescription( + typelib_TypeDescription ** ppRet, typelib_TypeClass eTypeClass, + rtl_uString * pTypeName, typelib_TypeDescriptionReference * pType, + sal_Int32 nMembers, typelib_CompoundMember_Init * pCompoundMembers, + typelib_StructMember_Init * pStructMembers) +{ + OSL_ASSERT( + (pCompoundMembers == 0 || pStructMembers == 0) + && (pStructMembers == 0 || eTypeClass == typelib_TypeClass_STRUCT)); + if (typelib_TypeClass_TYPEDEF == eTypeClass) + { + OSL_TRACE( "### unexpected typedef!" ); + typelib_typedescriptionreference_getDescription( ppRet, pType ); + return; + } + + typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName ); + + switch( eTypeClass ) + { + case typelib_TypeClass_SEQUENCE: + { + OSL_ASSERT( nMembers == 0 ); + typelib_typedescriptionreference_acquire( pType ); + ((typelib_IndirectTypeDescription *)*ppRet)->pType = pType; + } + break; + + case typelib_TypeClass_EXCEPTION: + case typelib_TypeClass_STRUCT: + { + // FEATURE_EMPTYCLASS + typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription*)*ppRet; + + sal_Int32 nOffset = 0; + if( pType ) + { + typelib_typedescriptionreference_getDescription( + (typelib_TypeDescription **)&pTmp->pBaseTypeDescription, pType ); + nOffset = ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize; + OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, "### unexpected offset!" ); + } + if( nMembers ) + { + pTmp->nMembers = nMembers; + pTmp->pMemberOffsets = new sal_Int32[ nMembers ]; + pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ]; + pTmp->ppMemberNames = new rtl_uString *[ nMembers ]; + bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT + && rtl::OUString::unacquired(&pTypeName).indexOf('<') >= 0; + OSL_ASSERT(!polymorphic || pStructMembers != 0); + if (polymorphic) { + reinterpret_cast< typelib_StructTypeDescription * >(pTmp)-> + pParameterizedTypes = new sal_Bool[nMembers]; + } + for( sal_Int32 i = 0 ; i < nMembers; i++ ) + { + // read the type and member names + pTmp->ppTypeRefs[i] = 0; + if (pCompoundMembers != 0) { + typelib_typedescriptionreference_new( + pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass, + pCompoundMembers[i].pTypeName ); + rtl_uString_acquire( + pTmp->ppMemberNames[i] + = pCompoundMembers[i].pMemberName ); + } else { + typelib_typedescriptionreference_new( + pTmp->ppTypeRefs +i, + pStructMembers[i].aBase.eTypeClass, + pStructMembers[i].aBase.pTypeName ); + rtl_uString_acquire( + pTmp->ppMemberNames[i] + = pStructMembers[i].aBase.pMemberName ); + } + // write offset + sal_Int32 size; + sal_Int32 alignment; + if (pTmp->ppTypeRefs[i]->eTypeClass == + typelib_TypeClass_SEQUENCE) + { + // Take care of recursion like + // struct S { sequence<S> x; }; + size = sizeof(void *); + alignment = adjustAlignment(size); + } else { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] ); + OSL_ENSURE( pTD->nSize, "### void member?" ); + size = pTD->nSize; + alignment = pTD->nAlignment; + TYPELIB_DANGER_RELEASE( pTD ); + } + nOffset = newAlignedSize( nOffset, size, alignment ); + pTmp->pMemberOffsets[i] = nOffset - size; + + if (polymorphic) { + reinterpret_cast< typelib_StructTypeDescription * >( + pTmp)->pParameterizedTypes[i] + = pStructMembers[i].bParameterizedType; + } + } + } + } + break; + + default: + break; + } + + if( !reallyWeak( eTypeClass ) ) + (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet; + if( eTypeClass != typelib_TypeClass_VOID ) + { + // sizeof( void ) not allowed + (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment ); + (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment ); + } +} + +} + +extern "C" void SAL_CALL typelib_typedescription_new( + typelib_TypeDescription ** ppRet, + typelib_TypeClass eTypeClass, + rtl_uString * pTypeName, + typelib_TypeDescriptionReference * pType, + sal_Int32 nMembers, + typelib_CompoundMember_Init * pMembers ) + SAL_THROW_EXTERN_C() +{ + newTypeDescription( + ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, 0); +} + +extern "C" void SAL_CALL typelib_typedescription_newStruct( + typelib_TypeDescription ** ppRet, + rtl_uString * pTypeName, + typelib_TypeDescriptionReference * pType, + sal_Int32 nMembers, + typelib_StructMember_Init * pMembers ) + SAL_THROW_EXTERN_C() +{ + newTypeDescription( + ppRet, typelib_TypeClass_STRUCT, pTypeName, pType, nMembers, 0, + pMembers); +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_newUnion( + typelib_TypeDescription ** ppRet, + rtl_uString * pTypeName, + typelib_TypeDescriptionReference * pDiscriminantTypeRef, + sal_Int64 nDefaultDiscriminant, + typelib_TypeDescriptionReference * pDefaultTypeRef, + sal_Int32 nMembers, + typelib_Union_Init * pMembers ) + SAL_THROW_EXTERN_C() +{ + typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_UNION, pTypeName ); + // discriminant type + typelib_UnionTypeDescription * pTmp = (typelib_UnionTypeDescription *)*ppRet; + typelib_typedescriptionreference_acquire( pTmp->pDiscriminantTypeRef = pDiscriminantTypeRef ); + + sal_Int32 nPos; + + pTmp->nMembers = nMembers; + // default discriminant + if (nMembers) + { + pTmp->pDiscriminants = new sal_Int64[ nMembers ]; + for ( nPos = nMembers; nPos--; ) + { + pTmp->pDiscriminants[nPos] = pMembers[nPos].nDiscriminant; + } + } + // default default discriminant + pTmp->nDefaultDiscriminant = nDefaultDiscriminant; + + // union member types + pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ]; + for ( nPos = nMembers; nPos--; ) + { + typelib_typedescriptionreference_acquire( pTmp->ppTypeRefs[nPos] = pMembers[nPos].pTypeRef ); + } + // union member names + pTmp->ppMemberNames = new rtl_uString *[ nMembers ]; + for ( nPos = nMembers; nPos--; ) + { + rtl_uString_acquire( pTmp->ppMemberNames[nPos] = pMembers[nPos].pMemberName ); + } + + // default union type + typelib_typedescriptionreference_acquire( pTmp->pDefaultTypeRef = pDefaultTypeRef ); + + if (! reallyWeak( typelib_TypeClass_UNION )) + (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet; + (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment ); + (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment ); +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_newEnum( + typelib_TypeDescription ** ppRet, + rtl_uString * pTypeName, + sal_Int32 nDefaultValue, + sal_Int32 nEnumValues, + rtl_uString ** ppEnumNames, + sal_Int32 * pEnumValues ) + SAL_THROW_EXTERN_C() +{ + typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName ); + typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)*ppRet; + + pEnum->nDefaultEnumValue = nDefaultValue; + pEnum->nEnumValues = nEnumValues; + pEnum->ppEnumNames = new rtl_uString * [ nEnumValues ]; + for ( sal_Int32 nPos = nEnumValues; nPos--; ) + { + rtl_uString_acquire( pEnum->ppEnumNames[nPos] = ppEnumNames[nPos] ); + } + pEnum->pEnumValues = new sal_Int32[ nEnumValues ]; + ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) ); + + (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet; + // sizeof( void ) not allowed + (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment ); + (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment ); +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_newArray( + typelib_TypeDescription ** ppRet, + typelib_TypeDescriptionReference * pElementTypeRef, + sal_Int32 nDimensions, + sal_Int32 * pDimensions ) + SAL_THROW_EXTERN_C () +{ + OUStringBuffer aBuf( 32 ); + aBuf.append( pElementTypeRef->pTypeName ); + sal_Int32 nElements = 1; + for (sal_Int32 i=0; i < nDimensions; i++) + { + aBuf.appendAscii("["); + aBuf.append(pDimensions[i]); + aBuf.appendAscii("]"); + nElements *= pDimensions[i]; + } + OUString aTypeName( aBuf.makeStringAndClear() ); + + + typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ARRAY, aTypeName.pData ); + typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)*ppRet; + + pArray->nDimensions = nDimensions; + pArray->nTotalElements = nElements; + pArray->pDimensions = new sal_Int32[ nDimensions ]; + ::memcpy( pArray->pDimensions, pDimensions, nDimensions * sizeof(sal_Int32) ); + + typelib_typedescriptionreference_acquire(pElementTypeRef); + ((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef; + + (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet; + // sizeof( void ) not allowed + (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( *ppRet, 0, (*ppRet)->nAlignment ); + (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment ); +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_newInterface( + typelib_InterfaceTypeDescription ** ppRet, + rtl_uString * pTypeName, + sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5, + typelib_TypeDescriptionReference * pBaseInterface, + sal_Int32 nMembers, + typelib_TypeDescriptionReference ** ppMembers ) + SAL_THROW_EXTERN_C() +{ + typelib_typedescription_newMIInterface( + ppRet, pTypeName, nUik1, nUik2, nUik3, nUik4, nUik5, + pBaseInterface == 0 ? 0 : 1, &pBaseInterface, nMembers, ppMembers); +} + +//------------------------------------------------------------------------ + +namespace { + +class BaseList { +public: + struct Entry { + sal_Int32 memberOffset; + sal_Int32 directBaseIndex; + sal_Int32 directBaseMemberOffset; + typelib_InterfaceTypeDescription const * base; + }; + + typedef std::vector< Entry > List; + + BaseList(typelib_InterfaceTypeDescription const * desc); + + List const & getList() const { return list; } + + sal_Int32 getBaseMembers() const { return members; } + +private: + typedef std::set< rtl::OUString > Set; + + void calculate( + sal_Int32 directBaseIndex, Set & directBaseSet, + sal_Int32 * directBaseMembers, + typelib_InterfaceTypeDescription const * desc); + + Set set; + List list; + sal_Int32 members; +}; + +BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) { + members = 0; + for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) { + Set directBaseSet; + sal_Int32 directBaseMembers = 0; + calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]); + } +} + +void BaseList::calculate( + sal_Int32 directBaseIndex, Set & directBaseSet, + sal_Int32 * directBaseMembers, + typelib_InterfaceTypeDescription const * desc) +{ + for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) { + calculate( + directBaseIndex, directBaseSet, directBaseMembers, + desc->ppBaseTypes[i]); + } + if (set.insert(desc->aBase.pTypeName).second) { + Entry e; + e.memberOffset = members; + e.directBaseIndex = directBaseIndex; + e.directBaseMemberOffset = *directBaseMembers; + e.base = desc; + list.push_back(e); + OSL_ASSERT(desc->ppAllMembers != 0); + members += desc->nMembers; + } + if (directBaseSet.insert(desc->aBase.pTypeName).second) { + OSL_ASSERT(desc->ppAllMembers != 0); + *directBaseMembers += desc->nMembers; + } +} + +} + +extern "C" void SAL_CALL typelib_typedescription_newMIInterface( + typelib_InterfaceTypeDescription ** ppRet, + rtl_uString * pTypeName, + sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5, + sal_Int32 nBaseInterfaces, + typelib_TypeDescriptionReference ** ppBaseInterfaces, + sal_Int32 nMembers, + typelib_TypeDescriptionReference ** ppMembers ) + SAL_THROW_EXTERN_C() +{ + if (*ppRet != 0) { + typelib_typedescription_release(&(*ppRet)->aBase); + *ppRet = 0; + } + + typelib_InterfaceTypeDescription * pITD = 0; + typelib_typedescription_newEmpty( + (typelib_TypeDescription **)&pITD, typelib_TypeClass_INTERFACE, pTypeName ); + + pITD->nBaseTypes = nBaseInterfaces; + pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces]; + for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) { + pITD->ppBaseTypes[i] = 0; + typelib_typedescriptionreference_getDescription( + reinterpret_cast< typelib_TypeDescription ** >( + &pITD->ppBaseTypes[i]), + ppBaseInterfaces[i]); + if (pITD->ppBaseTypes[i] == 0 + || !complete( + reinterpret_cast< typelib_TypeDescription ** >( + &pITD->ppBaseTypes[i]), + false)) + { + OSL_ASSERT(false); + return; + } + OSL_ASSERT(pITD->ppBaseTypes[i] != 0); + } + if (nBaseInterfaces > 0) { + pITD->pBaseTypeDescription = pITD->ppBaseTypes[0]; + } + // set the + pITD->aUik.m_Data1 = nUik1; + pITD->aUik.m_Data2 = nUik2; + pITD->aUik.m_Data3 = nUik3; + pITD->aUik.m_Data4 = nUik4; + pITD->aUik.m_Data5 = nUik5; + + BaseList aBaseList(pITD); + pITD->nAllMembers = nMembers + aBaseList.getBaseMembers(); + pITD->nMembers = nMembers; + + if( pITD->nAllMembers ) + { + // at minimum one member exist, allocate the memory + pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ]; + sal_Int32 n = 0; + + BaseList::List const & rList = aBaseList.getList(); + {for (BaseList::List::const_iterator i(rList.begin()); i != rList.end(); + ++i) + { + typelib_InterfaceTypeDescription const * pBase = i->base; + typelib_InterfaceTypeDescription const * pDirectBase + = pITD->ppBaseTypes[i->directBaseIndex]; + OSL_ASSERT(pBase->ppAllMembers != 0); + for (sal_Int32 j = 0; j < pBase->nMembers; ++j) { + typelib_TypeDescriptionReference const * pDirectBaseMember + = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j]; + rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName); + aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(":@")); + aBuf.append(i->directBaseIndex); + aBuf.append(static_cast< sal_Unicode >(',')); + aBuf.append(i->memberOffset + j); + aBuf.append(static_cast< sal_Unicode >(':')); + aBuf.append(pITD->aBase.pTypeName); + rtl::OUString aName(aBuf.makeStringAndClear()); + typelib_TypeDescriptionReference * pDerivedMember = 0; + typelib_typedescriptionreference_new( + &pDerivedMember, pDirectBaseMember->eTypeClass, + aName.pData); + pITD->ppAllMembers[n++] = pDerivedMember; + } + }} + + if( nMembers ) + { + pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers(); + } + + // add own members + {for( sal_Int32 i = 0; i < nMembers; i++ ) + { + typelib_typedescriptionreference_acquire( ppMembers[i] ); + pITD->ppAllMembers[n++] = ppMembers[i]; + }} + } + + typelib_TypeDescription * pTmp = (typelib_TypeDescription *)pITD; + if( !reallyWeak( typelib_TypeClass_INTERFACE ) ) + pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp; + pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment ); + pTmp->nAlignment = adjustAlignment( pTmp->nAlignment ); + pTmp->bComplete = sal_False; + + *ppRet = pITD; +} + +//------------------------------------------------------------------------ + +namespace { + +typelib_TypeDescriptionReference ** copyExceptions( + sal_Int32 count, rtl_uString ** typeNames) +{ + OSL_ASSERT(count >= 0); + if (count == 0) { + return 0; + } + typelib_TypeDescriptionReference ** p + = new typelib_TypeDescriptionReference *[count]; + for (sal_Int32 i = 0; i < count; ++i) { + p[i] = 0; + typelib_typedescriptionreference_new( + p + i, typelib_TypeClass_EXCEPTION, typeNames[i]); + } + return p; +} + +} + +extern "C" void SAL_CALL typelib_typedescription_newInterfaceMethod( + typelib_InterfaceMethodTypeDescription ** ppRet, + sal_Int32 nAbsolutePosition, + sal_Bool bOneWay, + rtl_uString * pTypeName, + typelib_TypeClass eReturnTypeClass, + rtl_uString * pReturnTypeName, + sal_Int32 nParams, + typelib_Parameter_Init * pParams, + sal_Int32 nExceptions, + rtl_uString ** ppExceptionNames ) + SAL_THROW_EXTERN_C() +{ + if (*ppRet != 0) { + typelib_typedescription_release(&(*ppRet)->aBase.aBase); + *ppRet = 0; + } + sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength( + pTypeName->buffer, pTypeName->length, ':'); + if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') { + OSL_ENSURE(false, "Bad interface method type name"); + return; + } + rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1); + typelib_InterfaceTypeDescription * pInterface = 0; + typelib_typedescription_getByName( + reinterpret_cast< typelib_TypeDescription ** >(&pInterface), + aInterfaceTypeName.pData); + if (pInterface == 0 + || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE + || !complete( + reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false)) + { + OSL_ENSURE(false, "No interface corresponding to interface method"); + return; + } + + typelib_typedescription_newEmpty( + (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName ); + typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet; + + rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName, + pTypeName->buffer + nOffset +1, + pTypeName->length - nOffset -1 ); + (*ppRet)->aBase.nPosition = nAbsolutePosition; + (*ppRet)->bOneWay = bOneWay; + typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName ); + (*ppRet)->nParams = nParams; + if( nParams ) + { + (*ppRet)->pParams = new typelib_MethodParameter[ nParams ]; + + for( sal_Int32 i = 0; i < nParams; i++ ) + { + // get the name of the parameter + (*ppRet)->pParams[ i ].pName = 0; + rtl_uString_acquire( (*ppRet)->pParams[ i ].pName = pParams[i].pParamName ); + (*ppRet)->pParams[ i ].pTypeRef = 0; + // get the type name of the parameter and create the weak reference + typelib_typedescriptionreference_new( + &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName ); + (*ppRet)->pParams[ i ].bIn = pParams[i].bIn; + (*ppRet)->pParams[ i ].bOut = pParams[i].bOut; + } + } + (*ppRet)->nExceptions = nExceptions; + (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames); + (*ppRet)->pInterface = pInterface; + (*ppRet)->pBaseRef = 0; + OSL_ASSERT( + (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers) + && nAbsolutePosition < pInterface->nAllMembers); + (*ppRet)->nIndex = nAbsolutePosition + - (pInterface->nAllMembers - pInterface->nMembers); + if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) ) + pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp; +} + + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_newInterfaceAttribute( + typelib_InterfaceAttributeTypeDescription ** ppRet, + sal_Int32 nAbsolutePosition, + rtl_uString * pTypeName, + typelib_TypeClass eAttributeTypeClass, + rtl_uString * pAttributeTypeName, + sal_Bool bReadOnly ) + SAL_THROW_EXTERN_C() +{ + typelib_typedescription_newExtendedInterfaceAttribute( + ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass, + pAttributeTypeName, bReadOnly, 0, 0, 0, 0); +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute( + typelib_InterfaceAttributeTypeDescription ** ppRet, + sal_Int32 nAbsolutePosition, + rtl_uString * pTypeName, + typelib_TypeClass eAttributeTypeClass, + rtl_uString * pAttributeTypeName, + sal_Bool bReadOnly, + sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames, + sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames ) + SAL_THROW_EXTERN_C() +{ + if (*ppRet != 0) { + typelib_typedescription_release(&(*ppRet)->aBase.aBase); + *ppRet = 0; + } + sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength( + pTypeName->buffer, pTypeName->length, ':'); + if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') { + OSL_ENSURE(false, "Bad interface attribute type name"); + return; + } + rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1); + typelib_InterfaceTypeDescription * pInterface = 0; + typelib_typedescription_getByName( + reinterpret_cast< typelib_TypeDescription ** >(&pInterface), + aInterfaceTypeName.pData); + if (pInterface == 0 + || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE + || !complete( + reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false)) + { + OSL_ENSURE(false, "No interface corresponding to interface attribute"); + return; + } + + typelib_typedescription_newEmpty( + (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName ); + typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet; + + rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName, + pTypeName->buffer + nOffset +1, + pTypeName->length - nOffset -1 ); + (*ppRet)->aBase.nPosition = nAbsolutePosition; + typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName ); + (*ppRet)->bReadOnly = bReadOnly; + (*ppRet)->pInterface = pInterface; + (*ppRet)->pBaseRef = 0; + OSL_ASSERT( + (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers) + && nAbsolutePosition < pInterface->nAllMembers); + (*ppRet)->nIndex = nAbsolutePosition + - (pInterface->nAllMembers - pInterface->nMembers); + (*ppRet)->nGetExceptions = nGetExceptions; + (*ppRet)->ppGetExceptions = copyExceptions( + nGetExceptions, ppGetExceptionNames); + (*ppRet)->nSetExceptions = nSetExceptions; + (*ppRet)->ppSetExceptions = copyExceptions( + nSetExceptions, ppSetExceptionNames); + if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) ) + pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp; +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_acquire( + typelib_TypeDescription * pTypeDescription ) + SAL_THROW_EXTERN_C() +{ + ::osl_incrementInterlockedCount( &pTypeDescription->nRefCount ); +} + +//------------------------------------------------------------------------ + +namespace { + +void deleteExceptions( + sal_Int32 count, typelib_TypeDescriptionReference ** exceptions) +{ + for (sal_Int32 i = 0; i < count; ++i) { + typelib_typedescriptionreference_release(exceptions[i]); + } + delete[] exceptions; +} + +} + +// frees anything except typelib_TypeDescription base! +static inline void typelib_typedescription_destructExtendedMembers( + typelib_TypeDescription * pTD ) + SAL_THROW( () ) +{ + OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass ); + + switch( pTD->eTypeClass ) + { + case typelib_TypeClass_ARRAY: + if( ((typelib_IndirectTypeDescription*)pTD)->pType ) + typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType ); + delete [] ((typelib_ArrayTypeDescription *)pTD)->pDimensions; + break; + case typelib_TypeClass_SEQUENCE: + if( ((typelib_IndirectTypeDescription*)pTD)->pType ) + typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType ); + break; + case typelib_TypeClass_UNION: + { + typelib_UnionTypeDescription * pUnionTD = (typelib_UnionTypeDescription *)pTD; + typelib_typedescriptionreference_release( pUnionTD->pDiscriminantTypeRef ); + typelib_typedescriptionreference_release( pUnionTD->pDefaultTypeRef ); + + sal_Int32 nPos; + typelib_TypeDescriptionReference ** ppTypeRefs = pUnionTD->ppTypeRefs; + for ( nPos = pUnionTD->nMembers; nPos--; ) + { + typelib_typedescriptionreference_release( ppTypeRefs[nPos] ); + } + + rtl_uString ** ppMemberNames = pUnionTD->ppMemberNames; + for ( nPos = pUnionTD->nMembers; nPos--; ) + { + rtl_uString_release( ppMemberNames[nPos] ); + } + delete [] pUnionTD->ppMemberNames; + delete [] pUnionTD->pDiscriminants; + delete [] pUnionTD->ppTypeRefs; + } + break; + case typelib_TypeClass_STRUCT: + delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)-> + pParameterizedTypes; + case typelib_TypeClass_EXCEPTION: + { + typelib_CompoundTypeDescription * pCTD = (typelib_CompoundTypeDescription*)pTD; + if( pCTD->pBaseTypeDescription ) + typelib_typedescription_release( (typelib_TypeDescription *)pCTD->pBaseTypeDescription ); + sal_Int32 i; + for( i = 0; i < pCTD->nMembers; i++ ) + { + typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] ); + } + if (pCTD->ppMemberNames) + { + for ( i = 0; i < pCTD->nMembers; i++ ) + { + rtl_uString_release( pCTD->ppMemberNames[i] ); + } + delete [] pCTD->ppMemberNames; + } + delete [] pCTD->ppTypeRefs; + delete [] pCTD->pMemberOffsets; + } + break; + case typelib_TypeClass_INTERFACE: + { + typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription*)pTD; + {for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ ) + { + typelib_typedescriptionreference_release( pITD->ppAllMembers[i] ); + }} + delete [] pITD->ppAllMembers; + delete [] pITD->pMapMemberIndexToFunctionIndex; + delete [] pITD->pMapFunctionIndexToMemberIndex; + {for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) { + typelib_typedescription_release( + reinterpret_cast< typelib_TypeDescription * >( + pITD->ppBaseTypes[i])); + }} + delete[] pITD->ppBaseTypes; + break; + } + case typelib_TypeClass_INTERFACE_METHOD: + { + typelib_InterfaceMethodTypeDescription * pIMTD = (typelib_InterfaceMethodTypeDescription*)pTD; + if( pIMTD->pReturnTypeRef ) + typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef ); + for( sal_Int32 i = 0; i < pIMTD->nParams; i++ ) + { + rtl_uString_release( pIMTD->pParams[ i ].pName ); + typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef ); + } + delete [] pIMTD->pParams; + deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions); + rtl_uString_release( pIMTD->aBase.pMemberName ); + typelib_typedescription_release(&pIMTD->pInterface->aBase); + if (pIMTD->pBaseRef != 0) { + typelib_typedescriptionreference_release(pIMTD->pBaseRef); + } + } + break; + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + typelib_InterfaceAttributeTypeDescription * pIATD = (typelib_InterfaceAttributeTypeDescription*)pTD; + deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions); + deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions); + if( pIATD->pAttributeTypeRef ) + typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef ); + if( pIATD->aBase.pMemberName ) + rtl_uString_release( pIATD->aBase.pMemberName ); + typelib_typedescription_release(&pIATD->pInterface->aBase); + if (pIATD->pBaseRef != 0) { + typelib_typedescriptionreference_release(pIATD->pBaseRef); + } + } + break; + case typelib_TypeClass_ENUM: + { + typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pTD; + for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; ) + { + rtl_uString_release( pEnum->ppEnumNames[nPos] ); + } + delete [] pEnum->ppEnumNames; + delete [] pEnum->pEnumValues; + } + break; + default: + break; + } +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_release( + typelib_TypeDescription * pTD ) + SAL_THROW_EXTERN_C() +{ + sal_Int32 ref = ::osl_decrementInterlockedCount( &pTD->nRefCount ); + OSL_ASSERT(ref >= 0); + if (0 == ref) + { + TypeDescriptor_Init_Impl &rInit = Init::get(); + if( reallyWeak( pTD->eTypeClass ) ) + { + if( pTD->pWeakRef ) + { + { + MutexGuard aGuard( rInit.getMutex() ); + // remove this description from the weak reference + pTD->pWeakRef->pType = 0; + } + typelib_typedescriptionreference_release( pTD->pWeakRef ); + } + } + else + { + // this description is a reference too, so remove it from the hash table + if( rInit.pWeakMap ) + { + MutexGuard aGuard( rInit.getMutex() ); + WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pTD->pTypeName->buffer ); + if( aIt != rInit.pWeakMap->end() && (void *)(*aIt).second == (void *)pTD ) + { + // remove only if it contains the same object + rInit.pWeakMap->erase( aIt ); + } + } + } + + typelib_typedescription_destructExtendedMembers( pTD ); + rtl_uString_release( pTD->pTypeName ); + +#if OSL_DEBUG_LEVEL > 1 + switch( pTD->eTypeClass ) + { + case typelib_TypeClass_ARRAY: + osl_decrementInterlockedCount( &rInit.nArrayTypeDescriptionCount ); + break; + case typelib_TypeClass_SEQUENCE: + osl_decrementInterlockedCount( &rInit.nIndirectTypeDescriptionCount ); + break; + case typelib_TypeClass_UNION: + osl_decrementInterlockedCount( &rInit.nUnionTypeDescriptionCount ); + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + osl_decrementInterlockedCount( &rInit.nCompoundTypeDescriptionCount ); + break; + case typelib_TypeClass_INTERFACE: + osl_decrementInterlockedCount( &rInit.nInterfaceTypeDescriptionCount ); + break; + case typelib_TypeClass_INTERFACE_METHOD: + osl_decrementInterlockedCount( &rInit.nInterfaceMethodTypeDescriptionCount ); + break; + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + osl_decrementInterlockedCount( &rInit.nInterfaceAttributeTypeDescriptionCount ); + break; + case typelib_TypeClass_ENUM: + osl_decrementInterlockedCount( &rInit.nEnumTypeDescriptionCount ); + break; + default: + osl_decrementInterlockedCount( &rInit.nTypeDescriptionCount ); + } +#endif + + delete pTD; + } +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescription_register( + typelib_TypeDescription ** ppNewDescription ) + SAL_THROW_EXTERN_C() +{ + // connect the description with the weak reference + TypeDescriptor_Init_Impl &rInit = Init::get(); + ClearableMutexGuard aGuard( rInit.getMutex() ); + + typelib_TypeDescriptionReference * pTDR = 0; + typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName ); + + OSL_ASSERT( (*ppNewDescription)->pWeakRef || reallyWeak( (*ppNewDescription)->eTypeClass ) ); + if( pTDR ) + { + OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass ); + if( pTDR->pType ) + { + if (reallyWeak( pTDR->eTypeClass )) + { + // pRef->pType->pWeakRef == 0 means that the description is empty + if (pTDR->pType->pWeakRef) + { + if (osl_incrementInterlockedCount( &pTDR->pType->nRefCount ) > 1) + { + // The refence is incremented. The object cannot be destroyed. + // Release the guard at the earliest point. + aGuard.clear(); + ::typelib_typedescription_release( *ppNewDescription ); + *ppNewDescription = pTDR->pType; + ::typelib_typedescriptionreference_release( pTDR ); + return; + } + else + { + // destruction of this type in progress (another thread!) + osl_decrementInterlockedCount( &pTDR->pType->nRefCount ); + } + } + // take new descr + pTDR->pType = *ppNewDescription; + OSL_ASSERT( ! (*ppNewDescription)->pWeakRef ); + (*ppNewDescription)->pWeakRef = pTDR; + return; + } + // !reallyWeak + + if (((void *)pTDR != (void *)*ppNewDescription) && // if different + (!pTDR->pType->pWeakRef || // uninit: ref data only set + // new one is complete: + (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) || + // new one may be partly initialized interface (except of tables): + (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass && + !((typelib_InterfaceTypeDescription *)pTDR->pType)->ppAllMembers && + (*(typelib_InterfaceTypeDescription **)ppNewDescription)->ppAllMembers))) + { + // uninitialized or incomplete + + if (pTDR->pType->pWeakRef) // if init + { + typelib_typedescription_destructExtendedMembers( pTDR->pType ); + } + + // pTDR->pType->pWeakRef == 0 means that the description is empty + // description is not weak and the not the same + sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass ); + + // copy all specific data for the descriptions + ::rtl_copyMemory( + pTDR->pType +1, + *ppNewDescription +1, + nSize - sizeof(typelib_TypeDescription) ); + + pTDR->pType->bComplete = (*ppNewDescription)->bComplete; + pTDR->pType->nSize = (*ppNewDescription)->nSize; + pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment; + + ::rtl_zeroMemory( + *ppNewDescription +1, nSize - sizeof( typelib_TypeDescription ) ); + + if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand ) + { + // switch from OnDemand to !OnDemand, so the description must be acquired + typelib_typedescription_acquire( pTDR->pType ); + } + else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand ) + { + // switch from !OnDemand to OnDemand, so the description must be relesed + typelib_typedescription_release( pTDR->pType ); + } + + pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand; + // initialized + pTDR->pType->pWeakRef = pTDR; + } + + typelib_typedescription_release( *ppNewDescription ); + // pTDR was acquired by getByName(), so it must not be acquired again + *ppNewDescription = pTDR->pType; + return; + } + } + else if( reallyWeak( (*ppNewDescription)->eTypeClass) ) + { + typelib_typedescriptionreference_new( + &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName ); + } + else + { + pTDR = (typelib_TypeDescriptionReference *)*ppNewDescription; + if( !rInit.pWeakMap ) + rInit.pWeakMap = new WeakMap_Impl; + + // description is the weak itself, so register it + (*rInit.pWeakMap)[pTDR->pTypeName->buffer] = pTDR; + OSL_ASSERT( (void *)*ppNewDescription == (void *)pTDR ); + } + + // By default this reference is not really weak. The reference hold the description + // and the description hold the reference. + if( !(*ppNewDescription)->bOnDemand ) + { + // nor OnDemand so the description must be acquired if registered + typelib_typedescription_acquire( *ppNewDescription ); + } + + pTDR->pType = *ppNewDescription; + (*ppNewDescription)->pWeakRef = pTDR; + OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 ); + OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass ); +} + +//------------------------------------------------------------------------ +static inline sal_Bool type_equals( + typelib_TypeDescriptionReference * p1, typelib_TypeDescriptionReference * p2 ) + SAL_THROW( () ) +{ + return (p1 == p2 || + (p1->eTypeClass == p2->eTypeClass && + p1->pTypeName->length == p2->pTypeName->length && + rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0)); +} +extern "C" sal_Bool SAL_CALL typelib_typedescription_equals( + const typelib_TypeDescription * p1, const typelib_TypeDescription * p2 ) + SAL_THROW_EXTERN_C() +{ + return type_equals( + (typelib_TypeDescriptionReference *)p1, (typelib_TypeDescriptionReference *)p2 ); +} + +//------------------------------------------------------------------------ +extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize( + const typelib_TypeDescription * pTypeDescription, + sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize ) + SAL_THROW_EXTERN_C() +{ + sal_Int32 nSize; + if( pTypeDescription->nSize ) + { + // size and alignment are set + rMaxIntegralTypeSize = pTypeDescription->nAlignment; + nSize = pTypeDescription->nSize; + } + else + { + nSize = 0; + rMaxIntegralTypeSize = 1; + + OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass ); + + switch( pTypeDescription->eTypeClass ) + { + case typelib_TypeClass_INTERFACE: + // FEATURE_INTERFACE + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * )); + break; + case typelib_TypeClass_UNION: + { + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof(sal_Int64)); + for ( sal_Int32 nPos = ((typelib_UnionTypeDescription *)pTypeDescription)->nMembers; nPos--; ) + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ((typelib_UnionTypeDescription *)pTypeDescription)->ppTypeRefs[nPos] ); + sal_Int32 nMaxIntegralTypeSize; + sal_Int32 nMemberSize = typelib_typedescription_getAlignedUnoSize( pTD, (sal_Int32)(sizeof(sal_Int64)), nMaxIntegralTypeSize ); + TYPELIB_DANGER_RELEASE( pTD ); + if (nSize < nMemberSize) + nSize = nMemberSize; + if (rMaxIntegralTypeSize < nMaxIntegralTypeSize) + rMaxIntegralTypeSize = nMaxIntegralTypeSize; + } + ((typelib_UnionTypeDescription *)pTypeDescription)->nValueOffset = rMaxIntegralTypeSize; + } + break; + case typelib_TypeClass_ENUM: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeClass )); + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + // FEATURE_EMPTYCLASS + { + typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription *)pTypeDescription; + sal_Int32 nStructSize = 0; + if( pTmp->pBaseTypeDescription ) + { + // inherit structs extends the base struct. + nStructSize = pTmp->pBaseTypeDescription->aBase.nSize; + rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment; + } + for( sal_Int32 i = 0; i < pTmp->nMembers; i++ ) + { + typelib_TypeDescription * pMemberType = 0; + typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i]; + + sal_Int32 nMaxIntegral; + if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE + || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE) + { + nMaxIntegral = (sal_Int32)(sizeof(void *)); + nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral ); + } + else + { + TYPELIB_DANGER_GET( &pMemberType, pMemberRef ); + nStructSize = typelib_typedescription_getAlignedUnoSize( + pMemberType, nStructSize, nMaxIntegral ); + TYPELIB_DANGER_RELEASE( pMemberType ); + } + if( nMaxIntegral > rMaxIntegralTypeSize ) + rMaxIntegralTypeSize = nMaxIntegral; + } +#ifdef __m68k__ + // Anything that is at least 16 bits wide is aligned on a 16-bit + // boundary on the m68k default abi + sal_Int32 nMaxAlign = (rMaxIntegralTypeSize > 2) ? 2 : rMaxIntegralTypeSize; + nStructSize = (nStructSize + nMaxAlign -1) / nMaxAlign * nMaxAlign; +#else + // Example: A { double; int; } structure has a size of 16 instead of 10. The + // compiler must follow this rule if it is possible to access members in arrays through: + // (Element *)((char *)pArray + sizeof( Element ) * ElementPos) + nStructSize = (nStructSize + rMaxIntegralTypeSize -1) + / rMaxIntegralTypeSize * rMaxIntegralTypeSize; +#endif + nSize += nStructSize; + } + break; + case typelib_TypeClass_ARRAY: + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescription)->pType ); + rMaxIntegralTypeSize = pTD->nSize; + TYPELIB_DANGER_RELEASE( pTD ); + nSize = ((typelib_ArrayTypeDescription *)pTypeDescription)->nTotalElements * rMaxIntegralTypeSize; + } + break; + case typelib_TypeClass_SEQUENCE: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * )); + break; + case typelib_TypeClass_ANY: + // FEATURE_ANY + nSize = (sal_Int32)(sizeof( uno_Any )); + rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * )); + break; + case typelib_TypeClass_TYPE: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeDescriptionReference * )); + break; + case typelib_TypeClass_BOOLEAN: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Bool )); + break; + case typelib_TypeClass_CHAR: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Unicode )); + break; + case typelib_TypeClass_STRING: + // FEATURE_STRING + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( rtl_uString * )); + break; + case typelib_TypeClass_FLOAT: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( float )); + break; + case typelib_TypeClass_DOUBLE: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( double )); + break; + case typelib_TypeClass_BYTE: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int8 )); + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int16 )); + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int32 )); + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int64 )); + break; + case typelib_TypeClass_UNKNOWN: + case typelib_TypeClass_SERVICE: + case typelib_TypeClass_MODULE: + default: + OSL_ENSURE( sal_False, "not convertable type" ); + }; + } + + return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize ); +} + +//------------------------------------------------------------------------ + +namespace { + +typelib_TypeDescriptionReference ** copyExceptions( + sal_Int32 count, typelib_TypeDescriptionReference ** source) +{ + typelib_TypeDescriptionReference ** p + = new typelib_TypeDescriptionReference *[count]; + for (sal_Int32 i = 0; i < count; ++i) { + typelib_typedescriptionreference_acquire(p[i] = source[i]); + } + return p; +} + +bool createDerivedInterfaceMemberDescription( + typelib_TypeDescription ** result, rtl::OUString const & name, + typelib_TypeDescriptionReference * baseRef, + typelib_TypeDescription const * base, typelib_TypeDescription * interface, + sal_Int32 index, sal_Int32 position) +{ + if (baseRef != 0 && base != 0 && interface != 0) { + switch (base->eTypeClass) { + case typelib_TypeClass_INTERFACE_METHOD: + { + typelib_typedescription_newEmpty( + result, typelib_TypeClass_INTERFACE_METHOD, name.pData); + typelib_InterfaceMethodTypeDescription const * baseMethod + = reinterpret_cast< + typelib_InterfaceMethodTypeDescription const * >(base); + typelib_InterfaceMethodTypeDescription * newMethod + = reinterpret_cast< + typelib_InterfaceMethodTypeDescription * >(*result); + newMethod->aBase.nPosition = position; + rtl_uString_acquire( + newMethod->aBase.pMemberName + = baseMethod->aBase.pMemberName); + typelib_typedescriptionreference_acquire( + newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef); + newMethod->nParams = baseMethod->nParams; + newMethod->pParams = new typelib_MethodParameter[ + newMethod->nParams]; + for (sal_Int32 i = 0; i < newMethod->nParams; ++i) { + rtl_uString_acquire( + newMethod->pParams[i].pName + = baseMethod->pParams[i].pName); + typelib_typedescriptionreference_acquire( + newMethod->pParams[i].pTypeRef + = baseMethod->pParams[i].pTypeRef); + newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn; + newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut; + } + newMethod->nExceptions = baseMethod->nExceptions; + newMethod->ppExceptions = copyExceptions( + baseMethod->nExceptions, baseMethod->ppExceptions); + newMethod->bOneWay = baseMethod->bOneWay; + newMethod->pInterface + = reinterpret_cast< typelib_InterfaceTypeDescription * >( + interface); + newMethod->pBaseRef = baseRef; + newMethod->nIndex = index; + return true; + } + + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + typelib_typedescription_newEmpty( + result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData); + typelib_InterfaceAttributeTypeDescription const * baseAttribute + = reinterpret_cast< + typelib_InterfaceAttributeTypeDescription const * >(base); + typelib_InterfaceAttributeTypeDescription * newAttribute + = reinterpret_cast< + typelib_InterfaceAttributeTypeDescription * >(*result); + newAttribute->aBase.nPosition = position; + rtl_uString_acquire( + newAttribute->aBase.pMemberName + = baseAttribute->aBase.pMemberName); + newAttribute->bReadOnly = baseAttribute->bReadOnly; + typelib_typedescriptionreference_acquire( + newAttribute->pAttributeTypeRef + = baseAttribute->pAttributeTypeRef); + newAttribute->pInterface + = reinterpret_cast< typelib_InterfaceTypeDescription * >( + interface); + newAttribute->pBaseRef = baseRef; + newAttribute->nIndex = index; + newAttribute->nGetExceptions = baseAttribute->nGetExceptions; + newAttribute->ppGetExceptions = copyExceptions( + baseAttribute->nGetExceptions, + baseAttribute->ppGetExceptions); + newAttribute->nSetExceptions = baseAttribute->nSetExceptions; + newAttribute->ppSetExceptions = copyExceptions( + baseAttribute->nSetExceptions, + baseAttribute->ppSetExceptions); + return true; + } + + default: + break; + } + } + return false; +} + +} + +extern "C" void SAL_CALL typelib_typedescription_getByName( + typelib_TypeDescription ** ppRet, rtl_uString * pName ) + SAL_THROW_EXTERN_C() +{ + if( *ppRet ) + { + typelib_typedescription_release( (*ppRet) ); + *ppRet = 0; + } + + static sal_Bool bInited = sal_False; + TypeDescriptor_Init_Impl &rInit = Init::get(); + + if( !bInited ) + { + // guard against multi thread access + MutexGuard aGuard( rInit.getMutex() ); + if( !bInited ) + { + // avoid recursion during the next ...new calls + bInited = sal_True; + + rtl_uString * pTypeName = 0; + typelib_TypeDescription * pType = 0; + rtl_uString_newFromAscii( &pTypeName, "type" ); + typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "void" ); + typelib_typedescription_new( &pType, typelib_TypeClass_VOID, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "boolean" ); + typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "char" ); + typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "byte" ); + typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "string" ); + typelib_typedescription_new( &pType, typelib_TypeClass_STRING, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "short" ); + typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "unsigned short" ); + typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "long" ); + typelib_typedescription_new( &pType, typelib_TypeClass_LONG, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "unsigned long" ); + typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "hyper" ); + typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "unsigned hyper" ); + typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "float" ); + typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "double" ); + typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + rtl_uString_newFromAscii( &pTypeName, "any" ); + typelib_typedescription_new( &pType, typelib_TypeClass_ANY, pTypeName, 0, 0, 0 ); + typelib_typedescription_register( &pType ); + typelib_typedescription_release( pType ); + rtl_uString_release( pTypeName ); + } + } + + typelib_TypeDescriptionReference * pTDR = 0; + typelib_typedescriptionreference_getByName( &pTDR, pName ); + if( pTDR ) + { + { + // guard against multi thread access + MutexGuard aGuard( rInit.getMutex() ); + // pTDR->pType->pWeakRef == 0 means that the description is empty + if( pTDR->pType && pTDR->pType->pWeakRef ) + { + typelib_typedescription_acquire( pTDR->pType ); + *ppRet = pTDR->pType; + } + } + typelib_typedescriptionreference_release( pTDR ); + } + + if (0 == *ppRet) + { + // check for sequence + OUString const & name = *reinterpret_cast< OUString const * >( &pName ); + if (2 < name.getLength() && '[' == name[ 0 ]) + { + OUString element_name( name.copy( 2 ) ); + typelib_TypeDescription * element_td = 0; + typelib_typedescription_getByName( &element_td, element_name.pData ); + if (0 != element_td) + { + typelib_typedescription_new( + ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, 0 ); + // register? + typelib_typedescription_release( element_td ); + } + } + if (0 == *ppRet) + { + // Check for derived interface member type: + sal_Int32 i1 = name.lastIndexOf( + rtl::OUString::createFromAscii(":@")); + if (i1 >= 0) { + sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@"); + sal_Int32 i3 = name.indexOf(',', i2); + if (i3 >= 0) { + sal_Int32 i4 = name.indexOf(':', i3); + if (i4 >= 0) { + typelib_TypeDescriptionReference * pBaseRef = 0; + typelib_TypeDescription * pBase = 0; + typelib_TypeDescription * pInterface = 0; + typelib_typedescriptionreference_getByName( + &pBaseRef, name.copy(0, i1).pData); + if (pBaseRef != 0) { + typelib_typedescriptionreference_getDescription( + &pBase, pBaseRef); + } + typelib_typedescription_getByName( + &pInterface, name.copy(i4 + 1).pData); + if (!createDerivedInterfaceMemberDescription( + ppRet, name, pBaseRef, pBase, pInterface, + name.copy(i2, i3 - i2).toInt32(), + name.copy(i3 + 1, i4 - i3 - 1).toInt32())) + { + if (pInterface != 0) { + typelib_typedescription_release(pInterface); + } + if (pBase != 0) { + typelib_typedescription_release(pBase); + } + if (pBaseRef != 0) { + typelib_typedescriptionreference_release( + pBaseRef); + } + } + } + } + } + } + if (0 == *ppRet) + { + // on demand access + rInit.callChain( ppRet, pName ); + } + + if( *ppRet ) + { + // typedescription found + if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass) + { + typelib_TypeDescription * pTD = 0; + typelib_typedescriptionreference_getDescription( + &pTD, ((typelib_IndirectTypeDescription *)*ppRet)->pType ); + typelib_typedescription_release( *ppRet ); + *ppRet = pTD; + } + else + { + // set to on demand + (*ppRet)->bOnDemand = sal_True; + // The type description is hold by the reference until + // on demand is activated. + typelib_typedescription_register( ppRet ); + + // insert into the chache + MutexGuard aGuard( rInit.getMutex() ); + if( !rInit.pCache ) + rInit.pCache = new TypeDescriptionList_Impl; + if( (sal_Int32)rInit.pCache->size() >= nCacheSize ) + { + typelib_typedescription_release( rInit.pCache->front() ); + rInit.pCache->pop_front(); + } + // descriptions in the cache must be acquired! + typelib_typedescription_acquire( *ppRet ); + rInit.pCache->push_back( *ppRet ); + } + } + } +} + + +//------------------------------------------------------------------------ +//------------------------------------------------------------------------ +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescriptionreference_newByAsciiName( + typelib_TypeDescriptionReference ** ppTDR, + typelib_TypeClass eTypeClass, + const sal_Char * pTypeName ) + SAL_THROW_EXTERN_C() +{ + OUString aTypeName( OUString::createFromAscii( pTypeName ) ); + typelib_typedescriptionreference_new( ppTDR, eTypeClass, aTypeName.pData ); +} +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescriptionreference_new( + typelib_TypeDescriptionReference ** ppTDR, + typelib_TypeClass eTypeClass, rtl_uString * pTypeName ) + SAL_THROW_EXTERN_C() +{ + TypeDescriptor_Init_Impl &rInit = Init::get(); + if( eTypeClass == typelib_TypeClass_TYPEDEF ) + { + // on demand access + typelib_TypeDescription * pRet = 0; + rInit.callChain( &pRet, pTypeName ); + if( pRet ) + { + // typedescription found + if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass) + { + typelib_typedescriptionreference_acquire( + ((typelib_IndirectTypeDescription *)pRet)->pType ); + if (*ppTDR) + typelib_typedescriptionreference_release( *ppTDR ); + *ppTDR = ((typelib_IndirectTypeDescription *)pRet)->pType; + typelib_typedescription_release( pRet ); + } + else + { + // set to on demand + pRet->bOnDemand = sal_True; + // The type description is hold by the reference until + // on demand is activated. + typelib_typedescription_register( &pRet ); + + // insert into the chache + MutexGuard aGuard( rInit.getMutex() ); + if( !rInit.pCache ) + rInit.pCache = new TypeDescriptionList_Impl; + if( (sal_Int32)rInit.pCache->size() >= nCacheSize ) + { + typelib_typedescription_release( rInit.pCache->front() ); + rInit.pCache->pop_front(); + } + rInit.pCache->push_back( pRet ); + // pRet kept acquired for cache + + typelib_typedescriptionreference_acquire( pRet->pWeakRef ); + if (*ppTDR) + typelib_typedescriptionreference_release( *ppTDR ); + *ppTDR = pRet->pWeakRef; + } + } + else if (*ppTDR) + { +#if OSL_DEBUG_LEVEL > 1 + OString aStr( OUStringToOString( pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_ENSURE( !"### typedef not found: ", aStr.getStr() ); +#endif + typelib_typedescriptionreference_release( *ppTDR ); + *ppTDR = 0; + } + return; + } + + MutexGuard aGuard( rInit.getMutex() ); + typelib_typedescriptionreference_getByName( ppTDR, pTypeName ); + if( *ppTDR ) + return; + + if( reallyWeak( eTypeClass ) ) + { + typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference(); +#if OSL_DEBUG_LEVEL > 1 + osl_incrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount ); +#endif + pTDR->nRefCount = 1; + pTDR->nStaticRefCount = 0; + pTDR->eTypeClass = eTypeClass; + pTDR->pUniqueIdentifier = 0; + pTDR->pReserved = 0; + rtl_uString_acquire( pTDR->pTypeName = pTypeName ); + pTDR->pType = 0; + *ppTDR = pTDR; + } + else + { + typelib_typedescription_newEmpty( (typelib_TypeDescription ** )ppTDR, eTypeClass, pTypeName ); + // description will be registered but not acquired + (*(typelib_TypeDescription ** )ppTDR)->bOnDemand = sal_True; + (*(typelib_TypeDescription ** )ppTDR)->bComplete = sal_False; + } + + if( !rInit.pWeakMap ) + rInit.pWeakMap = new WeakMap_Impl; + // Heavy hack, the const sal_Unicode * is hold by the typedescription reference + // not registered + rInit.pWeakMap->operator[]( (*ppTDR)->pTypeName->buffer ) = *ppTDR; +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescriptionreference_acquire( + typelib_TypeDescriptionReference * pRef ) + SAL_THROW_EXTERN_C() +{ + ::osl_incrementInterlockedCount( &pRef->nRefCount ); +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescriptionreference_release( + typelib_TypeDescriptionReference * pRef ) + SAL_THROW_EXTERN_C() +{ + // Is it a type description? + if( reallyWeak( pRef->eTypeClass ) ) + { + if( ! ::osl_decrementInterlockedCount( &pRef->nRefCount ) ) + { + TypeDescriptor_Init_Impl &rInit = Init::get(); + if( rInit.pWeakMap ) + { + MutexGuard aGuard( rInit.getMutex() ); + WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pRef->pTypeName->buffer ); + if( !(aIt == rInit.pWeakMap->end()) && (*aIt).second == pRef ) + { + // remove only if it contains the same object + rInit.pWeakMap->erase( aIt ); + } + } + + rtl_uString_release( pRef->pTypeName ); + OSL_ASSERT( pRef->pType == 0 ); +#if OSL_DEBUG_LEVEL > 1 + osl_decrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount ); +#endif + delete pRef; + } + } + else + { + typelib_typedescription_release( (typelib_TypeDescription *)pRef ); + } +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescriptionreference_getDescription( + typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef ) + SAL_THROW_EXTERN_C() +{ + if( *ppRet ) + { + typelib_typedescription_release( *ppRet ); + *ppRet = 0; + } + + if( !reallyWeak( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef ) + { + // reference is a description and initialized + osl_incrementInterlockedCount( &((typelib_TypeDescription *)pRef)->nRefCount ); + *ppRet = (typelib_TypeDescription *)pRef; + return; + } + + { + MutexGuard aGuard( Init::get().getMutex() ); + // pRef->pType->pWeakRef == 0 means that the description is empty + if( pRef->pType && pRef->pType->pWeakRef ) + { + sal_Int32 n = ::osl_incrementInterlockedCount( &pRef->pType->nRefCount ); + if( n > 1 ) + { + // The refence is incremented. The object cannot be destroyed. + // Release the guard at the earliest point. + *ppRet = pRef->pType; + return; + } + else + { + ::osl_decrementInterlockedCount( &pRef->pType->nRefCount ); + // detruction of this type in progress (another thread!) + // no acces through this weak reference + pRef->pType = 0; + } + } + } + + typelib_typedescription_getByName( ppRet, pRef->pTypeName ); + OSL_ASSERT( !*ppRet || rtl_ustr_compare( pRef->pTypeName->buffer, (*ppRet)->pTypeName->buffer ) == 0 ); + OSL_ASSERT( !*ppRet || pRef->eTypeClass == (*ppRet)->eTypeClass ); + OSL_ASSERT( !*ppRet || pRef == (*ppRet)->pWeakRef ); + pRef->pType = *ppRet; +} + +//------------------------------------------------------------------------ +extern "C" void SAL_CALL typelib_typedescriptionreference_getByName( + typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName ) + SAL_THROW_EXTERN_C() +{ + if( *ppRet ) + { + typelib_typedescriptionreference_release( *ppRet ); + *ppRet = 0; + } + TypeDescriptor_Init_Impl &rInit = Init::get(); + if( rInit.pWeakMap ) + { + MutexGuard aGuard( rInit.getMutex() ); + WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pName->buffer ); + if( !(aIt == rInit.pWeakMap->end()) ) // != failed on msc4.2 + { + sal_Int32 n = ::osl_incrementInterlockedCount( &(*aIt).second->nRefCount ); + if( n > 1 ) + { + // The refence is incremented. The object cannot be destroyed. + // Release the guard at the earliest point. + *ppRet = (*aIt).second; + } + else + { + // detruction of this type in progress (another thread!) + // no acces through this weak reference + ::osl_decrementInterlockedCount( &(*aIt).second->nRefCount ); + } + } + } +} + +//------------------------------------------------------------------------ +extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_equals( + const typelib_TypeDescriptionReference * p1, + const typelib_TypeDescriptionReference * p2 ) + SAL_THROW_EXTERN_C() +{ + return (p1 == p2 || + (p1->eTypeClass == p2->eTypeClass && + p1->pTypeName->length == p2->pTypeName->length && + rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0)); +} + +//################################################################################################## +extern "C" void SAL_CALL typelib_typedescriptionreference_assign( + typelib_TypeDescriptionReference ** ppDest, + typelib_TypeDescriptionReference * pSource ) + SAL_THROW_EXTERN_C() +{ + if (*ppDest != pSource) + { + ::typelib_typedescriptionreference_acquire( pSource ); + ::typelib_typedescriptionreference_release( *ppDest ); + *ppDest = pSource; + } +} + +//################################################################################################## +extern "C" void SAL_CALL typelib_setCacheSize( sal_Int32 nNewSize ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( nNewSize >= 0, "### illegal cache size given!" ); + if (nNewSize >= 0) + { + TypeDescriptor_Init_Impl &rInit = Init::get(); + MutexGuard aGuard( rInit.getMutex() ); + if ((nNewSize < nCacheSize) && rInit.pCache) + { + while ((sal_Int32)rInit.pCache->size() != nNewSize) + { + typelib_typedescription_release( rInit.pCache->front() ); + rInit.pCache->pop_front(); + } + } + nCacheSize = nNewSize; + } +} + + +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, 0, 0, 0, 0, 1, 0 }, +/* TypeClass_DOUBLE */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1 } +}; + +//################################################################################################## +extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom( + typelib_TypeDescriptionReference * pAssignable, + typelib_TypeDescriptionReference * pFrom ) + SAL_THROW_EXTERN_C() +{ + if (pAssignable && pFrom) + { + typelib_TypeClass eAssignable = pAssignable->eTypeClass; + typelib_TypeClass eFrom = pFrom->eTypeClass; + + if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .) + return sal_True; + if (eAssignable == eFrom) + { + if (type_equals( pAssignable, pFrom )) // first shot + { + return sal_True; + } + else + { + switch (eAssignable) + { + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pFromDescr = 0; + TYPELIB_DANGER_GET( &pFromDescr, pFrom ); + if (! ((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription) + { + TYPELIB_DANGER_RELEASE( pFromDescr ); + return sal_False; + } + sal_Bool bRet = typelib_typedescriptionreference_isAssignableFrom( + pAssignable, + ((typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)->pWeakRef ); + TYPELIB_DANGER_RELEASE( pFromDescr ); + return bRet; + } + case typelib_TypeClass_INTERFACE: + { + typelib_TypeDescription * pFromDescr = 0; + TYPELIB_DANGER_GET( &pFromDescr, pFrom ); + typelib_InterfaceTypeDescription * pFromIfc + = reinterpret_cast< + typelib_InterfaceTypeDescription * >(pFromDescr); + bool bRet = false; + for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) { + if (typelib_typedescriptionreference_isAssignableFrom( + pAssignable, + pFromIfc->ppBaseTypes[i]->aBase.pWeakRef)) + { + bRet = true; + break; + } + } + TYPELIB_DANGER_RELEASE( pFromDescr ); + return bRet; + } + default: + { + return sal_False; + } + } + } + } + return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE && + eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE && + s_aAssignableFromTab[eAssignable-1][eFrom-1]); + } + return sal_False; +} +//################################################################################################## +extern "C" sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom( + typelib_TypeDescription * pAssignable, + typelib_TypeDescription * pFrom ) + SAL_THROW_EXTERN_C() +{ + return typelib_typedescriptionreference_isAssignableFrom( + pAssignable->pWeakRef, pFrom->pWeakRef ); +} + +//################################################################################################## +extern "C" sal_Bool SAL_CALL typelib_typedescription_complete( + typelib_TypeDescription ** ppTypeDescr ) + SAL_THROW_EXTERN_C() +{ + return complete(ppTypeDescr, true); +} diff --git a/cppu/source/uno/EnvDcp.c b/cppu/source/uno/EnvDcp.c new file mode 100644 index 000000000000..7fb9a0e0ee68 --- /dev/null +++ b/cppu/source/uno/EnvDcp.c @@ -0,0 +1,49 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "uno/EnvDcp.h" + + +void uno_EnvDcp_getTypeName(rtl_uString const * pEnvDcp, rtl_uString ** ppEnvTypeName) +{ + sal_Int32 colIdx = rtl_ustr_indexOfChar_WithLength(pEnvDcp->buffer, pEnvDcp->length, ':'); + if (colIdx >= 0) + rtl_uString_newFromStr_WithLength(ppEnvTypeName, pEnvDcp->buffer, colIdx); + + else + rtl_uString_newFromStr(ppEnvTypeName, pEnvDcp->buffer); +} + +void uno_EnvDcp_getPurpose(rtl_uString const * pEnvDcp, rtl_uString ** ppEnvPurpose) +{ + sal_Int32 colIdx = rtl_ustr_indexOfChar_WithLength(pEnvDcp->buffer, pEnvDcp->length, ':'); + if (colIdx >= 0) + rtl_uString_newFromStr_WithLength(ppEnvPurpose, pEnvDcp->buffer + colIdx, pEnvDcp->length - colIdx); + + else + rtl_uString_new(ppEnvPurpose); +} diff --git a/cppu/source/uno/EnvStack.cxx b/cppu/source/uno/EnvStack.cxx new file mode 100644 index 000000000000..b7cefd42b4da --- /dev/null +++ b/cppu/source/uno/EnvStack.cxx @@ -0,0 +1,380 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "uno/environment.hxx" + +#include "cppu/EnvDcp.hxx" +#include "cppu/Enterable.hxx" + +#include "osl/thread.h" +#include "osl/mutex.hxx" + +#include <hash_map> + + +using namespace com::sun::star; + + +struct SAL_DLLPRIVATE oslThreadIdentifier_equal +{ + bool operator()(oslThreadIdentifier s1, oslThreadIdentifier s2) const; +}; + +bool oslThreadIdentifier_equal::operator()(oslThreadIdentifier s1, oslThreadIdentifier s2) const +{ + bool result = s1 == s2; + + return result; +} + + +struct SAL_DLLPRIVATE oslThreadIdentifier_hash +{ + size_t operator()(oslThreadIdentifier s1) const; +}; + +size_t oslThreadIdentifier_hash::operator()(oslThreadIdentifier s1) const +{ + return s1; +} + +typedef ::std::hash_map<oslThreadIdentifier, + uno_Environment *, + oslThreadIdentifier_hash, + oslThreadIdentifier_equal> ThreadMap; + +static osl::Mutex s_threadMap_mutex; +static ThreadMap s_threadMap; + + +static rtl::OUString s_uno_envDcp(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO)); + +static void s_setCurrent(uno_Environment * pEnv) +{ + oslThreadIdentifier threadId = osl_getThreadIdentifier(NULL); + + osl::MutexGuard guard(s_threadMap_mutex); + if (pEnv) + s_threadMap[threadId] = pEnv; + + else + { + ThreadMap::iterator iEnv = s_threadMap.find(threadId); + s_threadMap.erase(iEnv); + } +} + +static uno_Environment * s_getCurrent(void) +{ + uno_Environment * pEnv = NULL; + + oslThreadIdentifier threadId = osl_getThreadIdentifier(NULL); + + osl::MutexGuard guard(s_threadMap_mutex); + ThreadMap::iterator iEnv = s_threadMap.find(threadId); + if(iEnv != s_threadMap.end()) + pEnv = iEnv->second; + + return pEnv; +} + + +extern "C" void SAL_CALL uno_getCurrentEnvironment(uno_Environment ** ppEnv, rtl_uString * pTypeName) + SAL_THROW_EXTERN_C() +{ + if (*ppEnv) + { + (*ppEnv)->release(*ppEnv); + *ppEnv = NULL; + } + + rtl::OUString currPurpose; + + uno_Environment * pCurrEnv = s_getCurrent(); + if (pCurrEnv) // no environment means no purpose + currPurpose = cppu::EnvDcp::getPurpose(pCurrEnv->pTypeName); + + if (pTypeName && rtl_uString_getLength(pTypeName)) + { + rtl::OUString envDcp(pTypeName); + envDcp += currPurpose; + + uno_getEnvironment(ppEnv, envDcp.pData, NULL); + } + else + { + if (pCurrEnv) + { + *ppEnv = pCurrEnv; + (*ppEnv)->acquire(*ppEnv); + } + else + uno_getEnvironment(ppEnv, s_uno_envDcp.pData, NULL); + + } +} + +static rtl::OUString s_getPrefix(rtl::OUString const & str1, rtl::OUString const & str2) +{ + sal_Int32 nIndex1 = 0; + sal_Int32 nIndex2 = 0; + sal_Int32 sim = 0; + + rtl::OUString token1; + rtl::OUString token2; + + do + { + token1 = str1.getToken(0, ':', nIndex1); + token2 = str2.getToken(0, ':', nIndex2); + + if (token1.equals(token2)) + sim += token1.getLength() + 1; + } + while(nIndex1 == nIndex2 && nIndex1 >= 0 && token1.equals(token2)); + + rtl::OUString result; + + if (sim) + result = str1.copy(0, sim - 1); + + return result; +} + +static int s_getNextEnv(uno_Environment ** ppEnv, uno_Environment * pCurrEnv, uno_Environment * pTargetEnv) +{ + int res = 0; + + rtl::OUString nextPurpose; + + rtl::OUString currPurpose; + if (pCurrEnv) + currPurpose = cppu::EnvDcp::getPurpose(pCurrEnv->pTypeName); + + rtl::OUString targetPurpose; + if (pTargetEnv) + targetPurpose = cppu::EnvDcp::getPurpose(pTargetEnv->pTypeName); + + rtl::OUString intermPurpose(s_getPrefix(currPurpose, targetPurpose)); + if (currPurpose.getLength() > intermPurpose.getLength()) + { + sal_Int32 idx = currPurpose.lastIndexOf(':'); + nextPurpose = currPurpose.copy(0, idx); + + res = -1; + } + else if (intermPurpose.getLength() < targetPurpose.getLength()) + { + sal_Int32 idx = targetPurpose.indexOf(':', intermPurpose.getLength() + 1); + if (idx == -1) + nextPurpose = targetPurpose; + + else + nextPurpose = targetPurpose.copy(0, idx); + + res = 1; + } + + if (nextPurpose.getLength()) + { + rtl::OUString next_envDcp(s_uno_envDcp); + next_envDcp += nextPurpose; + + uno_getEnvironment(ppEnv, next_envDcp.pData, NULL); + } + else + { + if (*ppEnv) + (*ppEnv)->release(*ppEnv); + + *ppEnv = NULL; + } + + return res; +} + +extern "C" { static void s_pull(va_list * pParam) +{ + uno_EnvCallee * pCallee = va_arg(*pParam, uno_EnvCallee *); + va_list * pXparam = va_arg(*pParam, va_list *); + + pCallee(pXparam); +}} + +static void s_callInto_v(uno_Environment * pEnv, uno_EnvCallee * pCallee, va_list * pParam) +{ + cppu::Enterable * pEnterable = reinterpret_cast<cppu::Enterable *>(pEnv->pReserved); + if (pEnterable) + pEnterable->callInto(s_pull, pCallee, pParam); + + else + pCallee(pParam); +} + +static void s_callInto(uno_Environment * pEnv, uno_EnvCallee * pCallee, ...) +{ + va_list param; + + va_start(param, pCallee); + s_callInto_v(pEnv, pCallee, ¶m); + va_end(param); +} + +static void s_callOut_v(uno_Environment * pEnv, uno_EnvCallee * pCallee, va_list * pParam) +{ + cppu::Enterable * pEnterable = reinterpret_cast<cppu::Enterable *>(pEnv->pReserved); + if (pEnterable) + pEnterable->callOut_v(pCallee, pParam); + + else + pCallee(pParam); +} + +static void s_callOut(uno_Environment * pEnv, uno_EnvCallee * pCallee, ...) +{ + va_list param; + + va_start(param, pCallee); + s_callOut_v(pEnv, pCallee, ¶m); + va_end(param); +} + +static void s_environment_invoke_v(uno_Environment *, uno_Environment *, uno_EnvCallee *, va_list *); + +extern "C" { static void s_environment_invoke_vv(va_list * pParam) +{ + uno_Environment * pCurrEnv = va_arg(*pParam, uno_Environment *); + uno_Environment * pTargetEnv = va_arg(*pParam, uno_Environment *); + uno_EnvCallee * pCallee = va_arg(*pParam, uno_EnvCallee *); + va_list * pXparam = va_arg(*pParam, va_list *); + + s_environment_invoke_v(pCurrEnv, pTargetEnv, pCallee, pXparam); +}} + +static void s_environment_invoke_v(uno_Environment * pCurrEnv, uno_Environment * pTargetEnv, uno_EnvCallee * pCallee, va_list * pParam) +{ + uno_Environment * pNextEnv = NULL; + switch(s_getNextEnv(&pNextEnv, pCurrEnv, pTargetEnv)) + { + case -1: + s_setCurrent(pNextEnv); + s_callOut(pCurrEnv, s_environment_invoke_vv, pNextEnv, pTargetEnv, pCallee, pParam); + s_setCurrent(pCurrEnv); + break; + + case 0: { + uno_Environment * hld = s_getCurrent(); + s_setCurrent(pCurrEnv); + pCallee(pParam); + s_setCurrent(hld); + } + break; + + case 1: + s_setCurrent(pNextEnv); + s_callInto(pNextEnv, s_environment_invoke_vv, pNextEnv, pTargetEnv, pCallee, pParam); + s_setCurrent(pCurrEnv); + break; + } + + if (pNextEnv) + pNextEnv->release(pNextEnv); +} + +extern "C" void SAL_CALL uno_Environment_invoke_v(uno_Environment * pTargetEnv, uno_EnvCallee * pCallee, va_list * pParam) + SAL_THROW_EXTERN_C() +{ + s_environment_invoke_v(s_getCurrent(), pTargetEnv, pCallee, pParam); +} + +extern "C" void SAL_CALL uno_Environment_invoke(uno_Environment * pEnv, uno_EnvCallee * pCallee, ...) + SAL_THROW_EXTERN_C() +{ + va_list param; + + va_start(param, pCallee); + uno_Environment_invoke_v(pEnv, pCallee, ¶m); + va_end(param); +} + +extern "C" void SAL_CALL uno_Environment_enter(uno_Environment * pTargetEnv) + SAL_THROW_EXTERN_C() +{ + uno_Environment * pNextEnv = NULL; + uno_Environment * pCurrEnv = s_getCurrent(); + + int res; + while ( (res = s_getNextEnv(&pNextEnv, pCurrEnv, pTargetEnv)) != 0) + { + cppu::Enterable * pEnterable; + + switch(res) + { + case -1: + pEnterable = reinterpret_cast<cppu::Enterable *>(pCurrEnv->pReserved); + if (pEnterable) + pEnterable->leave(); + pCurrEnv->release(pCurrEnv); + break; + + case 1: + pNextEnv->acquire(pNextEnv); + pEnterable = reinterpret_cast<cppu::Enterable *>(pNextEnv->pReserved); + if (pEnterable) + pEnterable->enter(); + break; + } + + s_setCurrent(pNextEnv); + pCurrEnv = pNextEnv; + } +} + +int SAL_CALL uno_Environment_isValid(uno_Environment * pEnv, rtl_uString ** pReason) + SAL_THROW_EXTERN_C() +{ + int result = 1; + + rtl::OUString typeName(cppu::EnvDcp::getTypeName(pEnv->pTypeName)); + if (typeName.equals(s_uno_envDcp)) + { + cppu::Enterable * pEnterable = reinterpret_cast<cppu::Enterable *>(pEnv->pReserved); + if (pEnterable) + result = pEnterable->isValid((rtl::OUString *)pReason); + } + else + { + rtl::OUString envDcp(s_uno_envDcp); + envDcp += cppu::EnvDcp::getPurpose(pEnv->pTypeName); + + uno::Environment env(envDcp); + + result = env.isValid((rtl::OUString *)pReason); + } + + return result; +} diff --git a/cppu/source/uno/IdentityMapping.cxx b/cppu/source/uno/IdentityMapping.cxx new file mode 100644 index 000000000000..64721e2993ca --- /dev/null +++ b/cppu/source/uno/IdentityMapping.cxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "IdentityMapping.hxx" + +#include "uno/mapping.h" +#include "uno/environment.hxx" + +#include "osl/interlck.h" + + +using namespace ::com::sun::star; + +struct IdentityMapping : public uno_Mapping +{ + sal_Int32 m_nRef; + uno::Environment m_env; + + IdentityMapping(uno::Environment const & rEnv); +}; + +extern "C" +{ + +static void SAL_CALL s_free(uno_Mapping * pMapping) SAL_THROW(()) +{ + delete static_cast<IdentityMapping *>(pMapping); +} + +static void SAL_CALL s_acquire(uno_Mapping * pMapping) SAL_THROW(()) +{ + static rtl::OUString s_purpose; + + if (1 == ::osl_incrementInterlockedCount(&static_cast<IdentityMapping *>(pMapping)->m_nRef)) + { + uno_registerMapping( + &pMapping, + s_free, + static_cast<IdentityMapping *>(pMapping)->m_env.get(), + static_cast<IdentityMapping *>(pMapping)->m_env.get(), + s_purpose.pData); + } +} + +static void SAL_CALL s_release(uno_Mapping * pMapping) SAL_THROW(()) +{ + if (!::osl_decrementInterlockedCount(&static_cast<IdentityMapping *>(pMapping )->m_nRef)) + uno_revokeMapping(pMapping); +} + +static void SAL_CALL s_mapInterface(uno_Mapping * pMapping, + void ** ppOut, + void * pInterface, + struct _typelib_InterfaceTypeDescription * /*pInterfaceTypeDescr*/) + SAL_THROW(()) +{ + *ppOut = pInterface; + + if (pInterface) + { + IdentityMapping * that = static_cast<IdentityMapping *>(pMapping); + + (that->m_env.get()->pExtEnv->acquireInterface)(that->m_env.get()->pExtEnv, pInterface); + } +} +} + + +IdentityMapping::IdentityMapping(uno::Environment const & rEnv) + : m_nRef(0), + m_env(rEnv) +{ + uno_Mapping::acquire = s_acquire; + uno_Mapping::release = s_release; + uno_Mapping::mapInterface = s_mapInterface; +} + + +uno_Mapping * createIdentityMapping(uno::Environment const & rEnv) SAL_THROW(()) +{ + return new IdentityMapping(rEnv); +} diff --git a/cppu/source/uno/IdentityMapping.hxx b/cppu/source/uno/IdentityMapping.hxx new file mode 100644 index 000000000000..cf95a30b203c --- /dev/null +++ b/cppu/source/uno/IdentityMapping.hxx @@ -0,0 +1,39 @@ +/************************************************************************* + * + * 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 INCLUDED_IdentityMapping_hxx +#define INCLUDED_IdentityMapping_hxx + +#include "uno/mapping.h" + +namespace com { namespace sun { namespace star { namespace uno { +class Environment; +}}}} + +uno_Mapping * createIdentityMapping(const ::com::sun::star::uno::Environment & rEnv); + +#endif diff --git a/cppu/source/uno/any.cxx b/cppu/source/uno/any.cxx new file mode 100644 index 000000000000..29be833dfb86 --- /dev/null +++ b/cppu/source/uno/any.cxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "copy.hxx" +#include "destr.hxx" + +using namespace cppu; + + +extern "C" +{ +//################################################################################################## +void SAL_CALL uno_type_any_assign( + uno_Any * pDest, void * pSource, + typelib_TypeDescriptionReference * pType, + uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + _destructAny( pDest, release ); + if (pType) + { + _copyConstructAny( pDest, pSource, pType, 0, acquire, 0 ); + } + else + { + CONSTRUCT_EMPTY_ANY( pDest ); + } +} +//################################################################################################## +void SAL_CALL uno_any_assign( + uno_Any * pDest, void * pSource, + typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + _destructAny( pDest, release ); + if (pTypeDescr) + { + _copyConstructAny( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 ); + } + else + { + CONSTRUCT_EMPTY_ANY( pDest ); + } +} +//################################################################################################## +void SAL_CALL uno_type_any_construct( + uno_Any * pDest, void * pSource, + typelib_TypeDescriptionReference * pType, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C() +{ + if (pType) + { + _copyConstructAny( pDest, pSource, pType, 0, acquire, 0 ); + } + else + { + CONSTRUCT_EMPTY_ANY( pDest ); + } +} +//################################################################################################## +void SAL_CALL uno_any_construct( + uno_Any * pDest, void * pSource, + typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C() +{ + if (pTypeDescr) + { + _copyConstructAny( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 ); + } + else + { + CONSTRUCT_EMPTY_ANY( pDest ); + } +} +//################################################################################################## +void SAL_CALL uno_type_any_constructAndConvert( + uno_Any * pDest, void * pSource, + typelib_TypeDescriptionReference * pType, + uno_Mapping * mapping ) + SAL_THROW_EXTERN_C() +{ + if (pType) + { + _copyConstructAny( pDest, pSource, pType, 0, 0, mapping ); + } + else + { + CONSTRUCT_EMPTY_ANY( pDest ); + } +} +//################################################################################################## +void SAL_CALL uno_any_constructAndConvert( + uno_Any * pDest, void * pSource, + typelib_TypeDescription * pTypeDescr, + uno_Mapping * mapping ) + SAL_THROW_EXTERN_C() +{ + if (pTypeDescr) + { + _copyConstructAny( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, 0, mapping ); + } + else + { + CONSTRUCT_EMPTY_ANY( pDest ); + } +} +//################################################################################################## +void SAL_CALL uno_any_destruct( uno_Any * pValue, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + _destructAny( pValue, release ); +} +//################################################################################################## +void SAL_CALL uno_any_clear( uno_Any * pValue, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + _destructAny( pValue, release ); + CONSTRUCT_EMPTY_ANY( pValue ); +} +} diff --git a/cppu/source/uno/assign.hxx b/cppu/source/uno/assign.hxx new file mode 100644 index 000000000000..256bb31565db --- /dev/null +++ b/cppu/source/uno/assign.hxx @@ -0,0 +1,635 @@ +/************************************************************************* + * + * 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 ASSIGN_HXX +#define ASSIGN_HXX + +#include "prim.hxx" +#include "destr.hxx" +#include "constr.hxx" +#include "copy.hxx" + + +namespace cppu +{ + +//################################################################################################## +//#### assignment ################################################################################## +//################################################################################################## + + +//-------------------------------------------------------------------------------------------------- +inline void _assignInterface( + void ** ppDest, void * pSource, + uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + _acquire( pSource, acquire ); + void * const pToBeReleased = *ppDest; + *ppDest = pSource; + _release( pToBeReleased, release ); +} +//-------------------------------------------------------------------------------------------------- +inline void * _queryInterface( + void * pSource, + typelib_TypeDescriptionReference * pDestType, + uno_QueryInterfaceFunc queryInterface ) + SAL_THROW( () ) +{ + if (pSource) + { + if (0 == queryInterface) + queryInterface = binuno_queryInterface; + pSource = (*queryInterface)( pSource, pDestType ); + } + return pSource; +} +//================================================================================================== +sal_Bool assignStruct( + void * pDest, void * pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW( () ); +//-------------------------------------------------------------------------------------------------- +inline sal_Bool _assignStruct( + void * pDest, void * pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + if (pTypeDescr->pBaseTypeDescription) + { + // copy base value + if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, + queryInterface, acquire, release )) + { + return sal_False; + } + } + // then copy members + typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs; + sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; + sal_Int32 nDescr = pTypeDescr->nMembers; + while (nDescr--) + { + if (! ::uno_type_assignData( (char *)pDest + pMemberOffsets[nDescr], + ppTypeRefs[nDescr], + (char *)pSource + pMemberOffsets[nDescr], + ppTypeRefs[nDescr], + queryInterface, acquire, release )) + { + return sal_False; + } + } + return sal_True; +} +//-------------------------------------------------------------------------------------------------- +inline sal_Bool _assignArray( + void * pDest, void * pSource, + typelib_ArrayTypeDescription * pTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) +{ + typelib_TypeDescriptionReference * pElementTypeRef = + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; + typelib_TypeDescription * pElementTypeDescr = NULL; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef ); + sal_Int32 nTotalElements = pTypeDescr->nTotalElements; + sal_Int32 nElementSize = pElementTypeDescr->nSize; + sal_Int32 i; + sal_Bool bRet = sal_False; + + switch ( pElementTypeRef->eTypeClass ) + { + 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: + for (i=0; i < nTotalElements; i++) + { + ::rtl_copyMemory((sal_Char *)pDest + i * nElementSize, + (sal_Char *)pSource + i * nElementSize, + nElementSize); + } + bRet = sal_True; + break; + case typelib_TypeClass_STRING: + for (i=0; i < nTotalElements; i++) + { + ::rtl_uString_assign( (rtl_uString **)pDest + i, + ((rtl_uString **)pSource)[i] ); + } + bRet = sal_True; + break; + case typelib_TypeClass_TYPE: + for (i=0; i < nTotalElements; i++) + { + typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest + i; + ::typelib_typedescriptionreference_release( *pp ); + *pp = *((typelib_TypeDescriptionReference **)pSource + i); + TYPE_ACQUIRE( *pp ); + } + bRet = sal_True; + break; + case typelib_TypeClass_ANY: + for (i=0; i < nTotalElements; i++) + { + _destructAny( (uno_Any *)pDest + i, release ); + _copyConstructAny( (uno_Any *)pDest + i, (uno_Any *)pSource + i, + pElementTypeRef, pElementTypeDescr, acquire, 0 ); + } + bRet = sal_True; + break; + case typelib_TypeClass_ENUM: + for (i=0; i < nTotalElements; i++) + { + *((sal_Int32 *)pDest + i) = *((sal_Int32 *)pSource + i); + } + bRet = sal_True; + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + for (i=0; i < nTotalElements; i++) + { + bRet = _assignStruct( (sal_Char *)pDest + i * nElementSize, + (sal_Char *)pSource + i * nElementSize, + (typelib_CompoundTypeDescription *)pElementTypeDescr, + queryInterface, acquire, release ); + if (! bRet) + break; + } + bRet = sal_True; + break; + case typelib_TypeClass_UNION: + for (i=0; i < nTotalElements; i++) + { + _destructUnion( (sal_Char*)pDest + i * nElementSize, pElementTypeDescr, release ); + _copyConstructUnion( (sal_Char*)pDest + i * nElementSize, + (sal_Char*)pSource + i * nElementSize, + pElementTypeDescr, acquire, 0 ); + } + bRet = sal_True; + break; + case typelib_TypeClass_SEQUENCE: + for (i=0; i < nTotalElements; i++) + { + ::osl_incrementInterlockedCount( + &(*((uno_Sequence **)pSource + i))->nRefCount ); + idestructSequence( + *((uno_Sequence **)pDest + i), + pElementTypeRef, pElementTypeDescr, release ); + *((uno_Sequence **)pDest + i) = *((uno_Sequence **)pSource + i); + } + bRet = sal_True; + break; + case typelib_TypeClass_INTERFACE: + for (i=0; i < nTotalElements; i++) + { + _assignInterface( + (void **)((sal_Char*)pDest + i * nElementSize), + *(void **)((sal_Char*)pSource + i * nElementSize), + acquire, release ); + } + bRet = sal_True; + break; + default: + OSL_ASSERT(false); + break; + } + + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return bRet; +} +//-------------------------------------------------------------------------------------------------- +inline sal_Bool _assignData( + void * pDest, + typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr, + void * pSource, + typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + if (pDest == pSource) + return _type_equals( pDestType, pSourceType ); + + if (! pSource) + { + _destructData( pDest, pDestType, pDestTypeDescr, release ); + _defaultConstructData( pDest, pDestType, pDestTypeDescr ); + return sal_True; + } + while (typelib_TypeClass_ANY == pSourceType->eTypeClass) + { + pSourceTypeDescr = 0; + pSourceType = ((uno_Any *)pSource)->pType; + pSource = ((uno_Any *)pSource)->pData; + if (pDest == pSource) + return sal_True; + } + + switch (pDestType->eTypeClass) + { + case typelib_TypeClass_VOID: + return pSourceType->eTypeClass == typelib_TypeClass_VOID; + case typelib_TypeClass_CHAR: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_CHAR: + *(sal_Unicode *)pDest = *(sal_Unicode *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_BOOLEAN: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BOOLEAN: + *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False); + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_BYTE: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BYTE: + *(sal_Int8 *)pDest = *(sal_Int8 *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_SHORT: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BYTE: + *(sal_Int16 *)pDest = *(sal_Int8 *)pSource; + return sal_True; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_Int16 *)pDest = *(sal_Int16 *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_UNSIGNED_SHORT: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BYTE: + *(sal_uInt16 *)pDest = *(sal_Int8 *)pSource; + return sal_True; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_uInt16 *)pDest = *(sal_uInt16 *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_LONG: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BYTE: + *(sal_Int32 *)pDest = *(sal_Int8 *)pSource; + return sal_True; + case typelib_TypeClass_SHORT: + *(sal_Int32 *)pDest = *(sal_Int16 *)pSource; + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_Int32 *)pDest = *(sal_uInt16 *)pSource; + return sal_True; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + *(sal_Int32 *)pDest = *(sal_Int32 *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_UNSIGNED_LONG: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BYTE: + *(sal_uInt32 *)pDest = *(sal_Int8 *)pSource; + return sal_True; + case typelib_TypeClass_SHORT: + *(sal_uInt32 *)pDest = *(sal_Int16 *)pSource; + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_uInt32 *)pDest = *(sal_uInt16 *)pSource; + return sal_True; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + *(sal_uInt32 *)pDest = *(sal_uInt32 *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_HYPER: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BYTE: + *(sal_Int64 *)pDest = *(sal_Int8 *)pSource; + return sal_True; + case typelib_TypeClass_SHORT: + *(sal_Int64 *)pDest = *(sal_Int16 *)pSource; + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_Int64 *)pDest = *(sal_uInt16 *)pSource; + return sal_True; + case typelib_TypeClass_LONG: + *(sal_Int64 *)pDest = *(sal_Int32 *)pSource; + return sal_True; + case typelib_TypeClass_UNSIGNED_LONG: + *(sal_Int64 *)pDest = *(sal_uInt32 *)pSource; + return sal_True; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_UNSIGNED_HYPER: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BYTE: + *(sal_uInt64 *)pDest = *(sal_Int8 *)pSource; + return sal_True; + case typelib_TypeClass_SHORT: + *(sal_uInt64 *)pDest = *(sal_Int16 *)pSource; + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_uInt64 *)pDest = *(sal_uInt16 *)pSource; + return sal_True; + case typelib_TypeClass_LONG: + *(sal_uInt64 *)pDest = *(sal_Int32 *)pSource; + return sal_True; + case typelib_TypeClass_UNSIGNED_LONG: + *(sal_uInt64 *)pDest = *(sal_uInt32 *)pSource; + return sal_True; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + *(sal_uInt64 *)pDest = *(sal_uInt64 *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_FLOAT: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BYTE: + *(float *)pDest = *(sal_Int8 *)pSource; + return sal_True; + case typelib_TypeClass_SHORT: + *(float *)pDest = *(sal_Int16 *)pSource; + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + *(float *)pDest = *(sal_uInt16 *)pSource; + return sal_True; + case typelib_TypeClass_FLOAT: + *(float *)pDest = *(float *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_DOUBLE: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_BYTE: + *(double *)pDest = *(sal_Int8 *)pSource; + return sal_True; + case typelib_TypeClass_SHORT: + *(double *)pDest = *(sal_Int16 *)pSource; + return sal_True; + case typelib_TypeClass_UNSIGNED_SHORT: + *(double *)pDest = *(sal_uInt16 *)pSource; + return sal_True; + case typelib_TypeClass_LONG: + *(double *)pDest = *(sal_Int32 *)pSource; + return sal_True; + case typelib_TypeClass_UNSIGNED_LONG: + *(double *)pDest = *(sal_uInt32 *)pSource; + return sal_True; + case typelib_TypeClass_FLOAT: + *(double *)pDest = *(float *)pSource; + return sal_True; + case typelib_TypeClass_DOUBLE: + *(double *)pDest = *(double *)pSource; + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_STRING: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_STRING: + ::rtl_uString_assign( (rtl_uString **)pDest, *(rtl_uString **)pSource ); + return sal_True; + default: + return sal_False; + } + case typelib_TypeClass_TYPE: + switch (pSourceType->eTypeClass) + { + case typelib_TypeClass_TYPE: + { + typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest; + ::typelib_typedescriptionreference_release( *pp ); + *pp = *(typelib_TypeDescriptionReference **)pSource; + TYPE_ACQUIRE( *pp ); + return sal_True; + } + default: + return sal_False; + } + case typelib_TypeClass_ANY: + _destructAny( (uno_Any *)pDest, release ); + _copyConstructAny( (uno_Any *)pDest, pSource, pSourceType, pSourceTypeDescr, acquire, 0 ); + return sal_True; + case typelib_TypeClass_ENUM: + if (_type_equals( pDestType, pSourceType )) + { + *(sal_Int32 *)pDest = *(sal_Int32 *)pSource; + return sal_True; + } + return sal_False; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (typelib_TypeClass_STRUCT == pSourceType->eTypeClass || + typelib_TypeClass_EXCEPTION == pSourceType->eTypeClass) + { + sal_Bool bRet = sal_False; + if (pSourceTypeDescr) + { + typelib_CompoundTypeDescription * pTypeDescr = + (typelib_CompoundTypeDescription *)pSourceTypeDescr; + while (pTypeDescr && + !_type_equals( + ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType )) + { + pTypeDescr = pTypeDescr->pBaseTypeDescription; + } + if (pTypeDescr) + { + bRet = _assignStruct( + pDest, pSource, pTypeDescr, queryInterface, acquire, release ); + } + } + else + { + TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType ); + typelib_CompoundTypeDescription * pTypeDescr = + (typelib_CompoundTypeDescription *)pSourceTypeDescr; + while (pTypeDescr && + !_type_equals( + ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType )) + { + pTypeDescr = pTypeDescr->pBaseTypeDescription; + } + if (pTypeDescr) + { + bRet = _assignStruct( + pDest, pSource, pTypeDescr, queryInterface, acquire, release ); + } + TYPELIB_DANGER_RELEASE( pSourceTypeDescr ); + } + return bRet; + } + return sal_False; + case typelib_TypeClass_ARRAY: + { + sal_Bool bRet = sal_False; + if (pSourceTypeDescr) + { + typelib_ArrayTypeDescription * pTypeDescr = + (typelib_ArrayTypeDescription *)pSourceTypeDescr; + bRet = _assignArray( pDest, pSource, pTypeDescr, queryInterface, acquire, release ); + } + else + { + TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType ); + typelib_ArrayTypeDescription * pTypeDescr = + (typelib_ArrayTypeDescription *)pSourceTypeDescr; + if ( pTypeDescr ) + { + bRet = _assignArray( + pDest, pSource, pTypeDescr, queryInterface, acquire, release ); + } + TYPELIB_DANGER_RELEASE( pSourceTypeDescr ); + } + return bRet; + } + case typelib_TypeClass_UNION: + if (_type_equals( pDestType, pSourceType )) + { + if (pDestTypeDescr) + { + _destructUnion( pDest, pDestTypeDescr, release ); + _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 ); + } + else + { + TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType ); + _destructUnion( pDest, pDestTypeDescr, release ); + _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 ); + TYPELIB_DANGER_RELEASE( pDestTypeDescr ); + } + return sal_True; + } + return sal_False; + case typelib_TypeClass_SEQUENCE: + if (typelib_TypeClass_SEQUENCE != pSourceType->eTypeClass) + return sal_False; + // self assignment: + if (*(uno_Sequence **)pSource == *(uno_Sequence **)pDest) + return sal_True; + if (_type_equals( pDestType, pSourceType )) + { + ::osl_incrementInterlockedCount( + &(*(uno_Sequence **)pSource)->nRefCount ); + idestructSequence( + *(uno_Sequence **)pDest, pDestType, pDestTypeDescr, release ); + *(uno_Sequence **)pDest = *(uno_Sequence **)pSource; + return sal_True; + } + return sal_False; + case typelib_TypeClass_INTERFACE: + if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass) + return sal_False; + if (_type_equals( pDestType, pSourceType )) + { + _assignInterface( (void **)pDest, *(void **)pSource, acquire, release ); + return sal_True; + } + else if (*static_cast< void ** >(pSource) == 0) + { + // A null reference of any interface type can be converted to a null + // reference of any other interface type: + void * const pToBeReleased = *static_cast< void ** >(pDest); + *static_cast< void ** >(pDest) = 0; + _release( pToBeReleased, release ); + return true; + } + else + { + if (pSourceTypeDescr) + { + typelib_TypeDescription * pTD = pSourceTypeDescr; + while (pTD && !_type_equals( pTD->pWeakRef, pDestType )) + { + pTD = (typelib_TypeDescription *) + ((typelib_InterfaceTypeDescription *)pTD)->pBaseTypeDescription; + } + if (pTD) // is base of dest + { + _assignInterface( (void **)pDest, *(void **)pSource, acquire, release ); + return true; + } + } + + // query for interface: + void * pQueried = _queryInterface( *static_cast<void **>(pSource), + pDestType, queryInterface ); + if (pQueried != 0) { + void * const pToBeReleased = *static_cast<void **>(pDest); + *static_cast<void **>(pDest) = pQueried; + _release( pToBeReleased, release ); + } + return (pQueried != 0); + } + default: + OSL_ASSERT(false); + return sal_False; + } +} + +} + +#endif diff --git a/cppu/source/uno/cascade_mapping.cxx b/cppu/source/uno/cascade_mapping.cxx new file mode 100644 index 000000000000..ee870a52e286 --- /dev/null +++ b/cppu/source/uno/cascade_mapping.cxx @@ -0,0 +1,341 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include <iostream> + +#include "osl/interlck.h" +#include "rtl/ustring.hxx" +#include "uno/environment.hxx" +#include "uno/mapping.hxx" +#include "uno/dispatcher.h" + +//#include "cascade_mappping.hxx" +#include "cppu/EnvDcp.hxx" + + +//#define LOG_CALLING_named_purpose_getMapping + +//#define LOG_LIFECYLE_MediatorMapping +#ifdef LOG_LIFECYLE_MediatorMapping +# define LOG_LIFECYLE_MediatorMapping_emit(x) x + +#else +# define LOG_LIFECYLE_MediatorMapping_emit(x) + +#endif + + +using namespace com::sun::star; + +class MediatorMapping : public uno_Mapping +{ + oslInterlockedCount m_refCount; + + uno::Mapping m_from2uno; + uno::Mapping m_uno2to; + + uno::Environment m_from; + uno::Environment m_interm; + uno::Environment m_to; + +public: + void acquire(void); + void release(void); + + void mapInterface(void ** ppOut, + void * pInterface, + typelib_InterfaceTypeDescription * pInterfaceTypeDescr); + MediatorMapping(uno_Environment * pFrom, + uno_Environment * pInterm, + uno_Environment * pTo); + ~MediatorMapping(); +}; + +extern "C" { +static void SAL_CALL s_acquire(uno_Mapping * mapping) +{ + MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping); + pMediatorMapping->acquire(); +} + +static void SAL_CALL s_release(uno_Mapping * mapping) +{ + MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping); + pMediatorMapping->release(); +} + +static void SAL_CALL s_mapInterface( + uno_Mapping * mapping, + void ** ppOut, + void * pInterface, + typelib_InterfaceTypeDescription * pInterfaceTypeDescr) +{ + MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping); + pMediatorMapping->mapInterface(ppOut, pInterface, pInterfaceTypeDescr); +} +} + +MediatorMapping::MediatorMapping(uno_Environment * pFrom, + uno_Environment * pInterm, + uno_Environment * pTo) + : m_refCount(0), + m_from2uno(pFrom, pInterm), + m_uno2to (pInterm, pTo), + m_from (pFrom), + m_interm (pInterm), + m_to (pTo) +{ + LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl); + + if (!m_from2uno.get() || !m_uno2to.get()) + abort(); + + uno_Mapping::acquire = s_acquire; + uno_Mapping::release = s_release; + uno_Mapping::mapInterface = s_mapInterface; +} + +MediatorMapping::~MediatorMapping() +{ + LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl); +} + +void MediatorMapping::acquire(void) +{ + LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl); + + osl_incrementInterlockedCount(&m_refCount); +} + +void MediatorMapping::release(void) +{ + LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl); + + if (osl_decrementInterlockedCount(&m_refCount) == 0) + { + ::uno_revokeMapping(this); + } +} + +extern "C" { static void s_mapInterface_v(va_list * pParam) +{ + void ** ppOut = va_arg(*pParam, void **); + void * pInterface = va_arg(*pParam, void *); + typelib_InterfaceTypeDescription * pInterfaceTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *); + uno_Mapping * pMapping = va_arg(*pParam, uno_Mapping *); + + pMapping->mapInterface(pMapping, ppOut, pInterface, pInterfaceTypeDescr); +}} + +void MediatorMapping::mapInterface( + void ** ppOut, + void * pInterface, + typelib_InterfaceTypeDescription * pInterfaceTypeDescr) +{ + if (*ppOut != 0) + { + uno_ExtEnvironment * env = m_to.get()->pExtEnv; + OSL_ASSERT( env != 0 ); + env->releaseInterface( env, *ppOut ); + *ppOut = NULL; + } + + void * ret = 0; + uno_Interface * pUnoI = 0; + + m_from.invoke(s_mapInterface_v, &pUnoI, pInterface, pInterfaceTypeDescr, m_from2uno.get()); + + m_uno2to.mapInterface(&ret, pUnoI, pInterfaceTypeDescr); + + if (pUnoI) + m_interm.get()->pExtEnv->releaseInterface(m_interm.get()->pExtEnv, pUnoI); + + *ppOut = ret; +} + +extern "C" { static void SAL_CALL s_MediatorMapping_free(uno_Mapping * pMapping) + SAL_THROW_EXTERN_C() +{ + delete static_cast<MediatorMapping *>(pMapping); +}} + + + +static rtl::OUString getPrefix(rtl::OUString const & str1, rtl::OUString const & str2) +{ + sal_Int32 nIndex1 = 0; + sal_Int32 nIndex2 = 0; + sal_Int32 sim = 0; + + rtl::OUString token1; + rtl::OUString token2; + + do + { + token1 = str1.getToken(0, ':', nIndex1); + token2 = str2.getToken(0, ':', nIndex2); + + if (token1.equals(token2)) + sim += token1.getLength() + 1; + } + while(nIndex1 == nIndex2 && nIndex1 >= 0 && token1.equals(token2)); + + rtl::OUString result; + + if (sim) + result = str1.copy(0, sim - 1); + + return result; +} + +// rtl::OUString str1(RTL_CONSTASCII_USTRINGPARAM("abc:def:ghi")); +// rtl::OUString str2(RTL_CONSTASCII_USTRINGPARAM("abc:def")); +// rtl::OUString str3(RTL_CONSTASCII_USTRINGPARAM("abc")); +// rtl::OUString str4(RTL_CONSTASCII_USTRINGPARAM("")); + +// rtl::OUString pref; + +// pref = getPrefix(str1, str1); +// pref = getPrefix(str1, str2); +// pref = getPrefix(str1, str3); +// pref = getPrefix(str1, str4); + +// pref = getPrefix(str2, str1); +// pref = getPrefix(str3, str1); +// pref = getPrefix(str4, str1); + + +void getCascadeMapping(uno_Mapping ** ppMapping, + uno_Environment * pFrom, + uno_Environment * pTo, + rtl_uString * pAddPurpose) +{ + if (pAddPurpose && pAddPurpose->length) + return; + + rtl::OUString uno_envType(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO)); + + rtl::OUString from_envType = cppu::EnvDcp::getTypeName(pFrom->pTypeName); + rtl::OUString to_envType = cppu::EnvDcp::getTypeName(pTo->pTypeName); + rtl::OUString from_envPurpose = cppu::EnvDcp::getPurpose(pFrom->pTypeName); + rtl::OUString to_envPurpose = cppu::EnvDcp::getPurpose(pTo->pTypeName); + +#ifdef LOG_CALLING_named_purpose_getMapping + rtl::OString s_from_name = rtl::OUStringToOString(pFrom->pTypeName, RTL_TEXTENCODING_ASCII_US); + rtl::OString s_to_name = rtl::OUStringToOString(pTo->pTypeName, RTL_TEXTENCODING_ASCII_US); + + std::cerr << __FUNCTION__ << " - creating mediation "; + std::cerr << "pFrom: " << s_from_name.getStr(); + std::cerr <<" pTo: " << s_to_name.getStr() << std::endl; +#endif + + if (from_envPurpose == to_envPurpose) // gcc:bla => uno:bla + return; + + // reaching this point means, we need a mediated mapping!!! + // we generall mediate via uno[:free] + uno_Environment * pInterm = NULL; + + // chained uno -> uno + if (from_envType == uno_envType && to_envType == uno_envType) + { + rtl::OUString purpose = getPrefix(from_envPurpose, to_envPurpose); + + rtl::OUString uno_envDcp = uno_envType; + uno_envDcp += purpose; + + // direct mapping possible? + // uno:bla-->uno:bla:blubb + if (from_envPurpose.equals(purpose)) + { + rtl::OUString rest = to_envPurpose.copy(purpose.getLength()); + + sal_Int32 index = rest.indexOf(':', 1); + if (index == -1) + { + uno_getMapping(ppMapping, pFrom, pTo, rest.copy(1).pData); + return; + } + + uno_envDcp += rest.copy(0, index); + } + else if (to_envPurpose.equals(purpose)) + { + rtl::OUString rest = from_envPurpose.copy(purpose.getLength()); + + sal_Int32 index = rest.indexOf(':', 1); + if (index == -1) + { + uno_getMapping(ppMapping, pFrom, pTo, rest.copy(1).pData); + return; + } + + uno_envDcp += rest.copy(0, index); + } + + uno_getEnvironment(&pInterm, uno_envDcp.pData, NULL); + } + else if (from_envType != uno_envType && to_envType == uno_envType) // <ANY> -> UNO ? + // mediate via uno:purpose(fromEnv) + { + rtl::OUString envDcp = uno_envType; + + envDcp += from_envPurpose; + uno_getEnvironment(&pInterm, envDcp.pData, NULL); + } + else if (from_envType == uno_envType && to_envType != uno_envType) // UNO -> <ANY>? + // mediate via uno(context) + { + rtl::OUString envDcp = uno_envType; + + envDcp += to_envPurpose; + uno_getEnvironment(&pInterm, envDcp.pData, NULL); + } + else // everything else + // mediate via uno:purpose + { + rtl::OUString purpose = getPrefix(from_envPurpose, to_envPurpose); + + rtl::OUString uno_envDcp = uno_envType; + uno_envDcp += purpose; + + uno_getEnvironment(&pInterm, uno_envDcp.pData, NULL); + } + + uno_Mapping * pMapping = new MediatorMapping(pFrom, pInterm, pTo); + pInterm->release(pInterm); + + + pMapping->acquire(pMapping); + + ::uno_registerMapping(&pMapping, s_MediatorMapping_free, pFrom, pTo, pAddPurpose); + + if (*ppMapping) + (*ppMapping)->release(*ppMapping); + + *ppMapping = pMapping; +} diff --git a/cppu/source/uno/cascade_mapping.hxx b/cppu/source/uno/cascade_mapping.hxx new file mode 100644 index 000000000000..3b63e17198fb --- /dev/null +++ b/cppu/source/uno/cascade_mapping.hxx @@ -0,0 +1,41 @@ +/************************************************************************* + * + * 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 INCLUDED_cascade_mapping_hxx +#define INCLUDED_cascade_mapping_hxx + +#include "uno/environment.h" +#include "uno/mapping.h" +#include "rtl/ustring.h" + + +void getCascadeMapping(uno_Mapping ** ppMapping, + uno_Environment * pFrom, + uno_Environment * pTo, + rtl_uString * pAddPurpose ); + +#endif diff --git a/cppu/source/uno/constr.hxx b/cppu/source/uno/constr.hxx new file mode 100644 index 000000000000..8e6d35e9db64 --- /dev/null +++ b/cppu/source/uno/constr.hxx @@ -0,0 +1,267 @@ +/************************************************************************* + * + * 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 CONSTR_HXX +#define CONSTR_HXX + +#include "prim.hxx" + + +namespace cppu +{ + +//################################################################################################## +//#### construction ################################################################################ +//################################################################################################## + +//-------------------------------------------------------------------------------------------------- +inline void _defaultConstructUnion( + void * pMem, + typelib_TypeDescription * pTypeDescr ) + SAL_THROW( () ) +{ + ::uno_type_constructData( + (char *)pMem + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + ((typelib_UnionTypeDescription *)pTypeDescr)->pDefaultTypeRef ); + *(sal_Int64 *)pMem = ((typelib_UnionTypeDescription *)pTypeDescr)->nDefaultDiscriminant; +} +//================================================================================================== +void defaultConstructStruct( + void * pMem, + typelib_CompoundTypeDescription * pCompType ) + SAL_THROW( () ); +//-------------------------------------------------------------------------------------------------- +inline void _defaultConstructStruct( + void * pMem, + typelib_CompoundTypeDescription * pTypeDescr ) + SAL_THROW( () ) +{ + if (pTypeDescr->pBaseTypeDescription) + { + defaultConstructStruct( pMem, pTypeDescr->pBaseTypeDescription ); + } + + typelib_TypeDescriptionReference ** ppTypeRefs = (pTypeDescr)->ppTypeRefs; + sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; + sal_Int32 nDescr = pTypeDescr->nMembers; + + while (nDescr--) + { + ::uno_type_constructData( (char *)pMem + pMemberOffsets[nDescr], ppTypeRefs[nDescr] ); + } +} + +//-------------------------------------------------------------------------------------------------- +inline void _defaultConstructArray( + void * pMem, + typelib_ArrayTypeDescription * pTypeDescr ) +{ + typelib_TypeDescription * pElementType = NULL; + TYPELIB_DANGER_GET( &pElementType, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType ); + sal_Int32 nTotalElements = pTypeDescr->nTotalElements; + sal_Int32 nElementSize = pElementType->nSize; + sal_Int32 i; + switch ( pElementType->eTypeClass ) + { + 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_INTERFACE: + ::rtl_zeroMemory(pMem, nElementSize * nTotalElements); + break; + + case typelib_TypeClass_STRING: + for (i=0; i < nTotalElements; i++) + { + rtl_uString** ppElement = (rtl_uString **)pMem + i; + *ppElement = 0; + rtl_uString_new( ppElement); + } + break; + case typelib_TypeClass_TYPE: + for (i=0; i < nTotalElements; i++) + { + typelib_TypeDescriptionReference** ppElement = (typelib_TypeDescriptionReference **)pMem + i; + *ppElement = _getVoidType(); + } + break; + case typelib_TypeClass_ANY: + for (i=0; i < nTotalElements; i++) + { + CONSTRUCT_EMPTY_ANY( (uno_Any *)pMem + i ); + } + break; + case typelib_TypeClass_ENUM: + for (i=0; i < nTotalElements; i++) + { + *((sal_Int32 *)pMem + i) = ((typelib_EnumTypeDescription *)pElementType)->nDefaultEnumValue; + } + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + for (i=0; i < nTotalElements; i++) + { + _defaultConstructStruct( (sal_Char*)pMem + i * nElementSize, (typelib_CompoundTypeDescription *)pElementType ); + } + break; + case typelib_TypeClass_UNION: + for (i=0; i < nTotalElements; i++) + { + _defaultConstructUnion( (sal_Char*)pMem + i * nElementSize, pElementType ); + } + break; + case typelib_TypeClass_SEQUENCE: + for (i=0; i < nTotalElements; i++) + { + uno_Sequence** ppElement = (uno_Sequence **)pMem + i; + *ppElement = createEmptySequence(); + } + break; + default: + OSL_ASSERT(false); + break; + } + TYPELIB_DANGER_RELEASE( pElementType ); +} + +//-------------------------------------------------------------------------------------------------- +inline void _defaultConstructData( + void * pMem, + typelib_TypeDescriptionReference * pType, + typelib_TypeDescription * pTypeDescr ) + SAL_THROW( () ) +{ + switch (pType->eTypeClass) + { + case typelib_TypeClass_CHAR: + *(sal_Unicode *)pMem = '\0'; + break; + case typelib_TypeClass_BOOLEAN: + *(sal_Bool *)pMem = sal_False; + break; + case typelib_TypeClass_BYTE: + *(sal_Int8 *)pMem = 0; + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_Int16 *)pMem = 0; + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + *(sal_Int32 *)pMem = 0; + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + *(sal_Int64 *)pMem = 0; + break; + case typelib_TypeClass_FLOAT: + *(float *)pMem = 0.0; + break; + case typelib_TypeClass_DOUBLE: + *(double *)pMem = 0.0; + break; + case typelib_TypeClass_STRING: + *(rtl_uString **)pMem = 0; + ::rtl_uString_new( (rtl_uString **)pMem ); + break; + case typelib_TypeClass_TYPE: + *(typelib_TypeDescriptionReference **)pMem = _getVoidType(); + break; + case typelib_TypeClass_ANY: + CONSTRUCT_EMPTY_ANY( (uno_Any *)pMem ); + break; + case typelib_TypeClass_ENUM: + if (pTypeDescr) + { + *(sal_Int32 *)pMem = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue; + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + *(sal_Int32 *)pMem = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue; + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (pTypeDescr) + { + _defaultConstructStruct( pMem, (typelib_CompoundTypeDescription *)pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _defaultConstructStruct( pMem, (typelib_CompoundTypeDescription *)pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_ARRAY: + if (pTypeDescr) + { + _defaultConstructArray( pMem, (typelib_ArrayTypeDescription *)pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _defaultConstructArray( pMem, (typelib_ArrayTypeDescription *)pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_UNION: + if (pTypeDescr) + { + _defaultConstructUnion( pMem, pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _defaultConstructUnion( pMem, pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_SEQUENCE: + *(uno_Sequence **)pMem = createEmptySequence(); + break; + case typelib_TypeClass_INTERFACE: + *(void **)pMem = 0; // either cpp or c-uno interface + break; + default: + OSL_ASSERT(false); + break; + } +} + +} + +#endif diff --git a/cppu/source/uno/copy.hxx b/cppu/source/uno/copy.hxx new file mode 100644 index 000000000000..7999b5ae0d2b --- /dev/null +++ b/cppu/source/uno/copy.hxx @@ -0,0 +1,886 @@ +/************************************************************************* + * + * 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 COPY_HXX +#define COPY_HXX + +#include "prim.hxx" +#include "constr.hxx" + + +namespace cppu +{ + +//################################################################################################## +//#### copy construction ########################################################################### +//################################################################################################## + +//------------------------------------------------------------------------------ +inline uno_Sequence * allocSeq( + sal_Int32 nElementSize, sal_Int32 nElements ) +{ + OSL_ASSERT( nElements >= 0 && nElementSize >= 0 ); + uno_Sequence * pSeq = 0; + sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements ); + if (nSize > 0) + { + pSeq = (uno_Sequence *) rtl_allocateMemory( nSize ); + if (pSeq != 0) + { + // header init + pSeq->nRefCount = 1; + pSeq->nElements = nElements; + } + } + return pSeq; +} + +//-------------------------------------------------------------------------------------------------- +void copyConstructStruct( + void * pDest, void * pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ); +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructStruct( + void * pDest, void * pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + if (pTypeDescr->pBaseTypeDescription) + { + // copy base value + copyConstructStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, acquire, mapping ); + } + + // then copy members + typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs; + sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; + sal_Int32 nDescr = pTypeDescr->nMembers; + + if (mapping) + { + while (nDescr--) + { + ::uno_type_copyAndConvertData( + (char *)pDest + pMemberOffsets[nDescr], + (char *)pSource + pMemberOffsets[nDescr], + ppTypeRefs[nDescr], mapping ); + } + } + else + { + while (nDescr--) + { + ::uno_type_copyData( + (char *)pDest + pMemberOffsets[nDescr], + (char *)pSource + pMemberOffsets[nDescr], + ppTypeRefs[nDescr], acquire ); + } + } +} +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructArray( + void * pDest, void * pSource, + typelib_ArrayTypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) +{ + typelib_TypeDescriptionReference * pElementTypeRef = ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; + typelib_TypeDescription * pElementTypeDescr = NULL; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef ); + sal_Int32 nElementSize = ((typelib_TypeDescription*)pElementTypeDescr)->nSize; + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + sal_Int32 nTotalElements = pTypeDescr->nTotalElements; + + if (mapping) + { + for(sal_Int32 i = 0; i < nTotalElements; i++) + { + ::uno_type_copyAndConvertData( + (sal_Char *)pDest + i * nElementSize, + (sal_Char *)pSource + i * nElementSize, + pElementTypeRef, mapping ); + } + } + else + { + for(sal_Int32 i = 0; i < nTotalElements; i++) + { + ::uno_type_copyData( + (sal_Char *)pDest + (i * nElementSize), + (sal_Char *)pSource + (i * nElementSize), + pElementTypeRef, acquire ); + } + } +} +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructUnion( + void * pDest, void * pSource, + typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + typelib_TypeDescriptionReference * pSetType = _unionGetSetType( pSource, pTypeDescr ); + if (mapping) + { + ::uno_type_copyAndConvertData( + (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + pSetType, mapping ); + } + else + { + ::uno_type_copyData( + (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + pSetType, acquire ); + } + *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; + typelib_typedescriptionreference_release( pSetType ); +} + +//------------------------------------------------------------------------------ +uno_Sequence * copyConstructSequence( + uno_Sequence * pSource, + typelib_TypeDescriptionReference * pElementType, + uno_AcquireFunc acquire, uno_Mapping * mapping ); + +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructAnyFromData( + uno_Any * pDestAny, void * pSource, + typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + TYPE_ACQUIRE( pType ); + pDestAny->pType = pType; + + switch (pType->eTypeClass) + { + case typelib_TypeClass_CHAR: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Unicode *)&pDestAny->pReserved = *(sal_Unicode *)pSource; + break; + case typelib_TypeClass_BOOLEAN: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Bool *)&pDestAny->pReserved = (*(sal_Bool *)pSource != sal_False); + break; + case typelib_TypeClass_BYTE: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int8 *)&pDestAny->pReserved = *(sal_Int8 *)pSource; + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int16 *)&pDestAny->pReserved = *(sal_Int16 *)pSource; + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource; + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + if (sizeof(void *) >= sizeof(sal_Int64)) + { + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int64 *)&pDestAny->pReserved = *(sal_Int64 *)pSource; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) ); + *(sal_Int64 *)pDestAny->pData = *(sal_Int64 *)pSource; + } + break; + case typelib_TypeClass_FLOAT: + if (sizeof(void *) >= sizeof(float)) + { + pDestAny->pData = &pDestAny->pReserved; + *(float *)&pDestAny->pReserved = *(float *)pSource; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(float) ); + *(float *)pDestAny->pData = *(float *)pSource; + } + break; + case typelib_TypeClass_DOUBLE: + if (sizeof(void *) >= sizeof(double)) + { + pDestAny->pData = &pDestAny->pReserved; + *(double *)&pDestAny->pReserved = *(double *)pSource; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(double) ); + *(double *)pDestAny->pData = *(double *)pSource; + } + break; + case typelib_TypeClass_STRING: + ::rtl_uString_acquire( *(rtl_uString **)pSource ); + pDestAny->pData = &pDestAny->pReserved; + *(rtl_uString **)&pDestAny->pReserved = *(rtl_uString **)pSource; + break; + case typelib_TypeClass_TYPE: + TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource ); + pDestAny->pData = &pDestAny->pReserved; + *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = *(typelib_TypeDescriptionReference **)pSource; + break; + case typelib_TypeClass_ANY: + OSL_ENSURE( 0, "### unexpected nested any!" ); + break; + case typelib_TypeClass_ENUM: + pDestAny->pData = &pDestAny->pReserved; + // enum is forced to 32bit long + *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource; + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructStruct( + pDestAny->pData, pSource, + (typelib_CompoundTypeDescription *)pTypeDescr, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructStruct( + pDestAny->pData, pSource, + (typelib_CompoundTypeDescription *)pTypeDescr, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_ARRAY: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructArray( + pDestAny->pData, pSource, + (typelib_ArrayTypeDescription *)pTypeDescr, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructArray( + pDestAny->pData, pSource, + (typelib_ArrayTypeDescription *)pTypeDescr, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_UNION: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_SEQUENCE: + pDestAny->pData = &pDestAny->pReserved; + if (pTypeDescr) + { + *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence( + *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence( + *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_INTERFACE: + pDestAny->pData = &pDestAny->pReserved; + if (mapping) + { + pDestAny->pReserved = _map( *(void **)pSource, pType, pTypeDescr, mapping ); + } + else + { + _acquire( pDestAny->pReserved = *(void **)pSource, acquire ); + } + break; + default: + OSL_ASSERT(false); + break; + } +} +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructAny( + uno_Any * pDestAny, void * pSource, + typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + if (typelib_TypeClass_VOID == pType->eTypeClass) + { + CONSTRUCT_EMPTY_ANY( pDestAny ); + } + else + { + if (typelib_TypeClass_ANY == pType->eTypeClass) + { + if (pSource) + { + pType = ((uno_Any *)pSource)->pType; + if (typelib_TypeClass_VOID == pType->eTypeClass) + { + CONSTRUCT_EMPTY_ANY( pDestAny ); + return; + } + pTypeDescr = 0; + pSource = ((uno_Any *)pSource)->pData; + } + else + { + CONSTRUCT_EMPTY_ANY( pDestAny ); + return; + } + } + if (pSource) + { + _copyConstructAnyFromData( pDestAny, pSource, pType, pTypeDescr, acquire, mapping ); + } + else // default construct + { + TYPE_ACQUIRE( pType ); + pDestAny->pType = pType; + switch (pType->eTypeClass) + { + case typelib_TypeClass_CHAR: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Unicode *)&pDestAny->pReserved = '\0'; + break; + case typelib_TypeClass_BOOLEAN: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Bool *)&pDestAny->pReserved = sal_False; + break; + case typelib_TypeClass_BYTE: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int8 *)&pDestAny->pReserved = 0; + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int16 *)&pDestAny->pReserved = 0; + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int32 *)&pDestAny->pReserved = 0; + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + if (sizeof(void *) >= sizeof(sal_Int64)) + { + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int64 *)&pDestAny->pReserved = 0; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) ); + *(sal_Int64 *)pDestAny->pData = 0; + } + break; + case typelib_TypeClass_FLOAT: + if (sizeof(void *) >= sizeof(float)) + { + pDestAny->pData = &pDestAny->pReserved; + *(float *)&pDestAny->pReserved = 0.0; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(float) ); + *(float *)pDestAny->pData = 0.0; + } + break; + case typelib_TypeClass_DOUBLE: + if (sizeof(void *) >= sizeof(double)) + { + pDestAny->pData = &pDestAny->pReserved; + *(double *)&pDestAny->pReserved = 0.0; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(double) ); + *(double *)pDestAny->pData = 0.0; + } + break; + case typelib_TypeClass_STRING: + pDestAny->pData = &pDestAny->pReserved; + *(rtl_uString **)&pDestAny->pReserved = 0; + ::rtl_uString_new( (rtl_uString **)&pDestAny->pReserved ); + break; + case typelib_TypeClass_TYPE: + pDestAny->pData = &pDestAny->pReserved; + *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = _getVoidType(); + break; + case typelib_TypeClass_ENUM: + pDestAny->pData = &pDestAny->pReserved; + if (pTypeDescr) + { + *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue; + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue; + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructStruct( + pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructStruct( + pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_ARRAY: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructArray( + pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructArray( + pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_UNION: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructUnion( pDestAny->pData, pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructUnion( pDestAny->pData, pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_SEQUENCE: + pDestAny->pData = &pDestAny->pReserved; + *(uno_Sequence **)&pDestAny->pReserved = createEmptySequence(); + break; + case typelib_TypeClass_INTERFACE: + pDestAny->pData = &pDestAny->pReserved; + pDestAny->pReserved = 0; // either cpp or c-uno interface + break; + default: + OSL_ASSERT(false); + break; + } + } + } +} +//------------------------------------------------------------------------------ +inline uno_Sequence * icopyConstructSequence( + uno_Sequence * pSource, + typelib_TypeDescriptionReference * pElementType, + uno_AcquireFunc acquire, uno_Mapping * mapping ) +{ + typelib_TypeClass eTypeClass = pElementType->eTypeClass; + if (!mapping || + (eTypeClass <= typelib_TypeClass_ENUM && + eTypeClass != typelib_TypeClass_ANY)) + { + ::osl_incrementInterlockedCount( &pSource->nRefCount ); + return pSource; + } + else // create new sequence + { + uno_Sequence * pDest; + sal_Int32 nElements = pSource->nElements; + if (nElements) + { + switch (eTypeClass) + { + case typelib_TypeClass_ANY: + { + pDest = allocSeq( sizeof (uno_Any), nElements ); + if (pDest != 0) + { + uno_Any * pDestElements = (uno_Any *)pDest->elements; + uno_Any * pSourceElements = (uno_Any *)pSource->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + typelib_TypeDescriptionReference * pType = + pSourceElements[nPos].pType; + if (typelib_TypeClass_VOID == pType->eTypeClass) + { + CONSTRUCT_EMPTY_ANY( &pDestElements[nPos] ); + } + else + { + _copyConstructAnyFromData( + &pDestElements[nPos], + pSourceElements[nPos].pData, + pType, 0, + acquire, mapping ); + } + } + } + break; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + char * pSourceElements = pSource->elements; + pDest = allocSeq( nElementSize, nElements ); + if (pDest != 0) + { + char * pElements = pDest->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + _copyConstructStruct( + pElements + (nPos * nElementSize), + pSourceElements + (nPos * nElementSize), + (typelib_CompoundTypeDescription *) + pElementTypeDescr, + acquire, mapping ); + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_ARRAY: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + char * pSourceElements = pSource->elements; + pDest = allocSeq( nElementSize, nElements ); + if (pDest != 0) + { + char * pElements = pDest->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + _copyConstructArray( + pElements + (nPos * nElementSize), + pSourceElements + (nPos * nElementSize), + (typelib_ArrayTypeDescription *)pElementTypeDescr, + acquire, mapping ); + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_UNION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + sal_Int32 nValueOffset = + ((typelib_UnionTypeDescription *) + pElementTypeDescr)->nValueOffset; + pDest = allocSeq( nElementSize, nElements ); + if (pDest != 0) + { + char * pElements = pDest->elements; + char * pSourceElements = pSource->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + char * pDest2 = + pElements + (nPos * nElementSize); + char * pSource2 = + pSourceElements + (nPos * nElementSize); + + typelib_TypeDescriptionReference * pSetType = + _unionGetSetType( pSource2, pElementTypeDescr ); + ::uno_type_copyAndConvertData( + pDest2 + nValueOffset, pSource2 + nValueOffset, + pSetType, mapping ); + *(sal_Int64 *)pDest2 = *(sal_Int64 *)pSource2; + ::typelib_typedescriptionreference_release( pSetType ); + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_SEQUENCE: // sequence of sequence + { + pDest = allocSeq( sizeof (uno_Sequence *), nElements ); + if (pDest != 0) + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + typelib_TypeDescriptionReference * pSeqElementType = + ((typelib_IndirectTypeDescription *) + pElementTypeDescr)->pType; + + uno_Sequence ** pDestElements = + (uno_Sequence **) pDest->elements; + uno_Sequence ** pSourceElements = + (uno_Sequence **) pSource->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + uno_Sequence * pNew = copyConstructSequence( + pSourceElements[nPos], + pSeqElementType, + acquire, mapping ); + OSL_ASSERT( pNew != 0 ); + // ought never be a memory allocation problem, + // because of reference counted sequence handles + pDestElements[ nPos ] = pNew; + } + + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + } + break; + } + case typelib_TypeClass_INTERFACE: + { + pDest = allocSeq( sizeof (void *), nElements ); + if (pDest != 0) + { + char * pElements = pDest->elements; + void ** pSourceElements = (void **)pSource->elements; + if (mapping) + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + for ( sal_Int32 nPos = nElements; nPos--; ) + { + ((void **)pElements)[nPos] = 0; + if (((void **)pSourceElements)[nPos]) + { + (*mapping->mapInterface)( + mapping, (void **)pElements + nPos, + pSourceElements[nPos], + (typelib_InterfaceTypeDescription *) + pElementTypeDescr ); + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + } + else + { + for ( sal_Int32 nPos = nElements; nPos--; ) + { + ((void **)pElements)[nPos] = pSourceElements[nPos]; + _acquire( ((void **)pElements)[nPos], acquire ); + } + } + } + break; + } + default: + OSL_ENSURE( 0, "### unexepcted sequence element type!" ); + pDest = 0; + break; + } + } + else // empty sequence + { + pDest = allocSeq( 0, 0 ); + } + + return pDest; + } +} + +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructData( + void * pDest, void * pSource, + typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + switch (pType->eTypeClass) + { + case typelib_TypeClass_CHAR: + *(sal_Unicode *)pDest = *(sal_Unicode *)pSource; + break; + case typelib_TypeClass_BOOLEAN: + *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False); + break; + case typelib_TypeClass_BYTE: + *(sal_Int8 *)pDest = *(sal_Int8 *)pSource; + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_Int16 *)pDest = *(sal_Int16 *)pSource; + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + *(sal_Int32 *)pDest = *(sal_Int32 *)pSource; + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; + break; + case typelib_TypeClass_FLOAT: + *(float *)pDest = *(float *)pSource; + break; + case typelib_TypeClass_DOUBLE: + *(double *)pDest = *(double *)pSource; + break; + case typelib_TypeClass_STRING: + ::rtl_uString_acquire( *(rtl_uString **)pSource ); + *(rtl_uString **)pDest = *(rtl_uString **)pSource; + break; + case typelib_TypeClass_TYPE: + TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource ); + *(typelib_TypeDescriptionReference **)pDest = *(typelib_TypeDescriptionReference **)pSource; + break; + case typelib_TypeClass_ANY: + _copyConstructAny( + (uno_Any *)pDest, ((uno_Any *)pSource)->pData, + ((uno_Any *)pSource)->pType, 0, + acquire, mapping ); + break; + case typelib_TypeClass_ENUM: + *(sal_Int32 *)pDest = *(sal_Int32 *)pSource; + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (pTypeDescr) + { + _copyConstructStruct( + pDest, pSource, + (typelib_CompoundTypeDescription *)pTypeDescr, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _copyConstructStruct( + pDest, pSource, + (typelib_CompoundTypeDescription *)pTypeDescr, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_ARRAY: + if (pTypeDescr) + { + _copyConstructArray( + pDest, pSource, + (typelib_ArrayTypeDescription *)pTypeDescr, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _copyConstructArray( + pDest, pSource, + (typelib_ArrayTypeDescription *)pTypeDescr, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_UNION: + if (pTypeDescr) + { + _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_SEQUENCE: + if (mapping) + { + if (pTypeDescr) + { + *(uno_Sequence **)pDest = icopyConstructSequence( + *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + *(uno_Sequence **)pDest = icopyConstructSequence( + *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + } + else + { + ::osl_incrementInterlockedCount( &(*(uno_Sequence **)pSource)->nRefCount ); + *(uno_Sequence **)pDest = *(uno_Sequence **)pSource; + } + break; + case typelib_TypeClass_INTERFACE: + if (mapping) + *(void **)pDest = _map( *(void **)pSource, pType, pTypeDescr, mapping ); + else + _acquire( *(void **)pDest = *(void **)pSource, acquire ); + break; + default: + break; + } +} + +} + +#endif diff --git a/cppu/source/uno/data.cxx b/cppu/source/uno/data.cxx new file mode 100644 index 000000000000..bb2869ca037f --- /dev/null +++ b/cppu/source/uno/data.cxx @@ -0,0 +1,618 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include <cstddef> +#include <stdio.h> + +#include "cppu/macros.hxx" + +#include "osl/mutex.hxx" + +#include "constr.hxx" +#include "destr.hxx" +#include "copy.hxx" +#include "assign.hxx" +#include "eq.hxx" + +#include "boost/static_assert.hpp" + + +using namespace ::cppu; +using namespace ::rtl; +using namespace ::osl; + + +namespace cppu +{ + +// Sequence<>() (default ctor) relies on this being static: +uno_Sequence g_emptySeq = { 1, 0, { 0 } }; +typelib_TypeDescriptionReference * g_pVoidType = 0; + +//-------------------------------------------------------------------------------------------------- +void * binuno_queryInterface( void * pUnoI, typelib_TypeDescriptionReference * pDestType ) +{ + // init queryInterface() td + static typelib_TypeDescription * g_pQITD = 0; + if (0 == g_pQITD) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (0 == g_pQITD) + { + typelib_TypeDescriptionReference * type_XInterface = + * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ); + typelib_InterfaceTypeDescription * pTXInterfaceDescr = 0; + TYPELIB_DANGER_GET( (typelib_TypeDescription **) &pTXInterfaceDescr, type_XInterface ); + OSL_ASSERT( pTXInterfaceDescr->ppAllMembers ); + typelib_typedescriptionreference_getDescription( + &g_pQITD, pTXInterfaceDescr->ppAllMembers[ 0 ] ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *) pTXInterfaceDescr ); + } + } + + uno_Any aRet, aExc; + uno_Any * pExc = &aExc; + void * aArgs[ 1 ]; + aArgs[ 0 ] = &pDestType; + (*((uno_Interface *) pUnoI)->pDispatcher)( + (uno_Interface *) pUnoI, g_pQITD, &aRet, aArgs, &pExc ); + + uno_Interface * ret = 0; + if (0 == pExc) + { + typelib_TypeDescriptionReference * ret_type = aRet.pType; + switch (ret_type->eTypeClass) + { + case typelib_TypeClass_VOID: // common case + typelib_typedescriptionreference_release( ret_type ); + break; + case typelib_TypeClass_INTERFACE: + // tweaky... avoiding acquire/ release pair + typelib_typedescriptionreference_release( ret_type ); + ret = (uno_Interface *) aRet.pReserved; // serving acquired interface + break; + default: + _destructAny( &aRet, 0 ); + break; + } + } + else + { +#if OSL_DEBUG_LEVEL > 1 + OUStringBuffer buf( 128 ); + buf.appendAscii( + RTL_CONSTASCII_STRINGPARAM("### exception occured querying for interface ") ); + buf.append( * reinterpret_cast< OUString const * >( &pDestType->pTypeName ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": [") ); + buf.append( * reinterpret_cast< OUString const * >( &pExc->pType->pTypeName ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); + // Message is very first member + buf.append( * reinterpret_cast< OUString const * >( pExc->pData ) ); + OString cstr( + OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); + OSL_ENSURE( 0, cstr.getStr() ); +#endif + uno_any_destruct( pExc, 0 ); + } + return ret; +} + +//================================================================================================== +void defaultConstructStruct( + void * pMem, + typelib_CompoundTypeDescription * pCompType ) + SAL_THROW( () ) +{ + _defaultConstructStruct( pMem, pCompType ); +} +//================================================================================================== +void copyConstructStruct( + void * pDest, void * pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW( () ) +{ + _copyConstructStruct( pDest, pSource, pTypeDescr, acquire, mapping ); +} +//================================================================================================== +void destructStruct( + void * pValue, + typelib_CompoundTypeDescription * pTypeDescr, + uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + _destructStruct( pValue, pTypeDescr, release ); +} +//================================================================================================== +sal_Bool equalStruct( + void * pDest, void *pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + return _equalStruct( pDest, pSource, pTypeDescr, queryInterface, release ); +} +//================================================================================================== +sal_Bool assignStruct( + void * pDest, void * pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + return _assignStruct( pDest, pSource, pTypeDescr, queryInterface, acquire, release ); +} + +//============================================================================== +uno_Sequence * copyConstructSequence( + uno_Sequence * pSource, + typelib_TypeDescriptionReference * pElementType, + uno_AcquireFunc acquire, uno_Mapping * mapping ) +{ + return icopyConstructSequence( pSource, pElementType, acquire, mapping ); +} + +//============================================================================== +void destructSequence( + uno_Sequence * pSequence, + typelib_TypeDescriptionReference * pType, + typelib_TypeDescription * pTypeDescr, + uno_ReleaseFunc release ) +{ + idestructSequence( pSequence, pType, pTypeDescr, release ); +} + +//================================================================================================== +sal_Bool equalSequence( + uno_Sequence * pDest, uno_Sequence * pSource, + typelib_TypeDescriptionReference * pElementType, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + return _equalSequence( pDest, pSource, pElementType, queryInterface, release ); +} + +extern "C" +{ +//################################################################################################## +void SAL_CALL uno_type_constructData( + void * pMem, typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C() +{ + _defaultConstructData( pMem, pType, 0 ); +} +//################################################################################################## +void SAL_CALL uno_constructData( + void * pMem, typelib_TypeDescription * pTypeDescr ) + SAL_THROW_EXTERN_C() +{ + _defaultConstructData( pMem, pTypeDescr->pWeakRef, pTypeDescr ); +} +//################################################################################################## +void SAL_CALL uno_type_destructData( + void * pValue, typelib_TypeDescriptionReference * pType, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + _destructData( pValue, pType, 0, release ); +} +//################################################################################################## +void SAL_CALL uno_destructData( + void * pValue, + typelib_TypeDescription * pTypeDescr, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + _destructData( pValue, pTypeDescr->pWeakRef, pTypeDescr, release ); +} +//################################################################################################## +void SAL_CALL uno_type_copyData( + void * pDest, void * pSource, + typelib_TypeDescriptionReference * pType, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C() +{ + _copyConstructData( pDest, pSource, pType, 0, acquire, 0 ); +} +//################################################################################################## +void SAL_CALL uno_copyData( + void * pDest, void * pSource, + typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C() +{ + _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 ); +} +//################################################################################################## +void SAL_CALL uno_type_copyAndConvertData( + void * pDest, void * pSource, + typelib_TypeDescriptionReference * pType, + uno_Mapping * mapping ) + SAL_THROW_EXTERN_C() +{ + _copyConstructData( pDest, pSource, pType, 0, 0, mapping ); +} +//################################################################################################## +void SAL_CALL uno_copyAndConvertData( + void * pDest, void * pSource, + typelib_TypeDescription * pTypeDescr, + uno_Mapping * mapping ) + SAL_THROW_EXTERN_C() +{ + _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, 0, mapping ); +} +//################################################################################################## +sal_Bool SAL_CALL uno_type_equalData( + void * pVal1, typelib_TypeDescriptionReference * pVal1Type, + void * pVal2, typelib_TypeDescriptionReference * pVal2Type, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + return _equalData( + pVal1, pVal1Type, 0, + pVal2, pVal2Type, 0, + queryInterface, release ); +} +//################################################################################################## +sal_Bool SAL_CALL uno_equalData( + void * pVal1, typelib_TypeDescription * pVal1TD, + void * pVal2, typelib_TypeDescription * pVal2TD, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + return _equalData( + pVal1, pVal1TD->pWeakRef, pVal1TD, + pVal2, pVal2TD->pWeakRef, pVal2TD, + queryInterface, release ); +} +//################################################################################################## +sal_Bool SAL_CALL uno_type_assignData( + void * pDest, typelib_TypeDescriptionReference * pDestType, + void * pSource, typelib_TypeDescriptionReference * pSourceType, + uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + return _assignData( + pDest, pDestType, 0, + pSource, pSourceType, 0, + queryInterface, acquire, release ); +} +//################################################################################################## +sal_Bool SAL_CALL uno_assignData( + void * pDest, typelib_TypeDescription * pDestTD, + void * pSource, typelib_TypeDescription * pSourceTD, + uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + return _assignData( + pDest, pDestTD->pWeakRef, pDestTD, + pSource, pSourceTD->pWeakRef, pSourceTD, + queryInterface, acquire, release ); +} +//################################################################################################## +sal_Bool SAL_CALL uno_type_isAssignableFromData( + typelib_TypeDescriptionReference * pAssignable, + void * pFrom, typelib_TypeDescriptionReference * pFromType, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + if (::typelib_typedescriptionreference_isAssignableFrom( pAssignable, pFromType )) + return sal_True; + if (typelib_TypeClass_INTERFACE != pFromType->eTypeClass || + typelib_TypeClass_INTERFACE != pAssignable->eTypeClass) + { + return sal_False; + } + + // query + if (0 == pFrom) + return sal_False; + void * pInterface = *(void **)pFrom; + if (0 == pInterface) + return sal_False; + + if (0 == queryInterface) + queryInterface = binuno_queryInterface; + void * p = (*queryInterface)( pInterface, pAssignable ); + _release( p, release ); + return (0 != p); +} +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +#if OSL_DEBUG_LEVEL > 1 + +#if defined( SAL_W32) +#pragma pack(push, 8) +#elif defined(SAL_OS2) +#pragma pack(push, 4) +#endif + +#if defined(INTEL) \ + && (defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD) || defined(OS2)) || defined(MACOSX) \ + || defined(__SUNPRO_CC) && defined(SOLARIS)) +#define MAX_ALIGNMENT_4 +#endif + +#define OFFSET_OF( s, m ) reinterpret_cast< std::size_t >((char *)&((s *)16)->m -16) + +#define BINTEST_VERIFY( c ) \ + if (! (c)) { fprintf( stderr, "### binary compatibility test failed: %s [line %d]!!!\n", #c, __LINE__ ); abort(); } +#define BINTEST_VERIFYOFFSET( s, m, n ) \ + if (OFFSET_OF(s, m) != n) { fprintf( stderr, "### OFFSET_OF(" #s ", " #m ") = %" SAL_PRI_SIZET "u instead of expected %d!!!\n", OFFSET_OF(s, m), n ); abort(); } + +#if OSL_DEBUG_LEVEL > 1 +#if defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD)) && (defined(INTEL) || defined(POWERPC) || defined(X86_64) || defined(S390)) +#define BINTEST_VERIFYSIZE( s, n ) \ + fprintf( stderr, "> sizeof(" #s ") = %d; __alignof__ (" #s ") = %d\n", sizeof(s), __alignof__ (s) ); \ + if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); } +#else // ! GNUC +#define BINTEST_VERIFYSIZE( s, n ) \ + fprintf( stderr, "> sizeof(" #s ") = %d\n", sizeof(s) ); \ + if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); } +#endif +#else // ! OSL_DEBUG_LEVEL +#define BINTEST_VERIFYSIZE( s, n ) \ + if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); } +#endif + +struct C1 +{ + sal_Int16 n1; +}; +struct C2 : public C1 +{ + sal_Int32 n2 CPPU_GCC3_ALIGN( C1 ); +}; +struct C3 : public C2 +{ + double d3; + sal_Int32 n3; +}; +struct C4 : public C3 +{ + sal_Int32 n4 CPPU_GCC3_ALIGN( C3 ); + double d4; +}; +struct C5 : public C4 +{ + sal_Int64 n5; + sal_Bool b5; +}; +struct C6 : public C1 +{ + C5 c6 CPPU_GCC3_ALIGN( C1 ); + sal_Bool b6; +}; + +struct D +{ + sal_Int16 d; + sal_Int32 e; +}; +struct E +{ + sal_Bool a; + sal_Bool b; + sal_Bool c; + sal_Int16 d; + sal_Int32 e; +}; + +struct M +{ + sal_Int32 n; + sal_Int16 o; +}; + +struct N : public M +{ + sal_Int16 p CPPU_GCC3_ALIGN( M ); +}; +struct N2 +{ + M m; + sal_Int16 p; +}; + +struct O : public M +{ + double p; + sal_Int16 q; +}; +struct O2 : public O +{ + sal_Int16 p2 CPPU_GCC3_ALIGN( O ); +}; + +struct P : public N +{ + double p2; +}; + +struct empty +{ +}; +struct second : public empty +{ + int a; +}; + +struct AlignSize_Impl +{ + sal_Int16 nInt16; + double dDouble; +}; + +struct Char1 +{ + char c1; +}; +struct Char2 : public Char1 +{ + char c2 CPPU_GCC3_ALIGN( Char1 ); +}; +struct Char3 : public Char2 +{ + char c3 CPPU_GCC3_ALIGN( Char2 ); +}; +struct Char4 +{ + Char3 chars; + char c; +}; +class Ref +{ + void * p; +}; +enum Enum +{ + v = SAL_MAX_ENUM +}; + + +class BinaryCompatible_Impl +{ +public: + BinaryCompatible_Impl(); +}; +BinaryCompatible_Impl::BinaryCompatible_Impl() +{ + BOOST_STATIC_ASSERT( ((sal_Bool) true) == sal_True && + (1 != 0) == sal_True ); + BOOST_STATIC_ASSERT( ((sal_Bool) false) == sal_False && + (1 == 0) == sal_False ); +#ifdef MAX_ALIGNMENT_4 + // max alignment is 4 + BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 4 ); + BINTEST_VERIFYSIZE( AlignSize_Impl, 12 ); +#else + // max alignment is 8 + BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 8 ); + BINTEST_VERIFYSIZE( AlignSize_Impl, 16 ); +#endif + + // sequence + BINTEST_VERIFY( (SAL_SEQUENCE_HEADER_SIZE % 8) == 0 ); + // enum + BINTEST_VERIFY( sizeof( Enum ) == sizeof( sal_Int32 ) ); + // any + BINTEST_VERIFY( sizeof(void *) >= sizeof(sal_Int32) ); + BINTEST_VERIFY( sizeof( uno_Any ) == sizeof( void * ) * 3 ); + BINTEST_VERIFYOFFSET( uno_Any, pType, 0 ); + BINTEST_VERIFYOFFSET( uno_Any, pData, 1 * sizeof (void *) ); + BINTEST_VERIFYOFFSET( uno_Any, pReserved, 2 * sizeof (void *) ); + // interface + BINTEST_VERIFY( sizeof( Ref ) == sizeof( void * ) ); + // string + BINTEST_VERIFY( sizeof( OUString ) == sizeof( rtl_uString * ) ); + // struct + BINTEST_VERIFYSIZE( M, 8 ); + BINTEST_VERIFYOFFSET( M, o, 4 ); + BINTEST_VERIFYSIZE( N, 12 ); + BINTEST_VERIFYOFFSET( N, p, 8 ); + BINTEST_VERIFYSIZE( N2, 12 ); + BINTEST_VERIFYOFFSET( N2, p, 8 ); +#ifdef MAX_ALIGNMENT_4 + BINTEST_VERIFYSIZE( O, 20 ); +#else + BINTEST_VERIFYSIZE( O, 24 ); +#endif + BINTEST_VERIFYSIZE( D, 8 ); + BINTEST_VERIFYOFFSET( D, e, 4 ); + BINTEST_VERIFYOFFSET( E, d, 4 ); + BINTEST_VERIFYOFFSET( E, e, 8 ); + + BINTEST_VERIFYSIZE( C1, 2 ); + BINTEST_VERIFYSIZE( C2, 8 ); + BINTEST_VERIFYOFFSET( C2, n2, 4 ); + +#ifdef MAX_ALIGNMENT_4 + BINTEST_VERIFYSIZE( C3, 20 ); + BINTEST_VERIFYOFFSET( C3, d3, 8 ); + BINTEST_VERIFYOFFSET( C3, n3, 16 ); + BINTEST_VERIFYSIZE( C4, 32 ); + BINTEST_VERIFYOFFSET( C4, n4, 20 ); + BINTEST_VERIFYOFFSET( C4, d4, 24 ); + BINTEST_VERIFYSIZE( C5, 44 ); + BINTEST_VERIFYOFFSET( C5, n5, 32 ); + BINTEST_VERIFYOFFSET( C5, b5, 40 ); + BINTEST_VERIFYSIZE( C6, 52 ); + BINTEST_VERIFYOFFSET( C6, c6, 4 ); + BINTEST_VERIFYOFFSET( C6, b6, 48 ); + + BINTEST_VERIFYSIZE( O2, 24 ); + BINTEST_VERIFYOFFSET( O2, p2, 20 ); +#else + BINTEST_VERIFYSIZE( C3, 24 ); + BINTEST_VERIFYOFFSET( C3, d3, 8 ); + BINTEST_VERIFYOFFSET( C3, n3, 16 ); + BINTEST_VERIFYSIZE( C4, 40 ); + BINTEST_VERIFYOFFSET( C4, n4, 24 ); + BINTEST_VERIFYOFFSET( C4, d4, 32 ); + BINTEST_VERIFYSIZE( C5, 56 ); + BINTEST_VERIFYOFFSET( C5, n5, 40 ); + BINTEST_VERIFYOFFSET( C5, b5, 48 ); + BINTEST_VERIFYSIZE( C6, 72 ); + BINTEST_VERIFYOFFSET( C6, c6, 8 ); + BINTEST_VERIFYOFFSET( C6, b6, 64 ); + + BINTEST_VERIFYSIZE( O2, 32 ); + BINTEST_VERIFYOFFSET( O2, p2, 24 ); +#endif + + BINTEST_VERIFYSIZE( Char3, 3 ); + BINTEST_VERIFYOFFSET( Char4, c, 3 ); + +#ifdef MAX_ALIGNMENT_4 + // max alignment is 4 + BINTEST_VERIFYSIZE( P, 20 ); +#else + // alignment of P is 8, because of P[] ... + BINTEST_VERIFYSIZE( P, 24 ); + BINTEST_VERIFYSIZE( second, sizeof( int ) ); +#endif +} + +#ifdef SAL_W32 +# pragma pack(pop) +#elif defined(SAL_OS2) +# pragma pack() +#endif + +static BinaryCompatible_Impl aTest; + +#endif + +} diff --git a/cppu/source/uno/destr.hxx b/cppu/source/uno/destr.hxx new file mode 100644 index 000000000000..8f156038ade5 --- /dev/null +++ b/cppu/source/uno/destr.hxx @@ -0,0 +1,438 @@ +/************************************************************************* + * + * 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 DESTR_HXX +#define DESTR_HXX + +#include "prim.hxx" + + +namespace cppu +{ + +//################################################################################################## +//#### destruction ################################################################################# +//################################################################################################## + +//-------------------------------------------------------------------------------------------------- +inline void _destructUnion( + void * pValue, + typelib_TypeDescription * pTypeDescr, + uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + typelib_TypeDescriptionReference * pType = _unionGetSetType( pValue, pTypeDescr ); + ::uno_type_destructData( + (char *)pValue + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + pType, release ); + ::typelib_typedescriptionreference_release( pType ); +} +//================================================================================================== +void destructStruct( + void * pValue, + typelib_CompoundTypeDescription * pTypeDescr, + uno_ReleaseFunc release ) + SAL_THROW( () ); +//-------------------------------------------------------------------------------------------------- +inline void _destructStruct( + void * pValue, + typelib_CompoundTypeDescription * pTypeDescr, + uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + if (pTypeDescr->pBaseTypeDescription) + { + destructStruct( pValue, pTypeDescr->pBaseTypeDescription, release ); + } + + typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs; + sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; + sal_Int32 nDescr = pTypeDescr->nMembers; + while (nDescr--) + { + ::uno_type_destructData( + (char *)pValue + pMemberOffsets[nDescr], + ppTypeRefs[nDescr], release ); + } +} + +//-------------------------------------------------------------------------------------------------- +inline void _destructArray( + void * pValue, + typelib_ArrayTypeDescription * pTypeDescr, + uno_ReleaseFunc release ) + throw () +{ + typelib_TypeDescription * pElementType = NULL; + TYPELIB_DANGER_GET( &pElementType, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType ); + sal_Int32 nElementSize = pElementType->nSize; + TYPELIB_DANGER_RELEASE( pElementType ); + + sal_Int32 nTotalElements = pTypeDescr->nTotalElements; + for(sal_Int32 i=0; i < nTotalElements; i++) + { + ::uno_type_destructData( + (sal_Char *)pValue + i * nElementSize, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, release ); + } + + typelib_typedescriptionreference_release(((typelib_IndirectTypeDescription *)pTypeDescr)->pType); +} + +//============================================================================== +void destructSequence( + uno_Sequence * pSequence, + typelib_TypeDescriptionReference * pType, + typelib_TypeDescription * pTypeDescr, + uno_ReleaseFunc release ); + +//-------------------------------------------------------------------------------------------------- +inline void _destructAny( + uno_Any * pAny, + uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + typelib_TypeDescriptionReference * pType = pAny->pType; + + switch (pType->eTypeClass) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + if (sizeof(void *) < sizeof(sal_Int64)) + { + ::rtl_freeMemory( pAny->pData ); + } + break; + case typelib_TypeClass_FLOAT: + if (sizeof(void *) < sizeof(float)) + { + ::rtl_freeMemory( pAny->pData ); + } + break; + case typelib_TypeClass_DOUBLE: + if (sizeof(void *) < sizeof(double)) + { + ::rtl_freeMemory( pAny->pData ); + } + break; + case typelib_TypeClass_STRING: + ::rtl_uString_release( (rtl_uString *)pAny->pReserved ); + break; + case typelib_TypeClass_TYPE: + ::typelib_typedescriptionreference_release( + (typelib_TypeDescriptionReference *)pAny->pReserved ); + break; + case typelib_TypeClass_ANY: + OSL_ENSURE( sal_False, "### unexpected nested any!" ); + ::uno_any_destruct( (uno_Any *)pAny->pData, release ); + ::rtl_freeMemory( pAny->pData ); + break; + case typelib_TypeClass_TYPEDEF: + OSL_ENSURE( 0, "### unexpected typedef!" ); + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _destructStruct( pAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr, release ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + ::rtl_freeMemory( pAny->pData ); + break; + } + case typelib_TypeClass_UNION: + { + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _destructUnion( pAny->pData, pTypeDescr, release ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + ::rtl_freeMemory( pAny->pData ); + break; + } + case typelib_TypeClass_SEQUENCE: + { + destructSequence( + *(uno_Sequence **) &pAny->pReserved, pType, 0, release ); + break; + } + case typelib_TypeClass_INTERFACE: + _release( pAny->pReserved, release ); + break; + default: + break; + } +#if OSL_DEBUG_LEVEL > 0 + pAny->pData = (void *)0xdeadbeef; +#endif + + ::typelib_typedescriptionreference_release( pType ); +} +//-------------------------------------------------------------------------------------------------- +inline sal_Int32 idestructElements( + void * pElements, typelib_TypeDescriptionReference * pElementType, + sal_Int32 nStartIndex, sal_Int32 nStopIndex, + uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + switch (pElementType->eTypeClass) + { + case typelib_TypeClass_CHAR: + return (sal_Int32)(sizeof(sal_Unicode)); + case typelib_TypeClass_BOOLEAN: + return (sal_Int32)(sizeof(sal_Bool)); + case typelib_TypeClass_BYTE: + return (sal_Int32)(sizeof(sal_Int8)); + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + return (sal_Int32)(sizeof(sal_Int16)); + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + return (sal_Int32)(sizeof(sal_Int32)); + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + return (sal_Int32)(sizeof(sal_Int64)); + case typelib_TypeClass_FLOAT: + return (sal_Int32)(sizeof(float)); + case typelib_TypeClass_DOUBLE: + return (sal_Int32)(sizeof(double)); + + case typelib_TypeClass_STRING: + { + rtl_uString ** pDest = (rtl_uString **)pElements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + ::rtl_uString_release( pDest[nPos] ); + } + return (sal_Int32)(sizeof(rtl_uString *)); + } + case typelib_TypeClass_TYPE: + { + typelib_TypeDescriptionReference ** pDest = (typelib_TypeDescriptionReference **)pElements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + ::typelib_typedescriptionreference_release( pDest[nPos] ); + } + return (sal_Int32)(sizeof(typelib_TypeDescriptionReference *)); + } + case typelib_TypeClass_ANY: + { + uno_Any * pDest = (uno_Any *)pElements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + _destructAny( &pDest[nPos], release ); + } + return (sal_Int32)(sizeof(uno_Any)); + } + case typelib_TypeClass_ENUM: + return (sal_Int32)(sizeof(sal_Int32)); + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + _destructStruct( + (char *)pElements + (nElementSize * nPos), + (typelib_CompoundTypeDescription *)pElementTypeDescr, + release ); + } + sal_Int32 nSize = pElementTypeDescr->nSize; + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return nSize; + } + case typelib_TypeClass_UNION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + _destructUnion( + (char *)pElements + (nElementSize * nPos), + pElementTypeDescr, + release ); + } + sal_Int32 nSize = pElementTypeDescr->nSize; + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return nSize; + } + case typelib_TypeClass_SEQUENCE: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + uno_Sequence ** pDest = (uno_Sequence **)pElements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + destructSequence( + pDest[nPos], + pElementTypeDescr->pWeakRef, pElementTypeDescr, + release ); + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return (sal_Int32)(sizeof(uno_Sequence *)); + } + case typelib_TypeClass_INTERFACE: + { + if (release) + { + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + void * p = ((void **)pElements)[nPos]; + if (p) + { + (*release)( p ); + } + } + } + else + { + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + uno_Interface * p = ((uno_Interface **)pElements)[nPos]; + if (p) + { + (*p->release)( p ); + } + } + } + return (sal_Int32)(sizeof(void *)); + } + default: + OSL_ASSERT(false); + return 0; + } +} + +//------------------------------------------------------------------------------ +inline void idestructSequence( + uno_Sequence * pSeq, + typelib_TypeDescriptionReference * pType, + typelib_TypeDescription * pTypeDescr, + uno_ReleaseFunc release ) +{ + if (::osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0) + { + if (pSeq->nElements > 0) + { + if (pTypeDescr) + { + idestructElements( + pSeq->elements, + ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0, + pSeq->nElements, release ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + idestructElements( + pSeq->elements, + ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0, + pSeq->nElements, release ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + } + ::rtl_freeMemory( pSeq ); + } +} + +//-------------------------------------------------------------------------------------------------- +inline void _destructData( + void * pValue, + typelib_TypeDescriptionReference * pType, + typelib_TypeDescription * pTypeDescr, + uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + switch (pType->eTypeClass) + { + case typelib_TypeClass_STRING: + ::rtl_uString_release( *(rtl_uString **)pValue ); + break; + case typelib_TypeClass_TYPE: + ::typelib_typedescriptionreference_release( *(typelib_TypeDescriptionReference **)pValue ); + break; + case typelib_TypeClass_ANY: + _destructAny( (uno_Any *)pValue, release ); + break; + case typelib_TypeClass_TYPEDEF: + OSL_ENSURE( 0, "### unexpected typedef!" ); + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (pTypeDescr) + { + _destructStruct( pValue, (typelib_CompoundTypeDescription *)pTypeDescr, release ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _destructStruct( pValue, (typelib_CompoundTypeDescription *)pTypeDescr, release ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_ARRAY: + if (pTypeDescr) + { + _destructArray( pValue, (typelib_ArrayTypeDescription *)pTypeDescr, release ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _destructArray( pValue, (typelib_ArrayTypeDescription *)pTypeDescr, release ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_UNION: + if (pTypeDescr) + { + _destructUnion( pValue, pTypeDescr, release ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _destructUnion( pValue, pTypeDescr, release ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_SEQUENCE: + { + idestructSequence( + *(uno_Sequence **)pValue, pType, pTypeDescr, release ); + break; + } + case typelib_TypeClass_INTERFACE: + _release( *(void **)pValue, release ); + break; + default: + break; + } +} + +} + +#endif diff --git a/cppu/source/uno/env_subst.cxx b/cppu/source/uno/env_subst.cxx new file mode 100644 index 000000000000..4465a9e1815e --- /dev/null +++ b/cppu/source/uno/env_subst.cxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "rtl/ustring.hxx" +#include "uno/environment.h" +#include "env_subst.hxx" + + +void SAL_CALL uno_getEnvironment(uno_Environment ** ppEnv, + rtl_uString * pEnvDcp, + void * pContext) + SAL_THROW_EXTERN_C() +{ + rtl::OUString envDcp(pEnvDcp); + + rtl::OString a_envName("UNO_ENV_SUBST:"); + a_envName += rtl::OUStringToOString(envDcp, RTL_TEXTENCODING_ASCII_US); + char * c_value = getenv(a_envName.getStr()); + if (c_value && rtl_str_getLength(c_value)) + { + rtl::OString a_envDcp(a_envName.copy(a_envName.indexOf(':') + 1)); + + OSL_TRACE("UNO_ENV_SUBST \"%s\" -> \"%s\"", a_envDcp.getStr(), c_value); + rtl::OUString value(c_value, rtl_str_getLength(c_value), RTL_TEXTENCODING_ASCII_US); + + envDcp = value; + } + + uno_direct_getEnvironment(ppEnv, envDcp.pData, pContext); +} diff --git a/cppu/source/uno/env_subst.hxx b/cppu/source/uno/env_subst.hxx new file mode 100644 index 000000000000..8ee8631ced84 --- /dev/null +++ b/cppu/source/uno/env_subst.hxx @@ -0,0 +1,41 @@ +/************************************************************************* + * + * 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 INCLUDED_env_substs_hxx +#define INCLUDED_env_substs_hxx + +#include "rtl/ustring.hxx" +#include "uno/environment.h" + + +extern "C" void SAL_CALL uno_direct_getEnvironment(uno_Environment ** ppEnv, + rtl_uString * pEnvDcp, + void * pContext) + SAL_THROW_EXTERN_C(); + + +#endif diff --git a/cppu/source/uno/eq.hxx b/cppu/source/uno/eq.hxx new file mode 100644 index 000000000000..45bc0e79cfaa --- /dev/null +++ b/cppu/source/uno/eq.hxx @@ -0,0 +1,668 @@ +/************************************************************************* + * + * 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 EQ_HXX +#define EQ_HXX + +#include <math.h> +#include <rtl/memory.h> + +#include "prim.hxx" +#include "destr.hxx" + + +namespace cppu +{ + +//################################################################################################## +//#### equality #################################################################################### +//################################################################################################## + +//-------------------------------------------------------------------------------------------------- +inline sal_Bool _equalObject( + void * pI1, void * pI2, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + if (pI1 == pI2) + return sal_True; + if ((0 == pI1) || (0 == pI2)) + return sal_False; + sal_Bool bRet = sal_False; + + typelib_TypeDescriptionReference * type_XInterface = + * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ); + if (0 == queryInterface) + queryInterface = binuno_queryInterface; + pI1 = (*queryInterface)( pI1, type_XInterface ); + if (0 != pI1) + { + pI2 = (*queryInterface)( pI2, type_XInterface ); + if (0 != pI2) + { + bRet = (pI1 == pI2); + _release( pI2, release ); + } + _release( pI1, release ); + } + return bRet; +} + +//================================================================================================== +sal_Bool equalStruct( + void * pDest, void *pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW( () ); +//-------------------------------------------------------------------------------------------------- +inline sal_Bool _equalStruct( + void * pDest, void *pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + if (pTypeDescr->pBaseTypeDescription && + !equalStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, queryInterface, release )) + { + return sal_False; + } + + typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs; + sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; + sal_Int32 nDescr = pTypeDescr->nMembers; + + while (nDescr--) + { + sal_Int32 nOffset = pMemberOffsets[nDescr]; + if (! ::uno_type_equalData( (char *)pDest + nOffset, + ppTypeRefs[nDescr], + (char *)pSource + nOffset, + ppTypeRefs[nDescr], + queryInterface, release )) + { + return sal_False; + } + } + return sal_True; +} +//================================================================================================== +sal_Bool equalSequence( + uno_Sequence * pDest, uno_Sequence * pSource, + typelib_TypeDescriptionReference * pElementType, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW( () ); +//-------------------------------------------------------------------------------------------------- +inline sal_Bool _equalSequence( + uno_Sequence * pDest, uno_Sequence * pSource, + typelib_TypeDescriptionReference * pElementType, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + if (pDest == pSource) + return sal_True; + sal_Int32 nElements = pDest->nElements; + if (nElements != pSource->nElements) + return sal_False; + if (! nElements) + return sal_True; + + void * pDestElements = pDest->elements; + void * pSourceElements = pSource->elements; + + switch (pElementType->eTypeClass) + { + case typelib_TypeClass_CHAR: + return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Unicode) * nElements )); + case typelib_TypeClass_BOOLEAN: + { + for ( sal_Int32 nPos = nElements; nPos--; ) + { + if ((((sal_Bool *)pDestElements)[nPos] != sal_False) != + (((sal_Bool *)pSourceElements)[nPos] != sal_False)) + { + return sal_False; + } + } + return sal_True; + } + case typelib_TypeClass_BYTE: + return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int8) * nElements )); + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int16) * nElements )); + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int32) * nElements )); + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int64) * nElements )); + case typelib_TypeClass_FLOAT: + { + for ( sal_Int32 nPos = nElements; nPos--; ) + { + if (((float *)pDestElements)[nPos] != ((float *)pSourceElements)[nPos]) + return sal_False; + } + return sal_True; + } + case typelib_TypeClass_DOUBLE: + { + for ( sal_Int32 nPos = nElements; nPos--; ) + { + if (((double *)pDestElements)[nPos] != ((double *)pSourceElements)[nPos]) + return sal_False; + } + return sal_True; + } + case typelib_TypeClass_STRING: + { + for ( sal_Int32 nPos = nElements; nPos--; ) + { + if (! ((::rtl::OUString *)pDestElements +nPos)->equals( ((const ::rtl::OUString *)pSourceElements)[nPos] )) + return sal_False; + } + return sal_True; + } + case typelib_TypeClass_TYPE: + { + for ( sal_Int32 nPos = nElements; nPos--; ) + { + if (! _type_equals( ((typelib_TypeDescriptionReference **)pDestElements)[nPos], + ((typelib_TypeDescriptionReference **)pSourceElements)[nPos] )) + { + return sal_False; + } + } + return sal_True; + } + case typelib_TypeClass_ANY: + { + for ( sal_Int32 nPos = nElements; nPos--; ) + { + uno_Any * pDest2 = (uno_Any *)pDestElements + nPos; + uno_Any * pSource2 = (uno_Any *)pSourceElements + nPos; + if (! ::uno_type_equalData( pDest2->pData, pDest2->pType, + pSource2->pData, pSource2->pType, + queryInterface, release )) + { + return sal_False; + } + } + return sal_True; + } + case typelib_TypeClass_ENUM: + return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int32) * nElements )); + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + if (! _equalStruct( (char *)pDestElements + (nPos * nElementSize), + (char *)pSourceElements + (nPos * nElementSize), + (typelib_CompoundTypeDescription *)pElementTypeDescr, + queryInterface, release )) + { + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return sal_False; + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return sal_True; + } + case typelib_TypeClass_UNION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + sal_Int32 nValueOffset = ((typelib_UnionTypeDescription *)pElementTypeDescr)->nValueOffset; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + char * pDest2 = (char *)pDestElements + (nPos * nElementSize); + char * pSource2 = (char *)pSourceElements + (nPos * nElementSize); + typelib_TypeDescriptionReference * pSetType = _unionGetSetType( + pDest2, pElementTypeDescr ); + sal_Bool bRet = ::uno_type_equalData( + pDest2 + nValueOffset, pSetType, + pSource2 + nValueOffset, pSetType, + queryInterface, release ); + ::typelib_typedescriptionreference_release( pSetType ); + if (! bRet) + { + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return sal_False; + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return sal_True; + } + case typelib_TypeClass_SEQUENCE: // sequence of sequence + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + typelib_TypeDescriptionReference * pSeqElementType = + ((typelib_IndirectTypeDescription *)pElementTypeDescr)->pType; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + if (! equalSequence( ((uno_Sequence **)pDestElements)[nPos], + ((uno_Sequence **)pSourceElements)[nPos], + pSeqElementType, queryInterface, release )) + { + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return sal_False; + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + return sal_True; + } + case typelib_TypeClass_INTERFACE: + { + for ( sal_Int32 nPos = nElements; nPos--; ) + { + if (! _equalObject( ((void **)pDestElements)[nPos], ((void **)pSourceElements)[nPos], + queryInterface, release )) + { + return sal_False; + } + } + return sal_True; + } + default: + OSL_ASSERT(false); + return sal_False; + } +} +//-------------------------------------------------------------------------------------------------- +inline sal_Bool _equalData( + void * pDest, + typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr, + void * pSource, + typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr, + uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) + SAL_THROW( () ) +{ + typelib_TypeClass eSourceTypeClass, eDestTypeClass; + while (typelib_TypeClass_ANY == (eDestTypeClass = pDestType->eTypeClass)) + { + pDestTypeDescr = 0; + pDestType = ((uno_Any *)pDest)->pType; + pDest = ((uno_Any *)pDest)->pData; + } + while (typelib_TypeClass_ANY == (eSourceTypeClass = pSourceType->eTypeClass)) + { + pSourceTypeDescr = 0; + pSourceType = ((uno_Any *)pSource)->pType; + pSource = ((uno_Any *)pSource)->pData; + } + + switch (eDestTypeClass) + { + case typelib_TypeClass_VOID: + return eSourceTypeClass == typelib_TypeClass_VOID; + case typelib_TypeClass_CHAR: + return eSourceTypeClass == typelib_TypeClass_CHAR + && *(sal_Unicode *)pDest == *(sal_Unicode *)pSource; + case typelib_TypeClass_BOOLEAN: + return eSourceTypeClass == typelib_TypeClass_BOOLEAN + && ((*(sal_Bool *)pDest != sal_False) + == (*(sal_Bool *)pSource != sal_False)); + case typelib_TypeClass_BYTE: + switch (eSourceTypeClass) + { + case typelib_TypeClass_BYTE: + return (*(sal_Int8 *)pDest == *(sal_Int8 *)pSource); + case typelib_TypeClass_SHORT: + return ((sal_Int16)*(sal_Int8 *)pDest == *(sal_Int16 *)pSource); + case typelib_TypeClass_UNSIGNED_SHORT: + return ((sal_Int32)*(sal_Int8 *)pDest == (sal_Int32)*(sal_uInt16 *)pSource); + case typelib_TypeClass_LONG: + return ((sal_Int32)*(sal_Int8 *)pDest == *(sal_Int32 *)pSource); + case typelib_TypeClass_UNSIGNED_LONG: + return ((sal_Int64)*(sal_Int8 *)pDest == (sal_Int64)*(sal_uInt32 *)pSource); + case typelib_TypeClass_HYPER: + return ((sal_Int64)*(sal_Int8 *)pDest == *(sal_Int64 *)pSource); + case typelib_TypeClass_UNSIGNED_HYPER: + return (*(sal_Int8 *)pDest >= 0 && + (sal_Int64)*(sal_Int8 *)pDest == *(sal_Int64 *)pSource); // same size + case typelib_TypeClass_FLOAT: + return ((float)*(sal_Int8 *)pDest == *(float *)pSource); + case typelib_TypeClass_DOUBLE: + return ((double)*(sal_Int8 *)pDest == *(double *)pSource); + default: + return sal_False; + } + case typelib_TypeClass_SHORT: + switch (eSourceTypeClass) + { + case typelib_TypeClass_BYTE: + return (*(sal_Int16 *)pDest == (sal_Int16)*(sal_Int8 *)pSource); + case typelib_TypeClass_SHORT: + return (*(sal_Int16 *)pDest == *(sal_Int16 *)pSource); + case typelib_TypeClass_UNSIGNED_SHORT: + return ((sal_Int32)*(sal_Int16 *)pDest == (sal_Int32)*(sal_uInt16 *)pSource); + case typelib_TypeClass_LONG: + return ((sal_Int32)*(sal_Int16 *)pDest == *(sal_Int32 *)pSource); + case typelib_TypeClass_UNSIGNED_LONG: + return ((sal_Int64)*(sal_Int16 *)pDest == (sal_Int64)*(sal_uInt32 *)pSource); + case typelib_TypeClass_HYPER: + return ((sal_Int64)*(sal_Int16 *)pDest == *(sal_Int64 *)pSource); + case typelib_TypeClass_UNSIGNED_HYPER: + return (*(sal_Int16 *)pDest >= 0 && + (sal_Int64)*(sal_Int16 *)pDest == *(sal_Int64 *)pSource); // same size + case typelib_TypeClass_FLOAT: + return ((float)*(sal_Int16 *)pDest == *(float *)pSource); + case typelib_TypeClass_DOUBLE: + return ((double)*(sal_Int16 *)pDest == *(double *)pSource); + default: + return sal_False; + } + case typelib_TypeClass_UNSIGNED_SHORT: + switch (eSourceTypeClass) + { + case typelib_TypeClass_BYTE: + return ((sal_Int32)*(sal_uInt16 *)pDest == (sal_Int32)*(sal_Int8 *)pSource); + case typelib_TypeClass_SHORT: + return ((sal_Int32)*(sal_uInt16 *)pDest == (sal_Int32)*(sal_Int16 *)pSource); + case typelib_TypeClass_UNSIGNED_SHORT: + return (*(sal_uInt16 *)pDest == *(sal_uInt16 *)pSource); + case typelib_TypeClass_LONG: + return ((sal_Int32)*(sal_uInt16 *)pDest == *(sal_Int32 *)pSource); + case typelib_TypeClass_UNSIGNED_LONG: + return ((sal_uInt32)*(sal_uInt16 *)pDest == *(sal_uInt32 *)pSource); + case typelib_TypeClass_HYPER: + return ((sal_Int64)*(sal_uInt16 *)pDest == *(sal_Int64 *)pSource); + case typelib_TypeClass_UNSIGNED_HYPER: + return ((sal_uInt64)*(sal_uInt16 *)pDest == *(sal_uInt64 *)pSource); + case typelib_TypeClass_FLOAT: + return ((float)*(sal_uInt16 *)pDest == *(float *)pSource); + case typelib_TypeClass_DOUBLE: + return ((double)*(sal_uInt16 *)pDest == *(double *)pSource); + default: + return sal_False; + } + case typelib_TypeClass_LONG: + switch (eSourceTypeClass) + { + case typelib_TypeClass_BYTE: + return (*(sal_Int32 *)pDest == (sal_Int32)*(sal_Int8 *)pSource); + case typelib_TypeClass_SHORT: + return (*(sal_Int32 *)pDest == (sal_Int32)*(sal_Int16 *)pSource); + case typelib_TypeClass_UNSIGNED_SHORT: + return (*(sal_Int32 *)pDest == (sal_Int32)*(sal_uInt16 *)pSource); + case typelib_TypeClass_LONG: + return (*(sal_Int32 *)pDest == *(sal_Int32 *)pSource); + case typelib_TypeClass_UNSIGNED_LONG: + return ((sal_Int64)*(sal_Int32 *)pDest == (sal_Int64)*(sal_uInt32 *)pSource); + case typelib_TypeClass_HYPER: + return ((sal_Int64)*(sal_Int32 *)pDest == *(sal_Int64 *)pSource); + case typelib_TypeClass_UNSIGNED_HYPER: + return (*(sal_Int32 *)pDest >= 0 && + (sal_Int64)*(sal_Int32 *)pDest == *(sal_Int64 *)pSource); // same size + case typelib_TypeClass_FLOAT: + return ((float)*(sal_Int32 *)pDest == *(float *)pSource); + case typelib_TypeClass_DOUBLE: + return ((double)*(sal_Int32 *)pDest == *(double *)pSource); + default: + return sal_False; + } + case typelib_TypeClass_UNSIGNED_LONG: + switch (eSourceTypeClass) + { + case typelib_TypeClass_BYTE: + return ((sal_Int64)*(sal_uInt32 *)pDest == (sal_Int64)*(sal_Int8 *)pSource); + case typelib_TypeClass_SHORT: + return ((sal_Int64)*(sal_uInt32 *)pDest == (sal_Int64)*(sal_Int16 *)pSource); + case typelib_TypeClass_UNSIGNED_SHORT: + return (*(sal_uInt32 *)pDest == (sal_uInt32)*(sal_uInt16 *)pSource); + case typelib_TypeClass_LONG: + return ((sal_Int64)*(sal_uInt32 *)pDest == (sal_Int64)*(sal_Int32 *)pSource); + case typelib_TypeClass_UNSIGNED_LONG: + return (*(sal_uInt32 *)pDest == *(sal_uInt32 *)pSource); + case typelib_TypeClass_HYPER: + return ((sal_Int64)*(sal_uInt32 *)pDest == *(sal_Int64 *)pSource); + case typelib_TypeClass_UNSIGNED_HYPER: + return ((sal_uInt64)*(sal_uInt32 *)pDest == *(sal_uInt64 *)pSource); + case typelib_TypeClass_FLOAT: + return ((float)*(sal_uInt32 *)pDest == *(float *)pSource); + case typelib_TypeClass_DOUBLE: + return ((double)*(sal_uInt32 *)pDest == *(double *)pSource); + default: + return sal_False; + } + case typelib_TypeClass_HYPER: + switch (eSourceTypeClass) + { + case typelib_TypeClass_BYTE: + return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_Int8 *)pSource); + case typelib_TypeClass_SHORT: + return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_Int16 *)pSource); + case typelib_TypeClass_UNSIGNED_SHORT: + return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_uInt16 *)pSource); + case typelib_TypeClass_LONG: + return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_Int32 *)pSource); + case typelib_TypeClass_UNSIGNED_LONG: + return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_uInt32 *)pSource); + case typelib_TypeClass_HYPER: + return (*(sal_Int64 *)pDest == *(sal_Int64 *)pSource); + case typelib_TypeClass_UNSIGNED_HYPER: + return (*(sal_Int64 *)pDest >= 0 && + *(sal_Int64 *)pDest == *(sal_Int64 *)pSource); // same size + case typelib_TypeClass_FLOAT: + return ((float)*(sal_Int64 *)pDest == *(float *)pSource); + case typelib_TypeClass_DOUBLE: + return ((double)*(sal_Int64 *)pDest == *(double *)pSource); + default: + return sal_False; + } + case typelib_TypeClass_UNSIGNED_HYPER: + switch (eSourceTypeClass) + { + case typelib_TypeClass_BYTE: + return (*(sal_Int8 *)pSource >= 0 && + *(sal_uInt64 *)pDest == (sal_uInt64)*(sal_Int8 *)pSource); + case typelib_TypeClass_SHORT: + return (*(sal_Int16 *)pSource >= 0 && + *(sal_uInt64 *)pDest == (sal_uInt64)*(sal_Int16 *)pSource); + case typelib_TypeClass_UNSIGNED_SHORT: + return (*(sal_uInt64 *)pDest == (sal_uInt64)*(sal_uInt16 *)pSource); + case typelib_TypeClass_LONG: + return (*(sal_Int32 *)pSource >= 0 && + *(sal_uInt64 *)pDest == (sal_uInt64)*(sal_Int32 *)pSource); + case typelib_TypeClass_UNSIGNED_LONG: + return (*(sal_uInt64 *)pDest == (sal_uInt64)*(sal_uInt32 *)pSource); + case typelib_TypeClass_HYPER: + return (*(sal_Int64 *)pSource >= 0 && + *(sal_uInt64 *)pDest == (sal_uInt64)*(sal_Int64 *)pSource); + case typelib_TypeClass_UNSIGNED_HYPER: + return (*(sal_uInt64 *)pDest == *(sal_uInt64 *)pSource); + case typelib_TypeClass_FLOAT: + if (::floor( *(float *)pSource ) != *(float *)pSource || *(float *)pSource < 0) + return sal_False; + return (*(sal_uInt64 *)pDest == (sal_uInt64)*(float *)pSource); + case typelib_TypeClass_DOUBLE: + if (::floor( *(double *)pSource ) != *(double *)pSource || *(double *)pSource < 0) + return sal_False; + return (*(sal_uInt64 *)pDest == (sal_uInt64)*(double *)pSource); + default: + return sal_False; + } + case typelib_TypeClass_FLOAT: + switch (eSourceTypeClass) + { + case typelib_TypeClass_BYTE: + return (*(float *)pDest == (float)*(sal_Int8 *)pSource); + case typelib_TypeClass_SHORT: + return (*(float *)pDest == (float)*(sal_Int16 *)pSource); + case typelib_TypeClass_UNSIGNED_SHORT: + return (*(float *)pDest == (float)*(sal_uInt16 *)pSource); + case typelib_TypeClass_LONG: + return (*(float *)pDest == (float)*(sal_Int32 *)pSource); + case typelib_TypeClass_UNSIGNED_LONG: + return (*(float *)pDest == (float)*(sal_uInt32 *)pSource); + case typelib_TypeClass_HYPER: + return (*(float *)pDest == (float)*(sal_Int64 *)pSource); + case typelib_TypeClass_UNSIGNED_HYPER: + if (::floor( *(float *)pDest ) != *(float *)pDest || *(float *)pDest < 0) + return sal_False; + return ((sal_uInt64)*(float *)pDest == *(sal_uInt64 *)pSource); + case typelib_TypeClass_FLOAT: + return (*(float *)pDest == *(float *)pSource); + case typelib_TypeClass_DOUBLE: + return ((double)*(float *)pDest == *(double *)pSource); + default: + return sal_False; + } + case typelib_TypeClass_DOUBLE: + switch (eSourceTypeClass) + { + case typelib_TypeClass_BYTE: + return (*(double *)pDest == (double)*(sal_Int8 *)pSource); + case typelib_TypeClass_SHORT: + return (*(double *)pDest == (double)*(sal_Int16 *)pSource); + case typelib_TypeClass_UNSIGNED_SHORT: + return (*(double *)pDest == (double)*(sal_uInt16 *)pSource); + case typelib_TypeClass_LONG: + return (*(double *)pDest == (double)*(sal_Int32 *)pSource); + case typelib_TypeClass_UNSIGNED_LONG: + return (*(double *)pDest == (double)*(sal_uInt32 *)pSource); + case typelib_TypeClass_HYPER: + return (*(double *)pDest == (double)*(sal_Int64 *)pSource); + case typelib_TypeClass_UNSIGNED_HYPER: + if (::floor( *(double *)pDest ) != *(double *)pDest || *(double *)pDest < 0) + return sal_False; + return ((sal_uInt64)*(double *)pDest == *(sal_uInt64 *)pSource); + case typelib_TypeClass_FLOAT: + return (*(double *)pDest == (double)*(float *)pSource); + case typelib_TypeClass_DOUBLE: + return (*(double *)pDest == *(double *)pSource); + default: + return sal_False; + } + case typelib_TypeClass_STRING: + return eSourceTypeClass == typelib_TypeClass_STRING + && ((::rtl::OUString *)pDest)->equals( + *(::rtl::OUString const *)pSource ); + case typelib_TypeClass_TYPE: + return eSourceTypeClass == typelib_TypeClass_TYPE + && _type_equals( + *(typelib_TypeDescriptionReference **)pDest, + *(typelib_TypeDescriptionReference **)pSource ); + case typelib_TypeClass_ENUM: + return (_type_equals( pDestType, pSourceType ) && + *(sal_Int32 *)pDest == *(sal_Int32 *)pSource); + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (! _type_equals( pDestType, pSourceType )) + return sal_False; + if (pDestTypeDescr) + { + return _equalStruct( + pDest, pSource, + (typelib_CompoundTypeDescription *)pDestTypeDescr, + queryInterface, release ); + } + else + { + TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType ); + sal_Bool bRet = _equalStruct( + pDest, pSource, + (typelib_CompoundTypeDescription *)pDestTypeDescr, + queryInterface, release ); + TYPELIB_DANGER_RELEASE( pDestTypeDescr ); + return bRet; + } + case typelib_TypeClass_UNION: + if (_type_equals( pDestType, pSourceType ) && + *(sal_Int64 *)pDest == *(sal_Int64 *)pSource) // same discriminant + { + sal_Bool bRet; + if (pDestTypeDescr) + { + typelib_TypeDescriptionReference * pSetType = _unionGetSetType( + pDest, pDestTypeDescr ); + bRet = ::uno_type_equalData( + (char *)pDest + ((typelib_UnionTypeDescription *)pDestTypeDescr)->nValueOffset, + pSetType, + (char *)pSource + ((typelib_UnionTypeDescription *)pDestTypeDescr)->nValueOffset, + pSetType, + queryInterface, release ); + typelib_typedescriptionreference_release( pSetType ); + } + else + { + TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType ); + typelib_TypeDescriptionReference * pSetType = _unionGetSetType( + pDest, pDestTypeDescr ); + bRet = ::uno_type_equalData( + (char *)pDest + ((typelib_UnionTypeDescription *)pDestTypeDescr)->nValueOffset, + pSetType, + (char *)pSource + ((typelib_UnionTypeDescription *)pDestTypeDescr)->nValueOffset, + pSetType, + queryInterface, release ); + typelib_typedescriptionreference_release( pSetType ); + TYPELIB_DANGER_RELEASE( pDestTypeDescr ); + } + return bRet; + } + return sal_False; + case typelib_TypeClass_SEQUENCE: + if (_type_equals( pDestType, pSourceType )) + { + if (pDestTypeDescr) + { + return _equalSequence( + *(uno_Sequence **)pDest, *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pDestTypeDescr)->pType, + queryInterface, release ); + } + else + { + TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType ); + sal_Bool bRet = _equalSequence( + *(uno_Sequence **)pDest, *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pDestTypeDescr)->pType, + queryInterface, release ); + TYPELIB_DANGER_RELEASE( pDestTypeDescr ); + return bRet; + } + } + return sal_False; + case typelib_TypeClass_INTERFACE: + if (typelib_TypeClass_INTERFACE == eSourceTypeClass) + return _equalObject( *(void **)pDest, *(void **)pSource, queryInterface, release ); + break; + default: + OSL_ASSERT(false); + break; + } + return sal_False; +} + +} + +#endif diff --git a/cppu/source/uno/lbenv.cxx b/cppu/source/uno/lbenv.cxx new file mode 100644 index 000000000000..f9e382d7e7a5 --- /dev/null +++ b/cppu/source/uno/lbenv.cxx @@ -0,0 +1,1187 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "cppu/EnvDcp.hxx" + +#include "sal/alloca.h" +#include "osl/diagnose.h" +#include "osl/interlck.h" +#include "osl/mutex.hxx" +#include "osl/module.h" +#include "osl/process.h" +#include "rtl/process.h" +#include "rtl/unload.h" +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" +#include "rtl/ustrbuf.hxx" +#include "rtl/instance.hxx" +#include "typelib/typedescription.h" +#include "uno/dispatcher.h" +#include "uno/environment.h" +#include "uno/lbnames.h" +#include "prim.hxx" +#include "destr.hxx" +#include "loadmodule.hxx" + +#include <hash_map> +#include <vector> +#include <stdio.h> + + +using ::rtl::OUString; + +namespace +{ + +//------------------------------------------------------------------------------ +inline static bool td_equals( typelib_InterfaceTypeDescription * pTD1, + typelib_InterfaceTypeDescription * pTD2 ) +{ + return (pTD1 == pTD2 || + (((typelib_TypeDescription *)pTD1)->pTypeName->length == + ((typelib_TypeDescription *)pTD2)->pTypeName->length && + ::rtl_ustr_compare( + ((typelib_TypeDescription *) pTD1)->pTypeName->buffer, + ((typelib_TypeDescription *) pTD2)->pTypeName->buffer ) == 0)); +} + +struct ObjectEntry; +struct uno_DefaultEnvironment; + +//------------------------------------------------------------------------------ +struct InterfaceEntry +{ + sal_Int32 refCount; + void * pInterface; + uno_freeProxyFunc fpFreeProxy; + typelib_InterfaceTypeDescription * pTypeDescr; +}; + +struct ObjectEntry +{ + OUString oid; + sal_Int32 nRef; + ::std::vector< InterfaceEntry > aInterfaces; + bool mixedObject; + + inline ObjectEntry( const OUString & rOId_ ); + + inline void append( + uno_DefaultEnvironment * pEnv, + void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr, + uno_freeProxyFunc fpFreeProxy ); + inline InterfaceEntry * find( + typelib_InterfaceTypeDescription * pTypeDescr ); + inline sal_Int32 find( void * iface_ptr, ::std::size_t pos ); +}; + +//------------------------------------------------------------------------------ +struct FctPtrHash : + public ::std::unary_function< const void *, ::std::size_t > +{ + ::std::size_t operator () ( const void * pKey ) const + { return (::std::size_t) pKey; } +}; + +//------------------------------------------------------------------------------ +struct FctOUStringHash : + public ::std::unary_function< const OUString &, ::std::size_t > +{ + ::std::size_t operator () ( const OUString & rKey ) const + { return rKey.hashCode(); } +}; + +// mapping from environment name to environment +typedef ::std::hash_map< + OUString, uno_Environment *, FctOUStringHash, + ::std::equal_to< OUString > > OUString2EnvironmentMap; + +// mapping from ptr to object entry +typedef ::std::hash_map< + void *, ObjectEntry *, FctPtrHash, + ::std::equal_to< void * > > Ptr2ObjectMap; +// mapping from oid to object entry +typedef ::std::hash_map< + OUString, ObjectEntry *, FctOUStringHash, + ::std::equal_to< OUString > > OId2ObjectMap; + + +//============================================================================== +struct EnvironmentsData +{ + ::osl::Mutex mutex; + OUString2EnvironmentMap aName2EnvMap; + + EnvironmentsData() : isDisposing(false) {} + ~EnvironmentsData(); + + inline void getEnvironment( + uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext ); + inline void registerEnvironment( uno_Environment ** ppEnv ); + inline void getRegisteredEnvironments( + uno_Environment *** pppEnvs, sal_Int32 * pnLen, + uno_memAlloc memAlloc, const OUString & rEnvDcp ); + + bool isDisposing; +}; + +namespace +{ + struct theEnvironmentsData : public rtl::Static< EnvironmentsData, theEnvironmentsData > {}; +} + +//============================================================================== +struct uno_DefaultEnvironment : public uno_ExtEnvironment +{ + sal_Int32 nRef; + sal_Int32 nWeakRef; + + ::osl::Mutex mutex; + Ptr2ObjectMap aPtr2ObjectMap; + OId2ObjectMap aOId2ObjectMap; + + uno_DefaultEnvironment( + const OUString & rEnvDcp_, void * pContext_ ); + ~uno_DefaultEnvironment(); +}; + +//______________________________________________________________________________ +inline ObjectEntry::ObjectEntry( OUString const & rOId_ ) + : oid( rOId_ ), + nRef( 0 ), + mixedObject( false ) +{ + aInterfaces.reserve( 2 ); +} + +//______________________________________________________________________________ +inline void ObjectEntry::append( + uno_DefaultEnvironment * pEnv, + void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr, + uno_freeProxyFunc fpFreeProxy ) +{ + InterfaceEntry aNewEntry; + if (! fpFreeProxy) + (*pEnv->acquireInterface)( pEnv, pInterface ); + aNewEntry.refCount = 1; + aNewEntry.pInterface = pInterface; + aNewEntry.fpFreeProxy = fpFreeProxy; + typelib_typedescription_acquire( (typelib_TypeDescription *) pTypeDescr ); + aNewEntry.pTypeDescr = pTypeDescr; + + ::std::pair< Ptr2ObjectMap::iterator, bool > insertion( + pEnv->aPtr2ObjectMap.insert( Ptr2ObjectMap::value_type( + pInterface, this ) ) ); + OSL_ASSERT( insertion.second || + (find( pInterface, 0 ) >= 0 && + // points to the same object entry: + insertion.first->second == this) ); + aInterfaces.push_back( aNewEntry ); +} + +//______________________________________________________________________________ +inline InterfaceEntry * ObjectEntry::find( + typelib_InterfaceTypeDescription * pTypeDescr_ ) +{ + OSL_ASSERT( ! aInterfaces.empty() ); + if (aInterfaces.empty()) + return 0; + + // shortcut common case: + OUString const & type_name = + OUString::unacquired( + &((typelib_TypeDescription *) pTypeDescr_)->pTypeName ); + if (type_name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") )) + { + return &aInterfaces[ 0 ]; + } + + ::std::size_t nSize = aInterfaces.size(); + for ( ::std::size_t nPos = 0; nPos < nSize; ++nPos ) + { + typelib_InterfaceTypeDescription * pITD = + aInterfaces[ nPos ].pTypeDescr; + while (pITD) + { + if (td_equals( pITD, pTypeDescr_ )) + return &aInterfaces[ nPos ]; + pITD = pITD->pBaseTypeDescription; + } + } + return 0; +} + +//______________________________________________________________________________ +inline sal_Int32 ObjectEntry::find( + void * iface_ptr, ::std::size_t pos ) +{ + ::std::size_t size = aInterfaces.size(); + for ( ; pos < size; ++pos ) + { + if (aInterfaces[ pos ].pInterface == iface_ptr) + return pos; + } + return -1; +} + +extern "C" +{ + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_registerInterface( + uno_ExtEnvironment * pEnv, void ** ppInterface, + rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" ); + OUString const & rOId = OUString::unacquired( &pOId ); + + uno_DefaultEnvironment * that = + static_cast< uno_DefaultEnvironment * >( pEnv ); + ::osl::ClearableMutexGuard guard( that->mutex ); + + // try to insert dummy 0: + std::pair<OId2ObjectMap::iterator, bool> const insertion( + that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, 0 ) ) ); + if (insertion.second) + { + ObjectEntry * pOEntry = new ObjectEntry( rOId ); + insertion.first->second = pOEntry; + ++pOEntry->nRef; // another register call on object + pOEntry->append( that, *ppInterface, pTypeDescr, 0 ); + } + else // object entry exists + { + ObjectEntry * pOEntry = insertion.first->second; + ++pOEntry->nRef; // another register call on object + InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr ); + + if (pIEntry) // type entry exists + { + ++pIEntry->refCount; + if (pIEntry->pInterface != *ppInterface) + { + void * pInterface = pIEntry->pInterface; + (*pEnv->acquireInterface)( pEnv, pInterface ); + guard.clear(); + (*pEnv->releaseInterface)( pEnv, *ppInterface ); + *ppInterface = pInterface; + } + } + else + { + pOEntry->append( that, *ppInterface, pTypeDescr, 0 ); + } + } +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_registerProxyInterface( + uno_ExtEnvironment * pEnv, void ** ppInterface, uno_freeProxyFunc freeProxy, + rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr && freeProxy, + "### null ptr!" ); + OUString const & rOId = OUString::unacquired( &pOId ); + + uno_DefaultEnvironment * that = + static_cast< uno_DefaultEnvironment * >( pEnv ); + ::osl::ClearableMutexGuard guard( that->mutex ); + + // try to insert dummy 0: + std::pair<OId2ObjectMap::iterator, bool> const insertion( + that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, 0 ) ) ); + if (insertion.second) + { + ObjectEntry * pOEntry = new ObjectEntry( rOId ); + insertion.first->second = pOEntry; + ++pOEntry->nRef; // another register call on object + pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy ); + } + else // object entry exists + { + ObjectEntry * pOEntry = insertion.first->second; + + // first registration was an original, then registerProxyInterface(): + pOEntry->mixedObject |= + (!pOEntry->aInterfaces.empty() && + pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0); + + ++pOEntry->nRef; // another register call on object + InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr ); + + if (pIEntry) // type entry exists + { + if (pIEntry->pInterface == *ppInterface) + { + ++pIEntry->refCount; + } + else + { + void * pInterface = pIEntry->pInterface; + (*pEnv->acquireInterface)( pEnv, pInterface ); + --pOEntry->nRef; // manual revoke of proxy to be freed + guard.clear(); + (*freeProxy)( pEnv, *ppInterface ); + *ppInterface = pInterface; + } + } + else + { + pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy ); + } + } +} + +//------------------------------------------------------------------------------ +static void SAL_CALL s_stub_defenv_revokeInterface(va_list * pParam) +{ + uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *); + void * pInterface = va_arg(*pParam, void *); + + OSL_ENSURE( pEnv && pInterface, "### null ptr!" ); + uno_DefaultEnvironment * that = + static_cast< uno_DefaultEnvironment * >( pEnv ); + ::osl::ClearableMutexGuard guard( that->mutex ); + + Ptr2ObjectMap::const_iterator const iFind( + that->aPtr2ObjectMap.find( pInterface ) ); + OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() ); + ObjectEntry * pOEntry = iFind->second; + if (! --pOEntry->nRef) + { + // cleanup maps + that->aOId2ObjectMap.erase( pOEntry->oid ); + sal_Int32 nPos; + for ( nPos = pOEntry->aInterfaces.size(); nPos--; ) + { + that->aPtr2ObjectMap.erase( pOEntry->aInterfaces[nPos].pInterface ); + } + + // the last proxy interface of the environment might kill this + // environment, because of releasing its language binding!!! + guard.clear(); + + // release interfaces + for ( nPos = pOEntry->aInterfaces.size(); nPos--; ) + { + InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos]; + typelib_typedescription_release( + (typelib_TypeDescription *) rEntry.pTypeDescr ); + if (rEntry.fpFreeProxy) // is proxy or used interface? + { + (*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface ); + } + else + { + (*pEnv->releaseInterface)( pEnv, rEntry.pInterface ); + } + } + + delete pOEntry; + } + else if (pOEntry->mixedObject) + { + OSL_ASSERT( !pOEntry->aInterfaces.empty() && + pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0 ); + + sal_Int32 index = pOEntry->find( pInterface, 1 ); + OSL_ASSERT( index > 0 ); + if (index > 0) + { + InterfaceEntry & entry = pOEntry->aInterfaces[ index ]; + OSL_ASSERT( entry.pInterface == pInterface ); + if (entry.fpFreeProxy != 0) + { + --entry.refCount; + if (entry.refCount == 0) + { + uno_freeProxyFunc fpFreeProxy = entry.fpFreeProxy; + typelib_TypeDescription * pTypeDescr = + reinterpret_cast< typelib_TypeDescription * >( + entry.pTypeDescr ); + + pOEntry->aInterfaces.erase( + pOEntry->aInterfaces.begin() + index ); + if (pOEntry->find( pInterface, index ) < 0) + { + // proxy ptr not registered for another interface: + // remove from ptr map +#if OSL_DEBUG_LEVEL > 0 + ::std::size_t erased = +#endif + that->aPtr2ObjectMap.erase( pInterface ); + OSL_ASSERT( erased == 1 ); + } + + guard.clear(); + + typelib_typedescription_release( pTypeDescr ); + (*fpFreeProxy)( pEnv, pInterface ); + } + } + } + } +} + +static void SAL_CALL defenv_revokeInterface(uno_ExtEnvironment * pEnv, void * pInterface) +{ + uno_Environment_invoke(&pEnv->aBase, s_stub_defenv_revokeInterface, pEnv, pInterface); +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_getObjectIdentifier( + uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface ) +{ + OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" ); + if (*ppOId) + { + ::rtl_uString_release( *ppOId ); + *ppOId = 0; + } + + uno_DefaultEnvironment * that = + static_cast< uno_DefaultEnvironment * >( pEnv ); + ::osl::ClearableMutexGuard guard( that->mutex ); + + Ptr2ObjectMap::const_iterator const iFind( + that->aPtr2ObjectMap.find( pInterface ) ); + if (iFind == that->aPtr2ObjectMap.end()) + { + guard.clear(); + (*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface ); + } + else + { + rtl_uString * hstr = iFind->second->oid.pData; + rtl_uString_acquire( hstr ); + *ppOId = hstr; + } +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_getRegisteredInterface( + uno_ExtEnvironment * pEnv, void ** ppInterface, + rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" ); + if (*ppInterface) + { + (*pEnv->releaseInterface)( pEnv, *ppInterface ); + *ppInterface = 0; + } + + OUString const & rOId = OUString::unacquired( &pOId ); + uno_DefaultEnvironment * that = + static_cast< uno_DefaultEnvironment * >( pEnv ); + ::osl::MutexGuard guard( that->mutex ); + + OId2ObjectMap::const_iterator const iFind + ( that->aOId2ObjectMap.find( rOId ) ); + if (iFind != that->aOId2ObjectMap.end()) + { + InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr ); + if (pIEntry) + { + (*pEnv->acquireInterface)( pEnv, pIEntry->pInterface ); + *ppInterface = pIEntry->pInterface; + } + } +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_getRegisteredInterfaces( + uno_ExtEnvironment * pEnv, void *** pppInterfaces, sal_Int32 * pnLen, + uno_memAlloc memAlloc ) +{ + OSL_ENSURE( pEnv && pppInterfaces && pnLen && memAlloc, "### null ptr!" ); + uno_DefaultEnvironment * that = + static_cast< uno_DefaultEnvironment * >( pEnv ); + ::osl::MutexGuard guard( that->mutex ); + + sal_Int32 nLen = that->aPtr2ObjectMap.size(); + sal_Int32 nPos = 0; + void ** ppInterfaces = (void **) (*memAlloc)( nLen * sizeof (void *) ); + + Ptr2ObjectMap::const_iterator iPos( that->aPtr2ObjectMap.begin() ); + Ptr2ObjectMap::const_iterator const iEnd( that->aPtr2ObjectMap.end() ); + while (iPos != iEnd) + { + (*pEnv->acquireInterface)( pEnv, ppInterfaces[nPos++] = (*iPos).first ); + ++iPos; + } + + *pppInterfaces = ppInterfaces; + *pnLen = nLen; +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_acquire( uno_Environment * pEnv ) +{ + uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; + ::osl_incrementInterlockedCount( &that->nWeakRef ); + ::osl_incrementInterlockedCount( &that->nRef ); +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_release( uno_Environment * pEnv ) +{ + uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; + if (! ::osl_decrementInterlockedCount( &that->nRef )) + { + // invoke dispose callback + if (pEnv->environmentDisposing) + { + (*pEnv->environmentDisposing)( pEnv ); + } + + OSL_ENSURE( that->aOId2ObjectMap.empty(), "### object entries left!" ); + } + // free memory if no weak refs left + if (! ::osl_decrementInterlockedCount( &that->nWeakRef )) + { + delete that; + } +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_acquireWeak( uno_Environment * pEnv ) +{ + uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; + ::osl_incrementInterlockedCount( &that->nWeakRef ); +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_releaseWeak( uno_Environment * pEnv ) +{ + uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; + if (! ::osl_decrementInterlockedCount( &that->nWeakRef )) + { + delete that; + } +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_harden( + uno_Environment ** ppHardEnv, uno_Environment * pEnv ) +{ + if (*ppHardEnv) + { + (*(*ppHardEnv)->release)( *ppHardEnv ); + *ppHardEnv = 0; + } + + EnvironmentsData & rData = theEnvironmentsData::get(); + + if (rData.isDisposing) + return; + + uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; + { + ::osl::MutexGuard guard( rData.mutex ); + if (1 == ::osl_incrementInterlockedCount( &that->nRef )) // is dead + { + that->nRef = 0; + return; + } + } + ::osl_incrementInterlockedCount( &that->nWeakRef ); + *ppHardEnv = pEnv; +} + +//------------------------------------------------------------------------------ +static void SAL_CALL defenv_dispose( uno_Environment * ) +{ +} +} + +//______________________________________________________________________________ +uno_DefaultEnvironment::uno_DefaultEnvironment( + const OUString & rEnvDcp_, void * pContext_ ) + : nRef( 0 ), + nWeakRef( 0 ) +{ + uno_Environment * that = reinterpret_cast< uno_Environment * >(this); + that->pReserved = 0; + // functions + that->acquire = defenv_acquire; + that->release = defenv_release; + that->acquireWeak = defenv_acquireWeak; + that->releaseWeak = defenv_releaseWeak; + that->harden = defenv_harden; + that->dispose = defenv_dispose; + that->pExtEnv = this; + // identifier + ::rtl_uString_acquire( rEnvDcp_.pData ); + that->pTypeName = rEnvDcp_.pData; + that->pContext = pContext_; + + // will be late initialized + that->environmentDisposing = 0; + + uno_ExtEnvironment::registerInterface = defenv_registerInterface; + uno_ExtEnvironment::registerProxyInterface = defenv_registerProxyInterface; + uno_ExtEnvironment::revokeInterface = defenv_revokeInterface; + uno_ExtEnvironment::getObjectIdentifier = defenv_getObjectIdentifier; + uno_ExtEnvironment::getRegisteredInterface = defenv_getRegisteredInterface; + uno_ExtEnvironment::getRegisteredInterfaces = + defenv_getRegisteredInterfaces; + +} + +//______________________________________________________________________________ +uno_DefaultEnvironment::~uno_DefaultEnvironment() +{ + ::rtl_uString_release( ((uno_Environment *) this)->pTypeName ); +} + +//============================================================================== +static void writeLine( + void * stream, const sal_Char * pLine, const sal_Char * pFilter ) +{ + if (pFilter && *pFilter) + { + // lookup pFilter in pLine + while (*pLine) + { + if (*pLine == *pFilter) + { + sal_Int32 nPos = 1; + while (pLine[nPos] && pFilter[nPos] == pLine[nPos]) + { + ++nPos; + } + if (! pFilter[nPos]) + { + if (stream) + { + fprintf( (FILE *) stream, "%s\n", pLine ); + } + else + { + OSL_TRACE( pLine ); + OSL_TRACE( "\n" ); + } + } + } + ++pLine; + } + } + else + { + if (stream) + { + fprintf( (FILE *) stream, "%s\n", pLine ); + } + else + { + fprintf( stderr, "%s\n", pLine ); + } + } +} + +//============================================================================== +static void writeLine( + void * stream, const OUString & rLine, const sal_Char * pFilter ) +{ + ::rtl::OString aLine( ::rtl::OUStringToOString( + rLine, RTL_TEXTENCODING_ASCII_US ) ); + writeLine( stream, aLine.getStr(), pFilter ); +} + +//############################################################################## +extern "C" void SAL_CALL uno_dumpEnvironment( + void * stream, uno_Environment * pEnv, const sal_Char * pFilter ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( pEnv, "### null ptr!" ); + ::rtl::OUStringBuffer buf; + + if (! pEnv->pExtEnv) + { + writeLine( stream, "###################################" + "###########################################", pFilter ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment: ") ); + buf.append( pEnv->pTypeName ); + writeLine( stream, buf.makeStringAndClear(), pFilter ); + writeLine( stream, "NO INTERFACE INFORMATION AVAILABLE!", pFilter ); + return; + } + + writeLine( stream, "########################################" + "######################################", pFilter ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment dump: ") ); + buf.append( pEnv->pTypeName ); + writeLine( stream, buf.makeStringAndClear(), pFilter ); + + uno_DefaultEnvironment * that = + reinterpret_cast< uno_DefaultEnvironment * >(pEnv); + ::osl::MutexGuard guard( that->mutex ); + + Ptr2ObjectMap ptr2obj( that->aPtr2ObjectMap ); + OId2ObjectMap::const_iterator iPos( that->aOId2ObjectMap.begin() ); + while (iPos != that->aOId2ObjectMap.end()) + { + ObjectEntry * pOEntry = iPos->second; + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("+ ") ); + if (pOEntry->mixedObject) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("mixed ") ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("object entry: nRef=") ); + buf.append( pOEntry->nRef, 10 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; oid=\"") ); + buf.append( pOEntry->oid ); + buf.append( (sal_Unicode) '\"' ); + writeLine( stream, buf.makeStringAndClear(), pFilter ); + + for ( ::std::size_t nPos = 0; + nPos < pOEntry->aInterfaces.size(); ++nPos ) + { + const InterfaceEntry & rIEntry = pOEntry->aInterfaces[nPos]; + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" - ") ); + buf.append( + ((typelib_TypeDescription *) rIEntry.pTypeDescr)->pTypeName ); + if (rIEntry.fpFreeProxy) + { + buf.appendAscii( + RTL_CONSTASCII_STRINGPARAM("; proxy free=0x") ); + buf.append( + reinterpret_cast< sal_IntPtr >(rIEntry.fpFreeProxy), 16 ); + } + else + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; original") ); + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; ptr=0x") ); + buf.append( + reinterpret_cast< sal_IntPtr >(rIEntry.pInterface), 16 ); + + if (pOEntry->find( rIEntry.pInterface, nPos + 1 ) < 0) + { + ::std::size_t erased = ptr2obj.erase( rIEntry.pInterface ); + if (erased != 1) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( + " (ptr not found in map!)") ); + } + } + writeLine( stream, buf.makeStringAndClear(), pFilter ); + } + ++iPos; + } + if (! ptr2obj.empty()) + writeLine( stream, "ptr map inconsistency!!!", pFilter ); + writeLine( stream, "#####################################" + "#########################################", pFilter ); +} + +//############################################################################## +extern "C" void SAL_CALL uno_dumpEnvironmentByName( + void * stream, rtl_uString * pEnvDcp, const sal_Char * pFilter ) + SAL_THROW_EXTERN_C() +{ + uno_Environment * pEnv = 0; + uno_getEnvironment( &pEnv, pEnvDcp, 0 ); + if (pEnv) + { + ::uno_dumpEnvironment( stream, pEnv, pFilter ); + (*pEnv->release)( pEnv ); + } + else + { + ::rtl::OUStringBuffer buf( 32 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment \"") ); + buf.append( pEnvDcp ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not exist!") ); + writeLine( stream, buf.makeStringAndClear(), pFilter ); + } +} + +//------------------------------------------------------------------------------ +inline static const OUString & unoenv_getStaticOIdPart() +{ + static OUString * s_pStaticOidPart = 0; + if (! s_pStaticOidPart) + { + ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); + if (! s_pStaticOidPart) + { + ::rtl::OUStringBuffer aRet( 64 ); + aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") ); + // pid + oslProcessInfo info; + info.Size = sizeof(oslProcessInfo); + if (::osl_getProcessInfo( 0, osl_Process_IDENTIFIER, &info ) == + osl_Process_E_None) + { + aRet.append( (sal_Int64)info.Ident, 16 ); + } + else + { + aRet.appendAscii( + RTL_CONSTASCII_STRINGPARAM("unknown process id") ); + } + // good guid + sal_uInt8 ar[16]; + ::rtl_getGlobalProcessId( ar ); + aRet.append( (sal_Unicode)';' ); + for ( sal_Int32 i = 0; i < 16; ++i ) + aRet.append( (sal_Int32)ar[i], 16 ); + + static OUString s_aStaticOidPart( aRet.makeStringAndClear() ); + s_pStaticOidPart = &s_aStaticOidPart; + } + } + return *s_pStaticOidPart; +} + +extern "C" +{ + +//------------------------------------------------------------------------------ +static void SAL_CALL unoenv_computeObjectIdentifier( + uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface ) +{ + OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" ); + if (*ppOId) + { + ::rtl_uString_release( *ppOId ); + *ppOId = 0; + } + + uno_Interface * pUnoI = (uno_Interface *) + ::cppu::binuno_queryInterface( + pInterface, *typelib_static_type_getByTypeClass( + typelib_TypeClass_INTERFACE ) ); + if (0 != pUnoI) + { + (*pUnoI->release)( pUnoI ); + // interface + ::rtl::OUStringBuffer oid( 64 ); + oid.append( reinterpret_cast< sal_Int64 >(pUnoI), 16 ); + oid.append( static_cast< sal_Unicode >(';') ); + // environment[context] + oid.append( ((uno_Environment *) pEnv)->pTypeName ); + oid.append( static_cast< sal_Unicode >('[') ); + oid.append( reinterpret_cast< sal_Int64 >( + reinterpret_cast< + uno_Environment * >(pEnv)->pContext ), 16 ); + // process;good guid + oid.append( unoenv_getStaticOIdPart() ); + OUString aStr( oid.makeStringAndClear() ); + ::rtl_uString_acquire( *ppOId = aStr.pData ); + } +} + +//============================================================================== +static void SAL_CALL unoenv_acquireInterface( + uno_ExtEnvironment *, void * pUnoI_ ) +{ + uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_); + (*pUnoI->acquire)( pUnoI ); +} + +//============================================================================== +static void SAL_CALL unoenv_releaseInterface( + uno_ExtEnvironment *, void * pUnoI_ ) +{ + uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_); + (*pUnoI->release)( pUnoI ); +} +} + +//______________________________________________________________________________ +EnvironmentsData::~EnvironmentsData() +{ + ::osl::MutexGuard guard( mutex ); + isDisposing = true; + + for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() ); + iPos != aName2EnvMap.end(); ++iPos ) + { + uno_Environment * pWeak = iPos->second; + uno_Environment * pHard = 0; + (*pWeak->harden)( &pHard, pWeak ); + (*pWeak->releaseWeak)( pWeak ); + + if (pHard) + { +#if OSL_DEBUG_LEVEL > 1 + ::uno_dumpEnvironment( 0, pHard, 0 ); +#endif + (*pHard->dispose)( pHard ); // send explicit dispose + (*pHard->release)( pHard ); + } + } +} + +//______________________________________________________________________________ +inline void EnvironmentsData::getEnvironment( + uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext ) +{ + if (*ppEnv) + { + (*(*ppEnv)->release)( *ppEnv ); + *ppEnv = 0; + } + + OUString aKey( + OUString::valueOf( reinterpret_cast< sal_IntPtr >(pContext) ) ); + aKey += rEnvDcp; + + // try to find registered mapping + OUString2EnvironmentMap::const_iterator const iFind( + aName2EnvMap.find( aKey ) ); + if (iFind != aName2EnvMap.end()) + { + uno_Environment * pWeak = iFind->second; + (*pWeak->harden)( ppEnv, pWeak ); + } +} + +//______________________________________________________________________________ +inline void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv ) +{ + OSL_ENSURE( ppEnv, "### null ptr!" ); + uno_Environment * pEnv = *ppEnv; + + OUString aKey( + OUString::valueOf( reinterpret_cast< sal_IntPtr >(pEnv->pContext) ) ); + aKey += pEnv->pTypeName; + + // try to find registered environment + OUString2EnvironmentMap::const_iterator const iFind( + aName2EnvMap.find( aKey ) ); + if (iFind == aName2EnvMap.end()) + { + (*pEnv->acquireWeak)( pEnv ); + ::std::pair< OUString2EnvironmentMap::iterator, bool > insertion( + aName2EnvMap.insert( + OUString2EnvironmentMap::value_type( aKey, pEnv ) ) ); + OSL_ENSURE( + insertion.second, "### insertion of env into map failed?!" ); + } + else + { + uno_Environment * pHard = 0; + uno_Environment * pWeak = iFind->second; + (*pWeak->harden)( &pHard, pWeak ); + if (pHard) + { + if (pEnv) + (*pEnv->release)( pEnv ); + *ppEnv = pHard; + } + else // registered one is dead + { + (*pWeak->releaseWeak)( pWeak ); + (*pEnv->acquireWeak)( pEnv ); + aName2EnvMap[ aKey ] = pEnv; + } + } +} + +//______________________________________________________________________________ +inline void EnvironmentsData::getRegisteredEnvironments( + uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc, + const OUString & rEnvDcp ) +{ + OSL_ENSURE( pppEnvs && pnLen && memAlloc, "### null ptr!" ); + + // max size + uno_Environment ** ppFound = (uno_Environment **)alloca( + sizeof(uno_Environment *) * aName2EnvMap.size() ); + sal_Int32 nSize = 0; + + // find matching environment + for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() ); + iPos != aName2EnvMap.end(); ++iPos ) + { + uno_Environment * pWeak = iPos->second; + if (!rEnvDcp.getLength() || + rEnvDcp.equals( pWeak->pTypeName )) + { + ppFound[nSize] = 0; + (*pWeak->harden)( &ppFound[nSize], pWeak ); + if (ppFound[nSize]) + ++nSize; + } + } + + *pnLen = nSize; + if (nSize) + { + *pppEnvs = (uno_Environment **) (*memAlloc)( + sizeof (uno_Environment *) * nSize ); + OSL_ASSERT( *pppEnvs ); + while (nSize--) + { + (*pppEnvs)[nSize] = ppFound[nSize]; + } + } + else + { + *pppEnvs = 0; + } +} + +static bool loadEnv(OUString const & cLibStem, + uno_Environment * pEnv, + void * /*pContext*/) +{ + // late init with some code from matching uno language binding + // will be unloaded by environment + oslModule hMod = cppu::detail::loadModule( cLibStem ); + + if (!hMod) + return false; + + OUString aSymbolName(RTL_CONSTASCII_USTRINGPARAM(UNO_INIT_ENVIRONMENT)); + uno_initEnvironmentFunc fpInit = (uno_initEnvironmentFunc) + ::osl_getFunctionSymbol( hMod, aSymbolName.pData ); + if (!fpInit) + { + ::osl_unloadModule( hMod ); + return false; + } + + (*fpInit)( pEnv ); // init of environment + ::rtl_registerModuleForUnloading( hMod ); + + return true; +} + + +extern "C" +{ + +//------------------------------------------------------------------------------ +static uno_Environment * initDefaultEnvironment( + const OUString & rEnvDcp, void * pContext ) +{ + uno_Environment * pEnv = &(new uno_DefaultEnvironment( rEnvDcp, pContext ))->aBase; + (*pEnv->acquire)( pEnv ); + + OUString envTypeName = cppu::EnvDcp::getTypeName(rEnvDcp); + + // create default environment + if (envTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) )) + { + uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; + that->computeObjectIdentifier = unoenv_computeObjectIdentifier; + that->acquireInterface = unoenv_acquireInterface; + that->releaseInterface = unoenv_releaseInterface; + + OUString envPurpose = cppu::EnvDcp::getPurpose(rEnvDcp); + if (envPurpose.getLength()) + { + rtl::OUString libStem = envPurpose.copy(envPurpose.lastIndexOf(':') + 1); + libStem += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_uno_uno") ); + + if(!loadEnv(libStem, pEnv, pContext)) + { + pEnv->release(pEnv); + return NULL; + } + } + } + else + { + // late init with some code from matching uno language binding + ::rtl::OUStringBuffer aLibName( 16 ); + aLibName.append( envTypeName ); + aLibName.appendAscii( RTL_CONSTASCII_STRINGPARAM("_uno" ) ); + OUString aStr( aLibName.makeStringAndClear() ); + + if (!loadEnv(aStr, pEnv, pContext)) + { + pEnv->release(pEnv); + return NULL; + } + } + + return pEnv; +} + +//############################################################################## +void SAL_CALL uno_createEnvironment( + uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( ppEnv, "### null ptr!" ); + if (*ppEnv) + (*(*ppEnv)->release)( *ppEnv ); + + OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp ); + *ppEnv = initDefaultEnvironment( rEnvDcp, pContext ); +} + +//############################################################################## +void SAL_CALL uno_direct_getEnvironment( + uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( ppEnv, "### null ptr!" ); + OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp ); + + EnvironmentsData & rData = theEnvironmentsData::get(); + + ::osl::MutexGuard guard( rData.mutex ); + rData.getEnvironment( ppEnv, rEnvDcp, pContext ); + if (! *ppEnv) + { + *ppEnv = initDefaultEnvironment( rEnvDcp, pContext ); + if (*ppEnv) + { + // register new environment: + rData.registerEnvironment( ppEnv ); + } + } +} + +//############################################################################## +void SAL_CALL uno_getRegisteredEnvironments( + uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc, + rtl_uString * pEnvDcp ) + SAL_THROW_EXTERN_C() +{ + EnvironmentsData & rData = theEnvironmentsData::get(); + + ::osl::MutexGuard guard( rData.mutex ); + rData.getRegisteredEnvironments( + pppEnvs, pnLen, memAlloc, + (pEnvDcp ? OUString(pEnvDcp) : OUString()) ); +} + +} // extern "C" + +} + diff --git a/cppu/source/uno/lbmap.cxx b/cppu/source/uno/lbmap.cxx new file mode 100644 index 000000000000..d2c4a6f60641 --- /dev/null +++ b/cppu/source/uno/lbmap.cxx @@ -0,0 +1,692 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "IdentityMapping.hxx" + +#include <hash_map> +#include <set> +#include <algorithm> + +#include "rtl/unload.h" +#include "rtl/ustring.hxx" +#include "rtl/ustrbuf.hxx" +#include "osl/module.h" +#include "osl/diagnose.h" +#include "osl/mutex.hxx" +#include "osl/interlck.h" + +#include "uno/dispatcher.h" +#include "uno/mapping.h" +#include "uno/lbnames.h" +#include "uno/environment.hxx" + +#include "typelib/typedescription.h" + +#include "cppu/EnvDcp.hxx" +#include "cascade_mapping.hxx" +#include "IdentityMapping.hxx" +#include "loadmodule.hxx" + +using namespace std; +using namespace osl; +using namespace rtl; +using namespace com::sun::star::uno; + + +namespace cppu +{ + +class Mapping +{ + uno_Mapping * _pMapping; + +public: + inline Mapping( uno_Mapping * pMapping = 0 ) SAL_THROW( () ); + inline Mapping( const Mapping & rMapping ) SAL_THROW( () ); + inline ~Mapping() SAL_THROW( () ); + inline Mapping & SAL_CALL operator = ( uno_Mapping * pMapping ) SAL_THROW( () ); + inline Mapping & SAL_CALL operator = ( const Mapping & rMapping ) SAL_THROW( () ) + { return operator = ( rMapping._pMapping ); } + inline uno_Mapping * SAL_CALL get() const SAL_THROW( () ) + { return _pMapping; } + inline sal_Bool SAL_CALL is() const SAL_THROW( () ) + { return (_pMapping != 0); } +}; +//__________________________________________________________________________________________________ +inline Mapping::Mapping( uno_Mapping * pMapping ) SAL_THROW( () ) + : _pMapping( pMapping ) +{ + if (_pMapping) + (*_pMapping->acquire)( _pMapping ); +} +//__________________________________________________________________________________________________ +inline Mapping::Mapping( const Mapping & rMapping ) SAL_THROW( () ) + : _pMapping( rMapping._pMapping ) +{ + if (_pMapping) + (*_pMapping->acquire)( _pMapping ); +} +//__________________________________________________________________________________________________ +inline Mapping::~Mapping() SAL_THROW( () ) +{ + if (_pMapping) + (*_pMapping->release)( _pMapping ); +} +//__________________________________________________________________________________________________ +inline Mapping & Mapping::operator = ( uno_Mapping * pMapping ) SAL_THROW( () ) +{ + if (pMapping) + (*pMapping->acquire)( pMapping ); + if (_pMapping) + (*_pMapping->release)( _pMapping ); + _pMapping = pMapping; + return *this; +} + +//================================================================================================== +struct MappingEntry +{ + sal_Int32 nRef; + uno_Mapping * pMapping; + uno_freeMappingFunc freeMapping; + OUString aMappingName; + + MappingEntry( + uno_Mapping * pMapping_, uno_freeMappingFunc freeMapping_, + const OUString & rMappingName_ ) + SAL_THROW( () ) + : nRef( 1 ) + , pMapping( pMapping_ ) + , freeMapping( freeMapping_ ) + , aMappingName( rMappingName_ ) + {} +}; +//-------------------------------------------------------------------------------------------------- +struct FctOUStringHash : public unary_function< const OUString &, size_t > +{ + size_t operator()( const OUString & rKey ) const SAL_THROW( () ) + { return (size_t)rKey.hashCode(); } +}; +//-------------------------------------------------------------------------------------------------- +struct FctPtrHash : public unary_function< uno_Mapping *, size_t > +{ + size_t operator()( uno_Mapping * pKey ) const SAL_THROW( () ) + { return (size_t)pKey; } +}; + +typedef hash_map< + OUString, MappingEntry *, FctOUStringHash, equal_to< OUString > > t_OUString2Entry; +typedef hash_map< + uno_Mapping *, MappingEntry *, FctPtrHash, equal_to< uno_Mapping * > > t_Mapping2Entry; + +typedef set< uno_getMappingFunc > t_CallbackSet; +typedef set< OUString > t_OUStringSet; + +//================================================================================================== +struct MappingsData +{ + Mutex aMappingsMutex; + t_OUString2Entry aName2Entry; + t_Mapping2Entry aMapping2Entry; + + Mutex aCallbacksMutex; + t_CallbackSet aCallbacks; + + Mutex aNegativeLibsMutex; + t_OUStringSet aNegativeLibs; +}; +//-------------------------------------------------------------------------------------------------- +static MappingsData & getMappingsData() SAL_THROW( () ) +{ + static MappingsData * s_p = 0; + if (! s_p) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_p) + { + //TODO This memory is leaked; see #i63473# for when this should be + // changed again: + s_p = new MappingsData; + } + } + return *s_p; +} + +/** + * This class mediates two different mapping via uno, e.g. form any language to uno, + * then from uno to any other language. + */ +struct uno_Mediate_Mapping : public uno_Mapping +{ + sal_Int32 nRef; + + Environment aFrom; + Environment aTo; + + Mapping aFrom2Uno; + Mapping aUno2To; + + OUString aAddPurpose; + + uno_Mediate_Mapping( + const Environment & rFrom_, const Environment & rTo_, + const Mapping & rFrom2Uno_, const Mapping & rUno2To_, + const OUString & rAddPurpose ) + SAL_THROW( () ); +}; +extern "C" +{ +//-------------------------------------------------------------------------------------------------- +static void SAL_CALL mediate_free( uno_Mapping * pMapping ) + SAL_THROW( () ) +{ + delete static_cast< uno_Mediate_Mapping * >( pMapping ); +} +//-------------------------------------------------------------------------------------------------- +static void SAL_CALL mediate_acquire( uno_Mapping * pMapping ) + SAL_THROW( () ) +{ + if (1 == ::osl_incrementInterlockedCount( + & static_cast< uno_Mediate_Mapping * >( pMapping )->nRef )) + { + uno_registerMapping( + &pMapping, mediate_free, + static_cast< uno_Mediate_Mapping * >( pMapping )->aFrom.get(), + static_cast< uno_Mediate_Mapping * >( pMapping )->aTo.get(), + static_cast< uno_Mediate_Mapping * >( pMapping )->aAddPurpose.pData ); + } +} +//-------------------------------------------------------------------------------------------------- +static void SAL_CALL mediate_release( uno_Mapping * pMapping ) + SAL_THROW( () ) +{ + if (! ::osl_decrementInterlockedCount( + & static_cast< uno_Mediate_Mapping * >( pMapping )->nRef )) + { + uno_revokeMapping( pMapping ); + } +} +//-------------------------------------------------------------------------------------------------- +static void SAL_CALL mediate_mapInterface( + uno_Mapping * pMapping, + void ** ppOut, void * pInterface, + typelib_InterfaceTypeDescription * pInterfaceTypeDescr ) + SAL_THROW( () ) +{ + OSL_ENSURE( pMapping && ppOut, "### null ptr!" ); + if (pMapping && ppOut) + { + uno_Mediate_Mapping * that = static_cast< uno_Mediate_Mapping * >( pMapping ); + uno_Mapping * pFrom2Uno = that->aFrom2Uno.get(); + + uno_Interface * pUnoI = 0; + (*pFrom2Uno->mapInterface)( pFrom2Uno, (void **) &pUnoI, pInterface, pInterfaceTypeDescr ); + if (0 == pUnoI) + { + void * pOut = *ppOut; + if (0 != pOut) + { + uno_ExtEnvironment * pTo = that->aTo.get()->pExtEnv; + OSL_ENSURE( 0 != pTo, "### cannot release out interface: leaking!" ); + if (0 != pTo) + (*pTo->releaseInterface)( pTo, pOut ); + *ppOut = 0; // set to 0 anyway, because mapping was not successfull! + } + } + else + { + uno_Mapping * pUno2To = that->aUno2To.get(); + (*pUno2To->mapInterface)( pUno2To, ppOut, pUnoI, pInterfaceTypeDescr ); + (*pUnoI->release)( pUnoI ); + } + } +} +} +//__________________________________________________________________________________________________ +uno_Mediate_Mapping::uno_Mediate_Mapping( + const Environment & rFrom_, const Environment & rTo_, + const Mapping & rFrom2Uno_, const Mapping & rUno2To_, + const OUString & rAddPurpose_ ) + SAL_THROW( () ) + : nRef( 1 ) + , aFrom( rFrom_ ) + , aTo( rTo_ ) + , aFrom2Uno( rFrom2Uno_ ) + , aUno2To( rUno2To_ ) + , aAddPurpose( rAddPurpose_ ) +{ + uno_Mapping::acquire = mediate_acquire; + uno_Mapping::release = mediate_release; + uno_Mapping::mapInterface = mediate_mapInterface; +} + +//================================================================================================== +static inline OUString getMappingName( + const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) + SAL_THROW( () ) +{ + OUStringBuffer aKey( 64 ); + aKey.append( rAddPurpose ); + aKey.append( (sal_Unicode)';' ); + aKey.append( rFrom.getTypeName() ); + aKey.append( (sal_Unicode)'[' ); + aKey.append( reinterpret_cast< sal_IntPtr >(rFrom.get()), 16 ); + aKey.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") ); + aKey.append( rTo.getTypeName() ); + aKey.append( (sal_Unicode)'[' ); + aKey.append( reinterpret_cast< sal_IntPtr >(rTo.get()), 16 ); + aKey.append( (sal_Unicode)']' ); + return aKey.makeStringAndClear(); +} +//================================================================================================== +static inline OUString getBridgeName( + const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) + SAL_THROW( () ) +{ + OUStringBuffer aBridgeName( 16 ); + if (rAddPurpose.getLength()) + { + aBridgeName.append( rAddPurpose ); + aBridgeName.append( (sal_Unicode)'_' ); + } + aBridgeName.append( EnvDcp::getTypeName(rFrom.getTypeName()) ); + aBridgeName.append( (sal_Unicode)'_' ); + aBridgeName.append( EnvDcp::getTypeName(rTo.getTypeName()) ); + return aBridgeName.makeStringAndClear(); +} +//================================================================================================== +static inline void setNegativeBridge( const OUString & rBridgeName ) + SAL_THROW( () ) +{ + MappingsData & rData = getMappingsData(); + MutexGuard aGuard( rData.aNegativeLibsMutex ); + rData.aNegativeLibs.insert( rBridgeName ); +} +//================================================================================================== +static inline oslModule loadModule( const OUString & rBridgeName ) + SAL_THROW( () ) +{ + sal_Bool bNeg; + { + MappingsData & rData = getMappingsData(); + MutexGuard aGuard( rData.aNegativeLibsMutex ); + const t_OUStringSet::const_iterator iFind( rData.aNegativeLibs.find( rBridgeName ) ); + bNeg = (iFind != rData.aNegativeLibs.end()); + } + + if (! bNeg) + { + oslModule hModule = cppu::detail::loadModule( rBridgeName ); + + if (hModule) + return hModule; + + setNegativeBridge( rBridgeName ); // no load again + } + return 0; +} +//================================================================================================== +static Mapping loadExternalMapping( + const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) + SAL_THROW( () ) +{ + OSL_ASSERT( rFrom.is() && rTo.is() ); + if (rFrom.is() && rTo.is()) + { + // find proper lib + oslModule hModule = 0; + OUString aName; + + if (EnvDcp::getTypeName(rFrom.getTypeName()).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) )) + hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) ); + if (! hModule) + hModule = loadModule( aName = getBridgeName( rFrom, rTo, rAddPurpose ) ); + if (! hModule) + hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) ); + + if (hModule) + { + OUString aSymbolName( RTL_CONSTASCII_USTRINGPARAM(UNO_EXT_GETMAPPING) ); + uno_ext_getMappingFunc fpGetMapFunc = + (uno_ext_getMappingFunc)::osl_getFunctionSymbol( + hModule, aSymbolName.pData ); + + if (fpGetMapFunc) + { + Mapping aExt; + (*fpGetMapFunc)( (uno_Mapping **)&aExt, rFrom.get(), rTo.get() ); + OSL_ASSERT( aExt.is() ); + if (aExt.is()) + { + ::rtl_registerModuleForUnloading( hModule ); + return aExt; + } + } + ::osl_unloadModule( hModule ); + setNegativeBridge( aName ); + } + } + return Mapping(); +} + +//================================================================================================== +static Mapping getDirectMapping( + const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose = OUString() ) + SAL_THROW( () ) +{ + OSL_ASSERT( rFrom.is() && rTo.is() ); + if (rFrom.is() && rTo.is()) + { + MappingsData & rData = getMappingsData(); + ClearableMutexGuard aGuard( rData.aMappingsMutex ); + + // try to find registered mapping + const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find( + getMappingName( rFrom, rTo, rAddPurpose ) ) ); + + if (iFind == rData.aName2Entry.end()) + { + aGuard.clear(); + return loadExternalMapping( rFrom, rTo, rAddPurpose ); + } + else + { + return Mapping( (*iFind).second->pMapping ); + } + } + return Mapping(); +} + +//-------------------------------------------------------------------------------------------------- +static inline Mapping createMediateMapping( + const Environment & rFrom, const Environment & rTo, + const Mapping & rFrom2Uno, const Mapping & rUno2To, + const OUString & rAddPurpose ) + SAL_THROW( () ) +{ + uno_Mapping * pRet = new uno_Mediate_Mapping( + rFrom, rTo, rFrom2Uno, rUno2To, rAddPurpose ); // ref count initially 1 + uno_registerMapping( + &pRet, mediate_free, rFrom.get(), rTo.get(), rAddPurpose.pData ); + Mapping aRet( pRet ); + (*pRet->release)( pRet ); + return aRet; +} +//================================================================================================== +static Mapping getMediateMapping( + const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) + SAL_THROW( () ) +{ + Environment aUno; + Mapping aUno2To; + + // backwards: from dest to source of mapping chain + + // connect to uno + OUString aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ); + if (rTo.getTypeName() == aUnoEnvTypeName) // to is uno + { + aUno = rTo; + // no Uno2To mapping necessary + } + else + { + // get registered uno env + ::uno_getEnvironment( (uno_Environment **)&aUno, aUnoEnvTypeName.pData, 0 ); + + aUno2To = getDirectMapping( aUno, rTo ); + // : uno <-> to + if (! aUno2To.is()) + return Mapping(); + } + + // connect to uno + if (rAddPurpose.getLength()) // insert purpose mapping between new ano_uno <-> uno + { + // create anonymous uno env + Environment aAnUno; + ::uno_createEnvironment( (uno_Environment **)&aAnUno, aUnoEnvTypeName.pData, 0 ); + + Mapping aAnUno2Uno( getDirectMapping( aAnUno, aUno, rAddPurpose ) ); + if (! aAnUno2Uno.is()) + return Mapping(); + + if (aUno2To.is()) // to is not uno + { + // create another purposed mediate mapping + aUno2To = createMediateMapping( aAnUno, rTo, aAnUno2Uno, aUno2To, rAddPurpose ); + // : ano_uno <-> uno <-> to + } + else + { + aUno2To = aAnUno2Uno; + // : ano_uno <-> to (i.e., uno) + } + aUno = aAnUno; + } + + Mapping aFrom2Uno( getDirectMapping( rFrom, aUno ) ); + if (aFrom2Uno.is() && aUno2To.is()) + { + return createMediateMapping( rFrom, rTo, aFrom2Uno, aUno2To, rAddPurpose ); + // : from <-> some uno ... + } + + return Mapping(); +} +} + +using namespace ::cppu; + +extern "C" +{ +//################################################################################################## +void SAL_CALL uno_getMapping( + uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo, + rtl_uString * pAddPurpose ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" ); + if (*ppMapping) + { + (*(*ppMapping)->release)( *ppMapping ); + *ppMapping = 0; + } + + Mapping aRet; + Environment aFrom( pFrom ), aTo( pTo ); + + OUString aAddPurpose; + if (pAddPurpose) + aAddPurpose = pAddPurpose; + + MappingsData & rData = getMappingsData(); + + // try registered mapping + { + MutexGuard aGuard( rData.aMappingsMutex ); + const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find( + getMappingName( aFrom, aTo, aAddPurpose ) ) ); + if (iFind != rData.aName2Entry.end()) + aRet = (*iFind).second->pMapping; + } + + // See if an identity mapping does fit. + if (!aRet.is() && pFrom == pTo && !aAddPurpose.getLength()) + aRet = createIdentityMapping(pFrom); + + if (!aRet.is()) + { + getCascadeMapping(ppMapping, pFrom, pTo, pAddPurpose); + + if (*ppMapping) + return; + } + + if (! aRet.is()) // try callback chain + { + MutexGuard aGuard( rData.aCallbacksMutex ); + for ( t_CallbackSet::const_iterator iPos( rData.aCallbacks.begin() ); + iPos != rData.aCallbacks.end(); ++iPos ) + { + (**iPos)( ppMapping, pFrom, pTo, aAddPurpose.pData ); + if (*ppMapping) + return; + } + } + + if (! aRet.is()) + { + aRet = loadExternalMapping( aFrom, aTo, aAddPurpose ); // direct try + if (! aRet.is()) + aRet = getMediateMapping( aFrom, aTo, aAddPurpose ); // try via uno + } + + if (aRet.is()) + { + (*aRet.get()->acquire)( aRet.get() ); + *ppMapping = aRet.get(); + } +} +//################################################################################################## +void SAL_CALL uno_getMappingByName( + uno_Mapping ** ppMapping, rtl_uString * pFrom, rtl_uString * pTo, + rtl_uString * pAddPurpose ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" ); + if (*ppMapping) + { + (*(*ppMapping)->release)( *ppMapping ); + *ppMapping = 0; + } + + uno_Environment * pEFrom = 0; + uno_getEnvironment( &pEFrom, pFrom, 0 ); + OSL_ENSURE( pEFrom, "### cannot get source environment!" ); + if (pEFrom) + { + uno_Environment * pETo = 0; + uno_getEnvironment( &pETo, pTo, 0 ); + OSL_ENSURE( pETo, "### cannot get target environment!" ); + if (pETo) + { + ::uno_getMapping( ppMapping, pEFrom, pETo, pAddPurpose ); + (*pETo->release)( pETo ); + } + (*pEFrom->release)( pEFrom ); + } +} + +//################################################################################################## +void SAL_CALL uno_registerMapping( + uno_Mapping ** ppMapping, uno_freeMappingFunc freeMapping, + uno_Environment * pFrom, uno_Environment * pTo, rtl_uString * pAddPurpose ) + SAL_THROW_EXTERN_C() +{ + MappingsData & rData = getMappingsData(); + ClearableMutexGuard aGuard( rData.aMappingsMutex ); + + const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( *ppMapping ) ); + if (iFind == rData.aMapping2Entry.end()) + { + OUString aMappingName( + getMappingName( pFrom, pTo, pAddPurpose ? OUString(pAddPurpose) : OUString() ) ); +#if OSL_DEBUG_LEVEL > 1 + OString cstr( OUStringToOString( aMappingName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "> inserting new mapping: %s", cstr.getStr() ); +#endif + // count initially 1 + MappingEntry * pEntry = new MappingEntry( *ppMapping, freeMapping, aMappingName ); + rData.aName2Entry[ aMappingName ] = pEntry; + rData.aMapping2Entry[ *ppMapping ] = pEntry; + } + else + { + MappingEntry * pEntry = (*iFind).second; + ++pEntry->nRef; + + if (pEntry->pMapping != *ppMapping) // exchange mapping to be registered + { + (*pEntry->pMapping->acquire)( pEntry->pMapping ); + --pEntry->nRef; // correct count; kill mapping to be registered + aGuard.clear(); + (*freeMapping)( *ppMapping ); + *ppMapping = pEntry->pMapping; + } + } +} +//################################################################################################## +void SAL_CALL uno_revokeMapping( + uno_Mapping * pMapping ) + SAL_THROW_EXTERN_C() +{ + MappingsData & rData = getMappingsData(); + ClearableMutexGuard aGuard( rData.aMappingsMutex ); + + const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( pMapping ) ); + OSL_ASSERT( iFind != rData.aMapping2Entry.end() ); + MappingEntry * pEntry = (*iFind).second; + if (! --pEntry->nRef) + { + rData.aMapping2Entry.erase( pEntry->pMapping ); + rData.aName2Entry.erase( pEntry->aMappingName ); + aGuard.clear(); +#if OSL_DEBUG_LEVEL > 1 + OString cstr( OUStringToOString( pEntry->aMappingName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "> revoking mapping %s", cstr.getStr() ); +#endif + (*pEntry->freeMapping)( pEntry->pMapping ); + delete pEntry; + } +} + +//################################################################################################## +void SAL_CALL uno_registerMappingCallback( + uno_getMappingFunc pCallback ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( pCallback, "### null ptr!" ); + MappingsData & rData = getMappingsData(); + MutexGuard aGuard( rData.aCallbacksMutex ); + rData.aCallbacks.insert( pCallback ); +} +//################################################################################################## +void SAL_CALL uno_revokeMappingCallback( + uno_getMappingFunc pCallback ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( pCallback, "### null ptr!" ); + MappingsData & rData = getMappingsData(); + MutexGuard aGuard( rData.aCallbacksMutex ); + rData.aCallbacks.erase( pCallback ); +} +} // extern "C" + diff --git a/cppu/source/uno/loadmodule.cxx b/cppu/source/uno/loadmodule.cxx new file mode 100644 index 000000000000..e6858d247f04 --- /dev/null +++ b/cppu/source/uno/loadmodule.cxx @@ -0,0 +1,55 @@ +/************************************************************************* + * + * 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_cppu.hxx" + +#include "sal/config.h" + +#include "osl/module.h" +#include "rtl/string.h" +#include "rtl/ustrbuf.hxx" +#include "rtl/ustring.hxx" + +#include "loadmodule.hxx" + +namespace cppu { namespace detail { + +::oslModule loadModule(rtl::OUString const & name) { + rtl::OUStringBuffer b; +#if defined SAL_DLLPREFIX + b.appendAscii(RTL_CONSTASCII_STRINGPARAM(SAL_DLLPREFIX)); +#endif + b.append(name); + b.appendAscii(RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION)); + return ::osl_loadModuleRelative( + reinterpret_cast< oslGenericFunction >(&loadModule), + b.makeStringAndClear().pData, + SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_LAZY); +} + +} } diff --git a/cppu/source/uno/loadmodule.hxx b/cppu/source/uno/loadmodule.hxx new file mode 100644 index 000000000000..77a9bb8d6dc0 --- /dev/null +++ b/cppu/source/uno/loadmodule.hxx @@ -0,0 +1,51 @@ +/************************************************************************* + * + * 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 INCLUDED_CPPU_SOURCE_UNO_CREATEMODULENAME_HXX +#define INCLUDED_CPPU_SOURCE_UNO_CREATEMODULENAME_HXX + +#include "sal/config.h" +#include "osl/module.h" + +namespace rtl { class OUString; } + +namespace cppu { namespace detail { + +/** Load a module. + + @param name + the nucleus of a module name (without any "lib...so", ".dll", etc. + decoration, and without a path). + + @return + the handle returned by osl_loadModule. +*/ +::oslModule loadModule(::rtl::OUString const & name); + +} } + +#endif diff --git a/cppu/source/uno/makefile.mk b/cppu/source/uno/makefile.mk new file mode 100644 index 000000000000..63bf4f0387ac --- /dev/null +++ b/cppu/source/uno/makefile.mk @@ -0,0 +1,55 @@ +#************************************************************************* +# +# 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=cppu +TARGET=cppu_uno + +# --- Settings ----------------------------------------------------- + +.INCLUDE : ..$/..$/util$/makefile.pmk +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/data.obj \ + $(SLO)$/sequence.obj \ + $(SLO)$/any.obj \ + $(SLO)$/lbmap.obj \ + $(SLO)$/lbenv.obj \ + $(SLO)$/IdentityMapping.obj \ + $(SLO)$/EnvDcp.obj \ + $(SLO)$/cascade_mapping.obj \ + $(SLO)$/EnvStack.obj \ + $(SLO)$/env_subst.obj \ + $(SLO)$/loadmodule.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : ..$/..$/util$/target.pmk +.INCLUDE : target.mk diff --git a/cppu/source/uno/prim.hxx b/cppu/source/uno/prim.hxx new file mode 100644 index 000000000000..4acafd125d55 --- /dev/null +++ b/cppu/source/uno/prim.hxx @@ -0,0 +1,206 @@ +/************************************************************************* + * + * 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 PRIM_HXX +#define PRIM_HXX + +#include "typelib/typedescription.h" +#ifndef _typelib_TypeClass_H_ +#include "typelib/typeclass.h" +#endif +#include "uno/sequence2.h" +#include "uno/any2.h" +#include "uno/data.h" +#include "uno/mapping.h" +#include "uno/dispatcher.h" + +#ifndef _OSL_INTERLCK_H +#include "osl/interlck.h" +#endif +#include "osl/diagnose.h" +#ifndef _RTL_USTRING_HXX +#include "rtl/ustring.hxx" +#endif +#include "rtl/alloc.h" + +#if OSL_DEBUG_LEVEL > 1 +#include "rtl/ustrbuf.hxx" +#include "rtl/string.hxx" +#endif + + +namespace cppu +{ + +extern uno_Sequence g_emptySeq; +extern typelib_TypeDescriptionReference * g_pVoidType; + +//-------------------------------------------------------------------------------------------------- +inline void * _map( + void * p, + typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, + uno_Mapping * mapping ) + SAL_THROW( () ) +{ + void * pRet = 0; + if (p) + { + if (pTypeDescr) + { + (*mapping->mapInterface)( + mapping, &pRet, p, (typelib_InterfaceTypeDescription *)pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + (*mapping->mapInterface)( + mapping, &pRet, p, (typelib_InterfaceTypeDescription *)pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + } + return pRet; +} +//-------------------------------------------------------------------------------------------------- +inline void _acquire( void * p, uno_AcquireFunc acquire ) SAL_THROW( () ) +{ + if (p) + { + if (acquire) + { + (*acquire)( p ); + } + else + { + (*((uno_Interface *)p)->acquire)( (uno_Interface *)p ); + } + } +} +//-------------------------------------------------------------------------------------------------- +inline void _release( void * p, uno_ReleaseFunc release ) SAL_THROW( () ) +{ + if (p) + { + if (release) + { + (*release)( p ); + } + else + { + (*((uno_Interface *)p)->release)( (uno_Interface *)p ); + } + } +} + +//------------------------------------------------------------------------------ +inline sal_uInt32 calcSeqMemSize( + sal_Int32 nElementSize, sal_Int32 nElements ) +{ + sal_uInt64 nSize = + (sal_uInt64) SAL_SEQUENCE_HEADER_SIZE + + ((sal_uInt64) nElementSize * (sal_uInt64) nElements); + if (nSize > 0xffffffffU) + return 0; + else + return (sal_uInt32) nSize; +} + +//-------------------------------------------------------------------------------------------------- +inline uno_Sequence * createEmptySequence() SAL_THROW( () ) +{ + ::osl_incrementInterlockedCount( &g_emptySeq.nRefCount ); + return &g_emptySeq; +} +//-------------------------------------------------------------------------------------------------- +inline typelib_TypeDescriptionReference * _getVoidType() + SAL_THROW( () ) +{ + if (! g_pVoidType) + { + g_pVoidType = * ::typelib_static_type_getByTypeClass( typelib_TypeClass_VOID ); + } + ::typelib_typedescriptionreference_acquire( g_pVoidType ); + return g_pVoidType; +} + +//-------------------------------------------------------------------------------------------------- +#if OSL_DEBUG_LEVEL > 0 +#define CONSTRUCT_EMPTY_ANY( pAny ) \ +(pAny)->pType = _getVoidType(); \ +(pAny)->pData = (void *)0xdeadbeef; +#else +#define CONSTRUCT_EMPTY_ANY( pAny ) \ +(pAny)->pType = _getVoidType(); \ +(pAny)->pData = (pAny); +#endif + +//-------------------------------------------------------------------------------------------------- +#define TYPE_ACQUIRE( pType ) \ + ::osl_incrementInterlockedCount( &(pType)->nRefCount ); + +//-------------------------------------------------------------------------------------------------- +extern "C" void * binuno_queryInterface( + void * pUnoI, typelib_TypeDescriptionReference * pDestType ); + +//-------------------------------------------------------------------------------------------------- +inline typelib_TypeDescriptionReference * _unionGetSetType( + void * pUnion, typelib_TypeDescription * pTD ) + SAL_THROW( () ) +{ + typelib_TypeDescriptionReference * pRet = 0; + sal_Int32 nPos; + + sal_Int64 * pDiscr = ((typelib_UnionTypeDescription *)pTD)->pDiscriminants; + sal_Int64 nDiscr = *(sal_Int64 *)pUnion; + for ( nPos = ((typelib_UnionTypeDescription *)pTD)->nMembers; nPos--; ) + { + if (pDiscr[nPos] == nDiscr) + { + pRet = ((typelib_UnionTypeDescription *)pTD)->ppTypeRefs[nPos]; + break; + } + } + if (nPos >= 0) + { + // default + pRet = ((typelib_UnionTypeDescription *)pTD)->pDefaultTypeRef; + } + typelib_typedescriptionreference_acquire( pRet ); + return pRet; +} +//-------------------------------------------------------------------------------------------------- +inline sal_Bool _type_equals( + typelib_TypeDescriptionReference * pType1, typelib_TypeDescriptionReference * pType2 ) + SAL_THROW( () ) +{ + return (pType1 == pType2 || + (pType1->eTypeClass == pType2->eTypeClass && + pType1->pTypeName->length == pType2->pTypeName->length && + ::rtl_ustr_compare( pType1->pTypeName->buffer, pType2->pTypeName->buffer ) == 0)); +} + +} + +#endif diff --git a/cppu/source/uno/sequence.cxx b/cppu/source/uno/sequence.cxx new file mode 100644 index 000000000000..933d38fc6b4f --- /dev/null +++ b/cppu/source/uno/sequence.cxx @@ -0,0 +1,1016 @@ +/************************************************************************* + * + * 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_cppu.hxx" +#include <rtl/memory.h> +#include <rtl/alloc.h> +#include <osl/diagnose.h> +#include <osl/interlck.h> +#include <typelib/typedescription.h> +#include <uno/data.h> +#include <uno/dispatcher.h> +#include <uno/sequence2.h> + +#include "constr.hxx" +#include "copy.hxx" +#include "destr.hxx" + + +using namespace cppu; + +namespace cppu +{ + +//------------------------------------------------------------------------------ +static inline uno_Sequence * reallocSeq( + uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements ) +{ + OSL_ASSERT( nElements >= 0 ); + uno_Sequence * pNew = 0; + sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements ); + if (nSize > 0) + { + if (pReallocate == 0) + { + pNew = (uno_Sequence *) rtl_allocateMemory( nSize ); + } + else + { + pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize ); + } + if (pNew != 0) + { + // header init + pNew->nRefCount = 1; + pNew->nElements = nElements; + } + } + return pNew; +} + +//------------------------------------------------------------------------------ +static inline bool idefaultConstructElements( + uno_Sequence ** ppSeq, + typelib_TypeDescriptionReference * pElementType, + sal_Int32 nStartIndex, sal_Int32 nStopIndex, + sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements +{ + uno_Sequence * pSeq = *ppSeq; + switch (pElementType->eTypeClass) + { + case typelib_TypeClass_CHAR: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc ); + if (pSeq != 0) + { + ::rtl_zeroMemory( + pSeq->elements + (sizeof(sal_Unicode) * nStartIndex), + sizeof(sal_Unicode) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_BOOLEAN: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); + if (pSeq != 0) + { + ::rtl_zeroMemory( + pSeq->elements + (sizeof(sal_Bool) * nStartIndex), + sizeof(sal_Bool) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_BYTE: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); + if (pSeq != 0) + { + ::rtl_zeroMemory( + pSeq->elements + (sizeof(sal_Int8) * nStartIndex), + sizeof(sal_Int8) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc ); + if (pSeq != 0) + { + ::rtl_zeroMemory( + pSeq->elements + (sizeof(sal_Int16) * nStartIndex), + sizeof(sal_Int16) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); + if (pSeq != 0) + { + ::rtl_zeroMemory( + pSeq->elements + (sizeof(sal_Int32) * nStartIndex), + sizeof(sal_Int32) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc ); + if (pSeq != 0) + { + ::rtl_zeroMemory( + pSeq->elements + (sizeof(sal_Int64) * nStartIndex), + sizeof(sal_Int64) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_FLOAT: + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); + if (pSeq != 0) + { + float * pElements = (float *) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + pElements[nPos] = 0.0; + } + } + break; + } + case typelib_TypeClass_DOUBLE: + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(double), nAlloc ); + if (pSeq != 0) + { + double * pElements = (double *) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + pElements[nPos] = 0.0; + } + } + break; + } + case typelib_TypeClass_STRING: + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc ); + if (pSeq != 0) + { + rtl_uString ** pElements = (rtl_uString **) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + pElements[nPos] = 0; + rtl_uString_new( &pElements[nPos] ); + } + } + break; + } + case typelib_TypeClass_TYPE: + { + if (nAlloc >= 0) + { + pSeq = reallocSeq( + pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); + } + if (pSeq != 0) + { + typelib_TypeDescriptionReference ** pElements = + (typelib_TypeDescriptionReference **) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + pElements[nPos] = _getVoidType(); + } + } + break; + } + case typelib_TypeClass_ANY: + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc ); + if (pSeq != 0) + { + uno_Any * pElements = (uno_Any *) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + CONSTRUCT_EMPTY_ANY( &pElements[nPos] ); + } + } + break; + } + case typelib_TypeClass_ENUM: + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); + if (pSeq != 0) + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 eEnum = + ((typelib_EnumTypeDescription *) + pElementTypeDescr)->nDefaultEnumValue; + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + + sal_Int32 * pElements = (sal_Int32 *) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + pElements[nPos] = eEnum; + } + } + break; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); + if (pSeq != 0) + { + char * pElements = pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + _defaultConstructStruct( + pElements + (nElementSize * nPos), + (typelib_CompoundTypeDescription *)pElementTypeDescr ); + } + } + + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_ARRAY: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); + if (pSeq != 0) + { + char * pElements = pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + _defaultConstructArray( + pElements + (nElementSize * nPos), + (typelib_ArrayTypeDescription *)pElementTypeDescr ); + } + } + + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_UNION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); + if (pSeq != 0) + { + sal_Int32 nValueOffset = + ((typelib_UnionTypeDescription *) + pElementTypeDescr)->nValueOffset; + sal_Int64 nDefaultDiscr = + ((typelib_UnionTypeDescription *) + pElementTypeDescr)->nDefaultDiscriminant; + + typelib_TypeDescription * pDefaultTypeDescr = 0; + TYPELIB_DANGER_GET( + &pDefaultTypeDescr, + ((typelib_UnionTypeDescription *) + pElementTypeDescr)->pDefaultTypeRef ); + + char * pElements = pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + char * pMem = pElements + (nElementSize * nPos); + ::uno_constructData( + (char *)pMem + nValueOffset, pDefaultTypeDescr ); + *(sal_Int64 *)pMem = nDefaultDiscr; + } + TYPELIB_DANGER_RELEASE( pDefaultTypeDescr ); + } + + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_SEQUENCE: + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc ); + if (pSeq != 0) + { + uno_Sequence ** pElements = + (uno_Sequence **) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + pElements[nPos] = createEmptySequence(); + } + } + break; + } + case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc ); + if (pSeq != 0) + { + ::rtl_zeroMemory( + pSeq->elements + (sizeof(void *) * nStartIndex), + sizeof(void *) * (nStopIndex - nStartIndex) ); + } + break; + default: + OSL_ENSURE( 0, "### unexpected element type!" ); + pSeq = 0; + break; + } + + if (pSeq == 0) + { + OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure + return false; + } + else + { + *ppSeq = pSeq; + return true; + } +} + +//------------------------------------------------------------------------------ +static inline bool icopyConstructFromElements( + uno_Sequence ** ppSeq, void * pSourceElements, + typelib_TypeDescriptionReference * pElementType, + sal_Int32 nStartIndex, sal_Int32 nStopIndex, + uno_AcquireFunc acquire, + sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements +{ + uno_Sequence * pSeq = *ppSeq; + switch (pElementType->eTypeClass) + { + case typelib_TypeClass_CHAR: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc ); + if (pSeq != 0) + { + ::rtl_copyMemory( + pSeq->elements + (sizeof(sal_Unicode) * nStartIndex), + (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex), + sizeof(sal_Unicode) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_BOOLEAN: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); + if (pSeq != 0) + { + ::rtl_copyMemory( + pSeq->elements + (sizeof(sal_Bool) * nStartIndex), + (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex), + sizeof(sal_Bool) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_BYTE: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); + if (pSeq != 0) + { + ::rtl_copyMemory( + pSeq->elements + (sizeof(sal_Int8) * nStartIndex), + (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex), + sizeof(sal_Int8) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc ); + if (pSeq != 0) + { + ::rtl_copyMemory( + pSeq->elements + (sizeof(sal_Int16) * nStartIndex), + (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex), + sizeof(sal_Int16) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); + if (pSeq != 0) + { + ::rtl_copyMemory( + pSeq->elements + (sizeof(sal_Int32) * nStartIndex), + (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex), + sizeof(sal_Int32) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc ); + if (pSeq != 0) + { + ::rtl_copyMemory( + pSeq->elements + (sizeof(sal_Int64) * nStartIndex), + (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex), + sizeof(sal_Int64) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_FLOAT: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); + if (pSeq != 0) + { + ::rtl_copyMemory( + pSeq->elements + (sizeof(float) * nStartIndex), + (char *)pSourceElements + (sizeof(float) * nStartIndex), + sizeof(float) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_DOUBLE: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(double), nAlloc ); + if (pSeq != 0) + { + ::rtl_copyMemory( + pSeq->elements + (sizeof(double) * nStartIndex), + (char *)pSourceElements + (sizeof(double) * nStartIndex), + sizeof(double) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_ENUM: + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); + if (pSeq != 0) + { + ::rtl_copyMemory( + pSeq->elements + (sizeof(sal_Int32) * nStartIndex), + (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex), + sizeof(sal_Int32) * (nStopIndex - nStartIndex) ); + } + break; + case typelib_TypeClass_STRING: + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc ); + if (pSeq != 0) + { + rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + ::rtl_uString_acquire( + ((rtl_uString **)pSourceElements)[nPos] ); + pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos]; + } + } + break; + } + case typelib_TypeClass_TYPE: + { + if (nAlloc >= 0) + { + pSeq = reallocSeq( + pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); + } + if (pSeq != 0) + { + typelib_TypeDescriptionReference ** pDestElements = + (typelib_TypeDescriptionReference **) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + TYPE_ACQUIRE( + ((typelib_TypeDescriptionReference **) + pSourceElements)[nPos] ); + pDestElements[nPos] = + ((typelib_TypeDescriptionReference **) + pSourceElements)[nPos]; + } + } + break; + } + case typelib_TypeClass_ANY: + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc ); + if (pSeq != 0) + { + uno_Any * pDestElements = (uno_Any *) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + uno_Any * pSource = (uno_Any *)pSourceElements + nPos; + _copyConstructAny( + &pDestElements[nPos], + pSource->pData, + pSource->pType, 0, + acquire, 0 ); + } + } + break; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); + if (pSeq != 0) + { + char * pDestElements = pSeq->elements; + + typelib_CompoundTypeDescription * pTypeDescr = + (typelib_CompoundTypeDescription *)pElementTypeDescr; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + char * pDest = + pDestElements + (nElementSize * nPos); + char * pSource = + (char *)pSourceElements + (nElementSize * nPos); + + if (pTypeDescr->pBaseTypeDescription) + { + // copy base value + _copyConstructStruct( + pDest, pSource, + pTypeDescr->pBaseTypeDescription, acquire, 0 ); + } + + // then copy members + typelib_TypeDescriptionReference ** ppTypeRefs = + pTypeDescr->ppTypeRefs; + sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; + sal_Int32 nDescr = pTypeDescr->nMembers; + + while (nDescr--) + { + ::uno_type_copyData( + pDest + pMemberOffsets[nDescr], + pSource + pMemberOffsets[nDescr], + ppTypeRefs[nDescr], acquire ); + } + } + } + + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_UNION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); + if (pSeq != 0) + { + char * pDestElements = pSeq->elements; + + sal_Int32 nValueOffset = + ((typelib_UnionTypeDescription *) + pElementTypeDescr)->nValueOffset; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + char * pDest = + pDestElements + (nElementSize * nPos); + char * pSource = + (char *)pSourceElements + (nElementSize * nPos); + + typelib_TypeDescriptionReference * pSetType = _unionGetSetType( + pSource, pElementTypeDescr ); + ::uno_type_copyData( + pDest + nValueOffset, + pSource + nValueOffset, + pSetType, acquire ); + *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; + typelib_typedescriptionreference_release( pSetType ); + } + } + + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_SEQUENCE: // sequence of sequence + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc ); + if (pSeq != 0) + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + typelib_TypeDescriptionReference * pSeqElementType = + ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType; + uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + uno_Sequence * pNew = icopyConstructSequence( + ((uno_Sequence **) pSourceElements)[nPos], + pSeqElementType, acquire, 0 ); + OSL_ASSERT( pNew != 0 ); + // ought never be a memory allocation problem, + // because of reference counted sequence handles + pDestElements[ nPos ] = pNew; + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + } + break; + } + case typelib_TypeClass_INTERFACE: + { + if (nAlloc >= 0) + pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc ); + if (pSeq != 0) + { + void ** pDestElements = (void **) pSeq->elements; + for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) + { + _acquire( pDestElements[nPos] = + ((void **)pSourceElements)[nPos], acquire ); + } + } + break; + } + default: + OSL_ENSURE( 0, "### unexpected element type!" ); + pSeq = 0; + break; + } + + if (pSeq == 0) + { + OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure + return false; + } + else + { + *ppSeq = pSeq; + return true; + } +} + +//------------------------------------------------------------------------------ +static inline bool ireallocSequence( + uno_Sequence ** ppSequence, + typelib_TypeDescriptionReference * pElementType, + sal_Int32 nSize, + uno_AcquireFunc acquire, uno_ReleaseFunc release ) +{ + bool ret = true; + uno_Sequence * pSeq = *ppSequence; + sal_Int32 nElements = pSeq->nElements; + + if (pSeq->nRefCount > 1 || + // not mem-copyable elements? + typelib_TypeClass_ANY == pElementType->eTypeClass || + typelib_TypeClass_STRUCT == pElementType->eTypeClass || + typelib_TypeClass_EXCEPTION == pElementType->eTypeClass) + { + // split sequence and construct new one from scratch + uno_Sequence * pNew = 0; + + sal_Int32 nRest = nSize - nElements; + sal_Int32 nCopy = (nRest > 0 ? nElements : nSize); + + if (nCopy >= 0) + { + ret = icopyConstructFromElements( + &pNew, pSeq->elements, pElementType, + 0, nCopy, acquire, + nSize ); // alloc to nSize + } + if (ret && nRest > 0) + { + ret = idefaultConstructElements( + &pNew, pElementType, + nCopy, nSize, + nCopy >= 0 ? -1 /* no mem allocation */ : nSize ); + } + + if (ret) + { + // destruct sequence + if (osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0) + { + if (nElements > 0) + { + idestructElements( + pSeq->elements, pElementType, + 0, nElements, release ); + } + rtl_freeMemory( pSeq ); + } + *ppSequence = pNew; + } + } + else + { + OSL_ASSERT( pSeq->nRefCount == 1 ); + if (nSize > nElements) // default construct the rest + { + ret = idefaultConstructElements( + ppSequence, pElementType, + nElements, nSize, + nSize ); // realloc to nSize + } + else // or destruct the rest and realloc mem + { + sal_Int32 nElementSize = idestructElements( + pSeq->elements, pElementType, + nSize, nElements, release ); + // warning: it is assumed that the following will never fail, + // else this leads to a sequence null handle + *ppSequence = reallocSeq( pSeq, nElementSize, nSize ); + OSL_ASSERT( *ppSequence != 0 ); + ret = (*ppSequence != 0); + } + } + + return ret; +} + +} + +extern "C" +{ + +//############################################################################## +sal_Bool SAL_CALL uno_type_sequence_construct( + uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType, + void * pElements, sal_Int32 len, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C() +{ + bool ret; + if (len) + { + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + + typelib_TypeDescriptionReference * pElementType = + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; + + *ppSequence = 0; + if (pElements == 0) + { + ret = idefaultConstructElements( + ppSequence, pElementType, + 0, len, + len ); // alloc to len + } + else + { + ret = icopyConstructFromElements( + ppSequence, pElements, pElementType, + 0, len, acquire, + len ); // alloc to len + } + + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + else + { + *ppSequence = createEmptySequence(); + ret = true; + } + + OSL_ASSERT( (*ppSequence != 0) == ret ); + return ret; +} + +//############################################################################## +sal_Bool SAL_CALL uno_sequence_construct( + uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr, + void * pElements, sal_Int32 len, + uno_AcquireFunc acquire ) + SAL_THROW_EXTERN_C() +{ + bool ret; + if (len > 0) + { + typelib_TypeDescriptionReference * pElementType = + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; + + *ppSequence = 0; + if (pElements == 0) + { + ret = idefaultConstructElements( + ppSequence, pElementType, + 0, len, + len ); // alloc to len + } + else + { + ret = icopyConstructFromElements( + ppSequence, pElements, pElementType, + 0, len, acquire, + len ); // alloc to len + } + } + else + { + *ppSequence = createEmptySequence(); + ret = true; + } + + OSL_ASSERT( (*ppSequence != 0) == ret ); + return ret; +} + +//############################################################################## +sal_Bool SAL_CALL uno_type_sequence_realloc( + uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType, + sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( ppSequence, "### null ptr!" ); + OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" ); + + bool ret = true; + if (nSize != (*ppSequence)->nElements) + { + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + ret = ireallocSequence( + ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + nSize, acquire, release ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + return ret; +} + +//############################################################################## +sal_Bool SAL_CALL uno_sequence_realloc( + uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr, + sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( ppSequence, "### null ptr!" ); + OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" ); + + bool ret = true; + if (nSize != (*ppSequence)->nElements) + { + ret = ireallocSequence( + ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + nSize, acquire, release ); + } + return ret; +} + +//############################################################################## +sal_Bool SAL_CALL uno_type_sequence_reference2One( + uno_Sequence ** ppSequence, + typelib_TypeDescriptionReference * pType, + uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( ppSequence, "### null ptr!" ); + bool ret = true; + uno_Sequence * pSequence = *ppSequence; + if (pSequence->nRefCount > 1) + { + uno_Sequence * pNew = 0; + if (pSequence->nElements > 0) + { + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + + ret = icopyConstructFromElements( + &pNew, pSequence->elements, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + 0, pSequence->nElements, acquire, + pSequence->nElements ); // alloc nElements + if (ret) + { + idestructSequence( *ppSequence, pType, pTypeDescr, release ); + *ppSequence = pNew; + } + + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + else + { + pNew = allocSeq( 0, 0 ); + ret = (pNew != 0); + if (ret) + { + // easy destruction of empty sequence: + if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0) + rtl_freeMemory( pSequence ); + *ppSequence = pNew; + } + } + } + return ret; +} + +//############################################################################## +sal_Bool SAL_CALL uno_sequence_reference2One( + uno_Sequence ** ppSequence, + typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + OSL_ENSURE( ppSequence, "### null ptr!" ); + bool ret = true; + uno_Sequence * pSequence = *ppSequence; + if (pSequence->nRefCount > 1) + { + uno_Sequence * pNew = 0; + if (pSequence->nElements > 0) + { + ret = icopyConstructFromElements( + &pNew, pSequence->elements, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + 0, pSequence->nElements, acquire, + pSequence->nElements ); // alloc nElements + if (ret) + { + idestructSequence( + pSequence, pTypeDescr->pWeakRef, pTypeDescr, release ); + *ppSequence = pNew; + } + } + else + { + pNew = allocSeq( 0, 0 ); + ret = (pNew != 0); + if (ret) + { + // easy destruction of empty sequence: + if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0) + rtl_freeMemory( pSequence ); + *ppSequence = pNew; + } + } + + } + return ret; +} + +//############################################################################## +void SAL_CALL uno_sequence_assign( + uno_Sequence ** ppDest, + uno_Sequence * pSource, + typelib_TypeDescription * pTypeDescr, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + if (*ppDest != pSource) + { + ::osl_incrementInterlockedCount( &pSource->nRefCount ); + idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release ); + *ppDest = pSource; + } +} + +//############################################################################## +void SAL_CALL uno_type_sequence_assign( + uno_Sequence ** ppDest, + uno_Sequence * pSource, + typelib_TypeDescriptionReference * pType, + uno_ReleaseFunc release ) + SAL_THROW_EXTERN_C() +{ + if (*ppDest != pSource) + { + ::osl_incrementInterlockedCount( &pSource->nRefCount ); + idestructSequence( *ppDest, pType, 0, release ); + *ppDest = pSource; + } +} + +} diff --git a/cppu/util/cppu.map b/cppu/util/cppu.map new file mode 100755 index 000000000000..e89594615f53 --- /dev/null +++ b/cppu/util/cppu.map @@ -0,0 +1,127 @@ +UDK_3_0_0 { + global: + typelib_typedescription_new; + typelib_typedescription_newInterface; + typelib_typedescription_newInterfaceMethod; + typelib_typedescription_newInterfaceAttribute; + typelib_typedescription_newEnum; + typelib_typedescription_newUnion; + typelib_typedescription_newArray; + typelib_typedescription_acquire; + typelib_typedescription_release; + typelib_typedescription_register; + typelib_typedescription_equals; + typelib_typedescription_isAssignableFrom; + typelib_typedescription_getByName; + typelib_typedescription_registerCallback; + typelib_typedescription_revokeCallback; + typelib_typedescriptionreference_new; + typelib_typedescriptionreference_acquire; + typelib_typedescriptionreference_release; + typelib_typedescriptionreference_getDescription; + typelib_typedescriptionreference_equals; + typelib_typedescriptionreference_assign; + typelib_typedescriptionreference_isAssignableFrom; + + typelib_setCacheSize; + + typelib_typedescriptionreference_newByAsciiName; + typelib_static_type_getByTypeClass; + typelib_static_type_init; + typelib_static_sequence_type_init; + typelib_static_compound_type_init; + typelib_static_interface_type_init; + typelib_static_enum_type_init; + typelib_static_array_type_init; + typelib_typedescription_complete; + + uno_equalData; + uno_type_equalData; + uno_constructData; + uno_type_constructData; + uno_destructData; + uno_type_destructData; + uno_copyData; + uno_type_copyData; + uno_copyAndConvertData; + uno_type_copyAndConvertData; + uno_assignData; + uno_type_assignData; + uno_type_isAssignableFromData; + + uno_any_assign; + uno_type_any_assign; + uno_any_construct; + uno_type_any_construct; + uno_any_constructAndConvert; + uno_type_any_constructAndConvert; + uno_any_destruct; + uno_any_clear; + + uno_sequence_assign; + uno_type_sequence_assign; + uno_sequence_construct; + uno_type_sequence_construct; + uno_sequence_reference2One; + uno_type_sequence_reference2One; + uno_sequence_realloc; + uno_type_sequence_realloc; + + uno_createEnvironment; + uno_getEnvironment; + uno_getRegisteredEnvironments; + uno_dumpEnvironment; + uno_dumpEnvironmentByName; + uno_getMapping; + uno_getMappingByName; + uno_registerMapping; + uno_revokeMapping; + uno_registerMappingCallback; + uno_revokeMappingCallback; + + uno_getCurrentContext; + uno_setCurrentContext; + + uno_bindIdToCurrentThread; + uno_getIdOfCurrentThread; + uno_releaseIdFromCurrentThread; + uno_threadpool_enter; + uno_threadpool_create; + uno_threadpool_destroy; + uno_threadpool_putJob; + uno_threadpool_dispose; + uno_threadpool_attach; + uno_threadpool_detach; + + cppu_unsatisfied_iquery_msg; + local: + *; +}; + +UDK_3.1 { + global: + typelib_static_mi_interface_type_init; + typelib_static_struct_type_init; + typelib_typedescription_newExtendedInterfaceAttribute; + typelib_typedescription_newMIInterface; + typelib_typedescription_newStruct; + cppu_Any_extraction_failure_msg; +} UDK_3_0_0; + +UDK_3.2 { + global: + uno_EnvDcp_getTypeName; + uno_EnvDcp_getPurpose; + + uno_getCurrentEnvironment; + uno_Environment_invoke_v; + uno_Environment_invoke; + uno_Environment_enter; + + uno_Environment_isValid; +} UDK_3.1; + +UDK_3.3 { # OOo 2.4 + global: + cppu_unsatisfied_iset_msg; +} UDK_3.2; diff --git a/cppu/util/empty.def b/cppu/util/empty.def new file mode 100644 index 000000000000..269c8f14cffd --- /dev/null +++ b/cppu/util/empty.def @@ -0,0 +1,6 @@ +HEAPSIZE 0 +EXPORTS + + + + diff --git a/cppu/util/extra.mk b/cppu/util/extra.mk new file mode 100644 index 000000000000..f013516480fc --- /dev/null +++ b/cppu/util/extra.mk @@ -0,0 +1,89 @@ +#************************************************************************* +# +# 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 :=cppu +TARGET :=cppu +ENABLE_EXCEPTIONS:=TRUE +NO_BSYMBOLIC :=TRUE +USE_DEFFILE :=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : ../source/helper/purpenv/export.mk + +# --- Files -------------------------------------------------------- + +SHL3TARGET := unsafe_uno_uno +SHL3IMPLIB := i$(SHL3TARGET) +SHL3STDLIBS := $(purpenv_helper_LIB) $(SALLIB) +SHL3OBJS := $(SLO)$/UnsafeBridge.obj +.IF "$(GUI)"=="OS2" +SHL3VERSIONMAP=unsafe_os2.map +SHL3DEF=$(MISC)$/$(SHL3TARGET).def +DEF3NAME=$(SHL3TARGET) +.ELSE +SHL3DEF := empty.def +.ENDIF +SHL3OBJS := $(SLO)$/UnsafeBridge.obj +SHL3RPATH := URELIB + +SHL4TARGET := affine_uno_uno +SHL4IMPLIB := i$(SHL4TARGET) +SHL4STDLIBS := $(purpenv_helper_LIB) $(SALLIB) +SHL4OBJS := $(SLO)$/AffineBridge.obj +.IF "$(GUI)"=="OS2" +SHL4VERSIONMAP=unsafe_os2.map +SHL4DEF=$(MISC)$/$(SHL4TARGET).def +DEF4NAME=$(SHL4TARGET) +.ELSE +SHL4DEF := empty.def +.ENDIF +SHL4OBJS := $(SLO)$/AffineBridge.obj +SHL4RPATH := URELIB + + +SHL5TARGET := log_uno_uno +SHL5IMPLIB := i$(SHL5TARGET) +SHL5STDLIBS := $(purpenv_helper_LIB) $(SALLIB) $(CPPULIB) +SHL5OBJS := $(SLO)$/LogBridge.obj + +.IF "$(GUI)"=="OS2" +SHL5VERSIONMAP=unsafe_os2.map +SHL5DEF=$(MISC)$/$(SHL5TARGET).def +DEF5NAME=LogMapping.def +.ELSE +SHL5DEF := empty.def +.ENDIF +SHL5RPATH := URELIB + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/cppu/util/makefile.mk b/cppu/util/makefile.mk new file mode 100644 index 000000000000..2e52c28b5193 --- /dev/null +++ b/cppu/util/makefile.mk @@ -0,0 +1,105 @@ +#************************************************************************* +# +# 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=cppu +TARGET=cppu +USE_DEFFILE=TRUE +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +.IF "$(OS)" != "WNT" +UNIXVERSIONNAMES=UDK +.ENDIF + + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : ../source/helper/purpenv/export.mk + +# --- Files -------------------------------------------------------- + +SHL1LIBS= \ + $(SLB)$/cppu_typelib.lib \ + $(SLB)$/cppu_uno.lib \ + $(SLB)$/cppu_threadpool.lib \ + $(SLB)$/cppu_cppu.lib + +.IF "$(GUI)" == "WNT" || "$(GUI)"=="OS2" +SHL1TARGET=$(TARGET)$(UDK_MAJOR) +.ELSE +SHL1TARGET= uno_$(TARGET) +.ENDIF + +SHL1STDLIBS = $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB=i$(TARGET) +.IF "$(OS)"!="FREEBSD" +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +.ENDIF + +SHL1VERSIONMAP=$(TARGET).map +SHL1RPATH=URELIB + +DEF1NAME=$(SHL1TARGET) + + +SHL2TARGET := $(NAMEpurpenv_helper) +DEF2NAME := $(SHL2TARGET) +.IF "$(GUI)$(COM)"=="WNTGCC" +SHL2VERSIONMAP:=uno_purpenvhelper$(COMID).map +.ELIF "$(GUI)"=="OS2" +SHL2VERSIONMAP:=uno_purpenvhelperwntgcc.map +.ELSE +SHL2VERSIONMAP:=$(SHL2TARGET).map +.ENDIF # "$(GUI)$(COM)"=="WNTGCC" +SHL2DEF := $(MISC)$/$(SHL2TARGET).def +SHL2IMPLIB := i$(SHL2TARGET) +SHL2STDLIBS := $(CPPULIB) $(SALLIB) +SHL2RPATH := URELIB +SHL2OBJS := \ + $(SLO)$/helper_purpenv_Environment.obj \ + $(SLO)$/helper_purpenv_Mapping.obj \ + $(SLO)$/helper_purpenv_Proxy.obj + + +# --- Targets ------------------------------------------------------ + +.PHONY: ALLTAR + + +ALLTAR: $(SHL2TARGETN) + $(MAKE) $(MAKECMDGOALS) -f extra.mk + + +.INCLUDE : target.mk + + +$(SHL2TARGETN): $(SHL1TARGETN) + diff --git a/cppu/util/makefile.pmk b/cppu/util/makefile.pmk new file mode 100644 index 000000000000..c1259ddf4a10 --- /dev/null +++ b/cppu/util/makefile.pmk @@ -0,0 +1,32 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +.IF "$(GUI)" == "OS2" +STL_OS2_BUILDING=1 +.ENDIF diff --git a/cppu/util/purpenvhelper3MSC.map b/cppu/util/purpenvhelper3MSC.map new file mode 100644 index 000000000000..5bbb14e9a1ab --- /dev/null +++ b/cppu/util/purpenvhelper3MSC.map @@ -0,0 +1,8 @@ +UDK_3_0_0 { + global: + ?Environment_initWithEnterable@purpenv@helper@cppu@@YAXPAU_uno_Environment@@PAVEnterable@3@@Z; + ?createMapping@purpenv@helper@cppu@@YAXPAPAU_uno_Mapping@@PAU_uno_Environment@@1P6AX_NPAX3PAU_typelib_TypeDescriptionReference@@PAU_typelib_MethodParameter@@JPBU_typelib_TypeDescription@@3QAPAXPAPAU_uno_Any@@@Z3@Z; + + local: + *; +}; diff --git a/cppu/util/target.pmk b/cppu/util/target.pmk new file mode 100644 index 000000000000..3befcb154753 --- /dev/null +++ b/cppu/util/target.pmk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* +.IF "$(debug)" == "" + +# switch on aggressive opt + +# msvc++ +.IF "$(COM)" == "MSC" +CFLAGS += -Ox +.ENDIF + +# sunpro 5 +.IF "$(COM)" == "C50" +CFLAGS += -O5 -xO5 +.ENDIF + +# gcc +.IF "$(COM)" == "GCC" +CFLAGS += -O +.ENDIF + +.ELSE + +# msvc++: no inlining +.IF "$(COM)" == "MSC" +CFLAGS += -Ob0 +.ENDIF + +.ENDIF diff --git a/cppu/util/uno_purpenvhelperC52.map b/cppu/util/uno_purpenvhelperC52.map new file mode 100644 index 000000000000..5213c8ade00a --- /dev/null +++ b/cppu/util/uno_purpenvhelperC52.map @@ -0,0 +1,9 @@ +UDK_3_0_0 { + global: + __1cEcppuGhelperHpurpenvNcreateMapping6FppnM_uno_Mapping_pnQ_uno_Environment_7pFbpv8pnbH_typelib_TypeDescriptionReference_pnY_typelib_MethodParameter_lpknY_typelib_TypeDescription_8p8ppnI_uno_Any__v8_v_; # S-ILP32 + __1cEcppuGhelperHpurpenvNcreateMapping6FppnM_uno_Mapping_pnQ_uno_Environment_7pFbpv8pnbH_typelib_TypeDescriptionReference_pnY_typelib_MethodParameter_ipknY_typelib_TypeDescription_8p8ppnI_uno_Any__v8_v_; # S-LP64 + __1cEcppuGhelperHpurpenvbDEnvironment_initWithEnterable6FpnQ_uno_Environment_pn0AJEnterable__v_; + + local: + *; +}; diff --git a/cppu/util/uno_purpenvhelpergcc3.map b/cppu/util/uno_purpenvhelpergcc3.map new file mode 100644 index 000000000000..1a8f13238ab8 --- /dev/null +++ b/cppu/util/uno_purpenvhelpergcc3.map @@ -0,0 +1,8 @@ +UDK_3_0_0 { + global: + _ZN4cppu6helper7purpenv13createMappingEPP12_uno_MappingP16_uno_EnvironmentS6_PFvbPvS7_P33_typelib_TypeDescriptionReferenceP24_typelib_MethodParameter?PK24_typelib_TypeDescriptionS7_PS7_PP8_uno_AnyES7_; + _ZN4cppu6helper7purpenv29Environment_initWithEnterableEP16_uno_EnvironmentPNS_9EnterableE; + + local: + *; +}; diff --git a/cppu/util/uno_purpenvhelperwntgcc.map b/cppu/util/uno_purpenvhelperwntgcc.map new file mode 100644 index 000000000000..eb224df0b301 --- /dev/null +++ b/cppu/util/uno_purpenvhelperwntgcc.map @@ -0,0 +1,8 @@ +UDK_3_0_0 { + global: + _ZN4cppu6helper7purpenv13createMappingEPP12_uno_MappingP16_uno_EnvironmentS6_PFvbPvS7_P33_typelib_TypeDescriptionReferenceP24_typelib_MethodParameterlPK24_typelib_TypeDescriptionS7_PS7_PP8_uno_AnyES7_; + _ZN4cppu6helper7purpenv29Environment_initWithEnterableEP16_uno_EnvironmentPNS_9EnterableE; + + local: + *; +}; diff --git a/cppu/util/unsafe_os2.map b/cppu/util/unsafe_os2.map new file mode 100644 index 000000000000..cc6a0ddca448 --- /dev/null +++ b/cppu/util/unsafe_os2.map @@ -0,0 +1,7 @@ +UDK_3_0_0 { + global: + uno_initEnvironment; + uno_ext_getMapping; + local: + *; +}; |