LibreOffice Module pyuno (master) 1
pyuno_iterator.cxx
Go to the documentation of this file.
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
20#include <sal/config.h>
21
22#include "pyuno_impl.hxx"
23
24#include <com/sun/star/container/XEnumeration.hpp>
25#include <com/sun/star/container/XIndexAccess.hpp>
26#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27#include <com/sun/star/lang/WrappedTargetException.hpp>
28#include <com/sun/star/script/CannotConvertException.hpp>
29
30using com::sun::star::container::XEnumeration;
31using com::sun::star::container::XIndexAccess;
32using com::sun::star::lang::IndexOutOfBoundsException;
33using com::sun::star::lang::WrappedTargetException;
34using com::sun::star::uno::Any;
36using com::sun::star::uno::RuntimeException;
37
38
39namespace pyuno
40{
41
42static void PyUNO_iterator_del( PyObject* self )
43{
44 PyUNO_iterator* me = reinterpret_cast<PyUNO_iterator*>(self);
45
46 {
47 PyThreadDetach antiguard;
48 delete me->members;
49 }
50 PyObject_Del( self );
51}
52
53static PyObject* PyUNO_iterator_iter( PyObject *self )
54{
55 Py_INCREF( self );
56 return self;
57}
58
59static PyObject* PyUNO_iterator_next( PyObject *self )
60{
61 PyUNO_iterator* me = reinterpret_cast<PyUNO_iterator*>(self);
62
63 Runtime runtime;
64 Any aRet;
65
66 try
67 {
68 bool hasMoreElements = false;
69
70 {
71 PyThreadDetach antiguard;
72
73 hasMoreElements = me->members->xEnumeration->hasMoreElements();
74 if ( hasMoreElements )
75 {
76 aRet = me->members->xEnumeration->nextElement();
77 }
78 }
79
80 if ( hasMoreElements )
81 {
82 PyRef rRet = runtime.any2PyObject( aRet );
83 return rRet.getAcquired();
84 }
85
86 PyErr_SetString( PyExc_StopIteration, "" );
87 return nullptr;
88 }
89 catch( css::container::NoSuchElementException &e )
90 {
91 raisePyExceptionWithAny( css::uno::Any( e ) );
92 }
93 catch( css::script::CannotConvertException &e )
94 {
95 raisePyExceptionWithAny( css::uno::Any( e ) );
96 }
97 catch( css::lang::IllegalArgumentException &e )
98 {
99 raisePyExceptionWithAny( css::uno::Any( e ) );
100 }
101 catch( const css::lang::WrappedTargetException &e )
102 {
103 raisePyExceptionWithAny( css::uno::Any( e ) );
104 }
105 catch( const css::uno::RuntimeException &e )
106 {
107 raisePyExceptionWithAny( css::uno::Any( e ) );
108 }
109
110 return nullptr;
111}
112
113static PyTypeObject PyUNO_iterator_Type =
114{
115 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
116 "PyUNO_iterator",
117 sizeof (PyUNO_iterator),
118 0,
120#if PY_VERSION_HEX >= 0x03080000
121 0, // Py_ssize_t tp_vectorcall_offset
122#else
123 nullptr, // printfunc tp_print
124#endif
125 nullptr,
126 nullptr,
127 nullptr,
128 nullptr,
129 nullptr,
130 nullptr,
131 nullptr,
132 nullptr,
133 nullptr,
134 nullptr,
135 nullptr,
136 nullptr,
137 nullptr,
139 nullptr,
140 nullptr,
141 nullptr,
142 nullptr,
143 0,
144 PyUNO_iterator_iter, // Generic, reused between the iterator types
146 nullptr,
147 nullptr,
148 nullptr,
149 nullptr,
150 nullptr,
151 nullptr,
152 nullptr,
153 0,
154 nullptr,
155 nullptr,
156 nullptr,
157 nullptr,
158 nullptr,
159 nullptr,
160 nullptr,
161 nullptr,
162 nullptr,
163 nullptr,
164 nullptr,
165 0
166#if PY_VERSION_HEX >= 0x03040000
167 , nullptr
168#if PY_VERSION_HEX >= 0x03080000
169 , nullptr // vectorcallfunc tp_vectorcall
170#if PY_VERSION_HEX < 0x03090000
171#if defined __clang__
172#pragma clang diagnostic push
173#pragma clang diagnostic ignored "-Wdeprecated-declarations"
174#endif
175 , nullptr // tp_print
176#if defined __clang__
177#pragma clang diagnostic pop
178#endif
179#endif
180#endif
181#endif
182};
183
184PyObject* PyUNO_iterator_new( const Reference< XEnumeration >& xEnumeration )
185{
186 PyUNO_iterator* self = PyObject_New( PyUNO_iterator, &PyUNO_iterator_Type );
187 if ( self == nullptr )
188 return nullptr; // == error
190 self->members->xEnumeration = xEnumeration;
191 return reinterpret_cast<PyObject*>(self);
192}
193
195
196static void PyUNO_list_iterator_del( PyObject* self )
197{
198 PyUNO_list_iterator* me = reinterpret_cast<PyUNO_list_iterator*>(self);
199
200 {
201 PyThreadDetach antiguard;
202 delete me->members;
203 }
204 PyObject_Del( self );
205}
206
207
208static PyObject* PyUNO_list_iterator_next( PyObject *self )
209{
210 PyUNO_list_iterator* me = reinterpret_cast<PyUNO_list_iterator*>(self);
211
212 Runtime runtime;
213 Any aRet;
214
215 try
216 {
217 bool noMoreElements = false;
218 {
219 PyThreadDetach antiguard;
220 try {
221 aRet = me->members->xIndexAccess->getByIndex( me->members->index );
222 }
223 catch( const css::lang::IndexOutOfBoundsException & )
224 {
225 noMoreElements = true;
226 }
227 }
228
229 if ( noMoreElements )
230 {
231 PyErr_SetString( PyExc_StopIteration, "" );
232 return nullptr;
233 }
234
235 PyRef rRet = runtime.any2PyObject( aRet );
236 me->members->index++;
237 return rRet.getAcquired();
238 }
239 catch( css::script::CannotConvertException &e )
240 {
241 raisePyExceptionWithAny( css::uno::Any( e ) );
242 }
243 catch( css::lang::IllegalArgumentException &e )
244 {
245 raisePyExceptionWithAny( css::uno::Any( e ) );
246 }
247 catch( const css::lang::WrappedTargetException &e )
248 {
249 raisePyExceptionWithAny( css::uno::Any( e ) );
250 }
251 catch( const css::uno::RuntimeException &e )
252 {
253 raisePyExceptionWithAny( css::uno::Any( e ) );
254 }
255
256 return nullptr;
257}
258
259static PyTypeObject PyUNO_list_iterator_Type =
260{
261 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
262 "PyUNO_iterator",
263 sizeof (PyUNO_list_iterator),
264 0,
266#if PY_VERSION_HEX >= 0x03080000
267 0, // Py_ssize_t tp_vectorcall_offset
268#else
269 nullptr, // printfunc tp_print
270#endif
271 nullptr,
272 nullptr,
273 nullptr,
274 nullptr,
275 nullptr,
276 nullptr,
277 nullptr,
278 nullptr,
279 nullptr,
280 nullptr,
281 nullptr,
282 nullptr,
283 nullptr,
285 nullptr,
286 nullptr,
287 nullptr,
288 nullptr,
289 0,
290 PyUNO_iterator_iter, // Generic, reused between the iterator types
292 nullptr,
293 nullptr,
294 nullptr,
295 nullptr,
296 nullptr,
297 nullptr,
298 nullptr,
299 0,
300 nullptr,
301 nullptr,
302 nullptr,
303 nullptr,
304 nullptr,
305 nullptr,
306 nullptr,
307 nullptr,
308 nullptr,
309 nullptr,
310 nullptr,
311 0
312#if PY_VERSION_HEX >= 0x03040000
313 , nullptr
314#if PY_VERSION_HEX >= 0x03080000
315 , nullptr // vectorcallfunc tp_vectorcall
316#if PY_VERSION_HEX < 0x03090000
317#if defined __clang__
318#pragma clang diagnostic push
319#pragma clang diagnostic ignored "-Wdeprecated-declarations"
320#endif
321 , nullptr // tp_print
322#if defined __clang__
323#pragma clang diagnostic pop
324#endif
325#endif
326#endif
327#endif
328};
329
330PyObject* PyUNO_list_iterator_new( const Reference<XIndexAccess> &xIndexAccess )
331{
333 if ( self == nullptr )
334 return nullptr; // == error
336 self->members->xIndexAccess = xIndexAccess;
337 self->members->index = 0;
338 return reinterpret_cast<PyObject*>(self);
339}
340
341}
342
343/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Helper class for keeping references to python objects.
Definition: pyuno.hxx:80
PyObject * getAcquired() const
Definition: pyuno.hxx:101
helper class for detaching the current thread from the python runtime to do some blocking,...
Definition: pyuno.hxx:300
The pyuno::Runtime class keeps the internal state of the python UNO bridge for the currently in use p...
Definition: pyuno.hxx:164
PyRef any2PyObject(const css::uno::Any &source) const
converts something contained in a UNO Any to a Python object
Definition: pyuno.cxx:72
PyObject * PyUNO_list_iterator_new(const css::uno::Reference< css::container::XIndexAccess > &xIndexAccess)
static PyObject * PyUNO_list_iterator_next(PyObject *self)
static PyTypeObject PyUNO_iterator_Type
void raisePyExceptionWithAny(const css::uno::Any &anyExc)
PyObject * PyUNO_iterator_new(const css::uno::Reference< css::container::XEnumeration > &xEnumeration)
static void PyUNO_list_iterator_del(PyObject *self)
static PyObject * PyUNO_iterator_next(PyObject *self)
static PyTypeObject PyUNO_list_iterator_Type
static PyObject * PyUNO_iterator_iter(PyObject *self)
static void PyUNO_iterator_del(PyObject *self)
#define Py_TPFLAGS_HAVE_ITER
Definition: pyuno_impl.hxx:30
css::uno::Reference< css::container::XEnumeration > xEnumeration
Definition: pyuno_impl.hxx:146
PyObject_HEAD PyUNO_iterator_Internals * members
Definition: pyuno_impl.hxx:152
css::uno::Reference< css::container::XIndexAccess > xIndexAccess
Definition: pyuno_impl.hxx:160
PyObject_HEAD PyUNO_list_iterator_Internals * members
Definition: pyuno_impl.hxx:167