1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <rtl/byteseq.h>
23 #include <osl/thread.h>
24 #include <osl/mutex.hxx>
26 #include <uno/current_context.h>
27 #include <uno/environment.hxx>
28 #include <uno/mapping.hxx>
29 #include <typelib/typedescription.h>
31 #include "current.hxx"
34 using namespace ::osl
;
35 using namespace ::rtl
;
36 using namespace ::cppu
;
37 using namespace ::com::sun::star::uno
;
42 static typelib_InterfaceTypeDescription
* get_type_XCurrentContext()
44 static typelib_InterfaceTypeDescription
* s_type_XCurrentContext
= []() {
45 OUString
sTypeName("com.sun.star.uno.XCurrentContext");
46 typelib_InterfaceTypeDescription
* pTD
= nullptr;
47 typelib_TypeDescriptionReference
* pMembers
[1] = { nullptr };
48 OUString
sMethodName0("com.sun.star.uno.XCurrentContext::getValueByName");
49 typelib_typedescriptionreference_new(&pMembers
[0], typelib_TypeClass_INTERFACE_METHOD
,
51 typelib_typedescription_newInterface(
52 &pTD
, sTypeName
.pData
, 0, 0, 0, 0, 0,
53 *typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE
), 1, pMembers
);
55 typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription
**>(&pTD
));
56 typelib_typedescriptionreference_release(pMembers
[0]);
58 typelib_InterfaceMethodTypeDescription
* pMethod
= nullptr;
59 typelib_Parameter_Init aParameters
[1];
60 OUString
sParamName0("Name");
61 OUString
sParamType0("string");
62 aParameters
[0].pParamName
= sParamName0
.pData
;
63 aParameters
[0].eTypeClass
= typelib_TypeClass_STRING
;
64 aParameters
[0].pTypeName
= sParamType0
.pData
;
65 aParameters
[0].bIn
= true;
66 aParameters
[0].bOut
= false;
67 rtl_uString
* pExceptions
[1];
68 OUString
sExceptionName0("com.sun.star.uno.RuntimeException");
69 pExceptions
[0] = sExceptionName0
.pData
;
70 OUString
sReturnType0("any");
71 typelib_typedescription_newInterfaceMethod(&pMethod
, 3, false, sMethodName0
.pData
,
72 typelib_TypeClass_ANY
, sReturnType0
.pData
, 1,
73 aParameters
, 1, pExceptions
);
74 typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription
**>(&pMethod
));
75 typelib_typedescription_release(&pMethod
->aBase
.aBase
);
76 // another static ref:
77 ++reinterpret_cast<typelib_TypeDescription
*>(pTD
)->nStaticRefCount
;
81 return s_type_XCurrentContext
;
89 oslThreadKey _hThreadKey
;
90 oslThreadKeyCallbackFunction _pCallback
;
93 oslThreadKey
getThreadKey()
97 MutexGuard
aGuard( Mutex::getGlobalMutex() );
100 _hThreadKey
= ::osl_createThreadKey( _pCallback
);
107 explicit ThreadKey( oslThreadKeyCallbackFunction pCallback
)
109 , _hThreadKey(nullptr)
110 , _pCallback(pCallback
)
118 ::osl_destroyThreadKey( _hThreadKey
);
127 static void delete_IdContainer( void * p
)
132 IdContainer
* pId
= static_cast< IdContainer
* >( p
);
133 if (pId
->pCurrentContext
)
135 (*pId
->pCurrentContextEnv
->releaseInterface
)(
136 pId
->pCurrentContextEnv
, pId
->pCurrentContext
);
137 (*pId
->pCurrentContextEnv
->aBase
.release
)(
138 &pId
->pCurrentContextEnv
->aBase
);
142 ::rtl_byte_sequence_release( pId
->pLocalThreadId
);
143 ::rtl_byte_sequence_release( pId
->pCurrentId
);
150 IdContainer
* getIdContainer()
152 static ThreadKey
s_key( delete_IdContainer
);
153 oslThreadKey aKey
= s_key
.getThreadKey();
155 IdContainer
* pId
= static_cast< IdContainer
* >( ::osl_getThreadKeyData( aKey
) );
158 pId
= new IdContainer
;
159 pId
->pCurrentContext
= nullptr;
160 pId
->pCurrentContextEnv
= nullptr;
162 ::osl_setThreadKeyData( aKey
, pId
);
170 extern "C" sal_Bool SAL_CALL
uno_setCurrentContext(
171 void * pCurrentContext
,
172 rtl_uString
* pEnvTypeName
, void * pEnvContext
)
175 IdContainer
* pId
= getIdContainer();
179 if (pId
->pCurrentContext
)
181 (*pId
->pCurrentContextEnv
->releaseInterface
)(
182 pId
->pCurrentContextEnv
, pId
->pCurrentContext
);
183 (*pId
->pCurrentContextEnv
->aBase
.release
)(
184 &pId
->pCurrentContextEnv
->aBase
);
185 pId
->pCurrentContextEnv
= nullptr;
187 pId
->pCurrentContext
= nullptr;
192 uno_Environment
* pEnv
= nullptr;
193 ::uno_getEnvironment( &pEnv
, pEnvTypeName
, pEnvContext
);
194 OSL_ASSERT( pEnv
&& pEnv
->pExtEnv
);
199 pId
->pCurrentContextEnv
= pEnv
->pExtEnv
;
200 (*pId
->pCurrentContextEnv
->acquireInterface
)(
201 pId
->pCurrentContextEnv
, pCurrentContext
);
202 pId
->pCurrentContext
= pCurrentContext
;
206 (*pEnv
->release
)( pEnv
);
218 extern "C" sal_Bool SAL_CALL
uno_getCurrentContext(
219 void ** ppCurrentContext
, rtl_uString
* pEnvTypeName
, void * pEnvContext
)
222 IdContainer
* pId
= getIdContainer();
225 Environment target_env
;
227 // release inout parameter
228 if (*ppCurrentContext
)
230 target_env
= Environment(OUString(pEnvTypeName
), pEnvContext
);
231 OSL_ASSERT( target_env
.is() );
232 if (! target_env
.is())
234 uno_ExtEnvironment
* pEnv
= target_env
.get()->pExtEnv
;
235 OSL_ASSERT( nullptr != pEnv
);
238 (*pEnv
->releaseInterface
)( pEnv
, *ppCurrentContext
);
240 *ppCurrentContext
= nullptr;
244 if (nullptr == pId
->pCurrentContext
)
247 if (! target_env
.is())
249 target_env
= Environment(OUString(pEnvTypeName
), pEnvContext
);
250 OSL_ASSERT( target_env
.is() );
251 if (! target_env
.is())
255 Mapping
mapping(&pId
->pCurrentContextEnv
->aBase
, target_env
.get());
256 OSL_ASSERT( mapping
.is() );
260 mapping
.mapInterface(ppCurrentContext
, pId
->pCurrentContext
, ::cppu::get_type_XCurrentContext() );
265 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */