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 const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> &ssf, 162 const com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> &tc, 163 ConversionMode mode = REJECT_UNO_ANY ); 164 165 PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r ); 166 PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r ); 167 PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r); 168 PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r ); 169 170 PyObject *importToGlobal( PyObject *typeName, PyObject *dict, PyObject *targetName ); 171 172 PyRef getTypeClass( const Runtime &); 173 PyRef getEnumClass( const Runtime &); 174 PyRef getBoolClass( const Runtime &); 175 PyRef getCharClass( const Runtime &); 176 PyRef getByteSequenceClass( const Runtime & ); 177 PyRef getPyUnoClass(); 178 PyRef getClass( const rtl::OUString & name , const Runtime & runtime ); 179 PyRef getAnyClass( const Runtime &); 180 PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args ); 181 182 com::sun::star::uno::Any PyEnum2Enum( PyObject *obj ) 183 throw ( com::sun::star::uno::RuntimeException ); 184 sal_Bool PyBool2Bool( PyObject *o, const Runtime & r ) 185 throw ( com::sun::star::uno::RuntimeException ); 186 sal_Unicode PyChar2Unicode( PyObject *o ) 187 throw ( com::sun::star::uno::RuntimeException ); 188 com::sun::star::uno::Type PyType2Type( PyObject * o ) 189 throw( com::sun::star::uno::RuntimeException ); 190 191 void raisePyExceptionWithAny( const com::sun::star::uno::Any &a ); 192 const char *typeClassToString( com::sun::star::uno::TypeClass t ); 193 194 PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object ) 195 throw ( com::sun::star::uno::RuntimeException ); 196 197 sal_Bool isInterfaceClass( const Runtime &, PyObject *obj ); 198 bool isInstanceOfStructOrException( PyObject *obj); 199 com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces( 200 const Runtime & runtime, PyObject *obj ); 201 202 struct RuntimeCargo 203 { 204 com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation; 205 com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter; 206 com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext; 207 com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection; 208 com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr; 209 com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory; 210 com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection; 211 PyRef dictUnoModule; 212 bool valid; 213 ExceptionClassMap exceptionMap; 214 ClassSet interfaceSet; 215 PyRef2Adapter mappedObjects; 216 FILE *logFile; 217 sal_Int32 logLevel; 218 219 PyRef getUnoModule(); 220 }; 221 222 struct stRuntimeImpl 223 { 224 PyObject_HEAD 225 struct RuntimeCargo *cargo; 226 public: 227 static void del( PyObject *self ); 228 229 static PyRef create( 230 const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext ) 231 throw ( com::sun::star::uno::RuntimeException ); 232 }; 233 234 235 class Adapter : public cppu::WeakImplHelper2< 236 com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel > 237 { 238 PyRef mWrappedObject; 239 PyInterpreterState *mInterpreter; // interpreters don't seem to be refcounted ! 240 com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes; 241 MethodOutIndexMap m_methodOutIndexMap; 242 243 private: 244 com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const rtl::OUString & functionName ); 245 246 public: 247 public: 248 Adapter( const PyRef &obj, 249 const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types ); 250 251 static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId(); 252 PyRef getWrappedObject() { return mWrappedObject; } 253 com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; } 254 virtual ~Adapter(); 255 256 // XInvocation 257 virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess > 258 SAL_CALL getIntrospection( ) throw (::com::sun::star::uno::RuntimeException); 259 virtual ::com::sun::star::uno::Any SAL_CALL invoke( 260 const ::rtl::OUString& aFunctionName, 261 const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams, 262 ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex, 263 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam ) 264 throw (::com::sun::star::lang::IllegalArgumentException, 265 ::com::sun::star::script::CannotConvertException, 266 ::com::sun::star::reflection::InvocationTargetException, 267 ::com::sun::star::uno::RuntimeException); 268 269 virtual void SAL_CALL setValue( 270 const ::rtl::OUString& aPropertyName, 271 const ::com::sun::star::uno::Any& aValue ) 272 throw (::com::sun::star::beans::UnknownPropertyException, 273 ::com::sun::star::script::CannotConvertException, 274 ::com::sun::star::reflection::InvocationTargetException, 275 ::com::sun::star::uno::RuntimeException); 276 277 virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) 278 throw (::com::sun::star::beans::UnknownPropertyException, 279 ::com::sun::star::uno::RuntimeException); 280 virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) 281 throw (::com::sun::star::uno::RuntimeException); 282 virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) 283 throw (::com::sun::star::uno::RuntimeException); 284 285 // XUnoTunnel 286 virtual sal_Int64 SAL_CALL getSomething( 287 const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) 288 throw (::com::sun::star::uno::RuntimeException); 289 }; 290 291 292 /** releases a refcount on the interpreter object and on another given python object. 293 294 The function can be called from any thread regardless of whether the global 295 interpreter lock is held. 296 297 */ 298 void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object ); 299 300 } 301 302 #endif 303