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 196 : inline static typelib_TypeDescription * createCTD(
167 : const Reference< XCompoundTypeDescription > & xType )
168 : {
169 196 : typelib_TypeDescription * pRet = 0;
170 196 : if (xType.is())
171 : {
172 : typelib_TypeDescription * pBaseType = createCTD(
173 146 : Reference< XCompoundTypeDescription >::query( xType->getBaseType() ) );
174 146 : if (pBaseType)
175 96 : typelib_typedescription_register( &pBaseType );
176 :
177 : // construct member init array
178 146 : const Sequence<Reference< XTypeDescription > > & rMemberTypes = xType->getMemberTypes();
179 146 : const Sequence< OUString > & rMemberNames = xType->getMemberNames();
180 :
181 146 : const Reference< XTypeDescription > * pMemberTypes = rMemberTypes.getConstArray();
182 146 : const OUString * pMemberNames = rMemberNames.getConstArray();
183 :
184 146 : sal_Int32 nMembers = rMemberTypes.getLength();
185 : OSL_ENSURE( nMembers == rMemberNames.getLength(), "### lens differ!" );
186 :
187 146 : OUString aTypeName( xType->getName() );
188 :
189 146 : typelib_CompoundMember_Init * pMemberInits = (typelib_CompoundMember_Init *)alloca(
190 : sizeof(typelib_CompoundMember_Init) * nMembers );
191 :
192 : sal_Int32 nPos;
193 487 : for ( nPos = nMembers; nPos--; )
194 : {
195 195 : typelib_CompoundMember_Init & rInit = pMemberInits[nPos];
196 195 : rInit.eTypeClass = (typelib_TypeClass)pMemberTypes[nPos]->getTypeClass();
197 :
198 195 : OUString aMemberTypeName( pMemberTypes[nPos]->getName() );
199 195 : rtl_uString_acquire( rInit.pTypeName = aMemberTypeName.pData );
200 :
201 : // string is held by rMemberNames
202 195 : rInit.pMemberName = pMemberNames[nPos].pData;
203 195 : }
204 :
205 : typelib_typedescription_new(
206 : &pRet,
207 292 : (typelib_TypeClass)xType->getTypeClass(),
208 : aTypeName.pData,
209 : (pBaseType ? pBaseType->pWeakRef : 0),
210 438 : nMembers, pMemberInits );
211 :
212 : // cleanup
213 487 : for ( nPos = nMembers; nPos--; )
214 : {
215 195 : rtl_uString_release( pMemberInits[nPos].pTypeName );
216 : }
217 146 : if (pBaseType)
218 96 : typelib_typedescription_release( pBaseType );
219 : }
220 196 : return pRet;
221 : }
222 : //==================================================================================================
223 605 : inline static typelib_TypeDescription * createCTD(
224 : Reference< container::XHierarchicalNameAccess > const & access,
225 : const Reference< XStructTypeDescription > & xType )
226 : {
227 605 : typelib_TypeDescription * pRet = 0;
228 605 : if (xType.is() && xType->getTypeParameters().getLength() == 0)
229 : {
230 : typelib_TypeDescription * pBaseType = createCTD(
231 605 : access, xType->getBaseType() );
232 605 : if (pBaseType)
233 88 : typelib_typedescription_register( &pBaseType );
234 :
235 : // construct member init array
236 605 : const Sequence<Reference< XTypeDescription > > & rMemberTypes = xType->getMemberTypes();
237 605 : const Sequence< OUString > & rMemberNames = xType->getMemberNames();
238 :
239 605 : const Reference< XTypeDescription > * pMemberTypes = rMemberTypes.getConstArray();
240 605 : const OUString * pMemberNames = rMemberNames.getConstArray();
241 :
242 605 : sal_Int32 nMembers = rMemberTypes.getLength();
243 : OSL_ENSURE( nMembers == rMemberNames.getLength(), "### lens differ!" );
244 :
245 605 : OUString aTypeName( xType->getName() );
246 :
247 605 : typelib_StructMember_Init * pMemberInits = (typelib_StructMember_Init *)alloca(
248 : sizeof(typelib_StructMember_Init) * nMembers );
249 :
250 605 : Sequence< Reference< XTypeDescription > > templateMemberTypes;
251 605 : sal_Int32 i = aTypeName.indexOf('<');
252 605 : if (i >= 0) {
253 : Reference< XStructTypeDescription > templateDesc(
254 50 : access->getByHierarchicalName(aTypeName.copy(0, i)),
255 50 : UNO_QUERY_THROW);
256 : OSL_ASSERT(
257 : templateDesc->getTypeParameters().getLength()
258 : == xType->getTypeArguments().getLength());
259 50 : templateMemberTypes = templateDesc->getMemberTypes();
260 50 : OSL_ASSERT(templateMemberTypes.getLength() == nMembers);
261 : }
262 :
263 : sal_Int32 nPos;
264 3300 : for ( nPos = nMembers; nPos--; )
265 : {
266 2090 : typelib_StructMember_Init & rInit = pMemberInits[nPos];
267 : rInit.aBase.eTypeClass
268 2090 : = (typelib_TypeClass)pMemberTypes[nPos]->getTypeClass();
269 :
270 2090 : OUString aMemberTypeName( pMemberTypes[nPos]->getName() );
271 : rtl_uString_acquire(
272 2090 : rInit.aBase.pTypeName = aMemberTypeName.pData );
273 :
274 : // string is held by rMemberNames
275 2090 : rInit.aBase.pMemberName = pMemberNames[nPos].pData;
276 :
277 2090 : rInit.bParameterizedType = templateMemberTypes.getLength() != 0
278 64 : && (templateMemberTypes[nPos]->getTypeClass()
279 2154 : == TypeClass_UNKNOWN);
280 2090 : }
281 :
282 : typelib_typedescription_newStruct(
283 : &pRet,
284 : aTypeName.pData,
285 : (pBaseType ? pBaseType->pWeakRef : 0),
286 605 : nMembers, pMemberInits );
287 :
288 : // cleanup
289 3300 : for ( nPos = nMembers; nPos--; )
290 : {
291 2090 : rtl_uString_release( pMemberInits[nPos].aBase.pTypeName );
292 : }
293 605 : if (pBaseType)
294 88 : typelib_typedescription_release( pBaseType );
295 : }
296 605 : return pRet;
297 : }
298 : //==================================================================================================
299 387 : inline static typelib_TypeDescription * createCTD(
300 : const Reference< XInterfaceAttributeTypeDescription2 > & xAttribute )
301 : {
302 387 : typelib_TypeDescription * pRet = 0;
303 387 : if (xAttribute.is())
304 : {
305 387 : OUString aMemberName( xAttribute->getName() );
306 387 : Reference< XTypeDescription > xType( xAttribute->getType() );
307 387 : OUString aMemberTypeName( xType->getName() );
308 387 : std::vector< rtl_uString * > getExc;
309 : Sequence< Reference< XCompoundTypeDescription > > getExcs(
310 387 : xAttribute->getGetExceptions() );
311 388 : 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 387 : std::vector< rtl_uString * > setExc;
317 : Sequence< Reference< XCompoundTypeDescription > > setExcs(
318 387 : xAttribute->getSetExceptions() );
319 422 : for (sal_Int32 i = 0; i != setExcs.getLength(); ++i)
320 : {
321 : OSL_ASSERT( setExcs[i].is() );
322 35 : setExc.push_back( setExcs[i]->getName().pData );
323 : }
324 : typelib_typedescription_newExtendedInterfaceAttribute(
325 : (typelib_InterfaceAttributeTypeDescription **)&pRet,
326 774 : xAttribute->getPosition(),
327 : aMemberName.pData, // name
328 387 : (typelib_TypeClass)xType->getTypeClass(),
329 : aMemberTypeName.pData, // type name
330 387 : xAttribute->isReadOnly(),
331 774 : getExc.size(), getExc.empty() ? 0 : &getExc[0],
332 2709 : setExc.size(), setExc.empty() ? 0 : &setExc[0] );
333 : }
334 387 : return pRet;
335 : }
336 : //==================================================================================================
337 1463 : static typelib_TypeDescription * createCTD(
338 : const Reference< XInterfaceMethodTypeDescription > & xMethod )
339 : {
340 1463 : typelib_TypeDescription * pRet = 0;
341 1463 : if (xMethod.is())
342 : {
343 1463 : Reference< XTypeDescription > xReturnType( xMethod->getReturnType() );
344 :
345 : // init all params
346 1463 : const Sequence<Reference< XMethodParameter > > & rParams = xMethod->getParameters();
347 1463 : const Reference< XMethodParameter > * pParams = rParams.getConstArray();
348 1463 : sal_Int32 nParams = rParams.getLength();
349 :
350 1463 : typelib_Parameter_Init * pParamInit = (typelib_Parameter_Init *)alloca(
351 : sizeof(typelib_Parameter_Init) * nParams );
352 :
353 : sal_Int32 nPos;
354 4246 : for ( nPos = nParams; nPos--; )
355 : {
356 1320 : const Reference< XMethodParameter > & xParam = pParams[nPos];
357 1320 : const Reference< XTypeDescription > & xType = xParam->getType();
358 1320 : typelib_Parameter_Init & rInit = pParamInit[xParam->getPosition()];
359 :
360 1320 : rInit.eTypeClass = (typelib_TypeClass)xType->getTypeClass();
361 1320 : OUString aParamTypeName( xType->getName() );
362 1320 : rtl_uString_acquire( rInit.pTypeName = aParamTypeName.pData );
363 1320 : OUString aParamName( xParam->getName() );
364 1320 : rtl_uString_acquire( rInit.pParamName = aParamName.pData );
365 1320 : rInit.bIn = xParam->isIn();
366 1320 : rInit.bOut = xParam->isOut();
367 1320 : }
368 :
369 : // init all exception strings
370 1463 : const Sequence<Reference< XTypeDescription > > & rExceptions = xMethod->getExceptions();
371 1463 : const Reference< XTypeDescription > * pExceptions = rExceptions.getConstArray();
372 1463 : sal_Int32 nExceptions = rExceptions.getLength();
373 1463 : rtl_uString ** ppExceptionNames = (rtl_uString **)alloca(
374 : sizeof(rtl_uString *) * nExceptions );
375 :
376 3852 : for ( nPos = nExceptions; nPos--; )
377 : {
378 926 : OUString aExceptionTypeName( pExceptions[nPos]->getName() );
379 926 : rtl_uString_acquire( ppExceptionNames[nPos] = aExceptionTypeName.pData );
380 926 : }
381 :
382 1463 : OUString aTypeName( xMethod->getName() );
383 1463 : OUString aReturnTypeName( xReturnType->getName() );
384 :
385 : typelib_typedescription_newInterfaceMethod(
386 : (typelib_InterfaceMethodTypeDescription **)&pRet,
387 2926 : xMethod->getPosition(),
388 1463 : xMethod->isOneway(),
389 : aTypeName.pData,
390 1463 : (typelib_TypeClass)xReturnType->getTypeClass(),
391 : aReturnTypeName.pData,
392 : nParams, pParamInit,
393 7315 : nExceptions, ppExceptionNames );
394 :
395 4246 : for ( nPos = nParams; nPos--; )
396 : {
397 1320 : rtl_uString_release( pParamInit[nPos].pTypeName );
398 1320 : rtl_uString_release( pParamInit[nPos].pParamName );
399 : }
400 3852 : for ( nPos = nExceptions; nPos--; )
401 : {
402 926 : rtl_uString_release( ppExceptionNames[nPos] );
403 1463 : }
404 : }
405 1463 : return pRet;
406 : }
407 : //==================================================================================================
408 6411 : inline static typelib_TypeDescription * createCTD(
409 : Reference< container::XHierarchicalNameAccess > const & access,
410 : const Reference< XInterfaceTypeDescription2 > & xType )
411 : {
412 6411 : typelib_TypeDescription * pRet = 0;
413 6411 : if (xType.is())
414 : {
415 6411 : Sequence< Reference< XTypeDescription > > aBases(xType->getBaseTypes());
416 6411 : 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 6411 : new typelib_TypeDescription *[nBases]);
421 10519 : {for (sal_Int32 i = 0; i < nBases; ++i) {
422 4108 : typelib_TypeDescription * p = createCTD(access, aBases[i]);
423 : OSL_ASSERT(
424 : !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(p->eTypeClass));
425 4108 : typelib_typedescription_register(&p);
426 4108 : aBaseTypes[i] = p;
427 : }}
428 : typelib_TypeDescriptionReference ** pBaseTypeRefs
429 : = reinterpret_cast< typelib_TypeDescriptionReference ** >(
430 6411 : aBaseTypes.get());
431 :
432 : // construct all member refs
433 6411 : const Sequence<Reference< XInterfaceMemberTypeDescription > > & rMembers = xType->getMembers();
434 6411 : sal_Int32 nMembers = rMembers.getLength();
435 :
436 6411 : typelib_TypeDescriptionReference ** ppMemberRefs = (typelib_TypeDescriptionReference **)alloca(
437 : sizeof(typelib_TypeDescriptionReference *) * nMembers );
438 :
439 6411 : const Reference< XInterfaceMemberTypeDescription > * pMembers = rMembers.getConstArray();
440 :
441 6411 : OUString aTypeName( xType->getName() );
442 :
443 : sal_Int32 nPos;
444 33991 : for ( nPos = nMembers; nPos--; )
445 : {
446 21169 : OUString aMemberTypeName( pMembers[nPos]->getName() );
447 21169 : ppMemberRefs[nPos] = 0;
448 : typelib_typedescriptionreference_new(
449 : ppMemberRefs + nPos,
450 42338 : (typelib_TypeClass)pMembers[nPos]->getTypeClass(),
451 63507 : aMemberTypeName.pData );
452 21169 : }
453 :
454 6411 : 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 6411 : nMembers, ppMemberRefs );
462 :
463 : // cleanup refs and base type
464 10519 : {for (int i = 0; i < nBases; ++i) {
465 4108 : typelib_typedescription_release(aBaseTypes[i]);
466 : }}
467 :
468 33991 : for ( nPos = nMembers; nPos--; )
469 : {
470 21169 : typelib_typedescriptionreference_release( ppMemberRefs[nPos] );
471 6411 : }
472 : }
473 6411 : return pRet;
474 : }
475 : //==================================================================================================
476 109 : inline static typelib_TypeDescription * createCTD( const Reference< XEnumTypeDescription > & xType )
477 : {
478 109 : typelib_TypeDescription * pRet = 0;
479 109 : if (xType.is())
480 : {
481 109 : OUString aTypeName( xType->getName() );
482 109 : Sequence< OUString > aNames( xType->getEnumNames() );
483 : OSL_ASSERT( sizeof(OUString) == sizeof(rtl_uString *) ); // !!!
484 109 : Sequence< sal_Int32 > aValues( xType->getEnumValues() );
485 :
486 : typelib_typedescription_newEnum(
487 109 : &pRet, aTypeName.pData, xType->getDefaultEnumValue(),
488 : aNames.getLength(),
489 109 : (rtl_uString **)aNames.getConstArray(),
490 327 : const_cast< sal_Int32 * >( aValues.getConstArray() ) );
491 : }
492 109 : return pRet;
493 : }
494 : //==================================================================================================
495 32 : inline static typelib_TypeDescription * createCTD(
496 : Reference< container::XHierarchicalNameAccess > const & access,
497 : const Reference< XIndirectTypeDescription > & xType )
498 : {
499 32 : typelib_TypeDescription * pRet = 0;
500 32 : if (xType.is())
501 : {
502 : typelib_TypeDescription * pRefType = createCTD(
503 32 : access, xType->getReferencedType() );
504 32 : typelib_typedescription_register( &pRefType );
505 :
506 32 : OUString aTypeName( xType->getName() );
507 :
508 : typelib_typedescription_new(
509 : &pRet,
510 64 : (typelib_TypeClass)xType->getTypeClass(),
511 : aTypeName.pData,
512 : pRefType->pWeakRef,
513 96 : 0, 0 );
514 :
515 : // cleanup
516 32 : typelib_typedescription_release( pRefType );
517 : }
518 32 : return pRet;
519 : }
520 :
521 : //==================================================================================================
522 9637 : static typelib_TypeDescription * createCTD(
523 : Reference< container::XHierarchicalNameAccess > const & access,
524 : const Reference< XTypeDescription > & xType )
525 : {
526 9637 : typelib_TypeDescription * pRet = 0;
527 :
528 9637 : if (xType.is())
529 : {
530 9120 : switch (xType->getTypeClass())
531 : {
532 : // built in types
533 : case TypeClass_VOID:
534 : {
535 0 : OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 16 : OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("long") );
572 16 : typelib_typedescription_new( &pRet, typelib_TypeClass_LONG, aTypeName.pData, 0, 0, 0 );
573 16 : break;
574 : }
575 : case TypeClass_UNSIGNED_LONG:
576 : {
577 0 : OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 0 : OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("double") );
602 0 : typelib_typedescription_new( &pRet, typelib_TypeClass_DOUBLE, aTypeName.pData, 0, 0, 0 );
603 0 : break;
604 : }
605 : case TypeClass_STRING:
606 : {
607 0 : OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 50 : pRet = createCTD( Reference< XCompoundTypeDescription >::query( xType ) );
629 50 : break;
630 : case TypeClass_STRUCT:
631 : pRet = createCTD(
632 605 : access, Reference< XStructTypeDescription >::query( xType ) );
633 605 : break;
634 : case TypeClass_ENUM:
635 109 : pRet = createCTD( Reference< XEnumTypeDescription >::query( xType ) );
636 109 : break;
637 : case TypeClass_TYPEDEF:
638 : {
639 47 : Reference< XIndirectTypeDescription > xTypedef( xType, UNO_QUERY );
640 47 : if (xTypedef.is())
641 47 : pRet = createCTD( access, xTypedef->getReferencedType() );
642 47 : break;
643 : }
644 : case TypeClass_SEQUENCE:
645 : pRet = createCTD(
646 32 : access, Reference< XIndirectTypeDescription >::query( xType ) );
647 32 : break;
648 : case TypeClass_INTERFACE:
649 : pRet = createCTD(
650 : access,
651 6411 : Reference< XInterfaceTypeDescription2 >::query( xType ) );
652 6411 : break;
653 : case TypeClass_INTERFACE_METHOD:
654 1463 : pRet = createCTD( Reference< XInterfaceMethodTypeDescription >::query( xType ) );
655 1463 : break;
656 : case TypeClass_INTERFACE_ATTRIBUTE:
657 387 : pRet = createCTD( Reference< XInterfaceAttributeTypeDescription2 >::query( xType ) );
658 387 : break;
659 : default:
660 0 : break;
661 : }
662 : }
663 :
664 9637 : return pRet;
665 : }
666 :
667 :
668 : //==================================================================================================
669 : extern "C"
670 : {
671 4845 : 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 4845 : if (ppRet)
676 : {
677 4845 : if (*ppRet)
678 : {
679 0 : ::typelib_typedescription_release( *ppRet );
680 0 : *ppRet = 0;
681 : }
682 4845 : if (pContext && pTypeName)
683 : {
684 : Reference< container::XHierarchicalNameAccess > access(
685 : reinterpret_cast< container::XHierarchicalNameAccess * >(
686 4845 : pContext));
687 : try
688 : {
689 4845 : OUString const & rTypeName = OUString::unacquired( &pTypeName );
690 4845 : Reference< XTypeDescription > xTD;
691 4845 : if (access->getByHierarchicalName(rTypeName ) >>= xTD)
692 : {
693 4845 : *ppRet = createCTD( access, xTD );
694 4845 : }
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 4845 : }
712 : }
713 : }
714 4845 : }
715 : }
716 :
717 : //==================================================================================================
718 78 : class EventListenerImpl
719 : : public WeakImplHelper1< lang::XEventListener >
720 : {
721 : Reference< container::XHierarchicalNameAccess > m_xTDMgr;
722 :
723 : public:
724 259 : inline EventListenerImpl(
725 : Reference< container::XHierarchicalNameAccess > const & xTDMgr )
726 : SAL_THROW(())
727 259 : : m_xTDMgr( xTDMgr )
728 259 : {}
729 :
730 : // XEventListener
731 : virtual void SAL_CALL disposing( lang::EventObject const & rEvt )
732 : throw (RuntimeException);
733 : };
734 : //__________________________________________________________________________________________________
735 39 : void EventListenerImpl::disposing( lang::EventObject const & rEvt )
736 : throw (RuntimeException)
737 : {
738 39 : if (rEvt.Source != m_xTDMgr) {
739 : OSL_ASSERT(false);
740 : }
741 : // deregister of c typelib callback
742 39 : ::typelib_typedescription_revokeCallback( m_xTDMgr.get(), typelib_callback );
743 39 : }
744 :
745 : //==================================================================================================
746 259 : sal_Bool SAL_CALL installTypeDescriptionManager(
747 : Reference< container::XHierarchicalNameAccess > const & xTDMgr_c )
748 : SAL_THROW(())
749 : {
750 259 : uno::Environment curr_env(Environment::getCurrent());
751 259 : uno::Environment target_env(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))));
752 :
753 259 : uno::Mapping curr2target(curr_env, target_env);
754 :
755 :
756 : Reference<container::XHierarchicalNameAccess> xTDMgr(
757 : reinterpret_cast<container::XHierarchicalNameAccess *>(
758 259 : curr2target.mapInterface(xTDMgr_c.get(), ::getCppuType(&xTDMgr_c))),
759 259 : SAL_NO_ACQUIRE);
760 :
761 259 : Reference< lang::XComponent > xComp( xTDMgr, UNO_QUERY );
762 259 : if (xComp.is())
763 : {
764 259 : xComp->addEventListener( new EventListenerImpl( xTDMgr ) );
765 : // register c typelib callback
766 259 : ::typelib_typedescription_registerCallback( xTDMgr.get(), typelib_callback );
767 259 : return sal_True;
768 : }
769 0 : return sal_False;
770 : }
771 :
772 : } // end namespace cppu
773 :
774 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|