Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / pyuno / source / module / pyuno_callable.cxx
blob24bce95e6c3366cc9f24d458ae2b1f6b1f08f92d
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>
22 #include <osl/thread.h>
23 #include <rtl/ustrbuf.hxx>
25 using com::sun::star::uno::Sequence;
26 using com::sun::star::uno::Reference;
27 using com::sun::star::uno::Any;
28 using com::sun::star::uno::RuntimeException;
29 using com::sun::star::script::XInvocation2;
31 namespace pyuno
33 typedef struct
35 Reference<XInvocation2> xInvocation;
36 OUString methodName;
37 ConversionMode mode;
38 } PyUNO_callable_Internals;
40 typedef struct
42 PyObject_HEAD
43 PyUNO_callable_Internals* members;
44 } PyUNO_callable;
46 void PyUNO_callable_del (PyObject* self)
48 PyUNO_callable* me;
50 me = reinterpret_cast<PyUNO_callable*>(self);
51 delete me->members;
52 PyObject_Del (self);
54 return;
57 PyObject* PyUNO_callable_call(
58 PyObject* self, PyObject* args, SAL_UNUSED_PARAMETER PyObject*)
60 PyUNO_callable* me;
62 Sequence<short> aOutParamIndex;
63 Sequence<Any> aOutParam;
64 Sequence<Any> aParams;
65 Any any_params;
66 Any ret_value;
67 RuntimeCargo *cargo = nullptr;
68 me = reinterpret_cast<PyUNO_callable*>(self);
70 PyRef ret;
71 try
73 Runtime runtime;
74 cargo = runtime.getImpl()->cargo;
75 any_params = runtime.pyObject2Any (args, me->members->mode);
77 if (any_params.getValueTypeClass () == css::uno::TypeClass_SEQUENCE)
79 any_params >>= aParams;
81 else
83 aParams.realloc (1);
84 aParams [0] <<= any_params;
88 PyThreadDetach antiguard; //python free zone
90 // do some logging if desired ...
91 if( isLog( cargo, LogLevel::CALL ) )
93 logCall( cargo, "try py->uno[0x", me->members->xInvocation.get(),
94 me->members->methodName, aParams );
97 // do the call
98 ret_value = me->members->xInvocation->invoke (
99 me->members->methodName, aParams, aOutParamIndex, aOutParam);
101 // log the reply, if desired
102 if( isLog( cargo, LogLevel::CALL ) )
104 logReply( cargo, "success py->uno[0x", me->members->xInvocation.get(),
105 me->members->methodName, ret_value, aOutParam);
110 PyRef temp = runtime.any2PyObject (ret_value);
111 if( aOutParam.getLength() )
113 PyRef return_list( PyTuple_New (1+aOutParam.getLength()), SAL_NO_ACQUIRE, NOT_NULL );
114 PyTuple_SetItem (return_list.get(), 0, temp.getAcquired());
116 // initialize with defaults in case of exceptions
117 int i;
118 for( i = 1 ; i < 1+aOutParam.getLength() ; i ++ )
120 Py_INCREF( Py_None );
121 PyTuple_SetItem( return_list.get() , i , Py_None );
124 for( i = 0 ; i < aOutParam.getLength() ; i ++ )
126 PyRef ref = runtime.any2PyObject( aOutParam[i] );
127 PyTuple_SetItem (return_list.get(), 1+i, ref.getAcquired());
129 ret = return_list;
131 else
133 ret = temp;
136 catch( const css::reflection::InvocationTargetException & e )
139 if( isLog( cargo, LogLevel::CALL ) )
141 logException( cargo, "except py->uno[0x", me->members->xInvocation.get() ,
142 me->members->methodName, e.TargetException.getValue(), e.TargetException.getValueTypeRef());
144 raisePyExceptionWithAny( e.TargetException );
146 catch( const css::script::CannotConvertException &e )
148 if( isLog( cargo, LogLevel::CALL ) )
150 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
151 me->members->methodName, &e, cppu::UnoType<decltype(e)>::get().getTypeLibType());
153 raisePyExceptionWithAny( css::uno::makeAny( e ) );
155 catch( const css::lang::IllegalArgumentException &e )
157 if( isLog( cargo, LogLevel::CALL ) )
159 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
160 me->members->methodName, &e, cppu::UnoType<decltype(e)>::get().getTypeLibType());
162 raisePyExceptionWithAny( css::uno::makeAny( e ) );
164 catch (const css::uno::RuntimeException &e)
166 if( cargo && isLog( cargo, LogLevel::CALL ) )
168 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
169 me->members->methodName, &e, cppu::UnoType<decltype(e)>::get().getTypeLibType());
171 raisePyExceptionWithAny( css::uno::makeAny( e ) );
174 return ret.getAcquired();
178 static PyTypeObject PyUNO_callable_Type =
180 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
181 "PyUNO_callable",
182 sizeof (PyUNO_callable),
184 ::pyuno::PyUNO_callable_del,
185 nullptr,
186 nullptr,
187 nullptr,
188 nullptr,
189 nullptr,
190 nullptr,
191 nullptr,
192 nullptr,
193 nullptr,
194 ::pyuno::PyUNO_callable_call,
195 nullptr,
196 nullptr,
197 nullptr,
198 nullptr,
200 nullptr,
201 nullptr,
202 nullptr,
203 nullptr,
205 nullptr,
206 nullptr,
207 nullptr,
208 nullptr,
209 nullptr,
210 nullptr,
211 nullptr,
212 nullptr,
213 nullptr,
215 nullptr,
216 nullptr,
217 nullptr,
218 nullptr,
219 nullptr,
220 nullptr,
221 nullptr,
222 nullptr,
223 nullptr,
224 nullptr,
225 nullptr
226 #if PY_VERSION_HEX >= 0x02060000
228 #endif
229 #if PY_VERSION_HEX >= 0x03040000
230 , nullptr
231 #endif
234 PyRef PyUNO_callable_new (
235 const Reference<XInvocation2> &my_inv,
236 const OUString & methodName,
237 enum ConversionMode mode )
239 PyUNO_callable* self;
241 OSL_ENSURE (my_inv.is(), "XInvocation must be valid");
243 self = PyObject_New (PyUNO_callable, &PyUNO_callable_Type);
244 if (self == nullptr)
245 return nullptr; //NULL == Error!
247 self->members = new PyUNO_callable_Internals;
248 self->members->xInvocation = my_inv;
249 self->members->methodName = methodName;
250 self->members->mode = mode;
252 return PyRef( reinterpret_cast<PyObject*>(self), SAL_NO_ACQUIRE );
257 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */