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