File: | home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx |
Warning: | line 1001, column 31 Array access results in a null pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | #ifdef DISABLE_DYNLOADING | |||
21 | #include <config_java.h> | |||
22 | #endif | |||
23 | ||||
24 | #include <cppu/EnvDcp.hxx> | |||
25 | ||||
26 | #include <sal/log.hxx> | |||
27 | #include <osl/diagnose.h> | |||
28 | #include <osl/interlck.h> | |||
29 | #include <osl/mutex.hxx> | |||
30 | #include <osl/module.hxx> | |||
31 | #include <osl/process.h> | |||
32 | #include <rtl/process.h> | |||
33 | #include <rtl/string.hxx> | |||
34 | #include <rtl/ustring.hxx> | |||
35 | #include <rtl/ustrbuf.hxx> | |||
36 | #include <rtl/instance.hxx> | |||
37 | #include <typelib/typedescription.h> | |||
38 | #include <uno/dispatcher.h> | |||
39 | #include <uno/environment.h> | |||
40 | #include <uno/lbnames.h> | |||
41 | #include "prim.hxx" | |||
42 | #include "loadmodule.hxx" | |||
43 | ||||
44 | #include <unordered_map> | |||
45 | #include <vector> | |||
46 | #include <stdio.h> | |||
47 | ||||
48 | ||||
49 | namespace | |||
50 | { | |||
51 | ||||
52 | ||||
53 | bool td_equals( typelib_InterfaceTypeDescription const * pTD1, | |||
54 | typelib_InterfaceTypeDescription const * pTD2 ) | |||
55 | { | |||
56 | return (pTD1 == pTD2 || | |||
57 | (pTD1->aBase.pTypeName->length == pTD2->aBase.pTypeName->length && | |||
58 | ::rtl_ustr_compare( | |||
59 | pTD1->aBase.pTypeName->buffer, | |||
60 | pTD2->aBase.pTypeName->buffer ) == 0)); | |||
61 | } | |||
62 | ||||
63 | struct uno_DefaultEnvironment; | |||
64 | ||||
65 | ||||
66 | struct InterfaceEntry | |||
67 | { | |||
68 | sal_Int32 refCount; | |||
69 | void * pInterface; | |||
70 | uno_freeProxyFunc fpFreeProxy; | |||
71 | typelib_InterfaceTypeDescription * pTypeDescr; | |||
72 | }; | |||
73 | ||||
74 | struct ObjectEntry | |||
75 | { | |||
76 | OUString oid; | |||
77 | sal_Int32 nRef; | |||
78 | std::vector< InterfaceEntry > aInterfaces; | |||
79 | bool mixedObject; | |||
80 | ||||
81 | explicit ObjectEntry( const OUString & rOId_ ); | |||
82 | ||||
83 | void append( | |||
84 | uno_DefaultEnvironment * pEnv, | |||
85 | void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr, | |||
86 | uno_freeProxyFunc fpFreeProxy ); | |||
87 | InterfaceEntry * find( | |||
88 | typelib_InterfaceTypeDescription * pTypeDescr ); | |||
89 | sal_Int32 find( void const * iface_ptr, std::size_t pos ) const; | |||
90 | }; | |||
91 | ||||
92 | ||||
93 | struct FctPtrHash | |||
94 | { | |||
95 | std::size_t operator () ( const void * pKey ) const | |||
96 | { return reinterpret_cast< std::size_t>( pKey ); } | |||
97 | }; | |||
98 | ||||
99 | ||||
100 | // mapping from environment name to environment | |||
101 | typedef std::unordered_map< | |||
102 | OUString, uno_Environment * > OUString2EnvironmentMap; | |||
103 | ||||
104 | // mapping from ptr to object entry | |||
105 | typedef std::unordered_map< | |||
106 | void *, ObjectEntry *, FctPtrHash > Ptr2ObjectMap; | |||
107 | // mapping from oid to object entry | |||
108 | typedef std::unordered_map< | |||
109 | OUString, ObjectEntry * > OId2ObjectMap; | |||
110 | ||||
111 | struct EnvironmentsData | |||
112 | { | |||
113 | ::osl::Mutex mutex; | |||
114 | OUString2EnvironmentMap aName2EnvMap; | |||
115 | ||||
116 | EnvironmentsData() : isDisposing(false) {} | |||
117 | ~EnvironmentsData(); | |||
118 | ||||
119 | void getEnvironment( | |||
120 | uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext ); | |||
121 | void registerEnvironment( uno_Environment ** ppEnv ); | |||
122 | void getRegisteredEnvironments( | |||
123 | uno_Environment *** pppEnvs, sal_Int32 * pnLen, | |||
124 | uno_memAlloc memAlloc, const OUString & rEnvDcp ); | |||
125 | ||||
126 | bool isDisposing; | |||
127 | }; | |||
128 | ||||
129 | struct theEnvironmentsData : public rtl::Static< EnvironmentsData, theEnvironmentsData > {}; | |||
130 | ||||
131 | struct uno_DefaultEnvironment : public uno_ExtEnvironment | |||
132 | { | |||
133 | sal_Int32 nRef; | |||
134 | sal_Int32 nWeakRef; | |||
135 | ||||
136 | ::osl::Mutex mutex; | |||
137 | Ptr2ObjectMap aPtr2ObjectMap; | |||
138 | OId2ObjectMap aOId2ObjectMap; | |||
139 | ||||
140 | uno_DefaultEnvironment( | |||
141 | const OUString & rEnvDcp_, void * pContext_ ); | |||
142 | ~uno_DefaultEnvironment(); | |||
143 | }; | |||
144 | ||||
145 | ||||
146 | ObjectEntry::ObjectEntry( OUString const & rOId_ ) | |||
147 | : oid( rOId_ ), | |||
148 | nRef( 0 ), | |||
149 | mixedObject( false ) | |||
150 | { | |||
151 | aInterfaces.reserve( 2 ); | |||
152 | } | |||
153 | ||||
154 | ||||
155 | void ObjectEntry::append( | |||
156 | uno_DefaultEnvironment * pEnv, | |||
157 | void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr, | |||
158 | uno_freeProxyFunc fpFreeProxy ) | |||
159 | { | |||
160 | InterfaceEntry aNewEntry; | |||
161 | if (! fpFreeProxy) | |||
162 | (*pEnv->acquireInterface)( pEnv, pInterface ); | |||
163 | aNewEntry.refCount = 1; | |||
164 | aNewEntry.pInterface = pInterface; | |||
165 | aNewEntry.fpFreeProxy = fpFreeProxy; | |||
166 | typelib_typedescription_acquire( &pTypeDescr->aBase ); | |||
167 | aNewEntry.pTypeDescr = pTypeDescr; | |||
168 | ||||
169 | std::pair< Ptr2ObjectMap::iterator, bool > i( | |||
170 | pEnv->aPtr2ObjectMap.emplace( pInterface, this ) ); | |||
171 | SAL_WARN_IF(do { if (true && (!i.second && (find(pInterface , 0) == -1 || i.first->second != this))) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "cppu")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "map already contains " << i.first->second << " != " << this << " for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "map already contains " << i.first->second << " != " << this << " for " << pInterface ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu" ), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
172 | !i.second && (find(pInterface, 0) == -1 || i.first->second != this),do { if (true && (!i.second && (find(pInterface , 0) == -1 || i.first->second != this))) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "cppu")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "map already contains " << i.first->second << " != " << this << " for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "map already contains " << i.first->second << " != " << this << " for " << pInterface ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu" ), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
173 | "cppu",do { if (true && (!i.second && (find(pInterface , 0) == -1 || i.first->second != this))) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "cppu")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "map already contains " << i.first->second << " != " << this << " for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "map already contains " << i.first->second << " != " << this << " for " << pInterface ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu" ), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
174 | "map already contains " << i.first->second << " != " << this << " for "do { if (true && (!i.second && (find(pInterface , 0) == -1 || i.first->second != this))) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "cppu")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "map already contains " << i.first->second << " != " << this << " for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "map already contains " << i.first->second << " != " << this << " for " << pInterface ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu" ), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
175 | << pInterface)do { if (true && (!i.second && (find(pInterface , 0) == -1 || i.first->second != this))) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "cppu")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "map already contains " << i.first->second << " != " << this << " for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "map already contains " << i.first->second << " != " << this << " for " << pInterface ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu" ), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "map already contains " << i.first ->second << " != " << this << " for " << pInterface), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "map already contains " << i.first->second << " != " << this << " for " << pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "175" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
176 | aInterfaces.push_back( aNewEntry ); | |||
177 | } | |||
178 | ||||
179 | ||||
180 | InterfaceEntry * ObjectEntry::find( | |||
181 | typelib_InterfaceTypeDescription * pTypeDescr_ ) | |||
182 | { | |||
183 | OSL_ASSERT( ! aInterfaces.empty() )do { if (true && (!(! aInterfaces.empty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "183" ": "), "OSL_ASSERT: %s", "! aInterfaces.empty()"); } } while (false); | |||
184 | if (aInterfaces.empty()) | |||
185 | return nullptr; | |||
186 | ||||
187 | // shortcut common case: | |||
188 | OUString const & type_name = | |||
189 | OUString::unacquired( &pTypeDescr_->aBase.pTypeName ); | |||
190 | if ( type_name == "com.sun.star.uno.XInterface" ) | |||
191 | { | |||
192 | return aInterfaces.data(); | |||
193 | } | |||
194 | ||||
195 | std::size_t nSize = aInterfaces.size(); | |||
196 | for ( std::size_t nPos = 0; nPos < nSize; ++nPos ) | |||
197 | { | |||
198 | typelib_InterfaceTypeDescription * pITD = | |||
199 | aInterfaces[ nPos ].pTypeDescr; | |||
200 | while (pITD) | |||
201 | { | |||
202 | if (td_equals( pITD, pTypeDescr_ )) | |||
203 | return &aInterfaces[ nPos ]; | |||
204 | pITD = pITD->pBaseTypeDescription; | |||
205 | } | |||
206 | } | |||
207 | return nullptr; | |||
208 | } | |||
209 | ||||
210 | ||||
211 | sal_Int32 ObjectEntry::find( | |||
212 | void const * iface_ptr, std::size_t pos ) const | |||
213 | { | |||
214 | std::size_t size = aInterfaces.size(); | |||
215 | for ( ; pos < size; ++pos ) | |||
216 | { | |||
217 | if (aInterfaces[ pos ].pInterface == iface_ptr) | |||
218 | return pos; | |||
219 | } | |||
220 | return -1; | |||
221 | } | |||
222 | ||||
223 | extern "C" | |||
224 | { | |||
225 | ||||
226 | ||||
227 | static void defenv_registerInterface( | |||
228 | uno_ExtEnvironment * pEnv, void ** ppInterface, | |||
229 | rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr ) | |||
230 | { | |||
231 | OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" )do { if (true && (!(pEnv && ppInterface && pOId && pTypeDescr))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "231" ": "), "%s", "### null ptr!"); } } while (false); | |||
232 | OUString const & rOId = OUString::unacquired( &pOId ); | |||
233 | ||||
234 | uno_DefaultEnvironment * that = | |||
235 | static_cast< uno_DefaultEnvironment * >( pEnv ); | |||
236 | ::osl::ClearableMutexGuard guard( that->mutex ); | |||
237 | ||||
238 | // try to insert dummy 0: | |||
239 | std::pair<OId2ObjectMap::iterator, bool> const insertion( | |||
240 | that->aOId2ObjectMap.emplace( rOId, nullptr ) ); | |||
241 | if (insertion.second) | |||
242 | { | |||
243 | ObjectEntry * pOEntry = new ObjectEntry( rOId ); | |||
244 | insertion.first->second = pOEntry; | |||
245 | ++pOEntry->nRef; // another register call on object | |||
246 | pOEntry->append( that, *ppInterface, pTypeDescr, nullptr ); | |||
247 | } | |||
248 | else // object entry exists | |||
249 | { | |||
250 | ObjectEntry * pOEntry = insertion.first->second; | |||
251 | ++pOEntry->nRef; // another register call on object | |||
252 | InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr ); | |||
253 | ||||
254 | if (pIEntry) // type entry exists | |||
255 | { | |||
256 | ++pIEntry->refCount; | |||
257 | if (pIEntry->pInterface != *ppInterface) | |||
258 | { | |||
259 | void * pInterface = pIEntry->pInterface; | |||
260 | (*pEnv->acquireInterface)( pEnv, pInterface ); | |||
261 | guard.clear(); | |||
262 | (*pEnv->releaseInterface)( pEnv, *ppInterface ); | |||
263 | *ppInterface = pInterface; | |||
264 | } | |||
265 | } | |||
266 | else | |||
267 | { | |||
268 | pOEntry->append( that, *ppInterface, pTypeDescr, nullptr ); | |||
269 | } | |||
270 | } | |||
271 | } | |||
272 | ||||
273 | ||||
274 | static void defenv_registerProxyInterface( | |||
275 | uno_ExtEnvironment * pEnv, void ** ppInterface, uno_freeProxyFunc freeProxy, | |||
276 | rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr ) | |||
277 | { | |||
278 | OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr && freeProxy,do { if (true && (!(pEnv && ppInterface && pOId && pTypeDescr && freeProxy))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "279" ": "), "%s", "### null ptr!"); } } while (false) | |||
279 | "### null ptr!" )do { if (true && (!(pEnv && ppInterface && pOId && pTypeDescr && freeProxy))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "279" ": "), "%s", "### null ptr!"); } } while (false); | |||
280 | OUString const & rOId = OUString::unacquired( &pOId ); | |||
281 | ||||
282 | uno_DefaultEnvironment * that = | |||
283 | static_cast< uno_DefaultEnvironment * >( pEnv ); | |||
284 | ::osl::ClearableMutexGuard guard( that->mutex ); | |||
285 | ||||
286 | // try to insert dummy 0: | |||
287 | std::pair<OId2ObjectMap::iterator, bool> const insertion( | |||
288 | that->aOId2ObjectMap.emplace( rOId, nullptr ) ); | |||
289 | if (insertion.second) | |||
290 | { | |||
291 | ObjectEntry * pOEntry = new ObjectEntry( rOId ); | |||
292 | insertion.first->second = pOEntry; | |||
293 | ++pOEntry->nRef; // another register call on object | |||
294 | pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy ); | |||
295 | } | |||
296 | else // object entry exists | |||
297 | { | |||
298 | ObjectEntry * pOEntry = insertion.first->second; | |||
299 | ||||
300 | // first registration was an original, then registerProxyInterface(): | |||
301 | pOEntry->mixedObject |= | |||
302 | (!pOEntry->aInterfaces.empty() && | |||
303 | pOEntry->aInterfaces[ 0 ].fpFreeProxy == nullptr); | |||
304 | ||||
305 | ++pOEntry->nRef; // another register call on object | |||
306 | InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr ); | |||
307 | ||||
308 | if (pIEntry) // type entry exists | |||
309 | { | |||
310 | if (pIEntry->pInterface == *ppInterface) | |||
311 | { | |||
312 | ++pIEntry->refCount; | |||
313 | } | |||
314 | else | |||
315 | { | |||
316 | void * pInterface = pIEntry->pInterface; | |||
317 | (*pEnv->acquireInterface)( pEnv, pInterface ); | |||
318 | --pOEntry->nRef; // manual revoke of proxy to be freed | |||
319 | guard.clear(); | |||
320 | (*freeProxy)( pEnv, *ppInterface ); | |||
321 | *ppInterface = pInterface; | |||
322 | } | |||
323 | } | |||
324 | else | |||
325 | { | |||
326 | pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy ); | |||
327 | } | |||
328 | } | |||
329 | } | |||
330 | ||||
331 | ||||
332 | static void s_stub_defenv_revokeInterface(va_list * pParam) | |||
333 | { | |||
334 | uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *)__builtin_va_arg(*pParam, uno_ExtEnvironment *); | |||
335 | void * pInterface = va_arg(*pParam, void *)__builtin_va_arg(*pParam, void *); | |||
336 | ||||
337 | OSL_ENSURE( pEnv && pInterface, "### null ptr!" )do { if (true && (!(pEnv && pInterface))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "337" ": "), "%s", "### null ptr!"); } } while (false); | |||
338 | uno_DefaultEnvironment * that = | |||
339 | static_cast< uno_DefaultEnvironment * >( pEnv ); | |||
340 | ::osl::ClearableMutexGuard guard( that->mutex ); | |||
341 | ||||
342 | Ptr2ObjectMap::const_iterator const iFind( | |||
343 | that->aPtr2ObjectMap.find( pInterface ) ); | |||
344 | OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() )do { if (true && (!(iFind != that->aPtr2ObjectMap. end()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ( "legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "344" ": "), "OSL_ASSERT: %s", "iFind != that->aPtr2ObjectMap.end()" ); } } while (false); | |||
345 | ObjectEntry * pOEntry = iFind->second; | |||
346 | if (! --pOEntry->nRef) | |||
347 | { | |||
348 | // cleanup maps | |||
349 | that->aOId2ObjectMap.erase( pOEntry->oid ); | |||
350 | sal_Int32 nPos; | |||
351 | for ( nPos = pOEntry->aInterfaces.size(); nPos--; ) | |||
352 | { | |||
353 | that->aPtr2ObjectMap.erase( pOEntry->aInterfaces[nPos].pInterface ); | |||
354 | } | |||
355 | ||||
356 | // the last proxy interface of the environment might kill this | |||
357 | // environment, because of releasing its language binding!!! | |||
358 | guard.clear(); | |||
359 | ||||
360 | // release interfaces | |||
361 | for ( nPos = pOEntry->aInterfaces.size(); nPos--; ) | |||
362 | { | |||
363 | InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos]; | |||
364 | typelib_typedescription_release( &rEntry.pTypeDescr->aBase ); | |||
365 | if (rEntry.fpFreeProxy) // is proxy or used interface? | |||
366 | { | |||
367 | (*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface ); | |||
368 | } | |||
369 | else | |||
370 | { | |||
371 | (*pEnv->releaseInterface)( pEnv, rEntry.pInterface ); | |||
372 | } | |||
373 | } | |||
374 | ||||
375 | delete pOEntry; | |||
376 | } | |||
377 | else if (pOEntry->mixedObject) | |||
378 | { | |||
379 | OSL_ASSERT( !pOEntry->aInterfaces.empty() &&do { if (true && (!(!pOEntry->aInterfaces.empty() && pOEntry->aInterfaces[ 0 ].fpFreeProxy == nullptr))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "380" ": "), "OSL_ASSERT: %s", "!pOEntry->aInterfaces.empty() && pOEntry->aInterfaces[ 0 ].fpFreeProxy == nullptr" ); } } while (false) | |||
380 | pOEntry->aInterfaces[ 0 ].fpFreeProxy == nullptr )do { if (true && (!(!pOEntry->aInterfaces.empty() && pOEntry->aInterfaces[ 0 ].fpFreeProxy == nullptr))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "380" ": "), "OSL_ASSERT: %s", "!pOEntry->aInterfaces.empty() && pOEntry->aInterfaces[ 0 ].fpFreeProxy == nullptr" ); } } while (false); | |||
381 | ||||
382 | sal_Int32 index = pOEntry->find( pInterface, 1 ); | |||
383 | OSL_ASSERT( index > 0 )do { if (true && (!(index > 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "383" ": "), "OSL_ASSERT: %s", "index > 0"); } } while (false); | |||
384 | if (index > 0) | |||
385 | { | |||
386 | InterfaceEntry & entry = pOEntry->aInterfaces[ index ]; | |||
387 | OSL_ASSERT( entry.pInterface == pInterface )do { if (true && (!(entry.pInterface == pInterface))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "387" ": "), "OSL_ASSERT: %s", "entry.pInterface == pInterface" ); } } while (false); | |||
388 | if (entry.fpFreeProxy != nullptr) | |||
389 | { | |||
390 | --entry.refCount; | |||
391 | if (entry.refCount == 0) | |||
392 | { | |||
393 | uno_freeProxyFunc fpFreeProxy = entry.fpFreeProxy; | |||
394 | typelib_TypeDescription * pTypeDescr = | |||
395 | reinterpret_cast< typelib_TypeDescription * >( | |||
396 | entry.pTypeDescr ); | |||
397 | ||||
398 | pOEntry->aInterfaces.erase( | |||
399 | pOEntry->aInterfaces.begin() + index ); | |||
400 | if (pOEntry->find( pInterface, index ) < 0) | |||
401 | { | |||
402 | // proxy ptr not registered for another interface: | |||
403 | // remove from ptr map | |||
404 | std::size_t erased = | |||
405 | that->aPtr2ObjectMap.erase( pInterface ); | |||
406 | OSL_ASSERT( erased == 1 )do { if (true && (!(erased == 1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "406" ": "), "OSL_ASSERT: %s", "erased == 1"); } } while (false); | |||
407 | } | |||
408 | ||||
409 | guard.clear(); | |||
410 | ||||
411 | typelib_typedescription_release( pTypeDescr ); | |||
412 | (*fpFreeProxy)( pEnv, pInterface ); | |||
413 | } | |||
414 | } | |||
415 | } | |||
416 | } | |||
417 | } | |||
418 | ||||
419 | static void defenv_revokeInterface(uno_ExtEnvironment * pEnv, void * pInterface) | |||
420 | { | |||
421 | uno_Environment_invoke(&pEnv->aBase, s_stub_defenv_revokeInterface, pEnv, pInterface); | |||
422 | } | |||
423 | ||||
424 | ||||
425 | static void defenv_getObjectIdentifier( | |||
426 | uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface ) | |||
427 | { | |||
428 | OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" )do { if (true && (!(pEnv && ppOId && pInterface ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "428" ": "), "%s", "### null ptr!"); } } while (false); | |||
429 | if (*ppOId) | |||
430 | { | |||
431 | ::rtl_uString_release( *ppOId ); | |||
432 | *ppOId = nullptr; | |||
433 | } | |||
434 | ||||
435 | uno_DefaultEnvironment * that = | |||
436 | static_cast< uno_DefaultEnvironment * >( pEnv ); | |||
437 | ::osl::ClearableMutexGuard guard( that->mutex ); | |||
438 | ||||
439 | Ptr2ObjectMap::const_iterator const iFind( | |||
440 | that->aPtr2ObjectMap.find( pInterface ) ); | |||
441 | if (iFind == that->aPtr2ObjectMap.end()) | |||
442 | { | |||
443 | guard.clear(); | |||
444 | (*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface ); | |||
445 | } | |||
446 | else | |||
447 | { | |||
448 | rtl_uString * hstr = iFind->second->oid.pData; | |||
449 | rtl_uString_acquire( hstr ); | |||
450 | *ppOId = hstr; | |||
451 | } | |||
452 | } | |||
453 | ||||
454 | ||||
455 | static void defenv_getRegisteredInterface( | |||
456 | uno_ExtEnvironment * pEnv, void ** ppInterface, | |||
457 | rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr ) | |||
458 | { | |||
459 | OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" )do { if (true && (!(pEnv && ppInterface && pOId && pTypeDescr))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "459" ": "), "%s", "### null ptr!"); } } while (false); | |||
460 | if (*ppInterface) | |||
461 | { | |||
462 | (*pEnv->releaseInterface)( pEnv, *ppInterface ); | |||
463 | *ppInterface = nullptr; | |||
464 | } | |||
465 | ||||
466 | OUString const & rOId = OUString::unacquired( &pOId ); | |||
467 | uno_DefaultEnvironment * that = | |||
468 | static_cast< uno_DefaultEnvironment * >( pEnv ); | |||
469 | ::osl::MutexGuard guard( that->mutex ); | |||
470 | ||||
471 | OId2ObjectMap::const_iterator const iFind | |||
472 | ( that->aOId2ObjectMap.find( rOId ) ); | |||
473 | if (iFind != that->aOId2ObjectMap.end()) | |||
474 | { | |||
475 | InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr ); | |||
476 | if (pIEntry) | |||
477 | { | |||
478 | (*pEnv->acquireInterface)( pEnv, pIEntry->pInterface ); | |||
479 | *ppInterface = pIEntry->pInterface; | |||
480 | } | |||
481 | } | |||
482 | } | |||
483 | ||||
484 | ||||
485 | static void defenv_getRegisteredInterfaces( | |||
486 | uno_ExtEnvironment * pEnv, void *** pppInterfaces, sal_Int32 * pnLen, | |||
487 | uno_memAlloc memAlloc ) | |||
488 | { | |||
489 | assert(pEnv && pppInterfaces && pnLen && memAlloc && "### null ptr!")(static_cast <bool> (pEnv && pppInterfaces && pnLen && memAlloc && "### null ptr!") ? void (0) : __assert_fail ("pEnv && pppInterfaces && pnLen && memAlloc && \"### null ptr!\"" , "/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" , 489, __extension__ __PRETTY_FUNCTION__)); | |||
490 | uno_DefaultEnvironment * that = | |||
491 | static_cast< uno_DefaultEnvironment * >( pEnv ); | |||
492 | ::osl::MutexGuard guard( that->mutex ); | |||
493 | ||||
494 | sal_Int32 nLen = that->aPtr2ObjectMap.size(); | |||
495 | sal_Int32 nPos = 0; | |||
496 | void ** ppInterfaces = static_cast<void **>((*memAlloc)( nLen * sizeof (void *) )); | |||
497 | ||||
498 | for (const auto& rEntry : that->aPtr2ObjectMap) | |||
499 | { | |||
500 | ppInterfaces[nPos] = rEntry.first; | |||
501 | (*pEnv->acquireInterface)( pEnv, ppInterfaces[nPos] ); | |||
502 | nPos++; | |||
503 | } | |||
504 | ||||
505 | *pppInterfaces = ppInterfaces; | |||
506 | *pnLen = nLen; | |||
507 | } | |||
508 | ||||
509 | ||||
510 | static void defenv_acquire( uno_Environment * pEnv ) | |||
511 | { | |||
512 | uno_DefaultEnvironment * that = reinterpret_cast<uno_DefaultEnvironment *>(pEnv); | |||
513 | osl_atomic_increment( &that->nWeakRef )__sync_add_and_fetch((&that->nWeakRef), 1); | |||
514 | osl_atomic_increment( &that->nRef )__sync_add_and_fetch((&that->nRef), 1); | |||
515 | } | |||
516 | ||||
517 | ||||
518 | static void defenv_release( uno_Environment * pEnv ) | |||
519 | { | |||
520 | uno_DefaultEnvironment * that = reinterpret_cast<uno_DefaultEnvironment *>(pEnv); | |||
521 | if (! osl_atomic_decrement( &that->nRef )__sync_sub_and_fetch((&that->nRef), 1)) | |||
522 | { | |||
523 | // invoke dispose callback | |||
524 | if (pEnv->environmentDisposing) | |||
525 | { | |||
526 | (*pEnv->environmentDisposing)( pEnv ); | |||
527 | } | |||
528 | ||||
529 | OSL_ENSURE( that->aOId2ObjectMap.empty(), "### object entries left!" )do { if (true && (!(that->aOId2ObjectMap.empty())) ) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "529" ": "), "%s", "### object entries left!"); } } while (false); | |||
530 | } | |||
531 | // free memory if no weak refs left | |||
532 | if (! osl_atomic_decrement( &that->nWeakRef )__sync_sub_and_fetch((&that->nWeakRef), 1)) | |||
533 | { | |||
534 | delete that; | |||
535 | } | |||
536 | } | |||
537 | ||||
538 | ||||
539 | static void defenv_acquireWeak( uno_Environment * pEnv ) | |||
540 | { | |||
541 | uno_DefaultEnvironment * that = reinterpret_cast<uno_DefaultEnvironment *>(pEnv); | |||
542 | osl_atomic_increment( &that->nWeakRef )__sync_add_and_fetch((&that->nWeakRef), 1); | |||
543 | } | |||
544 | ||||
545 | ||||
546 | static void defenv_releaseWeak( uno_Environment * pEnv ) | |||
547 | { | |||
548 | uno_DefaultEnvironment * that = reinterpret_cast<uno_DefaultEnvironment *>(pEnv); | |||
549 | if (! osl_atomic_decrement( &that->nWeakRef )__sync_sub_and_fetch((&that->nWeakRef), 1)) | |||
550 | { | |||
551 | delete that; | |||
552 | } | |||
553 | } | |||
554 | ||||
555 | ||||
556 | static void defenv_harden( | |||
557 | uno_Environment ** ppHardEnv, uno_Environment * pEnv ) | |||
558 | { | |||
559 | if (*ppHardEnv) | |||
560 | { | |||
561 | (*(*ppHardEnv)->release)( *ppHardEnv ); | |||
562 | *ppHardEnv = nullptr; | |||
563 | } | |||
564 | ||||
565 | EnvironmentsData & rData = theEnvironmentsData::get(); | |||
566 | ||||
567 | if (rData.isDisposing) | |||
568 | return; | |||
569 | ||||
570 | uno_DefaultEnvironment * that = reinterpret_cast<uno_DefaultEnvironment *>(pEnv); | |||
571 | { | |||
572 | ::osl::MutexGuard guard( rData.mutex ); | |||
573 | if (1 == osl_atomic_increment( &that->nRef )__sync_add_and_fetch((&that->nRef), 1)) // is dead | |||
574 | { | |||
575 | that->nRef = 0; | |||
576 | return; | |||
577 | } | |||
578 | } | |||
579 | osl_atomic_increment( &that->nWeakRef )__sync_add_and_fetch((&that->nWeakRef), 1); | |||
580 | *ppHardEnv = pEnv; | |||
581 | } | |||
582 | ||||
583 | ||||
584 | static void defenv_dispose( SAL_UNUSED_PARAMETER__attribute__ ((unused)) uno_Environment * ) | |||
585 | { | |||
586 | } | |||
587 | } | |||
588 | ||||
589 | ||||
590 | uno_DefaultEnvironment::uno_DefaultEnvironment( | |||
591 | const OUString & rEnvDcp_, void * pContext_ ) | |||
592 | : nRef( 0 ), | |||
593 | nWeakRef( 0 ) | |||
594 | { | |||
595 | uno_Environment * that = reinterpret_cast< uno_Environment * >(this); | |||
596 | that->pReserved = nullptr; | |||
597 | // functions | |||
598 | that->acquire = defenv_acquire; | |||
599 | that->release = defenv_release; | |||
600 | that->acquireWeak = defenv_acquireWeak; | |||
601 | that->releaseWeak = defenv_releaseWeak; | |||
602 | that->harden = defenv_harden; | |||
603 | that->dispose = defenv_dispose; | |||
604 | that->pExtEnv = this; | |||
605 | // identifier | |||
606 | ::rtl_uString_acquire( rEnvDcp_.pData ); | |||
607 | that->pTypeName = rEnvDcp_.pData; | |||
608 | that->pContext = pContext_; | |||
609 | ||||
610 | // will be late initialized | |||
611 | that->environmentDisposing = nullptr; | |||
612 | ||||
613 | uno_ExtEnvironment::registerInterface = defenv_registerInterface; | |||
614 | uno_ExtEnvironment::registerProxyInterface = defenv_registerProxyInterface; | |||
615 | uno_ExtEnvironment::revokeInterface = defenv_revokeInterface; | |||
616 | uno_ExtEnvironment::getObjectIdentifier = defenv_getObjectIdentifier; | |||
617 | uno_ExtEnvironment::getRegisteredInterface = defenv_getRegisteredInterface; | |||
618 | uno_ExtEnvironment::getRegisteredInterfaces = | |||
619 | defenv_getRegisteredInterfaces; | |||
620 | ||||
621 | } | |||
622 | ||||
623 | ||||
624 | uno_DefaultEnvironment::~uno_DefaultEnvironment() | |||
625 | { | |||
626 | ::rtl_uString_release( aBase.pTypeName ); | |||
627 | } | |||
628 | ||||
629 | ||||
630 | void writeLine( | |||
631 | void * stream, const char * pLine, const char * pFilter ) | |||
632 | { | |||
633 | if (pFilter && *pFilter) | |||
634 | { | |||
635 | // lookup pFilter in pLine | |||
636 | while (*pLine) | |||
637 | { | |||
638 | if (*pLine == *pFilter) | |||
639 | { | |||
640 | sal_Int32 nPos = 1; | |||
641 | while (pLine[nPos] && pFilter[nPos] == pLine[nPos]) | |||
642 | { | |||
643 | ++nPos; | |||
644 | } | |||
645 | if (! pFilter[nPos]) | |||
646 | { | |||
647 | if (stream) | |||
648 | { | |||
649 | fprintf( static_cast<FILE *>(stream), "%s\n", pLine ); | |||
650 | } | |||
651 | else | |||
652 | { | |||
653 | SAL_WARN("cppu", pLine )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "cppu")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << pLine) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "653" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << pLine), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << pLine; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "653" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << pLine) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "653" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << pLine), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << pLine; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "653" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
654 | } | |||
655 | } | |||
656 | } | |||
657 | ++pLine; | |||
658 | } | |||
659 | } | |||
660 | else | |||
661 | { | |||
662 | if (stream) | |||
663 | { | |||
664 | fprintf( static_cast<FILE *>(stream), "%s\n", pLine ); | |||
665 | } | |||
666 | else | |||
667 | { | |||
668 | fprintf( stderrstderr, "%s\n", pLine ); | |||
669 | } | |||
670 | } | |||
671 | } | |||
672 | ||||
673 | ||||
674 | void writeLine( | |||
675 | void * stream, const OUString & rLine, const char * pFilter ) | |||
676 | { | |||
677 | OString aLine( OUStringToOString( | |||
678 | rLine, RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11)) ) ); | |||
679 | writeLine( stream, aLine.getStr(), pFilter ); | |||
680 | } | |||
681 | ||||
682 | } | |||
683 | ||||
684 | extern "C" void SAL_CALL uno_dumpEnvironment( | |||
685 | void * stream, uno_Environment * pEnv, const char * pFilter ) | |||
686 | SAL_THROW_EXTERN_C()throw () | |||
687 | { | |||
688 | OSL_ENSURE( pEnv, "### null ptr!" )do { if (true && (!(pEnv))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "688" ": "), "%s", "### null ptr!"); } } while (false); | |||
689 | OUStringBuffer buf; | |||
690 | ||||
691 | if (! pEnv->pExtEnv) | |||
692 | { | |||
693 | writeLine( stream, "###################################" | |||
694 | "###########################################", pFilter ); | |||
695 | buf.append( "environment: " ); | |||
696 | buf.append( pEnv->pTypeName ); | |||
697 | writeLine( stream, buf.makeStringAndClear(), pFilter ); | |||
698 | writeLine( stream, "NO INTERFACE INFORMATION AVAILABLE!", pFilter ); | |||
699 | return; | |||
700 | } | |||
701 | ||||
702 | writeLine( stream, "########################################" | |||
703 | "######################################", pFilter ); | |||
704 | buf.append( "environment dump: " ); | |||
705 | buf.append( pEnv->pTypeName ); | |||
706 | writeLine( stream, buf.makeStringAndClear(), pFilter ); | |||
707 | ||||
708 | uno_DefaultEnvironment * that = | |||
709 | reinterpret_cast< uno_DefaultEnvironment * >(pEnv); | |||
710 | ::osl::MutexGuard guard( that->mutex ); | |||
711 | ||||
712 | Ptr2ObjectMap ptr2obj( that->aPtr2ObjectMap ); | |||
713 | for (const auto& rEntry : that->aOId2ObjectMap) | |||
714 | { | |||
715 | ObjectEntry * pOEntry = rEntry.second; | |||
716 | ||||
717 | buf.append( "+ " ); | |||
718 | if (pOEntry->mixedObject) | |||
719 | buf.append( "mixed " ); | |||
720 | buf.append( "object entry: nRef=" ); | |||
721 | buf.append( pOEntry->nRef ); | |||
722 | buf.append( "; oid=\"" ); | |||
723 | buf.append( pOEntry->oid ); | |||
724 | buf.append( '\"' ); | |||
725 | writeLine( stream, buf.makeStringAndClear(), pFilter ); | |||
726 | ||||
727 | for ( std::size_t nPos = 0; | |||
728 | nPos < pOEntry->aInterfaces.size(); ++nPos ) | |||
729 | { | |||
730 | const InterfaceEntry & rIEntry = pOEntry->aInterfaces[nPos]; | |||
731 | ||||
732 | buf.append( " - " ); | |||
733 | buf.append( rIEntry.pTypeDescr->aBase.pTypeName ); | |||
734 | if (rIEntry.fpFreeProxy) | |||
735 | { | |||
736 | buf.append( "; proxy free=0x" ); | |||
737 | buf.append( | |||
738 | reinterpret_cast< sal_IntPtr >(rIEntry.fpFreeProxy), 16 ); | |||
739 | } | |||
740 | else | |||
741 | { | |||
742 | buf.append( "; original" ); | |||
743 | } | |||
744 | buf.append( "; ptr=0x" ); | |||
745 | buf.append( | |||
746 | reinterpret_cast< sal_IntPtr >(rIEntry.pInterface), 16 ); | |||
747 | ||||
748 | if (pOEntry->find( rIEntry.pInterface, nPos + 1 ) < 0) | |||
749 | { | |||
750 | std::size_t erased = ptr2obj.erase( rIEntry.pInterface ); | |||
751 | if (erased != 1) | |||
752 | { | |||
753 | buf.append( " (ptr not found in map!)" ); | |||
754 | } | |||
755 | } | |||
756 | writeLine( stream, buf.makeStringAndClear(), pFilter ); | |||
757 | } | |||
758 | } | |||
759 | if (! ptr2obj.empty()) | |||
760 | writeLine( stream, "ptr map inconsistency!!!", pFilter ); | |||
761 | writeLine( stream, "#####################################" | |||
762 | "#########################################", pFilter ); | |||
763 | } | |||
764 | ||||
765 | ||||
766 | extern "C" void SAL_CALL uno_dumpEnvironmentByName( | |||
767 | void * stream, rtl_uString * pEnvDcp, const char * pFilter ) | |||
768 | SAL_THROW_EXTERN_C()throw () | |||
769 | { | |||
770 | uno_Environment * pEnv = nullptr; | |||
771 | uno_getEnvironment( &pEnv, pEnvDcp, nullptr ); | |||
772 | if (pEnv) | |||
773 | { | |||
774 | ::uno_dumpEnvironment( stream, pEnv, pFilter ); | |||
775 | (*pEnv->release)( pEnv ); | |||
776 | } | |||
777 | else | |||
778 | { | |||
779 | writeLine( | |||
780 | stream, "environment \"" + OUString::unacquired(&pEnvDcp) + "\" does not exist!", | |||
781 | pFilter ); | |||
782 | } | |||
783 | } | |||
784 | ||||
785 | namespace | |||
786 | { | |||
787 | class makeOIdPart | |||
788 | { | |||
789 | private: | |||
790 | OUString m_sOidPart; | |||
791 | public: | |||
792 | makeOIdPart() | |||
793 | { | |||
794 | OUStringBuffer aRet( 64 ); | |||
795 | aRet.append( "];" ); | |||
796 | // pid | |||
797 | oslProcessInfo info; | |||
798 | info.Size = sizeof(oslProcessInfo); | |||
799 | if (::osl_getProcessInfo( nullptr, osl_Process_IDENTIFIER0x0001, &info ) == | |||
800 | osl_Process_E_None) | |||
801 | { | |||
802 | aRet.append( static_cast<sal_Int64>(info.Ident), 16 ); | |||
803 | } | |||
804 | else | |||
805 | { | |||
806 | aRet.append( "unknown process id" ); | |||
807 | } | |||
808 | // good guid | |||
809 | sal_uInt8 ar[16]; | |||
810 | ::rtl_getGlobalProcessId( ar ); | |||
811 | aRet.append( ';' ); | |||
812 | for (unsigned char i : ar) | |||
813 | aRet.append( static_cast<sal_Int32>(i), 16 ); | |||
814 | ||||
815 | m_sOidPart = aRet.makeStringAndClear(); | |||
816 | } | |||
817 | const OUString& getOIdPart() const { return m_sOidPart; } | |||
818 | }; | |||
819 | ||||
820 | class theStaticOIdPart : public rtl::Static<makeOIdPart, theStaticOIdPart> {}; | |||
821 | ||||
822 | const OUString & unoenv_getStaticOIdPart() | |||
823 | { | |||
824 | return theStaticOIdPart::get().getOIdPart(); | |||
825 | } | |||
826 | ||||
827 | } | |||
828 | ||||
829 | extern "C" | |||
830 | { | |||
831 | ||||
832 | ||||
833 | static void unoenv_computeObjectIdentifier( | |||
834 | uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface ) | |||
835 | { | |||
836 | assert(pEnv && ppOId && pInterface && "### null ptr!")(static_cast <bool> (pEnv && ppOId && pInterface && "### null ptr!") ? void (0) : __assert_fail ("pEnv && ppOId && pInterface && \"### null ptr!\"" , "/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" , 836, __extension__ __PRETTY_FUNCTION__)); | |||
837 | if (*ppOId) | |||
838 | { | |||
839 | ::rtl_uString_release( *ppOId ); | |||
840 | *ppOId = nullptr; | |||
841 | } | |||
842 | ||||
843 | uno_Interface * pUnoI = static_cast<uno_Interface *>( | |||
844 | ::cppu::binuno_queryInterface( | |||
845 | pInterface, *typelib_static_type_getByTypeClass( | |||
846 | typelib_TypeClass_INTERFACE ) )); | |||
847 | if (nullptr == pUnoI) | |||
848 | return; | |||
849 | ||||
850 | (*pUnoI->release)( pUnoI ); | |||
851 | // interface | |||
852 | OUStringBuffer oid( 64 ); | |||
853 | oid.append( reinterpret_cast< sal_Int64 >(pUnoI), 16 ); | |||
854 | oid.append( ';' ); | |||
855 | // environment[context] | |||
856 | oid.append( pEnv->aBase.pTypeName ); | |||
857 | oid.append( '[' ); | |||
858 | oid.append( reinterpret_cast< sal_Int64 >( | |||
859 | reinterpret_cast< | |||
860 | uno_Environment * >(pEnv)->pContext ), 16 ); | |||
861 | // process;good guid | |||
862 | oid.append( unoenv_getStaticOIdPart() ); | |||
863 | OUString aStr( oid.makeStringAndClear() ); | |||
864 | *ppOId = aStr.pData; | |||
865 | ::rtl_uString_acquire( *ppOId ); | |||
866 | } | |||
867 | ||||
868 | ||||
869 | static void unoenv_acquireInterface( | |||
870 | SAL_UNUSED_PARAMETER__attribute__ ((unused)) uno_ExtEnvironment *, void * pUnoI_ ) | |||
871 | { | |||
872 | uno_Interface * pUnoI = static_cast< uno_Interface * >(pUnoI_); | |||
873 | (*pUnoI->acquire)( pUnoI ); | |||
874 | } | |||
875 | ||||
876 | ||||
877 | static void unoenv_releaseInterface( | |||
878 | SAL_UNUSED_PARAMETER__attribute__ ((unused)) uno_ExtEnvironment *, void * pUnoI_ ) | |||
879 | { | |||
880 | uno_Interface * pUnoI = static_cast< uno_Interface * >(pUnoI_); | |||
881 | (*pUnoI->release)( pUnoI ); | |||
882 | } | |||
883 | } | |||
884 | ||||
885 | namespace { | |||
886 | ||||
887 | EnvironmentsData::~EnvironmentsData() | |||
888 | { | |||
889 | ::osl::MutexGuard guard( mutex ); | |||
890 | isDisposing = true; | |||
891 | ||||
892 | for ( const auto& rEntry : aName2EnvMap ) | |||
893 | { | |||
894 | uno_Environment * pWeak = rEntry.second; | |||
895 | uno_Environment * pHard = nullptr; | |||
896 | (*pWeak->harden)( &pHard, pWeak ); | |||
897 | (*pWeak->releaseWeak)( pWeak ); | |||
898 | ||||
899 | if (pHard) | |||
900 | { | |||
901 | (*pHard->dispose)( pHard ); // send explicit dispose | |||
902 | (*pHard->release)( pHard ); | |||
903 | } | |||
904 | } | |||
905 | } | |||
906 | ||||
907 | ||||
908 | void EnvironmentsData::getEnvironment( | |||
909 | uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext ) | |||
910 | { | |||
911 | if (*ppEnv) | |||
912 | { | |||
913 | (*(*ppEnv)->release)( *ppEnv ); | |||
914 | *ppEnv = nullptr; | |||
915 | } | |||
916 | ||||
917 | OUString aKey = OUString::number( reinterpret_cast< sal_IntPtr >(pContext) ) + rEnvDcp; | |||
918 | ||||
919 | // try to find registered mapping | |||
920 | OUString2EnvironmentMap::const_iterator const iFind( | |||
921 | aName2EnvMap.find( aKey ) ); | |||
922 | if (iFind != aName2EnvMap.end()) | |||
923 | { | |||
924 | uno_Environment * pWeak = iFind->second; | |||
925 | (*pWeak->harden)( ppEnv, pWeak ); | |||
926 | } | |||
927 | } | |||
928 | ||||
929 | ||||
930 | void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv ) | |||
931 | { | |||
932 | OSL_ENSURE( ppEnv, "### null ptr!" )do { if (true && (!(ppEnv))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "932" ": "), "%s", "### null ptr!"); } } while (false); | |||
933 | uno_Environment * pEnv = *ppEnv; | |||
934 | ||||
935 | OUString aKey = | |||
936 | OUString::number( reinterpret_cast< sal_IntPtr >(pEnv->pContext) ) + | |||
937 | OUString::unacquired(&pEnv->pTypeName); | |||
938 | ||||
939 | // try to find registered environment | |||
940 | OUString2EnvironmentMap::const_iterator const iFind( | |||
941 | aName2EnvMap.find( aKey ) ); | |||
942 | if (iFind == aName2EnvMap.end()) | |||
943 | { | |||
944 | (*pEnv->acquireWeak)( pEnv ); | |||
945 | std::pair< OUString2EnvironmentMap::iterator, bool > insertion ( | |||
946 | aName2EnvMap.emplace( aKey, pEnv ) ); | |||
947 | SAL_WARN_IF( !insertion.second, "cppu", "key " << aKey << " already in env map" )do { if (true && (!insertion.second)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "cppu")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "key " << aKey << " already in env map") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "947" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "key " << aKey << " already in env map" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "key " << aKey << " already in env map" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu") , ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "947" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "key " << aKey << " already in env map" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu" ), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "947" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "key " << aKey << " already in env map" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "key " << aKey << " already in env map" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu") , ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "947" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
948 | } | |||
949 | else | |||
950 | { | |||
951 | uno_Environment * pHard = nullptr; | |||
952 | uno_Environment * pWeak = iFind->second; | |||
953 | (*pWeak->harden)( &pHard, pWeak ); | |||
954 | if (pHard) | |||
955 | { | |||
956 | (*pEnv->release)( pEnv ); | |||
957 | *ppEnv = pHard; | |||
958 | } | |||
959 | else // registered one is dead | |||
960 | { | |||
961 | (*pWeak->releaseWeak)( pWeak ); | |||
962 | (*pEnv->acquireWeak)( pEnv ); | |||
963 | aName2EnvMap[ aKey ] = pEnv; | |||
964 | } | |||
965 | } | |||
966 | } | |||
967 | ||||
968 | ||||
969 | void EnvironmentsData::getRegisteredEnvironments( | |||
970 | uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc, | |||
971 | const OUString & rEnvDcp ) | |||
972 | { | |||
973 | assert(pppEnvs && pnLen && memAlloc && "### null ptr!")(static_cast <bool> (pppEnvs && pnLen && memAlloc && "### null ptr!") ? void (0) : __assert_fail ("pppEnvs && pnLen && memAlloc && \"### null ptr!\"" , "/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" , 973, __extension__ __PRETTY_FUNCTION__)); | |||
974 | ||||
975 | // max size | |||
976 | std::vector<uno_Environment*> aFounds(aName2EnvMap.size()); | |||
977 | sal_Int32 nSize = 0; | |||
978 | ||||
979 | // find matching environment | |||
980 | for ( const auto& rEntry : aName2EnvMap ) | |||
981 | { | |||
982 | uno_Environment * pWeak = rEntry.second; | |||
983 | if (rEnvDcp.isEmpty() || | |||
984 | rEnvDcp == pWeak->pTypeName ) | |||
985 | { | |||
986 | aFounds[nSize] = nullptr; | |||
987 | (*pWeak->harden)( &aFounds[nSize], pWeak ); | |||
988 | if (aFounds[nSize]) | |||
989 | ++nSize; | |||
990 | } | |||
991 | } | |||
992 | ||||
993 | *pnLen = nSize; | |||
994 | if (nSize
| |||
995 | { | |||
996 | *pppEnvs = static_cast<uno_Environment **>((*memAlloc)( | |||
997 | sizeof (uno_Environment *) * nSize )); | |||
998 | OSL_ASSERT( *pppEnvs )do { if (true && (!(*pppEnvs))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "998" ": "), "OSL_ASSERT: %s", "*pppEnvs"); } } while (false ); | |||
999 | while (nSize--) | |||
1000 | { | |||
1001 | (*pppEnvs)[nSize] = aFounds[nSize]; | |||
| ||||
1002 | } | |||
1003 | } | |||
1004 | else | |||
1005 | { | |||
1006 | *pppEnvs = nullptr; | |||
1007 | } | |||
1008 | } | |||
1009 | ||||
1010 | bool loadEnv(OUString const & cLibStem, | |||
1011 | uno_Environment * pEnv) | |||
1012 | { | |||
1013 | #ifdef DISABLE_DYNLOADING | |||
1014 | uno_initEnvironmentFunc fpInit; | |||
1015 | ||||
1016 | if ( cLibStem == CPPU_CURRENT_LANGUAGE_BINDING_NAME"gcc3" "_uno" ) | |||
1017 | fpInit = CPPU_ENV_uno_initEnvironment; | |||
1018 | #if HAVE_FEATURE_JAVA | |||
1019 | else if ( cLibStem == "java_uno" ) | |||
1020 | fpInit = java_uno_initEnvironment; | |||
1021 | #endif | |||
1022 | else | |||
1023 | { | |||
1024 | SAL_INFO("cppu", ": Unhandled env: " << cLibStem)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "cppu")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << ": Unhandled env: " << cLibStem) == 1) { :: sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "1024" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << ": Unhandled env: " << cLibStem ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << ": Unhandled env: " << cLibStem; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "1024" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << ": Unhandled env: " << cLibStem) == 1) { :: sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "1024" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << ": Unhandled env: " << cLibStem ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << ": Unhandled env: " << cLibStem; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("cppu"), ("/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" ":" "1024" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1025 | return false; | |||
1026 | } | |||
1027 | #else | |||
1028 | // late init with some code from matching uno language binding | |||
1029 | // will be unloaded by environment | |||
1030 | osl::Module aMod; | |||
1031 | try { | |||
1032 | bool bMod = cppu::detail::loadModule(aMod, cLibStem); | |||
1033 | if (!bMod) | |||
1034 | return false; | |||
1035 | } | |||
1036 | catch(...) { | |||
1037 | // Catch everything and convert to return false | |||
1038 | return false; | |||
1039 | } | |||
1040 | ||||
1041 | ||||
1042 | uno_initEnvironmentFunc fpInit = reinterpret_cast<uno_initEnvironmentFunc>(aMod.getSymbol(UNO_INIT_ENVIRONMENT"uno_initEnvironment")); | |||
1043 | ||||
1044 | if (!fpInit) | |||
1045 | return false; | |||
1046 | ||||
1047 | aMod.release(); | |||
1048 | #endif | |||
1049 | ||||
1050 | (*fpInit)( pEnv ); // init of environment | |||
1051 | return true; | |||
1052 | } | |||
1053 | ||||
1054 | } | |||
1055 | ||||
1056 | extern "C" | |||
1057 | { | |||
1058 | ||||
1059 | ||||
1060 | static uno_Environment * initDefaultEnvironment( | |||
1061 | const OUString & rEnvDcp, void * pContext ) | |||
1062 | { | |||
1063 | // coverity[leaked_storage : FALSE] - lifetime is controlled by acquire()/release() calls | |||
1064 | uno_Environment * pEnv = &(new uno_DefaultEnvironment( rEnvDcp, pContext ))->aBase; | |||
1065 | (*pEnv->acquire)( pEnv ); | |||
1066 | ||||
1067 | OUString envTypeName = cppu::EnvDcp::getTypeName(rEnvDcp); | |||
1068 | ||||
1069 | // create default environment | |||
1070 | if ( envTypeName == UNO_LB_UNO"uno" ) | |||
1071 | { | |||
1072 | uno_DefaultEnvironment * that = reinterpret_cast<uno_DefaultEnvironment *>(pEnv); | |||
1073 | that->computeObjectIdentifier = unoenv_computeObjectIdentifier; | |||
1074 | that->acquireInterface = unoenv_acquireInterface; | |||
1075 | that->releaseInterface = unoenv_releaseInterface; | |||
1076 | ||||
1077 | OUString envPurpose = cppu::EnvDcp::getPurpose(rEnvDcp); | |||
1078 | if (!envPurpose.isEmpty()) | |||
1079 | { | |||
1080 | OUString libStem( | |||
1081 | envPurpose.copy(envPurpose.lastIndexOf(':') + 1) + "_uno_uno"); | |||
1082 | if(!loadEnv(libStem, pEnv)) | |||
1083 | { | |||
1084 | pEnv->release(pEnv); | |||
1085 | return nullptr; | |||
1086 | } | |||
1087 | } | |||
1088 | } | |||
1089 | else | |||
1090 | { | |||
1091 | // late init with some code from matching uno language binding | |||
1092 | OUString aStr( envTypeName + "_uno" ); | |||
1093 | ||||
1094 | if (!loadEnv(aStr, pEnv)) | |||
1095 | { | |||
1096 | pEnv->release(pEnv); | |||
1097 | return nullptr; | |||
1098 | } | |||
1099 | } | |||
1100 | ||||
1101 | return pEnv; | |||
1102 | } | |||
1103 | ||||
1104 | ||||
1105 | void SAL_CALL uno_createEnvironment( | |||
1106 | uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext ) | |||
1107 | SAL_THROW_EXTERN_C()throw () | |||
1108 | { | |||
1109 | assert(ppEnv && "### null ptr!")(static_cast <bool> (ppEnv && "### null ptr!") ? void (0) : __assert_fail ("ppEnv && \"### null ptr!\"" , "/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" , 1109, __extension__ __PRETTY_FUNCTION__)); | |||
1110 | if (*ppEnv) | |||
1111 | (*(*ppEnv)->release)( *ppEnv ); | |||
1112 | ||||
1113 | OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp ); | |||
1114 | *ppEnv = initDefaultEnvironment( rEnvDcp, pContext ); | |||
1115 | } | |||
1116 | ||||
1117 | void SAL_CALL uno_getEnvironment( | |||
1118 | uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext ) | |||
1119 | SAL_THROW_EXTERN_C()throw () | |||
1120 | { | |||
1121 | assert(ppEnv && "### null ptr!")(static_cast <bool> (ppEnv && "### null ptr!") ? void (0) : __assert_fail ("ppEnv && \"### null ptr!\"" , "/home/maarten/src/libreoffice/core/cppu/source/uno/lbenv.cxx" , 1121, __extension__ __PRETTY_FUNCTION__)); | |||
1122 | OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp ); | |||
1123 | ||||
1124 | EnvironmentsData & rData = theEnvironmentsData::get(); | |||
1125 | ||||
1126 | ::osl::MutexGuard guard( rData.mutex ); | |||
1127 | rData.getEnvironment( ppEnv, rEnvDcp, pContext ); | |||
1128 | if (! *ppEnv) | |||
1129 | { | |||
1130 | *ppEnv = initDefaultEnvironment( rEnvDcp, pContext ); | |||
1131 | if (*ppEnv) | |||
1132 | { | |||
1133 | // register new environment: | |||
1134 | rData.registerEnvironment( ppEnv ); | |||
1135 | } | |||
1136 | } | |||
1137 | } | |||
1138 | ||||
1139 | void SAL_CALL uno_getRegisteredEnvironments( | |||
1140 | uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc, | |||
1141 | rtl_uString * pEnvDcp ) | |||
1142 | SAL_THROW_EXTERN_C()throw () | |||
1143 | { | |||
1144 | EnvironmentsData & rData = theEnvironmentsData::get(); | |||
1145 | ||||
1146 | ::osl::MutexGuard guard( rData.mutex ); | |||
1147 | rData.getRegisteredEnvironments( | |||
1148 | pppEnvs, pnLen, memAlloc, | |||
1149 | (pEnvDcp ? OUString(pEnvDcp) : OUString()) ); | |||
| ||||
1150 | } | |||
1151 | ||||
1152 | } // extern "C" | |||
1153 | ||||
1154 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |