1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
45 #include <unordered_map>
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>
61 #ifdef TEST_LIST_CLASSES
62 typedef std::list
< OUString
> ClassNameList
;
63 extern ClassNameList g_aClassNames
;
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
;
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
);
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
);
109 explicit IdlReflectionServiceImpl( const css::uno::Reference
< css::uno::XComponentContext
> & xContext
);
110 virtual ~IdlReflectionServiceImpl() override
;
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
;
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
;
126 virtual css::uno::Sequence
< css::uno::Type
> SAL_CALL
getTypes() override
;
127 virtual css::uno::Sequence
< sal_Int8
> SAL_CALL
getImplementationId() override
;
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
);
145 : public ::cppu::WeakImplHelper
< css::reflection::XIdlClass
>
147 rtl::Reference
<IdlReflectionServiceImpl
>
151 css::uno::TypeClass _eTypeClass
;
153 typelib_TypeDescription
* _pTypeDescr
;
156 typelib_TypeDescription
* getTypeDescr() const
157 { return _pTypeDescr
; }
158 IdlReflectionServiceImpl
* getReflection() const
159 { return m_xReflection
.get(); }
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
;
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
;
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
;
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
;
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
;
206 sal_Int32 _nAttributes
;
211 typelib_InterfaceTypeDescription
* getTypeDescr() const
212 { return reinterpret_cast<typelib_InterfaceTypeDescription
*>(IdlClassImpl::getTypeDescr()); }
215 InterfaceIdlClassImpl( IdlReflectionServiceImpl
* pReflection
,
216 const OUString
& rName
, typelib_TypeClass eTypeClass
,
217 typelib_TypeDescription
* pTypeDescr
)
218 : IdlClassImpl( pReflection
, rName
, eTypeClass
, pTypeDescr
)
219 , _pSortedMemberInit( nullptr )
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
>
242 std::unique_ptr
< css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlField
> > >
244 OUString2Field _aName2Field
;
247 typelib_CompoundTypeDescription
* getTypeDescr() const
248 { return reinterpret_cast<typelib_CompoundTypeDescription
*>(IdlClassImpl::getTypeDescr()); }
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
272 typelib_IndirectTypeDescription
* getTypeDescr() const
273 { return reinterpret_cast<typelib_IndirectTypeDescription
*>(IdlClassImpl::getTypeDescr()); }
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
;
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
;
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
;
310 typelib_EnumTypeDescription
* getTypeDescr() const
311 { return reinterpret_cast<typelib_EnumTypeDescription
*>(IdlClassImpl::getTypeDescr()); }
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
;
330 : public ::cppu::WeakImplHelper
< css::reflection::XIdlMember
>
332 rtl::Reference
<IdlReflectionServiceImpl
>
336 typelib_TypeDescription
* _pTypeDescr
;
337 typelib_TypeDescription
* _pDeclTypeDescr
;
340 css::uno::Reference
< css::reflection::XIdlClass
> _xDeclClass
;
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
; }
351 IdlMemberImpl( IdlReflectionServiceImpl
* pReflection
, const OUString
& rName
,
352 typelib_TypeDescription
* pTypeDescr
, typelib_TypeDescription
* pDeclTypeDescr
);
353 virtual ~IdlMemberImpl() override
;
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
364 const css::uno::Any
& rObj
, typelib_InterfaceTypeDescription
* pTo
,
365 css::uno::Reference
< css::uno::XInterface
> & rDest
,
366 IdlReflectionServiceImpl
* pRefl
)
371 if (! rObj
.hasValue())
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() );
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();
409 else if (pTD
->eTypeClass
== typelib_TypeClass_ANY
)
411 return uno_assignData(
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
) );
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: */