Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 : #include "pyuno_impl.hxx"
20 :
21 : #include <osl/diagnose.h>
22 : #include <osl/thread.h>
23 : #include <rtl/ustrbuf.hxx>
24 :
25 : using com::sun::star::uno::Sequence;
26 : using com::sun::star::uno::Reference;
27 : using com::sun::star::uno::XInterface;
28 : using com::sun::star::uno::Any;
29 : using com::sun::star::uno::Type;
30 : using com::sun::star::uno::TypeClass;
31 : using com::sun::star::uno::RuntimeException;
32 : using com::sun::star::uno::XComponentContext;
33 : using com::sun::star::lang::XSingleServiceFactory;
34 : using com::sun::star::script::XTypeConverter;
35 : using com::sun::star::script::XInvocation2;
36 :
37 : namespace pyuno
38 : {
39 : typedef struct
40 474 : {
41 : Reference<XInvocation2> xInvocation;
42 : OUString methodName;
43 : ConversionMode mode;
44 474 : } PyUNO_callable_Internals;
45 :
46 : typedef struct
47 : {
48 : PyObject_HEAD
49 : PyUNO_callable_Internals* members;
50 : } PyUNO_callable;
51 :
52 474 : void PyUNO_callable_del (PyObject* self)
53 : {
54 : PyUNO_callable* me;
55 :
56 474 : me = reinterpret_cast<PyUNO_callable*>(self);
57 474 : delete me->members;
58 474 : PyObject_Del (self);
59 :
60 474 : return;
61 : }
62 :
63 474 : PyObject* PyUNO_callable_call(
64 : PyObject* self, PyObject* args, SAL_UNUSED_PARAMETER PyObject*)
65 : {
66 : PyUNO_callable* me;
67 :
68 474 : Sequence<short> aOutParamIndex;
69 948 : Sequence<Any> aOutParam;
70 948 : Sequence<Any> aParams;
71 948 : Any any_params;
72 948 : Any ret_value;
73 474 : RuntimeCargo *cargo = 0;
74 474 : me = reinterpret_cast<PyUNO_callable*>(self);
75 :
76 948 : PyRef ret;
77 : try
78 : {
79 474 : Runtime runtime;
80 474 : cargo = runtime.getImpl()->cargo;
81 474 : any_params = runtime.pyObject2Any (args, me->members->mode);
82 :
83 474 : if (any_params.getValueTypeClass () == com::sun::star::uno::TypeClass_SEQUENCE)
84 : {
85 474 : any_params >>= aParams;
86 : }
87 : else
88 : {
89 0 : aParams.realloc (1);
90 0 : aParams [0] <<= any_params;
91 : }
92 :
93 : {
94 474 : PyThreadDetach antiguard; //pyhton free zone
95 :
96 : // do some logging if desired ...
97 474 : if( isLog( cargo, LogLevel::CALL ) )
98 : {
99 0 : logCall( cargo, "try py->uno[0x", me->members->xInvocation.get(),
100 0 : me->members->methodName, aParams );
101 : }
102 :
103 : // do the call
104 1420 : ret_value = me->members->xInvocation->invoke (
105 946 : me->members->methodName, aParams, aOutParamIndex, aOutParam);
106 :
107 : // log the reply, if desired
108 472 : if( isLog( cargo, LogLevel::CALL ) )
109 : {
110 0 : logReply( cargo, "success py->uno[0x", me->members->xInvocation.get(),
111 0 : me->members->methodName, ret_value, aOutParam);
112 474 : }
113 : }
114 :
115 :
116 944 : PyRef temp = runtime.any2PyObject (ret_value);
117 472 : if( aOutParam.getLength() )
118 : {
119 0 : PyRef return_list( PyTuple_New (1+aOutParam.getLength()), SAL_NO_ACQUIRE, NOT_NULL );
120 0 : PyTuple_SetItem (return_list.get(), 0, temp.getAcquired());
121 :
122 : // initialize with defaults in case of exceptions
123 : int i;
124 0 : for( i = 1 ; i < 1+aOutParam.getLength() ; i ++ )
125 : {
126 0 : Py_INCREF( Py_None );
127 0 : PyTuple_SetItem( return_list.get() , i , Py_None );
128 : }
129 :
130 0 : for( i = 0 ; i < aOutParam.getLength() ; i ++ )
131 : {
132 0 : PyRef ref = runtime.any2PyObject( aOutParam[i] );
133 0 : PyTuple_SetItem (return_list.get(), 1+i, ref.getAcquired());
134 0 : }
135 0 : ret = return_list;
136 : }
137 : else
138 : {
139 472 : ret = temp;
140 474 : }
141 : }
142 4 : catch( const com::sun::star::reflection::InvocationTargetException & e )
143 : {
144 :
145 2 : if( isLog( cargo, LogLevel::CALL ) )
146 : {
147 0 : logException( cargo, "except py->uno[0x", me->members->xInvocation.get() ,
148 0 : me->members->methodName, e.TargetException.getValue(), e.TargetException.getValueTypeRef());
149 : }
150 2 : raisePyExceptionWithAny( e.TargetException );
151 : }
152 0 : catch( const com::sun::star::script::CannotConvertException &e )
153 : {
154 0 : if( isLog( cargo, LogLevel::CALL ) )
155 : {
156 0 : logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
157 0 : me->members->methodName, &e, cppu::UnoType<decltype(e)>::get().getTypeLibType());
158 : }
159 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
160 : }
161 0 : catch( const com::sun::star::lang::IllegalArgumentException &e )
162 : {
163 0 : if( isLog( cargo, LogLevel::CALL ) )
164 : {
165 0 : logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
166 0 : me->members->methodName, &e, cppu::UnoType<decltype(e)>::get().getTypeLibType());
167 : }
168 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
169 : }
170 0 : catch (const ::com::sun::star::uno::RuntimeException &e)
171 : {
172 0 : if( cargo && isLog( cargo, LogLevel::CALL ) )
173 : {
174 0 : logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
175 0 : me->members->methodName, &e, cppu::UnoType<decltype(e)>::get().getTypeLibType());
176 : }
177 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
178 : }
179 :
180 948 : return ret.getAcquired();
181 : }
182 :
183 :
184 : static PyTypeObject PyUNO_callable_Type =
185 : {
186 : PyVarObject_HEAD_INIT( &PyType_Type, 0 )
187 : "PyUNO_callable",
188 : sizeof (PyUNO_callable),
189 : 0,
190 : ::pyuno::PyUNO_callable_del,
191 : nullptr,
192 : nullptr,
193 : nullptr,
194 : 0,
195 : nullptr,
196 : 0,
197 : 0,
198 : 0,
199 : nullptr,
200 : ::pyuno::PyUNO_callable_call,
201 : nullptr,
202 : nullptr,
203 : nullptr,
204 : NULL,
205 : 0,
206 : NULL,
207 : nullptr,
208 : nullptr,
209 : nullptr,
210 : 0,
211 : nullptr,
212 : nullptr,
213 : NULL,
214 : NULL,
215 : NULL,
216 : NULL,
217 : NULL,
218 : nullptr,
219 : nullptr,
220 : 0,
221 : nullptr,
222 : nullptr,
223 : nullptr,
224 : nullptr,
225 : nullptr,
226 : NULL,
227 : NULL,
228 : NULL,
229 : NULL,
230 : NULL,
231 : nullptr
232 : #if PY_VERSION_HEX >= 0x02060000
233 : , 0
234 : #endif
235 : #if PY_VERSION_HEX >= 0x03040000
236 : , 0
237 : #endif
238 : };
239 :
240 474 : PyRef PyUNO_callable_new (
241 : const Reference<XInvocation2> &my_inv,
242 : const OUString & methodName,
243 : enum ConversionMode mode )
244 : {
245 : PyUNO_callable* self;
246 :
247 : OSL_ENSURE (my_inv.is(), "XInvocation must be valid");
248 :
249 474 : self = PyObject_New (PyUNO_callable, &PyUNO_callable_Type);
250 474 : if (self == NULL)
251 0 : return NULL; //NULL == Error!
252 :
253 474 : self->members = new PyUNO_callable_Internals;
254 474 : self->members->xInvocation = my_inv;
255 474 : self->members->methodName = methodName;
256 474 : self->members->mode = mode;
257 :
258 474 : return PyRef( reinterpret_cast<PyObject*>(self), SAL_NO_ACQUIRE );
259 : }
260 :
261 : }
262 :
263 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|