xref: /trunk/main/cppuhelper/source/tdmgr.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cppuhelper.hxx"
30 
31 #include "sal/config.h"
32 
33 #include <vector>
34 
35 #include <sal/alloca.h>
36 
37 #include <osl/diagnose.h>
38 #include <rtl/alloc.h>
39 #include <rtl/ustring.hxx>
40 
41 #include <uno/mapping.hxx>
42 
43 #include <cppuhelper/bootstrap.hxx>
44 #include <cppuhelper/implbase1.hxx>
45 #include <typelib/typedescription.h>
46 
47 #include <com/sun/star/lang/XComponent.hpp>
48 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
49 #include <com/sun/star/reflection/XTypeDescription.hpp>
50 #include <com/sun/star/reflection/XEnumTypeDescription.hpp>
51 #include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
52 #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
53 #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
54 #include <com/sun/star/reflection/XMethodParameter.hpp>
55 #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
56 #include <com/sun/star/reflection/XInterfaceTypeDescription2.hpp>
57 #include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
58 #include <com/sun/star/reflection/XStructTypeDescription.hpp>
59 #include <com/sun/star/reflection/XUnionTypeDescription.hpp>
60 #include "com/sun/star/uno/RuntimeException.hpp"
61 
62 #include "boost/scoped_array.hpp"
63 
64 using namespace ::rtl;
65 using namespace ::com::sun::star;
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::reflection;
68 
69 
70 namespace cppu
71 {
72 
73 static typelib_TypeDescription * createCTD(
74     Reference< container::XHierarchicalNameAccess > const & access,
75     const Reference< XTypeDescription > & xType );
76 
77 //==================================================================================================
78 inline static sal_Int64 coerceToInt64( const Any & rVal )
79 {
80     switch (rVal.getValueTypeClass())
81     {
82     case TypeClass_CHAR:
83         return *(sal_Unicode *)rVal.getValue();
84     case TypeClass_BOOLEAN:
85         return (*(sal_Bool *)rVal.getValue() ? 1 : 0);
86     case TypeClass_BYTE:
87         return *(sal_Int8 *)rVal.getValue();
88     case TypeClass_SHORT:
89         return *(sal_Int16 *)rVal.getValue();
90     case TypeClass_UNSIGNED_SHORT:
91         return *(sal_uInt16 *)rVal.getValue();
92     case TypeClass_LONG:
93         return *(sal_Int32 *)rVal.getValue();
94     case TypeClass_UNSIGNED_LONG:
95         return *(sal_uInt32 *)rVal.getValue();
96     case TypeClass_HYPER:
97         return *(sal_Int64 *)rVal.getValue();
98     case TypeClass_UNSIGNED_HYPER:
99         return *(sal_uInt64 *)rVal.getValue();
100     case TypeClass_ENUM:
101         return *(int *)rVal.getValue();
102     default:
103         OSL_ASSERT(false);
104         return 0;
105     }
106 }
107 //==================================================================================================
108 inline static typelib_TypeDescription * createCTD(
109     const Reference< XUnionTypeDescription > & xType )
110 {
111     typelib_TypeDescription * pRet = 0;
112     if (xType.is())
113     {
114         OUString aTypeName( xType->getName() );
115 
116         // discriminant type
117         Reference< XTypeDescription > xDiscrTD( xType->getDiscriminantType() );
118         OUString aDiscrTypeName( xDiscrTD->getName() );
119         typelib_TypeDescriptionReference * pDiscrTypeRef = 0;
120         typelib_typedescriptionreference_new( &pDiscrTypeRef,
121                                               (typelib_TypeClass)xDiscrTD->getTypeClass(),
122                                               aDiscrTypeName.pData );
123         // default member type
124         Reference< XTypeDescription > xDefaultMemberTD( xType->getDefaultMemberType() );
125         OUString aDefMemberTypeName( xDefaultMemberTD->getName() );
126         typelib_TypeDescriptionReference * pDefMemberTypeRef = 0;
127         typelib_typedescriptionreference_new( &pDefMemberTypeRef,
128                                               (typelib_TypeClass)xDefaultMemberTD->getTypeClass(),
129                                               aDefMemberTypeName.pData );
130         // init array
131         Sequence< Any > aDiscriminants( xType->getDiscriminants() );
132         Sequence< Reference< XTypeDescription > > aMemberTypes( xType->getMemberTypes() );
133         Sequence< OUString > aMemberNames( xType->getMemberNames() );
134         sal_Int32 nMembers = aDiscriminants.getLength();
135         OSL_ASSERT( nMembers == aMemberNames.getLength() && nMembers == aMemberTypes.getLength() );
136 
137         const Any * pDiscriminants                          = aDiscriminants.getConstArray();
138         const Reference< XTypeDescription > * pMemberTypes  = aMemberTypes.getConstArray();
139         const OUString * pMemberNames                       = aMemberNames.getConstArray();
140 
141         typelib_Union_Init * pMembers = (typelib_Union_Init *)alloca( nMembers * sizeof(typelib_Union_Init) );
142 
143         sal_Int32 nPos;
144         for ( nPos = nMembers; nPos--; )
145         {
146             typelib_Union_Init & rEntry = pMembers[nPos];
147             // member discriminant
148             rEntry.nDiscriminant = coerceToInt64( pDiscriminants[nPos] );
149             // member type
150             OUString aMemberTypeName( pMemberTypes[nPos]->getName() );
151             rEntry.pTypeRef = 0;
152             typelib_typedescriptionreference_new( &rEntry.pTypeRef,
153                                                   (typelib_TypeClass)pMemberTypes[nPos]->getTypeClass(),
154                                                   aMemberTypeName.pData );
155             // member name
156             rEntry.pMemberName = pMemberNames[nPos].pData;
157         }
158 
159         typelib_typedescription_newUnion( &pRet, aTypeName.pData,
160                                           pDiscrTypeRef,
161                                           coerceToInt64( xType->getDefaultDiscriminant() ),
162                                           pDefMemberTypeRef,
163                                           nMembers, pMembers );
164 
165         for ( nPos = nMembers; nPos--; )
166         {
167             typelib_typedescriptionreference_release( pMembers[nPos].pTypeRef );
168         }
169 
170         typelib_typedescriptionreference_release( pDiscrTypeRef );
171         typelib_typedescriptionreference_release( pDefMemberTypeRef );
172     }
173     return pRet;
174 }
175 //==================================================================================================
176 inline static typelib_TypeDescription * createCTD(
177     const Reference< XCompoundTypeDescription > & xType )
178 {
179     typelib_TypeDescription * pRet = 0;
180     if (xType.is())
181     {
182         typelib_TypeDescription * pBaseType = createCTD(
183             Reference< XCompoundTypeDescription >::query( xType->getBaseType() ) );
184         if (pBaseType)
185             typelib_typedescription_register( &pBaseType );
186 
187         // construct member init array
188         const Sequence<Reference< XTypeDescription > > & rMemberTypes = xType->getMemberTypes();
189         const Sequence< OUString > & rMemberNames                     = xType->getMemberNames();
190 
191         const Reference< XTypeDescription > * pMemberTypes = rMemberTypes.getConstArray();
192         const OUString * pMemberNames                      = rMemberNames.getConstArray();
193 
194         sal_Int32 nMembers = rMemberTypes.getLength();
195         OSL_ENSURE( nMembers == rMemberNames.getLength(), "### lens differ!" );
196 
197         OUString aTypeName( xType->getName() );
198 
199         typelib_CompoundMember_Init * pMemberInits = (typelib_CompoundMember_Init *)alloca(
200             sizeof(typelib_CompoundMember_Init) * nMembers );
201 
202         sal_Int32 nPos;
203         for ( nPos = nMembers; nPos--; )
204         {
205             typelib_CompoundMember_Init & rInit = pMemberInits[nPos];
206             rInit.eTypeClass = (typelib_TypeClass)pMemberTypes[nPos]->getTypeClass();
207 
208             OUString aMemberTypeName( pMemberTypes[nPos]->getName() );
209             rtl_uString_acquire( rInit.pTypeName = aMemberTypeName.pData );
210 
211             // string is held by rMemberNames
212             rInit.pMemberName = pMemberNames[nPos].pData;
213         }
214 
215         typelib_typedescription_new(
216             &pRet,
217             (typelib_TypeClass)xType->getTypeClass(),
218             aTypeName.pData,
219             (pBaseType ? pBaseType->pWeakRef : 0),
220             nMembers, pMemberInits );
221 
222         // cleanup
223         for ( nPos = nMembers; nPos--; )
224         {
225             rtl_uString_release( pMemberInits[nPos].pTypeName );
226         }
227         if (pBaseType)
228             typelib_typedescription_release( pBaseType );
229     }
230     return pRet;
231 }
232 //==================================================================================================
233 inline static typelib_TypeDescription * createCTD(
234     Reference< container::XHierarchicalNameAccess > const & access,
235     const Reference< XStructTypeDescription > & xType )
236 {
237     typelib_TypeDescription * pRet = 0;
238     if (xType.is() && xType->getTypeParameters().getLength() == 0)
239     {
240         typelib_TypeDescription * pBaseType = createCTD(
241             access, xType->getBaseType() );
242         if (pBaseType)
243             typelib_typedescription_register( &pBaseType );
244 
245         // construct member init array
246         const Sequence<Reference< XTypeDescription > > & rMemberTypes = xType->getMemberTypes();
247         const Sequence< OUString > & rMemberNames                     = xType->getMemberNames();
248 
249         const Reference< XTypeDescription > * pMemberTypes = rMemberTypes.getConstArray();
250         const OUString * pMemberNames                      = rMemberNames.getConstArray();
251 
252         sal_Int32 nMembers = rMemberTypes.getLength();
253         OSL_ENSURE( nMembers == rMemberNames.getLength(), "### lens differ!" );
254 
255         OUString aTypeName( xType->getName() );
256 
257         typelib_StructMember_Init * pMemberInits = (typelib_StructMember_Init *)alloca(
258             sizeof(typelib_StructMember_Init) * nMembers );
259 
260         Sequence< Reference< XTypeDescription > > templateMemberTypes;
261         sal_Int32 i = aTypeName.indexOf('<');
262         if (i >= 0) {
263             Reference< XStructTypeDescription > templateDesc(
264                 access->getByHierarchicalName(aTypeName.copy(0, i)),
265                 UNO_QUERY_THROW);
266             OSL_ASSERT(
267                 templateDesc->getTypeParameters().getLength()
268                 == xType->getTypeArguments().getLength());
269             templateMemberTypes = templateDesc->getMemberTypes();
270             OSL_ASSERT(templateMemberTypes.getLength() == nMembers);
271         }
272 
273         sal_Int32 nPos;
274         for ( nPos = nMembers; nPos--; )
275         {
276             typelib_StructMember_Init & rInit = pMemberInits[nPos];
277             rInit.aBase.eTypeClass
278                 = (typelib_TypeClass)pMemberTypes[nPos]->getTypeClass();
279 
280             OUString aMemberTypeName( pMemberTypes[nPos]->getName() );
281             rtl_uString_acquire(
282                 rInit.aBase.pTypeName = aMemberTypeName.pData );
283 
284             // string is held by rMemberNames
285             rInit.aBase.pMemberName = pMemberNames[nPos].pData;
286 
287             rInit.bParameterizedType = templateMemberTypes.getLength() != 0
288                 && (templateMemberTypes[nPos]->getTypeClass()
289                     == TypeClass_UNKNOWN);
290         }
291 
292         typelib_typedescription_newStruct(
293             &pRet,
294             aTypeName.pData,
295             (pBaseType ? pBaseType->pWeakRef : 0),
296             nMembers, pMemberInits );
297 
298         // cleanup
299         for ( nPos = nMembers; nPos--; )
300         {
301             rtl_uString_release( pMemberInits[nPos].aBase.pTypeName );
302         }
303         if (pBaseType)
304             typelib_typedescription_release( pBaseType );
305     }
306     return pRet;
307 }
308 //==================================================================================================
309 inline static typelib_TypeDescription * createCTD(
310     const Reference< XInterfaceAttributeTypeDescription2 > & xAttribute )
311 {
312     typelib_TypeDescription * pRet = 0;
313     if (xAttribute.is())
314     {
315         OUString aMemberName( xAttribute->getName() );
316         Reference< XTypeDescription > xType( xAttribute->getType() );
317         OUString aMemberTypeName( xType->getName() );
318         std::vector< rtl_uString * > getExc;
319         Sequence< Reference< XCompoundTypeDescription > > getExcs(
320             xAttribute->getGetExceptions() );
321         for (sal_Int32 i = 0; i != getExcs.getLength(); ++i)
322         {
323             OSL_ASSERT( getExcs[i].is() );
324             getExc.push_back( getExcs[i]->getName().pData );
325         }
326         std::vector< rtl_uString * > setExc;
327         Sequence< Reference< XCompoundTypeDescription > > setExcs(
328             xAttribute->getSetExceptions() );
329         for (sal_Int32 i = 0; i != setExcs.getLength(); ++i)
330         {
331             OSL_ASSERT( setExcs[i].is() );
332             setExc.push_back( setExcs[i]->getName().pData );
333         }
334         typelib_typedescription_newExtendedInterfaceAttribute(
335             (typelib_InterfaceAttributeTypeDescription **)&pRet,
336             xAttribute->getPosition(),
337             aMemberName.pData, // name
338             (typelib_TypeClass)xType->getTypeClass(),
339             aMemberTypeName.pData, // type name
340             xAttribute->isReadOnly(),
341             getExc.size(), getExc.empty() ? 0 : &getExc[0],
342             setExc.size(), setExc.empty() ? 0 : &setExc[0] );
343     }
344     return pRet;
345 }
346 //==================================================================================================
347 static typelib_TypeDescription * createCTD(
348     const Reference< XInterfaceMethodTypeDescription > & xMethod )
349 {
350     typelib_TypeDescription * pRet = 0;
351     if (xMethod.is())
352     {
353         Reference< XTypeDescription > xReturnType( xMethod->getReturnType() );
354 
355         // init all params
356         const Sequence<Reference< XMethodParameter > > & rParams = xMethod->getParameters();
357         const Reference< XMethodParameter > * pParams            = rParams.getConstArray();
358         sal_Int32 nParams = rParams.getLength();
359 
360         typelib_Parameter_Init * pParamInit = (typelib_Parameter_Init *)alloca(
361             sizeof(typelib_Parameter_Init) * nParams );
362 
363         sal_Int32 nPos;
364         for ( nPos = nParams; nPos--; )
365         {
366             const Reference< XMethodParameter > & xParam = pParams[nPos];
367             const Reference< XTypeDescription > & xType  = xParam->getType();
368             typelib_Parameter_Init & rInit = pParamInit[xParam->getPosition()];
369 
370             rInit.eTypeClass = (typelib_TypeClass)xType->getTypeClass();
371             OUString aParamTypeName( xType->getName() );
372             rtl_uString_acquire( rInit.pTypeName = aParamTypeName.pData );
373             OUString aParamName( xParam->getName() );
374             rtl_uString_acquire( rInit.pParamName = aParamName.pData );
375             rInit.bIn  = xParam->isIn();
376             rInit.bOut = xParam->isOut();
377         }
378 
379         // init all exception strings
380         const Sequence<Reference< XTypeDescription > > & rExceptions = xMethod->getExceptions();
381         const Reference< XTypeDescription > * pExceptions = rExceptions.getConstArray();
382         sal_Int32 nExceptions = rExceptions.getLength();
383         rtl_uString ** ppExceptionNames = (rtl_uString **)alloca(
384             sizeof(rtl_uString *) * nExceptions );
385 
386         for ( nPos = nExceptions; nPos--; )
387         {
388             OUString aExceptionTypeName( pExceptions[nPos]->getName() );
389             rtl_uString_acquire( ppExceptionNames[nPos] = aExceptionTypeName.pData );
390         }
391 
392         OUString aTypeName( xMethod->getName() );
393         OUString aReturnTypeName( xReturnType->getName() );
394 
395         typelib_typedescription_newInterfaceMethod(
396             (typelib_InterfaceMethodTypeDescription **)&pRet,
397             xMethod->getPosition(),
398             xMethod->isOneway(),
399             aTypeName.pData,
400             (typelib_TypeClass)xReturnType->getTypeClass(),
401             aReturnTypeName.pData,
402             nParams, pParamInit,
403             nExceptions, ppExceptionNames );
404 
405         for ( nPos = nParams; nPos--; )
406         {
407             rtl_uString_release( pParamInit[nPos].pTypeName );
408             rtl_uString_release( pParamInit[nPos].pParamName );
409         }
410         for ( nPos = nExceptions; nPos--; )
411         {
412             rtl_uString_release( ppExceptionNames[nPos] );
413         }
414     }
415     return pRet;
416 }
417 //==================================================================================================
418 inline static typelib_TypeDescription * createCTD(
419     Reference< container::XHierarchicalNameAccess > const & access,
420     const Reference< XInterfaceTypeDescription2 > & xType )
421 {
422     typelib_TypeDescription * pRet = 0;
423     if (xType.is())
424     {
425         Sequence< Reference< XTypeDescription > > aBases(xType->getBaseTypes());
426         sal_Int32 nBases = aBases.getLength();
427         // Exploit the fact that a typelib_TypeDescription for an interface type
428         // is also the typelib_TypeDescriptionReference for that type:
429         boost::scoped_array< typelib_TypeDescription * > aBaseTypes(
430             new typelib_TypeDescription *[nBases]);
431         {for (sal_Int32 i = 0; i < nBases; ++i) {
432             typelib_TypeDescription * p = createCTD(access, aBases[i]);
433             OSL_ASSERT(
434                 !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(p->eTypeClass));
435             typelib_typedescription_register(&p);
436             aBaseTypes[i] = p;
437         }}
438         typelib_TypeDescriptionReference ** pBaseTypeRefs
439             = reinterpret_cast< typelib_TypeDescriptionReference ** >(
440                 aBaseTypes.get());
441 
442         // construct all member refs
443         const Sequence<Reference< XInterfaceMemberTypeDescription > > & rMembers = xType->getMembers();
444         sal_Int32 nMembers = rMembers.getLength();
445 
446         typelib_TypeDescriptionReference ** ppMemberRefs = (typelib_TypeDescriptionReference **)alloca(
447             sizeof(typelib_TypeDescriptionReference *) * nMembers );
448 
449         const Reference< XInterfaceMemberTypeDescription > * pMembers = rMembers.getConstArray();
450 
451         OUString aTypeName( xType->getName() );
452 
453         sal_Int32 nPos;
454         for ( nPos = nMembers; nPos--; )
455         {
456             OUString aMemberTypeName( pMembers[nPos]->getName() );
457             ppMemberRefs[nPos] = 0;
458             typelib_typedescriptionreference_new(
459                 ppMemberRefs + nPos,
460                 (typelib_TypeClass)pMembers[nPos]->getTypeClass(),
461                 aMemberTypeName.pData );
462         }
463 
464         Uik uik = xType->getUik();
465 
466         typelib_typedescription_newMIInterface(
467             (typelib_InterfaceTypeDescription **)&pRet,
468             aTypeName.pData,
469             uik.m_Data1, uik.m_Data2, uik.m_Data3, uik.m_Data4, uik.m_Data5,
470             nBases, pBaseTypeRefs,
471             nMembers, ppMemberRefs );
472 
473         // cleanup refs and base type
474         {for (int i = 0; i < nBases; ++i) {
475             typelib_typedescription_release(aBaseTypes[i]);
476         }}
477 
478         for ( nPos = nMembers; nPos--; )
479         {
480             typelib_typedescriptionreference_release( ppMemberRefs[nPos] );
481         }
482     }
483     return pRet;
484 }
485 //==================================================================================================
486 inline static typelib_TypeDescription * createCTD( const Reference< XEnumTypeDescription > & xType )
487 {
488     typelib_TypeDescription * pRet = 0;
489     if (xType.is())
490     {
491         OUString aTypeName( xType->getName() );
492         Sequence< OUString > aNames( xType->getEnumNames() );
493         OSL_ASSERT( sizeof(OUString) == sizeof(rtl_uString *) ); // !!!
494         Sequence< sal_Int32 > aValues( xType->getEnumValues() );
495 
496         typelib_typedescription_newEnum(
497             &pRet, aTypeName.pData, xType->getDefaultEnumValue(),
498             aNames.getLength(),
499             (rtl_uString **)aNames.getConstArray(),
500             const_cast< sal_Int32 * >( aValues.getConstArray() ) );
501     }
502     return pRet;
503 }
504 //==================================================================================================
505 inline static typelib_TypeDescription * createCTD(
506     Reference< container::XHierarchicalNameAccess > const & access,
507     const Reference< XIndirectTypeDescription > & xType )
508 {
509     typelib_TypeDescription * pRet = 0;
510     if (xType.is())
511     {
512         typelib_TypeDescription * pRefType = createCTD(
513             access, xType->getReferencedType() );
514         typelib_typedescription_register( &pRefType );
515 
516         OUString aTypeName( xType->getName() );
517 
518         typelib_typedescription_new(
519             &pRet,
520             (typelib_TypeClass)xType->getTypeClass(),
521             aTypeName.pData,
522             pRefType->pWeakRef,
523             0, 0 );
524 
525         // cleanup
526         if (pRefType)
527             typelib_typedescription_release( pRefType );
528     }
529     return pRet;
530 }
531 
532 //==================================================================================================
533 static typelib_TypeDescription * createCTD(
534     Reference< container::XHierarchicalNameAccess > const & access,
535     const Reference< XTypeDescription > & xType )
536 {
537     typelib_TypeDescription * pRet = 0;
538 
539     if (xType.is())
540     {
541         switch (xType->getTypeClass())
542         {
543             // built in types
544         case TypeClass_VOID:
545         {
546             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("void") );
547             typelib_typedescription_new( &pRet, typelib_TypeClass_VOID, aTypeName.pData, 0, 0, 0 );
548             break;
549         }
550         case TypeClass_CHAR:
551         {
552             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("char") );
553             typelib_typedescription_new( &pRet, typelib_TypeClass_CHAR, aTypeName.pData, 0, 0, 0 );
554             break;
555         }
556         case TypeClass_BOOLEAN:
557         {
558             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("boolean") );
559             typelib_typedescription_new( &pRet, typelib_TypeClass_BOOLEAN, aTypeName.pData, 0, 0, 0 );
560             break;
561         }
562         case TypeClass_BYTE:
563         {
564             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("byte") );
565             typelib_typedescription_new( &pRet, typelib_TypeClass_BYTE, aTypeName.pData, 0, 0, 0 );
566             break;
567         }
568         case TypeClass_SHORT:
569         {
570             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("short") );
571             typelib_typedescription_new( &pRet, typelib_TypeClass_SHORT, aTypeName.pData, 0, 0, 0 );
572             break;
573         }
574         case TypeClass_UNSIGNED_SHORT:
575         {
576             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("unsigned short") );
577             typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_SHORT, aTypeName.pData, 0, 0, 0 );
578             break;
579         }
580         case TypeClass_LONG:
581         {
582             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("long") );
583             typelib_typedescription_new( &pRet, typelib_TypeClass_LONG, aTypeName.pData, 0, 0, 0 );
584             break;
585         }
586         case TypeClass_UNSIGNED_LONG:
587         {
588             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("unsigned long") );
589             typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_LONG, aTypeName.pData, 0, 0, 0 );
590             break;
591         }
592         case TypeClass_HYPER:
593         {
594             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("hyper") );
595             typelib_typedescription_new( &pRet, typelib_TypeClass_HYPER, aTypeName.pData, 0, 0, 0 );
596             break;
597         }
598         case TypeClass_UNSIGNED_HYPER:
599         {
600             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("unsigned hyper") );
601             typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_HYPER, aTypeName.pData, 0, 0, 0 );
602             break;
603         }
604         case TypeClass_FLOAT:
605         {
606             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("float") );
607             typelib_typedescription_new( &pRet, typelib_TypeClass_FLOAT, aTypeName.pData, 0, 0, 0 );
608             break;
609         }
610         case TypeClass_DOUBLE:
611         {
612             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("double") );
613             typelib_typedescription_new( &pRet, typelib_TypeClass_DOUBLE, aTypeName.pData, 0, 0, 0 );
614             break;
615         }
616         case TypeClass_STRING:
617         {
618             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("string") );
619             typelib_typedescription_new( &pRet, typelib_TypeClass_STRING, aTypeName.pData, 0, 0, 0 );
620             break;
621         }
622         case TypeClass_TYPE:
623         {
624             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("type") );
625             typelib_typedescription_new( &pRet, typelib_TypeClass_TYPE, aTypeName.pData, 0, 0, 0 );
626             break;
627         }
628         case TypeClass_ANY:
629         {
630             OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("any") );
631             typelib_typedescription_new( &pRet, typelib_TypeClass_ANY, aTypeName.pData, 0, 0, 0 );
632             break;
633         }
634 
635         case TypeClass_UNION:
636             pRet = createCTD( Reference< XUnionTypeDescription >::query( xType ) );
637             break;
638         case TypeClass_EXCEPTION:
639             pRet = createCTD( Reference< XCompoundTypeDescription >::query( xType ) );
640             break;
641         case TypeClass_STRUCT:
642             pRet = createCTD(
643                 access, Reference< XStructTypeDescription >::query( xType ) );
644             break;
645         case TypeClass_ENUM:
646             pRet = createCTD( Reference< XEnumTypeDescription >::query( xType ) );
647             break;
648         case TypeClass_TYPEDEF:
649         {
650             Reference< XIndirectTypeDescription > xTypedef( xType, UNO_QUERY );
651             if (xTypedef.is())
652                 pRet = createCTD( access, xTypedef->getReferencedType() );
653             break;
654         }
655         case TypeClass_SEQUENCE:
656             pRet = createCTD(
657                 access, Reference< XIndirectTypeDescription >::query( xType ) );
658             break;
659         case TypeClass_INTERFACE:
660             pRet = createCTD(
661                 access,
662                 Reference< XInterfaceTypeDescription2 >::query( xType ) );
663             break;
664         case TypeClass_INTERFACE_METHOD:
665             pRet = createCTD( Reference< XInterfaceMethodTypeDescription >::query( xType ) );
666             break;
667         case TypeClass_INTERFACE_ATTRIBUTE:
668             pRet = createCTD( Reference< XInterfaceAttributeTypeDescription2 >::query( xType ) );
669             break;
670         default:
671             break;
672         }
673     }
674 
675     return pRet;
676 }
677 
678 
679 //==================================================================================================
680 extern "C"
681 {
682 static void SAL_CALL typelib_callback(
683     void * pContext, typelib_TypeDescription ** ppRet, rtl_uString * pTypeName )
684 {
685     OSL_ENSURE( pContext && ppRet && pTypeName, "### null ptr!" );
686     if (ppRet)
687     {
688         if (*ppRet)
689         {
690             ::typelib_typedescription_release( *ppRet );
691             *ppRet = 0;
692         }
693         if (pContext && pTypeName)
694         {
695             Reference< container::XHierarchicalNameAccess > access(
696                 reinterpret_cast< container::XHierarchicalNameAccess * >(
697                     pContext));
698             try
699             {
700                 OUString const & rTypeName = OUString::unacquired( &pTypeName );
701                 Reference< XTypeDescription > xTD;
702                 if (access->getByHierarchicalName(rTypeName ) >>= xTD)
703                 {
704                     *ppRet = createCTD( access, xTD );
705                 }
706             }
707             catch (container::NoSuchElementException & exc)
708             {
709                 (void) exc; // avoid warning about unused variable
710                 OSL_TRACE(
711                     "typelibrary type not available: %s",
712                     OUStringToOString(
713                         exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
714             }
715             catch (Exception & exc)
716             {
717                 (void) exc; // avoid warning about unused variable
718                 OSL_TRACE(
719                     "%s",
720                     OUStringToOString(
721                         exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
722             }
723         }
724     }
725 }
726 }
727 
728 //==================================================================================================
729 class EventListenerImpl
730     : public WeakImplHelper1< lang::XEventListener >
731 {
732     Reference< container::XHierarchicalNameAccess > m_xTDMgr;
733 
734 public:
735     inline EventListenerImpl(
736         Reference< container::XHierarchicalNameAccess > const & xTDMgr )
737         SAL_THROW( () )
738         : m_xTDMgr( xTDMgr )
739         {}
740 
741     // XEventListener
742     virtual void SAL_CALL disposing( lang::EventObject const & rEvt )
743         throw (RuntimeException);
744 };
745 //__________________________________________________________________________________________________
746 void EventListenerImpl::disposing( lang::EventObject const & rEvt )
747     throw (RuntimeException)
748 {
749     if (rEvt.Source != m_xTDMgr) {
750         OSL_ASSERT(false);
751     }
752     // deregister of c typelib callback
753     ::typelib_typedescription_revokeCallback( m_xTDMgr.get(), typelib_callback );
754 }
755 
756 //==================================================================================================
757 sal_Bool SAL_CALL installTypeDescriptionManager(
758     Reference< container::XHierarchicalNameAccess > const & xTDMgr_c )
759     SAL_THROW( () )
760 {
761     uno::Environment curr_env(Environment::getCurrent());
762     uno::Environment target_env(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))));
763 
764     uno::Mapping curr2target(curr_env, target_env);
765 
766 
767     Reference<container::XHierarchicalNameAccess> xTDMgr(
768         reinterpret_cast<container::XHierarchicalNameAccess *>(
769             curr2target.mapInterface(xTDMgr_c.get(), ::getCppuType(&xTDMgr_c))),
770         SAL_NO_ACQUIRE);
771 
772     Reference< lang::XComponent > xComp( xTDMgr, UNO_QUERY );
773     if (xComp.is())
774     {
775         xComp->addEventListener( new EventListenerImpl( xTDMgr ) );
776         // register c typelib callback
777         ::typelib_typedescription_registerCallback( xTDMgr.get(), typelib_callback );
778         return sal_True;
779     }
780     return sal_False;
781 }
782 
783 } // end namespace cppu
784 
785