Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/cppuhelper/source/tdmgr.cxx
Line
Count
Source
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
#include <sal/log.hxx>
23
24
#include <vector>
25
26
#include <osl/diagnose.h>
27
#include <rtl/ustring.hxx>
28
29
#include <uno/lbnames.h>
30
#include <uno/mapping.hxx>
31
32
#include <cppuhelper/bootstrap.hxx>
33
#include <cppuhelper/implbase.hxx>
34
#include <typelib/typedescription.h>
35
36
#include <com/sun/star/lang/XComponent.hpp>
37
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38
#include <com/sun/star/reflection/XTypeDescription.hpp>
39
#include <com/sun/star/reflection/XEnumTypeDescription.hpp>
40
#include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
41
#include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
42
#include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
43
#include <com/sun/star/reflection/XMethodParameter.hpp>
44
#include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
45
#include <com/sun/star/reflection/XInterfaceTypeDescription2.hpp>
46
#include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
47
#include <com/sun/star/reflection/XStructTypeDescription.hpp>
48
49
#include <memory>
50
51
using namespace ::com::sun::star;
52
using namespace ::com::sun::star::uno;
53
using namespace ::com::sun::star::reflection;
54
55
namespace cppu
56
{
57
58
static typelib_TypeDescription * createCTD(
59
    Reference< container::XHierarchicalNameAccess > const & access,
60
    const Reference< XTypeDescription > & xType );
61
62
63
static typelib_TypeDescription * createCTD(
64
    const Reference< XCompoundTypeDescription > & xType )
65
272
{
66
272
    typelib_TypeDescription * pRet = nullptr;
67
272
    if (xType.is())
68
200
    {
69
200
        typelib_TypeDescription * pBaseType = createCTD(
70
200
            Reference< XCompoundTypeDescription >::query( xType->getBaseType() ) );
71
200
        if (pBaseType)
72
128
            typelib_typedescription_register( &pBaseType );
73
74
        // construct member init array
75
200
        const Sequence<Reference< XTypeDescription > > aMemberTypes = xType->getMemberTypes();
76
200
        const Sequence< OUString > aMemberNames                     = xType->getMemberNames();
77
78
200
        sal_Int32 nMembers = aMemberTypes.getLength();
79
200
        OSL_ENSURE( nMembers == aMemberNames.getLength(), "### lens differ!" );
80
81
200
        OUString aTypeName( xType->getName() );
82
83
200
        typelib_CompoundMember_Init * pMemberInits = static_cast<typelib_CompoundMember_Init *>(alloca(
84
200
            sizeof(typelib_CompoundMember_Init) * nMembers ));
85
86
200
        sal_Int32 nPos;
87
603
        for ( nPos = nMembers; nPos--; )
88
403
        {
89
403
            typelib_CompoundMember_Init & rInit = pMemberInits[nPos];
90
403
            rInit.eTypeClass = static_cast<typelib_TypeClass>(aMemberTypes[nPos]->getTypeClass());
91
92
403
            OUString aMemberTypeName(aMemberTypes[nPos]->getName());
93
403
            rInit.pTypeName = aMemberTypeName.pData;
94
403
            rtl_uString_acquire( rInit.pTypeName );
95
96
            // string is held by rMemberNames
97
403
            rInit.pMemberName = aMemberNames[nPos].pData;
98
403
        }
99
100
200
        typelib_typedescription_new(
101
200
            &pRet,
102
200
            static_cast<typelib_TypeClass>(xType->getTypeClass()),
103
200
            aTypeName.pData,
104
200
            (pBaseType ? pBaseType->pWeakRef : nullptr),
105
200
            nMembers, pMemberInits );
106
107
        // cleanup
108
603
        for ( nPos = nMembers; nPos--; )
109
403
        {
110
403
            rtl_uString_release( pMemberInits[nPos].pTypeName );
111
403
        }
112
200
        if (pBaseType)
113
128
            typelib_typedescription_release( pBaseType );
114
200
    }
115
272
    return pRet;
116
272
}
117
118
static typelib_TypeDescription * createCTD(
119
    Reference< container::XHierarchicalNameAccess > const & access,
120
    const Reference< XStructTypeDescription > & xType )
121
463
{
122
463
    typelib_TypeDescription * pRet = nullptr;
123
463
    if (xType.is() && !xType->getTypeParameters().hasElements())
124
463
    {
125
463
        typelib_TypeDescription * pBaseType = createCTD(
126
463
            access, xType->getBaseType() );
127
463
        if (pBaseType)
128
72
            typelib_typedescription_register( &pBaseType );
129
130
        // construct member init array
131
463
        const Sequence<Reference< XTypeDescription > > aMemberTypes = xType->getMemberTypes();
132
463
        const Sequence< OUString > aMemberNames                     = xType->getMemberNames();
133
134
463
        sal_Int32 nMembers = aMemberTypes.getLength();
135
463
        OSL_ENSURE( nMembers == aMemberNames.getLength(), "### lens differ!" );
136
137
463
        OUString aTypeName( xType->getName() );
138
139
463
        typelib_StructMember_Init * pMemberInits = static_cast<typelib_StructMember_Init *>(alloca(
140
463
            sizeof(typelib_StructMember_Init) * nMembers ));
141
142
463
        Sequence< Reference< XTypeDescription > > templateMemberTypes;
143
463
        sal_Int32 i = aTypeName.indexOf('<');
144
463
        if (i >= 0) {
145
0
            Reference< XStructTypeDescription > templateDesc(
146
0
                access->getByHierarchicalName(aTypeName.copy(0, i)),
147
0
                UNO_QUERY_THROW);
148
0
            OSL_ASSERT(
149
0
                templateDesc->getTypeParameters().getLength()
150
0
                == xType->getTypeArguments().getLength());
151
0
            templateMemberTypes = templateDesc->getMemberTypes();
152
0
            OSL_ASSERT(templateMemberTypes.getLength() == nMembers);
153
0
        }
154
155
463
        sal_Int32 nPos;
156
2.40k
        for ( nPos = nMembers; nPos--; )
157
1.94k
        {
158
1.94k
            typelib_StructMember_Init & rInit = pMemberInits[nPos];
159
1.94k
            rInit.aBase.eTypeClass
160
1.94k
                = static_cast<typelib_TypeClass>(aMemberTypes[nPos]->getTypeClass());
161
162
1.94k
            OUString aMemberTypeName(aMemberTypes[nPos]->getName());
163
1.94k
            rInit.aBase.pTypeName = aMemberTypeName.pData;
164
1.94k
            rtl_uString_acquire( rInit.aBase.pTypeName );
165
166
            // string is held by rMemberNames
167
1.94k
            rInit.aBase.pMemberName = aMemberNames[nPos].pData;
168
169
1.94k
            rInit.bParameterizedType = templateMemberTypes.hasElements()
170
0
                && (templateMemberTypes[nPos]->getTypeClass()
171
0
                    == TypeClass_UNKNOWN);
172
1.94k
        }
173
174
463
        typelib_typedescription_newStruct(
175
463
            &pRet,
176
463
            aTypeName.pData,
177
463
            (pBaseType ? pBaseType->pWeakRef : nullptr),
178
463
            nMembers, pMemberInits );
179
180
        // cleanup
181
2.40k
        for ( nPos = nMembers; nPos--; )
182
1.94k
        {
183
1.94k
            rtl_uString_release( pMemberInits[nPos].aBase.pTypeName );
184
1.94k
        }
185
463
        if (pBaseType)
186
72
            typelib_typedescription_release( pBaseType );
187
463
    }
188
463
    return pRet;
189
463
}
190
191
static typelib_TypeDescription * createCTD(
192
    const Reference< XInterfaceAttributeTypeDescription2 > & xAttribute )
193
14
{
194
14
    typelib_TypeDescription * pRet = nullptr;
195
14
    if (xAttribute.is())
196
14
    {
197
14
        OUString aMemberName( xAttribute->getName() );
198
14
        Reference< XTypeDescription > xType( xAttribute->getType() );
199
14
        OUString aMemberTypeName( xType->getName() );
200
14
        std::vector< rtl_uString * > getExc;
201
14
        const Sequence< Reference< XCompoundTypeDescription > > getExcs(
202
14
            xAttribute->getGetExceptions() );
203
14
        for (const auto & ctd : getExcs)
204
0
        {
205
0
            OSL_ASSERT( ctd.is() );
206
0
            getExc.push_back( ctd->getName().pData );
207
0
        }
208
14
        std::vector< rtl_uString * > setExc;
209
14
        const Sequence< Reference< XCompoundTypeDescription > > setExcs(
210
14
            xAttribute->getSetExceptions() );
211
14
        for (const auto & ctd : setExcs)
212
0
        {
213
0
            OSL_ASSERT( ctd.is() );
214
0
            setExc.push_back( ctd->getName().pData );
215
0
        }
216
14
        typelib_typedescription_newExtendedInterfaceAttribute(
217
14
            reinterpret_cast<typelib_InterfaceAttributeTypeDescription **>(&pRet),
218
14
            xAttribute->getPosition(),
219
14
            aMemberName.pData, // name
220
14
            static_cast<typelib_TypeClass>(xType->getTypeClass()),
221
14
            aMemberTypeName.pData, // type name
222
14
            xAttribute->isReadOnly(),
223
14
            getExc.size(), getExc.data(),
224
14
            setExc.size(), setExc.data() );
225
14
    }
226
14
    return pRet;
227
14
}
228
229
static typelib_TypeDescription * createCTD(
230
    const Reference< XInterfaceMethodTypeDescription > & xMethod )
231
0
{
232
0
    typelib_TypeDescription * pRet = nullptr;
233
0
    if (xMethod.is())
234
0
    {
235
0
        Reference< XTypeDescription > xReturnType( xMethod->getReturnType() );
236
237
        // init all params
238
0
        const Sequence<Reference< XMethodParameter > > aParams = xMethod->getParameters();
239
0
        sal_Int32 nParams = aParams.getLength();
240
241
0
        typelib_Parameter_Init * pParamInit = static_cast<typelib_Parameter_Init *>(alloca(
242
0
            sizeof(typelib_Parameter_Init) * nParams ));
243
244
0
        sal_Int32 nPos;
245
0
        for ( nPos = nParams; nPos--; )
246
0
        {
247
0
            const Reference<XMethodParameter>& xParam = aParams[nPos];
248
0
            const Reference< XTypeDescription > xType  = xParam->getType();
249
0
            typelib_Parameter_Init & rInit = pParamInit[xParam->getPosition()];
250
251
0
            rInit.eTypeClass = static_cast<typelib_TypeClass>(xType->getTypeClass());
252
0
            OUString aParamTypeName( xType->getName() );
253
0
            rInit.pTypeName = aParamTypeName.pData;
254
0
            rtl_uString_acquire( rInit.pTypeName );
255
0
            OUString aParamName( xParam->getName() );
256
0
            rInit.pParamName = aParamName.pData;
257
0
            rtl_uString_acquire( rInit.pParamName );
258
0
            rInit.bIn  = xParam->isIn();
259
0
            rInit.bOut = xParam->isOut();
260
0
        }
261
262
        // init all exception strings
263
0
        const Sequence<Reference< XTypeDescription > > aExceptions = xMethod->getExceptions();
264
0
        sal_Int32 nExceptions = aExceptions.getLength();
265
0
        rtl_uString ** ppExceptionNames = static_cast<rtl_uString **>(alloca(
266
0
            sizeof(rtl_uString *) * nExceptions ));
267
268
0
        for ( nPos = nExceptions; nPos--; )
269
0
        {
270
0
            OUString aExceptionTypeName(aExceptions[nPos]->getName());
271
0
            ppExceptionNames[nPos] = aExceptionTypeName.pData;
272
0
            rtl_uString_acquire( ppExceptionNames[nPos] );
273
0
        }
274
275
0
        OUString aTypeName( xMethod->getName() );
276
0
        OUString aReturnTypeName( xReturnType->getName() );
277
278
0
        typelib_typedescription_newInterfaceMethod(
279
0
            reinterpret_cast<typelib_InterfaceMethodTypeDescription **>(&pRet),
280
0
            xMethod->getPosition(),
281
0
            xMethod->isOneway(),
282
0
            aTypeName.pData,
283
0
            static_cast<typelib_TypeClass>(xReturnType->getTypeClass()),
284
0
            aReturnTypeName.pData,
285
0
            nParams, pParamInit,
286
0
            nExceptions, ppExceptionNames );
287
288
0
        for ( nPos = nParams; nPos--; )
289
0
        {
290
0
            rtl_uString_release( pParamInit[nPos].pTypeName );
291
0
            rtl_uString_release( pParamInit[nPos].pParamName );
292
0
        }
293
0
        for ( nPos = nExceptions; nPos--; )
294
0
        {
295
0
            rtl_uString_release( ppExceptionNames[nPos] );
296
0
        }
297
0
    }
298
0
    return pRet;
299
0
}
300
301
static typelib_TypeDescription * createCTD(
302
    Reference< container::XHierarchicalNameAccess > const & access,
303
    const Reference< XInterfaceTypeDescription2 > & xType )
304
3.68k
{
305
3.68k
    typelib_TypeDescription * pRet = nullptr;
306
3.68k
    if (xType.is())
307
3.68k
    {
308
3.68k
        Sequence< Reference< XTypeDescription > > aBases(xType->getBaseTypes());
309
3.68k
        sal_Int32 nBases = aBases.getLength();
310
        // Exploit the fact that a typelib_TypeDescription for an interface type
311
        // is also the typelib_TypeDescriptionReference for that type:
312
3.68k
        std::unique_ptr< typelib_TypeDescription * []> aBaseTypes(
313
3.68k
            new typelib_TypeDescription *[nBases]);
314
6.14k
        for (sal_Int32 i = 0; i < nBases; ++i) {
315
2.45k
            typelib_TypeDescription * p = createCTD(access, aBases[i]);
316
2.45k
            OSL_ASSERT(
317
2.45k
                !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(p->eTypeClass));
318
2.45k
            typelib_typedescription_register(&p);
319
2.45k
            aBaseTypes[i] = p;
320
2.45k
        }
321
3.68k
        typelib_TypeDescriptionReference ** pBaseTypeRefs
322
3.68k
            = reinterpret_cast< typelib_TypeDescriptionReference ** >(
323
3.68k
                aBaseTypes.get());
324
325
        // construct all member refs
326
3.68k
        const Sequence<Reference< XInterfaceMemberTypeDescription > > aMembers = xType->getMembers();
327
3.68k
        sal_Int32 nMembers = aMembers.getLength();
328
329
3.68k
        typelib_TypeDescriptionReference ** ppMemberRefs = static_cast<typelib_TypeDescriptionReference **>(alloca(
330
3.68k
            sizeof(typelib_TypeDescriptionReference *) * nMembers ));
331
332
3.68k
        OUString aTypeName( xType->getName() );
333
334
3.68k
        sal_Int32 nPos;
335
16.2k
        for ( nPos = nMembers; nPos--; )
336
12.5k
        {
337
12.5k
            OUString aMemberTypeName(aMembers[nPos]->getName());
338
12.5k
            ppMemberRefs[nPos] = nullptr;
339
12.5k
            typelib_typedescriptionreference_new(
340
12.5k
                ppMemberRefs + nPos,
341
12.5k
                static_cast<typelib_TypeClass>(aMembers[nPos]->getTypeClass()),
342
12.5k
                aMemberTypeName.pData );
343
12.5k
        }
344
345
3.68k
        typelib_typedescription_newMIInterface(
346
3.68k
            reinterpret_cast<typelib_InterfaceTypeDescription **>(&pRet),
347
3.68k
            aTypeName.pData,
348
3.68k
            0, 0, 0, 0, 0,
349
3.68k
            nBases, pBaseTypeRefs,
350
3.68k
            nMembers, ppMemberRefs );
351
352
        // cleanup refs and base type
353
6.14k
        for (int i = 0; i < nBases; ++i) {
354
2.45k
            typelib_typedescription_release(aBaseTypes[i]);
355
2.45k
        }
356
357
16.2k
        for ( nPos = nMembers; nPos--; )
358
12.5k
        {
359
12.5k
            typelib_typedescriptionreference_release( ppMemberRefs[nPos] );
360
12.5k
        }
361
3.68k
    }
362
3.68k
    return pRet;
363
3.68k
}
364
365
static typelib_TypeDescription * createCTD( const Reference< XEnumTypeDescription > & xType )
366
75
{
367
75
    typelib_TypeDescription * pRet = nullptr;
368
75
    if (xType.is())
369
75
    {
370
75
        OUString aTypeName( xType->getName() );
371
75
        Sequence< OUString > aNames( xType->getEnumNames() );
372
75
        OSL_ASSERT( sizeof(OUString) == sizeof(rtl_uString *) ); // !!!
373
75
        Sequence< sal_Int32 > aValues( xType->getEnumValues() );
374
375
75
        typelib_typedescription_newEnum(
376
75
            &pRet, aTypeName.pData, xType->getDefaultEnumValue(),
377
75
            aNames.getLength(),
378
75
            const_cast<rtl_uString **>(reinterpret_cast<rtl_uString * const *>(aNames.getConstArray())),
379
75
            const_cast< sal_Int32 * >( aValues.getConstArray() ) );
380
75
    }
381
75
    return pRet;
382
75
}
383
384
static typelib_TypeDescription * createCTD(
385
    Reference< container::XHierarchicalNameAccess > const & access,
386
    const Reference< XIndirectTypeDescription > & xType )
387
34
{
388
34
    typelib_TypeDescription * pRet = nullptr;
389
34
    if (xType.is())
390
34
    {
391
34
        typelib_TypeDescription * pRefType = createCTD(
392
34
            access, xType->getReferencedType() );
393
34
        typelib_typedescription_register( &pRefType );
394
395
34
        OUString aTypeName( xType->getName() );
396
397
34
        typelib_typedescription_new(
398
34
            &pRet,
399
34
            static_cast<typelib_TypeClass>(xType->getTypeClass()),
400
34
            aTypeName.pData,
401
34
            pRefType->pWeakRef,
402
34
            0, nullptr );
403
404
        // cleanup
405
34
        typelib_typedescription_release( pRefType );
406
34
    }
407
34
    return pRet;
408
34
}
409
410
411
static typelib_TypeDescription * createCTD(
412
    Reference< container::XHierarchicalNameAccess > const & access,
413
    const Reference< XTypeDescription > & xType )
414
4.86k
{
415
4.86k
    typelib_TypeDescription * pRet = nullptr;
416
417
4.86k
    if (xType.is())
418
4.47k
    {
419
4.47k
        switch (xType->getTypeClass())
420
4.47k
        {
421
            // built in types
422
0
        case TypeClass_VOID:
423
0
        {
424
0
            OUString aTypeName(u"void"_ustr);
425
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_VOID, aTypeName.pData, nullptr, 0, nullptr );
426
0
            break;
427
0
        }
428
0
        case TypeClass_CHAR:
429
0
        {
430
0
            OUString aTypeName(u"char"_ustr);
431
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_CHAR, aTypeName.pData, nullptr, 0, nullptr );
432
0
            break;
433
0
        }
434
0
        case TypeClass_BOOLEAN:
435
0
        {
436
0
            OUString aTypeName(u"boolean"_ustr);
437
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_BOOLEAN, aTypeName.pData, nullptr, 0, nullptr );
438
0
            break;
439
0
        }
440
0
        case TypeClass_BYTE:
441
0
        {
442
0
            OUString aTypeName(u"byte"_ustr);
443
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_BYTE, aTypeName.pData, nullptr, 0, nullptr );
444
0
            break;
445
0
        }
446
0
        case TypeClass_SHORT:
447
0
        {
448
0
            OUString aTypeName(u"short"_ustr);
449
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_SHORT, aTypeName.pData, nullptr, 0, nullptr );
450
0
            break;
451
0
        }
452
0
        case TypeClass_UNSIGNED_SHORT:
453
0
        {
454
0
            OUString aTypeName(u"unsigned short"_ustr);
455
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_SHORT, aTypeName.pData, nullptr, 0, nullptr );
456
0
            break;
457
0
        }
458
27
        case TypeClass_LONG:
459
27
        {
460
27
            OUString aTypeName(u"long"_ustr);
461
27
            typelib_typedescription_new( &pRet, typelib_TypeClass_LONG, aTypeName.pData, nullptr, 0, nullptr );
462
27
            break;
463
0
        }
464
0
        case TypeClass_UNSIGNED_LONG:
465
0
        {
466
0
            OUString aTypeName(u"unsigned long"_ustr);
467
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_LONG, aTypeName.pData, nullptr, 0, nullptr );
468
0
            break;
469
0
        }
470
0
        case TypeClass_HYPER:
471
0
        {
472
0
            OUString aTypeName(u"hyper"_ustr);
473
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_HYPER, aTypeName.pData, nullptr, 0, nullptr );
474
0
            break;
475
0
        }
476
0
        case TypeClass_UNSIGNED_HYPER:
477
0
        {
478
0
            OUString aTypeName(u"unsigned hyper"_ustr);
479
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_UNSIGNED_HYPER, aTypeName.pData, nullptr, 0, nullptr );
480
0
            break;
481
0
        }
482
0
        case TypeClass_FLOAT:
483
0
        {
484
0
            OUString aTypeName(u"float"_ustr);
485
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_FLOAT, aTypeName.pData, nullptr, 0, nullptr );
486
0
            break;
487
0
        }
488
18
        case TypeClass_DOUBLE:
489
18
        {
490
18
            OUString aTypeName(u"double"_ustr);
491
18
            typelib_typedescription_new( &pRet, typelib_TypeClass_DOUBLE, aTypeName.pData, nullptr, 0, nullptr );
492
18
            break;
493
0
        }
494
0
        case TypeClass_STRING:
495
0
        {
496
0
            OUString aTypeName(u"string"_ustr);
497
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_STRING, aTypeName.pData, nullptr, 0, nullptr );
498
0
            break;
499
0
        }
500
0
        case TypeClass_TYPE:
501
0
        {
502
0
            OUString aTypeName(u"type"_ustr);
503
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_TYPE, aTypeName.pData, nullptr, 0, nullptr );
504
0
            break;
