1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #include "pyuno_impl.hxx" 24 25 #include <osl/thread.h> 26 #include <rtl/ustrbuf.hxx> 27 28 using rtl::OUStringToOString; 29 using rtl::OUString; 30 using com::sun::star::uno::Sequence; 31 using com::sun::star::uno::Reference; 32 using com::sun::star::uno::XInterface; 33 using com::sun::star::uno::Any; 34 using com::sun::star::uno::Type; 35 using com::sun::star::uno::TypeClass; 36 using com::sun::star::uno::RuntimeException; 37 using com::sun::star::uno::XComponentContext; 38 using com::sun::star::lang::XSingleServiceFactory; 39 using com::sun::star::script::XTypeConverter; 40 using com::sun::star::script::XInvocation2; 41 42 namespace pyuno 43 { 44 typedef struct 45 { 46 Reference<XInvocation2> xInvocation; 47 Reference<XSingleServiceFactory> xInvocationFactory; 48 Reference<XTypeConverter> xTypeConverter; 49 OUString methodName; 50 ConversionMode mode; 51 } PyUNO_callable_Internals; 52 53 typedef struct 54 { 55 PyObject_HEAD 56 PyUNO_callable_Internals* members; 57 } PyUNO_callable; 58 59 void PyUNO_callable_del (PyObject* self) 60 { 61 PyUNO_callable* me; 62 63 me = (PyUNO_callable*) self; 64 delete me->members; 65 PyObject_Del (self); 66 67 return; 68 } 69 70 PyObject* PyUNO_callable_call (PyObject* self, PyObject* args, PyObject*) 71 { 72 PyUNO_callable* me; 73 74 Sequence<short> aOutParamIndex; 75 Sequence<Any> aOutParam; 76 Sequence<Any> aParams; 77 Sequence<Type> aParamTypes; 78 Any any_params; 79 Any out_params; 80 Any ret_value; 81 RuntimeCargo *cargo = 0; 82 me = (PyUNO_callable*) self; 83 84 PyRef ret; 85 try 86 { 87 Runtime runtime; 88 cargo = runtime.getImpl()->cargo; 89 any_params = runtime.pyObject2Any (args, me->members->mode); 90 91 if (any_params.getValueTypeClass () == com::sun::star::uno::TypeClass_SEQUENCE) 92 { 93 any_params >>= aParams; 94 } 95 else 96 { 97 aParams.realloc (1); 98 aParams [0] <<= any_params; 99 } 100 101 { 102 PyThreadDetach antiguard; //pyhton free zone 103 104 // do some logging if desired ... 105 if( isLog( cargo, LogLevel::CALL ) ) 106 { 107 logCall( cargo, "try py->uno[0x", me->members->xInvocation.get(), 108 me->members->methodName, aParams ); 109 } 110 111 // do the call 112 ret_value = me->members->xInvocation->invoke ( 113 me->members->methodName, aParams, aOutParamIndex, aOutParam); 114 115 // log the reply, if desired 116 if( isLog( cargo, LogLevel::CALL ) ) 117 { 118 logReply( cargo, "success py->uno[0x", me->members->xInvocation.get(), 119 me->members->methodName, ret_value, aOutParam); 120 } 121 } 122 123 124 PyRef temp = runtime.any2PyObject (ret_value); 125 if( aOutParam.getLength() ) 126 { 127 PyRef return_list( PyTuple_New (1+aOutParam.getLength()), SAL_NO_ACQUIRE ); 128 PyTuple_SetItem (return_list.get(), 0, temp.getAcquired()); 129 130 // initialize with defaults in case of exceptions 131 int i; 132 for( i = 1 ; i < 1+aOutParam.getLength() ; i ++ ) 133 { 134 Py_INCREF( Py_None ); 135 PyTuple_SetItem( return_list.get() , i , Py_None ); 136 } 137 138 for( i = 0 ; i < aOutParam.getLength() ; i ++ ) 139 { 140 PyRef ref = runtime.any2PyObject( aOutParam[i] ); 141 PyTuple_SetItem (return_list.get(), 1+i, ref.getAcquired()); 142 } 143 ret = return_list; 144 } 145 else 146 { 147 ret = temp; 148 } 149 } 150 catch( com::sun::star::reflection::InvocationTargetException & e ) 151 { 152 153 if( isLog( cargo, LogLevel::CALL ) ) 154 { 155 logException( cargo, "except py->uno[0x", me->members->xInvocation.get() , 156 me->members->methodName, e.TargetException.getValue(), e.TargetException.getValueTypeRef()); 157 } 158 raisePyExceptionWithAny( e.TargetException ); 159 } 160 catch( com::sun::star::script::CannotConvertException &e ) 161 { 162 if( isLog( cargo, LogLevel::CALL ) ) 163 { 164 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() , 165 me->members->methodName, &e, getCppuType(&e).getTypeLibType()); 166 } 167 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); 168 } 169 catch( com::sun::star::lang::IllegalArgumentException &e ) 170 { 171 if( isLog( cargo, LogLevel::CALL ) ) 172 { 173 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() , 174 me->members->methodName, &e, getCppuType(&e).getTypeLibType()); 175 } 176 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); 177 } 178 catch (::com::sun::star::uno::RuntimeException &e) 179 { 180 if( cargo && isLog( cargo, LogLevel::CALL ) ) 181 { 182 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() , 183 me->members->methodName, &e, getCppuType(&e).getTypeLibType()); 184 } 185 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); 186 } 187 188 return ret.getAcquired(); 189 } 190 191 192 static PyTypeObject PyUNO_callable_Type = 193 { 194 PyVarObject_HEAD_INIT(&PyType_Type, 0) 195 const_cast< char * >("PyUNO_callable"), 196 sizeof (PyUNO_callable), 197 0, 198 (destructor) ::pyuno::PyUNO_callable_del, 199 (printfunc) 0, 200 (getattrfunc) 0, 201 (setattrfunc) 0, 202 #if PY_MAJOR_VERSION >= 3 203 0, 204 #else 205 (cmpfunc) 0, 206 #endif 207 (reprfunc) 0, 208 0, 209 0, 210 0, 211 (hashfunc) 0, 212 (ternaryfunc) ::pyuno::PyUNO_callable_call, 213 (reprfunc) 0, 214 (getattrofunc)0, 215 (setattrofunc)0, 216 NULL, 217 0, 218 NULL, 219 (traverseproc)0, 220 (inquiry)0, 221 (richcmpfunc)0, 222 0, 223 (getiterfunc)0, 224 (iternextfunc)0, 225 NULL, 226 NULL, 227 NULL, 228 NULL, 229 NULL, 230 (descrgetfunc)0, 231 (descrsetfunc)0, 232 0, 233 (initproc)0, 234 (allocfunc)0, 235 (newfunc)0, 236 (freefunc)0, 237 (inquiry)0, 238 NULL, 239 NULL, 240 NULL, 241 NULL, 242 NULL, 243 (destructor)0 244 #if PY_VERSION_HEX >= 0x02060000 245 , 0 246 #endif 247 }; 248 249 PyRef PyUNO_callable_new ( 250 const Reference<XInvocation2> &my_inv, 251 const OUString & methodName, 252 const Reference<XSingleServiceFactory> &xInvocationFactory, 253 const Reference<XTypeConverter> &tc, 254 enum ConversionMode mode ) 255 { 256 PyUNO_callable* self; 257 258 self = PyObject_New (PyUNO_callable, &PyUNO_callable_Type); 259 if (self == NULL) 260 return NULL; //NULL == Error! 261 262 self->members = new PyUNO_callable_Internals; 263 self->members->xInvocation = my_inv; 264 self->members->methodName = methodName; 265 self->members->xInvocationFactory = xInvocationFactory; 266 self->members->xTypeConverter = tc; 267 self->members->mode = mode; 268 269 return PyRef( (PyObject*)self, SAL_NO_ACQUIRE ); 270 } 271 272 } 273