1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_PYUNO_SOURCE_MODULE_PYUNO_IMPL_HXX
20 #define INCLUDED_PYUNO_SOURCE_MODULE_PYUNO_IMPL_HXX
23 // Workaround for some horrible hypot() mess
29 #if PY_VERSION_HEX < 0x03020000
30 typedef long Py_hash_t
;
33 //Must define PyVarObject_HEAD_INIT for Python 2.5 or older
34 #ifndef PyVarObject_HEAD_INIT
35 #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
38 //Python 3.0 and newer don't have these flags
39 #ifndef Py_TPFLAGS_HAVE_ITER
40 # define Py_TPFLAGS_HAVE_ITER 0
42 #ifndef Py_TPFLAGS_HAVE_RICHCOMPARE
43 # define Py_TPFLAGS_HAVE_RICHCOMPARE 0
45 #ifndef Py_TPFLAGS_HAVE_SEQUENCE_IN
46 # define Py_TPFLAGS_HAVE_SEQUENCE_IN 0
49 #include <pyuno/pyuno.hxx>
51 #include <unordered_map>
52 #include <unordered_set>
54 #include <com/sun/star/beans/XIntrospection.hpp>
55 #include <com/sun/star/script/XTypeConverter.hpp>
56 #include <com/sun/star/script/XInvocation2.hpp>
57 #include <com/sun/star/script/XInvocationAdapterFactory2.hpp>
59 #include <com/sun/star/reflection/XIdlReflection.hpp>
61 #include <com/sun/star/container/XEnumeration.hpp>
62 #include <com/sun/star/container/XIndexAccess.hpp>
63 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
65 #include <com/sun/star/lang/XUnoTunnel.hpp>
66 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
68 #include <cppuhelper/implbase.hxx>
69 #include <cppuhelper/weakref.hxx>
71 #include <osl/module.hxx>
73 // In Python 3, the PyString_* functions have been replaced by PyBytes_*
74 // and PyUnicode_* functions.
75 #if PY_MAJOR_VERSION >= 3
77 // compatibility wrappers for Python "str" type (PyUnicode in 3, PyString in 2)
78 inline PyObject
* PyStr_FromString(const char *string
)
80 return PyUnicode_FromString(string
);
83 inline char * PyStr_AsString(PyObject
*object
)
85 return PyUnicode_AsUTF8(object
);
88 inline bool PyStr_Check(PyObject
*object
)
90 return PyUnicode_Check(object
);
93 // compatibility wrappers for Python non-Unicode string/buffer type
94 // (PyBytes in 3, PyString in 2)
95 inline bool PyStrBytes_Check(PyObject
*object
)
97 return PyBytes_Check(object
);
100 inline char* PyStrBytes_AsString(PyObject
*object
)
102 return PyBytes_AsString(object
);
105 inline Py_ssize_t
PyStrBytes_Size(PyObject
*object
)
107 return PyBytes_Size(object
);
110 inline PyObject
* PyStrBytes_FromStringAndSize(const char *string
, Py_ssize_t len
)
112 return PyBytes_FromStringAndSize(string
, len
);
115 inline char * PyStr_AsString(PyObject
*object
)
117 return PyString_AsString(object
);
120 inline PyObject
* PyStr_FromString(const char *string
)
122 return PyString_FromString(string
);
125 inline bool PyStr_Check(PyObject
*object
)
127 return PyString_Check(object
);
129 inline bool PyStrBytes_Check(PyObject
*object
)
131 return PyString_Check(object
);
134 inline char* PyStrBytes_AsString(PyObject
*object
)
136 return PyString_AsString(object
);
139 inline Py_ssize_t
PyStrBytes_Size(PyObject
*object
)
141 return PyString_Size(object
);
144 inline PyObject
* PyStrBytes_FromStringAndSize(const char *string
, Py_ssize_t len
)
146 return PyString_FromStringAndSize(string
, len
);
148 #endif /* PY_MAJOR_VERSION >= 3 */
154 // Logging API - implementation can be found in pyuno_util
159 // when you add a loglevel, extend the log function !
160 static const sal_Int32 NONE
= 0;
161 static const sal_Int32 CALL
= 1;
162 static const sal_Int32 ARGS
= 2;
165 bool isLog( RuntimeCargo
*cargo
, sal_Int32 loglevel
);
166 void log( RuntimeCargo
*cargo
, sal_Int32 level
, const OUString
&logString
);
167 void log( RuntimeCargo
*cargo
, sal_Int32 level
, const char *str
);
168 void logCall( RuntimeCargo
*cargo
, const char *intro
,
169 void * ptr
, const OUString
& aFunctionName
,
170 const css::uno::Sequence
< css::uno::Any
> & args
);
171 void logReply( RuntimeCargo
*cargo
, const char *intro
,
172 void * ptr
, const OUString
& aFunctionName
,
173 const css::uno::Any
&returnValue
,
174 const css::uno::Sequence
< css::uno::Any
> & args
);
175 void logException( RuntimeCargo
*cargo
, const char *intro
,
176 void * ptr
, const OUString
&aFunctionName
,
177 const void * data
, const css::uno::Type
& type
);
178 static const sal_Int32 VAL2STR_MODE_DEEP
= 0;
179 static const sal_Int32 VAL2STR_MODE_SHALLOW
= 1;
180 OUString
val2str( const void * pVal
, typelib_TypeDescriptionReference
* pTypeRef
, sal_Int32 mode
= VAL2STR_MODE_DEEP
);
183 typedef std::unordered_map
186 css::uno::WeakReference
< css::script::XInvocation
>,
191 typedef std::unordered_map
198 typedef std::unordered_map
201 css::uno::Sequence
< sal_Int16
>,
205 typedef std::unordered_set
< PyRef
, PyRef::Hash
> ClassSet
;
207 int PyUNO_initType();
208 int PyUNOStruct_initType();
211 const css::uno::Any
& targetInterface
,
212 const css::uno::Reference
<css::lang::XSingleServiceFactory
> & ssf
);
214 PyRef
PyUNOStruct_new (
215 const css::uno::Any
&targetInterface
,
216 const css::uno::Reference
<css::lang::XSingleServiceFactory
> &ssf
);
220 css::uno::Reference
<css::script::XInvocation2
> xInvocation
;
221 css::uno::Any wrappedObject
;
227 PyUNOInternals
* members
;
230 PyObject
* PyUNO_iterator_new (
231 const css::uno::Reference
<css::container::XEnumeration
>& xEnumeration
);
235 css::uno::Reference
<css::container::XEnumeration
> xEnumeration
;
236 } PyUNO_iterator_Internals
;
241 PyUNO_iterator_Internals
* members
;
244 PyObject
* PyUNO_list_iterator_new (
245 const css::uno::Reference
<css::container::XIndexAccess
> &xIndexAccess
);
249 css::uno::Reference
<css::container::XIndexAccess
> xIndexAccess
;
251 } PyUNO_list_iterator_Internals
;
256 PyUNO_list_iterator_Internals
* members
;
257 } PyUNO_list_iterator
;
259 PyRef
ustring2PyUnicode( const OUString
&source
);
260 PyRef
ustring2PyString( const OUString
& source
);
261 OUString
pyString2ustring( PyObject
*str
);
264 void raiseInvocationTargetExceptionWhenNeeded( const Runtime
&runtime
)
265 throw ( css::reflection::InvocationTargetException
);
267 PyRef
PyUNO_callable_new (
268 const css::uno::Reference
<css::script::XInvocation2
> &xInv
,
269 const OUString
&methodName
,
270 ConversionMode mode
= REJECT_UNO_ANY
);
272 PyObject
* PyUNO_Type_new (const char *typeName
, css::uno::TypeClass t
, const Runtime
&r
);
273 PyObject
* PyUNO_Enum_new( const char *enumBase
, const char *enumValue
, const Runtime
&r
);
274 PyObject
* PyUNO_char_new (sal_Unicode c
, const Runtime
&r
);
275 PyObject
*PyUNO_ByteSequence_new( const css::uno::Sequence
< sal_Int8
> &, const Runtime
&r
);
277 PyRef
getTypeClass( const Runtime
&);
278 PyRef
getEnumClass( const Runtime
&);
279 PyRef
getCharClass( const Runtime
&);
280 PyRef
getByteSequenceClass( const Runtime
& );
281 PyRef
getPyUnoClass();
282 PyRef
getPyUnoStructClass();
283 PyRef
getClass( const OUString
& name
, const Runtime
& runtime
);
284 PyRef
getAnyClass( const Runtime
&);
285 PyObject
*PyUNO_invoke( PyObject
*object
, const char *name
, PyObject
*args
);
287 css::uno::Any
PyEnum2Enum( PyObject
*obj
)
288 throw ( css::uno::RuntimeException
);
289 sal_Unicode
PyChar2Unicode( PyObject
*o
)
290 throw ( css::uno::RuntimeException
);
291 css::uno::Type
PyType2Type( PyObject
* o
)
292 throw( css::uno::RuntimeException
);
294 void raisePyExceptionWithAny( const css::uno::Any
&a
);
295 const char *typeClassToString( css::uno::TypeClass t
);
297 PyRef
getObjectFromUnoModule( const Runtime
&runtime
, const char * object
)
298 throw ( css::uno::RuntimeException
);
300 bool isInterfaceClass( const Runtime
&, PyObject
*obj
);
301 bool isInstanceOfStructOrException( PyObject
*obj
);
305 css::uno::Reference
< css::lang::XSingleServiceFactory
> xInvocation
;
306 css::uno::Reference
< css::script::XTypeConverter
> xTypeConverter
;
307 css::uno::Reference
< css::uno::XComponentContext
> xContext
;
308 css::uno::Reference
< css::reflection::XIdlReflection
> xCoreReflection
;
309 css::uno::Reference
< css::container::XHierarchicalNameAccess
> xTdMgr
;
310 css::uno::Reference
< css::script::XInvocationAdapterFactory2
> xAdapterFactory
;
311 css::uno::Reference
< css::beans::XIntrospection
> xIntrospection
;
313 osl::Module testModule
;
315 ExceptionClassMap exceptionMap
;
316 ClassSet interfaceSet
;
317 PyRef2Adapter mappedObjects
;
321 PyRef
getUnoModule();
327 struct RuntimeCargo
*cargo
;
329 static void del( PyObject
*self
);
332 const css::uno::Reference
< css::uno::XComponentContext
> & xContext
)
333 throw ( css::uno::RuntimeException
, std::exception
);
337 class Adapter
: public cppu::WeakImplHelper
<
338 css::script::XInvocation
, css::lang::XUnoTunnel
>
340 PyRef mWrappedObject
;
341 PyInterpreterState
*mInterpreter
; // interpreters don't seem to be refcounted !
342 css::uno::Sequence
< css::uno::Type
> mTypes
;
343 MethodOutIndexMap m_methodOutIndexMap
;
346 css::uno::Sequence
< sal_Int16
> getOutIndexes( const OUString
& functionName
);
350 Adapter( const PyRef
&obj
,
351 const css::uno::Sequence
< css::uno::Type
> & types
);
353 static css::uno::Sequence
< sal_Int8
> getUnoTunnelImplementationId();
354 const PyRef
& getWrappedObject() const { return mWrappedObject
; }
355 const css::uno::Sequence
< css::uno::Type
>& getWrappedTypes() const { return mTypes
; }
359 virtual css::uno::Reference
< css::beans::XIntrospectionAccess
>
360 SAL_CALL
getIntrospection( ) throw (css::uno::RuntimeException
, std::exception
) override
;
361 virtual css::uno::Any SAL_CALL
invoke(
362 const OUString
& aFunctionName
,
363 const css::uno::Sequence
< css::uno::Any
>& aParams
,
364 css::uno::Sequence
< sal_Int16
>& aOutParamIndex
,
365 css::uno::Sequence
< css::uno::Any
>& aOutParam
)
366 throw (css::lang::IllegalArgumentException
,
367 css::script::CannotConvertException
,
368 css::reflection::InvocationTargetException
,
369 css::uno::RuntimeException
, std::exception
) override
;
371 virtual void SAL_CALL
setValue(
372 const OUString
& aPropertyName
,
373 const css::uno::Any
& aValue
)
374 throw (css::beans::UnknownPropertyException
,
375 css::script::CannotConvertException
,
376 css::reflection::InvocationTargetException
,
377 css::uno::RuntimeException
, std::exception
) override
;
379 virtual css::uno::Any SAL_CALL
getValue( const OUString
& aPropertyName
)
380 throw (css::beans::UnknownPropertyException
,
381 css::uno::RuntimeException
, std::exception
) override
;
382 virtual sal_Bool SAL_CALL
hasMethod( const OUString
& aName
)
383 throw (css::uno::RuntimeException
, std::exception
) override
;
384 virtual sal_Bool SAL_CALL
hasProperty( const OUString
& aName
)
385 throw (css::uno::RuntimeException
, std::exception
) override
;
388 virtual sal_Int64 SAL_CALL
getSomething(
389 const css::uno::Sequence
< sal_Int8
>& aIdentifier
)
390 throw (css::uno::RuntimeException
, std::exception
) override
;
394 /** releases a refcount on the interpreter object and on another given python object.
396 The function can be called from any thread regardless of whether the global
397 interpreter lock is held.
400 void decreaseRefCount( PyInterpreterState
*interpreter
, PyObject
*object
);
406 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */