Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "rtl/uuid.h"
22 : #include "osl/thread.h"
23 : #include "osl/mutex.hxx"
24 :
25 : #include "uno/environment.hxx"
26 : #include "uno/mapping.hxx"
27 : #include "uno/lbnames.h"
28 : #include "typelib/typedescription.h"
29 :
30 : #include "current.hxx"
31 :
32 :
33 : using namespace ::osl;
34 : using namespace ::rtl;
35 : using namespace ::cppu;
36 : using namespace ::com::sun::star::uno;
37 :
38 : namespace cppu
39 : {
40 :
41 1108 : static typelib_InterfaceTypeDescription * get_type_XCurrentContext()
42 : {
43 : static typelib_InterfaceTypeDescription * s_type_XCurrentContext = 0;
44 1108 : if (0 == s_type_XCurrentContext)
45 : {
46 87 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
47 87 : if (0 == s_type_XCurrentContext)
48 : {
49 87 : OUString sTypeName("com.sun.star.uno.XCurrentContext");
50 87 : typelib_InterfaceTypeDescription * pTD = 0;
51 87 : typelib_TypeDescriptionReference * pMembers[1] = { 0 };
52 174 : OUString sMethodName0("com.sun.star.uno.XCurrentContext::getValueByName");
53 : typelib_typedescriptionreference_new(
54 : &pMembers[0],
55 : typelib_TypeClass_INTERFACE_METHOD,
56 87 : sMethodName0.pData );
57 : typelib_typedescription_newInterface(
58 : &pTD,
59 : sTypeName.pData, 0x00000000, 0x0000, 0x0000, 0x00000000, 0x00000000,
60 87 : * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ),
61 : 1,
62 87 : pMembers );
63 :
64 87 : typelib_typedescription_register( (typelib_TypeDescription**)&pTD );
65 87 : typelib_typedescriptionreference_release( pMembers[0] );
66 :
67 87 : typelib_InterfaceMethodTypeDescription * pMethod = 0;
68 : typelib_Parameter_Init aParameters[1];
69 174 : OUString sParamName0("Name");
70 174 : OUString sParamType0("string");
71 87 : aParameters[0].pParamName = sParamName0.pData;
72 87 : aParameters[0].eTypeClass = typelib_TypeClass_STRING;
73 87 : aParameters[0].pTypeName = sParamType0.pData;
74 87 : aParameters[0].bIn = sal_True;
75 87 : aParameters[0].bOut = sal_False;
76 : rtl_uString * pExceptions[1];
77 174 : OUString sExceptionName0("com.sun.star.uno.RuntimeException");
78 87 : pExceptions[0] = sExceptionName0.pData;
79 174 : OUString sReturnType0("any");
80 : typelib_typedescription_newInterfaceMethod(
81 : &pMethod,
82 : 3, sal_False,
83 : sMethodName0.pData,
84 : typelib_TypeClass_ANY, sReturnType0.pData,
85 87 : 1, aParameters, 1, pExceptions );
86 87 : typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
87 87 : typelib_typedescription_release( (typelib_TypeDescription*)pMethod );
88 : // another static ref:
89 : ++reinterpret_cast< typelib_TypeDescription * >( pTD )->
90 87 : nStaticRefCount;
91 174 : s_type_XCurrentContext = pTD;
92 87 : }
93 : }
94 1108 : return s_type_XCurrentContext;
95 : }
96 :
97 : //##################################################################################################
98 :
99 : //==================================================================================================
100 : class ThreadKey
101 : {
102 : sal_Bool _bInit;
103 : oslThreadKey _hThreadKey;
104 : oslThreadKeyCallbackFunction _pCallback;
105 :
106 : public:
107 : inline oslThreadKey getThreadKey() SAL_THROW(());
108 :
109 : inline ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW(());
110 : inline ~ThreadKey() SAL_THROW(());
111 : };
112 : //__________________________________________________________________________________________________
113 154 : inline ThreadKey::ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW(())
114 : : _bInit( sal_False )
115 154 : , _pCallback( pCallback )
116 : {
117 154 : }
118 : //__________________________________________________________________________________________________
119 154 : inline ThreadKey::~ThreadKey() SAL_THROW(())
120 : {
121 154 : if (_bInit)
122 : {
123 154 : ::osl_destroyThreadKey( _hThreadKey );
124 : }
125 154 : }
126 : //__________________________________________________________________________________________________
127 913678 : inline oslThreadKey ThreadKey::getThreadKey() SAL_THROW(())
128 : {
129 913678 : if (! _bInit)
130 : {
131 154 : MutexGuard aGuard( Mutex::getGlobalMutex() );
132 154 : if (! _bInit)
133 : {
134 154 : _hThreadKey = ::osl_createThreadKey( _pCallback );
135 154 : _bInit = sal_True;
136 154 : }
137 : }
138 913678 : return _hThreadKey;
139 : }
140 :
141 : //==================================================================================================
142 886 : extern "C" void SAL_CALL delete_IdContainer( void * p )
143 : {
144 886 : if (p)
145 : {
146 886 : IdContainer * pId = reinterpret_cast< IdContainer * >( p );
147 886 : if (pId->pCurrentContext)
148 : {
149 : (*pId->pCurrentContextEnv->releaseInterface)(
150 0 : pId->pCurrentContextEnv, pId->pCurrentContext );
151 : (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
152 0 : (uno_Environment *)pId->pCurrentContextEnv );
153 : }
154 886 : if (pId->bInit)
155 : {
156 886 : ::rtl_byte_sequence_release( pId->pLocalThreadId );
157 886 : ::rtl_byte_sequence_release( pId->pCurrentId );
158 : }
159 886 : delete pId;
160 : }
161 886 : }
162 : //==================================================================================================
163 913678 : IdContainer * getIdContainer() SAL_THROW(())
164 : {
165 913678 : static ThreadKey s_key( delete_IdContainer );
166 913678 : oslThreadKey aKey = s_key.getThreadKey();
167 :
168 913678 : IdContainer * pId = reinterpret_cast< IdContainer * >( ::osl_getThreadKeyData( aKey ) );
169 913678 : if (! pId)
170 : {
171 1039 : pId = new IdContainer();
172 1039 : pId->pCurrentContext = 0;
173 1039 : pId->pCurrentContextEnv = 0;
174 1039 : pId->bInit = sal_False;
175 1039 : ::osl_setThreadKeyData( aKey, pId );
176 : }
177 913678 : return pId;
178 : }
179 :
180 : }
181 :
182 : //##################################################################################################
183 389000 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL uno_setCurrentContext(
184 : void * pCurrentContext,
185 : rtl_uString * pEnvTypeName, void * pEnvContext )
186 : SAL_THROW_EXTERN_C()
187 : {
188 389000 : IdContainer * pId = getIdContainer();
189 : OSL_ASSERT( pId );
190 :
191 : // free old one
192 389000 : if (pId->pCurrentContext)
193 : {
194 : (*pId->pCurrentContextEnv->releaseInterface)(
195 912 : pId->pCurrentContextEnv, pId->pCurrentContext );
196 : (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
197 912 : (uno_Environment *)pId->pCurrentContextEnv );
198 912 : pId->pCurrentContextEnv = 0;
199 :
200 912 : pId->pCurrentContext = 0;
201 : }
202 :
203 389000 : if (pCurrentContext)
204 : {
205 1063 : uno_Environment * pEnv = 0;
206 1063 : ::uno_getEnvironment( &pEnv, pEnvTypeName, pEnvContext );
207 : OSL_ASSERT( pEnv && pEnv->pExtEnv );
208 1063 : if (pEnv)
209 : {
210 1063 : if (pEnv->pExtEnv)
211 : {
212 1063 : pId->pCurrentContextEnv = pEnv->pExtEnv;
213 : (*pId->pCurrentContextEnv->acquireInterface)(
214 1063 : pId->pCurrentContextEnv, pCurrentContext );
215 1063 : pId->pCurrentContext = pCurrentContext;
216 : }
217 : else
218 : {
219 0 : (*pEnv->release)( pEnv );
220 0 : return sal_False;
221 : }
222 : }
223 : else
224 : {
225 0 : return sal_False;
226 : }
227 : }
228 389000 : return sal_True;
229 : }
230 : //##################################################################################################
231 206856 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL uno_getCurrentContext(
232 : void ** ppCurrentContext, rtl_uString * pEnvTypeName, void * pEnvContext )
233 : SAL_THROW_EXTERN_C()
234 : {
235 206856 : IdContainer * pId = getIdContainer();
236 : OSL_ASSERT( pId );
237 :
238 206856 : Environment target_env;
239 :
240 : // release inout parameter
241 206856 : if (*ppCurrentContext)
242 : {
243 0 : target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
244 : OSL_ASSERT( target_env.is() );
245 0 : if (! target_env.is())
246 0 : return sal_False;
247 0 : uno_ExtEnvironment * pEnv = target_env.get()->pExtEnv;
248 : OSL_ASSERT( 0 != pEnv );
249 0 : if (0 == pEnv)
250 0 : return sal_False;
251 0 : (*pEnv->releaseInterface)( pEnv, *ppCurrentContext );
252 :
253 0 : *ppCurrentContext = 0;
254 : }
255 :
256 : // case: null-ref
257 206856 : if (0 == pId->pCurrentContext)
258 205748 : return sal_True;
259 :
260 1108 : if (! target_env.is())
261 : {
262 1108 : target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
263 : OSL_ASSERT( target_env.is() );
264 1108 : if (! target_env.is())
265 0 : return sal_False;
266 : }
267 :
268 2216 : Mapping mapping((uno_Environment *) pId->pCurrentContextEnv, target_env.get());
269 : OSL_ASSERT( mapping.is() );
270 1108 : if (! mapping.is())
271 0 : return sal_False;
272 :
273 1108 : mapping.mapInterface(ppCurrentContext, pId->pCurrentContext, ::cppu::get_type_XCurrentContext() );
274 :
275 207964 : return sal_True;
276 : }
277 :
278 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|