diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-09-14 08:19:47 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-09-15 06:07:36 +0200 |
commit | 05bc93db2de56000f65764d7e394d03747cac23d (patch) | |
tree | 975de9ae83572aac8a5c3ea8db281e1017ee5be0 /include | |
parent | 8cbb414ed737f9ffc76e1258e6671769bf63fc6c (diff) |
Use <comphelper/servicehelper.hxx> implementing XUnoTunnel part 1
The header got some changes:
1. Move UnoTunnelIdInit and isUnoTunnelId into 'comphelper' namespace
2. Rename UnoTunnelIdInit to UnoIdInit, as a precondition to replace
of uses of OImplementationId with it, including in XTypeProvider
3. Introduce convenience functions 'getSomething_cast' to cast between
sal_Int64 and object pointers uniformly.
4. Rename getUnoTunnelImplementation to getFromUnoTunnel, both to make
it a bit shorter, and to reflect its function better. Templatize it
to take also css::uno::Any for convenience.
5. Introduce getSomethingImpl, inspired by sw::UnoTunnelImpl; allow it
handle cases both with and without fallback to parent.
6. Adjust UNO3_GETIMPLEMENTATION_* macros
TODO (in separate commits):
- Drop sw::UnoTunnelImpl and sw::UnoTunnelGetImplementation
- Replace all uses of OImplementationId in core with UnoIdInit
- Deprecate OImplementationId in <cppuhelper/typeprovider.hxx>
- Change implementations of getSomething to use getSomethingImpl
- Revise uses of getSomething to use getFromUnoTunnel
Change-Id: If4a3cb024130f1f552f988f0479589da1cd066e7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122022
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/comphelper/servicehelper.hxx | 111 |
1 files changed, 76 insertions, 35 deletions
diff --git a/include/comphelper/servicehelper.hxx b/include/comphelper/servicehelper.hxx index 8be9ee975178..fa906075e1b6 100644 --- a/include/comphelper/servicehelper.hxx +++ b/include/comphelper/servicehelper.hxx @@ -25,37 +25,89 @@ #include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/uno/Sequence.hxx> -class UnoTunnelIdInit -{ -private: - css::uno::Sequence< sal_Int8 > m_aSeq; -public: - UnoTunnelIdInit() : m_aSeq(16) +#include <type_traits> + +namespace comphelper { + + // Class incapsulating UIDs used as e.g. tunnel IDs for css::lang::XUnoTunnel, + // or implementation IDs for css::lang::XTypeProvider + class UnoIdInit { - rtl_createUuid( reinterpret_cast<sal_uInt8*>(m_aSeq.getArray()), nullptr, true ); + 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)); } - const css::uno::Sequence< sal_Int8 >& getSeq() const { return m_aSeq; } -}; -namespace comphelper { + 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* getUnoTunnelImplementation( const css::uno::Reference< css::uno::XInterface >& xIface ) + template <class T> T* getFromUnoTunnel(const css::uno::Reference<css::lang::XUnoTunnel>& xUT) { - css::uno::Reference< css::lang::XUnoTunnel > xUT( xIface, css::uno::UNO_QUERY ); if (!xUT.is()) return nullptr; - return reinterpret_cast<T*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething( T::getUnoTunnelId() ))); + 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); + } -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; } /** the UNO3_GETIMPLEMENTATION_* macros implement a static helper function @@ -63,7 +115,7 @@ inline bool isUnoTunnelId(const css::uno::Sequence< sal_Int8 >& rId) if possible. Example: - MyClass* pClass = comphelper::getUnoTunnelImplementation<MyClass>( xRef ); + MyClass* pClass = comphelper::getFromUnoTunnel<MyClass>( xRef ); Usage: Put a UNO3_GETIMPLEMENTATION_DECL( classname ) inside your class @@ -79,7 +131,7 @@ inline bool isUnoTunnelId(const css::uno::Sequence< sal_Int8 >& rId) #define UNO3_GETIMPLEMENTATION_BASE_IMPL( classname ) \ const css::uno::Sequence< sal_Int8 > & classname::getUnoTunnelId() noexcept \ { \ - static const UnoTunnelIdInit aId; \ + static const comphelper::UnoIdInit aId; \ return aId.getSeq(); \ } @@ -87,25 +139,14 @@ const css::uno::Sequence< sal_Int8 > & classname::getUnoTunnelId() noexcept \ UNO3_GETIMPLEMENTATION_BASE_IMPL(classname)\ sal_Int64 SAL_CALL classname::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) \ { \ - if( isUnoTunnelId<classname>(rId) ) \ - { \ - return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); \ - } \ - return 0; \ + 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 ) \ { \ - if( isUnoTunnelId<classname>(rId) ) \ - { \ - return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); \ - } \ - else \ - { \ - return baseclass::getSomething( rId ); \ - } \ + return comphelper::getSomethingImpl(rId, this, comphelper::FallbackToGetSomethingOf<baseclass>{}); \ } |