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 "typelib/typedescription.h"
28 :
29 : #include "current.hxx"
30 :
31 :
32 : using namespace ::osl;
33 : using namespace ::rtl;
34 : using namespace ::cppu;
35 : using namespace ::com::sun::star::uno;
36 :
37 : namespace cppu
38 : {
39 :
40 2 : static typelib_InterfaceTypeDescription * get_type_XCurrentContext()
41 : {
42 : static typelib_InterfaceTypeDescription * s_type_XCurrentContext = 0;
43 2 : if (0 == s_type_XCurrentContext)
44 : {
45 1 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
46 1 : if (0 == s_type_XCurrentContext)
47 : {
48 1 : OUString sTypeName("com.sun.star.uno.XCurrentContext");
49 1 : typelib_InterfaceTypeDescription * pTD = 0;
50 1 : typelib_TypeDescriptionReference * pMembers[1] = { 0 };
51 2 : OUString sMethodName0("com.sun.star.uno.XCurrentContext::getValueByName");
52 : typelib_typedescriptionreference_new(
53 : &pMembers[0],
54 : typelib_TypeClass_INTERFACE_METHOD,
55 1 : sMethodName0.pData );
56 : typelib_typedescription_newInterface(
57 : &pTD,
58 : sTypeName.pData, 0, 0, 0, 0, 0,
59 1 : * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ),
60 : 1,
61 1 : pMembers );
62 :
63 1 : typelib_typedescription_register( (typelib_TypeDescription**)&pTD );
64 1 : typelib_typedescriptionreference_release( pMembers[0] );
65 :
66 1 : typelib_InterfaceMethodTypeDescription * pMethod = 0;
67 : typelib_Parameter_Init aParameters[1];
68 2 : OUString sParamName0("Name");
69 2 : OUString sParamType0("string");
70 1 : aParameters[0].pParamName = sParamName0.pData;
71 1 : aParameters[0].eTypeClass = typelib_TypeClass_STRING;
72 1 : aParameters[0].pTypeName = sParamType0.pData;
73 1 : aParameters[0].bIn = sal_True;
74 1 : aParameters[0].bOut = sal_False;
75 : rtl_uString * pExceptions[1];
76 2 : OUString sExceptionName0("com.sun.star.uno.RuntimeException");
77 1 : pExceptions[0] = sExceptionName0.pData;
78 2 : OUString sReturnType0("any");
79 : typelib_typedescription_newInterfaceMethod(
80 : &pMethod,
81 : 3, sal_False,
82 : sMethodName0.pData,
83 : typelib_TypeClass_ANY, sReturnType0.pData,
84 1 : 1, aParameters, 1, pExceptions );
85 1 : typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
86 1 : typelib_typedescription_release( (typelib_TypeDescription*)pMethod );
87 : // another static ref:
88 : ++reinterpret_cast< typelib_TypeDescription * >( pTD )->
89 1 : nStaticRefCount;
90 2 : s_type_XCurrentContext = pTD;
91 1 : }
92 : }
93 2 : return s_type_XCurrentContext;
94 : }
95 :
96 :
97 :
98 :
99 : class ThreadKey
100 : {
101 : bool _bInit;
102 : oslThreadKey _hThreadKey;
103 : oslThreadKeyCallbackFunction _pCallback;
104 :
105 : public:
106 : inline oslThreadKey getThreadKey() SAL_THROW(());
107 :
108 : inline ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW(());
109 : inline ~ThreadKey() SAL_THROW(());
110 : };
111 :
112 1 : inline ThreadKey::ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW(())
113 : : _bInit( false )
114 1 : , _pCallback( pCallback )
115 : {
116 1 : }
117 :
118 1 : inline ThreadKey::~ThreadKey() SAL_THROW(())
119 : {
120 1 : if (_bInit)
121 : {
122 1 : ::osl_destroyThreadKey( _hThreadKey );
123 : }
124 1 : }
125 :
126 6 : inline oslThreadKey ThreadKey::getThreadKey() SAL_THROW(())
127 : {
128 6 : if (! _bInit)
129 : {
130 1 : MutexGuard aGuard( Mutex::getGlobalMutex() );
131 1 : if (! _bInit)
132 : {
133 1 : _hThreadKey = ::osl_createThreadKey( _pCallback );
134 1 : _bInit = true;
135 1 : }
136 : }
137 6 : return _hThreadKey;
138 : }
139 :
140 :
141 0 : extern "C" void SAL_CALL delete_IdContainer( void * p )
142 : {
143 0 : if (p)
144 : {
145 0 : IdContainer * pId = reinterpret_cast< IdContainer * >( p );
146 0 : if (pId->pCurrentContext)
147 : {
148 : (*pId->pCurrentContextEnv->releaseInterface)(
149 0 : pId->pCurrentContextEnv, pId->pCurrentContext );
150 : (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
151 0 : (uno_Environment *)pId->pCurrentContextEnv );
152 : }
153 0 : if (pId->bInit)
154 : {
155 0 : ::rtl_byte_sequence_release( pId->pLocalThreadId );
156 0 : ::rtl_byte_sequence_release( pId->pCurrentId );
157 : }
158 0 : delete pId;
159 : }
160 0 : }
161 :
162 6 : IdContainer * getIdContainer() SAL_THROW(())
163 : {
164 6 : static ThreadKey s_key( delete_IdContainer );
165 6 : oslThreadKey aKey = s_key.getThreadKey();
166 :
167 6 : IdContainer * pId = reinterpret_cast< IdContainer * >( ::osl_getThreadKeyData( aKey ) );
168 6 : if (! pId)
169 : {
170 1 : pId = new IdContainer();
171 1 : pId->pCurrentContext = 0;
172 1 : pId->pCurrentContextEnv = 0;
173 1 : pId->bInit = false;
174 1 : ::osl_setThreadKeyData( aKey, pId );
175 : }
176 6 : return pId;
177 : }
178 :
179 : }
180 :
181 :
182 3 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL uno_setCurrentContext(
183 : void * pCurrentContext,
184 : rtl_uString * pEnvTypeName, void * pEnvContext )
185 : SAL_THROW_EXTERN_C()
186 : {
187 3 : IdContainer * pId = getIdContainer();
188 : OSL_ASSERT( pId );
189 :
190 : // free old one
191 3 : if (pId->pCurrentContext)
192 : {
193 : (*pId->pCurrentContextEnv->releaseInterface)(
194 2 : pId->pCurrentContextEnv, pId->pCurrentContext );
195 : (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
196 2 : (uno_Environment *)pId->pCurrentContextEnv );
197 2 : pId->pCurrentContextEnv = 0;
198 :
199 2 : pId->pCurrentContext = 0;
200 : }
201 :
202 3 : if (pCurrentContext)
203 : {
204 3 : uno_Environment * pEnv = 0;
205 3 : ::uno_getEnvironment( &pEnv, pEnvTypeName, pEnvContext );
206 : OSL_ASSERT( pEnv && pEnv->pExtEnv );
207 3 : if (pEnv)
208 : {
209 3 : if (pEnv->pExtEnv)
210 : {
211 3 : pId->pCurrentContextEnv = pEnv->pExtEnv;
212 : (*pId->pCurrentContextEnv->acquireInterface)(
213 3 : pId->pCurrentContextEnv, pCurrentContext );
214 3 : pId->pCurrentContext = pCurrentContext;
215 : }
216 : else
217 : {
218 0 : (*pEnv->release)( pEnv );
219 0 : return sal_False;
220 : }
221 : }
222 : else
223 : {
224 0 : return sal_False;
225 : }
226 : }
227 3 : return sal_True;
228 : }
229 :
230 3 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL uno_getCurrentContext(
231 : void ** ppCurrentContext, rtl_uString * pEnvTypeName, void * pEnvContext )
232 : SAL_THROW_EXTERN_C()
233 : {
234 3 : IdContainer * pId = getIdContainer();
235 : OSL_ASSERT( pId );
236 :
237 3 : Environment target_env;
238 :
239 : // release inout parameter
240 3 : if (*ppCurrentContext)
241 : {
242 0 : target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
243 : OSL_ASSERT( target_env.is() );
244 0 : if (! target_env.is())
245 0 : return sal_False;
246 0 : uno_ExtEnvironment * pEnv = target_env.get()->pExtEnv;
247 : OSL_ASSERT( 0 != pEnv );
248 0 : if (0 == pEnv)
249 0 : return sal_False;
250 0 : (*pEnv->releaseInterface)( pEnv, *ppCurrentContext );
251 :
252 0 : *ppCurrentContext = 0;
253 : }
254 :
255 : // case: null-ref
256 3 : if (0 == pId->pCurrentContext)
257 1 : return sal_True;
258 :
259 2 : if (! target_env.is())
260 : {
261 2 : target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
262 : OSL_ASSERT( target_env.is() );
263 2 : if (! target_env.is())
264 0 : return sal_False;
265 : }
266 :
267 4 : Mapping mapping((uno_Environment *) pId->pCurrentContextEnv, target_env.get());
268 : OSL_ASSERT( mapping.is() );
269 2 : if (! mapping.is())
270 0 : return sal_False;
271 :
272 2 : mapping.mapInterface(ppCurrentContext, pId->pCurrentContext, ::cppu::get_type_XCurrentContext() );
273 :
274 5 : return sal_True;
275 : }
276 :
277 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|