/src/libreoffice/cppu/source/threadpool/current.cxx
Line | Count | Source |
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 | | #include <sal/config.h> |
21 | | |
22 | | #include <rtl/byteseq.h> |
23 | | |
24 | | #include <uno/current_context.h> |
25 | | #include <uno/environment.hxx> |
26 | | #include <uno/mapping.hxx> |
27 | | #include <typelib/typedescription.h> |
28 | | |
29 | | #include "current.hxx" |
30 | | |
31 | | |
32 | | using namespace ::rtl; |
33 | | using namespace ::cppu; |
34 | | using namespace ::com::sun::star::uno; |
35 | | |
36 | | namespace cppu |
37 | | { |
38 | | |
39 | | static typelib_InterfaceTypeDescription * impl_get_type_XCurrentContext() |
40 | 0 | { |
41 | 0 | OUString sTypeName(u"com.sun.star.uno.XCurrentContext"_ustr); |
42 | 0 | typelib_InterfaceTypeDescription* pTD = nullptr; |
43 | 0 | typelib_TypeDescriptionReference* pMembers[1] = { nullptr }; |
44 | 0 | OUString sMethodName0(u"com.sun.star.uno.XCurrentContext::getValueByName"_ustr); |
45 | 0 | typelib_typedescriptionreference_new(&pMembers[0], typelib_TypeClass_INTERFACE_METHOD, |
46 | 0 | sMethodName0.pData); |
47 | 0 | typelib_typedescription_newInterface( |
48 | 0 | &pTD, sTypeName.pData, 0, 0, 0, 0, 0, |
49 | 0 | *typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE), 1, pMembers); |
50 | |
|
51 | 0 | typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription**>(&pTD)); |
52 | 0 | typelib_typedescriptionreference_release(pMembers[0]); |
53 | |
|
54 | 0 | typelib_InterfaceMethodTypeDescription* pMethod = nullptr; |
55 | 0 | typelib_Parameter_Init aParameters[1]; |
56 | 0 | OUString sParamName0(u"Name"_ustr); |
57 | 0 | OUString sParamType0(u"string"_ustr); |
58 | 0 | aParameters[0].pParamName = sParamName0.pData; |
59 | 0 | aParameters[0].eTypeClass = typelib_TypeClass_STRING; |
60 | 0 | aParameters[0].pTypeName = sParamType0.pData; |
61 | 0 | aParameters[0].bIn = true; |
62 | 0 | aParameters[0].bOut = false; |
63 | 0 | rtl_uString* pExceptions[1]; |
64 | 0 | OUString sExceptionName0(u"com.sun.star.uno.RuntimeException"_ustr); |
65 | 0 | pExceptions[0] = sExceptionName0.pData; |
66 | 0 | OUString sReturnType0(u"any"_ustr); |
67 | 0 | typelib_typedescription_newInterfaceMethod(&pMethod, 3, false, sMethodName0.pData, |
68 | 0 | typelib_TypeClass_ANY, sReturnType0.pData, 1, |
69 | 0 | aParameters, 1, pExceptions); |
70 | 0 | typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription**>(&pMethod)); |
71 | 0 | typelib_typedescription_release(&pMethod->aBase.aBase); |
72 | | // another static ref: |
73 | 0 | ++reinterpret_cast<typelib_TypeDescription*>(pTD)->nStaticRefCount; |
74 | 0 | return pTD; |
75 | 0 | } |
76 | | |
77 | | static typelib_InterfaceTypeDescription * get_type_XCurrentContext() |
78 | 0 | { |
79 | 0 | static typelib_InterfaceTypeDescription* s_type_XCurrentContext = impl_get_type_XCurrentContext(); |
80 | 0 | return s_type_XCurrentContext; |
81 | 0 | } |
82 | | |
83 | | IdContainer::IdContainer() |
84 | 1 | : pCurrentContext(nullptr) |
85 | 1 | , pCurrentContextEnv(nullptr) |
86 | 1 | , pLocalThreadId(nullptr) |
87 | 1 | , pCurrentId(nullptr) |
88 | 1 | , nRefCountOfCurrentId(0) |
89 | 1 | , bInit(false) |
90 | 1 | { |
91 | 1 | } |
92 | | |
93 | | IdContainer::~IdContainer() |
94 | 1 | { |
95 | 1 | if (pCurrentContext) |
96 | 0 | { |
97 | 0 | (*pCurrentContextEnv->releaseInterface)( |
98 | 0 | pCurrentContextEnv, pCurrentContext ); |
99 | 0 | (*pCurrentContextEnv->aBase.release)( |
100 | 0 | &pCurrentContextEnv->aBase ); |
101 | 0 | } |
102 | 1 | if (bInit) |
103 | 0 | { |
104 | 0 | ::rtl_byte_sequence_release( pLocalThreadId ); |
105 | 0 | ::rtl_byte_sequence_release( pCurrentId ); |
106 | 0 | } |
107 | 1 | } |
108 | | |
109 | | IdContainer& getIdContainer() |
110 | 308 | { |
111 | 308 | static thread_local IdContainer aId; |
112 | 308 | return aId; |
113 | 308 | } |
114 | | |
115 | | } |
116 | | |
117 | | extern "C" sal_Bool SAL_CALL uno_setCurrentContext( |
118 | | void * pCurrentContext, |
119 | | rtl_uString * pEnvTypeName, void * pEnvContext ) noexcept |
120 | 154 | { |
121 | 154 | IdContainer& id = getIdContainer(); |
122 | | |
123 | | // free old one |
124 | 154 | if (id.pCurrentContext) |
125 | 77 | { |
126 | 77 | (*id.pCurrentContextEnv->releaseInterface)( |
127 | 77 | id.pCurrentContextEnv, id.pCurrentContext ); |
128 | 77 | (*id.pCurrentContextEnv->aBase.release)( |
129 | 77 | &id.pCurrentContextEnv->aBase ); |
130 | 77 | id.pCurrentContextEnv = nullptr; |
131 | | |
132 | 77 | id.pCurrentContext = nullptr; |
133 | 77 | } |
134 | | |
135 | 154 | if (!pCurrentContext) |
136 | 77 | return true; |
137 | | |
138 | 77 | uno_Environment * pEnv = nullptr; |
139 | 77 | ::uno_getEnvironment( &pEnv, pEnvTypeName, pEnvContext ); |
140 | 77 | OSL_ASSERT( pEnv && pEnv->pExtEnv ); |
141 | 77 | if (pEnv) |
142 | 77 | { |
143 | 77 | if (pEnv->pExtEnv) |
144 | 77 | { |
145 | 77 | id.pCurrentContextEnv = pEnv->pExtEnv; |
146 | 77 | (*id.pCurrentContextEnv->acquireInterface)( |
147 | 77 | id.pCurrentContextEnv, pCurrentContext ); |
148 | 77 | id.pCurrentContext = pCurrentContext; |
149 | 77 | } |
150 | 0 | else |
151 | 0 | { |
152 | 0 | (*pEnv->release)( pEnv ); |
153 | 0 | return false; |
154 | 0 | } |
155 | 77 | } |
156 | 0 | else |
157 | 0 | { |
158 | 0 | return false; |
159 | 0 | } |
160 | 77 | return true; |
161 | 77 | } |
162 | | |
163 | | extern "C" sal_Bool SAL_CALL uno_getCurrentContext( |
164 | | void ** ppCurrentContext, rtl_uString * pEnvTypeName, void * pEnvContext ) noexcept |
165 | 154 | { |
166 | 154 | IdContainer& id = getIdContainer(); |
167 | | |
168 | 154 | Environment target_env; |
169 | | |
170 | | // release inout parameter |
171 | 154 | if (*ppCurrentContext) |
172 | 0 | { |
173 | 0 | target_env = Environment(OUString(pEnvTypeName), pEnvContext); |
174 | 0 | OSL_ASSERT( target_env.is() ); |
175 | 0 | if (! target_env.is()) |
176 | 0 | return false; |
177 | 0 | uno_ExtEnvironment * pEnv = target_env.get()->pExtEnv; |
178 | 0 | OSL_ASSERT( nullptr != pEnv ); |
179 | 0 | if (nullptr == pEnv) |
180 | 0 | return false; |
181 | 0 | (*pEnv->releaseInterface)( pEnv, *ppCurrentContext ); |
182 | |
|
183 | 0 | *ppCurrentContext = nullptr; |
184 | 0 | } |
185 | | |
186 | | // case: null-ref |
187 | 154 | if (nullptr == id.pCurrentContext) |
188 | 154 | return true; |
189 | | |
190 | 0 | if (! target_env.is()) |
191 | 0 | { |
192 | 0 | target_env = Environment(OUString(pEnvTypeName), pEnvContext); |
193 | 0 | OSL_ASSERT( target_env.is() ); |
194 | 0 | if (! target_env.is()) |
195 | 0 | return false; |
196 | 0 | } |
197 | | |
198 | 0 | Mapping mapping(&id.pCurrentContextEnv->aBase, target_env.get()); |
199 | 0 | OSL_ASSERT( mapping.is() ); |
200 | 0 | if (! mapping.is()) |
201 | 0 | return false; |
202 | | |
203 | 0 | mapping.mapInterface(ppCurrentContext, id.pCurrentContext, ::cppu::get_type_XCurrentContext()); |
204 | |
|
205 | 0 | return true; |
206 | 0 | } |
207 | | |
208 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |