1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_cppu.hxx" 26 27 #include "IdentityMapping.hxx" 28 29 #include <hash_map> 30 #include <set> 31 #include <algorithm> 32 33 #include "rtl/unload.h" 34 #include "rtl/ustring.hxx" 35 #include "rtl/ustrbuf.hxx" 36 #include "osl/module.h" 37 #include "osl/diagnose.h" 38 #include "osl/mutex.hxx" 39 #include "osl/interlck.h" 40 41 #include "uno/dispatcher.h" 42 #include "uno/mapping.h" 43 #include "uno/lbnames.h" 44 #include "uno/environment.hxx" 45 46 #include "typelib/typedescription.h" 47 48 #include "cppu/EnvDcp.hxx" 49 #include "cascade_mapping.hxx" 50 #include "IdentityMapping.hxx" 51 #include "loadmodule.hxx" 52 53 using namespace std; 54 using namespace osl; 55 using namespace rtl; 56 using namespace com::sun::star::uno; 57 58 59 namespace cppu 60 { 61 62 class Mapping 63 { 64 uno_Mapping * _pMapping; 65 66 public: 67 inline Mapping( uno_Mapping * pMapping = 0 ) SAL_THROW( () ); 68 inline Mapping( const Mapping & rMapping ) SAL_THROW( () ); 69 inline ~Mapping() SAL_THROW( () ); 70 inline Mapping & SAL_CALL operator = ( uno_Mapping * pMapping ) SAL_THROW( () ); 71 inline Mapping & SAL_CALL operator = ( const Mapping & rMapping ) SAL_THROW( () ) 72 { return operator = ( rMapping._pMapping ); } 73 inline uno_Mapping * SAL_CALL get() const SAL_THROW( () ) 74 { return _pMapping; } 75 inline sal_Bool SAL_CALL is() const SAL_THROW( () ) 76 { return (_pMapping != 0); } 77 }; 78 //__________________________________________________________________________________________________ 79 inline Mapping::Mapping( uno_Mapping * pMapping ) SAL_THROW( () ) 80 : _pMapping( pMapping ) 81 { 82 if (_pMapping) 83 (*_pMapping->acquire)( _pMapping ); 84 } 85 //__________________________________________________________________________________________________ 86 inline Mapping::Mapping( const Mapping & rMapping ) SAL_THROW( () ) 87 : _pMapping( rMapping._pMapping ) 88 { 89 if (_pMapping) 90 (*_pMapping->acquire)( _pMapping ); 91 } 92 //__________________________________________________________________________________________________ 93 inline Mapping::~Mapping() SAL_THROW( () ) 94 { 95 if (_pMapping) 96 (*_pMapping->release)( _pMapping ); 97 } 98 //__________________________________________________________________________________________________ 99 inline Mapping & Mapping::operator = ( uno_Mapping * pMapping ) SAL_THROW( () ) 100 { 101 if (pMapping) 102 (*pMapping->acquire)( pMapping ); 103 if (_pMapping) 104 (*_pMapping->release)( _pMapping ); 105 _pMapping = pMapping; 106 return *this; 107 } 108 109 //================================================================================================== 110 struct MappingEntry 111 { 112 sal_Int32 nRef; 113 uno_Mapping * pMapping; 114 uno_freeMappingFunc freeMapping; 115 OUString aMappingName; 116 117 MappingEntry( 118 uno_Mapping * pMapping_, uno_freeMappingFunc freeMapping_, 119 const OUString & rMappingName_ ) 120 SAL_THROW( () ) 121 : nRef( 1 ) 122 , pMapping( pMapping_ ) 123 , freeMapping( freeMapping_ ) 124 , aMappingName( rMappingName_ ) 125 {} 126 }; 127 //-------------------------------------------------------------------------------------------------- 128 struct FctOUStringHash : public unary_function< const OUString &, size_t > 129 { 130 size_t operator()( const OUString & rKey ) const SAL_THROW( () ) 131 { return (size_t)rKey.hashCode(); } 132 }; 133 //-------------------------------------------------------------------------------------------------- 134 struct FctPtrHash : public unary_function< uno_Mapping *, size_t > 135 { 136 size_t operator()( uno_Mapping * pKey ) const SAL_THROW( () ) 137 { return (size_t)pKey; } 138 }; 139 140 typedef hash_map< 141 OUString, MappingEntry *, FctOUStringHash, equal_to< OUString > > t_OUString2Entry; 142 typedef hash_map< 143 uno_Mapping *, MappingEntry *, FctPtrHash, equal_to< uno_Mapping * > > t_Mapping2Entry; 144 145 typedef set< uno_getMappingFunc > t_CallbackSet; 146 typedef set< OUString > t_OUStringSet; 147 148 //================================================================================================== 149 struct MappingsData 150 { 151 Mutex aMappingsMutex; 152 t_OUString2Entry aName2Entry; 153 t_Mapping2Entry aMapping2Entry; 154 155 Mutex aCallbacksMutex; 156 t_CallbackSet aCallbacks; 157 158 Mutex aNegativeLibsMutex; 159 t_OUStringSet aNegativeLibs; 160 }; 161 //-------------------------------------------------------------------------------------------------- 162 static MappingsData & getMappingsData() SAL_THROW( () ) 163 { 164 static MappingsData * s_p = 0; 165 if (! s_p) 166 { 167 MutexGuard aGuard( Mutex::getGlobalMutex() ); 168 if (! s_p) 169 { 170 //TODO This memory is leaked; see #i63473# for when this should be 171 // changed again: 172 s_p = new MappingsData; 173 } 174 } 175 return *s_p; 176 } 177 178 /** 179 * This class mediates two different mapping via uno, e.g. form any language to uno, 180 * then from uno to any other language. 181 */ 182 struct uno_Mediate_Mapping : public uno_Mapping 183 { 184 sal_Int32 nRef; 185 186 Environment aFrom; 187 Environment aTo; 188 189 Mapping aFrom2Uno; 190 Mapping aUno2To; 191 192 OUString aAddPurpose; 193 194 uno_Mediate_Mapping( 195 const Environment & rFrom_, const Environment & rTo_, 196 const Mapping & rFrom2Uno_, const Mapping & rUno2To_, 197 const OUString & rAddPurpose ) 198 SAL_THROW( () ); 199 }; 200 extern "C" 201 { 202 //-------------------------------------------------------------------------------------------------- 203 static void SAL_CALL mediate_free( uno_Mapping * pMapping ) 204 SAL_THROW( () ) 205 { 206 delete static_cast< uno_Mediate_Mapping * >( pMapping ); 207 } 208 //-------------------------------------------------------------------------------------------------- 209 static void SAL_CALL mediate_acquire( uno_Mapping * pMapping ) 210 SAL_THROW( () ) 211 { 212 if (1 == ::osl_incrementInterlockedCount( 213 & static_cast< uno_Mediate_Mapping * >( pMapping )->nRef )) 214 { 215 uno_registerMapping( 216 &pMapping, mediate_free, 217 static_cast< uno_Mediate_Mapping * >( pMapping )->aFrom.get(), 218 static_cast< uno_Mediate_Mapping * >( pMapping )->aTo.get(), 219 static_cast< uno_Mediate_Mapping * >( pMapping )->aAddPurpose.pData ); 220 } 221 } 222 //-------------------------------------------------------------------------------------------------- 223 static void SAL_CALL mediate_release( uno_Mapping * pMapping ) 224 SAL_THROW( () ) 225 { 226 if (! ::osl_decrementInterlockedCount( 227 & static_cast< uno_Mediate_Mapping * >( pMapping )->nRef )) 228 { 229 uno_revokeMapping( pMapping ); 230 } 231 } 232 //-------------------------------------------------------------------------------------------------- 233 static void SAL_CALL mediate_mapInterface( 234 uno_Mapping * pMapping, 235 void ** ppOut, void * pInterface, 236 typelib_InterfaceTypeDescription * pInterfaceTypeDescr ) 237 SAL_THROW( () ) 238 { 239 OSL_ENSURE( pMapping && ppOut, "### null ptr!" ); 240 if (pMapping && ppOut) 241 { 242 uno_Mediate_Mapping * that = static_cast< uno_Mediate_Mapping * >( pMapping ); 243 uno_Mapping * pFrom2Uno = that->aFrom2Uno.get(); 244 245 uno_Interface * pUnoI = 0; 246 (*pFrom2Uno->mapInterface)( pFrom2Uno, (void **) &pUnoI, pInterface, pInterfaceTypeDescr ); 247 if (0 == pUnoI) 248 { 249 void * pOut = *ppOut; 250 if (0 != pOut) 251 { 252 uno_ExtEnvironment * pTo = that->aTo.get()->pExtEnv; 253 OSL_ENSURE( 0 != pTo, "### cannot release out interface: leaking!" ); 254 if (0 != pTo) 255 (*pTo->releaseInterface)( pTo, pOut ); 256 *ppOut = 0; // set to 0 anyway, because mapping was not successfull! 257 } 258 } 259 else 260 { 261 uno_Mapping * pUno2To = that->aUno2To.get(); 262 (*pUno2To->mapInterface)( pUno2To, ppOut, pUnoI, pInterfaceTypeDescr ); 263 (*pUnoI->release)( pUnoI ); 264 } 265 } 266 } 267 } 268 //__________________________________________________________________________________________________ 269 uno_Mediate_Mapping::uno_Mediate_Mapping( 270 const Environment & rFrom_, const Environment & rTo_, 271 const Mapping & rFrom2Uno_, const Mapping & rUno2To_, 272 const OUString & rAddPurpose_ ) 273 SAL_THROW( () ) 274 : nRef( 1 ) 275 , aFrom( rFrom_ ) 276 , aTo( rTo_ ) 277 , aFrom2Uno( rFrom2Uno_ ) 278 , aUno2To( rUno2To_ ) 279 , aAddPurpose( rAddPurpose_ ) 280 { 281 uno_Mapping::acquire = mediate_acquire; 282 uno_Mapping::release = mediate_release; 283 uno_Mapping::mapInterface = mediate_mapInterface; 284 } 285 286 //================================================================================================== 287 static inline OUString getMappingName( 288 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) 289 SAL_THROW( () ) 290 { 291 OUStringBuffer aKey( 64 ); 292 aKey.append( rAddPurpose ); 293 aKey.append( (sal_Unicode)';' ); 294 aKey.append( rFrom.getTypeName() ); 295 aKey.append( (sal_Unicode)'[' ); 296 aKey.append( reinterpret_cast< sal_IntPtr >(rFrom.get()), 16 ); 297 aKey.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") ); 298 aKey.append( rTo.getTypeName() ); 299 aKey.append( (sal_Unicode)'[' ); 300 aKey.append( reinterpret_cast< sal_IntPtr >(rTo.get()), 16 ); 301 aKey.append( (sal_Unicode)']' ); 302 return aKey.makeStringAndClear(); 303 } 304 //================================================================================================== 305 static inline OUString getBridgeName( 306 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) 307 SAL_THROW( () ) 308 { 309 OUStringBuffer aBridgeName( 16 ); 310 if (rAddPurpose.getLength()) 311 { 312 aBridgeName.append( rAddPurpose ); 313 aBridgeName.append( (sal_Unicode)'_' ); 314 } 315 aBridgeName.append( EnvDcp::getTypeName(rFrom.getTypeName()) ); 316 aBridgeName.append( (sal_Unicode)'_' ); 317 aBridgeName.append( EnvDcp::getTypeName(rTo.getTypeName()) ); 318 return aBridgeName.makeStringAndClear(); 319 } 320 //================================================================================================== 321 static inline void setNegativeBridge( const OUString & rBridgeName ) 322 SAL_THROW( () ) 323 { 324 MappingsData & rData = getMappingsData(); 325 MutexGuard aGuard( rData.aNegativeLibsMutex ); 326 rData.aNegativeLibs.insert( rBridgeName ); 327 } 328 //================================================================================================== 329 static inline oslModule loadModule( const OUString & rBridgeName ) 330 SAL_THROW( () ) 331 { 332 sal_Bool bNeg; 333 { 334 MappingsData & rData = getMappingsData(); 335 MutexGuard aGuard( rData.aNegativeLibsMutex ); 336 const t_OUStringSet::const_iterator iFind( rData.aNegativeLibs.find( rBridgeName ) ); 337 bNeg = (iFind != rData.aNegativeLibs.end()); 338 } 339 340 if (! bNeg) 341 { 342 oslModule hModule = cppu::detail::loadModule( rBridgeName ); 343 344 if (hModule) 345 return hModule; 346 347 setNegativeBridge( rBridgeName ); // no load again 348 } 349 return 0; 350 } 351 //================================================================================================== 352 static Mapping loadExternalMapping( 353 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) 354 SAL_THROW( () ) 355 { 356 OSL_ASSERT( rFrom.is() && rTo.is() ); 357 if (rFrom.is() && rTo.is()) 358 { 359 // find proper lib 360 oslModule hModule = 0; 361 OUString aName; 362 363 if (EnvDcp::getTypeName(rFrom.getTypeName()).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) )) 364 hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) ); 365 if (! hModule) 366 hModule = loadModule( aName = getBridgeName( rFrom, rTo, rAddPurpose ) ); 367 if (! hModule) 368 hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) ); 369 370 if (hModule) 371 { 372 OUString aSymbolName( RTL_CONSTASCII_USTRINGPARAM(UNO_EXT_GETMAPPING) ); 373 uno_ext_getMappingFunc fpGetMapFunc = 374 (uno_ext_getMappingFunc)::osl_getFunctionSymbol( 375 hModule, aSymbolName.pData ); 376 377 if (fpGetMapFunc) 378 { 379 Mapping aExt; 380 (*fpGetMapFunc)( (uno_Mapping **)&aExt, rFrom.get(), rTo.get() ); 381 OSL_ASSERT( aExt.is() ); 382 if (aExt.is()) 383 { 384 ::rtl_registerModuleForUnloading( hModule ); 385 return aExt; 386 } 387 } 388 ::osl_unloadModule( hModule ); 389 setNegativeBridge( aName ); 390 } 391 } 392 return Mapping(); 393 } 394 395 //================================================================================================== 396 static Mapping getDirectMapping( 397 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose = OUString() ) 398 SAL_THROW( () ) 399 { 400 OSL_ASSERT( rFrom.is() && rTo.is() ); 401 if (rFrom.is() && rTo.is()) 402 { 403 MappingsData & rData = getMappingsData(); 404 ClearableMutexGuard aGuard( rData.aMappingsMutex ); 405 406 // try to find registered mapping 407 const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find( 408 getMappingName( rFrom, rTo, rAddPurpose ) ) ); 409 410 if (iFind == rData.aName2Entry.end()) 411 { 412 aGuard.clear(); 413 return loadExternalMapping( rFrom, rTo, rAddPurpose ); 414 } 415 else 416 { 417 return Mapping( (*iFind).second->pMapping ); 418 } 419 } 420 return Mapping(); 421 } 422 423 //-------------------------------------------------------------------------------------------------- 424 static inline Mapping createMediateMapping( 425 const Environment & rFrom, const Environment & rTo, 426 const Mapping & rFrom2Uno, const Mapping & rUno2To, 427 const OUString & rAddPurpose ) 428 SAL_THROW( () ) 429 { 430 uno_Mapping * pRet = new uno_Mediate_Mapping( 431 rFrom, rTo, rFrom2Uno, rUno2To, rAddPurpose ); // ref count initially 1 432 uno_registerMapping( 433 &pRet, mediate_free, rFrom.get(), rTo.get(), rAddPurpose.pData ); 434 Mapping aRet( pRet ); 435 (*pRet->release)( pRet ); 436 return aRet; 437 } 438 //================================================================================================== 439 static Mapping getMediateMapping( 440 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) 441 SAL_THROW( () ) 442 { 443 Environment aUno; 444 Mapping aUno2To; 445 446 // backwards: from dest to source of mapping chain 447 448 // connect to uno 449 OUString aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ); 450 if (rTo.getTypeName() == aUnoEnvTypeName) // to is uno 451 { 452 aUno = rTo; 453 // no Uno2To mapping necessary 454 } 455 else 456 { 457 // get registered uno env 458 ::uno_getEnvironment( (uno_Environment **)&aUno, aUnoEnvTypeName.pData, 0 ); 459 460 aUno2To = getDirectMapping( aUno, rTo ); 461 // : uno <-> to 462 if (! aUno2To.is()) 463 return Mapping(); 464 } 465 466 // connect to uno 467 if (rAddPurpose.getLength()) // insert purpose mapping between new ano_uno <-> uno 468 { 469 // create anonymous uno env 470 Environment aAnUno; 471 ::uno_createEnvironment( (uno_Environment **)&aAnUno, aUnoEnvTypeName.pData, 0 ); 472 473 Mapping aAnUno2Uno( getDirectMapping( aAnUno, aUno, rAddPurpose ) ); 474 if (! aAnUno2Uno.is()) 475 return Mapping(); 476 477 if (aUno2To.is()) // to is not uno 478 { 479 // create another purposed mediate mapping 480 aUno2To = createMediateMapping( aAnUno, rTo, aAnUno2Uno, aUno2To, rAddPurpose ); 481 // : ano_uno <-> uno <-> to 482 } 483 else 484 { 485 aUno2To = aAnUno2Uno; 486 // : ano_uno <-> to (i.e., uno) 487 } 488 aUno = aAnUno; 489 } 490 491 Mapping aFrom2Uno( getDirectMapping( rFrom, aUno ) ); 492 if (aFrom2Uno.is() && aUno2To.is()) 493 { 494 return createMediateMapping( rFrom, rTo, aFrom2Uno, aUno2To, rAddPurpose ); 495 // : from <-> some uno ... 496 } 497 498 return Mapping(); 499 } 500 } 501 502 using namespace ::cppu; 503 504 extern "C" 505 { 506 //################################################################################################## 507 void SAL_CALL uno_getMapping( 508 uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo, 509 rtl_uString * pAddPurpose ) 510 SAL_THROW_EXTERN_C() 511 { 512 OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" ); 513 if (*ppMapping) 514 { 515 (*(*ppMapping)->release)( *ppMapping ); 516 *ppMapping = 0; 517 } 518 519 Mapping aRet; 520 Environment aFrom( pFrom ), aTo( pTo ); 521 522 OUString aAddPurpose; 523 if (pAddPurpose) 524 aAddPurpose = pAddPurpose; 525 526 MappingsData & rData = getMappingsData(); 527 528 // try registered mapping 529 { 530 MutexGuard aGuard( rData.aMappingsMutex ); 531 const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find( 532 getMappingName( aFrom, aTo, aAddPurpose ) ) ); 533 if (iFind != rData.aName2Entry.end()) 534 aRet = (*iFind).second->pMapping; 535 } 536 537 // See if an identity mapping does fit. 538 if (!aRet.is() && pFrom == pTo && !aAddPurpose.getLength()) 539 aRet = createIdentityMapping(pFrom); 540 541 if (!aRet.is()) 542 { 543 getCascadeMapping(ppMapping, pFrom, pTo, pAddPurpose); 544 545 if (*ppMapping) 546 return; 547 } 548 549 if (! aRet.is()) // try callback chain 550 { 551 MutexGuard aGuard( rData.aCallbacksMutex ); 552 for ( t_CallbackSet::const_iterator iPos( rData.aCallbacks.begin() ); 553 iPos != rData.aCallbacks.end(); ++iPos ) 554 { 555 (**iPos)( ppMapping, pFrom, pTo, aAddPurpose.pData ); 556 if (*ppMapping) 557 return; 558 } 559 } 560 561 if (! aRet.is()) 562 { 563 aRet = loadExternalMapping( aFrom, aTo, aAddPurpose ); // direct try 564 if (! aRet.is()) 565 aRet = getMediateMapping( aFrom, aTo, aAddPurpose ); // try via uno 566 } 567 568 if (aRet.is()) 569 { 570 (*aRet.get()->acquire)( aRet.get() ); 571 *ppMapping = aRet.get(); 572 } 573 } 574 //################################################################################################## 575 void SAL_CALL uno_getMappingByName( 576 uno_Mapping ** ppMapping, rtl_uString * pFrom, rtl_uString * pTo, 577 rtl_uString * pAddPurpose ) 578 SAL_THROW_EXTERN_C() 579 { 580 OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" ); 581 if (*ppMapping) 582 { 583 (*(*ppMapping)->release)( *ppMapping ); 584 *ppMapping = 0; 585 } 586 587 uno_Environment * pEFrom = 0; 588 uno_getEnvironment( &pEFrom, pFrom, 0 ); 589 OSL_ENSURE( pEFrom, "### cannot get source environment!" ); 590 if (pEFrom) 591 { 592 uno_Environment * pETo = 0; 593 uno_getEnvironment( &pETo, pTo, 0 ); 594 OSL_ENSURE( pETo, "### cannot get target environment!" ); 595 if (pETo) 596 { 597 ::uno_getMapping( ppMapping, pEFrom, pETo, pAddPurpose ); 598 (*pETo->release)( pETo ); 599 } 600 (*pEFrom->release)( pEFrom ); 601 } 602 } 603 604 //################################################################################################## 605 void SAL_CALL uno_registerMapping( 606 uno_Mapping ** ppMapping, uno_freeMappingFunc freeMapping, 607 uno_Environment * pFrom, uno_Environment * pTo, rtl_uString * pAddPurpose ) 608 SAL_THROW_EXTERN_C() 609 { 610 MappingsData & rData = getMappingsData(); 611 ClearableMutexGuard aGuard( rData.aMappingsMutex ); 612 613 const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( *ppMapping ) ); 614 if (iFind == rData.aMapping2Entry.end()) 615 { 616 OUString aMappingName( 617 getMappingName( pFrom, pTo, pAddPurpose ? OUString(pAddPurpose) : OUString() ) ); 618 #if OSL_DEBUG_LEVEL > 1 619 OString cstr( OUStringToOString( aMappingName, RTL_TEXTENCODING_ASCII_US ) ); 620 OSL_TRACE( "> inserting new mapping: %s", cstr.getStr() ); 621 #endif 622 // count initially 1 623 MappingEntry * pEntry = new MappingEntry( *ppMapping, freeMapping, aMappingName ); 624 rData.aName2Entry[ aMappingName ] = pEntry; 625 rData.aMapping2Entry[ *ppMapping ] = pEntry; 626 } 627 else 628 { 629 MappingEntry * pEntry = (*iFind).second; 630 ++pEntry->nRef; 631 632 if (pEntry->pMapping != *ppMapping) // exchange mapping to be registered 633 { 634 (*pEntry->pMapping->acquire)( pEntry->pMapping ); 635 --pEntry->nRef; // correct count; kill mapping to be registered 636 aGuard.clear(); 637 (*freeMapping)( *ppMapping ); 638 *ppMapping = pEntry->pMapping; 639 } 640 } 641 } 642 //################################################################################################## 643 void SAL_CALL uno_revokeMapping( 644 uno_Mapping * pMapping ) 645 SAL_THROW_EXTERN_C() 646 { 647 MappingsData & rData = getMappingsData(); 648 ClearableMutexGuard aGuard( rData.aMappingsMutex ); 649 650 const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( pMapping ) ); 651 OSL_ASSERT( iFind != rData.aMapping2Entry.end() ); 652 MappingEntry * pEntry = (*iFind).second; 653 if (! --pEntry->nRef) 654 { 655 rData.aMapping2Entry.erase( pEntry->pMapping ); 656 rData.aName2Entry.erase( pEntry->aMappingName ); 657 aGuard.clear(); 658 #if OSL_DEBUG_LEVEL > 1 659 OString cstr( OUStringToOString( pEntry->aMappingName, RTL_TEXTENCODING_ASCII_US ) ); 660 OSL_TRACE( "> revoking mapping %s", cstr.getStr() ); 661 #endif 662 (*pEntry->freeMapping)( pEntry->pMapping ); 663 delete pEntry; 664 } 665 } 666 667 //################################################################################################## 668 void SAL_CALL uno_registerMappingCallback( 669 uno_getMappingFunc pCallback ) 670 SAL_THROW_EXTERN_C() 671 { 672 OSL_ENSURE( pCallback, "### null ptr!" ); 673 MappingsData & rData = getMappingsData(); 674 MutexGuard aGuard( rData.aCallbacksMutex ); 675 rData.aCallbacks.insert( pCallback ); 676 } 677 //################################################################################################## 678 void SAL_CALL uno_revokeMappingCallback( 679 uno_getMappingFunc pCallback ) 680 SAL_THROW_EXTERN_C() 681 { 682 OSL_ENSURE( pCallback, "### null ptr!" ); 683 MappingsData & rData = getMappingsData(); 684 MutexGuard aGuard( rData.aCallbacksMutex ); 685 rData.aCallbacks.erase( pCallback ); 686 } 687 } // extern "C" 688 689