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 (cmpfunc) 0, 203 (reprfunc) 0, 204 0, 205 0, 206 0, 207 (hashfunc) 0, 208 (ternaryfunc) ::pyuno::PyUNO_callable_call, 209 (reprfunc) 0, 210 (getattrofunc)0, 211 (setattrofunc)0, 212 NULL, 213 0, 214 NULL, 215 (traverseproc)0, 216 (inquiry)0, 217 (richcmpfunc)0, 218 0, 219 (getiterfunc)0, 220 (iternextfunc)0, 221 NULL, 222 NULL, 223 NULL, 224 NULL, 225 NULL, 226 (descrgetfunc)0, 227 (descrsetfunc)0, 228 0, 229 (initproc)0, 230 (allocfunc)0, 231 (newfunc)0, 232 (freefunc)0, 233 (inquiry)0, 234 NULL, 235 NULL, 236 NULL, 237 NULL, 238 NULL, 239 (destructor)0 240 #if PY_VERSION_HEX >= 0x02060000 241 , 0 242 #endif 243 }; 244 245 PyRef PyUNO_callable_new ( 246 const Reference<XInvocation2> &my_inv, 247 const OUString & methodName, 248 const Reference<XSingleServiceFactory> &xInvocationFactory, 249 const Reference<XTypeConverter> &tc, 250 enum ConversionMode mode ) 251 { 252 PyUNO_callable* self; 253 254 self = PyObject_New (PyUNO_callable, &PyUNO_callable_Type); 255 if (self == NULL) 256 return NULL; //NULL == Error! 257 258 self->members = new PyUNO_callable_Internals; 259 self->members->xInvocation = my_inv; 260 self->members->methodName = methodName; 261 self->members->xInvocationFactory = xInvocationFactory; 262 self->members->xTypeConverter = tc; 263 self->members->mode = mode; 264 265 return PyRef( (PyObject*)self, SAL_NO_ACQUIRE ); 266 } 267 268 } 269