LibreOffice Module cppu (master) 1
typelib.cxx
Go to the documentation of this file.
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 <algorithm>
22#include <unordered_map>
23#include <cassert>
24#include <list>
25#include <set>
26#include <utility>
27#include <vector>
28
29#include <stdlib.h>
30#include <string.h>
31#include <sal/log.hxx>
32#include <osl/interlck.h>
33#include <osl/mutex.hxx>
34#include <rtl/ustring.hxx>
35#include <osl/diagnose.h>
36#include <typelib/typedescription.h>
37#include <uno/any2.h>
38#include <o3tl/string_view.hxx>
39#include "typelib.hxx"
40
41using namespace osl;
42
43#ifdef _WIN32
44#pragma pack(push, 8)
45#endif
46
47namespace {
48
55struct AlignSize_Impl
56{
57 sal_Int16 nInt16;
58 double dDouble;
59};
60
61}
62
63#ifdef _WIN32
64#pragma pack(pop)
65#endif
66
67// the value of the maximal alignment
68const sal_Int32 nMaxAlignment = static_cast<sal_Int32>( reinterpret_cast<sal_Size>(&reinterpret_cast<AlignSize_Impl *>(16)->dDouble) - 16);
69
70static sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
71{
72 if( nRequestedAlignment > nMaxAlignment )
73 nRequestedAlignment = nMaxAlignment;
74 return nRequestedAlignment;
75}
76
80static sal_Int32 newAlignedSize(
81 sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
82{
83 NeededAlignment = adjustAlignment( NeededAlignment );
84 return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
85}
86
87static sal_Int32 getDescriptionSize( typelib_TypeClass eTypeClass )
88{
89 OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
90
91 sal_Int32 nSize;
92 // The reference is the description
93 // if the description is empty, then it must be filled with
94 // the new description
95 switch( eTypeClass )
96 {
97 case typelib_TypeClass_SEQUENCE:
98 nSize = sal_Int32(sizeof( typelib_IndirectTypeDescription ));
99 break;
100
101 case typelib_TypeClass_STRUCT:
102 nSize = sal_Int32(sizeof( typelib_StructTypeDescription ));
103 break;
104
105 case typelib_TypeClass_EXCEPTION:
106 nSize = sal_Int32(sizeof( typelib_CompoundTypeDescription ));
107 break;
108
109 case typelib_TypeClass_ENUM:
110 nSize = sal_Int32(sizeof( typelib_EnumTypeDescription ));
111 break;
112
113 case typelib_TypeClass_INTERFACE:
114 nSize = sal_Int32(sizeof( typelib_InterfaceTypeDescription ));
115 break;
116
117 case typelib_TypeClass_INTERFACE_METHOD:
118 nSize = sal_Int32(sizeof( typelib_InterfaceMethodTypeDescription ));
119 break;
120
121 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
122 nSize = sal_Int32(sizeof( typelib_InterfaceAttributeTypeDescription ));
123 break;
124
125 default:
126 nSize = sal_Int32(sizeof( typelib_TypeDescription ));
127 }
128 return nSize;
129}
130
131namespace {
132
133struct equalStr_Impl
134{
135 bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const
136 { return 0 == rtl_ustr_compare( s1, s2 ); }
137};
138
139
140struct hashStr_Impl
141{
142 size_t operator()(const sal_Unicode * const & s) const
143 { return rtl_ustr_hashCode( s ); }
144};
145
146}
147
148// Heavy hack, the const sal_Unicode * is hold by the typedescription reference
149typedef std::unordered_map< const sal_Unicode *, typelib_TypeDescriptionReference *,
150 hashStr_Impl, equalStr_Impl > WeakMap_Impl;
151
152typedef std::pair< void *, typelib_typedescription_Callback > CallbackEntry;
153typedef std::list< CallbackEntry > CallbackSet_Impl;
154typedef std::list< typelib_TypeDescription * > TypeDescriptionList_Impl;
155
156// # of cached elements
157constexpr auto nCacheSize = 256;
158
159namespace {
160
161struct TypeDescriptor_Init_Impl
162{
163 // all type description references
164 WeakMap_Impl maWeakMap;
165 // all type description callbacks
166 CallbackSet_Impl maCallbacks;
167 // A cache to hold descriptions
169 // The mutex to guard all type library accesses
170 Mutex maMutex;
171
172 inline void callChain( typelib_TypeDescription ** ppRet, rtl_uString * pName );
173
174#if OSL_DEBUG_LEVEL > 0
175 // only for debugging
176 sal_Int32 nTypeDescriptionCount = 0;
177 sal_Int32 nCompoundTypeDescriptionCount = 0;
178 sal_Int32 nIndirectTypeDescriptionCount = 0;
179 sal_Int32 nEnumTypeDescriptionCount = 0;
180 sal_Int32 nInterfaceMethodTypeDescriptionCount = 0;
181 sal_Int32 nInterfaceAttributeTypeDescriptionCount = 0;
182 sal_Int32 nInterfaceTypeDescriptionCount = 0;
183 sal_Int32 nTypeDescriptionReferenceCount = 0;
184#endif
185
186 TypeDescriptor_Init_Impl() = default;
187
188 ~TypeDescriptor_Init_Impl();
189};
190
191}
192
193inline void TypeDescriptor_Init_Impl::callChain(
194 typelib_TypeDescription ** ppRet, rtl_uString * pName )
195{
196 assert(ppRet != nullptr);
197 assert(*ppRet == nullptr);
198 for( const CallbackEntry & rEntry : maCallbacks )
199 {
200 (*rEntry.second)( rEntry.first, ppRet, pName );
201 if( *ppRet )
202 return;
203 }
204}
205
206
207TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl()
208{
209 for( typelib_TypeDescription* pItem : maCache )
210 {
212 }
213
214 {
215 std::vector< typelib_TypeDescriptionReference * > ppTDR;
216 ppTDR.reserve( maWeakMap.size() );
217
218 // save all weak references
219 for( const auto& rEntry : maWeakMap )
220 {
221 ppTDR.push_back( rEntry.second );
223 }
224
225 for( typelib_TypeDescriptionReference * pTDR : ppTDR )
226 {
227 OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
228 pTDR->nRefCount -= pTDR->nStaticRefCount;
229
230 if( pTDR->pType && !pTDR->pType->bOnDemand )
231 {
232 pTDR->pType->bOnDemand = true;
233 typelib_typedescription_release( pTDR->pType );
234 }
236 }
237
238#if defined SAL_LOG_INFO
239 for( const auto& rEntry : maWeakMap )
240 {
241 typelib_TypeDescriptionReference * pTDR = rEntry.second;
242 if (pTDR)
243 {
244 OString aTypeName( OUStringToOString( OUString::unacquired(&pTDR->pTypeName), RTL_TEXTENCODING_ASCII_US ) );
245 SAL_INFO("cppu.typelib", "remaining type: " << aTypeName << "; ref count = " << pTDR->nRefCount);
246 }
247 else
248 {
249 SAL_INFO("cppu.typelib", "remaining null type entry!?");
250 }
251 }
252#endif
253 }
254#if OSL_DEBUG_LEVEL > 0
255 SAL_INFO_IF( nTypeDescriptionCount, "cppu.typelib", "nTypeDescriptionCount is not zero" );
256 SAL_INFO_IF( nCompoundTypeDescriptionCount, "cppu.typelib", "nCompoundTypeDescriptionCount is not zero" );
257 SAL_INFO_IF( nIndirectTypeDescriptionCount, "cppu.typelib", "nIndirectTypeDescriptionCount is not zero" );
258 SAL_INFO_IF( nEnumTypeDescriptionCount, "cppu.typelib", "nEnumTypeDescriptionCount is not zero" );
259 SAL_INFO_IF( nInterfaceMethodTypeDescriptionCount, "cppu.typelib", "nInterfaceMethodTypeDescriptionCount is not zero" );
260 SAL_INFO_IF( nInterfaceAttributeTypeDescriptionCount, "cppu.typelib", "nInterfaceAttributeTypeDescriptionCount is not zero" );
261 SAL_INFO_IF( nInterfaceTypeDescriptionCount, "cppu.typelib", "nInterfaceTypeDescriptionCount is not zero" );
262 SAL_INFO_IF( nTypeDescriptionReferenceCount, "cppu.typelib", "nTypeDescriptionReferenceCount is not zero" );
263#endif
264
265 SAL_INFO_IF( !maCallbacks.empty(), "cppu.typelib", "pCallbacks is not NULL or empty" );
266};
267
268namespace {
269TypeDescriptor_Init_Impl& Init()
270{
271 static TypeDescriptor_Init_Impl SINGLETON;
272 return SINGLETON;
273}
274}
275
277 void * pContext, typelib_typedescription_Callback pCallback )
279{
280 // todo mt safe: guard is no solution, can not acquire while calling callback!
281 TypeDescriptor_Init_Impl &rInit = Init();
282// OslGuard aGuard( rInit.getMutex() );
283 rInit.maCallbacks.push_back( CallbackEntry( pContext, pCallback ) );
284}
285
286
288 void * pContext, typelib_typedescription_Callback pCallback )
290{
291 TypeDescriptor_Init_Impl &rInit = Init();
292 {
293 // todo mt safe: guard is no solution, can not acquire while calling callback!
294// OslGuard aGuard( rInit.getMutex() );
295 CallbackEntry aEntry( pContext, pCallback );
296 rInit.maCallbacks.erase(std::remove(rInit.maCallbacks.begin(), rInit.maCallbacks.end(), aEntry),
297 rInit.maCallbacks.end());
298 }
299}
300
303{
304 typelib_InterfaceTypeDescription * pITD = reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD);
305
306 std::vector<bool> aReadWriteAttributes(pITD->nAllMembers);
307 for ( sal_Int32 i = pITD->nAllMembers; i--; )
308 {
309 aReadWriteAttributes[i] = false;
310 if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
311 {
312 typelib_TypeDescription * pM = nullptr;
313 TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
314 OSL_ASSERT( pM );
315 if (pM)
316 {
317 aReadWriteAttributes[i] = !reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>(pM)->bReadOnly;
318 TYPELIB_DANGER_RELEASE( pM );
319 }
320 else
321 {
322 SAL_INFO( "cppu.typelib", "cannot get attribute type description: " << pITD->ppAllMembers[i]->pTypeName );
323 }
324 }
325 }
326
327 MutexGuard aGuard( Init().maMutex );
328 if( pTD->bComplete )
329 return;
330
331 // create the index table from member to function table
332 pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
333 sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
334 sal_Int32 i;
335 for( i = 0; i < pITD->nAllMembers; i++ )
336 {
337 // index to the get method of the attribute
338 pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
339 // extra offset if it is a read/write attribute?
340 if (aReadWriteAttributes[i])
341 {
342 // a read/write attribute
343 nAdditionalOffset++;
344 }
345 }
346
347 // create the index table from function to member table
348 pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
349 nAdditionalOffset = 0; // +1 for read/write attributes
350 for( i = 0; i < pITD->nAllMembers; i++ )
351 {
352 // index to the get method of the attribute
353 pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
354 // extra offset if it is a read/write attribute?
355 if (aReadWriteAttributes[i])
356 {
357 // a read/write attribute
358 pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
359 }
360 }
361 // must be the last action after all initialization is done
362 pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
363 pTD->bComplete = true;
364}
365
366namespace {
367
368template<typename T> T * allocTypeDescription() {
369 return reinterpret_cast<T *>(new char[sizeof (T)]);
370}
371
372void freeTypeDescription(typelib_TypeDescription const * desc) {
373 delete[] reinterpret_cast<char const *>(desc);
374}
375
376// In some situations (notably typelib_typedescription_newInterfaceMethod and
377// typelib_typedescription_newInterfaceAttribute), only the members nMembers,
378// ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
379// description are necessary, but not the additional
380// pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
381// pMapFunctionIndexToMemberIndex (which are computed by
382// typelib_typedescription_initTables). Furthermore, in those situations, it
383// might be illegal to compute those tables, as the creation of the interface
384// member type descriptions would recursively require a complete interface type
385// description. The parameter initTables controls whether or not to call
386// typelib_typedescription_initTables in those situations.
387bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
388 if ((*ppTypeDescr)->bComplete)
389 return true;
390
391 OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass ||
392 typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass ||
393 typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass ||
394 typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) &&
395 !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppTypeDescr)->eTypeClass ) );
396
397 if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
398 reinterpret_cast<typelib_InterfaceTypeDescription *>(*ppTypeDescr)->ppAllMembers)
399 {
400 if (initTables) {
402 }
403 return true;
404 }
405
406 typelib_TypeDescription * pTD = nullptr;
407 // on demand access of complete td
408 TypeDescriptor_Init_Impl &rInit = Init();
409 rInit.callChain( &pTD, (*ppTypeDescr)->pTypeName );
410 if (pTD)
411 {
412 if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass)
413 {
415 &pTD, reinterpret_cast<typelib_IndirectTypeDescription *>(pTD)->pType );
416 OSL_ASSERT( pTD );
417 if (! pTD)
418 return false;
419 }
420
421 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
422 // typedescription found
423 // set to on demand
424 pTD->bOnDemand = true;
425
426 if (pTD->eTypeClass == typelib_TypeClass_INTERFACE
427 && !pTD->bComplete && initTables)
428 {
429 // mandatory info from callback chain
430 OSL_ASSERT( reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD)->ppAllMembers );
431 // complete except of tables init
433 pTD->bComplete = true;
434 }
435
436 // The type description is hold by the reference until
437 // on demand is activated.
438 ::typelib_typedescription_register( &pTD ); // replaces incomplete one
439 OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one
440
441 // insert into the cache
442 MutexGuard aGuard( rInit.maMutex );
443 if( rInit.maCache.size() >= nCacheSize )
444 {
445 typelib_typedescription_release( rInit.maCache.front() );
446 rInit.maCache.pop_front();
447 }
448 // descriptions in the cache must be acquired!
450 rInit.maCache.push_back( pTD );
451
452 OSL_ASSERT(
453 pTD->bComplete
454 || (pTD->eTypeClass == typelib_TypeClass_INTERFACE
455 && !initTables));
456
457 ::typelib_typedescription_release( *ppTypeDescr );
458 *ppTypeDescr = pTD;
459 }
460 else
461 {
462 SAL_INFO(
463 "cppu.typelib",
464 "type cannot be completed: " << OUString::unacquired(&(*ppTypeDescr)->pTypeName));
465 return false;
466 }
467 return true;
468}
469
470}
471
472
475 typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
477{
478 if( *ppRet )
479 {
481 *ppRet = nullptr;
482 }
483
484 OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
485
487 switch( eTypeClass )
488 {
489 case typelib_TypeClass_SEQUENCE:
490 {
491 auto pTmp = allocTypeDescription<typelib_IndirectTypeDescription>();
492 pRet = &pTmp->aBase;
493#if OSL_DEBUG_LEVEL > 0
494 osl_atomic_increment( &Init().nIndirectTypeDescriptionCount );
495#endif
496 pTmp->pType = nullptr;
497 // coverity[leaked_storage] - this is on purpose
498 }
499 break;
500
501 case typelib_TypeClass_STRUCT:
502 {
503 // FEATURE_EMPTYCLASS
504 auto pTmp = allocTypeDescription<typelib_StructTypeDescription>();
505 pRet = &pTmp->aBase.aBase;
506#if OSL_DEBUG_LEVEL > 0
507 osl_atomic_increment( &Init().nCompoundTypeDescriptionCount );
508#endif
509 pTmp->aBase.pBaseTypeDescription = nullptr;
510 pTmp->aBase.nMembers = 0;
511 pTmp->aBase.pMemberOffsets = nullptr;
512 pTmp->aBase.ppTypeRefs = nullptr;
513 pTmp->aBase.ppMemberNames = nullptr;
514 pTmp->pParameterizedTypes = nullptr;
515 // coverity[leaked_storage] - this is on purpose
516 }
517 break;
518
519 case typelib_TypeClass_EXCEPTION:
520 {
521 // FEATURE_EMPTYCLASS
522 auto pTmp = allocTypeDescription<typelib_CompoundTypeDescription>();
523 pRet = &pTmp->aBase;
524#if OSL_DEBUG_LEVEL > 0
525 osl_atomic_increment( &Init().nCompoundTypeDescriptionCount );
526#endif
527 pTmp->pBaseTypeDescription = nullptr;
528 pTmp->nMembers = 0;
529 pTmp->pMemberOffsets = nullptr;
530 pTmp->ppTypeRefs = nullptr;
531 pTmp->ppMemberNames = nullptr;
532 // coverity[leaked_storage] - this is on purpose
533 }
534 break;
535
536 case typelib_TypeClass_ENUM:
537 {
538 auto pTmp = allocTypeDescription<typelib_EnumTypeDescription>();
539 pRet = &pTmp->aBase;
540#if OSL_DEBUG_LEVEL > 0
541 osl_atomic_increment( &Init().nEnumTypeDescriptionCount );
542#endif
543 pTmp->nDefaultEnumValue = 0;
544 pTmp->nEnumValues = 0;
545 pTmp->ppEnumNames = nullptr;
546 pTmp->pEnumValues = nullptr;
547 // coverity[leaked_storage] - this is on purpose
548 }
549 break;
550
551 case typelib_TypeClass_INTERFACE:
552 {
553 auto pTmp = allocTypeDescription<
554 typelib_InterfaceTypeDescription>();
555 pRet = &pTmp->aBase;
556#if OSL_DEBUG_LEVEL > 0
557 osl_atomic_increment( &Init().nInterfaceTypeDescriptionCount );
558#endif
559 pTmp->pBaseTypeDescription = nullptr;
560 pTmp->nMembers = 0;
561 pTmp->ppMembers = nullptr;
562 pTmp->nAllMembers = 0;
563 pTmp->ppAllMembers = nullptr;
564 pTmp->nMapFunctionIndexToMemberIndex = 0;
565 pTmp->pMapFunctionIndexToMemberIndex = nullptr;
566 pTmp->pMapMemberIndexToFunctionIndex= nullptr;
567 pTmp->nBaseTypes = 0;
568 pTmp->ppBaseTypes = nullptr;
569 // coverity[leaked_storage] - this is on purpose
570 }
571 break;
572
573 case typelib_TypeClass_INTERFACE_METHOD:
574 {
575 auto pTmp = allocTypeDescription<
576 typelib_InterfaceMethodTypeDescription>();
577 pRet = &pTmp->aBase.aBase;
578#if OSL_DEBUG_LEVEL > 0
579 osl_atomic_increment( &Init().nInterfaceMethodTypeDescriptionCount );
580#endif
581 pTmp->aBase.pMemberName = nullptr;
582 pTmp->pReturnTypeRef = nullptr;
583 pTmp->nParams = 0;
584 pTmp->pParams = nullptr;
585 pTmp->nExceptions = 0;
586 pTmp->ppExceptions = nullptr;
587 pTmp->pInterface = nullptr;
588 pTmp->pBaseRef = nullptr;
589 pTmp->nIndex = 0;
590 // coverity[leaked_storage] - this is on purpose
591 }
592 break;
593
594 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
595 {
596 auto * pTmp = allocTypeDescription<
597 typelib_InterfaceAttributeTypeDescription>();
598 pRet = &pTmp->aBase.aBase;
599#if OSL_DEBUG_LEVEL > 0
600 osl_atomic_increment( &Init().nInterfaceAttributeTypeDescriptionCount );
601#endif
602 pTmp->aBase.pMemberName = nullptr;
603 pTmp->pAttributeTypeRef = nullptr;
604 pTmp->pInterface = nullptr;
605 pTmp->pBaseRef = nullptr;
606 pTmp->nIndex = 0;
607 pTmp->nGetExceptions = 0;
608 pTmp->ppGetExceptions = nullptr;
609 pTmp->nSetExceptions = 0;
610 pTmp->ppSetExceptions = nullptr;
611 // coverity[leaked_storage] - this is on purpose
612 }
613 break;
614
615 default:
616 {
617 pRet = allocTypeDescription<typelib_TypeDescription>();
618#if OSL_DEBUG_LEVEL > 0
619 osl_atomic_increment( &Init().nTypeDescriptionCount );
620#endif
621 }
622 }
623
624 pRet->nRefCount = 1; // reference count is initially 1
625 pRet->nStaticRefCount = 0;
626 pRet->eTypeClass = eTypeClass;
627 pRet->pUniqueIdentifier = nullptr;
628 pRet->pReserved = nullptr;
629 pRet->pTypeName = pTypeName;
630 rtl_uString_acquire( pRet->pTypeName );
631 pRet->pSelf = pRet;
632 pRet->bComplete = true;
633 pRet->nSize = 0;
634 pRet->nAlignment = 0;
635 pRet->pWeakRef = nullptr;
636 pRet->bOnDemand = false;
637 *ppRet = pRet;
638}
639
640
641namespace {
642
643void newTypeDescription(
644 typelib_TypeDescription ** ppRet, typelib_TypeClass eTypeClass,
645 rtl_uString * pTypeName, typelib_TypeDescriptionReference * pType,
646 sal_Int32 nMembers, typelib_CompoundMember_Init * pCompoundMembers,
647 typelib_StructMember_Init * pStructMembers)
648{
649 OSL_ASSERT(
650 (pCompoundMembers == nullptr || pStructMembers == nullptr)
651 && (pStructMembers == nullptr || eTypeClass == typelib_TypeClass_STRUCT));
652 if (typelib_TypeClass_TYPEDEF == eTypeClass)
653 {
654 SAL_WARN("cppu.typelib", "unexpected typedef!" );
656 return;
657 }
658
659 typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
660
661 switch( eTypeClass )
662 {
663 case typelib_TypeClass_SEQUENCE:
664 {
665 OSL_ASSERT( nMembers == 0 );
667 reinterpret_cast<typelib_IndirectTypeDescription *>(*ppRet)->pType = pType;
668 }
669 break;
670
671 case typelib_TypeClass_EXCEPTION:
672 case typelib_TypeClass_STRUCT:
673 {
674 // FEATURE_EMPTYCLASS
675 typelib_CompoundTypeDescription * pTmp = reinterpret_cast<typelib_CompoundTypeDescription*>(*ppRet);
676
677 sal_Int32 nOffset = 0;
678 if( pType )
679 {
681 reinterpret_cast<typelib_TypeDescription **>(&pTmp->pBaseTypeDescription), pType );
682 nOffset = pTmp->pBaseTypeDescription->aBase.nSize;
683 OSL_ENSURE( newAlignedSize( 0, pTmp->pBaseTypeDescription->aBase.nSize, pTmp->pBaseTypeDescription->aBase.nAlignment ) == pTmp->pBaseTypeDescription->aBase.nSize, "### unexpected offset!" );
684 }
685 if( nMembers )
686 {
687 pTmp->nMembers = nMembers;
688 pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
689 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
690 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
691 bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
692 && OUString::unacquired(&pTypeName).indexOf('<') >= 0;
693 OSL_ASSERT(!polymorphic || pStructMembers != nullptr);
694 if (polymorphic) {
695 reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
696 pParameterizedTypes = new sal_Bool[nMembers];
697 }
698 for( sal_Int32 i = 0 ; i < nMembers; i++ )
699 {
700 // read the type and member names
701 pTmp->ppTypeRefs[i] = nullptr;
702 if (pCompoundMembers != nullptr) {
704 pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
705 pCompoundMembers[i].pTypeName );
706 pTmp->ppMemberNames[i]
707 = pCompoundMembers[i].pMemberName;
708 rtl_uString_acquire( pTmp->ppMemberNames[i] );
709 } else {
711 pTmp->ppTypeRefs +i,
712 pStructMembers[i].aBase.eTypeClass,
713 pStructMembers[i].aBase.pTypeName );
714 pTmp->ppMemberNames[i]
715 = pStructMembers[i].aBase.pMemberName;
716 rtl_uString_acquire(pTmp->ppMemberNames[i]);
717 }
718 // write offset
719 sal_Int32 size;
720 sal_Int32 alignment;
721 if (pTmp->ppTypeRefs[i]->eTypeClass ==
722 typelib_TypeClass_SEQUENCE)
723 {
724 // Take care of recursion like
725 // struct S { sequence<S> x; };
726 size = sizeof(void *);
727 alignment = adjustAlignment(size);
728 } else {
729 typelib_TypeDescription * pTD = nullptr;
730 TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
731 OSL_ENSURE( pTD->nSize, "### void member?" );
732 size = pTD->nSize;
733 alignment = pTD->nAlignment;
734 TYPELIB_DANGER_RELEASE( pTD );
735 }
736 nOffset = newAlignedSize( nOffset, size, alignment );
737 pTmp->pMemberOffsets[i] = nOffset - size;
738
739 if (polymorphic) {
740 reinterpret_cast< typelib_StructTypeDescription * >(
741 pTmp)->pParameterizedTypes[i]
742 = pStructMembers[i].bParameterizedType;
743 }
744 }
745 }
746 }
747 break;
748
749 default:
750 break;
751 }
752
753 if( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass ) )
754 (*ppRet)->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(*ppRet);
755 if( eTypeClass != typelib_TypeClass_VOID )
756 {
757 // sizeof(void) not allowed
758 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
759 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
760 }
761}
762
763}
764
765extern "C" void SAL_CALL typelib_typedescription_new(
767 typelib_TypeClass eTypeClass,
768 rtl_uString * pTypeName,
769 typelib_TypeDescriptionReference * pType,
770 sal_Int32 nMembers,
771 typelib_CompoundMember_Init * pMembers )
773{
774 newTypeDescription(
775 ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, nullptr);
776}
777
778extern "C" void SAL_CALL typelib_typedescription_newStruct(
780 rtl_uString * pTypeName,
781 typelib_TypeDescriptionReference * pType,
782 sal_Int32 nMembers,
783 typelib_StructMember_Init * pMembers )
785{
786 newTypeDescription(
787 ppRet, typelib_TypeClass_STRUCT, pTypeName, pType, nMembers, nullptr,
788 pMembers);
789}
790
791
792extern "C" void SAL_CALL typelib_typedescription_newEnum(
794 rtl_uString * pTypeName,
795 sal_Int32 nDefaultValue,
796 sal_Int32 nEnumValues,
797 rtl_uString ** ppEnumNames,
798 sal_Int32 * pEnumValues )
800{
801 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
802 typelib_EnumTypeDescription * pEnum = reinterpret_cast<typelib_EnumTypeDescription *>(*ppRet);
803
804 pEnum->nDefaultEnumValue = nDefaultValue;
805 pEnum->nEnumValues = nEnumValues;
806 pEnum->ppEnumNames = new rtl_uString * [ nEnumValues ];
807 for ( sal_Int32 nPos = nEnumValues; nPos--; )
808 {
809 pEnum->ppEnumNames[nPos] = ppEnumNames[nPos];
810 rtl_uString_acquire( pEnum->ppEnumNames[nPos] );
811 }
812 pEnum->pEnumValues = new sal_Int32[ nEnumValues ];
813 ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
814
815 static_assert(!TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM));
816 (*ppRet)->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(*ppRet);
817 // sizeof(void) not allowed
818 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
819 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
820}
821
822
824 typelib_InterfaceTypeDescription ** ppRet,
825 rtl_uString * pTypeName,
826 SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt16,
827 SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt32,
828 SAL_UNUSED_PARAMETER sal_uInt32,
829 typelib_TypeDescriptionReference * pBaseInterface,
830 sal_Int32 nMembers,
831 typelib_TypeDescriptionReference ** ppMembers )
833{
834 // coverity[callee_ptr_arith] - not a bug
836 ppRet, pTypeName, 0, 0, 0, 0, 0, pBaseInterface == nullptr ? 0 : 1,
837 &pBaseInterface, nMembers, ppMembers);
838}
839
840namespace {
841
842class BaseList {
843public:
844 struct Entry {
845 sal_Int32 memberOffset;
846 sal_Int32 directBaseIndex;
847 sal_Int32 directBaseMemberOffset;
848 typelib_InterfaceTypeDescription const * base;
849 };
850
851 typedef std::vector< Entry > List;
852
853 explicit BaseList(typelib_InterfaceTypeDescription const * desc);
854
855 List const & getList() const { return list; }
856
857 sal_Int32 getBaseMembers() const { return members; }
858
859private:
860 typedef std::set< OUString > Set;
861
862 void calculate(
863 Set& allSet,
864 sal_Int32 directBaseIndex, Set & directBaseSet,
865 sal_Int32 * directBaseMembers,
866 typelib_InterfaceTypeDescription const * desc);
867
868 List list;
869 sal_Int32 members;
870};
871
872BaseList::BaseList(typelib_InterfaceTypeDescription const * desc)
873 : members(0)
874{
875 Set allSet;
876 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
877 Set directBaseSet;
878 sal_Int32 directBaseMembers = 0;
879 calculate(allSet, i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
880 }
881}
882
883void BaseList::calculate(
884 Set& allSet,
885 sal_Int32 directBaseIndex, Set & directBaseSet,
886 sal_Int32 * directBaseMembers,
887 typelib_InterfaceTypeDescription const * desc)
888{
889 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
890 calculate(allSet,
891 directBaseIndex, directBaseSet, directBaseMembers,
892 desc->ppBaseTypes[i]);
893 }
894 if (allSet.insert(desc->aBase.pTypeName).second) {
895 Entry e;
896 e.memberOffset = members;
897 e.directBaseIndex = directBaseIndex;
898 e.directBaseMemberOffset = *directBaseMembers;
899 e.base = desc;
900 list.push_back(e);
901 OSL_ASSERT(desc->ppAllMembers != nullptr);
902 members += desc->nMembers;
903 }
904 if (directBaseSet.insert(desc->aBase.pTypeName).second) {
905 OSL_ASSERT(desc->ppAllMembers != nullptr);
906 *directBaseMembers += desc->nMembers;
907 }
908}
909
910}
911
913 typelib_InterfaceTypeDescription ** ppRet,
914 rtl_uString * pTypeName,
915 SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt16,
916 SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt32,
917 SAL_UNUSED_PARAMETER sal_uInt32,
918 sal_Int32 nBaseInterfaces,
919 typelib_TypeDescriptionReference ** ppBaseInterfaces,
920 sal_Int32 nMembers,
921 typelib_TypeDescriptionReference ** ppMembers )
923{
924 if (*ppRet != nullptr) {
925 typelib_typedescription_release(&(*ppRet)->aBase);
926 *ppRet = nullptr;
927 }
928
929 typelib_InterfaceTypeDescription * pITD = nullptr;
931 reinterpret_cast<typelib_TypeDescription **>(&pITD), typelib_TypeClass_INTERFACE, pTypeName );
932
933 pITD->nBaseTypes = nBaseInterfaces;
934 pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
935 for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
936 pITD->ppBaseTypes[i] = nullptr;
938 reinterpret_cast< typelib_TypeDescription ** >(
939 &pITD->ppBaseTypes[i]),
940 ppBaseInterfaces[i]);
941 if (pITD->ppBaseTypes[i] == nullptr
942 || !complete(
943 reinterpret_cast< typelib_TypeDescription ** >(
944 &pITD->ppBaseTypes[i]),
945 false))
946 {
947 OSL_ASSERT(false);
948 return;
949 }
950 OSL_ASSERT(pITD->ppBaseTypes[i] != nullptr);
951 }
952 if (nBaseInterfaces > 0) {
953 pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
954 }
955 // set the
956 pITD->aUik.m_Data1 = 0;
957 pITD->aUik.m_Data2 = 0;
958 pITD->aUik.m_Data3 = 0;
959 pITD->aUik.m_Data4 = 0;
960 pITD->aUik.m_Data5 = 0;
961
962 BaseList aBaseList(pITD);
963 pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
964 pITD->nMembers = nMembers;
965
966 if( pITD->nAllMembers )
967 {
968 // at minimum one member exist, allocate the memory
969 pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
970 sal_Int32 n = 0;
971
972 BaseList::List const & rList = aBaseList.getList();
973 for (const auto& rEntry : rList)
974 {
975 typelib_InterfaceTypeDescription const * pBase = rEntry.base;
976 typelib_InterfaceTypeDescription const * pDirectBase
977 = pITD->ppBaseTypes[rEntry.directBaseIndex];
978 OSL_ASSERT(pBase->ppAllMembers != nullptr);
979 for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
980 typelib_TypeDescriptionReference const * pDirectBaseMember
981 = pDirectBase->ppAllMembers[rEntry.directBaseMemberOffset + j];
982 OUString aName = OUString::unacquired(&pDirectBaseMember->pTypeName) +
983 ":@" +
984 OUString::number(rEntry.directBaseIndex) +
985 "," +
986 OUString::number(rEntry.memberOffset + j) +
987 ":" +
988 OUString::unacquired(&pITD->aBase.pTypeName);
989 typelib_TypeDescriptionReference * pDerivedMember = nullptr;
991 &pDerivedMember, pDirectBaseMember->eTypeClass,
992 aName.pData);
993 pITD->ppAllMembers[n++] = pDerivedMember;
994 }
995 }
996
997 if( nMembers )
998 {
999 pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
1000 }
1001
1002 // add own members
1003 for( sal_Int32 i = 0; i < nMembers; i++ )
1004 {
1006 pITD->ppAllMembers[n++] = ppMembers[i];
1007 }
1008 }
1009
1010 typelib_TypeDescription * pTmp = &pITD->aBase;
1011 static_assert( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE ) );
1012 pTmp->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pTmp);
1013 pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
1014 pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
1015 pTmp->bComplete = false;
1016
1017 *ppRet = pITD;
1018}
1019
1020
1021namespace {
1022
1023typelib_TypeDescriptionReference ** copyExceptions(
1024 sal_Int32 count, rtl_uString ** typeNames)
1025{
1026 OSL_ASSERT(count >= 0);
1027 if (count == 0) {
1028 return nullptr;
1029 }
1030 typelib_TypeDescriptionReference ** p
1031 = new typelib_TypeDescriptionReference *[count];
1032 for (sal_Int32 i = 0; i < count; ++i) {
1033 p[i] = nullptr;
1035 p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
1036 }
1037 return p;
1038}
1039
1040}
1041
1043 typelib_InterfaceMethodTypeDescription ** ppRet,
1044 sal_Int32 nAbsolutePosition,
1045 sal_Bool bOneWay,
1046 rtl_uString * pTypeName,
1047 typelib_TypeClass eReturnTypeClass,
1048 rtl_uString * pReturnTypeName,
1049 sal_Int32 nParams,
1050 typelib_Parameter_Init * pParams,
1051 sal_Int32 nExceptions,
1052 rtl_uString ** ppExceptionNames )
1054{
1055 if (*ppRet != nullptr) {
1056 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1057 *ppRet = nullptr;
1058 }
1059 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1060 pTypeName->buffer, pTypeName->length, ':');
1061 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1062 OSL_FAIL("Bad interface method type name");
1063 return;
1064 }
1065 OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1066 typelib_InterfaceTypeDescription * pInterface = nullptr;
1068 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1069 aInterfaceTypeName.pData);
1070 if (pInterface == nullptr
1071 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1072 || !complete(
1073 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1074 {
1075 OSL_FAIL("No interface corresponding to interface method");
1076 return;
1077 }
1078
1080 reinterpret_cast<typelib_TypeDescription **>(ppRet), typelib_TypeClass_INTERFACE_METHOD, pTypeName );
1081
1082 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1083 pTypeName->buffer + nOffset +1,
1084 pTypeName->length - nOffset -1 );
1085 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1086 (*ppRet)->bOneWay = bOneWay;
1087 typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
1088 (*ppRet)->nParams = nParams;
1089 if( nParams )
1090 {
1091 (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
1092
1093 for( sal_Int32 i = 0; i < nParams; i++ )
1094 {
1095 // get the name of the parameter
1096 (*ppRet)->pParams[ i ].pName = pParams[i].pParamName;
1097 rtl_uString_acquire( (*ppRet)->pParams[ i ].pName );
1098 (*ppRet)->pParams[ i ].pTypeRef = nullptr;
1099 // get the type name of the parameter and create the weak reference
1101 &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
1102 (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
1103 (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
1104 }
1105 }
1106 (*ppRet)->nExceptions = nExceptions;
1107 (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
1108 (*ppRet)->pInterface = pInterface;
1109 (*ppRet)->pBaseRef = nullptr;
1110 OSL_ASSERT(
1111 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1112 && nAbsolutePosition < pInterface->nAllMembers);
1113 (*ppRet)->nIndex = nAbsolutePosition
1114 - (pInterface->nAllMembers - pInterface->nMembers);
1115 static_assert( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE_METHOD ) );
1116 assert(reinterpret_cast<typelib_TypeDescription *>(*ppRet)->pWeakRef == nullptr);
1117}
1118
1119
1121 typelib_InterfaceAttributeTypeDescription ** ppRet,
1122 sal_Int32 nAbsolutePosition,
1123 rtl_uString * pTypeName,
1124 typelib_TypeClass eAttributeTypeClass,
1125 rtl_uString * pAttributeTypeName,
1126 sal_Bool bReadOnly )
1128{
1130 ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
1131 pAttributeTypeName, bReadOnly, 0, nullptr, 0, nullptr);
1132}
1133
1134
1136 typelib_InterfaceAttributeTypeDescription ** ppRet,
1137 sal_Int32 nAbsolutePosition,
1138 rtl_uString * pTypeName,
1139 typelib_TypeClass eAttributeTypeClass,
1140 rtl_uString * pAttributeTypeName,
1141 sal_Bool bReadOnly,
1142 sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames,
1143 sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames )
1145{
1146 if (*ppRet != nullptr) {
1147 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1148 *ppRet = nullptr;
1149 }
1150 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1151 pTypeName->buffer, pTypeName->length, ':');
1152 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1153 OSL_FAIL("Bad interface attribute type name");
1154 return;
1155 }
1156 OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1157 typelib_InterfaceTypeDescription * pInterface = nullptr;
1159 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1160 aInterfaceTypeName.pData);
1161 if (pInterface == nullptr
1162 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1163 || !complete(
1164 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1165 {
1166 OSL_FAIL("No interface corresponding to interface attribute");
1167 return;
1168 }
1169
1171 reinterpret_cast<typelib_TypeDescription **>(ppRet), typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
1172
1173 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1174 pTypeName->buffer + nOffset +1,
1175 pTypeName->length - nOffset -1 );
1176 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1177 typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
1178 (*ppRet)->bReadOnly = bReadOnly;
1179 (*ppRet)->pInterface = pInterface;
1180 (*ppRet)->pBaseRef = nullptr;
1181 OSL_ASSERT(
1182 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1183 && nAbsolutePosition < pInterface->nAllMembers);
1184 (*ppRet)->nIndex = nAbsolutePosition
1185 - (pInterface->nAllMembers - pInterface->nMembers);
1186 (*ppRet)->nGetExceptions = nGetExceptions;
1187 (*ppRet)->ppGetExceptions = copyExceptions(
1188 nGetExceptions, ppGetExceptionNames);
1189 (*ppRet)->nSetExceptions = nSetExceptions;
1190 (*ppRet)->ppSetExceptions = copyExceptions(
1191 nSetExceptions, ppSetExceptionNames);
1192 static_assert( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE_ATTRIBUTE ) );
1193 assert(reinterpret_cast<typelib_TypeDescription *>(*ppRet)->pWeakRef == nullptr);
1194}
1195
1196
1197extern "C" void SAL_CALL typelib_typedescription_acquire(
1198 typelib_TypeDescription * pTypeDescription )
1200{
1201 osl_atomic_increment( &pTypeDescription->nRefCount );
1202}
1203
1204
1205namespace {
1206
1207void deleteExceptions(
1208 sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
1209{
1210 for (sal_Int32 i = 0; i < count; ++i) {
1212 }
1213 delete[] exceptions;
1214}
1215
1216}
1217
1218// frees anything except typelib_TypeDescription base!
1221{
1222 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
1223
1224 switch( pTD->eTypeClass )
1225 {
1226 case typelib_TypeClass_SEQUENCE:
1227 if( reinterpret_cast<typelib_IndirectTypeDescription*>(pTD)->pType )
1228 typelib_typedescriptionreference_release( reinterpret_cast<typelib_IndirectTypeDescription*>(pTD)->pType );
1229 break;
1230 case typelib_TypeClass_STRUCT:
1231 delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
1232 pParameterizedTypes;
1233 [[fallthrough]];
1234 case typelib_TypeClass_EXCEPTION:
1235 {
1236 typelib_CompoundTypeDescription * pCTD = reinterpret_cast<typelib_CompoundTypeDescription*>(pTD);
1237 if( pCTD->pBaseTypeDescription )
1238 typelib_typedescription_release( &pCTD->pBaseTypeDescription->aBase );
1239 sal_Int32 i;
1240 for( i = 0; i < pCTD->nMembers; i++ )
1241 {
1242 typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
1243 }
1244 if (pCTD->ppMemberNames)
1245 {
1246 for ( i = 0; i < pCTD->nMembers; i++ )
1247 {
1248 rtl_uString_release( pCTD->ppMemberNames[i] );
1249 }
1250 delete [] pCTD->ppMemberNames;
1251 }
1252 delete [] pCTD->ppTypeRefs;
1253 delete [] pCTD->pMemberOffsets;
1254 }
1255 break;
1256 case typelib_TypeClass_INTERFACE:
1257 {
1258 typelib_InterfaceTypeDescription * pITD = reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD);
1259 for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
1260 {
1261 typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
1262 }
1263 delete [] pITD->ppAllMembers;
1264 delete [] pITD->pMapMemberIndexToFunctionIndex;
1265 delete [] pITD->pMapFunctionIndexToMemberIndex;
1266 for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
1268 reinterpret_cast< typelib_TypeDescription * >(
1269 pITD->ppBaseTypes[i]));
1270 }
1271 delete[] pITD->ppBaseTypes;
1272 break;
1273 }
1274 case typelib_TypeClass_INTERFACE_METHOD:
1275 {
1276 typelib_InterfaceMethodTypeDescription * pIMTD = reinterpret_cast<typelib_InterfaceMethodTypeDescription*>(pTD);
1277 if( pIMTD->pReturnTypeRef )
1278 typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
1279 for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
1280 {
1281 rtl_uString_release( pIMTD->pParams[ i ].pName );
1282 typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
1283 }
1284 delete [] pIMTD->pParams;
1285 deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
1286 rtl_uString_release( pIMTD->aBase.pMemberName );
1287 typelib_typedescription_release(&pIMTD->pInterface->aBase);
1288 if (pIMTD->pBaseRef != nullptr) {
1290 }
1291 }
1292 break;
1293 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1294 {
1295 typelib_InterfaceAttributeTypeDescription * pIATD = reinterpret_cast<typelib_InterfaceAttributeTypeDescription*>(pTD);
1296 deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
1297 deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
1298 if( pIATD->pAttributeTypeRef )
1299 typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
1300 if( pIATD->aBase.pMemberName )
1301 rtl_uString_release( pIATD->aBase.pMemberName );
1302 typelib_typedescription_release(&pIATD->pInterface->aBase);
1303 if (pIATD->pBaseRef != nullptr) {
1305 }
1306 }
1307 break;
1308 case typelib_TypeClass_ENUM:
1309 {
1310 typelib_EnumTypeDescription * pEnum = reinterpret_cast<typelib_EnumTypeDescription *>(pTD);
1311 for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
1312 {
1313 rtl_uString_release( pEnum->ppEnumNames[nPos] );
1314 }
1315 delete [] pEnum->ppEnumNames;
1316 delete [] pEnum->pEnumValues;
1317 }
1318 break;
1319 default:
1320 break;
1321 }
1322}
1323
1324
1325extern "C" void SAL_CALL typelib_typedescription_release(
1328{
1329 sal_Int32 ref = osl_atomic_decrement( &pTD->nRefCount );
1330 OSL_ASSERT(ref >= 0);
1331 if (0 != ref)
1332 return;
1333
1334 TypeDescriptor_Init_Impl &rInit = Init();
1335 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pTD->eTypeClass ) )
1336 {
1337 if( pTD->pWeakRef )
1338 {
1339 {
1340 MutexGuard aGuard( rInit.maMutex );
1341 // remove this description from the weak reference
1342 pTD->pWeakRef->pType = nullptr;
1343 }
1345 }
1346 }
1347 else
1348 {
1349 // this description is a reference too, so remove it from the hash table
1350 MutexGuard aGuard( rInit.maMutex );
1351 WeakMap_Impl::iterator aIt = rInit.maWeakMap.find( pTD->pTypeName->buffer );
1352 if( aIt != rInit.maWeakMap.end() && static_cast<void *>((*aIt).second) == static_cast<void *>(pTD) )
1353 {
1354 // remove only if it contains the same object
1355 rInit.maWeakMap.erase( aIt );
1356 }
1357 }
1358
1360 rtl_uString_release( pTD->pTypeName );
1361
1362#if OSL_DEBUG_LEVEL > 0
1363 switch( pTD->eTypeClass )
1364 {
1365 case typelib_TypeClass_SEQUENCE:
1366 osl_atomic_decrement( &rInit.nIndirectTypeDescriptionCount );
1367 break;
1368 case typelib_TypeClass_STRUCT:
1369 case typelib_TypeClass_EXCEPTION:
1370 osl_atomic_decrement( &rInit.nCompoundTypeDescriptionCount );
1371 break;
1372 case typelib_TypeClass_INTERFACE:
1373 osl_atomic_decrement( &rInit.nInterfaceTypeDescriptionCount );
1374 break;
1375 case typelib_TypeClass_INTERFACE_METHOD:
1376 osl_atomic_decrement( &rInit.nInterfaceMethodTypeDescriptionCount );
1377 break;
1378 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1379 osl_atomic_decrement( &rInit.nInterfaceAttributeTypeDescriptionCount );
1380 break;
1381 case typelib_TypeClass_ENUM:
1382 osl_atomic_decrement( &rInit.nEnumTypeDescriptionCount );
1383 break;
1384 default:
1385 osl_atomic_decrement( &rInit.nTypeDescriptionCount );
1386 }
1387#endif
1388
1389 freeTypeDescription(pTD);
1390}
1391
1392
1393extern "C" void SAL_CALL typelib_typedescription_register(
1394 typelib_TypeDescription ** ppNewDescription )
1396{
1397 // connect the description with the weak reference
1398 TypeDescriptor_Init_Impl &rInit = Init();
1399 ClearableMutexGuard aGuard( rInit.maMutex );
1400
1401 typelib_TypeDescriptionReference * pTDR = nullptr;
1402 typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
1403
1404 OSL_ASSERT( (*ppNewDescription)->pWeakRef || TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppNewDescription)->eTypeClass ) );
1405 if( pTDR )
1406 {
1407 OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
1408 if( pTDR->pType )
1409 {
1410 if (TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pTDR->eTypeClass ))
1411 {
1412 // pRef->pType->pWeakRef == 0 means that the description is empty
1413 if (pTDR->pType->pWeakRef)
1414 {
1415 if (osl_atomic_increment( &pTDR->pType->nRefCount ) > 1)
1416 {
1417 // The reference is incremented. The object cannot be destroyed.
1418 // Release the guard at the earliest point.
1419 aGuard.clear();
1420 ::typelib_typedescription_release( *ppNewDescription );
1421 *ppNewDescription = pTDR->pType;
1423 return;
1424 }
1425 // destruction of this type in progress (another thread!)
1426 (void)osl_atomic_decrement( &pTDR->pType->nRefCount );
1427 }
1428 // take new descr
1429 pTDR->pType = *ppNewDescription;
1430 OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
1431 (*ppNewDescription)->pWeakRef = pTDR;
1432 return;
1433 }
1434 // !reallyWeak
1435
1436 if ((static_cast<void *>(pTDR) != static_cast<void *>(*ppNewDescription)) && // if different
1437 (!pTDR->pType->pWeakRef || // uninit: ref data only set
1438 // new one is complete:
1439 (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
1440 // new one may be partly initialized interface (except of tables):
1441 (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
1442 !reinterpret_cast<typelib_InterfaceTypeDescription *>(pTDR->pType)->ppAllMembers &&
1443 (*reinterpret_cast<typelib_InterfaceTypeDescription **>(ppNewDescription))->ppAllMembers)))
1444 {
1445 // uninitialized or incomplete
1446
1447 if (pTDR->pType->pWeakRef) // if init
1448 {
1449 switch (pTDR->pType->eTypeClass) {
1450 case typelib_TypeClass_ENUM:
1451 {
1452 auto const src = reinterpret_cast<typelib_EnumTypeDescription *>(
1453 *ppNewDescription);
1454 auto const dst = reinterpret_cast<typelib_EnumTypeDescription *>(
1455 pTDR->pType);
1456 assert(dst->nEnumValues == 0);
1457 assert(dst->ppEnumNames == nullptr);
1458 assert(dst->pEnumValues == nullptr);
1459 std::swap(src->nEnumValues, dst->nEnumValues);
1460 std::swap(src->ppEnumNames, dst->ppEnumNames);
1461 std::swap(src->pEnumValues, dst->pEnumValues);
1462 break;
1463 }
1464 case typelib_TypeClass_STRUCT:
1465 case typelib_TypeClass_EXCEPTION:
1466 {
1467 auto const src = reinterpret_cast<typelib_CompoundTypeDescription *>(
1468 *ppNewDescription);
1469 auto const dst = reinterpret_cast<typelib_CompoundTypeDescription *>(
1470 pTDR->pType);
1471 assert(
1472 (dst->pBaseTypeDescription == nullptr)
1473 == (src->pBaseTypeDescription == nullptr));
1474 assert(dst->nMembers == src->nMembers);
1475 assert((dst->pMemberOffsets == nullptr) == (dst->nMembers == 0));
1476 assert((dst->ppTypeRefs == nullptr) == (dst->nMembers == 0));
1477 assert(dst->ppMemberNames == nullptr);
1478 assert(
1479 pTDR->pType->eTypeClass != typelib_TypeClass_STRUCT
1480 || ((reinterpret_cast<typelib_StructTypeDescription *>(
1481 dst)->pParameterizedTypes
1482 == nullptr)
1483 == (reinterpret_cast<typelib_StructTypeDescription *>(
1484 src)->pParameterizedTypes
1485 == nullptr)));
1486 std::swap(src->ppMemberNames, dst->ppMemberNames);
1487 break;
1488 }
1489 case typelib_TypeClass_INTERFACE:
1490 {
1491 auto const src = reinterpret_cast<typelib_InterfaceTypeDescription *>(
1492 *ppNewDescription);
1493 auto const dst = reinterpret_cast<typelib_InterfaceTypeDescription *>(
1494 pTDR->pType);
1495 assert(
1496 (dst->pBaseTypeDescription == nullptr)
1497 == (src->pBaseTypeDescription == nullptr));
1498 assert(dst->nMembers == 0);
1499 assert(dst->ppMembers == nullptr);
1500 assert(dst->nAllMembers == 0);
1501 assert(dst->ppAllMembers == nullptr);
1502 assert(dst->pMapMemberIndexToFunctionIndex == nullptr);
1503 assert(dst->nMapFunctionIndexToMemberIndex == 0);
1504 assert(dst->pMapFunctionIndexToMemberIndex == nullptr);
1505 assert(dst->nBaseTypes == src->nBaseTypes);
1506 assert((dst->ppBaseTypes == nullptr) == (src->ppBaseTypes == nullptr));
1507 std::swap(src->nMembers, dst->nMembers);
1508 std::swap(src->ppMembers, dst->ppMembers);
1509 std::swap(src->nAllMembers, dst->nAllMembers);
1510 std::swap(src->ppAllMembers, dst->ppAllMembers);
1511 std::swap(
1512 src->pMapMemberIndexToFunctionIndex,
1513 dst->pMapMemberIndexToFunctionIndex);
1514 std::swap(
1515 src->nMapFunctionIndexToMemberIndex,
1516 dst->nMapFunctionIndexToMemberIndex);
1517 std::swap(
1518 src->pMapFunctionIndexToMemberIndex,
1519 dst->pMapFunctionIndexToMemberIndex);
1520 break;
1521 }
1522 default:
1523 assert(false); // this cannot happen
1524 }
1525 }
1526 else
1527 {
1528 // pTDR->pType->pWeakRef == 0 means that the description is empty
1529 // description is not weak and the not the same
1530 sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
1531
1532 // copy all specific data for the descriptions
1533 memcpy(
1534 pTDR->pType +1,
1535 *ppNewDescription +1,
1536 nSize - sizeof(typelib_TypeDescription) );
1537
1538 memset(
1539 *ppNewDescription +1,
1540 0,
1541 nSize - sizeof( typelib_TypeDescription ) );
1542 }
1543
1544 pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
1545 pTDR->pType->nSize = (*ppNewDescription)->nSize;
1546 pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
1547
1548 if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
1549 {
1550 // switch from OnDemand to !OnDemand, so the description must be acquired
1551 typelib_typedescription_acquire( pTDR->pType );
1552 }
1553 else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
1554 {
1555 // switch from !OnDemand to OnDemand, so the description must be released
1556 assert(pTDR->pType->nRefCount > 1);
1557 // coverity[freed_arg] - pType's nRefCount is > 1 here
1558 typelib_typedescription_release( pTDR->pType );
1559 }
1560
1561 pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
1562 // initialized
1563 pTDR->pType->pWeakRef = pTDR;
1564 }
1565
1566 typelib_typedescription_release( *ppNewDescription );
1567 // pTDR was acquired by getByName(), so it must not be acquired again
1568 *ppNewDescription = pTDR->pType;
1569 return;
1570 }
1571 }
1572 else if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppNewDescription)->eTypeClass) )
1573 {
1575 &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
1576 }
1577 else
1578 {
1579 pTDR = reinterpret_cast<typelib_TypeDescriptionReference *>(*ppNewDescription);
1580
1581 // description is the weak itself, so register it
1582 rInit.maWeakMap[pTDR->pTypeName->buffer] = pTDR;
1583 OSL_ASSERT( static_cast<void *>(*ppNewDescription) == static_cast<void *>(pTDR) );
1584 }
1585
1586 // By default this reference is not really weak. The reference hold the description
1587 // and the description hold the reference.
1588 if( !(*ppNewDescription)->bOnDemand )
1589 {
1590 // nor OnDemand so the description must be acquired if registered
1591 typelib_typedescription_acquire( *ppNewDescription );
1592 }
1593
1594 pTDR->pType = *ppNewDescription;
1595 (*ppNewDescription)->pWeakRef = pTDR;
1596 OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
1597 OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
1598}
1599
1600
1601static bool type_equals(
1602 typelib_TypeDescriptionReference const * p1, typelib_TypeDescriptionReference const * p2 )
1603{
1604 return (p1 == p2 ||
1605 (p1->eTypeClass == p2->eTypeClass &&
1606 p1->pTypeName->length == p2->pTypeName->length &&
1607 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
1608}
1610 const typelib_TypeDescription * p1, const typelib_TypeDescription * p2 )
1612{
1613 return type_equals(
1614 reinterpret_cast<typelib_TypeDescriptionReference const *>(p1), reinterpret_cast<typelib_TypeDescriptionReference const *>(p2) );
1615}
1616
1617
1619 const typelib_TypeDescription * pTypeDescription,
1620 sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
1622{
1623 sal_Int32 nSize;
1624 if( pTypeDescription->nSize )
1625 {
1626 // size and alignment are set
1627 rMaxIntegralTypeSize = pTypeDescription->nAlignment;
1628 nSize = pTypeDescription->nSize;
1629 }
1630 else
1631 {
1632 nSize = 0;
1633 rMaxIntegralTypeSize = 1;
1634
1635 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
1636
1637 switch( pTypeDescription->eTypeClass )
1638 {
1639 case typelib_TypeClass_INTERFACE:
1640 // FEATURE_INTERFACE
1641 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( void * ));
1642 break;
1643 case typelib_TypeClass_ENUM:
1644 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( typelib_TypeClass ));
1645 break;
1646 case typelib_TypeClass_STRUCT:
1647 case typelib_TypeClass_EXCEPTION:
1648 // FEATURE_EMPTYCLASS
1649 {
1650 typelib_CompoundTypeDescription const * pTmp = reinterpret_cast<typelib_CompoundTypeDescription const *>(pTypeDescription);
1651 sal_Int32 nStructSize = 0;
1652 if( pTmp->pBaseTypeDescription )
1653 {
1654 // inherit structs extends the base struct.
1655 nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
1656 rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
1657 }
1658 for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
1659 {
1660 typelib_TypeDescription * pMemberType = nullptr;
1661 typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
1662
1663 sal_Int32 nMaxIntegral;
1664 if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
1665 || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
1666 {
1667 nMaxIntegral = sal_Int32(sizeof(void *));
1668 nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
1669 }
1670 else
1671 {
1672 TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
1674 pMemberType, nStructSize, nMaxIntegral );
1675 TYPELIB_DANGER_RELEASE( pMemberType );
1676 }
1677 if( nMaxIntegral > rMaxIntegralTypeSize )
1678 rMaxIntegralTypeSize = nMaxIntegral;
1679 }
1680#ifdef __m68k__
1681 // Anything that is at least 16 bits wide is aligned on a 16-bit
1682 // boundary on the m68k default abi
1683 sal_Int32 nMaxAlign = std::min(rMaxIntegralTypeSize, sal_Int32( 2 ));
1684 nStructSize = (nStructSize + nMaxAlign -1) / nMaxAlign * nMaxAlign;
1685#else
1686 // Example: A { double; int; } structure has a size of 16 instead of 10. The
1687 // compiler must follow this rule if it is possible to access members in arrays through:
1688 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
1689 nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
1690 / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
1691#endif
1692 nSize += nStructSize;
1693 }
1694 break;
1695 case typelib_TypeClass_SEQUENCE:
1696 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( void * ));
1697 break;
1698 case typelib_TypeClass_ANY:
1699 // FEATURE_ANY
1700 nSize = sal_Int32(sizeof( uno_Any ));
1701 rMaxIntegralTypeSize = sal_Int32(sizeof( void * ));
1702 break;
1703 case typelib_TypeClass_TYPE:
1704 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( typelib_TypeDescriptionReference * ));
1705 break;
1706 case typelib_TypeClass_BOOLEAN:
1707 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Bool ));
1708 break;
1709 case typelib_TypeClass_CHAR:
1710 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Unicode ));
1711 break;
1712 case typelib_TypeClass_STRING:
1713 // FEATURE_STRING
1714 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( rtl_uString * ));
1715 break;
1716 case typelib_TypeClass_FLOAT:
1717 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( float ));
1718 break;
1719 case typelib_TypeClass_DOUBLE:
1720 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( double ));
1721 break;
1722 case typelib_TypeClass_BYTE:
1723 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Int8 ));
1724 break;
1725 case typelib_TypeClass_SHORT:
1726 case typelib_TypeClass_UNSIGNED_SHORT:
1727 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Int16 ));
1728 break;
1729 case typelib_TypeClass_LONG:
1730 case typelib_TypeClass_UNSIGNED_LONG:
1731 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Int32 ));
1732 break;
1733 case typelib_TypeClass_HYPER:
1734 case typelib_TypeClass_UNSIGNED_HYPER:
1735 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Int64 ));
1736 break;
1737 case typelib_TypeClass_UNKNOWN:
1738 case typelib_TypeClass_SERVICE:
1739 case typelib_TypeClass_MODULE:
1740 default:
1741 OSL_FAIL( "not convertible type" );
1742 };
1743 }
1744
1745 return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
1746}
1747
1748
1749namespace {
1750
1751typelib_TypeDescriptionReference ** copyExceptions(
1752 sal_Int32 count, typelib_TypeDescriptionReference ** source)
1753{
1754 typelib_TypeDescriptionReference ** p
1755 = new typelib_TypeDescriptionReference *[count];
1756 for (sal_Int32 i = 0; i < count; ++i) {
1757 p[i] = source[i];
1759 }
1760 return p;
1761}
1762
1763bool createDerivedInterfaceMemberDescription(
1764 typelib_TypeDescription ** result, OUString const & name,
1765 typelib_TypeDescriptionReference * baseRef,
1766 typelib_TypeDescription const * base, typelib_TypeDescription * interface,
1767 sal_Int32 index, sal_Int32 position)
1768{
1769 if (!baseRef || !base || !interface)
1770 return false;
1771
1772 switch (base->eTypeClass) {
1773 case typelib_TypeClass_INTERFACE_METHOD:
1774 {
1776 result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
1777 typelib_InterfaceMethodTypeDescription const * baseMethod
1778 = reinterpret_cast<
1779 typelib_InterfaceMethodTypeDescription const * >(base);
1780 typelib_InterfaceMethodTypeDescription * newMethod
1781 = reinterpret_cast<
1782 typelib_InterfaceMethodTypeDescription * >(*result);
1783 newMethod->aBase.nPosition = position;
1784 newMethod->aBase.pMemberName
1785 = baseMethod->aBase.pMemberName;
1786 rtl_uString_acquire(
1787 newMethod->aBase.pMemberName);
1788 newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef;
1790 newMethod->pReturnTypeRef);
1791 newMethod->nParams = baseMethod->nParams;
1792 newMethod->pParams = new typelib_MethodParameter[
1793 newMethod->nParams];
1794 for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
1795 newMethod->pParams[i].pName
1796 = baseMethod->pParams[i].pName;
1797 rtl_uString_acquire(
1798 newMethod->pParams[i].pName);
1799 newMethod->pParams[i].pTypeRef
1800 = baseMethod->pParams[i].pTypeRef;
1802 newMethod->pParams[i].pTypeRef);
1803 newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
1804 newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
1805 }
1806 newMethod->nExceptions = baseMethod->nExceptions;
1807 newMethod->ppExceptions = copyExceptions(
1808 baseMethod->nExceptions, baseMethod->ppExceptions);
1809 newMethod->bOneWay = baseMethod->bOneWay;
1810 newMethod->pInterface
1811 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
1812 interface);
1813 newMethod->pBaseRef = baseRef;
1814 newMethod->nIndex = index;
1815 return true;
1816 }
1817
1818 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1819 {
1821 result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
1822 typelib_InterfaceAttributeTypeDescription const * baseAttribute
1823 = reinterpret_cast<
1824 typelib_InterfaceAttributeTypeDescription const * >(base);
1825 typelib_InterfaceAttributeTypeDescription * newAttribute
1826 = reinterpret_cast<
1827 typelib_InterfaceAttributeTypeDescription * >(*result);
1828 newAttribute->aBase.nPosition = position;
1829 newAttribute->aBase.pMemberName
1830 = baseAttribute->aBase.pMemberName;
1831 rtl_uString_acquire(newAttribute->aBase.pMemberName);
1832 newAttribute->bReadOnly = baseAttribute->bReadOnly;
1833 newAttribute->pAttributeTypeRef
1834 = baseAttribute->pAttributeTypeRef;
1835 typelib_typedescriptionreference_acquire(newAttribute->pAttributeTypeRef);
1836 newAttribute->pInterface
1837 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
1838 interface);
1839 newAttribute->pBaseRef = baseRef;
1840 newAttribute->nIndex = index;
1841 newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
1842 newAttribute->ppGetExceptions = copyExceptions(
1843 baseAttribute->nGetExceptions,
1844 baseAttribute->ppGetExceptions);
1845 newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
1846 newAttribute->ppSetExceptions = copyExceptions(
1847 baseAttribute->nSetExceptions,
1848 baseAttribute->ppSetExceptions);
1849 return true;
1850 }
1851
1852 default:
1853 break;
1854 }
1855 return false;
1856}
1857
1858}
1859
1860extern "C" void SAL_CALL typelib_typedescription_getByName(
1861 typelib_TypeDescription ** ppRet, rtl_uString * pName )
1863{
1864 if( *ppRet )
1865 {
1867 *ppRet = nullptr;
1868 }
1869
1870 static bool bInited = false;
1871 TypeDescriptor_Init_Impl &rInit = Init();
1872
1873 if( !bInited )
1874 {
1875 // guard against multi thread access
1876 MutexGuard aGuard( rInit.maMutex );
1877 if( !bInited )
1878 {
1879 // avoid recursion during the next ...new calls
1880 bInited = true;
1881
1882 typelib_TypeDescription * pType = nullptr;
1883 typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, OUString("type").pData, nullptr, 0, nullptr );
1885 typelib_typedescription_new( &pType, typelib_TypeClass_VOID, OUString("void").pData, nullptr, 0, nullptr );
1887 typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, OUString("boolean").pData, nullptr, 0, nullptr );
1889 typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, OUString("char").pData, nullptr, 0, nullptr );
1891 typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, OUString("byte").pData, nullptr, 0, nullptr );
1893 typelib_typedescription_new( &pType, typelib_TypeClass_STRING, OUString("string").pData, nullptr, 0, nullptr );
1895 typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, OUString("short").pData, nullptr, 0, nullptr );
1897 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, OUString("unsigned short").pData, nullptr, 0, nullptr );
1899 typelib_typedescription_new( &pType, typelib_TypeClass_LONG, OUString("long").pData, nullptr, 0, nullptr );
1901 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, OUString("unsigned long").pData, nullptr, 0, nullptr );
1903 typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, OUString("hyper").pData, nullptr, 0, nullptr );
1905 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, OUString("unsigned hyper").pData, nullptr, 0, nullptr );
1907 typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, OUString("float").pData, nullptr, 0, nullptr );
1909 typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, OUString("double").pData, nullptr, 0, nullptr );
1911 typelib_typedescription_new( &pType, typelib_TypeClass_ANY, OUString("any").pData, nullptr, 0, nullptr );
1914 }
1915 }
1916
1917 typelib_TypeDescriptionReference * pTDR = nullptr;
1919 if( pTDR )
1920 {
1921 {
1922 // guard against multi thread access
1923 MutexGuard aGuard( rInit.maMutex );
1924 // pTDR->pType->pWeakRef == 0 means that the description is empty
1925 if( pTDR->pType && pTDR->pType->pWeakRef )
1926 {
1927 typelib_typedescription_acquire( pTDR->pType );
1928 *ppRet = pTDR->pType;
1929 }
1930 }
1932 }
1933
1934 if (nullptr != *ppRet)
1935 return;
1936
1937 // check for sequence
1938 OUString const & name = OUString::unacquired( &pName );
1939 if (2 < name.getLength() && '[' == name[ 0 ])
1940 {
1941 OUString element_name( name.copy( 2 ) );
1942 typelib_TypeDescription * element_td = nullptr;
1943 typelib_typedescription_getByName( &element_td, element_name.pData );
1944 if (nullptr != element_td)
1945 {
1947 ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, nullptr );
1948 // register?
1949 typelib_typedescription_release( element_td );
1950 }
1951 }
1952 if (nullptr == *ppRet)
1953 {
1954 // Check for derived interface member type:
1955 sal_Int32 i1 = name.lastIndexOf(":@");
1956 if (i1 >= 0) {
1957 sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
1958 sal_Int32 i3 = name.indexOf(',', i2);
1959 if (i3 >= 0) {
1960 sal_Int32 i4 = name.indexOf(':', i3);
1961 if (i4 >= 0) {
1962 typelib_TypeDescriptionReference * pBaseRef = nullptr;
1963 typelib_TypeDescription * pBase = nullptr;
1964 typelib_TypeDescription * pInterface = nullptr;
1966 &pBaseRef, name.copy(0, i1).pData);
1967 if (pBaseRef != nullptr) {
1969 &pBase, pBaseRef);
1970 }
1972 &pInterface, name.copy(i4 + 1).pData);
1973 if (!createDerivedInterfaceMemberDescription(
1974 ppRet, name, pBaseRef, pBase, pInterface,
1975 o3tl::toInt32(name.subView(i2, i3 - i2)),
1976 o3tl::toInt32(name.subView(i3 + 1, i4 - i3 - 1))))
1977 {
1978 if (pInterface != nullptr) {
1980 }
1981 if (pBase != nullptr) {
1983 }
1984 if (pBaseRef != nullptr) {
1986 pBaseRef);
1987 }
1988 }
1989 }
1990 }
1991 }
1992 }
1993 if (nullptr == *ppRet)
1994 {
1995 // on demand access
1996 rInit.callChain( ppRet, pName );
1997 }
1998
1999 if( !(*ppRet) )
2000 return;
2001
2002 // typedescription found
2003 if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
2004 {
2005 typelib_TypeDescription * pTD = nullptr;
2007 &pTD, reinterpret_cast<typelib_IndirectTypeDescription *>(*ppRet)->pType );
2009 *ppRet = pTD;
2010 }
2011 else
2012 {
2013 // set to on demand
2014 (*ppRet)->bOnDemand = true;
2015 // The type description is hold by the reference until
2016 // on demand is activated.
2018
2019 // insert into the cache
2020 MutexGuard aGuard( rInit.maMutex );
2021 if( rInit.maCache.size() >= nCacheSize )
2022 {
2023 typelib_typedescription_release( rInit.maCache.front() );
2024 rInit.maCache.pop_front();
2025 }
2026 // descriptions in the cache must be acquired!
2028 rInit.maCache.push_back( *ppRet );
2029 }
2030}
2031
2033 typelib_TypeDescriptionReference ** ppTDR,
2034 typelib_TypeClass eTypeClass,
2035 const char * pTypeName )
2037{
2038 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
2039 typelib_typedescriptionreference_new( ppTDR, eTypeClass, aTypeName.pData );
2040}
2041
2043 typelib_TypeDescriptionReference ** ppTDR,
2044 typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
2046{
2047 TypeDescriptor_Init_Impl &rInit = Init();
2048 if( eTypeClass == typelib_TypeClass_TYPEDEF )
2049 {
2050 // on demand access
2051 typelib_TypeDescription * pRet = nullptr;
2052 rInit.callChain( &pRet, pTypeName );
2053 if( pRet )
2054 {
2055 // typedescription found
2056 if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
2057 {
2059 reinterpret_cast<typelib_IndirectTypeDescription *>(pRet)->pType );
2060 if (*ppTDR)
2062 *ppTDR = reinterpret_cast<typelib_IndirectTypeDescription *>(pRet)->pType;
2064 }
2065 else
2066 {
2067 // set to on demand
2068 pRet->bOnDemand = true;
2069 // The type description is hold by the reference until
2070 // on demand is activated.
2072
2073 // insert into the cache
2074 MutexGuard aGuard( rInit.maMutex );
2075 if( rInit.maCache.size() >= nCacheSize )
2076 {
2077 typelib_typedescription_release( rInit.maCache.front() );
2078 rInit.maCache.pop_front();
2079 }
2080 rInit.maCache.push_back( pRet );
2081 // pRet kept acquired for cache
2082
2084 if (*ppTDR)
2086 *ppTDR = pRet->pWeakRef;
2087 }
2088 }
2089 else if (*ppTDR)
2090 {
2091 SAL_INFO("cppu.typelib", "typedef not found : " << pTypeName);
2093 *ppTDR = nullptr;
2094 }
2095 return;
2096 }
2097
2098 MutexGuard aGuard( rInit.maMutex );
2100 if( *ppTDR )
2101 return;
2102
2103 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass ) )
2104 {
2105 typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference;
2106#if OSL_DEBUG_LEVEL > 0
2107 osl_atomic_increment( &rInit.nTypeDescriptionReferenceCount );
2108#endif
2109 pTDR->nRefCount = 1;
2110 pTDR->nStaticRefCount = 0;
2111 pTDR->eTypeClass = eTypeClass;
2112 pTDR->pUniqueIdentifier = nullptr;
2113 pTDR->pReserved = nullptr;
2114 pTDR->pTypeName = pTypeName;
2115 rtl_uString_acquire( pTDR->pTypeName );
2116 pTDR->pType = nullptr;
2117 *ppTDR = pTDR;
2118 }
2119 else
2120 {
2121 typelib_typedescription_newEmpty( reinterpret_cast<typelib_TypeDescription ** >(ppTDR), eTypeClass, pTypeName );
2122 // description will be registered but not acquired
2123 (*reinterpret_cast<typelib_TypeDescription **>(ppTDR))->bOnDemand = true;
2124 (*reinterpret_cast<typelib_TypeDescription **>(ppTDR))->bComplete = false;
2125 }
2126
2127 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2128 // not registered
2129 rInit.maWeakMap[ (*ppTDR)->pTypeName->buffer ] = *ppTDR;
2130}
2131
2132
2134 typelib_TypeDescriptionReference * pRef )
2136{
2137 osl_atomic_increment( &pRef->nRefCount );
2138}
2139
2140
2142 typelib_TypeDescriptionReference * pRef )
2144{
2145 // Is it a type description?
2146 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pRef->eTypeClass ) )
2147 {
2148 if( ! osl_atomic_decrement( &pRef->nRefCount ) )
2149 {
2150 TypeDescriptor_Init_Impl &rInit = Init();
2151 MutexGuard aGuard( rInit.maMutex );
2152 WeakMap_Impl::iterator aIt = rInit.maWeakMap.find( pRef->pTypeName->buffer );
2153 if( aIt != rInit.maWeakMap.end() && (*aIt).second == pRef )
2154 {
2155 // remove only if it contains the same object
2156 rInit.maWeakMap.erase( aIt );
2157 }
2158
2159 rtl_uString_release( pRef->pTypeName );
2160 OSL_ASSERT( pRef->pType == nullptr );
2161#if OSL_DEBUG_LEVEL > 0
2162 osl_atomic_decrement( &rInit.nTypeDescriptionReferenceCount );
2163#endif
2164 delete pRef;
2165 }
2166 }
2167 else
2168 {
2169 typelib_typedescription_release( reinterpret_cast<typelib_TypeDescription *>(pRef) );
2170 }
2171}
2172
2173
2175 typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef )
2177{
2178 if( *ppRet )
2179 {
2181 *ppRet = nullptr;
2182 }
2183
2184 if( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
2185 {
2186 // reference is a description and initialized
2187 osl_atomic_increment( &reinterpret_cast<typelib_TypeDescription *>(pRef)->nRefCount );
2188 *ppRet = reinterpret_cast<typelib_TypeDescription *>(pRef);
2189 return;
2190 }
2191
2192 {
2193 MutexGuard aGuard( Init().maMutex );
2194 // pRef->pType->pWeakRef == 0 means that the description is empty
2195 if( pRef->pType && pRef->pType->pWeakRef )
2196 {
2197 sal_Int32 n = osl_atomic_increment( &pRef->pType->nRefCount );
2198 if( n > 1 )
2199 {
2200 // The reference is incremented. The object cannot be destroyed.
2201 // Release the guard at the earliest point.
2202 *ppRet = pRef->pType;
2203 return;
2204 }
2205 (void)osl_atomic_decrement( &pRef->pType->nRefCount );
2206 // destruction of this type in progress (another thread!)
2207 // no access through this weak reference
2208 pRef->pType = nullptr;
2209 }
2210 }
2211
2212 typelib_typedescription_getByName( ppRet, pRef->pTypeName );
2213 OSL_ASSERT( !*ppRet || rtl_ustr_compare( pRef->pTypeName->buffer, (*ppRet)->pTypeName->buffer ) == 0 );
2214 OSL_ASSERT( !*ppRet || pRef->eTypeClass == (*ppRet)->eTypeClass );
2215 OSL_ASSERT( !*ppRet || pRef == (*ppRet)->pWeakRef );
2216 pRef->pType = *ppRet;
2217}
2218
2219
2221 typelib_TypeDescriptionReference ** ppRet, rtl_uString const * pName )
2223{
2224 if( *ppRet )
2225 {
2227 *ppRet = nullptr;
2228 }
2229 TypeDescriptor_Init_Impl &rInit = Init();
2230
2231 MutexGuard aGuard( rInit.maMutex );
2232 WeakMap_Impl::const_iterator aIt = rInit.maWeakMap.find( pName->buffer );
2233 if( aIt == rInit.maWeakMap.end() )
2234 return;
2235
2236 sal_Int32 n = osl_atomic_increment( &(*aIt).second->nRefCount );
2237 if( n > 1 )
2238 {
2239 // The reference is incremented. The object cannot be destroyed.
2240 // Release the guard at the earliest point.
2241 *ppRet = (*aIt).second;
2242 }
2243 else
2244 {
2245 // destruction of this type in progress (another thread!)
2246 // no access through this weak reference
2247 (void)osl_atomic_decrement( &(*aIt).second->nRefCount );
2248 }
2249}
2250
2251
2253 const typelib_TypeDescriptionReference * p1,
2254 const typelib_TypeDescriptionReference * p2 )
2256{
2257 return (p1 == p2 ||
2258 (p1->eTypeClass == p2->eTypeClass &&
2259 p1->pTypeName->length == p2->pTypeName->length &&
2260 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
2261}
2262
2263
2265 typelib_TypeDescriptionReference ** ppDest,
2266 typelib_TypeDescriptionReference * pSource )
2268{
2269 if (*ppDest != pSource)
2270 {
2273 *ppDest = pSource;
2274 }
2275}
2276
2277
2278extern "C" void SAL_CALL typelib_setCacheSize( sal_Int32 )
2280{
2281}
2282
2283
2284const bool s_aAssignableFromTab[11][11] =
2285{
2286 /* from CH, BO, BY, SH, US, LO, UL, HY, UH, FL, DO */
2287/* TypeClass_CHAR */ { true, false, false, false, false, false, false, false, false, false, false },
2288/* TypeClass_BOOLEAN */ { false, true, false, false, false, false, false, false, false, false, false },
2289/* TypeClass_BYTE */ { false, false, true, false, false, false, false, false, false, false, false },
2290/* TypeClass_SHORT */ { false, false, true, true, true, false, false, false, false, false, false },
2291/* TypeClass_UNSIGNED_SHORT */ { false, false, true, true, true, false, false, false, false, false, false },
2292/* TypeClass_LONG */ { false, false, true, true, true, true, true, false, false, false, false },
2293/* TypeClass_UNSIGNED_LONG */ { false, false, true, true, true, true, true, false, false, false, false },
2294/* TypeClass_HYPER */ { false, false, true, true, true, true, true, true, true, false, false },
2295/* TypeClass_UNSIGNED_HYPER */ { false, false, true, true, true, true, true, true, true, false, false },
2296/* TypeClass_FLOAT */ { false, false, true, true, true, false, false, false, false, true, false },
2297/* TypeClass_DOUBLE */ { false, false, true, true, true, true, true, false, false, true, true }
2298};
2299
2300
2302 typelib_TypeDescriptionReference * pAssignable,
2303 typelib_TypeDescriptionReference * pFrom )
2305{
2306 if (!pAssignable || !pFrom)
2307 return false;
2308
2309 typelib_TypeClass eAssignable = pAssignable->eTypeClass;
2310 typelib_TypeClass eFrom = pFrom->eTypeClass;
2311
2312 if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
2313 return true;
2314 if (eAssignable == eFrom)
2315 {
2316 if (type_equals( pAssignable, pFrom )) // first shot
2317 {
2318 return true;
2319 }
2320 switch (eAssignable)
2321 {
2322 case typelib_TypeClass_STRUCT:
2323 case typelib_TypeClass_EXCEPTION:
2324 {
2325 typelib_TypeDescription * pFromDescr = nullptr;
2326 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2327 if (!reinterpret_cast<typelib_CompoundTypeDescription *>(pFromDescr)->pBaseTypeDescription)
2328 {
2329 TYPELIB_DANGER_RELEASE( pFromDescr );
2330 return false;
2331 }
2333 pAssignable,
2334 reinterpret_cast<typelib_CompoundTypeDescription *>(pFromDescr)->pBaseTypeDescription->aBase.pWeakRef );
2335 TYPELIB_DANGER_RELEASE( pFromDescr );
2336 return bRet;
2337 }
2338 case typelib_TypeClass_INTERFACE:
2339 {
2340 typelib_TypeDescription * pFromDescr = nullptr;
2341 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2342 typelib_InterfaceTypeDescription * pFromIfc
2343 = reinterpret_cast<
2344 typelib_InterfaceTypeDescription * >(pFromDescr);
2345 bool bRet = false;
2346 for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
2348 pAssignable,
2349 pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
2350 {
2351 bRet = true;
2352 break;
2353 }
2354 }
2355 TYPELIB_DANGER_RELEASE( pFromDescr );
2356 return bRet;
2357 }
2358 default:
2359 {
2360 return false;
2361 }
2362 }
2363 }
2364 return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
2365 eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
2366 s_aAssignableFromTab[eAssignable-1][eFrom-1]);
2367}
2368
2370 typelib_TypeDescription * pAssignable,
2371 typelib_TypeDescription * pFrom )
2373{
2375 pAssignable->pWeakRef, pFrom->pWeakRef );
2376}
2377
2378
2380 typelib_TypeDescription ** ppTypeDescr )
2382{
2383 return complete(ppTypeDescr, true);
2384}
2385
2386/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::mutex maMutex
const char * pName
void Init()
sal_Int32 nRefCount
Definition: copy.hxx:38
bool bReadOnly
ColCacheType maCache
void const * base
const char * name
OUString aName
void * p
sal_Int64 n
sal_uInt16 nPos
#define SAL_INFO_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
struct _typelib_TypeDescription typelib_TypeDescription
struct _uno_Any uno_Any
def position(n=-1)
size
int i
index
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
PyObject_HEAD PyUNO_callable_Internals * members
void SAL_CALL typelib_typedescriptionreference_new(typelib_TypeDescriptionReference **ppTDR, typelib_TypeClass eTypeClass, rtl_uString *pTypeName) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2042
void SAL_CALL typelib_typedescription_revokeCallback(void *pContext, typelib_typedescription_Callback pCallback) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:287
static sal_Int32 getDescriptionSize(typelib_TypeClass eTypeClass)
Definition: typelib.cxx:87
void SAL_CALL typelib_setCacheSize(sal_Int32) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2278
constexpr auto nCacheSize
Definition: typelib.cxx:157
static void typelib_typedescription_destructExtendedMembers(typelib_TypeDescription *pTD)
Definition: typelib.cxx:1219
void SAL_CALL typelib_typedescription_register(typelib_TypeDescription **ppNewDescription) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:1393
void SAL_CALL typelib_typedescriptionreference_acquire(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2133
sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom(typelib_TypeDescription *pAssignable, typelib_TypeDescription *pFrom) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2369
void SAL_CALL typelib_typedescription_newEnum(typelib_TypeDescription **ppRet, rtl_uString *pTypeName, sal_Int32 nDefaultValue, sal_Int32 nEnumValues, rtl_uString **ppEnumNames, sal_Int32 *pEnumValues) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:792
void SAL_CALL typelib_typedescription_newMIInterface(typelib_InterfaceTypeDescription **ppRet, rtl_uString *pTypeName, SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt32, sal_Int32 nBaseInterfaces, typelib_TypeDescriptionReference **ppBaseInterfaces, sal_Int32 nMembers, typelib_TypeDescriptionReference **ppMembers) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:912
const sal_Int32 nMaxAlignment
Definition: typelib.cxx:68
const bool s_aAssignableFromTab[11][11]
Definition: typelib.cxx:2284
void SAL_CALL typelib_typedescription_newInterface(typelib_InterfaceTypeDescription **ppRet, rtl_uString *pTypeName, SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt32, typelib_TypeDescriptionReference *pBaseInterface, sal_Int32 nMembers, typelib_TypeDescriptionReference **ppMembers) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:823
std::pair< void *, typelib_typedescription_Callback > CallbackEntry
Definition: typelib.cxx:152
void SAL_CALL typelib_typedescriptionreference_assign(typelib_TypeDescriptionReference **ppDest, typelib_TypeDescriptionReference *pSource) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2264
static sal_Int32 adjustAlignment(sal_Int32 nRequestedAlignment)
Definition: typelib.cxx:70
void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute(typelib_InterfaceAttributeTypeDescription **ppRet, sal_Int32 nAbsolutePosition, rtl_uString *pTypeName, typelib_TypeClass eAttributeTypeClass, rtl_uString *pAttributeTypeName, sal_Bool bReadOnly, sal_Int32 nGetExceptions, rtl_uString **ppGetExceptionNames, sal_Int32 nSetExceptions, rtl_uString **ppSetExceptionNames) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:1135
void typelib_typedescription_newEmpty(typelib_TypeDescription **ppRet, typelib_TypeClass eTypeClass, rtl_uString *pTypeName) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:473
std::list< CallbackEntry > CallbackSet_Impl
Definition: typelib.cxx:153
void SAL_CALL typelib_typedescription_release(typelib_TypeDescription *pTD) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:1325
void SAL_CALL typelib_typedescription_registerCallback(void *pContext, typelib_typedescription_Callback pCallback) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:276
sal_Bool SAL_CALL typelib_typedescription_complete(typelib_TypeDescription **ppTypeDescr) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2379
std::unordered_map< const sal_Unicode *, typelib_TypeDescriptionReference *, hashStr_Impl, equalStr_Impl > WeakMap_Impl
Definition: typelib.cxx:150
void SAL_CALL typelib_typedescriptionreference_getDescription(typelib_TypeDescription **ppRet, typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2174
void SAL_CALL typelib_typedescription_acquire(typelib_TypeDescription *pTypeDescription) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:1197
sal_Bool SAL_CALL typelib_typedescriptionreference_equals(const typelib_TypeDescriptionReference *p1, const typelib_TypeDescriptionReference *p2) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2252
sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(typelib_TypeDescriptionReference *pAssignable, typelib_TypeDescriptionReference *pFrom) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2301
static sal_Int32 newAlignedSize(sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment)
Calculate the new size of the structure.
Definition: typelib.cxx:80
void SAL_CALL typelib_typedescription_getByName(typelib_TypeDescription **ppRet, rtl_uString *pName) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:1860
static bool type_equals(typelib_TypeDescriptionReference const *p1, typelib_TypeDescriptionReference const *p2)
Definition: typelib.cxx:1601
void SAL_CALL typelib_typedescriptionreference_release(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2141
void SAL_CALL typelib_typedescription_newInterfaceAttribute(typelib_InterfaceAttributeTypeDescription **ppRet, sal_Int32 nAbsolutePosition, rtl_uString *pTypeName, typelib_TypeClass eAttributeTypeClass, rtl_uString *pAttributeTypeName, sal_Bool bReadOnly) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:1120
static void typelib_typedescription_initTables(typelib_TypeDescription *pTD)
Definition: typelib.cxx:301
void SAL_CALL typelib_typedescription_new(typelib_TypeDescription **ppRet, typelib_TypeClass eTypeClass, rtl_uString *pTypeName, typelib_TypeDescriptionReference *pType, sal_Int32 nMembers, typelib_CompoundMember_Init *pMembers) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:765
std::list< typelib_TypeDescription * > TypeDescriptionList_Impl
Definition: typelib.cxx:154
void SAL_CALL typelib_typedescription_newStruct(typelib_TypeDescription **ppRet, rtl_uString *pTypeName, typelib_TypeDescriptionReference *pType, sal_Int32 nMembers, typelib_StructMember_Init *pMembers) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:778
void SAL_CALL typelib_typedescriptionreference_newByAsciiName(typelib_TypeDescriptionReference **ppTDR, typelib_TypeClass eTypeClass, const char *pTypeName) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2032
sal_Bool SAL_CALL typelib_typedescription_equals(const typelib_TypeDescription *p1, const typelib_TypeDescription *p2) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:1609
void typelib_typedescriptionreference_getByName(typelib_TypeDescriptionReference **ppRet, rtl_uString const *pName) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:2220
sal_Int32 typelib_typedescription_getAlignedUnoSize(const typelib_TypeDescription *pTypeDescription, sal_Int32 nOffset, sal_Int32 &rMaxIntegralTypeSize) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:1618
void SAL_CALL typelib_typedescription_newInterfaceMethod(typelib_InterfaceMethodTypeDescription **ppRet, sal_Int32 nAbsolutePosition, sal_Bool bOneWay, rtl_uString *pTypeName, typelib_TypeClass eReturnTypeClass, rtl_uString *pReturnTypeName, sal_Int32 nParams, typelib_Parameter_Init *pParams, sal_Int32 nExceptions, rtl_uString **ppExceptionNames) SAL_THROW_EXTERN_C()
Definition: typelib.cxx:1042
unsigned char sal_Bool
#define SAL_THROW_EXTERN_C()
sal_uInt16 sal_Unicode
signed char sal_Int8