dont use GetItemSurrogates for gathering SwFormatINetFormat
[LibreOffice.git] / cppuhelper / source / tdmgr.cxx
bloba5f368f3a45f6ff7d729157cb90c0cf02424bf4b
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 .
21 #include <sal/config.h>
22 #include <sal/log.hxx>
24 #include <vector>
26 #include <osl/diagnose.h>
27 #include <rtl/ustring.hxx>
29 #include <uno/lbnames.h>
30 #include <uno/mapping.hxx>
32 #include <cppuhelper/bootstrap.hxx>
33 #include <cppuhelper/implbase.hxx>
34 #include <typelib/typedescription.h>
36 #include <com/sun/star/lang/XComponent.hpp>
37 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38 #include <com/sun/star/reflection/XTypeDescription.hpp>
39 #include <com/sun/star/reflection/XEnumTypeDescription.hpp>
40 #include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
41 #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
42 #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
43 #include <com/sun/star/reflection/XMethodParameter.hpp>
44 #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
45 #include <com/sun/star/reflection/XInterfaceTypeDescription2.hpp>
46 #include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
47 #include <com/sun/star/reflection/XStructTypeDescription.hpp>
49 #include <memory>
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::reflection;
55 namespace cppu
58 static typelib_TypeDescription * createCTD(
59 Reference< container::XHierarchicalNameAccess > const & access,
60 const Reference< XTypeDescription > & xType );
63 static typelib_TypeDescription * createCTD(
64 const Reference< XCompoundTypeDescription > & xType )
66 typelib_TypeDescription * pRet = nullptr;
67 if (xType.is())
69 typelib_TypeDescription * pBaseType = createCTD(
70 Reference< XCompoundTypeDescription >::query( xType->getBaseType() ) );
71 if (pBaseType)
72 typelib_typedescription_register( &pBaseType );
74 // construct member init array
75 const Sequence<Reference< XTypeDescription > > & rMemberTypes = xType->getMemberTypes();
76 const Sequence< OUString > & rMemberNames = xType->getMemberNames();
78 sal_Int32 nMembers = rMemberTypes.getLength();
79 OSL_ENSURE( nMembers == rMemberNames.getLength(), "### lens differ!" );
81 OUString aTypeName( xType->getName() );
83 typelib_CompoundMember_Init * pMemberInits = static_cast<typelib_CompoundMember_Init *>(alloca(
84 sizeof(typelib_CompoundMember_Init) * nMembers ));
86 sal_Int32 nPos;
87 for ( nPos = nMembers; nPos--; )
89 typelib_CompoundMember_Init & rInit = pMemberInits[nPos];
90 rInit.eTypeClass = static_cast<typelib_TypeClass>(rMemberTypes[nPos]->getTypeClass());
92 OUString aMemberTypeName(rMemberTypes[nPos]->getName());
93 rInit.pTypeName = aMemberTypeName.pData;
94 rtl_uString_acquire( rInit.pTypeName );
96 // string is held by rMemberNames
97 rInit.pMemberName = rMemberNames[nPos].pData;
100 typelib_typedescription_new(
101 &pRet,
102 static_cast<typelib_TypeClass>(xType->getTypeClass()),
103 aTypeName.pData,
104 (pBaseType ? pBaseType->pWeakRef : nullptr),
105 nMembers, pMemberInits );
107 // cleanup
108 for ( nPos = nMembers; nPos--; )
110 rtl_uString_release( pMemberInits[nPos].pTypeName );
112 if (pBaseType)
113 typelib_typedescription_release( pBaseType );
115 return pRet;
118 static typelib_TypeDescription * createCTD(
119 Reference< container::XHierarchicalNameAccess > const & access,
120 const Reference< XStructTypeDescription > & xType )
122 typelib_TypeDescription * pRet = nullptr;
123 if (xType.is() && !xType->getTypeParameters().hasElements())
125 typelib_TypeDescription * pBaseType = createCTD(
126 access, xType->getBaseType() );
127 if (pBaseType)
128 typelib_typedescription_register( &pBaseType );
130 // construct member init array
131 const Sequence<Reference< XTypeDescription > > & rMemberTypes = xType->getMemberTypes();
132 const Sequence< OUString > & rMemberNames = xType->getMemberNames();
134 sal_Int32 nMembers = rMemberTypes.getLength();
135 OSL_ENSURE( nMembers == rMemberNames.getLength(), "### lens differ!" );
137 OUString aTypeName( xType->getName() );
139 typelib_StructMember_Init * pMemberInits = static_cast<typelib_StructMember_Init *>(alloca(
140 sizeof(typelib_StructMember_Init) * nMembers ));
142 Sequence< Reference< XTypeDescription > > templateMemberTypes;
143 sal_Int32 i = aTypeName.indexOf('<');
144 if (i >= 0) {
145 Reference< XStructTypeDescription > templateDesc(
146 access->getByHierarchicalName(aTypeName.copy(0, i)),
147 UNO_QUERY_THROW);
148 OSL_ASSERT(
149 templateDesc->getTypeParameters().getLength()
150 == xType->getTypeArguments().getLength());
151 templateMemberTypes = templateDesc->getMemberTypes();
152 OSL_ASSERT(templateMemberTypes.getLength() == nMembers);
155 sal_Int32 nPos;
156 for ( nPos = nMembers; nPos--; )
158 typelib_StructMember_Init & rInit = pMemberInits[nPos];
159 rInit.aBase.eTypeClass
160 = static_cast<typelib_TypeClass>(rMemberTypes[nPos]->getTypeClass());
162 OUString aMemberTypeName(rMemberTypes[nPos]->getName());
163 rInit.aBase.pTypeName = aMemberTypeName.pData;
164 rtl_uString_acquire( rInit.aBase.pTypeName );
166 // string is held by rMemberNames
167 rInit.aBase.pMemberName = rMemberNames[nPos].pData;
169 rInit.bParameterizedType = templateMemberTypes.hasElements()
170 && (templateMemberTypes[nPos]->getTypeClass()
171 == TypeClass_UNKNOWN);
174 typelib_typedescription_newStruct(
175 &pRet,
176 aTypeName.pData,
177 (pBaseType ? pBaseType->pWeakRef : nullptr),
178 nMembers, pMemberInits );
180 // cleanup
181 for ( nPos = nMembers; nPos--; )
183 rtl_uString_release( pMemberInits[nPos].aBase.pTypeName );
185 if (pBaseType)
186 typelib_typedescription_release( pBaseType );
188 return pRet;
191 static typelib_TypeDescription * createCTD(
192 const Reference< XInterfaceAttributeTypeDescription2 > & xAttribute )
194 typelib_TypeDescription * pRet = nullptr;
195 if (xAttribute.is())
197 OUString aMemberName( xAttribute->getName() );
198 Reference< XTypeDescription > xType( xAttribute->getType() );
199 OUString aMemberTypeName( xType->getName() );
200 std::vector< rtl_uString * > getExc;
201 const Sequence< Reference< XCompoundTypeDescription > > getExcs(
202 xAttribute->getGetExceptions() );
203 for (const auto & ctd : getExcs)
205 OSL_ASSERT( ctd.is() );
206 getExc.push_back( ctd->getName().pData );
208 std::vector< rtl_uString * > setExc;
209 const Sequence< Reference< XCompoundTypeDescription > > setExcs(
210 xAttribute->getSetExceptions() );
211 for (const auto & ctd : setExcs)
213 OSL_ASSERT( ctd.is() );
214 setExc.push_back( ctd->getName().pData );
216 typelib_typedescription_newExtendedInterfaceAttribute(
217 reinterpret_cast<typelib_InterfaceAttributeTypeDescription **>(&pRet),
218 xAttribute->getPosition(),
219 aMemberName.pData, // name
220 static_cast<typelib_TypeClass>(xType->getTypeClass()),
221 aMemberTypeName.pData, // type name
222 xAttribute->isReadOnly(),
223 getExc.size(), getExc.data(),
224 setExc.size(), setExc.data() );
226 return pRet;
229 static typelib_TypeDescription * createCTD(
230 const Reference< XInterfaceMethodTypeDescription > & xMethod )
232 typelib_TypeDescription * pRet = nullptr;
233 if (xMethod.is())
235 Reference< XTypeDescription > xReturnType( xMethod->getReturnType() );
237 // init all params
238 const Sequence<Reference< XMethodParameter > > & rParams = xMethod->getParameters();
239 sal_Int32 nParams = rParams.getLength();
241 typelib_Parameter_Init * pParamInit = static_cast<typelib_Parameter_Init *>(alloca(
242 sizeof(typelib_Parameter_Init) * nParams ));
244 sal_Int32 nPos;
245 for ( nPos = nParams; nPos--; )
247 const Reference<XMethodParameter>& xParam = rParams[nPos];
248 const Reference< XTypeDescription > & xType = xParam->getType();
249 typelib_Parameter_Init & rInit = pParamInit[xParam->getPosition()];
251 rInit.eTypeClass = static_cast<typelib_TypeClass>(xType->getTypeClass());
252 OUString aParamTypeName( xType->getName() );
253 rInit.pTypeName = aParamTypeName.pData;
254 rtl_uString_acquire( rInit.pTypeName );
255 OUString aParamName( xParam->getName() );
256 rInit.pParamName = aParamName.pData;
257 rtl_uString_acquire( rInit.pParamName );
258 rInit.bIn = xParam->isIn();
259 rInit.bOut = xParam->isOut();
262 // init all exception strings
263 const Sequence<Reference< XTypeDescription > > & rExceptions = xMethod->getExceptions();
264 sal_Int32 nExceptions = rExceptions.getLength();
265 rtl_uString ** ppExceptionNames = static_cast<rtl_uString **>(alloca(
266 sizeof(rtl_uString *) * nExceptions ));
268 for ( nPos = nExceptions; nPos--; )
270 OUString aExceptionTypeName(rExceptions[nPos]->getName());
271 ppExceptionNames[nPos] = aExceptionTypeName.pData;
272 rtl_uString_acquire( ppExceptionNames[nPos] );
275 OUString aTypeName( xMethod->getName() );
276 OUString aReturnTypeName( xReturnType->getName() );
278 typelib_typedescription_newInterfaceMethod(
279 reinterpret_cast<typelib_InterfaceMethodTypeDescription **>(&pRet),
280 xMethod->getPosition(),
281 xMethod->isOneway(),
282 aTypeName.pData,
283 static_cast<typelib_TypeClass>(xReturnType->getTypeClass()),
284 aReturnTypeName.pData,
285 nParams, pParamInit,
286 nExceptions, ppExceptionNames );
288 for ( nPos = nParams; nPos--; )
290 rtl_uString_release( pParamInit[nPos].pTypeName );
291 rtl_uString_release( pParamInit[nPos].pParamName );
293 for ( nPos = nExceptions; nPos--; )
295 rtl_uString_release( ppExceptionNames[nPos] );
298 return pRet;
301 static typelib_TypeDescription * createCTD(
302 Reference< container::XHierarchicalNameAccess > const & access,
303 const Reference< XInterfaceTypeDescription2 > & xType )
305 typelib_TypeDescription * pRet = nullptr;
306 if (xType.is())
308 Sequence< Reference< XTypeDescription > > aBases(xType->getBaseTypes());
309 sal_Int32 nBases = aBases.getLength();
310 // Exploit the fact that a typelib_TypeDescription for an interface type
311 // is also the typelib_TypeDescriptionReference for that type:
312 std::unique_ptr< typelib_TypeDescription * []> aBaseTypes(
313 new typelib_TypeDescription *[nBases]);
314 for (sal_Int32 i = 0; i < nBases; ++i) {
315 typelib_TypeDescription * p = createCTD(access, aBases[i]);
316 OSL_ASSERT(
317 !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(p->eTypeClass));
318 typelib_typedescription_register(&p);
319 aBaseTypes[i] = p;
321 typelib_TypeDescriptionReference ** pBaseTypeRefs
322 = reinterpret_cast< typelib_TypeDescriptionReference ** >(
323 aBaseTypes.get());
325 // construct all member refs
326 const Sequence<Reference< XInterfaceMemberTypeDescription > > & rMembers = xType->getMembers();
327 sal_Int32 nMembers = rMembers.getLength();
329 typelib_TypeDescriptionReference ** ppMemberRefs = static_cast<typelib_TypeDescriptionReference **>(alloca(
330 sizeof(typelib_TypeDescriptionReference *) * nMembers ));
332 OUString aTypeName( xType->getName() );
334 sal_Int32 nPos;
335 for ( nPos = nMembers; nPos--; )
337 OUString aMemberTypeName(rMembers[nPos]->getName());
338 ppMemberRefs[nPos] = nullptr;
339 typelib_typedescriptionreference_new(
340 ppMemberRefs + nPos,
341 static_cast<typelib_TypeClass>(rMembers[nPos]->getTypeClass()),
342 aMemberTypeName.pData );
345 typelib_typedescription_newMIInterface(
346 reinterpret_cast<typelib_InterfaceTypeDescription **>(&pRet),
347 aTypeName.pData,
348 0, 0, 0, 0, 0,
349 nBases, pBaseTypeRefs,
350 nMembers, ppMemberRefs );
352 // cleanup refs and base type
353 for (int i = 0; i < nBases; ++i) {
354 typelib_typedescription_release(aBaseTypes[i]);
357 for ( nPos = nMembers; nPos--; )
359 typelib_typedescriptionreference_release( ppMemberRefs[nPos] );
362 return pRet;
365 static typelib_TypeDescription * createCTD( const Reference< XEnumTypeDescription > & xType )
367 typelib_TypeDescription * pRet = nullptr;
368 if (xType.is())
370 OUString aTypeName( xType->getName() );
371 Sequence< OUString > aNames( xType->getEnumNames() );
372 OSL_ASSERT( sizeof(OUString) == sizeof(rtl_uString *) ); // !!!
373 Sequence< sal_Int32 > aValues( xType->getEnumValues() );
375 typelib_typedescription_newEnum(
376 &pRet, aTypeName.pData, xType->getDefaultEnumValue(),
377 aNames.getLength(),
378 const_cast<rtl_uString **>(reinterpret_cast<rtl_uString * const *>(aNames.getConstArray())),
379 const_cast< sal_Int32 * >( aValues.getConstArray() ) );
381 return pRet;
384 static typelib_TypeDescription * createCTD(
385 Reference< container::XHierarchicalNameAccess > const & access,
386 const Reference< XIndirectTypeDescription > & xType )
388 typelib_TypeDescription * pRet = nullptr;
389 if (xType.is())
391 typelib_TypeDescription * pRefType = createCTD(
392 access, xType->getReferencedType() );
393 typelib_typedescription_register( &pRefType );
395 OUString aTypeName( xType->getName() );
397 typelib_typedescription_new(
398 &pRet,
399 static_cast<typelib_TypeClass>(xType->getTypeClass()),
400 aTypeName.pData,
401 pRefType->pWeakRef,
402 0, nullptr );
404 // cleanup
405 typelib_typedescription_release( pRefType );
407 return pRet;
411 static typelib_TypeDescription * createCTD(
412 Reference< container::XHierarchicalNameAccess > const & access,
413 const Reference< XTypeDescription > & xType )
415 typelib_TypeDescription * pRet = nullptr;
417 if (xType.is())
419 switch (xType->getTypeClass())
421 // built in types
422 case TypeClass_VOID:
424 OUString aTypeName(u"void"_ustr);
425 typelib_typedescription_new( &pRet, typelib_TypeClass_VOID, aTypeName.pData, nullptr, 0, nullptr );
426 break;
428 case TypeClass_CHAR:
430 OUString aTypeName(u"char"_ustr);
431 typelib_typedescription_new( &pRet, typelib_TypeClass_CHAR, aTypeName.pData, nullptr, 0, nullptr );
432 break;
434 case TypeClass_BOOLEAN:
436 OUString aTypeName(u"boolean"_ustr);
437 typelib_typedescription_new( &pRet, typelib_TypeClass_BOOLEAN, aTypeName.pData, nullptr, 0, nullptr );
438 break;
440 case TypeClass_BYTE:
442 OUString aTypeName(u"byte"_ustr);
443 typelib_typedescription_new( &pRet, typelib_TypeClass_BYTE, aTypeName.pData, nullptr, 0, nullptr );
444 break;
446 case TypeClass_SHORT:
448 OUString aTypeName(u"short"_ustr);
449 typelib_typedescription_new( &pRet, typelib_TypeClass_SHORT, aTypeName.pData, nullptr, 0, nullptr );
450 break;
452 case TypeClass_UNSIGNED_SHORT:
454 OUString aTypeName(u"unsigned short"_ustr);
455 typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_SHORT, aTypeName.pData, nullptr, 0, nullptr );
456 break;
458 case TypeClass_LONG:
460 OUString aTypeName(u"long"_ustr);
461 typelib_typedescription_new( &pRet, typelib_TypeClass_LONG, aTypeName.pData, nullptr, 0, nullptr );
462 break;
464 case TypeClass_UNSIGNED_LONG:
466 OUString aTypeName(u"unsigned long"_ustr);
467 typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_LONG, aTypeName.pData, nullptr, 0, nullptr );
468 break;
470 case TypeClass_HYPER:
472 OUString aTypeName(u"hyper"_ustr);
473 typelib_typedescription_new( &pRet, typelib_TypeClass_HYPER, aTypeName.pData, nullptr, 0, nullptr );
474 break;
476 case TypeClass_UNSIGNED_HYPER:
478 OUString aTypeName(u"unsigned hyper"_ustr);
479 typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_HYPER, aTypeName.pData, nullptr, 0, nullptr );
480 break;
482 case TypeClass_FLOAT:
484 OUString aTypeName(u"float"_ustr);
485 typelib_typedescription_new( &pRet, typelib_TypeClass_FLOAT, aTypeName.pData, nullptr, 0, nullptr );
486 break;
488 case TypeClass_DOUBLE:
490 OUString aTypeName(u"double"_ustr);
491 typelib_typedescription_new( &pRet, typelib_TypeClass_DOUBLE, aTypeName.pData, nullptr, 0, nullptr );
492 break;
494 case TypeClass_STRING:
496 OUString aTypeName(u"string"_ustr);
497 typelib_typedescription_new( &pRet, typelib_TypeClass_STRING, aTypeName.pData, nullptr, 0, nullptr );
498 break;
500 case TypeClass_TYPE:
502 OUString aTypeName(u"type"_ustr);
503 typelib_typedescription_new( &pRet, typelib_TypeClass_TYPE, aTypeName.pData, nullptr, 0, nullptr );
504 break;
506 case TypeClass_ANY:
508 OUString aTypeName(u"any"_ustr);
509 typelib_typedescription_new( &pRet, typelib_TypeClass_ANY, aTypeName.pData, nullptr, 0, nullptr );
510 break;
513 case TypeClass_EXCEPTION:
514 pRet = createCTD( Reference< XCompoundTypeDescription >::query( xType ) );
515 break;
516 case TypeClass_STRUCT:
517 pRet = createCTD(
518 access, Reference< XStructTypeDescription >::query( xType ) );
519 break;
520 case TypeClass_ENUM:
521 pRet = createCTD( Reference< XEnumTypeDescription >::query( xType ) );
522 break;
523 case TypeClass_TYPEDEF:
525 Reference< XIndirectTypeDescription > xTypedef( xType, UNO_QUERY );
526 if (xTypedef.is())
527 pRet = createCTD( access, xTypedef->getReferencedType() );
528 break;
530 case TypeClass_SEQUENCE:
531 pRet = createCTD(
532 access, Reference< XIndirectTypeDescription >::query( xType ) );
533 break;
534 case TypeClass_INTERFACE:
535 pRet = createCTD(
536 access,
537 Reference< XInterfaceTypeDescription2 >::query( xType ) );
538 break;
539 case TypeClass_INTERFACE_METHOD:
540 pRet = createCTD( Reference< XInterfaceMethodTypeDescription >::query( xType ) );
541 break;
542 case TypeClass_INTERFACE_ATTRIBUTE:
543 pRet = createCTD( Reference< XInterfaceAttributeTypeDescription2 >::query( xType ) );
544 break;
545 default:
546 break;
550 return pRet;
554 extern "C"
556 static void typelib_callback(
557 void * pContext, typelib_TypeDescription ** ppRet, rtl_uString * pTypeName )
559 OSL_ENSURE( pContext && ppRet && pTypeName, "### null ptr!" );
560 if (!ppRet)
561 return;
563 if (*ppRet)
565 ::typelib_typedescription_release( *ppRet );
566 *ppRet = nullptr;
568 if (!(pContext && pTypeName))
569 return;
571 Reference< container::XHierarchicalNameAccess > access(
572 static_cast< container::XHierarchicalNameAccess * >(
573 pContext));
576 OUString const & rTypeName = OUString::unacquired( &pTypeName );
577 Reference< XTypeDescription > xTD;
578 if (access->getByHierarchicalName(rTypeName ) >>= xTD)
580 *ppRet = createCTD( access, xTD );
583 catch (const container::NoSuchElementException & exc)
585 SAL_INFO("cppuhelper", "typelibrary type not available: " << exc );
587 catch (const Exception & exc)
589 SAL_INFO("cppuhelper", exc );
594 namespace {
596 class EventListenerImpl
597 : public WeakImplHelper< lang::XEventListener >
599 Reference< container::XHierarchicalNameAccess > m_xTDMgr;
601 public:
602 explicit EventListenerImpl(
603 Reference< container::XHierarchicalNameAccess > const & xTDMgr )
604 : m_xTDMgr( xTDMgr )
607 // XEventListener
608 virtual void SAL_CALL disposing( lang::EventObject const & rEvt ) override;
613 void EventListenerImpl::disposing( lang::EventObject const & rEvt )
615 if (rEvt.Source != m_xTDMgr) {
616 OSL_ASSERT(false);
618 // deregister of c typelib callback
619 ::typelib_typedescription_revokeCallback( m_xTDMgr.get(), typelib_callback );
623 sal_Bool SAL_CALL installTypeDescriptionManager(
624 Reference< container::XHierarchicalNameAccess > const & xTDMgr_c )
626 uno::Environment curr_env(Environment::getCurrent());
627 uno::Environment target_env(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
629 uno::Mapping curr2target(curr_env, target_env);
632 Reference<container::XHierarchicalNameAccess> xTDMgr(
633 static_cast<container::XHierarchicalNameAccess *>(
634 curr2target.mapInterface(xTDMgr_c.get(), cppu::UnoType<decltype(xTDMgr_c)>::get())),
635 SAL_NO_ACQUIRE);
637 Reference< lang::XComponent > xComp( xTDMgr, UNO_QUERY );
638 if (xComp.is())
640 xComp->addEventListener( new EventListenerImpl( xTDMgr ) );
641 // register c typelib callback
642 ::typelib_typedescription_registerCallback( xTDMgr.get(), typelib_callback );
643 return true;
645 return false;
648 } // end namespace cppu
650 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */