File: | cppu/source/uno/lbmap.cxx |
Location: | line 640, column 9 |
Description: | Dereference of null pointer (loaded from variable 'ppMapping') |
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 | |
47 | using namespace std; |
48 | using namespace osl; |
49 | using namespace com::sun::star::uno; |
50 | using ::rtl::OUString; |
51 | using ::rtl::OUStringBuffer; |
52 | using ::rtl::OUStringToOString; |
53 | using ::rtl::OString; |
54 | |
55 | namespace cppu |
56 | { |
57 | |
58 | class Mapping |
59 | { |
60 | uno_Mapping * _pMapping; |
61 | |
62 | public: |
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 | //__________________________________________________________________________________________________ |
75 | inline Mapping::Mapping( uno_Mapping * pMapping ) SAL_THROW(()) |
76 | : _pMapping( pMapping ) |
77 | { |
78 | if (_pMapping) |
79 | (*_pMapping->acquire)( _pMapping ); |
80 | } |
81 | //__________________________________________________________________________________________________ |
82 | inline Mapping::Mapping( const Mapping & rMapping ) SAL_THROW(()) |
83 | : _pMapping( rMapping._pMapping ) |
84 | { |
85 | if (_pMapping) |
86 | (*_pMapping->acquire)( _pMapping ); |
87 | } |
88 | //__________________________________________________________________________________________________ |
89 | inline Mapping::~Mapping() SAL_THROW(()) |
90 | { |
91 | if (_pMapping) |
92 | (*_pMapping->release)( _pMapping ); |
93 | } |
94 | //__________________________________________________________________________________________________ |
95 | inline 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 | //================================================================================================== |
106 | struct 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 | //-------------------------------------------------------------------------------------------------- |
124 | struct 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 | //-------------------------------------------------------------------------------------------------- |
130 | struct 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 | |
136 | typedef boost::unordered_map< |
137 | OUString, MappingEntry *, FctOUStringHash, equal_to< OUString > > t_OUString2Entry; |
138 | typedef boost::unordered_map< |
139 | uno_Mapping *, MappingEntry *, FctPtrHash, equal_to< uno_Mapping * > > t_Mapping2Entry; |
140 | |
141 | typedef set< uno_getMappingFunc > t_CallbackSet; |
142 | typedef set< OUString > t_OUStringSet; |
143 | |
144 | //================================================================================================== |
145 | struct 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 | //-------------------------------------------------------------------------------------------------- |
158 | static 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 | */ |
178 | struct 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 | }; |
196 | extern "C" |
197 | { |
198 | //-------------------------------------------------------------------------------------------------- |
199 | static void SAL_CALL mediate_free( uno_Mapping * pMapping ) |
200 | SAL_THROW(()) |
201 | { |
202 | delete static_cast< uno_Mediate_Mapping * >( pMapping ); |
203 | } |
204 | //-------------------------------------------------------------------------------------------------- |
205 | static 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 | //-------------------------------------------------------------------------------------------------- |
219 | static 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 | //-------------------------------------------------------------------------------------------------- |
229 | static 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 | //__________________________________________________________________________________________________ |
265 | uno_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 | //================================================================================================== |
283 | static 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 | //================================================================================================== |
301 | static 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 | //================================================================================================== |
317 | static 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 | |
327 | static 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 | |
347 | static 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 | //================================================================================================== |
373 | static 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 | //================================================================================================== |
455 | static 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 | //-------------------------------------------------------------------------------------------------- |
483 | static 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 | //================================================================================================== |
498 | static 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 | |
561 | using namespace ::cppu; |
562 | |
563 | extern "C" |
564 | { |
565 | //################################################################################################## |
566 | void 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 | //################################################################################################## |
634 | void 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 | //################################################################################################## |
664 | CPPU_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 | //################################################################################################## |
702 | CPPU_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 | //################################################################################################## |
727 | CPPU_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 | //################################################################################################## |
737 | CPPU_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: */ |