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 _PYUNO_IMPL_
20 : #define _PYUNO_IMPL_
21 :
22 : #if defined(_MSC_VER) && (_MSC_VER >= 1700)
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 <boost/unordered_map.hpp>
37 : #include <boost/unordered_set.hpp>
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 : // In Python 3, the PyString_* functions have been replaced by PyBytes_*
55 : // and PyUnicode_* functions.
56 : #if PY_MAJOR_VERSION >= 3
57 :
58 : // compatibility wrappers for Python "str" type (PyUnicode in 3, PyString in 2)
59 0 : inline PyObject* PyStr_FromString(const char *string)
60 : {
61 0 : return PyUnicode_FromString(string);
62 : }
63 :
64 0 : inline char * PyStr_AsString(PyObject *object)
65 : {
66 0 : return PyUnicode_AsUTF8(object);
67 : }
68 :
69 0 : inline int PyStr_Check(PyObject *object)
70 : {
71 0 : return PyUnicode_Check(object);
72 : }
73 :
74 : // compatibility wrappers for Python non-Unicode string/buffer type
75 : // (PyBytes in 3, PyString in 2)
76 0 : inline int PyStrBytes_Check(PyObject *object)
77 : {
78 0 : return PyBytes_Check(object);
79 : }
80 :
81 0 : inline char* PyStrBytes_AsString(PyObject *object)
82 : {
83 0 : return PyBytes_AsString(object);
84 : }
85 :
86 0 : inline Py_ssize_t PyStrBytes_Size(PyObject *object)
87 : {
88 0 : return PyBytes_Size(object);
89 : }
90 :
91 0 : inline PyObject* PyStrBytes_FromStringAndSize(const char *string, Py_ssize_t len)
92 : {
93 0 : return PyBytes_FromStringAndSize(string, len);
94 : }
95 : #else
96 : inline char * PyStr_AsString(PyObject *object)
97 : {
98 : return PyString_AsString(object);
99 : }
100 :
101 : inline PyObject* PyStr_FromString(const char *string)
102 : {
103 : return PyString_FromString(string);
104 : }
105 :
106 : inline int PyStr_Check(PyObject *object)
107 : {
108 : return PyString_Check(object);
109 : }
110 : inline int PyStrBytes_Check(PyObject *object)
111 : {
112 : return PyString_Check(object);
113 : }
114 :
115 : inline char* PyStrBytes_AsString(PyObject *object)
116 : {
117 : return PyString_AsString(object);
118 : }
119 :
120 : inline Py_ssize_t PyStrBytes_Size(PyObject *object)
121 : {
122 : return PyString_Size(object);
123 : }
124 :
125 : inline PyObject* PyStrBytes_FromStringAndSize(const char *string, Py_ssize_t len)
126 : {
127 : return PyString_FromStringAndSize(string, len);
128 : }
129 : #endif /* PY_MAJOR_VERSION >= 3 */
130 :
131 : namespace pyuno
132 : {
133 :
134 : //--------------------------------------------------
135 : // Logging API - implementation can be found in pyuno_util
136 : //--------------------------------------------------
137 : struct RuntimeCargo;
138 : namespace LogLevel
139 : {
140 : // when you add a loglevel, extend the log function !
141 : static const sal_Int32 NONE = 0;
142 : static const sal_Int32 CALL = 1;
143 : static const sal_Int32 ARGS = 2;
144 : }
145 :
146 : bool isLog( RuntimeCargo *cargo, sal_Int32 loglevel );
147 : void log( RuntimeCargo *cargo, sal_Int32 level, const rtl::OUString &logString );
148 : void log( RuntimeCargo *cargo, sal_Int32 level, const char *str );
149 : void logCall( RuntimeCargo *cargo, const char *intro,
150 : void * ptr, const rtl::OUString & aFunctionName,
151 : const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
152 : void logReply( RuntimeCargo *cargo, const char *intro,
153 : void * ptr, const rtl::OUString & aFunctionName,
154 : const com::sun::star::uno::Any &returnValue,
155 : const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
156 : void logException( RuntimeCargo *cargo, const char *intro,
157 : void * ptr, const rtl::OUString &aFunctionName,
158 : const void * data, const com::sun::star::uno::Type & type );
159 : static const sal_Int32 VAL2STR_MODE_DEEP = 0;
160 : static const sal_Int32 VAL2STR_MODE_SHALLOW = 1;
161 : rtl::OUString val2str( const void * pVal, typelib_TypeDescriptionReference * pTypeRef, sal_Int32 mode = VAL2STR_MODE_DEEP ) SAL_THROW(());
162 : //--------------------------------------------------
163 :
164 : typedef ::boost::unordered_map
165 : <
166 : PyRef,
167 : com::sun::star::uno::WeakReference< com::sun::star::script::XInvocation >,
168 : PyRef::Hash,
169 : std::equal_to< PyRef >
170 : > PyRef2Adapter;
171 :
172 :
173 : typedef ::boost::unordered_map
174 : <
175 : rtl::OUString,
176 : PyRef,
177 : rtl::OUStringHash,
178 : std::equal_to<rtl::OUString>
179 : > ExceptionClassMap;
180 :
181 : typedef ::boost::unordered_map
182 : <
183 : rtl::OUString,
184 : com::sun::star::uno::Sequence< sal_Int16 >,
185 : rtl::OUStringHash,
186 : std::equal_to< rtl::OUString >
187 : > MethodOutIndexMap;
188 :
189 : typedef ::boost::unordered_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet;
190 :
191 : PyObject* PyUNO_new(
192 : const com::sun::star::uno::Any & targetInterface,
193 : const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
194 :
195 : PyObject* PyUNO_new_UNCHECKED (
196 : const com::sun::star::uno::Any & targetInterface,
197 : const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
198 :
199 : typedef struct
200 0 : {
201 : com::sun::star::uno::Reference <com::sun::star::script::XInvocation2> xInvocation;
202 : com::sun::star::uno::Any wrappedObject;
203 0 : } PyUNOInternals;
204 :
205 : typedef struct
206 : {
207 : PyObject_HEAD
208 : PyUNOInternals* members;
209 : } PyUNO;
210 :
211 : PyRef ustring2PyUnicode( const rtl::OUString &source );
212 : PyRef ustring2PyString( const ::rtl::OUString & source );
213 : rtl::OUString pyString2ustring( PyObject *str );
214 :
215 :
216 : PyRef AnyToPyObject (const com::sun::star::uno::Any & a, const Runtime &r )
217 : throw ( com::sun::star::uno::RuntimeException );
218 :
219 : com::sun::star::uno::Any PyObjectToAny (PyObject* o)
220 : throw ( com::sun::star::uno::RuntimeException );
221 :
222 : void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime )
223 : throw ( com::sun::star::reflection::InvocationTargetException );
224 :
225 : com::sun::star::uno::TypeClass StringToTypeClass (char* string);
226 :
227 : PyRef PyUNO_callable_new (
228 : const com::sun::star::uno::Reference<com::sun::star::script::XInvocation2> &xInv,
229 : const rtl::OUString &methodName,
230 : const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> &ssf,
231 : const com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> &tc,
232 : ConversionMode mode = REJECT_UNO_ANY );
233 :
234 : PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r );
235 : PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r );
236 : PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r);
237 : PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r );
238 :
239 : PyRef getTypeClass( const Runtime &);
240 : PyRef getEnumClass( const Runtime &);
241 : PyRef getBoolClass( const Runtime &);
242 : PyRef getCharClass( const Runtime &);
243 : PyRef getByteSequenceClass( const Runtime & );
244 : PyRef getPyUnoClass();
245 : PyRef getClass( const rtl::OUString & name , const Runtime & runtime );
246 : PyRef getAnyClass( const Runtime &);
247 : PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args );
248 :
249 : com::sun::star::uno::Any PyEnum2Enum( PyObject *obj )
250 : throw ( com::sun::star::uno::RuntimeException );
251 : sal_Bool PyBool2Bool( PyObject *o, const Runtime & r )
252 : throw ( com::sun::star::uno::RuntimeException );
253 : sal_Unicode PyChar2Unicode( PyObject *o )
254 : throw ( com::sun::star::uno::RuntimeException );
255 : com::sun::star::uno::Type PyType2Type( PyObject * o )
256 : throw( com::sun::star::uno::RuntimeException );
257 :
258 : void raisePyExceptionWithAny( const com::sun::star::uno::Any &a );
259 : const char *typeClassToString( com::sun::star::uno::TypeClass t );
260 :
261 : PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object )
262 : throw ( com::sun::star::uno::RuntimeException );
263 :
264 : sal_Bool isInterfaceClass( const Runtime &, PyObject *obj );
265 : bool isInstanceOfStructOrException( PyObject *obj);
266 : com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces(
267 : const Runtime & runtime, PyObject *obj );
268 :
269 0 : struct RuntimeCargo
270 : {
271 : com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation;
272 : com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter;
273 : com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext;
274 : com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection;
275 : com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr;
276 : com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory;
277 : com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection;
278 : PyRef dictUnoModule;
279 : bool valid;
280 : ExceptionClassMap exceptionMap;
281 : ClassSet interfaceSet;
282 : PyRef2Adapter mappedObjects;
283 : FILE *logFile;
284 : sal_Int32 logLevel;
285 :
286 : PyRef getUnoModule();
287 : };
288 :
289 : struct stRuntimeImpl
290 : {
291 : PyObject_HEAD
292 : struct RuntimeCargo *cargo;
293 : public:
294 : static void del( PyObject *self );
295 :
296 : static PyRef create(
297 : const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext )
298 : throw ( com::sun::star::uno::RuntimeException );
299 : };
300 :
301 :
302 : class Adapter : public cppu::WeakImplHelper2<
303 : com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel >
304 : {
305 : PyRef mWrappedObject;
306 : PyInterpreterState *mInterpreter; // interpreters don't seem to be refcounted !
307 : com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes;
308 : MethodOutIndexMap m_methodOutIndexMap;
309 :
310 : private:
311 : com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const rtl::OUString & functionName );
312 :
313 : public:
314 : public:
315 : Adapter( const PyRef &obj,
316 : const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types );
317 :
318 : static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
319 0 : PyRef getWrappedObject() { return mWrappedObject; }
320 0 : com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; }
321 : virtual ~Adapter();
322 :
323 : // XInvocation
324 : virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >
325 : SAL_CALL getIntrospection( ) throw (::com::sun::star::uno::RuntimeException);
326 : virtual ::com::sun::star::uno::Any SAL_CALL invoke(
327 : const ::rtl::OUString& aFunctionName,
328 : const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams,
329 : ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
330 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam )
331 : throw (::com::sun::star::lang::IllegalArgumentException,
332 : ::com::sun::star::script::CannotConvertException,
333 : ::com::sun::star::reflection::InvocationTargetException,
334 : ::com::sun::star::uno::RuntimeException);
335 :
336 : virtual void SAL_CALL setValue(
337 : const ::rtl::OUString& aPropertyName,
338 : const ::com::sun::star::uno::Any& aValue )
339 : throw (::com::sun::star::beans::UnknownPropertyException,
340 : ::com::sun::star::script::CannotConvertException,
341 : ::com::sun::star::reflection::InvocationTargetException,
342 : ::com::sun::star::uno::RuntimeException);
343 :
344 : virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName )
345 : throw (::com::sun::star::beans::UnknownPropertyException,
346 : ::com::sun::star::uno::RuntimeException);
347 : virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName )
348 : throw (::com::sun::star::uno::RuntimeException);
349 : virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName )
350 : throw (::com::sun::star::uno::RuntimeException);
351 :
352 : // XUnoTunnel
353 : virtual sal_Int64 SAL_CALL getSomething(
354 : const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
355 : throw (::com::sun::star::uno::RuntimeException);
356 : };
357 :
358 :
359 : /** releases a refcount on the interpreter object and on another given python object.
360 :
361 : The function can be called from any thread regardless of whether the global
362 : interpreter lock is held.
363 :
364 : */
365 : void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object );
366 :
367 : }
368 :
369 : #endif
370 :
371 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|