505
0
        }
506
0
        case TypeClass_ANY:
507
0
        {
508
0
            OUString aTypeName(u"any"_ustr);
509
0
            typelib_typedescription_new( &pRet, typelib_TypeClass_ANY, aTypeName.pData, nullptr, 0, nullptr );
510
0
            break;
511
0
        }
512
513
72
        case TypeClass_EXCEPTION:
514
72
            pRet = createCTD( Reference< XCompoundTypeDescription >::query( xType ) );
515
72
            break;
516
463
        case TypeClass_STRUCT:
517
463
            pRet = createCTD(
518
463
                access, Reference< XStructTypeDescription >::query( xType ) );
519
463
            break;
520
75
        case TypeClass_ENUM:
521
75
            pRet = createCTD( Reference< XEnumTypeDescription >::query( xType ) );
522
75
            break;
523
79
        case TypeClass_TYPEDEF:
524
79
        {
525
79
            Reference< XIndirectTypeDescription > xTypedef( xType, UNO_QUERY );
526
79
            if (xTypedef.is())
527
79
                pRet = createCTD( access, xTypedef->getReferencedType() );
528
79
            break;
529
0
        }
530
34
        case TypeClass_SEQUENCE:
531
34
            pRet = createCTD(
532
34
                access, Reference< XIndirectTypeDescription >::query( xType ) );
533
34
            break;
534
3.68k
        case TypeClass_INTERFACE:
535
3.68k
            pRet = createCTD(
536
3.68k
                access,
537
3.68k
                Reference< XInterfaceTypeDescription2 >::query( xType ) );
538
3.68k
            break;
539
0
        case TypeClass_INTERFACE_METHOD:
540
0
            pRet = createCTD( Reference< XInterfaceMethodTypeDescription >::query( xType ) );
541
0
            break;
542
14
        case TypeClass_INTERFACE_ATTRIBUTE:
543
14
            pRet = createCTD( Reference< XInterfaceAttributeTypeDescription2 >::query( xType ) );
544
14
            break;
545
0
        default:
546
0
            break;
547
4.47k
        }
548
4.47k
    }
549
550
4.86k
    return pRet;
551
4.86k
}
552
553
554
extern "C"
555
{
556
static void typelib_callback(
557
    void * pContext, typelib_TypeDescription ** ppRet, rtl_uString * pTypeName )
558
1.82k
{
559
1.82k
    OSL_ENSURE( pContext && ppRet && pTypeName, "### null ptr!" );
560
1.82k
    if (!ppRet)
561
0
        return;
562
563
1.82k
    if (*ppRet)
564
0
    {
565
0
        ::typelib_typedescription_release( *ppRet );
566
0
        *ppRet = nullptr;
567
0
    }
568
1.82k
    if (!(pContext && pTypeName))
569
0
        return;
570
571
1.82k
    Reference< container::XHierarchicalNameAccess > access(
572
1.82k
        static_cast< container::XHierarchicalNameAccess * >(
573
1.82k
            pContext));
574
1.82k
    try
575
1.82k
    {
576
1.82k
        OUString const & rTypeName = OUString::unacquired( &pTypeName );
577
1.82k
        Reference< XTypeDescription > xTD;
578
1.82k
        if (access->getByHierarchicalName(rTypeName ) >>= xTD)
579
1.82k
        {
580
1.82k
            *ppRet = createCTD( access, xTD );
581
1.82k
        }
582
1.82k
    }
583
1.82k
    catch (const container::NoSuchElementException & exc)
584
1.82k
    {
585
0
        SAL_INFO("cppuhelper", "typelibrary type not available: " << exc );
586
0
    }
587
1.82k
    catch (const Exception & exc)
588
1.82k
    {
589
0
        SAL_INFO("cppuhelper", exc );
590
0
    }
591
1.82k
}
592
}
593
594
namespace {
595
596
class EventListenerImpl
597
    : public WeakImplHelper< lang::XEventListener >
598
{
599
    Reference< container::XHierarchicalNameAccess > m_xTDMgr;
600
601
public:
602
    explicit EventListenerImpl(
603
        Reference< container::XHierarchicalNameAccess > const & xTDMgr )
604
103
        : m_xTDMgr( xTDMgr )
605
103
        {}
606
607
    // XEventListener
608
    virtual void SAL_CALL disposing( lang::EventObject const & rEvt ) override;
609
};
610
611
}
612
613
void EventListenerImpl::disposing( lang::EventObject const & rEvt )
614
0
{
615
0
    if (rEvt.Source != m_xTDMgr) {
616
0
        OSL_ASSERT(false);
617
0
    }
618
    // deregister of c typelib callback
619
0
    ::typelib_typedescription_revokeCallback( m_xTDMgr.get(), typelib_callback );
620
0
}
621
622
623
sal_Bool SAL_CALL installTypeDescriptionManager(
624
    Reference< container::XHierarchicalNameAccess > const & xTDMgr_c )
625
103
{
626
103
    uno::Environment curr_env(Environment::getCurrent());
627
103
    uno::Environment target_env(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
628
629
103
    uno::Mapping curr2target(curr_env, target_env);
630
631
632
103
    Reference<container::XHierarchicalNameAccess> xTDMgr(
633
103
        static_cast<container::XHierarchicalNameAccess *>(
634
103
            curr2target.mapInterface(xTDMgr_c.get(), cppu::UnoType<decltype(xTDMgr_c)>::get())),
635
103
        SAL_NO_ACQUIRE);
636
637
103
    Reference< lang::XComponent > xComp( xTDMgr, UNO_QUERY );
638
103
    if (xComp.is())
639
103
    {
640
103
        xComp->addEventListener( new EventListenerImpl( xTDMgr ) );
641
        // register c typelib callback
642
103
        ::typelib_typedescription_registerCallback( xTDMgr.get(), typelib_callback );
643
103
        return true;
644
103
    }
645
0
    return false;
646
103
}
647
648
} // end namespace cppu
649
650
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */