2222
2323// Macro to wrap data iterators
2424%define DATA_ITERATOR (container_type, datum_type)
25- %feature(" python:slot" , " tp_str" , functype=" reprfunc" )
26- container_type##_iterator::__str__;
27- %feature(" python:slot" , " tp_iter" , functype=" getiterfunc" )
28- container_type##_iterator::__iter__;
29- %feature(" python:slot" , " tp_iternext" , functype=" iternextfunc" )
30- container_type##_iterator::__next__;
31- %noexception container_type##_iterator::__iter__;
32- %noexception container_type##_iterator::operator ==;
33- %noexception container_type##_iterator::operator !=;
34- %ignore container_type##_iterator::size;
35- %ignore container_type##_iterator::##container_type##_iterator;
36- %ignore container_type##_iterator::operator *;
37- %ignore container_type##_iterator::_invalidate;
38- %feature(" docstring" ) container_type##_iterator "
39- Python wrapper for an :class:`" #container_type " ` iterator. It has most of
40- the methods of :class:`" #datum_type " ` allowing easy access to the
41- data it points to."
4225// Creating a new iterator keeps a reference to the current one
4326KEEP_REFERENCE(container_type##_iterator*)
44- // Detect end of iteration
45- %typemap(out) Exiv2::datum_type* __next__ {
46- if (!$1 ) {
47- PyErr_SetNone (PyExc_StopIteration);
48- SWIG_fail;
49- }
50- $typemap (out, Exiv2::datum_type*)
51- }
52- %inline %{
53- class container_type ##_iterator {
54- private:
55- Exiv2::container_type::iterator ptr;
56- Exiv2::container_type::iterator end;
57- bool invalidated;
58- public:
59- container_type##_iterator(Exiv2::container_type::iterator ptr,
60- Exiv2::container_type::iterator end) {
61- this ->ptr = ptr;
62- this ->end = end;
63- invalidated = false ;
64- }
65- container_type##_iterator* __iter__ () { return this ; }
66- Exiv2::datum_type* __next__ () {
67- if (invalidated)
68- throw std::runtime_error (
69- " container_type changed size during iteration" );
70- if (ptr == end)
71- return NULL ;
72- return &(*ptr++);
73- }
74- Exiv2::container_type::iterator operator *() const { return ptr; }
75- bool operator ==(const container_type##_iterator &other) const {
76- return *other == ptr;
77- }
78- bool operator !=(const container_type##_iterator &other) const {
79- return *other != ptr;
80- }
81- std::string __str__ () {
82- if (invalidated)
83- return " invalid iterator" ;
84- if (ptr == end)
85- return " iterator<end>" ;
86- return " iterator<" + ptr->key () + " : " + ptr->print () + " >" ;
87- }
88- // Invalidate iterator unilaterally
89- void _invalidate () { invalidated = true ; }
90- // Invalidate iterator if what it points to has been deleted
91- bool _invalidate (Exiv2::container_type::iterator deleted) {
92- if (deleted == ptr)
93- invalidated = true ;
94- return invalidated;
95- }
96- // Provide size() C++ method for buffer size check
97- size_t size () {
98- if (invalidated || ptr == end)
99- return 0 ;
100- return ptr->size ();
101- }
102- // Dereference operator gives access to all datum methods
103- Exiv2::datum_type* operator ->() const {
104- if (invalidated)
105- throw std::runtime_error (
106- " container_type changed size during iteration" );
107- if (ptr == end)
108- throw std::runtime_error (
109- " container_type iterator is at end of data" );
110- return &(*ptr);
111- }
112- };
113- %}
11427
115- %typemap(in) Exiv2::container_type::iterator
116- (container_type##_iterator *argp=NULL ) %{
117- {
118- container_type##_iterator* arg$argnum = NULL ;
119- $typemap (in, container_type##_iterator*)
120- argp = arg$argnum;
121- }
122- $1 = **argp;
123- %}
12428#if SWIG_VERSION < 0x040400
12529// erase() invalidates the iterator
12630%typemap(in) (Exiv2::container_type::iterator pos)
@@ -132,7 +36,7 @@ public:
13236 $typemap (in, container_type##_iterator*)
13337 argp = arg$argnum;
13438 }
135- $1 = ** argp;
39+ $1 = argp-> _ptr () ;
13640 argp->_invalidate ();
13741}
13842#endif
@@ -145,7 +49,7 @@ public:
14549 $typemap (in, container_type##_iterator*)
14650 argp = arg$argnum;
14751 }
148- it = ** argp;
52+ it = argp-> _ptr () ;
14953 $1 = ⁢
15054#if SWIG_VERSION < 0x040400
15155 argp->_invalidate ();
@@ -251,29 +155,7 @@ static int store_iterator(PyObject* py_self, PyObject* iterator) {
251155}
252156#endif // SWIG_VERSION
253157
254- %newobject Exiv2::container_type::begin;
255- %newobject Exiv2::container_type::end;
256- %newobject Exiv2::container_type::erase;
257- %newobject Exiv2::container_type::findId;
258- %newobject Exiv2::container_type::findKey;
259- // Assumes arg1 is the base class parent
260- #if SWIG_VERSION >= 0x040400
261- %typemap(out, fragment=" iterator_store" )
262- Exiv2::container_type::iterator {
263- #else
264- %typemap (out) Exiv2::container_type::iterator {
265- #endif
266- Exiv2::container_type::iterator tmp = $1 ;
267- container_type##_iterator* $1 = new container_type##_iterator (
268- tmp, arg1->end ());
269- $typemap (out, container_type##_iterator*);
270- #if SWIG_VERSION >= 0x040400
271- // Keep weak reference to the Python iterator
272- if (store_iterator (self, $result)) {
273- SWIG_fail;
274- }
275- #endif // SWIG_VERSION
276- }
277158// Keep a reference to the data being iterated
278159KEEP_REFERENCE (Exiv2::container_type::iterator)
160+
279161%enddef // DATA_ITERATOR
0 commit comments