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