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