Bug Summary

File:cppu/source/uno/lbmap.cxx
Location:line 640, column 9
Description:Dereference of null pointer (loaded from variable 'ppMapping')

Annotated Source Code

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