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>
24 #include "osl/thread.h"
25 #include "osl/mutex.hxx"
27 #include "uno/current_context.h"
28 #include "uno/environment.hxx"
29 #include "uno/mapping.hxx"
30 #include "typelib/typedescription.h"
32 #include "current.hxx"
35 using namespace ::osl
;
36 using namespace ::rtl
;
37 using namespace ::cppu
;
38 using namespace ::com::sun::star::uno
;
43 static typelib_InterfaceTypeDescription
* get_type_XCurrentContext()
45 static typelib_InterfaceTypeDescription
* s_type_XCurrentContext
= 0;
46 if (0 == s_type_XCurrentContext
)
48 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
49 if (0 == s_type_XCurrentContext
)
51 OUString
sTypeName("com.sun.star.uno.XCurrentContext");
52 typelib_InterfaceTypeDescription
* pTD
= 0;
53 typelib_TypeDescriptionReference
* pMembers
[1] = { 0 };
54 OUString
sMethodName0("com.sun.star.uno.XCurrentContext::getValueByName");
55 typelib_typedescriptionreference_new(
57 typelib_TypeClass_INTERFACE_METHOD
,
59 typelib_typedescription_newInterface(
61 sTypeName
.pData
, 0, 0, 0, 0, 0,
62 * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE
),
66 typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pTD
) );
67 typelib_typedescriptionreference_release( pMembers
[0] );
69 typelib_InterfaceMethodTypeDescription
* pMethod
= 0;
70 typelib_Parameter_Init aParameters
[1];
71 OUString
sParamName0("Name");
72 OUString
sParamType0("string");
73 aParameters
[0].pParamName
= sParamName0
.pData
;
74 aParameters
[0].eTypeClass
= typelib_TypeClass_STRING
;
75 aParameters
[0].pTypeName
= sParamType0
.pData
;
76 aParameters
[0].bIn
= sal_True
;
77 aParameters
[0].bOut
= sal_False
;
78 rtl_uString
* pExceptions
[1];
79 OUString
sExceptionName0("com.sun.star.uno.RuntimeException");
80 pExceptions
[0] = sExceptionName0
.pData
;
81 OUString
sReturnType0("any");
82 typelib_typedescription_newInterfaceMethod(
86 typelib_TypeClass_ANY
, sReturnType0
.pData
,
87 1, aParameters
, 1, pExceptions
);
88 typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pMethod
) );
89 typelib_typedescription_release( &pMethod
->aBase
.aBase
);
90 // another static ref:
91 ++reinterpret_cast< typelib_TypeDescription
* >( pTD
)->
93 s_type_XCurrentContext
= pTD
;
96 return s_type_XCurrentContext
;
105 oslThreadKey _hThreadKey
;
106 oslThreadKeyCallbackFunction _pCallback
;
109 inline oslThreadKey
getThreadKey();
111 inline ThreadKey( oslThreadKeyCallbackFunction pCallback
);
115 inline ThreadKey::ThreadKey( oslThreadKeyCallbackFunction pCallback
)
118 , _pCallback( pCallback
)
122 inline ThreadKey::~ThreadKey()
126 ::osl_destroyThreadKey( _hThreadKey
);
130 inline oslThreadKey
ThreadKey::getThreadKey()
134 MutexGuard
aGuard( Mutex::getGlobalMutex() );
137 _hThreadKey
= ::osl_createThreadKey( _pCallback
);
145 extern "C" void SAL_CALL
delete_IdContainer( void * p
)
149 IdContainer
* pId
= static_cast< IdContainer
* >( p
);
150 if (pId
->pCurrentContext
)
152 (*pId
->pCurrentContextEnv
->releaseInterface
)(
153 pId
->pCurrentContextEnv
, pId
->pCurrentContext
);
154 (*pId
->pCurrentContextEnv
->aBase
.release
)(
155 &pId
->pCurrentContextEnv
->aBase
);
159 ::rtl_byte_sequence_release( pId
->pLocalThreadId
);
160 ::rtl_byte_sequence_release( pId
->pCurrentId
);
166 IdContainer
* getIdContainer()
168 static ThreadKey
s_key( delete_IdContainer
);
169 oslThreadKey aKey
= s_key
.getThreadKey();
171 IdContainer
* pId
= static_cast< IdContainer
* >( ::osl_getThreadKeyData( aKey
) );
174 pId
= new IdContainer();
175 pId
->pCurrentContext
= 0;
176 pId
->pCurrentContextEnv
= 0;
178 ::osl_setThreadKeyData( aKey
, pId
);
186 extern "C" sal_Bool SAL_CALL
uno_setCurrentContext(
187 void * pCurrentContext
,
188 rtl_uString
* pEnvTypeName
, void * pEnvContext
)
191 IdContainer
* pId
= getIdContainer();
195 if (pId
->pCurrentContext
)
197 (*pId
->pCurrentContextEnv
->releaseInterface
)(
198 pId
->pCurrentContextEnv
, pId
->pCurrentContext
);
199 (*pId
->pCurrentContextEnv
->aBase
.release
)(
200 &pId
->pCurrentContextEnv
->aBase
);
201 pId
->pCurrentContextEnv
= 0;
203 pId
->pCurrentContext
= 0;
208 uno_Environment
* pEnv
= 0;
209 ::uno_getEnvironment( &pEnv
, pEnvTypeName
, pEnvContext
);
210 OSL_ASSERT( pEnv
&& pEnv
->pExtEnv
);
215 pId
->pCurrentContextEnv
= pEnv
->pExtEnv
;
216 (*pId
->pCurrentContextEnv
->acquireInterface
)(
217 pId
->pCurrentContextEnv
, pCurrentContext
);
218 pId
->pCurrentContext
= pCurrentContext
;
222 (*pEnv
->release
)( pEnv
);
234 extern "C" sal_Bool SAL_CALL
uno_getCurrentContext(
235 void ** ppCurrentContext
, rtl_uString
* pEnvTypeName
, void * pEnvContext
)
238 IdContainer
* pId
= getIdContainer();
241 Environment target_env
;
243 // release inout parameter
244 if (*ppCurrentContext
)
246 target_env
= Environment(rtl::OUString(pEnvTypeName
), pEnvContext
);
247 OSL_ASSERT( target_env
.is() );
248 if (! target_env
.is())
250 uno_ExtEnvironment
* pEnv
= target_env
.get()->pExtEnv
;
251 OSL_ASSERT( 0 != pEnv
);
254 (*pEnv
->releaseInterface
)( pEnv
, *ppCurrentContext
);
256 *ppCurrentContext
= 0;
260 if (0 == pId
->pCurrentContext
)
263 if (! target_env
.is())
265 target_env
= Environment(rtl::OUString(pEnvTypeName
), pEnvContext
);
266 OSL_ASSERT( target_env
.is() );
267 if (! target_env
.is())
271 Mapping
mapping(&pId
->pCurrentContextEnv
->aBase
, target_env
.get());
272 OSL_ASSERT( mapping
.is() );
276 mapping
.mapInterface(ppCurrentContext
, pId
->pCurrentContext
, ::cppu::get_type_XCurrentContext() );
281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */