tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / bridges / source / cpp_uno / gcc3_wasm / uno2cpp.cxx
blobf3b257dc1d9b6398b43b1742c38c88b2eb8e48d2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <sal/config.h>
12 #include <exception>
13 #include <typeinfo>
14 #include <vector>
16 #include <alloca.h>
18 #include <com/sun/star/uno/Exception.hpp>
19 #include <com/sun/star/uno/RuntimeException.hpp>
20 #include <com/sun/star/uno/genfunc.hxx>
21 #include <cppu/unotype.hxx>
22 #include <o3tl/runtimetooustring.hxx>
23 #include <o3tl/temporary.hxx>
24 #include <o3tl/unreachable.hxx>
25 #include <rtl/strbuf.hxx>
26 #include <typelib/typeclass.h>
27 #include <typelib/typedescription.h>
28 #include <typelib/typedescription.hxx>
29 #include <uno/any2.h>
30 #include <uno/data.h>
32 #include <bridge.hxx>
33 #include <types.hxx>
34 #include <unointerfaceproxy.hxx>
35 #include <vtables.hxx>
36 #include <wasm/generated.hxx>
38 #include "abi.hxx"
40 namespace
42 void call(bridges::cpp_uno::shared::UnoInterfaceProxy* proxy,
43 bridges::cpp_uno::shared::VtableSlot slot, typelib_TypeDescriptionReference* returnType,
44 sal_Int32 count, typelib_MethodParameter* parameters, void* returnValue, void** arguments,
45 uno_Any** exception)
47 css::uno::TypeDescription rtd(returnType);
48 auto const retConv = bridges::cpp_uno::shared::relatesToInterfaceType(rtd.get());
49 auto const ret = retConv ? alloca(rtd.get()->nSize) : returnValue;
50 OStringBuffer sig;
51 std::vector<sal_uInt64> args;
52 switch (rtd.get()->eTypeClass)
54 case typelib_TypeClass_VOID:
55 sig.append('v');
56 break;
57 case typelib_TypeClass_BOOLEAN:
58 case typelib_TypeClass_BYTE:
59 case typelib_TypeClass_SHORT:
60 case typelib_TypeClass_UNSIGNED_SHORT:
61 case typelib_TypeClass_LONG:
62 case typelib_TypeClass_UNSIGNED_LONG:
63 case typelib_TypeClass_CHAR:
64 case typelib_TypeClass_ENUM:
65 sig.append('i');
66 break;
67 case typelib_TypeClass_HYPER:
68 case typelib_TypeClass_UNSIGNED_HYPER:
69 sig.append('j');
70 break;
71 case typelib_TypeClass_FLOAT:
72 sig.append('f');
73 break;
74 case typelib_TypeClass_DOUBLE:
75 sig.append('d');
76 break;
77 case typelib_TypeClass_STRING:
78 case typelib_TypeClass_TYPE:
79 case typelib_TypeClass_ANY:
80 case typelib_TypeClass_SEQUENCE:
81 case typelib_TypeClass_INTERFACE:
82 sig.append("vi");
83 args.push_back(reinterpret_cast<sal_uInt32>(ret));
84 break;
85 case typelib_TypeClass_STRUCT:
87 switch (abi_wasm::getKind(
88 reinterpret_cast<typelib_CompoundTypeDescription const*>(rtd.get())))
90 case abi_wasm::StructKind::Empty:
91 break;
92 case abi_wasm::StructKind::I32:
93 sig.append('i');
94 break;
95 case abi_wasm::StructKind::I64:
96 sig.append('j');
97 break;
98 case abi_wasm::StructKind::F32:
99 sig.append('f');
100 break;
101 case abi_wasm::StructKind::F64:
102 sig.append('d');
103 break;
104 case abi_wasm::StructKind::General:
105 sig.append("vi");
106 args.push_back(reinterpret_cast<sal_uInt32>(ret));
107 break;
109 break;
111 default:
112 O3TL_UNREACHABLE;
114 sig.append('i');
115 sal_uInt32 const* const* thisPtr
116 = reinterpret_cast<sal_uInt32 const* const*>(proxy->getCppI()) + slot.offset;
117 args.push_back(reinterpret_cast<sal_uInt32>(thisPtr));
118 std::vector<void*> cppArgs(count);
119 std::vector<css::uno::TypeDescription> ptds(count);
120 for (sal_Int32 i = 0; i != count; ++i)
122 if (!parameters[i].bOut && bridges::cpp_uno::shared::isSimpleType(parameters[i].pTypeRef))
124 switch (parameters[i].pTypeRef->eTypeClass)
126 case typelib_TypeClass_BOOLEAN:
127 sig.append('i');
128 args.push_back(*reinterpret_cast<sal_Bool const*>(arguments[i]));
129 break;
130 case typelib_TypeClass_BYTE:
131 sig.append('i');
132 args.push_back(*reinterpret_cast<sal_Int8 const*>(arguments[i]));
133 break;
134 case typelib_TypeClass_SHORT:
135 sig.append('i');
136 args.push_back(*reinterpret_cast<sal_Int16 const*>(arguments[i]));
137 break;
138 case typelib_TypeClass_UNSIGNED_SHORT:
139 sig.append('i');
140 args.push_back(*reinterpret_cast<sal_uInt16 const*>(arguments[i]));
141 break;
142 case typelib_TypeClass_LONG:
143 case typelib_TypeClass_ENUM:
144 sig.append('i');
145 args.push_back(*reinterpret_cast<sal_Int32 const*>(arguments[i]));
146 break;
147 case typelib_TypeClass_UNSIGNED_LONG:
148 sig.append('i');
149 args.push_back(*reinterpret_cast<sal_uInt32 const*>(arguments[i]));
150 break;
151 case typelib_TypeClass_HYPER:
152 sig.append('j');
153 args.push_back(*reinterpret_cast<sal_Int64 const*>(arguments[i]));
154 break;
155 case typelib_TypeClass_UNSIGNED_HYPER:
156 sig.append('j');
157 args.push_back(*reinterpret_cast<sal_uInt64 const*>(arguments[i]));
158 break;
159 case typelib_TypeClass_FLOAT:
160 sig.append('f');
161 args.push_back(*reinterpret_cast<sal_uInt32 const*>(arguments[i]));
162 break;
163 case typelib_TypeClass_DOUBLE:
164 sig.append('d');
165 args.push_back(*reinterpret_cast<sal_uInt64 const*>(arguments[i]));
166 break;
167 case typelib_TypeClass_CHAR:
168 sig.append('i');
169 args.push_back(*reinterpret_cast<sal_Unicode const*>(arguments[i]));
170 break;
171 default:
172 O3TL_UNREACHABLE;
175 else
177 sig.append('i');
178 css::uno::TypeDescription ptd(parameters[i].pTypeRef);
179 if (!parameters[i].bIn)
181 cppArgs[i] = alloca(ptd.get()->nSize);
182 uno_constructData(cppArgs[i], ptd.get());
183 ptds[i] = ptd;
184 args.push_back(reinterpret_cast<sal_uInt32>(cppArgs[i]));
186 else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd.get()))
188 cppArgs[i] = alloca(ptd.get()->nSize);
189 uno_copyAndConvertData(cppArgs[i], arguments[i], ptd.get(),
190 proxy->getBridge()->getUno2Cpp());
191 ptds[i] = ptd;
192 args.push_back(reinterpret_cast<sal_uInt32>(cppArgs[i]));
194 else
196 args.push_back(reinterpret_cast<sal_uInt32>(arguments[i]));
204 callVirtualFunction(sig, (*thisPtr)[slot.index], args.data(), ret);
206 catch (css::uno::Exception&)
208 throw;
210 catch (std::exception& e)
212 throw css::uno::RuntimeException("C++ code threw "
213 + o3tl::runtimeToOUString(typeid(e).name()) + ": "
214 + o3tl::runtimeToOUString(e.what()));
216 catch (...)
218 throw css::uno::RuntimeException("C++ code threw unknown exception");
221 catch (css::uno::Exception&)
223 __cxxabiv1::__cxa_exception* header
224 = reinterpret_cast<__cxxabiv1::__cxa_eh_globals*>(__cxxabiv1::__cxa_get_globals())
225 ->caughtExceptions;
226 abi_wasm::mapException(header, __cxxabiv1::__cxa_current_exception_type(), *exception,
227 proxy->getBridge()->getCpp2Uno());
228 for (sal_Int32 i = 0; i != count; ++i)
230 if (cppArgs[i] != nullptr)
232 uno_destructData(cppArgs[i], ptds[i].get(),
233 reinterpret_cast<uno_ReleaseFunc>(css::uno::cpp_release));
236 return;
238 *exception = nullptr;
239 for (sal_Int32 i = 0; i != count; ++i)
241 if (cppArgs[i] != nullptr)
243 if (parameters[i].bOut)
245 if (parameters[i].bIn)
247 uno_destructData(arguments[i], ptds[i].get(), nullptr);
249 uno_copyAndConvertData(arguments[i], cppArgs[i], ptds[i].get(),
250 proxy->getBridge()->getCpp2Uno());
252 uno_destructData(cppArgs[i], ptds[i].get(),
253 reinterpret_cast<uno_ReleaseFunc>(css::uno::cpp_release));
256 if (retConv)
258 uno_copyAndConvertData(returnValue, ret, rtd.get(), proxy->getBridge()->getCpp2Uno());
259 uno_destructData(ret, rtd.get(), reinterpret_cast<uno_ReleaseFunc>(css::uno::cpp_release));
264 namespace bridges::cpp_uno::shared
266 void unoInterfaceProxyDispatch(uno_Interface* pUnoI, const typelib_TypeDescription* pMemberDescr,
267 void* pReturn, void* pArgs[], uno_Any** ppException)
269 bridges::cpp_uno::shared::UnoInterfaceProxy* pThis
270 = static_cast<bridges::cpp_uno::shared::UnoInterfaceProxy*>(pUnoI);
272 switch (pMemberDescr->eTypeClass)
274 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
276 auto const atd
277 = reinterpret_cast<typelib_InterfaceAttributeTypeDescription const*>(pMemberDescr);
278 VtableSlot slot(getVtableSlot(atd));
279 if (pReturn == nullptr)
281 slot.index += 1;
282 call(pThis, slot, cppu::UnoType<void>::get().getTypeLibType(), 1,
283 &o3tl::temporary(
284 typelib_MethodParameter{ nullptr, atd->pAttributeTypeRef, true, false }),
285 pReturn, pArgs, ppException);
287 else
289 call(pThis, slot, atd->pAttributeTypeRef, 0, nullptr, pReturn, pArgs, ppException);
291 break;
293 case typelib_TypeClass_INTERFACE_METHOD:
295 VtableSlot aVtableSlot(getVtableSlot(
296 reinterpret_cast<typelib_InterfaceMethodTypeDescription const*>(pMemberDescr)));
298 switch (aVtableSlot.index)
300 case 1: // acquire uno interface
301 (*pUnoI->acquire)(pUnoI);
302 *ppException = 0;
303 break;
304 case 2: // release uno interface
305 (*pUnoI->release)(pUnoI);
306 *ppException = 0;
307 break;
308 case 0: // queryInterface() opt
310 typelib_TypeDescription* pTD = 0;
311 TYPELIB_DANGER_GET(
312 &pTD, reinterpret_cast<css::uno::Type*>(pArgs[0])->getTypeLibType());
313 if (pTD)
315 uno_Interface* pInterface = 0;
316 (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
317 pThis->getBridge()->getUnoEnv(), (void**)&pInterface, pThis->oid.pData,
318 (typelib_InterfaceTypeDescription*)pTD);
320 if (pInterface)
322 ::uno_any_construct(reinterpret_cast<uno_Any*>(pReturn), &pInterface,
323 pTD, 0);
324 (*pInterface->release)(pInterface);
325 TYPELIB_DANGER_RELEASE(pTD);
326 *ppException = 0;
327 break;
329 TYPELIB_DANGER_RELEASE(pTD);
331 } // else perform queryInterface()
332 [[fallthrough]];
333 default:
335 auto const mtd
336 = reinterpret_cast<typelib_InterfaceMethodTypeDescription const*>(
337 pMemberDescr);
338 call(pThis, aVtableSlot, mtd->pReturnTypeRef, mtd->nParams, mtd->pParams,
339 pReturn, pArgs, ppException);
342 break;
344 default:
346 ::com::sun::star::uno::RuntimeException aExc(
347 "illegal member type description!",
348 ::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface>());
350 css::uno::Type const& rExcType = cppu::UnoType<decltype(aExc)>::get();
351 // binary identical null reference
352 ::uno_type_any_construct(*ppException, &aExc, rExcType.getTypeLibType(), 0);
357 } // namespace bridges::cpp_uno::shared
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */