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