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