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