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 ::rtl
;
34 using namespace ::cppu
;
35 using namespace ::com::sun::star::uno
;
40 static typelib_InterfaceTypeDescription
* impl_get_type_XCurrentContext()
42 OUString
sTypeName(u
"com.sun.star.uno.XCurrentContext"_ustr
);
43 typelib_InterfaceTypeDescription
* pTD
= nullptr;
44 typelib_TypeDescriptionReference
* pMembers
[1] = { nullptr };
45 OUString
sMethodName0(u
"com.sun.star.uno.XCurrentContext::getValueByName"_ustr
);
46 typelib_typedescriptionreference_new(&pMembers
[0], typelib_TypeClass_INTERFACE_METHOD
,
48 typelib_typedescription_newInterface(
49 &pTD
, sTypeName
.pData
, 0, 0, 0, 0, 0,
50 *typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE
), 1, pMembers
);
52 typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription
**>(&pTD
));
53 typelib_typedescriptionreference_release(pMembers
[0]);
55 typelib_InterfaceMethodTypeDescription
* pMethod
= nullptr;
56 typelib_Parameter_Init aParameters
[1];
57 OUString
sParamName0(u
"Name"_ustr
);
58 OUString
sParamType0(u
"string"_ustr
);
59 aParameters
[0].pParamName
= sParamName0
.pData
;
60 aParameters
[0].eTypeClass
= typelib_TypeClass_STRING
;
61 aParameters
[0].pTypeName
= sParamType0
.pData
;
62 aParameters
[0].bIn
= true;
63 aParameters
[0].bOut
= false;
64 rtl_uString
* pExceptions
[1];
65 OUString
sExceptionName0(u
"com.sun.star.uno.RuntimeException"_ustr
);
66 pExceptions
[0] = sExceptionName0
.pData
;
67 OUString
sReturnType0(u
"any"_ustr
);
68 typelib_typedescription_newInterfaceMethod(&pMethod
, 3, false, sMethodName0
.pData
,
69 typelib_TypeClass_ANY
, sReturnType0
.pData
, 1,
70 aParameters
, 1, pExceptions
);
71 typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription
**>(&pMethod
));
72 typelib_typedescription_release(&pMethod
->aBase
.aBase
);
73 // another static ref:
74 ++reinterpret_cast<typelib_TypeDescription
*>(pTD
)->nStaticRefCount
;
78 static typelib_InterfaceTypeDescription
* get_type_XCurrentContext()
80 static typelib_InterfaceTypeDescription
* s_type_XCurrentContext
= impl_get_type_XCurrentContext();
81 return s_type_XCurrentContext
;
84 IdContainer::IdContainer()
85 : pCurrentContext(nullptr)
86 , pCurrentContextEnv(nullptr)
87 , pLocalThreadId(nullptr)
89 , nRefCountOfCurrentId(0)
94 IdContainer::~IdContainer()
98 (*pCurrentContextEnv
->releaseInterface
)(
99 pCurrentContextEnv
, pCurrentContext
);
100 (*pCurrentContextEnv
->aBase
.release
)(
101 &pCurrentContextEnv
->aBase
);
105 ::rtl_byte_sequence_release( pLocalThreadId
);
106 ::rtl_byte_sequence_release( pCurrentId
);
110 IdContainer
& getIdContainer()
112 static thread_local IdContainer aId
;
118 extern "C" sal_Bool SAL_CALL
uno_setCurrentContext(
119 void * pCurrentContext
,
120 rtl_uString
* pEnvTypeName
, void * pEnvContext
) noexcept
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;
136 if (!pCurrentContext
)
139 uno_Environment
* pEnv
= nullptr;
140 ::uno_getEnvironment( &pEnv
, pEnvTypeName
, pEnvContext
);
141 OSL_ASSERT( pEnv
&& pEnv
->pExtEnv
);
146 id
.pCurrentContextEnv
= pEnv
->pExtEnv
;
147 (*id
.pCurrentContextEnv
->acquireInterface
)(
148 id
.pCurrentContextEnv
, pCurrentContext
);
149 id
.pCurrentContext
= pCurrentContext
;
153 (*pEnv
->release
)( pEnv
);
164 extern "C" sal_Bool SAL_CALL
uno_getCurrentContext(
165 void ** ppCurrentContext
, rtl_uString
* pEnvTypeName
, void * pEnvContext
) noexcept
167 IdContainer
& id
= getIdContainer();
169 Environment target_env
;
171 // release inout parameter
172 if (*ppCurrentContext
)
174 target_env
= Environment(OUString(pEnvTypeName
), pEnvContext
);
175 OSL_ASSERT( target_env
.is() );
176 if (! target_env
.is())
178 uno_ExtEnvironment
* pEnv
= target_env
.get()->pExtEnv
;
179 OSL_ASSERT( nullptr != pEnv
);
182 (*pEnv
->releaseInterface
)( pEnv
, *ppCurrentContext
);
184 *ppCurrentContext
= nullptr;
188 if (nullptr == id
.pCurrentContext
)
191 if (! target_env
.is())
193 target_env
= Environment(OUString(pEnvTypeName
), pEnvContext
);
194 OSL_ASSERT( target_env
.is() );
195 if (! target_env
.is())
199 Mapping
mapping(&id
.pCurrentContextEnv
->aBase
, target_env
.get());
200 OSL_ASSERT( mapping
.is() );
204 mapping
.mapInterface(ppCurrentContext
, id
.pCurrentContext
, ::cppu::get_type_XCurrentContext());
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */