diff options
Diffstat (limited to 'include/com/sun/star/uno')
-rw-r--r-- | include/com/sun/star/uno/Any.h | 486 | ||||
-rw-r--r-- | include/com/sun/star/uno/Any.hxx | 764 | ||||
-rw-r--r-- | include/com/sun/star/uno/Reference.h | 567 | ||||
-rw-r--r-- | include/com/sun/star/uno/Reference.hxx | 477 | ||||
-rw-r--r-- | include/com/sun/star/uno/Sequence.h | 335 | ||||
-rw-r--r-- | include/com/sun/star/uno/Sequence.hxx | 371 | ||||
-rw-r--r-- | include/com/sun/star/uno/Type.h | 494 | ||||
-rw-r--r-- | include/com/sun/star/uno/Type.hxx | 219 | ||||
-rw-r--r-- | include/com/sun/star/uno/genfunc.h | 60 | ||||
-rw-r--r-- | include/com/sun/star/uno/genfunc.hxx | 80 |
10 files changed, 3853 insertions, 0 deletions
diff --git a/include/com/sun/star/uno/Any.h b/include/com/sun/star/uno/Any.h new file mode 100644 index 000000000..577b31344 --- /dev/null +++ b/include/com/sun/star/uno/Any.h @@ -0,0 +1,486 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_ANY_H +#define INCLUDED_COM_SUN_STAR_UNO_ANY_H + +#include "sal/config.h" + +#include <cstddef> + +#include "rtl/ustring.hxx" +#include "uno/any2.h" +#include "typelib/typedescription.h" +#include "cppu/unotype.hxx" +#include "com/sun/star/uno/TypeClass.hdl" +#include "rtl/alloc.h" + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + +class Type; + +/** 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 SAL_WARN_UNUSED SAL_DLLPUBLIC_RTTI Any : public uno_Any +{ +public: + /// @cond INTERNAL + // these are here to force memory de/allocation to sal lib. + static void * SAL_CALL operator new ( size_t nSize ) + { return ::rtl_allocateMemory( nSize ); } + static void SAL_CALL operator delete ( void * pMem ) + { ::rtl_freeMemory( pMem ); } + static void * SAL_CALL operator new ( size_t, void * pMem ) + { return pMem; } + static void SAL_CALL operator delete ( void *, void * ) + {} + /// @endcond + + /** Default constructor: Any holds no value; its type is void. + */ + inline Any(); + + /** 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 ); + +#if defined LIBO_INTERNAL_ONLY + template<typename T1, typename T2> + explicit inline Any(rtl::OUStringConcat<T1, T2> && value); + template<typename T1, typename T2> + explicit Any(rtl::OUStringConcat<T1, T2> const &) = delete; +#endif + + /** Copy constructor: Sets value of the given any. + + @param rAny another any + */ + inline Any( const Any & rAny ); + + /** Constructor: Sets a copy of the given data. + + @param pData_ value + @param rType type of value + */ + inline Any( const void * pData_, const Type & rType ); + + /** Constructor: Sets a copy of the given data. + + @param pData_ value + @param pTypeDescr type of value + */ + inline Any( const void * pData_, typelib_TypeDescription * pTypeDescr ); + + /** Constructor: Sets a copy of the given data. + + @param pData_ value + @param pType_ type of value + */ + inline Any( const void * pData_, typelib_TypeDescriptionReference * pType_ ); + +#if defined LIBO_INTERNAL_ONLY + Any(bool const *, Type const &) = delete; + Any(bool const *, typelib_TypeDescription *) = delete; + Any(bool const *, typelib_TypeDescriptionReference *) = delete; + Any(sal_Bool const *, Type const &) = delete; + Any(sal_Bool const *, typelib_TypeDescription *) = delete; + Any(sal_Bool const *, typelib_TypeDescriptionReference *) = delete; + Any(std::nullptr_t, Type const & type): + Any(static_cast<void *>(nullptr), type) {} + Any(std::nullptr_t, typelib_TypeDescription * type): + Any(static_cast<void *>(nullptr), type) {} + Any(std::nullptr_t, typelib_TypeDescriptionReference * type): + Any(static_cast<void *>(nullptr), type) {} +#endif + + /** Destructor: Destructs any content and frees memory. + */ + inline ~Any(); + + /** 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 ); + +#if defined LIBO_INTERNAL_ONLY + inline Any(Any && other) noexcept; + inline Any & operator =(Any && other) noexcept; +#endif + + /** Gets the type of the set value. + + @return a Type object of the set value + */ + const Type & SAL_CALL getValueType() const + { return * reinterpret_cast< const Type * >( &pType ); } + /** Gets the type of the set value. + + @return the unacquired type description reference of the set value + */ + typelib_TypeDescriptionReference * SAL_CALL getValueTypeRef() const + { 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 ppTypeDescr a pointer to type description pointer + */ + void SAL_CALL getValueTypeDescription( typelib_TypeDescription ** ppTypeDescr ) const + { ::typelib_typedescriptionreference_getDescription( ppTypeDescr, pType ); } + + /** Gets the type class of the set value. + + @return the type class of the set value + */ + TypeClass SAL_CALL getValueTypeClass() const + { return static_cast<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; + + /** Tests if any contains a value. + + @return true if any has a value, false otherwise + */ + bool SAL_CALL hasValue() const + { return (typelib_TypeClass_VOID != pType->eTypeClass); } + + /** Gets a pointer to the set value. + + @return a pointer to the set value + */ + const void * SAL_CALL getValue() const + { return pData; } + + /** 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 com::sun::star::uno::RuntimeException if the specified type + cannot be provided. + + @return value of specified type + @exception com::sun::star::uno::RuntimeException + in case the specified type cannot be provided + */ + template <typename T> + inline T get() const; + + /** 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 ); + /** 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_ ); + /** 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 ); + +#if defined LIBO_INTERNAL_ONLY + void setValue(bool const *, Type const &) = delete; + void setValue(bool const *, typelib_TypeDescriptionReference *) = delete; + void setValue(bool const *, typelib_TypeDescription *) = delete; + void setValue(sal_Bool const *, Type const &) = delete; + void setValue(sal_Bool const *, typelib_TypeDescriptionReference *) + = delete; + void setValue(sal_Bool const *, typelib_TypeDescription *) = delete; + void setValue(std::nullptr_t, Type const & type) + { setValue(static_cast<void *>(nullptr), type); } + void setValue(std::nullptr_t, typelib_TypeDescriptionReference * type) + { setValue(static_cast<void *>(nullptr), type); } + void setValue(std::nullptr_t, typelib_TypeDescription * type) + { setValue(static_cast<void *>(nullptr), type); } +#endif + + /** 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(); + + /** 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 bool SAL_CALL isExtractableTo( const Type & rType ) const; + + /** 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 bool SAL_CALL operator == ( const Any & rAny ) const; + /** Inequality 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 bool SAL_CALL operator != ( const Any & rAny ) const; + +private: +#if !defined LIBO_INTERNAL_ONLY + /// @cond INTERNAL + // Forbid use with ambiguous type (sal_Unicode, sal_uInt16): + explicit Any(sal_uInt16) SAL_DELETED_FUNCTION; + /// @endcond +#endif +}; + +#if !defined LIBO_INTERNAL_ONLY +/// @cond INTERNAL +// Forbid use with ambiguous type (sal_Unicode, sal_uInt16): +template<> sal_uInt16 Any::get<sal_uInt16>() const SAL_DELETED_FUNCTION; +template<> bool Any::has<sal_uInt16>() const SAL_DELETED_FUNCTION; +/// @endcond +#endif + +/** Template function to generically construct an any from a C++ value. + + This can be useful with an explicitly specified template parameter, when the + (UNO) type recorded in the Any instance shall be different from what would + be deduced from the (C++) type of the argument if no template parameter were + specified explicitly. + + @tparam C value type + @param value a value + @return an any +*/ +template< class C > +inline Any SAL_CALL makeAny( const C & value ); + +#if !defined LIBO_INTERNAL_ONLY +template<> inline Any SAL_CALL makeAny(sal_uInt16 const & value); +#endif + +template<> Any SAL_CALL makeAny(Any const &) SAL_DELETED_FUNCTION; + +/** Wrap a value in an Any, if necessary. + + The difference to makeAny is that makeAny cannot be called on an Any, while + toAny just returns the given Any. + + @since LibreOffice 5.0 +*/ +template<typename T> inline Any toAny(T const & value); + +template<> inline Any toAny(Any const & value); + +#if defined LIBO_INTERNAL_ONLY + +/** Extract a value from an Any, if necessary. + + The difference to operator >>= is that operator >>= cannot be called with an + Any as right-hand side (in LIBO_INTERNAL_ONLY), while fromAny just passes on + the given Any (and always succeeds) in the specialization for T = Any. + + @tparam T any type representing a UNO type + + @param any any Any value + + @param value a non-null pointer, receiving the extracted value if + extraction succeeded (and left unmodified otherwise) + + @return true iff extraction succeeded + + @since LibreOffice 5.3 +*/ +template<typename T> inline bool fromAny(Any const & any, T * value); + +template<> inline bool fromAny(Any const & any, Any * value); + +#endif + +class BaseReference; + +/** Template binary <<= operator to set the value of an any. + + @tparam 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 ); + +// additionally for C++ bool: +template<> +inline void SAL_CALL operator <<= ( Any & rAny, bool const & value ); + +/** 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. + + @tparam 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 bool SAL_CALL operator >>= ( const Any & rAny, C & value ); + +/** 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. + + @tparam 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 bool SAL_CALL operator == ( const Any & rAny, const C & value ); +/** Template inequality 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. + + @tparam 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 bool SAL_CALL operator != ( const Any & rAny, const C & value ); + +// additional specialized >>= and == operators +// bool +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Bool & value ); +template<> +inline bool SAL_CALL operator == ( const Any & rAny, const sal_Bool & value ); +template<> +inline bool SAL_CALL operator >>= ( Any const & rAny, bool & value ); +template<> +inline bool SAL_CALL operator == ( Any const & rAny, bool const & value ); +// byte +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int8 & value ); +// short +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int16 & value ); +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt16 & value ); +// long +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int32 & value ); +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt32 & value ); +// hyper +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int64 & value ); +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt64 & value ); +// float +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, float & value ); +// double +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, double & value ); +// string +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, ::rtl::OUString & value ); +template<> +inline bool SAL_CALL operator == ( const Any & rAny, const ::rtl::OUString & value ); +// type +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, Type & value ); +template<> +inline bool SAL_CALL operator == ( const Any & rAny, const Type & value ); +// any +#if !defined LIBO_INTERNAL_ONLY +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, Any & value ); +#endif +// interface +template<> +inline bool SAL_CALL operator == ( const Any & rAny, const BaseReference & value ); + +} +} +} +} + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type any + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const ::com::sun::star::uno::Any * ) +{ + return ::cppu::UnoType< ::com::sun::star::uno::Any >::get(); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/com/sun/star/uno/Any.hxx b/include/com/sun/star/uno/Any.hxx new file mode 100644 index 000000000..c7089a0b5 --- /dev/null +++ b/include/com/sun/star/uno/Any.hxx @@ -0,0 +1,764 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_ANY_HXX +#define INCLUDED_COM_SUN_STAR_UNO_ANY_HXX + +#include "sal/config.h" + +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <iomanip> +#include <ostream> +#include <utility> + +#include "com/sun/star/uno/Any.h" +#include "uno/data.h" +#include "uno/sequence2.h" +#include "com/sun/star/uno/Type.hxx" +#include "com/sun/star/uno/Reference.h" +#include "com/sun/star/uno/genfunc.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "cppu/cppudllapi.h" +#include "cppu/unotype.hxx" + +extern "C" CPPU_DLLPUBLIC rtl_uString * SAL_CALL cppu_Any_extraction_failure_msg( + uno_Any const * pAny, typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C(); + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + + +inline Any::Any() +{ + ::uno_any_construct( this, NULL, NULL, cpp_acquire ); +} + + +template <typename T> +inline Any::Any( T const & value ) +{ + ::uno_type_any_construct( + this, const_cast<T *>(&value), + ::cppu::getTypeFavourUnsigned(&value).getTypeLibType(), + cpp_acquire ); +} + +inline Any::Any( bool value ) +{ + sal_Bool b = value; + ::uno_type_any_construct( + this, &b, cppu::UnoType<bool>::get().getTypeLibType(), + cpp_acquire ); +} + +#if defined LIBO_INTERNAL_ONLY +template<typename T1, typename T2> +Any::Any(rtl::OUStringConcat<T1, T2> && value): + Any(rtl::OUString(std::move(value))) +{} +#endif + +inline Any::Any( const Any & rAny ) +{ + ::uno_type_any_construct( this, rAny.pData, rAny.pType, cpp_acquire ); +} + +inline Any::Any( const void * pData_, const Type & rType ) +{ + ::uno_type_any_construct( + this, const_cast< void * >( pData_ ), rType.getTypeLibType(), + cpp_acquire ); +} + +inline Any::Any( const void * pData_, typelib_TypeDescription * pTypeDescr ) +{ + ::uno_any_construct( + this, const_cast< void * >( pData_ ), pTypeDescr, cpp_acquire ); +} + +inline Any::Any( const void * pData_, typelib_TypeDescriptionReference * pType_ ) +{ + ::uno_type_any_construct( + this, const_cast< void * >( pData_ ), pType_, cpp_acquire ); +} + +inline Any::~Any() +{ + ::uno_any_destruct( + this, cpp_release ); +} + +inline Any & Any::operator = ( const Any & rAny ) +{ + if (this != &rAny) + { + ::uno_type_any_assign( + this, rAny.pData, rAny.pType, + cpp_acquire, cpp_release ); + } + return *this; +} + +#if defined LIBO_INTERNAL_ONLY + +namespace detail { + +inline void moveAnyInternals(Any & from, Any & to) noexcept { + uno_any_construct(&to, nullptr, nullptr, &cpp_acquire); + std::swap(from.pType, to.pType); + std::swap(from.pData, to.pData); + std::swap(from.pReserved, to.pReserved); + if (to.pData == &from.pReserved) { + to.pData = &to.pReserved; + } + // This leaves from.pData (where "from" is now VOID) dangling to somewhere (cf. + // CONSTRUCT_EMPTY_ANY, cppu/source/uno/prim.hxx), but what's relevant is + // only that it isn't a nullptr (as e.g. >>= -> uno_type_assignData -> + // _assignData takes a null pSource to mean "construct a default value"). +} + +} + +Any::Any(Any && other) noexcept { + detail::moveAnyInternals(other, *this); +} + +Any & Any::operator =(Any && other) noexcept { + uno_any_destruct(this, &cpp_release); + detail::moveAnyInternals(other, *this); + return *this; +} + +#endif + +inline ::rtl::OUString Any::getValueTypeName() const +{ + return ::rtl::OUString( pType->pTypeName ); +} + +inline void Any::setValue( const void * pData_, const Type & rType ) +{ + ::uno_type_any_assign( + this, const_cast< void * >( pData_ ), rType.getTypeLibType(), + cpp_acquire, cpp_release ); +} + +inline void Any::setValue( const void * pData_, typelib_TypeDescriptionReference * pType_ ) +{ + ::uno_type_any_assign( + this, const_cast< void * >( pData_ ), pType_, + cpp_acquire, cpp_release ); +} + +inline void Any::setValue( const void * pData_, typelib_TypeDescription * pTypeDescr ) +{ + ::uno_any_assign( + this, const_cast< void * >( pData_ ), pTypeDescr, + cpp_acquire, cpp_release ); +} + +inline void Any::clear() +{ + ::uno_any_clear( + this, cpp_release ); +} + +inline bool Any::isExtractableTo( const Type & rType ) const +{ + return ::uno_type_isAssignableFromData( + rType.getTypeLibType(), pData, pType, + cpp_queryInterface, 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, + cpp_queryInterface, + cpp_release ); +} + +#if defined LIBO_INTERNAL_ONLY +template<> bool Any::has<Any>() const = delete; +#endif + +inline bool Any::operator == ( const Any & rAny ) const +{ + return ::uno_type_equalData( + pData, pType, rAny.pData, rAny.pType, + cpp_queryInterface, cpp_release ); +} + +inline bool Any::operator != ( const Any & rAny ) const +{ + return (! ::uno_type_equalData( + pData, pType, rAny.pData, rAny.pType, + cpp_queryInterface, cpp_release )); +} + + +template< class C > +inline Any SAL_CALL makeAny( const C & value ) +{ + return Any(value); +} + +#if !defined LIBO_INTERNAL_ONLY +template<> Any makeAny(sal_uInt16 const & value) +{ return Any(&value, cppu::UnoType<cppu::UnoUnsignedShortType>::get()); } +#endif + +template<typename T> Any toAny(T const & value) { return makeAny(value); } + +template<> Any toAny(Any const & value) { return value; } + +#if defined LIBO_INTERNAL_ONLY + +template<typename T1, typename T2> +Any makeAny(rtl::OUStringConcat<T1, T2> && value) +{ return Any(std::move(value)); } + +template<typename T1, typename T2> +Any toAny(rtl::OUStringConcat<T1, T2> && value) +{ return makeAny(std::move(value)); } + +template<typename T> +Any makeAny(rtl::OUStringNumber<T> && value) +{ return Any(OUString(std::move(value))); } + +template<typename T> +Any toAny(rtl::OUStringNumber<T> && value) +{ return makeAny(std::move(value)); } + +template<typename T> bool fromAny(Any const & any, T * value) { + assert(value != nullptr); + return any >>= *value; +} + +template<> bool fromAny(Any const & any, Any * value) { + assert(value != nullptr); + *value = any; + return true; +} + +#endif + +template< class C > +inline void SAL_CALL operator <<= ( Any & rAny, const C & value ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned(&value); + ::uno_type_any_assign( + &rAny, const_cast< C * >( &value ), rType.getTypeLibType(), + cpp_acquire, cpp_release ); +} + +// additionally for C++ bool: + +template<> +inline void SAL_CALL operator <<= ( Any & rAny, bool const & value ) +{ + sal_Bool b = value; + ::uno_type_any_assign( + &rAny, &b, cppu::UnoType<bool>::get().getTypeLibType(), + cpp_acquire, cpp_release ); +} + + +#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING" +template< class C1, class C2 > +inline void SAL_CALL operator <<= ( Any & rAny, rtl::OUStringConcat< C1, C2 >&& value ) +{ + const rtl::OUString str( std::move(value) ); + const Type & rType = ::cppu::getTypeFavourUnsigned(&str); + ::uno_type_any_assign( + &rAny, const_cast< rtl::OUString * >( &str ), rType.getTypeLibType(), + cpp_acquire, cpp_release ); +} +template<typename T1, typename T2> +void operator <<=(Any &, rtl::OUStringConcat<T1, T2> const &) = delete; +template< class C > +inline void SAL_CALL operator <<= ( Any & rAny, rtl::OUStringNumber< C >&& value ) +{ + const rtl::OUString str( std::move(value) ); + const Type & rType = ::cppu::getTypeFavourUnsigned(&str); + ::uno_type_any_assign( + &rAny, const_cast< rtl::OUString * >( &str ), rType.getTypeLibType(), + cpp_acquire, cpp_release ); +} +template<typename T> +void operator <<=(Any &, rtl::OUStringNumber<T> const &) = delete; +#endif + +#if defined LIBO_INTERNAL_ONLY +template<> void SAL_CALL operator <<=(Any &, Any const &) = delete; +#endif + +template< class C > +inline bool SAL_CALL operator >>= ( const Any & rAny, C & value ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned(&value); + return ::uno_type_assignData( + &value, rType.getTypeLibType(), + rAny.pData, rAny.pType, + cpp_queryInterface, + cpp_acquire, cpp_release ); +} + +// bool + +template<> +inline bool SAL_CALL operator >>= ( const ::com::sun::star::uno::Any & rAny, sal_Bool & value ) +{ + if (typelib_TypeClass_BOOLEAN == rAny.pType->eTypeClass) + { + value = bool(* static_cast< const sal_Bool * >( rAny.pData )); + return true; + } + return false; +} + +template<> +inline bool SAL_CALL operator == ( const Any & rAny, const sal_Bool & value ) +{ + return (typelib_TypeClass_BOOLEAN == rAny.pType->eTypeClass && + bool(value) == bool(* static_cast< const sal_Bool * >( rAny.pData ))); +} + + +template<> +inline bool SAL_CALL operator >>= ( Any const & rAny, bool & value ) +{ + if (rAny.pType->eTypeClass == typelib_TypeClass_BOOLEAN) + { + value = *static_cast< sal_Bool const * >( rAny.pData ); + return true; + } + return false; +} + + +template<> +inline bool SAL_CALL operator == ( Any const & rAny, bool const & value ) +{ + return (rAny.pType->eTypeClass == typelib_TypeClass_BOOLEAN && + (value == + bool(*static_cast< sal_Bool const * >( rAny.pData )))); +} + +// byte + +template<> +inline bool SAL_CALL operator >>= ( const ::com::sun::star::uno::Any & rAny, sal_Int8 & value ) +{ + if (typelib_TypeClass_BYTE == rAny.pType->eTypeClass) + { + value = * static_cast< const sal_Int8 * >( rAny.pData ); + return true; + } + return false; +} +// short + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int16 & value ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * static_cast< const sal_Int8 * >( rAny.pData ); + return true; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + value = * static_cast< const sal_Int16 * >( rAny.pData ); + return true; + default: + return false; + } +} + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt16 & value ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = static_cast<sal_uInt16>( * static_cast< const sal_Int8 * >( rAny.pData ) ); + return true; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + value = * static_cast< const sal_uInt16 * >( rAny.pData ); + return true; + default: + return false; + } +} +// long + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int32 & value ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * static_cast< const sal_Int8 * >( rAny.pData ); + return true; + case typelib_TypeClass_SHORT: + value = * static_cast< const sal_Int16 * >( rAny.pData ); + return true; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * static_cast< const sal_uInt16 * >( rAny.pData ); + return true; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + value = * static_cast< const sal_Int32 * >( rAny.pData ); + return true; + default: + return false; + } +} + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt32 & value ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = static_cast<sal_uInt32>( * static_cast< const sal_Int8 * >( rAny.pData ) ); + return true; + case typelib_TypeClass_SHORT: + value = static_cast<sal_uInt32>( * static_cast< const sal_Int16 * >( rAny.pData ) ); + return true; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * static_cast< const sal_uInt16 * >( rAny.pData ); + return true; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + value = * static_cast< const sal_uInt32 * >( rAny.pData ); + return true; + default: + return false; + } +} +// hyper + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int64 & value ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * static_cast< const sal_Int8 * >( rAny.pData ); + return true; + case typelib_TypeClass_SHORT: + value = * static_cast< const sal_Int16 * >( rAny.pData ); + return true; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * static_cast< const sal_uInt16 * >( rAny.pData ); + return true; + case typelib_TypeClass_LONG: + value = * static_cast< const sal_Int32 * >( rAny.pData ); + return true; + case typelib_TypeClass_UNSIGNED_LONG: + value = * static_cast< const sal_uInt32 * >( rAny.pData ); + return true; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + value = * static_cast< const sal_Int64 * >( rAny.pData ); + return true; + default: + return false; + } +} + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt64 & value ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = static_cast<sal_uInt64>( * static_cast< const sal_Int8 * >( rAny.pData ) ); + return true; + case typelib_TypeClass_SHORT: + value = static_cast<sal_uInt64>( * static_cast< const sal_Int16 * >( rAny.pData ) ); + return true; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * static_cast< const sal_uInt16 * >( rAny.pData ); + return true; + case typelib_TypeClass_LONG: + value = static_cast<sal_uInt64>( * static_cast< const sal_Int32 * >( rAny.pData ) ); + return true; + case typelib_TypeClass_UNSIGNED_LONG: + value = * static_cast< const sal_uInt32 * >( rAny.pData ); + return true; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + value = * static_cast< const sal_uInt64 * >( rAny.pData ); + return true; + default: + return false; + } +} +// float + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, float & value ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * static_cast< const sal_Int8 * >( rAny.pData ); + return true; + case typelib_TypeClass_SHORT: + value = * static_cast< const sal_Int16 * >( rAny.pData ); + return true; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * static_cast< const sal_uInt16 * >( rAny.pData ); + return true; + case typelib_TypeClass_FLOAT: + value = * static_cast< const float * >( rAny.pData ); + return true; + default: + return false; + } +} +// double + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, double & value ) +{ + switch (rAny.pType->eTypeClass) + { + case typelib_TypeClass_BYTE: + value = * static_cast< const sal_Int8 * >( rAny.pData ); + return true; + case typelib_TypeClass_SHORT: + value = * static_cast< const sal_Int16 * >( rAny.pData ); + return true; + case typelib_TypeClass_UNSIGNED_SHORT: + value = * static_cast< const sal_uInt16 * >( rAny.pData ); + return true; + case typelib_TypeClass_LONG: + value = * static_cast< const sal_Int32 * >( rAny.pData ); + return true; + case typelib_TypeClass_UNSIGNED_LONG: + value = * static_cast< const sal_uInt32 * >( rAny.pData ); + return true; + case typelib_TypeClass_FLOAT: + value = * static_cast< const float * >( rAny.pData ); + return true; + case typelib_TypeClass_DOUBLE: + value = * static_cast< const double * >( rAny.pData ); + return true; + default: + return false; + } +} +// string + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, ::rtl::OUString & value ) +{ + if (typelib_TypeClass_STRING == rAny.pType->eTypeClass) + { + value = * static_cast< const ::rtl::OUString * >( rAny.pData ); + return true; + } + return false; +} + +template<> +inline bool SAL_CALL operator == ( const Any & rAny, const ::rtl::OUString & value ) +{ + return (typelib_TypeClass_STRING == rAny.pType->eTypeClass && + value == * static_cast< const ::rtl::OUString * >( rAny.pData ) ); +} +// type + +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, Type & value ) +{ + if (typelib_TypeClass_TYPE == rAny.pType->eTypeClass) + { + value = * static_cast< const Type * >( rAny.pData ); + return true; + } + return false; +} + +template<> +inline bool SAL_CALL operator == ( const Any & rAny, const Type & value ) +{ + return (typelib_TypeClass_TYPE == rAny.pType->eTypeClass && + value.equals( * static_cast< const Type * >( rAny.pData ) )); +} +// any + +#if defined LIBO_INTERNAL_ONLY +template<> bool SAL_CALL operator >>=(Any const &, Any &) = delete; +#else +template<> +inline bool SAL_CALL operator >>= ( const Any & rAny, Any & value ) +{ + if (&rAny != &value) + { + ::uno_type_any_assign( + &value, rAny.pData, rAny.pType, + cpp_acquire, cpp_release ); + } + return true; +} +#endif +// interface + +template<> +inline bool SAL_CALL operator == ( const Any & rAny, const BaseReference & value ) +{ + if (typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass) + { + return static_cast< const BaseReference * >( rAny.pData )->operator == ( value ); + } + return false; +} + +// operator to compare to an any. + +template< class C > +inline bool SAL_CALL operator == ( const Any & rAny, const C & value ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned(&value); + return ::uno_type_equalData( + rAny.pData, rAny.pType, + const_cast< C * >( &value ), rType.getTypeLibType(), + cpp_queryInterface, cpp_release ); +} +// operator to compare to an any. may use specialized operators ==. + +template< class C > +inline bool SAL_CALL operator != ( const Any & rAny, const C & value ) +{ + return (! operator == ( rAny, value )); +} + +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 ) ); + } + return value; +} + +#if defined LIBO_INTERNAL_ONLY +template<> Any Any::get() const = delete; +#endif + +/** + Support for Any in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO + macros, for example). + + @since LibreOffice 4.2 +*/ +template<typename charT, typename traits> +inline std::basic_ostream<charT, traits> &operator<<(std::basic_ostream<charT, traits> &o, Any const &any) { + o << "<Any: (" << any.getValueTypeName() << ')'; + switch(any.pType->eTypeClass) { + case typelib_TypeClass_VOID: + break; + case typelib_TypeClass_BOOLEAN: + o << ' ' << any.get<bool>(); + break; + case typelib_TypeClass_BYTE: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_LONG: + case typelib_TypeClass_HYPER: + o << ' ' << any.get<sal_Int64>(); + break; + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_UNSIGNED_HYPER: + o << ' ' << any.get<sal_uInt64>(); + break; + case typelib_TypeClass_FLOAT: + case typelib_TypeClass_DOUBLE: + o << ' ' << any.get<double>(); + break; + case typelib_TypeClass_CHAR: { + std::ios_base::fmtflags flgs = o.setf( + std::ios_base::hex, std::ios_base::basefield); + charT fill = o.fill('0'); + o << " U+" << std::setw(4) + << unsigned(*static_cast<sal_Unicode const *>(any.getValue())); + o.setf(flgs); + o.fill(fill); + break; + } + case typelib_TypeClass_STRING: + o << ' ' << any.get<rtl::OUString>(); + break; + case typelib_TypeClass_TYPE: + o << ' ' << any.get<css::uno::Type>().getTypeName(); + break; + case typelib_TypeClass_SEQUENCE: + o << " len " + << ((*static_cast<uno_Sequence * const *>(any.getValue()))-> + nElements); + break; + case typelib_TypeClass_ENUM: + o << ' ' << *static_cast<sal_Int32 const *>(any.getValue()); + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + o << ' ' << any.getValue(); + break; + case typelib_TypeClass_INTERFACE: + o << ' ' << *static_cast<void * const *>(any.getValue()); + break; + default: + assert(false); // this cannot happen + break; + } + o << '>'; + return o; +} + +} +} +} +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/com/sun/star/uno/Reference.h b/include/com/sun/star/uno/Reference.h new file mode 100644 index 000000000..0221f0ca5 --- /dev/null +++ b/include/com/sun/star/uno/Reference.h @@ -0,0 +1,567 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H +#define INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H + +#include "sal/config.h" + +#include <cassert> +#include <cstddef> + +#if defined LIBO_INTERNAL_ONLY +#include <type_traits> +#endif + +#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 ); + /** 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 ); + +public: + /** Gets interface pointer. This call does not acquire the interface. + + @return UNacquired interface pointer + */ + XInterface * SAL_CALL get() const + { return _pInterface; } + + /** Checks if reference is null. + + @return true if reference acquires an interface, i.e. true if it is not null + */ + bool SAL_CALL is() const + { return (NULL != _pInterface); } + +#if defined LIBO_INTERNAL_ONLY + /** Checks if reference is null. + + @return true if reference acquires an interface, i.e. true if it is not null + */ + explicit operator bool() const + { return is(); } +#endif + + /** Equality operator: compares two interfaces + Checks if both references are null or refer to the same object. + + @param pInterface another interface + @return true if both references are null or refer to the same object, false otherwise + */ + inline bool SAL_CALL operator == ( XInterface * pInterface ) const; + /** Inequality operator: compares two interfaces + Checks if both references are null or refer to the same object. + + @param pInterface another interface + @return false if both references are null or refer to the same object, true otherwise + */ + inline bool SAL_CALL operator != ( XInterface * pInterface ) const; + + /** 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 bool SAL_CALL operator == ( const BaseReference & rRef ) const; + /** Inequality 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 bool SAL_CALL operator != ( const BaseReference & rRef ) const; + + /** Needed by some STL containers. + + @param rRef another reference + @return true, if this reference is less than rRef + */ + inline bool SAL_CALL operator < ( const BaseReference & rRef ) const; +}; + +/** Enum defining UNO_QUERY for implicit interface query. +*/ +enum UnoReference_Query +{ + /** This enum value can be used for implicit interface query. + */ + UNO_QUERY +}; +/** Enum defining UNO_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 +}; +/** 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 +}; + +/** Template reference class for interface type derived from BaseReference. + A special constructor given the UNO_QUERY identifier queries interfaces + for reference type. +*/ +template< class interface_type > +class SAL_DLLPUBLIC_RTTI 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 ); + /** 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 ); + /** 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 ); + + /** 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 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 XInterface * castToXInterface(interface_type * p) { + return static_cast< XInterface * >(static_cast< void * >(p)); + } + +public: + /// @cond INTERNAL + // these are here to force memory de/allocation to sal lib. + static void * SAL_CALL operator new ( ::size_t nSize ) + { return ::rtl_allocateMemory( nSize ); } + static void SAL_CALL operator delete ( void * pMem ) + { ::rtl_freeMemory( pMem ); } + static void * SAL_CALL operator new ( ::size_t, void * pMem ) + { return pMem; } + static void SAL_CALL operator delete ( void *, void * ) + {} + /// @endcond + + /** Destructor: Releases interface if set. + */ + inline ~Reference() COVERITY_NOEXCEPT_FALSE; + + /** Default Constructor: Sets null reference. + */ + inline Reference(); + + /** Copy constructor: Copies interface reference. + + @param rRef another reference + */ + inline Reference( const Reference< interface_type > & rRef ); + +#if defined LIBO_INTERNAL_ONLY + /** Move constructor + + @param rRef another reference + */ + inline Reference( Reference< interface_type > && rRef ) noexcept; + + /** Up-casting conversion constructor: Copies interface reference. + + Does not work for up-casts to ambiguous bases. For the special case of + up-casting to Reference< XInterface >, see the corresponding conversion + operator. + + @param rRef another reference + */ + template< class derived_type > + inline Reference( + const Reference< derived_type > & rRef, + std::enable_if_t< + std::is_base_of_v<interface_type, derived_type> + && !std::is_same_v<interface_type, XInterface>, void *> = nullptr); +#endif + + /** Constructor: Sets given interface pointer. + + @param pInterface an interface pointer + */ + inline Reference( interface_type * pInterface ); + + /** 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 dummy); + /** 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 SAL_DEPRECATED("use SAL_NO_ACQUIRE version") Reference( interface_type * pInterface, UnoReference_NoAcquire dummy ); + + /** Constructor: Queries given interface for reference interface type (interface_type). + + @param rRef another reference + @param dummy UNO_QUERY to force obvious distinction to other constructors + */ + inline Reference( const BaseReference & rRef, UnoReference_Query dummy ); + /** 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 dummy); + /** 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 dummy); + /** 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 to force obvious distinction + to other constructors + */ + inline Reference( const BaseReference & rRef, UnoReference_QueryThrow dummy ); +#ifdef LIBO_INTERNAL_ONLY + /** + Prevent code from calling the QUERY_THROW constructor, when they meant to use the SET_THROW constructor. + */ + Reference( const Reference< interface_type > & rRef, UnoReference_QueryThrow dummy ) = delete; +#endif + /** 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 to force obvious distinction + to other constructors + */ + inline Reference( XInterface * pInterface, UnoReference_QueryThrow dummy ); + /** 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 to force obvious distinction + to other constructors + */ + inline Reference( const Any & rAny, UnoReference_QueryThrow dummy ); + /** 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 dummy ); + /** 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 dummy ); + + /** 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. + */ + SAL_CALL operator const Reference< XInterface > & () const + { return * reinterpret_cast< const Reference< XInterface > * >( this ); } + + /** Dereference operator: Used to call interface methods. + + @return UNacquired interface pointer + */ + interface_type * SAL_CALL operator -> () const { + assert(_pInterface != NULL); + return castFromXInterface(_pInterface); + } + + /** Indirection operator. + + @since LibreOffice 6.3 + @return UNacquired interface reference + */ + interface_type & SAL_CALL operator * () const { + assert(_pInterface != NULL); + return *castFromXInterface(_pInterface); + } + + /** Gets interface pointer. This call does not acquire the interface. + + @return UNacquired interface pointer + */ + interface_type * SAL_CALL get() const + { return castFromXInterface(_pInterface); } + + /** Clears reference, i.e. releases interface. Reference is null after clear() call. + */ + inline void SAL_CALL clear(); + + /** Sets the given interface. An interface already set will be released. + + @param rRef another reference + @return true, if non-null interface was set + */ + inline bool SAL_CALL set( const Reference< interface_type > & rRef ); + /** Sets the given interface. An interface already set will be released. + + @param pInterface another interface + @return true, if non-null interface was set + */ + inline bool SAL_CALL set( interface_type * pInterface ); + + /** 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 bool SAL_CALL set( interface_type * pInterface, __sal_NoAcquire dummy); + /** 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_DEPRECATED("use SAL_NO_ACQUIRE version") bool SAL_CALL set( interface_type * pInterface, UnoReference_NoAcquire dummy); + + /** 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 to force obvious distinction to set methods + @return true, if non-null interface was set + */ + inline bool SAL_CALL set( XInterface * pInterface, UnoReference_Query dummy ); + /** 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 to force obvious distinction to set methods + @return true, if non-null interface was set + */ + inline bool SAL_CALL set( const BaseReference & rRef, UnoReference_Query dummy); + + /** 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 to force obvious distinction + to set methods + @return + true, if non-null interface was set + */ + inline bool set( Any const & rAny, UnoReference_Query dummy ); + + /** 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 to force obvious distinction + to set methods + */ + inline void SAL_CALL set( XInterface * pInterface, UnoReference_QueryThrow dummy ); + /** 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 to force obvious distinction + to set methods + */ + inline void SAL_CALL set( const BaseReference & rRef, UnoReference_QueryThrow dummy ); +#ifdef LIBO_INTERNAL_ONLY + /** + Prevent code from calling the QUERY_THROW version, when they meant to use the SET_THROW version. + */ + void set( const Reference< interface_type > & rRef, UnoReference_QueryThrow dummy ) = delete; +#endif + + /** 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 to force obvious distinction to set methods + */ + inline void set( Any const & rAny, UnoReference_QueryThrow dummy); + /** sets the given interface + An interface already set will be released. + Throws a RuntimeException if the source interface is @b 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 dummy); + /** sets the given interface + An interface already set will be released. + Throws a RuntimeException if the source interface is @b 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 dummy); + + + /** 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 ); + /** 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 ); +#if defined LIBO_INTERNAL_ONLY + /** Assignment move 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 = ( Reference< interface_type > && rRef ) noexcept; +#endif + /** Queries given interface reference for type interface_type. + + @param rRef interface reference + @return interface reference of demanded type (may be null) + */ + SAL_WARN_UNUSED_RESULT inline static Reference< interface_type > SAL_CALL query( const BaseReference & rRef ); + /** Queries given interface for type interface_type. + + @param pInterface interface pointer + @return interface reference of demanded type (may be null) + */ + SAL_WARN_UNUSED_RESULT inline static Reference< interface_type > SAL_CALL query( XInterface * pInterface ); +}; + +} +} +} +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/com/sun/star/uno/Reference.hxx b/include/com/sun/star/uno/Reference.hxx new file mode 100644 index 000000000..c78f2681e --- /dev/null +++ b/include/com/sun/star/uno/Reference.hxx @@ -0,0 +1,477 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_REFERENCE_HXX +#define INCLUDED_COM_SUN_STAR_UNO_REFERENCE_HXX + +#include "sal/config.h" + +#include <cstddef> +#include <ostream> + +#include "com/sun/star/uno/Reference.h" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/XInterface.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "cppu/cppudllapi.h" + +extern "C" CPPU_DLLPUBLIC rtl_uString * SAL_CALL cppu_unsatisfied_iquery_msg( + typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C(); +extern "C" CPPU_DLLPUBLIC rtl_uString * SAL_CALL cppu_unsatisfied_iset_msg( + typelib_TypeDescriptionReference * pType ) + SAL_THROW_EXTERN_C(); + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + + +inline XInterface * BaseReference::iquery( + XInterface * pInterface, const Type & rType ) +{ + if (pInterface) + { + Any aRet( pInterface->queryInterface( rType ) ); + if (typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass) + { + XInterface * pRet = static_cast< XInterface * >( aRet.pReserved ); + aRet.pReserved = NULL; + return pRet; + } + } + return NULL; +} + +template< class interface_type > +inline XInterface * Reference< interface_type >::iquery( + XInterface * pInterface ) +{ + return BaseReference::iquery(pInterface, interface_type::static_type()); +} + +inline XInterface * BaseReference::iquery_throw( + XInterface * pInterface, const Type & rType ) +{ + 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 ) +{ + return BaseReference::iquery_throw( + pInterface, interface_type::static_type()); +} + +template< class interface_type > +inline interface_type * Reference< interface_type >::iset_throw( + interface_type * pInterface ) +{ + if (pInterface) + { + castToXInterface(pInterface)->acquire(); + return pInterface; + } + throw RuntimeException( + ::rtl::OUString( cppu_unsatisfied_iset_msg( interface_type::static_type().getTypeLibType() ), SAL_NO_ACQUIRE ), + NULL ); +} + +template< class interface_type > +inline Reference< interface_type >::~Reference() COVERITY_NOEXCEPT_FALSE +{ + if (_pInterface) + _pInterface->release(); +} + +template< class interface_type > +inline Reference< interface_type >::Reference() +{ + _pInterface = NULL; +} + +template< class interface_type > +inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef ) +{ + _pInterface = rRef._pInterface; + if (_pInterface) + _pInterface->acquire(); +} + +#if defined LIBO_INTERNAL_ONLY +template< class interface_type > +inline Reference< interface_type >::Reference( Reference< interface_type > && rRef ) noexcept +{ + _pInterface = rRef._pInterface; + rRef._pInterface = nullptr; +} + +template< class interface_type > template< class derived_type > +inline Reference< interface_type >::Reference( + const Reference< derived_type > & rRef, + std::enable_if_t< + std::is_base_of_v<interface_type, derived_type> + && !std::is_same_v<interface_type, XInterface>, void *>) +{ + interface_type * p = rRef.get(); + _pInterface = p; + if (_pInterface) + _pInterface->acquire(); +} +#endif + +template< class interface_type > +inline Reference< interface_type >::Reference( interface_type * pInterface ) +{ + _pInterface = castToXInterface(pInterface); + if (_pInterface) + _pInterface->acquire(); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( interface_type * pInterface, __sal_NoAcquire ) +{ + _pInterface = castToXInterface(pInterface); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( interface_type * pInterface, UnoReference_NoAcquire ) +{ + _pInterface = castToXInterface(pInterface); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_Query ) +{ + _pInterface = iquery( rRef.get() ); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_Query ) +{ + _pInterface = iquery( pInterface ); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_Query ) +{ + _pInterface = (typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass + ? iquery( static_cast< XInterface * >( rAny.pReserved ) ) : NULL); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_QueryThrow ) +{ + _pInterface = iquery_throw( rRef.get() ); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_QueryThrow ) +{ + _pInterface = iquery_throw( pInterface ); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_QueryThrow ) +{ + _pInterface = iquery_throw( typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass + ? static_cast< XInterface * >( rAny.pReserved ) : NULL ); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef, UnoReference_SetThrow ) +{ + _pInterface = castToXInterface( iset_throw( rRef.get() ) ); +} + +template< class interface_type > +inline Reference< interface_type >::Reference( interface_type * pInterface, UnoReference_SetThrow ) +{ + _pInterface = castToXInterface( iset_throw( pInterface ) ); +} + + +template< class interface_type > +inline void Reference< interface_type >::clear() +{ + if (_pInterface) + { + XInterface * const pOld = _pInterface; + _pInterface = NULL; + pOld->release(); + } +} + +template< class interface_type > +inline bool Reference< interface_type >::set( + interface_type * pInterface ) +{ + if (pInterface) + castToXInterface(pInterface)->acquire(); + XInterface * const pOld = _pInterface; + _pInterface = castToXInterface(pInterface); + if (pOld) + pOld->release(); + return (NULL != pInterface); +} + +template< class interface_type > +inline bool Reference< interface_type >::set( + interface_type * pInterface, __sal_NoAcquire ) +{ + XInterface * const pOld = _pInterface; + _pInterface = castToXInterface(pInterface); + if (pOld) + pOld->release(); + return (NULL != pInterface); +} + +template< class interface_type > +inline bool Reference< interface_type >::set( + interface_type * pInterface, UnoReference_NoAcquire ) +{ + return set( pInterface, SAL_NO_ACQUIRE ); +} + + +template< class interface_type > +inline bool Reference< interface_type >::set( + const Reference< interface_type > & rRef ) +{ + return set( castFromXInterface( rRef._pInterface ) ); +} + +template< class interface_type > +inline bool Reference< interface_type >::set( + XInterface * pInterface, UnoReference_Query ) +{ + return set( castFromXInterface(iquery( pInterface )), SAL_NO_ACQUIRE ); +} + +template< class interface_type > +inline bool Reference< interface_type >::set( + const BaseReference & rRef, UnoReference_Query ) +{ + 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 ) : NULL )), + SAL_NO_ACQUIRE ); +} + + +template< class interface_type > +inline void Reference< interface_type >::set( + XInterface * pInterface, UnoReference_QueryThrow ) +{ + set( castFromXInterface(iquery_throw( pInterface )), SAL_NO_ACQUIRE ); +} + +template< class interface_type > +inline void Reference< interface_type >::set( + const BaseReference & rRef, UnoReference_QueryThrow ) +{ + 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 ) : NULL )), + SAL_NO_ACQUIRE ); +} + +template< class interface_type > +inline void Reference< interface_type >::set( + interface_type * pInterface, UnoReference_SetThrow ) +{ + set( iset_throw( pInterface ), SAL_NO_ACQUIRE ); +} + +template< class interface_type > +inline void Reference< interface_type >::set( + const Reference< interface_type > & rRef, UnoReference_SetThrow ) +{ + set( rRef.get(), UNO_SET_THROW ); +} + + +template< class interface_type > +inline Reference< interface_type > & Reference< interface_type >::operator = ( + interface_type * pInterface ) +{ + set( pInterface ); + return *this; +} + +template< class interface_type > +inline Reference< interface_type > & Reference< interface_type >::operator = ( + const Reference< interface_type > & rRef ) +{ + set( castFromXInterface( rRef._pInterface ) ); + return *this; +} + +#if defined LIBO_INTERNAL_ONLY +template< class interface_type > +inline Reference< interface_type > & Reference< interface_type >::operator = ( + Reference< interface_type > && rRef ) noexcept +{ + if (_pInterface) + _pInterface->release(); + _pInterface = rRef._pInterface; + rRef._pInterface = nullptr; + return *this; +} +#endif + +template< class interface_type > +inline Reference< interface_type > Reference< interface_type >::query( + const BaseReference & rRef ) +{ + 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 ) +{ + return Reference< interface_type >( + castFromXInterface(iquery( pInterface )), SAL_NO_ACQUIRE ); +} + + +inline bool BaseReference::operator == ( XInterface * pInterface ) const +{ + if (_pInterface == pInterface) + return true; + try + { + // 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); + } + catch (RuntimeException &) + { + return false; + } +} + + +inline bool BaseReference::operator < ( + const BaseReference & rRef ) const +{ + if (_pInterface == rRef._pInterface) + return false; + try + { + // 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); + } + catch (RuntimeException &) + { + return false; + } +} + + +inline bool BaseReference::operator != ( XInterface * pInterface ) const +{ + return (! operator == ( pInterface )); +} + +inline bool BaseReference::operator == ( const BaseReference & rRef ) const +{ + return operator == ( rRef._pInterface ); +} + +inline bool BaseReference::operator != ( const BaseReference & rRef ) const +{ + return (! operator == ( rRef._pInterface )); +} + +#if defined LIBO_INTERNAL_ONLY +/** + Support for BaseReference in std::ostream (and thus in CPPUNIT_ASSERT or + SAL_INFO macros, for example). + + @since LibreOffice 5.4 +*/ +template<typename charT, typename traits> std::basic_ostream<charT, traits> & +operator <<( + std::basic_ostream<charT, traits> & stream, BaseReference const & ref) +{ return stream << ref.get(); } +#endif + +} +} +} +} + +#if defined LIBO_INTERNAL_ONLY +namespace std +{ + +/** + Make css::uno::Reference hashable by default for use in STL containers. + + @since LibreOffice 6.3 +*/ +template<typename T> +struct hash<::css::uno::Reference<T>> +{ + std::size_t operator()(::css::uno::Reference<T> const & s) const + { return size_t(s.get()); } +}; + +} + +#endif + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/com/sun/star/uno/Sequence.h b/include/com/sun/star/uno/Sequence.h new file mode 100644 index 000000000..2ba8c71f8 --- /dev/null +++ b/include/com/sun/star/uno/Sequence.h @@ -0,0 +1,335 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_SEQUENCE_H +#define INCLUDED_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" + +#include <new> + +#if defined LIBO_INTERNAL_ONLY +#include <cassert> +#include <initializer_list> +#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). + + @tparam E element type of sequence +*/ +template< class E > +class SAL_WARN_UNUSED SAL_DLLPUBLIC_RTTI Sequence +{ + /** sequence handle + */ + uno_Sequence * _pSequence; + +public: + /// @cond INTERNAL + + // these are here to force memory de/allocation to sal lib. + static void * SAL_CALL operator new ( ::size_t nSize ) + { return ::rtl_allocateMemory( nSize ); } + static void SAL_CALL operator delete ( void * pMem ) + { ::rtl_freeMemory( pMem ); } + static void * SAL_CALL operator new ( ::size_t, void * pMem ) + { return pMem; } + static void SAL_CALL operator delete ( void *, void * ) + {} + + /** Static pointer to typelib type of sequence. + Don't use directly, call getCppuType(). + */ + static typelib_TypeDescriptionReference * s_pType; + + /// @endcond + + /** typedefs the element type of the sequence + */ + typedef E ElementType; + + /** Default constructor: Creates an empty sequence. + */ + inline Sequence(); + + /** Copy constructor: Creates a copy of given sequence. + + @param rSeq another sequence of same type + */ + inline Sequence( const Sequence & rSeq ); + + /** 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 dummy ); + + /** Constructor: Creates a copy of given elements. + + @param pElements 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 ); + +#if defined LIBO_INTERNAL_ONLY + /** Create a sequence with the given elements. + + @param init an initializer_list + + @since LibreOffice 5.0 + */ + inline Sequence(std::initializer_list<E> init); +#endif + + /** Destructor: Releases sequence handle. Last handle will destruct + elements and free memory. + */ + inline ~Sequence(); + + /** Assignment operator: Acquires given sequence handle and releases + previously set handle. + + @param rSeq another sequence of same type + @return this sequence + */ + inline Sequence & SAL_CALL operator = ( const Sequence & rSeq ); + + /** Gets length of the sequence. + + @return length of sequence + */ + sal_Int32 SAL_CALL getLength() const + { 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 + */ + bool SAL_CALL hasElements() const + { return (_pSequence->nElements > 0); } + +#if defined LIBO_INTERNAL_ONLY + /** This function allows to use Sequence in cases where std::size is needed, and the like. + + @since LibreOffice 6.4 + */ + sal_uInt32 size() const + { assert(getLength() >= 0); return static_cast<sal_uInt32>(getLength()); } +#endif + + /** 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 + */ + const E * SAL_CALL getConstArray() const + { 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(); + + /** This function allows to use Sequence in standard algorithms, like std::find + and others. + + @since LibreOffice 4.2 + */ + inline E * begin(); + + /** This function allows to use Sequence in standard algorithms, like std::find + and others. + + @since LibreOffice 4.2 + */ + inline E const * begin() const; + + /** This function allows to use Sequence in standard algorithms, like std::find + and others. + + @since LibreOffice 4.2 + */ + inline E * end(); + + /** This function allows to use Sequence in standard algorithms, like std::find + and others. + + @since LibreOffice 4.2 + */ + inline E const * end() const; + + /** 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; + + /** Equality operator: Compares two sequences. + + @param rSeq another sequence of same type (right side) + @return true if both sequences are equal, false otherwise + */ + inline bool SAL_CALL operator == ( const Sequence & rSeq ) const; + + /** Inequality operator: Compares two sequences. + + @param rSeq another sequence of same type (right side) + @return false if both sequences are equal, true otherwise + */ + inline bool SAL_CALL operator != ( const Sequence & rSeq ) const; + + /** 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 + */ + uno_Sequence * SAL_CALL get() const + { return _pSequence; } +}; + +// Find uses of illegal Sequence<bool> (instead of Sequence<sal_Bool>) during +// compilation: +template<> class Sequence<bool> { + Sequence(Sequence<bool> const &) SAL_DELETED_FUNCTION; +}; + +/** 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 ); + +} +} +} +} + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @tparam E element type of sequence + @return type of IDL sequence + + @deprecated + Use cppu::UnoType instead. +*/ +template< class E > SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & +SAL_CALL getCppuType( const ::com::sun::star::uno::Sequence< E > * ); + +/** 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. + + @attention + the given element type must be the same as the template argument type! + @tparam E element type of sequence + @param rElementType element type of sequence + @return type of IDL sequence + + @deprecated + Use cppu::UnoType instead. +*/ +template< class E > SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & +SAL_CALL getCppuSequenceType( const ::com::sun::star::uno::Type & rElementType ); + +/** Gets the meta type of IDL sequence< char >. + This function has been introduced due to ambiguities with unsigned short. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL sequence< char > + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & +SAL_CALL getCharSequenceCppuType(); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/com/sun/star/uno/Sequence.hxx b/include/com/sun/star/uno/Sequence.hxx new file mode 100644 index 000000000..373d97624 --- /dev/null +++ b/include/com/sun/star/uno/Sequence.hxx @@ -0,0 +1,371 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_SEQUENCE_HXX +#define INCLUDED_COM_SUN_STAR_UNO_SEQUENCE_HXX + +#include "sal/config.h" + +#include <cassert> +#include <cstddef> +#if defined LIBO_INTERNAL_ONLY +# include <type_traits> +# include <ostream> +#endif + +#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 +{ + +/// @cond INTERNAL +template< class E > +typelib_TypeDescriptionReference * Sequence< E >::s_pType = NULL; +/// @endcond + +template< class E > +inline Sequence< E >::Sequence() +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + ::uno_type_sequence_construct( + &_pSequence, rType.getTypeLibType(), + NULL, 0, cpp_acquire ); + // no bad_alloc, because empty sequence is statically allocated in cppu +} + +template< class E > +inline Sequence< E >::Sequence( const Sequence & rSeq ) +{ + osl_atomic_increment( &rSeq._pSequence->nRefCount ); + _pSequence = rSeq._pSequence; +} + +template< class E > +inline Sequence< E >::Sequence( + uno_Sequence * pSequence, __sal_NoAcquire ) + : _pSequence( pSequence ) +{ +} + +#if defined(__COVERITY__) +extern "C" void __coverity_tainted_data_sanitize__(void *); +#endif + +template< class E > +inline Sequence< E >::Sequence( const E * pElements, sal_Int32 len ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + +#if defined(__COVERITY__) + // cid#1448292 coverity has difficulty with css::uno::Sequence + __coverity_tainted_data_sanitize__(pElements); +#endif + + bool success = + ::uno_type_sequence_construct( + &_pSequence, rType.getTypeLibType(), + const_cast< E * >( pElements ), len, cpp_acquire ); + if (! success) + throw ::std::bad_alloc(); +} + +template< class E > +inline Sequence< E >::Sequence( sal_Int32 len ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + bool success = + ::uno_type_sequence_construct( + &_pSequence, rType.getTypeLibType(), + NULL, len, cpp_acquire ); + if (! success) + throw ::std::bad_alloc(); +} + +#if defined LIBO_INTERNAL_ONLY +template<typename E> Sequence<E>::Sequence(std::initializer_list<E> init) { + if (!uno_type_sequence_construct( + &_pSequence, cppu::getTypeFavourUnsigned(this).getTypeLibType(), + const_cast<E *>(init.begin()), init.size(), cpp_acquire)) + { + throw std::bad_alloc(); + } +} +#endif + +template< class E > +inline Sequence< E >::~Sequence() +{ + if (osl_atomic_decrement( &_pSequence->nRefCount ) == 0) + { + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + uno_type_sequence_destroy( + _pSequence, rType.getTypeLibType(), cpp_release ); + } +} + +template< class E > +inline Sequence< E > & Sequence< E >::operator = ( const Sequence & rSeq ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + ::uno_type_sequence_assign( + &_pSequence, rSeq._pSequence, rType.getTypeLibType(), cpp_release ); + return *this; +} + +template< class E > +inline bool Sequence< E >::operator == ( const Sequence & rSeq ) const +{ + if (_pSequence == rSeq._pSequence) + return true; + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + return ::uno_type_equalData( + const_cast< Sequence * >( this ), rType.getTypeLibType(), + const_cast< Sequence * >( &rSeq ), rType.getTypeLibType(), + cpp_queryInterface, + cpp_release ); +} + +template< class E > +inline bool Sequence< E >::operator != ( const Sequence & rSeq ) const +{ + return (! operator == ( rSeq )); +} + +template< class E > +inline E * Sequence< E >::getArray() +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + bool success = + ::uno_type_sequence_reference2One( + &_pSequence, rType.getTypeLibType(), + cpp_acquire, cpp_release ); + if (! success) + throw ::std::bad_alloc(); + return reinterpret_cast< E * >( _pSequence->elements ); +} + +template<class E> E * Sequence<E>::begin() { return getArray(); } + +template<class E> E const * Sequence<E>::begin() const +{ return getConstArray(); } + +template<class E> E * Sequence<E>::end() { return begin() + getLength(); } + +template<class E> E const * Sequence<E>::end() const +{ return begin() + getLength(); } + +template< class E > +inline E & Sequence< E >::operator [] ( sal_Int32 nIndex ) +{ + // silence spurious -Werror=strict-overflow warnings from GCC 4.8.2 + assert(nIndex >= 0 && static_cast<sal_uInt32>(nIndex) < static_cast<sal_uInt32>(getLength())); + return getArray()[ nIndex ]; +} + +template< class E > +inline const E & Sequence< E >::operator [] ( sal_Int32 nIndex ) const +{ + // silence spurious -Werror=strict-overflow warnings from GCC 4.8.2 + assert(nIndex >= 0 && static_cast<sal_uInt32>(nIndex) < static_cast<sal_uInt32>(getLength())); + 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 ); + bool success = + ::uno_type_sequence_realloc( + &_pSequence, rType.getTypeLibType(), nSize, + cpp_acquire, cpp_release ); + if (!success) + throw ::std::bad_alloc(); +} + +inline ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL toUnoSequence( + const ::rtl::ByteSequence & rByteSequence ) +{ + return * reinterpret_cast< const ::com::sun::star::uno::Sequence< sal_Int8 > * >( &rByteSequence ); +} + +#if defined LIBO_INTERNAL_ONLY + +/// @cond INTERNAL + +namespace uno_detail { + +template< typename value_t, typename charT, typename traits > +void sequence_output_elems( std::basic_ostream<charT, traits> &os, const value_t *pAry, sal_Int32 nLen, std::true_type ) +{ + // for integral types, use hex notation + auto const flags = os.setf(std::ios_base::hex); + for(sal_Int32 i=0; i<nLen-1; ++i) + os << "0x" << *pAry++ << ", "; + if( nLen > 1 ) + os << "0x" << *pAry++; + os.setf(flags); +} + +template< typename value_t, typename charT, typename traits > +void sequence_output_elems( std::basic_ostream<charT, traits> &os, const value_t *pAry, sal_Int32 nLen, std::false_type ) +{ + // every other type: rely on their own ostream operator<< + for(sal_Int32 i=0; i<nLen-1; ++i) + os << *pAry++ << ", "; + if( nLen > 1 ) + os << *pAry++; +} + +template< typename value_t, typename charT, typename traits > +void sequence_output_bytes( std::basic_ostream<charT, traits> &os, const value_t *pAry, sal_Int32 nLen ) +{ + // special case bytes - ostream operator<< outputs those as char + // values, but we need raw ints here + auto const flags = os.setf(std::ios_base::hex); + for(sal_Int32 i=0; i<nLen-1; ++i) + os << "0x" << (0xFF & +*pAry++) << ", "; + if( nLen > 1 ) + os << "0x" << (0xFF & +*pAry++); + os.setf(flags); +} + +} + +/** + Support for Sequence in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO + macros, for example). + + @since LibreOffice 6.1 +*/ +template< typename value_t, typename charT, typename traits > +inline std::basic_ostream<charT, traits> &operator<<(std::basic_ostream<charT, traits> &os, css::uno::Sequence<value_t> const& v) +{ + const value_t *pAry = v.getConstArray(); + sal_Int32 nLen = v.getLength(); + if constexpr (std::is_same<sal_Int8, value_t>::value) { + uno_detail::sequence_output_bytes(os, pAry, nLen); + } else { + uno_detail::sequence_output_elems(os, pAry, nLen, std::is_integral<value_t>()); + } + return os; +} + +/// @endcond + +#endif + +} +} +} +} + +namespace cppu { + +template< typename T > inline ::com::sun::star::uno::Type const & +getTypeFavourUnsigned( + SAL_UNUSED_PARAMETER ::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( + SAL_UNUSED_PARAMETER ::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 = NULL; + if (td == NULL) { + ::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( + SAL_UNUSED_PARAMETER const ::com::sun::star::uno::Sequence< E > * ) +{ + 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 ) +{ + 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 ); +} + +// char sequence +inline const ::com::sun::star::uno::Type & +SAL_CALL getCharSequenceCppuType() +{ + static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = NULL; + if (! s_pType_com_sun_star_uno_Sequence_Char) + { + const ::com::sun::star::uno::Type & rElementType = cppu::UnoType<cppu::UnoCharType>::get(); + ::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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/com/sun/star/uno/Type.h b/include/com/sun/star/uno/Type.h new file mode 100644 index 000000000..056f6ba5f --- /dev/null +++ b/include/com/sun/star/uno/Type.h @@ -0,0 +1,494 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_TYPE_H +#define INCLUDED_COM_SUN_STAR_UNO_TYPE_H + +#include "typelib/typedescription.h" +#include "com/sun/star/uno/TypeClass.hdl" +#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 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 SAL_WARN_UNUSED SAL_DLLPUBLIC_RTTI Type +{ + /** the C typelib reference pointer + */ + typelib_TypeDescriptionReference * _pType; + +public: + /// @cond INTERNAL + // these are here to force memory de/allocation to sal lib. + static void * SAL_CALL operator new ( size_t nSize ) + { return ::rtl_allocateMemory( nSize ); } + static void SAL_CALL operator delete ( void * pMem ) + { ::rtl_freeMemory( pMem ); } + static void * SAL_CALL operator new ( size_t, void * pMem ) + { return pMem; } + static void SAL_CALL operator delete ( void *, void * ) + {} + /// @endcond + + /** Default Constructor: Type is set to void. + */ + inline Type(); + + /** 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 ); + + /** 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 ); + + /** Constructor: Type is (copy) constructed by given C type description reference. + + @param pType C type description reference + */ + inline Type( typelib_TypeDescriptionReference * pType ); + + /** 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 dummy ); + /** 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 dummy ); + + /** Copy constructor: Type is copy constructed by given type. + + @param rType another type + */ + inline Type( const Type & rType ); + + /** Destructor: Releases acquired C type description reference. + */ + ~Type() + { ::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 ); + + /** Gets the type class of set type. + + @return type class of set type + */ + TypeClass SAL_CALL getTypeClass() const + { return static_cast<TypeClass>(_pType->eTypeClass); } + + /** Gets the name of the set type. + + @return name of the set type + */ + inline ::rtl::OUString SAL_CALL getTypeName() const; + + /** Obtains a full type description of set type. + + @param ppDescr [inout] type description + */ + void SAL_CALL getDescription( typelib_TypeDescription ** ppDescr ) const + { ::typelib_typedescriptionreference_getDescription( ppDescr, _pType ); } + + /** Gets the C typelib type description reference pointer. Does not acquire the reference! + + @return UNacquired type description reference + */ + typelib_TypeDescriptionReference * SAL_CALL getTypeLibType() const + { 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 + */ + bool SAL_CALL isAssignableFrom( const Type & rType ) const + { 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 + */ + bool SAL_CALL equals( const Type & rType ) const + { 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 + */ + bool SAL_CALL operator == ( const Type & rType ) const + { return ::typelib_typedescriptionreference_equals( _pType, rType._pType ); } + /** Inequality operator: Compares two types. + + @param rType another type + @return false if both types refer the same type, true otherwise + */ + bool SAL_CALL operator != ( const Type & rType ) const + { 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type "type" + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const ::com::sun::star::uno::Type * ); + +/** Gets the meta type of IDL type void. + @return type of IDL type void + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuVoidType(); +/** Gets the meta type of IDL type void. + + @return type of IDL type void + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getVoidCppuType(); + +/** Gets the meta type of IDL type boolean. + + @return type of IDL type boolean + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuBooleanType(); +/** Gets the meta type of IDL type boolean. + + @return type of IDL type boolean + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getBooleanCppuType(); +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type boolean + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Bool * ); +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type boolean + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( + bool const * ); + +/** Gets the meta type of IDL type char. + + @return type of IDL type char + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCharCppuType(); +/** Gets the meta type of IDL type char. + + @return type of IDL type char + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuCharType(); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type byte + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int8 * ); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type string + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const ::rtl::OUString * ); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type short + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int16 * ); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type unsigned short + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_uInt16 * ); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type long + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int32 * ); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type unsigned long + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_uInt32 * ); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type hyper + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_Int64 * ); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type unsigned hyper + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const sal_uInt64 * ); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type float + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const float * ); + +/** 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. + + The dummy parameter is just a typed pointer for function signature. + + @return type of IDL type double + + @deprecated + Use cppu::UnoType instead. +*/ +SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const double * ); + +/** 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 > SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL +getCppuType(); + +/** 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<> SAL_DEPRECATED("use cppu::UnoType") +inline const ::com::sun::star::uno::Type & SAL_CALL +getCppuType< sal_Unicode >(); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/com/sun/star/uno/Type.hxx b/include/com/sun/star/uno/Type.hxx new file mode 100644 index 000000000..770734f99 --- /dev/null +++ b/include/com/sun/star/uno/Type.hxx @@ -0,0 +1,219 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_TYPE_HXX +#define INCLUDED_COM_SUN_STAR_UNO_TYPE_HXX + +#include "sal/config.h" + +#include <cstddef> +#include <ostream> + +#include "com/sun/star/uno/Type.h" +#include "cppu/unotype.hxx" + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + + +inline Type::Type() +{ + _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 ) + : _pType( NULL ) +{ + ::typelib_typedescriptionreference_new( &_pType, static_cast<typelib_TypeClass>(eTypeClass), rTypeName.pData ); +} + +inline Type::Type( TypeClass eTypeClass, const sal_Char * pTypeName ) + : _pType( NULL ) +{ + ::typelib_typedescriptionreference_newByAsciiName( &_pType, static_cast<typelib_TypeClass>(eTypeClass), pTypeName ); +} + +inline Type::Type( typelib_TypeDescriptionReference * pType ) + : _pType( pType ) +{ + ::typelib_typedescriptionreference_acquire( _pType ); +} + +inline Type::Type( typelib_TypeDescriptionReference * pType, UnoType_NoAcquire ) + : _pType( pType ) +{ +} + +inline Type::Type( typelib_TypeDescriptionReference * pType, __sal_NoAcquire ) + : _pType( pType ) +{ +} + +inline Type::Type( const Type & rType ) + : _pType( rType._pType ) +{ + ::typelib_typedescriptionreference_acquire( _pType ); +} + +inline ::rtl::OUString Type::getTypeName() const +{ + return ::rtl::OUString( _pType->pTypeName ); +} + +inline Type & Type::operator = ( const Type & rType ) +{ + ::typelib_typedescriptionreference_assign( &_pType, rType._pType ); + return *this; +} + + +template< class T > +typelib_TypeDescriptionReference * Array< T >::s_pType = NULL; + +#if defined LIBO_INTERNAL_ONLY +/** + Support for Type in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO + macros, for example). + + @since LibreOffice 5.4 +*/ +template<typename charT, typename traits> std::basic_ostream<charT, traits> & +operator <<(std::basic_ostream<charT, traits> & stream, Type const & type) +{ return stream << type.getTypeName(); } +#endif + +} +} +} +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const ::com::sun::star::uno::Type * ) +{ + return ::cppu::UnoType< ::com::sun::star::uno::Type >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuVoidType() +{ + return ::cppu::UnoType<void>::get(); +} +inline const ::com::sun::star::uno::Type & SAL_CALL getVoidCppuType() +{ + return ::cppu::UnoType<void>::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuBooleanType() +{ + return ::cppu::UnoType< bool >::get(); +} +inline const ::com::sun::star::uno::Type & SAL_CALL getBooleanCppuType() +{ + return ::cppu::UnoType< bool >::get(); +} +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const sal_Bool * ) +{ + return ::cppu::UnoType< bool >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( + SAL_UNUSED_PARAMETER bool const * ) +{ + return ::cppu::UnoType< bool >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCharCppuType() +{ + return ::cppu::UnoType< ::cppu::UnoCharType >::get(); +} +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuCharType() +{ + return ::cppu::UnoType< ::cppu::UnoCharType >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const sal_Int8 * ) +{ + return ::cppu::UnoType< ::sal_Int8 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const ::rtl::OUString * ) +{ + return ::cppu::UnoType< ::rtl::OUString >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const sal_Int16 * ) +{ + return ::cppu::UnoType< ::sal_Int16 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const sal_uInt16 * ) +{ + return ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const sal_Int32 * ) +{ + return ::cppu::UnoType< ::sal_Int32 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const sal_uInt32 * ) +{ + return ::cppu::UnoType< ::sal_uInt32 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const sal_Int64 * ) +{ + return ::cppu::UnoType< ::sal_Int64 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const sal_uInt64 * ) +{ + return ::cppu::UnoType< ::sal_uInt64 >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const float * ) +{ + return ::cppu::UnoType< float >::get(); +} + +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( SAL_UNUSED_PARAMETER const double * ) +{ + return ::cppu::UnoType< double >::get(); +} + +template< typename T > +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType() +{ + return ::cppu::UnoType< T >::get(); +} + +template<> +inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType< sal_Unicode >() +{ + return ::cppu::UnoType< ::cppu::UnoCharType >::get(); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/com/sun/star/uno/genfunc.h b/include/com/sun/star/uno/genfunc.h new file mode 100644 index 000000000..eb1b028cc --- /dev/null +++ b/include/com/sun/star/uno/genfunc.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_GENFUNC_H +#define INCLUDED_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 ); +/** Function to release a C++ interface. + + @param pCppI C++ interface pointer +*/ +inline void SAL_CALL cpp_release( void * pCppI ); +/** 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 ); + +} +} +} +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/com/sun/star/uno/genfunc.hxx b/include/com/sun/star/uno/genfunc.hxx new file mode 100644 index 000000000..45acb99ed --- /dev/null +++ b/include/com/sun/star/uno/genfunc.hxx @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_COM_SUN_STAR_UNO_GENFUNC_HXX +#define INCLUDED_COM_SUN_STAR_UNO_GENFUNC_HXX + +#include "sal/config.h" + +#include <cstddef> + +#include "com/sun/star/uno/genfunc.h" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/XInterface.hpp" + + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ + + +inline void SAL_CALL cpp_acquire( void * pCppI ) +{ + static_cast< XInterface * >( pCppI )->acquire(); +} + +inline void SAL_CALL cpp_release( void * pCppI ) +{ + static_cast< XInterface * >( pCppI )->release(); +} + +inline void * SAL_CALL cpp_queryInterface( void * pCppI, typelib_TypeDescriptionReference * pType ) +{ + if (pCppI) + { + try + { + Any aRet( static_cast< XInterface * >( pCppI )->queryInterface( + * reinterpret_cast< const Type * >( &pType ) ) ); + if (typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass) + { + XInterface * pRet = static_cast< XInterface * >( aRet.pReserved ); + aRet.pReserved = NULL; + return pRet; + } + } + catch (RuntimeException &) + { + } + } + return NULL; +} + +} +} +} +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |