Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / stoc / source / corereflection / base.hxx
blob6638493ad3fa39b161888e55004a430faaf8085a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 // #define TEST_LIST_CLASSES
21 #ifndef INCLUDED_STOC_SOURCE_COREREFLECTION_BASE_HXX
22 #define INCLUDED_STOC_SOURCE_COREREFLECTION_BASE_HXX
24 #include <sal/config.h>
26 #include <o3tl/any.hxx>
27 #include <osl/diagnose.h>
28 #include <osl/mutex.hxx>
29 #include <uno/mapping.hxx>
30 #include <uno/dispatcher.h>
31 #include <cppuhelper/implbase.hxx>
32 #include <cppuhelper/weak.hxx>
33 #include <cppuhelper/factory.hxx>
34 #include <cppuhelper/component.hxx>
35 #include <cppuhelper/typeprovider.hxx>
36 #include <rtl/ustring.hxx>
37 #include <rtl/ref.hxx>
39 #include "lrucache.hxx"
41 #ifdef TEST_LIST_CLASSES
42 #include <list>
43 #include <algorithm>
44 #endif
45 #include <unordered_map>
46 #include <memory>
48 #include <com/sun/star/uno/XComponentContext.hpp>
49 #include <com/sun/star/lang/XServiceInfo.hpp>
50 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
52 #include <com/sun/star/reflection/XIdlClass.hpp>
53 #include <com/sun/star/reflection/XIdlReflection.hpp>
54 #include <com/sun/star/reflection/XIdlField.hpp>
55 #include <com/sun/star/reflection/XIdlField2.hpp>
56 #include <com/sun/star/reflection/XIdlMethod.hpp>
58 namespace stoc_corefl
61 #ifdef TEST_LIST_CLASSES
62 typedef std::list< OUString > ClassNameList;
63 extern ClassNameList g_aClassNames;
64 #endif
67 ::osl::Mutex & getMutexAccess();
70 inline bool td_equals( typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType )
72 return (pTD->pWeakRef == pType ||
73 (pTD->pTypeName->length == pType->pTypeName->length &&
74 rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0));
77 typedef std::unordered_map< OUString, css::uno::WeakReference< css::reflection::XIdlField >,
78 OUStringHash > OUString2Field;
79 typedef std::unordered_map< OUString, css::uno::WeakReference< css::reflection::XIdlMethod >,
80 OUStringHash > OUString2Method;
83 class IdlReflectionServiceImpl
84 : public ::cppu::OComponentHelper
85 , public css::reflection::XIdlReflection
86 , public css::container::XHierarchicalNameAccess
87 , public css::lang::XServiceInfo
89 ::osl::Mutex _aComponentMutex;
90 css::uno::Reference< css::container::XHierarchicalNameAccess > _xTDMgr;
92 // caching
93 LRU_CacheAnyByOUString _aElements;
95 css::uno::Mapping _aCpp2Uno;
96 css::uno::Mapping _aUno2Cpp;
98 inline css::uno::Reference< css::reflection::XIdlClass > constructClass( typelib_TypeDescription * pTypeDescr );
100 public:
101 /// @throws css::uno::RuntimeException
102 const css::uno::Mapping & getCpp2Uno();
103 /// @throws css::uno::RuntimeException
104 const css::uno::Mapping & getUno2Cpp();
105 /// @throws css::uno::RuntimeException
106 uno_Interface * mapToUno( const css::uno::Any & rObj, typelib_InterfaceTypeDescription * pTo );
108 // ctor/ dtor
109 explicit IdlReflectionServiceImpl( const css::uno::Reference< css::uno::XComponentContext > & xContext );
110 virtual ~IdlReflectionServiceImpl() override;
112 // XInterface
113 virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override;
114 virtual void SAL_CALL acquire() throw() override;
115 virtual void SAL_CALL release() throw() override;
117 // some XComponent part from OComponentHelper
118 virtual void SAL_CALL dispose() override;
120 // XServiceInfo
121 virtual OUString SAL_CALL getImplementationName() override;
122 virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) override;
123 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
125 // XTypeProvider
126 virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override;
127 virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
129 // XIdlReflection
130 virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL forName( const OUString & rTypeName ) override;
131 virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getType( const css::uno::Any & rObj ) override;
133 // XHierarchicalNameAccess
134 virtual css::uno::Any SAL_CALL getByHierarchicalName( const OUString & rName ) override;
135 virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) override;
137 /// @throws css::uno::RuntimeException
138 css::uno::Reference< css::reflection::XIdlClass > forType( typelib_TypeDescription * pTypeDescr );
139 /// @throws css::uno::RuntimeException
140 css::uno::Reference< css::reflection::XIdlClass > forType( typelib_TypeDescriptionReference * pRef );
144 class IdlClassImpl
145 : public ::cppu::WeakImplHelper< css::reflection::XIdlClass >
147 rtl::Reference<IdlReflectionServiceImpl>
148 m_xReflection;
150 OUString _aName;
151 css::uno::TypeClass _eTypeClass;
153 typelib_TypeDescription * _pTypeDescr;
155 public:
156 typelib_TypeDescription * getTypeDescr() const
157 { return _pTypeDescr; }
158 IdlReflectionServiceImpl * getReflection() const
159 { return m_xReflection.get(); }
161 // Ctor
162 IdlClassImpl( IdlReflectionServiceImpl * pReflection,
163 const OUString & rName, typelib_TypeClass eTypeClass,
164 typelib_TypeDescription * pTypeDescr );
165 virtual ~IdlClassImpl() override;
167 // XIdlClassImpl default implementation
168 virtual css::uno::TypeClass SAL_CALL getTypeClass() override;
169 virtual OUString SAL_CALL getName() override;
170 virtual sal_Bool SAL_CALL equals( const css::uno::Reference< css::reflection::XIdlClass >& xType ) override;
172 virtual sal_Bool SAL_CALL isAssignableFrom( const css::uno::Reference< css::reflection::XIdlClass > & xType ) override;
173 virtual void SAL_CALL createObject( css::uno::Any & rObj ) override;
175 // def impl ????
176 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getClasses() override;
177 virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getClass( const OUString & rName ) override;
178 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getInterfaces() override;
180 // structs, interfaces
181 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getSuperclasses() override;
182 // structs
183 virtual css::uno::Reference< css::reflection::XIdlField > SAL_CALL getField( const OUString & rName ) override;
184 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > SAL_CALL getFields() override;
185 // interfaces
186 virtual css::uno::Uik SAL_CALL getUik() override;
187 virtual css::uno::Reference< css::reflection::XIdlMethod > SAL_CALL getMethod( const OUString & rName ) override;
188 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlMethod > > SAL_CALL getMethods() override;
189 // array
190 virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getComponentType() override;
191 virtual css::uno::Reference< css::reflection::XIdlArray > SAL_CALL getArray() override;
195 class InterfaceIdlClassImpl
196 : public IdlClassImpl
198 typedef std::pair< OUString, typelib_TypeDescription * > MemberInit;
200 css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > _xSuperClasses;
202 MemberInit * _pSortedMemberInit; // first methods, then attributes
203 OUString2Field _aName2Field;
204 OUString2Method _aName2Method;
205 sal_Int32 _nMethods;
206 sal_Int32 _nAttributes;
208 void initMembers();
210 public:
211 typelib_InterfaceTypeDescription * getTypeDescr() const
212 { return reinterpret_cast<typelib_InterfaceTypeDescription *>(IdlClassImpl::getTypeDescr()); }
214 // ctor/ dtor
215 InterfaceIdlClassImpl( IdlReflectionServiceImpl * pReflection,
216 const OUString & rName, typelib_TypeClass eTypeClass,
217 typelib_TypeDescription * pTypeDescr )
218 : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
219 , _pSortedMemberInit( nullptr )
220 , _nMethods( 0 )
221 , _nAttributes( 0 )
223 virtual ~InterfaceIdlClassImpl() override;
225 // IdlClassImpl modifications
226 virtual sal_Bool SAL_CALL isAssignableFrom( const css::uno::Reference< css::reflection::XIdlClass > & xType ) override;
227 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getSuperclasses() override;
228 virtual css::uno::Uik SAL_CALL getUik() override;
229 virtual css::uno::Reference< css::reflection::XIdlMethod > SAL_CALL getMethod( const OUString & rName ) override;
230 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlMethod > > SAL_CALL getMethods() override;
231 virtual css::uno::Reference< css::reflection::XIdlField > SAL_CALL getField( const OUString & rName ) override;
232 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > SAL_CALL getFields() override;
233 virtual void SAL_CALL createObject( css::uno::Any & rObj ) override;
237 class CompoundIdlClassImpl
238 : public IdlClassImpl
240 css::uno::Reference< css::reflection::XIdlClass >
241 _xSuperClass;
242 std::unique_ptr< css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > >
243 _pFields;
244 OUString2Field _aName2Field;
246 public:
247 typelib_CompoundTypeDescription * getTypeDescr() const
248 { return reinterpret_cast<typelib_CompoundTypeDescription *>(IdlClassImpl::getTypeDescr()); }
250 // ctor/ dtor
251 CompoundIdlClassImpl( IdlReflectionServiceImpl * pReflection,
252 const OUString & rName, typelib_TypeClass eTypeClass,
253 typelib_TypeDescription * pTypeDescr )
254 : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
255 , _pFields( nullptr )
257 virtual ~CompoundIdlClassImpl() override;
259 // IdlClassImpl modifications
260 virtual sal_Bool SAL_CALL isAssignableFrom( const css::uno::Reference< css::reflection::XIdlClass > & xType ) override;
261 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlClass > > SAL_CALL getSuperclasses() override;
262 virtual css::uno::Reference< css::reflection::XIdlField > SAL_CALL getField( const OUString & rName ) override;
263 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > SAL_CALL getFields() override;
267 class ArrayIdlClassImpl
268 : public IdlClassImpl
269 , public css::reflection::XIdlArray
271 public:
272 typelib_IndirectTypeDescription * getTypeDescr() const
273 { return reinterpret_cast<typelib_IndirectTypeDescription *>(IdlClassImpl::getTypeDescr()); }
275 // ctor
276 ArrayIdlClassImpl( IdlReflectionServiceImpl * pReflection,
277 const OUString & rName, typelib_TypeClass eTypeClass,
278 typelib_TypeDescription * pTypeDescr )
279 : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
282 virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override;
283 virtual void SAL_CALL acquire() throw() override;
284 virtual void SAL_CALL release() throw() override;
286 // XTypeProvider
287 virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override;
288 virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
290 // IdlClassImpl modifications
291 virtual sal_Bool SAL_CALL isAssignableFrom( const css::uno::Reference< css::reflection::XIdlClass > & xType ) override;
292 virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getComponentType() override;
293 virtual css::uno::Reference< css::reflection::XIdlArray > SAL_CALL getArray() override;
295 // XIdlArray
296 virtual void SAL_CALL realloc( css::uno::Any & rArray, sal_Int32 nLen ) override;
297 virtual sal_Int32 SAL_CALL getLen( const css::uno::Any & rArray ) override;
298 virtual css::uno::Any SAL_CALL get( const css::uno::Any & rArray, sal_Int32 nIndex ) override;
299 virtual void SAL_CALL set( css::uno::Any & rArray, sal_Int32 nIndex, const css::uno::Any & rNewValue ) override;
303 class EnumIdlClassImpl
304 : public IdlClassImpl
306 std::unique_ptr< css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > > _pFields;
307 OUString2Field _aName2Field;
309 public:
310 typelib_EnumTypeDescription * getTypeDescr() const
311 { return reinterpret_cast<typelib_EnumTypeDescription *>(IdlClassImpl::getTypeDescr()); }
313 // ctor/ dtor
314 EnumIdlClassImpl( IdlReflectionServiceImpl * pReflection,
315 const OUString & rName, typelib_TypeClass eTypeClass,
316 typelib_TypeDescription * pTypeDescr )
317 : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
318 , _pFields( nullptr )
320 virtual ~EnumIdlClassImpl() override;
322 // IdlClassImpl modifications
323 virtual css::uno::Reference< css::reflection::XIdlField > SAL_CALL getField( const OUString & rName ) override;
324 virtual css::uno::Sequence< css::uno::Reference< css::reflection::XIdlField > > SAL_CALL getFields() override;
325 virtual void SAL_CALL createObject( css::uno::Any & rObj ) override;
329 class IdlMemberImpl
330 : public ::cppu::WeakImplHelper< css::reflection::XIdlMember >
332 rtl::Reference<IdlReflectionServiceImpl>
333 m_xReflection;
334 OUString _aName;
336 typelib_TypeDescription * _pTypeDescr;
337 typelib_TypeDescription * _pDeclTypeDescr;
339 protected:
340 css::uno::Reference< css::reflection::XIdlClass > _xDeclClass;
342 public:
343 IdlReflectionServiceImpl * getReflection() const
344 { return m_xReflection.get(); }
345 typelib_TypeDescription * getTypeDescr() const
346 { return _pTypeDescr; }
347 typelib_TypeDescription * getDeclTypeDescr() const
348 { return _pDeclTypeDescr; }
350 // ctor/ dtor
351 IdlMemberImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
352 typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr );
353 virtual ~IdlMemberImpl() override;
355 // XIdlMember
356 virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getDeclaringClass() override;
357 virtual OUString SAL_CALL getName() override;
361 // coerces to type descr pTo else queries for it: the interface pointer is returned via rDest
362 // ## type to XidlClass coercion possible
363 inline bool extract(
364 const css::uno::Any & rObj, typelib_InterfaceTypeDescription * pTo,
365 css::uno::Reference< css::uno::XInterface > & rDest,
366 IdlReflectionServiceImpl * pRefl )
368 rDest.clear();
369 if (nullptr != pTo)
371 if (! rObj.hasValue())
372 return true;
373 if (rObj.getValueTypeClass() == css::uno::TypeClass_INTERFACE)
375 return ::uno_type_assignData(
376 &rDest, pTo->aBase.pWeakRef,
377 const_cast< void * >( rObj.getValue() ), rObj.getValueTypeRef(),
378 reinterpret_cast< uno_QueryInterfaceFunc >(css::uno::cpp_queryInterface),
379 reinterpret_cast< uno_AcquireFunc >(css::uno::cpp_acquire),
380 reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release) );
382 else if (auto t = o3tl::tryAccess<css::uno::Type>(rObj))
384 rDest = pRefl->forType( t->getTypeLibType() );
385 return rDest.is();
388 return false;
391 inline bool coerce_assign(
392 void * pDest, typelib_TypeDescription * pTD, const css::uno::Any & rSource,
393 IdlReflectionServiceImpl * pRefl )
395 if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
397 css::uno::Reference< css::uno::XInterface > xVal;
398 if (extract( rSource, reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD), xVal, pRefl ))
400 if (*static_cast<css::uno::XInterface **>(pDest))
401 (*static_cast<css::uno::XInterface **>(pDest))->release();
402 *static_cast<css::uno::XInterface **>(pDest) = xVal.get();
403 if (*static_cast<css::uno::XInterface **>(pDest))
404 (*static_cast<css::uno::XInterface **>(pDest))->acquire();
405 return true;
407 return false;
409 else if (pTD->eTypeClass == typelib_TypeClass_ANY)
411 return uno_assignData(
412 pDest, pTD,
413 const_cast<css::uno::Any *>(&rSource), pTD,
414 reinterpret_cast< uno_QueryInterfaceFunc >(css::uno::cpp_queryInterface),
415 reinterpret_cast< uno_AcquireFunc >(css::uno::cpp_acquire),
416 reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release) );
418 else
420 return uno_type_assignData(
421 pDest, pTD->pWeakRef,
422 const_cast<void *>(rSource.getValue()), rSource.getValueTypeRef(),
423 reinterpret_cast< uno_QueryInterfaceFunc >(css::uno::cpp_queryInterface),
424 reinterpret_cast< uno_AcquireFunc >(css::uno::cpp_acquire),
425 reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release) );
432 #endif // INCLUDED_STOC_SOURCE_COREREFLECTION_BASE_HXX
434 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */