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