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