diff options
Diffstat (limited to '')
141 files changed, 21626 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..f232ccd90 --- /dev/null +++ b/include/com/sun/star/uno/Any.h @@ -0,0 +1,493 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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 using the <<= operators. + 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; + template<typename T> explicit inline Any(rtl::OUStringNumber<T> && value); + template<typename T> explicit Any(rtl::OUStringNumber<T> const &) = delete; + template <std::size_t N> explicit inline Any(const rtl::OUStringLiteral<N>& value); +#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 + +#if !defined LIBO_INTERNAL_ONLY +/** Template function to generically construct an any from a C++ value. + + @deprecated Just use an Any constructor with an appropriately typed argument. (When the + (UNO) type recorded in the Any instance shall be different from what would + be deduced from the (C++) type of the argument, cast the argument to the appropriate type + first.) + + @tparam C value type + @param value a value + @return an any +*/ +template< class C > +inline Any SAL_CALL makeAny( const C & value ); + +template<> inline Any SAL_CALL makeAny(sal_uInt16 const & value); + +template<> Any SAL_CALL makeAny(Any const &) SAL_DELETED_FUNCTION; +#endif + +/** Wrap a value in an Any, if necessary. + + (A difference to the deprecated 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..d73b2a586 --- /dev/null +++ b/include/com/sun/star/uno/Any.hxx @@ -0,0 +1,765 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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))) +{} +template<typename T> +Any::Any(rtl::OUStringNumber<T> && value): Any(rtl::OUString(std::move(value))) {} +template <std::size_t N> +Any::Any(const rtl::OUStringLiteral<N>& value): Any(rtl::OUString(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 + +Any::Any(Any && other) noexcept { + uno_any_construct(this, nullptr, nullptr, &cpp_acquire); + std::swap(other.pType, pType); + std::swap(other.pData, pData); + std::swap(other.pReserved, pReserved); + if (pData == &other.pReserved) { + pData = &pReserved; + } + // This leaves other.pData (where "other" 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::operator =(Any && other) noexcept { + std::swap(other.pType, pType); + std::swap(other.pData, pData); + std::swap(other.pReserved, pReserved); + if (pData == &other.pReserved) { + pData = &pReserved; + } + if (other.pData == &pReserved) { + other.pData = &other.pReserved; + } + 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 * >(NULL)); + 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 )); +} + + +#if !defined LIBO_INTERNAL_ONLY +template< class C > +inline Any SAL_CALL makeAny( const C & value ) +{ + return Any(value); +} + +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 Any(value); +} + +template<> Any toAny(Any const & value) { return value; } + +#if defined LIBO_INTERNAL_ONLY + +template<typename T1, typename T2> +Any toAny(rtl::OUStringConcat<T1, T2> && value) +{ return Any(std::move(value)); } + +template<typename T> +Any toAny(rtl::OUStringNumber<T> && value) +{ return Any(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 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 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..85c0d929e --- /dev/null +++ b/include/com/sun/star/uno/Reference.h @@ -0,0 +1,571 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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 > & 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..7632c5504 --- /dev/null +++ b/include/com/sun/star/uno/Reference.hxx @@ -0,0 +1,481 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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 = castToXInterface(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..1b9f6a2aa --- /dev/null +++ b/include/com/sun/star/uno/Sequence.h @@ -0,0 +1,361 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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 ); + +#if defined LIBO_INTERNAL_ONLY + inline Sequence & operator =(Sequence && other); +#endif + + /** 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(); + +#if !defined LIBO_INTERNAL_ONLY + /** This function allows to use Sequence in standard algorithms, like std::find + and others. + + @since LibreOffice 4.2 + */ + inline E * begin(); +#endif + + /** This function allows to use Sequence in standard algorithms, like std::find + and others. + + @since LibreOffice 4.2 + */ + inline E const * begin() const; + +#if !defined LIBO_INTERNAL_ONLY + /** This function allows to use Sequence in standard algorithms, like std::find + and others. + + @since LibreOffice 4.2 + */ + inline E * end(); +#endif + + /** 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 operator[] is not available in internal code. Consider explicit use +// of getArray(), out of tight loops if possible to avoid unneeded COW overhead. +#if !defined LIBO_INTERNAL_ONLY + /** 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 ); +#endif + + /** 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; } + +#if defined LIBO_INTERNAL_ONLY + /** Swaps sequences efficiently exchanging their underlying representations. + + @param other another sequence of same type + + @since LibreOffice 7.3 + */ + inline void swap(Sequence& other); +#endif +}; + +// 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..34d5def3b --- /dev/null +++ b/include/com/sun/star/uno/Sequence.hxx @@ -0,0 +1,406 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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> +# include <utility> +#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 ) +{ +} + +template< class E > +inline Sequence< E >::Sequence( const E * pElements, sal_Int32 len ) +{ + const Type & rType = ::cppu::getTypeFavourUnsigned( this ); + + 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; +} + +#if defined LIBO_INTERNAL_ONLY +template<typename E> Sequence<E> & Sequence<E>::operator =(Sequence && other) { + std::swap(_pSequence, other._pSequence); + return *this; +} +#endif + +template< class E > +inline bool Sequence< E >::operator == ( const Sequence & rSeq ) const +{ + if (_pSequence == rSeq._pSequence) + return true; + if (_pSequence->nElements != rSeq._pSequence->nElements) + return false; + 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 ); +} + +#if !defined LIBO_INTERNAL_ONLY +template<class E> E * Sequence<E>::begin() { return getArray(); } +#endif + +template<class E> E const * Sequence<E>::begin() const +{ return getConstArray(); } + +#if !defined LIBO_INTERNAL_ONLY +template<class E> E * Sequence<E>::end() { return begin() + getLength(); } +#endif + +template<class E> E const * Sequence<E>::end() const +{ return begin() + getLength(); } + +#if !defined LIBO_INTERNAL_ONLY +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 ]; +} +#endif + +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(); +} + +#if defined LIBO_INTERNAL_ONLY +template <class E> inline void Sequence<E>::swap(Sequence& other) +{ + std::swap(_pSequence, other._pSequence); +} +#endif + +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; +} + +template <class E> inline auto asNonConstRange(css::uno::Sequence<E>& s) +{ + // Two iterators [begin, end] representing the non-const range of the Sequence. + // It only calls Sequence::getArray once, to avoid the second COW overhead when + // Sequence::begin() and Sequence::end() are called in pairs. + // Inheriting from pair allows to use std::tie to unpack the two iterators. + struct SequenceRange : public std::pair<E*, E*> + { + SequenceRange(E* ptr, sal_Int32 len) : std::pair<E*, E*>(ptr, ptr + len) {} + // These allow to pass it as range-expression to range-based for loops + E* begin() { return std::pair<E*, E*>::first; } + E* end() { return std::pair<E*, E*>::second; } + E& operator[](sal_Int32 i) { assert(i >= 0 && i < end() - begin()); return begin()[i]; } + }; + return SequenceRange(s.getLength() ? s.getArray() : nullptr, s.getLength()); +}; + +/// @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 == NULL) { + ::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 * >( + NULL)). + 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 * >( + NULL)). + 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..5dc1b41e0 --- /dev/null +++ b/include/com/sun/star/uno/Type.h @@ -0,0 +1,502 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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 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 ); + +#if defined LIBO_INTERNAL_ONLY + inline Type & SAL_CALL operator = ( Type && ); +#endif + + /** 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..f62d0a17b --- /dev/null +++ b/include/com/sun/star/uno/Type.hxx @@ -0,0 +1,231 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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 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; +} + +#if defined LIBO_INTERNAL_ONLY +inline Type & Type::operator = ( Type && rType ) +{ + std::swap(_pType, rType._pType); + return *this; +} +#endif + + +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..4ec0ec203 --- /dev/null +++ b/include/com/sun/star/uno/genfunc.h @@ -0,0 +1,62 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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..ad1b8bc7e --- /dev/null +++ b/include/com/sun/star/uno/genfunc.hxx @@ -0,0 +1,84 @@ +/* -*- 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ +#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: */ diff --git a/include/comphelper/AccessibleImplementationHelper.hxx b/include/comphelper/AccessibleImplementationHelper.hxx new file mode 100644 index 000000000..b6c8d9ab0 --- /dev/null +++ b/include/comphelper/AccessibleImplementationHelper.hxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 . + */ + +#pragma once + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> + +namespace com::sun::star::awt +{ +struct KeyStroke; +} +namespace com::sun::star::uno +{ +template <class E> class Sequence; +} + +namespace comphelper +{ +/** + * Helper function used for converting keybinding to string. + * + * @param keySet the key stroke sequence. + */ +COMPHELPER_DLLPUBLIC OUString +GetkeyBindingStrByXkeyBinding(const css::uno::Sequence<css::awt::KeyStroke>& keySet); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/comphelper/ChainablePropertySet.hxx b/include/comphelper/ChainablePropertySet.hxx new file mode 100644 index 000000000..fb4fbd744 --- /dev/null +++ b/include/comphelper/ChainablePropertySet.hxx @@ -0,0 +1,148 @@ +/* -*- 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_COMPHELPER_CHAINABLEPROPERTYSET_HXX +#define INCLUDED_COMPHELPER_CHAINABLEPROPERTYSET_HXX + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <comphelper/comphelperdllapi.h> +#include <cppuhelper/implbase.hxx> +#include <rtl/ref.hxx> + +namespace comphelper { class SolarMutex; } +namespace comphelper { struct PropertyInfo; } + +namespace comphelper +{ + class ChainablePropertySetInfo; +} + +/* + * A ChainablePropertySet has the following features: + * + * 1. It implements both the PropertySet and MultiPropertySet interfaces. + * 2. It can be 'included' in a MasterPropertySet to seamlessly appear as if + * if it's properties were in the master. + * + * To be used as a base class for PropertySets, the subclass must implement + * the 6 protected pure virtual functions. If a mutex is passed to the + * constructor, this is locked before any call to _getSingleValue or + * _setSingleValue and released after all processing has completed + * (including _postSetValues or _postGetValues ) + * + * Any MasterPropertySet implementations that can include an + * implementation of a given ChainablePropertySet must be + * declared as a 'friend' in the implementation of the ChainablePropertySet. + * + */ + +namespace comphelper +{ + typedef cppu::WeakImplHelper + < + css::beans::XPropertySet, + css::beans::XMultiPropertySet, + css::lang::XServiceInfo + > + ChainablePropertySetBase; + class COMPHELPER_DLLPUBLIC ChainablePropertySet : public ChainablePropertySetBase, + public css::beans::XPropertyState + { + friend class MasterPropertySet; + protected: + SolarMutex* const mpMutex; + rtl::Reference < ChainablePropertySetInfo > mxInfo; + + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual void _preSetValues () = 0; + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual void _setSingleValue(const comphelper::PropertyInfo & rInfo, const css::uno::Any &rValue) = 0; + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual void _postSetValues () = 0; + + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual void _preGetValues () = 0; + /// @throws css::beans::UnknownPropertyException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual void _getSingleValue( const comphelper::PropertyInfo & rInfo, css::uno::Any & rValue ) = 0; + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + virtual void _postGetValues () = 0; + + public: + ChainablePropertySet( comphelper::ChainablePropertySetInfo* pInfo, SolarMutex* pMutex ) + noexcept; + virtual ~ChainablePropertySet() + noexcept override; + + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override + { return ChainablePropertySetBase::queryInterface( aType ); } + void SAL_CALL acquire( ) noexcept override + { ChainablePropertySetBase::acquire( ); } + void SAL_CALL release( ) noexcept override + { ChainablePropertySetBase::release( ); } + + // XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XMultiPropertySet + virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override; + virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override; + virtual void SAL_CALL addPropertiesChangeListener( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + virtual void SAL_CALL firePropertiesChangeEvent( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + + // XPropertyState + virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override; + virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates( const css::uno::Sequence< OUString >& aPropertyName ) override; + virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override; + virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override; + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/ChainablePropertySetInfo.hxx b/include/comphelper/ChainablePropertySetInfo.hxx new file mode 100644 index 000000000..5ece0701c --- /dev/null +++ b/include/comphelper/ChainablePropertySetInfo.hxx @@ -0,0 +1,64 @@ +/* -*- 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_COMPHELPER_CHAINABLEPROPERTYSETINFO_HXX +#define INCLUDED_COMPHELPER_CHAINABLEPROPERTYSETINFO_HXX + +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <comphelper/PropertyInfoHash.hxx> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> + +/* + * A ChainablePropertySetInfo is usually initialised with a pointer to the first element + * of a null-terminated static table of PropertyInfo structs. This is placed in a hash_map + * for fast access + * + */ +namespace comphelper +{ + // workaround for incremental linking bugs in MSVC2015 + class SAL_DLLPUBLIC_TEMPLATE ChainablePropertySetInfo_Base : public cppu::WeakImplHelper< css::beans::XPropertySetInfo > {}; + + class COMPHELPER_DLLPUBLIC ChainablePropertySetInfo final : public ChainablePropertySetInfo_Base + { + public: + ChainablePropertySetInfo( PropertyInfo const * pMap ); + + void remove( const OUString& aName ); + + private: + virtual ~ChainablePropertySetInfo() + noexcept override; + + // XPropertySetInfo + virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties() override; + virtual css::beans::Property SAL_CALL getPropertyByName( const OUString& aName ) override; + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override; + + PropertyInfoHash maMap; + css::uno::Sequence < css::beans::Property > maProperties; + + friend class ChainablePropertySet; + friend class MasterPropertySet; + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/DirectoryHelper.hxx b/include/comphelper/DirectoryHelper.hxx new file mode 100644 index 000000000..321e9f960 --- /dev/null +++ b/include/comphelper/DirectoryHelper.hxx @@ -0,0 +1,38 @@ +/* -*- 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/. + */ + +#pragma once + +#include <sal/config.h> + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> +#include <set> +#include <string_view> + +namespace comphelper +{ +class COMPHELPER_DLLPUBLIC DirectoryHelper +{ +public: + static std::u16string_view splitAtLastToken(std::u16string_view rSrc, sal_Unicode aToken, + OUString& rRight); + static bool fileExists(const OUString& rBaseURL); + static bool dirExists(const OUString& rDirURL); + + // all rDirs and rFiles strings are already URI encoded, so safe for concat + static void scanDirsAndFiles(const OUString& rDirURL, std::set<OUString>& rDirs, + std::set<std::pair<OUString, OUString>>& rFiles); + static bool deleteDirRecursively(const OUString& rDirURL); + static bool moveDirContent(const OUString& rSourceDirURL, std::u16string_view rTargetDirURL, + const std::set<OUString>& rExcludeList); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/IdPropArrayHelper.hxx b/include/comphelper/IdPropArrayHelper.hxx new file mode 100644 index 000000000..8b70db849 --- /dev/null +++ b/include/comphelper/IdPropArrayHelper.hxx @@ -0,0 +1,106 @@ +/* -*- 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 . + */ +#pragma once + +#include <sal/config.h> + +#include <mutex> +#include <cppuhelper/propshlp.hxx> +#include <cassert> +#include <unordered_map> + +namespace comphelper +{ + + typedef std::unordered_map< sal_Int32, ::cppu::IPropertyArrayHelper* > OIdPropertyArrayMap; + template <class TYPE> + class OIdPropertyArrayUsageHelper + { + public: + OIdPropertyArrayUsageHelper(); + virtual ~OIdPropertyArrayUsageHelper() + { + std::unique_lock aGuard(theMutex()); + assert(s_nRefCount > 0 && "OIdPropertyArrayUsageHelper::~OIdPropertyArrayUsageHelper : suspicious call : have a refcount of 0 !"); + if (!--s_nRefCount) + { + // delete the element + for (auto const& elem : *s_pMap) + delete elem.second; + delete s_pMap; + s_pMap = nullptr; + } + } + + /** call this in the getInfoHelper method of your derived class. The method returns the array helper of the + class, which is created if necessary. + */ + ::cppu::IPropertyArrayHelper* getArrayHelper(sal_Int32 nId); + + protected: + /** used to implement the creation of the array helper which is shared amongst all instances of the class. + This method needs to be implemented in derived classes. + <BR> + The method gets called with Mutex acquired. + @return a pointer to the newly created array helper. Must not be NULL. + */ + virtual ::cppu::IPropertyArrayHelper* createArrayHelper(sal_Int32 nId) const = 0; + private: + static sal_Int32 s_nRefCount; + static OIdPropertyArrayMap* s_pMap; + static std::mutex& theMutex() + { + static std::mutex SINGLETON; + return SINGLETON; + } + }; + + template<class TYPE> + sal_Int32 OIdPropertyArrayUsageHelper< TYPE >::s_nRefCount = 0; + + template<class TYPE> + OIdPropertyArrayMap* OIdPropertyArrayUsageHelper< TYPE >::s_pMap = nullptr; + + template <class TYPE> + OIdPropertyArrayUsageHelper<TYPE>::OIdPropertyArrayUsageHelper() + { + std::unique_lock aGuard(theMutex()); + // create the map if necessary + if (!s_pMap) + s_pMap = new OIdPropertyArrayMap; + ++s_nRefCount; + } + + template <class TYPE> + ::cppu::IPropertyArrayHelper* OIdPropertyArrayUsageHelper<TYPE>::getArrayHelper(sal_Int32 nId) + { + assert(s_nRefCount && "OIdPropertyArrayUsageHelper::getArrayHelper : suspicious call : have a refcount of 0 !"); + std::unique_lock aGuard(theMutex()); + // do we have the array already? + auto& rEntry = (*s_pMap)[nId]; + if (!rEntry) + { + rEntry = createArrayHelper(nId); + assert(rEntry && "OIdPropertyArrayUsageHelper::getArrayHelper : createArrayHelper returned nonsense !"); + } + return (*s_pMap)[nId]; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/MasterPropertySet.hxx b/include/comphelper/MasterPropertySet.hxx new file mode 100644 index 000000000..acd9ce9c4 --- /dev/null +++ b/include/comphelper/MasterPropertySet.hxx @@ -0,0 +1,135 @@ +/* -*- 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_COMPHELPER_MASTERPROPERTYSET_HXX +#define INCLUDED_COMPHELPER_MASTERPROPERTYSET_HXX +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <comphelper/comphelperdllapi.h> +#include <comphelper/ChainablePropertySet.hxx> +#include <rtl/ref.hxx> +#include <map> + +namespace comphelper { class SolarMutex; } +namespace comphelper { struct PropertyInfo; } + +namespace comphelper +{ + class MasterPropertySetInfo; + class ChainablePropertySet; + struct SlaveData + { + rtl::Reference < ChainablePropertySet > mxSlave; + bool mbInit; + + SlaveData ( ChainablePropertySet *pSlave); + bool IsInit () const { return mbInit;} + void SetInit ( bool bInit) { mbInit = bInit; } + }; +} + +/* + * A MasterPropertySet implements all of the features of a ChainablePropertySet + * (it is not inherited from ChainablePropertySet to prevent MasterPropertySets + * being chained to each other), but also allows properties implemented in + * other ChainablePropertySets to be included as 'native' properties in a + * given MasterPropertySet implementation. These are registered using the + * 'registerSlave' method, and require that the implementation of the + * ChainablePropertySet and the implementation of the ChainablePropertySetInfo + * both declare the implementation of the MasterPropertySet as a friend. + */ +namespace comphelper +{ + class COMPHELPER_DLLPUBLIC MasterPropertySet : public css::beans::XPropertySet, + public css::beans::XPropertyState, + public css::beans::XMultiPropertySet + { + protected: + SolarMutex* const mpMutex; + sal_uInt8 mnLastId; + std::map< sal_uInt8, comphelper::SlaveData* > maSlaveMap; + rtl::Reference< MasterPropertySetInfo > mxInfo; + + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + virtual void _preSetValues () = 0; + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual void _setSingleValue( const comphelper::PropertyInfo & rInfo, const css::uno::Any &rValue ) = 0; + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + virtual void _postSetValues () = 0; + + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + virtual void _preGetValues () = 0; + /// @throws css::beans::UnknownPropertyException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual void _getSingleValue( const comphelper::PropertyInfo & rInfo, css::uno::Any & rValue ) = 0; + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + virtual void _postGetValues () = 0; + + public: + MasterPropertySet( comphelper::MasterPropertySetInfo* pInfo, SolarMutex* pMutex ) + noexcept; + virtual ~MasterPropertySet() + noexcept; + void registerSlave ( ChainablePropertySet *pNewSet ) + noexcept; + + // XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XMultiPropertySet + virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override; + virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override; + virtual void SAL_CALL addPropertiesChangeListener( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + virtual void SAL_CALL firePropertiesChangeEvent( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + + // XPropertyState + virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override; + virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates( const css::uno::Sequence< OUString >& aPropertyName ) override; + virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override; + virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override; + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/MasterPropertySetInfo.hxx b/include/comphelper/MasterPropertySetInfo.hxx new file mode 100644 index 000000000..0e50cc457 --- /dev/null +++ b/include/comphelper/MasterPropertySetInfo.hxx @@ -0,0 +1,56 @@ +/* -*- 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_COMPHELPER_MASTERPROPERTYSETINFO_HXX +#define INCLUDED_COMPHELPER_MASTERPROPERTYSETINFO_HXX +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <comphelper/PropertyInfoHash.hxx> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace comphelper +{ + // workaround for incremental linking bugs in MSVC2015 + class SAL_DLLPUBLIC_TEMPLATE MasterPropertySetInfo_Base : public cppu::WeakImplHelper< css::beans::XPropertySetInfo > {}; + + class COMPHELPER_DLLPUBLIC MasterPropertySetInfo final : public MasterPropertySetInfo_Base + { + public: + MasterPropertySetInfo( PropertyInfo const * pMap ); + + private: + virtual ~MasterPropertySetInfo() + noexcept override; + + void add( PropertyInfoHash &rHash, sal_uInt8 nMapId ); + + // XPropertySetInfo + virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties() override; + virtual css::beans::Property SAL_CALL getPropertyByName( const OUString& aName ) override; + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override; + + PropertyDataHash maMap; + css::uno::Sequence < css::beans::Property > maProperties; + + friend class MasterPropertySet; + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/PropertyInfoHash.hxx b/include/comphelper/PropertyInfoHash.hxx new file mode 100644 index 000000000..8c584ce5a --- /dev/null +++ b/include/comphelper/PropertyInfoHash.hxx @@ -0,0 +1,57 @@ +/* -*- 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_COMPHELPER_PROPERTYINFOHASH_HXX +#define INCLUDED_COMPHELPER_PROPERTYINFOHASH_HXX + +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/Type.h> +#include <unordered_map> + +namespace comphelper +{ + struct PropertyInfo + { + OUString maName; + css::uno::Type maType; + sal_Int32 mnHandle; + sal_Int16 mnAttributes; + + PropertyInfo(OUString const & aName, sal_Int32 nHandle, css::uno::Type const & aType, sal_Int16 nAttributes) + : maName(aName), maType(aType), mnHandle(nHandle), mnAttributes(nAttributes) {} + PropertyInfo(OUString && aName, sal_Int32 nHandle, css::uno::Type const & aType, sal_Int16 nAttributes) + : maName(std::move(aName)), maType(aType), mnHandle(nHandle), mnAttributes(nAttributes) {} + }; + struct PropertyData + { + sal_uInt8 mnMapId; + const PropertyInfo *mpInfo; + PropertyData ( sal_uInt8 nMapId, PropertyInfo const *pInfo ) + : mnMapId ( nMapId ) + , mpInfo ( pInfo ) {} + }; +} + +typedef std::unordered_map < OUString, + ::comphelper::PropertyInfo const * > PropertyInfoHash; +typedef std::unordered_map < OUString, + ::comphelper::PropertyData* > PropertyDataHash; +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/SelectionMultiplex.hxx b/include/comphelper/SelectionMultiplex.hxx new file mode 100644 index 000000000..ab980984a --- /dev/null +++ b/include/comphelper/SelectionMultiplex.hxx @@ -0,0 +1,93 @@ +/* -*- 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_COMPHELPER_SELECTIONMULTIPLEX_HXX +#define INCLUDED_COMPHELPER_SELECTIONMULTIPLEX_HXX + +#include <com/sun/star/view/XSelectionChangeListener.hpp> +#include <com/sun/star/lang/EventObject.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::view { class XSelectionSupplier; } + +//= selection helper classes + + +namespace comphelper +{ + + + //= OSelectionChangeListener + + /// simple listener adapter for selections + class COMPHELPER_DLLPUBLIC OSelectionChangeListener + { + friend class OSelectionChangeMultiplexer; + + public: + virtual ~OSelectionChangeListener(); + + /// @throws css::uno::RuntimeException + virtual void _selectionChanged( const css::lang::EventObject& aEvent ) = 0; + /// @throws css::uno::RuntimeException + virtual void _disposing(const css::lang::EventObject& _rSource); + }; + + + //= OSelectionChangeMultiplexer + + /// multiplexer for selection changes + class COMPHELPER_DLLPUBLIC OSelectionChangeMultiplexer final : public cppu::WeakImplHelper< css::view::XSelectionChangeListener> + { + friend class OSelectionChangeListener; + css::uno::Reference< css::view::XSelectionSupplier> m_xSet; + OSelectionChangeListener* m_pListener; + sal_Int32 m_nLockCount; + + OSelectionChangeMultiplexer(const OSelectionChangeMultiplexer&) = delete; + OSelectionChangeMultiplexer& operator=(const OSelectionChangeMultiplexer&) = delete; + + virtual ~OSelectionChangeMultiplexer() override; + public: + OSelectionChangeMultiplexer(OSelectionChangeListener* _pListener, const css::uno::Reference< css::view::XSelectionSupplier>& _rxSet); + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // XSelectionChangeListener + virtual void SAL_CALL selectionChanged( const css::lang::EventObject& aEvent ) override; + + /// incremental lock + void lock(); + /// incremental unlock + void unlock(); + /// get the lock count + sal_Int32 locked() const { return m_nLockCount; } + + void dispose(); + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_SELECTIONMULTIPLEX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/SetFlagContextHelper.hxx b/include/comphelper/SetFlagContextHelper.hxx new file mode 100644 index 000000000..b1b15eabb --- /dev/null +++ b/include/comphelper/SetFlagContextHelper.hxx @@ -0,0 +1,71 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_SETFLAGCONTEXTHELPER_HXX +#define INCLUDED_COMPHELPER_SETFLAGCONTEXTHELPER_HXX + +#include <com/sun/star/uno/XCurrentContext.hpp> +#include <cppuhelper/implbase.hxx> +#include <uno/current_context.hxx> +#include <utility> + +namespace comphelper +{ +// Used to flag some named value to be true for all code running in this context +class SetFlagContext final : public cppu::WeakImplHelper<css::uno::XCurrentContext> +{ +public: + explicit SetFlagContext(OUString sName, css::uno::Reference<css::uno::XCurrentContext> xContext) + : m_sName(std::move(sName)) + , mxNextContext(std::move(xContext)) + { + } + SetFlagContext(const SetFlagContext&) = delete; + SetFlagContext& operator=(const SetFlagContext&) = delete; + + virtual css::uno::Any SAL_CALL getValueByName(OUString const& Name) override + { + if (Name == m_sName) + return css::uno::Any(true); + else if (mxNextContext.is()) + return mxNextContext->getValueByName(Name); + else + return css::uno::Any(); + } + +private: + OUString m_sName; + css::uno::Reference<css::uno::XCurrentContext> mxNextContext; +}; + +// Returns a new context that reports the named value to be true +inline css::uno::Reference<css::uno::XCurrentContext> NewFlagContext(const OUString& sName) +{ + return new SetFlagContext(sName, css::uno::getCurrentContext()); +} + +// A specialization for preventing "Java must be enabled" interaction +inline css::uno::Reference<css::uno::XCurrentContext> NoEnableJavaInteractionContext() +{ + return NewFlagContext("DontEnableJava"); +} + +inline bool IsContextFlagActive(const OUString& sName) +{ + bool bFlag = false; + if (const auto xContext = css::uno::getCurrentContext()) + xContext->getValueByName(sName) >>= bFlag; + return bFlag; +} + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_SETFLAGCONTEXTHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/accessiblecomponenthelper.hxx b/include/comphelper/accessiblecomponenthelper.hxx new file mode 100644 index 000000000..963bea96b --- /dev/null +++ b/include/comphelper/accessiblecomponenthelper.hxx @@ -0,0 +1,142 @@ +/* -*- 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_COMPHELPER_ACCESSIBLECOMPONENTHELPER_HXX +#define INCLUDED_COMPHELPER_ACCESSIBLECOMPONENTHELPER_HXX + +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/uno3.hxx> +#include <comphelper/comphelperdllapi.h> + + +namespace comphelper +{ + + + //= OCommonAccessibleComponent + + /** base class encapsulating common functionality for the helper classes implementing + the XAccessibleComponent respectively XAccessibleExtendendComponent + */ + class COMPHELPER_DLLPUBLIC OCommonAccessibleComponent : public OAccessibleContextHelper + { + protected: + /// see the respective base class ctor for an extensive comment on this, please + OCommonAccessibleComponent(); + virtual ~OCommonAccessibleComponent() override; + + protected: + /// implements the calculation of the bounding rectangle - still waiting to be overwritten + /// + /// @throws css::uno::RuntimeException + virtual css::awt::Rectangle implGetBounds( ) = 0; + + protected: + /** non-virtual versions of the methods which can be implemented using <method>implGetBounds</method> + note: getLocationOnScreen relies on a valid parent (XAccessibleContext::getParent()->getAccessibleContext()), + which itself implements XAccessibleComponent + + @throws css::uno::RuntimeException + */ + bool containsPoint( const css::awt::Point& aPoint ); + /// @throws css::uno::RuntimeException + css::awt::Point getLocation( ); + /// @throws css::uno::RuntimeException + css::awt::Point getLocationOnScreen( ); + /// @throws css::uno::RuntimeException + css::awt::Size getSize( ); + /// @throws css::uno::RuntimeException + css::awt::Rectangle getBounds( ); + }; + + + //= OAccessibleComponentHelper + + + struct OAccessibleComponentHelper_Base : + public ::cppu::ImplHelper1< css::accessibility::XAccessibleComponent > + { + protected: + ~OAccessibleComponentHelper_Base() {} + }; + + /** a helper class for implementing an AccessibleContext which at the same time + supports an XAccessibleComponent interface. + */ + class COMPHELPER_DLLPUBLIC OAccessibleComponentHelper + :public OCommonAccessibleComponent + ,public OAccessibleComponentHelper_Base + { + protected: + OAccessibleComponentHelper(); + + public: + // XInterface + DECLARE_XINTERFACE( ) + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleComponent - default implementations + virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override; + virtual css::awt::Point SAL_CALL getLocation( ) override; + virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override; + virtual css::awt::Size SAL_CALL getSize( ) override; + virtual css::awt::Rectangle SAL_CALL getBounds( ) override; + }; + + + //= OAccessibleExtendedComponentHelper + + + typedef ::cppu::ImplHelper1 < css::accessibility::XAccessibleExtendedComponent + > OAccessibleExtendedComponentHelper_Base; + + /** a helper class for implementing an AccessibleContext which at the same time + supports an XAccessibleExtendedComponent interface. + */ + class COMPHELPER_DLLPUBLIC OAccessibleExtendedComponentHelper + :public OCommonAccessibleComponent + ,public OAccessibleExtendedComponentHelper_Base + { + protected: + OAccessibleExtendedComponentHelper( ); + + public: + // XInterface + DECLARE_XINTERFACE( ) + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleComponent - default implementations + virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override; + virtual css::awt::Point SAL_CALL getLocation( ) override; + virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override; + virtual css::awt::Size SAL_CALL getSize( ) override; + virtual css::awt::Rectangle SAL_CALL getBounds( ) override; + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_ACCESSIBLECOMPONENTHELPER_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/accessiblecontexthelper.hxx b/include/comphelper/accessiblecontexthelper.hxx new file mode 100644 index 000000000..dc367fbe1 --- /dev/null +++ b/include/comphelper/accessiblecontexthelper.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_COMPHELPER_ACCESSIBLECONTEXTHELPER_HXX +#define INCLUDED_COMPHELPER_ACCESSIBLECONTEXTHELPER_HXX + +#include <cppuhelper/compbase2.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/accessibility/XAccessibleContext2.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <comphelper/accessibleeventnotifier.hxx> +#include <comphelper/comphelperdllapi.h> +#include <comphelper/solarmutex.hxx> + + +namespace comphelper +{ + + + //= OAccessibleContextHelper + + + typedef ::cppu::WeakAggComponentImplHelper2 < css::accessibility::XAccessibleContext2, + css::accessibility::XAccessibleEventBroadcaster + > OAccessibleContextHelper_Base; + + /** helper class for implementing an AccessibleContext + */ + class COMPHELPER_DLLPUBLIC OAccessibleContextHelper + :public ::cppu::BaseMutex + ,public OAccessibleContextHelper_Base + { + friend class OContextEntryGuard; + private: + css::uno::WeakReference< css::accessibility::XAccessible > m_aCreator; // the XAccessible which created our XAccessibleContext + AccessibleEventNotifier::TClientId m_nClientId; + + protected: + virtual ~OAccessibleContextHelper( ) override; + + OAccessibleContextHelper( ); + + /** late construction + @param _rxAccessible + the Accessible object which created this context. + <p>If your derived implementation implements the XAccessible (and does not follow the proposed + separation of XAccessible from XAccessibleContext), you may pass <code>this</code> here.</p> + + <p>The object is hold weak, so its life time is not affected.</p> + + <p>The object is needed for performance reasons: for <method>getAccessibleIndexInParent</method>, + all children (which are XAccessible's theirself) of our parent have to be asked. If we know our + XAccessible, we can compare it with all the children, instead of asking all children for their + context and comparing this context with ourself.</p> + */ + void lateInit( const css::uno::Reference< css::accessibility::XAccessible >& _rxAccessible ); + + /** retrieves the creator previously set with <method>lateInit</method> + */ + css::uno::Reference< css::accessibility::XAccessible > + getAccessibleCreator( ) const; + + public: + // XAccessibleEventBroadcaster + virtual void SAL_CALL addAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + virtual void SAL_CALL removeAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + + // XAccessibleContext - still waiting to be overwritten + virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) override = 0; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) override = 0; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override = 0; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override = 0; + virtual OUString SAL_CALL getAccessibleDescription( ) override = 0; + virtual OUString SAL_CALL getAccessibleName( ) override = 0; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override = 0; + virtual css::uno::Reference< css::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) override = 0; + + // XAccessibleContext2 - default implementation + virtual OUString SAL_CALL getAccessibleId( ) override; + + // XAccessibleContext - default implementations + /** default implementation for retrieving the index of this object within the parent + <p>This basic implementation here returns the index <code>i</code> of the child for which + <code><parent>.getAccessibleChild( i )</code> equals our creator.</p> + */ + virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) override; + /** default implementation for retrieving the locale + <p>This basic implementation returns the locale of the parent context, + as retrieved via getAccessibleParent()->getAccessibleContext.</p> + */ + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + protected: + // OComponentHelper + virtual void SAL_CALL disposing() override; + + protected: + // helper + /** notifies all AccessibleEventListeners of a certain event + + @precond not to be called with our mutex locked + @param _nEventId + the id of the event. See AccessibleEventType + @param _rOldValue + the old value to be notified + @param _rNewValue + the new value to be notified + */ + void NotifyAccessibleEvent( + const sal_Int16 _nEventId, + const css::uno::Any& _rOldValue, + const css::uno::Any& _rNewValue + ); + + // life time control + /// checks whether the object is alive (returns <TRUE/> then) or disposed + bool isAlive() const; + /// checks for being alive. If the object is already disposed (i.e. not alive), an exception is thrown. + void ensureAlive() const; + + /** ensures that the object is disposed. + @precond + to be called from within the destructor of your derived class only! + */ + void ensureDisposed( ); + + /** shortcut for retrieving the context of the parent (returned by getAccessibleParent) + */ + css::uno::Reference< css::accessibility::XAccessibleContext > + implGetParentContext(); + + // access to the base class' broadcast helper/mutex + ::osl::Mutex& GetMutex() { return m_aMutex; } + }; + + + //= OContextEntryGuard + + /** helper class for guarding the entry into OAccessibleContextHelper methods. + + <p>The class has two responsibilities: + <ul><li>it locks the mutex of an OAccessibleContextHelper instance, as long as the guard lives</li> + <li>it checks if a given OAccessibleContextHelper instance is alive, else an exception is thrown + our of the constructor of the guard</li> + </ul> + <br/> + This makes it your first choice (hopefully :) for guarding any interface method implementations of + you derived class. + </p> + */ + class OContextEntryGuard : public ::osl::ClearableMutexGuard + { + public: + /** constructs the guard + + <p>The given context (it's mutex, respectively) is locked, and an exception is thrown if the context + is not alive anymore. In the latter case, of course, the mutex is freed, again.</p> + + @param _pContext + the context which shall be guarded + @precond <arg>_pContext</arg> != NULL + */ + inline OContextEntryGuard( OAccessibleContextHelper* _pContext ); + }; + + + inline OContextEntryGuard::OContextEntryGuard( OAccessibleContextHelper* _pContext ) + : ::osl::ClearableMutexGuard( _pContext->GetMutex() ) + { + _pContext->ensureAlive(); + } + + + //= OExternalLockGuard + + class OExternalLockGuard + :public osl::Guard<SolarMutex> + ,public OContextEntryGuard + { + public: + inline OExternalLockGuard( OAccessibleContextHelper* _pContext ); + }; + + + inline OExternalLockGuard::OExternalLockGuard( OAccessibleContextHelper* _pContext ) + :osl::Guard<SolarMutex>( SolarMutex::get() ) + ,OContextEntryGuard( _pContext ) + { + // Only lock the external mutex, + // release the ::osl::Mutex of the OAccessibleContextHelper instance. + // If you call into another UNO object with locked ::osl::Mutex, + // this may lead to dead locks. + clear(); + } + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_ACCESSIBLECONTEXTHELPER_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/accessibleeventnotifier.hxx b/include/comphelper/accessibleeventnotifier.hxx new file mode 100644 index 000000000..75828cda6 --- /dev/null +++ b/include/comphelper/accessibleeventnotifier.hxx @@ -0,0 +1,116 @@ +/* -*- 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_COMPHELPER_ACCESSIBLEEVENTNOTIFIER_HXX +#define INCLUDED_COMPHELPER_ACCESSIBLEEVENTNOTIFIER_HXX + +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::uno { class XInterface; } +namespace com::sun::star::uno { template <class interface_type> class Reference; } +namespace com::sun::star::accessibility { class XAccessibleEventListener; } +namespace com::sun::star::accessibility { struct AccessibleEventObject; } + +namespace comphelper { + +class COMPHELPER_DLLPUBLIC AccessibleEventNotifier +{ +public: + typedef sal_uInt32 TClientId; + +public: + AccessibleEventNotifier() = delete; + ~AccessibleEventNotifier() = delete; + AccessibleEventNotifier( const AccessibleEventNotifier& ) = delete; + AccessibleEventNotifier& operator=( const AccessibleEventNotifier& ) = delete; + + /** registers a client of this class, means a broadcaster of AccessibleEvents + + <p>No precaution is taken to care for disposal of this component. When the component + dies, it <b>must</b> call <member>revokeClient</member> or <member>revokeClientNotifyDisposing</member> + explicitly itself.</p> + */ + static TClientId registerClient(); + + /** revokes a broadcaster of AccessibleEvents + + <p>Note that no disposing event is fired when you use this method, the client is simply revoked. + You can for instance revoke a client if the last listener for it is revoked, but the client + itself is not disposed.<br/> + When the client is disposed, you should prefer <member>revokeClientNotifyDisposing</member></p> + + <p>Any possibly pending events for this client are removed from the queue.</p> + + @seealso revokeClientNotifyDisposing + */ + static void revokeClient( const TClientId _nClient ); + + /** revokes a client, with additionally notifying a disposing event to all listeners registered for + this client + + <p>Any other possibly pending events for this client are removed from the queue</p> + + @param _nClient + the id of the client which should be revoked + @param _rxEventSource + the source to be notified together with the <member scope="com.sun.star.lang">XComponent::disposing</member> + call. + */ + static void revokeClientNotifyDisposing( + const TClientId _nClient, + const css::uno::Reference< css::uno::XInterface >& _rxEventSource ); + + /** registers a listener for the given client + + @param _nClient + the id of the client for which a listener should be registered + @return + the number of event listeners currently registered for this client + */ + static sal_Int32 addEventListener( + const TClientId _nClient, + const css::uno::Reference< css::accessibility::XAccessibleEventListener >& _rxListener ); + + /** revokes a listener for the given client + + @param _nClient + the id of the client for which a listener should be revoked + @return + the number of event listeners currently registered for this client + */ + static sal_Int32 removeEventListener( + const TClientId _nClient, + const css::uno::Reference< css::accessibility::XAccessibleEventListener >& _rxListener ); + + /** adds an event, which is to be broadcasted, to the queue + + @param _nClient + the id of the client which needs to broadcast the event + */ + static void addEvent( + const TClientId _nClient, + const css::accessibility::AccessibleEventObject& _rEvent ); + +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_ACCESSIBLEEVENTNOTIFIER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/accessiblekeybindinghelper.hxx b/include/comphelper/accessiblekeybindinghelper.hxx new file mode 100644 index 000000000..fe6b03521 --- /dev/null +++ b/include/comphelper/accessiblekeybindinghelper.hxx @@ -0,0 +1,70 @@ +/* -*- 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_COMPHELPER_ACCESSIBLEKEYBINDINGHELPER_HXX +#define INCLUDED_COMPHELPER_ACCESSIBLEKEYBINDINGHELPER_HXX + +#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> +#include <comphelper/comphelperdllapi.h> +#include <cppuhelper/implbase.hxx> +#include <mutex> +#include <vector> + +namespace comphelper +{ + + + // OAccessibleKeyBindingHelper + + + typedef ::cppu::WeakImplHelper < css::accessibility::XAccessibleKeyBinding + > OAccessibleKeyBindingHelper_Base; + + /** a helper class for implementing an accessible keybinding + */ + class COMPHELPER_DLLPUBLIC OAccessibleKeyBindingHelper final : public OAccessibleKeyBindingHelper_Base + { + private: + typedef ::std::vector< css::uno::Sequence< css::awt::KeyStroke > > KeyBindings; + KeyBindings m_aKeyBindings; + std::mutex m_aMutex; + + virtual ~OAccessibleKeyBindingHelper() override; + + public: + OAccessibleKeyBindingHelper(); + OAccessibleKeyBindingHelper( const OAccessibleKeyBindingHelper& rHelper ); + + /// @throws css::uno::RuntimeException + void AddKeyBinding( const css::uno::Sequence< css::awt::KeyStroke >& rKeyBinding ); + /// @throws css::uno::RuntimeException + void AddKeyBinding( const css::awt::KeyStroke& rKeyStroke ); + + // XAccessibleKeyBinding + virtual sal_Int32 SAL_CALL getAccessibleKeyBindingCount() override; + virtual css::uno::Sequence< css::awt::KeyStroke > SAL_CALL getAccessibleKeyBinding( sal_Int32 nIndex ) override; + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_ACCESSIBLEKEYBINDINGHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/accessibleselectionhelper.hxx b/include/comphelper/accessibleselectionhelper.hxx new file mode 100644 index 000000000..3a49c1ffd --- /dev/null +++ b/include/comphelper/accessibleselectionhelper.hxx @@ -0,0 +1,135 @@ +/* -*- 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_COMPHELPER_ACCESSIBLESELECTIONHELPER_HXX +#define INCLUDED_COMPHELPER_ACCESSIBLESELECTIONHELPER_HXX + +#include <config_options.h> +#include <comphelper/uno3.hxx> +#include <comphelper/accessiblecomponenthelper.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <comphelper/comphelperdllapi.h> + +#define ACCESSIBLE_SELECTION_CHILD_ALL (sal_Int32(-1)) +#define ACCESSIBLE_SELECTION_CHILD_SELF ((sal_Int32)-2) + + +namespace comphelper +{ + + + //= OCommonAccessibleSelection + + /** base class encapsulating common functionality for the helper classes implementing + the XAccessibleSelection + */ + class COMPHELPER_DLLPUBLIC OCommonAccessibleSelection + { + protected: + + OCommonAccessibleSelection(); + + ~OCommonAccessibleSelection(); + + protected: + + // access to context - still waiting to be overwritten + /// @throws css::uno::RuntimeException + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + implGetAccessibleContext() = 0; + + // return if the specified child is visible => watch for special ChildIndexes (ACCESSIBLE_SELECTION_CHILD_xxx) + /// @throws css::uno::RuntimeException + virtual bool + implIsSelected( sal_Int32 nAccessibleChildIndex ) = 0; + + // select the specified child => watch for special ChildIndexes (ACCESSIBLE_SELECTION_CHILD_xxx) + /// @throws css::uno::RuntimeException + virtual void + implSelect( sal_Int32 nAccessibleChildIndex, bool bSelect ) = 0; + + protected: + + /** non-virtual versions of the methods which can be implemented using <method>implIsSelected</method> and <method>implSelect</method> + + @throws css::lang::IndexOutOfBoundsException + @throws css::uno::RuntimeException + */ + void selectAccessibleChild( sal_Int32 nChildIndex ); + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::uno::RuntimeException + bool isAccessibleChildSelected( sal_Int32 nChildIndex ); + /// @throws css::uno::RuntimeException + void clearAccessibleSelection( ); + /// @throws css::uno::RuntimeException + void selectAllAccessibleChildren( ); + /// @throws css::uno::RuntimeException + sal_Int32 getSelectedAccessibleChildCount( ); + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::uno::RuntimeException + css::uno::Reference< css::accessibility::XAccessible > getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ); + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::uno::RuntimeException + void deselectAccessibleChild( sal_Int32 nSelectedChildIndex ); + }; + + + //= OAccessibleSelectionHelper + + + typedef ::cppu::ImplHelper1< css::accessibility::XAccessibleSelection > OAccessibleSelectionHelper_Base; + + /** a helper class for implementing an AccessibleSelection which at the same time + supports an XAccessibleSelection interface. + */ + class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OAccessibleSelectionHelper : public OAccessibleComponentHelper, + public OCommonAccessibleSelection, + public OAccessibleSelectionHelper_Base + { + protected: + + OAccessibleSelectionHelper(); + + // return ourself here by default + virtual css::uno::Reference< css::accessibility::XAccessibleContext > implGetAccessibleContext() override; + + public: + + // XInterface + DECLARE_XINTERFACE( ) + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleSelection - default implementations + virtual void SAL_CALL selectAccessibleChild( sal_Int32 nChildIndex ) override; + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int32 nChildIndex ) override; + virtual void SAL_CALL clearAccessibleSelection( ) override; + virtual void SAL_CALL selectAllAccessibleChildren( ) override; + virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) override; + virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) override; + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_ACCESSIBLESELECTIONHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/accessibletexthelper.hxx b/include/comphelper/accessibletexthelper.hxx new file mode 100644 index 000000000..607004aee --- /dev/null +++ b/include/comphelper/accessibletexthelper.hxx @@ -0,0 +1,176 @@ +/* -*- 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_COMPHELPER_ACCESSIBLETEXTHELPER_HXX +#define INCLUDED_COMPHELPER_ACCESSIBLETEXTHELPER_HXX + +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include <com/sun/star/accessibility/TextSegment.hpp> +#include <comphelper/accessiblecomponenthelper.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::i18n { class XBreakIterator; } +namespace com::sun::star::i18n { class XCharacterClassification; } +namespace com::sun::star::i18n { struct Boundary; } + +namespace comphelper +{ + + + // OCommonAccessibleText + + /** base class encapsulating common functionality for the helper classes implementing + the XAccessibleText + */ + class COMPHELPER_DLLPUBLIC OCommonAccessibleText + { + private: + css::uno::Reference < css::i18n::XBreakIterator > m_xBreakIter; + css::uno::Reference < css::i18n::XCharacterClassification > m_xCharClass; + + protected: + OCommonAccessibleText(); + virtual ~OCommonAccessibleText(); + + css::uno::Reference < css::i18n::XBreakIterator > const & implGetBreakIterator(); + css::uno::Reference < css::i18n::XCharacterClassification > const & implGetCharacterClassification(); + static bool implIsValidBoundary( css::i18n::Boundary const & rBoundary, sal_Int32 nLength ); + static bool implIsValidIndex( sal_Int32 nIndex, sal_Int32 nLength ); + static bool implIsValidRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex, sal_Int32 nLength ); + static sal_Unicode implGetCharacter( std::u16string_view rText, sal_Int32 nIndex ); + static OUString implGetTextRange( std::u16string_view rText, sal_Int32 nStartIndex, sal_Int32 nEndIndex ); + virtual OUString implGetText() = 0; + virtual css::lang::Locale implGetLocale() = 0; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) = 0; + void implGetGlyphBoundary( const OUString& rText, css::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + bool implGetWordBoundary( const OUString& rText, css::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + void implGetSentenceBoundary( const OUString& rText, css::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + virtual void implGetParagraphBoundary( const OUString& rText, css::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + virtual void implGetLineBoundary( const OUString& rText, css::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + + /** non-virtual versions of the methods + + @throws css::lang::IndexOutOfBoundsException + @throws css::uno::RuntimeException + */ + OUString getSelectedText(); + /// @throws css::uno::RuntimeException + sal_Int32 getSelectionStart(); + /// @throws css::uno::RuntimeException + sal_Int32 getSelectionEnd(); + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::lang::IllegalArgumentException + /// @throws css::uno::RuntimeException + css::accessibility::TextSegment getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ); + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::lang::IllegalArgumentException + /// @throws css::uno::RuntimeException + css::accessibility::TextSegment getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ); + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::lang::IllegalArgumentException + /// @throws css::uno::RuntimeException + css::accessibility::TextSegment getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ); + + public: + + /** Helper method, that detects the difference between + two strings and returns the deleted selection and + the inserted selection if available. + + @returns true if there are differences between the + two strings and false if both are equal + + @see css::accessibility::AccessibleEventId + css::accessibility::TextSegment + */ + static bool implInitTextChangedEvent( + std::u16string_view rOldString, + std::u16string_view rNewString, + /*out*/ css::uno::Any& rDeleted, + /*out*/ css::uno::Any& rInserted); // throw() + }; + + + // OAccessibleTextHelper + + + typedef ::cppu::ImplHelper1 < css::accessibility::XAccessibleText + > OAccessibleTextHelper_Base; + + /** a helper class for implementing an AccessibleExtendedComponent which at the same time + supports an XAccessibleText interface + */ + class COMPHELPER_DLLPUBLIC OAccessibleTextHelper : public OAccessibleExtendedComponentHelper, + public OCommonAccessibleText, + public OAccessibleTextHelper_Base + { + protected: + OAccessibleTextHelper(); + + public: + // XInterface + DECLARE_XINTERFACE( ) + + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleText + virtual OUString SAL_CALL getSelectedText() override; + virtual sal_Int32 SAL_CALL getSelectionStart() override; + virtual sal_Int32 SAL_CALL getSelectionEnd() override; + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + }; + + +} // namespace comphelper + + +// OAccessibleTextHelper is a helper class for implementing the +// XAccessibleText interface. + +// The following methods have a default implementation: + +// getCharacter +// getSelectedText +// getSelectionStart +// getSelectionEnd +// getTextRange +// getTextAtIndex +// getTextBeforeIndex +// getTextBehindIndex + +// The following methods must be overridden by derived classes: + +// implGetText +// implGetLocale +// implGetSelection +// getCaretPosition +// setCaretPosition +// getCharacterAttributes +// getCharacterBounds +// getIndexAtPoint +// setSelection +// copyText + +#endif // INCLUDED_COMPHELPER_ACCESSIBLETEXTHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/accessiblewrapper.hxx b/include/comphelper/accessiblewrapper.hxx new file mode 100644 index 000000000..13fb29bff --- /dev/null +++ b/include/comphelper/accessiblewrapper.hxx @@ -0,0 +1,401 @@ +/* -*- 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_COMPHELPER_ACCESSIBLEWRAPPER_HXX +#define INCLUDED_COMPHELPER_ACCESSIBLEWRAPPER_HXX + +#include <config_options.h> +#include <sal/config.h> + +#include <map> + +#include <comphelper/proxyaggregation.hxx> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/uno3.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <comphelper/accessibleeventnotifier.hxx> +#include <comphelper/comphelperdllapi.h> +#include <rtl/ref.hxx> + +namespace com::sun::star::uno { class XComponentContext; } + +namespace comphelper +{ + + + //= OAccessibleWrapper + + + class OAccessibleContextWrapper; + class OWrappedAccessibleChildrenManager; + + struct OAccessibleWrapper_Base : + public ::cppu::ImplHelper1 < css::accessibility::XAccessible > + { + protected: + ~OAccessibleWrapper_Base() {} + }; + + /** a class which aggregates a proxy for an XAccessible, and wrapping the context returned by this + XAccessible. + */ + class COMPHELPER_DLLPUBLIC OAccessibleWrapper:public OAccessibleWrapper_Base + ,public OComponentProxyAggregation + + { + private: + css::uno::Reference< css::accessibility::XAccessible > + m_xParentAccessible; + css::uno::WeakReference< css::accessibility::XAccessibleContext > + m_aContext; + + protected: + css::uno::Reference< css::accessibility::XAccessible > + m_xInnerAccessible; + + public: + /** ctor + @param _rxContext + a service factory + + @param _rxInnerAccessible + the object to wrap + + @param _rxParentAccessible + The XAccessible which is our parent + */ + OAccessibleWrapper( + const css::uno::Reference< css::uno::XComponentContext >& _rxContext, + const css::uno::Reference< css::accessibility::XAccessible >& _rxInnerAccessible, + const css::uno::Reference< css::accessibility::XAccessible >& _rxParentAccessible + ); + DECLARE_XINTERFACE() + DECLARE_XTYPEPROVIDER() + + // returns the context without creating it + css::uno::Reference< css::accessibility::XAccessibleContext > + getContextNoCreate( ) const; + + protected: + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL + getAccessibleContext( ) override; + + const css::uno::Reference< css::accessibility::XAccessible >& + getParent() const { return m_xParentAccessible; } + + // own overridables + virtual rtl::Reference<OAccessibleContextWrapper> createAccessibleContext( + const css::uno::Reference< css::accessibility::XAccessibleContext >& _rxInnerContext + ); + + protected: + virtual ~OAccessibleWrapper( ) override; + + private: + OAccessibleWrapper( const OAccessibleWrapper& ) = delete; + OAccessibleWrapper& operator=( const OAccessibleWrapper& ) = delete; + }; + + + //= OAccessibleContextWrapperHelper + + + typedef ::cppu::ImplHelper1 < css::accessibility::XAccessibleEventListener + > OAccessibleContextWrapperHelper_Base; + + /** Helper for wrapping an XAccessibleContext by aggregating a proxy for it. + + <p>This class does not have own ref counting. In addition, it does not implement + the XAccessibleContext interface, but provides all the methods from this interface + which must be implemented using the inner context (such as getAccessibleChild*).</p> + + <p>Children of the aggregated XAccessibleContext are wrapped, too.</p> + + <p>AccessibleEvents fired by the inner context are multiplexed, especially, any references to + children in such events are translated. This means that even in such events, no un-wrapped object + will ever leave this class - if the aggregated context notifies a child event, the child passed + to the event is wrapped</p> + + @seealso OAccessibleContextWrapper + */ + class COMPHELPER_DLLPUBLIC OAccessibleContextWrapperHelper + :private OComponentProxyAggregationHelper + ,public OAccessibleContextWrapperHelper_Base + { + protected: + /// the context we're wrapping (properly typed, in opposite to OComponentProxyAggregationHelper::m_xInner) + css::uno::Reference< css::accessibility::XAccessibleContext > + m_xInnerContext; + /// the XAccessible which created this context + css::uno::Reference< css::accessibility::XAccessible > + m_xOwningAccessible; + /// the XAccessible which is to be returned in getAccessibleParent + css::uno::Reference< css::accessibility::XAccessible > + m_xParentAccessible; + + rtl::Reference<OWrappedAccessibleChildrenManager> m_xChildMapper; // for mapping children from our inner context to our callers + + protected: + /** ctor + + @param _rxContext + a service factory + + @param _rxInnerAccessibleContext + the object to wrap + + @param _rxOwningAccessible + The XAccessible which created this object. This is necessary because children + of our wrapped context need to be wrapped, too, and if they're asked for a parent, + they of course should return the proper parent<br/> + The object will be held with a hard reference + + @param _rxParentAccessible + The XAccessible to return in the getAccessibleParent call + */ + OAccessibleContextWrapperHelper( + const css::uno::Reference< css::uno::XComponentContext >& _rxContext, + ::cppu::OBroadcastHelper& _rBHelper, + const css::uno::Reference< css::accessibility::XAccessibleContext >& _rxInnerAccessibleContext, + const css::uno::Reference< css::accessibility::XAccessible >& _rxOwningAccessible, + const css::uno::Reference< css::accessibility::XAccessible >& _rxParentAccessible + ); + + /// to be called from within your ctor - does the aggregation of a proxy for m_xInnerContext + void aggregateProxy( + oslInterlockedCount& _rRefCount, + ::cppu::OWeakObject& _rDelegator + ); + + protected: + // XInterface + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& _rType ) override; + + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleContext + /// @throws css::uno::RuntimeException + sal_Int32 baseGetAccessibleChildCount( ); + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::uno::RuntimeException + css::uno::Reference< css::accessibility::XAccessible > baseGetAccessibleChild( sal_Int32 i ); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::accessibility::XAccessibleRelationSet > baseGetAccessibleRelationSet( ); + + // XAccessibleEventListener + virtual void SAL_CALL notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) override; + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // XComponent/OComponentProxyAggregationHelper + virtual void SAL_CALL dispose() override; + + // own overridables + /** notify an accessible event which has been translated (if necessary) + + <p>Usually, you derive your class from both OAccessibleContextWrapperHelper and XAccessibleEventBroadcaster, + and simply call all your XAccessibleEventListener with the given event.</p> + + <p>The mutex of the BroadcastHelper passed to the instance's ctor is <em>not</em> locked when calling + into this method</p> + + @throws css::uno::RuntimeException + */ + virtual void notifyTranslatedEvent( const css::accessibility::AccessibleEventObject& _rEvent ) = 0; + + protected: + virtual ~OAccessibleContextWrapperHelper( ) override; + + OAccessibleContextWrapperHelper(const OAccessibleContextWrapperHelper&) = delete; + OAccessibleContextWrapperHelper& operator=(const OAccessibleContextWrapperHelper&) = delete; + }; + + + //= OAccessibleContextWrapper + + typedef ::cppu::WeakComponentImplHelper< css::accessibility::XAccessibleEventBroadcaster + , css::accessibility::XAccessibleContext + > OAccessibleContextWrapper_CBase; + + class COMPHELPER_DLLPUBLIC OAccessibleContextWrapper + :public cppu::BaseMutex + ,public OAccessibleContextWrapper_CBase + ,public OAccessibleContextWrapperHelper + { + private: + ::comphelper::AccessibleEventNotifier::TClientId m_nNotifierClient; // for notifying AccessibleEvents + + public: + /** ctor + + @param _rxContext + a service factory + + @param _rxInnerAccessibleContext + the object to wrap + + @param _rxOwningAccessible + The XAccessible which created this object. This is necessary because children + of our wrapped context need to be wrapped, too, and if they're asked for a parent, + they of course should return the proper parent<br/> + The object will be held with a hard reference + + @param _rxParentAccessible + The XAccessible to return in the getAccessibleParent call + */ + OAccessibleContextWrapper( + const css::uno::Reference< css::uno::XComponentContext >& _rxContext, + const css::uno::Reference< css::accessibility::XAccessibleContext >& _rxInnerAccessibleContext, + const css::uno::Reference< css::accessibility::XAccessible >& _rxOwningAccessible, + const css::uno::Reference< css::accessibility::XAccessible >& _rxParentAccessible + ); + + // XInterface + DECLARE_XINTERFACE( ) + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleContext + virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleEventBroadcaster + virtual void SAL_CALL addAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + virtual void SAL_CALL removeAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + + // OAccessibleContextWrapper + virtual void notifyTranslatedEvent( const css::accessibility::AccessibleEventObject& _rEvent ) override; + + // OComponentHelper + using OAccessibleContextWrapperHelper::disposing; + virtual void SAL_CALL disposing() override; + + protected: + virtual ~OAccessibleContextWrapper() override; + + private: + OAccessibleContextWrapper( const OAccessibleContextWrapper& ) = delete; + OAccessibleContextWrapper& operator=( const OAccessibleContextWrapper& ) = delete; + }; + + + //= OWrappedAccessibleChildrenManager + + + typedef ::std::map < css::uno::Reference< css::accessibility::XAccessible > + , rtl::Reference< comphelper::OAccessibleWrapper > + > AccessibleMap; + // TODO: think about if we should hold these objects weak + + typedef ::cppu::WeakImplHelper< css::lang::XEventListener + > OWrappedAccessibleChildrenManager_Base; + /** manages wrapping XAccessible's to XAccessible's + */ + class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OWrappedAccessibleChildrenManager final : public OWrappedAccessibleChildrenManager_Base + { + css::uno::Reference< css::uno::XComponentContext > + m_xContext; + css::uno::WeakReference< css::accessibility::XAccessible > + m_aOwningAccessible; // the XAccessible which belongs to the XAccessibleContext which we work for + AccessibleMap m_aChildrenMap; // for caching children + bool m_bTransientChildren; // are we prohibited to cache our children? + + public: + /// ctor + OWrappedAccessibleChildrenManager( + const css::uno::Reference< css::uno::XComponentContext >& _rxContext + ); + + /** specifies if the children are to be considered transient (i.e.: not cached) + <p>to be called only once per lifetime</p> + */ + void setTransientChildren( bool _bSet ); + + /** sets the XAccessible which belongs to the XAccessibleContext which we work for + <p>to be called only once per lifetime</p> + */ + void setOwningAccessible( const css::uno::Reference< css::accessibility::XAccessible >& _rxAcc ); + + /// retrieves a wrapper for the given accessible + css::uno::Reference< css::accessibility::XAccessible > + getAccessibleWrapperFor( + const css::uno::Reference< css::accessibility::XAccessible >& _rxKey + ); + + /// erases the given key from the map (if it is present there) + void removeFromCache( const css::uno::Reference< css::accessibility::XAccessible >& _rxKey ); + + /// invalidates (i.e. empties) the map + void invalidateAll( ); + + /** disposes (i.e. clears) the manager + + <p>Note that the XAccessibleContext's of the mapped XAccessible objects are disposed, too.</p> + */ + void dispose(); + + /** handles a notification as got from the parent of the children we're managing + <p>This applies only to the notifications which have a direct impact on our map.</p> + */ + void handleChildNotification( const css::accessibility::AccessibleEventObject& _rEvent ); + + /** translates events as got from the parent of the children we're managing + <p>This applies only to the notifications which deal with child objects which we manage.</p> + */ + void translateAccessibleEvent( + const css::accessibility::AccessibleEventObject& _rEvent, + css::accessibility::AccessibleEventObject& _rTranslatedEvent + ); + + private: + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + void implTranslateChildEventValue( const css::uno::Any& _rInValue, css::uno::Any& _rOutValue ); + + virtual ~OWrappedAccessibleChildrenManager( ) override; + + OWrappedAccessibleChildrenManager( const OWrappedAccessibleChildrenManager& ) = delete; + OWrappedAccessibleChildrenManager& operator=( const OWrappedAccessibleChildrenManager& ) = delete; + }; + + +} // namespace accessibility + + +#endif // INCLUDED_COMPHELPER_ACCESSIBLEWRAPPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/accimplaccess.hxx b/include/comphelper/accimplaccess.hxx new file mode 100644 index 000000000..e716d4d18 --- /dev/null +++ b/include/comphelper/accimplaccess.hxx @@ -0,0 +1,73 @@ +/* -*- 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_COMPHELPER_ACCIMPLACCESS_HXX +#define INCLUDED_COMPHELPER_ACCIMPLACCESS_HXX + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <comphelper/comphelperdllapi.h> + +namespace comphelper +{ + //= OAccessibleImplementationAccess + + typedef ::cppu::ImplHelper1 < css::lang::XUnoTunnel + > OAccImpl_Base; + + /** This is a helper class which allows accessing several aspects of the implementation + of an AccessibleContext. + + <p>For instance, when you want to implement a context which can be re-parented, you: + <ul><li>derive your class from OAccessibleImplementationAccess</li> + <li>use <code>setAccessibleParent( <em>component</em>, <em>new_parent</em> )</code> + </ul> + </p> + + <p>Another aspect which can be controlled from the outside are states. If you have a class which + has only partial control over it's states, you may consider deriving from OAccessibleImplementationAccess.<br/> + For instance, say you have an implementation (say component A) which is <em>unable</em> to know or to + determine if the represented object is selected, but another component (say B) which uses A (and integrates + it into a tree of accessibility components) is.<br/> + In this case, if A is derived from OAccessibleImplementationAccess, B can manipulate this + foreign-controlled state flag "SELECTED" by using the static helper methods on this class.</p> + + <p>Please note that the support for foreign controlled states is rather restrictive: You can't have states + which <em>may be</em> controlled by a foreign instances. This is implied by the fact that a derived + class can ask for states which are <em>set</em> only, not for the ones which are <em>reset</em> currently. + </p> + */ + class COMPHELPER_DLLPUBLIC OAccessibleImplementationAccess : public OAccImpl_Base + { + protected: + OAccessibleImplementationAccess( ); + virtual ~OAccessibleImplementationAccess( ); + + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& _rIdentifier ) override; + + public: + COMPHELPER_DLLPRIVATE static const css::uno::Sequence<sal_Int8> & getUnoTunnelId(); + }; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_ACCIMPLACCESS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/anycompare.hxx b/include/comphelper/anycompare.hxx new file mode 100644 index 000000000..3618106db --- /dev/null +++ b/include/comphelper/anycompare.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_COMPHELPER_ANYCOMPARE_HXX +#define INCLUDED_COMPHELPER_ANYCOMPARE_HXX + +#include <comphelper/comphelperdllapi.h> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/i18n/XCollator.hpp> + +#include <comphelper/extract.hxx> + +#include <memory> +#include <utility> + + +namespace comphelper +{ + + + //= IKeyPredicateLess + + class SAL_NO_VTABLE IKeyPredicateLess + { + public: + virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const = 0; + virtual ~IKeyPredicateLess() {} + }; + + + //= LessPredicateAdapter + + struct LessPredicateAdapter + { + LessPredicateAdapter( const IKeyPredicateLess& _predicate ) + :m_predicate( _predicate ) + { + } + + bool operator()( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const + { + return m_predicate.isLess( _lhs, _rhs ); + } + + private: + IKeyPredicateLess const & m_predicate; + }; + + + //= ScalarPredicateLess + + template< typename SCALAR > + class ScalarPredicateLess final : public IKeyPredicateLess + { + public: + virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const override + { + SCALAR lhs(0), rhs(0); + if ( !( _lhs >>= lhs ) + || !( _rhs >>= rhs ) + ) + throw css::lang::IllegalArgumentException(); + return lhs < rhs; + } + }; + + + //= StringPredicateLess + + class StringPredicateLess final : public IKeyPredicateLess + { + public: + virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const override + { + OUString lhs, rhs; + if ( !( _lhs >>= lhs ) + || !( _rhs >>= rhs ) + ) + throw css::lang::IllegalArgumentException(); + return lhs < rhs; + } + }; + + + //= StringCollationPredicateLess + + class StringCollationPredicateLess final : public IKeyPredicateLess + { + public: + StringCollationPredicateLess( css::uno::Reference< css::i18n::XCollator > i_collator ) + :m_collator(std::move( i_collator )) + { + } + + virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const override + { + OUString lhs, rhs; + if ( !( _lhs >>= lhs ) + || !( _rhs >>= rhs ) + ) + throw css::lang::IllegalArgumentException(); + return m_collator->compareString( lhs, rhs ) < 0; + } + + private: + css::uno::Reference< css::i18n::XCollator > const m_collator; + }; + + + //= TypePredicateLess + + class TypePredicateLess final : public IKeyPredicateLess + { + public: + virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const override + { + css::uno::Type lhs, rhs; + if ( !( _lhs >>= lhs ) + || !( _rhs >>= rhs ) + ) + throw css::lang::IllegalArgumentException(); + return lhs.getTypeName() < rhs.getTypeName(); + } + }; + + + //= EnumPredicateLess + + class EnumPredicateLess final : public IKeyPredicateLess + { + public: + EnumPredicateLess( css::uno::Type const & _enumType ) + :m_enumType( _enumType ) + { + } + + virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const override + { + sal_Int32 lhs(0), rhs(0); + if ( !::cppu::enum2int( lhs, _lhs ) + || !::cppu::enum2int( rhs, _rhs ) + || !_lhs.getValueType().equals( m_enumType ) + || !_rhs.getValueType().equals( m_enumType ) + ) + throw css::lang::IllegalArgumentException(); + return lhs < rhs; + } + + private: + css::uno::Type const m_enumType; + }; + + + //= InterfacePredicateLess + + class InterfacePredicateLess final : public IKeyPredicateLess + { + public: + virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const override + { + if ( ( _lhs.getValueTypeClass() != css::uno::TypeClass_INTERFACE ) + || ( _rhs.getValueTypeClass() != css::uno::TypeClass_INTERFACE ) + ) + throw css::lang::IllegalArgumentException(); + + css::uno::Reference< css::uno::XInterface > lhs( _lhs, css::uno::UNO_QUERY ); + css::uno::Reference< css::uno::XInterface > rhs( _rhs, css::uno::UNO_QUERY ); + return lhs.get() < rhs.get(); + } + }; + + + //= getStandardLessPredicate + + /** creates a default IKeyPredicateLess instance for the given UNO type + @param i_type + the type for which a predicate instance should be created + @param i_collator + specifies a collator instance to use, or <NULL/>. If <NULL/>, strings will be compared using the <code><</code> + operator, otherwise the collator will be used. The parameter is ignored if <arg>i_type</arg> does not specify + the string type. + @return + a default implementation of IKeyPredicateLess, which is able to compare values of the given type. If no + such default implementation is known for the given type, then <NULL/> is returned. + */ + ::std::unique_ptr< IKeyPredicateLess > COMPHELPER_DLLPUBLIC + getStandardLessPredicate( + css::uno::Type const & i_type, + css::uno::Reference< css::i18n::XCollator > const & i_collator + ); + + /** + Compare two Anys. + */ + bool COMPHELPER_DLLPUBLIC anyLess( css::uno::Any const & lhs, css::uno::Any const & rhs); + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_ANYCOMPARE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/anytohash.hxx b/include/comphelper/anytohash.hxx new file mode 100644 index 000000000..0aa14f47e --- /dev/null +++ b/include/comphelper/anytohash.hxx @@ -0,0 +1,48 @@ +/* -*- 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_COMPHELPER_ANYTOHASH_HXX +#define INCLUDED_COMPHELPER_ANYTOHASH_HXX + +#include <comphelper/comphelperdllapi.h> + +#include <optional> + +namespace com::sun::star::uno +{ +class Any; +} + +namespace comphelper +{ +/** Tries to get a hash value for an ANY value. + + Not all cases may be implemented, in which case no value is returned. + + @param value + ANY value + @return + hash of given ANY value, or not available +*/ +COMPHELPER_DLLPUBLIC std::optional<size_t> anyToHash(css::uno::Any const& value); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/anytostring.hxx b/include/comphelper/anytostring.hxx new file mode 100644 index 000000000..6d100221e --- /dev/null +++ b/include/comphelper/anytostring.hxx @@ -0,0 +1,45 @@ +/* -*- 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_COMPHELPER_ANYTOSTRING_HXX +#define INCLUDED_COMPHELPER_ANYTOSTRING_HXX + +#include <rtl/ustring.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::uno +{ +class Any; +} + +namespace comphelper +{ +/** Creates a STRING representation out of an ANY value. + + @param value + ANY value + @return + STRING representation of given ANY value +*/ +COMPHELPER_DLLPUBLIC OUString anyToString(css::uno::Any const& value); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/asyncnotification.hxx b/include/comphelper/asyncnotification.hxx new file mode 100644 index 000000000..ea6b067cc --- /dev/null +++ b/include/comphelper/asyncnotification.hxx @@ -0,0 +1,226 @@ +/* -*- 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_COMPHELPER_ASYNCNOTIFICATION_HXX +#define INCLUDED_COMPHELPER_ASYNCNOTIFICATION_HXX + +#include <sal/config.h> + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ref.hxx> +#include <sal/types.h> +#include <salhelper/thread.hxx> +#include <salhelper/simplereferenceobject.hxx> +#include <memory> +#include <utility> + +namespace comphelper +{ + //= AnyEvent + + /** the very basic instance to hold a description of an event + */ + class COMPHELPER_DLLPUBLIC AnyEvent : public salhelper::SimpleReferenceObject + { + public: + AnyEvent(); + + protected: + virtual ~AnyEvent() override; + + private: + AnyEvent( AnyEvent const & ) = delete; + AnyEvent& operator=( AnyEvent const & ) = delete; + }; + + + //= typedefs + + typedef ::rtl::Reference< AnyEvent > AnyEventRef; + + + //= IEventProcessor + + /** an event processor + + @see AsyncEventNotifier + */ + class SAL_NO_VTABLE IEventProcessor + { + public: + /** process a single event + */ + virtual void processEvent( const AnyEvent& _rEvent ) = 0; + + virtual void SAL_CALL acquire() noexcept = 0; + virtual void SAL_CALL release() noexcept = 0; + + protected: + ~IEventProcessor() {} + }; + + + //= AsyncEventNotifier + + struct EventNotifierImpl; + + /** a helper class for notifying events asynchronously + + If you need to notify certain events to external components, you usually should + not do this while you have mutexes locked, to prevent multi-threading issues. + + However, you do not always have complete control over all mutex guards on the stack. + If, in such a case, the listener notification is one-way, you can decide to do it + asynchronously. + + The ->AsyncEventNotifier helps you to process such events asynchronously. Every + event is tied to an ->IEventProcessor which is responsible for processing it. + + The AsyncEventNotifier is implemented as a thread itself, which sleeps as long as there are no + events in the queue. As soon as you add an event, the thread is woken up, processes the event, + and sleeps again. + */ + class COMPHELPER_DLLPUBLIC AsyncEventNotifierBase + { + friend struct EventNotifierImpl; + + protected: + std::unique_ptr<EventNotifierImpl> m_xImpl; + + SAL_DLLPRIVATE virtual ~AsyncEventNotifierBase(); + + // Thread + SAL_DLLPRIVATE virtual void execute(); + + public: + AsyncEventNotifierBase(); + + /** terminates the thread + + Note that this is a cooperative termination - if you call this from a thread different + from the notification thread itself, then it will block until the notification thread + finished processing the current event. If you call it from the notification thread + itself, it will return immediately, and the thread will be terminated as soon as + the current notification is finished. + */ + virtual void SAL_CALL terminate(); + + /** adds an event to the queue, together with the instance which is responsible for + processing it + + @param _rEvent + the event to add to the queue + @param _xProcessor + the processor for the event.<br/> + Beware of life time issues here. If your event processor dies or becomes otherwise + nonfunctional, you are responsible for removing all respective events from the queue. + You can do this by calling ->removeEventsForProcessor + */ + void addEvent( const AnyEventRef& _rEvent, const ::rtl::Reference< IEventProcessor >& _xProcessor ); + + /** removes all events for the given event processor from the queue + */ + void removeEventsForProcessor( const ::rtl::Reference< IEventProcessor >& _xProcessor ); + }; + + /** This class is usable with rtl::Reference. + As always, the thread must be joined somewhere. + */ + class COMPHELPER_DLLPUBLIC AsyncEventNotifier final + : public AsyncEventNotifierBase + , public salhelper::Thread + { + + private: + SAL_DLLPRIVATE virtual ~AsyncEventNotifier() override; + + SAL_DLLPRIVATE virtual void execute() override; + + public: + /** constructs a notifier thread + + @param name the thread name, see ::osl_setThreadName; must not be + null + */ + AsyncEventNotifier(char const* name); + + virtual void SAL_CALL terminate() override; + }; + + /** This is a hack (when proper joining is not possible), use of which + should be avoided by good design. + */ + class COMPHELPER_DLLPUBLIC AsyncEventNotifierAutoJoin final + : public AsyncEventNotifierBase + , private osl::Thread + { + + private: + SAL_DLLPRIVATE AsyncEventNotifierAutoJoin(char const* name); + + SAL_DLLPRIVATE virtual void SAL_CALL run() override; + SAL_DLLPRIVATE virtual void SAL_CALL onTerminated() override; + + public: + // only public so shared_ptr finds it + SAL_DLLPRIVATE virtual ~AsyncEventNotifierAutoJoin() override; + + static std::shared_ptr<AsyncEventNotifierAutoJoin> + newAsyncEventNotifierAutoJoin(char const* name); + + virtual void SAL_CALL terminate() override; + + using osl::Thread::join; + using osl::Thread::operator new; + using osl::Thread::operator delete; // clang really wants this? + + static void launch(std::shared_ptr<AsyncEventNotifierAutoJoin> const&); + }; + + + //= EventHolder + + /** AnyEvent derivee holding a foreign event instance + */ + template < typename EVENT_OBJECT > + class SAL_DLLPUBLIC_RTTI EventHolder final : public AnyEvent + { + public: + typedef EVENT_OBJECT EventObjectType; + + private: + EventObjectType const m_aEvent; + + public: + EventHolder( EventObjectType _aEvent ) + :m_aEvent(std::move( _aEvent )) + { + } + + const EventObjectType& getEventObject() const { return m_aEvent; } + }; + + COMPHELPER_DLLPUBLIC void JoinAsyncEventNotifiers(); + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_ASYNCNOTIFICATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/asyncquithandler.hxx b/include/comphelper/asyncquithandler.hxx new file mode 100644 index 000000000..ce3db23a1 --- /dev/null +++ b/include/comphelper/asyncquithandler.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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_COMPHELPER_ASYNCQUITHANDLER_HXX +#define INCLUDED_COMPHELPER_ASYNCQUITHANDLER_HXX + +#include <comphelper/comphelperdllapi.h> +#include <tools/link.hxx> + +// Use: Application::PostUserEvent( LINK( &AsyncQuitHandler::instance(), AsyncQuitHandler, OnAsyncQuit ) ); + +class COMPHELPER_DLLPUBLIC AsyncQuitHandler +{ + AsyncQuitHandler(); + +public: + AsyncQuitHandler(const AsyncQuitHandler&) = delete; + const AsyncQuitHandler& operator=(const AsyncQuitHandler&) = delete; + + static AsyncQuitHandler& instance(); + static void QuitApplication(); + + DECL_STATIC_LINK(AsyncQuitHandler, OnAsyncQuit, void*, void); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/attributelist.hxx b/include/comphelper/attributelist.hxx new file mode 100644 index 000000000..0309ab608 --- /dev/null +++ b/include/comphelper/attributelist.hxx @@ -0,0 +1,92 @@ +/* -*- 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_COMPHELPER_ATTRIBUTELIST_HXX +#define INCLUDED_COMPHELPER_ATTRIBUTELIST_HXX + +#include <sal/config.h> + +#include <memory> +#include <vector> + +#include <com/sun/star/util/XCloneable.hpp> +#include <com/sun/star/xml/sax/XAttributeList.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace comphelper +{ + +struct TagAttribute +{ + OUString sName; + OUString sType; + OUString sValue; +}; + +class COMPHELPER_DLLPUBLIC AttributeList final : + public ::cppu::WeakImplHelper<css::xml::sax::XAttributeList, css::util::XCloneable> +{ + std::vector<TagAttribute> mAttributes; +public: + AttributeList(); + AttributeList(const AttributeList &r); + + virtual ~AttributeList() override; + + // methods that are not contained in any interface + void AddAttribute(const OUString &sName , const OUString &sType , const OUString &sValue) + { + mAttributes.push_back({sName, sType, sValue}); + } + void Clear() + { + mAttributes.clear(); + } + + // css::xml::sax::XAttributeList + virtual sal_Int16 SAL_CALL getLength() override + { + return static_cast<sal_Int16>(mAttributes.size()); + } + virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) override + { + return mAttributes[i].sName; + } + virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) override + { + return mAttributes[i].sType; + } + virtual OUString SAL_CALL getTypeByName(const OUString& aName) override; + virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) override + { + return mAttributes[i].sValue; + } + virtual OUString SAL_CALL getValueByName(const OUString& aName) override; + + // css::util::XCloneable + virtual css::uno::Reference< XCloneable > SAL_CALL + createClone() override; +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_ATTRIBUTELIST_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/automationinvokedzone.hxx b/include/comphelper/automationinvokedzone.hxx new file mode 100644 index 000000000..81b0bfab6 --- /dev/null +++ b/include/comphelper/automationinvokedzone.hxx @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#ifndef INCLUDED_COMPHELPER_AUTOMATIONINVOKEDZONE_HXX +#define INCLUDED_COMPHELPER_AUTOMATIONINVOKEDZONE_HXX + +#include <comphelper/comphelperdllapi.h> + +// Helpers for use when calling into LO from an Automation (OLE +// Automation) client. + +namespace comphelper::Automation +{ +// Create an object of this class at the start of a function directly invoked from an Automation +// client. + +class COMPHELPER_DLLPUBLIC AutomationInvokedZone +{ +public: + AutomationInvokedZone(); + + ~AutomationInvokedZone(); + + static bool isActive(); +}; +} + +#endif // INCLUDED_COMPHELPER_AUTOMATIONINVOKEDZONE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/backupfilehelper.hxx b/include/comphelper/backupfilehelper.hxx new file mode 100644 index 000000000..abf8044a2 --- /dev/null +++ b/include/comphelper/backupfilehelper.hxx @@ -0,0 +1,216 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_BACKUPFILEHELPER_HXX +#define INCLUDED_COMPHELPER_BACKUPFILEHELPER_HXX + +#include <sal/config.h> + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> +#include <set> +#include <string_view> +#include <vector> + +namespace comphelper +{ + /** Helper class to backup/restore a single file + * + * This is a general class to manage backups/restore of the file + * given by the URL. The container holding the backups is created + * aside the original file, e.g for 'test.txt' a container + * called '.test.pack' will be used. If it was not yet backed-up + * this container file will be created at the 1st backup and deleted + * when the last gets removed. The container holds a stack with a + * maximum given number (in the constructor) of copies, these are by + * default compressed, but don't have to be (see tryPush). + * + * Due to being on a low system level here, no UNO API and not much + * other tooling can be used, as a consequence for the container a + * own simple format is used and e.g. the zip lib directly. + * + * You need to hand over the URL of the file to look at and + * a maximum number of allowed copies. That number is internally + * limited to an absolute max of 10 (see implementation). The number + * of allowed copies is limited to [1..max]. + * + * Calling tryPush() will check if there is no backup yet or if + * there is one that the file has changed. If yes, a new copy is + * created on a kind of 'stack' of copies. The return value can + * be used to see if a backup was indeed created. + * + * Calling tryPop() will do the opposite: if a backup is available, + * delete the orig file and re-instantiate the backup. The backup + * is taken off the 'stack' of copies. The return value can be + * used to check if this was done. + * + * isPopPossible can be called to see if there is a backup available + * before calling tryPop(). + * + * The 'stack' of copies works by using the same path, filename + * and extension, but adding a '_1' -> '_(num_of_copy)' to it. + */ + class COMPHELPER_DLLPUBLIC BackupFileHelper + { + private: + // internal data + std::set< OUString > maDirs; + std::set< std::pair< OUString, OUString > > maFiles; + + sal_uInt16 mnNumBackups; + sal_uInt16 mnMode; + + bool mbActive; + bool mbExtensions; + bool mbCompress; + + // internal flag if _exit() was called already - a hint to evtl. + // not create copies of potentially not well-defined data. This + // may be used in destructors of static instances - which unfortunately + // get called on WNT but not on linux. Thus I thought about encapsulating + // in some '#ifdefs', but it's just more safe to always do it and + // allows to add a SAL_WARN when one of these destructors is called + // after _exit() + static bool mbExitWasCalled; + + // internal detector if SafeModeName dir exists + static bool mbSafeModeDirExists; + + // internal upper limit (max) of allowed backups + static sal_uInt16 mnMaxAllowedBackups; + + // path to User's configuration directory and derived strings + static OUString maInitialBaseURL; + static OUString maUserConfigBaseURL; + static OUString maUserConfigWorkURL; + static OUString maRegModName; + static OUString maExt; + + // get path to User's configuration directory (created on-demand) + static const OUString& getInitialBaseURL(); + + // the name of the SafeMode directory for temporary processing + static const OUString& getSafeModeName(); + + public: + /** Constructor to handle Backups of the given file, will internally + * detect configuration values and URL to initial registrymodifications + * and thus the User configuration directory + */ + BackupFileHelper(); + + // allow to set static global flag when app had to call _exit() + static void setExitWasCalled(); + static bool getExitWasCalled(); + + // This call initializes the state of the UserDirectory as needed, it may + // initialize to SafeMode configuration or return from it by moving files + // in that directory + static void reactOnSafeMode(bool bSafeMode); + + /** tries to create a new backup, if there is none yet, or if the + * last differs from the base file. It will then put a new version + * on the 'stack' of copies and evtl. delete the oldest backup. + * Also may cleanup older backups when NumBackups given in the + * constructor has changed. + * + * tryPushExtensionInfo is the specialized version for ExtensionInfo + */ + void tryPush(); + void tryPushExtensionInfo(); + + /** finds out if a restore is possible + * + * @return bool + * returns true if a restore to an older backup is possible + * + * isPopPossibleExtensionInfo is the specialized version for ExtensionInfo + */ + bool isPopPossible(); + bool isPopPossibleExtensionInfo() const; + + /** tries to execute a restore. Will overwrite the base file + * in that case and take one version off the 'stack' of copies. + * Also may cleanup older backups when NumBackups given in the + * constructor has changed. + * + * tryPopExtensionInfo is the specialized version for ExtensionInfo + */ + void tryPop(); + void tryPopExtensionInfo(); + + /** tries to iterate the extensions and to disable all of them + */ + static bool isTryDisableAllExtensionsPossible(); + static void tryDisableAllExtensions(); + + /** Deinstall all User Extensions (installed for User only) + */ + static bool isTryDeinstallUserExtensionsPossible(); + static void tryDeinstallUserExtensions(); + + /** Reset shared Extensions + */ + static bool isTryResetSharedExtensionsPossible(); + static void tryResetSharedExtensions(); + + /** Reset bundled Extensions + */ + static bool isTryResetBundledExtensionsPossible(); + static void tryResetBundledExtensions(); + + /// Disables OpenGL and OpenCL + static void tryDisableHWAcceleration(); + + /** resets User-Customizations like Settings and UserInterface modifications + */ + static bool isTryResetCustomizationsPossible(); + static void tryResetCustomizations(); + + /** resets the whole UserProfile + */ + static void tryResetUserProfile(); + + /** Return the profile url */ + static const OUString& getUserProfileURL(); + + /** Return the url of the backed up profile (when in safe mode) */ + static const OUString& getUserProfileWorkURL(); + + private: + // internal helper methods + static OUString getPackURL(); + static const std::vector< OUString >& getCustomizationDirNames(); + static const std::vector< OUString >& getCustomizationFileNames(); + + // file push helpers + bool tryPush_Files(const std::set< OUString >& rDirs, const std::set< std::pair< OUString, OUString > >& rFiles, std::u16string_view rSourceURL, const OUString& rTargetURL); + bool tryPush_file(std::u16string_view rSourceURL, std::u16string_view rTargetURL, std::u16string_view rName, std::u16string_view rExt); + + // file pop possibilities helper + bool isPopPossible_files(const std::set< OUString >& rDirs, const std::set< std::pair< OUString, OUString > >& rFiles, std::u16string_view rSourceURL, std::u16string_view rTargetURL); + static bool isPopPossible_file(std::u16string_view rSourceURL, std::u16string_view rTargetURL, std::u16string_view rName, std::u16string_view rExt); + + // file pop helpers + bool tryPop_files(const std::set< OUString >& rDirs, const std::set< std::pair< OUString, OUString > >& rFiles, std::u16string_view rSourceURL, const OUString& rTargetURL); + bool tryPop_file(std::u16string_view rSourceURL, std::u16string_view rTargetURL, std::u16string_view rName, std::u16string_view rExt); + + // ExtensionInfo helpers + bool tryPush_extensionInfo(std::u16string_view rTargetURL); + static bool isPopPossible_extensionInfo(std::u16string_view rTargetURL); + bool tryPop_extensionInfo(std::u16string_view rTargetURL); + + // FileDirInfo helpers + void fillDirFileInfo(); + }; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/base64.hxx b/include/comphelper/base64.hxx new file mode 100644 index 000000000..78a0bacb5 --- /dev/null +++ b/include/comphelper/base64.hxx @@ -0,0 +1,62 @@ +/* -*- 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_COMPHELPER_BASE64_HXX +#define INCLUDED_COMPHELPER_BASE64_HXX + +#include <sal/config.h> + +#include <cstddef> + +#include <comphelper/comphelperdllapi.h> + +#include <sal/types.h> +#include <rtl/ustrbuf.hxx> +#include <rtl/strbuf.hxx> + +namespace com::sun::star::uno +{ +template <class E> class Sequence; +} + +namespace comphelper +{ +class COMPHELPER_DLLPUBLIC Base64 +{ +public: + /** encodes the given byte sequence into Base64 */ + static void encode(OUStringBuffer& aStrBuffer, const css::uno::Sequence<sal_Int8>& aPass); + + static void encode(OStringBuffer& aStrBuffer, const css::uno::Sequence<sal_Int8>& aPass); + + // Decode a base 64 encoded string into a sequence of bytes. The first + // version can be used for attribute values only, because it does not + // return any chars left from conversion. + // For text submitted through the SAX characters call, the later method + // must be used! + static void decode(css::uno::Sequence<sal_Int8>& aPass, std::u16string_view sBuffer); + + static std::size_t decodeSomeChars(css::uno::Sequence<sal_Int8>& aPass, + std::u16string_view sBuffer); +}; +} + +#endif // INCLUDED_COMPHELPER_BASE64_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/basicio.hxx b/include/comphelper/basicio.hxx new file mode 100644 index 000000000..62260e3da --- /dev/null +++ b/include/comphelper/basicio.hxx @@ -0,0 +1,88 @@ +/* -*- 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_COMPHELPER_BASICIO_HXX +#define INCLUDED_COMPHELPER_BASICIO_HXX + +#include <com/sun/star/io/XObjectOutputStream.hpp> +#include <com/sun/star/io/XObjectInputStream.hpp> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::awt { struct FontDescriptor; } + +namespace comphelper +{ + +// bool +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectInputStream>& operator >> (const css::uno::Reference<css::io::XObjectInputStream>& _rxInStream, bool& _rVal); +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectOutputStream>& operator << (const css::uno::Reference<css::io::XObjectOutputStream>& _rxOutStream, bool _bVal); +void operator <<( + css::uno::Reference<css::io::XObjectOutputStream> const &, sal_Bool) + = delete; + +// OUString +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectInputStream>& operator >> (const css::uno::Reference<css::io::XObjectInputStream>& _rxInStream, OUString& _rStr); +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectOutputStream>& operator << (const css::uno::Reference<css::io::XObjectOutputStream>& _rxOutStream, const OUString& _rStr); + +// sal_Int16 +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectInputStream>& operator >> (const css::uno::Reference<css::io::XObjectInputStream>& _rxInStream, sal_Int16& _rValue); +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectOutputStream>& operator << (const css::uno::Reference<css::io::XObjectOutputStream>& _rxOutStream, sal_Int16 _nValue); + +// sal_uInt16 +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectInputStream>& operator >> (const css::uno::Reference<css::io::XObjectInputStream>& _rxInStream, sal_uInt16& _rValue); +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectOutputStream>& operator << (const css::uno::Reference<css::io::XObjectOutputStream>& _rxOutStream, sal_uInt16 _nValue); + +// sal_uInt32 +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectInputStream>& operator >> (const css::uno::Reference<css::io::XObjectInputStream>& _rxInStream, sal_uInt32& _rValue); +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectOutputStream>& operator << (const css::uno::Reference<css::io::XObjectOutputStream>& _rxOutStream, sal_uInt32 _nValue); + +// sal_Int16 +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectInputStream>& operator >> (const css::uno::Reference<css::io::XObjectInputStream>& _rxInStream, sal_Int32& _rValue); +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectOutputStream>& operator << (const css::uno::Reference<css::io::XObjectOutputStream>& _rxOutStream, sal_Int32 _nValue); + +// FontDescriptor +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectInputStream>& operator >> (const css::uno::Reference<css::io::XObjectInputStream>& InStream, css::awt::FontDescriptor& rVal); +COMPHELPER_DLLPUBLIC const css::uno::Reference<css::io::XObjectOutputStream>& operator << (const css::uno::Reference<css::io::XObjectOutputStream>& OutStream, const css::awt::FontDescriptor& rVal); + +// sequences +template <class ELEMENT> +const css::uno::Reference<css::io::XObjectInputStream>& operator >> (const css::uno::Reference<css::io::XObjectInputStream>& _rxInStream, css::uno::Sequence<ELEMENT>& _rSeq) +{ + _rSeq.realloc(_rxInStream->readLong()); + for (ELEMENT& rElement : asNonConstRange(_rSeq)) + _rxInStream >> rElement; + return _rxInStream; +} + +template <class ELEMENT> +const css::uno::Reference<css::io::XObjectOutputStream>& operator << (const css::uno::Reference<css::io::XObjectOutputStream>& _rxOutStream, const css::uno::Sequence<ELEMENT>& _rSeq) +{ + _rxOutStream->writeLong(_rSeq.getLength()); + for (const ELEMENT& rElement : _rSeq) + _rxOutStream << rElement; + return _rxOutStream; +} + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_BASICIO_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/broadcasthelper.hxx b/include/comphelper/broadcasthelper.hxx new file mode 100644 index 000000000..65fa6d315 --- /dev/null +++ b/include/comphelper/broadcasthelper.hxx @@ -0,0 +1,51 @@ +/* -*- 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_COMPHELPER_BROADCASTHELPER_HXX +#define INCLUDED_COMPHELPER_BROADCASTHELPER_HXX + +#include <osl/mutex.hxx> +#include <cppuhelper/interfacecontainer.h> + +namespace comphelper +{ + // OMutexAndBroadcastHelper - a class which holds a Mutex and an OBroadcastHelper; + // needed because when deriving from OPropertySetHelper, + // the OBroadcastHelper has to be initialized before + // the OPropertySetHelper + + class OMutexAndBroadcastHelper + { + protected: + ::osl::Mutex m_aMutex; + ::cppu::OBroadcastHelper m_aBHelper; + + public: + OMutexAndBroadcastHelper() : m_aBHelper( m_aMutex ) { } + + ::osl::Mutex& GetMutex() { return m_aMutex; } + ::cppu::OBroadcastHelper& GetBroadcastHelper() { return m_aBHelper; } + const ::cppu::OBroadcastHelper& GetBroadcastHelper() const { return m_aBHelper; } + + }; +} + +#endif // INCLUDED_COMPHELPER_BROADCASTHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/bytereader.hxx b/include/comphelper/bytereader.hxx new file mode 100644 index 000000000..a7e899098 --- /dev/null +++ b/include/comphelper/bytereader.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ +#pragma once + +#include <comphelper/comphelperdllapi.h> +#include <com/sun/star/uno/Sequence.hxx> + +namespace comphelper +{ +/** + * Interface that we can cast to, to bypass the inefficiency of using Sequence<sal_Int8> + * when reading via XInputStream. + */ +class COMPHELPER_DLLPUBLIC ByteReader +{ +public: + virtual ~ByteReader(); + virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) = 0; + + static const css::uno::Sequence<sal_Int8>& getUnoTunnelId(); +}; + +/** + * Interface that we can cast to, to bypass the inefficiency of using Sequence<sal_Int8> + * when writing via XOutputStream. + */ +class COMPHELPER_DLLPUBLIC ByteWriter +{ +public: + virtual ~ByteWriter(); + virtual sal_Int32 writeSomeBytes(const sal_Int8* aData, sal_Int32 nBytesToWrite) = 0; + + static const css::uno::Sequence<sal_Int8>& getUnoTunnelId(); +}; + +} // namespace utl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/comphelper/classids.hxx b/include/comphelper/classids.hxx new file mode 100644 index 000000000..4c345b84b --- /dev/null +++ b/include/comphelper/classids.hxx @@ -0,0 +1,334 @@ +/* -*- 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_COMPHELPER_CLASSIDS_HXX +#define INCLUDED_COMPHELPER_CLASSIDS_HXX + +/* + * StarWriter + */ + +/* 3.0 */ + +#define SO3_SW_CLASSID_30 \ + 0xDC5C7E40L, 0xB35C, 0x101B, 0x99, 0x61, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 + +/* 4.0 */ + +#define SO3_SW_CLASSID_40 \ + 0x8b04e9b0, 0x420e, 0x11d0, 0xa4, 0x5e, 0x0, \ + 0xa0, 0x24, 0x9d, 0x57, 0xb1 + +/* 5.0 */ + +#define SO3_SW_CLASSID_50 \ + 0xc20cf9d1, 0x85ae, 0x11d1, 0xaa, 0xb4, 0x0, \ + 0x60, 0x97, 0xda, 0x56, 0x1a + + /* 6.0, 7, 8 */ + +#define SO3_SW_CLASSID_60 \ + 0x8BC6B165, 0xB1B2, 0x4EDD, 0xAA, 0x47, 0xDA, \ + 0xE2, 0xEE, 0x68, 0x9D, 0xD6 + + /* ole embed 6.0, 7 */ + +#define SO3_SW_OLE_EMBED_CLASSID_60 \ + 0x30a2652a, 0xddf7, 0x45e7, 0xac, 0xa6, 0x3e, \ + 0xab, 0x26, 0xfc, 0x8a, 0x4e + + /* ole embed 8 */ + +#define SO3_SW_OLE_EMBED_CLASSID_8 \ + 0xf616b81f, 0x7bb8, 0x4f22, 0xb8, 0xa5, 0x47, \ + 0x42, 0x8d, 0x59, 0xf8, 0xad + +/* current */ + +#define SO3_SW_CLASSID SO3_SW_CLASSID_60 + +/* + * StarWriter/Web + */ + +/* 6.0, 7, 8 */ + +#define SO3_SWWEB_CLASSID_60 \ + 0xA8BBA60C, 0x7C60, 0x4550, 0x91, 0xCE, 0x39, \ + 0xC3, 0x90, 0x3F, 0xAC, 0x5E + +/* current */ + +#define SO3_SWWEB_CLASSID SO3_SWWEB_CLASSID_60 + +/* + * Globaldokument + */ + +/* 6.0, 7, 8 */ + +#define SO3_SWGLOB_CLASSID_60 \ + 0xB21A0A7C, 0xE403, 0x41FE, 0x95, 0x62, 0xBD, \ + 0x13, 0xEA, 0x6F, 0x15, 0xA0 + +/* current */ + +#define SO3_SWGLOB_CLASSID SO3_SWGLOB_CLASSID_60 + + +/* + * StarCalc + */ + +/* 3.0 */ + +#define SO3_SC_CLASSID_30 \ + 0x3F543FA0L, 0xB6A6, 0x101B, 0x99, 0x61, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 + +/* 4.0 */ + +#define SO3_SC_CLASSID_40 \ + 0x6361d441L, 0x4235, 0x11d0, 0x89, 0xcb, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* 5.0 */ + +#define SO3_SC_CLASSID_50 \ + 0xc6a5b861L, 0x85d6, 0x11d1, 0x89, 0xcb, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* 6.0 */ + +#define SO3_SC_CLASSID_60 \ + 0x47BBB4CB, 0xCE4C, 0x4E80, 0xA5, 0x91, 0x42, \ + 0xD9, 0xAE, 0x74, 0x95, 0x0F + +/* ole embed 6.0, 7 */ + +#define SO3_SC_OLE_EMBED_CLASSID_60 \ + 0x7b342dc4, 0x139a, 0x4a46, 0x8a, 0x93, 0xdb, \ + 0x8, 0x27, 0xcc, 0xee, 0x9c + +/* ole embed 8 */ + +#define SO3_SC_OLE_EMBED_CLASSID_8 \ + 0x7fa8ae11, 0xb3e3, 0x4d88, 0xaa, 0xbf, 0x25, \ + 0x55, 0x26, 0xcd, 0x1c, 0xe8 + +/* current */ + +#define SO3_SC_CLASSID SO3_SC_CLASSID_60 + +/**************************************************** +* StarImpress +****************************************************/ + +/* 3.0 */ + +#define SO3_SIMPRESS_CLASSID_30 \ + 0xAF10AAE0L, 0xB36D, 0x101B, 0x99, 0x61, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 + +/* 4.0 */ + +#define SO3_SIMPRESS_CLASSID_40 \ + 0x12d3cc0L, 0x4216, 0x11d0, 0x89, 0xcb, 0x0, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* 5.0 */ + +#define SO3_SIMPRESS_CLASSID_50 \ + 0x565c7221L, 0x85bc, 0x11d1, 0x89, 0xd0, 0x0, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* 6.0 */ + +#define SO3_SIMPRESS_CLASSID_60 \ + 0x9176E48A, 0x637A, 0x4D1F, 0x80, 0x3B, 0x99, \ + 0xD9, 0xBF, 0xAC, 0x10, 0x47 + +/* ole embed 6.0, 7 */ + +#define SO3_SIMPRESS_OLE_EMBED_CLASSID_60 \ + 0xe5a0b632, 0xdfba, 0x4549, 0x93, 0x46, 0xe4, \ + 0x14, 0xda, 0x6, 0xe6, 0xf8 + +/* ole embed 8 */ + +#define SO3_SIMPRESS_OLE_EMBED_CLASSID_8 \ + 0xee5d1ea4, 0xd445, 0x4289, 0xb2, 0xfc, 0x55, \ + 0xfc, 0x93, 0x69, 0x39, 0x17 + +/* current */ + +#define SO3_SIMPRESS_CLASSID SO3_SIMPRESS_CLASSID_60 + +/**************************************************** +* StarDraw +****************************************************/ + +/* 5.0 */ + +#define SO3_SDRAW_CLASSID_50 \ + 0x2e8905a0L, 0x85bd, 0x11d1, 0x89, 0xd0, 0x0, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* 6.0 */ +#define SO3_SDRAW_CLASSID_60 \ + 0x4BAB8970, 0x8A3B, 0x45B3, 0x99, 0x1C, 0xCB, \ + 0xEE, 0xAC, 0x6B, 0xD5, 0xE3 + +/* ole embed 6.0, 7 */ + +#define SO3_SDRAW_OLE_EMBED_CLASSID_60 \ + 0x41662fc2, 0xd57, 0x4aff, 0xab, 0x27, 0xad, \ + 0x2e, 0x12, 0xe7, 0xc2, 0x73 + +/* ole embed 8 */ + +#define SO3_SDRAW_OLE_EMBED_CLASSID_8 \ + 0x448bb771, 0xcfe2, 0x47c4, 0xbc, 0xdf, 0x1f, \ + 0xbf, 0x37, 0x8e, 0x20, 0x2c + +/* current */ + +#define SO3_SDRAW_CLASSID SO3_SDRAW_CLASSID_60 + +/**************************************************** +* StarChart +****************************************************/ + +/* 3.0 */ + +#define SO3_SCH_CLASSID_30 \ + 0xFB9C99E0L, 0x2C6D, 0x101C, 0x8E, 0x2C, 0x00, \ + 0x00, 0x1B, 0x4C, 0xC7, 0x11 + +/* 4.0 */ + +#define SO3_SCH_CLASSID_40 \ + 0x2b3b7e0L, 0x4225, 0x11d0, 0x89, 0xca, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* 5.0 */ + +#define SO3_SCH_CLASSID_50 \ + 0xbf884321L, 0x85dd, 0x11d1, 0x89, 0xd0, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* 6.0 */ + +#define SO3_SCH_CLASSID_60 \ + 0x12DCAE26, 0x281F, 0x416F, 0xA2, 0x34, 0xC3, \ + 0x08, 0x61, 0x27, 0x38, 0x2E + +/* ole embed 6.0, 7 */ + +#define SO3_SCH_OLE_EMBED_CLASSID_60 \ + 0xd415cd93, 0x35c4, 0x4c6f, 0x81, 0x9d, 0xa6, \ + 0x64, 0xa1, 0xc8, 0x13, 0xae + +/* ole embed 8 */ + +#define SO3_SCH_OLE_EMBED_CLASSID_8 \ + 0xdd0a57f, 0xcf3b, 0x4fd2, 0xbd, 0xa4, 0x94, \ + 0x42, 0x71, 0x9b, 0x2a, 0x73 + +/* current */ + +#define SO3_SCH_CLASSID SO3_SCH_CLASSID_60 + +// Report chart + +#define SO3_RPTCH_CLASSID \ + 0x80243D39, 0x6741, 0x46C5, 0x92, 0x6E, 0x06, \ + 0x91, 0x64, 0xFF, 0x87, 0xBB + +/*************************************************** +* StarMath +***************************************************/ + +/* 3.0 */ + +#define SO3_SM_CLASSID_30 \ + 0xD4590460L, 0x35FD, 0x101C, 0xB1, 0x2A, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 + +/* 4.0 */ + +#define SO3_SM_CLASSID_40 \ + 0x2b3b7e1L, 0x4225, 0x11d0, 0x89, 0xca, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* 5.0 */ + +#define SO3_SM_CLASSID_50 \ + 0xffb5e640L, 0x85de, 0x11d1, 0x89, 0xd0, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* 6.0, 7, 8 */ + +#define SO3_SM_CLASSID_60 \ + 0x078B7ABA, 0x54FC, 0x457F, 0x85, 0x51, 0x61, \ + 0x47, 0xE7, 0x76, 0xA9, 0x97 + +/* ole embed 6.0, 7 */ + +#define SO3_SM_OLE_EMBED_CLASSID_60 \ + 0xd0484de6, 0xaaee, 0x468a, 0x99, 0x1f, 0x8d, \ + 0x4b, 0x7, 0x37, 0xb5, 0x7a + +/* ole embed 8 */ + +#define SO3_SM_OLE_EMBED_CLASSID_8 \ + 0xd2d59cd1, 0xa6a, 0x4d36, 0xae, 0x20, 0x47, \ + 0x81, 0x70, 0x77, 0xd5, 0x7c + +/* current */ + +#define SO3_SM_CLASSID SO3_SM_CLASSID_60 + +#define SO3_OUT_CLASSID \ + 0x970b1e82, 0xcf2d, 0x11cf, 0x89, 0xca, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +#define SO3_DUMMY_CLASSID \ + 0x970b1fff, 0xcf2d, 0x11cf, \ + 0x89,0xca,0x00,0x80,0x29,0xe4,0xb0,0xb1 + +#define SO3_APPLET_CLASSID \ + 0x970b1e81, 0xcf2d, 0x11cf, \ + 0x89,0xca,0x00,0x80,0x29,0xe4,0xb0,0xb1 + +#define SO3_PLUGIN_CLASSID \ + 0x4caa7761, 0x6b8b, 0x11cf, \ + 0x89,0xca,0x0,0x80,0x29,0xe4,0xb0,0xb1 + +#define SO3_IFRAME_CLASSID \ + 0x1a8a6701, 0xde58, 0x11cf, \ + 0x89, 0xca, 0x0, 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +#define SO3_RPT_CLASSID_90 \ + 0xd7896d52, 0xb7af, 0x4820, \ + 0x9d, 0xfe, 0xd4, 0x04, 0xd0, 0x15, 0x96, 0x0f + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/compbase.hxx b/include/comphelper/compbase.hxx new file mode 100644 index 000000000..38380ede2 --- /dev/null +++ b/include/comphelper/compbase.hxx @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include <sal/config.h> + +#include <comphelper/comphelperdllapi.h> +#include <comphelper/interfacecontainer4.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <mutex> + +namespace comphelper +{ +/** + Serves two purposes + (1) extracts code that doesn't need to be templated + (2) helps to handle the custom where we have conflicting interfaces + e.g. multiple UNO interfaces that extend css::lang::XComponent +*/ +class COMPHELPER_DLLPUBLIC WeakComponentImplHelperBase : public cppu::OWeakObject, + public css::lang::XComponent +{ +public: + virtual ~WeakComponentImplHelperBase() override; + + // css::lang::XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL + addEventListener(css::uno::Reference<css::lang::XEventListener> const& rxListener) override; + virtual void SAL_CALL + removeEventListener(css::uno::Reference<css::lang::XEventListener> const& rxListener) override; + + virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const& rType) override; + + /** + Called by dispose for subclasses to do dispose() work. + The mutex is held when called, and subclasses can unlock() the guard if necessary. + */ + virtual void disposing(std::unique_lock<std::mutex>&); + +protected: + comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> maEventListeners; + mutable std::mutex m_aMutex; + bool m_bDisposed = false; +}; + +template <typename... Ifc> +class SAL_DLLPUBLIC_TEMPLATE WeakComponentImplHelper : public WeakComponentImplHelperBase, + public css::lang::XTypeProvider, + public Ifc... +{ +public: + virtual void SAL_CALL acquire() noexcept final override { OWeakObject::acquire(); } + + virtual void SAL_CALL release() noexcept final override { OWeakObject::release(); } + + // css::lang::XComponent + virtual void SAL_CALL dispose() noexcept final override + { + WeakComponentImplHelperBase::dispose(); + } + virtual void SAL_CALL addEventListener( + css::uno::Reference<css::lang::XEventListener> const& rxListener) final override + { + WeakComponentImplHelperBase::addEventListener(rxListener); + } + virtual void SAL_CALL removeEventListener( + css::uno::Reference<css::lang::XEventListener> const& rxListener) final override + { + WeakComponentImplHelperBase::removeEventListener(rxListener); + } + + virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const& rType) override + { + return WeakComponentImplHelper_query(rType, class_data_get(), this); + } + + // css::lang::XTypeProvider + virtual css::uno::Sequence<css::uno::Type> SAL_CALL getTypes() override + { + static const css::uno::Sequence<css::uno::Type> aTypeList{ + cppu::UnoType<css::uno::XWeak>::get(), cppu::UnoType<css::lang::XComponent>::get(), + cppu::UnoType<css::lang::XTypeProvider>::get(), cppu::UnoType<Ifc>::get()... + }; + return aTypeList; + } + virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override + { + return css::uno::Sequence<sal_Int8>(); + } + +private: + static cppu::class_data* class_data_get() + { + return cppu::detail::ImplClassData<WeakComponentImplHelper, Ifc...>{}(); + } +}; + +/** WeakComponentImplHelper +*/ +COMPHELPER_DLLPUBLIC css::uno::Any +WeakComponentImplHelper_query(css::uno::Type const& rType, cppu::class_data* cd, + WeakComponentImplHelperBase* pBase); + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/comphelper/comphelperdllapi.h b/include/comphelper/comphelperdllapi.h new file mode 100644 index 000000000..361326a4e --- /dev/null +++ b/include/comphelper/comphelperdllapi.h @@ -0,0 +1,33 @@ +/* -*- 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_COMPHELPER_COMPHELPERDLLAPI_H +#define INCLUDED_COMPHELPER_COMPHELPERDLLAPI_H + +#include <sal/types.h> + +#if defined(COMPHELPER_DLLIMPLEMENTATION) +#define COMPHELPER_DLLPUBLIC SAL_DLLPUBLIC_EXPORT +#else +#define COMPHELPER_DLLPUBLIC SAL_DLLPUBLIC_IMPORT +#endif +#define COMPHELPER_DLLPRIVATE SAL_DLLPRIVATE + +#endif // INCLUDED_COMPHELPER_COMPHELPERDLLAPI_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/componentbase.hxx b/include/comphelper/componentbase.hxx new file mode 100644 index 000000000..ce6353be4 --- /dev/null +++ b/include/comphelper/componentbase.hxx @@ -0,0 +1,139 @@ +/* -*- 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_COMPHELPER_COMPONENTBASE_HXX +#define INCLUDED_COMPHELPER_COMPONENTBASE_HXX + +#include <comphelper/comphelperdllapi.h> +#include <cppuhelper/interfacecontainer.h> + + +namespace comphelper +{ + + + //= ComponentBase + + class COMPHELPER_DLLPUBLIC ComponentBase + { + protected: + /** creates a ComponentBase instance + + The instance is not initialized. As a consequence, every ComponentMethodGuard instantiated for + this component will throw a css::lang::NotInitializedException, + until ->setInitialized() is called. + */ + ComponentBase( ::cppu::OBroadcastHelper& _rBHelper ) + :m_rBHelper( _rBHelper ) + ,m_bInitialized( false ) + { + } + + struct NoInitializationNeeded { }; + + /** creates a ComponentBase instance + + The instance is already initialized, so there's no need to call setInitialized later on. Use this + constructor for component implementations which do not require explicit initialization. + */ + ComponentBase( ::cppu::OBroadcastHelper& _rBHelper, NoInitializationNeeded ) + :m_rBHelper( _rBHelper ) + ,m_bInitialized( true ) + { + } + + ~ComponentBase() COVERITY_NOEXCEPT_FALSE {} + + /** marks the instance as initialized + + Subsequent instantiations of a ComponentMethodGuard won't throw the NotInitializedException now. + */ + void setInitialized() { m_bInitialized = true; } + + public: + /// helper struct to grant access to selected public methods to the ComponentMethodGuard class + struct GuardAccess { friend class ComponentMethodGuard; private: GuardAccess() { } }; + + /// retrieves the component's mutex + ::osl::Mutex& getMutex( GuardAccess ) { return getMutex(); } + /// checks whether the component is already disposed, throws a DisposedException if so. + void checkDisposed( GuardAccess ) const; + /// checks whether the component is already initialized, throws a NotInitializedException if not. + void checkInitialized( GuardAccess ) const; + + protected: + /// retrieves the component's broadcast helper + ::cppu::OBroadcastHelper& getBroadcastHelper() { return m_rBHelper; } + /// retrieves the component's mutex + ::osl::Mutex& getMutex() { return m_rBHelper.rMutex; } + /// determines whether the instance is already disposed + bool impl_isDisposed() const { return m_rBHelper.bDisposed; } + + /// determines whether the component is already initialized + bool + impl_isInitialized_nothrow() const { return m_bInitialized; } + + /** returns the context to be used when throwing exceptions + + The default implementation returns <NULL/>. + */ + static css::uno::Reference< css::uno::XInterface > + getComponent(); + + private: + ::cppu::OBroadcastHelper& m_rBHelper; + bool m_bInitialized; + }; + + class ComponentMethodGuard + { + public: + enum class MethodType + { + /// allow the method to be called only when being initialized and not being disposed + Default, + /// allow the method to be called without being initialized + WithoutInit + + }; + + ComponentMethodGuard( ComponentBase& _rComponent, const MethodType _eType = MethodType::Default ) + :m_aMutexGuard( _rComponent.getMutex( ComponentBase::GuardAccess() ) ) + { + if ( _eType != MethodType::WithoutInit ) + _rComponent.checkInitialized( ComponentBase::GuardAccess() ); + _rComponent.checkDisposed( ComponentBase::GuardAccess() ); + } + + void clear() + { + m_aMutexGuard.clear(); + } + + private: + osl::ClearableMutexGuard m_aMutexGuard; + }; + + +} // namespace ComponentBase + + +#endif // INCLUDED_COMPHELPER_COMPONENTBASE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/componentguard.hxx b/include/comphelper/componentguard.hxx new file mode 100644 index 000000000..f3cf1bd5e --- /dev/null +++ b/include/comphelper/componentguard.hxx @@ -0,0 +1,58 @@ +/* -*- 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_COMPHELPER_COMPONENTGUARD_HXX +#define INCLUDED_COMPHELPER_COMPONENTGUARD_HXX + +#include <com/sun/star/lang/DisposedException.hpp> + +#include <cppuhelper/weak.hxx> +#include <cppuhelper/interfacecontainer.h> + + +namespace comphelper +{ + + + //= ComponentGuard + + class ComponentGuard + { + public: + ComponentGuard( ::cppu::OWeakObject& i_component, ::cppu::OBroadcastHelper & i_broadcastHelper ) + :m_aGuard( i_broadcastHelper.rMutex ) + { + if ( i_broadcastHelper.bDisposed ) + throw css::lang::DisposedException( OUString(), &i_component ); + } + + void clear() { m_aGuard.clear(); } + void reset() { m_aGuard.reset(); } + + private: + ::osl::ResettableMutexGuard m_aGuard; + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_COMPONENTGUARD_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/configuration.hxx b/include/comphelper/configuration.hxx new file mode 100644 index 000000000..222b9d5af --- /dev/null +++ b/include/comphelper/configuration.hxx @@ -0,0 +1,342 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_CONFIGURATION_HXX +#define INCLUDED_COMPHELPER_CONFIGURATION_HXX + +#include <sal/config.h> + +#include <optional> +#include <string_view> + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Reference.h> +#include <comphelper/comphelperdllapi.h> +#include <comphelper/processfactory.hxx> +#include <sal/types.h> +#include <memory> + +namespace com::sun::star { + namespace configuration { class XReadWriteAccess; } + namespace container { + class XHierarchicalNameAccess; + class XHierarchicalNameReplace; + class XNameAccess; + class XNameContainer; + } + namespace uno { class XComponentContext; } +} + +namespace comphelper { + +namespace detail { class ConfigurationWrapper; } + +/// A batch of configuration changes that is committed as a whole. +/// +/// Client code needs to call commit explicitly; otherwise the changes are lost +/// when the instance is destroyed. +/// +/// This is the only class from this header file that client code should use +/// directly. +class COMPHELPER_DLLPUBLIC ConfigurationChanges { +public: + static std::shared_ptr<ConfigurationChanges> create(); + + ~ConfigurationChanges(); + + void commit() const; + +private: + ConfigurationChanges(const ConfigurationChanges&) = delete; + ConfigurationChanges& operator=(const ConfigurationChanges&) = delete; + + SAL_DLLPRIVATE ConfigurationChanges( + css::uno::Reference< css::uno::XComponentContext > + const & context); + + SAL_DLLPRIVATE void setPropertyValue( + OUString const & path, css::uno::Any const & value) + const; + + SAL_DLLPRIVATE css::uno::Reference< + css::container::XHierarchicalNameReplace > + getGroup(OUString const & path) const; + + SAL_DLLPRIVATE + css::uno::Reference< css::container::XNameContainer > + getSet(OUString const & path) const; + + css::uno::Reference< + css::configuration::XReadWriteAccess > access_; + + friend class detail::ConfigurationWrapper; +}; + +namespace detail { + +/// @internal +class COMPHELPER_DLLPUBLIC ConfigurationWrapper { +public: + static ConfigurationWrapper const & get(); + + bool isReadOnly(OUString const & path) const; + + css::uno::Any getPropertyValue(std::u16string_view path) const; + + static void setPropertyValue( + std::shared_ptr< ConfigurationChanges > const & batch, + OUString const & path, css::uno::Any const & value); + + css::uno::Any getLocalizedPropertyValue( + std::u16string_view path) const; + + static void setLocalizedPropertyValue( + std::shared_ptr< ConfigurationChanges > const & batch, + OUString const & path, css::uno::Any const & value); + + css::uno::Reference< + css::container::XHierarchicalNameAccess > + getGroupReadOnly(OUString const & path) const; + + static css::uno::Reference< + css::container::XHierarchicalNameReplace > + getGroupReadWrite( + std::shared_ptr< ConfigurationChanges > const & batch, + OUString const & path); + + css::uno::Reference< css::container::XNameAccess > + getSetReadOnly(OUString const & path) const; + + static css::uno::Reference< css::container::XNameContainer > + getSetReadWrite( + std::shared_ptr< ConfigurationChanges > const & batch, + OUString const & path); + + std::shared_ptr< ConfigurationChanges > createChanges() const; + +private: + SAL_DLLPRIVATE explicit ConfigurationWrapper(); + + SAL_DLLPRIVATE ~ConfigurationWrapper(); + + ConfigurationWrapper(const ConfigurationWrapper&) = delete; + ConfigurationWrapper& operator=(const ConfigurationWrapper&) = delete; + + css::uno::Reference< css::uno::XComponentContext > context_; + + css::uno::Reference< css::configuration::XReadWriteAccess > access_; + // should really be a css.configuration.ReadOnlyAccess (with added + // css.beans.XHierarchicalPropertySetInfo), but then + // configmgr::Access::asProperty() would report all properties as + // READONLY, so isReadOnly() would not work +}; + +/// @internal +template< typename T > struct Convert { + static css::uno::Any toAny(T const & value) + { return css::uno::Any(value); } + + static T fromAny(css::uno::Any const & value) + { return value.get< T >(); } + +private: + Convert(const Convert&) = delete; + Convert& operator=(const Convert&) = delete; + + Convert() = delete; + ~Convert() = delete; +}; + +/// @internal +template< typename T > struct Convert< std::optional< T > > +{ + static css::uno::Any toAny(std::optional< T > const & value) { + return value + ? css::uno::Any(*value) + : css::uno::Any(); + } + + static std::optional< T > fromAny(css::uno::Any const & value) + { + return value.hasValue() + ? std::optional< T >(value.get< T >()) : std::optional< T >(); + } + +private: + Convert(const Convert&) = delete; + Convert& operator=(const Convert&) = delete; + + Convert() = delete; + ~Convert() = delete; +}; + +} + +/// A type-safe wrapper around a (non-localized) configuration property. +/// +/// Automatically generated headers for the various configuration properties +/// derive from this template and make available its member functions to access +/// each given configuration property. +template< typename T, typename U > struct ConfigurationProperty +{ + /// Get the read-only status of the given (non-localized) configuration + /// property. + static bool isReadOnly() + { + return detail::ConfigurationWrapper::get().isReadOnly(T::path()); + } + + /// Get the value of the given (non-localized) configuration property. + /// + /// For nillable properties, U is of type std::optional<U'>. + static U get() + { + // Folding this into one statement causes a bogus error at least with + // Red Hat GCC 4.6.2-1: + css::uno::Any a( + detail::ConfigurationWrapper::get().getPropertyValue( + T::path())); + return detail::Convert< U >::fromAny(a); + } + + /// Set the value of the given (non-localized) configuration property, via a + /// given changes batch. + /// + /// For nillable properties, U is of type std::optional<U'>. + static void set( + U const & value, + std::shared_ptr< ConfigurationChanges > const & batch) + { + comphelper::detail::ConfigurationWrapper::setPropertyValue( + batch, T::path(), detail::Convert< U >::toAny(value)); + } + +private: + ConfigurationProperty(const ConfigurationProperty&) = delete; + ConfigurationProperty& operator=(const ConfigurationProperty&) = delete; + + ConfigurationProperty() = delete; + ~ConfigurationProperty() = delete; +}; + +/// A type-safe wrapper around a localized configuration property. +/// +/// Automatically generated headers for the various localized configuration +/// properties derive from this template and make available its member functions +/// to access each given localized configuration property. +template< typename T, typename U > struct ConfigurationLocalizedProperty +{ + /// Get the value of the given localized configuration property, for the + /// locale currently set at the + /// com.sun.star.configuration.theDefaultProvider. + /// + /// For nillable properties, U is of type std::optional<U'>. + static U get() + { + // Folding this into one statement causes a bogus error at least with + // Red Hat GCC 4.6.2-1: + css::uno::Any a( + detail::ConfigurationWrapper::get(). + getLocalizedPropertyValue(T::path())); + return detail::Convert< U >::fromAny(a); + } + + /// Set the value of the given localized configuration property, for the + /// locale currently set at the + /// com.sun.star.configuration.theDefaultProvider, via a given changes + /// batch. + /// + /// For nillable properties, U is of type std::optional<U'>. + static void set( + U const & value, + std::shared_ptr< ConfigurationChanges > const & batch) + { + comphelper::detail::ConfigurationWrapper::setLocalizedPropertyValue( + batch, T::path(), detail::Convert< U >::toAny(value)); + } + +private: + ConfigurationLocalizedProperty(const ConfigurationLocalizedProperty&) = delete; + ConfigurationLocalizedProperty& operator=(const ConfigurationLocalizedProperty&) = delete; + + ConfigurationLocalizedProperty() = delete; + ~ConfigurationLocalizedProperty() = delete; +}; + +/// A type-safe wrapper around a configuration group. +/// +/// Automatically generated headers for the various configuration groups derive +/// from this template and make available its member functions to access each +/// given configuration group. +template< typename T > struct ConfigurationGroup { + /// Get read-only access to the given configuration group. + static css::uno::Reference< + css::container::XHierarchicalNameAccess > + get() + { + return detail::ConfigurationWrapper::get().getGroupReadOnly( + T::path()); + } + + /// Get read/write access to the given configuration group, storing any + /// modifications via the given changes batch. + static css::uno::Reference< + css::container::XHierarchicalNameReplace > + get(std::shared_ptr< ConfigurationChanges > const & batch) + { + return comphelper::detail::ConfigurationWrapper::getGroupReadWrite( + batch, T::path()); + } + +private: + ConfigurationGroup(const ConfigurationGroup&) = delete; + ConfigurationGroup& operator=(const ConfigurationGroup&) = delete; + + ConfigurationGroup() = delete; + ~ConfigurationGroup() = delete; +}; + +/// A type-safe wrapper around a configuration set. +/// +/// Automatically generated headers for the various configuration sets derive +/// from this template and make available its member functions to access each +/// given configuration set. +template< typename T > struct ConfigurationSet { + /// Get read-only access to the given configuration set. + static + css::uno::Reference< css::container::XNameAccess > + get() + { + return detail::ConfigurationWrapper::get().getSetReadOnly( + T::path()); + } + + /// Get read/write access to the given configuration set, storing any + /// modifications via the given changes batch. + static + css::uno::Reference< css::container::XNameContainer > + get(std::shared_ptr< ConfigurationChanges > const & batch) + { + return comphelper::detail::ConfigurationWrapper::getSetReadWrite( + batch, T::path()); + } + +private: + ConfigurationSet(const ConfigurationSet&) = delete; + ConfigurationSet& operator=(const ConfigurationSet&) = delete; + + ConfigurationSet() = delete; + ~ConfigurationSet() = delete; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/configurationhelper.hxx b/include/comphelper/configurationhelper.hxx new file mode 100644 index 000000000..162319316 --- /dev/null +++ b/include/comphelper/configurationhelper.hxx @@ -0,0 +1,239 @@ +/* -*- 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_COMPHELPER_CONFIGURATIONHELPER_HXX +#define INCLUDED_COMPHELPER_CONFIGURATIONHELPER_HXX + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/Any.hxx> +#include <rtl/ustring.hxx> +#include <comphelper/comphelperdllapi.h> +#include <o3tl/typed_flags_set.hxx> + +namespace com::sun::star::uno { class XComponentContext; } +namespace com::sun::star::uno { class XInterface; } + +namespace comphelper +{ + /** specify all possible modes, which can be used to open a configuration access. + * + * @see openConfig() + * @see readDirectKey() + * @see writeDirectKey() + */ + enum class EConfigurationModes + { + /// opens configuration in read/write mode (without LAZY writing!) + Standard = 0, + /// configuration will be opened readonly + ReadOnly = 1, + /// all localized nodes will be interpreted as XInterface instead of interpreting it as atomic value nodes + AllLocales = 2 + }; + + +} + +namespace o3tl +{ + template<> struct typed_flags<comphelper::EConfigurationModes> : is_typed_flags<comphelper::EConfigurationModes, 0x3> {}; +} + +namespace comphelper +{ + +class COMPHELPER_DLLPUBLIC ConfigurationHelper +{ +public: + /** returns access to the specified configuration package. + * + * This method should be used, if e.g. more than one request to the same + * configuration package is needed. The configuration access can be cached + * outside and used inbetween. + * + * @param rxContext + * the uno service manager, which should be used to create the + * configuration access. + * + * @param sPackage + * the name of the configuration package. + * e.g. <ul> + * <li>org.openoffice.Office.Common</li> + * <li>org.openoffice.Office.Common/Menu</li> + * </ul> + * + * @param eMode + * specify the open mode for the returned configuration access. + * It's interpreted as a flag field and can be any useful combination + * of values of EConfigurationModes. + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::uno::Exception if the configuration could not be opened. + */ + static css::uno::Reference< css::uno::XInterface > openConfig(const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const OUString& sPackage, + EConfigurationModes eMode ); + + + /** reads the value of an existing(!) configuration key, + * which is searched relative to the specified configuration access. + * + * This method must be used in combination with openConfig(). + * The cached configuration access must be provided here ... and + * all operations are made relative to this access point. + * + * @param xCFG + * the configuration root, where sRelPath should be interpreted. + * as relative path + * + * @param sRelPath + * path relative to xCFG parameter. + * + * @param sKey + * the configuration node, where we should read the value. + * + * @return [css.uno.Any] + * the value of sKey. + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::container::NoSuchElementException if the specified + * key does not exists. + */ + static css::uno::Any readRelativeKey(const css::uno::Reference< css::uno::XInterface >& xCFG , + const OUString& sRelPath, + const OUString& sKey ); + + + /** writes a new value for an existing(!) configuration key, + * which is searched relative to the specified configuration access. + * + * This method must be used in combination with openConfig(). + * The cached configuration access must be provided here ... and + * all operations are made relative to this access point. + * + * @param xCFG + * the configuration root, where sRelPath should be interpreted. + * as relative path + * + * @param sRelPath + * path relative to xCFG parameter. + * + * @param sKey + * the configuration node, where we should write the new value. + * + * @param aValue + * the new value for sKey. + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::container::NoSuchElementException if the specified + * key does not exists or css::uno::Exception if the provided configuration + * access does not allow writing for this key. + */ + static void writeRelativeKey(const css::uno::Reference< css::uno::XInterface >& xCFG , + const OUString& sRelPath, + const OUString& sKey , + const css::uno::Any& aValue ); + + + /** it checks if the specified set node exists ... or create an empty one + * otherwise. + * + * This method must be used in combination with openConfig(). + * The cached configuration access must be provided here ... and + * all operations are made relative to this access point. + * + * Further this method must be used only with configuration set's. + * Atomic keys can't be "created"... they "exist every time". + * + * @param xCFG + * the configuration root, where sRelPathToSet should be interpreted + * as relative path. + * + * @param sRelPathToSet + * path relative to xCFG parameter. + * + * @param sSetNode + * the set node, which should be checked if its exists ... + * or which should be created with default values. + * + * @return A reference to the found (or new created) set node. + * Can't be NULL .. in such case an exception occurs! + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::uno::Exception if the provided configuration + * access does not allow writing for this set. + */ + static css::uno::Reference< css::uno::XInterface > makeSureSetNodeExists(const css::uno::Reference< css::uno::XInterface >& xCFG , + const OUString& sRelPathToSet, + const OUString& sSetNode ); + + + /** commit all changes made on the specified configuration access. + * + * This method must be used in combination with openConfig(). + * The cached configuration access must be provided here. + * + * @param xCFG + * the configuration root, where changes should be committed. + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::uno::Exception if the provided configuration + * access does not allow writing for this set. + */ + static void flush(const css::uno::Reference< css::uno::XInterface >& xCFG); + + + /** does the same then openConfig() & readRelativeKey() together. + * + * This method should be used for reading one key at one code place only. + * Because it opens the specified configuration package, reads the key and + * closes the configuration again. + * + * So it's not very useful to use this method for reading multiple keys at the same time. + * (Excepting these keys exists inside different configuration packages ...)) + */ + static css::uno::Any readDirectKey(const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const OUString& sPackage, + const OUString& sRelPath, + const OUString& sKey , + EConfigurationModes eMode ); + + + /** does the same then openConfig() / writeRelativeKey() & flush() together. + * + * This method should be used for writing one key at one code place only. + * Because it opens the specified configuration package, writes the key, flush + * all changes and closes the configuration again. + * + * So it's not very useful to use this method for writing multiple keys at the same time. + * (Excepting these keys exists inside different configuration packages ...)) + */ + static void writeDirectKey(const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const OUString& sPackage, + const OUString& sRelPath, + const OUString& sKey , + const css::uno::Any& aValue , + EConfigurationModes eMode ); +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_CONFIGURATIONHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/configurationlistener.hxx b/include/comphelper/configurationlistener.hxx new file mode 100644 index 000000000..55342514c --- /dev/null +++ b/include/comphelper/configurationlistener.hxx @@ -0,0 +1,121 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_CONFIGURATIONLISTENER_HXX +#define INCLUDED_COMPHELPER_CONFIGURATIONLISTENER_HXX + +#include <vector> +#include <comphelper/comphelperdllapi.h> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#include <rtl/ref.hxx> +#include <cppuhelper/implbase.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/configurationhelper.hxx> + +namespace com::sun::star::beans { struct PropertyChangeEvent; } +namespace com::sun::star::uno { class XComponentContext; } + +namespace comphelper { + +class ConfigurationListener; + +class COMPHELPER_DLLPUBLIC ConfigurationListenerPropertyBase { +public: + OUString maName; + rtl::Reference<ConfigurationListener> mxListener; + + virtual ~ConfigurationListenerPropertyBase() {} + virtual void setProperty(const css::uno::Any &aProperty) = 0; + void dispose() { mxListener.clear(); } +}; + +/// Access to this class must be protected by the SolarMutex +template< typename uno_type > class ConfigurationListenerProperty : public ConfigurationListenerPropertyBase +{ + uno_type maValue; +protected: + virtual void setProperty(const css::uno::Any &aProperty) override + { + aProperty >>= maValue; + } +public: + /** + * Provide a mirror of the configmgr's version of this property + * for the lifecycle of this property. The property value tracks + * the same value in the configuration. + */ + inline ConfigurationListenerProperty(const rtl::Reference< ConfigurationListener > &xListener, + const OUString &rProp ); + + virtual inline ~ConfigurationListenerProperty() override; + + uno_type get() const { return maValue; } +}; + +// workaround for incremental linking bugs in MSVC2019 +class SAL_DLLPUBLIC_TEMPLATE ConfigurationListener_Base : public cppu::WeakImplHelper< css::beans::XPropertyChangeListener > {}; +class COMPHELPER_DLLPUBLIC ConfigurationListener final : public ConfigurationListener_Base +{ + css::uno::Reference< css::beans::XPropertySet > mxConfig; + std::vector< ConfigurationListenerPropertyBase * > maListeners; + bool mbDisposed; +public: + /// Public health warning, you -must- dispose this if you use it. + ConfigurationListener(const OUString &rPath, + css::uno::Reference< css::uno::XComponentContext > + const & xContext = comphelper::getProcessComponentContext()) + : mxConfig( ConfigurationHelper::openConfig( xContext, rPath, EConfigurationModes::ReadOnly ), + css::uno::UNO_QUERY_THROW ) + , mbDisposed(false) + { } + + virtual ~ConfigurationListener() override + { + dispose(); + } + + /// Listen for the specific property denoted by the listener + void addListener(ConfigurationListenerPropertyBase *pListener); + + /// Stop listening. + void removeListener(ConfigurationListenerPropertyBase *pListener); + + /// Release various circular references + void dispose(); + + // XPropertyChangeListener implementation + virtual void SAL_CALL disposing(css::lang::EventObject const &) override; + + /// Notify of the property change + virtual void SAL_CALL propertyChange( + css::beans::PropertyChangeEvent const &rEvt ) override; + + bool isDisposed() const { return mbDisposed; } +}; + +template< typename uno_type > ConfigurationListenerProperty< uno_type >::ConfigurationListenerProperty(const rtl::Reference< ConfigurationListener > &xListener, const OUString &rProp ) + : maValue() +{ + maName = rProp; + mxListener = xListener; + mxListener->addListener(this); +} + +template< typename uno_type > ConfigurationListenerProperty< uno_type >::~ConfigurationListenerProperty() +{ + if (mxListener.is()) + mxListener->removeListener(this); +} + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_CONFIGURATIONLISTENER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/container.hxx b/include/comphelper/container.hxx new file mode 100644 index 000000000..84acfc5b0 --- /dev/null +++ b/include/comphelper/container.hxx @@ -0,0 +1,76 @@ +/* -*- 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_COMPHELPER_CONTAINER_HXX +#define INCLUDED_COMPHELPER_CONTAINER_HXX + +#include <vector> +#include <com/sun/star/uno/Reference.hxx> +#include <comphelper/comphelperdllapi.h> + + +namespace comphelper +{ + + +//= IndexAccessIterator + +/** an iterator that iterates through all elements, starting from an XIndexAccess (pre-order) +*/ +class COMPHELPER_DLLPUBLIC IndexAccessIterator +{ +protected: + css::uno::Reference< css::uno::XInterface> m_xStartingPoint; + + css::uno::Reference< css::uno::XInterface> m_xCurrentObject; + // The current object + ::std::vector<sal_Int32> m_arrChildIndizies; + + // I'm moving through a tree, but its elements have no GetNextSibling, + // so I have to remember where each child is in relation to its parent. + // That is the path from the root node to m_xCurrentObject + +public: + IndexAccessIterator(css::uno::Reference< css::uno::XInterface> xStartingPoint); + + virtual ~IndexAccessIterator(); + + css::uno::Reference< css::uno::XInterface> const & Next(); + + virtual void Invalidate() { m_xCurrentObject = nullptr; } + +protected: + virtual bool ShouldHandleElement(const css::uno::Reference< css::uno::XInterface>& /*rElement*/) { return true; } + + // This can be used to exclude certain elements; elements for which + // this function returns sal_True will be simply skipped. + // If this element is returned from Next(), then one can get + // here get a little more information on the element. + // That's why this method is not const. + virtual bool ShouldStepInto(const css::uno::Reference< css::uno::XInterface>& /*xContainer*/) const { return true; } +}; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_CONTAINER_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/containermultiplexer.hxx b/include/comphelper/containermultiplexer.hxx new file mode 100644 index 000000000..5b40b62ae --- /dev/null +++ b/include/comphelper/containermultiplexer.hxx @@ -0,0 +1,106 @@ +/* -*- 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_COMPHELPER_CONTAINERMULTIPLEXER_HXX +#define INCLUDED_COMPHELPER_CONTAINERMULTIPLEXER_HXX + +#include <com/sun/star/container/XContainerListener.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> +#include <rtl/ref.hxx> + +namespace osl { class Mutex; } +namespace com::sun::star::container { class XContainer; } + + +namespace comphelper +{ + + + class OContainerListenerAdapter; + + //= OContainerListener + + /** a non-UNO container listener + <p>Useful if you have a non-refcountable class which should act as container listener.<br/> + In this case, derive this class from OContainerListener, and create an adapter + OContainerListenerAdapter which multiplexes the changes.</p> + */ + class COMPHELPER_DLLPUBLIC OContainerListener + { + friend class OContainerListenerAdapter; + protected: + rtl::Reference<OContainerListenerAdapter> m_xAdapter; + ::osl::Mutex& m_rMutex; + + public: + OContainerListener(::osl::Mutex& _rMutex); + virtual ~OContainerListener(); + + /// @throws css::uno::RuntimeException + virtual void _elementInserted( const css::container::ContainerEvent& _rEvent ); + /// @throws css::uno::RuntimeException + virtual void _elementRemoved( const css::container::ContainerEvent& _rEvent ); + /// @throws css::uno::RuntimeException + virtual void _elementReplaced( const css::container::ContainerEvent& _rEvent ); + /// @throws css::uno::RuntimeException + virtual void _disposing(const css::lang::EventObject& _rSource); + + protected: + void setAdapter(OContainerListenerAdapter* _pAdapter); + }; + + // workaround for incremental linking bugs in MSVC2015 + class SAL_DLLPUBLIC_TEMPLATE OContainerListenerAdapter_Base : public cppu::WeakImplHelper< css::container::XContainerListener > {}; + + class COMPHELPER_DLLPUBLIC OContainerListenerAdapter final : public OContainerListenerAdapter_Base + { + friend class OContainerListener; + + private: + css::uno::Reference< css::container::XContainer > + m_xContainer; + OContainerListener* m_pListener; + + virtual ~OContainerListenerAdapter() override; + + public: + OContainerListenerAdapter(OContainerListener* _pListener, + const css::uno::Reference< css::container::XContainer >& _rxContainer); + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // XContainerListener + virtual void SAL_CALL elementInserted( const css::container::ContainerEvent& Event ) override; + virtual void SAL_CALL elementRemoved( const css::container::ContainerEvent& Event ) override; + virtual void SAL_CALL elementReplaced( const css::container::ContainerEvent& Event ) override; + + /// dispose the object. No multiplexing anymore + void dispose(); + + }; + + +} // namespace dbaui + + +#endif // INCLUDED_COMPHELPER_CONTAINERMULTIPLEXER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/crashzone.hxx b/include/comphelper/crashzone.hxx new file mode 100644 index 000000000..f15f848cd --- /dev/null +++ b/include/comphelper/crashzone.hxx @@ -0,0 +1,70 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_CRASHZONE_H +#define INCLUDED_COMPHELPER_CRASHZONE_H + +#include <sal/config.h> + +#include <atomic> +#include <csignal> +#include <type_traits> + +struct CrashWatchdogTimingsValues +{ + /// delays to take various actions in 1/4 of a second increments. + int mnDisableEntries; + int const mnAbortAfter; +}; + +/** + * A generic class for detecting if a given crash or a lock-up came from a specific + * area of code (such as OpenGL). + * Use this helper to track that. + * The class is a template so that there can be multiple instances of static variables. + */ +template <typename Dummy> class CrashZone +{ +// gnEnterCount and gnLeaveCount are accessed both from multiple threads (cf. +// WatchdogThread::execute; so need to be of atomic type) and from signal handlers (cf. +// VCLExceptionSignal_impl; so need to be of lock-free atomic type). sig_atomic_t is chosen as +// the underlying type under the assumption that it is most likely to lead to an atomic type +// that is actually lock-free. However, gnEnterCount and gnLeaveCount are both monotonically +// increasing, so will eventually overflow, so the underlying type better be unsigned, which +// sig_atomic_t is not guaranteed to be: +#if !defined ARM32 || (defined ARM32 && defined __ARM_PCS_VFP) + using AtomicCounter = std::atomic<std::make_unsigned_t<std::sig_atomic_t>>; + static_assert(AtomicCounter::is_always_lock_free); +#else + using AtomicCounter = volatile std::make_unsigned_t<std::sig_atomic_t>; +#endif + + /// how many times have we entered a zone + static inline AtomicCounter gnEnterCount = 0; + /// how many times have we left a new zone + static inline AtomicCounter gnLeaveCount = 0; + +public: + CrashZone() { enter(); } + ~CrashZone() { leave(); } + static bool isInZone() { return gnEnterCount != gnLeaveCount; } + static const AtomicCounter& enterCount() { return gnEnterCount; } + // prefer creating instances to manually calling enter()/leave() + static void enter() { gnEnterCount++; } + static void leave() { gnLeaveCount++; } + // these should be implemented for each specific zone if needed + // static void hardDisable(); + // static const CrashWatchdogTimingsValues& getCrashWatchdogTimingsValues(); + // static void checkDebug(int nUnchanged, const CrashWatchdogTimingsValues& aTimingValues); + // static const char* name(); +}; + +#endif // INCLUDED_COMPHELPER_CRASHZONE_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/debuggerinfo.hxx b/include/comphelper/debuggerinfo.hxx new file mode 100644 index 000000000..8c4c0a4cb --- /dev/null +++ b/include/comphelper/debuggerinfo.hxx @@ -0,0 +1,38 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_DEBUGINFO_HXX +#define INCLUDED_COMPHELPER_DEBUGINFO_HXX + +#include <comphelper/comphelperdllapi.h> + +namespace comphelper +{ +#if defined DBG_UTIL +/// Returns true if the process is running with a debugger attached. +/// +/// This is useful to disable watchdogs or increase timeouts if they trigger +/// too soon while using a debugger. +COMPHELPER_DLLPUBLIC bool isDebuggerAttached(); +#endif + +// For detecting whether Valgrind is used, add valgrind to gb_Library_use_externals +// and then in code use: +// #if defined HAVE_VALGRIND_HEADERS +// #include <valgrind/memcheck.h> +// #endif +// ... +// #if defined HAVE_VALGRIND_HEADERS +// if( RUNNING_ON_VALGRIND ) + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_DEBUGINFO_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/dispatchcommand.hxx b/include/comphelper/dispatchcommand.hxx new file mode 100644 index 000000000..384536952 --- /dev/null +++ b/include/comphelper/dispatchcommand.hxx @@ -0,0 +1,43 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_DISPATCHCOMMAND_HXX +#define INCLUDED_COMPHELPER_DISPATCHCOMMAND_HXX + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/Reference.hxx> + +namespace com::sun::star::beans { struct PropertyValue; } +namespace com::sun::star::frame { class XDispatchResultListener; class XFrame; } +namespace com::sun::star::uno { template <typename > class Sequence; } + +namespace comphelper +{ + +/** Dispatch the given UNO command in the active frame. + + @param rCommand the command to dispatch, like ".uno:Bold". + + @return true on success. +*/ +COMPHELPER_DLLPUBLIC bool dispatchCommand(const OUString& rCommand, + const css::uno::Sequence<css::beans::PropertyValue>& rArguments, + const css::uno::Reference<css::frame::XDispatchResultListener>& rListener = css::uno::Reference<css::frame::XDispatchResultListener>()); + +COMPHELPER_DLLPUBLIC bool dispatchCommand(const OUString& rCommand, + const css::uno::Reference<css::frame::XFrame>& rFrame, + const css::uno::Sequence<css::beans::PropertyValue>& rArguments, + const css::uno::Reference<css::frame::XDispatchResultListener>& rListener = css::uno::Reference<css::frame::XDispatchResultListener>()); + +} + +#endif // INCLUDED_COMPHELPER_DISPATCHCOMMAND_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/docpasswordhelper.hxx b/include/comphelper/docpasswordhelper.hxx new file mode 100644 index 000000000..64d7ba978 --- /dev/null +++ b/include/comphelper/docpasswordhelper.hxx @@ -0,0 +1,447 @@ +/* -*- 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_COMPHELPER_DOCPASSWORDHELPER_HXX +#define INCLUDED_COMPHELPER_DOCPASSWORDHELPER_HXX + +#include <comphelper/comphelperdllapi.h> +#include <string_view> +#include <vector> +#include <comphelper/docpasswordrequest.hxx> +#include <comphelper/hash.hxx> + +namespace com::sun::star::task { class XInteractionHandler; } +namespace com::sun::star::beans { struct PropertyValue; } +namespace com::sun::star::beans { struct NamedValue; } + +namespace comphelper { + +enum class DocPasswordVerifierResult +{ + OK, + WrongPassword, + Abort +}; + + +/** Base class for a password verifier used by the DocPasswordHelper class + below. + + Users have to implement the virtual functions and pass an instance of the + verifier to one of the password request functions. + */ +class COMPHELPER_DLLPUBLIC IDocPasswordVerifier +{ +public: + virtual ~IDocPasswordVerifier(); + + /** Will be called every time a password needs to be verified. + + @param rPassword + The password to be verified + + @param o_rEncryptionData + Output parameter, that is filled with the EncryptionData generated + from the password. The data is filled only if the validation was + successful. + + @return The result of the verification. + - DocPasswordVerifierResult_OK, if and only if the passed password + is valid and can be used to process the related document. + - DocPasswordVerifierResult_WRONG_PASSWORD, if the password is + wrong. The user may be asked again for a new password. + - DocPasswordVerifierResult_ABORT, if an unrecoverable error + occurred while password verification. The password request loop + will be aborted. + */ + virtual DocPasswordVerifierResult verifyPassword( const OUString& rPassword, css::uno::Sequence< css::beans::NamedValue >& o_rEncryptionData ) = 0; + + /** Will be called every time an encryption data needs to be verified. + + @param rEncryptionData + The data will be validated + + @return The result of the verification. + - DocPasswordVerifierResult_OK, if and only if the passed encryption data + is valid and can be used to process the related document. + - DocPasswordVerifierResult_WRONG_PASSWORD, if the encryption data is + wrong. + - DocPasswordVerifierResult_ABORT, if an unrecoverable error + occurred while data verification. The password request loop + will be aborted. + */ + virtual DocPasswordVerifierResult verifyEncryptionData( const css::uno::Sequence< css::beans::NamedValue >& o_rEncryptionData ) = 0; + +}; + + +/** Helper that asks for a document password and checks its validity. + */ +class COMPHELPER_DLLPUBLIC DocPasswordHelper +{ +public: + + + /** This helper function generates the information related + to "Password to modify" provided by user. The result + sequence contains the hash and the algorithm-related + info. + + @param aString + The string for which the info should be generated + + @return + The sequence containing the hash and the algorithm-related info + */ + + static css::uno::Sequence< css::beans::PropertyValue > + GenerateNewModifyPasswordInfo( std::u16string_view aPassword ); + + /** This helper function converts a grab-bagged password, e.g. the + trackChanges password which has no complete inner equivalent to + the inner format. The result sequence contains the hash and the + algorithm-related info to use e.g. in IsModifyPasswordCorrect(). + + @param aInfo + The sequence containing the hash and the algorithm-related info + according to the OOXML origin, used by grab-bagging. + + @return + The sequence containing the hash and the algorithm-related info + in the inner format. + */ + + static css::uno::Sequence< css::beans::PropertyValue > ConvertPasswordInfo( + const css::uno::Sequence< css::beans::PropertyValue >& aInfo ); + + static css::uno::Sequence<css::beans::PropertyValue> + GenerateNewModifyPasswordInfoOOXML(std::u16string_view aPassword); + + /** This helper function allows to check whether + the "Password to modify" provided by user is the correct one. + + @param aString + The string containing the provided password + + @param aInfo + The sequence containing the hash and the algorithm-info + + @return + <TRUE/> if the password is correct one + <FALSE/> otherwise + */ + + static bool IsModifyPasswordCorrect( + std::u16string_view aPassword, + const css::uno::Sequence< css::beans::PropertyValue >& aInfo ); + + + /** This helper function generates the hash code based on the algorithm + specified by MS for "Password to modify" feature of Word. + + @param aString + The string for which the hash should be calculated + + @return + The hash represented by sal_uInt32 + */ + + static sal_uInt32 GetWordHashAsUINT32( std::u16string_view aString ); + + + /** This helper function generates the hash code based on the algorithm + specified by MS for "Password to modify" and passwords related to + table protection of Excel. + + @param aString + The string for which the hash should be calculated + + @param nEnc + The encoding that should be used to generate the 8-bit string + before the hash is generated + + @return + The hash represented by sal_uInt16 + */ + + static sal_uInt16 GetXLHashAsUINT16( + std::u16string_view aString, + rtl_TextEncoding nEnc = RTL_TEXTENCODING_UTF8 ); + + + /** This helper function generates the hash code based on the algorithm + specified by MS for "Password to modify" and passwords related to + table protection. + + @param aString + The string for which the hash should be calculated + + @return + The hash represented by sequence of bytes in BigEndian form + */ + + static css::uno::Sequence< sal_Int8 > GetXLHashAsSequence( + std::u16string_view aString ); + + + /** Convenience function to calculate a salted hash with iterations as + specified in https://msdn.microsoft.com/en-us/library/dd920692 for the + OOXML sheetProtection and fileSharing elements, or + https://msdn.microsoft.com/en-us/library/dd924776 and + https://msdn.microsoft.com/en-us/library/dd925430 for Standard and + Agile Encryption. + + @param rPassword + UTF-16 encoded string without leading BOM character + + @param rSaltValue + Base64 encoded salt that will be decoded and prepended to password + data. + + @param nSpinCount + If >0 the number of repeated iterations. + + @param eIterCount + If Hash::IterCount::APPEND, append iteration count as per + https://msdn.microsoft.com/en-us/library/dd920692 + If Hash::IterCount::PREPEND, prepend iteration count as per + https://msdn.microsoft.com/en-us/library/dd924776 and + https://msdn.microsoft.com/en-us/library/dd925430 + If Hash::IterCount::NONE, do not add the iteration count to hash + iterations. + + @param rAlgorithmName + One of "SHA-512", "SHA-256", ... as listed for AlgorithmName in + https://msdn.microsoft.com/en-us/library/dd920692 + or "SHA512", "SHA256", ... as listed for HashAlgorithm in + https://msdn.microsoft.com/en-us/library/dd925810 + that have a valid match in comphelper::HashType. If not, an + empty sequence is returned. Not all algorithm names are + supported. + + @return the raw hash value as sal_Int8 sequence. + */ + static css::uno::Sequence<sal_Int8> GetOoxHashAsSequence( + const OUString& rPassword, + std::u16string_view rSaltValue, + sal_uInt32 nSpinCount, + comphelper::Hash::IterCount eIterCount, + std::u16string_view rAlgorithmName); + + + /** Convenience function to calculate a salted hash with iterations as + specified in https://msdn.microsoft.com/en-us/library/dd920692 for the + OOXML sheetProtection and fileSharing elements, or + https://msdn.microsoft.com/en-us/library/dd924776 and + https://msdn.microsoft.com/en-us/library/dd925430 for Standard and + Agile Encryption. + + @param rPassword + UTF-16 encoded string without leading BOM character + + @param rSaltValue + Base64 encoded salt that will be decoded and prepended to password + data. + + @param nSpinCount + If >0 the number of repeated iterations. + + @param eIterCount + If Hash::IterCount::APPEND, append iteration count as per + https://msdn.microsoft.com/en-us/library/dd920692 + If Hash::IterCount::PREPEND, prepend iteration count as per + https://msdn.microsoft.com/en-us/library/dd924776 and + https://msdn.microsoft.com/en-us/library/dd925430 + If Hash::IterCount::NONE, do not add the iteration count to hash + iterations. + + @param rAlgorithmName + One of "SHA-512", "SHA-256", ... as listed for AlgorithmName in + https://msdn.microsoft.com/en-us/library/dd920692 + or "SHA512", "SHA256", ... as listed for HashAlgorithm in + https://msdn.microsoft.com/en-us/library/dd925810 + that have a valid match in comphelper::HashType. If not, an + empty sequence is returned. Not all algorithm names are + supported. + + @return the base64 encoded string of the hash value, that can be + compared against a stored base64 encoded hash value. + */ + static OUString GetOoxHashAsBase64( + const OUString& rPassword, + std::u16string_view rSaltValue, + sal_uInt32 nSpinCount, + comphelper::Hash::IterCount eIterCount, + std::u16string_view rAlgorithmName); + + + /** Convenience function to calculate a salted hash with iterations as + specified in https://msdn.microsoft.com/en-us/library/dd920692 for the + OOXML sheetProtection and fileSharing elements, or + https://msdn.microsoft.com/en-us/library/dd924776 and + https://msdn.microsoft.com/en-us/library/dd925430 for Standard and + Agile Encryption. + + @param rPassword + UTF-16 encoded string without leading BOM character + + @param rSaltValue + A raw salt that will be prepended to password data. + + @param nSpinCount + If >0 the number of repeated iterations. + + @param eIterCount + If Hash::IterCount::APPEND, append iteration count as per + https://msdn.microsoft.com/en-us/library/dd920692 + If Hash::IterCount::PREPEND, prepend iteration count as per + https://msdn.microsoft.com/en-us/library/dd924776 and + https://msdn.microsoft.com/en-us/library/dd925430 + If Hash::IterCount::NONE, do not add the iteration count to hash + iterations. + + @param rAlgorithmName + One of "SHA-512", "SHA-256", ... as listed for AlgorithmName in + https://msdn.microsoft.com/en-us/library/dd920692 + or "SHA512", "SHA256", ... as listed for HashAlgorithm in + https://msdn.microsoft.com/en-us/library/dd925810 + that have a valid match in comphelper::HashType. If not, an + empty sequence is returned. Not all algorithm names are + supported. + + @return the raw the hash value. + */ + static std::vector<unsigned char> GetOoxHashAsVector( + const OUString& rPassword, + const std::vector<unsigned char>& rSaltValue, + sal_uInt32 nSpinCount, + comphelper::Hash::IterCount eIterCount, + std::u16string_view rAlgorithmName); + + + /** This helper function generates a random sequence of bytes of + requested length. + */ + + static css::uno::Sequence< sal_Int8 > GenerateRandomByteSequence( + sal_Int32 nLength ); + + + /** This helper function generates a byte sequence representing the + key digest value used by MSCodec_Std97 codec. + */ + + static css::uno::Sequence< sal_Int8 > GenerateStd97Key( + std::u16string_view aPassword, + const css::uno::Sequence< sal_Int8 >& aDocId ); + + + /** This helper function generates a byte sequence representing the + key digest value used by MSCodec_Std97 codec. + */ + + static css::uno::Sequence< sal_Int8 > GenerateStd97Key( + const sal_uInt16 pPassData[16], + const css::uno::Sequence< sal_Int8 >& aDocId ); + + /** This helper function generates a byte sequence representing the + key digest value used by MSCodec_Std97 codec. + */ + + static css::uno::Sequence< sal_Int8 > GenerateStd97Key( + const sal_uInt16 pPassData[16], + const sal_uInt8 pDocId[16] ); + + + /** This helper function tries to request and verify a password to load a + protected document. + + First, the list of default passwords will be tried if provided. This is + needed by import filters for external file formats that have to check a + predefined password in some cases without asking the user for a + password. Every password is checked using the passed password verifier. + + If not successful, the passed password of a medium is tried, that has + been set e.g. by an API call to load a document. If existing, the + password is checked using the passed password verifier. + + If still not successful, the passed interaction handler is used to + request a password from the user. This will be repeated until the + passed password verifier validates the entered password, or if the user + chooses to cancel password input. + + @param rVerifier + The password verifier used to check every processed password. + + @param rMediaPassword + If not empty, will be passed to the password validator before + requesting a password from the user. This password usually should + be querried from a media descriptor. + + @param rxInteractHandler + The interaction handler that will be used to request a password + from the user, e.g. by showing a password input dialog. + + @param rDocumentUrl + The URL of the related document that will be shown in the password + input dialog. + + @param eRequestType + The password request type that will be passed to the + DocPasswordRequest object created internally. See + docpasswordrequest.hxx for more details. + + @param pDefaultPasswords + If not null, contains default passwords that will be tried before a + password will be requested from the media descriptor or the user. + + @param pbIsDefaultPassword + (output parameter) If not null, the type of the found password will + be returned. True means the password has been found in the passed + list of default passwords. False means the password has been taken + from the rMediaPassword parameter or has been entered by the user. + + @return + If not empty, contains the password that has been validated by the + passed password verifier. If empty, no valid password has been + found, or the user has chosen to cancel password input. + */ + static css::uno::Sequence< css::beans::NamedValue > requestAndVerifyDocPassword( + IDocPasswordVerifier& rVerifier, + const css::uno::Sequence< css::beans::NamedValue >& rMediaEncData, + const OUString& rMediaPassword, + const css::uno::Reference< css::task::XInteractionHandler >& rxInteractHandler, + const OUString& rDocumentUrl, + DocPasswordRequestType eRequestType, + const ::std::vector< OUString >* pDefaultPasswords = nullptr, + bool* pbIsDefaultPassword = nullptr ); + + static css::uno::Sequence< css::beans::NamedValue > decryptGpgSession( + const css::uno::Sequence< css::uno::Sequence< css::beans::NamedValue > >& rGpgProperties); + +private: + ~DocPasswordHelper(); +}; + + +} // namespace comphelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/docpasswordrequest.hxx b/include/comphelper/docpasswordrequest.hxx new file mode 100644 index 000000000..a4e8704eb --- /dev/null +++ b/include/comphelper/docpasswordrequest.hxx @@ -0,0 +1,110 @@ +/* -*- 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_COMPHELPER_DOCPASSWORDREQUEST_HXX +#define INCLUDED_COMPHELPER_DOCPASSWORDREQUEST_HXX + +#include <comphelper/comphelperdllapi.h> +#include <com/sun/star/task/PasswordRequestMode.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> +#include <cppuhelper/implbase.hxx> +#include <rtl/ref.hxx> + +namespace com::sun::star::task { class XInteractionAbort; } + +namespace comphelper { + +class PasswordContinuation; + + +/** Selects which UNO document password request type to use. */ +enum class DocPasswordRequestType +{ + Standard, /// Uses the standard com.sun.star.task.DocumentPasswordRequest request. + MS /// Uses the com.sun.star.task.DocumentMSPasswordRequest request. +}; + + +class COMPHELPER_DLLPUBLIC SimplePasswordRequest final : + public cppu::WeakImplHelper<css::task::XInteractionRequest> +{ +public: + explicit SimplePasswordRequest(); + virtual ~SimplePasswordRequest() override; + + bool isPassword() const; + + OUString getPassword() const; + +private: + SimplePasswordRequest(SimplePasswordRequest const&) = delete; + SimplePasswordRequest& operator=(SimplePasswordRequest const&) = delete; + + // XInteractionRequest + virtual css::uno::Any SAL_CALL getRequest() override; + virtual css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > SAL_CALL getContinuations() override; + +private: + css::uno::Any maRequest; + css::uno::Reference<css::task::XInteractionAbort> mxAbort; + rtl::Reference<PasswordContinuation> mxPassword; +}; + + +/** Implements the task.XInteractionRequest interface for requesting a password + string for a document. + */ +class COMPHELPER_DLLPUBLIC DocPasswordRequest final : + public cppu::WeakImplHelper<css::task::XInteractionRequest> +{ +public: + explicit DocPasswordRequest( + DocPasswordRequestType eType, + css::task::PasswordRequestMode eMode, + const OUString& rDocumentUrl, + bool bPasswordToModify = false ); + virtual ~DocPasswordRequest() override; + + bool isPassword() const; + + OUString getPassword() const; + + OUString getPasswordToModify() const; + bool getRecommendReadOnly() const; + +private: + DocPasswordRequest(DocPasswordRequest const&) = delete; + DocPasswordRequest& operator=(DocPasswordRequest const&) = delete; + + // XInteractionRequest + virtual css::uno::Any SAL_CALL getRequest() override; + virtual css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > SAL_CALL getContinuations() override; + +private: + css::uno::Any maRequest; + css::uno::Reference<css::task::XInteractionAbort> mxAbort; + rtl::Reference<PasswordContinuation> mxPassword; +}; + + +} // namespace comphelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/documentconstants.hxx b/include/comphelper/documentconstants.hxx new file mode 100644 index 000000000..aafa84e75 --- /dev/null +++ b/include/comphelper/documentconstants.hxx @@ -0,0 +1,130 @@ +/* -*- 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_COMPHELPER_DOCUMENTCONSTANTS_HXX +#define INCLUDED_COMPHELPER_DOCUMENTCONSTANTS_HXX + +#include <o3tl/typed_flags_set.hxx> +#include <rtl/ustring.hxx> + +// formats of SO6/7 +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_WRITER_ASCII = u"application/vnd.sun.xml.writer"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII = u"application/vnd.sun.xml.writer.web"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII = u"application/vnd.sun.xml.writer.global"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_DRAW_ASCII = u"application/vnd.sun.xml.draw"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_IMPRESS_ASCII = u"application/vnd.sun.xml.impress"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_CALC_ASCII = u"application/vnd.sun.xml.calc"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_CHART_ASCII = u"application/vnd.sun.xml.chart"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_MATH_ASCII = u"application/vnd.sun.xml.math"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_BASE_ASCII = u"application/vnd.sun.xml.base"; + +// template formats of SO6/7 +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII = u"application/vnd.sun.xml.writer.template"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII = u"application/vnd.sun.xml.draw.template"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII = u"application/vnd.sun.xml.impress.template"; +inline constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII = u"application/vnd.sun.xml.calc.template"; + +// formats of SO8 +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII = u"application/vnd.oasis.opendocument.text"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII = u"application/vnd.oasis.opendocument.text-web"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII = u"application/vnd.oasis.opendocument.text-master"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII = u"application/vnd.oasis.opendocument.graphics"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII = u"application/vnd.oasis.opendocument.presentation"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII = u"application/vnd.oasis.opendocument.spreadsheet"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII = u"application/vnd.oasis.opendocument.chart"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII = u"application/vnd.oasis.opendocument.formula"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII = u"application/vnd.oasis.opendocument.base"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII = u"application/vnd.sun.xml.report"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII = u"application/vnd.sun.xml.report.chart"; + +// template formats of SO8 +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII = u"application/vnd.oasis.opendocument.text-template"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_TEMPLATE_ASCII = u"application/vnd.oasis.opendocument.text-master-template"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII = u"application/vnd.oasis.opendocument.graphics-template"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII = u"application/vnd.oasis.opendocument.presentation-template"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII = u"application/vnd.oasis.opendocument.spreadsheet-template"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII = u"application/vnd.oasis.opendocument.chart-template"; +inline constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII = u"application/vnd.oasis.opendocument.formula-template"; + + +// ODF versions +inline constexpr OUStringLiteral ODFVER_010_TEXT = u"1.0"; +inline constexpr OUStringLiteral ODFVER_011_TEXT = u"1.1"; +inline constexpr OUStringLiteral ODFVER_012_TEXT = u"1.2"; +inline constexpr OUStringLiteral ODFVER_013_TEXT = u"1.3"; + +// filter flags +// TODO/LATER: The flags should be part of the UNO specification +// +// http://www.mail-archive.com/dev@openoffice.org/msg05047.html says: +// +// I can just sum up what comes into my mind, hope I don't miss one: +// +// Import - should be self explaining +// Export - should be self explaining +// Template - deprecated +// TemplatePath - filter for a documenttemplate +// Own - one of the OOo file formats +// Alien - no zip container based format +// Preferred - preferred filter for a particular type +// 3rdPartyFilter - implemented as a UNO component +// Default - default filter for this document type +// Exotic - an unusual/legacy file-format, we don't normally see +// +// (The 3rdPartyFilter flag is here called StarONE) +// +enum class SfxFilterFlags +{ + NONE = 0, + IMPORT = 0x00000001, + EXPORT = 0x00000002, + TEMPLATE = 0x00000004, + INTERNAL = 0x00000008, + TEMPLATEPATH = 0x00000010, + OWN = 0x00000020, + ALIEN = 0x00000040, + + DEFAULT = 0x00000100, + SUPPORTSSELECTION = 0x00000400, + NOTINFILEDLG = 0x00001000, + + OPENREADONLY = 0x00010000, + MUSTINSTALL = 0x00020000, + CONSULTSERVICE = 0x00040000, + STARONEFILTER = 0x00080000, + PACKED = 0x00100000, + EXOTIC = 0x00200000, + COMBINED = 0x00800000, + + ENCRYPTION = 0x01000000, + PASSWORDTOMODIFY = 0x02000000, + GPGENCRYPTION = 0x04000000, + PREFERED = 0x10000000, + STARTPRESENTATION = 0x20000000, + SUPPORTSSIGNING = 0x40000000, +}; + +namespace o3tl +{ + template<> struct typed_flags<SfxFilterFlags> : is_typed_flags<SfxFilterFlags, 0x77bf157f> {}; +} + +#define SFX_FILTER_NOTINSTALLED (SfxFilterFlags::MUSTINSTALL | SfxFilterFlags::CONSULTSERVICE) + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/documentinfo.hxx b/include/comphelper/documentinfo.hxx new file mode 100644 index 000000000..a7002120a --- /dev/null +++ b/include/comphelper/documentinfo.hxx @@ -0,0 +1,51 @@ +/* -*- 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_COMPHELPER_DOCUMENTINFO_HXX +#define INCLUDED_COMPHELPER_DOCUMENTINFO_HXX + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> + +namespace com::sun::star::frame { class XModel; } +namespace com::sun::star::uno { template <class interface_type> class Reference; } + + +namespace comphelper { + + + //= DocumentInfo + + namespace DocumentInfo + { + /** retrieves the UI title of the given document + */ + COMPHELPER_DLLPUBLIC OUString getDocumentTitle( const css::uno::Reference< css::frame::XModel >& _rxDocument ); + + /** notify that this document contains a macro event handler + */ + COMPHELPER_DLLPUBLIC void notifyMacroEventRead( const css::uno::Reference< css::frame::XModel >& _rxDocument ); + } + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_DOCUMENTINFO_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/doublecheckedinit.hxx b/include/comphelper/doublecheckedinit.hxx new file mode 100644 index 000000000..200a9c88c --- /dev/null +++ b/include/comphelper/doublecheckedinit.hxx @@ -0,0 +1,64 @@ +/* -*- 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_COMPHELPER_DOUBLECHECKEDINIT_HXX +#define INCLUDED_COMPHELPER_DOUBLECHECKEDINIT_HXX + +#include <osl/getglobalmutex.hxx> + +#include <atomic> +// HACK: <atomic> includes <stdbool.h>, which in some Clang versions does '#define bool bool', +// which confuses clang plugins. +#undef bool +#include <functional> + +namespace comphelper +{ +/** + * Thread-safe singleton creation. + * + * It is normally sufficient to create singletons using static variables in a function. + * This function is only for use cases that have a more complex lifetime of the object, + * such as when the object may require specific cleanup or may be created more times + * (e.g. when there is a "singleton" per each instance of another object). + */ +template <typename Type, typename Function = std::function<Type*()>, + typename Guard = osl::MutexGuard, typename GuardCtor = osl::GetGlobalMutex> +static inline Type* doubleCheckedInit(std::atomic<Type*>& pointer, Function function, + GuardCtor guardCtor = osl::GetGlobalMutex()) +{ + Type* p = pointer.load(std::memory_order_acquire); + if (!p) + { + Guard guard(guardCtor()); + p = pointer.load(std::memory_order_relaxed); + if (!p) + { + p = function(); + pointer.store(p, std::memory_order_release); + } + } + return p; +} + +} // namespace + +#endif // INCLUDED_COMPHELPER_DOUBLECHECKEDINIT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/embeddedobjectcontainer.hxx b/include/comphelper/embeddedobjectcontainer.hxx new file mode 100644 index 000000000..cc040da15 --- /dev/null +++ b/include/comphelper/embeddedobjectcontainer.hxx @@ -0,0 +1,193 @@ +/* -*- 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_COMPHELPER_EMBEDDEDOBJECTCONTAINER_HXX +#define INCLUDED_COMPHELPER_EMBEDDEDOBJECTCONTAINER_HXX + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/Sequence.h> +#include <comphelper/comphelperdllapi.h> + +#include <rtl/ustring.hxx> +#include <memory> + +namespace com::sun::star::beans { struct PropertyValue; } +namespace com::sun::star::embed { class XEmbeddedObject; } +namespace com::sun::star::embed { class XStorage; } +namespace com::sun::star::io { class XInputStream; } +namespace com::sun::star::task { class XInteractionHandler; } +namespace com::sun::star::uno { class XInterface; } + +namespace comphelper +{ + class EmbeddedObjectContainer; + /** Helper interface to give access to some common object which replace the SfxObjectShell + */ + class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI IEmbeddedHelper + { + public: + virtual EmbeddedObjectContainer& getEmbeddedObjectContainer() const = 0; + virtual css::uno::Reference < css::embed::XStorage > getStorage() const = 0; + virtual css::uno::Reference< css::task::XInteractionHandler > getInteractionHandler() const = 0; + virtual bool isEnableSetModified() const = 0; + virtual OUString getDocumentBaseURL() const = 0; + + protected: + ~IEmbeddedHelper() {} + }; + +struct EmbedImpl; +class COMPHELPER_DLLPUBLIC EmbeddedObjectContainer +{ + std::unique_ptr<EmbedImpl> pImpl; + + css::uno::Reference < css::embed::XEmbeddedObject > Get_Impl( const OUString&, + const css::uno::Reference < css::embed::XEmbeddedObject >& xCopy, + OUString const* pBaseURL); + +public: + // add an embedded object to the container storage + bool StoreEmbeddedObject( + const css::uno::Reference<css::embed::XEmbeddedObject>& xObj, OUString& rName, bool bCopy, + const OUString& rSrcShellID, const OUString& rDestShellID ); + + // add an embedded object that has been imported from the container storage - should only be called by filters! + void AddEmbeddedObject( const css::uno::Reference < css::embed::XEmbeddedObject >&, const OUString& ); + + EmbeddedObjectContainer(); + EmbeddedObjectContainer( const css::uno::Reference < css::embed::XStorage >& ); + EmbeddedObjectContainer( const css::uno::Reference < css::embed::XStorage >&, + const css::uno::Reference < css::uno::XInterface >& ); + ~EmbeddedObjectContainer(); + + void SwitchPersistence( const css::uno::Reference < css::embed::XStorage >& ); + bool CommitImageSubStorage(); + void ReleaseImageSubStorage(); + + OUString CreateUniqueObjectName(); + + // get a list of object names that have been added so far + css::uno::Sequence < OUString > GetObjectNames() const; + + // check for existence of objects at all + bool HasEmbeddedObjects() const; + + // check existence of an object - either by identity or by name + bool HasEmbeddedObject( const OUString& ); + bool HasEmbeddedObject( const css::uno::Reference < css::embed::XEmbeddedObject >& ) const; + bool HasInstantiatedEmbeddedObject( const OUString& ); + + // get the object name of an object - this is the persist name if the object has persistence + OUString GetEmbeddedObjectName( const css::uno::Reference < css::embed::XEmbeddedObject >& ) const; + + // retrieve an embedded object by name that either has been added already or is available in the container storage + css::uno::Reference<css::embed::XEmbeddedObject> GetEmbeddedObject(const OUString&, OUString const* pBaseURL = nullptr); + + // create an object from a ClassId + css::uno::Reference < css::embed::XEmbeddedObject > + CreateEmbeddedObject( const css::uno::Sequence < sal_Int8 >&, OUString&, + OUString const* pBaseURL = nullptr ); + + css::uno::Reference < css::embed::XEmbeddedObject > + CreateEmbeddedObject( const css::uno::Sequence < sal_Int8 >&, + const css::uno::Sequence < css::beans::PropertyValue >&, OUString&, + OUString const* pBaseURL = nullptr ); + + // insert an embedded object into the container - objects persistent representation will be added to the storage + bool InsertEmbeddedObject( const css::uno::Reference < css::embed::XEmbeddedObject >&, OUString& ); + + // load an embedded object from a MediaDescriptor and insert it into the container + // a new object will be created from the new content and returned + css::uno::Reference < css::embed::XEmbeddedObject > + InsertEmbeddedObject( const css::uno::Sequence < css::beans::PropertyValue >&, OUString& rName, OUString const* pBaseURL = nullptr); + + // create an embedded link based on a MediaDescriptor and insert it into the container + // a new object will be created from the new content and returned + css::uno::Reference < css::embed::XEmbeddedObject > + InsertEmbeddedLink( const css::uno::Sequence < css::beans::PropertyValue >&, OUString& ); + + // create an object from a stream that contains its persistent representation and insert it as usual (usually called from clipboard) + // a new object will be created from the new content and returned + css::uno::Reference < css::embed::XEmbeddedObject > + InsertEmbeddedObject( const css::uno::Reference < css::io::XInputStream >&, OUString& ); + + // copy an embedded object into the storage, open the new copy and return it + css::uno::Reference <css::embed::XEmbeddedObject> CopyAndGetEmbeddedObject( + EmbeddedObjectContainer& rSrc, const css::uno::Reference <css::embed::XEmbeddedObject>& xObj, OUString& rName, + const OUString& rSrcShellID, const OUString& rDestShellID ); + + // remove an embedded object from the container and from the storage; if object can't be closed + // #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+ + void RemoveEmbeddedObject( const OUString& rName, bool bKeepToTempStorage = true); + bool RemoveEmbeddedObject( const css::uno::Reference < css::embed::XEmbeddedObject >&, bool bKeepToTempStorage = true); + + // close and remove an embedded object from the container without removing it from the storage + void CloseEmbeddedObject( const css::uno::Reference < css::embed::XEmbeddedObject >& ); + + // move an embedded object to another container (keep the persistent name) + bool MoveEmbeddedObject( const OUString& rName, EmbeddedObjectContainer& ); + + // get the stored graphical representation for the object + css::uno::Reference < css::io::XInputStream > GetGraphicStream( const css::uno::Reference < css::embed::XEmbeddedObject >&, OUString* pMediaType=nullptr ); + + // get the stored graphical representation by the object name + css::uno::Reference < css::io::XInputStream > GetGraphicStream( const OUString& aName, OUString* pMediaType=nullptr ); + + // add a graphical representation for an object + bool InsertGraphicStream( const css::uno::Reference < css::io::XInputStream >& rStream, const OUString& rObjectName, const OUString& rMediaType ); + + // try to add a graphical representation for an object in optimized way ( might fail ) + bool InsertGraphicStreamDirectly( const css::uno::Reference < css::io::XInputStream >& rStream, const OUString& rObjectName, const OUString& rMediaType ); + + // remove a graphical representation for an object + void RemoveGraphicStream( const OUString& rObjectName ); + + // copy the graphical representation from different container + bool TryToCopyGraphReplacement( EmbeddedObjectContainer& rSrc, + const OUString& aOrigName, + const OUString& aTargetName ); + + void CloseEmbeddedObjects(); + bool StoreChildren(bool _bOasisFormat,bool _bObjectsOnly); + bool StoreAsChildren( bool _bOasisFormat + ,bool _bCreateEmbedded + ,bool _bAutoSaveEvent + ,const css::uno::Reference < css::embed::XStorage >& _xStorage); + + static css::uno::Reference< css::io::XInputStream > GetGraphicReplacementStream( + sal_Int64 nViewAspect, + const css::uno::Reference < css::embed::XEmbeddedObject >&, + OUString* pMediaType ); + + /** call setPersistentEntry for each embedded object in the container + * + * \param _xStorage The storage where to store the objects. + * \param _bClearModifiedFlag If <TRUE/> then the modified flag will be set to <FALSE/> otherwise nothing happen. + * \return <FALSE/> if no error occurred, otherwise <TRUE/>. + */ + bool SetPersistentEntries(const css::uno::Reference< css::embed::XStorage >& _xStorage,bool _bClearModifiedFlag = true); + + bool getUserAllowsLinkUpdate() const; + void setUserAllowsLinkUpdate(bool bNew); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/enumhelper.hxx b/include/comphelper/enumhelper.hxx new file mode 100644 index 000000000..fb26de489 --- /dev/null +++ b/include/comphelper/enumhelper.hxx @@ -0,0 +1,122 @@ +/* -*- 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_COMPHELPER_ENUMHELPER_HXX +#define INCLUDED_COMPHELPER_ENUMHELPER_HXX + +#include <com/sun/star/container/XEnumeration.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <comphelper/comphelperdllapi.h> +#include <cppuhelper/implbase.hxx> +#include <mutex> +#include <variant> +#include <vector> + +namespace com::sun::star::container { class XIndexAccess; } +namespace com::sun::star::container { class XNameAccess; } + +namespace comphelper +{ + +/** provides a com.sun.star.container::XEnumeration access based + on an object implementing the com.sun.star.container::XNameAccess interface +*/ +class COMPHELPER_DLLPUBLIC OEnumerationByName final : + public ::cppu::WeakImplHelper< css::container::XEnumeration , + css::lang::XEventListener > +{ + std::variant<css::uno::Sequence< OUString >, std::vector<OUString>> m_aNames; + css::uno::Reference< css::container::XNameAccess > m_xAccess; + sal_Int32 m_nPos; + bool m_bListening; + std::mutex m_aLock; + +public: + OEnumerationByName(const css::uno::Reference< css::container::XNameAccess > _xAccess); + OEnumerationByName(const css::uno::Reference< css::container::XNameAccess > _xAccess, + std::vector<OUString> _aNames ); + virtual ~OEnumerationByName() override; + + virtual sal_Bool SAL_CALL hasMoreElements( ) override; + virtual css::uno::Any SAL_CALL nextElement( ) override; + + virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) override; + +private: + sal_Int32 getLength() const; + const OUString& getElement(sal_Int32 nIndex) const; + COMPHELPER_DLLPRIVATE void impl_startDisposeListening(); + COMPHELPER_DLLPRIVATE void impl_stopDisposeListening(); +}; + +/** provides a com.sun.star.container::XEnumeration access based + on an object implementing the com.sun.star.container::XNameAccess interface +*/ +class COMPHELPER_DLLPUBLIC OEnumerationByIndex final : + public ::cppu::WeakImplHelper< css::container::XEnumeration , + css::lang::XEventListener > +{ + css::uno::Reference< css::container::XIndexAccess > m_xAccess; + sal_Int32 m_nPos; + bool m_bListening; + std::mutex m_aLock; + +public: + OEnumerationByIndex(css::uno::Reference< css::container::XIndexAccess > _xAccess); + virtual ~OEnumerationByIndex() override; + + virtual sal_Bool SAL_CALL hasMoreElements( ) override; + virtual css::uno::Any SAL_CALL nextElement( ) override; + + virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) override; + +private: + COMPHELPER_DLLPRIVATE void impl_startDisposeListening(); + COMPHELPER_DLLPRIVATE void impl_stopDisposeListening(); +}; + +// this is the way that works for ENABLE_LTO with MSVC 2013 +class SAL_DLLPUBLIC_TEMPLATE OAnyEnumeration_BASE + : public ::cppu::WeakImplHelper<css::container::XEnumeration> {}; + +/** provides a com.sun.star.container::XEnumeration + for an outside set vector of Any's. + +*/ +class COMPHELPER_DLLPUBLIC OAnyEnumeration final : + public OAnyEnumeration_BASE +{ + sal_Int32 m_nPos; + css::uno::Sequence< css::uno::Any > m_lItems; + std::mutex m_aLock; + +public: + OAnyEnumeration(const css::uno::Sequence< css::uno::Any >& lItems); + virtual ~OAnyEnumeration() override; + + virtual sal_Bool SAL_CALL hasMoreElements( ) override; + virtual css::uno::Any SAL_CALL nextElement( ) override; + +}; + +} + +#endif // INCLUDED_COMPHELPER_ENUMHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/eventattachermgr.hxx b/include/comphelper/eventattachermgr.hxx new file mode 100644 index 000000000..4a2a99909 --- /dev/null +++ b/include/comphelper/eventattachermgr.hxx @@ -0,0 +1,48 @@ +/* -*- 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_COMPHELPER_EVENTATTACHERMGR_HXX +#define INCLUDED_COMPHELPER_EVENTATTACHERMGR_HXX + +#include <com/sun/star/uno/Reference.h> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star { +namespace uno { + class XComponentContext; +} +namespace script { + class XEventAttacherManager; +} +} + + +namespace comphelper +{ + +/// @throws css::uno::Exception +COMPHELPER_DLLPUBLIC css::uno::Reference< css::script::XEventAttacherManager > +createEventAttacherManager( + const css::uno::Reference< css::uno::XComponentContext > & rxContext ); + +} + +#endif // INCLUDED_COMPHELPER_EVENTATTACHERMGR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/evtlistenerhlp.hxx b/include/comphelper/evtlistenerhlp.hxx new file mode 100644 index 000000000..212d94662 --- /dev/null +++ b/include/comphelper/evtlistenerhlp.hxx @@ -0,0 +1,49 @@ +/* -*- 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_COMPHELPER_EVTLISTENERHLP_HXX +#define INCLUDED_COMPHELPER_EVTLISTENERHLP_HXX + +#include <config_options.h> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/lang/XEventListener.hpp> +#include <cppuhelper/weakref.hxx> +#include <comphelper/comphelperdllapi.h> + + +namespace comphelper +{ + + + //= OCommandsListener + // is helper class to avoid a cycle in refcount between the XEventListener + // and the member XComponent + + class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OEventListenerHelper final : public ::cppu::WeakImplHelper< css::lang::XEventListener > + { + css::uno::WeakReference< css::lang::XEventListener> m_xListener; + public: + OEventListenerHelper(const css::uno::Reference< css::lang::XEventListener>& _rxListener); + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + }; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_EVTLISTENERHLP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/evtmethodhelper.hxx b/include/comphelper/evtmethodhelper.hxx new file mode 100644 index 000000000..f420b1869 --- /dev/null +++ b/include/comphelper/evtmethodhelper.hxx @@ -0,0 +1,32 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/uno/Sequence.h> +#include <comphelper/comphelperdllapi.h> + +namespace comphelper +{ +COMPHELPER_DLLPUBLIC css::uno::Sequence<OUString> +getEventMethodsForType(const css::uno::Type& type); + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/extract.hxx b/include/comphelper/extract.hxx new file mode 100644 index 000000000..c8ab9c6e6 --- /dev/null +++ b/include/comphelper/extract.hxx @@ -0,0 +1,113 @@ +/* -*- 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_COMPHELPER_EXTRACT_HXX +#define INCLUDED_COMPHELPER_EXTRACT_HXX + +#include <sal/config.h> + +#include <cassert> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/TypeClass.hpp> +#include <com/sun/star/uno/Type.h> +#include <com/sun/star/uno/Any.hxx> + +namespace cppu +{ +/** + * Sets enum from int32 value. This function does NOT check for valid enum values! + * + * @param nEnum int32 enum value + * @param rType enum type + * @return enum or empty any. + */ +inline css::uno::Any int2enum(sal_Int32 nEnum, const css::uno::Type& rType) +{ + assert(rType.getTypeClass() == css::uno::TypeClass_ENUM); + return css::uno::Any(&nEnum, rType); +} + +/** + * Sets int32 from enum or int in any. + * + * @param[out] rnEnum int32 enum value + * @param rAny enum or int + * @retval true if enum or int value was set + * @retval false otherwise + */ +inline bool enum2int(sal_Int32& rnEnum, const css::uno::Any& rAny) +{ + if (rAny.getValueTypeClass() == css::uno::TypeClass_ENUM) + { + rnEnum = *static_cast<const sal_Int32*>(rAny.getValue()); + return true; + } + + return rAny >>= rnEnum; +} + +/** + * Sets int32 from enum or int in any with additional typecheck + * + * @param[out] eRet the enum value as int. If there is no enum of the given type + * a css::lang::IllegalArgumentException is thrown + * @param rAny enum or int + * @throws css::lang::IllegalArgumentException + */ +template <typename E> inline void any2enum(E& eRet, const css::uno::Any& rAny) +{ + // check for typesafe enum + if (!(rAny >>= eRet)) + { + // if not enum, maybe integer? + sal_Int32 nValue = 0; + if (!(rAny >>= nValue)) + throw css::lang::IllegalArgumentException(); + + eRet = static_cast<E>(nValue); + } +} + +/** + * Extracts a boolean either as a bool or an integer from + * an any. If there is no bool or integer inside the any + * a css::lang::IllegalArgumentException is thrown + * + * @throws css::lang::IllegalArgumentException + */ +inline bool any2bool(const css::uno::Any& rAny) +{ + bool b; + if (rAny >>= b) + { + return b; + } + else + { + sal_Int32 nValue = 0; + if (!(rAny >>= nValue)) + throw css::lang::IllegalArgumentException(); + return nValue != 0; + } +} +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/fileformat.h b/include/comphelper/fileformat.h new file mode 100644 index 000000000..7eabf5829 --- /dev/null +++ b/include/comphelper/fileformat.h @@ -0,0 +1,34 @@ +/* -*- 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_COMPHELPER_FILEFORMAT_H +#define INCLUDED_COMPHELPER_FILEFORMAT_H + +/* file format versions *************************************************/ + +#define SOFFICE_FILEFORMAT_31 3450 +#define SOFFICE_FILEFORMAT_40 3580 +#define SOFFICE_FILEFORMAT_50 5050 +#define SOFFICE_FILEFORMAT_60 6200 +#define SOFFICE_FILEFORMAT_8 6800 +#define SOFFICE_FILEFORMAT_CURRENT SOFFICE_FILEFORMAT_8 + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/fileurl.hxx b/include/comphelper/fileurl.hxx new file mode 100644 index 000000000..27ac6b576 --- /dev/null +++ b/include/comphelper/fileurl.hxx @@ -0,0 +1,36 @@ +/* -*- 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_COMPHELPER_FILEURL_HXX +#define INCLUDED_COMPHELPER_FILEURL_HXX + +#include <sal/config.h> + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> + +namespace comphelper +{ +// Return true iff url is an absolute URL of "file" scheme: +COMPHELPER_DLLPUBLIC bool isFileUrl(OUString const& url); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/flagguard.hxx b/include/comphelper/flagguard.hxx new file mode 100644 index 000000000..14eee07a8 --- /dev/null +++ b/include/comphelper/flagguard.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_COMPHELPER_FLAGGUARD_HXX +#define INCLUDED_COMPHELPER_FLAGGUARD_HXX + +#include <comphelper/scopeguard.hxx> +#include <utility> + +namespace comphelper +{ + + //= ValueRestorationGuard + + // note: can't store the originalValue in a ValueRestorationGuard member, + // because it will be used from base class dtor + template <typename T> struct ValueRestorationGuard_Impl + { + T& rVal; + T const originalValue; + ValueRestorationGuard_Impl(T& i_valRef) + : rVal(i_valRef), originalValue(i_valRef) {} + void operator()() + { + rVal = originalValue; + } + }; + + template <typename T> + class ValueRestorationGuard : public ScopeGuard<ValueRestorationGuard_Impl<T>> + { + public: + template <typename T1> + ValueRestorationGuard(T& i_valRef, T1&& i_temporaryValue) + : ScopeGuard<ValueRestorationGuard_Impl<T>>(ValueRestorationGuard_Impl(i_valRef)) + { + i_valRef = std::forward<T1>(i_temporaryValue); + } + }; + + typedef ValueRestorationGuard<bool> FlagRestorationGuard; + + //= FlagGuard + + // Guarantees that the flag is true within the scope of the guard, and is set to false after + // its destruction, regardless of initial flag value + class FlagGuard : public FlagRestorationGuard + { + public: + // Set flag to false before passing its reference to base class ctor, so that it would be + // reset back to false in base class dtor + explicit FlagGuard(bool& i_flagRef) + : FlagRestorationGuard((i_flagRef = false), true) + { + } + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_FLAGGUARD_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/genericpropertyset.hxx b/include/comphelper/genericpropertyset.hxx new file mode 100644 index 000000000..2450ef047 --- /dev/null +++ b/include/comphelper/genericpropertyset.hxx @@ -0,0 +1,43 @@ +/* -*- 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_COMPHELPER_GENERICPROPERTYSET_HXX +#define INCLUDED_COMPHELPER_GENERICPROPERTYSET_HXX + +#include <com/sun/star/uno/Reference.h> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::beans +{ +class XPropertySet; +} +namespace comphelper +{ +class PropertySetInfo; +} + +namespace comphelper +{ +COMPHELPER_DLLPUBLIC css::uno::Reference<css::beans::XPropertySet> +GenericPropertySet_CreateInstance(PropertySetInfo* pInfo); +} + +#endif // INCLUDED_COMPHELPER_GENERICPROPERTYSET_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/getexpandeduri.hxx b/include/comphelper/getexpandeduri.hxx new file mode 100644 index 000000000..5b75c43d4 --- /dev/null +++ b/include/comphelper/getexpandeduri.hxx @@ -0,0 +1,42 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_GETEXPANDEDURI_HXX +#define INCLUDED_COMPHELPER_GETEXPANDEDURI_HXX + +#include <sal/config.h> + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> + +namespace com::sun::star::uno +{ +class XComponentContext; +} +namespace com::sun::star::uno +{ +template <typename> class Reference; +} + +namespace comphelper +{ +/** + A helper function to expand vnd.sun.star.expand URLs. + + If the given URI is a vnd.sun.star.expand URL, it is expanded (using the + given component context's com.sun.star.util.theMacroExpander); otherwise it + is returned unchanged. +*/ +COMPHELPER_DLLPUBLIC OUString getExpandedUri( + css::uno::Reference<css::uno::XComponentContext> const& context, OUString const& uri); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/graphicmimetype.hxx b/include/comphelper/graphicmimetype.hxx new file mode 100644 index 000000000..94a3cd3cd --- /dev/null +++ b/include/comphelper/graphicmimetype.hxx @@ -0,0 +1,49 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_GMH_HXX +#define INCLUDED_COMPHELPER_GMH_HXX + +#include <sal/config.h> + +#include <string_view> + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> +#include <vcl/salctype.hxx> + +#include <com/sun/star/uno/Reference.h> + +namespace com::sun::star::graphic +{ +class XGraphic; +} +namespace com::sun::star::io +{ +class XInputStream; +} + +namespace comphelper +{ +class COMPHELPER_DLLPUBLIC GraphicMimeTypeHelper +{ +public: + static OUString GetMimeTypeForExtension(std::string_view rExt); + static OUString + GetMimeTypeForXGraphic(const css::uno::Reference<css::graphic::XGraphic>& xGraphic); + static OUString + GetMimeTypeForImageStream(const css::uno::Reference<css::io::XInputStream>& xInputStream); + static OUString GetMimeTypeForConvertDataFormat(ConvertDataFormat convertDataFormat); + static char const* GetExtensionForConvertDataFormat(ConvertDataFormat nFormat); +}; +} + +#endif // INCLUDED_COMPHELPER_GMH_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/guarding.hxx b/include/comphelper/guarding.hxx new file mode 100644 index 000000000..3bbf4ac71 --- /dev/null +++ b/include/comphelper/guarding.hxx @@ -0,0 +1,55 @@ +/* -*- 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_COMPHELPER_GUARDING_HXX +#define INCLUDED_COMPHELPER_GUARDING_HXX + +namespace osl { class Mutex; } + + +namespace comphelper +{ + + +// = class MutexRelease - + + +/** opposite of OGuard :) + (a mutex is released within the constructor and acquired within the destructor) + use only when you're sure the mutex is acquired ! +*/ +template <class MUTEX> +class ORelease +{ + MUTEX& m_rMutex; + +public: + ORelease(MUTEX& _rMutex) : m_rMutex(_rMutex) { _rMutex.release(); } + ~ORelease() { m_rMutex.acquire(); } +}; + +typedef ORelease< ::osl::Mutex > MutexRelease; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_GUARDING_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/hash.hxx b/include/comphelper/hash.hxx new file mode 100644 index 000000000..54ab3a251 --- /dev/null +++ b/include/comphelper/hash.hxx @@ -0,0 +1,121 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_HASH_HXX +#define INCLUDED_COMPHELPER_HASH_HXX + +#include <comphelper/comphelperdllapi.h> +#include <rtl/digest.h> + +#include <memory> +#include <vector> + +namespace rtl { + class OUString; +} + +namespace comphelper { + +enum class HashType +{ + MD5, + SHA1, + SHA256, + SHA512 +}; + +const sal_uInt32 MD5_HASH_LENGTH = RTL_DIGEST_LENGTH_MD5; +const sal_uInt32 SHA1_HASH_LENGTH = RTL_DIGEST_LENGTH_SHA1; +const sal_uInt32 SHA256_HASH_LENGTH = 32; +const sal_uInt32 SHA512_HASH_LENGTH = 64; + +struct HashImpl; + +class COMPHELPER_DLLPUBLIC Hash +{ +private: + std::unique_ptr<HashImpl> mpImpl; + +public: + + enum class IterCount + { + NONE, /// Iteration count not added to hash iterations. + PREPEND, /// Iteration count prepended to hash iterations. + APPEND /// Iteration count appended to hash iterations. + }; + + Hash(HashType eType); + ~Hash(); + + void update(const unsigned char* pInput, size_t length); + + std::vector<unsigned char> finalize(); + + static std::vector<unsigned char> calculateHash(const unsigned char* pInput, size_t length, HashType eType); + + /** Calculate hash value with salt (pSalt,nSaltLen) prepended to password + (pInput,nLength) and repeated iterations run if nSpinCount>0. + + This implements the algorithms as specified in + https://msdn.microsoft.com/en-us/library/dd920692 or + https://msdn.microsoft.com/en-us/library/dd924776 and + https://msdn.microsoft.com/en-us/library/dd925430 + + @param pSalt + may be nullptr thus no salt prepended + + @param nSpinCount + If >0, repeat nSpinCount iterations. For each iteration, the + previous iteration's result plus a 4 byte value (0-based, + little endian) containing the number of the iteration prepended + or appended to the hash value is the input for the next + iteration. + + @param eIterCount + If IterCount::APPEND, append iteration count as per + https://msdn.microsoft.com/en-us/library/dd920692 + If IterCount::PREPEND, prepend iteration count as per + https://msdn.microsoft.com/en-us/library/dd924776 and + https://msdn.microsoft.com/en-us/library/dd925430 + If IterCount::NONE, do not add the iteration count to hash + iterations. + + @return the raw hash value + */ + static std::vector<unsigned char> calculateHash( + const unsigned char* pInput, size_t nLength, + const unsigned char* pSalt, size_t nSaltLen, + sal_uInt32 nSpinCount, + IterCount eIterCount, + HashType eType); + + /** Convenience function to calculate a salted hash with iterations. + + @param rPassword + UTF-16 encoded string, hashed byte-wise as unsigned char. + + @param rSaltValue + Salt that will be prepended to password data. + */ + static std::vector<unsigned char> calculateHash( + const rtl::OUString& rPassword, + const std::vector<unsigned char>& rSaltValue, + sal_uInt32 nSpinCount, + IterCount eIterCount, + HashType eType); + + size_t getLength() const; +}; + +} + +#endif // INCLUDED_COMPHELPER_HASH_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/indexedpropertyvalues.hxx b/include/comphelper/indexedpropertyvalues.hxx new file mode 100644 index 000000000..5a5f3e8ba --- /dev/null +++ b/include/comphelper/indexedpropertyvalues.hxx @@ -0,0 +1,55 @@ +/* -*- 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/. + */ +#pragma once + +#include <sal/config.h> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/Sequence.h> +#include <comphelper/comphelperdllapi.h> +#include <cppuhelper/implbase.hxx> +#include <vector> + +namespace comphelper +{ +typedef std::vector<css::uno::Sequence<css::beans::PropertyValue>> IndexedPropertyValues; + +class COMPHELPER_DLLPUBLIC IndexedPropertyValuesContainer final + : public cppu::WeakImplHelper<css::container::XIndexContainer, css::lang::XServiceInfo> +{ +public: + IndexedPropertyValuesContainer() noexcept; + + // XIndexContainer + virtual void SAL_CALL insertByIndex(sal_Int32 nIndex, const css::uno::Any& aElement) override; + virtual void SAL_CALL removeByIndex(sal_Int32 nIndex) override; + + // XIndexReplace + virtual void SAL_CALL replaceByIndex(sal_Int32 nIndex, const css::uno::Any& aElement) override; + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() override; + virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) override; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual sal_Bool SAL_CALL hasElements() override; + + //XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override; + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + +private: + IndexedPropertyValues maProperties; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/interaction.hxx b/include/comphelper/interaction.hxx new file mode 100644 index 000000000..0f783e946 --- /dev/null +++ b/include/comphelper/interaction.hxx @@ -0,0 +1,119 @@ +/* -*- 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_COMPHELPER_INTERACTION_HXX +#define INCLUDED_COMPHELPER_INTERACTION_HXX + +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/task/XInteractionApprove.hpp> +#include <com/sun/star/task/XInteractionDisapprove.hpp> +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/task/XInteractionRetry.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> +#include <comphelper/comphelperdllapi.h> +#include <vector> + + +namespace comphelper +{ + + + //= OInteraction + + /** template for instantiating concrete interaction handlers<p/> + the template argument must be an interface derived from XInteractionContinuation + */ + template <class INTERACTION> + class OInteraction + : public ::cppu::WeakImplHelper< INTERACTION > + { + public: + OInteraction() : m_bSelected(false) {} + + /// determines whether or not this handler was selected + bool wasSelected() const { return m_bSelected; } + + // XInteractionContinuation + virtual void SAL_CALL select() override; + private: + bool m_bSelected : 1; /// indicates if the select event occurred + }; + + + template <class INTERACTION> + void SAL_CALL OInteraction< INTERACTION >::select( ) + { + m_bSelected = true; + } + + + //= OInteractionApprove + + typedef OInteraction< css::task::XInteractionApprove > OInteractionApprove; + + + //= OInteractionDisapprove + + typedef OInteraction< css::task::XInteractionDisapprove > OInteractionDisapprove; + + + //= OInteractionAbort + + typedef OInteraction< css::task::XInteractionAbort > OInteractionAbort; + + + //= OInteractionRetry + + typedef OInteraction< css::task::XInteractionRetry > OInteractionRetry; + + + //= OInteractionRequest + + typedef ::cppu::WeakImplHelper < css::task::XInteractionRequest + > OInteractionRequest_Base; + /** implements an interaction request (com.sun.star.task::XInteractionRequest)<p/> + at run time, you can freely add any interaction continuation objects + */ + class COMPHELPER_DLLPUBLIC OInteractionRequest final : public OInteractionRequest_Base + { + css::uno::Any const + m_aRequest; /// the request we represent + std::vector< css::uno::Reference< css::task::XInteractionContinuation > > + m_aContinuations; /// all registered continuations + + public: + OInteractionRequest(css::uno::Any aRequestDescription); + OInteractionRequest(css::uno::Any aRequestDescription, + std::vector<css::uno::Reference<css::task::XInteractionContinuation>>&& rContinuations); + + /// add a new continuation + void addContinuation(const css::uno::Reference< css::task::XInteractionContinuation >& _rxContinuation); + + // XInteractionRequest + virtual css::uno::Any SAL_CALL getRequest( ) override; + virtual css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > SAL_CALL getContinuations( ) override; + }; + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_INTERACTION_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/interfacecontainer2.hxx b/include/comphelper/interfacecontainer2.hxx new file mode 100644 index 000000000..3df7c71d4 --- /dev/null +++ b/include/comphelper/interfacecontainer2.hxx @@ -0,0 +1,290 @@ +/* -*- 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_COMPHELPER_INTERFACECONTAINER2_H +#define INCLUDED_COMPHELPER_INTERFACECONTAINER2_H + +#include <sal/config.h> + +#include <vector> + +#include <com/sun/star/lang/EventObject.hpp> + +#include <com/sun/star/lang/DisposedException.hpp> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::uno { class XInterface; } +namespace osl { class Mutex; } + +namespace comphelper +{ + +namespace detail { + + /** + This is here to optimise space in the common case that there are zero or one + listeners. + */ + union element_alias2 + { + std::vector< css::uno::Reference< css::uno::XInterface > > *pAsVector; + css::uno::XInterface * pAsInterface; + element_alias2() : pAsInterface(nullptr) {} + }; + +} + + +class OInterfaceContainerHelper2; +/** + This is the iterator of an OInterfaceContainerHelper2. Typically + one constructs an instance on the stack for one firing session. + It is not allowed to assign or copy an instance of this class. + + @see OInterfaceContainerHelper2 + */ +class COMPHELPER_DLLPUBLIC OInterfaceIteratorHelper2 +{ +public: + /** + Create an iterator over the elements of the container. The iterator + copies the elements of the container. A change to the container + during the lifetime of an iterator is allowed and does not + affect the iterator-instance. The iterator and the container take cares + themself for concurrent access, no additional guarding is necessary. + + Remark: The copy is on demand. The iterator copy the elements only if the container + change the contents. It is not allowed to destroy the container as long + as an iterator exist. + + @param rCont the container of the elements. + */ + OInterfaceIteratorHelper2( OInterfaceContainerHelper2 & rCont ); + + /** + Releases the connection to the container. + */ + ~OInterfaceIteratorHelper2(); + + /** Return true, if there are more elements in the iterator. */ + bool hasMoreElements() const + { return nRemain != 0; } + /** Return the next element of the iterator. Calling this method if + hasMoreElements() has returned false, is an error. Cast the + returned pointer to the + */ + css::uno::XInterface * next(); + + /** Removes the current element (the last one returned by next()) + from the underlying container. Calling this method before + next() has been called or calling it twice with no next() + inbetween is an error. + */ + void remove(); + +private: + OInterfaceContainerHelper2 & rCont; + detail::element_alias2 aData; + sal_Int32 nRemain; + bool bIsList; + + OInterfaceIteratorHelper2( const OInterfaceIteratorHelper2 & ) = delete; + OInterfaceIteratorHelper2 & operator = ( const OInterfaceIteratorHelper2 & ) = delete; +}; + + +/** + A container of interfaces. To access the elements use an iterator. + This implementation is thread-safe. + + This is a copy of the code at include/cppuhelper/interfacecontainer.h, + Except that it uses a std::vector instead of a Sequence for the mutable listener + list, which provides far better performance. + + @see OInterfaceIteratorHelper2 + */ +class COMPHELPER_DLLPUBLIC OInterfaceContainerHelper2 +{ +public: + /** + Create an interface container. + + @param rMutex the mutex to protect multi thread access. + The lifetime must be longer than the lifetime + of this object. + */ + OInterfaceContainerHelper2( ::osl::Mutex & rMutex ); + /** + Release all interfaces. All iterators must be destroyed before + the container is destructed. + */ + ~OInterfaceContainerHelper2(); + /** + Return the number of Elements in the container. Only useful if you have acquired + the mutex. + */ + sal_Int32 getLength() const; + + /** + Return all interfaces added to this container. + **/ + std::vector< css::uno::Reference< css::uno::XInterface > > getElements() const; + + /** Inserts an element into the container. The position is not specified, thus it is not + specified in which order events are fired. + + @attention + If you add the same interface more than once, then it will be added to the elements list + more than once and thus if you want to remove that interface from the list, you have to call + removeInterface() the same number of times. + In the latter case, you will also get events fired more than once (if the interface is a + listener interface). + + @param rxIFace + interface to be added; it is allowed to insert null or + the same interface more than once + @return + the new count of elements in the container + */ + sal_Int32 addInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace ); + /** Removes an element from the container. It uses interface equality to remove the interface. + + @param rxIFace + interface to be removed + @return + the new count of elements in the container + */ + sal_Int32 removeInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace ); + /** Return an interface by index */ + css::uno::Reference< css::uno::XInterface > getInterface(sal_Int32 nIndex) const; + /** + Call disposing on all object in the container that + support XEventListener. Then clear the container. + */ + void disposeAndClear( const css::lang::EventObject & rEvt ); + /** + Clears the container without calling disposing(). + */ + void clear(); + + /** Executes a functor for each contained listener of specified type, e.g. + <code>forEach<awt::XPaintListener>(...</code>. + + If a css::lang::DisposedException occurs which relates to + the called listener, then that listener is removed from the container. + + @tparam ListenerT listener type + @tparam FuncT unary functor type, let your compiler deduce this for you + @param func unary functor object expecting an argument of type + css::uno::Reference<ListenerT> + */ + template <typename ListenerT, typename FuncT> + inline void forEach( FuncT const& func ); + + /** Calls a UNO listener method for each contained listener. + + The listener method must take a single argument of type EventT, + and return <code>void</code>. + + If a css::lang::DisposedException occurs which relates to + the called listener, then that listener is removed from the container. + + @tparam ListenerT UNO event listener type, let your compiler deduce this for you + @tparam EventT event type, let your compiler deduce this for you + @param NotificationMethod + Pointer to a method of a ListenerT interface. + @param Event + Event to notify to all contained listeners + + Example: +@code + awt::PaintEvent aEvent( static_cast< cppu::OWeakObject* >( this ), ... ); + listeners.notifyEach( &XPaintListener::windowPaint, aEvent ); +@endcode + */ + template< typename ListenerT, typename EventT > + inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event ); + +private: +friend class OInterfaceIteratorHelper2; + /** + bIsList == TRUE -> aData.pAsVector of type vector< XInterfaceSequence >, + otherwise aData.pAsInterface == of type (XEventListener *) + */ + detail::element_alias2 aData; + ::osl::Mutex & rMutex; + /** TRUE -> used by an iterator. */ + bool bInUse; + /** TRUE -> aData.pAsVector is of type Sequence< XInterfaceSequence >. */ + bool bIsList; + + OInterfaceContainerHelper2( const OInterfaceContainerHelper2 & ) = delete; + OInterfaceContainerHelper2 & operator = ( const OInterfaceContainerHelper2 & ) = delete; + + /* + Duplicate content of the container and release the old one without destroying. + The mutex must be locked and the memberbInUse must be true. + */ + void copyAndResetInUse(); + +private: + template< typename ListenerT, typename EventT > + class NotifySingleListener + { + private: + typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ); + NotificationMethod const m_pMethod; + const EventT& m_rEvent; + public: + NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { } + + void operator()( const css::uno::Reference<ListenerT>& listener ) const + { + (listener.get()->*m_pMethod)( m_rEvent ); + } + }; +}; + +template <typename ListenerT, typename FuncT> +inline void OInterfaceContainerHelper2::forEach( FuncT const& func ) +{ + OInterfaceIteratorHelper2 iter( *this ); + while (iter.hasMoreElements()) { + css::uno::Reference<ListenerT> const xListener( iter.next(), css::uno::UNO_QUERY ); + if (xListener.is()) { + try { + func( xListener ); + } + catch (css::lang::DisposedException const& exc) { + if (exc.Context == xListener) + iter.remove(); + } + } + } +} + +template< typename ListenerT, typename EventT > +inline void OInterfaceContainerHelper2::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event ) +{ + forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) ); +} + +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/interfacecontainer3.hxx b/include/comphelper/interfacecontainer3.hxx new file mode 100644 index 000000000..4b3d44bab --- /dev/null +++ b/include/comphelper/interfacecontainer3.hxx @@ -0,0 +1,379 @@ +/* -*- 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 . + */ +#pragma once + +#include <sal/config.h> + +#include <com/sun/star/lang/EventObject.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <o3tl/cow_wrapper.hxx> +#include <vector> + +namespace com::sun::star::uno +{ +class XInterface; +} +namespace osl +{ +class Mutex; +} + +namespace comphelper +{ +template <class ListenerT> class OInterfaceContainerHelper3; +/** + This is the iterator of an OInterfaceContainerHelper3. Typically + one constructs an instance on the stack for one firing session. + It is not allowed to assign or copy an instance of this class. + + @tparam ListenerT UNO event listener type + @see OInterfaceContainerHelper3 + */ +template <class ListenerT> class OInterfaceIteratorHelper3 +{ +public: + /** + Create an iterator over the elements of the container. The iterator + copies the elements of the container. A change to the container + during the lifetime of an iterator is allowed and does not + affect the iterator-instance. The iterator and the container take cares + themself for concurrent access, no additional guarding is necessary. + + Remark: The copy is on demand. The iterator copy the elements only if the container + change the contents... + + @param rCont the container of the elements. + */ + OInterfaceIteratorHelper3(OInterfaceContainerHelper3<ListenerT>& rCont_) + : rCont(rCont_) + , maData(rCont.maData) + , nRemain(maData->size()) + { + } + + /** Return true, if there are more elements in the iterator. */ + bool hasMoreElements() const { return nRemain != 0; } + /** Return the next element of the iterator. Calling this method if + hasMoreElements() has returned false, is an error. + */ + css::uno::Reference<ListenerT> const& next(); + + /** Removes the current element (the last one returned by next()) + from the underlying container. Calling this method before + next() has been called or calling it twice with no next() + in between is an error. + */ + void remove(); + +private: + OInterfaceContainerHelper3<ListenerT>& rCont; + o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>, + o3tl::ThreadSafeRefCountingPolicy> + maData; + sal_Int32 nRemain; + + OInterfaceIteratorHelper3(const OInterfaceIteratorHelper3&) = delete; + OInterfaceIteratorHelper3& operator=(const OInterfaceIteratorHelper3&) = delete; +}; + +template <class ListenerT> +const css::uno::Reference<ListenerT>& OInterfaceIteratorHelper3<ListenerT>::next() +{ + nRemain--; + return (*maData)[nRemain]; +} + +template <class ListenerT> void OInterfaceIteratorHelper3<ListenerT>::remove() +{ + rCont.removeInterface((*maData)[nRemain]); +} + +/** + A container of interfaces. To access the elements use an iterator. + This implementation is thread-safe. + + This is a copy of the code at include/comphelper/interfacecontainer2.hxx, + except that it is templatized on the type of the listener, which allows + some parts of the code to avoid doing an UNO_QUERY that can be expensive + in bulk. + + @tparam ListenerT UNO event listener type + @see OInterfaceIteratorHelper + */ +template <class ListenerT> class OInterfaceContainerHelper3 +{ +public: + /** + Create an interface container. + + @param rMutex the mutex to protect multi thread access. + The lifetime must be longer than the lifetime + of this object. + */ + inline OInterfaceContainerHelper3(::osl::Mutex& rMutex_); + + /** + Return the number of Elements in the container. Only useful if you have acquired + the mutex. + */ + sal_Int32 getLength() const; + + /** + Return all interfaces added to this container. + **/ + std::vector<css::uno::Reference<ListenerT>> getElements() const; + + /** Inserts an element into the container. The position is not specified, thus it is not + specified in which order events are fired. + + @attention + If you add the same interface more than once, then it will be added to the elements list + more than once and thus if you want to remove that interface from the list, you have to call + removeInterface() the same number of times. + In the latter case, you will also get events fired more than once (if the interface is a + listener interface). + + @param rxIFace + interface to be added; it is allowed to insert + the same interface more than once + @return + the new count of elements in the container + */ + sal_Int32 addInterface(const css::uno::Reference<ListenerT>& rxIFace); + /** Removes an element from the container. It uses interface equality to remove the interface. + + @param rxIFace + interface to be removed + @return + the new count of elements in the container + */ + sal_Int32 removeInterface(const css::uno::Reference<ListenerT>& rxIFace); + /** Return an interface by index + */ + const css::uno::Reference<ListenerT>& getInterface(sal_Int32 nIndex) const; + /** + Call disposing on all object in the container that + support XEventListener. Then clear the container. + */ + void disposeAndClear(const css::lang::EventObject& rEvt); + /** + Clears the container without calling disposing(). + */ + void clear(); + + /** Executes a functor for each contained listener of specified type, e.g. + <code>forEach<awt::XPaintListener>(...</code>. + + If a css::lang::DisposedException occurs which relates to + the called listener, then that listener is removed from the container. + + @tparam FuncT unary functor type, let your compiler deduce this for you + @param func unary functor object expecting an argument of type + css::uno::Reference<ListenerT> + */ + template <typename FuncT> inline void forEach(FuncT const& func); + + /** Calls a UNO listener method for each contained listener. + + The listener method must take a single argument of type EventT, + and return <code>void</code>. + + If a css::lang::DisposedException occurs which relates to + the called listener, then that listener is removed from the container. + + @tparam EventT event type, let your compiler deduce this for you + @param NotificationMethod + Pointer to a method of a ListenerT interface. + @param Event + Event to notify to all contained listeners + + Example: +@code + awt::PaintEvent aEvent( static_cast< cppu::OWeakObject* >( this ), ... ); + listeners.notifyEach( &XPaintListener::windowPaint, aEvent ); +@endcode + */ + template <typename EventT> + inline void notifyEach(void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&), + const EventT& Event); + +private: + friend class OInterfaceIteratorHelper3<ListenerT>; + o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>, + o3tl::ThreadSafeRefCountingPolicy> + maData; + ::osl::Mutex& mrMutex; + OInterfaceContainerHelper3(const OInterfaceContainerHelper3&) = delete; + OInterfaceContainerHelper3& operator=(const OInterfaceContainerHelper3&) = delete; + + static o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>, + o3tl::ThreadSafeRefCountingPolicy>& + DEFAULT() + { + static o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>, + o3tl::ThreadSafeRefCountingPolicy> + SINGLETON; + return SINGLETON; + } + +private: + template <typename EventT> class NotifySingleListener + { + private: + typedef void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&); + NotificationMethod const m_pMethod; + const EventT& m_rEvent; + + public: + NotifySingleListener(NotificationMethod method, const EventT& event) + : m_pMethod(method) + , m_rEvent(event) + { + } + + void operator()(const css::uno::Reference<ListenerT>& listener) const + { + (listener.get()->*m_pMethod)(m_rEvent); + } + }; +}; + +template <class T> +inline OInterfaceContainerHelper3<T>::OInterfaceContainerHelper3(::osl::Mutex& rMutex_) + : maData(OInterfaceContainerHelper3<T>::DEFAULT()) + , mrMutex(rMutex_) +{ +} + +template <class T> +template <typename FuncT> +inline void OInterfaceContainerHelper3<T>::forEach(FuncT const& func) +{ + OInterfaceIteratorHelper3<T> iter(*this); + while (iter.hasMoreElements()) + { + auto xListener = iter.next(); + try + { + func(xListener); + } + catch (css::lang::DisposedException const& exc) + { + if (exc.Context == xListener) + iter.remove(); + } + } +} + +template <class ListenerT> +template <typename EventT> +inline void OInterfaceContainerHelper3<ListenerT>::notifyEach( + void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&), const EventT& Event) +{ + forEach<NotifySingleListener<EventT>>(NotifySingleListener<EventT>(NotificationMethod, Event)); +} + +template <class ListenerT> sal_Int32 OInterfaceContainerHelper3<ListenerT>::getLength() const +{ + osl::MutexGuard aGuard(mrMutex); + return maData->size(); +} + +template <class ListenerT> +std::vector<css::uno::Reference<ListenerT>> +OInterfaceContainerHelper3<ListenerT>::getElements() const +{ + std::vector<css::uno::Reference<ListenerT>> rVec; + osl::MutexGuard aGuard(mrMutex); + rVec = *maData; + return rVec; +} + +template <class ListenerT> +sal_Int32 +OInterfaceContainerHelper3<ListenerT>::addInterface(const css::uno::Reference<ListenerT>& rListener) +{ + assert(rListener.is()); + osl::MutexGuard aGuard(mrMutex); + + maData->push_back(rListener); + return maData->size(); +} + +template <class ListenerT> +sal_Int32 OInterfaceContainerHelper3<ListenerT>::removeInterface( + const css::uno::Reference<ListenerT>& rListener) +{ + assert(rListener.is()); + osl::MutexGuard aGuard(mrMutex); + + // It is not valid to compare the pointer directly, but it's faster. + auto it = std::find_if(maData->begin(), maData->end(), + [&rListener](const css::uno::Reference<css::uno::XInterface>& rItem) { + return rItem.get() == rListener.get(); + }); + + // interface not found, use the correct compare method + if (it == maData->end()) + it = std::find(maData->begin(), maData->end(), rListener); + + if (it != maData->end()) + maData->erase(it); + + return maData->size(); +} + +template <class ListenerT> +const css::uno::Reference<ListenerT>& +OInterfaceContainerHelper3<ListenerT>::getInterface(sal_Int32 nIndex) const +{ + osl::MutexGuard aGuard(mrMutex); + + return (*maData)[nIndex]; +} + +template <class ListenerT> +void OInterfaceContainerHelper3<ListenerT>::disposeAndClear(const css::lang::EventObject& rEvt) +{ + osl::ClearableMutexGuard aGuard(mrMutex); + OInterfaceIteratorHelper3<ListenerT> aIt(*this); + maData->clear(); + aGuard.clear(); + while (aIt.hasMoreElements()) + { + try + { + aIt.next()->disposing(rEvt); + } + catch (css::uno::RuntimeException&) + { + // be robust, if e.g. a remote bridge has disposed already. + // there is no way to delegate the error to the caller :o(. + } + } +} + +template <class ListenerT> void OInterfaceContainerHelper3<ListenerT>::clear() +{ + osl::MutexGuard aGuard(mrMutex); + maData->clear(); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/interfacecontainer4.hxx b/include/comphelper/interfacecontainer4.hxx new file mode 100644 index 000000000..bdd6a6b60 --- /dev/null +++ b/include/comphelper/interfacecontainer4.hxx @@ -0,0 +1,401 @@ +/* -*- 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 . + */ +#pragma once + +#include <sal/config.h> + +#include <com/sun/star/lang/EventObject.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <o3tl/cow_wrapper.hxx> +#include <mutex> +#include <vector> + +namespace com::sun::star::uno +{ +class XInterface; +} + +namespace comphelper +{ +template <class ListenerT> class OInterfaceContainerHelper4; +/** + This is the iterator of an OInterfaceContainerHelper4. Typically + one constructs an instance on the stack for one firing session. + It is not allowed to assign or copy an instance of this class. + + @tparam ListenerT UNO event listener type + @see OInterfaceContainerHelper4 + */ +template <class ListenerT> class OInterfaceIteratorHelper4 +{ +public: + /** + Create an iterator over the elements of the container. The iterator + copies the elements of the container. A change to the container + during the lifetime of an iterator is allowed and does not + affect the iterator-instance. The iterator and the container take cares + themself for concurrent access, no additional guarding is necessary. + + Remark: The copy is on demand. The iterator copy the elements only if the container + change the contents... + + @param rCont the container of the elements. + @param rGuard + this parameter only here to make that this container is accessed while locked + */ + OInterfaceIteratorHelper4(std::unique_lock<std::mutex>& /*rGuard*/, + OInterfaceContainerHelper4<ListenerT>& rCont_) + : rCont(rCont_) + , maData(rCont.maData) + // const_cast so we don't trigger make_unique via o3tl::cow_wrapper::operator-> + , nRemain(std::as_const(maData)->size()) + { + } + + /** Return true, if there are more elements in the iterator. */ + bool hasMoreElements() const { return nRemain != 0; } + /** Return the next element of the iterator. Calling this method if + hasMoreElements() has returned false, is an error. + */ + css::uno::Reference<ListenerT> const& next(); + + /** Removes the current element (the last one returned by next()) + from the underlying container. Calling this method before + next() has been called or calling it twice with no next() + in between is an error. + @param rGuard + this parameter only here to make that this container is accessed while locked + */ + void remove(::std::unique_lock<::std::mutex>& rGuard); + +private: + OInterfaceContainerHelper4<ListenerT>& rCont; + o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>, + o3tl::ThreadSafeRefCountingPolicy> + maData; + sal_Int32 nRemain; + + OInterfaceIteratorHelper4(const OInterfaceIteratorHelper4&) = delete; + OInterfaceIteratorHelper4& operator=(const OInterfaceIteratorHelper4&) = delete; +}; + +template <class ListenerT> +const css::uno::Reference<ListenerT>& OInterfaceIteratorHelper4<ListenerT>::next() +{ + nRemain--; + return (*std::as_const(maData))[nRemain]; +} + +template <class ListenerT> +void OInterfaceIteratorHelper4<ListenerT>::remove(::std::unique_lock<::std::mutex>& rGuard) +{ + rCont.removeInterface(rGuard, (*std::as_const(maData))[nRemain]); +} + +/** + A container of interfaces. To access the elements use an iterator. + This implementation is thread-safe. + + This is a copy of the code at include/comphelper/interfacecontainer3.hxx, + except that it (a) uses std::mutex instead of osl::Mutex and (b) does not + store a reference to the mutex, but relies on the calling class to take + a lock around using it. + + @tparam ListenerT UNO event listener type + @see OInterfaceIteratorHelper + */ +template <class ListenerT> class OInterfaceContainerHelper4 +{ +public: + OInterfaceContainerHelper4(); + + /** + Return the number of Elements in the container. Only useful if you have acquired + the mutex. + @param rGuard + this parameter only here to make that this container is accessed while locked + */ + sal_Int32 getLength(std::unique_lock<std::mutex>& rGuard) const; + + /** + Return all interfaces added to this container. + @param rGuard + this parameter only here to make that this container is accessed while locked + **/ + std::vector<css::uno::Reference<ListenerT>> + getElements(std::unique_lock<std::mutex>& rGuard) const; + + /** Inserts an element into the container. The position is not specified, thus it is not + specified in which order events are fired. + + @attention + If you add the same interface more than once, then it will be added to the elements list + more than once and thus if you want to remove that interface from the list, you have to call + removeInterface() the same number of times. + In the latter case, you will also get events fired more than once (if the interface is a + listener interface). + + @param rxIFace + interface to be added; it is allowed to insert + the same interface more than once + @param rGuard + this parameter only here to make that this container is accessed while locked + @return + the new count of elements in the container + */ + sal_Int32 addInterface(std::unique_lock<std::mutex>& rGuard, + const css::uno::Reference<ListenerT>& rxIFace); + /** Removes an element from the container. It uses interface equality to remove the interface. + + @param rxIFace + interface to be removed + @param rGuard + this parameter only here to make that this container is accessed while locked + @return + the new count of elements in the container + */ + sal_Int32 removeInterface(std::unique_lock<std::mutex>& rGuard, + const css::uno::Reference<ListenerT>& rxIFace); + /** + Call disposing on all object in the container that + support XEventListener. Then clear the container. + The guard is unlock()'ed before calling the listeners. + */ + void disposeAndClear(::std::unique_lock<::std::mutex>& rGuard, + const css::lang::EventObject& rEvt); + /** + Clears the container without calling disposing(). + @param rGuard + this parameter only here to make that this container is accessed while locked + */ + void clear(::std::unique_lock<::std::mutex>& rGuard); + + /** Executes a functor for each contained listener of specified type, e.g. + <code>forEach<awt::XPaintListener>(...</code>. + + If a css::lang::DisposedException occurs which relates to + the called listener, then that listener is removed from the container. + + @tparam FuncT unary functor type, let your compiler deduce this for you + @param func unary functor object expecting an argument of type + css::uno::Reference<ListenerT> + @param rGuard + this parameter only here to make that this container is accessed while locked + */ + template <typename FuncT> + inline void forEach(std::unique_lock<std::mutex>& rGuard, FuncT const& func); + + /** Calls a UNO listener method for each contained listener. + + The listener method must take a single argument of type EventT, + and return <code>void</code>. + + If a css::lang::DisposedException occurs which relates to + the called listener, then that listener is removed from the container. + + @tparam EventT event type, let your compiler deduce this for you + @param NotificationMethod + Pointer to a method of a ListenerT interface. + @param Event + Event to notify to all contained listeners + @param rGuard + this parameter only here to make that this container is accessed while locked + + Example: +@code + awt::PaintEvent aEvent( static_cast< cppu::OWeakObject* >( this ), ... ); + listeners.notifyEach( &XPaintListener::windowPaint, aEvent ); +@endcode + */ + template <typename EventT> + inline void notifyEach(std::unique_lock<std::mutex>& rGuard, + void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&), + const EventT& Event); + +private: + friend class OInterfaceIteratorHelper4<ListenerT>; + o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>, + o3tl::ThreadSafeRefCountingPolicy> + maData; + OInterfaceContainerHelper4(const OInterfaceContainerHelper4&) = delete; + OInterfaceContainerHelper4& operator=(const OInterfaceContainerHelper4&) = delete; + + static o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>, + o3tl::ThreadSafeRefCountingPolicy>& + DEFAULT() + { + static o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>, + o3tl::ThreadSafeRefCountingPolicy> + SINGLETON; + return SINGLETON; + } + +private: + template <typename EventT> class NotifySingleListener + { + private: + typedef void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&); + NotificationMethod const m_pMethod; + const EventT& m_rEvent; + + public: + NotifySingleListener(NotificationMethod method, const EventT& event) + : m_pMethod(method) + , m_rEvent(event) + { + } + + void operator()(const css::uno::Reference<ListenerT>& listener) const + { + (listener.get()->*m_pMethod)(m_rEvent); + } + }; +}; + +template <class T> +inline OInterfaceContainerHelper4<T>::OInterfaceContainerHelper4() + : maData(OInterfaceContainerHelper4<T>::DEFAULT()) +{ +} + +template <class T> +template <typename FuncT> +inline void OInterfaceContainerHelper4<T>::forEach(std::unique_lock<std::mutex>& rGuard, + FuncT const& func) +{ + if (std::as_const(maData)->size() == 0) + { + return; + } + maData.make_unique(); // so we can iterate over the data without holding the lock + OInterfaceIteratorHelper4<T> iter(rGuard, *this); + rGuard.unlock(); + while (iter.hasMoreElements()) + { + auto xListener = iter.next(); + try + { + func(xListener); + } + catch (css::lang::DisposedException const& exc) + { + if (exc.Context == xListener) + { + rGuard.lock(); + iter.remove(rGuard); + rGuard.unlock(); + } + } + } + rGuard.lock(); +} + +template <class ListenerT> +template <typename EventT> +inline void OInterfaceContainerHelper4<ListenerT>::notifyEach( + std::unique_lock<std::mutex>& rGuard, + void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&), const EventT& Event) +{ + forEach<NotifySingleListener<EventT>>(rGuard, + NotifySingleListener<EventT>(NotificationMethod, Event)); +} + +template <class ListenerT> +sal_Int32 +OInterfaceContainerHelper4<ListenerT>::getLength(std::unique_lock<std::mutex>& /*rGuard*/) const +{ + return maData->size(); +} + +template <class ListenerT> +std::vector<css::uno::Reference<ListenerT>> +OInterfaceContainerHelper4<ListenerT>::getElements(std::unique_lock<std::mutex>& /*rGuard*/) const +{ + return *maData; +} + +template <class ListenerT> +sal_Int32 +OInterfaceContainerHelper4<ListenerT>::addInterface(std::unique_lock<std::mutex>& /*rGuard*/, + const css::uno::Reference<ListenerT>& rListener) +{ + assert(rListener.is()); + maData->push_back(rListener); + return maData->size(); +} + +template <class ListenerT> +sal_Int32 OInterfaceContainerHelper4<ListenerT>::removeInterface( + std::unique_lock<std::mutex>& /*rGuard*/, const css::uno::Reference<ListenerT>& rListener) +{ + assert(rListener.is()); + + // It is not valid to compare the pointer directly, but it's faster. + auto it = std::find_if(maData->begin(), maData->end(), + [&rListener](const css::uno::Reference<css::uno::XInterface>& rItem) { + return rItem.get() == rListener.get(); + }); + + // interface not found, use the correct compare method + if (it == maData->end()) + it = std::find(maData->begin(), maData->end(), rListener); + + if (it != maData->end()) + maData->erase(it); + + return maData->size(); +} + +template <class ListenerT> +void OInterfaceContainerHelper4<ListenerT>::disposeAndClear(std::unique_lock<std::mutex>& rGuard, + const css::lang::EventObject& rEvt) +{ + { + OInterfaceIteratorHelper4<ListenerT> aIt(rGuard, *this); + maData + = DEFAULT(); // cheaper than calling maData->clear() because it doesn't allocate a new vector + rGuard.unlock(); + // unlock followed by iterating is only safe because we are not going to call remove() on the iterator + while (aIt.hasMoreElements()) + { + try + { + aIt.next()->disposing(rEvt); + } + catch (css::uno::RuntimeException&) + { + // be robust, if e.g. a remote bridge has disposed already. + // there is no way to delegate the error to the caller :o(. + } + } + } + // tdf#152077 need to destruct the OInterfaceIteratorHelper4 before we take the lock again + // because there is a vague chance that destructing it will trigger a call back into something + // that wants to take the lock. + rGuard.lock(); +} + +template <class ListenerT> +void OInterfaceContainerHelper4<ListenerT>::clear(::std::unique_lock<::std::mutex>& /*rGuard*/) +{ + maData->clear(); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/logging.hxx b/include/comphelper/logging.hxx new file mode 100644 index 000000000..f0a599765 --- /dev/null +++ b/include/comphelper/logging.hxx @@ -0,0 +1,460 @@ +/* -*- 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_COMPHELPER_LOGGING_HXX +#define INCLUDED_COMPHELPER_LOGGING_HXX + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> + +#include <optional> +#include <memory> + +namespace com::sun::star::uno { template <class interface_type> class Reference; } +namespace com::sun::star::uno { class XComponentContext; } +namespace com::sun::star::logging { class XLogger; } + +namespace comphelper +{ + + + //= string conversions, employed by the templatized log* members of + //= EventLogger + + + namespace log::convert + { + inline const OUString& convertLogArgToString( const OUString& _rValue ) + { + return _rValue; + } + + inline OUString convertLogArgToString( const char* _pAsciiValue ) + { + return OUString::createFromAscii( _pAsciiValue ); + } + + inline OUString convertLogArgToString( double _nValue ) { return OUString::number( _nValue ); } + inline OUString convertLogArgToString( float _nValue ) { return OUString::number( _nValue ); } + inline OUString convertLogArgToString( sal_Int64 _nValue ) { return OUString::number( _nValue ); } + inline OUString convertLogArgToString( sal_Int32 _nValue ) { return OUString::number( _nValue ); } + inline OUString convertLogArgToString( sal_Int16 _nValue ) { return OUString::number( _nValue ); } + inline OUString convertLogArgToString( sal_Unicode _nValue ) { return OUString( _nValue ); } + inline OUString convertLogArgToString( bool _bValue ) { return OUString::boolean( _bValue ); } + void convertLogArgToString(sal_Bool) = delete; + + } // namespace log::convert + + + //= EventLogger + + class EventLogger_Impl; + typedef ::std::optional< OUString > OptionalString; + + /** encapsulates a css::logging::XLogger + + The class silences several (unlikely) errors which could potentially happen + when working with a logger. Additionally, it provides some convenience methods + for logging events. + + You can use this class as follows +<pre> + EventLogger aLogger( xContext, sLoggerName ); + ... + aLogger.log( LogLevel::SEVERE, sSomeMessage ); + aLogger.logp( LogLevel::CONFIG, "MyClass", "MyMethod", sSomeMessage, SomeParameter1, SomeParameter2, SomeParameter3 ); +</pre> + + The <code>log</code> and <code>logp</code> calls support up to 6 parameters, which can be of + arbitrary type. For every parameter, there must exist a function <code>convertLogArgToString</code> + which takes an argument of the respective type, and returns a string. + + After a parameter has been converted to a string using the above mentioned + <code>convertLogArgToString</code> function, a placeholder $1$ (resp. $2$ resp. $4$ ...) + in the message will be replaced with this string, and the resulting message will be logged. + */ + class COMPHELPER_DLLPUBLIC EventLogger + { + protected: + std::shared_ptr< EventLogger_Impl > m_pImpl; + + public: + /** creates an <code>EventLogger</code> instance working with a css.logging.XLogger + instance given by ASCII name. + + @param _rxContext + the component context to create services + + @param _rLoggerName + the ASCII name of the logger to create. + */ + EventLogger( + const css::uno::Reference< css::uno::XComponentContext >& _rxContext, + const char* _pAsciiLoggerName + ); + + public: + /// determines whether an event with the given level would be logged + bool isLoggable( const sal_Int32 _nLogLevel ) const; + + + //- XLogger::log equivalents/wrappers + //- string messages + + /// logs a given message, without any arguments, or source class/method names + void log( const sal_Int32 _nLogLevel, const OUString& rMessage ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log(_nLogLevel, nullptr, nullptr, rMessage); + } + + const css::uno::Reference<css::logging::XLogger> & getLogger() const; + + /** logs a given message, replacing a placeholder in the message with an argument + + The function takes, additionally to the log level and the message, an arbitrary + argument. This argument is converted to a string using an overloaded function + named <code>convertLogArgToString</code>. Then, a placeholder "$1$" + is searched in the message string, and replaced with the argument string. + */ + template< typename ARGTYPE1 > + void log( const sal_Int32 _nLogLevel, const OUString& _rMessage, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + } + + /// logs a given message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + void log( const sal_Int32 _nLogLevel, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + } + + /// logs a given message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + void log( const sal_Int32 _nLogLevel, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + } + + /// logs a given message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + void log( const sal_Int32 _nLogLevel, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + } + + /// logs a given message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + void log( const sal_Int32 _nLogLevel, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + } + + /// logs a given message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + void log( const sal_Int32 _nLogLevel, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + } + + + //- XLogger::log equivalents/wrappers + //- ASCII messages + + /** logs a given message, replacing a placeholder in the message with an argument + + The function takes, additionally to the log level and the message, an arbitrary + argument. This argument is converted to a string using an overloaded function + named <code>convertLogArgToString</code>. Then, a placeholder "$1$" + is searched in the message string, and replaced with the argument string. + */ + template< typename ARGTYPE1 > + void log( const sal_Int32 _nLogLevel, const char* _pMessage, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + } + + /// logs a given message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + void log( const sal_Int32 _nLogLevel, const char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + } + + /// logs a given message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + void log( const sal_Int32 _nLogLevel, const char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + } + + /// logs a given message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + void log( const sal_Int32 _nLogLevel, const char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + } + + /// logs a given message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + void log( const sal_Int32 _nLogLevel, const char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + } + + /// logs a given message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + void log( const sal_Int32 _nLogLevel, const char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, nullptr, nullptr, OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + } + + + //- XLogger::logp equivalents/wrappers + //- string messages + + /** logs a given message, replacing a placeholder in the message with an argument + + The function takes, additionally to the logp level and the message, an arbitrary + argument. This argument is converted to a string using an overloaded function + named <code>convertLogArgToString</code>. Then, a placeholder "$1$" + is searched in the message string, and replaced with the argument string. + */ + template< typename ARGTYPE1 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const OUString& _rMessage, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + } + + /// logs a given message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + } + + /// logs a given message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + } + + /// logs a given message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + } + + /// logs a given message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + } + + /// logs a given message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + } + + + //- XLogger::logp equivalents/wrappers + //- ASCII messages + + /** logs a given ASCII message, replacing a placeholder in the message with an argument + + The function takes, additionally to the logp level and the message, an arbitrary + argument. This argument is converted to a string using an overloaded function + named <code>convertLogArgToString</code>. Then, a placeholder "$1$" + is searched in the message string, and replaced with the argument string. + */ + template< typename ARGTYPE1 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const char* _pAsciiMessage, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + } + + /// logs a given ASCII message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + } + + /// logs a given ASCII message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + } + + /// logs a given ASCII message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + } + + /// logs a given ASCII message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + } + + /// logs a given ASCII message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + void logp( const sal_Int32 _nLogLevel, const char* _pSourceClass, const char* _pSourceMethod, const char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + } + + protected: + void impl_log( + const sal_Int32 _nLogLevel, + const char* _pSourceClass, + const char* _pSourceMethod, + const OUString& _rMessage, + const OptionalString& _rArgument1 = OptionalString(), + const OptionalString& _rArgument2 = OptionalString(), + const OptionalString& _rArgument3 = OptionalString(), + const OptionalString& _rArgument4 = OptionalString(), + const OptionalString& _rArgument5 = OptionalString(), + const OptionalString& _rArgument6 = OptionalString() + ) const; + }; +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_LOGGING_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx new file mode 100644 index 000000000..66784e8e4 --- /dev/null +++ b/include/comphelper/lok.hxx @@ -0,0 +1,117 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#ifndef INCLUDED_COMPHELPER_LOK_HXX +#define INCLUDED_COMPHELPER_LOK_HXX + +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> + +class LanguageTag; + +// Interface between the LibreOfficeKit implementation called by LibreOfficeKit clients and other +// LibreOffice code. + +namespace comphelper::LibreOfficeKit +{ +// Functions to be called only from the LibreOfficeKit implementation in desktop, not from other +// places in LibreOffice code. + +COMPHELPER_DLLPUBLIC void setActive(bool bActive = true); + +enum class statusIndicatorCallbackType +{ + Start, + SetValue, + Finish +}; + +COMPHELPER_DLLPUBLIC void setStatusIndicatorCallback( + void (*callback)(void* data, statusIndicatorCallbackType type, int percent, const char* pText), + void* data); + +// Functions that can be called from arbitrary places in LibreOffice. + +// Check whether the code is running as invoked through LibreOfficeKit. +COMPHELPER_DLLPUBLIC bool isActive(); + +/// Shift the coordinates before rendering each bitmap. +/// Used by Calc to render each tile separately. +/// This should be unnecessary (and removed) once Calc +/// moves to using 100MM Unit. +COMPHELPER_DLLPUBLIC void setLocalRendering(bool bLocalRendering = true); +COMPHELPER_DLLPUBLIC bool isLocalRendering(); + +/// Check whether clients want a part number in an invalidation payload. +COMPHELPER_DLLPUBLIC bool isPartInInvalidation(); +/// Set whether clients want a part number in an invalidation payload. +COMPHELPER_DLLPUBLIC void setPartInInvalidation(bool bPartInInvalidation); + +/// Check if we are doing tiled painting. +COMPHELPER_DLLPUBLIC bool isTiledPainting(); +/// Set if we are doing tiled painting. +COMPHELPER_DLLPUBLIC void setTiledPainting(bool bTiledPainting); +/// Check if we are painting the dialog. +COMPHELPER_DLLPUBLIC bool isDialogPainting(); +/// Set if we are painting the dialog. +COMPHELPER_DLLPUBLIC void setDialogPainting(bool bDialogPainting); +/// Set the DPI scale for rendering for HiDPI displays. +COMPHELPER_DLLPUBLIC void setDPIScale(double fDPIScale); +/// Get the DPI scale for rendering for HiDPI displays. +COMPHELPER_DLLPUBLIC double getDPIScale(); +/// Set if we want no annotations rendering +COMPHELPER_DLLPUBLIC void setTiledAnnotations(bool bTiledAnnotations); +/// Check if annotations rendering is turned off +COMPHELPER_DLLPUBLIC bool isTiledAnnotations(); +/// Set if we want range based header data +COMPHELPER_DLLPUBLIC void setRangeHeaders(bool bTiledAnnotations); +/// Check if range based header data is enabled +COMPHELPER_DLLPUBLIC bool isRangeHeaders(); + +enum Compat : sal_uInt32 +{ + none = 0, + scNoGridBackground = 1, + scPrintTwipsMsgs = 2, +}; +/// Set compatibility flags +COMPHELPER_DLLPUBLIC void setCompatFlag(Compat flag); +/// Get compatibility flags +COMPHELPER_DLLPUBLIC bool isCompatFlagSet(Compat flag); + +/// Check whether clients want viewId in visible cursor invalidation payload. +COMPHELPER_DLLPUBLIC bool isViewIdForVisCursorInvalidation(); +/// Set whether clients want viewId in visible cursor invalidation payload. +COMPHELPER_DLLPUBLIC void setViewIdForVisCursorInvalidation(bool bViewIdForVisCursorInvalidation); + +/// Update the current LOK's locale. +COMPHELPER_DLLPUBLIC void setLocale(const LanguageTag& languageTag); +/// Get the current LOK's locale. +COMPHELPER_DLLPUBLIC const LanguageTag& getLocale(); + +/// Update the current LOK's language. +COMPHELPER_DLLPUBLIC void setLanguageTag(const LanguageTag& languageTag); +/// Get the current LOK's language. +COMPHELPER_DLLPUBLIC const LanguageTag& getLanguageTag(); +/// If the language name should be used for this LOK instance. +COMPHELPER_DLLPUBLIC bool isAllowlistedLanguage(const OUString& lang); + +// Status indicator handling. Even if in theory there could be several status indicators active at +// the same time, in practice there is only one at a time, so we don't handle any identification of +// status indicator in this API. +COMPHELPER_DLLPUBLIC void statusIndicatorStart(const OUString& sText); +COMPHELPER_DLLPUBLIC void statusIndicatorSetValue(int percent); +COMPHELPER_DLLPUBLIC void statusIndicatorFinish(); + +COMPHELPER_DLLPUBLIC void setBlockedCommandList(const char* blockedCommandList); +} + +#endif // INCLUDED_COMPHELPER_LOK_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/make_shared_from_uno.hxx b/include/comphelper/make_shared_from_uno.hxx new file mode 100644 index 000000000..7075e3000 --- /dev/null +++ b/include/comphelper/make_shared_from_uno.hxx @@ -0,0 +1,68 @@ +/* -*- 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_COMPHELPER_MAKE_SHARED_FROM_UNO_HXX +#define INCLUDED_COMPHELPER_MAKE_SHARED_FROM_UNO_HXX + +#include <memory> + +namespace comphelper +{ +/// @internal +namespace detail +{ +/// @internal +template <typename T> struct ReleaseFunc +{ + void operator()(T* p) const { p->release(); } +}; +} // namespace detail + +/** Makes a std::shared_ptr from a ref-counted UNO object pointer. + This makes sense if the object is used via UNO (implementing some X + interface) and also internally using its implementation class, e.g. + + <pre> + std::shared_ptr<MyUnoImpl> const ptr( + comphelper::make_shared_from_UNO( new MyUnoImpl ) ); + ... + xUno->callingUno( uno::Reference<XSomeInterface>( ptr.get() ) ); + ... + takeSharedPtr( ptr ); + ... + </pre> + + @attention The shared_ptr operates on a separate reference counter, so + weak pointers (std::weak_ptr) are invalidated when the last + shared_ptr is destroyed, although the UNO object may still be + alive. + + @param p object pointer + @return shared_ptr to object +*/ +template <typename T> inline std::shared_ptr<T> make_shared_from_UNO(T* p) +{ + p->acquire(); + return std::shared_ptr<T>(p, detail::ReleaseFunc<T>()); +} + +} // namespace comphelper + +#endif // ! defined(INCLUDED_COMPHELPER_MAKE_SHARED_FROM_UNO_HXX) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/mimeconfighelper.hxx b/include/comphelper/mimeconfighelper.hxx new file mode 100644 index 000000000..5dd99664a --- /dev/null +++ b/include/comphelper/mimeconfighelper.hxx @@ -0,0 +1,142 @@ +/* -*- 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_COMPHELPER_MIMECONFIGHELPER_HXX +#define INCLUDED_COMPHELPER_MIMECONFIGHELPER_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <comphelper/comphelperdllapi.h> +#include <mutex> + +namespace com::sun::star::beans { struct NamedValue; } +namespace com::sun::star::beans { struct PropertyValue; } +namespace com::sun::star::container { class XContainerQuery; } +namespace com::sun::star::container { class XNameAccess; } +namespace com::sun::star::embed { struct VerbDescriptor; } +namespace com::sun::star::lang { class XMultiServiceFactory; } +namespace com::sun::star::uno { class XComponentContext; } + +enum class SfxFilterFlags; + +namespace comphelper { + +class COMPHELPER_DLLPUBLIC MimeConfigurationHelper +{ + std::mutex m_aMutex; + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::lang::XMultiServiceFactory > m_xConfigProvider; + + css::uno::Reference< css::container::XNameAccess > m_xObjectConfig; + css::uno::Reference< css::container::XNameAccess > m_xVerbsConfig; + css::uno::Reference< css::container::XNameAccess > m_xMediaTypeConfig; + + css::uno::Reference< css::container::XNameAccess > m_xFilterFactory; + +public: + + MimeConfigurationHelper( css::uno::Reference< css::uno::XComponentContext > xContext ); + + + static OUString GetStringClassIDRepresentation( const css::uno::Sequence< sal_Int8 >& aClassID ); + + static css::uno::Sequence< sal_Int8 > GetSequenceClassIDRepresentation( std::u16string_view aClassID ); + + + css::uno::Reference< css::container::XNameAccess > GetObjConfiguration(); + css::uno::Reference< css::container::XNameAccess > GetVerbsConfiguration(); + css::uno::Reference< css::container::XNameAccess > GetMediaTypeConfiguration(); + + + OUString GetDocServiceNameFromFilter( const OUString& aFilterName ); + + OUString GetDocServiceNameFromMediaType( const OUString& aMediaType ); + + css::uno::Sequence< css::beans::NamedValue > GetObjPropsFromConfigEntry( + const css::uno::Sequence< sal_Int8 >& aClassID, + const css::uno::Reference< css::container::XNameAccess >& xObjectProps ); + + bool GetVerbByShortcut( const OUString& aVerbShortcut, + css::embed::VerbDescriptor& aDescriptor ); + + OUString GetExplicitlyRegisteredObjClassID( const OUString& aMediaType ); + + + // retrieving object description from configuration + css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByStringClassID( + const OUString& aStringClassID ); + + css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByClassID( + const css::uno::Sequence< sal_Int8 >& aClassID ); + + css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByMediaType( + const OUString& aMediaType ); + + css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByFilter( + const OUString& aFilterName ); + + css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByDocumentName( + std::u16string_view aDocumentName ); + + // retrieving object factory from configuration + OUString GetFactoryNameByStringClassID( const OUString& aStringClassID ); + OUString GetFactoryNameByClassID( const css::uno::Sequence< sal_Int8 >& aClassID ); + OUString GetFactoryNameByDocumentName( std::u16string_view aDocName ); + OUString GetFactoryNameByMediaType( const OUString& aMediaType ); + + // typedetection related + css::uno::Reference< css::container::XNameAccess > GetFilterFactory(); + + OUString UpdateMediaDescriptorWithFilterName( + css::uno::Sequence< css::beans::PropertyValue >& aMediaDescr, + bool bIgnoreType ); + OUString UpdateMediaDescriptorWithFilterName( + css::uno::Sequence< css::beans::PropertyValue >& aMediaDescr, + css::uno::Sequence< css::beans::NamedValue >& aObject ); +#ifdef _WIN32 + SfxFilterFlags GetFilterFlags( const OUString& aFilterName ); + + bool AddFilterNameCheckOwnFile( + css::uno::Sequence< css::beans::PropertyValue >& aMediaDescr ); +#endif + + OUString GetDefaultFilterFromServiceName( const OUString& aServName, sal_Int32 nVersion ); + + OUString GetExportFilterFromImportFilter( const OUString& aImportFilterName ); + + static css::uno::Sequence< css::beans::PropertyValue > SearchForFilter( + const css::uno::Reference< css::container::XContainerQuery >& xFilterQuery, + const css::uno::Sequence< css::beans::NamedValue >& aSearchRequest, + SfxFilterFlags nMustFlags, + SfxFilterFlags nDontFlags ); + + static bool ClassIDsEqual( const css::uno::Sequence< sal_Int8 >& aClassID1, + const css::uno::Sequence< sal_Int8 >& aClassID2 ); + static css::uno::Sequence< sal_Int8 > GetSequenceClassID( sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3, + sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11, + sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 b15 ); +private: + css::uno::Reference< css::container::XNameAccess > + GetConfigurationByPathImpl( const OUString& aPath ); +}; + +} + +#endif // INCLUDED_COMPHELPER_MIMECONFIGHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/multicontainer2.hxx b/include/comphelper/multicontainer2.hxx new file mode 100644 index 000000000..91875b668 --- /dev/null +++ b/include/comphelper/multicontainer2.hxx @@ -0,0 +1,133 @@ +/* -*- 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 . + */ + +#pragma once + +#include <sal/config.h> + +#include <osl/mutex.hxx> +#include <com/sun/star/lang/EventObject.hpp> +#include <comphelper/comphelperdllapi.h> +#include <comphelper/interfacecontainer2.hxx> +#include <memory> +#include <vector> +#include <utility> + +namespace com::sun::star::uno +{ +class XInterface; +} + +namespace comphelper +{ +/** This is a copy of cppu::OMultiTypeInterfaceContainerHelper2 in include/cppuhelper/interfacecontainer.h, + except that it uses comphelper::OInterfaceContainerHelper2, which is more efficient. +*/ +class COMPHELPER_DLLPUBLIC OMultiTypeInterfaceContainerHelper2 +{ +public: + /** + Create a container of interface containers. + + @param rMutex the mutex to protect multi thread access. + The lifetime must be longer than the lifetime + of this object. + */ + OMultiTypeInterfaceContainerHelper2(::osl::Mutex& rMutex); + /** + Delete all containers. + */ + ~OMultiTypeInterfaceContainerHelper2(); + + /** + Return all id's under which at least one interface is added. + */ + std::vector<css::uno::Type> getContainedTypes() const; + + /** + Return the container created under this key. + @return the container created under this key. If the container + was not created, null was returned. + */ + OInterfaceContainerHelper2* getContainer(const css::uno::Type& rKey) const; + + /** Inserts an element into the container with the specified key. + The position is not specified, thus it is not specified in which order events are fired. + + @attention + If you add the same interface more than once, then it will be added to the elements list + more than once and thus if you want to remove that interface from the list, you have to call + removeInterface() the same number of times. + In the latter case, you will also get events fired more than once (if the interface is a + listener interface). + + @param rKey + the id of the container + @param r + interface to be added; it is allowed, to insert null or + the same interface more than once + @return + the new count of elements in the container + */ + sal_Int32 addInterface(const css::uno::Type& rKey, + const css::uno::Reference<css::uno::XInterface>& r); + + /** Removes an element from the container with the specified key. + It uses interface equality to remove the interface. + + @param rKey + the id of the container + @param rxIFace + interface to be removed + @return + the new count of elements in the container + */ + sal_Int32 removeInterface(const css::uno::Type& rKey, + const css::uno::Reference<css::uno::XInterface>& rxIFace); + + /** + Call disposing on all object in the container that + support XEventListener. Then clear the container. + */ + void disposeAndClear(const css::lang::EventObject& rEvt); + /** + Remove all elements of all containers. Does not delete the container. + */ + void clear(); + + typedef css::uno::Type keyType; + +private: + typedef std::vector<std::pair<css::uno::Type, std::unique_ptr<OInterfaceContainerHelper2>>> + t_type2ptr; + + t_type2ptr::iterator findType(const css::uno::Type& rKey); + t_type2ptr::const_iterator findType(const css::uno::Type& rKey) const; + + t_type2ptr m_aMap; + ::osl::Mutex& rMutex; + + OMultiTypeInterfaceContainerHelper2(const OMultiTypeInterfaceContainerHelper2&) = delete; + OMultiTypeInterfaceContainerHelper2& operator=(const OMultiTypeInterfaceContainerHelper2&) + = delete; +}; + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/multiinterfacecontainer3.hxx b/include/comphelper/multiinterfacecontainer3.hxx new file mode 100644 index 000000000..87199885e --- /dev/null +++ b/include/comphelper/multiinterfacecontainer3.hxx @@ -0,0 +1,217 @@ +/* -*- 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 . + */ +#pragma once + +#include <sal/config.h> + +#include <com/sun/star/lang/EventObject.hpp> +#include <comphelper/interfacecontainer3.hxx> +#include <memory> +#include <vector> + +namespace osl +{ +class Mutex; +} + +namespace comphelper +{ +/** + A helper class to store interface references of different types. + This is a copy of the similar class at include/cppuhelper/interfacecontainer.h, + but now uses the improved comphelper::InterfaceContainer3. + + @see OInterfaceIteratorHelper3 + @see OInterfaceContainerHelper3 + */ +template <class listener, class key, class equalImpl = std::equal_to<key>> +class OMultiTypeInterfaceContainerHelperVar3 +{ +public: + /** + Create a container of interface containers. + + @param rMutex the mutex to protect multi thread access. + The lifetime must be longer than the lifetime + of this object. + */ + inline OMultiTypeInterfaceContainerHelperVar3(::osl::Mutex& rMutex_) + : rMutex(rMutex_) + { + } + + /** + Return all id's under which at least one interface is added. + */ + inline std::vector<key> getContainedTypes() const + { + ::osl::MutexGuard aGuard(rMutex); + std::vector<key> aInterfaceTypes; + aInterfaceTypes.reserve(m_aMap.size()); + for (const auto& rPair : m_aMap) + // are interfaces added to this container? + if (rPair.second->getLength()) + // yes, put the type in the array + aInterfaceTypes.push_back(rPair.first); + return aInterfaceTypes; + } + + inline bool hasContainedTypes() const + { + ::osl::MutexGuard aGuard(rMutex); + for (const auto& rPair : m_aMap) + // are interfaces added to this container? + if (rPair.second->getLength()) + return true; + return false; + } + + /** + Return the container created under this key. + The InterfaceContainerHelper exists until the whole MultiTypeContainer is destroyed. + @return the container created under this key. If the container + was not created, null was returned. + */ + inline OInterfaceContainerHelper3<listener>* getContainer(const key& rKey) const + { + ::osl::MutexGuard aGuard(rMutex); + + auto iter = find(rKey); + if (iter != m_aMap.end()) + return (*iter).second.get(); + return nullptr; + } + + /** Inserts an element into the container with the specified key. + The position is not specified, thus it is not specified in which order events are fired. + + @attention + If you add the same interface more than once, then it will be added to the elements list + more than once and thus if you want to remove that interface from the list, you have to call + removeInterface() the same number of times. + In the latter case, you will also get events fired more than once (if the interface is a + listener interface). + + @param rKey + the id of the container + @param r + interface to be added; it is allowed, to insert null or + the same interface more than once + @return + the new count of elements in the container + */ + inline sal_Int32 addInterface(const key& rKey, const css::uno::Reference<listener>& rListener) + { + ::osl::MutexGuard aGuard(rMutex); + auto iter = find(rKey); + if (iter == m_aMap.end()) + { + auto pLC = new OInterfaceContainerHelper3<listener>(rMutex); + m_aMap.emplace_back(rKey, pLC); + return pLC->addInterface(rListener); + } + else + return (*iter).second->addInterface(rListener); + } + + /** Removes an element from the container with the specified key. + It uses interface equality to remove the interface. + + @param rKey + the id of the container + @param rxIFace + interface to be removed + @return + the new count of elements in the container + */ + inline sal_Int32 removeInterface(const key& rKey, + const css::uno::Reference<listener>& rListener) + { + ::osl::MutexGuard aGuard(rMutex); + + // search container with id nUik + auto iter = find(rKey); + // container found? + if (iter != m_aMap.end()) + return (*iter).second->removeInterface(rListener); + + // no container with this id. Always return 0 + return 0; + } + + /** + Call disposing on all references in the container, that + support XEventListener. Then clears the container. + @param rEvt the event object which is passed during disposing() call + */ + inline void disposeAndClear(const css::lang::EventObject& rEvt) + { + // create a copy, because do not fire event in a guarded section + InterfaceMap tempMap; + { + ::osl::MutexGuard aGuard(rMutex); + tempMap = std::move(m_aMap); + } + + for (auto& rPair : tempMap) + rPair.second->disposeAndClear(rEvt); + } + + /** + Remove all elements of all containers. Does not delete the container. + */ + inline void clear() + { + ::osl::MutexGuard aGuard(rMutex); + + for (const auto& rPair : m_aMap) + rPair.second->clear(); + } + + typedef key keyType; + +private: + typedef ::std::vector<std::pair<key, std::unique_ptr<OInterfaceContainerHelper3<listener>>>> + InterfaceMap; + InterfaceMap m_aMap; + ::osl::Mutex& rMutex; + + typename InterfaceMap::const_iterator find(const key& rKey) const + { + auto iter = m_aMap.begin(); + auto end = m_aMap.end(); + + while (iter != end) + { + equalImpl equal; + if (equal(iter->first, rKey)) + break; + ++iter; + } + return iter; + } + + OMultiTypeInterfaceContainerHelperVar3(const OMultiTypeInterfaceContainerHelperVar3&) = delete; + OMultiTypeInterfaceContainerHelperVar3& operator=(const OMultiTypeInterfaceContainerHelperVar3&) + = delete; +}; + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/multiinterfacecontainer4.hxx b/include/comphelper/multiinterfacecontainer4.hxx new file mode 100644 index 000000000..eeccd2092 --- /dev/null +++ b/include/comphelper/multiinterfacecontainer4.hxx @@ -0,0 +1,190 @@ +/* -*- 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 . + */ +#pragma once +#include <sal/config.h> +#include <com/sun/star/lang/EventObject.hpp> +#include <comphelper/interfacecontainer4.hxx> +#include <memory> +#include <mutex> +#include <vector> +/** */ //for docpp +namespace comphelper +{ +/** + A helper class to store interface references of different types. + This is a copy of the code at include/comphelper/multiinterfacecontainer3.hxx, + except that it (a) uses std::mutex instead of osl::Mutex and (b) does not + store a reference to the mutex, but relies on the calling class to take + a lock around using it. + @see OInterfaceIteratorHelper3 + @see OInterfaceContainerHelper3 + */ +template <class key, class listener, class equalImpl = std::equal_to<key>> +class OMultiTypeInterfaceContainerHelperVar4 +{ +public: + OMultiTypeInterfaceContainerHelperVar4() {} + /** + Return all id's under which at least one interface is added. + */ + inline std::vector<key> getContainedTypes(std::unique_lock<std::mutex>& rGuard) const + { + std::vector<key> aInterfaceTypes; + aInterfaceTypes.reserve(m_aMap.size()); + for (const auto& rPair : m_aMap) + // are interfaces added to this container? + if (rPair.second->getLength(rGuard)) + // yes, put the type in the array + aInterfaceTypes.push_back(rPair.first); + return aInterfaceTypes; + } + inline bool hasContainedTypes() const + { + for (const auto& rPair : m_aMap) + // are interfaces added to this container? + if (rPair.second->getLength()) + return true; + return false; + } + /** + Return the container created under this key. + The InterfaceContainerHelper exists until the whole MultiTypeContainer is destroyed. + @return the container created under this key. If the container + was not created, null was returned. + */ + inline OInterfaceContainerHelper4<listener>* getContainer(const key& rKey) const + { + auto iter = find(rKey); + if (iter != m_aMap.end()) + return (*iter).second.get(); + return nullptr; + } + /** Inserts an element into the container with the specified key. + The position is not specified, thus it is not specified in which order events are fired. + @attention + If you add the same interface more than once, then it will be added to the elements list + more than once and thus if you want to remove that interface from the list, you have to call + removeInterface() the same number of times. + In the latter case, you will also get events fired more than once (if the interface is a + listener interface). + @param rKey + the id of the container + @param r + interface to be added; it is allowed, to insert null or + the same interface more than once + @return + the new count of elements in the container + */ + inline sal_Int32 addInterface(::std::unique_lock<::std::mutex>& rGuard, const key& rKey, + const css::uno::Reference<listener>& rListener) + { + auto iter = find(rKey); + if (iter == m_aMap.end()) + { + auto pLC = new OInterfaceContainerHelper4<listener>(); + m_aMap.emplace_back(rKey, pLC); + return pLC->addInterface(rGuard, rListener); + } + else + return (*iter).second->addInterface(rGuard, rListener); + } + /** Removes an element from the container with the specified key. + It uses interface equality to remove the interface. + @param rKey + the id of the container + @param rxIFace + interface to be removed + @return + the new count of elements in the container + */ + inline sal_Int32 removeInterface(::std::unique_lock<::std::mutex>& rGuard, const key& rKey, + const css::uno::Reference<listener>& rListener) + { + // search container with id nUik + auto iter = find(rKey); + // container found? + if (iter != m_aMap.end()) + return (*iter).second->removeInterface(rGuard, rListener); + // no container with this id. Always return 0 + return 0; + } + /** + Call disposing on all references in the container, that + support XEventListener. Then clears the container. + @param rEvt the event object which is passed during disposing() call + */ + inline void disposeAndClear(std::unique_lock<std::mutex>& rGuard, + const css::lang::EventObject& rEvt) + { + // create a copy, because do not fire event in a guarded section + InterfaceMap tempMap; + { + tempMap = std::move(m_aMap); + } + rGuard.unlock(); + for (auto& rPair : tempMap) + { + OInterfaceIteratorHelper4<listener> aIt(rGuard, *rPair.second); + while (aIt.hasMoreElements()) + { + try + { + aIt.next()->disposing(rEvt); + } + catch (css::uno::RuntimeException&) + { + // be robust, if e.g. a remote bridge has disposed already. + // there is no way to delegate the error to the caller :o(. + } + } + } + } + /** + Remove all elements of all containers. Does not delete the container. + */ + inline void clear() + { + for (const auto& rPair : m_aMap) + rPair.second->clear(); + } + typedef key keyType; + +private: + typedef ::std::vector<std::pair<key, std::unique_ptr<OInterfaceContainerHelper4<listener>>>> + InterfaceMap; + InterfaceMap m_aMap; + typename InterfaceMap::const_iterator find(const key& rKey) const + { + auto iter = m_aMap.begin(); + auto end = m_aMap.end(); + while (iter != end) + { + equalImpl equal; + if (equal(iter->first, rKey)) + break; + ++iter; + } + return iter; + } + OMultiTypeInterfaceContainerHelperVar4(const OMultiTypeInterfaceContainerHelperVar4&) = delete; + OMultiTypeInterfaceContainerHelperVar4& operator=(const OMultiTypeInterfaceContainerHelperVar4&) + = delete; +}; +} // namespace comphelper +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/namecontainer.hxx b/include/comphelper/namecontainer.hxx new file mode 100644 index 000000000..616b07f1a --- /dev/null +++ b/include/comphelper/namecontainer.hxx @@ -0,0 +1,40 @@ +/* -*- 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_COMPHELPER_NAMECONTAINER_HXX +#define INCLUDED_COMPHELPER_NAMECONTAINER_HXX + +#include <com/sun/star/uno/Type.h> +#include <com/sun/star/uno/Reference.h> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::container +{ +class XNameContainer; +} + +namespace comphelper +{ +COMPHELPER_DLLPUBLIC css::uno::Reference<css::container::XNameContainer> +NameContainer_createInstance(const css::uno::Type& aType); +} + +#endif // INCLUDED_COMPHELPER_NAMECONTAINER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/namedvaluecollection.hxx b/include/comphelper/namedvaluecollection.hxx new file mode 100644 index 000000000..b92646e40 --- /dev/null +++ b/include/comphelper/namedvaluecollection.hxx @@ -0,0 +1,322 @@ +/* -*- 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_COMPHELPER_NAMEDVALUECOLLECTION_HXX +#define INCLUDED_COMPHELPER_NAMEDVALUECOLLECTION_HXX + +#include <comphelper/comphelperdllapi.h> + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/NamedValue.hpp> + +#include <vector> +#include <unordered_map> + +namespace comphelper +{ + + + // = NamedValueCollection + + /** a collection of named values, packed in various formats. + */ + class COMPHELPER_DLLPUBLIC NamedValueCollection + { + std::unordered_map< OUString, css::uno::Any > maValues; + public: + NamedValueCollection() = default; + + NamedValueCollection( const NamedValueCollection& _rCopySource ) = default; + NamedValueCollection(NamedValueCollection&& _rCopySource) noexcept = default; + + NamedValueCollection& operator=( const NamedValueCollection& i_rCopySource ) = default; + NamedValueCollection& operator=(NamedValueCollection&& i_rCopySource) noexcept = default; + + /** constructs a collection + @param _rElements + the wrapped elements of the collection. The @c Any might contain a sequence of + property values, a sequence of named values, or directly a property value or named value. + All other cases are worth an assertion in non-product builds. + */ + NamedValueCollection( const css::uno::Any& _rElements ); + + /** constructs a collection + @param _rArguments + a sequence of Any's containing either PropertyValue's or NamedValue's. + */ + NamedValueCollection( const css::uno::Sequence< css::uno::Any >& _rArguments ); + + /** constructs a collection + @param _rArguments + a sequence of PropertyValues's + */ + NamedValueCollection( const css::uno::Sequence< css::beans::PropertyValue >& _rArguments ); + + /** constructs a collection + @param _rArguments + a sequence of NamedValue's + */ + NamedValueCollection( const css::uno::Sequence< css::beans::NamedValue >& _rArguments ); + + void assign( const css::uno::Sequence< css::uno::Any >& _rArguments ) + { + impl_assign( _rArguments ); + } + + void clear() + { + impl_assign( css::uno::Sequence< css::beans::NamedValue >() ); + } + + /** determines whether or not named values can be extracted from the given value + + @return + true if and only if the given @c Any contains a @c NamedValue, a + @c PropertyValue, or a sequence thereof. + */ + static bool canExtractFrom( css::uno::Any const & i_value ); + + /// returns the number of elements in the collection + size_t size() const; + + /// determines whether the collection is empty + bool empty() const; + + /** returns the names of all elements in the collection + */ + ::std::vector< OUString > + getNames() const; + + /** merges the content of another collection into @c this + @param _rAdditionalValues + the collection whose values are to be merged + @param _bOverwriteExisting + defines whether or not elements which are already present in @c this + should be overwritten (true) or preserved (false). + @return @c *this + */ + NamedValueCollection& + merge( + const NamedValueCollection& _rAdditionalValues, + bool _bOverwriteExisting + ); + + /** retrieves a value with a given name from the collection, if it is present + + @param _pAsciiValueName + the ASCII name of the value to retrieve + + @param _out_rValue + is the output parameter taking the desired value upon successful return. If + a value with the given name is not present in the collection, or if a wrong-typed + value is present, then this parameter will not be touched. + + @retval + true if there is a value with the given name, which could successfully + be extracted. In this case, @c _out_rValue will contain the requested + value. + @retval + false, if there is no value with the given name. + + @throws IllegalArgumentException + in case there is a value with the given name, but it cannot legally assigned to + _out_rValue. + */ + template < typename VALUE_TYPE > + bool get_ensureType( const OUString& _rValueName, VALUE_TYPE& _out_rValue ) const + { + return get_ensureType( _rValueName, &_out_rValue, ::cppu::UnoType< VALUE_TYPE >::get() ); + } + + /** retrieves a value with a given name, or defaults it to a given value, if it's not present + in the collection + */ + template < typename VALUE_TYPE > + VALUE_TYPE getOrDefault( const OUString& _rValueName, const VALUE_TYPE& _rDefault ) const + { + VALUE_TYPE retVal( _rDefault ); + get_ensureType( _rValueName, retVal ); + return retVal; + } + + /** Retrieves a value with a given name, or defaults it to a given value, if it's not present + in the collection. + For when you only need a single value from a Sequence<PropertyValue>. + */ + template < typename VALUE_TYPE > + static VALUE_TYPE getOrDefault( const css::uno::Sequence<css::beans::PropertyValue> & rPropSeq, + std::u16string_view _rValueName, const VALUE_TYPE& _rDefault ) + { + VALUE_TYPE retVal( _rDefault ); + get_ensureType( rPropSeq, _rValueName, &retVal, ::cppu::UnoType< VALUE_TYPE >::get() ); + return retVal; + } + + /** retrieves a (untyped) value with a given name + + If the collection does not contain a value with the given name, an empty + Any is returned. + */ + const css::uno::Any& get( const OUString& _rValueName ) const + { + return impl_get( _rValueName ); + } + + /** retrieves a (untyped) value with a given name. For when you only need a single value from a Sequence<PropertyValue>. + + If the collection does not contain a value with the given name, an empty + Any is returned. + */ + static const css::uno::Any& get( const css::uno::Sequence<css::beans::PropertyValue>& rPropSeq, std::u16string_view _rValueName ); + + /// determines whether a value with a given name is present in the collection + bool has( const OUString& _rValueName ) const + { + return impl_has( _rValueName ); + } + + /** puts a value into the collection + + @return true if and only if a value was already present previously, in + which case it has been overwritten. + */ + template < typename VALUE_TYPE > + bool put( const OUString& _rValueName, const VALUE_TYPE& _rValue ) + { + return impl_put( _rValueName, css::uno::Any( _rValue ) ); + } + + bool put( const OUString& _rValueName, const css::uno::Any& _rValue ) + { + return impl_put( _rValueName, _rValue ); + } + + /** removes the value with the given name from the collection + + @return true if and only if a value with the given name existed in the collection. + */ + bool remove( const OUString& _rValueName ) + { + return impl_remove( _rValueName ); + } + + /** transforms the collection to a sequence of PropertyValues + + @return + the number of elements in the sequence + */ + sal_Int32 operator >>= ( css::uno::Sequence< css::beans::PropertyValue >& _out_rValues ) const; + + /** transforms the collection to a sequence of NamedValues + + @return + the number of elements in the sequence + */ + sal_Int32 operator >>= ( css::uno::Sequence< css::beans::NamedValue >& _out_rValues ) const; + + /** transforms the collection into a sequence of PropertyValues + */ + css::uno::Sequence< css::beans::PropertyValue > + getPropertyValues() const + { + css::uno::Sequence< css::beans::PropertyValue > aValues; + *this >>= aValues; + return aValues; + } + + /** returns a Sequence< Any >, containing PropertyValues + */ + css::uno::Sequence< css::uno::Any > + getWrappedPropertyValues() const + { + return impl_wrap< css::beans::PropertyValue >(); + } + + /** returns a Sequence< Any >, containing NamedValues + */ + css::uno::Sequence< css::uno::Any > + getWrappedNamedValues() const + { + return impl_wrap< css::beans::NamedValue >(); + } + + /** transforms the collection into a sequence of NamedValues + */ + css::uno::Sequence< css::beans::NamedValue > + getNamedValues() const + { + css::uno::Sequence< css::beans::NamedValue > aValues; + *this >>= aValues; + return aValues; + } + + private: + void impl_assign( const css::uno::Any& i_rWrappedElements ); + void impl_assign( const css::uno::Sequence< css::uno::Any >& _rArguments ); + void impl_assign( const css::uno::Sequence< css::beans::PropertyValue >& _rArguments ); + void impl_assign( const css::uno::Sequence< css::beans::NamedValue >& _rArguments ); + + bool get_ensureType( + const OUString& _rValueName, + void* _pValueLocation, + const css::uno::Type& _rExpectedValueType + ) const; + + static bool get_ensureType( + const css::uno::Sequence<css::beans::PropertyValue> & rPropSeq, + std::u16string_view _rValueName, + void* _pValueLocation, + const css::uno::Type& _rExpectedValueType + ); + + const css::uno::Any& + impl_get( const OUString& _rValueName ) const; + + bool impl_has( const OUString& _rValueName ) const; + + bool impl_put( const OUString& _rValueName, const css::uno::Any& _rValue ); + + bool impl_remove( const OUString& _rValueName ); + + template< class VALUE_TYPE > + css::uno::Sequence< css::uno::Any > impl_wrap() const + { + css::uno::Sequence< VALUE_TYPE > aValues; + *this >>= aValues; + css::uno::Sequence< css::uno::Any > aWrappedValues( aValues.getLength() ); + + css::uno::Any* pO = aWrappedValues.getArray(); + const VALUE_TYPE* pV = aValues.getConstArray(); + const sal_Int32 nLen = aValues.getLength(); + for( sal_Int32 i = 0; i < nLen; ++i ) + *(pO++) = css::uno::Any( *(pV++) ); + + return aWrappedValues; + } + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_NAMEDVALUECOLLECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/newarray.hxx b/include/comphelper/newarray.hxx new file mode 100644 index 000000000..d3eaccd77 --- /dev/null +++ b/include/comphelper/newarray.hxx @@ -0,0 +1,42 @@ +/* -*- 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_COMPHELPER_NEWARRAY_HXX +#define INCLUDED_COMPHELPER_NEWARRAY_HXX + +#include <limits> +#include <new> +#include <stddef.h> + +namespace comphelper { + +template<typename T> T * +newArray_null(size_t const n) noexcept +{ + if ((::std::numeric_limits<size_t>::max() / sizeof(T)) <= n) { + return nullptr; + } + return new (::std::nothrow) T[n]; +} + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_NEWARRAY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/numberedcollection.hxx b/include/comphelper/numberedcollection.hxx new file mode 100644 index 000000000..3dbb1f534 --- /dev/null +++ b/include/comphelper/numberedcollection.hxx @@ -0,0 +1,168 @@ +/* -*- 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_COMPHELPER_NUMBEREDCOLLECTION_HXX +#define INCLUDED_COMPHELPER_NUMBEREDCOLLECTION_HXX + +#include <comphelper/comphelperdllapi.h> + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/frame/XUntitledNumbers.hpp> + +#include <cppuhelper/weakref.hxx> +#include <cppuhelper/implbase.hxx> + +#include <unordered_map> +#include <mutex> +#include <vector> + +namespace com::sun::star::uno { class XInterface; } + +namespace comphelper{ + +/** @short defines a collection of UNO components, where every component will get its own unique number. + + @descr Such number will be unique at runtime only... but it supports fragmentation. + Note: This collection uses weak references only to know her components. + So lifetime of these components must be controlled outside. + + @threadsafe + */ +class COMPHELPER_DLLPUBLIC NumberedCollection final : + public ::cppu::WeakImplHelper< css::frame::XUntitledNumbers > +{ + + // types, const + private: + + struct TNumberedItem + { + css::uno::WeakReference< css::uno::XInterface > xItem; + ::sal_Int32 nNumber; + }; + + typedef std::unordered_map< + sal_IntPtr, + TNumberedItem > TNumberedItemHash; + + typedef ::std::vector< sal_IntPtr > TDeadItemList; + + + // interface + public: + + + /** @short lightweight constructor. + */ + NumberedCollection(); + + + /** @short free all internally used resources. + */ + virtual ~NumberedCollection() override; + + + /** set an outside component which uses this container and must be set + as source of all broadcasted messages, exceptions. + + It's holded weak only so we do not need any complex dispose sessions. + + Note: Passing NULL as parameter will be allowed. It will reset the internal + member reference only. + + @param xOwner + the new owner of this collection. + */ + void setOwner (const css::uno::Reference< css::uno::XInterface >& xOwner); + + + /** set the localized prefix to be used for untitled components. + + Localization has to be done outside. This container will return + those value then. There are no further checks. Its up to you to define + a suitable string here :-) + + @param sPrefix + the new prefix for untitled components. + */ + void setUntitledPrefix(const OUString& sPrefix); + + + /** @see css.frame.XUntitledNumbers */ + virtual ::sal_Int32 SAL_CALL leaseNumber(const css::uno::Reference< css::uno::XInterface >& xComponent) override; + + + /** @see css.frame.XUntitledNumbers */ + virtual void SAL_CALL releaseNumber(::sal_Int32 nNumber) override; + + + /** @see css.frame.XUntitledNumbers */ + virtual void SAL_CALL releaseNumberForComponent(const css::uno::Reference< css::uno::XInterface >& xComponent) override; + + + /** @see css.frame.XUntitledNumbers */ + virtual OUString SAL_CALL getUntitledPrefix() override; + + + // internal + private: + + + /** @short tries to find a unique number not already used within this collection. + + @descr It reuses the smallest number which isn't used by any component + of this collection. (fragmentation!) If collection is full (means there + is no free number) the special value INVALID_NUMBER will be returned. + + @note Those method can't be called within a multithreaded environment. + Because such number won't be "reserved" for the call of these method + it can happen that two calls returns the same number (reasoned by the fact that first call + doesn't used the returned number already. + + So the outside code has to make sure that retrieving and using of those numbers + will be an atomic operation. + + @return a unique number or special value INVALID_NUMBER if collection is full. + */ + ::sal_Int32 impl_searchFreeNumber (); + + static void impl_cleanUpDeadItems ( TNumberedItemHash& lItems , + const TDeadItemList& lDeadItems); + + + // member + private: + + /// localized string to be used for untitled components + OUString m_sUntitledPrefix; + + /// cache of all "leased numbers" and its bound components + TNumberedItemHash m_lComponents; + + /// used as source of broadcasted messages or exceptions (can be null !) + css::uno::WeakReference< css::uno::XInterface > m_xOwner; + + std::mutex m_aMutex; +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_NUMBEREDCOLLECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/numbers.hxx b/include/comphelper/numbers.hxx new file mode 100644 index 000000000..e486bac0b --- /dev/null +++ b/include/comphelper/numbers.hxx @@ -0,0 +1,56 @@ +/* -*- 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_COMPHELPER_NUMBERS_HXX +#define INCLUDED_COMPHELPER_NUMBERS_HXX + +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/Reference.h> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::util { class XNumberFormats; } +namespace com::sun::star::util { class XNumberFormatter; } + +namespace comphelper +{ + + /// returns the css::util::NumberFormat of the given key under the given formats + COMPHELPER_DLLPUBLIC sal_Int16 getNumberFormatType(const css::uno::Reference<css::util::XNumberFormats>& xFormats, sal_Int32 nKey); + + /// returns the css::util::NumberFormat of the given key under the given formatter + COMPHELPER_DLLPUBLIC sal_Int16 getNumberFormatType(const css::uno::Reference<css::util::XNumberFormatter>& xFormatter, sal_Int32 nKey); + + /// returns the decimals of the given numeric number formatunder the given formats + COMPHELPER_DLLPUBLIC css::uno::Any getNumberFormatDecimals(const css::uno::Reference<css::util::XNumberFormats>& xFormats, sal_Int32 nKey); + + /** retrieves the value of a given property for a given format key, relating to a given formatter + */ + COMPHELPER_DLLPUBLIC css::uno::Any getNumberFormatProperty( + const css::uno::Reference< css::util::XNumberFormatter >& _rxFormatter, + sal_Int32 _nKey, + const OUString& _rPropertyName + ); + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_NUMBERS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/ofopxmlhelper.hxx b/include/comphelper/ofopxmlhelper.hxx new file mode 100644 index 000000000..fe778bf1e --- /dev/null +++ b/include/comphelper/ofopxmlhelper.hxx @@ -0,0 +1,101 @@ +/* -*- 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_COMPHELPER_OFOPXMLHELPER_HXX +#define INCLUDED_COMPHELPER_OFOPXMLHELPER_HXX + +#include <sal/config.h> + +#include <string_view> + +#include <com/sun/star/uno/Sequence.h> + +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::beans { struct StringPair; } +namespace com::sun::star::io { class XInputStream; } +namespace com::sun::star::io { class XOutputStream; } +namespace com::sun::star::uno { class XComponentContext; } +namespace com::sun::star::uno { template <class interface_type> class Reference; } + +namespace comphelper::OFOPXMLHelper { + + // returns sequence of elements, where each element is described by sequence of tags, + // where each tag is described by StringPair ( First - name, Second - value ) + // the first tag of each element sequence must be "Id" + /// @throws css::uno::Exception + COMPHELPER_DLLPUBLIC + css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > + ReadRelationsInfoSequence( + const css::uno::Reference< css::io::XInputStream >& xInStream, + std::u16string_view aStreamName, + const css::uno::Reference< css::uno::XComponentContext >& rContext ); + + // returns sequence containing two entries of type sequence<StringPair> + // the first sequence describes "Default" elements, where each element is described + // by StringPair object ( First - Extension, Second - ContentType ) + // the second sequence describes "Override" elements, where each element is described + // by StringPair object ( First - PartName, Second - ContentType ) + /// @throws css::uno::Exception + COMPHELPER_DLLPUBLIC + css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > + ReadContentTypeSequence( + const css::uno::Reference< css::io::XInputStream >& xInStream, + const css::uno::Reference< css::uno::XComponentContext >& rContext ); + + // returns the ContentType for the given name, or empty when not found. + // rContentTypes is a sequence containing two entries of type sequence<StringPair> + // the first sequence describes "Default" elements, where each element is described + // by StringPair object ( First - Extension, Second - ContentType ) + // the second sequence describes "Override" elements, where each element is described + // by StringPair object ( First - PartName, Second - ContentType ) + // The "Override" sequence is searched first before falling back on "Default". + COMPHELPER_DLLPUBLIC + OUString + GetContentTypeByName(const css::uno::Sequence<css::uno::Sequence<css::beans::StringPair>>& rContentTypes, + const OUString& rFilename); + + // writes sequence of elements, where each element is described by sequence of tags, + // where each tag is described by StringPair ( First - name, Second - value ) + // the first tag of each element sequence must be "Id" + /// @throws css::uno::Exception + COMPHELPER_DLLPUBLIC + void WriteRelationsInfoSequence( + const css::uno::Reference< css::io::XOutputStream >& xOutStream, + const css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > >& aSequence, + const css::uno::Reference< css::uno::XComponentContext >& rContext ); + + // writes two entries of type sequence<StringPair> + // the first sequence describes "Default" elements, where each element is described + // by StringPair object ( First - Extension, Second - ContentType ) + // the second sequence describes "Override" elements, where each element is described + // by StringPair object ( First - PartName, Second - ContentType ) + /// @throws css::uno::Exception + COMPHELPER_DLLPUBLIC + void WriteContentSequence( + const css::uno::Reference< css::io::XOutputStream >& xOutStream, + const css::uno::Sequence< css::beans::StringPair >& aDefaultsSequence, + const css::uno::Sequence< css::beans::StringPair >& aOverridesSequence, + const css::uno::Reference< css::uno::XComponentContext >& rContext ); + +} // namespace comphelper::OFOPXMLHelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/oslfile2streamwrap.hxx b/include/comphelper/oslfile2streamwrap.hxx new file mode 100644 index 000000000..c80c7b344 --- /dev/null +++ b/include/comphelper/oslfile2streamwrap.hxx @@ -0,0 +1,78 @@ +/* -*- 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_COMPHELPER_OSLFILE2STREAMWRAP_HXX +#define INCLUDED_COMPHELPER_OSLFILE2STREAMWRAP_HXX + +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> +#include <mutex> + +namespace osl { class File; } + +namespace comphelper +{ + +// Stream to read and write data, based on File + +class OSLInputStreamWrapper final : public ::cppu::WeakImplHelper<css::io::XInputStream> +{ +public: + COMPHELPER_DLLPUBLIC OSLInputStreamWrapper(::osl::File& _rStream); + +private: + virtual ~OSLInputStreamWrapper() override; + +// css::io::XInputStream + virtual sal_Int32 SAL_CALL readBytes(css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) override; + virtual sal_Int32 SAL_CALL readSomeBytes(css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) override; + virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) override; + virtual sal_Int32 SAL_CALL available() override; + virtual void SAL_CALL closeInput() override; + + std::mutex m_aMutex; + ::osl::File* m_pFile; +}; + + +// data sink for the files + +class OSLOutputStreamWrapper final : public ::cppu::WeakImplHelper<css::io::XOutputStream> +{ +public: + COMPHELPER_DLLPUBLIC OSLOutputStreamWrapper(::osl::File& _rFile); + +private: + virtual ~OSLOutputStreamWrapper() override; + +// css::io::XOutputStream + virtual void SAL_CALL writeBytes(const css::uno::Sequence< sal_Int8 >& aData) override; + virtual void SAL_CALL flush() override; + virtual void SAL_CALL closeOutput() override; + + ::osl::File& rFile; +}; + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_OSLFILE2STREAMWRAP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/parallelsort.hxx b/include/comphelper/parallelsort.hxx new file mode 100644 index 000000000..94d86e0d1 --- /dev/null +++ b/include/comphelper/parallelsort.hxx @@ -0,0 +1,373 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_PARALLELSORT_HXX +#define INCLUDED_COMPHELPER_PARALLELSORT_HXX + +#include <comphelper/threadpool.hxx> +#include <tools/cpuid.hxx> + +#include <memory> +#include <iterator> +#include <thread> +#include <algorithm> +#include <cmath> +#include <random> +#include <functional> +#include <iostream> +#include <chrono> + +namespace comphelper +{ +const size_t nThreadCountGlobal = std::thread::hardware_concurrency(); +const bool bHyperThreadingActive = cpuid::hasHyperThreading(); +static comphelper::ThreadPool& rTPool(comphelper::ThreadPool::getSharedOptimalPool()); + +static thread_local std::mt19937 aGenerator{ std::random_device{}() }; + +#define PARALLELSORT_ENABLEPZ 0 + +namespace +{ +class ProfileZone +{ +public: +#if PARALLELSORT_ENABLEPZ + ProfileZone(const char* pTag) + : maTag(pTag) + , maStart(std::chrono::steady_clock::now()) + , mbFinished(false) + { + } + + ~ProfileZone() + { + if (!mbFinished) + showTimeElapsed(); + } + + void stop() + { + showTimeElapsed(); + mbFinished = true; + } +#else + ProfileZone(const char* /*pTag*/) + : mbDummy(true) + { + } + + void stop() + { + // Avoid loplugin:staticmethods, loplugin:staticaccess errors + (void)mbDummy; + } +#endif + +private: +#if PARALLELSORT_ENABLEPZ + + void showTimeElapsed() + { + auto end = std::chrono::steady_clock::now(); + size_t elapsed + = std::chrono::duration_cast<std::chrono::milliseconds>(end - maStart).count(); + std::cout << maTag << " : " << elapsed << " ms" << std::endl << std::flush; + } + + std::string maTag; + std::chrono::steady_clock::time_point maStart; + bool mbFinished; +#else + bool mbDummy; + +#endif +}; + +class ParallelRunner +{ + class Executor final : public comphelper::ThreadTask + { + public: + Executor(const std::shared_ptr<comphelper::ThreadTaskTag>& rTag, + std::function<void()> aFunc) + : comphelper::ThreadTask(rTag) + , maFunc(std::move(aFunc)) + { + } + + virtual void doWork() override { maFunc(); } + + private: + const std::function<void()> maFunc; + }; + +public: + ParallelRunner() { maTag = comphelper::ThreadPool::createThreadTaskTag(); } + + void enqueue(std::function<void()> aFunc) + { + rTPool.pushTask(std::make_unique<Executor>(maTag, aFunc)); + } + + void wait() { rTPool.waitUntilDone(maTag, false); } + +private: + std::shared_ptr<comphelper::ThreadTaskTag> maTag; +}; + +constexpr size_t nMaxTreeArraySize = 64; + +size_t lcl_round_down_pow2(size_t nNum) +{ + size_t nPow2; + for (nPow2 = 1; nPow2 <= nNum; nPow2 <<= 1) + ; + return std::min((nPow2 >> 1), nMaxTreeArraySize); +} + +template <class RandItr> struct Sampler +{ + using ValueType = typename std::iterator_traits<RandItr>::value_type; + + static void sample(RandItr aBegin, RandItr aEnd, ValueType* pSamples, size_t nSamples, + size_t /*nParallelism*/) + { + ProfileZone aZone("\tsample()"); + assert(aBegin <= aEnd); + size_t nLen = static_cast<std::size_t>(aEnd - aBegin); + assert(std::mt19937::max() >= nLen); + + for (size_t nIdx = 0; nIdx < nSamples; ++nIdx) + { + size_t nSel = aGenerator() % nLen--; + using namespace std; + swap(*(aBegin + nSel), *(aBegin + nLen)); + pSamples[nIdx] = *(aBegin + nLen); + } + } +}; + +template <class RandItr, class Compare> class Binner +{ + using ValueType = typename std::iterator_traits<RandItr>::value_type; + + const size_t mnTreeArraySize; + const size_t mnDividers; + constexpr static size_t mnMaxStaticSize = 1024 * 50; + uint8_t maLabels[mnMaxStaticSize]; + ValueType maDividers[nMaxTreeArraySize]; + std::unique_ptr<uint8_t[]> pLabels; + size_t maSepBinEnds[nMaxTreeArraySize * nMaxTreeArraySize]; + bool mbThreaded; + +public: + size_t maBinEnds[nMaxTreeArraySize]; + + Binner(const ValueType* pSamples, size_t nSamples, size_t nBins, bool bThreaded) + : mnTreeArraySize(lcl_round_down_pow2(nBins)) + , mnDividers(mnTreeArraySize - 1) + , mbThreaded(bThreaded) + { + assert((nSamples % mnTreeArraySize) == 0); + assert(mnTreeArraySize <= nMaxTreeArraySize); + std::fill(maBinEnds, maBinEnds + mnTreeArraySize, 0); + std::fill(maSepBinEnds, maSepBinEnds + mnTreeArraySize * mnTreeArraySize, 0); + fillTreeArray(1, pSamples, pSamples + nSamples); + } + + void fillTreeArray(size_t nPos, const ValueType* pLow, const ValueType* pHigh) + { + assert(pLow <= pHigh); + const ValueType* pMid = pLow + (pHigh - pLow) / 2; + maDividers[nPos] = *pMid; + + if (2 * nPos < mnDividers) // So that 2*nPos < mnTreeArraySize + { + fillTreeArray(2 * nPos, pLow, pMid); + fillTreeArray(2 * nPos + 1, pMid + 1, pHigh); + } + } + + constexpr inline size_t findBin(const ValueType& rVal, Compare& aComp) + { + size_t nIdx = 1; + while (nIdx <= mnDividers) + nIdx = ((nIdx << 1) + aComp(maDividers[nIdx], rVal)); + return (nIdx - mnTreeArraySize); + } + + void label(const RandItr aBegin, const RandItr aEnd, Compare& aComp) + { + ProfileZone aZoneSetup("\tlabel():setup"); + size_t nLen = static_cast<std::size_t>(aEnd - aBegin); + if (nLen > mnMaxStaticSize) + pLabels = std::make_unique<uint8_t[]>(nLen); + uint8_t* pLabelsRaw = (nLen > mnMaxStaticSize) ? pLabels.get() : maLabels; + aZoneSetup.stop(); + ProfileZone aZoneFindBins("\tFindBins()"); + if (mbThreaded) + { + ParallelRunner aPRunner; + const size_t nBins = mnTreeArraySize; + for (size_t nTIdx = 0; nTIdx < nBins; ++nTIdx) + { + aPRunner.enqueue([this, nTIdx, nBins, nLen, aBegin, pLabelsRaw, &aComp] { + ProfileZone aZoneIn("\t\tFindBinsThreaded()"); + size_t nBinEndsStartIdx = nTIdx * mnTreeArraySize; + size_t* pBinEnds = maSepBinEnds + nBinEndsStartIdx; + size_t aBinEndsF[nMaxTreeArraySize] = { 0 }; + for (size_t nIdx = nTIdx; nIdx < nLen; nIdx += nBins) + { + size_t nBinIdx = findBin(*(aBegin + nIdx), aComp); + pLabelsRaw[nIdx] = static_cast<uint8_t>(nBinIdx); + ++aBinEndsF[nBinIdx]; + } + + for (size_t nIdx = 0; nIdx < mnTreeArraySize; ++nIdx) + pBinEnds[nIdx] = aBinEndsF[nIdx]; + }); + } + + aPRunner.wait(); + + // Populate maBinEnds from maSepBinEnds + for (size_t nTIdx = 0; nTIdx < mnTreeArraySize; ++nTIdx) + { + for (size_t nSepIdx = 0; nSepIdx < mnTreeArraySize; ++nSepIdx) + maBinEnds[nTIdx] += maSepBinEnds[nSepIdx * mnTreeArraySize + nTIdx]; + } + } + else + { + uint8_t* pLabel = pLabelsRaw; + for (RandItr aItr = aBegin; aItr != aEnd; ++aItr) + { + size_t nBinIdx = findBin(*aItr, aComp); + *pLabel++ = nBinIdx; + ++maBinEnds[nBinIdx]; + } + } + + aZoneFindBins.stop(); + + size_t nSum = 0; + // Store each bin's starting position in maBinEnds array for now. + for (size_t nIdx = 0; nIdx < mnTreeArraySize; ++nIdx) + { + size_t nSize = maBinEnds[nIdx]; + maBinEnds[nIdx] = nSum; + nSum += nSize; + } + + // Now maBinEnds has end positions of each bin. + } + + void bin(const RandItr aBegin, const RandItr aEnd, ValueType* pOut) + { + ProfileZone aZone("\tbin()"); + const size_t nLen = static_cast<std::size_t>(aEnd - aBegin); + uint8_t* pLabelsRaw = (nLen > mnMaxStaticSize) ? pLabels.get() : maLabels; + size_t nIdx; + for (nIdx = 0; nIdx < nLen; ++nIdx) + { + pOut[maBinEnds[pLabelsRaw[nIdx]]++] = *(aBegin + nIdx); + } + } +}; + +template <class RandItr, class Compare = std::less<>> +void s3sort(const RandItr aBegin, const RandItr aEnd, Compare aComp = Compare(), + bool bThreaded = true) +{ + static size_t nThreadCount = nThreadCountGlobal; + + constexpr size_t nBaseCaseSize = 1024; + const std::size_t nLen = static_cast<std::size_t>(aEnd - aBegin); + if (nLen < nBaseCaseSize) + { + std::sort(aBegin, aEnd, aComp); + return; + } + + using ValueType = typename std::iterator_traits<RandItr>::value_type; + auto pOut = std::make_unique<ValueType[]>(nLen); + + const size_t nBins = lcl_round_down_pow2(nThreadCount); + const size_t nOverSamplingFactor = std::max(1.0, std::sqrt(static_cast<double>(nLen) / 64)); + const size_t nSamples = nOverSamplingFactor * nBins; + auto aSamples = std::make_unique<ValueType[]>(nSamples); + ProfileZone aZoneSampleAnsSort("SampleAndSort"); + // Select samples and sort them + Sampler<RandItr>::sample(aBegin, aEnd, aSamples.get(), nSamples, nBins); + std::sort(aSamples.get(), aSamples.get() + nSamples, aComp); + aZoneSampleAnsSort.stop(); + + if (!aComp(aSamples[0], aSamples[nSamples - 1])) + { + // All samples are equal, fallback to standard sort. + std::sort(aBegin, aEnd, aComp); + return; + } + + ProfileZone aZoneBinner("Binner"); + // Create and populate bins using pOut from input iterators. + Binner<RandItr, Compare> aBinner(aSamples.get(), nSamples, nBins, bThreaded); + aBinner.label(aBegin, aEnd, aComp); + aBinner.bin(aBegin, aEnd, pOut.get()); + aZoneBinner.stop(); + + ProfileZone aZoneSortBins("SortBins"); + ValueType* pOutRaw = pOut.get(); + if (bThreaded) + { + ParallelRunner aPRunner; + // Sort the bins separately. + for (size_t nBinIdx = 0, nBinStart = 0; nBinIdx < nBins; ++nBinIdx) + { + size_t nBinEnd = aBinner.maBinEnds[nBinIdx]; + aPRunner.enqueue([pOutRaw, nBinStart, nBinEnd, &aComp] { + std::sort(pOutRaw + nBinStart, pOutRaw + nBinEnd, aComp); + }); + + nBinStart = nBinEnd; + } + + aPRunner.wait(); + } + else + { + for (size_t nBinIdx = 0, nBinStart = 0; nBinIdx < nBins; ++nBinIdx) + { + auto nBinEnd = aBinner.maBinEnds[nBinIdx]; + std::sort(pOutRaw + nBinStart, pOutRaw + nBinEnd, aComp); + nBinStart = nBinEnd; + } + } + + aZoneSortBins.stop(); + + // Move the sorted array to the array specified by input iterators. + std::move(pOutRaw, pOutRaw + nLen, aBegin); +} + +} // anonymous namespace + +template <class RandItr, class Compare = std::less<>> +void parallelSort(const RandItr aBegin, const RandItr aEnd, Compare aComp = Compare()) +{ + assert(aBegin <= aEnd); + s3sort(aBegin, aEnd, aComp); +} + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_PARALLELSORT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/processfactory.hxx b/include/comphelper/processfactory.hxx new file mode 100644 index 000000000..0f74e5b13 --- /dev/null +++ b/include/comphelper/processfactory.hxx @@ -0,0 +1,72 @@ +/* -*- 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_COMPHELPER_PROCESSFACTORY_HXX +#define INCLUDED_COMPHELPER_PROCESSFACTORY_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::lang { + class XMultiServiceFactory; +} +namespace com::sun::star::uno { class XComponentContext; } + +namespace comphelper +{ + +/** + * This function set the process service factory. + */ +COMPHELPER_DLLPUBLIC void setProcessServiceFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMgr); + +/** + * This function gets the process service factory. + * + * If no service factory is set the function throws a RuntimeException. + */ +COMPHELPER_DLLPUBLIC css::uno::Reference< css::lang::XMultiServiceFactory > getProcessServiceFactory(); + +/** Obtains a component context from a service factory. + + Throws a RuntimeException if no component context can be obtained. + + @param factory may be null + @return may be null + */ +COMPHELPER_DLLPUBLIC +css::uno::Reference< css::uno::XComponentContext > +getComponentContext( + css::uno::Reference< css::lang::XMultiServiceFactory > + const & factory); + +/** + * This function gets the process service factory's default component context. + * + * Throws a RuntimeException if no component context can be obtained. + */ +COMPHELPER_DLLPUBLIC +css::uno::Reference< css::uno::XComponentContext > +getProcessComponentContext(); + +} + +#endif // INCLUDED_COMPHELPER_PROCESSFACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/profilezone.hxx b/include/comphelper/profilezone.hxx new file mode 100644 index 000000000..71f9fa30b --- /dev/null +++ b/include/comphelper/profilezone.hxx @@ -0,0 +1,92 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. +*/ + +#ifndef INCLUDED_COMPHELPER_PROFILEZONE_HXX +#define INCLUDED_COMPHELPER_PROFILEZONE_HXX + +#include <sal/config.h> + +#include <sal/log.hxx> + +#include <comphelper/traceevent.hxx> + +// implementation of XToolkitExperimental profiling API + +namespace comphelper +{ +class COMPHELPER_DLLPUBLIC ProfileZone : public NamedEvent +{ + long long m_nCreateTime; + int m_nNesting; + + void addRecording(); + + static void setNestingLevel(int nNestingLevel); + static int getNestingLevel(); + + ProfileZone(const char* sName, const OUString& sArgs) + : NamedEvent(sName, sArgs) + , m_nNesting(-1) + { + if (s_bRecording) + { + m_nCreateTime = getNow(); + + m_nNesting = getNestingLevel(); + setNestingLevel(getNestingLevel() + 1); + } + else + m_nCreateTime = 0; + } + +public: + /** + * Starts measuring the cost of a C++ scope. + * + * Note that the char pointer is stored as such in the ProfileZone object and used in the + * destructor, so be sure to pass a pointer that stays valid for the duration of the object's + * lifetime. + */ + ProfileZone(const char* sName, const std::map<OUString, OUString>& aArgs) + : ProfileZone(sName, createArgsString(aArgs)) + { + } + + ProfileZone(const char* sName) + : ProfileZone(sName, OUString()) + { + } + + ~ProfileZone() + { + if (m_nCreateTime > 0) + { + setNestingLevel(getNestingLevel() - 1); + + if (m_nNesting != getNestingLevel()) + { + SAL_WARN("comphelper.traceevent", "Incorrect ProfileZone nesting for " << m_sName); + } + else + { + if (s_bRecording) + addRecording(); + } + } + } + + ProfileZone(const ProfileZone&) = delete; + void operator=(const ProfileZone&) = delete; +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_PROFILEZONE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propagg.hxx b/include/comphelper/propagg.hxx new file mode 100644 index 000000000..949251892 --- /dev/null +++ b/include/comphelper/propagg.hxx @@ -0,0 +1,325 @@ +/* -*- 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_COMPHELPER_PROPAGG_HXX +#define INCLUDED_COMPHELPER_PROPAGG_HXX + +#include <config_options.h> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include <com/sun/star/beans/XPropertiesChangeListener.hpp> +#include <com/sun/star/beans/XVetoableChangeListener.hpp> +#include <com/sun/star/lang/EventObject.hpp> +#include <comphelper/propstate.hxx> +#include <comphelper/comphelperdllapi.h> + +#include <cstddef> +#include <map> +#include <memory> +#include <vector> + + +//= property helper classes + + +namespace comphelper +{ + + +//= OPropertyAccessor +//= internal helper class for OPropertyArrayAggregationHelper + +namespace internal +{ + struct OPropertyAccessor + { + sal_Int32 nOriginalHandle; + std::size_t nPos; + bool bAggregate; + + OPropertyAccessor(sal_Int32 _nOriginalHandle, std::size_t _nPos, bool _bAggregate) + :nOriginalHandle(_nOriginalHandle) ,nPos(_nPos) ,bAggregate(_bAggregate) { } + + bool operator==(const OPropertyAccessor& rOb) const { return nPos == rOb.nPos; } + bool operator <(const OPropertyAccessor& rOb) const { return nPos < rOb.nPos; } + }; +} + + +/** + * used as callback for an OPropertyArrayAggregationHelper + */ +class IPropertyInfoService +{ +public: + /** get the preferred handle for the given property + @param _rName the property name + @return the handle the property should be referred by, or -1 if there are no + preferences for the given property + */ + virtual sal_Int32 getPreferredPropertyId(const OUString& _rName) = 0; + +protected: + ~IPropertyInfoService() {} +}; + +/** + * used for implementing a cppu::IPropertyArrayHelper for classes + * aggregating property sets + */ + +#define DEFAULT_AGGREGATE_PROPERTY_ID 10000 + +class COMPHELPER_DLLPUBLIC OPropertyArrayAggregationHelper final : public ::cppu::IPropertyArrayHelper +{ + friend class OPropertySetAggregationHelper; + + std::vector<css::beans::Property> m_aProperties; + std::map< sal_Int32, internal::OPropertyAccessor > m_aPropertyAccessors; + +public: + /** construct the object. + @param _rProperties the properties of the object doing the aggregation. These properties + are used without any checks, so the caller has to ensure that the names and + handles are valid. + @param _rAggProperties the properties of the aggregate, usually got via a call to getProperties on the + XPropertySetInfo of the aggregate. + The names of the properties are used without any checks, so the caller has to ensure + that there are no doubles. + The handles are stored for later quick access, but the outside-handles the + aggregate properties get depend from the following two parameters. + @param _pInfoService + If not NULL, the object pointed to is used to calc handles which should be used + for referring the aggregate's properties from outside. + If one of the properties returned from the info service conflict with other handles + already present (e.g. through _rProperties), the property is handled as if -1 was returned. + If NULL (or, for a special property, a call to getPreferredPropertyId returns -1), + the aggregate property(ies) get a new handle which they can be referred by from outside. + @param _nFirstAggregateId + if the object is about to create new handles for the aggregate properties, it uses + id's ascending from this given id. + No checks are made if the handle range determined by _nFirstAggregateId conflicts with other + handles within _rProperties. + */ + OPropertyArrayAggregationHelper(const css::uno::Sequence< css::beans::Property>& _rProperties, + const css::uno::Sequence< css::beans::Property>& _rAggProperties, + IPropertyInfoService* _pInfoService = nullptr, + sal_Int32 _nFirstAggregateId = DEFAULT_AGGREGATE_PROPERTY_ID); + + + /// inherited from IPropertyArrayHelper + virtual sal_Bool SAL_CALL fillPropertyMembersByHandle( OUString* _pPropName, sal_Int16* _pAttributes, + sal_Int32 _nHandle) override ; + + /// inherited from IPropertyArrayHelper + virtual css::uno::Sequence< css::beans::Property> SAL_CALL getProperties() override; + /// inherited from IPropertyArrayHelper + virtual css::beans::Property SAL_CALL getPropertyByName(const OUString& _rPropertyName) override; + + /// inherited from IPropertyArrayHelper + virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& _rPropertyName) override ; + /// inherited from IPropertyArrayHelper + virtual sal_Int32 SAL_CALL getHandleByName(const OUString & _rPropertyName) override; + /// inherited from IPropertyArrayHelper + virtual sal_Int32 SAL_CALL fillHandles( /*out*/sal_Int32* _pHandles, const css::uno::Sequence< OUString >& _rPropNames ) override; + + /** returns information about a property of the aggregate. + @param _pPropName points to a string to receive the property name. No name is returned if this is NULL. + @param _pOriginalHandle points to a sal_Int32 to receive the original property handle. No original handle is returned + if this is NULL. + @param _nHandle the handle of the property as got by, for instance, fillHandles + + @return sal_True, if _nHandle marks an aggregate property, otherwise sal_False + */ + bool fillAggregatePropertyInfoByHandle(OUString* _pPropName, sal_Int32* _pOriginalHandle, + sal_Int32 _nHandle) const; + + /** returns information about a property given by handle + */ + bool getPropertyByHandle( sal_Int32 _nHandle, css::beans::Property& _rProperty ) const; + + + enum class PropertyOrigin + { + Aggregate, + Delegator, + Unknown + }; + /** prefer this one over the XPropertySetInfo of the aggregate! + + <p>The reason is that OPropertyArrayAggregationHelper is the only instance which really knows + which properties of the aggregate are to be exposed. <br/> + + For instance, some derivee of OPropertySetAggregationHelper may decide to create an + OPropertyArrayAggregationHelper which contains only a subset of the aggregate properties. This way, + some of the aggregate properties may be hidden to the public.<br/> + + When using the XPropertySetInfo of the aggregate set to determine the existence of a property, then this + would return false positives.</p> + */ + PropertyOrigin classifyProperty( const OUString& _rName ); + +private: + const css::beans::Property* findPropertyByName(const OUString& _rName) const; +}; + + +namespace internal +{ + class PropertyForwarder; +} + +/** + * helper class for implementing the property-set-related interfaces + * for an object doin' aggregation + * supports at least XPropertySet and XMultiPropertySet + * + */ +class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OPropertySetAggregationHelper :public OPropertyStateHelper + ,public css::beans::XPropertiesChangeListener + ,public css::beans::XVetoableChangeListener +{ + friend class internal::PropertyForwarder; + +protected: + css::uno::Reference< css::beans::XPropertyState> m_xAggregateState; + css::uno::Reference< css::beans::XPropertySet> m_xAggregateSet; + css::uno::Reference< css::beans::XMultiPropertySet> m_xAggregateMultiSet; + css::uno::Reference< css::beans::XFastPropertySet> m_xAggregateFastSet; + + std::unique_ptr<internal::PropertyForwarder> m_pForwarder; + bool m_bListening : 1; + +public: + OPropertySetAggregationHelper( ::cppu::OBroadcastHelper& rBHelper ); + + virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type& aType) override; + +// XEventListener + virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override; + +// XFastPropertySet + virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const css::uno::Any& aValue) override; + virtual css::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) override; + +// XPropertySet + virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener) override; + virtual void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener) override; + +// XPropertiesChangeListener + virtual void SAL_CALL propertiesChange(const css::uno::Sequence< css::beans::PropertyChangeEvent >& evt) override; + +// XVetoableChangeListener + virtual void SAL_CALL vetoableChange(const css::beans::PropertyChangeEvent& aEvent) override; + +// XMultiPropertySet + virtual void SAL_CALL setPropertyValues(const css::uno::Sequence< OUString >& PropertyNames, const css::uno::Sequence< css::uno::Any >& Values) override; + virtual void SAL_CALL addPropertiesChangeListener(const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener) override; + +// XPropertyState + virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString& PropertyName) override; + virtual void SAL_CALL setPropertyToDefault(const OUString& PropertyName) override; + virtual css::uno::Any SAL_CALL getPropertyDefault(const OUString& aPropertyName) override; + +// OPropertySetHelper + /** still waiting to be overwritten ... + you <B>must<B/> use an OPropertyArrayAggregationHelper here, as the implementation strongly relies on this. + */ + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override = 0; + + /** only implemented for "forwarded" properties, every other property must be handled + in the derivee, and will assert if passed herein + */ + virtual sal_Bool SAL_CALL convertFastPropertyValue( css::uno::Any& _rConvertedValue, css::uno::Any& _rOldValue, sal_Int32 _nHandle, const css::uno::Any& _rValue ) override; + + /** only implemented for "forwarded" properties, every other property must be handled + in the derivee, and will assert if passed herein + */ + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const css::uno::Any& _rValue ) override; + +protected: + virtual ~OPropertySetAggregationHelper() override; + + virtual void SAL_CALL getFastPropertyValue(css::uno::Any& rValue, sal_Int32 nHandle) const override; + void disposing(); + + sal_Int32 getOriginalHandle( sal_Int32 _nHandle ) const; + OUString getPropertyName( sal_Int32 _nHandle ) const; + + /** declares the property with the given (public) handle as one to be forwarded to the aggregate + + Sometimes, you might want to <em>overwrite</em> properties at the aggregate. That is, + though the aggregate implements this property, and still is to hold the property value, + you want to do additional handling upon setting the property, but then forward the value + to the aggregate. + + Use this method to declare such properties. + + When a "forwarded property" is set from outside, the class first calls + <member>forwardingPropertyValue</member> for any preprocessing, then forwards the property + value to the aggregate, and then calls <member>forwardedPropertyValue</member>. + + When you declare a property as "forwarded", the class takes care for some multi-threading + issues, for instance, it won't fire any property change notifications which result from + forwarding a property value, unless it's safe to do so (i.e. unless our mutex is + released). + + @see forwardingPropertyValue + @see forwardedPropertyValue + */ + void declareForwardedProperty( sal_Int32 _nHandle ); + + /** checks whether we're actually forwarding a property value to our aggregate + + @see declareForwardedProperty + @see forwardingPropertyValue + @see forwardedPropertyValue + */ + bool isCurrentlyForwardingProperty( sal_Int32 _nHandle ) const; + + /** called immediately before a property value which is overwritten in this instance + is forwarded to the aggregate + + @see declareForwardedProperty + @see forwardedPropertyValue + */ + virtual void forwardingPropertyValue( sal_Int32 _nHandle ); + + /** called immediately after a property value which is overwritten in this instance + has been forwarded to the aggregate + + @see declareForwardedProperty + @see forwardingPropertyValue + */ + virtual void forwardedPropertyValue( sal_Int32 _nHandle ); + + /// must be called before aggregation, if aggregation is used + /// + /// @throws css::lang::IllegalArgumentException + void setAggregation(const css::uno::Reference< css::uno::XInterface >&); + void startListening(); +}; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_PROPAGG_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/proparrhlp.hxx b/include/comphelper/proparrhlp.hxx new file mode 100644 index 000000000..5db95972f --- /dev/null +++ b/include/comphelper/proparrhlp.hxx @@ -0,0 +1,141 @@ +/* -*- 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_COMPHELPER_PROPARRHLP_HXX +#define INCLUDED_COMPHELPER_PROPARRHLP_HXX + +#include <comphelper/propagg.hxx> +#include <cppuhelper/propshlp.hxx> +#include <mutex> +#include <osl/diagnose.h> + +namespace comphelper +{ + +template <class TYPE> +class OPropertyArrayUsageHelper +{ +protected: + static sal_Int32 s_nRefCount; + static ::cppu::IPropertyArrayHelper* s_pProps; + static std::mutex& theMutex() + { + static std::mutex SINGLETON; + return SINGLETON; + } +public: + OPropertyArrayUsageHelper(); + virtual ~OPropertyArrayUsageHelper(); + + /** call this in the getInfoHelper method of your derived class. The method returns the array helper of the + class, which is created if necessary. + */ + ::cppu::IPropertyArrayHelper* getArrayHelper(); + +protected: + /** used to implement the creation of the array helper which is shared amongst all instances of the class. + This method needs to be implemented in derived classes. + <BR> + The method gets called with Mutex acquired. + @return a pointer to the newly created array helper. Must not be NULL. + */ + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const = 0; +}; + +/** an OPropertyArrayUsageHelper which will create an OPropertyArrayAggregationHelper +*/ +template <class TYPE> +class OAggregationArrayUsageHelper: public OPropertyArrayUsageHelper<TYPE> +{ +protected: + /** overwrite this in your derived class. initialize the two sequences with your and your aggregate's + properties. + <BR> + The method gets called with Mutex acquired. + @param _rProps out parameter to be filled with the property descriptions of your own class + @param _rAggregateProps out parameter to be filled with the properties of your aggregate. + */ + virtual void fillProperties( + css::uno::Sequence< css::beans::Property >& /* [out] */ _rProps, + css::uno::Sequence< css::beans::Property >& /* [out] */ _rAggregateProps + ) const = 0; + + /** creates an OPropertyArrayAggregationHelper filled with properties for which's initialization + fillProperties is called. getInfoService and getFirstAggregateId may be overwritten to determine + the additional parameters of the OPropertyArrayAggregationHelper. + */ + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const; +}; + +template<class TYPE> +sal_Int32 OPropertyArrayUsageHelper< TYPE >::s_nRefCount = 0; + +template<class TYPE> +::cppu::IPropertyArrayHelper* OPropertyArrayUsageHelper< TYPE >::s_pProps = nullptr; + +template <class TYPE> +OPropertyArrayUsageHelper<TYPE>::OPropertyArrayUsageHelper() +{ + std::unique_lock aGuard(theMutex()); + ++s_nRefCount; +} + +template <class TYPE> +OPropertyArrayUsageHelper<TYPE>::~OPropertyArrayUsageHelper() +{ + std::unique_lock aGuard(theMutex()); + OSL_ENSURE(s_nRefCount > 0, "OPropertyArrayUsageHelper::~OPropertyArrayUsageHelper : suspicious call : have a refcount of 0 !"); + if (!--s_nRefCount) + { + delete s_pProps; + s_pProps = nullptr; + } +} + +template <class TYPE> +::cppu::IPropertyArrayHelper* OPropertyArrayUsageHelper<TYPE>::getArrayHelper() +{ + OSL_ENSURE(s_nRefCount, "OPropertyArrayUsageHelper::getArrayHelper : suspicious call : have a refcount of 0 !"); + if (!s_pProps) + { + std::unique_lock aGuard(theMutex()); + if (!s_pProps) + { + s_pProps = createArrayHelper(); + OSL_ENSURE(s_pProps, "OPropertyArrayUsageHelper::getArrayHelper : createArrayHelper returned nonsense !"); + } + } + return s_pProps; +} + +template <class TYPE> inline +::cppu::IPropertyArrayHelper* OAggregationArrayUsageHelper<TYPE>::createArrayHelper() const +{ + css::uno::Sequence< css::beans::Property > aProps; + css::uno::Sequence< css::beans::Property > aAggregateProps; + fillProperties(aProps, aAggregateProps); + OSL_ENSURE(aProps.hasElements(), "OAggregationArrayUsageHelper::createArrayHelper : fillProperties returned nonsense !"); + return new OPropertyArrayAggregationHelper(aProps, aAggregateProps, nullptr, DEFAULT_AGGREGATE_PROPERTY_ID); +} + +} + +#endif // INCLUDED_COMPHELPER_PROPARRHLP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/property.hxx b/include/comphelper/property.hxx new file mode 100644 index 000000000..b9787f130 --- /dev/null +++ b/include/comphelper/property.hxx @@ -0,0 +1,131 @@ +/* -*- 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_COMPHELPER_PROPERTY_HXX +#define INCLUDED_COMPHELPER_PROPERTY_HXX + +#include <cppuhelper/proptypehlp.hxx> +#include <comphelper/extract.hxx> +#include <com/sun/star/beans/Property.hpp> +#include <type_traits> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::beans { class XPropertySet; } + +namespace comphelper +{ + + // comparing two property instances + struct PropertyCompareByName + { + bool operator() (const css::beans::Property& x, const css::beans::Property& y) const + { + return x.Name.compareTo(y.Name) < 0; + } + }; + +/// remove the property with the given name from the given sequence +COMPHELPER_DLLPUBLIC void RemoveProperty(css::uno::Sequence<css::beans::Property>& seqProps, const OUString& _rPropName); + +/** within the given property sequence, modify attributes of a special property + @param _rProps the sequence of properties to search in + @param _sPropName the name of the property which's attributes should be modified + @param _nAddAttrib the attributes which should be added + @param _nRemoveAttrib the attributes which should be removed +*/ +COMPHELPER_DLLPUBLIC void ModifyPropertyAttributes(css::uno::Sequence<css::beans::Property>& _rProps, const OUString& _sPropName, sal_Int16 _nAddAttrib, sal_Int16 _nRemoveAttrib); + +/** check if the given set has the given property. +*/ +COMPHELPER_DLLPUBLIC bool hasProperty(const OUString& _rName, const css::uno::Reference<css::beans::XPropertySet>& _rxSet); + +/** copy properties between property sets, in compliance with the property + attributes of the target object +*/ +COMPHELPER_DLLPUBLIC void copyProperties(const css::uno::Reference<css::beans::XPropertySet>& _rxSource, + const css::uno::Reference<css::beans::XPropertySet>& _rxDest); + +/** helper for implementing ::cppu::OPropertySetHelper::convertFastPropertyValue + @param _rConvertedValue the conversion result (if successful) + @param _rOldValue the old value of the property, calculated from _rCurrentValue + @param _rValueToSet the new value which is about to be set + @param _rCurrentValue the current value of the property + @return sal_True, if the value could be converted and has changed + sal_False, if the value could be converted and has not changed + @exception InvalidArgumentException thrown if the value could not be converted to the requested type (which is the template argument) +*/ +template <typename T> +bool tryPropertyValue(css::uno::Any& /*out*/_rConvertedValue, css::uno::Any& /*out*/_rOldValue, const css::uno::Any& _rValueToSet, const T& _rCurrentValue) +{ + bool bModified(false); + T aNewValue = T(); + ::cppu::convertPropertyValue(aNewValue, _rValueToSet); + if (aNewValue != _rCurrentValue) + { + _rConvertedValue <<= aNewValue; + _rOldValue <<= _rCurrentValue; + bModified = true; + } + return bModified; +} + +/** helper for implementing ::cppu::OPropertySetHelper::convertFastPropertyValue for enum values + @param _rConvertedValue the conversion result (if successful) + @param _rOldValue the old value of the property, calculated from _rCurrentValue + @param _rValueToSet the new value which is about to be set + @param _rCurrentValue the current value of the property + @return sal_True, if the value could be converted and has changed + sal_False, if the value could be converted and has not changed + @exception InvalidArgumentException thrown if the value could not be converted to the requested type (which is the template argument) +*/ +template <class ENUMTYPE> +typename std::enable_if<std::is_enum<ENUMTYPE>::value, bool>::type +tryPropertyValueEnum(css::uno::Any& /*out*/_rConvertedValue, css::uno::Any& /*out*/_rOldValue, const css::uno::Any& _rValueToSet, const ENUMTYPE& _rCurrentValue) +{ + bool bModified(false); + ENUMTYPE aNewValue; + ::cppu::any2enum(aNewValue, _rValueToSet); + // will throw an exception if not convertible + + if (aNewValue != _rCurrentValue) + { + _rConvertedValue <<= aNewValue; + _rOldValue <<= _rCurrentValue; + bModified = true; + } + return bModified; +} + +/** helper for implementing ::cppu::OPropertySetHelper::convertFastPropertyValue + @param _rConvertedValue the conversion result (if successful) + @param _rOldValue the old value of the property, calculated from _rCurrentValue + @param _rValueToSet the new value which is about to be set + @param _rCurrentValue the current value of the property + @param _rExpectedType the type which the property should have (if not void) + @return sal_True, if the value could be converted and has changed + sal_False, if the value could be converted and has not changed + @exception InvalidArgumentException thrown if the value could not be converted to the requested type (which is the template argument) +*/ +COMPHELPER_DLLPUBLIC bool tryPropertyValue(css::uno::Any& _rConvertedValue, css::uno::Any& _rOldValue, const css::uno::Any& _rValueToSet, const css::uno::Any& _rCurrentValue, const css::uno::Type& _rExpectedType); + +} + +#endif // INCLUDED_COMPHELPER_PROPERTY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propertybag.hxx b/include/comphelper/propertybag.hxx new file mode 100644 index 000000000..3cf9de9ff --- /dev/null +++ b/include/comphelper/propertybag.hxx @@ -0,0 +1,226 @@ +/* -*- 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_COMPHELPER_PROPERTYBAG_HXX +#define INCLUDED_COMPHELPER_PROPERTYBAG_HXX + +#include <config_options.h> +#include <com/sun/star/uno/Any.h> +#include <comphelper/comphelperdllapi.h> +#include <comphelper/propertycontainerhelper.hxx> + +#include <map> + + +namespace comphelper +{ + + + //= PropertyBag + + /** provides a bag of properties associated with their values + + This class can, for instance, be used for components which need to implement + the com.sun.star.beans.PropertyBag service. + */ + class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) PropertyBag final : protected OPropertyContainerHelper + { + std::map< sal_Int32, css::uno::Any > aDefaults; + bool m_bAllowEmptyPropertyName; + public: + PropertyBag(); + virtual ~PropertyBag(); + + /** allow adding property with empty string as name + (by default, such names are rejected with IllegalActionException). + @param i_isAllowed + iff true, empty property name will be allowed + */ + void setAllowEmptyPropertyName(bool i_isAllowed); + + /** adds a property to the bag + + The type of the property is determined from its initial value (<code>_rInitialValue</code>). + + @param _rName + the name of the new property. Must not be empty unless + explicitly allowed with setAllowEmptyPropertyName. + @param _nHandle + the handle of the new property + @param _nAttributes + the attributes of the property + @param _rInitialValue + the initial value of the property. Must not be <NULL/>, to allow + determining the property type. + + @throws css::beans::IllegalTypeException + if the initial value is <NULL/> + @throws css::beans::PropertyExistException + if the name or the handle are already used + @throws css::beans::IllegalArgumentException + if the name is empty + */ + void addProperty( + const OUString& _rName, + sal_Int32 _nHandle, + sal_Int32 _nAttributes, + const css::uno::Any& _rInitialValue + ); + + /** adds a property to the bag + + The initial value of the property is <NULL/>. + + @param _rName + the name of the new property. Must not be empty unless + explicitly allowed with setAllowEmptyPropertyName. + @param _rType + the type of the new property + @param _nHandle + the handle of the new property + @param _nAttributes + the attributes of the property + + @throws css::beans::IllegalTypeException + if the initial value is <NULL/> + @throws css::beans::PropertyExistException + if the name or the handle are already used + @throws css::beans::IllegalArgumentException + if the name is empty + */ + void addVoidProperty( + const OUString& _rName, + const css::uno::Type& _rType, + sal_Int32 _nHandle, + sal_Int32 _nAttributes + ); + + /** removes a property from the bag + @param _rName + the name of the to-be-removed property. + @throws UnknownPropertyException + if the bag does not contain a property with the given name + @throws NotRemoveableException + if the property with the given name is not removable, as indicated + by the property attributes used in a previous <code>addProperty</code> + call. + */ + void removeProperty( + const OUString& _rName + ); + + /** describes all properties in the bag + @param _out_rProps + takes, upon return, the descriptions of all properties in the bag + */ + void describeProperties( + css::uno::Sequence< css::beans::Property >& _out_rProps + ) const + { + OPropertyContainerHelper::describeProperties( _out_rProps ); + } + + /** retrieves the value of a property given by handle + @param _nHandle + the handle of the property whose value is to be retrieved + @param _out_rValue + output parameter taking the property value + @throws UnknownPropertyException + if the given handle does not denote a property in the bag + */ + void getFastPropertyValue( + sal_Int32 _nHandle, + css::uno::Any& _out_rValue + ) const; + + /** converts a to-be-set value of a property (given by handle) so that it can + be used in subsequent calls to setFastPropertyValue + @param _nHandle + the handle of the property + @param _rNewValue + the new value, which should be converted + @param _out_rConvertedValue + output parameter taking the converted value + @param _out_rCurrentValue + output parameter taking the current value of the + property + @throws UnknownPropertyException + if the given handle does not denote a property in the bag + @throws IllegalArgumentException + if the given value cannot be lossless converted into a value + for the given property. + */ + bool convertFastPropertyValue( + sal_Int32 _nHandle, + const css::uno::Any& _rNewValue, + css::uno::Any& _out_rConvertedValue, + css::uno::Any& _out_rCurrentValue + ) const; + + /** sets a new value for a property given by handle + @throws UnknownPropertyException + if the given handle does not denote a property in the bag + */ + void setFastPropertyValue( + sal_Int32 _nHandle, + const css::uno::Any& _rValue + ); + + /** returns the default value for a property given by handle + + The default value of a property is its initial value, as passed + to ->addProperty. + + @param _nHandle + handle of the property whose default value is to be obtained + @param _out_rValue + the default value + @throws UnknownPropertyException + if the given handle does not denote a property in the bag + */ + void getPropertyDefaultByHandle( + sal_Int32 _nHandle, + css::uno::Any& _out_rValue + ) const; + + /** determines whether a property with a given name is part of the bag + */ + bool hasPropertyByName( const OUString& _rName ) const + { + return isRegisteredProperty( _rName ); + } + + /** determines whether a property with a given handle is part of the bag + */ + bool hasPropertyByHandle( sal_Int32 _nHandle ) const + { + return isRegisteredProperty( _nHandle ); + } + protected: + using OPropertyContainerHelper::convertFastPropertyValue; + using OPropertyContainerHelper::getFastPropertyValue; + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_PROPERTYBAG_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propertycontainer.hxx b/include/comphelper/propertycontainer.hxx new file mode 100644 index 000000000..2c64b2cdf --- /dev/null +++ b/include/comphelper/propertycontainer.hxx @@ -0,0 +1,87 @@ +/* -*- 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_COMPHELPER_PROPERTYCONTAINER_HXX +#define INCLUDED_COMPHELPER_PROPERTYCONTAINER_HXX + +#include <comphelper/propertycontainerhelper.hxx> +#include <cppuhelper/propshlp.hxx> +#include <comphelper/comphelperdllapi.h> + + +namespace com::sun::star::uno { class Any; } +namespace com::sun::star::uno { class Type; } + +namespace comphelper +{ + + +/** an OPropertySetHelper implementation which is just a simple container for properties represented + by class members, usually in a derived class. + <BR> + A restriction of this class is that no value conversions are made on a setPropertyValue call. Though + the base class supports this with the convertFastPropertyValue method, the OPropertyContainer accepts only + values which already have the correct type, it's unable to convert, for instance, a long to a short. +*/ +class COMPHELPER_DLLPUBLIC OPropertyContainer + :public cppu::OPropertySetHelper + ,public OPropertyContainerHelper +{ +public: + // this dtor is needed otherwise we can get a wrong delete operator + virtual ~OPropertyContainer(); + +protected: + OPropertyContainer(::cppu::OBroadcastHelper& _rBHelper); + + /// for scripting : the types of the interfaces supported by this class + /// + /// @throws css::uno::RuntimeException + static css::uno::Sequence< css::uno::Type > getBaseTypes(); + +// OPropertySetHelper overridables + virtual sal_Bool SAL_CALL convertFastPropertyValue( + css::uno::Any & rConvertedValue, + css::uno::Any & rOldValue, + sal_Int32 nHandle, + const css::uno::Any& rValue ) override; + + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, + const css::uno::Any& rValue + ) override; + + using OPropertySetHelper::getFastPropertyValue; + virtual void SAL_CALL getFastPropertyValue( + css::uno::Any& rValue, + sal_Int32 nHandle + ) const override; + + // disambiguate a base class method (XFastPropertySet) + using OPropertySetHelper::setFastPropertyValue; +}; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_PROPERTYCONTAINER_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propertycontainerhelper.hxx b/include/comphelper/propertycontainerhelper.hxx new file mode 100644 index 000000000..73a0ce513 --- /dev/null +++ b/include/comphelper/propertycontainerhelper.hxx @@ -0,0 +1,197 @@ +/* -*- 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_COMPHELPER_PROPERTYCONTAINERHELPER_HXX +#define INCLUDED_COMPHELPER_PROPERTYCONTAINERHELPER_HXX + +#include <com/sun/star/uno/Type.hxx> +#include <com/sun/star/beans/Property.hpp> +#include <cstddef> +#include <limits> +#include <vector> +#include <comphelper/comphelperdllapi.h> + + +namespace comphelper +{ + + +// infos about one single property +struct COMPHELPER_DLLPUBLIC PropertyDescription +{ + // the possibilities where a property holding object may be located + enum class LocationType + { + DerivedClassRealType, // within the derived class, it's a "real" (non-Any) type + DerivedClassAnyType, // within the derived class, it's a com.sun.star.uno::Any + HoldMyself // within m_aHoldProperties + }; + // the location of an object holding a property value : + union LocationAccess + { + void* pDerivedClassMember; // a pointer to a member of an object of a derived class + std::size_t nOwnClassVectorIndex; // an index within m_aHoldProperties + }; + + css::beans::Property aProperty; + LocationType eLocated; // where is the object containing the value located ? + LocationAccess aLocation; // access to the property value + + PropertyDescription() + :aProperty( OUString(), -1, css::uno::Type(), 0 ) + ,eLocated( LocationType::HoldMyself ) + { + aLocation.nOwnClassVectorIndex = std::numeric_limits<std::size_t>::max(); + } +}; + + +//= OPropertyContainerHelper + +/** helper class for managing property values, and implementing most of the X*Property* interfaces + + The property values are usually held in derived classes, but can also be given to the + responsibility of this class here. + + For more information, see http://wiki.openoffice.org/wiki/Development/Cpp/Helper/PropertyContainerHelper. +*/ +class COMPHELPER_DLLPUBLIC OPropertyContainerHelper +{ + typedef ::std::vector< css::uno::Any > PropertyContainer; + PropertyContainer m_aHoldProperties; + // the properties which are hold by this class' instance, not the derived one's + +private: + typedef ::std::vector< PropertyDescription > Properties; + typedef Properties::iterator PropertiesIterator; + typedef Properties::const_iterator ConstPropertiesIterator; + Properties m_aProperties; + +protected: + OPropertyContainerHelper(); + ~OPropertyContainerHelper(); + + /** register a property. The property is represented through a member of the derived class which calls + this method. + @param _rName the name of the property + @param _nHandle the handle of the property + @param _nAttributes the attributes of the property + @param _pPointerToMember the pointer to the member representing the property + within the derived class. + @param _rMemberType the cppu type of the property represented by the object + to which _pPointerToMember points. + */ + void registerProperty(const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, + void* _pPointerToMember, const css::uno::Type& _rMemberType); + + + /** register a property. The property is represented through a css::uno::Any member of the + derived class which calls this method. + @param _rName the name of the property + @param _nHandle the handle of the property + @param _nAttributes the attributes of the property + @param _pPointerToMember the pointer to the member representing the property + within the derived class, which has to be a css::uno::Any. + @param _rExpectedType the expected type of the property. NOT the type of the object to which + _pPointerToMember points (this is always an Any). + */ + void registerMayBeVoidProperty(const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, + css::uno::Any* _pPointerToMember, const css::uno::Type& _rExpectedType); + + /** register a property. The repository will create an own object holding this property, so there is no + need to declare an extra member in your derived class + @param _rName the name of the property + @param _nHandle the handle of the property + @param _nAttributes the attributes of the property + @param _rType the type of the property + @param _pInitialValue the initial value of the property. May be void if _nAttributes includes + the css::beans::PropertyAttribute::MAYBEVOID flag. + Else it must contain a value compatible with the type described by _rType. + */ + void registerPropertyNoMember(const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, + const css::uno::Type& _rType, css::uno::Any const & _pInitialValue); + + /** revokes a previously registered property + @throw css::beans::UnknownPropertyException + if no property with the given handle is registered + */ + void revokeProperty( sal_Int32 _nHandle ); + + + /// checks whether a property with the given handle has been registered + bool isRegisteredProperty( sal_Int32 _nHandle ) const; + + /// checks whether a property with the given name has been registered + bool isRegisteredProperty( const OUString& _rName ) const; + + + // helper for implementing OPropertySetHelper overridables + bool convertFastPropertyValue( + css::uno::Any & rConvertedValue, + css::uno::Any & rOldValue, + sal_Int32 nHandle, + const css::uno::Any& rValue + ); + + void setFastPropertyValue( + sal_Int32 nHandle, + const css::uno::Any& rValue + ); + + void getFastPropertyValue( + css::uno::Any& rValue, + sal_Int32 nHandle + ) const; + +// helper + /** appends the descriptions of all properties which were registered 'til that moment to the given sequence, + keeping the array sorted (by name) + @precond + the given sequence is already sorted by name + @param _rProps + initial property sequence which is to be extended + */ + void describeProperties(css::uno::Sequence< css::beans::Property >& /* [out] */ _rProps) const; + + /** retrieves the description for a registered property + @throw css::beans::UnknownPropertyException + if no property with the given name is registered + */ + const css::beans::Property& + getProperty( const OUString& _rName ) const; + +private: + /// insertion of _rProp into m_aProperties, keeping the sort order + COMPHELPER_DLLPRIVATE void implPushBackProperty(const PropertyDescription& _rProp); + + /// search the PropertyDescription for the given handle (within m_aProperties) + COMPHELPER_DLLPRIVATE PropertiesIterator searchHandle(sal_Int32 _nHandle); + +private: + OPropertyContainerHelper( const OPropertyContainerHelper& ) = delete; + OPropertyContainerHelper& operator=( const OPropertyContainerHelper& ) = delete; +}; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_PROPERTYCONTAINERHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propertysequence.hxx b/include/comphelper/propertysequence.hxx new file mode 100644 index 000000000..e788f56f4 --- /dev/null +++ b/include/comphelper/propertysequence.hxx @@ -0,0 +1,62 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_PROPERTYSEQUENCE_HXX +#define INCLUDED_COMPHELPER_PROPERTYSEQUENCE_HXX + +#include <utility> +#include <algorithm> +#include <initializer_list> +#include <vector> + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <comphelper/comphelperdllapi.h> + +namespace comphelper +{ + /// Init list for property sequences. + inline css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence( + ::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit) + { + css::uno::Sequence< css::beans::PropertyValue> vResult{static_cast<sal_Int32>(vInit.size())}; + std::transform(vInit.begin(), vInit.end(), vResult.getArray(), + [](const std::pair<OUString, css::uno::Any>& rInit) { + return css::beans::PropertyValue(rInit.first, -1, rInit.second, + css::beans::PropertyState_DIRECT_VALUE); + }); + return vResult; + } + + /// Init list for property sequences that wrap the PropertyValues in Anys. + /// + /// This is particularly useful for creation of sequences that are later + /// unwrapped using comphelper::SequenceAsHashMap. + inline css::uno::Sequence< css::uno::Any > InitAnyPropertySequence( + ::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit) + { + css::uno::Sequence<css::uno::Any> vResult{static_cast<sal_Int32>(vInit.size())}; + std::transform(vInit.begin(), vInit.end(), vResult.getArray(), + [](const std::pair<OUString, css::uno::Any>& rInit) { + return css::uno::Any( + css::beans::PropertyValue(rInit.first, -1, rInit.second, + css::beans::PropertyState_DIRECT_VALUE)); + }); + return vResult; + } + + COMPHELPER_DLLPUBLIC std::vector<css::beans::PropertyValue> JsonToPropertyValues(const OString& rJson); +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_PROPERTYSEQUENCE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propertysethelper.hxx b/include/comphelper/propertysethelper.hxx new file mode 100644 index 000000000..a4746a02f --- /dev/null +++ b/include/comphelper/propertysethelper.hxx @@ -0,0 +1,96 @@ +/* -*- 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_COMPHELPER_PROPERTYSETHELPER_HXX +#define INCLUDED_COMPHELPER_PROPERTYSETHELPER_HXX + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <comphelper/comphelperdllapi.h> +#include <rtl/ref.hxx> + +namespace comphelper +{ +class PropertySetInfo; +struct PropertyMapEntry; + +class COMPHELPER_DLLPUBLIC PropertySetHelper : public css::beans::XPropertySet, + public css::beans::XPropertyState, + public css::beans::XMultiPropertySet +{ +private: + rtl::Reference<PropertySetInfo> mxInfo; + +protected: + /// @throws css::beans::UnknownPropertyException + /// @throws css::beans::PropertyVetoException + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const css::uno::Any* pValues ) = 0; + /// @throws css::beans::UnknownPropertyException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, css::uno::Any* pValue ) = 0; + + /// @throws css::beans::UnknownPropertyException + /// @throws css::uno::RuntimeException + virtual void _getPropertyStates( const comphelper::PropertyMapEntry** ppEntries, css::beans::PropertyState* pStates ); + /// @throws css::beans::UnknownPropertyException + /// @throws css::uno::RuntimeException + virtual void _setPropertyToDefault( const comphelper::PropertyMapEntry* pEntry ); + /// @throws css::beans::UnknownPropertyException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + virtual css::uno::Any _getPropertyDefault( const comphelper::PropertyMapEntry* pEntry ); + +public: + PropertySetHelper( rtl::Reference<comphelper::PropertySetInfo> xInfo ) noexcept; + virtual ~PropertySetHelper() noexcept; + + // XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XMultiPropertySet +// virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(css::uno::RuntimeException); + virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override; + virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override; + virtual void SAL_CALL addPropertiesChangeListener( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + virtual void SAL_CALL firePropertiesChangeEvent( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + + // XPropertyState + virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override; + virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates( const css::uno::Sequence< OUString >& aPropertyName ) override; + virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override; + virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override; +}; + +} + +#endif // _UTL_PROPERTYSETHELPER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propertysetinfo.hxx b/include/comphelper/propertysetinfo.hxx new file mode 100644 index 000000000..ee26d8698 --- /dev/null +++ b/include/comphelper/propertysetinfo.hxx @@ -0,0 +1,123 @@ +/* -*- 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_COMPHELPER_PROPERTYSETINFO_HXX +#define INCLUDED_COMPHELPER_PROPERTYSETINFO_HXX + +#include <sal/config.h> + +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> +#include <o3tl/span.hxx> +#include <o3tl/typed_flags_set.hxx> +#include <unordered_map> +#include <utility> + +enum class PropertyMoreFlags : sal_uInt8 { + NONE = 0x00, + METRIC_ITEM = 0x01, +}; +namespace o3tl { + template<> struct typed_flags<PropertyMoreFlags> : is_typed_flags<PropertyMoreFlags, 0x1> {}; +} + +namespace comphelper +{ + +struct PropertyMapEntry +{ + OUString maName; + css::uno::Type maType; + sal_Int32 mnHandle; + /// flag bitmap, @see css::beans::PropertyAttribute + sal_Int16 mnAttributes; + sal_uInt8 mnMemberId; + PropertyMoreFlags mnMoreFlags; + + PropertyMapEntry(OUString _aName, sal_Int32 _nHandle, css::uno::Type const & _rType, + sal_Int16 _nAttributes, sal_uInt8 _nMemberId, PropertyMoreFlags _nMoreFlags = PropertyMoreFlags::NONE) + : maName(std::move( _aName )) + , maType( _rType ) + , mnHandle( _nHandle ) + , mnAttributes( _nAttributes ) + , mnMemberId( _nMemberId ) + , mnMoreFlags( _nMoreFlags ) + { + assert(mnAttributes <= 0x1ff ); + assert( (_nMemberId & 0x40) == 0 ); + // Verify that if METRIC_ITEM is set, we are one of the types supported by + // SvxUnoConvertToMM. + assert(!(_nMoreFlags & PropertyMoreFlags::METRIC_ITEM) || + ( (maType.getTypeClass() == css::uno::TypeClass_BYTE) + || (maType.getTypeClass() == css::uno::TypeClass_SHORT) + || (maType.getTypeClass() == css::uno::TypeClass_UNSIGNED_SHORT) + || (maType.getTypeClass() == css::uno::TypeClass_LONG) + || (maType.getTypeClass() == css::uno::TypeClass_UNSIGNED_LONG) + ) ); + } + PropertyMapEntry() = default; +}; + +typedef std::unordered_map<OUString, PropertyMapEntry const *> PropertyMap; + +// don't export to avoid duplicate WeakImplHelper definitions with MSVC +class SAL_DLLPUBLIC_TEMPLATE PropertySetInfo_BASE + : public ::cppu::WeakImplHelper< css::beans::XPropertySetInfo > +{}; + +/** this class implements a XPropertySetInfo that is initialized with arrays of PropertyMapEntry. + It is used by the class PropertySetHelper. +*/ +class COMPHELPER_DLLPUBLIC PropertySetInfo final + : public PropertySetInfo_BASE +{ +public: + PropertySetInfo() noexcept; + PropertySetInfo( o3tl::span<const PropertyMapEntry> pMap ) noexcept; + virtual ~PropertySetInfo() noexcept override; + + /** returns a stl map with all PropertyMapEntry pointer.<p> + The key is the property name. + */ + const PropertyMap& getPropertyMap() const noexcept { return maPropertyMap; } + + /** adds an array of PropertyMapEntry to this instance.<p> + The end is marked with a PropertyMapEntry where mpName equals NULL</p> + */ + void add( o3tl::span<PropertyMapEntry const> pMap ) noexcept; + + /** removes an already added PropertyMapEntry which string in mpName equals to aName */ + void remove( const OUString& aName ) noexcept; + + virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties() override; + virtual css::beans::Property SAL_CALL getPropertyByName( const OUString& aName ) override; + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override; + +private: + PropertyMap maPropertyMap; + /// Cache the value we return in getProperties because it is expensive to construct + css::uno::Sequence< css::beans::Property > maProperties; +}; + +} + +#endif // _UTL_PROPERTSETINFO_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propertystatecontainer.hxx b/include/comphelper/propertystatecontainer.hxx new file mode 100644 index 000000000..966e2cb99 --- /dev/null +++ b/include/comphelper/propertystatecontainer.hxx @@ -0,0 +1,110 @@ +/* -*- 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_COMPHELPER_PROPERTYSTATECONTAINER_HXX +#define INCLUDED_COMPHELPER_PROPERTYSTATECONTAINER_HXX + +#include <comphelper/propertycontainer.hxx> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/uno3.hxx> +#include <comphelper/comphelperdllapi.h> + + +namespace comphelper +{ + + + //= OPropertyStateContainer + + typedef ::cppu::ImplHelper1 < css::beans::XPropertyState + > OPropertyStateContainer_TBase; + + /** helper implementation for components which have properties with a default + + <p>This class is not intended for direct use, you need to derive from it.</p> + + @see com.sun.star.beans.XPropertyState + */ + class COMPHELPER_DLLPUBLIC OPropertyStateContainer + :public OPropertyContainer + ,public OPropertyStateContainer_TBase + { + protected: + /** ctor + @param _rBHelper + help to be used for broadcasting events + */ + OPropertyStateContainer( ::cppu::OBroadcastHelper& _rBHelper ); + + + // XPropertyState + virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override; + virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates( const css::uno::Sequence< OUString >& aPropertyName ) override; + virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override; + virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override; + + + // own overridables + // these are the impl-methods for the XPropertyState members - they are implemented already by this class, + // but you may want to override them for whatever reasons (for instance, if your derived class + // supports the AMBIGUOUS state for properties) + + /** get the PropertyState of the property denoted by the given handle + + <p>Already implemented by this base class, no need to override</p> + @precond <arg>_nHandle</arg> is a valid property handle + */ + css::beans::PropertyState getPropertyStateByHandle( sal_Int32 _nHandle ) const; + + /** set the property denoted by the given handle to its default value + + <p>Already implemented by this base class, no need to override</p> + @precond <arg>_nHandle</arg> is a valid property handle + */ + void setPropertyToDefaultByHandle( sal_Int32 _nHandle ); + + /** get the default value for the property denoted by the given handle + + @precond + <arg>_nHandle</arg> is a valid property handle + */ + virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, css::uno::Any& _rDefault ) const = 0; + + protected: + // XInterface + virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& _rType ) override; + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + protected: + /** returns the handle for the given name + + @throw UnknownPropertyException if the given name is not a registered property + */ + sal_Int32 getHandleForName( const OUString& _rPropertyName ); + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_PROPERTYSTATECONTAINER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propertyvalue.hxx b/include/comphelper/propertyvalue.hxx new file mode 100644 index 000000000..de7179110 --- /dev/null +++ b/include/comphelper/propertyvalue.hxx @@ -0,0 +1,45 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_PROPERTYVALUE_HXX +#define INCLUDED_COMPHELPER_PROPERTYVALUE_HXX + +#include <sal/config.h> + +#include <type_traits> +#include <utility> + +#include <com/sun/star/beans/PropertyValue.hpp> + +namespace comphelper +{ +/** + * Creates a beans::PropertyValue easily, i.e. you can write: + * + * function(comphelper::makePropertyValue("Foo", nBar)); + * + * instead of writing 3 extra lines to set the name and value of the beans::PropertyValue. + */ +template <typename T, std::enable_if_t<!std::is_arithmetic_v<std::remove_reference_t<T>>, int> = 0> +css::beans::PropertyValue makePropertyValue(const OUString& rName, T&& rValue) +{ + return { rName, 0, css::uno::toAny(std::forward<T>(rValue)), + css::beans::PropertyState_DIRECT_VALUE }; +} +// Allows to pass e.g. bit fields +template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0> +css::beans::PropertyValue makePropertyValue(const OUString& rName, T aValue) +{ + return makePropertyValue(rName, css::uno::toAny(aValue)); +} +} + +#endif // INCLUDED_COMPHELPER_PROPERTYVALUE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propmultiplex.hxx b/include/comphelper/propmultiplex.hxx new file mode 100644 index 000000000..41d456d43 --- /dev/null +++ b/include/comphelper/propmultiplex.hxx @@ -0,0 +1,115 @@ +/* -*- 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_COMPHELPER_PROPMULTIPLEX_HXX +#define INCLUDED_COMPHELPER_PROPMULTIPLEX_HXX + +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> +#include <rtl/ref.hxx> +#include <vector> + +namespace com::sun::star::beans { class XPropertySet; } + +//= property helper classes + + +namespace comphelper +{ + + + class OPropertyChangeMultiplexer; + + + //= OPropertyChangeListener + + /// simple listener adapter for property sets + class COMPHELPER_DLLPUBLIC OPropertyChangeListener + { + friend class OPropertyChangeMultiplexer; + + rtl::Reference<OPropertyChangeMultiplexer> m_xAdapter; + ::osl::Mutex& m_rMutex; + + public: + OPropertyChangeListener(::osl::Mutex& _rMutex) + : m_rMutex(_rMutex) { } + virtual ~OPropertyChangeListener(); + + /// @throws css::uno::RuntimeException + virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) = 0; + /// @throws css::uno::RuntimeException + virtual void _disposing(const css::lang::EventObject& _rSource); + + protected: + /** If the derivee also owns the mutex which we know as reference, then call this within your + derivee's dtor. + */ + void disposeAdapter(); + + // pseudo-private. Making it private now could break compatibility + void setAdapter( OPropertyChangeMultiplexer* _pAdapter ); + }; + + + //= OPropertyChangeMultiplexer + + /// multiplexer for property changes + // workaround for incremental linking bugs in MSVC2019 + class SAL_DLLPUBLIC_TEMPLATE OPropertyChangeMultiplexer_Base : public cppu::WeakImplHelper< css::beans::XPropertyChangeListener > {}; + class COMPHELPER_DLLPUBLIC OPropertyChangeMultiplexer final : public OPropertyChangeMultiplexer_Base + { + friend class OPropertyChangeListener; + std::vector< OUString > m_aProperties; + css::uno::Reference< css::beans::XPropertySet> m_xSet; + OPropertyChangeListener* m_pListener; + sal_Int32 m_nLockCount; + bool m_bListening : 1; + bool const m_bAutoSetRelease : 1; + + + virtual ~OPropertyChangeMultiplexer() override; + public: + OPropertyChangeMultiplexer(OPropertyChangeListener* _pListener, const css::uno::Reference< css::beans::XPropertySet>& _rxSet, bool _bAutoReleaseSet = true); + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // XPropertyChangeListener + virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override; + + /// incremental lock + void lock(); + /// incremental unlock + void unlock(); + /// get the lock count + sal_Int32 locked() const { return m_nLockCount; } + + void addProperty(const OUString& aPropertyName); + void dispose(); + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_PROPMULTIPLEX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/propstate.hxx b/include/comphelper/propstate.hxx new file mode 100644 index 000000000..7729aaa9b --- /dev/null +++ b/include/comphelper/propstate.hxx @@ -0,0 +1,102 @@ +/* -*- 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_COMPHELPER_PROPSTATE_HXX +#define INCLUDED_COMPHELPER_PROPSTATE_HXX + +#include <config_options.h> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/uno/Sequence.h> + + +#include <cppuhelper/propshlp.hxx> +#include <cppuhelper/weak.hxx> +#include <comphelper/uno3.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <comphelper/comphelperdllapi.h> + + +//= property helper classes + + +namespace comphelper +{ + + + //= OPropertyStateHelper + + /// helper class for implementing property states + class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OPropertyStateHelper :public ::cppu::OPropertySetHelper2 + ,public css::beans::XPropertyState + { + public: + OPropertyStateHelper(::cppu::OBroadcastHelper& rBHlp):OPropertySetHelper2(rBHlp) { } + OPropertyStateHelper(::cppu::OBroadcastHelper& rBHlp, + ::cppu::IEventNotificationHook *i_pFireEvents); + + virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type& aType) override; + + // XPropertyState + virtual css::beans::PropertyState SAL_CALL + getPropertyState(const OUString& PropertyName) override; + virtual css::uno::Sequence< css::beans::PropertyState> SAL_CALL + getPropertyStates(const css::uno::Sequence< OUString >& aPropertyName) override; + virtual void SAL_CALL + setPropertyToDefault(const OUString& PropertyName) override; + virtual css::uno::Any SAL_CALL + getPropertyDefault(const OUString& aPropertyName) override; + + // access via handle + virtual css::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle); + virtual void setPropertyToDefaultByHandle(sal_Int32 nHandle); + virtual css::uno::Any getPropertyDefaultByHandle(sal_Int32 nHandle) const; + + protected: + virtual ~OPropertyStateHelper() override; + + void firePropertyChange(sal_Int32 nHandle, const css::uno::Any& aNewValue, const css::uno::Any& aOldValue); + + static css::uno::Sequence<css::uno::Type> getTypes(); + }; + + + //= OPropertyStateHelper + + class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OStatefulPropertySet :public ::cppu::OWeakObject + ,public css::lang::XTypeProvider + ,public OMutexAndBroadcastHelper // order matters: before OPropertyStateHelper/OPropertySetHelper + ,public OPropertyStateHelper + { + protected: + OStatefulPropertySet(); + virtual ~OStatefulPropertySet() override; + + protected: + DECLARE_XINTERFACE() + DECLARE_XTYPEPROVIDER() + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_PROPSTATE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/proxyaggregation.hxx b/include/comphelper/proxyaggregation.hxx new file mode 100644 index 000000000..48444355c --- /dev/null +++ b/include/comphelper/proxyaggregation.hxx @@ -0,0 +1,218 @@ +/* -*- 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_COMPHELPER_PROXYAGGREGATION_HXX +#define INCLUDED_COMPHELPER_PROXYAGGREGATION_HXX + +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/uno3.hxx> +#include <cppuhelper/compbase_ex.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::uno { + class XComponentContext; +} +namespace com::sun::star::uno { class XAggregation; } +namespace com::sun::star::lang { class XComponent; } + +/* class hierarchy herein: + + +-------------------+ helper class for aggregating the proxy to another object + | OProxyAggregation | - not ref counted + +-------------------+ - no UNO implementation, i.e. not derived from XInterface + ^ (neither direct nor indirect) + | + | + +----------------------------------+ helper class for aggregating a proxy to an XComponent + | OComponentProxyAggregationHelper | - life time coupling: if the inner component (the "aggregate") + +----------------------------------+ is disposed, the outer (the delegator) is disposed, too, and + ^ vice versa + | - UNO based, implementing XEventListener + | + +----------------------------+ component aggregating another XComponent + | OComponentProxyAggregation | - life time coupling as above + +----------------------------+ - ref-counted + - implements an XComponent itself + + If you need to + + - wrap a foreign object which is a XComponent + => use OComponentProxyAggregation + - call componentAggregateProxyFor in your ctor + - call implEnsureDisposeInDtor in your dtor + + - wrap a foreign object which is a XComponent, but already have ref-counting mechanisms + inherited from somewhere else + => use OComponentProxyAggregationHelper + - override dispose - don't forget to call the base class' dispose! + - call componentAggregateProxyFor in your ctor + + - wrap a foreign object which is no XComponent + => use OProxyAggregation + - call baseAggregateProxyFor in your ctor +*/ + + +namespace comphelper +{ + + + //= OProxyAggregation + + /** helper class for aggregating a proxy for a foreign object + */ + class OProxyAggregation + { + private: + css::uno::Reference< css::uno::XAggregation > m_xProxyAggregate; + css::uno::Reference< css::lang::XTypeProvider > m_xProxyTypeAccess; + css::uno::Reference< css::uno::XComponentContext > m_xContext; + + protected: + const css::uno::Reference< css::uno::XComponentContext >& getComponentContext() const + { + return m_xContext; + } + + protected: + OProxyAggregation( const css::uno::Reference< css::uno::XComponentContext >& _rxContext ); + ~OProxyAggregation(); + + /// to be called from within your ctor + void baseAggregateProxyFor( + const css::uno::Reference< css::uno::XInterface >& _rxComponent, + oslInterlockedCount& _rRefCount, + ::cppu::OWeakObject& _rDelegator + ); + + // XInterface and XTypeProvider + /// @throws css::uno::RuntimeException + css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ); + /// @throws css::uno::RuntimeException + css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ); + + private: + OProxyAggregation( const OProxyAggregation& ) = delete; + OProxyAggregation& operator=( const OProxyAggregation& ) = delete; + }; + + + //= OComponentProxyAggregationHelper + + /** a helper class for aggregating a proxy to an XComponent + + <p>The object couples the life time of itself and the component: if one of the both + dies (in a sense of being disposed), the other one dies, too.</p> + + <p>The class itself does not implement XComponent so you need to forward any XComponent::dispose + calls which your derived class gets to the dispose method of this class.</p> + */ + + class OComponentProxyAggregationHelper :public ::cppu::ImplHelper1 < css::lang::XEventListener + > + ,private OProxyAggregation + { + private: + typedef ::cppu::ImplHelper1 < css::lang::XEventListener + > BASE; // prevents some MSVC problems + + protected: + css::uno::Reference< css::lang::XComponent > + m_xInner; + ::cppu::OBroadcastHelper& m_rBHelper; + + protected: + // OProxyAggregation + using OProxyAggregation::getComponentContext; + + // XInterface + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& _rType ) override; + + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + protected: + OComponentProxyAggregationHelper( + const css::uno::Reference< css::uno::XComponentContext >& _rxContext, + ::cppu::OBroadcastHelper& _rBHelper + ); + virtual ~OComponentProxyAggregationHelper( ); + + /// to be called from within your ctor + void componentAggregateProxyFor( + const css::uno::Reference< css::lang::XComponent >& _rxComponent, + oslInterlockedCount& _rRefCount, + ::cppu::OWeakObject& _rDelegator + ); + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // XComponent + /// @throws css::uno::RuntimeException + virtual void SAL_CALL dispose() = 0; + + private: + OComponentProxyAggregationHelper( const OComponentProxyAggregationHelper& ) = delete; + OComponentProxyAggregationHelper& operator=( const OComponentProxyAggregationHelper& ) = delete; + }; + + + //= OComponentProxyAggregation + + class COMPHELPER_DLLPUBLIC OComponentProxyAggregation : public cppu::BaseMutex + ,public cppu::WeakComponentImplHelperBase + ,public OComponentProxyAggregationHelper + { + protected: + OComponentProxyAggregation( + const css::uno::Reference< css::uno::XComponentContext >& _rxContext, + const css::uno::Reference< css::lang::XComponent >& _rxComponent + ); + + virtual ~OComponentProxyAggregation() override; + + // XInterface + DECLARE_XINTERFACE() + // XTypeProvider + DECLARE_XTYPEPROVIDER() + + // OComponentHelper + virtual void SAL_CALL disposing() override; + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& _rSource ) override; + + // XComponent/OComponentProxyAggregationHelper + virtual void SAL_CALL dispose() override; + + private: + OComponentProxyAggregation( const OComponentProxyAggregation& ) = delete; + OComponentProxyAggregation& operator=( const OComponentProxyAggregation& ) = delete; + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_PROXYAGGREGATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/random.hxx b/include/comphelper/random.hxx new file mode 100644 index 000000000..345d57c71 --- /dev/null +++ b/include/comphelper/random.hxx @@ -0,0 +1,39 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_RANDOM_HXX +#define INCLUDED_COMPHELPER_RANDOM_HXX + +#include <comphelper/comphelperdllapi.h> + +namespace comphelper::rng +{ +// These functions obey the SAL_RAND_REPEATABLE environment +// variable: If it is set, use a fixed seed. + +// note that uniform_int_distribution is inclusive of b, i.e. [a,b] while +// uniform_real_distribution is exclusive of b, i.e. [a,b), std::nextafter may be your friend there + +/// uniform distribution in [a,b) +COMPHELPER_DLLPUBLIC double uniform_real_distribution(double a = 0.0, double b = 1.0); + +/// uniform distribution in [a,b] +COMPHELPER_DLLPUBLIC int uniform_int_distribution(int a, int b); + +/// uniform distribution in [a,b] +COMPHELPER_DLLPUBLIC unsigned int uniform_uint_distribution(unsigned int a, unsigned int b); + +/// uniform distribution in [a,b] +COMPHELPER_DLLPUBLIC size_t uniform_size_distribution(size_t a, size_t b); + +} // namespace + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/refcountedmutex.hxx b/include/comphelper/refcountedmutex.hxx new file mode 100644 index 000000000..fcda72097 --- /dev/null +++ b/include/comphelper/refcountedmutex.hxx @@ -0,0 +1,43 @@ +/* -*- 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_COMPHELPER_REFCOUNTEDMUTEX_HXX +#define INCLUDED_COMPHELPER_REFCOUNTEDMUTEX_HXX + +#include <comphelper/comphelperdllapi.h> +#include <osl/mutex.hxx> +#include <salhelper/simplereferenceobject.hxx> + +namespace comphelper +{ +class COMPHELPER_DLLPUBLIC RefCountedMutex final : public salhelper::SimpleReferenceObject +{ + osl::Mutex m_aMutex; + +public: + ~RefCountedMutex() override; + + ::osl::Mutex& GetMutex() { return m_aMutex; } +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_REFCOUNTEDMUTEX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/scopeguard.hxx b/include/comphelper/scopeguard.hxx new file mode 100644 index 000000000..95832c505 --- /dev/null +++ b/include/comphelper/scopeguard.hxx @@ -0,0 +1,92 @@ +/* -*- 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_COMPHELPER_SCOPEGUARD_HXX +#define INCLUDED_COMPHELPER_SCOPEGUARD_HXX + +#include <sal/config.h> + +#include <utility> + +#include <o3tl/deleter.hxx> + +// For some reason, Android buildbot issues -Werror like this: +// In file included from +// /home/android/lo/master-android-arm/filter/source/xmlfilteradaptor/XmlFilterAdaptor.cxx:50: +// /home/android/lo/master-android-arm/include/comphelper/scopeguard.hxx:36:14: +// error: function 'comphelper::<deduction guide for ScopeGuard><(lambda at +// /home/android/lo/master-android-arm/filter/source/xmlfilteradaptor/XmlFilterAdaptor.cxx:146:34)>' +// has internal linkage but is not defined [-Werror,-Wundefined-internal] +// explicit ScopeGuard( Func && func ) : m_func( std::move(func) ) {} +// ^ +// /home/android/lo/master-android-arm/filter/source/xmlfilteradaptor/XmlFilterAdaptor.cxx:146:28: +// note: used here +// comphelper::ScopeGuard guard([&]() { +// ^ +#ifdef ANDROID +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundefined-internal" +#endif +#endif + + +namespace comphelper { + +/** ScopeGuard to ease writing exception-safe code. + */ +template <class Func> class ScopeGuard +{ +public: + /** @param func function object to be executed in dtor + */ + explicit ScopeGuard( Func && func ) : m_func( std::move(func) ) {} + + ~ScopeGuard() + { + if (m_bDismissed) + return; + suppress_fun_call_w_exception(m_func()); + } + + /** Dismisses the scope guard, i.e. the function won't + be executed. + */ + void dismiss() { m_bDismissed = true; } + +private: + // noncopyable until we have good reasons... + ScopeGuard(const ScopeGuard&) = delete; + ScopeGuard& operator=(const ScopeGuard&) = delete; + + Func m_func; + bool m_bDismissed = false; +}; + +} // namespace comphelper + +#ifdef ANDROID +#if defined __clang__ +#pragma clang diagnostic pop +#endif +#endif + +#endif // ! defined(INCLUDED_COMPHELPER_SCOPEGUARD_HXX) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/seekableinput.hxx b/include/comphelper/seekableinput.hxx new file mode 100644 index 000000000..0c2092f7b --- /dev/null +++ b/include/comphelper/seekableinput.hxx @@ -0,0 +1,83 @@ +/* -*- 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_COMPHELPER_SEEKABLEINPUT_HXX +#define INCLUDED_COMPHELPER_SEEKABLEINPUT_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> +#include <mutex> + +namespace com::sun::star::uno { class XComponentContext; } + +namespace comphelper +{ + +class SAL_DLLPUBLIC_TEMPLATE OSeekableInputWrapper_BASE + : public ::cppu::WeakImplHelper< css::io::XInputStream, + css::io::XSeekable > +{}; + +class COMPHELPER_DLLPUBLIC OSeekableInputWrapper final + : public OSeekableInputWrapper_BASE +{ + std::mutex m_aMutex; + + css::uno::Reference< css::uno::XComponentContext > m_xContext; + + css::uno::Reference< css::io::XInputStream > m_xOriginalStream; + + css::uno::Reference< css::io::XInputStream > m_xCopyInput; + css::uno::Reference< css::io::XSeekable > m_xCopySeek; + +private: + COMPHELPER_DLLPRIVATE void PrepareCopy_Impl(); + +public: + OSeekableInputWrapper( + css::uno::Reference< css::io::XInputStream > xInStream, + css::uno::Reference< css::uno::XComponentContext > xContext ); + + virtual ~OSeekableInputWrapper() override; + + static css::uno::Reference< css::io::XInputStream > CheckSeekableCanWrap( + const css::uno::Reference< css::io::XInputStream >& xInStream, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ); + +// XInputStream + virtual sal_Int32 SAL_CALL readBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) override; + virtual sal_Int32 SAL_CALL readSomeBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) override; + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) override; + virtual sal_Int32 SAL_CALL available() override; + virtual void SAL_CALL closeInput() override; + +// XSeekable + virtual void SAL_CALL seek( sal_Int64 location ) override; + virtual sal_Int64 SAL_CALL getPosition() override; + virtual sal_Int64 SAL_CALL getLength() override; + +}; + +} // namespace comphelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/seqstream.hxx b/include/comphelper/seqstream.hxx new file mode 100644 index 000000000..c2ba39134 --- /dev/null +++ b/include/comphelper/seqstream.hxx @@ -0,0 +1,135 @@ +/* -*- 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_COMPHELPER_SEQSTREAM_HXX +#define INCLUDED_COMPHELPER_SEQSTREAM_HXX + +#include <config_options.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/comphelperdllapi.h> +#include <comphelper/bytereader.hxx> +#include <mutex> + +namespace comphelper +{ + + +// SequenceInputStream +// stream for reading data from a sequence of bytes + + +class COMPHELPER_DLLPUBLIC SequenceInputStream final + : public ::cppu::WeakImplHelper< css::io::XInputStream, css::io::XSeekable, css::lang::XUnoTunnel >, + public comphelper::ByteReader +{ + std::mutex m_aMutex; + css::uno::Sequence<sal_Int8> const m_aData; + sal_Int32 m_nPos; + +public: + SequenceInputStream(css::uno::Sequence<sal_Int8> const & rData); + +// css::io::XInputStream + virtual sal_Int32 SAL_CALL readBytes( css::uno::Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead ) override; + + virtual sal_Int32 SAL_CALL readSomeBytes( css::uno::Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead ) override; + + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) override; + + virtual sal_Int32 SAL_CALL available( ) override; + + virtual void SAL_CALL closeInput( ) override; + + virtual void SAL_CALL seek( sal_Int64 location ) override; + virtual sal_Int64 SAL_CALL getPosition( ) override; + virtual sal_Int64 SAL_CALL getLength( ) override; + +// css::lang::XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override; + +// comphelper::ByteReader + virtual sal_Int32 readSomeBytes( sal_Int8* pData, sal_Int32 nBytesToRead ) override; + +private: + sal_Int32 avail(); +}; + +// don't export to avoid duplicate WeakImplHelper definitions with MSVC +class SAL_DLLPUBLIC_TEMPLATE OSequenceOutputStream_Base + : public ::cppu::WeakImplHelper< css::io::XOutputStream > +{}; + +class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OSequenceOutputStream final : public OSequenceOutputStream_Base +{ +private: + css::uno::Sequence< sal_Int8 >& m_rSequence; + double m_nResizeFactor; + sal_Int32 const m_nMinimumResize; + sal_Int32 m_nSize; + // the size of the virtual stream. This is not the size of the sequence, but the number of bytes written + // into the stream at a given moment. + + bool m_bConnected; + // closeOutput has been called ? + + std::mutex m_aMutex; + + void finalizeOutput(); + virtual ~OSequenceOutputStream() override { if (m_bConnected) finalizeOutput(); } + +public: + /** constructs the object. Everything written into the stream through the XOutputStream methods will be forwarded + to the sequence, reallocating it if necessary. Writing will start at offset 0 within the sequence. + @param _rSeq a reference to the sequence which will be used for output. + The caller is responsible for taking care of the lifetime of the stream + object and the sequence. If you're in doubt about this, use <code>closeOutput</code> + before destroying the sequence + @param _nResizeFactor the factor which is used for resizing the sequence when necessary. In every + resize step, the new sequence size will be calculated by multiplying the current + size with this factor, rounded off to the next multiple of 4. + @param _nMinimumResize the minimal number of bytes which is additionally allocated on resizing + @see closeOutput + */ + OSequenceOutputStream( + css::uno::Sequence< sal_Int8 >& _rSeq, + double _nResizeFactor = 1.3, + sal_Int32 _nMinimumResize = 128 + ); + + /// same as XOutputStream::writeBytes (as expected :) + virtual void SAL_CALL writeBytes( const css::uno::Sequence< sal_Int8 >& aData ) override; + /// this is a dummy in this implementation, no buffering is used + virtual void SAL_CALL flush( ) override; + /** closes the output stream. In the case of this class, this means that the sequence used for writing is + resized to the really used size and not used any further, every subsequent call to one of the XOutputStream + methods will throw a <code>NotConnectedException</code>. + */ + virtual void SAL_CALL closeOutput( ) override; +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_SEQSTREAM_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/sequence.hxx b/include/comphelper/sequence.hxx new file mode 100644 index 000000000..bc67559df --- /dev/null +++ b/include/comphelper/sequence.hxx @@ -0,0 +1,322 @@ +/* -*- 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_COMPHELPER_SEQUENCE_HXX +#define INCLUDED_COMPHELPER_SEQUENCE_HXX + +#include <com/sun/star/uno/Sequence.hxx> +#include <osl/diagnose.h> + +#include <algorithm> +#include <vector> + +namespace comphelper +{ + /** Search the given value within the given sequence, return the position of the first occurrence. + Returns -1 if nothing found. + */ + template <class T1, class T2> + inline sal_Int32 findValue(const css::uno::Sequence<T1>& _rList, const T2& _rValue) + { + // at which position do I find the value? + for (sal_Int32 i = 0; i < _rList.getLength(); ++i) + { + if (_rList[i] == _rValue) + return i; + } + + return -1; + } + + /// concat several sequences + template <class T, class... Ss> + inline css::uno::Sequence<T> concatSequences(const css::uno::Sequence<T>& rS1, const Ss&... rSn) + { + // unary fold to disallow empty parameter pack: at least have one sequence in rSn + css::uno::Sequence<T> aReturn(std::size(rS1) + (... + std::size(rSn))); + T* pReturn = std::copy(std::begin(rS1), std::end(rS1), aReturn.getArray()); + (..., (pReturn = std::copy(std::begin(rSn), std::end(rSn), pReturn))); + return aReturn; + } + + /// concat additional elements from right sequence to left sequence + /// + /// be aware that this takes time O(|left| * |right|) + template<typename T> inline css::uno::Sequence<T> combineSequences( + css::uno::Sequence<T> const & left, css::uno::Sequence<T> const & right) + { + sal_Int32 n1 = left.getLength(); + css::uno::Sequence<T> ret(n1 + right.getLength()); + //TODO: check for overflow + auto pRet = ret.getArray(); + std::copy_n(left.getConstArray(), n1, pRet); + sal_Int32 n2 = n1; + for (sal_Int32 i = 0; i != right.getLength(); ++i) { + bool found = false; + for (sal_Int32 j = 0; j != n1; ++j) { + if (right[i] == left[j]) { + found = true; + break; + } + } + if (!found) { + pRet[n2++] = right[i]; + } + } + ret.realloc(n2); + return ret; + } + + /// remove a specified element from a sequences + template<class T> + inline void removeElementAt(css::uno::Sequence<T>& _rSeq, sal_Int32 _nPos) + { + sal_Int32 nLength = _rSeq.getLength(); + + OSL_ENSURE(0 <= _nPos && _nPos < nLength, "invalid index"); + + T* pPos = _rSeq.getArray() + _nPos; + std::move(pPos + 1, pPos + nLength - _nPos, pPos); + + _rSeq.realloc(nLength-1); + } + + /** Copy from a plain C/C++ array into a Sequence. + + @tpl SrcType + Array element type. Must be assignable to DstType + + @tpl DstType + Sequence element type. Must be assignable from SrcType + + @param i_pArray + Valid pointer to at least num elements of type SrcType + + @param nNum + Number of array elements to copy + + @return the resulting Sequence + + @attention when copying from e.g. a double array to a + Sequence<int>, no proper rounding will be performed, but the + values will be truncated. There's currently no measure to + prevent or detect precision loss, overflow or truncation. + */ + template < typename DstType, typename SrcType > + inline css::uno::Sequence< DstType > arrayToSequence( const SrcType* i_pArray, sal_Int32 nNum ) + { + if constexpr (std::is_same_v< DstType, SrcType >) + { + return css::uno::Sequence< DstType >( i_pArray, nNum ); + } + else + { + css::uno::Sequence< DstType > result( nNum ); + ::std::copy( i_pArray, i_pArray+nNum, result.getArray() ); + return result; + } + } + + + /** Copy from a Sequence into a plain C/C++ array + + @tpl SrcType + Sequence element type. Must be assignable to DstType + + @tpl DstType + Array element type. Must be assignable from SrcType + + @param io_pArray + Valid pointer to at least i_Sequence.getLength() elements of + type DstType + + @param i_Sequence + Reference to a Sequence of SrcType elements + + @return a pointer to the array + + @attention when copying from e.g. a Sequence<double> to an int + array, no proper rounding will be performed, but the values + will be truncated. There's currently no measure to prevent or + detect precision loss, overflow or truncation. + */ + template < typename DstType, typename SrcType > + inline DstType* sequenceToArray( DstType* io_pArray, const css::uno::Sequence< SrcType >& i_Sequence ) + { + ::std::copy( i_Sequence.begin(), i_Sequence.end(), io_pArray ); + return io_pArray; + } + + + /** Copy from a container into a Sequence + + @tpl SrcType + Container type. This type must fulfill the STL container + concept, in particular, the size(), begin() and end() methods + must be available and have the usual semantics. + + @tpl DstType + Sequence element type. Must be assignable from SrcType's + elements + + @param i_Container + Reference to the input contain with elements of type SrcType + + @return the generated Sequence + + @attention this function always performs a copy. Furthermore, + when copying from e.g. a vector<double> to a Sequence<int>, no + proper rounding will be performed, but the values will be + truncated. There's currently no measure to prevent or detect + precision loss, overflow or truncation. + */ + template < typename DstElementType, typename SrcType > + inline css::uno::Sequence< DstElementType > containerToSequence( const SrcType& i_Container ) + { + using ::std::size, ::std::begin, ::std::end; + css::uno::Sequence< DstElementType > result( size(i_Container) ); + ::std::copy( begin(i_Container), end(i_Container), result.getArray() ); + return result; + } + + // this one does better type deduction, but does not allow us to copy into a different element type + template < typename SrcType > + inline css::uno::Sequence< typename SrcType::value_type > containerToSequence( const SrcType& i_Container ) + { + return containerToSequence<typename SrcType::value_type, SrcType>(i_Container); + } + + // handle arrays + template<typename ElementType, std::size_t SrcSize> + inline css::uno::Sequence< ElementType > containerToSequence( ElementType const (&i_Array)[ SrcSize ] ) + { + return css::uno::Sequence< ElementType >( i_Array, SrcSize ); + } + + template <typename T> + inline css::uno::Sequence<T> containerToSequence( + ::std::vector<T> const& v ) + { + return css::uno::Sequence<T>( + v.data(), static_cast<sal_Int32>(v.size()) ); + } + + + /** Copy from a Sequence into a container + + @tpl SrcType + Sequence element type. Must be assignable to SrcType's + elements + + @tpl DstType + Container type. This type must have a constructor taking a pair + of iterators defining a range to copy from + + @param i_Sequence + Reference to a Sequence of SrcType elements + + @return the generated container. C++17 copy elision rules apply + + @attention this function always performs a copy. Furthermore, + when copying from e.g. a Sequence<double> to a vector<int>, no + proper rounding will be performed, but the values will be + truncated. There's currently no measure to prevent or detect + precision loss, overflow or truncation. + */ + template < typename DstType, typename SrcType > + inline DstType sequenceToContainer( const css::uno::Sequence< SrcType >& i_Sequence ) + { + return DstType(i_Sequence.begin(), i_Sequence.end()); + } + + // this one does better type deduction, but does not allow us to copy into a different element type + template < typename DstType > + inline DstType sequenceToContainer( const css::uno::Sequence< typename DstType::value_type >& i_Sequence ) + { + return DstType(i_Sequence.begin(), i_Sequence.end()); + } + + /** Copy from a Sequence into an existing container + + This potentially saves a needless extra copy operation over + the whole container, as it passes the target object by + reference. + + @tpl SrcType + Sequence element type. Must be assignable to SrcType's + elements + + @tpl DstType + Container type. This type must fulfill the STL container and + sequence concepts, in particular, the begin(), end() and + resize(int) methods must be available and have the usual + semantics. + + @param o_Output + Reference to the target container + + @param i_Sequence + Reference to a Sequence of SrcType elements + + @return a non-const reference to the given container + + @attention this function always performs a copy. Furthermore, + when copying from e.g. a Sequence<double> to a vector<int>, no + proper rounding will be performed, but the values will be + truncated. There's currently no measure to prevent or detect + precision loss, overflow or truncation. + */ + template < typename DstType, typename SrcType > + inline DstType& sequenceToContainer( DstType& o_Output, const css::uno::Sequence< SrcType >& i_Sequence ) + { + o_Output.resize( i_Sequence.getLength() ); + ::std::copy( i_Sequence.begin(), i_Sequence.end(), o_Output.begin() ); + return o_Output; + } + + /** Copy (keys or values) from an associate container into a Sequence + + @tpl M map container type eg. std::map/std::unordered_map + + @return the generated Sequence + */ + template < typename M > + inline css::uno::Sequence< typename M::key_type > mapKeysToSequence( M const& map ) + { + css::uno::Sequence< typename M::key_type > ret( static_cast<sal_Int32>(map.size()) ); + std::transform(map.begin(), map.end(), ret.getArray(), + [](const auto& i) { return i.first; }); + return ret; + } + + template < typename M > + inline css::uno::Sequence< typename M::mapped_type > mapValuesToSequence( M const& map ) + { + css::uno::Sequence< typename M::mapped_type > ret( static_cast<sal_Int32>(map.size()) ); + std::transform(map.begin(), map.end(), ret.getArray(), + [](const auto& i) { return i.second; }); + return ret; + } + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_SEQUENCE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/sequenceashashmap.hxx b/include/comphelper/sequenceashashmap.hxx new file mode 100644 index 000000000..59ab4c298 --- /dev/null +++ b/include/comphelper/sequenceashashmap.hxx @@ -0,0 +1,426 @@ +/* -*- 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_COMPHELPER_SEQUENCEASHASHMAP_HXX +#define INCLUDED_COMPHELPER_SEQUENCEASHASHMAP_HXX + +#include <unordered_map> +#include <com/sun/star/uno/Sequence.hxx> + +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::beans { struct NamedValue; } +namespace com::sun::star::beans { struct PropertyValue; } + +namespace comphelper{ + + +/** @short Implements a stl hash map on top of some + specialized sequence from type PropertyValue + or NamedValue. + + @descr That provides the possibility to modify + such name sequences very easy ... + */ + +/** Cache the hash code since calculating it for every comparison adds up */ +struct OUStringAndHashCode +{ + OUString maString; + sal_Int32 mnHashCode; + + OUStringAndHashCode(OUString s) : maString(s), mnHashCode(maString.hashCode()) {} +}; +struct OUStringAndHashCodeEqual +{ + bool operator()(const OUStringAndHashCode & lhs, const OUStringAndHashCode & rhs) const + { + return lhs.mnHashCode == rhs.mnHashCode && lhs.maString == rhs.maString; + } +}; +struct OUStringAndHashCodeHash +{ + size_t operator()(const OUStringAndHashCode & i) const + { + return i.mnHashCode; + } +}; +using SequenceAsHashMapBase = std::unordered_map<OUStringAndHashCode, css::uno::Any, OUStringAndHashCodeHash, OUStringAndHashCodeEqual>; + +class SAL_WARN_UNUSED COMPHELPER_DLLPUBLIC SequenceAsHashMap +{ + + public: + + + /** @short creates an empty hash map. + */ + SequenceAsHashMap(); + + + /** @see operator<<(const css::uno::Any&) + */ + SequenceAsHashMap(const css::uno::Any& aSource); + + + /** @see operator<<(const css::uno::Sequence< css::uno::Any >&) + */ + SequenceAsHashMap(const css::uno::Sequence< css::uno::Any >& lSource); + + + /** @see operator<<(const css::uno::Sequence< css::beans::PropertyValue >&) + */ + SequenceAsHashMap(const css::uno::Sequence< css::beans::PropertyValue >& lSource); + + + /** @see operator<<(const css::uno::Sequence< css::beans::NamedValue >&) + */ + SequenceAsHashMap(const css::uno::Sequence< css::beans::NamedValue >& lSource); + + + /** @short fill this map from the given + Any, which of course must contain + a suitable sequence of element types + "css.beans.PropertyValue" or "css.beans.NamedValue". + + @attention If the given Any is an empty one + (if it's set to VOID), no exception + is thrown. In such case this instance will + be created as an empty one too! + + @param aSource + contains the new items for this map. + + @throw A css::lang::IllegalArgumentException + is thrown, if the given Any does not contain a suitable sequence ... + but not if it's a VOID Any! + */ + void operator<<(const css::uno::Any& aSource); + + + /** @short fill this map from the given + sequence, where every Any must contain + an item from type "css.beans.PropertyValue" + "css.beans.NamedValue". + + @param lSource + contains the new items for this map. + + @throw A css::lang::IllegalArgumentException + is thrown, if the given Any sequence + uses wrong types for its items. VOID Any will be ignored! + */ + void operator<<(const css::uno::Sequence< css::uno::Any >& lSource); + + + /** @short fill this map from the given + PropertyValue sequence. + + @param lSource + contains the new items for this map. + */ + void operator<<(const css::uno::Sequence< css::beans::PropertyValue >& lSource); + + + /** @short fill this map from the given + NamedValue sequence. + + @param lSource + contains the new items for this map. + */ + void operator<<(const css::uno::Sequence< css::beans::NamedValue >& lSource); + + + /** @short converts this map instance to an + PropertyValue sequence. + + @param lDestination + target sequence for converting. + */ + void operator>>(css::uno::Sequence< css::beans::PropertyValue >& lDestination) const; + + + /** @short converts this map instance to an + NamedValue sequence. + + @param lDestination + target sequence for converting. + */ + void operator>>(css::uno::Sequence< css::beans::NamedValue >& lDestination) const; + + + /** @short return this map instance as an + Any, which can be + used in const environments only. + + @descr It's made const to prevent using of the + return value directly as an in/out parameter! + usage: myMethod(stlDequeAdapter.getAsAnyList()); + + @param bAsPropertyValue + switch between using of PropertyValue or NamedValue as + value type. + + @return A const Any, which + contains all items of this map. + */ + css::uno::Any getAsConstAny(bool bAsPropertyValue) const; + + + /** @short return this map instance to as a + NamedValue sequence, which can be + used in const environments only. + + @descr It's made const to prevent using of the + return value directly as an in/out parameter! + usage: myMethod(stlDequeAdapter.getAsNamedValueList()); + + @return A const sequence of type NamedValue, which + contains all items of this map. + */ + css::uno::Sequence< css::beans::NamedValue > getAsConstNamedValueList() const; + + + /** @short return this map instance to as a + PropertyValue sequence, which can be + used in const environments only. + + @descr It's made const to prevent using of the + return value directly as an in/out parameter! + usage: myMethod(stlDequeAdapter.getAsPropertyValueList()); + + @return A const sequence of type PropertyValue, which + contains all items of this map. + */ + css::uno::Sequence< css::beans::PropertyValue > getAsConstPropertyValueList() const; + + + /** @short check if the specified item exists + and return its (unpacked!) value or it returns the + specified default value otherwise. + + @descr If a value should be extracted only in case + the requested property exists really (without creating + of new items as it the index operator of a + hash map does!) this method can be used. + + @param sKey + key name of the item. + + @param aDefault + the default value, which is returned + if the specified item could not + be found. + + @return The (unpacked!) value of the specified property or + the given default value otherwise. + + @attention "unpacked" means the Any content of every iterator->second! + */ + template< class TValueType > + TValueType getUnpackedValueOrDefault(const OUString& sKey , + const TValueType& aDefault) const + { + auto pIt = m_aMap.find(sKey); + if (pIt == m_aMap.end()) + return aDefault; + + TValueType aValue = TValueType(); + if (!(pIt->second >>= aValue)) + return aDefault; + + return aValue; + } + + /** @short check if the specified item exists + and return its value or it returns + an empty css::uno::Any. + + @descr If a value should be extracted only in case + the requested property exists really (without creating + of new items as the index operator of a + hash map does!) this method can be used. + + @param sKey + key name of the item. + + @return The value of the specified property or + an empty css::uno::Any. + */ + css::uno::Any getValue(const OUString& sKey) const + { + auto pIt = m_aMap.find(sKey); + if (pIt == m_aMap.end()) + return css::uno::Any(); + + return pIt->second; + } + + + /** @short creates a new item with the specified + name and value only in case such item name + does not already exist. + + @descr To check if the property already exists only + its name is used for compare. Its value isn't + checked! + + @param sKey + key name of the property. + + @param aValue + the new (unpacked!) value. + Note: This value will be transformed to an Any + internally, because only Any values can be + part of a PropertyValue or NamedValue structure. + + @return TRUE if this property was added as new item; + FALSE if it already exists. + */ + template< class TValueType > + bool createItemIfMissing(const OUString& sKey , + const TValueType& aValue) + { + if (m_aMap.find(sKey) == m_aMap.end()) + { + (*this)[sKey] = css::uno::toAny(aValue); + return true; + } + + return false; + } + + + /** @short check if all items of given map + exists in these called map also. + + @descr Every item of the given map must exists + with same name and value inside these map. + But these map can contain additional items + which are not part of the search-map. + + @param rCheck + the map containing all items for checking. + + @return + TRUE if all items of Rcheck could be found + in these map; FALSE otherwise. + */ + bool match(const SequenceAsHashMap& rCheck) const; + + + /** @short merge all values from the given map into + this one. + + @descr Existing items will be overwritten ... + missing items will be created new ... + but non specified items will stay alive ! + + @param rSource + the map containing all items for the update. + */ + void update(const SequenceAsHashMap& rSource); + + css::uno::Any& operator[](const OUString& rKey) + { + return m_aMap[rKey]; + } + + css::uno::Any& operator[](const OUStringAndHashCode& rKey) + { + return m_aMap[rKey]; + } + + using iterator = SequenceAsHashMapBase::iterator; + using const_iterator = SequenceAsHashMapBase::const_iterator; + + void clear() + { + m_aMap.clear(); + } + + size_t size() const + { + return m_aMap.size(); + } + + bool empty() const + { + return m_aMap.empty(); + } + + iterator begin() + { + return m_aMap.begin(); + } + + const_iterator begin() const + { + return m_aMap.begin(); + } + + iterator end() + { + return m_aMap.end(); + } + + const_iterator end() const + { + return m_aMap.end(); + } + + iterator find(const OUString& rKey) + { + return m_aMap.find(rKey); + } + + const_iterator find(const OUString& rKey) const + { + return m_aMap.find(rKey); + } + + iterator find(const OUStringAndHashCode& rKey) + { + return m_aMap.find(rKey); + } + + const_iterator find(const OUStringAndHashCode& rKey) const + { + return m_aMap.find(rKey); + } + + iterator erase(iterator it) + { + return m_aMap.erase(it); + } + + size_t erase(const OUString& rKey) + { + return m_aMap.erase(rKey); + } + +private: + SequenceAsHashMapBase m_aMap; +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_SEQUENCEASHASHMAP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/servicedecl.hxx b/include/comphelper/servicedecl.hxx new file mode 100644 index 000000000..57da446e6 --- /dev/null +++ b/include/comphelper/servicedecl.hxx @@ -0,0 +1,155 @@ +/* -*- 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_COMPHELPER_SERVICEDECL_HXX +#define INCLUDED_COMPHELPER_SERVICEDECL_HXX + +#include <comphelper/comphelperdllapi.h> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <functional> +#include <initializer_list> + +namespace comphelper::service_decl { + +class ServiceDecl; + +namespace detail { +typedef ::std::function< + css::uno::Reference<css::uno::XInterface> /* return */ + (ServiceDecl const&, + css::uno::Sequence<css::uno::Any> const&, + css::uno::Reference<css::uno::XComponentContext> const&)> CreateFuncF; +} + +/** Class to declare a service implementation. There is no need to implement + lang::XServiceInfo nor lang::XInitialization anymore. + The declaration can be done in various ways, the (simplest) form is + + <pre> + class MyClass : public cppu::WeakImplHelper<XInterface1, XInterface2> { + public: + MyClass( uno::Reference<uno::XComponentContext> const& xContext ) + [...] + }; + [...] + namespace sdecl = comphelper::service_decl; + sdecl::ServiceDecl const myDecl( + sdecl::class_<MyClass>(), + "my.unique.implementation.name", + "MyServiceSpec1;MyServiceSpec2" ); + </pre> + + If the service demands initialization by arguments, the implementation + class has to define a constructor taking both arguments and component + context: + + <pre> + class MyClass : public cppu::WeakImplHelper<XInterface1, XInterface2> { + public: + MyClass( uno::Sequence<uno::Any> const& args, + uno::Reference<uno:XComponentContext> const& xContext ) + [...] + }; + [...] + namespace sdecl = comphelper::service_decl; + sdecl::ServiceDecl const myDecl( + sdecl::class_<MyClass, sdecl::with_args<true> >(), + "my.unique.implementation.name", + "MyServiceSpec1;MyServiceSpec2" ); + </pre> + + Additionally, there is the possibility to process some code after creation, + e.g. to add the newly created object as a listener or perform aggregation + (C++-UNO only): + + <pre> + uno::Reference<uno::XInterface> somePostProcCode( MyClass * p ); + [...] + namespace sdecl = comphelper::service_decl; + sdecl::ServiceDecl const myDecl( + sdecl::class_<MyClass, ... >(&somePostProcCode), + "my.unique.implementation.name", + "MyServiceSpec1;MyServiceSpec2" ); + </pre> + + In the latter case, somePostProcCode gets the yet unacquired "raw" pointer. +*/ +class COMPHELPER_DLLPUBLIC ServiceDecl +{ +public: + /** Ctor for multiple supported service names. + + @param implClass implementation class description + @param pImplName implementation name + @param pSupportedServiceNames supported service names + @param cDelim delimiter for supported service names + */ + ServiceDecl( const ServiceDecl& ) = delete; + ServiceDecl& operator=( const ServiceDecl& ) = delete; + template <typename ImplClassT> + ServiceDecl( ImplClassT const& implClass, + char const* pImplName, + char const* pSupportedServiceNames ) + : m_createFunc(implClass.m_createFunc), + m_pImplName(pImplName), + m_pServiceNames(pSupportedServiceNames) {} + + /// @internal gets called by component_getFactoryHelper() + void * getFactory( char const* pImplName ) const; + + /// @return supported service names + css::uno::Sequence< OUString> getSupportedServiceNames() const; + + /// @return whether name is in set of supported service names + bool supportsService( std::u16string_view name ) const; + + /// @return implementation name + OUString getImplementationName() const; + +private: + class Factory; + friend class Factory; + + detail::CreateFuncF const m_createFunc; + char const* const m_pImplName; + char const* const m_pServiceNames; +}; + +/** To specify whether the implementation class expects arguments + (uno::Sequence<uno::Any>). +*/ +template <bool> struct with_args; + +/// @internal +namespace detail { + +} // namespace detail + + +COMPHELPER_DLLPUBLIC +void* component_getFactoryHelper( const char* pImplName, + std::initializer_list<ServiceDecl const *> args ); + +} // namespace comphelper::service_decl + + +#endif // ! defined( INCLUDED_COMPHELPER_SERVICEDECL_HXX) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/servicehelper.hxx b/include/comphelper/servicehelper.hxx new file mode 100644 index 000000000..c225494cc --- /dev/null +++ b/include/comphelper/servicehelper.hxx @@ -0,0 +1,152 @@ +/* -*- 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_COMPHELPER_SERVICEHELPER_HXX +#define INCLUDED_COMPHELPER_SERVICEHELPER_HXX + +#include <rtl/uuid.h> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/uno/Sequence.hxx> + +namespace comphelper { + + // Class incapsulating UIDs used as e.g. tunnel IDs for css::lang::XUnoTunnel, + // or implementation IDs for css::lang::XTypeProvider + class UnoIdInit + { + private: + css::uno::Sequence< sal_Int8 > m_aSeq; + public: + UnoIdInit() : m_aSeq(16) + { + rtl_createUuid(reinterpret_cast<sal_uInt8*>(m_aSeq.getArray()), nullptr, true); + } + const css::uno::Sequence< sal_Int8 >& getSeq() const { return m_aSeq; } + }; + + inline sal_Int64 getSomething_cast(void* p) + { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(p)); + } + + template<class T> inline T* getSomething_cast(sal_Int64 n) + { + return reinterpret_cast<T*>(sal::static_int_cast<sal_IntPtr>(n)); + } + + template <class T> T* getFromUnoTunnel(const css::uno::Reference<css::lang::XUnoTunnel>& xUT) + { + if (!xUT.is()) + return nullptr; + + return getSomething_cast<T>(xUT->getSomething(T::getUnoTunnelId())); + } + + // Takes an interface + template <class T> T* getFromUnoTunnel(const css::uno::Reference<css::uno::XInterface>& xIface) + { + return getFromUnoTunnel<T>( + css::uno::Reference<css::lang::XUnoTunnel>{ xIface, css::uno::UNO_QUERY }); + } + + // Takes an Any + template <class T> T* getFromUnoTunnel(const css::uno::Any& rAny) + { + // For unclear reason, using a Reference ctor taking an Any + // gives different results compared to use of operator >>=. + css::uno::Reference<css::lang::XUnoTunnel> xUnoTunnel; + rAny >>= xUnoTunnel; + return getFromUnoTunnel<T>(xUnoTunnel); + } + + template <typename T> + inline bool isUnoTunnelId(const css::uno::Sequence< sal_Int8 >& rId) + { + return rId.getLength() == 16 + && memcmp(T::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16) == 0; + } + + template <class Base> struct FallbackToGetSomethingOf + { + static sal_Int64 get(const css::uno::Sequence<sal_Int8>& rId, Base* p) + { + return p->Base::getSomething(rId); + } + }; + + template <> struct FallbackToGetSomethingOf<void> + { + static sal_Int64 get(const css::uno::Sequence<sal_Int8>&, void*) { return 0; } + }; + + template <class T, class Base = void> + sal_Int64 getSomethingImpl(const css::uno::Sequence<sal_Int8>& rId, T* pThis, + FallbackToGetSomethingOf<Base> = {}) + { + if (isUnoTunnelId<T>(rId)) + return getSomething_cast(pThis); + + return FallbackToGetSomethingOf<Base>::get(rId, pThis); + } + +} + +/** the UNO3_GETIMPLEMENTATION_* macros implement a static helper function + that gives access to your implementation for a given interface reference, + if possible. + + Example: + MyClass* pClass = comphelper::getFromUnoTunnel<MyClass>( xRef ); + + Usage: + Put a UNO3_GETIMPLEMENTATION_DECL( classname ) inside your class + definition and UNO3_GETIMPLEMENTATION_IMPL( classname ) inside + your cxx file. Your class must inherit css::lang::XUnoTunnel + and export it with queryInterface. Implementation of XUnoTunnel is + done by this macro. +*/ +#define UNO3_GETIMPLEMENTATION_DECL( classname ) \ + static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId() noexcept; \ + virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override; + +#define UNO3_GETIMPLEMENTATION_BASE_IMPL( classname ) \ +const css::uno::Sequence< sal_Int8 > & classname::getUnoTunnelId() noexcept \ +{ \ + static const comphelper::UnoIdInit aId; \ + return aId.getSeq(); \ +} + +#define UNO3_GETIMPLEMENTATION_IMPL( classname )\ +UNO3_GETIMPLEMENTATION_BASE_IMPL(classname)\ +sal_Int64 SAL_CALL classname::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) \ +{ \ + return comphelper::getSomethingImpl(rId, this); \ +} + +#define UNO3_GETIMPLEMENTATION2_IMPL( classname, baseclass )\ +UNO3_GETIMPLEMENTATION_BASE_IMPL(classname)\ +sal_Int64 SAL_CALL classname::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) \ +{ \ + return comphelper::getSomethingImpl(rId, this, comphelper::FallbackToGetSomethingOf<baseclass>{}); \ +} + + +#endif // INCLUDED_COMPHELPER_SERVICEHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/sharedmutex.hxx b/include/comphelper/sharedmutex.hxx new file mode 100644 index 000000000..a92c7ccb3 --- /dev/null +++ b/include/comphelper/sharedmutex.hxx @@ -0,0 +1,77 @@ +/* -*- 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_COMPHELPER_SHAREDMUTEX_HXX +#define INCLUDED_COMPHELPER_SHAREDMUTEX_HXX + +#include <comphelper/comphelperdllapi.h> +#include <memory> + +namespace osl { class Mutex; } + +namespace comphelper +{ + + + //= SharedMutex + + class COMPHELPER_DLLPUBLIC SharedMutex + { + public: + SharedMutex(); + + operator ::osl::Mutex& () { return *m_pMutexImpl; } + + private: + std::shared_ptr< ::osl::Mutex > m_pMutexImpl; + }; + + + //= SharedMutexBase + + /** sometimes, it's necessary to have an initialized ::osl::Mutex to pass + to some ctor call of your base class. In this case, you can't hold the + SharedMutex as member, but you need to move it into another base class, + which is initialized before the mutex-requiring class is. + */ + class COMPHELPER_DLLPUBLIC SharedMutexBase + { + protected: + SharedMutexBase() + { + } + ~SharedMutexBase() + { + } + + protected: + ::osl::Mutex& getMutex() const { return m_aMutex; } + SharedMutex& getSharedMutex() const { return m_aMutex; } + + private: + mutable SharedMutex m_aMutex; + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_SHAREDMUTEX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/simplefileaccessinteraction.hxx b/include/comphelper/simplefileaccessinteraction.hxx new file mode 100644 index 000000000..e9295d4d7 --- /dev/null +++ b/include/comphelper/simplefileaccessinteraction.hxx @@ -0,0 +1,52 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_SIMPLEFILEACCESSINTERACTION_HXX +#define INCLUDED_COMPHELPER_SIMPLEFILEACCESSINTERACTION_HXX + +#include <sal/config.h> +#include <ucbhelper/interceptedinteraction.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::task { class XInteractionHandler; } +namespace com::sun::star::task { class XInteractionRequest; } + +namespace comphelper { +/** An interaction handler wrapper for simple file access. + + This wrapper is to be used together with XSimpleFileAccess when + you want to avoid the error messages displayed when accessing a file (the messages activated + by ucphelper::cancelCommandExecution). + + This wrapper is especially useful when you need to access a Web/DAV connection + enabling https certificate validation and optionally enabling the authentication + dialog that may be needed in these operations. + + @param xHandler + Used handler, always needed. + It will be used for Certificate Validation dialog or authentication dialog. + The authentication is used in Web/DAV access when the server requests credentials to be accessed. +*/ +class COMPHELPER_DLLPUBLIC SimpleFileAccessInteraction final : public ::ucbhelper::InterceptedInteraction +{ + +public: + SimpleFileAccessInteraction(const css::uno::Reference< css::task::XInteractionHandler >& xHandler); + virtual ~SimpleFileAccessInteraction() override; + +private: + + virtual ucbhelper::InterceptedInteraction::EInterceptionState intercepted(const ::ucbhelper::InterceptedInteraction::InterceptedRequest& aRequest, + const css::uno::Reference< css::task::XInteractionRequest >& xRequest) override; + +}; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/solarmutex.hxx b/include/comphelper/solarmutex.hxx new file mode 100644 index 000000000..4094e08ee --- /dev/null +++ b/include/comphelper/solarmutex.hxx @@ -0,0 +1,98 @@ +/* -*- 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_COMPHELPER_SOLARMUTEX_HXX +#define INCLUDED_COMPHELPER_SOLARMUTEX_HXX + +#include <sal/config.h> + +#include <assert.h> +#include <atomic> + +#include <osl/thread.h> +#include <osl/mutex.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace comphelper { + + +/** + * SolarMutex, needed for VCL's Application::GetSolarMutex(). + * + * The SolarMutex is the one big recursive code lock used + * to protect the vast majority of the LibreOffice code-base, + * in particular anything that is graphical and the cores of + * the applications. + * + * Treat this as a singleton, as its constructor sets a global + * pointing at itself. + */ +class COMPHELPER_DLLPUBLIC SolarMutex { +public: + typedef void (*BeforeReleaseHandler) (); + + SolarMutex(); + virtual ~SolarMutex(); + + void SetBeforeReleaseHandler( const BeforeReleaseHandler& rLink ) + { m_aBeforeReleaseHandler = rLink; } + + void acquire( sal_uInt32 nLockCount = 1 ); + sal_uInt32 release( bool bUnlockAll = false ); + + virtual bool tryToAcquire(); + + // returns true, if the mutex is owned by the current thread + virtual bool IsCurrentThread() const; + + /// Help components to get the SolarMutex easily. + static SolarMutex *get(); + +protected: + virtual sal_uInt32 doRelease( bool bUnlockAll ); + virtual void doAcquire( sal_uInt32 nLockCount ); + + osl::Mutex m_aMutex; + sal_uInt32 m_nCount; + +private: + std::atomic<oslThreadIdentifier> m_nThreadId; + + SolarMutex(const SolarMutex&) = delete; + SolarMutex& operator=(const SolarMutex&) = delete; + + BeforeReleaseHandler m_aBeforeReleaseHandler; +}; + +inline void SolarMutex::acquire( sal_uInt32 nLockCount ) +{ + assert( nLockCount > 0 ); + doAcquire( nLockCount ); +} + +inline sal_uInt32 SolarMutex::release( bool bUnlockAll ) +{ + return doRelease( bUnlockAll ); +} + +} + +#endif // INCLUDED_COMPHELPER_SOLARMUTEX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/stillreadwriteinteraction.hxx b/include/comphelper/stillreadwriteinteraction.hxx new file mode 100644 index 000000000..fb03a7ad1 --- /dev/null +++ b/include/comphelper/stillreadwriteinteraction.hxx @@ -0,0 +1,62 @@ +/* -*- 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_COMPHELPER_STILLREADWRITEINTERACTION_HXX +#define INCLUDED_COMPHELPER_STILLREADWRITEINTERACTION_HXX + +#include <config_options.h> +#include <ucbhelper/interceptedinteraction.hxx> + +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::task { class XInteractionHandler; } +namespace com::sun::star::task { class XInteractionRequest; } + + +namespace comphelper{ +class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) StillReadWriteInteraction final : public ::ucbhelper::InterceptedInteraction +{ +private: + static const sal_Int32 HANDLE_INTERACTIVEIOEXCEPTION = 0; + static const sal_Int32 HANDLE_UNSUPPORTEDDATASINKEXCEPTION = 1; + static const sal_Int32 HANDLE_AUTHENTICATIONREQUESTEXCEPTION = 2; + static const sal_Int32 HANDLE_CERTIFICATEVALIDATIONREQUESTEXCEPTION = 3; + + bool m_bUsed; + bool m_bHandledByMySelf; + +public: + StillReadWriteInteraction(const css::uno::Reference< css::task::XInteractionHandler >& xHandler, + css::uno::Reference< css::task::XInteractionHandler > xAuxiliaryHandler); + + void resetInterceptions(); + void resetErrorStates(); + bool wasWriteError() const { return (m_bUsed && m_bHandledByMySelf);} + +private: + css::uno::Reference< css::task::XInteractionHandler > m_xAuxiliaryHandler; + + virtual ucbhelper::InterceptedInteraction::EInterceptionState intercepted(const ::ucbhelper::InterceptedInteraction::InterceptedRequest& aRequest, + const css::uno::Reference< css::task::XInteractionRequest >& xRequest) override; + +}; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/stl_types.hxx b/include/comphelper/stl_types.hxx new file mode 100644 index 000000000..6b21dd77d --- /dev/null +++ b/include/comphelper/stl_types.hxx @@ -0,0 +1,176 @@ +/* -*- 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_COMPHELPER_STL_TYPES_HXX +#define INCLUDED_COMPHELPER_STL_TYPES_HXX + +#include <sal/config.h> + +#include <algorithm> +#include <memory> +#include <string_view> + +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <o3tl/string_view.hxx> + +namespace com::sun::star::uno { template <typename > class Reference; } + +namespace comphelper +{ + +// comparison functors + +struct UStringMixLess +{ + bool m_bCaseSensitive; +public: + UStringMixLess(bool bCaseSensitive = true):m_bCaseSensitive(bCaseSensitive){} + bool operator() (std::u16string_view x, std::u16string_view y) const + { + if (m_bCaseSensitive) + return x < y; + else + return o3tl::compareToIgnoreAsciiCase(x, y) < 0; + } + + bool isCaseSensitive() const {return m_bCaseSensitive;} +}; + +class UStringMixEqual +{ + bool const m_bCaseSensitive; + +public: + UStringMixEqual(bool bCaseSensitive = true):m_bCaseSensitive(bCaseSensitive){} + bool operator() (std::u16string_view lhs, std::u16string_view rhs) const + { + return m_bCaseSensitive ? lhs == rhs : o3tl::equalsIgnoreAsciiCase( lhs, rhs ); + } + bool isCaseSensitive() const {return m_bCaseSensitive;} +}; + +/// by-value less functor for std::set<std::unique_ptr<T>> +template<class T> struct UniquePtrValueLess +{ + bool operator()(std::unique_ptr<T> const& lhs, + std::unique_ptr<T> const& rhs) const + { + assert(lhs.get()); + assert(rhs.get()); + return (*lhs) < (*rhs); + } + // The following are so we can search in std::set without allocating a temporary entry on the heap + typedef bool is_transparent; + bool operator()(T const& lhs, + std::unique_ptr<T> const& rhs) const + { + assert(rhs.get()); + return lhs < (*rhs); + } + bool operator()(std::unique_ptr<T> const& lhs, + T const& rhs) const + { + assert(lhs.get()); + return (*lhs) < rhs; + } +}; + +/// by-value implementation of std::foo<std::unique_ptr<T>>::operator== +template<template<typename, typename...> class C, typename T, typename... Etc> +bool ContainerUniquePtrEquals( + C<std::unique_ptr<T>, Etc...> const& lhs, + C<std::unique_ptr<T>, Etc...> const& rhs) +{ + return lhs.size() == rhs.size() + && std::equal(lhs.begin(), lhs.end(), rhs.begin(), + [](const auto& p1, const auto& p2) { return *p1 == *p2; }); +}; + + +template <class Tp, class Arg> +class mem_fun1_t +{ + typedef void (Tp::*_fun_type)(Arg); +public: + explicit mem_fun1_t(_fun_type pf) : M_f(pf) {} + void operator()(Tp* p, Arg x) const { (p->*M_f)(x); } +private: + _fun_type const M_f; +}; + +template <class Tp, class Arg> +inline mem_fun1_t<Tp,Arg> mem_fun(void (Tp::*f)(Arg)) +{ + return mem_fun1_t<Tp,Arg>(f); +} + +/** output iterator that appends OUStrings into an OUStringBuffer. + */ +class OUStringBufferAppender +{ +public: + typedef OUStringBufferAppender Self; + typedef ::std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void reference; + typedef void pointer; + typedef size_t difference_type; + + OUStringBufferAppender(OUStringBuffer & i_rBuffer) + : m_rBuffer(&i_rBuffer) { } + Self & operator=(std::u16string_view i_rStr) + { + m_rBuffer->append( i_rStr ); + return *this; + } + Self & operator*() { return *this; } // so operator= works + Self & operator++() { return *this; } + +private: + OUStringBuffer * m_rBuffer; +}; + +/** algorithm similar to std::copy, but inserts a separator between elements. + */ +template< typename ForwardIter, typename OutputIter, typename T > +OutputIter intersperse( + ForwardIter start, ForwardIter end, OutputIter out, T const & separator) +{ + if (start != end) { + *out = *start; + ++start; + ++out; + } + + while (start != end) { + *out = separator; + ++out; + *out = *start; + ++start; + ++out; + } + + return out; +} + +} + +#endif // INCLUDED_COMPHELPER_STL_TYPES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/storagehelper.hxx b/include/comphelper/storagehelper.hxx new file mode 100644 index 000000000..c6c47c1a5 --- /dev/null +++ b/include/comphelper/storagehelper.hxx @@ -0,0 +1,206 @@ +/* -*- 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_COMPHELPER_STORAGEHELPER_HXX +#define INCLUDED_COMPHELPER_STORAGEHELPER_HXX + +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/embed/ElementModes.hpp> +#include <comphelper/comphelperdllapi.h> +#include <memory> +#include <string_view> + +inline constexpr OUStringLiteral PACKAGE_STORAGE_FORMAT_STRING = u"PackageFormat"; +inline constexpr OUStringLiteral ZIP_STORAGE_FORMAT_STRING = u"ZipFormat"; +inline constexpr OUStringLiteral OFOPXML_STORAGE_FORMAT_STRING = u"OFOPXMLFormat"; + +inline constexpr OUStringLiteral PACKAGE_ENCRYPTIONDATA_SHA256UTF8 = u"PackageSHA256UTF8EncryptionKey"; +inline constexpr OUStringLiteral PACKAGE_ENCRYPTIONDATA_SHA1UTF8 = u"PackageSHA1UTF8EncryptionKey"; +inline constexpr OUStringLiteral PACKAGE_ENCRYPTIONDATA_SHA1MS1252 = u"PackageSHA1MS1252EncryptionKey"; +inline constexpr OUStringLiteral PACKAGE_ENCRYPTIONDATA_SHA1CORRECT = u"PackageSHA1CorrectEncryptionKey"; + +namespace com::sun::star { + namespace beans { struct NamedValue; } + namespace embed { class XStorage; } + namespace io { + class XInputStream; + class XOutputStream; + class XStream; + } + namespace lang { class XSingleServiceFactory; } + namespace uno { class XComponentContext; } +} + +namespace comphelper { + +// Unfortunately - the impl.s of XStorage like to invalidate all +// their sub streams and storages when you release references, so +// it is necessary to keep references to all storages down the +// path - this is 'beautiful' (TM). So we need this ugly hack: +class COMPHELPER_DLLPUBLIC LifecycleProxy +{ +private: + class Impl; +public: + std::unique_ptr<Impl> m_xBadness; + LifecycleProxy(); + ~LifecycleProxy(); + // commit the storages: necessary for writes to streams to take effect! + void commitStorages(); +}; + +class COMPHELPER_DLLPUBLIC OStorageHelper +{ +public: + /// @throws css::uno::Exception + static css::uno::Reference< css::lang::XSingleServiceFactory > + GetStorageFactory( + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >() ); + + /// @throws css::uno::Exception + static css::uno::Reference< css::lang::XSingleServiceFactory > + GetFileSystemStorageFactory( + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >() ); + + /// @throws css::uno::Exception + static css::uno::Reference< css::embed::XStorage > + GetTemporaryStorage( + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >() ); + + /// this one will only return Storage + /// + /// @throws css::uno::Exception + static css::uno::Reference< css::embed::XStorage > + GetStorageFromURL( + const OUString& aURL, + sal_Int32 nStorageMode, + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >() ); + + /// this one will return either Storage or FileSystemStorage + /// + /// @throws css::uno::Exception + static css::uno::Reference< css::embed::XStorage > + GetStorageFromURL2( + const OUString& aURL, + sal_Int32 nStorageMode, + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >() ); + + /// @throws css::uno::Exception + static css::uno::Reference< css::embed::XStorage > + GetStorageFromInputStream( + const css::uno::Reference < css::io::XInputStream >& xStream, + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >() ); + + /// @throws css::uno::Exception + static css::uno::Reference< css::embed::XStorage > + GetStorageFromStream( + const css::uno::Reference < css::io::XStream >& xStream, + sal_Int32 nStorageMode = css::embed::ElementModes::READWRITE, + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >() ); + + /// @throws css::uno::Exception + static void CopyInputToOutput( + const css::uno::Reference< css::io::XInputStream >& xInput, + const css::uno::Reference< css::io::XOutputStream >& xOutput ); + + /// @throws css::uno::Exception + static css::uno::Reference< css::io::XInputStream > + GetInputStreamFromURL( + const OUString& aURL, + const css::uno::Reference< css::uno::XComponentContext >& context ); + + /// @throws css::uno::Exception + static void SetCommonStorageEncryptionData( + const css::uno::Reference< css::embed::XStorage >& xStorage, + const css::uno::Sequence< css::beans::NamedValue >& aEncryptionData ); + + // the following method supports only storages of OOo formats + /// @throws css::uno::Exception + static sal_Int32 GetXStorageFormat( + const css::uno::Reference< css::embed::XStorage >& xStorage ); + + /// @throws css::uno::Exception + static css::uno::Reference< css::embed::XStorage > + GetStorageOfFormatFromURL( + const OUString& aFormat, + const OUString& aURL, + sal_Int32 nStorageMode, + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >() ); + + /// @throws css::uno::Exception + static css::uno::Reference< css::embed::XStorage > + GetStorageOfFormatFromInputStream( + const OUString& aFormat, + const css::uno::Reference < css::io::XInputStream >& xStream, + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >(), + bool bRepairStorage = false ); + + /// @throws css::uno::Exception + static css::uno::Reference< css::embed::XStorage > + GetStorageOfFormatFromStream( + const OUString& aFormat, + const css::uno::Reference < css::io::XStream >& xStream, + sal_Int32 nStorageMode = css::embed::ElementModes::READWRITE, + const css::uno::Reference< css::uno::XComponentContext >& rxContext + = css::uno::Reference< css::uno::XComponentContext >(), + bool bRepairStorage = false ); + + static css::uno::Sequence< css::beans::NamedValue > + CreatePackageEncryptionData( + std::u16string_view aPassword ); + + static css::uno::Sequence< css::beans::NamedValue > + CreateGpgPackageEncryptionData(); + + static bool IsValidZipEntryFileName( std::u16string_view aName, bool bSlashAllowed ); + static bool IsValidZipEntryFileName( const sal_Unicode *pChar, sal_Int32 nLength, bool bSlashAllowed ); + + static bool PathHasSegment( std::u16string_view aPath, std::u16string_view aSegment ); + + // Methods to allow easy use of hierarchical names inside storages + + static css::uno::Reference< css::embed::XStorage > GetStorageAtPath( + const css::uno::Reference< css::embed::XStorage > &xStorage, + std::u16string_view aPath, sal_uInt32 nOpenMode, LifecycleProxy const &rNastiness ); + static css::uno::Reference< css::io::XStream > GetStreamAtPath( + const css::uno::Reference< css::embed::XStorage > &xStorage, + std::u16string_view aPath, sal_uInt32 nOpenMode, LifecycleProxy const &rNastiness ); + static css::uno::Reference< css::io::XStream > GetStreamAtPackageURL( + const css::uno::Reference< css::embed::XStorage > &xStorage, + const OUString& rURL, sal_uInt32 const nOpenMode, + LifecycleProxy const & rNastiness ); + + static OUString + GetODFVersionFromStorage(const css::uno::Reference<css::embed::XStorage>& xStorage); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/streamsection.hxx b/include/comphelper/streamsection.hxx new file mode 100644 index 000000000..fa1fe8ac9 --- /dev/null +++ b/include/comphelper/streamsection.hxx @@ -0,0 +1,79 @@ +/* -*- 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_COMPHELPER_STREAMSECTION_HXX +#define INCLUDED_COMPHELPER_STREAMSECTION_HXX + +#include <config_options.h> +#include <com/sun/star/uno/Reference.h> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::io +{ +class XDataInputStream; +} +namespace com::sun::star::io +{ +class XDataOutputStream; +} +namespace com::sun::star::io +{ +class XMarkableStream; +} + +namespace comphelper +{ +/** implements handling for compatibly reading/writing data from/into an input/output stream. + data written in a block secured by this class should be readable by older versions which + use the same mechanism. +*/ + +class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OStreamSection +{ + css::uno::Reference<css::io::XMarkableStream> m_xMarkStream; + css::uno::Reference<css::io::XDataInputStream> m_xInStream; + css::uno::Reference<css::io::XDataOutputStream> m_xOutStream; + + sal_Int32 m_nBlockStart; + sal_Int32 m_nBlockLen; + +public: + /** starts reading of a "skippable" section of data within the given input stream<BR> + @param _rxInput the stream to read from. Must support the + css::io::XMarkableStream interface + */ + OStreamSection(const css::uno::Reference<css::io::XDataInputStream>& _rxInput); + + /** starts writing of a "skippable" section of data into the given output stream + @param _rxOutput the stream the stream to write to. Must support the + css::io::XMarkableStream interface + */ + OStreamSection(const css::uno::Reference<css::io::XDataOutputStream>& _rxOutput); + + /** dtor. <BR>If constructed for writing, the section "opened" by this object will be "closed".<BR> + If constructed for reading, any remaining bytes 'til the end of the section will be skipped. + */ + ~OStreamSection(); +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_STREAMSECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/string.hxx b/include/comphelper/string.hxx new file mode 100644 index 000000000..a722e2cc4 --- /dev/null +++ b/include/comphelper/string.hxx @@ -0,0 +1,386 @@ +/* -*- 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 . + */ +#pragma once + +#include <sal/config.h> + +#include <algorithm> +#include <vector> +#include <comphelper/comphelperdllapi.h> +#include <sal/types.h> +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/uno/Reference.hxx> + +#include <com/sun/star/lang/Locale.hpp> + +namespace com::sun::star::i18n { class XBreakIterator; } +namespace com::sun::star::i18n { class XCollator; } +namespace com::sun::star::uno { class XComponentContext; } + +// OUString helper functions that are not widespread or mature enough to +// go into the stable URE API: +namespace comphelper::string { + +/** Removes all occurrences of a character from within the source string + + @param rIn The input OUStringBuffer + @param c The character to be removed + + @return The resulting OUStringBuffer + */ +inline OUStringBuffer& remove(OUStringBuffer &rIn, + sal_Unicode c) +{ + sal_Int32 index = 0; + while (true) + { + if (index >= rIn.getLength()) + break; + index = rIn.indexOf(c, index); + if (index == -1) + break; + rIn.remove(index, 1); + } + return rIn; +} + +/** Strips occurrences of a character from the start of the source string + + @param rIn The input OString + @param c The character to be stripped from the start + + @return The resulting OString + */ +COMPHELPER_DLLPUBLIC OString stripStart(const OString& rIn, + char c); +COMPHELPER_DLLPUBLIC std::string_view stripStart(std::string_view rIn, + char c); + +/** Strips occurrences of a character from the start of the source string + + @param rIn The input OUString + @param c The character to be stripped from the start + + @return The resulting OUString + */ +COMPHELPER_DLLPUBLIC OUString stripStart(const OUString& rIn, + sal_Unicode c); +COMPHELPER_DLLPUBLIC std::u16string_view stripStart(std::u16string_view rIn, + sal_Unicode c); + +/** Strips occurrences of a character from the end of the source string + + @param rIn The input OString + @param c The character to be stripped from the end + + @return The resulting OString + */ +COMPHELPER_DLLPUBLIC OString stripEnd(const OString& rIn, + char c); +COMPHELPER_DLLPUBLIC std::string_view stripEnd(std::string_view rIn, + char c); + +/** Strips occurrences of a character from the end of the source string + + @param rIn The input OUString + @param c The character to be stripped from the end + + @return The resulting OUString + */ +COMPHELPER_DLLPUBLIC OUString stripEnd(const OUString& rIn, + sal_Unicode c); +COMPHELPER_DLLPUBLIC std::u16string_view stripEnd(std::u16string_view rIn, + sal_Unicode c); + +/** Strips occurrences of a character from the start and end of the source string + + @param rIn The input OString + @param c The character to be stripped from the start and end + + @return The resulting OString + */ +COMPHELPER_DLLPUBLIC OString strip(const OString& rIn, + char c); +COMPHELPER_DLLPUBLIC std::string_view strip(std::string_view rIn, + char c); + +/** Strips occurrences of a character from the start and end of the source string + + @param rIn The input OUString + @param c The character to be stripped from the start and end + + @return The resulting OUString + */ +COMPHELPER_DLLPUBLIC OUString strip(const OUString& rIn, + sal_Unicode c); +COMPHELPER_DLLPUBLIC std::u16string_view strip(std::u16string_view rIn, + sal_Unicode c); + +/** Returns number of tokens in an OUString + + @param rIn the input OString + @param cTok the character which separate the tokens. + @return the number of tokens +*/ +COMPHELPER_DLLPUBLIC sal_Int32 getTokenCount(std::string_view rIn, char cTok); + +/** Returns number of tokens in an OUString + + @param rIn the input OUString + @param cTok the character which separate the tokens. + @return the number of tokens +*/ +COMPHELPER_DLLPUBLIC sal_Int32 getTokenCount(std::u16string_view rIn, sal_Unicode cTok); + +/** Reverse an OUString's UTF-16 code units. + + @param rIn the input OUString + @return the reversed input +*/ +COMPHELPER_DLLPUBLIC OUString reverseString(std::u16string_view rStr); + +/** Reverse an OString + + @param rIn the input OString + @return the reversed input +*/ +COMPHELPER_DLLPUBLIC OString reverseString(std::string_view rStr); + +/** Reverse an OUString's Unicode code points. +*/ +COMPHELPER_DLLPUBLIC OUString reverseCodePoints(OUString const & str); + +namespace detail +{ + template<typename B> B& truncateToLength(B& rBuffer, sal_Int32 nLen) + { + if (nLen < rBuffer.getLength()) + rBuffer.setLength(nLen); + return rBuffer; + } +} + +/** Truncate a buffer to a given length. + + If the StringBuffer has more characters than nLength it will be truncated + on the right to nLength characters. + + Has no effect if the StringBuffer is <= nLength + + @param rBuf StringBuffer to operate on + @param nLength Length to truncate the buffer to + + @return rBuf; + */ +inline OUStringBuffer& truncateToLength( + OUStringBuffer& rBuffer, sal_Int32 nLength) +{ + return detail::truncateToLength(rBuffer, nLength); +} + +namespace detail +{ + template<typename B, typename U> B& padToLength(B& rBuffer, sal_Int32 nLen, U cFill) + { + const sal_Int32 nPadLen = nLen - rBuffer.getLength(); + if (nPadLen > 0) + std::fill_n(rBuffer.appendUninitialized(nPadLen), nPadLen, cFill); + return rBuffer; + } +} + +/** Pad a buffer to a given length using a given char. + + If the StringBuffer has less characters than nLength it will be expanded on + the right to nLength characters, with the expansion filled using cFill. + + Has no effect if the StringBuffer is >= nLength + + @param rBuf StringBuffer to operate on + @param nLength Length to pad the buffer to + @param cFill character to fill expansion with + + @return rBuf; + */ +inline OStringBuffer& padToLength( + OStringBuffer& rBuffer, sal_Int32 nLength, + char cFill = '\0') +{ + return detail::padToLength(rBuffer, nLength, cFill); +} + +inline OUStringBuffer& padToLength( + OUStringBuffer& rBuffer, sal_Int32 nLength, + sal_Unicode cFill = '\0') +{ + return detail::padToLength(rBuffer, nLength, cFill); +} + +/** Similar to OUString::replaceAt, but for an OUStringBuffer. + + Replace n = count characters + from position index in this string with newStr. + */ +COMPHELPER_DLLPUBLIC void replaceAt(OUStringBuffer& rIn, sal_Int32 index, sal_Int32 count, std::u16string_view newStr ); + +/** Replace a token in a string + @param rIn OUString in which the token is to be replaced + @param nToken which nToken to replace + @param cTok token delimiter + @param rNewToken replacement token + + @return original string with token nToken replaced by rNewToken + */ +COMPHELPER_DLLPUBLIC OUString setToken(const OUString& rIn, sal_Int32 nToken, sal_Unicode cTok, + std::u16string_view rNewToken); + +/** Find any of a list of code units in the string. + @param rIn OUString to search + @param pChars 0-terminated array of sal_Unicode code units to search for + @param nPos start position + + @return position of first occurrence of any of the elements of pChars + or -1 if none of the code units occur in the string + */ +COMPHELPER_DLLPUBLIC sal_Int32 indexOfAny(std::u16string_view rIn, + sal_Unicode const*const pChars, sal_Int32 const nPos); + +/** Remove any of a list of code units in the string. + @param rIn OUString to search + @param pChars 0-terminated array of sal_Unicode code units to search for + + @return OUString that has all of the pChars code units removed + */ +COMPHELPER_DLLPUBLIC OUString removeAny(std::u16string_view rIn, + sal_Unicode const*const pChars); + +/** Convert a sequence of strings to a single comma separated string. + + Note that no escaping of commas or anything fancy is done. + + @param i_rSeq A list of strings to be concatenated. + + @return A single string containing the concatenation of the given + list, interspersed with the string ", ". + */ +COMPHELPER_DLLPUBLIC OUString convertCommaSeparated( + css::uno::Sequence< OUString > const & i_rSeq); + +/// Return a string which is the concatenation of the strings in the sequence. +COMPHELPER_DLLPUBLIC OString join(std::string_view rSeparator, const std::vector<OString>& rSequence); + +/** Convert a decimal string to a number. + + The string must be base-10, no sign but can contain any + codepoint listed in the "Number, Decimal Digit" Unicode + category. + + No verification is made about the validity of the string, + passing string not containing decimal digit code points + gives unspecified results + + If your string is guaranteed to contain only ASCII digit + use OUString::toInt32 instead. + + @param str The string to convert containing only decimal + digit codepoints. + + @return The value of the string as an int32. + */ +COMPHELPER_DLLPUBLIC sal_uInt32 decimalStringToNumber( + OUString const & str ); + +COMPHELPER_DLLPUBLIC std::vector<OUString> + split(std::u16string_view rString, const sal_Unicode cSeparator); + +/** Convert a single comma separated string to a sequence of strings. + + Note that no escaping of commas or anything fancy is done. + + @param i_rString A string containing comma-separated words. + + @return A sequence of strings resulting from splitting the given + string at ',' tokens and stripping whitespace. + */ +COMPHELPER_DLLPUBLIC css::uno::Sequence< OUString > + convertCommaSeparated( std::u16string_view i_rString ); + +/** + Compares two strings using natural order. + + For non digit characters, the comparison use the same algorithm as + rtl_str_compare. When a number is encountered during the comparison, + natural order is used. Thus, Heading 10 will be considered as greater + than Heading 2. Numerical comparison is done using decimal representation. + + Beware that "MyString 001" and "MyString 1" will be considered as equal + since leading 0 are meaningless. + + @param str the object to be compared. + @return 0 - if both strings are equal + < 0 - if this string is less than the string argument + > 0 - if this string is greater than the string argument +*/ +COMPHELPER_DLLPUBLIC sal_Int32 compareNatural( const OUString &rLHS, const OUString &rRHS, + const css::uno::Reference< css::i18n::XCollator > &rCollator, + const css::uno::Reference< css::i18n::XBreakIterator > &rBI, + const css::lang::Locale &rLocale ); + +class COMPHELPER_DLLPUBLIC NaturalStringSorter +{ +private: + css::lang::Locale const m_aLocale; + css::uno::Reference< css::i18n::XCollator > m_xCollator; + css::uno::Reference< css::i18n::XBreakIterator > m_xBI; +public: + NaturalStringSorter( + const css::uno::Reference< css::uno::XComponentContext > &rContext, + css::lang::Locale aLocale); + sal_Int32 compare(const OUString &rLHS, const OUString &rRHS) const + { + return compareNatural(rLHS, rRHS, m_xCollator, m_xBI, m_aLocale); + } + const css::lang::Locale& getLocale() const { return m_aLocale; } +}; + +/** Determine if an OString contains solely ASCII numeric digits + + @param rString An OString + + @return false if string contains any characters outside + the ASCII '0'-'9' range + true otherwise, including for empty string + */ +COMPHELPER_DLLPUBLIC bool isdigitAsciiString(std::string_view rString); + +/** Determine if an OUString contains solely ASCII numeric digits + + @param rString An OUString + + @return false if string contains any characters outside + the ASCII '0'-'9' range + true otherwise, including for empty string + */ +COMPHELPER_DLLPUBLIC bool isdigitAsciiString(std::u16string_view rString); + +} // namespace comphelper::string + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/synchronousdispatch.hxx b/include/comphelper/synchronousdispatch.hxx new file mode 100644 index 000000000..8503b2a43 --- /dev/null +++ b/include/comphelper/synchronousdispatch.hxx @@ -0,0 +1,64 @@ +/* -*- 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_COMPHELPER_SYNCHRONOUSDISPATCH_HXX +#define INCLUDED_COMPHELPER_SYNCHRONOUSDISPATCH_HXX + +#include <comphelper/comphelperdllapi.h> + +#include <com/sun/star/uno/Reference.h> +#include <rtl/ustring.hxx> + +namespace com::sun::star { + namespace uno { + class XInterface; } + namespace lang { + class XComponent; } +} + +namespace com::sun::star::beans { struct PropertyValue; } +namespace com::sun::star::uno { template <class E> class Sequence; } + + +namespace comphelper +{ + + + //= SynchronousDispatch + + /** a helper class for working with the dispatch interface replacing + loadComponentFromURL + */ + class SynchronousDispatch + { + public: + static COMPHELPER_DLLPUBLIC css::uno::Reference< css::lang::XComponent > dispatch( + const css::uno::Reference< css::uno::XInterface > &xStartPoint, + const OUString &sURL, + const OUString &sTarget, + const css::uno::Sequence< css::beans::PropertyValue > &lArguments ); + }; + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_SYNCHRONOUSDISPATCH_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/syntaxhighlight.hxx b/include/comphelper/syntaxhighlight.hxx new file mode 100644 index 000000000..c8bc100d3 --- /dev/null +++ b/include/comphelper/syntaxhighlight.hxx @@ -0,0 +1,84 @@ +/* -*- 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_COMPHELPER_SYNTAXHIGHLIGHT_HXX +#define INCLUDED_COMPHELPER_SYNTAXHIGHLIGHT_HXX + +#include <rtl/ustring.hxx> + +#include <comphelper/comphelperdllapi.h> + +#include <vector> +#include <memory> + +enum class TokenType +{ + Unknown, + Identifier, + Whitespace, + Number, + String, + EOL, + Comment, + Error, + Operator, + Keywords, + Parameter, + LAST = Parameter +}; + +struct HighlightPortion { + sal_Int32 nBegin; + sal_Int32 nEnd; + TokenType tokenType; + + HighlightPortion( + sal_Int32 theBegin, sal_Int32 theEnd, TokenType theTokenType): + nBegin(theBegin), nEnd(theEnd), tokenType(theTokenType) + {} +}; + +// Language mode of the Highlighter (possibly to be refined later with keyword +// lists, C comment flags) +enum class HighlighterLanguage +{ + Basic, + SQL +}; + +class COMPHELPER_DLLPUBLIC SyntaxHighlighter +{ + class Tokenizer; + + std::unique_ptr<Tokenizer> m_tokenizer; + + SyntaxHighlighter(const SyntaxHighlighter&) = delete; + SyntaxHighlighter& operator=(const SyntaxHighlighter&) = delete; +public: + SyntaxHighlighter(HighlighterLanguage language); + ~SyntaxHighlighter(); + + void getHighlightPortions( std::u16string_view rLine, + std::vector<HighlightPortion>& pPortions ) const; + + HighlighterLanguage GetLanguage() const; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/threadpool.hxx b/include/comphelper/threadpool.hxx new file mode 100644 index 000000000..84f9dc928 --- /dev/null +++ b/include/comphelper/threadpool.hxx @@ -0,0 +1,114 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_THREADPOOL_HXX +#define INCLUDED_COMPHELPER_THREADPOOL_HXX + +#include <sal/config.h> +#include <rtl/ref.hxx> +#include <comphelper/comphelperdllapi.h> +#include <mutex> +#include <condition_variable> +#include <cstddef> +#include <vector> +#include <memory> + +namespace comphelper +{ +class ThreadTaskTag; + +class COMPHELPER_DLLPUBLIC ThreadTask +{ +friend class ThreadPool; +friend struct std::default_delete<ThreadTask>; + std::shared_ptr<ThreadTaskTag> mpTag; + + /// execute this task + void exec(); +protected: + /// override to get your task performed by the pool + virtual void doWork() = 0; + /// once pushed ThreadTasks are destroyed by the pool + virtual ~ThreadTask() {} +public: + ThreadTask(std::shared_ptr<ThreadTaskTag> pTag); +}; + +/// A very basic thread-safe thread pool implementation +class COMPHELPER_DLLPUBLIC ThreadPool final +{ +public: + /// returns a pointer to a shared pool with optimal thread + /// count for the CPU + static ThreadPool& getSharedOptimalPool(); + + static std::shared_ptr<ThreadTaskTag> createThreadTaskTag(); + + static bool isTaskTagDone(const std::shared_ptr<ThreadTaskTag>&); + + /// returns a configurable max-concurrency + /// limit to avoid spawning an unnecessarily + /// large number of threads on high-core boxes. + /// MAX_CONCURRENCY env. var. controls the cap. + static std::size_t getPreferredConcurrency(); + + ThreadPool( std::size_t nWorkers ); + ~ThreadPool(); + + /// push a new task onto the work queue + void pushTask( std::unique_ptr<ThreadTask> pTask); + + /** Wait until all queued tasks associated with the tag are completed + @param bJoin - if set call joinThreadsIfIdle() at the end + */ + void waitUntilDone(const std::shared_ptr<ThreadTaskTag>&, bool bJoin = true); + + /// join all threads if there are no tasks presently. + void joinThreadsIfIdle(); + + /// return true if there are no queued or worked-on tasks + bool isIdle() const { return maTasks.empty() && mnBusyWorkers == 0; }; + + /// return the number of live worker threads + sal_Int32 getWorkerCount() const { return mnMaxWorkers; } + + /// wait until all work is completed, then join all threads + void shutdown(); + +private: + ThreadPool(const ThreadPool&) = delete; + ThreadPool& operator=(const ThreadPool&) = delete; + + class ThreadWorker; + friend class ThreadWorker; + + /** Pop a work task + @param bWait - if set wait until task present or termination + @return a new task to perform, or NULL if list empty or terminated + */ + std::unique_ptr<ThreadTask> popWorkLocked( std::unique_lock< std::mutex > & rGuard, bool bWait ); + void shutdownLocked(std::unique_lock<std::mutex>&); + void incBusyWorker(); + void decBusyWorker(); + + /// signalled when all in-progress tasks are complete + std::mutex maMutex; + std::condition_variable maTasksChanged; + bool mbTerminate; + std::size_t const mnMaxWorkers; + std::size_t mnBusyWorkers; + std::vector< std::unique_ptr<ThreadTask> > maTasks; + std::vector< rtl::Reference< ThreadWorker > > maWorkers; +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_THREADPOOL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/traceevent.hxx b/include/comphelper/traceevent.hxx new file mode 100644 index 000000000..a0fe9cae1 --- /dev/null +++ b/include/comphelper/traceevent.hxx @@ -0,0 +1,222 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. +*/ + +#ifndef INCLUDED_COMPHELPER_TRACEEVENT_HXX +#define INCLUDED_COMPHELPER_TRACEEVENT_HXX + +#include <sal/config.h> + +#include <atomic> +#include <map> +#include <memory> +#include <utility> +#include <vector> + +#include <osl/process.h> +#include <osl/thread.h> +#include <osl/time.h> +#include <com/sun/star/uno/Sequence.h> +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> + +// implementation of XToolkitExperimental profiling API + +namespace comphelper +{ +class COMPHELPER_DLLPUBLIC TraceEvent +{ +private: + static int getPid() + { + oslProcessInfo aProcessInfo; + aProcessInfo.Size = sizeof(oslProcessInfo); + if (osl_getProcessInfo(nullptr, osl_Process_IDENTIFIER, &aProcessInfo) + == osl_Process_E_None) + return aProcessInfo.Ident; + return -1; + } + + static std::size_t s_nBufferSize; + static void (*s_pBufferFullCallback)(); + +protected: + static std::atomic<bool> s_bRecording; // true during recording + + static void addRecording(const OUString& sObject); + + static long long getNow() + { + TimeValue systemTime; + osl_getSystemTime(&systemTime); + return static_cast<long long>(systemTime.Seconds) * 1000000 + systemTime.Nanosec / 1000; + } + + static OUString createArgsString(const std::map<OUString, OUString>& args) + { + if (args.size() == 0) + return ""; + + OUStringBuffer sResult; + sResult.append(",\"args\":{"); + bool first = true; + for (auto& i : args) + { + if (!first) + sResult.append(','); + sResult.append('"'); + sResult.append(i.first); + sResult.append("\":\""); + sResult.append(i.second); + sResult.append('"'); + first = false; + } + sResult.append('}'); + + return sResult.makeStringAndClear(); + } + + const int m_nPid; + const OUString m_sArgs; + + TraceEvent(OUString sArgs) + : m_nPid(s_bRecording ? getPid() : 1) + , m_sArgs(std::move(sArgs)) + { + } + + TraceEvent(const std::map<OUString, OUString>& aArgs) + : TraceEvent(createArgsString(aArgs)) + { + } + +public: + static void addInstantEvent(const char* sName, const std::map<OUString, OUString>& args + = std::map<OUString, OUString>()); + + static void startRecording(); + static void stopRecording(); + static void setBufferSizeAndCallback(std::size_t bufferSize, void (*bufferFullCallback)()); + + static std::vector<OUString> getEventVectorAndClear(); + + static css::uno::Sequence<OUString> getRecordingAndClear(); +}; + +class COMPHELPER_DLLPUBLIC NamedEvent : public TraceEvent +{ +protected: + const char* m_sName; + + NamedEvent(const char* sName, const OUString& sArgs) + : TraceEvent(sArgs) + , m_sName(sName ? sName : "(null)") + { + } + + NamedEvent(const char* sName, const std::map<OUString, OUString>& aArgs) + : TraceEvent(aArgs) + , m_sName(sName ? sName : "(null)") + { + } +}; + +// An AsyncEvent generates an 'S' (start) event when constructed and a 'F' (finish) event when it +// is destructed. + +// The Trace Event specification claims that these event types are deprecated and replaces by +// nestable 'b' (begin) and 'e' (end) events, but Chrome does not seem to support those. + +// To generate a pair of 'S' and 'F' events, create an AsyncEvent object using the AsyncEvent(const +// char* sName) constructor when you want the 'S' event to be generated, and destroy it when you +// want the corresponding 'F' event to be generated. + +class COMPHELPER_DLLPUBLIC AsyncEvent : public NamedEvent, + public std::enable_shared_from_this<AsyncEvent> +{ + static int s_nIdCounter; + int m_nId; + bool m_bBeginRecorded; + + AsyncEvent(const char* sName, int nId, const std::map<OUString, OUString>& args) + : NamedEvent(sName, args) + , m_nId(nId) + , m_bBeginRecorded(false) + { + if (!s_bRecording) + return; + + long long nNow = getNow(); + + // Generate a "Start" (type S) event + TraceEvent::addRecording("{" + "\"name\":\"" + + OUString(m_sName, strlen(m_sName), RTL_TEXTENCODING_UTF8) + + "\"," + "\"ph\":\"S\"" + "," + "\"id\":" + + OUString::number(m_nId) + m_sArgs + + "," + "\"ts\":" + + OUString::number(nNow) + + "," + "\"pid\":" + + OUString::number(m_nPid) + + "," + "\"tid\":" + + OUString::number(osl_getThreadIdentifier(nullptr)) + "},"); + m_bBeginRecorded = true; + } + + void generateEnd() + { + if (!m_bBeginRecorded) + return; + + m_bBeginRecorded = false; + + long long nNow = getNow(); + // Generate a "Finish" (type F) event + TraceEvent::addRecording("{" + "\"name\":\"" + + OUString(m_sName, strlen(m_sName), RTL_TEXTENCODING_UTF8) + + "\"," + "\"ph\":\"F\"" + "," + "\"id\":" + + OUString::number(m_nId) + m_sArgs + + "," + "\"ts\":" + + OUString::number(nNow) + + "," + "\"pid\":" + + OUString::number(m_nPid) + + "," + "\"tid\":" + + OUString::number(osl_getThreadIdentifier(nullptr)) + "},"); + } + +public: + AsyncEvent(const char* sName, + const std::map<OUString, OUString>& args = std::map<OUString, OUString>()) + : AsyncEvent(sName, s_nIdCounter++, args) + { + } + + ~AsyncEvent() { generateEnd(); } + + void finish() { generateEnd(); } +}; + +} // namespace comphelper + +#endif // INCLUDED_COMPHELPER_TRACEEVENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/types.hxx b/include/comphelper/types.hxx new file mode 100644 index 000000000..203bbbe02 --- /dev/null +++ b/include/comphelper/types.hxx @@ -0,0 +1,88 @@ +/* -*- 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_COMPHELPER_TYPES_HXX +#define INCLUDED_COMPHELPER_TYPES_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <comphelper/comphelperdllapi.h> + +namespace com::sun::star::awt { + struct FontDescriptor; +} + +namespace com::sun::star::uno { class Any; } +namespace com::sun::star::uno { class XInterface; } + + +namespace comphelper +{ + /// returns sal_True if objects of the types given are "compatible" + COMPHELPER_DLLPUBLIC bool isAssignableFrom(const css::uno::Type& _rAssignable, const css::uno::Type& _rFrom); + + /** ask the given object for an XComponent interface and dispose on it + */ + template <class TYPE> + void disposeComponent(css::uno::Reference<TYPE>& _rxComp) + { + css::uno::Reference<css::lang::XComponent> xComp(_rxComp, css::uno::UNO_QUERY); + if (xComp.is()) + { + xComp->dispose(); + _rxComp = nullptr; + } + } + + + /** get a css::awt::FontDescriptor that is fully initialized with + the XXX_DONTKNOW enum values (which isn't the case if you instantiate it + via the default constructor) + */ + COMPHELPER_DLLPUBLIC css::awt::FontDescriptor getDefaultFont(); + + /** examine a sequence for the com.sun.star.uno::Type of its elements. + */ + COMPHELPER_DLLPUBLIC css::uno::Type getSequenceElementType(const css::uno::Type& _rSequenceType); + + +//= replacement of the former UsrAny.getXXX methods + + // may be used if you need the return value just as temporary, else it's may be too inefficient... + + // no, we don't use templates here. This would lead to a lot of implicit uses of the conversion methods, + // which would be difficult to trace... + + COMPHELPER_DLLPUBLIC sal_Int64 getINT64(const css::uno::Any& _rAny); + COMPHELPER_DLLPUBLIC sal_Int32 getINT32(const css::uno::Any& _rAny); + COMPHELPER_DLLPUBLIC sal_Int16 getINT16(const css::uno::Any& _rAny); + COMPHELPER_DLLPUBLIC double getDouble(const css::uno::Any& _rAny); + COMPHELPER_DLLPUBLIC float getFloat(const css::uno::Any& _rAny); + COMPHELPER_DLLPUBLIC OUString getString(const css::uno::Any& _rAny); + COMPHELPER_DLLPUBLIC bool getBOOL(const css::uno::Any& _rAny); + + /// @throws css::lang::IllegalArgumentException + COMPHELPER_DLLPUBLIC sal_Int32 getEnumAsINT32(const css::uno::Any& _rAny); + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_TYPES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/unique_disposing_ptr.hxx b/include/comphelper/unique_disposing_ptr.hxx new file mode 100644 index 000000000..5994799fc --- /dev/null +++ b/include/comphelper/unique_disposing_ptr.hxx @@ -0,0 +1,187 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_UNIQUE_DISPOSING_PTR_HXX +#define INCLUDED_COMPHELPER_UNIQUE_DISPOSING_PTR_HXX + +#include <memory> +#include <cppuhelper/implbase.hxx> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <o3tl/deleter.hxx> +#include <utility> +#include <vcl/svapp.hxx> + +namespace comphelper +{ +//Similar to std::unique_ptr, except additionally releases the ptr on XComponent::disposing and/or XTerminateListener::notifyTermination if supported +template<class T> class unique_disposing_ptr +{ +private: + std::unique_ptr<T, o3tl::default_delete<T>> m_xItem; + css::uno::Reference< css::frame::XTerminateListener> m_xTerminateListener; + + unique_disposing_ptr(const unique_disposing_ptr&) = delete; + unique_disposing_ptr& operator=(const unique_disposing_ptr&) = delete; +public: + unique_disposing_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr, bool bComponent = false) + : m_xItem(p) + { + m_xTerminateListener = new TerminateListener(rComponent, *this, bComponent); + } + + virtual void reset(T * p = nullptr) + { + m_xItem.reset(p); + } + + T & operator*() const + { + return *m_xItem; + } + + T * get() const + { + return m_xItem.get(); + } + + T * operator->() const + { + return m_xItem.get(); + } + + operator bool () const + { + return static_cast< bool >(m_xItem); + } + + virtual ~unique_disposing_ptr() COVERITY_NOEXCEPT_FALSE + { + reset(); + } +private: + class TerminateListener final : public ::cppu::WeakImplHelper< css::frame::XTerminateListener, + css::lang::XServiceInfo> + { + private: + css::uno::Reference< css::lang::XComponent > m_xComponent; + unique_disposing_ptr<T>& m_rItem; + bool const mbComponentDLL; + public: + TerminateListener(css::uno::Reference< css::lang::XComponent > xComponent, + unique_disposing_ptr<T>& rItem, bool bComponentDLL) : + m_xComponent(std::move(xComponent)), + m_rItem(rItem), + mbComponentDLL(bComponentDLL) + { + if (m_xComponent.is()) + { + css::uno::Reference< css::frame::XDesktop> xDesktop(m_xComponent, css::uno::UNO_QUERY); + if (xDesktop.is()) + xDesktop->addTerminateListener(this); + else + m_xComponent->addEventListener(this); + } + } + + virtual ~TerminateListener() override + { + if ( m_xComponent.is() ) + { + css::uno::Reference< css::frame::XDesktop> xDesktop(m_xComponent, css::uno::UNO_QUERY); + if (xDesktop.is()) + xDesktop->removeTerminateListener(this); + else + m_xComponent->removeEventListener(this); + } + } + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& rEvt ) override + { + bool shutDown = (rEvt.Source == m_xComponent); + + if (shutDown && m_xComponent.is()) + { + css::uno::Reference< css::frame::XDesktop> xDesktop(m_xComponent, css::uno::UNO_QUERY); + if (xDesktop.is()) + xDesktop->removeTerminateListener(this); + else + m_xComponent->removeEventListener(this); + m_xComponent.clear(); + } + + if (shutDown) + m_rItem.reset(); + } + + // XTerminateListener + virtual void SAL_CALL queryTermination( const css::lang::EventObject& ) override + { + } + + virtual void SAL_CALL notifyTermination( const css::lang::EventObject& rEvt ) override + { + disposing(rEvt); + } + + virtual OUString SAL_CALL getImplementationName() override + { + if (mbComponentDLL) + return "com.sun.star.comp.ComponentDLLListener"; + else + return "com.sun.star.comp.DisposingTerminateListener"; + } + + virtual sal_Bool SAL_CALL supportsService(const OUString& /*rName*/) override + { + return false; + } + + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override + { + return css::uno::Sequence<OUString>(); + } + }; +}; + +//Something like an OutputDevice requires the SolarMutex to be taken before use +//for threadsafety. The user can ensure this, except in the case of its dtor +//being called from reset due to a terminate on the XComponent being called +//from an arbitrary thread +template<class T> class unique_disposing_solar_mutex_reset_ptr + : public unique_disposing_ptr<T> +{ +public: + unique_disposing_solar_mutex_reset_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr, bool bComponent = false) + : unique_disposing_ptr<T>(rComponent, p, bComponent) + { + } + + virtual void reset(T * p = nullptr) override + { + SolarMutexGuard aGuard; + unique_disposing_ptr<T>::reset(p); + } + + virtual ~unique_disposing_solar_mutex_reset_ptr() override + { + if (unique_disposing_ptr<T>::get() && comphelper::SolarMutex::get()) + reset(); + } +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/uno3.hxx b/include/comphelper/uno3.hxx new file mode 100644 index 000000000..517398fd7 --- /dev/null +++ b/include/comphelper/uno3.hxx @@ -0,0 +1,169 @@ +/* -*- 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_COMPHELPER_UNO3_HXX +#define INCLUDED_COMPHELPER_UNO3_HXX + +#include <com/sun/star/uno/XAggregation.hpp> +#include <comphelper/sequence.hxx> + + +namespace comphelper +{ + /** used for declaring UNO3-Defaults, i.e. acquire/release + */ + #define DECLARE_UNO3_DEFAULTS(classname, baseclass) \ + virtual void SAL_CALL acquire() noexcept override { baseclass::acquire(); } \ + virtual void SAL_CALL release() noexcept override { baseclass::release(); } + + /** used for declaring UNO3-Defaults, i.e. acquire/release if you want to forward all queryInterfaces to the base class, + (e.g. if you override queryAggregation) + */ + #define DECLARE_UNO3_AGG_DEFAULTS(classname, baseclass) \ + virtual void SAL_CALL acquire() noexcept override { baseclass::acquire(); } \ + virtual void SAL_CALL release() noexcept override { baseclass::release(); } \ + virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type& _rType) override \ + { return baseclass::queryInterface(_rType); } + + /** Use this macro to forward XComponent methods to base class + + When using the ::cppu::WeakComponentImplHelper base classes to + implement a UNO interface, a problem occurs when the interface + itself already derives from XComponent (like e.g. awt::XWindow + or awt::XControl): ::cppu::WeakComponentImplHelper is then + still abstract. Using this macro in the most derived class + definition provides overrides for the XComponent methods, + forwarding them to the given baseclass. + + @param classname + Name of the class this macro is issued within + + @param baseclass + Name of the baseclass that should have the XInterface methods + forwarded to - that's usually the WeakComponentImplHelperN base + + @param implhelper + Name of the baseclass that should have the XComponent methods + forwarded to - in the case of the WeakComponentImplHelper, + that would be ::cppu::WeakComponentImplHelperBase + */ + #define DECLARE_UNO3_XCOMPONENT_AGG_DEFAULTS(classname, baseclass, implhelper) \ + virtual void SAL_CALL acquire() noexcept override { baseclass::acquire(); } \ + virtual void SAL_CALL release() noexcept override { baseclass::release(); } \ + virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type& _rType) override \ + { return baseclass::queryInterface(_rType); } \ + virtual void SAL_CALL dispose() override \ + { \ + implhelper::dispose(); \ + } \ + virtual void SAL_CALL addEventListener( \ + css::uno::Reference< css::lang::XEventListener > const & xListener ) override \ + { \ + implhelper::addEventListener(xListener); \ + } \ + virtual void SAL_CALL removeEventListener( \ + css::uno::Reference< css::lang::XEventListener > const & xListener ) override \ + { \ + implhelper::removeEventListener(xListener); \ + } + + //= deriving from multiple XInterface-derived classes + + //= forwarding/merging XInterface functionality + + #define DECLARE_XINTERFACE( ) \ + virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override; \ + virtual void SAL_CALL acquire() noexcept override; \ + virtual void SAL_CALL release() noexcept override; + + #define IMPLEMENT_FORWARD_REFCOUNT( classname, refcountbase ) \ + void SAL_CALL classname::acquire() noexcept { refcountbase::acquire(); } \ + void SAL_CALL classname::release() noexcept { refcountbase::release(); } + + #define IMPLEMENT_FORWARD_XINTERFACE2( classname, refcountbase, baseclass2 ) \ + IMPLEMENT_FORWARD_REFCOUNT( classname, refcountbase ) \ + css::uno::Any SAL_CALL classname::queryInterface( const css::uno::Type& _rType ) \ + { \ + css::uno::Any aReturn = refcountbase::queryInterface( _rType ); \ + if ( !aReturn.hasValue() ) \ + aReturn = baseclass2::queryInterface( _rType ); \ + return aReturn; \ + } + + #define IMPLEMENT_FORWARD_XINTERFACE3( classname, refcountbase, baseclass2, baseclass3 ) \ + IMPLEMENT_FORWARD_REFCOUNT( classname, refcountbase ) \ + css::uno::Any SAL_CALL classname::queryInterface( const css::uno::Type& _rType ) \ + { \ + css::uno::Any aReturn = refcountbase::queryInterface( _rType ); \ + if ( !aReturn.hasValue() ) \ + { \ + aReturn = baseclass2::queryInterface( _rType ); \ + if ( !aReturn.hasValue() ) \ + aReturn = baseclass3::queryInterface( _rType ); \ + } \ + return aReturn; \ + } + + + //= forwarding/merging XTypeProvider functionality + + #define DECLARE_XTYPEPROVIDER( ) \ + virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override; \ + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) override; + + #define IMPLEMENT_GET_IMPLEMENTATION_ID( classname ) \ + css::uno::Sequence< sal_Int8 > SAL_CALL classname::getImplementationId( ) \ + { \ + return css::uno::Sequence<sal_Int8>(); \ + } + + #define IMPLEMENT_FORWARD_XTYPEPROVIDER2( classname, baseclass1, baseclass2 ) \ + css::uno::Sequence< css::uno::Type > SAL_CALL classname::getTypes( ) \ + { \ + return ::comphelper::concatSequences( \ + baseclass1::getTypes(), \ + baseclass2::getTypes() \ + ); \ + } \ + \ + IMPLEMENT_GET_IMPLEMENTATION_ID( classname ) + + /** ask for an iface of an aggregated object + usage:<br/> + Reference<XFoo> xFoo;<br/> + if (query_aggregation(xAggregatedObject, xFoo))<br/> + ... + */ + template <class iface> + bool query_aggregation(const css::uno::Reference< css::uno::XAggregation >& _rxAggregate, css::uno::Reference<iface>& _rxOut) + { + _rxOut.clear(); + if (_rxAggregate.is()) + { + _rxAggregate->queryAggregation(cppu::UnoType<iface>::get()) + >>= _rxOut; + } + return _rxOut.is(); + } +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_UNO3_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/unwrapargs.hxx b/include/comphelper/unwrapargs.hxx new file mode 100644 index 000000000..76eb8b838 --- /dev/null +++ b/include/comphelper/unwrapargs.hxx @@ -0,0 +1,122 @@ +/* -*- 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_COMPHELPER_UNWRAPARGS_HXX +#define INCLUDED_COMPHELPER_UNWRAPARGS_HXX + +#include <sal/config.h> + +#include <optional> + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <cppu/unotype.hxx> + +namespace comphelper { + +/// @internal +namespace detail { + inline void unwrapArgsError( + const OUString& str, sal_Int32 nArg, + const css::uno::Reference< css::uno::XInterface >& xErrorContext = + css::uno::Reference< css::uno::XInterface >() ) + { + throw css::lang::IllegalArgumentException( + str, xErrorContext, static_cast< sal_Int16 >( nArg ) ); + } + + template< typename T, typename... Args > + inline void unwrapArgsError( const OUString& str, sal_Int32 nArg, T&, Args&... args ) + { + return unwrapArgsError( str, nArg, args... ); + } + + inline void unwrapArgs( + const css::uno::Sequence< css::uno::Any >&, + sal_Int32, + const css::uno::Reference< css::uno::XInterface >& ) + { + return; + } + + inline void unwrapArgs( + const css::uno::Sequence< css::uno::Any >&, + sal_Int32 ) + { + return; + } + + template< typename T, typename... Args > + inline void unwrapArgs( + const css::uno::Sequence< css::uno::Any >& seq, + sal_Int32 nArg, ::std::optional< T >& v, Args&... args ); + + template< typename T, typename... Args > + inline void unwrapArgs( + const css::uno::Sequence< css::uno::Any >& seq, + sal_Int32 nArg, T& v, Args&... args ) + { + if( seq.getLength() <= nArg ) + { + return unwrapArgsError( OUString( "No such argument available!"), + nArg, args... ); + } + if( !fromAny( seq[nArg], &v ) ) + { + OUString msg = + "Cannot extract ANY { " + + seq[nArg].getValueType().getTypeName() + + " } to " + + ::cppu::UnoType<T>::get().getTypeName() + + "!"; + return unwrapArgsError( msg, nArg, args... ); + } + return unwrapArgs( seq, ++nArg, args... ); + } + + template< typename T, typename... Args > + inline void unwrapArgs( + const css::uno::Sequence< css::uno::Any >& seq, + sal_Int32 nArg, ::std::optional< T >& v, Args&... args ) + { + if( nArg < seq.getLength() ) + { + T t; + unwrapArgs( seq, nArg, t, args... ); + v = t; + } else { + unwrapArgs( seq, ++nArg, args... ); + } + } +} + +template< typename... Args > +inline void unwrapArgs( + const css::uno::Sequence< css::uno::Any >& seq, + Args&... args ) +{ + return detail::unwrapArgs( seq, 0, args... ); +} + +} // namespace comphelper + +#endif // ! defined( INCLUDED_COMPHELPER_UNWRAPARGS_HXX) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/weak.hxx b/include/comphelper/weak.hxx new file mode 100644 index 000000000..28a23445d --- /dev/null +++ b/include/comphelper/weak.hxx @@ -0,0 +1,64 @@ +/* -*- 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_COMPHELPER_WEAK_HXX +#define INCLUDED_COMPHELPER_WEAK_HXX + +#include <comphelper/comphelperdllapi.h> + +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <cppuhelper/weak.hxx> + +namespace comphelper +{ +/** Base class to implement a UNO object supporting types and weak references, i.e. the object can be held + weakly (by a css::uno::WeakReference). + This implementation copes with reference counting. Upon last release(), the virtual dtor + is called. + + In addition to the features from cppu::OWeakObject, derivations from this class can + also used as a base class for ::cppu::ImplInheritanceHelper? +*/ +class COMPHELPER_DLLPUBLIC OWeakTypeObject : public ::cppu::OWeakObject, public css::lang::XTypeProvider +{ +public: + OWeakTypeObject(); + virtual ~OWeakTypeObject() override; + + OWeakTypeObject(OWeakTypeObject const &) = default; + OWeakTypeObject(OWeakTypeObject &&) = default; + OWeakTypeObject & operator =(OWeakTypeObject const &) = default; + OWeakTypeObject & operator =(OWeakTypeObject &&) = default; + + virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type & rType ) override; + virtual void SAL_CALL acquire() noexcept override + { ::cppu::OWeakObject::acquire(); } + virtual void SAL_CALL release() noexcept override + { ::cppu::OWeakObject::release(); } + + virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override; + virtual css::uno::Sequence< ::sal_Int8 > SAL_CALL getImplementationId( ) override; + +}; + +} + +#endif + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/weakbag.hxx b/include/comphelper/weakbag.hxx new file mode 100644 index 000000000..c52defab2 --- /dev/null +++ b/include/comphelper/weakbag.hxx @@ -0,0 +1,84 @@ +/* -*- 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_COMPHELPER_WEAKBAG_HXX +#define INCLUDED_COMPHELPER_WEAKBAG_HXX + +#include <sal/config.h> + +#include <vector> +#include <com/sun/star/uno/Reference.h> +#include <cppuhelper/weakref.hxx> +#include <osl/diagnose.h> + +namespace comphelper { + +/** + A bag of UNO weak references. +*/ +template< typename T > class WeakBag { +public: + /** + Add a new weak reference. + + The implementation keeps the amount of memory consumed linear in the + number of living references added, not linear in the number of total + references added. + + @param e + a non-null reference. + */ + void add(css::uno::Reference< T > const & e) { + OSL_ASSERT(e.is()); + for (auto i = m_list.begin(); i != m_list.end();) { + if (css::uno::Reference< T >(*i).is()) { + ++i; + } else { + i = m_list.erase(i); + } + } + m_list.push_back(css::uno::WeakReference< T >(e)); + } + + /** + Remove a living reference. + + @return + a living reference, or null if there are none. + */ + css::uno::Reference< T > remove() { + while (!m_list.empty()) { + css::uno::Reference< T > r(m_list.back()); + m_list.pop_back(); + if (r.is()) { + return r; + } + } + return css::uno::Reference< T >(); + } + +private: + std::vector< css::uno::WeakReference< T > > m_list; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/weakeventlistener.hxx b/include/comphelper/weakeventlistener.hxx new file mode 100644 index 000000000..d64f302d8 --- /dev/null +++ b/include/comphelper/weakeventlistener.hxx @@ -0,0 +1,183 @@ +/* -*- 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_COMPHELPER_WEAKEVENTLISTENER_HXX +#define INCLUDED_COMPHELPER_WEAKEVENTLISTENER_HXX + +#include <config_options.h> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/weakref.hxx> +#include <comphelper/comphelperdllapi.h> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <utility> + +namespace com::sun::star::uno { class XWeak; } + +namespace comphelper +{ + + + //= OWeakListenerAdapterBase + + /** (the base for) an adapter which allows to add as listener to a foreign component, without + being held hard. + + <p>The idea is that this adapter is added as listener to a foreign component, which usually + holds it's listener hard. The adapter itself knows the real listener as weak reference, + thus not affecting its life time.</p> + */ + class OWeakListenerAdapterBase : public cppu::BaseMutex + { + private: + css::uno::WeakReference< css::uno::XInterface > + m_aListener; + css::uno::Reference< css::uno::XInterface > + m_xBroadcaster; + + protected: + css::uno::Reference< css::uno::XInterface > + getListener( ) const + { + return m_aListener.get(); + } + + const css::uno::Reference< css::uno::XInterface >& + getBroadcaster( ) const + { + return m_xBroadcaster; + } + + void resetListener( ) + { + m_aListener.clear(); + } + + + protected: + OWeakListenerAdapterBase( + const css::uno::Reference< css::uno::XWeak >& _rxListener, + css::uno::Reference< css::uno::XInterface > _xBroadcaster + ) + :m_aListener ( _rxListener ) + ,m_xBroadcaster (std::move( _xBroadcaster )) + { + } + + protected: + virtual ~OWeakListenerAdapterBase(); + }; + + + //= OWeakListenerAdapter + + template< class BROADCASTER, class LISTENER > + /** yet another base for weak listener adapters, this time with some type safety + + <p>Note that derived classes need to overwrite all virtual methods of their interface + except XEventListener::disposing, and forward it to their master listener.</p> + + <p>Additionally, derived classes need to add themself as listener to the broadcaster, + as this can't be done in a generic way</p> + */ + class OWeakListenerAdapter + :public ::cppu::WeakComponentImplHelper< LISTENER > + ,public OWeakListenerAdapterBase + { + protected: + /** ctor + <p>Note that derived classes still need to add themself as listener to the broadcaster, + as this can't be done in a generic way</p> + */ + OWeakListenerAdapter( + const css::uno::Reference< css::uno::XWeak >& _rxListener, + const css::uno::Reference< BROADCASTER >& _rxBroadcaster + ); + + protected: + css::uno::Reference< LISTENER > getListener( ) const + { + return css::uno::Reference< LISTENER >( OWeakListenerAdapterBase::getListener(), css::uno::UNO_QUERY ); + } + + // XEventListener overridables + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + protected: + // OComponentHelper overridables + // to be overridden, again - the derived class should revoke the listener from the broadcaster + virtual void SAL_CALL disposing( ) override = 0; + }; + + + //= OWeakEventListenerAdapter + + typedef OWeakListenerAdapter < css::lang::XComponent + , css::lang::XEventListener + > OWeakEventListenerAdapter_Base; + /** the most simple listener adapter: for XEventListeners at XComponents + */ + class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OWeakEventListenerAdapter final : public OWeakEventListenerAdapter_Base + { + public: + OWeakEventListenerAdapter( + css::uno::Reference< css::uno::XWeak > const & _rxListener, + css::uno::Reference< css::lang::XComponent > const & _rxBroadcaster + ); + + // nothing to do except an own ctor - the forwarding of the "disposing" is already done + // in the base class + + private: + using OWeakEventListenerAdapter_Base::disposing; + virtual void SAL_CALL disposing( ) override; + }; + + + //= OWeakListenerAdapter + + + template< class BROADCASTER, class LISTENER > + OWeakListenerAdapter< BROADCASTER, LISTENER >::OWeakListenerAdapter( + const css::uno::Reference< css::uno::XWeak >& _rxListener, + const css::uno::Reference< BROADCASTER >& _rxBroadcaster + ) + : ::cppu::WeakComponentImplHelper< LISTENER >( m_aMutex ) + , OWeakListenerAdapterBase( _rxListener, _rxBroadcaster ) + { + } + + + template< class BROADCASTER, class LISTENER > + void SAL_CALL OWeakListenerAdapter< BROADCASTER, LISTENER >::disposing( const css::lang::EventObject& _rSource ) + { + css::uno::Reference< LISTENER > xListener( getListener() ); + if ( xListener.is() ) + xListener->disposing( _rSource ); + } + + +} // namespace comphelper + + +#endif // INCLUDED_COMPHELPER_WEAKEVENTLISTENER_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/windowsStart.hxx b/include/comphelper/windowsStart.hxx new file mode 100644 index 000000000..a727733d9 --- /dev/null +++ b/include/comphelper/windowsStart.hxx @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef INCLUDED_COMPHELPER_WINSTART_HXX +#define INCLUDED_COMPHELPER_WINSTART_HXX + +#ifdef _WIN32 +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#endif + +/** + * Launch a child process with the specified arguments. + * @note argv[0] is ignored + */ +BOOL +WinLaunchChild(const wchar_t *exePath, int argc, + wchar_t **argv, HANDLE userToken = nullptr, + HANDLE *hProcess = nullptr); + +wchar_t* MakeCommandLine(int argc, wchar_t **argv); + +#endif diff --git a/include/comphelper/windowsdebugoutput.hxx b/include/comphelper/windowsdebugoutput.hxx new file mode 100644 index 000000000..0315933c7 --- /dev/null +++ b/include/comphelper/windowsdebugoutput.hxx @@ -0,0 +1,796 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +/* Debug output operators for Windows-specific types. For use in SAL_INFO(), SAL_WARN(), and + * friends. The exact format of the generated output is not guaranteed to be stable or contain + * complete information. + */ + +#ifndef INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX +#define INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX + +#include <codecvt> +#include <iomanip> +#include <ostream> +#include <string> +#include <vector> + +#ifdef LIBO_INTERNAL_ONLY +#include <prewin.h> +#include <postwin.h> +#else +#include <windows.h> +#endif +#include <initguid.h> + +namespace +{ +DEFINE_GUID(IID_IdentityUnmarshal, 0x0000001B, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x46); +} + +template <typename charT, typename traits> +inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, + const IID& rIid) +{ + LPOLESTR pRiid; + if (StringFromIID(rIid, &pRiid) != S_OK) + return stream << "?"; + + stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes( + std::wstring(pRiid)); + + DWORD nSize; + if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"CLSID\\").append(pRiid).data(), nullptr, + RRF_RT_REG_SZ, nullptr, nullptr, &nSize) + == ERROR_SUCCESS) + { + std::vector<wchar_t> sValue(nSize / 2); + if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"CLSID\\").append(pRiid).data(), nullptr, + RRF_RT_REG_SZ, nullptr, sValue.data(), &nSize) + == ERROR_SUCCESS) + { + stream << "=\"" + << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes( + std::wstring(sValue.data())) + << "\""; + } + } + else if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"Interface\\").append(pRiid).data(), + nullptr, RRF_RT_REG_SZ, nullptr, nullptr, &nSize) + == ERROR_SUCCESS) + { + std::vector<wchar_t> sValue(nSize / 2); + if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"Interface\\").append(pRiid).data(), + nullptr, RRF_RT_REG_SZ, nullptr, sValue.data(), &nSize) + == ERROR_SUCCESS) + { + stream << "=\"" + << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes( + std::wstring(sValue.data())) + << "\""; + } + } + else + { + // Special case well-known interfaces that pop up a lot, but which don't have their name in + // the Registry. + + if (IsEqualIID(rIid, IID_IMarshal)) + stream << "=\"IMarshal\""; + else if (IsEqualIID(rIid, IID_IMarshal2)) + stream << "=\"IMarshal2\""; + else if (IsEqualIID(rIid, IID_INoMarshal)) + stream << "=\"INoMarshal\""; + else if (IsEqualIID(rIid, IID_IdentityUnmarshal)) + stream << "=\"IdentityUnmarshal\""; + else if (IsEqualIID(rIid, IID_IFastRundown)) + stream << "=\"IFastRundown\""; + else if (IsEqualIID(rIid, IID_IStdMarshalInfo)) + stream << "=\"IStdMarshalInfo\""; + else if (IsEqualIID(rIid, IID_IAgileObject)) + stream << "=\"IAgileObject\""; + else if (IsEqualIID(rIid, IID_IExternalConnection)) + stream << "=\"IExternalConnection\""; + else if (IsEqualIID(rIid, IID_ICallFactory)) + stream << "=\"ICallFactory\""; + } + + CoTaskMemFree(pRiid); + return stream; +} + +template <typename charT, typename traits> +inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, + const VARIANT& rVariant) +{ + if (rVariant.vt & VT_VECTOR) + stream << "VECTOR:"; + if (rVariant.vt & VT_ARRAY) + stream << "ARRAY:"; + if (rVariant.vt & VT_BYREF) + stream << "BYREF:"; + + switch (rVariant.vt & ~(VT_VECTOR | VT_ARRAY | VT_BYREF)) + { + case VT_EMPTY: + stream << "EMPTY"; + break; + case VT_NULL: + stream << "NULL"; + break; + case VT_I2: + stream << "I2"; + break; + case VT_I4: + stream << "I4"; + break; + case VT_R4: + stream << "R4"; + break; + case VT_R8: + stream << "R8"; + break; + case VT_CY: + stream << "CY"; + break; + case VT_DATE: + stream << "DATE"; + break; + case VT_BSTR: + stream << "BSTR"; + break; + case VT_DISPATCH: + stream << "DISPATCH"; + break; + case VT_ERROR: + stream << "ERROR"; + break; + case VT_BOOL: + stream << "BOOL"; + break; + case VT_VARIANT: + stream << "VARIANT"; + break; + case VT_UNKNOWN: + stream << "UNKNOWN"; + break; + case VT_DECIMAL: + stream << "DECIMAL"; + break; + case VT_I1: + stream << "I1"; + break; + case VT_UI1: + stream << "UI1"; + break; + case VT_UI2: + stream << "UI2"; + break; + case VT_UI4: + stream << "UI4"; + break; + case VT_I8: + stream << "I8"; + break; + case VT_UI8: + stream << "UI8"; + break; + case VT_INT: + stream << "INT"; + break; + case VT_UINT: + stream << "UINT"; + break; + case VT_VOID: + stream << "VOID"; + break; + case VT_HRESULT: + stream << "HRESULT"; + break; + case VT_PTR: + stream << "PTR"; + break; + case VT_SAFEARRAY: + stream << "SAFEARRAY"; + break; + case VT_CARRAY: + stream << "CARRAY"; + break; + case VT_USERDEFINED: + stream << "USERDEFINED"; + break; + case VT_LPSTR: + stream << "LPSTR"; + break; + case VT_LPWSTR: + stream << "LPWSTR"; + break; + case VT_RECORD: + stream << "RECORD"; + break; + case VT_INT_PTR: + stream << "INT_PTR"; + break; + case VT_UINT_PTR: + stream << "UINT_PTR"; + break; + case VT_FILETIME: + stream << "FILETIME"; + break; + case VT_BLOB: + stream << "BLOB"; + break; + case VT_STREAM: + stream << "STREAM"; + break; + case VT_STORAGE: + stream << "STORAGE"; + break; + case VT_STREAMED_OBJECT: + stream << "STREAMED_OBJECT"; + break; + case VT_STORED_OBJECT: + stream << "STORED_OBJECT"; + break; + case VT_BLOB_OBJECT: + stream << "BLOB_OBJECT"; + break; + case VT_CF: + stream << "CF"; + break; + case VT_CLSID: + stream << "CLSID"; + break; + case VT_VERSIONED_STREAM: + stream << "VERSIONED_STREAM"; + break; + case VT_BSTR_BLOB: + stream << "BSTR_BLOB"; + break; + default: + stream << rVariant.vt; + break; + } + if (rVariant.vt == VT_EMPTY || rVariant.vt == VT_NULL || rVariant.vt == VT_VOID) + return stream; + stream << ":"; + + std::ios_base::fmtflags flags; + std::streamsize width; + charT fill; + + if (rVariant.vt & VT_BYREF) + { + stream << rVariant.byref << ":"; + if (rVariant.byref == nullptr) + return stream; + if ((rVariant.vt & VT_TYPEMASK) == VT_VOID || (rVariant.vt & VT_TYPEMASK) == VT_USERDEFINED) + return stream; + stream << ":"; + switch (rVariant.vt & VT_TYPEMASK) + { + case VT_I2: + stream << *static_cast<short*>(rVariant.byref); + break; + case VT_I4: + stream << *static_cast<int*>(rVariant.byref); + break; + case VT_R4: + stream << *static_cast<float*>(rVariant.byref); + break; + case VT_R8: + stream << *static_cast<double*>(rVariant.byref); + break; + case VT_CY: + stream << static_cast<CY*>(rVariant.byref)->int64; + break; + case VT_DATE: + stream << *static_cast<double*>(rVariant.byref); + break; // FIXME + case VT_BSTR: + stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes( + *static_cast<OLECHAR**>(rVariant.byref)); + break; + case VT_DISPATCH: + stream << rVariant.byref; + break; + case VT_ERROR: + case VT_HRESULT: + flags = stream.flags(); + stream << std::hex << *static_cast<int*>(rVariant.byref); + stream.setf(flags); + break; + case VT_BOOL: + stream << (*static_cast<VARIANT_BOOL*>(rVariant.byref) ? "YES" : "NO"); + break; + case VT_VARIANT: + stream << *static_cast<VARIANT*>(rVariant.byref); + break; + case VT_UNKNOWN: + stream << *static_cast<IUnknown**>(rVariant.byref); + break; + case VT_DECIMAL: + flags = stream.flags(); + width = stream.width(); + fill = stream.fill(); + stream << std::hex << std::setw(8) << std::setfill('0') + << static_cast<DECIMAL*>(rVariant.byref)->Hi32; + stream << std::setw(16) << static_cast<DECIMAL*>(rVariant.byref)->Lo64; + stream.setf(flags); + stream << std::setw(width) << std::setfill(fill); + break; + case VT_I1: + stream << static_cast<int>(*static_cast<char*>(rVariant.byref)); + break; + case VT_UI1: + stream << static_cast<unsigned int>(*static_cast<unsigned char*>(rVariant.byref)); + break; + case VT_UI2: + stream << *static_cast<unsigned short*>(rVariant.byref); + break; + case VT_UI4: + stream << *static_cast<unsigned int*>(rVariant.byref); + break; + case VT_I8: + stream << *static_cast<long long*>(rVariant.byref); + break; + case VT_UI8: + stream << *static_cast<unsigned long long*>(rVariant.byref); + break; + case VT_INT: + stream << *static_cast<int*>(rVariant.byref); + break; + case VT_UINT: + stream << *static_cast<unsigned int*>(rVariant.byref); + break; + case VT_INT_PTR: + stream << *static_cast<intptr_t*>(rVariant.byref); + break; + case VT_UINT_PTR: + stream << *static_cast<uintptr_t*>(rVariant.byref); + break; + case VT_PTR: + case VT_CARRAY: + stream << *static_cast<void**>(rVariant.byref); + break; + case VT_SAFEARRAY: + break; // FIXME + case VT_LPSTR: + stream << *static_cast<char**>(rVariant.byref); + break; + case VT_LPWSTR: + stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes( + std::wstring(*static_cast<wchar_t**>(rVariant.byref))); + break; + case VT_FILETIME: + break; // FIXME + case VT_BLOB: + break; // FIXME + case VT_STREAM: + break; // FIXME + case VT_STORAGE: + break; // FIXME + case VT_STREAMED_OBJECT: + break; // FIXME + case VT_STORED_OBJECT: + break; // FIXME + case VT_BLOB_OBJECT: + break; // FIXME + case VT_CF: + break; // FIXME + case VT_CLSID: + stream << *static_cast<IID*>(rVariant.byref); + break; + case VT_VERSIONED_STREAM: + break; // FIXME + case VT_BSTR_BLOB: + break; // FIXME + default: + stream << "?(" << (rVariant.vt & VT_TYPEMASK) << ")"; + break; + } + return stream; + } + + switch (rVariant.vt & VT_TYPEMASK) + { + case VT_I2: + stream << rVariant.iVal; + break; + case VT_I4: + stream << rVariant.lVal; + break; + case VT_R4: + stream << rVariant.fltVal; + break; + case VT_R8: + stream << rVariant.dblVal; + break; + case VT_CY: + stream << rVariant.cyVal.int64; + break; + case VT_DATE: + stream << static_cast<double>(rVariant.date); + break; // FIXME + case VT_BSTR: + if (rVariant.bstrVal == nullptr) + stream << "(null)"; + else + stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes( + rVariant.bstrVal); + break; + case VT_DISPATCH: + stream << rVariant.pdispVal; + break; + case VT_ERROR: + case VT_HRESULT: + flags = stream.flags(); + stream << std::hex << rVariant.lVal; + stream.setf(flags); + break; + case VT_BOOL: + stream << (rVariant.boolVal ? "YES" : "NO"); + break; + case VT_UNKNOWN: + stream << rVariant.punkVal; + break; + case VT_DECIMAL: + flags = stream.flags(); + width = stream.width(); + fill = stream.fill(); + stream << std::hex << std::setw(8) << std::setfill('0') << rVariant.decVal.Hi32; + stream << std::setw(16) << rVariant.decVal.Lo64; + stream.setf(flags); + stream << std::setw(width) << std::setfill(fill); + break; + case VT_I1: + stream << static_cast<int>(rVariant.bVal); + break; + case VT_UI1: + stream << static_cast<unsigned int>(rVariant.bVal); + break; + case VT_UI2: + stream << static_cast<unsigned short>(rVariant.iVal); + break; + case VT_UI4: + stream << static_cast<unsigned int>(rVariant.lVal); + break; + case VT_I8: + stream << rVariant.llVal; + break; + case VT_UI8: + stream << static_cast<unsigned long long>(rVariant.llVal); + break; + case VT_INT: + stream << rVariant.lVal; + break; + case VT_UINT: + stream << static_cast<unsigned int>(rVariant.lVal); + break; + case VT_INT_PTR: + stream << reinterpret_cast<intptr_t>(rVariant.plVal); + break; + case VT_UINT_PTR: + stream << reinterpret_cast<uintptr_t>(rVariant.plVal); + break; + case VT_PTR: + case VT_CARRAY: + stream << rVariant.byref; + break; + case VT_SAFEARRAY: + break; // FIXME + case VT_LPSTR: + stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes( + rVariant.bstrVal); + break; + case VT_LPWSTR: + stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes( + std::wstring(static_cast<wchar_t*>(rVariant.byref))); + break; + case VT_FILETIME: + break; // FIXME + case VT_BLOB: + break; // FIXME + case VT_STREAM: + break; // FIXME + case VT_STORAGE: + break; // FIXME + case VT_STREAMED_OBJECT: + break; // FIXME + case VT_STORED_OBJECT: + break; // FIXME + case VT_BLOB_OBJECT: + break; // FIXME + case VT_CF: + break; // FIXME + case VT_VERSIONED_STREAM: + break; // FIXME + case VT_BSTR_BLOB: + break; // FIXME + default: + stream << "?(" << (rVariant.vt & VT_TYPEMASK) << ")"; + break; + } + return stream; +} + +inline std::string DMPAPER_to_string(int dmpaper) +{ + switch (dmpaper) + { + case DMPAPER_LETTER: + return "LETTER"; + case DMPAPER_LETTERSMALL: + return "LETTERSMALL"; + case DMPAPER_TABLOID: + return "TABLOID"; + case DMPAPER_LEDGER: + return "LEDGER"; + case DMPAPER_LEGAL: + return "LEGAL"; + case DMPAPER_STATEMENT: + return "STATEMENT"; + case DMPAPER_EXECUTIVE: + return "EXECUTIVE"; + case DMPAPER_A3: + return "A3"; + case DMPAPER_A4: + return "A4"; + case DMPAPER_A4SMALL: + return "A4SMALL"; + case DMPAPER_A5: + return "A5"; + case DMPAPER_B4: + return "B4"; + case DMPAPER_B5: + return "B5"; + case DMPAPER_FOLIO: + return "FOLIO"; + case DMPAPER_QUARTO: + return "QUARTO"; + case DMPAPER_10X14: + return "10X14"; + case DMPAPER_11X17: + return "11X17"; + case DMPAPER_NOTE: + return "NOTE"; + case DMPAPER_ENV_9: + return "ENV_9"; + case DMPAPER_ENV_10: + return "ENV_10"; + case DMPAPER_ENV_11: + return "ENV_11"; + case DMPAPER_ENV_12: + return "ENV_12"; + case DMPAPER_ENV_14: + return "ENV_14"; + case DMPAPER_CSHEET: + return "CSHEET"; + case DMPAPER_DSHEET: + return "DSHEET"; + case DMPAPER_ESHEET: + return "ESHEET"; + case DMPAPER_ENV_DL: + return "ENV_DL"; + case DMPAPER_ENV_C5: + return "ENV_C5"; + case DMPAPER_ENV_C3: + return "ENV_C3"; + case DMPAPER_ENV_C4: + return "ENV_C4"; + case DMPAPER_ENV_C6: + return "ENV_C6"; + case DMPAPER_ENV_C65: + return "ENV_C65"; + case DMPAPER_ENV_B4: + return "ENV_B4"; + case DMPAPER_ENV_B5: + return "ENV_B5"; + case DMPAPER_ENV_B6: + return "ENV_B6"; + case DMPAPER_ENV_ITALY: + return "ENV_ITALY"; + case DMPAPER_ENV_MONARCH: + return "ENV_MONARCH"; + case DMPAPER_ENV_PERSONAL: + return "ENV_PERSONAL"; + case DMPAPER_FANFOLD_US: + return "FANFOLD_US"; + case DMPAPER_FANFOLD_STD_GERMAN: + return "FANFOLD_STD_GERMAN"; + case DMPAPER_FANFOLD_LGL_GERMAN: + return "FANFOLD_LGL_GERMAN"; + case DMPAPER_ISO_B4: + return "ISO_B4"; + case DMPAPER_JAPANESE_POSTCARD: + return "JAPANESE_POSTCARD"; + case DMPAPER_9X11: + return "9X11"; + case DMPAPER_10X11: + return "10X11"; + case DMPAPER_15X11: + return "15X11"; + case DMPAPER_ENV_INVITE: + return "ENV_INVITE"; + case DMPAPER_RESERVED_48: + return "RESERVED_48"; + case DMPAPER_RESERVED_49: + return "RESERVED_49"; + case DMPAPER_LETTER_EXTRA: + return "LETTER_EXTRA"; + case DMPAPER_LEGAL_EXTRA: + return "LEGAL_EXTRA"; + case DMPAPER_TABLOID_EXTRA: + return "TABLOID_EXTRA"; + case DMPAPER_A4_EXTRA: + return "A4_EXTRA"; + case DMPAPER_LETTER_TRANSVERSE: + return "LETTER_TRANSVERSE"; + case DMPAPER_A4_TRANSVERSE: + return "A4_TRANSVERSE"; + case DMPAPER_LETTER_EXTRA_TRANSVERSE: + return "LETTER_EXTRA_TRANSVERSE"; + case DMPAPER_A_PLUS: + return "A_PLUS"; + case DMPAPER_B_PLUS: + return "B_PLUS"; + case DMPAPER_LETTER_PLUS: + return "LETTER_PLUS"; + case DMPAPER_A4_PLUS: + return "A4_PLUS"; + case DMPAPER_A5_TRANSVERSE: + return "A5_TRANSVERSE"; + case DMPAPER_B5_TRANSVERSE: + return "B5_TRANSVERSE"; + case DMPAPER_A3_EXTRA: + return "A3_EXTRA"; + case DMPAPER_A5_EXTRA: + return "A5_EXTRA"; + case DMPAPER_B5_EXTRA: + return "B5_EXTRA"; + case DMPAPER_A2: + return "A2"; + case DMPAPER_A3_TRANSVERSE: + return "A3_TRANSVERSE"; + case DMPAPER_A3_EXTRA_TRANSVERSE: + return "A3_EXTRA_TRANSVERSE"; + case DMPAPER_DBL_JAPANESE_POSTCARD: + return "DBL_JAPANESE_POSTCARD"; + case DMPAPER_A6: + return "A6"; + case DMPAPER_JENV_KAKU2: + return "JENV_KAKU2"; + case DMPAPER_JENV_KAKU3: + return "JENV_KAKU3"; + case DMPAPER_JENV_CHOU3: + return "JENV_CHOU3"; + case DMPAPER_JENV_CHOU4: + return "JENV_CHOU4"; + case DMPAPER_LETTER_ROTATED: + return "LETTER_ROTATED"; + case DMPAPER_A3_ROTATED: + return "A3_ROTATED"; + case DMPAPER_A4_ROTATED: + return "A4_ROTATED"; + case DMPAPER_A5_ROTATED: + return "A5_ROTATED"; + case DMPAPER_B4_JIS_ROTATED: + return "B4_JIS_ROTATED"; + case DMPAPER_B5_JIS_ROTATED: + return "B5_JIS_ROTATED"; + case DMPAPER_JAPANESE_POSTCARD_ROTATED: + return "JAPANESE_POSTCARD_ROTATED"; + case DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED: + return "DBL_JAPANESE_POSTCARD_ROTATED"; + case DMPAPER_A6_ROTATED: + return "A6_ROTATED"; + case DMPAPER_JENV_KAKU2_ROTATED: + return "JENV_KAKU2_ROTATED"; + case DMPAPER_JENV_KAKU3_ROTATED: + return "JENV_KAKU3_ROTATED"; + case DMPAPER_JENV_CHOU3_ROTATED: + return "JENV_CHOU3_ROTATED"; + case DMPAPER_JENV_CHOU4_ROTATED: + return "JENV_CHOU4_ROTATED"; + case DMPAPER_B6_JIS: + return "B6_JIS"; + case DMPAPER_B6_JIS_ROTATED: + return "B6_JIS_ROTATED"; + case DMPAPER_12X11: + return "12X11"; + case DMPAPER_JENV_YOU4: + return "JENV_YOU4"; + case DMPAPER_JENV_YOU4_ROTATED: + return "JENV_YOU4_ROTATED"; + case DMPAPER_P16K: + return "P16K"; + case DMPAPER_P32K: + return "P32K"; + case DMPAPER_P32KBIG: + return "P32KBIG"; + case DMPAPER_PENV_1: + return "PENV_1"; + case DMPAPER_PENV_2: + return "PENV_2"; + case DMPAPER_PENV_3: + return "PENV_3"; + case DMPAPER_PENV_4: + return "PENV_4"; + case DMPAPER_PENV_5: + return "PENV_5"; + case DMPAPER_PENV_6: + return "PENV_6"; + case DMPAPER_PENV_7: + return "PENV_7"; + case DMPAPER_PENV_8: + return "PENV_8"; + case DMPAPER_PENV_9: + return "PENV_9"; + case DMPAPER_PENV_10: + return "PENV_10"; + case DMPAPER_P16K_ROTATED: + return "P16K_ROTATED"; + case DMPAPER_P32K_ROTATED: + return "P32K_ROTATED"; + case DMPAPER_P32KBIG_ROTATED: + return "P32KBIG_ROTATED"; + case DMPAPER_PENV_1_ROTATED: + return "PENV_1_ROTATED"; + case DMPAPER_PENV_2_ROTATED: + return "PENV_2_ROTATED"; + case DMPAPER_PENV_3_ROTATED: + return "PENV_3_ROTATED"; + case DMPAPER_PENV_4_ROTATED: + return "PENV_4_ROTATED"; + case DMPAPER_PENV_5_ROTATED: + return "PENV_5_ROTATED"; + case DMPAPER_PENV_6_ROTATED: + return "PENV_6_ROTATED"; + case DMPAPER_PENV_7_ROTATED: + return "PENV_7_ROTATED"; + case DMPAPER_PENV_8_ROTATED: + return "PENV_8_ROTATED"; + case DMPAPER_PENV_9_ROTATED: + return "PENV_9_ROTATED"; + case DMPAPER_PENV_10_ROTATED: + return "PENV_10_ROTATED"; + default: + return "?" + std::to_string(dmpaper); + } +} + +inline std::string DC_PAPERSIZE_array_to_string(POINT* pPaperSizes, DWORD nCount) +{ + std::string result; + + for (DWORD i = 0; i < nCount; i++) + { + if (i > 0) + result += ", "; + + result += std::to_string(std::lround(pPaperSizes[i].x / 10.0)) + "x" + + std::to_string(std::lround(pPaperSizes[i].y / 10.0)); + +#if 0 + // WIP. Printer::GetPaperName() should really be inline in <i18nutil/paper.hxx> or + // something, so that it can be used anywhere. We can't depend on vcl in this file as we + // might be included in modules that precede vcl. + PaperInfo paperInfo(pPaperSizes[i].x * 10, pPaperSizes[i].y * 10); + paperInfo.doSloppyFit(true); + if (paperInfo.getPaper() != PAPER_USER) + result += "(" + std::string(Printer::GetPaperName(paperInfo.getPaper()).toUtf8().getStr()) + ")"; +#endif + } + return result; +} + +#endif // INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/windowserrorstring.hxx b/include/comphelper/windowserrorstring.hxx new file mode 100644 index 000000000..1b50f1ead --- /dev/null +++ b/include/comphelper/windowserrorstring.hxx @@ -0,0 +1,68 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_WINDOWSERRORSTRING_HXX +#define INCLUDED_COMPHELPER_WINDOWSERRORSTRING_HXX + +#include <prewin.h> +#include <postwin.h> +#include <rtl/ustring.hxx> +#include <o3tl/char16_t2wchar_t.hxx> + +namespace { + +inline OUString WindowsErrorString(DWORD nErrorCode) +{ + LPWSTR pMsgBuf; + + if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + nErrorCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + reinterpret_cast<LPWSTR>(&pMsgBuf), + 0, + nullptr) == 0) + return OUString::number(nErrorCode, 16); + + OUString result(o3tl::toU(pMsgBuf)); + result.endsWith("\r\n", &result); + + HeapFree(GetProcessHeap(), 0, pMsgBuf); + + return result; +} + +inline OUString WindowsErrorStringFromHRESULT(HRESULT hr) +{ + // See https://blogs.msdn.microsoft.com/oldnewthing/20061103-07/?p=29133 + // Also https://social.msdn.microsoft.com/Forums/vstudio/en-US/c33d9a4a-1077-4efd-99e8-0c222743d2f8 + // (which refers to https://msdn.microsoft.com/en-us/library/aa382475) + // explains why can't we just reinterpret_cast HRESULT to DWORD Win32 error: + // we might actually have a Win32 error code converted using HRESULT_FROM_WIN32 macro + + DWORD nErrorCode = DWORD(hr); + if (HRESULT(hr & 0xFFFF0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0) || hr == S_OK) + { + nErrorCode = HRESULT_CODE(hr); + // https://msdn.microsoft.com/en-us/library/ms679360 mentions that the codes might have + // high word bits set (e.g., bit 29 could be set if error comes from a 3rd-party library). + // So try to restore the original error code to avoid wrong error messages + DWORD nLastError = GetLastError(); + if ((nLastError & 0xFFFF) == nErrorCode) + nErrorCode = nLastError; + } + + return WindowsErrorString(nErrorCode); +} + +} // anonymous namespace + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/xmlsechelper.hxx b/include/comphelper/xmlsechelper.hxx new file mode 100644 index 000000000..9a245877f --- /dev/null +++ b/include/comphelper/xmlsechelper.hxx @@ -0,0 +1,46 @@ +/* -*- 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_COMPHELPER_XMLSECHELPER_HXX +#define INCLUDED_COMPHELPER_XMLSECHELPER_HXX + +#include <comphelper/comphelperdllapi.h> + +#include <com/sun/star/security/CertificateKind.hpp> +#include <com/sun/star/uno/Sequence.hxx> + +#include <vector> + +namespace comphelper::xmlsec +{ +COMPHELPER_DLLPUBLIC OUString GetCertificateKind(const css::security::CertificateKind& rKind); + +COMPHELPER_DLLPUBLIC std::vector<std::pair<OUString, OUString>> +parseDN(std::u16string_view rRawString); +COMPHELPER_DLLPUBLIC std::pair<OUString, OUString> +GetDNForCertDetailsView(std::u16string_view rRawString); +COMPHELPER_DLLPUBLIC OUString GetContentPart(const OUString& _rRawString, + const css::security::CertificateKind& rKind); + +COMPHELPER_DLLPUBLIC OUString GetHexString(const css::uno::Sequence<sal_Int8>& _rSeq, + const char* _pSep, sal_uInt16 _nLineBreak = 0xFFFF); +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/xmltools.hxx b/include/comphelper/xmltools.hxx new file mode 100644 index 000000000..9ef64b17d --- /dev/null +++ b/include/comphelper/xmltools.hxx @@ -0,0 +1,24 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_COMPHELPER_XMLTOOLS_HXX +#define INCLUDED_COMPHELPER_XMLTOOLS_HXX + +#include <rtl/string.hxx> +#include <comphelper/comphelperdllapi.h> + +namespace comphelper::xml +{ + COMPHELPER_DLLPUBLIC OString makeXMLChaff(); + COMPHELPER_DLLPUBLIC OString generateGUIDString(); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |