/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// Convert in and inout arguments for (int i = 0; i < nParams; ++i)
{ const typelib_MethodParameter& param = pParams[i]; if (param.bIn)
{
map_uno_to_net_value(pArgs[i], &pArgsRetExc[i], param.pTypeRef, false);
}
}
// Calculate size of memory required for return value
sal_Int32 nReturnSize = sizeof(largest); if (pReturnTDRef)
{ if (pReturnTDRef->eTypeClass == typelib_TypeClass_VOID)
{
nReturnSize = 0;
} elseif (pReturnTDRef->eTypeClass == typelib_TypeClass_STRUCT
|| pReturnTDRef->eTypeClass == typelib_TypeClass_EXCEPTION)
{
TypeDescHolder returnTD(pReturnTDRef); if (o3tl::make_unsigned(returnTD.get()->nSize) > sizeof(largest))
nReturnSize = returnTD.get()->nSize;
}
}
// Prepare a memory block to contain all the converted arguments and return value // // The memory block contains pointers to small arguments stored in the same block. // If an argument is larger then `largest` union, such as a struct, then the pointer // points to an extra block of memory. // // The argument pointers are followed by the return value. If the return value is // larger than the `largest` union, this is a pointer to an extra block containing // the return value instead. // // For example: 2 arguments and return value // | Pointer 1 (void*) // | Pointer 2 (void*) // | Return Value (void*) // | Argument 1 (largest*) // | Argument 2 (largest*)
// Complete memory block char* mem = static_cast<char*>(
alloca(nParams * sizeof(void*) + nReturnSize + nParams * sizeof(largest))); // Array of argument pointers; at the start of the memory block void** uno_args = reinterpret_cast<void**>(mem); // Pointer to return value memory; after all argument pointers void* uno_ret = nReturnSize == 0 ? nullptr : mem + nParams * sizeof(void*); // Space for actual arguments; after return value
largest* uno_args_mem = reinterpret_cast<largest*>(mem + nParams * sizeof(void*) + nReturnSize);
for (sal_Int32 i = 0; i < nParams; ++i)
{ const typelib_MethodParameter& param = pParams[i];
typelib_TypeDescriptionReference* type = param.pTypeRef;
// Propagate function call to binary uno
(*pUnoI->pDispatcher)(pUnoI, pMethodTD, uno_ret, uno_args, &uno_exc);
if (!uno_exc)
{ // Convert out arguments and destruct previously converted uno args for (sal_Int32 i = 0; i < nParams; ++i)
{ const typelib_MethodParameter& param = pParams[i];
typelib_TypeDescriptionReference* type = param.pTypeRef;
if (param.bOut)
{ try
{
map_uno_to_net_value(uno_args[i], &pArgs[i], param.pTypeRef, false);
} catch (...)
{ // Cleanup rest of uno args for (sal_Int32 n = i; n < nParams; ++n)
{
uno_type_destructData(uno_args[n], pParams[n].pTypeRef, nullptr);
}
// Cleanup uno return value
uno_type_destructData(uno_ret, pReturnTDRef, nullptr);
returntrue;
} else// An exception occurred
{ // Destruct uno in arguments for (sal_Int32 i = 0; i < nParams; ++i)
{ const typelib_MethodParameter& param = pParams[i]; if (param.bIn)
{
uno_type_destructData(uno_args[i], param.pTypeRef, nullptr);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.