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