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