Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #ifndef INCLUDED_PYUNO_SOURCE_MODULE_PYUNO_IMPL_HXX
20 : #define INCLUDED_PYUNO_SOURCE_MODULE_PYUNO_IMPL_HXX
21 :
22 : #if defined(_MSC_VER)
23 : // Workaround for some horrible hypot() mess
24 : #include <math.h>
25 : #endif
26 :
27 : #include <Python.h>
28 :
29 : //Must define PyVarObject_HEAD_INIT for Python 2.5 or older
30 : #ifndef PyVarObject_HEAD_INIT
31 : #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
32 : #endif
33 :
34 : #include <pyuno/pyuno.hxx>
35 :
36 : #include <unordered_map>
37 : #include <unordered_set>
38 :
39 : #include <com/sun/star/beans/XIntrospection.hpp>
40 : #include <com/sun/star/script/XTypeConverter.hpp>
41 : #include <com/sun/star/script/XInvocation2.hpp>
42 : #include <com/sun/star/script/XInvocationAdapterFactory2.hpp>
43 :
44 : #include <com/sun/star/reflection/XIdlReflection.hpp>
45 :
46 : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
47 :
48 : #include <com/sun/star/lang/XUnoTunnel.hpp>
49 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
50 :
51 : #include <cppuhelper/implbase2.hxx>
52 : #include <cppuhelper/weakref.hxx>
53 :
54 : #include <osl/module.hxx>
55 :
56 : // In Python 3, the PyString_* functions have been replaced by PyBytes_*
57 : // and PyUnicode_* functions.
58 : #if PY_MAJOR_VERSION >= 3
59 :
60 : // compatibility wrappers for Python "str" type (PyUnicode in 3, PyString in 2)
61 819 : inline PyObject* PyStr_FromString(const char *string)
62 : {
63 819 : return PyUnicode_FromString(string);
64 : }
65 :
66 777 : inline char * PyStr_AsString(PyObject *object)
67 : {
68 777 : return PyUnicode_AsUTF8(object);
69 : }
70 :
71 1105 : inline bool PyStr_Check(PyObject *object)
72 : {
73 1105 : return PyUnicode_Check(object);
74 : }
75 :
76 : // compatibility wrappers for Python non-Unicode string/buffer type
77 : // (PyBytes in 3, PyString in 2)
78 1575 : inline bool PyStrBytes_Check(PyObject *object)
79 : {
80 1575 : return PyBytes_Check(object);
81 : }
82 :
83 0 : inline char* PyStrBytes_AsString(PyObject *object)
84 : {
85 0 : return PyBytes_AsString(object);
86 : }
87 :
88 0 : inline Py_ssize_t PyStrBytes_Size(PyObject *object)
89 : {
90 0 : return PyBytes_Size(object);
91 : }
92 :
93 2 : inline PyObject* PyStrBytes_FromStringAndSize(const char *string, Py_ssize_t len)
94 : {
95 2 : return PyBytes_FromStringAndSize(string, len);
96 : }
97 : #else
98 : inline char * PyStr_AsString(PyObject *object)
99 : {
100 : return PyString_AsString(object);
101 : }
102 :
103 : inline PyObject* PyStr_FromString(const char *string)
104 : {
105 : return PyString_FromString(string);
106 : }
107 :
108 : inline bool PyStr_Check(PyObject *object)
109 : {
110 : return PyString_Check(object);
111 : }
112 : inline bool PyStrBytes_Check(PyObject *object)
113 : {
114 : return PyString_Check(object);
115 : }
116 :
117 : inline char* PyStrBytes_AsString(PyObject *object)
118 : {
119 : return PyString_AsString(object);
120 : }
121 :
122 : inline Py_ssize_t PyStrBytes_Size(PyObject *object)
123 : {
124 : return PyString_Size(object);
125 : }
126 :
127 : inline PyObject* PyStrBytes_FromStringAndSize(const char *string, Py_ssize_t len)
128 : {
129 : return PyString_FromStringAndSize(string, len);
130 : }
131 : #endif /* PY_MAJOR_VERSION >= 3 */
132 :
133 : namespace pyuno
134 : {
135 :
136 :
137 : // Logging API - implementation can be found in pyuno_util
138 :
139 : struct RuntimeCargo;
140 : namespace LogLevel
141 : {
142 : // when you add a loglevel, extend the log function !
143 : static const sal_Int32 NONE = 0;
144 : static const sal_Int32 CALL = 1;
145 : static const sal_Int32 ARGS = 2;
146 : }
147 :
148 : bool isLog( RuntimeCargo *cargo, sal_Int32 loglevel );
149 : void log( RuntimeCargo *cargo, sal_Int32 level, const OUString &logString );
150 : void log( RuntimeCargo *cargo, sal_Int32 level, const char *str );
151 : void logCall( RuntimeCargo *cargo, const char *intro,
152 : void * ptr, const OUString & aFunctionName,
153 : const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
154 : void logReply( RuntimeCargo *cargo, const char *intro,
155 : void * ptr, const OUString & aFunctionName,
156 : const com::sun::star::uno::Any &returnValue,
157 : const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
158 : void logException( RuntimeCargo *cargo, const char *intro,
159 : void * ptr, const OUString &aFunctionName,
160 : const void * data, const com::sun::star::uno::Type & type );
161 : static const sal_Int32 VAL2STR_MODE_DEEP = 0;
162 : static const sal_Int32 VAL2STR_MODE_SHALLOW = 1;
163 : OUString val2str( const void * pVal, typelib_TypeDescriptionReference * pTypeRef, sal_Int32 mode = VAL2STR_MODE_DEEP );
164 :
165 :
166 : typedef std::unordered_map
167 : <
168 : PyRef,
169 : com::sun::star::uno::WeakReference< com::sun::star::script::XInvocation >,
170 : PyRef::Hash,
171 : std::equal_to< PyRef >
172 : > PyRef2Adapter;
173 :
174 :
175 : typedef std::unordered_map
176 : <
177 : OUString,
178 : PyRef,
179 : OUStringHash,
180 : std::equal_to<OUString>
181 : > ExceptionClassMap;
182 :
183 : typedef std::unordered_map
184 : <
185 : OUString,
186 : com::sun::star::uno::Sequence< sal_Int16 >,
187 : OUStringHash,
188 : std::equal_to< OUString >
189 : > MethodOutIndexMap;
190 :
191 : typedef std::unordered_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet;
192 :
193 : int PyUNO_initType();
194 :
195 : PyObject* PyUNO_new(
196 : const com::sun::star::uno::Any & targetInterface,
197 : const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
198 :
199 : PyObject* PyUNO_new_UNCHECKED (
200 : const com::sun::star::uno::Any & targetInterface,
201 : const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
202 :
203 : typedef struct
204 790 : {
205 : com::sun::star::uno::Reference <com::sun::star::script::XInvocation2> xInvocation;
206 : com::sun::star::uno::Any wrappedObject;
207 767 : } PyUNOInternals;
208 :
209 : typedef struct
210 : {
211 : PyObject_HEAD
212 : PyUNOInternals* members;
213 : } PyUNO;
214 :
215 : PyRef ustring2PyUnicode( const OUString &source );
216 : PyRef ustring2PyString( const OUString & source );
217 : OUString pyString2ustring( PyObject *str );
218 :
219 :
220 : PyRef AnyToPyObject (const com::sun::star::uno::Any & a, const Runtime &r )
221 : throw ( com::sun::star::uno::RuntimeException );
222 :
223 : com::sun::star::uno::Any PyObjectToAny (PyObject* o)
224 : throw ( com::sun::star::uno::RuntimeException );
225 :
226 : void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime )
227 : throw ( com::sun::star::reflection::InvocationTargetException );
228 :
229 : com::sun::star::uno::TypeClass StringToTypeClass (char* string);
230 :
231 : PyRef PyUNO_callable_new (
232 : const com::sun::star::uno::Reference<com::sun::star::script::XInvocation2> &xInv,
233 : const OUString &methodName,
234 : ConversionMode mode = REJECT_UNO_ANY );
235 :
236 : PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r );
237 : PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r );
238 : PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r);
239 : PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r );
240 :
241 : PyRef getTypeClass( const Runtime &);
242 : PyRef getEnumClass( const Runtime &);
243 : PyRef getBoolClass( const Runtime &);
244 : PyRef getCharClass( const Runtime &);
245 : PyRef getByteSequenceClass( const Runtime & );
246 : PyRef getPyUnoClass();
247 : PyRef getClass( const OUString & name , const Runtime & runtime );
248 : PyRef getAnyClass( const Runtime &);
249 : PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args );
250 :
251 : com::sun::star::uno::Any PyEnum2Enum( PyObject *obj )
252 : throw ( com::sun::star::uno::RuntimeException );
253 : bool PyBool2Bool( PyObject *o, const Runtime & r )
254 : throw ( com::sun::star::uno::RuntimeException );
255 : sal_Unicode PyChar2Unicode( PyObject *o )
256 : throw ( com::sun::star::uno::RuntimeException );
257 : com::sun::star::uno::Type PyType2Type( PyObject * o )
258 : throw( com::sun::star::uno::RuntimeException );
259 :
260 : void raisePyExceptionWithAny( const com::sun::star::uno::Any &a );
261 : const char *typeClassToString( com::sun::star::uno::TypeClass t );
262 :
263 : PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object )
264 : throw ( com::sun::star::uno::RuntimeException );
265 :
266 : bool isInterfaceClass( const Runtime &, PyObject *obj );
267 : bool isInstanceOfStructOrException( PyObject *obj);
268 : com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces(
269 : const Runtime & runtime, PyObject *obj );
270 :
271 3 : struct RuntimeCargo
272 : {
273 : com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation;
274 : com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter;
275 : com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext;
276 : com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection;
277 : com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr;
278 : com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory;
279 : com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection;
280 : PyRef dictUnoModule;
281 : osl::Module testModule;
282 : bool valid;
283 : ExceptionClassMap exceptionMap;
284 : ClassSet interfaceSet;
285 : PyRef2Adapter mappedObjects;
286 : FILE *logFile;
287 : sal_Int32 logLevel;
288 :
289 : PyRef getUnoModule();
290 : };
291 :
292 : struct stRuntimeImpl
293 : {
294 : PyObject_HEAD
295 : struct RuntimeCargo *cargo;
296 : public:
297 : static void del( PyObject *self );
298 :
299 : static PyRef create(
300 : const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext )
301 : throw ( com::sun::star::uno::RuntimeException );
302 : };
303 :
304 :
305 : class Adapter : public cppu::WeakImplHelper2<
306 : com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel >
307 : {
308 : PyRef mWrappedObject;
309 : PyInterpreterState *mInterpreter; // interpreters don't seem to be refcounted !
310 : com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes;
311 : MethodOutIndexMap m_methodOutIndexMap;
312 :
313 : private:
314 : com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const OUString & functionName );
315 :
316 : public:
317 : public:
318 : Adapter( const PyRef &obj,
319 : const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types );
320 :
321 : static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
322 0 : PyRef getWrappedObject() { return mWrappedObject; }
323 0 : com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; }
324 : virtual ~Adapter();
325 :
326 : // XInvocation
327 : virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >
328 : SAL_CALL getIntrospection( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
329 : virtual ::com::sun::star::uno::Any SAL_CALL invoke(
330 : const OUString& aFunctionName,
331 : const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams,
332 : ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
333 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam )
334 : throw (::com::sun::star::lang::IllegalArgumentException,
335 : ::com::sun::star::script::CannotConvertException,
336 : ::com::sun::star::reflection::InvocationTargetException,
337 : ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
338 :
339 : virtual void SAL_CALL setValue(
340 : const OUString& aPropertyName,
341 : const ::com::sun::star::uno::Any& aValue )
342 : throw (::com::sun::star::beans::UnknownPropertyException,
343 : ::com::sun::star::script::CannotConvertException,
344 : ::com::sun::star::reflection::InvocationTargetException,
345 : ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
346 :
347 : virtual ::com::sun::star::uno::Any SAL_CALL getValue( const OUString& aPropertyName )
348 : throw (::com::sun::star::beans::UnknownPropertyException,
349 : ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
350 : virtual sal_Bool SAL_CALL hasMethod( const OUString& aName )
351 : throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
352 : virtual sal_Bool SAL_CALL hasProperty( const OUString& aName )
353 : throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
354 :
355 : // XUnoTunnel
356 : virtual sal_Int64 SAL_CALL getSomething(
357 : const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
358 : throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
359 : };
360 :
361 :
362 : /** releases a refcount on the interpreter object and on another given python object.
363 :
364 : The function can be called from any thread regardless of whether the global
365 : interpreter lock is held.
366 :
367 : */
368 : void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object );
369 :
370 : }
371 :
372 : #endif
373 :
374 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|