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