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/mutex.hxx>
25 #include <uno/current_context.h>
26 #include <uno/environment.hxx>
27 #include <uno/mapping.hxx>
28 #include <typelib/typedescription.h>
30 #include "current.hxx"
33 using namespace ::osl
;
34 using namespace ::rtl
;
35 using namespace ::cppu
;
36 using namespace ::com::sun::star::uno
;
41 static typelib_InterfaceTypeDescription
* get_type_XCurrentContext()
43 static typelib_InterfaceTypeDescription
* s_type_XCurrentContext
= []() {
44 OUString
sTypeName("com.sun.star.uno.XCurrentContext");
45 typelib_InterfaceTypeDescription
* pTD
= nullptr;
46 typelib_TypeDescriptionReference
* pMembers
[1] = { nullptr };
47 OUString
sMethodName0("com.sun.star.uno.XCurrentContext::getValueByName");
48 typelib_typedescriptionreference_new(&pMembers
[0], typelib_TypeClass_INTERFACE_METHOD
,
50 typelib_typedescription_newInterface(
51 &pTD
, sTypeName
.pData
, 0, 0, 0, 0, 0,
52 *typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE
), 1, pMembers
);
54 typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription
**>(&pTD
));
55 typelib_typedescriptionreference_release(pMembers
[0]);
57 typelib_InterfaceMethodTypeDescription
* pMethod
= nullptr;
58 typelib_Parameter_Init aParameters
[1];
59 OUString
sParamName0("Name");
60 OUString
sParamType0("string");
61 aParameters
[0].pParamName
= sParamName0
.pData
;
62 aParameters
[0].eTypeClass
= typelib_TypeClass_STRING
;
63 aParameters
[0].pTypeName
= sParamType0
.pData
;
64 aParameters
[0].bIn
= true;
65 aParameters
[0].bOut
= false;
66 rtl_uString
* pExceptions
[1];
67 OUString
sExceptionName0("com.sun.star.uno.RuntimeException");
68 pExceptions
[0] = sExceptionName0
.pData
;
69 OUString
sReturnType0("any");
70 typelib_typedescription_newInterfaceMethod(&pMethod
, 3, false, sMethodName0
.pData
,
71 typelib_TypeClass_ANY
, sReturnType0
.pData
, 1,
72 aParameters
, 1, pExceptions
);
73 typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription
**>(&pMethod
));
74 typelib_typedescription_release(&pMethod
->aBase
.aBase
);
75 // another static ref:
76 ++reinterpret_cast<typelib_TypeDescription
*>(pTD
)->nStaticRefCount
;
80 return s_type_XCurrentContext
;
83 IdContainer::IdContainer()
84 : pCurrentContext(nullptr)
85 , pCurrentContextEnv(nullptr)
86 , pLocalThreadId(nullptr)
88 , nRefCountOfCurrentId(0)
93 IdContainer::~IdContainer()
97 (*pCurrentContextEnv
->releaseInterface
)(
98 pCurrentContextEnv
, pCurrentContext
);
99 (*pCurrentContextEnv
->aBase
.release
)(
100 &pCurrentContextEnv
->aBase
);
104 ::rtl_byte_sequence_release( pLocalThreadId
);
105 ::rtl_byte_sequence_release( pCurrentId
);
109 IdContainer
& getIdContainer()
111 static thread_local IdContainer aId
;
117 extern "C" sal_Bool SAL_CALL
uno_setCurrentContext(
118 void * pCurrentContext
,
119 rtl_uString
* pEnvTypeName
, void * pEnvContext
)
122 IdContainer
& id
= getIdContainer();
125 if (id
.pCurrentContext
)
127 (*id
.pCurrentContextEnv
->releaseInterface
)(
128 id
.pCurrentContextEnv
, id
.pCurrentContext
);
129 (*id
.pCurrentContextEnv
->aBase
.release
)(
130 &id
.pCurrentContextEnv
->aBase
);
131 id
.pCurrentContextEnv
= nullptr;
133 id
.pCurrentContext
= nullptr;
138 uno_Environment
* pEnv
= nullptr;
139 ::uno_getEnvironment( &pEnv
, pEnvTypeName
, pEnvContext
);
140 OSL_ASSERT( pEnv
&& pEnv
->pExtEnv
);
145 id
.pCurrentContextEnv
= pEnv
->pExtEnv
;
146 (*id
.pCurrentContextEnv
->acquireInterface
)(
147 id
.pCurrentContextEnv
, pCurrentContext
);
148 id
.pCurrentContext
= pCurrentContext
;
152 (*pEnv
->release
)( pEnv
);
164 extern "C" sal_Bool SAL_CALL
uno_getCurrentContext(
165 void ** ppCurrentContext
, rtl_uString
* pEnvTypeName
, void * pEnvContext
)
168 IdContainer
& id
= getIdContainer();
170 Environment target_env
;
172 // release inout parameter
173 if (*ppCurrentContext
)
175 target_env
= Environment(OUString(pEnvTypeName
), pEnvContext
);
176 OSL_ASSERT( target_env
.is() );
177 if (! target_env
.is())
179 uno_ExtEnvironment
* pEnv
= target_env
.get()->pExtEnv
;
180 OSL_ASSERT( nullptr != pEnv
);
183 (*pEnv
->releaseInterface
)( pEnv
, *ppCurrentContext
);
185 *ppCurrentContext
= nullptr;
189 if (nullptr == id
.pCurrentContext
)
192 if (! target_env
.is())
194 target_env
= Environment(OUString(pEnvTypeName
), pEnvContext
);
195 OSL_ASSERT( target_env
.is() );
196 if (! target_env
.is())
200 Mapping
mapping(&id
.pCurrentContextEnv
->aBase
, target_env
.get());
201 OSL_ASSERT( mapping
.is() );
205 mapping
.mapInterface(ppCurrentContext
, id
.pCurrentContext
, ::cppu::get_type_XCurrentContext());
210 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */