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>
PyErr_SetString(PyObject * pyObj,const rtl::OString & rName)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();
getWrappedObject()237 PyRef getWrappedObject() { return mWrappedObject; }
getWrappedTypes()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