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