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 #ifndef _PYUNO_IMPL_ 24 #define _PYUNO_IMPL_ 25 26 #include <pyuno/pyuno.hxx> 27 28 #include <hash_map> 29 #include <hash_set> 30 31 #include <com/sun/star/beans/XIntrospection.hpp> 32 #include <com/sun/star/script/XTypeConverter.hpp> 33 #include <com/sun/star/script/XInvocation2.hpp> 34 #include <com/sun/star/script/XInvocationAdapterFactory2.hpp> 35 36 #include <com/sun/star/reflection/XIdlReflection.hpp> 37 38 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 39 40 #include <com/sun/star/lang/XUnoTunnel.hpp> 41 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 42 43 #include <cppuhelper/implbase2.hxx> 44 #include <cppuhelper/weakref.hxx> 45 46 // 47 // Local workarounds for compatibility issues 48 // 49 #if PY_MAJOR_VERSION >= 3 50 #define PYSTR_FROMSTR PyUnicode_FromString 51 #define USTR_TO_PYSTR ustring2PyUnicode 52 #define PYSTR_CHECK PyUnicode_Check 53 #else 54 #define PYSTR_FROMSTR PyBytes_FromString 55 #define USTR_TO_PYSTR ustring2PyString 56 #define PYSTR_CHECK PyBytes_Check 57 #endif 58 59 #include <rtl/string.hxx> 60 inline void PyErr_SetString( PyObject* pyObj, const rtl::OString& rName) { PyErr_SetString( pyObj, rName.getStr());} 61 62 namespace pyuno 63 { 64 65 //-------------------------------------------------- 66 // Logging API - implementation can be found in pyuno_util 67 //-------------------------------------------------- 68 struct RuntimeCargo; 69 namespace LogLevel 70 { 71 // when you add a loglevel, extend the log function ! 72 static const sal_Int32 NONE = 0; 73 static const sal_Int32 CALL = 1; 74 static const sal_Int32 ARGS = 2; 75 } 76 77 bool isLog( RuntimeCargo *cargo, sal_Int32 loglevel ); 78 void log( RuntimeCargo *cargo, sal_Int32 level, const rtl::OUString &logString ); 79 void log( RuntimeCargo *cargo, sal_Int32 level, const char *str ); 80 void logCall( RuntimeCargo *cargo, const char *intro, 81 void * ptr, const rtl::OUString & aFunctionName, 82 const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args ); 83 void logReply( RuntimeCargo *cargo, const char *intro, 84 void * ptr, const rtl::OUString & aFunctionName, 85 const com::sun::star::uno::Any &returnValue, 86 const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args ); 87 void logException( RuntimeCargo *cargo, const char *intro, 88 void * ptr, const rtl::OUString &aFunctionName, 89 const void * data, const com::sun::star::uno::Type & type ); 90 static const sal_Int32 VAL2STR_MODE_DEEP = 0; 91 static const sal_Int32 VAL2STR_MODE_SHALLOW = 1; 92 rtl::OUString val2str( const void * pVal, typelib_TypeDescriptionReference * pTypeRef, sal_Int32 mode = VAL2STR_MODE_DEEP ) SAL_THROW( () ); 93 //-------------------------------------------------- 94 95 typedef ::std::hash_map 96 < 97 PyRef, 98 com::sun::star::uno::WeakReference< com::sun::star::script::XInvocation >, 99 PyRef::Hash, 100 std::equal_to< PyRef > 101 > PyRef2Adapter; 102 103 104 typedef ::std::hash_map 105 < 106 rtl::OUString, 107 PyRef, 108 rtl::OUStringHash, 109 std::equal_to<rtl::OUString> 110 > ExceptionClassMap; 111 112 typedef ::std::hash_map 113 < 114 rtl::OUString, 115 com::sun::star::uno::Sequence< sal_Int16 >, 116 rtl::OUStringHash, 117 std::equal_to< rtl::OUString > 118 > MethodOutIndexMap; 119 120 typedef ::std::hash_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet; 121 122 PyObject* PyUNO_new( 123 const com::sun::star::uno::Any & targetInterface, 124 const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf); 125 126 PyObject* PyUNO_new_UNCHECKED ( 127 const com::sun::star::uno::Any & targetInterface, 128 const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf); 129 130 typedef struct 131 { 132 com::sun::star::uno::Reference <com::sun::star::script::XInvocation2> xInvocation; 133 com::sun::star::uno::Any wrappedObject; 134 } PyUNOInternals; 135 136 typedef struct 137 { 138 PyObject_HEAD 139 PyUNOInternals* members; 140 } PyUNO; 141 142 PyRef ustring2PyUnicode( const rtl::OUString &source ); 143 PyRef ustring2PyString( const ::rtl::OUString & source ); 144 rtl::OUString pyString2ustring( PyObject *str ); 145 146 147 PyRef AnyToPyObject (const com::sun::star::uno::Any & a, const Runtime &r ) 148 throw ( com::sun::star::uno::RuntimeException ); 149 150 com::sun::star::uno::Any PyObjectToAny (PyObject* o) 151 throw ( com::sun::star::uno::RuntimeException ); 152 153 void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime ) 154 throw ( com::sun::star::reflection::InvocationTargetException ); 155 156 // bool CheckPyObjectTypes (PyObject* o, Sequence<Type> types); 157 // bool CheckPyObjectType (PyObject* o, Type type); //Only check 1 object. 158 159 com::sun::star::uno::TypeClass StringToTypeClass (char* string); 160 161 PyRef PyUNO_callable_new ( 162 const com::sun::star::uno::Reference<com::sun::star::script::XInvocation2> &xInv, 163 const rtl::OUString &methodName, 164 ConversionMode mode = REJECT_UNO_ANY ); 165 166 PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r ); 167 PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r ); 168 PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r); 169 PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r ); 170 171 PyObject *importToGlobal( PyObject *typeName, PyObject *dict, PyObject *targetName ); 172 173 PyRef getTypeClass( const Runtime &); 174 PyRef getEnumClass( const Runtime &); 175 PyRef getBoolClass( const Runtime &); 176 PyRef getCharClass( const Runtime &); 177 PyRef getByteSequenceClass( const Runtime & ); 178 PyRef getPyUnoClass(); 179 PyRef getClass( const rtl::OUString & name , const Runtime & runtime ); 180 PyRef getAnyClass( const Runtime &); 181 PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args ); 182 183 com::sun::star::uno::Any PyEnum2Enum( PyObject *obj ) 184 throw ( com::sun::star::uno::RuntimeException ); 185 sal_Bool PyBool2Bool( PyObject *o, const Runtime & r ) 186 throw ( com::sun::star::uno::RuntimeException ); 187 sal_Unicode PyChar2Unicode( PyObject *o ) 188 throw ( com::sun::star::uno::RuntimeException ); 189 com::sun::star::uno::Type PyType2Type( PyObject * o ) 190 throw( com::sun::star::uno::RuntimeException ); 191 192 void raisePyExceptionWithAny( const com::sun::star::uno::Any &a ); 193 const char *typeClassToString( com::sun::star::uno::TypeClass t ); 194 195 PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object ) 196 throw ( com::sun::star::uno::RuntimeException ); 197 198 sal_Bool isInterfaceClass( const Runtime &, PyObject *obj ); 199 bool isInstanceOfStructOrException( PyObject *obj); 200 com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces( 201 const Runtime & runtime, PyObject *obj ); 202 203 struct RuntimeCargo 204 { 205 com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation; 206 com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter; 207 com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext; 208 com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection; 209 com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr; 210 com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory; 211 com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection; 212 PyRef dictUnoModule; 213 bool valid; 214 ExceptionClassMap exceptionMap; 215 ClassSet interfaceSet; 216 PyRef2Adapter mappedObjects; 217 FILE *logFile; 218 sal_Int32 logLevel; 219 220 PyRef getUnoModule(); 221 }; 222 223 struct stRuntimeImpl 224 { 225 PyObject_HEAD 226 struct RuntimeCargo *cargo; 227 public: 228 static void del( PyObject *self ); 229 230 static PyRef create( 231 const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext ) 232 throw ( com::sun::star::uno::RuntimeException ); 233 }; 234 235 236 class Adapter : public cppu::WeakImplHelper2< 237 com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel > 238 { 239 PyRef mWrappedObject; 240 PyInterpreterState *mInterpreter; // interpreters don't seem to be refcounted ! 241 com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes; 242 MethodOutIndexMap m_methodOutIndexMap; 243 244 private: 245 com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const rtl::OUString & functionName ); 246 247 public: 248 public: 249 Adapter( const PyRef &obj, 250 const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types ); 251 252 static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId(); 253 PyRef getWrappedObject() { return mWrappedObject; } 254 com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; } 255 virtual ~Adapter(); 256 257 // XInvocation 258 virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess > 259 SAL_CALL getIntrospection( ) throw (::com::sun::star::uno::RuntimeException); 260 virtual ::com::sun::star::uno::Any SAL_CALL invoke( 261 const ::rtl::OUString& aFunctionName, 262 const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams, 263 ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex, 264 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam ) 265 throw (::com::sun::star::lang::IllegalArgumentException, 266 ::com::sun::star::script::CannotConvertException, 267 ::com::sun::star::reflection::InvocationTargetException, 268 ::com::sun::star::uno::RuntimeException); 269 270 virtual void SAL_CALL setValue( 271 const ::rtl::OUString& aPropertyName, 272 const ::com::sun::star::uno::Any& aValue ) 273 throw (::com::sun::star::beans::UnknownPropertyException, 274 ::com::sun::star::script::CannotConvertException, 275 ::com::sun::star::reflection::InvocationTargetException, 276 ::com::sun::star::uno::RuntimeException); 277 278 virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) 279 throw (::com::sun::star::beans::UnknownPropertyException, 280 ::com::sun::star::uno::RuntimeException); 281 virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) 282 throw (::com::sun::star::uno::RuntimeException); 283 virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) 284 throw (::com::sun::star::uno::RuntimeException); 285 286 // XUnoTunnel 287 virtual sal_Int64 SAL_CALL getSomething( 288 const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) 289 throw (::com::sun::star::uno::RuntimeException); 290 }; 291 292 293 /** releases a refcount on the interpreter object and on another given python object. 294 295 The function can be called from any thread regardless of whether the global 296 interpreter lock is held. 297 298 */ 299 void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object ); 300 301 } 302 303 #endif 304