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