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