GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / cli_ure / source / uno_bridge / cli_uno.cxx
blobe705de141d8d81b314d572203c5534281ef4aeee
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/.
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/alloca.h>
21 #include "rtl/ustrbuf.hxx"
22 #include "cli_base.h"
23 #include "cli_bridge.h"
25 namespace sr=System::Reflection;
28 namespace cli_uno
31 union largest
33 sal_Int64 n;
34 double d;
35 void * p;
36 uno_Any a;
39 System::Object^ Bridge::call_uno(uno_Interface * pUnoI,
40 typelib_TypeDescription* member_td,
41 typelib_TypeDescriptionReference * return_type,
42 sal_Int32 nParams, typelib_MethodParameter const * pParams,
43 array<System::Object^>^ args, array<System::Type^>^ argTypes,
44 System::Object^* ppExc) const
46 // return mem
47 sal_Int32 return_size = sizeof (largest);
48 if ((0 != return_type) &&
49 (typelib_TypeClass_STRUCT == return_type->eTypeClass ||
50 typelib_TypeClass_EXCEPTION == return_type->eTypeClass))
52 TypeDescr return_td( return_type );
53 if (return_td.get()->nSize > sizeof (largest))
54 return_size = return_td.get()->nSize;
56 //Prepare memory that contains all converted arguments and return valuse
57 //The memory block contains first pointers to the arguments which are in the same block
58 // For example, 2 arguments, 1 ret.
60 // | Pointer
61 // | Pointer
62 // | Return value
63 // | Arg 1
64 // | Arg 2
66 // If an argument is larger then union largest, such as some structures, then the pointer
67 // points to an extra block of memory. The same goes for a big return value.
69 char * mem = (char *)alloca(
70 (nParams * sizeof (void *)) + return_size + (nParams * sizeof (largest)) );
71 //array of pointers to args
72 void ** uno_args = (void **)mem;
73 //If an attribute is set, then uno_ret must be null, e.g void setAttribute(int )
74 void * uno_ret= NULL;
75 if ( !(member_td->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE && nParams == 1))
76 uno_ret = (mem + (nParams * sizeof (void *)));
77 largest * uno_args_mem = (largest *)(mem + (nParams * sizeof (void *)) + return_size);
79 OSL_ASSERT( (0 == nParams) || (nParams == args->Length) );
80 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
82 typelib_MethodParameter const & param = pParams[ nPos ];
83 typelib_TypeDescriptionReference * type = param.pTypeRef;
85 uno_args[ nPos ] = &uno_args_mem[ nPos ];
86 if (typelib_TypeClass_STRUCT == type->eTypeClass ||
87 typelib_TypeClass_EXCEPTION == type->eTypeClass)
89 TypeDescr td( type );
90 if (td.get()->nSize > sizeof (largest))
91 uno_args[ nPos ] = alloca( td.get()->nSize );
94 if (param.bIn)
96 try
98 // in, in/out params
99 map_to_uno(
100 uno_args[ nPos ],args[nPos] , type, false /* no assign */);
102 catch (...)
104 // cleanup uno in args
105 for (sal_Int32 n = 0; n < nPos; ++n)
107 typelib_MethodParameter const & param = pParams[n];
108 if (param.bIn)
110 uno_type_destructData(uno_args[n], param.pTypeRef, 0);
113 throw;
117 uno_Any uno_exc_holder;
118 uno_Any * uno_exc = &uno_exc_holder;
119 // call binary uno
121 (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc );
123 if (0 == uno_exc)
125 // convert out args; destruct uno args
126 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
128 typelib_MethodParameter const & param = pParams[ nPos ];
129 typelib_TypeDescriptionReference * type = param.pTypeRef;
130 if (param.bOut)
134 pin_ptr<System::Object^> ptr = &args[nPos];
135 map_to_cli(
136 ptr, uno_args[nPos], param.pTypeRef,
137 argTypes != nullptr ? argTypes[nPos] : nullptr, false );
139 catch (...)
141 // cleanup further uno args
142 for ( sal_Int32 n = nPos; n < nParams; ++n )
144 uno_type_destructData( uno_args[n], pParams[n].pTypeRef, 0 );
146 // cleanup uno return value
147 uno_type_destructData( uno_ret, return_type, 0 );
148 throw;
151 //cleanup args
152 if (typelib_TypeClass_DOUBLE < type->eTypeClass &&
153 typelib_TypeClass_ENUM != type->eTypeClass) // opt
155 uno_type_destructData(uno_args[nPos], type, 0);
159 if ((0 != return_type) &&
160 (typelib_TypeClass_VOID != return_type->eTypeClass))
162 // convert uno return value
165 System::Object^ cli_ret;
166 map_to_cli(
167 &cli_ret, uno_ret, return_type, nullptr, false);
168 uno_type_destructData(uno_ret, return_type, 0);
169 return cli_ret;
171 catch (...)
173 uno_type_destructData(uno_ret, return_type, 0);
174 throw;
177 return nullptr; // void return
179 else // exception occurred
181 // destruct uno in args
182 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
184 typelib_MethodParameter const & param = pParams[ nPos ];
185 if (param.bIn)
187 uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 );
190 map_to_cli(ppExc, uno_exc_holder.pData,
191 uno_exc_holder.pType, nullptr, false);
192 return nullptr;
196 void Bridge::call_cli(
197 System::Object^ cliI,
198 sr::MethodInfo^ method,
199 typelib_TypeDescriptionReference * return_type,
200 typelib_MethodParameter * params, int nParams,
201 void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const
203 array<System::Object^>^ args= gcnew array<System::Object^>(nParams);
204 for (int nPos= 0; nPos < nParams; nPos++)
206 typelib_MethodParameter const & param= params[nPos];
207 if (param.bIn)
209 pin_ptr<System::Object^> ptr = &args[nPos];
210 map_to_cli( ptr,
211 uno_args[nPos], param.pTypeRef, nullptr, false);
214 System::Object^ retInvoke= nullptr;
217 retInvoke= method->Invoke(cliI, args);
219 catch (sr::TargetInvocationException^ e)
221 System::Exception^ exc= e->InnerException;
222 css::uno::TypeDescription td(mapCliType(exc->GetType()));
223 // memory for exception
224 std::auto_ptr< rtl_mem > memExc(rtl_mem::allocate(td.get()->nSize));
225 map_to_uno(memExc.get(), exc, td.get()->pWeakRef, false);
226 (*uno_exc)->pType= td.get()->pWeakRef;
227 (*uno_exc)->pData= memExc.release();
228 return;
230 catch (System::Exception^ e)
232 OUStringBuffer buf( 128 );
233 buf.append( "Unexpected exception during invocation of cli object. "
234 "Original message is: \n" );
235 buf.append(mapCliString(e->Message));
236 throw BridgeRuntimeError( buf.makeStringAndClear() );
239 //convert out, in/out params
240 for (int nPos = 0; nPos < nParams; ++nPos )
242 typelib_MethodParameter const & param = params[ nPos ];
244 if (param.bOut)
248 map_to_uno(
249 uno_args[ nPos ], args[ nPos ], param.pTypeRef,
250 sal_True == param.bIn /* assign if inout */);
251 // out array
253 catch (...)
255 // cleanup uno pure out
256 for ( sal_Int32 n = 0; n < nPos; ++n )
258 typelib_MethodParameter const & param = params[ n ];
259 if (! param.bIn)
260 uno_type_destructData( uno_args[ n ], param.pTypeRef, 0 );
262 throw;
266 // return value
267 if (0 != return_type)
269 map_to_uno(
270 uno_ret, retInvoke, return_type, false /* no assign */);
272 // no exception occurred
273 *uno_exc = 0;
281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */