Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / pyuno / source / module / pyuno_callable.cxx
blob656d1c84cb0e5f0b3b139f619b2ceb039dce82d3
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 .
19 #include "pyuno_impl.hxx"
21 #include <osl/diagnose.h>
23 #include <com/sun/star/script/CannotConvertException.hpp>
24 #include <com/sun/star/script/XInvocation2.hpp>
26 using com::sun::star::uno::Sequence;
27 using com::sun::star::uno::Reference;
28 using com::sun::star::uno::Any;
29 using com::sun::star::uno::RuntimeException;
30 using com::sun::star::script::XInvocation2;
32 namespace pyuno
34 struct PyUNO_callable_Internals
36 Reference<XInvocation2> xInvocation;
37 OUString methodName;
38 ConversionMode mode;
41 struct PyUNO_callable
43 PyObject_HEAD
44 PyUNO_callable_Internals* members;
47 static void PyUNO_callable_del (PyObject* self)
49 PyUNO_callable* me;
51 me = reinterpret_cast<PyUNO_callable*>(self);
52 delete me->members;
53 PyObject_Del (self);
56 static PyObject* PyUNO_callable_call(
57 PyObject* self, PyObject* args, SAL_UNUSED_PARAMETER PyObject*)
59 PyUNO_callable* me;
61 Sequence<short> aOutParamIndex;
62 Sequence<Any> aOutParam;
63 Sequence<Any> aParams;
64 Any any_params;
65 Any ret_value;
66 RuntimeCargo *cargo = nullptr;
67 me = reinterpret_cast<PyUNO_callable*>(self);
69 PyRef ret;
70 try
72 Runtime runtime;
73 cargo = runtime.getImpl()->cargo;
74 any_params = runtime.pyObject2Any (args, me->members->mode);
76 if (any_params.getValueTypeClass () == css::uno::TypeClass_SEQUENCE)
78 any_params >>= aParams;
80 else
82 aParams.realloc (1);
83 aParams [0] = any_params;
87 PyThreadDetach antiguard; //python free zone
89 // do some logging if desired ...
90 if( isLog( cargo, LogLevel::CALL ) )
92 logCall( cargo, "try py->uno[0x", me->members->xInvocation.get(),
93 me->members->methodName, aParams );
96 // do the call
97 ret_value = me->members->xInvocation->invoke (
98 me->members->methodName, aParams, aOutParamIndex, aOutParam);
100 // log the reply, if desired
101 if( isLog( cargo, LogLevel::CALL ) )
103 logReply( cargo, "success py->uno[0x", me->members->xInvocation.get(),
104 me->members->methodName, ret_value, aOutParam);
109 PyRef temp = runtime.any2PyObject (ret_value);
110 if( aOutParam.getLength() )
112 PyRef return_list( PyTuple_New (1+aOutParam.getLength()), SAL_NO_ACQUIRE, NOT_NULL );
113 PyTuple_SetItem (return_list.get(), 0, temp.getAcquired());
115 // initialize with defaults in case of exceptions
116 int i;
117 for( i = 1 ; i < 1+aOutParam.getLength() ; i ++ )
119 Py_INCREF( Py_None );
120 PyTuple_SetItem( return_list.get() , i , Py_None );
123 for( i = 0 ; i < aOutParam.getLength() ; i ++ )
125 PyRef ref = runtime.any2PyObject( aOutParam[i] );
126 PyTuple_SetItem (return_list.get(), 1+i, ref.getAcquired());
128 ret = return_list;
130 else
132 ret = temp;
135 catch( const css::reflection::InvocationTargetException & e )
138 if( isLog( cargo, LogLevel::CALL ) )
140 logException( cargo, "except py->uno[0x", me->members->xInvocation.get() ,
141 me->members->methodName, e.TargetException.getValue(), e.TargetException.getValueTypeRef());
143 raisePyExceptionWithAny( e.TargetException );
145 catch( const css::script::CannotConvertException &e )
147 if( isLog( cargo, LogLevel::CALL ) )
149 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
150 me->members->methodName, &e, cppu::UnoType<decltype(e)>::get().getTypeLibType());
152 raisePyExceptionWithAny( css::uno::makeAny( e ) );
154 catch( const css::lang::IllegalArgumentException &e )
156 if( isLog( cargo, LogLevel::CALL ) )
158 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
159 me->members->methodName, &e, cppu::UnoType<decltype(e)>::get().getTypeLibType());
161 raisePyExceptionWithAny( css::uno::makeAny( e ) );
163 catch (const css::uno::RuntimeException &e)
165 if( cargo && isLog( cargo, LogLevel::CALL ) )
167 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
168 me->members->methodName, &e, cppu::UnoType<decltype(e)>::get().getTypeLibType());
170 raisePyExceptionWithAny( css::uno::makeAny( e ) );
173 return ret.getAcquired();
177 static PyTypeObject PyUNO_callable_Type =
179 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
180 "PyUNO_callable",
181 sizeof (PyUNO_callable),
183 ::pyuno::PyUNO_callable_del,
184 #if PY_VERSION_HEX >= 0x03080000
185 0, // Py_ssize_t tp_vectorcall_offset
186 #else
187 nullptr, // printfunc tp_print
188 #endif
189 nullptr,
190 nullptr,
191 nullptr,
192 nullptr,
193 nullptr,
194 nullptr,
195 nullptr,
196 nullptr,
197 ::pyuno::PyUNO_callable_call,
198 nullptr,
199 nullptr,
200 nullptr,
201 nullptr,
203 nullptr,
204 nullptr,
205 nullptr,
206 nullptr,
208 nullptr,
209 nullptr,
210 nullptr,
211 nullptr,
212 nullptr,
213 nullptr,
214 nullptr,
215 nullptr,
216 nullptr,
218 nullptr,
219 nullptr,
220 nullptr,
221 nullptr,
222 nullptr,
223 nullptr,
224 nullptr,
225 nullptr,
226 nullptr,
227 nullptr,
228 nullptr
230 #if PY_VERSION_HEX >= 0x03040000
231 , nullptr
232 #if PY_VERSION_HEX >= 0x03080000
233 , nullptr // vectorcallfunc tp_vectorcall
234 #endif
235 #endif
238 PyRef PyUNO_callable_new (
239 const Reference<XInvocation2> &my_inv,
240 const OUString & methodName,
241 enum ConversionMode mode )
243 PyUNO_callable* self;
245 OSL_ENSURE (my_inv.is(), "XInvocation must be valid");
247 self = PyObject_New (PyUNO_callable, &PyUNO_callable_Type);
248 if (self == nullptr)
249 return nullptr; //NULL == Error!
251 self->members = new PyUNO_callable_Internals;
252 self->members->xInvocation = my_inv;
253 self->members->methodName = methodName;
254 self->members->mode = mode;
256 return PyRef( reinterpret_cast<PyObject*>(self), SAL_NO_ACQUIRE );
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */