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 .
21 #include <sal/config.h>
25 #include <sal/alloca.h>
27 #include <osl/diagnose.h>
28 #include <rtl/alloc.h>
29 #include <rtl/ustring.hxx>
31 #include <uno/lbnames.h>
32 #include <uno/mapping.hxx>
34 #include <cppuhelper/bootstrap.hxx>
35 #include <cppuhelper/implbase1.hxx>
36 #include <typelib/typedescription.h>
38 #include <com/sun/star/lang/XComponent.hpp>
39 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
40 #include <com/sun/star/reflection/XTypeDescription.hpp>
41 #include <com/sun/star/reflection/XEnumTypeDescription.hpp>
42 #include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
43 #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
44 #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
45 #include <com/sun/star/reflection/XMethodParameter.hpp>
46 #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
47 #include <com/sun/star/reflection/XInterfaceTypeDescription2.hpp>
48 #include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
49 #include <com/sun/star/reflection/XStructTypeDescription.hpp>
50 #include <com/sun/star/uno/RuntimeException.hpp>
52 #include <boost/scoped_array.hpp>
54 using namespace ::com::sun::star
;
55 using namespace ::com::sun::star::uno
;
56 using namespace ::com::sun::star::reflection
;
63 static typelib_TypeDescription
* createCTD(
64 Reference
< container::XHierarchicalNameAccess
> const & access
,
65 const Reference
< XTypeDescription
> & xType
);
68 inline static typelib_TypeDescription
* createCTD(
69 const Reference
< XCompoundTypeDescription
> & xType
)
71 typelib_TypeDescription
* pRet
= 0;
74 typelib_TypeDescription
* pBaseType
= createCTD(
75 Reference
< XCompoundTypeDescription
>::query( xType
->getBaseType() ) );
77 typelib_typedescription_register( &pBaseType
);
79 // construct member init array
80 const Sequence
<Reference
< XTypeDescription
> > & rMemberTypes
= xType
->getMemberTypes();
81 const Sequence
< OUString
> & rMemberNames
= xType
->getMemberNames();
83 const Reference
< XTypeDescription
> * pMemberTypes
= rMemberTypes
.getConstArray();
84 const OUString
* pMemberNames
= rMemberNames
.getConstArray();
86 sal_Int32 nMembers
= rMemberTypes
.getLength();
87 OSL_ENSURE( nMembers
== rMemberNames
.getLength(), "### lens differ!" );
89 OUString
aTypeName( xType
->getName() );
91 typelib_CompoundMember_Init
* pMemberInits
= static_cast<typelib_CompoundMember_Init
*>(alloca(
92 sizeof(typelib_CompoundMember_Init
) * nMembers
));
95 for ( nPos
= nMembers
; nPos
--; )
97 typelib_CompoundMember_Init
& rInit
= pMemberInits
[nPos
];
98 rInit
.eTypeClass
= (typelib_TypeClass
)pMemberTypes
[nPos
]->getTypeClass();
100 OUString
aMemberTypeName( pMemberTypes
[nPos
]->getName() );
101 rtl_uString_acquire( rInit
.pTypeName
= aMemberTypeName
.pData
);
103 // string is held by rMemberNames
104 rInit
.pMemberName
= pMemberNames
[nPos
].pData
;
107 typelib_typedescription_new(
109 (typelib_TypeClass
)xType
->getTypeClass(),
111 (pBaseType
? pBaseType
->pWeakRef
: 0),
112 nMembers
, pMemberInits
);
115 for ( nPos
= nMembers
; nPos
--; )
117 rtl_uString_release( pMemberInits
[nPos
].pTypeName
);
120 typelib_typedescription_release( pBaseType
);
125 inline static typelib_TypeDescription
* createCTD(
126 Reference
< container::XHierarchicalNameAccess
> const & access
,
127 const Reference
< XStructTypeDescription
> & xType
)
129 typelib_TypeDescription
* pRet
= 0;
130 if (xType
.is() && xType
->getTypeParameters().getLength() == 0)
132 typelib_TypeDescription
* pBaseType
= createCTD(
133 access
, xType
->getBaseType() );
135 typelib_typedescription_register( &pBaseType
);
137 // construct member init array
138 const Sequence
<Reference
< XTypeDescription
> > & rMemberTypes
= xType
->getMemberTypes();
139 const Sequence
< OUString
> & rMemberNames
= xType
->getMemberNames();
141 const Reference
< XTypeDescription
> * pMemberTypes
= rMemberTypes
.getConstArray();
142 const OUString
* pMemberNames
= rMemberNames
.getConstArray();
144 sal_Int32 nMembers
= rMemberTypes
.getLength();
145 OSL_ENSURE( nMembers
== rMemberNames
.getLength(), "### lens differ!" );
147 OUString
aTypeName( xType
->getName() );
149 typelib_StructMember_Init
* pMemberInits
= static_cast<typelib_StructMember_Init
*>(alloca(
150 sizeof(typelib_StructMember_Init
) * nMembers
));
152 Sequence
< Reference
< XTypeDescription
> > templateMemberTypes
;
153 sal_Int32 i
= aTypeName
.indexOf('<');
155 Reference
< XStructTypeDescription
> templateDesc(
156 access
->getByHierarchicalName(aTypeName
.copy(0, i
)),
159 templateDesc
->getTypeParameters().getLength()
160 == xType
->getTypeArguments().getLength());
161 templateMemberTypes
= templateDesc
->getMemberTypes();
162 OSL_ASSERT(templateMemberTypes
.getLength() == nMembers
);
166 for ( nPos
= nMembers
; nPos
--; )
168 typelib_StructMember_Init
& rInit
= pMemberInits
[nPos
];
169 rInit
.aBase
.eTypeClass
170 = (typelib_TypeClass
)pMemberTypes
[nPos
]->getTypeClass();
172 OUString
aMemberTypeName( pMemberTypes
[nPos
]->getName() );
174 rInit
.aBase
.pTypeName
= aMemberTypeName
.pData
);
176 // string is held by rMemberNames
177 rInit
.aBase
.pMemberName
= pMemberNames
[nPos
].pData
;
179 rInit
.bParameterizedType
= templateMemberTypes
.getLength() != 0
180 && (templateMemberTypes
[nPos
]->getTypeClass()
181 == TypeClass_UNKNOWN
);
184 typelib_typedescription_newStruct(
187 (pBaseType
? pBaseType
->pWeakRef
: 0),
188 nMembers
, pMemberInits
);
191 for ( nPos
= nMembers
; nPos
--; )
193 rtl_uString_release( pMemberInits
[nPos
].aBase
.pTypeName
);
196 typelib_typedescription_release( pBaseType
);
201 inline static typelib_TypeDescription
* createCTD(
202 const Reference
< XInterfaceAttributeTypeDescription2
> & xAttribute
)
204 typelib_TypeDescription
* pRet
= 0;
207 OUString
aMemberName( xAttribute
->getName() );
208 Reference
< XTypeDescription
> xType( xAttribute
->getType() );
209 OUString
aMemberTypeName( xType
->getName() );
210 std::vector
< rtl_uString
* > getExc
;
211 Sequence
< Reference
< XCompoundTypeDescription
> > getExcs(
212 xAttribute
->getGetExceptions() );
213 for (sal_Int32 i
= 0; i
!= getExcs
.getLength(); ++i
)
215 OSL_ASSERT( getExcs
[i
].is() );
216 getExc
.push_back( getExcs
[i
]->getName().pData
);
218 std::vector
< rtl_uString
* > setExc
;
219 Sequence
< Reference
< XCompoundTypeDescription
> > setExcs(
220 xAttribute
->getSetExceptions() );
221 for (sal_Int32 i
= 0; i
!= setExcs
.getLength(); ++i
)
223 OSL_ASSERT( setExcs
[i
].is() );
224 setExc
.push_back( setExcs
[i
]->getName().pData
);
226 typelib_typedescription_newExtendedInterfaceAttribute(
227 reinterpret_cast<typelib_InterfaceAttributeTypeDescription
**>(&pRet
),
228 xAttribute
->getPosition(),
229 aMemberName
.pData
, // name
230 (typelib_TypeClass
)xType
->getTypeClass(),
231 aMemberTypeName
.pData
, // type name
232 xAttribute
->isReadOnly(),
233 getExc
.size(), getExc
.data(),
234 setExc
.size(), setExc
.data() );
239 static typelib_TypeDescription
* createCTD(
240 const Reference
< XInterfaceMethodTypeDescription
> & xMethod
)
242 typelib_TypeDescription
* pRet
= 0;
245 Reference
< XTypeDescription
> xReturnType( xMethod
->getReturnType() );
248 const Sequence
<Reference
< XMethodParameter
> > & rParams
= xMethod
->getParameters();
249 const Reference
< XMethodParameter
> * pParams
= rParams
.getConstArray();
250 sal_Int32 nParams
= rParams
.getLength();
252 typelib_Parameter_Init
* pParamInit
= static_cast<typelib_Parameter_Init
*>(alloca(
253 sizeof(typelib_Parameter_Init
) * nParams
));
256 for ( nPos
= nParams
; nPos
--; )
258 const Reference
< XMethodParameter
> & xParam
= pParams
[nPos
];
259 const Reference
< XTypeDescription
> & xType
= xParam
->getType();
260 typelib_Parameter_Init
& rInit
= pParamInit
[xParam
->getPosition()];
262 rInit
.eTypeClass
= (typelib_TypeClass
)xType
->getTypeClass();
263 OUString
aParamTypeName( xType
->getName() );
264 rtl_uString_acquire( rInit
.pTypeName
= aParamTypeName
.pData
);
265 OUString
aParamName( xParam
->getName() );
266 rtl_uString_acquire( rInit
.pParamName
= aParamName
.pData
);
267 rInit
.bIn
= xParam
->isIn();
268 rInit
.bOut
= xParam
->isOut();
271 // init all exception strings
272 const Sequence
<Reference
< XTypeDescription
> > & rExceptions
= xMethod
->getExceptions();
273 const Reference
< XTypeDescription
> * pExceptions
= rExceptions
.getConstArray();
274 sal_Int32 nExceptions
= rExceptions
.getLength();
275 rtl_uString
** ppExceptionNames
= static_cast<rtl_uString
**>(alloca(
276 sizeof(rtl_uString
*) * nExceptions
));
278 for ( nPos
= nExceptions
; nPos
--; )
280 OUString
aExceptionTypeName( pExceptions
[nPos
]->getName() );
281 rtl_uString_acquire( ppExceptionNames
[nPos
] = aExceptionTypeName
.pData
);
284 OUString
aTypeName( xMethod
->getName() );
285 OUString
aReturnTypeName( xReturnType
->getName() );
287 typelib_typedescription_newInterfaceMethod(
288 reinterpret_cast<typelib_InterfaceMethodTypeDescription
**>(&pRet
),
289 xMethod
->getPosition(),
292 (typelib_TypeClass
)xReturnType
->getTypeClass(),
293 aReturnTypeName
.pData
,
295 nExceptions
, ppExceptionNames
);
297 for ( nPos
= nParams
; nPos
--; )
299 rtl_uString_release( pParamInit
[nPos
].pTypeName
);
300 rtl_uString_release( pParamInit
[nPos
].pParamName
);
302 for ( nPos
= nExceptions
; nPos
--; )
304 rtl_uString_release( ppExceptionNames
[nPos
] );
310 inline static typelib_TypeDescription
* createCTD(
311 Reference
< container::XHierarchicalNameAccess
> const & access
,
312 const Reference
< XInterfaceTypeDescription2
> & xType
)
314 typelib_TypeDescription
* pRet
= 0;
317 Sequence
< Reference
< XTypeDescription
> > aBases(xType
->getBaseTypes());
318 sal_Int32 nBases
= aBases
.getLength();
319 // Exploit the fact that a typelib_TypeDescription for an interface type
320 // is also the typelib_TypeDescriptionReference for that type:
321 boost::scoped_array
< typelib_TypeDescription
* > aBaseTypes(
322 new typelib_TypeDescription
*[nBases
]);
323 for (sal_Int32 i
= 0; i
< nBases
; ++i
) {
324 typelib_TypeDescription
* p
= createCTD(access
, aBases
[i
]);
326 !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(p
->eTypeClass
));
327 typelib_typedescription_register(&p
);
330 typelib_TypeDescriptionReference
** pBaseTypeRefs
331 = reinterpret_cast< typelib_TypeDescriptionReference
** >(
334 // construct all member refs
335 const Sequence
<Reference
< XInterfaceMemberTypeDescription
> > & rMembers
= xType
->getMembers();
336 sal_Int32 nMembers
= rMembers
.getLength();
338 typelib_TypeDescriptionReference
** ppMemberRefs
= static_cast<typelib_TypeDescriptionReference
**>(alloca(
339 sizeof(typelib_TypeDescriptionReference
*) * nMembers
));
341 const Reference
< XInterfaceMemberTypeDescription
> * pMembers
= rMembers
.getConstArray();
343 OUString
aTypeName( xType
->getName() );
346 for ( nPos
= nMembers
; nPos
--; )
348 OUString
aMemberTypeName( pMembers
[nPos
]->getName() );
349 ppMemberRefs
[nPos
] = 0;
350 typelib_typedescriptionreference_new(
352 (typelib_TypeClass
)pMembers
[nPos
]->getTypeClass(),
353 aMemberTypeName
.pData
);
356 typelib_typedescription_newMIInterface(
357 reinterpret_cast<typelib_InterfaceTypeDescription
**>(&pRet
),
360 nBases
, pBaseTypeRefs
,
361 nMembers
, ppMemberRefs
);
363 // cleanup refs and base type
364 for (int i
= 0; i
< nBases
; ++i
) {
365 typelib_typedescription_release(aBaseTypes
[i
]);
368 for ( nPos
= nMembers
; nPos
--; )
370 typelib_typedescriptionreference_release( ppMemberRefs
[nPos
] );
376 inline static typelib_TypeDescription
* createCTD( const Reference
< XEnumTypeDescription
> & xType
)
378 typelib_TypeDescription
* pRet
= 0;
381 OUString
aTypeName( xType
->getName() );
382 Sequence
< OUString
> aNames( xType
->getEnumNames() );
383 OSL_ASSERT( sizeof(OUString
) == sizeof(rtl_uString
*) ); // !!!
384 Sequence
< sal_Int32
> aValues( xType
->getEnumValues() );
386 typelib_typedescription_newEnum(
387 &pRet
, aTypeName
.pData
, xType
->getDefaultEnumValue(),
389 const_cast<rtl_uString
**>(reinterpret_cast<rtl_uString
* const *>(aNames
.getConstArray())),
390 const_cast< sal_Int32
* >( aValues
.getConstArray() ) );
395 inline static typelib_TypeDescription
* createCTD(
396 Reference
< container::XHierarchicalNameAccess
> const & access
,
397 const Reference
< XIndirectTypeDescription
> & xType
)
399 typelib_TypeDescription
* pRet
= 0;
402 typelib_TypeDescription
* pRefType
= createCTD(
403 access
, xType
->getReferencedType() );
404 typelib_typedescription_register( &pRefType
);
406 OUString
aTypeName( xType
->getName() );
408 typelib_typedescription_new(
410 (typelib_TypeClass
)xType
->getTypeClass(),
416 typelib_typedescription_release( pRefType
);
422 static typelib_TypeDescription
* createCTD(
423 Reference
< container::XHierarchicalNameAccess
> const & access
,
424 const Reference
< XTypeDescription
> & xType
)
426 typelib_TypeDescription
* pRet
= 0;
430 switch (xType
->getTypeClass())
435 OUString
aTypeName("void");
436 typelib_typedescription_new( &pRet
, typelib_TypeClass_VOID
, aTypeName
.pData
, 0, 0, 0 );
441 OUString
aTypeName("char");
442 typelib_typedescription_new( &pRet
, typelib_TypeClass_CHAR
, aTypeName
.pData
, 0, 0, 0 );
445 case TypeClass_BOOLEAN
:
447 OUString
aTypeName("boolean");
448 typelib_typedescription_new( &pRet
, typelib_TypeClass_BOOLEAN
, aTypeName
.pData
, 0, 0, 0 );
453 OUString
aTypeName("byte");
454 typelib_typedescription_new( &pRet
, typelib_TypeClass_BYTE
, aTypeName
.pData
, 0, 0, 0 );
457 case TypeClass_SHORT
:
459 OUString
aTypeName("short");
460 typelib_typedescription_new( &pRet
, typelib_TypeClass_SHORT
, aTypeName
.pData
, 0, 0, 0 );
463 case TypeClass_UNSIGNED_SHORT
:
465 OUString
aTypeName("unsigned short");
466 typelib_typedescription_new( &pRet
, typelib_TypeClass_UNSIGNED_SHORT
, aTypeName
.pData
, 0, 0, 0 );
471 OUString
aTypeName("long");
472 typelib_typedescription_new( &pRet
, typelib_TypeClass_LONG
, aTypeName
.pData
, 0, 0, 0 );
475 case TypeClass_UNSIGNED_LONG
:
477 OUString
aTypeName("unsigned long");
478 typelib_typedescription_new( &pRet
, typelib_TypeClass_UNSIGNED_LONG
, aTypeName
.pData
, 0, 0, 0 );
481 case TypeClass_HYPER
:
483 OUString
aTypeName("hyper");
484 typelib_typedescription_new( &pRet
, typelib_TypeClass_HYPER
, aTypeName
.pData
, 0, 0, 0 );
487 case TypeClass_UNSIGNED_HYPER
:
489 OUString
aTypeName("unsigned hyper");
490 typelib_typedescription_new( &pRet
, typelib_TypeClass_UNSIGNED_HYPER
, aTypeName
.pData
, 0, 0, 0 );
493 case TypeClass_FLOAT
:
495 OUString
aTypeName("float");
496 typelib_typedescription_new( &pRet
, typelib_TypeClass_FLOAT
, aTypeName
.pData
, 0, 0, 0 );
499 case TypeClass_DOUBLE
:
501 OUString
aTypeName("double");
502 typelib_typedescription_new( &pRet
, typelib_TypeClass_DOUBLE
, aTypeName
.pData
, 0, 0, 0 );
505 case TypeClass_STRING
:
507 OUString
aTypeName("string");
508 typelib_typedescription_new( &pRet
, typelib_TypeClass_STRING
, aTypeName
.pData
, 0, 0, 0 );
513 OUString
aTypeName("type");
514 typelib_typedescription_new( &pRet
, typelib_TypeClass_TYPE
, aTypeName
.pData
, 0, 0, 0 );
519 OUString
aTypeName("any");
520 typelib_typedescription_new( &pRet
, typelib_TypeClass_ANY
, aTypeName
.pData
, 0, 0, 0 );
524 case TypeClass_EXCEPTION
:
525 pRet
= createCTD( Reference
< XCompoundTypeDescription
>::query( xType
) );
527 case TypeClass_STRUCT
:
529 access
, Reference
< XStructTypeDescription
>::query( xType
) );
532 pRet
= createCTD( Reference
< XEnumTypeDescription
>::query( xType
) );
534 case TypeClass_TYPEDEF
:
536 Reference
< XIndirectTypeDescription
> xTypedef( xType
, UNO_QUERY
);
538 pRet
= createCTD( access
, xTypedef
->getReferencedType() );
541 case TypeClass_SEQUENCE
:
543 access
, Reference
< XIndirectTypeDescription
>::query( xType
) );
545 case TypeClass_INTERFACE
:
548 Reference
< XInterfaceTypeDescription2
>::query( xType
) );
550 case TypeClass_INTERFACE_METHOD
:
551 pRet
= createCTD( Reference
< XInterfaceMethodTypeDescription
>::query( xType
) );
553 case TypeClass_INTERFACE_ATTRIBUTE
:
554 pRet
= createCTD( Reference
< XInterfaceAttributeTypeDescription2
>::query( xType
) );
568 static void SAL_CALL
typelib_callback(
569 void * pContext
, typelib_TypeDescription
** ppRet
, rtl_uString
* pTypeName
)
571 OSL_ENSURE( pContext
&& ppRet
&& pTypeName
, "### null ptr!" );
576 ::typelib_typedescription_release( *ppRet
);
579 if (pContext
&& pTypeName
)
581 Reference
< container::XHierarchicalNameAccess
> access(
582 static_cast< container::XHierarchicalNameAccess
* >(
586 OUString
const & rTypeName
= OUString::unacquired( &pTypeName
);
587 Reference
< XTypeDescription
> xTD
;
588 if (access
->getByHierarchicalName(rTypeName
) >>= xTD
)
590 *ppRet
= createCTD( access
, xTD
);
593 catch (container::NoSuchElementException
& exc
)
595 (void) exc
; // avoid warning about unused variable
597 "typelibrary type not available: %s",
599 exc
.Message
, RTL_TEXTENCODING_UTF8
).getStr() );
601 catch (Exception
& exc
)
603 (void) exc
; // avoid warning about unused variable
607 exc
.Message
, RTL_TEXTENCODING_UTF8
).getStr() );
615 class EventListenerImpl
616 : public WeakImplHelper1
< lang::XEventListener
>
618 Reference
< container::XHierarchicalNameAccess
> m_xTDMgr
;
621 inline EventListenerImpl(
622 Reference
< container::XHierarchicalNameAccess
> const & xTDMgr
)
627 virtual void SAL_CALL
disposing( lang::EventObject
const & rEvt
)
628 throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
631 void EventListenerImpl::disposing( lang::EventObject
const & rEvt
)
632 throw (RuntimeException
, std::exception
)
634 if (rEvt
.Source
!= m_xTDMgr
) {
637 // deregister of c typelib callback
638 ::typelib_typedescription_revokeCallback( m_xTDMgr
.get(), typelib_callback
);
642 sal_Bool SAL_CALL
installTypeDescriptionManager(
643 Reference
< container::XHierarchicalNameAccess
> const & xTDMgr_c
)
645 uno::Environment
curr_env(Environment::getCurrent());
646 uno::Environment
target_env(CPPU_CURRENT_LANGUAGE_BINDING_NAME
);
648 uno::Mapping
curr2target(curr_env
, target_env
);
651 Reference
<container::XHierarchicalNameAccess
> xTDMgr(
652 static_cast<container::XHierarchicalNameAccess
*>(
653 curr2target
.mapInterface(xTDMgr_c
.get(), cppu::UnoType
<decltype(xTDMgr_c
)>::get())),
656 Reference
< lang::XComponent
> xComp( xTDMgr
, UNO_QUERY
);
659 xComp
->addEventListener( new EventListenerImpl( xTDMgr
) );
660 // register c typelib callback
661 ::typelib_typedescription_registerCallback( xTDMgr
.get(), typelib_callback
);
667 } // end namespace cppu
669 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */