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 .
20 #include <sal/config.h>
25 #include <rtl/strbuf.hxx>
26 #include <rtl/ustrbuf.hxx>
28 #include <typelib/typedescription.hxx>
30 #include <com/sun/star/lang/XServiceInfo.hpp>
31 #include <com/sun/star/lang/XTypeProvider.hpp>
32 #include <com/sun/star/beans/UnknownPropertyException.hpp>
33 #include <com/sun/star/container/XEnumerationAccess.hpp>
34 #include <com/sun/star/container/XIndexAccess.hpp>
35 #include <com/sun/star/container/XIndexContainer.hpp>
36 #include <com/sun/star/container/XIndexReplace.hpp>
37 #include <com/sun/star/container/XNameAccess.hpp>
38 #include <com/sun/star/container/XNameContainer.hpp>
39 #include <com/sun/star/container/XNameReplace.hpp>
40 #include <com/sun/star/script/CannotConvertException.hpp>
41 #include <com/sun/star/script/XInvocation2.hpp>
42 #include <com/sun/star/script/XTypeConverter.hpp>
43 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
44 #include <comphelper/servicehelper.hxx>
46 #include "pyuno_impl.hxx"
48 using com::sun::star::uno::Sequence
;
49 using com::sun::star::uno::Reference
;
50 using com::sun::star::uno::XInterface
;
51 using com::sun::star::uno::Any
;
52 using com::sun::star::uno::makeAny
;
53 using com::sun::star::uno::UNO_QUERY
;
54 using com::sun::star::uno::Type
;
55 using com::sun::star::uno::TypeClass
;
56 using com::sun::star::uno::TypeDescription
;
57 using com::sun::star::uno::RuntimeException
;
58 using com::sun::star::uno::Exception
;
59 using com::sun::star::lang::XSingleServiceFactory
;
60 using com::sun::star::lang::XServiceInfo
;
61 using com::sun::star::lang::XTypeProvider
;
62 using com::sun::star::lang::XUnoTunnel
;
63 using com::sun::star::script::XInvocation2
;
64 using com::sun::star::container::XEnumeration
;
65 using com::sun::star::container::XEnumerationAccess
;
66 using com::sun::star::container::XIndexAccess
;
67 using com::sun::star::container::XIndexContainer
;
68 using com::sun::star::container::XIndexReplace
;
69 using com::sun::star::container::XNameAccess
;
70 using com::sun::star::container::XNameContainer
;
71 using com::sun::star::container::XNameReplace
;
76 static PyObject
*PyUNO_str( PyObject
* self
);
78 static void PyUNO_del (PyObject
* self
)
80 PyUNO
* me
= reinterpret_cast< PyUNO
* > (self
);
82 PyThreadDetach antiguard
;
89 OUString
val2str( const void * pVal
, typelib_TypeDescriptionReference
* pTypeRef
, sal_Int32 mode
)
92 if (pTypeRef
->eTypeClass
== typelib_TypeClass_VOID
)
95 OUStringBuffer
buf( 64 );
96 buf
.append( "(" + OUString::unacquired(&pTypeRef
->pTypeName
) + ")" );
98 switch (pTypeRef
->eTypeClass
)
100 case typelib_TypeClass_INTERFACE
:
103 OUString::number( reinterpret_cast< sal_IntPtr
>(*static_cast<void * const *>(pVal
)), 16 ));
104 if( VAL2STR_MODE_DEEP
== mode
)
106 buf
.append( "{" ); Reference
< XInterface
> r
= *static_cast<Reference
< XInterface
> const *>(pVal
);
107 Reference
< XServiceInfo
> serviceInfo( r
, UNO_QUERY
);
108 Reference
< XTypeProvider
> typeProvider(r
,UNO_QUERY
);
109 if( serviceInfo
.is() )
111 buf
.append("implementationName=" );
112 buf
.append(serviceInfo
->getImplementationName() );
113 buf
.append(", supportedServices={" );
114 Sequence
< OUString
> seq
= serviceInfo
->getSupportedServiceNames();
115 for( int i
= 0 ; i
< seq
.getLength() ; i
++ )
117 buf
.append( seq
[i
] );
118 if( i
+1 != seq
.getLength() )
124 if( typeProvider
.is() )
126 buf
.append(", supportedInterfaces={" );
127 Sequence
< Type
> seq (typeProvider
->getTypes());
128 for( int i
= 0 ; i
< seq
.getLength() ; i
++ )
130 buf
.append(seq
[i
].getTypeName());
131 if( i
+1 != seq
.getLength() )
141 case typelib_TypeClass_STRUCT
:
142 case typelib_TypeClass_EXCEPTION
:
145 typelib_TypeDescription
* pTypeDescr
= nullptr;
146 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
147 assert( pTypeDescr
);
149 typelib_CompoundTypeDescription
* pCompType
= reinterpret_cast<typelib_CompoundTypeDescription
*>(pTypeDescr
);
150 sal_Int32 nDescr
= pCompType
->nMembers
;
152 if (pCompType
->pBaseTypeDescription
)
154 buf
.append( val2str( pVal
, pCompType
->pBaseTypeDescription
->aBase
.pWeakRef
, mode
) );
159 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompType
->ppTypeRefs
;
160 sal_Int32
* pMemberOffsets
= pCompType
->pMemberOffsets
;
161 rtl_uString
** ppMemberNames
= pCompType
->ppMemberNames
;
163 for ( sal_Int32 nPos
= 0; nPos
< nDescr
; ++nPos
)
165 buf
.append( OUString::unacquired(&ppMemberNames
[nPos
]) + " = " );
166 typelib_TypeDescription
* pMemberType
= nullptr;
167 TYPELIB_DANGER_GET( &pMemberType
, ppTypeRefs
[nPos
] );
168 buf
.append( val2str( static_cast<char const *>(pVal
) + pMemberOffsets
[nPos
], pMemberType
->pWeakRef
, mode
) );
169 TYPELIB_DANGER_RELEASE( pMemberType
);
170 if (nPos
< (nDescr
-1))
174 TYPELIB_DANGER_RELEASE( pTypeDescr
);
179 case typelib_TypeClass_SEQUENCE
:
181 typelib_TypeDescription
* pTypeDescr
= nullptr;
182 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
184 uno_Sequence
* pSequence
= *static_cast<uno_Sequence
* const *>(pVal
);
185 typelib_TypeDescription
* pElementTypeDescr
= nullptr;
186 TYPELIB_DANGER_GET( &pElementTypeDescr
, reinterpret_cast<typelib_IndirectTypeDescription
*>(pTypeDescr
)->pType
);
188 sal_Int32 nElementSize
= pElementTypeDescr
->nSize
;
189 sal_Int32 nElements
= pSequence
->nElements
;
194 char * pElements
= pSequence
->elements
;
195 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
197 buf
.append( val2str( pElements
+ (nElementSize
* nPos
), pElementTypeDescr
->pWeakRef
, mode
) );
198 if (nPos
< (nElements
-1))
207 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
208 TYPELIB_DANGER_RELEASE( pTypeDescr
);
211 case typelib_TypeClass_ANY
:
213 buf
.append( val2str( static_cast<uno_Any
const *>(pVal
)->pData
,
214 static_cast<uno_Any
const *>(pVal
)->pType
,
218 case typelib_TypeClass_TYPE
:
219 buf
.append( (*static_cast<typelib_TypeDescriptionReference
* const *>(pVal
))->pTypeName
);
221 case typelib_TypeClass_STRING
:
223 OUString::unacquired(&*static_cast<rtl_uString
* const *>(pVal
)) +
226 case typelib_TypeClass_ENUM
:
228 typelib_TypeDescription
* pTypeDescr
= nullptr;
229 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
231 sal_Int32
* pValues
= reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->pEnumValues
;
232 sal_Int32 nPos
= reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->nEnumValues
;
235 if (pValues
[nPos
] == *static_cast<int const *>(pVal
))
239 buf
.append( reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->ppEnumNames
[nPos
] );
243 TYPELIB_DANGER_RELEASE( pTypeDescr
);
246 case typelib_TypeClass_BOOLEAN
:
247 if (*static_cast<sal_Bool
const *>(pVal
))
248 buf
.append( "true" );
250 buf
.append( "false" );
252 case typelib_TypeClass_CHAR
:
254 buf
.append( *static_cast<sal_Unicode
const *>(pVal
) );
257 case typelib_TypeClass_FLOAT
:
258 buf
.append( *static_cast<float const *>(pVal
) );
260 case typelib_TypeClass_DOUBLE
:
261 buf
.append( *static_cast<double const *>(pVal
) );
263 case typelib_TypeClass_BYTE
:
265 OUString::number( static_cast<sal_Int32
>(*static_cast<sal_Int8
const *>(pVal
)), 16 ));
267 case typelib_TypeClass_SHORT
:
269 OUString::number( static_cast<sal_Int32
>(*static_cast<sal_Int16
const *>(pVal
)), 16 ));
271 case typelib_TypeClass_UNSIGNED_SHORT
:
273 OUString::number( static_cast<sal_Int32
>(*static_cast<sal_uInt16
const *>(pVal
)), 16 ));
275 case typelib_TypeClass_LONG
:
277 OUString::number( *static_cast<sal_Int32
const *>(pVal
), 16 ));
279 case typelib_TypeClass_UNSIGNED_LONG
:
281 OUString::number( static_cast<sal_Int64
>(*static_cast<sal_uInt32
const *>(pVal
)), 16 ));
283 case typelib_TypeClass_HYPER
:
284 case typelib_TypeClass_UNSIGNED_HYPER
:
286 #if defined(__GNUC__) && defined(SPARC)
287 // I guess this really should check if there are strict alignment
288 // requirements, not just "GCC on SPARC".
291 *(sal_Int32
*)&aVal
= *(sal_Int32
*)pVal
;
292 *((sal_Int32
*)&aVal
+1)= *((sal_Int32
*)pVal
+1);
293 buf
.append( aVal
, 16 );
296 buf
.append( *static_cast<sal_Int64
const *>(pVal
), 16 );
300 case typelib_TypeClass_VOID
:
301 case typelib_TypeClass_UNKNOWN
:
302 case typelib_TypeClass_SERVICE
:
303 case typelib_TypeClass_MODULE
:
308 return buf
.makeStringAndClear();
311 static sal_Int32
lcl_PyNumber_AsSal_Int32( PyObject
*pObj
)
313 // Check object is an index
314 PyRef
rIndex( PyNumber_Index( pObj
), SAL_NO_ACQUIRE
);
318 // Convert Python number to platform long, then check actual value against
319 // bounds of sal_Int32
320 #if PY_VERSION_HEX >= 0x03020000
322 long nResult
= PyLong_AsLongAndOverflow( pObj
, &nOverflow
);
323 if ( nOverflow
|| nResult
> SAL_MAX_INT32
|| nResult
< SAL_MIN_INT32
) {
325 long nResult
= PyLong_AsLong( pObj
);
326 if ( nResult
> SAL_MAX_INT32
|| nResult
< SAL_MIN_INT32
) {
328 PyErr_SetString( PyExc_IndexError
, "Python int too large to convert to UNO long" );
335 static int lcl_PySlice_GetIndicesEx( PyObject
*pObject
, sal_Int32 nLen
, sal_Int32
*nStart
, sal_Int32
*nStop
, sal_Int32
*nStep
, sal_Int32
*nSliceLength
)
337 Py_ssize_t nStart_ssize
, nStop_ssize
, nStep_ssize
, nSliceLength_ssize
;
339 int nResult
= PySlice_GetIndicesEx(
340 #if PY_VERSION_HEX >= 0x030200f0
343 reinterpret_cast<PySliceObject
*>(pObject
),
345 nLen
, &nStart_ssize
, &nStop_ssize
, &nStep_ssize
, &nSliceLength_ssize
);
349 if ( nStart_ssize
> SAL_MAX_INT32
|| nStart_ssize
< SAL_MIN_INT32
350 || nStop_ssize
> SAL_MAX_INT32
|| nStop_ssize
< SAL_MIN_INT32
351 || nStep_ssize
> SAL_MAX_INT32
|| nStep_ssize
< SAL_MIN_INT32
352 || nSliceLength_ssize
> SAL_MAX_INT32
|| nSliceLength_ssize
< SAL_MIN_INT32
)
354 PyErr_SetString( PyExc_IndexError
, "Python int too large to convert to UNO long" );
358 *nStart
= static_cast<sal_Int32
>(nStart_ssize
);
359 *nStop
= static_cast<sal_Int32
>(nStop_ssize
);
360 *nStep
= static_cast<sal_Int32
>(nStep_ssize
);
361 *nSliceLength
= static_cast<sal_Int32
>(nSliceLength_ssize
);
365 static bool lcl_hasInterfaceByName( Any
const &object
, OUString
const & interfaceName
)
367 Reference
< XInterface
> xInterface( object
, UNO_QUERY
);
368 TypeDescription
typeDesc( interfaceName
);
369 Any aInterface
= xInterface
->queryInterface( typeDesc
.get()->pWeakRef
);
371 return aInterface
.hasValue();
374 static PyObject
*PyUNO_repr( PyObject
* self
)
376 return PyUNO_str( self
);
379 static Py_hash_t
PyUNO_hash( PyObject
*self
)
382 PyUNO
*me
= reinterpret_cast<PyUNO
*>(self
);
384 // Py_hash_t is not necessarily the same size as a pointer, but this is not
385 // important for hashing - it just has to return the same value each time
386 return sal::static_int_cast
< Py_hash_t
>( reinterpret_cast< sal_IntPtr
> (
387 *static_cast<void * const *>(me
->members
->wrappedObject
.getValue()) ) );
391 PyObject
*PyUNO_invoke( PyObject
*object
, const char *name
, PyObject
*args
)
398 PyRef paras
,callable
;
399 if( PyObject_IsInstance( object
, getPyUnoClass().get() ) )
401 PyUNO
* me
= reinterpret_cast<PyUNO
*>(object
);
402 OUString attrName
= OUString::createFromAscii(name
);
403 if (! me
->members
->xInvocation
->hasMethod (attrName
))
405 throw RuntimeException( "Attribute " + attrName
+ " unknown" );
407 callable
= PyUNO_callable_new (
408 me
->members
->xInvocation
,
415 // clean the tuple from uno.Any !
416 int size
= PyTuple_Size( args
);
417 { // for CC, keeping ref-count of tuple being 1
418 paras
= PyRef(PyTuple_New( size
), SAL_NO_ACQUIRE
);
420 for( int i
= 0 ; i
< size
;i
++ )
422 PyObject
* element
= PyTuple_GetItem( args
, i
);
423 if( PyObject_IsInstance( element
, getAnyClass( runtime
).get() ) )
425 element
= PyObject_GetAttrString(
430 Py_XINCREF( element
);
432 PyTuple_SetItem( paras
.get(), i
, element
);
434 callable
= PyRef( PyObject_GetAttrString( object
, name
), SAL_NO_ACQUIRE
);
438 ret
= PyRef( PyObject_CallObject( callable
.get(), paras
.get() ), SAL_NO_ACQUIRE
);
440 catch (const css::lang::IllegalArgumentException
&e
)
442 raisePyExceptionWithAny( css::uno::makeAny( e
) );
444 catch (const css::script::CannotConvertException
&e
)
446 raisePyExceptionWithAny( css::uno::makeAny( e
) );
448 catch (const css::uno::RuntimeException
&e
)
450 raisePyExceptionWithAny( css::uno::makeAny( e
) );
452 catch (const css::uno::Exception
&e
)
454 raisePyExceptionWithAny( css::uno::makeAny( e
) );
457 return ret
.getAcquired();
460 PyObject
*PyUNO_str( PyObject
* self
)
462 PyUNO
*me
= reinterpret_cast<PyUNO
*>(self
);
467 PyThreadDetach antiguard
;
469 OUString s
= val2str( me
->members
->wrappedObject
.getValue(),
470 me
->members
->wrappedObject
.getValueType().getTypeLibType() );
471 buf
= "pyuno object " + OUStringToOString(s
,RTL_TEXTENCODING_ASCII_US
);
474 return PyStr_FromString( buf
.getStr() );
477 static PyObject
* PyUNO_dir (PyObject
* self
)
479 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
481 PyObject
* member_list
= nullptr;
482 Sequence
<OUString
> oo_member_list
;
486 oo_member_list
= me
->members
->xInvocation
->getMemberNames ();
487 member_list
= PyList_New (oo_member_list
.getLength ());
488 for (int i
= 0; i
< oo_member_list
.getLength (); i
++)
490 // setitem steals a reference
491 PyList_SetItem (member_list
, i
, ustring2PyString(oo_member_list
[i
]).getAcquired() );
494 catch( const RuntimeException
&e
)
496 raisePyExceptionWithAny( makeAny(e
) );
502 static sal_Int32
lcl_detach_getLength( PyUNO
const *me
)
504 PyThreadDetach antiguard
;
506 // If both XIndexContainer and XNameContainer are implemented, it is
507 // assumed that getCount() gives the same result as the number of names
508 // returned by getElementNames(), or the user may be surprised.
510 // For XIndexContainer
511 Reference
< XIndexAccess
> xIndexAccess( me
->members
->xInvocation
, UNO_QUERY
);
512 if ( xIndexAccess
.is() )
514 return xIndexAccess
->getCount();
517 // For XNameContainer
518 // Not terribly efficient - get the count of all the names
519 Reference
< XNameAccess
> xNameAccess( me
->members
->xInvocation
, UNO_QUERY
);
520 if ( xNameAccess
.is() )
522 return xNameAccess
->getElementNames().getLength();
528 static int PyUNO_bool( PyObject
* self
)
530 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
534 int nLen
= lcl_detach_getLength( me
);
536 return nLen
== 0 ? 0 : 1;
538 // Anything which doesn't have members is a scalar object and therefore true
541 catch( const css::uno::RuntimeException
&e
)
543 raisePyExceptionWithAny( css::uno::makeAny( e
) );
549 static Py_ssize_t
PyUNO_len( PyObject
* self
)
551 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
555 int nLen
= lcl_detach_getLength( me
);
559 PyErr_SetString( PyExc_TypeError
, "object has no len()" );
561 catch( const css::uno::RuntimeException
&e
)
563 raisePyExceptionWithAny( css::uno::makeAny( e
) );
569 static void lcl_getRowsColumns( PyUNO
const * me
, sal_Int32
& nRows
, sal_Int32
& nColumns
)
571 Sequence
<short> aOutParamIndex
;
572 Sequence
<Any
> aOutParam
;
573 Sequence
<Any
> aParams
;
574 Any aRet
= me
->members
->xInvocation
->invoke ( "getRows", aParams
, aOutParamIndex
, aOutParam
);
575 Reference
< XIndexAccess
> xIndexAccessRows( aRet
, UNO_QUERY
);
576 nRows
= xIndexAccessRows
->getCount();
577 aRet
= me
->members
->xInvocation
->invoke ( "getColumns", aParams
, aOutParamIndex
, aOutParam
);
578 Reference
< XIndexAccess
> xIndexAccessCols( aRet
, UNO_QUERY
);
579 nColumns
= xIndexAccessCols
->getCount();
582 static PyRef
lcl_indexToSlice( const PyRef
& rIndex
)
584 Py_ssize_t nIndex
= PyNumber_AsSsize_t( rIndex
.get(), PyExc_IndexError
);
585 if (nIndex
== -1 && PyErr_Occurred())
587 PyRef
rStart( PyLong_FromSsize_t( nIndex
), SAL_NO_ACQUIRE
);
588 PyRef
rStop( PyLong_FromSsize_t( nIndex
+1 ), SAL_NO_ACQUIRE
);
589 PyRef
rStep( PyLong_FromLong( 1 ), SAL_NO_ACQUIRE
);
590 PyRef
rSlice( PySlice_New( rStart
.get(), rStop
.get(), rStep
.get() ), SAL_NO_ACQUIRE
);
595 static PyObject
* lcl_getitem_XCellRange( PyUNO
const * me
, PyObject
* pKey
)
599 Sequence
<short> aOutParamIndex
;
600 Sequence
<Any
> aOutParam
;
601 Sequence
<Any
> aParams
;
604 // Single string key is sugar for getCellRangeByName()
605 if ( PyStr_Check( pKey
) ) {
608 aParams
[0] <<= pyString2ustring( pKey
);
610 PyThreadDetach antiguard
;
611 aRet
= me
->members
->xInvocation
->invoke (
612 "getCellRangeByName", aParams
, aOutParamIndex
, aOutParam
);
614 PyRef rRet
= runtime
.any2PyObject ( aRet
);
615 return rRet
.getAcquired();
620 if ( PyIndex_Check( pKey
) )
622 // [0] is equivalent to [0,:]
624 rKey1
= PySlice_New( nullptr, nullptr, nullptr );
626 else if ( PyTuple_Check( pKey
) && (PyTuple_Size( pKey
) == 2) )
628 rKey0
= PyTuple_GetItem( pKey
, 0 );
629 rKey1
= PyTuple_GetItem( pKey
, 1 );
633 PyErr_SetString( PyExc_KeyError
, "invalid subscript" );
637 // If both keys are indices, return the corresponding cell
638 if ( PyIndex_Check( rKey0
.get() ) && PyIndex_Check( rKey1
.get() ))
640 sal_Int32 nKey0_s
= lcl_PyNumber_AsSal_Int32( rKey0
.get() );
641 sal_Int32 nKey1_s
= lcl_PyNumber_AsSal_Int32( rKey1
.get() );
643 if ( ((nKey0_s
== -1) || (nKey1_s
== -1)) && PyErr_Occurred() )
646 aParams
.realloc( 2 );
647 aParams
[0] <<= nKey1_s
;
648 aParams
[1] <<= nKey0_s
;
650 PyThreadDetach antiguard
;
651 aRet
= me
->members
->xInvocation
->invoke (
652 "getCellByPosition", aParams
, aOutParamIndex
, aOutParam
);
654 PyRef rRet
= runtime
.any2PyObject( aRet
);
655 return rRet
.getAcquired();
658 // If either argument is an index, coerce it to a slice
659 if ( PyIndex_Check( rKey0
.get() ) )
660 rKey0
= lcl_indexToSlice( rKey0
);
662 if ( PyIndex_Check( rKey1
.get() ) )
663 rKey1
= lcl_indexToSlice( rKey1
);
665 // If both arguments are slices, return the corresponding cell range
666 if ( PySlice_Check( rKey0
.get() ) && PySlice_Check( rKey1
.get() ) )
668 sal_Int32 nLen0
= SAL_MAX_INT32
, nLen1
= SAL_MAX_INT32
;
669 sal_Int32 nStart0
= 0, nStop0
= 0, nStep0
= 0, nSliceLength0
= 0;
670 sal_Int32 nStart1
= 0, nStop1
= 0, nStep1
= 0, nSliceLength1
= 0;
673 PyThreadDetach antiguard
;
675 if ( lcl_hasInterfaceByName( me
->members
->wrappedObject
, "com.sun.star.table.XColumnRowRange" ) )
677 lcl_getRowsColumns (me
, nLen0
, nLen1
);
681 int nSuccess1
= lcl_PySlice_GetIndicesEx( rKey0
.get(), nLen0
, &nStart0
, &nStop0
, &nStep0
, &nSliceLength0
);
682 int nSuccess2
= lcl_PySlice_GetIndicesEx( rKey1
.get(), nLen1
, &nStart1
, &nStop1
, &nStep1
, &nSliceLength1
);
683 if ( ((nSuccess1
== -1) || (nSuccess2
== -1)) && PyErr_Occurred() )
686 if ( nSliceLength0
<= 0 || nSliceLength1
<= 0 )
688 PyErr_SetString( PyExc_KeyError
, "invalid number of rows or columns" );
692 if ( nStep0
== 1 && nStep1
== 1 )
695 aParams
[0] <<= nStart1
;
696 aParams
[1] <<= nStart0
;
697 aParams
[2] <<= nStop1
- 1;
698 aParams
[3] <<= nStop0
- 1;
700 PyThreadDetach antiguard
;
701 aRet
= me
->members
->xInvocation
->invoke (
702 "getCellRangeByPosition", aParams
, aOutParamIndex
, aOutParam
);
704 PyRef rRet
= runtime
.any2PyObject( aRet
);
705 return rRet
.getAcquired();
708 PyErr_SetString( PyExc_KeyError
, "step != 1 not supported" );
712 PyErr_SetString( PyExc_KeyError
, "invalid subscript" );
716 static PyObject
* lcl_getitem_index( PyUNO
const *me
, PyObject
*pKey
, Runtime
const & runtime
)
721 nIndex
= lcl_PyNumber_AsSal_Int32( pKey
);
722 if (nIndex
== -1 && PyErr_Occurred())
726 PyThreadDetach antiguard
;
728 Reference
< XIndexAccess
> xIndexAccess( me
->members
->xInvocation
, UNO_QUERY
);
729 if ( xIndexAccess
.is() )
732 nIndex
+= xIndexAccess
->getCount();
733 aRet
= xIndexAccess
->getByIndex( nIndex
);
736 if ( aRet
.hasValue() )
738 PyRef
rRet ( runtime
.any2PyObject( aRet
) );
739 return rRet
.getAcquired();
745 static PyObject
* lcl_getitem_slice( PyUNO
const *me
, PyObject
*pKey
)
749 Reference
< XIndexAccess
> xIndexAccess
;
753 PyThreadDetach antiguard
;
755 xIndexAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
756 if ( xIndexAccess
.is() )
757 nLen
= xIndexAccess
->getCount();
760 if ( xIndexAccess
.is() )
762 sal_Int32 nStart
= 0, nStop
= 0, nStep
= 0, nSliceLength
= 0;
763 int nSuccess
= lcl_PySlice_GetIndicesEx(pKey
, nLen
, &nStart
, &nStop
, &nStep
, &nSliceLength
);
764 if ( nSuccess
== -1 && PyErr_Occurred() )
767 PyRef
rTuple( PyTuple_New( nSliceLength
), SAL_NO_ACQUIRE
, NOT_NULL
);
769 for ( nCur
= nStart
, i
= 0; i
< nSliceLength
; nCur
+= nStep
, i
++ )
774 PyThreadDetach antiguard
;
776 aRet
= xIndexAccess
->getByIndex( nCur
);
778 PyRef rRet
= runtime
.any2PyObject( aRet
);
779 PyTuple_SetItem( rTuple
.get(), i
, rRet
.getAcquired() );
782 return rTuple
.getAcquired();
788 static PyObject
* lcl_getitem_string( PyUNO
const *me
, PyObject
*pKey
, Runtime
const & runtime
)
790 OUString sKey
= pyString2ustring( pKey
);
794 PyThreadDetach antiguard
;
796 Reference
< XNameAccess
> xNameAccess( me
->members
->xInvocation
, UNO_QUERY
);
797 if ( xNameAccess
.is() )
799 aRet
= xNameAccess
->getByName( sKey
);
802 if ( aRet
.hasValue() )
804 PyRef rRet
= runtime
.any2PyObject( aRet
);
805 return rRet
.getAcquired();
811 static PyObject
* PyUNO_getitem( PyObject
*self
, PyObject
*pKey
)
813 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
818 // XIndexAccess access by index
819 if ( PyIndex_Check( pKey
) )
821 PyObject
* pRet
= lcl_getitem_index( me
, pKey
, runtime
);
822 if ( pRet
!= nullptr || PyErr_Occurred() )
826 // XIndexAccess access by slice
827 if ( PySlice_Check( pKey
) )
829 PyObject
* pRet
= lcl_getitem_slice( me
, pKey
);
830 if ( pRet
!= nullptr || PyErr_Occurred() )
834 // XNameAccess access by key
835 if ( PyStr_Check( pKey
) )
837 PyObject
* pRet
= lcl_getitem_string( me
, pKey
, runtime
);
838 if ( pRet
!= nullptr )
842 // XCellRange/XColumnRowRange specialisation
843 // Uses reflection as we can't have a hard dependency on XCellRange here
844 bool hasXCellRange
= false;
847 PyThreadDetach antiguard
;
849 hasXCellRange
= lcl_hasInterfaceByName( me
->members
->wrappedObject
, "com.sun.star.table.XCellRange" );
853 return lcl_getitem_XCellRange( me
, pKey
);
857 // If the object is an XIndexAccess and/or XNameAccess, but the
858 // key passed wasn't suitable, give a TypeError which specifically
860 Reference
< XIndexAccess
> xIndexAccess( me
->members
->xInvocation
, UNO_QUERY
);
861 Reference
< XNameAccess
> xNameAccess( me
->members
->xInvocation
, UNO_QUERY
);
862 if ( xIndexAccess
.is() || xNameAccess
.is() )
864 PyErr_SetString( PyExc_TypeError
, "subscription with invalid type" );
868 PyErr_SetString( PyExc_TypeError
, "object is not subscriptable" );
870 catch( const css::lang::IndexOutOfBoundsException
& )
872 PyErr_SetString( PyExc_IndexError
, "index out of range" );
874 catch( const css::container::NoSuchElementException
& )
876 PyErr_SetString( PyExc_KeyError
, "key not found" );
878 catch( const css::script::CannotConvertException
&e
)
880 raisePyExceptionWithAny( css::uno::makeAny( e
) );
882 catch( const css::lang::IllegalArgumentException
&e
)
884 raisePyExceptionWithAny( css::uno::makeAny( e
) );
886 catch( const css::lang::WrappedTargetException
&e
)
888 raisePyExceptionWithAny( css::uno::makeAny( e
) );
890 catch( const css::uno::RuntimeException
&e
)
892 raisePyExceptionWithAny( css::uno::makeAny( e
) );
898 static int lcl_setitem_index( PyUNO
const *me
, PyObject
*pKey
, PyObject
*pValue
)
902 Reference
< XIndexContainer
> xIndexContainer
;
903 Reference
< XIndexReplace
> xIndexReplace
;
904 sal_Int32 nIndex
= lcl_PyNumber_AsSal_Int32( pKey
);
905 if ( nIndex
== -1 && PyErr_Occurred() )
908 bool isTuple
= false;
911 if ( pValue
!= nullptr )
913 isTuple
= PyTuple_Check( pValue
);
917 aValue
= runtime
.pyObject2Any( pValue
);
919 catch ( const css::uno::RuntimeException
& )
921 // TODO pyObject2Any can't convert e.g. dicts but only throws
922 // RuntimeException on failure. Fixing this will require an audit of
923 // all the rest of PyUNO
924 throw css::script::CannotConvertException();
929 PyThreadDetach antiguard
;
931 xIndexContainer
.set( me
->members
->xInvocation
, UNO_QUERY
);
932 if ( xIndexContainer
.is() )
933 xIndexReplace
= xIndexContainer
;
935 xIndexReplace
.set( me
->members
->xInvocation
, UNO_QUERY
);
937 if ( xIndexReplace
.is() && nIndex
< 0 )
938 nIndex
+= xIndexReplace
->getCount();
940 // XIndexReplace replace by index
941 if ( (pValue
!= nullptr) && xIndexReplace
.is() )
945 // Apply type specialisation to ensure the correct kind of sequence is passed
946 Type aType
= xIndexReplace
->getElementType();
947 aValue
= runtime
.getImpl()->cargo
->xTypeConverter
->convertTo( aValue
, aType
);
950 xIndexReplace
->replaceByIndex( nIndex
, aValue
);
954 // XIndexContainer remove by index
955 if ( (pValue
== nullptr) && xIndexContainer
.is() )
957 xIndexContainer
->removeByIndex( nIndex
);
962 PyErr_SetString( PyExc_TypeError
, "cannot assign to object" );
966 static int lcl_setitem_slice( PyUNO
const *me
, PyObject
*pKey
, PyObject
*pValue
)
968 // XIndexContainer insert/remove/replace by slice
971 Reference
< XIndexReplace
> xIndexReplace
;
972 Reference
< XIndexContainer
> xIndexContainer
;
976 PyThreadDetach antiguard
;
978 xIndexContainer
.set( me
->members
->xInvocation
, UNO_QUERY
);
979 if ( xIndexContainer
.is() )
980 xIndexReplace
= xIndexContainer
;
982 xIndexReplace
.set( me
->members
->xInvocation
, UNO_QUERY
);
984 if ( xIndexReplace
.is() )
985 nLen
= xIndexReplace
->getCount();
988 if ( xIndexReplace
.is() )
990 sal_Int32 nStart
= 0, nStop
= 0, nStep
= 0, nSliceLength
= 0;
991 int nSuccess
= lcl_PySlice_GetIndicesEx( pKey
, nLen
, &nStart
, &nStop
, &nStep
, &nSliceLength
);
992 if ( (nSuccess
== -1) && PyErr_Occurred() )
995 if ( pValue
== nullptr )
997 pValue
= PyTuple_New( 0 );
1000 if ( !PyTuple_Check (pValue
) )
1002 PyErr_SetString( PyExc_TypeError
, "value is not a tuple" );
1006 Py_ssize_t nTupleLength_ssize
= PyTuple_Size( pValue
);
1007 if ( nTupleLength_ssize
> SAL_MAX_INT32
)
1009 PyErr_SetString( PyExc_ValueError
, "tuple too large" );
1012 sal_Int32 nTupleLength
= static_cast<sal_Int32
>(nTupleLength_ssize
);
1014 if ( (nTupleLength
!= nSliceLength
) && (nStep
!= 1) )
1016 PyErr_SetString( PyExc_ValueError
, "number of items assigned must be equal" );
1020 if ( (nTupleLength
!= nSliceLength
) && !xIndexContainer
.is() )
1022 PyErr_SetString( PyExc_ValueError
, "cannot change length" );
1027 sal_Int32 nMax
= ::std::max( nSliceLength
, nTupleLength
);
1028 for ( nCur
= nStart
, i
= 0; i
< nMax
; nCur
+= nStep
, i
++ )
1030 if ( i
< nTupleLength
)
1032 PyRef rItem
= PyTuple_GetItem( pValue
, i
);
1033 bool isTuple
= PyTuple_Check( rItem
.get() );
1038 aItem
= runtime
.pyObject2Any( rItem
.get() );
1040 catch ( const css::uno::RuntimeException
& )
1042 // TODO pyObject2Any can't convert e.g. dicts but only throws
1043 // RuntimeException on failure. Fixing this will require an audit of
1044 // all the rest of PyUNO
1045 throw css::script::CannotConvertException();
1049 PyThreadDetach antiguard
;
1053 // Apply type specialisation to ensure the correct kind of sequence is passed
1054 Type aType
= xIndexReplace
->getElementType();
1055 aItem
= runtime
.getImpl()->cargo
->xTypeConverter
->convertTo( aItem
, aType
);
1058 if ( i
< nSliceLength
)
1060 xIndexReplace
->replaceByIndex( nCur
, aItem
);
1064 xIndexContainer
->insertByIndex( nCur
, aItem
);
1070 PyThreadDetach antiguard
;
1072 xIndexContainer
->removeByIndex( nCur
);
1080 PyErr_SetString( PyExc_TypeError
, "cannot assign to object" );
1084 static int lcl_setitem_string( PyUNO
const *me
, PyObject
*pKey
, PyObject
*pValue
)
1088 OUString sKey
= pyString2ustring( pKey
);
1089 bool isTuple
= false;
1092 if ( pValue
!= nullptr)
1094 isTuple
= PyTuple_Check( pValue
);
1097 aValue
= runtime
.pyObject2Any( pValue
);
1099 catch( const css::uno::RuntimeException
& )
1101 // TODO pyObject2Any can't convert e.g. dicts but only throws
1102 // RuntimeException on failure. Fixing this will require an audit of
1103 // all the rest of PyUNO
1104 throw css::script::CannotConvertException();
1109 PyThreadDetach antiguard
;
1111 Reference
< XNameContainer
> xNameContainer( me
->members
->xInvocation
, UNO_QUERY
);
1112 Reference
< XNameReplace
> xNameReplace
;
1113 if ( xNameContainer
.is() )
1114 xNameReplace
= xNameContainer
;
1116 xNameReplace
.set( me
->members
->xInvocation
, UNO_QUERY
);
1118 if ( xNameReplace
.is() )
1120 if ( isTuple
&& aValue
.hasValue() )
1122 // Apply type specialisation to ensure the correct kind of sequence is passed
1123 Type aType
= xNameReplace
->getElementType();
1124 aValue
= runtime
.getImpl()->cargo
->xTypeConverter
->convertTo( aValue
, aType
);
1127 if ( aValue
.hasValue() )
1129 if ( xNameContainer
.is() )
1132 xNameContainer
->insertByName( sKey
, aValue
);
1135 catch( const css::container::ElementExistException
& )
1137 // Fall through, try replace instead
1141 xNameReplace
->replaceByName( sKey
, aValue
);
1144 else if ( xNameContainer
.is() )
1146 xNameContainer
->removeByName( sKey
);
1152 PyErr_SetString( PyExc_TypeError
, "cannot assign to object" );
1156 static int PyUNO_setitem( PyObject
*self
, PyObject
*pKey
, PyObject
*pValue
)
1158 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1162 if ( PyIndex_Check( pKey
) )
1164 return lcl_setitem_index( me
, pKey
, pValue
);
1166 else if ( PySlice_Check( pKey
) )
1168 return lcl_setitem_slice( me
, pKey
, pValue
);
1170 else if ( PyStr_Check( pKey
) )
1172 return lcl_setitem_string( me
, pKey
, pValue
);
1175 PyErr_SetString( PyExc_TypeError
, "list index has invalid type" );
1177 catch( const css::lang::IndexOutOfBoundsException
& )
1179 PyErr_SetString( PyExc_IndexError
, "list index out of range" );
1181 catch( const css::container::NoSuchElementException
& )
1183 PyErr_SetString( PyExc_KeyError
, "key not found" );
1185 catch( const css::lang::IllegalArgumentException
& )
1187 PyErr_SetString( PyExc_TypeError
, "value has invalid type" );
1189 catch( const css::script::CannotConvertException
& )
1191 PyErr_SetString( PyExc_TypeError
, "value has invalid type" );
1193 catch( const css::container::ElementExistException
&e
)
1195 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1197 catch( const css::lang::WrappedTargetException
&e
)
1199 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1201 catch( const css::uno::RuntimeException
&e
)
1203 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1209 static PyObject
* PyUNO_iter( PyObject
*self
)
1211 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1215 Reference
< XEnumerationAccess
> xEnumerationAccess
;
1216 Reference
< XEnumeration
> xEnumeration
;
1217 Reference
< XIndexAccess
> xIndexAccess
;
1218 Reference
< XNameAccess
> xNameAccess
;
1221 PyThreadDetach antiguard
;
1223 xEnumerationAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1224 if ( xEnumerationAccess
.is() )
1225 xEnumeration
= xEnumerationAccess
->createEnumeration();
1227 xEnumeration
.set( me
->members
->wrappedObject
, UNO_QUERY
);
1229 if ( !xEnumeration
.is() )
1230 xIndexAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1232 if ( !xIndexAccess
.is() )
1233 xNameAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1236 // XEnumerationAccess iterator
1237 // XEnumeration iterator
1238 if (xEnumeration
.is())
1240 return PyUNO_iterator_new( xEnumeration
);
1243 // XIndexAccess iterator
1244 if ( xIndexAccess
.is() )
1246 // We'd like to be able to use PySeqIter_New() here, but we're not
1247 // allowed to because we also implement the mapping protocol
1248 return PyUNO_list_iterator_new( xIndexAccess
);
1251 // XNameAccess iterator
1252 if (xNameAccess
.is())
1254 // There's no generic mapping iterator, but we can cobble our own
1255 // together using PySeqIter_New()
1260 PyThreadDetach antiguard
;
1261 aRet
<<= xNameAccess
->getElementNames();
1263 PyRef rNames
= runtime
.any2PyObject( aRet
);
1264 return PySeqIter_New( rNames
.getAcquired() );
1267 PyErr_SetString ( PyExc_TypeError
, "object is not iterable" );
1269 catch( css::script::CannotConvertException
&e
)
1271 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1273 catch( css::lang::IllegalArgumentException
&e
)
1275 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1277 catch( const css::uno::RuntimeException
&e
)
1279 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1285 static int PyUNO_contains( PyObject
*self
, PyObject
*pKey
)
1287 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1296 aValue
= runtime
.pyObject2Any( pKey
);
1298 catch( const css::uno::RuntimeException
& )
1300 // TODO pyObject2Any can't convert e.g. dicts but only throws
1301 // RuntimeException on failure. Fixing this will require an audit of
1302 // all the rest of PyUNO
1303 throw css::script::CannotConvertException();
1306 // XNameAccess is tried first, because checking key presence is much more
1307 // useful for objects which implement both XIndexAccess and XNameAccess
1310 if ( PyStr_Check( pKey
) )
1314 Reference
< XNameAccess
> xNameAccess
;
1317 PyThreadDetach antiguard
;
1319 xNameAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1320 if ( xNameAccess
.is() )
1322 bool hasKey
= xNameAccess
->hasByName( sKey
);
1323 return hasKey
? 1 : 0;
1328 // For any other type of PyUNO iterable: Ugly iterative search by
1329 // content (XIndexAccess, XEnumerationAccess, XEnumeration)
1330 PyRef
rIterator( PyUNO_iter( self
), SAL_NO_ACQUIRE
);
1331 if ( rIterator
.is() )
1333 while ( PyObject
* pItem
= PyIter_Next( rIterator
.get() ) )
1335 PyRef
rItem( pItem
, SAL_NO_ACQUIRE
);
1336 if ( PyObject_RichCompareBool( pKey
, rItem
.get(), Py_EQ
) == 1 )
1344 PyErr_SetString( PyExc_TypeError
, "argument is not iterable" );
1346 catch( const css::script::CannotConvertException
& )
1348 PyErr_SetString( PyExc_TypeError
, "invalid type passed as left argument to 'in'" );
1350 catch( const css::container::NoSuchElementException
&e
)
1352 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1354 catch( const css::lang::IndexOutOfBoundsException
&e
)
1356 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1358 catch( const css::lang::IllegalArgumentException
&e
)
1360 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1362 catch( const css::lang::WrappedTargetException
&e
)
1364 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1366 catch( const css::uno::RuntimeException
&e
)
1368 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1374 static PyObject
* PyUNO_getattr (PyObject
* self
, char* name
)
1383 me
= reinterpret_cast<PyUNO
*>(self
);
1384 if (strcmp (name
, "__dict__") == 0)
1386 Py_INCREF (Py_TYPE(me
)->tp_dict
);
1387 return Py_TYPE(me
)->tp_dict
;
1389 if (strcmp (name
, "__class__") == 0)
1391 Py_INCREF (Py_None
);
1395 PyObject
*pRet
= PyObject_GenericGetAttr( self
, PyUnicode_FromString( name
) );
1400 OUString
attrName( OUString::createFromAscii( name
) );
1401 //We need to find out if it's a method...
1402 if (me
->members
->xInvocation
->hasMethod (attrName
))
1404 //Create a callable object to invoke this...
1405 PyRef ret
= PyUNO_callable_new (
1406 me
->members
->xInvocation
,
1408 Py_XINCREF( ret
.get() );
1414 if (me
->members
->xInvocation
->hasProperty ( attrName
))
1416 //Return the value of the property
1419 PyThreadDetach antiguard
;
1420 anyRet
= me
->members
->xInvocation
->getValue (attrName
);
1422 PyRef ret
= runtime
.any2PyObject(anyRet
);
1423 Py_XINCREF( ret
.get() );
1428 PyErr_SetString (PyExc_AttributeError
, name
);
1430 catch( const css::reflection::InvocationTargetException
& e
)
1432 raisePyExceptionWithAny( e
.TargetException
);
1434 catch( const css::beans::UnknownPropertyException
& e
)
1436 raisePyExceptionWithAny( makeAny(e
) );
1438 catch( const css::lang::IllegalArgumentException
&e
)
1440 raisePyExceptionWithAny( makeAny(e
) );
1442 catch( const css::script::CannotConvertException
&e
)
1444 raisePyExceptionWithAny( makeAny(e
) );
1446 catch( const RuntimeException
&e
)
1448 raisePyExceptionWithAny( makeAny(e
) );
1454 static int PyUNO_setattr (PyObject
* self
, char* name
, PyObject
* value
)
1458 me
= reinterpret_cast<PyUNO
*>(self
);
1462 Any val
= runtime
.pyObject2Any(value
, ACCEPT_UNO_ANY
);
1464 OUString
attrName( OUString::createFromAscii( name
) );
1466 PyThreadDetach antiguard
;
1467 if (me
->members
->xInvocation
->hasProperty (attrName
))
1469 me
->members
->xInvocation
->setValue (attrName
, val
);
1470 return 0; //Keep with Python's boolean system
1474 catch( const css::reflection::InvocationTargetException
& e
)
1476 raisePyExceptionWithAny( e
.TargetException
);
1479 catch( const css::beans::UnknownPropertyException
& e
)
1481 raisePyExceptionWithAny( makeAny(e
) );
1484 catch( const css::script::CannotConvertException
&e
)
1486 raisePyExceptionWithAny( makeAny(e
) );
1489 catch( const RuntimeException
& e
)
1491 raisePyExceptionWithAny( makeAny( e
) );
1494 PyErr_SetString (PyExc_AttributeError
, name
);
1495 return 1; //as above.
1498 static PyObject
* PyUNO_cmp( PyObject
*self
, PyObject
*that
, int op
)
1502 if(op
!= Py_EQ
&& op
!= Py_NE
)
1504 PyErr_SetString(PyExc_TypeError
, "only '==' and '!=' comparisons are defined");
1509 result
= (op
== Py_EQ
? Py_True
: Py_False
);
1516 if( PyObject_IsInstance( that
, getPyUnoClass().get() ) )
1519 PyUNO
*me
= reinterpret_cast< PyUNO
*> ( self
);
1520 PyUNO
*other
= reinterpret_cast< PyUNO
*> (that
);
1521 css::uno::TypeClass tcMe
= me
->members
->wrappedObject
.getValueTypeClass();
1522 css::uno::TypeClass tcOther
= other
->members
->wrappedObject
.getValueTypeClass();
1524 if( tcMe
== tcOther
)
1526 if( me
->members
->wrappedObject
== other
->members
->wrappedObject
)
1528 result
= (op
== Py_EQ
? Py_True
: Py_False
);
1535 catch( const css::uno::RuntimeException
& e
)
1537 raisePyExceptionWithAny( makeAny( e
) );
1540 result
= (op
== Py_EQ
? Py_False
: Py_True
);
1545 static PyMethodDef PyUNOMethods
[] =
1547 {"__dir__", reinterpret_cast<PyCFunction
>(PyUNO_dir
), METH_NOARGS
, nullptr},
1548 {nullptr, nullptr, 0, nullptr}
1551 static PyNumberMethods PyUNONumberMethods
[] =
1553 nullptr, /* nb_add */
1554 nullptr, /* nb_subtract */
1555 nullptr, /* nb_multiply */
1556 #if PY_MAJOR_VERSION < 3
1557 nullptr, /* nb_divide */
1559 nullptr, /* nb_remainder */
1560 nullptr, /* nb_divmod */
1561 nullptr, /* nb_power */
1562 nullptr, /* nb_negative */
1563 nullptr, /* nb_positive */
1564 nullptr, /* nb_absolute */
1565 PyUNO_bool
, /* nb_bool */
1566 nullptr, /* nb_invert */
1567 nullptr, /* nb_lshift */
1568 nullptr, /* nb_rshift */
1569 nullptr, /* nb_and */
1570 nullptr, /* nb_xor */
1571 nullptr, /* nb_or */
1572 #if PY_MAJOR_VERSION < 3
1573 nullptr, /* nb_coerce */
1575 nullptr, /* nb_int */
1576 nullptr, /* nb_reserved */
1577 nullptr, /* nb_float */
1578 #if PY_MAJOR_VERSION < 3
1579 nullptr, /* nb_oct */
1580 nullptr, /* nb_hex */
1582 nullptr, /* nb_inplace_add */
1583 nullptr, /* nb_inplace_subtract */
1584 nullptr, /* nb_inplace_multiply */
1585 #if PY_MAJOR_VERSION < 3
1586 nullptr, /* nb_inplace_divide */
1588 nullptr, /* nb_inplace_remainder */
1589 nullptr, /* nb_inplace_power */
1590 nullptr, /* nb_inplace_lshift */
1591 nullptr, /* nb_inplace_rshift */
1592 nullptr, /* nb_inplace_and */
1593 nullptr, /* nb_inplace_xor */
1594 nullptr, /* nb_inplace_or */
1596 nullptr, /* nb_floor_divide */
1597 nullptr, /* nb_true_divide */
1598 nullptr, /* nb_inplace_floor_divide */
1599 nullptr, /* nb_inplace_true_divide */
1601 nullptr, /* nb_index */
1602 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
1603 nullptr, /* nb_matrix_multiply */
1604 nullptr, /* nb_inplace_matrix_multiply */
1608 static PySequenceMethods PyUNOSequenceMethods
[] =
1610 nullptr, /* sq_length */
1611 nullptr, /* sq_concat */
1612 nullptr, /* sq_repeat */
1613 nullptr, /* sq_item */
1614 nullptr, /* sq_slice */
1615 nullptr, /* sq_ass_item */
1616 nullptr, /* sq_ass_slice */
1617 PyUNO_contains
, /* sq_contains */
1618 nullptr, /* sq_inplace_concat */
1619 nullptr /* sq_inplace_repeat */
1622 static PyMappingMethods PyUNOMappingMethods
[] =
1624 PyUNO_len
, /* mp_length */
1625 PyUNO_getitem
, /* mp_subscript */
1626 PyUNO_setitem
, /* mp_ass_subscript */
1629 static PyTypeObject PyUNOType
=
1631 PyVarObject_HEAD_INIT( &PyType_Type
, 0 )
1636 #if PY_VERSION_HEX >= 0x03080000
1637 0, // Py_ssize_t tp_vectorcall_offset
1639 nullptr, // printfunc tp_print
1643 /* this type does not exist in Python 3: (cmpfunc) */ nullptr,
1646 PyUNOSequenceMethods
,
1647 PyUNOMappingMethods
,
1654 Py_TPFLAGS_HAVE_ITER
| Py_TPFLAGS_HAVE_RICHCOMPARE
| Py_TPFLAGS_HAVE_SEQUENCE_IN
,
1682 #if PY_VERSION_HEX >= 0x03040000
1684 #if PY_VERSION_HEX >= 0x03080000
1685 , nullptr // vectorcallfunc tp_vectorcall
1690 int PyUNO_initType()
1692 return PyType_Ready(&PyUNOType
);
1695 PyRef
getPyUnoClass()
1697 return PyRef( reinterpret_cast< PyObject
* > ( &PyUNOType
) );
1701 const Any
&targetInterface
,
1702 const Reference
<XSingleServiceFactory
> &ssf
)
1704 Reference
<XInvocation2
> xInvocation
;
1707 PyThreadDetach antiguard
;
1709 ssf
->createInstanceWithArguments( Sequence
<Any
>( &targetInterface
, 1 ) ), css::uno::UNO_QUERY_THROW
);
1711 auto that
= comphelper::getUnoTunnelImplementation
<Adapter
>(
1712 xInvocation
->getIntrospection()->queryAdapter(cppu::UnoType
<XUnoTunnel
>::get()));
1714 return that
->getWrappedObject();
1716 if( !Py_IsInitialized() )
1717 throw RuntimeException();
1719 PyUNO
* self
= PyObject_New (PyUNO
, &PyUNOType
);
1720 if (self
== nullptr)
1721 return PyRef(); // == error
1722 self
->members
= new PyUNOInternals
;
1723 self
->members
->xInvocation
= xInvocation
;
1724 self
->members
->wrappedObject
= targetInterface
;
1725 return PyRef( reinterpret_cast<PyObject
*>(self
), SAL_NO_ACQUIRE
);
1731 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */