xref: /trunk/main/cppuhelper/source/tdmgr.cxx (revision cdf0e10c)
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