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
23 #include <sal/config.h>
25 #include <o3tl/any.hxx>
26 #include <osl/mutex.hxx>
27 #include <uno/mapping.hxx>
28 #include <uno/dispatcher.h>
29 #include <cppuhelper/implbase.hxx>
30 #include <cppuhelper/compbase.hxx>
31 #include <rtl/ustring.hxx>
32 #include <rtl/ref.hxx>
34 #include "lrucache.hxx"
36 #ifdef TEST_LIST_CLASSES
40 #include <unordered_map>
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
46 #include <com/sun/star/reflection/XIdlReflection.hpp>
48 namespace com::sun::star::uno
{ class XComponentContext
; }
49 namespace com::sun::star::reflection
{ class XIdlClass
; }
50 namespace com::sun::star::reflection
{ class XIdlField
; }
51 namespace com::sun::star::reflection
{ class XIdlMethod
; }
56 #ifdef TEST_LIST_CLASSES
57 extern std::vector
<OUString
> g_aClassNames
;
61 ::osl::Mutex
& getMutexAccess();
64 inline bool td_equals( typelib_TypeDescription
* pTD
, typelib_TypeDescriptionReference
* pType
)
66 return (pTD
->pWeakRef
== pType
||
67 (pTD
->pTypeName
->length
== pType
->pTypeName
->length
&&
68 rtl_ustr_compare( pTD
->pTypeName
->buffer
, pType
->pTypeName
->buffer
) == 0));
71 typedef std::unordered_map
< OUString
, css::uno::WeakReference
< css::reflection::XIdlField
> > OUString2Field
;
72 typedef std::unordered_map
< OUString
, css::uno::WeakReference
< css::reflection::XIdlMethod
> > OUString2Method
;
75 class IdlReflectionServiceImpl
76 : public ::cppu::WeakComponentImplHelper
<
77 css::reflection::XIdlReflection
,
78 css::container::XHierarchicalNameAccess
,
79 css::lang::XServiceInfo
>
81 ::osl::Mutex _aComponentMutex
;
82 css::uno::Reference
< css::container::XHierarchicalNameAccess
> _xTDMgr
;
85 LRU_CacheAnyByOUString _aElements
;
87 css::uno::Mapping _aCpp2Uno
;
88 css::uno::Mapping _aUno2Cpp
;
90 inline css::uno::Reference
< css::reflection::XIdlClass
> constructClass( typelib_TypeDescription
* pTypeDescr
);
93 /// @throws css::uno::RuntimeException
94 const css::uno::Mapping
& getCpp2Uno();
95 /// @throws css::uno::RuntimeException
96 const css::uno::Mapping
& getUno2Cpp();
97 /// @throws css::uno::RuntimeException
98 uno_Interface
* mapToUno( const css::uno::Any
& rObj
, typelib_InterfaceTypeDescription
* pTo
);
101 explicit IdlReflectionServiceImpl( const css::uno::Reference
< css::uno::XComponentContext
> & xContext
);
102 virtual ~IdlReflectionServiceImpl() override
;
104 // WeakComponentImplHelper
105 virtual void SAL_CALL
disposing() override
;
108 virtual OUString SAL_CALL
getImplementationName() override
;
109 virtual sal_Bool SAL_CALL
supportsService( const OUString
& rServiceName
) override
;
110 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
113 virtual css::uno::Reference
< css::reflection::XIdlClass
> SAL_CALL
forName( const OUString
& rTypeName
) override
;
114 virtual css::uno::Reference
< css::reflection::XIdlClass
> SAL_CALL
getType( const css::uno::Any
& rObj
) override
;
116 // XHierarchicalNameAccess
117 virtual css::uno::Any SAL_CALL
getByHierarchicalName( const OUString
& rName
) override
;
118 virtual sal_Bool SAL_CALL
hasByHierarchicalName( const OUString
& rName
) override
;
120 /// @throws css::uno::RuntimeException
121 css::uno::Reference
< css::reflection::XIdlClass
> forType( typelib_TypeDescription
* pTypeDescr
);
122 /// @throws css::uno::RuntimeException
123 css::uno::Reference
< css::reflection::XIdlClass
> forType( typelib_TypeDescriptionReference
* pRef
);
128 : public ::cppu::WeakImplHelper
< css::reflection::XIdlClass
>
130 rtl::Reference
<IdlReflectionServiceImpl
>
134 css::uno::TypeClass _eTypeClass
;
136 typelib_TypeDescription
* _pTypeDescr
;
139 typelib_TypeDescription
* getTypeDescr() const
140 { return _pTypeDescr
; }
141 IdlReflectionServiceImpl
* getReflection() const
142 { return m_xReflection
.get(); }
145 IdlClassImpl( IdlReflectionServiceImpl
* pReflection
,
146 OUString aName
, typelib_TypeClass eTypeClass
,
147 typelib_TypeDescription
* pTypeDescr
);
148 virtual ~IdlClassImpl() override
;
150 // XIdlClassImpl default implementation
151 virtual css::uno::TypeClass SAL_CALL
getTypeClass() override
;
152 virtual OUString SAL_CALL
getName() override
;
153 virtual sal_Bool SAL_CALL
equals( const css::uno::Reference
< css::reflection::XIdlClass
>& xType
) override
;
155 virtual sal_Bool SAL_CALL
isAssignableFrom( const css::uno::Reference
< css::reflection::XIdlClass
> & xType
) override
;
156 virtual void SAL_CALL
createObject( css::uno::Any
& rObj
) override
;
159 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlClass
> > SAL_CALL
getClasses() override
;
160 virtual css::uno::Reference
< css::reflection::XIdlClass
> SAL_CALL
getClass( const OUString
& rName
) override
;
161 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlClass
> > SAL_CALL
getInterfaces() override
;
163 // structs, interfaces
164 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlClass
> > SAL_CALL
getSuperclasses() override
;
166 virtual css::uno::Reference
< css::reflection::XIdlField
> SAL_CALL
getField( const OUString
& rName
) override
;
167 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlField
> > SAL_CALL
getFields() override
;
169 virtual css::uno::Uik SAL_CALL
getUik() override
;
170 virtual css::uno::Reference
< css::reflection::XIdlMethod
> SAL_CALL
getMethod( const OUString
& rName
) override
;
171 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlMethod
> > SAL_CALL
getMethods() override
;
173 virtual css::uno::Reference
< css::reflection::XIdlClass
> SAL_CALL
getComponentType() override
;
174 virtual css::uno::Reference
< css::reflection::XIdlArray
> SAL_CALL
getArray() override
;
178 class InterfaceIdlClassImpl
179 : public IdlClassImpl
181 typedef std::pair
< OUString
, typelib_TypeDescription
* > MemberInit
;
183 css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlClass
> > _xSuperClasses
;
185 std::unique_ptr
<MemberInit
[]> _pSortedMemberInit
; // first methods, then attributes
186 OUString2Field _aName2Field
;
187 OUString2Method _aName2Method
;
189 sal_Int32 _nAttributes
;
194 typelib_InterfaceTypeDescription
* getTypeDescr() const
195 { return reinterpret_cast<typelib_InterfaceTypeDescription
*>(IdlClassImpl::getTypeDescr()); }
198 InterfaceIdlClassImpl( IdlReflectionServiceImpl
* pReflection
,
199 const OUString
& rName
, typelib_TypeClass eTypeClass
,
200 typelib_TypeDescription
* pTypeDescr
)
201 : IdlClassImpl( pReflection
, rName
, eTypeClass
, pTypeDescr
)
205 virtual ~InterfaceIdlClassImpl() override
;
207 // IdlClassImpl modifications
208 virtual sal_Bool SAL_CALL
isAssignableFrom( const css::uno::Reference
< css::reflection::XIdlClass
> & xType
) override
;
209 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlClass
> > SAL_CALL
getSuperclasses() override
;
210 virtual css::uno::Uik SAL_CALL
getUik() override
;
211 virtual css::uno::Reference
< css::reflection::XIdlMethod
> SAL_CALL
getMethod( const OUString
& rName
) override
;
212 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlMethod
> > SAL_CALL
getMethods() override
;
213 virtual css::uno::Reference
< css::reflection::XIdlField
> SAL_CALL
getField( const OUString
& rName
) override
;
214 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlField
> > SAL_CALL
getFields() override
;
215 virtual void SAL_CALL
createObject( css::uno::Any
& rObj
) override
;
219 class CompoundIdlClassImpl
220 : public IdlClassImpl
222 css::uno::Reference
< css::reflection::XIdlClass
>
224 std::optional
< css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlField
> > >
226 OUString2Field _aName2Field
;
229 typelib_CompoundTypeDescription
* getTypeDescr() const
230 { return reinterpret_cast<typelib_CompoundTypeDescription
*>(IdlClassImpl::getTypeDescr()); }
233 CompoundIdlClassImpl( IdlReflectionServiceImpl
* pReflection
,
234 const OUString
& rName
, typelib_TypeClass eTypeClass
,
235 typelib_TypeDescription
* pTypeDescr
)
236 : IdlClassImpl( pReflection
, rName
, eTypeClass
, pTypeDescr
)
238 virtual ~CompoundIdlClassImpl() override
;
240 // IdlClassImpl modifications
241 virtual sal_Bool SAL_CALL
isAssignableFrom( const css::uno::Reference
< css::reflection::XIdlClass
> & xType
) override
;
242 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlClass
> > SAL_CALL
getSuperclasses() override
;
243 virtual css::uno::Reference
< css::reflection::XIdlField
> SAL_CALL
getField( const OUString
& rName
) override
;
244 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlField
> > SAL_CALL
getFields() override
;
248 typedef cppu::ImplInheritanceHelper
<IdlClassImpl
, css::reflection::XIdlArray
> ArrayIdlClassImpl_Base
;
249 class ArrayIdlClassImpl
: public ArrayIdlClassImpl_Base
252 typelib_IndirectTypeDescription
* getTypeDescr() const
253 { return reinterpret_cast<typelib_IndirectTypeDescription
*>(IdlClassImpl::getTypeDescr()); }
256 ArrayIdlClassImpl( IdlReflectionServiceImpl
* pReflection
,
257 const OUString
& rName
, typelib_TypeClass eTypeClass
,
258 typelib_TypeDescription
* pTypeDescr
)
259 : ArrayIdlClassImpl_Base( pReflection
, rName
, eTypeClass
, pTypeDescr
)
262 // IdlClassImpl modifications
263 virtual sal_Bool SAL_CALL
isAssignableFrom( const css::uno::Reference
< css::reflection::XIdlClass
> & xType
) override
;
264 virtual css::uno::Reference
< css::reflection::XIdlClass
> SAL_CALL
getComponentType() override
;
265 virtual css::uno::Reference
< css::reflection::XIdlArray
> SAL_CALL
getArray() override
;
268 virtual void SAL_CALL
realloc( css::uno::Any
& rArray
, sal_Int32 nLen
) override
;
269 virtual sal_Int32 SAL_CALL
getLen( const css::uno::Any
& rArray
) override
;
270 virtual css::uno::Any SAL_CALL
get( const css::uno::Any
& rArray
, sal_Int32 nIndex
) override
;
271 virtual void SAL_CALL
set( css::uno::Any
& rArray
, sal_Int32 nIndex
, const css::uno::Any
& rNewValue
) override
;
275 class EnumIdlClassImpl
276 : public IdlClassImpl
278 std::optional
< css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlField
> > > m_xFields
;
279 OUString2Field _aName2Field
;
282 typelib_EnumTypeDescription
* getTypeDescr() const
283 { return reinterpret_cast<typelib_EnumTypeDescription
*>(IdlClassImpl::getTypeDescr()); }
286 EnumIdlClassImpl( IdlReflectionServiceImpl
* pReflection
,
287 const OUString
& rName
, typelib_TypeClass eTypeClass
,
288 typelib_TypeDescription
* pTypeDescr
)
289 : IdlClassImpl( pReflection
, rName
, eTypeClass
, pTypeDescr
)
291 virtual ~EnumIdlClassImpl() override
;
293 // IdlClassImpl modifications
294 virtual css::uno::Reference
< css::reflection::XIdlField
> SAL_CALL
getField( const OUString
& rName
) override
;
295 virtual css::uno::Sequence
< css::uno::Reference
< css::reflection::XIdlField
> > SAL_CALL
getFields() override
;
296 virtual void SAL_CALL
createObject( css::uno::Any
& rObj
) override
;
301 : public ::cppu::WeakImplHelper
< css::reflection::XIdlMember
>
303 rtl::Reference
<IdlReflectionServiceImpl
>
307 typelib_TypeDescription
* _pTypeDescr
;
308 typelib_TypeDescription
* _pDeclTypeDescr
;
311 css::uno::Reference
< css::reflection::XIdlClass
> _xDeclClass
;
314 IdlReflectionServiceImpl
* getReflection() const
315 { return m_xReflection
.get(); }
316 typelib_TypeDescription
* getTypeDescr() const
317 { return _pTypeDescr
; }
318 typelib_TypeDescription
* getDeclTypeDescr() const
319 { return _pDeclTypeDescr
; }
322 IdlMemberImpl( IdlReflectionServiceImpl
* pReflection
, OUString aName
,
323 typelib_TypeDescription
* pTypeDescr
, typelib_TypeDescription
* pDeclTypeDescr
);
324 virtual ~IdlMemberImpl() override
;
327 virtual css::uno::Reference
< css::reflection::XIdlClass
> SAL_CALL
getDeclaringClass() override
;
328 virtual OUString SAL_CALL
getName() override
;
332 // coerces to type descr pTo else queries for it: the interface pointer is returned via rDest
333 // ## type to XidlClass coercion possible
335 const css::uno::Any
& rObj
, typelib_InterfaceTypeDescription
* pTo
,
336 css::uno::Reference
< css::uno::XInterface
> & rDest
,
337 IdlReflectionServiceImpl
* pRefl
)
342 if (! rObj
.hasValue())
344 if (rObj
.getValueTypeClass() == css::uno::TypeClass_INTERFACE
)
346 return ::uno_type_assignData(
347 &rDest
, pTo
->aBase
.pWeakRef
,
348 const_cast< void * >( rObj
.getValue() ), rObj
.getValueTypeRef(),
349 reinterpret_cast< uno_QueryInterfaceFunc
>(css::uno::cpp_queryInterface
),
350 reinterpret_cast< uno_AcquireFunc
>(css::uno::cpp_acquire
),
351 reinterpret_cast< uno_ReleaseFunc
>(css::uno::cpp_release
) );
353 else if (auto t
= o3tl::tryAccess
<css::uno::Type
>(rObj
))
355 rDest
= pRefl
->forType( t
->getTypeLibType() );
362 inline bool coerce_assign(
363 void * pDest
, typelib_TypeDescription
* pTD
, const css::uno::Any
& rSource
,
364 IdlReflectionServiceImpl
* pRefl
)
366 if (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
)
368 css::uno::Reference
< css::uno::XInterface
> xVal
;
369 if (extract( rSource
, reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
), xVal
, pRefl
))
371 if (*static_cast<css::uno::XInterface
**>(pDest
))
372 (*static_cast<css::uno::XInterface
**>(pDest
))->release();
373 *static_cast<css::uno::XInterface
**>(pDest
) = xVal
.get();
374 if (*static_cast<css::uno::XInterface
**>(pDest
))
375 (*static_cast<css::uno::XInterface
**>(pDest
))->acquire();
380 else if (pTD
->eTypeClass
== typelib_TypeClass_ANY
)
382 return uno_assignData(
384 const_cast<css::uno::Any
*>(&rSource
), pTD
,
385 reinterpret_cast< uno_QueryInterfaceFunc
>(css::uno::cpp_queryInterface
),
386 reinterpret_cast< uno_AcquireFunc
>(css::uno::cpp_acquire
),
387 reinterpret_cast< uno_ReleaseFunc
>(css::uno::cpp_release
) );
391 return uno_type_assignData(
392 pDest
, pTD
->pWeakRef
,
393 const_cast<void *>(rSource
.getValue()), rSource
.getValueTypeRef(),
394 reinterpret_cast< uno_QueryInterfaceFunc
>(css::uno::cpp_queryInterface
),
395 reinterpret_cast< uno_AcquireFunc
>(css::uno::cpp_acquire
),
396 reinterpret_cast< uno_ReleaseFunc
>(css::uno::cpp_release
) );
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */