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
51 #include <unordered_map>
52 #include <unordered_set>
54 #include <com/sun/star/container/XIndexAccess.hpp>
55 #include <com/sun/star/lang/XUnoTunnel.hpp>
56 #include <com/sun/star/script/XInvocation.hpp>
58 #include <cppuhelper/implbase.hxx>
59 #include <cppuhelper/weakref.hxx>
61 #include <osl/module.hxx>
63 namespace com::sun::star::beans
{ class XIntrospection
; }
64 namespace com::sun::star::container
{ class XEnumeration
; }
65 namespace com::sun::star::container
{ class XHierarchicalNameAccess
; }
66 namespace com::sun::star::lang
{ class XSingleServiceFactory
; }
67 namespace com::sun::star::reflection
{ class XIdlReflection
; }
68 namespace com::sun::star::script
{ class XInvocation2
; }
69 namespace com::sun::star::script
{ class XInvocationAdapterFactory2
; }
70 namespace com::sun::star::script
{ class XTypeConverter
; }
72 // In Python 3, the PyString_* functions have been replaced by PyBytes_*
73 // and PyUnicode_* functions.
74 #if PY_MAJOR_VERSION >= 3
76 // compatibility wrappers for Python "str" type (PyUnicode in 3, PyString in 2)
77 inline PyObject
* PyStr_FromString(const char *string
)
79 return PyUnicode_FromString(string
);
82 inline char const * PyStr_AsString(PyObject
*object
)
84 return PyUnicode_AsUTF8(object
);
87 inline bool PyStr_Check(PyObject
const *object
)
89 return PyUnicode_Check(object
);
92 // compatibility wrappers for Python non-Unicode string/buffer type
93 // (PyBytes in 3, PyString in 2)
94 inline bool PyStrBytes_Check(PyObject
const *object
)
96 return PyBytes_Check(object
);
99 inline char* PyStrBytes_AsString(PyObject
*object
)
101 return PyBytes_AsString(object
);
104 inline Py_ssize_t
PyStrBytes_Size(PyObject
*object
)
106 return PyBytes_Size(object
);
109 inline PyObject
* PyStrBytes_FromStringAndSize(const char *string
, Py_ssize_t len
)
111 return PyBytes_FromStringAndSize(string
, len
);
114 inline char * PyStr_AsString(PyObject
*object
)
116 return PyString_AsString(object
);
119 inline PyObject
* PyStr_FromString(const char *string
)
121 return PyString_FromString(string
);
124 inline bool PyStr_Check(PyObject
*object
)
126 return PyString_Check(object
);
128 inline bool PyStrBytes_Check(PyObject
*object
)
130 return PyString_Check(object
);
133 inline char* PyStrBytes_AsString(PyObject
*object
)
135 return PyString_AsString(object
);
138 inline Py_ssize_t
PyStrBytes_Size(PyObject
*object
)
140 return PyString_Size(object
);
143 inline PyObject
* PyStrBytes_FromStringAndSize(const char *string
, Py_ssize_t len
)
145 return PyString_FromStringAndSize(string
, len
);
147 #endif /* PY_MAJOR_VERSION >= 3 */
153 // Logging API - implementation can be found in pyuno_util
158 // when you add a loglevel, extend the log function !
159 static const sal_Int32 NONE
= 0;
160 static const sal_Int32 CALL
= 1;
161 static const sal_Int32 ARGS
= 2;
164 bool isLog( RuntimeCargo
const *cargo
, sal_Int32 loglevel
);
165 void log( RuntimeCargo
*cargo
, sal_Int32 level
, const OUString
&logString
);
166 void log( RuntimeCargo
*cargo
, sal_Int32 level
, const char *str
);
167 void logCall( RuntimeCargo
*cargo
, const char *intro
,
168 void * ptr
, const OUString
& aFunctionName
,
169 const css::uno::Sequence
< css::uno::Any
> & args
);
170 void logReply( RuntimeCargo
*cargo
, const char *intro
,
171 void * ptr
, const OUString
& aFunctionName
,
172 const css::uno::Any
&returnValue
,
173 const css::uno::Sequence
< css::uno::Any
> & args
);
174 void logException( RuntimeCargo
*cargo
, const char *intro
,
175 void * ptr
, const OUString
&aFunctionName
,
176 const void * data
, const css::uno::Type
& type
);
177 static const sal_Int32 VAL2STR_MODE_DEEP
= 0;
178 static const sal_Int32 VAL2STR_MODE_SHALLOW
= 1;
179 OUString
val2str( const void * pVal
, typelib_TypeDescriptionReference
* pTypeRef
, sal_Int32 mode
= VAL2STR_MODE_DEEP
);
182 typedef std::unordered_map
185 css::uno::WeakReference
< css::script::XInvocation
>,
190 typedef std::unordered_map
196 typedef std::unordered_map
199 css::uno::Sequence
< sal_Int16
>
202 typedef std::unordered_set
< PyRef
, PyRef::Hash
> ClassSet
;
204 int PyUNO_initType();
205 int PyUNOStruct_initType();
208 const css::uno::Any
& targetInterface
,
209 const css::uno::Reference
<css::lang::XSingleServiceFactory
> & ssf
);
211 PyRef
PyUNOStruct_new (
212 const css::uno::Any
&targetInterface
,
213 const css::uno::Reference
<css::lang::XSingleServiceFactory
> &ssf
);
217 css::uno::Reference
<css::script::XInvocation2
> xInvocation
;
218 css::uno::Any wrappedObject
;
224 PyUNOInternals
* members
;
227 PyObject
* PyUNO_iterator_new (
228 const css::uno::Reference
<css::container::XEnumeration
>& xEnumeration
);
232 css::uno::Reference
<css::container::XEnumeration
> xEnumeration
;
233 } PyUNO_iterator_Internals
;
238 PyUNO_iterator_Internals
* members
;
241 PyObject
* PyUNO_list_iterator_new (
242 const css::uno::Reference
<css::container::XIndexAccess
> &xIndexAccess
);
246 css::uno::Reference
<css::container::XIndexAccess
> xIndexAccess
;
248 } PyUNO_list_iterator_Internals
;
253 PyUNO_list_iterator_Internals
* members
;
254 } PyUNO_list_iterator
;
256 PyRef
ustring2PyUnicode( const OUString
&source
);
257 PyRef
ustring2PyString( const OUString
& source
);
258 OUString
pyString2ustring( PyObject
*str
);
260 /// @throws css::reflection::InvocationTargetException
261 /// @throws css::uno::RuntimeException
262 void raiseInvocationTargetExceptionWhenNeeded( const Runtime
&runtime
);
264 PyRef
PyUNO_callable_new (
265 const css::uno::Reference
<css::script::XInvocation2
> &xInv
,
266 const OUString
&methodName
,
267 ConversionMode mode
= REJECT_UNO_ANY
);
269 PyObject
* PyUNO_Type_new (const char *typeName
, css::uno::TypeClass t
, const Runtime
&r
);
270 PyObject
* PyUNO_Enum_new( const char *enumBase
, const char *enumValue
, const Runtime
&r
);
271 PyObject
* PyUNO_char_new (sal_Unicode c
, const Runtime
&r
);
272 PyObject
*PyUNO_ByteSequence_new( const css::uno::Sequence
< sal_Int8
> &, const Runtime
&r
);
274 PyRef
getTypeClass( const Runtime
&);
275 PyRef
getEnumClass( const Runtime
&);
276 PyRef
getCharClass( const Runtime
&);
277 PyRef
getByteSequenceClass( const Runtime
& );
278 PyRef
getPyUnoClass();
279 PyRef
getPyUnoStructClass();
280 PyRef
getClass( const OUString
& name
, const Runtime
& runtime
);
281 PyRef
getAnyClass( const Runtime
&);
282 PyObject
*PyUNO_invoke( PyObject
*object
, const char *name
, PyObject
*args
);
284 /// @throws css::uno::RuntimeException
285 css::uno::Any
PyEnum2Enum( PyObject
*obj
);
286 /// @throws css::uno::RuntimeException
287 sal_Unicode
PyChar2Unicode( PyObject
*o
);
288 /// @throws css::uno::RuntimeException
289 css::uno::Type
PyType2Type( PyObject
* o
);
291 void raisePyExceptionWithAny( const css::uno::Any
&a
);
292 const char *typeClassToString( css::uno::TypeClass t
);
294 /// @throws css::uno::RuntimeException
295 PyRef
getObjectFromUnoModule( const Runtime
&runtime
, const char * object
);
297 bool isInterfaceClass( const Runtime
&, PyObject
*obj
);
298 bool isInstanceOfStructOrException( PyObject
*obj
);
302 css::uno::Reference
< css::lang::XSingleServiceFactory
> xInvocation
;
303 css::uno::Reference
< css::script::XTypeConverter
> xTypeConverter
;
304 css::uno::Reference
< css::uno::XComponentContext
> xContext
;
305 css::uno::Reference
< css::reflection::XIdlReflection
> xCoreReflection
;
306 css::uno::Reference
< css::container::XHierarchicalNameAccess
> xTdMgr
;
307 css::uno::Reference
< css::script::XInvocationAdapterFactory2
> xAdapterFactory
;
308 css::uno::Reference
< css::beans::XIntrospection
> xIntrospection
;
310 osl::Module testModule
;
312 ExceptionClassMap exceptionMap
;
313 ClassSet interfaceSet
;
314 PyRef2Adapter mappedObjects
;
318 PyRef
const & getUnoModule();
324 struct RuntimeCargo
*cargo
;
326 static void del( PyObject
*self
);
328 /// @throws css::uno::RuntimeException
330 const css::uno::Reference
< css::uno::XComponentContext
> & xContext
);
334 class Adapter
: public cppu::WeakImplHelper
<
335 css::script::XInvocation
, css::lang::XUnoTunnel
>
337 PyRef mWrappedObject
;
338 PyInterpreterState
* const mInterpreter
; // interpreters don't seem to be refcounted !
339 css::uno::Sequence
< css::uno::Type
> const mTypes
;
340 MethodOutIndexMap m_methodOutIndexMap
;
343 css::uno::Sequence
< sal_Int16
> getOutIndexes( const OUString
& functionName
);
347 Adapter( const PyRef
&obj
,
348 const css::uno::Sequence
< css::uno::Type
> & types
);
350 static css::uno::Sequence
< sal_Int8
> getUnoTunnelId();
351 const PyRef
& getWrappedObject() const { return mWrappedObject
; }
352 const css::uno::Sequence
< css::uno::Type
>& getWrappedTypes() const { return mTypes
; }
353 virtual ~Adapter() override
;
356 virtual css::uno::Reference
< css::beans::XIntrospectionAccess
>
357 SAL_CALL
getIntrospection( ) override
;
358 virtual css::uno::Any SAL_CALL
invoke(
359 const OUString
& aFunctionName
,
360 const css::uno::Sequence
< css::uno::Any
>& aParams
,
361 css::uno::Sequence
< sal_Int16
>& aOutParamIndex
,
362 css::uno::Sequence
< css::uno::Any
>& aOutParam
) override
;
364 virtual void SAL_CALL
setValue(
365 const OUString
& aPropertyName
,
366 const css::uno::Any
& aValue
) override
;
368 virtual css::uno::Any SAL_CALL
getValue( const OUString
& aPropertyName
) override
;
369 virtual sal_Bool SAL_CALL
hasMethod( const OUString
& aName
) override
;
370 virtual sal_Bool SAL_CALL
hasProperty( const OUString
& aName
) override
;
373 virtual sal_Int64 SAL_CALL
getSomething(
374 const css::uno::Sequence
< sal_Int8
>& aIdentifier
) override
;
378 /** releases a refcount on the interpreter object and on another given python object.
380 The function can be called from any thread regardless of whether the global
381 interpreter lock is held.
384 void decreaseRefCount( PyInterpreterState
*interpreter
, PyObject
*object
);
390 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */