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