summaryrefslogtreecommitdiffstats
path: root/stoc/source/corereflection/base.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'stoc/source/corereflection/base.hxx')
-rw-r--r--stoc/source/corereflection/base.hxx424
1 files changed, 424 insertions, 0 deletions
diff --git a/stoc/source/corereflection/base.hxx b/stoc/source/corereflection/base.hxx
new file mode 100644
index 000000000..16d42213d
--- /dev/null
+++ b/stoc/source/corereflection/base.hxx
@@ -0,0 +1,424 @@
+/* -*- 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 .
+ */
+// #define TEST_LIST_CLASSES
+
+#ifndef INCLUDED_STOC_SOURCE_COREREFLECTION_BASE_HXX
+#define INCLUDED_STOC_SOURCE_COREREFLECTION_BASE_HXX
+
+#include <sal/config.h>
+
+#include <o3tl/any.hxx>
+#include <osl/mutex.hxx>
+#include <uno/mapping.hxx>
+#include <uno/dispatcher.h>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/component.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ref.hxx>
+
+#include "lrucache.hxx"
+
+#ifdef TEST_LIST_CLASSES
+#include <vector>
+#include <algorithm>
+#endif
+#include <unordered_map>
+#include <memory>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+
+namespace com::sun::star::uno { class XComponentContext; }
+namespace com::sun::star::reflection { class XIdlClass; }
+namespace com::sun::star::reflection { class XIdlField; }
+namespace com::sun::star::reflection { class XIdlMethod; }
+
+namespace stoc_corefl
+{
+
+#ifdef TEST_LIST_CLASSES
+extern std::vector<OUString> g_aClassNames;
+#endif
+
+
+::osl::Mutex & getMutexAccess();
+
+
+inline bool td_equals( typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType )
+{
+ return (pTD->pWeakRef == pType ||
+ (pTD->pTypeName->length == pType->pTypeName->length &&
+ rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0));
+}
+
+typedef std::unordered_map< OUString, css::uno::WeakReference< css::reflection::XIdlField > > OUString2Field;
+typedef std::unordered_map< OUString, css::uno::WeakReference< css::reflection::XIdlMethod > > OUString2Method;
+
+
+class IdlReflectionServiceImpl
+ : public ::cppu::OComponentHelper
+ , public css::reflection::XIdlReflection
+ , public css::container::XHierarchicalNameAccess
+ , public css::lang::XServiceInfo
+{
+ ::osl::Mutex _aComponentMutex;
+ css::uno::Reference< css::container::XHierarchicalNameAccess > _xTDMgr;
+
+ // caching
+ LRU_CacheAnyByOUString _aElements;
+
+ css::uno::Mapping _aCpp2Uno;
+ css::uno::Mapping _aUno2Cpp;
+
+ inline css::uno::Reference< css::reflection::XIdlClass > constructClass( typelib_TypeDescription * pTypeDescr );
+
+public:
+ /// @throws css::uno::RuntimeException
+ const css::uno::Mapping & getCpp2Uno();
+ /// @throws css::uno::RuntimeException
+ const css::uno::Mapping & getUno2Cpp();
+ /// @throws css::uno::RuntimeException
+ uno_Interface * mapToUno( const css::uno::Any & rObj, typelib_InterfaceTypeDescription * pTo );
+
+ // ctor/ dtor
+ explicit IdlReflectionServiceImpl( const css::uno::Reference< css::uno::XComponentContext > & xContext );
+ virtual ~IdlReflectionServiceImpl() override;
+
+ // XInterface
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override;
+ virtual void SAL_CALL acquire() noexcept override;
+ virtual void SAL_CALL release() noexcept override;
+
+ // some XComponent part from OComponentHelper
+ virtual void SAL_CALL dispose() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ // XTypeProvider
+ virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override;
+ virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
+
+ // XIdlReflection
+ virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL forName( const OUString & rTypeName ) override;
+ virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getType( const css::uno::Any & rObj ) override;
+
+ // XHierarchicalNameAccess
+ virtual css::uno::Any SAL_CALL getByHierarchicalName( const OUString & rName ) override;
+ virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) override;
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::reflection::XIdlClass > forType( typelib_TypeDescription * pTypeDescr );
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::reflection::XIdlClass > forType( typelib_TypeDescriptionReference * pRef );
+};
+
+
+class IdlClassImpl
+ : public ::cppu::WeakImplHelper< css::reflection::XIdlClass >
+{
+ rtl::Reference<IdlReflectionServiceImpl>
+ m_xReflection;
+
+ OUString _aName;
+ css::uno::TypeClass _eTypeClass;
+
+ typelib_TypeDescription * _pTypeDescr;
+
+public:
+ typelib_TypeDescription * getTypeDescr() const
+ { return _pTypeDescr; }
+ IdlReflectionServiceImpl * getReflection() const
+ { return m_xReflection.get(); }
+
+ // Ctor
+ IdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr );
+ virtual ~IdlClassImpl() override;
+
+ // XIdlClassImpl default implementation
+ virtual css::uno::TypeClass SAL_CALL getTypeClass() override;
+ virtual OUString SAL_CALL getName() override;
+ virtual sal_Bool SAL_CALL equals( const css::uno::Reference< css::reflection::XIdlClass >& xType ) override;
+
+ virtual sal_Bool SAL_CALL isAssignableFrom( const css::uno::Reference< css::reflection::XIdlClass > & xType ) override;
+ virtual void SAL_CALL createObject( css::uno::Any & rObj ) override;
+
+ // def impl ????
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getClasses() override;
+ virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getClass( const OUString & rName ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getInterfaces() override;
+
+ // structs, interfaces
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getSuperclasses() override;
+ // structs
+ virtual css::uno::Reference< css::reflection::XIdlField > SAL_CALL getField( const OUString & rName ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > SAL_CALL getFields() override;
+ // interfaces
+ virtual css::uno::Uik SAL_CALL getUik() override;
+ virtual css::uno::Reference< css::reflection::XIdlMethod > SAL_CALL getMethod( const OUString & rName ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlMethod > > SAL_CALL getMethods() override;
+ // array
+ virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getComponentType() override;
+ virtual css::uno::Reference< css::reflection::XIdlArray > SAL_CALL getArray() override;
+};
+
+
+class InterfaceIdlClassImpl
+ : public IdlClassImpl
+{
+ typedef std::pair< OUString, typelib_TypeDescription * > MemberInit;
+
+ css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > _xSuperClasses;
+
+ std::unique_ptr<MemberInit[]> _pSortedMemberInit; // first methods, then attributes
+ OUString2Field _aName2Field;
+ OUString2Method _aName2Method;
+ sal_Int32 _nMethods;
+ sal_Int32 _nAttributes;
+
+ void initMembers();
+
+public:
+ typelib_InterfaceTypeDescription * getTypeDescr() const
+ { return reinterpret_cast<typelib_InterfaceTypeDescription *>(IdlClassImpl::getTypeDescr()); }
+
+ // ctor/ dtor
+ InterfaceIdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr )
+ : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
+ , _nMethods( 0 )
+ , _nAttributes( 0 )
+ {}
+ virtual ~InterfaceIdlClassImpl() override;
+
+ // IdlClassImpl modifications
+ virtual sal_Bool SAL_CALL isAssignableFrom( const css::uno::Reference< css::reflection::XIdlClass > & xType ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getSuperclasses() override;
+ virtual css::uno::Uik SAL_CALL getUik() override;
+ virtual css::uno::Reference< css::reflection::XIdlMethod > SAL_CALL getMethod( const OUString & rName ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlMethod > > SAL_CALL getMethods() override;
+ virtual css::uno::Reference< css::reflection::XIdlField > SAL_CALL getField( const OUString & rName ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > SAL_CALL getFields() override;
+ virtual void SAL_CALL createObject( css::uno::Any & rObj ) override;
+};
+
+
+class CompoundIdlClassImpl
+ : public IdlClassImpl
+{
+ css::uno::Reference< css::reflection::XIdlClass >
+ _xSuperClass;
+ std::optional< css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > >
+ m_xFields;
+ OUString2Field _aName2Field;
+
+public:
+ typelib_CompoundTypeDescription * getTypeDescr() const
+ { return reinterpret_cast<typelib_CompoundTypeDescription *>(IdlClassImpl::getTypeDescr()); }
+
+ // ctor/ dtor
+ CompoundIdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr )
+ : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
+ {}
+ virtual ~CompoundIdlClassImpl() override;
+
+ // IdlClassImpl modifications
+ virtual sal_Bool SAL_CALL isAssignableFrom( const css::uno::Reference< css::reflection::XIdlClass > & xType ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getSuperclasses() override;
+ virtual css::uno::Reference< css::reflection::XIdlField > SAL_CALL getField( const OUString & rName ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > SAL_CALL getFields() override;
+};
+
+
+class ArrayIdlClassImpl
+ : public IdlClassImpl
+ , public css::reflection::XIdlArray
+{
+public:
+ typelib_IndirectTypeDescription * getTypeDescr() const
+ { return reinterpret_cast<typelib_IndirectTypeDescription *>(IdlClassImpl::getTypeDescr()); }
+
+ // ctor
+ ArrayIdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr )
+ : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
+ {}
+
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override;
+ virtual void SAL_CALL acquire() noexcept override;
+ virtual void SAL_CALL release() noexcept override;
+
+ // XTypeProvider
+ virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override;
+ virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
+
+ // IdlClassImpl modifications
+ virtual sal_Bool SAL_CALL isAssignableFrom( const css::uno::Reference< css::reflection::XIdlClass > & xType ) override;
+ virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getComponentType() override;
+ virtual css::uno::Reference< css::reflection::XIdlArray > SAL_CALL getArray() override;
+
+ // XIdlArray
+ virtual void SAL_CALL realloc( css::uno::Any & rArray, sal_Int32 nLen ) override;
+ virtual sal_Int32 SAL_CALL getLen( const css::uno::Any & rArray ) override;
+ virtual css::uno::Any SAL_CALL get( const css::uno::Any & rArray, sal_Int32 nIndex ) override;
+ virtual void SAL_CALL set( css::uno::Any & rArray, sal_Int32 nIndex, const css::uno::Any & rNewValue ) override;
+};
+
+
+class EnumIdlClassImpl
+ : public IdlClassImpl
+{
+ std::optional< css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > > m_xFields;
+ OUString2Field _aName2Field;
+
+public:
+ typelib_EnumTypeDescription * getTypeDescr() const
+ { return reinterpret_cast<typelib_EnumTypeDescription *>(IdlClassImpl::getTypeDescr()); }
+
+ // ctor/ dtor
+ EnumIdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr )
+ : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
+ {}
+ virtual ~EnumIdlClassImpl() override;
+
+ // IdlClassImpl modifications
+ virtual css::uno::Reference< css::reflection::XIdlField > SAL_CALL getField( const OUString & rName ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > SAL_CALL getFields() override;
+ virtual void SAL_CALL createObject( css::uno::Any & rObj ) override;
+};
+
+
+class IdlMemberImpl
+ : public ::cppu::WeakImplHelper< css::reflection::XIdlMember >
+{
+ rtl::Reference<IdlReflectionServiceImpl>
+ m_xReflection;
+ OUString _aName;
+
+ typelib_TypeDescription * _pTypeDescr;
+ typelib_TypeDescription * _pDeclTypeDescr;
+
+protected:
+ css::uno::Reference< css::reflection::XIdlClass > _xDeclClass;
+
+public:
+ IdlReflectionServiceImpl * getReflection() const
+ { return m_xReflection.get(); }
+ typelib_TypeDescription * getTypeDescr() const
+ { return _pTypeDescr; }
+ typelib_TypeDescription * getDeclTypeDescr() const
+ { return _pDeclTypeDescr; }
+
+ // ctor/ dtor
+ IdlMemberImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
+ typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr );
+ virtual ~IdlMemberImpl() override;
+
+ // XIdlMember
+ virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getDeclaringClass() override;
+ virtual OUString SAL_CALL getName() override;
+};
+
+
+// coerces to type descr pTo else queries for it: the interface pointer is returned via rDest
+// ## type to XidlClass coercion possible
+inline bool extract(
+ const css::uno::Any & rObj, typelib_InterfaceTypeDescription * pTo,
+ css::uno::Reference< css::uno::XInterface > & rDest,
+ IdlReflectionServiceImpl * pRefl )
+{
+ rDest.clear();
+ if (nullptr != pTo)
+ {
+ if (! rObj.hasValue())
+ return true;
+ if (rObj.getValueTypeClass() == css::uno::TypeClass_INTERFACE)
+ {
+ return ::uno_type_assignData(
+ &rDest, pTo->aBase.pWeakRef,
+ const_cast< void * >( rObj.getValue() ), rObj.getValueTypeRef(),
+ reinterpret_cast< uno_QueryInterfaceFunc >(css::uno::cpp_queryInterface),
+ reinterpret_cast< uno_AcquireFunc >(css::uno::cpp_acquire),
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release) );
+ }
+ else if (auto t = o3tl::tryAccess<css::uno::Type>(rObj))
+ {
+ rDest = pRefl->forType( t->getTypeLibType() );
+ return rDest.is();
+ }
+ }
+ return false;
+}
+
+inline bool coerce_assign(
+ void * pDest, typelib_TypeDescription * pTD, const css::uno::Any & rSource,
+ IdlReflectionServiceImpl * pRefl )
+{
+ if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
+ {
+ css::uno::Reference< css::uno::XInterface > xVal;
+ if (extract( rSource, reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD), xVal, pRefl ))
+ {
+ if (*static_cast<css::uno::XInterface **>(pDest))
+ (*static_cast<css::uno::XInterface **>(pDest))->release();
+ *static_cast<css::uno::XInterface **>(pDest) = xVal.get();
+ if (*static_cast<css::uno::XInterface **>(pDest))
+ (*static_cast<css::uno::XInterface **>(pDest))->acquire();
+ return true;
+ }
+ return false;
+ }
+ else if (pTD->eTypeClass == typelib_TypeClass_ANY)
+ {
+ return uno_assignData(
+ pDest, pTD,
+ const_cast<css::uno::Any *>(&rSource), pTD,
+ reinterpret_cast< uno_QueryInterfaceFunc >(css::uno::cpp_queryInterface),
+ reinterpret_cast< uno_AcquireFunc >(css::uno::cpp_acquire),
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release) );
+ }
+ else
+ {
+ return uno_type_assignData(
+ pDest, pTD->pWeakRef,
+ const_cast<void *>(rSource.getValue()), rSource.getValueTypeRef(),
+ reinterpret_cast< uno_QueryInterfaceFunc >(css::uno::cpp_queryInterface),
+ reinterpret_cast< uno_AcquireFunc >(css::uno::cpp_acquire),
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release) );
+ }
+}
+
+}
+
+
+#endif // INCLUDED_STOC_SOURCE_COREREFLECTION_BASE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */