Skip to content

Commit 26bdd62

Browse files
Only invalidate iterators that need to be
When using swig >= 4.4.
1 parent c38f184 commit 26bdd62

File tree

8 files changed

+158
-201
lines changed

8 files changed

+158
-201
lines changed

src/interface/shared/data_iterator.i

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
%ignore container_type##_iterator::size;
3535
%ignore container_type##_iterator::##container_type##_iterator;
3636
%ignore container_type##_iterator::operator*;
37+
%ignore container_type##_iterator::_invalidate;
3738
%feature("docstring") container_type##_iterator "
3839
Python wrapper for an :class:`" #container_type "` iterator. It has most of
3940
the methods of :class:`" #datum_type "` allowing easy access to the
@@ -84,8 +85,25 @@ public:
8485
return "iterator<end>";
8586
return "iterator<" + ptr->key() + ": " + ptr->print() + ">";
8687
}
87-
// Provide method to invalidate iterator
88+
// Provide method to invalidate iterator unilaterally
8889
void _invalidate() { invalidated = true; }
90+
// Provide method to invalidate iterator if in deleted range
91+
void _invalidate(Exiv2::container_type::iterator b,
92+
Exiv2::container_type::iterator e) {
93+
if (b == e) {
94+
// begin() == end() after clear()
95+
if (b == ptr || b == end)
96+
invalidated = true;
97+
return;
98+
}
99+
while (b != e) {
100+
if (b == ptr) {
101+
invalidated = true;
102+
return;
103+
}
104+
b++;
105+
}
106+
}
89107
// Provide size() C++ method for buffer size check
90108
size_t size() {
91109
if (invalidated || ptr == end)
@@ -145,25 +163,35 @@ public:
145163
#endif
146164
}
147165

166+
#if SWIG_VERSION >= 0x040400
148167
// Functions to store weak references to iterators (swig >= v4.4)
149168
%fragment("iterator_weakref_funcs", "header", fragment="private_data") {
150-
static void _process_list(PyObject* list, bool invalidate) {
151-
PyObject* iterator = NULL;
169+
static void _process_list(PyObject* list,
170+
Exiv2::container_type::iterator* beg,
171+
Exiv2::container_type::iterator* end) {
172+
PyObject* py_it = NULL;
173+
container_type##_iterator* cpp_it = NULL;
152174
for (Py_ssize_t idx = PyList_Size(list); idx > 0; idx--) {
153-
iterator = PyWeakref_GetObject(PyList_GetItem(list, idx-1));
154-
if (iterator == Py_None)
175+
py_it = PyWeakref_GetObject(PyList_GetItem(list, idx-1));
176+
if (py_it == Py_None)
155177
PyList_SetSlice(list, idx-1, idx, NULL);
156-
else if (invalidate)
157-
Py_XDECREF(PyObject_CallMethod(iterator, "_invalidate", NULL));
178+
else if (beg) {
179+
if (SWIG_IsOK(SWIG_ConvertPtr(
180+
py_it, (void**)&cpp_it,
181+
$descriptor(container_type##_iterator*), 0)))
182+
cpp_it->_invalidate(*beg, *end);
183+
}
158184
}
159185
};
160186
static void purge_iterators(PyObject* list) {
161-
_process_list(list, false);
187+
_process_list(list, NULL, NULL);
162188
};
163-
static void invalidate_iterators(PyObject* py_self) {
189+
static void invalidate_iterators(PyObject* py_self,
190+
Exiv2::container_type::iterator beg,
191+
Exiv2::container_type::iterator end) {
164192
PyObject* list = private_store_get(py_self, "iterators");
165193
if (list)
166-
_process_list(list, true);
194+
_process_list(list, &beg, &end);
167195
};
168196
static int store_iterator_weakref(PyObject* py_self, PyObject* iterator) {
169197
PyObject* list = private_store_get(py_self, "iterators");
@@ -186,17 +214,23 @@ static int store_iterator_weakref(PyObject* py_self, PyObject* iterator) {
186214
return result;
187215
};
188216
}
217+
#endif
189218

190219
#if SWIG_VERSION >= 0x040400
191220
// clear() invalidates all iterators
192221
%typemap(ret, typemap="iterator_weakref_funcs") void clear {
193-
invalidate_iterators(self);
222+
invalidate_iterators(self, arg1->begin(), arg1->end());
194223
}
195224
// erase() and eraseFamily() may invalidate iterators
196-
%typemap(check) (Exiv2::container_type::iterator pos),
197-
(Exiv2::container_type::iterator beg),
198-
(Exiv2::container_type::iterator&) {
199-
invalidate_iterators(self);
225+
%typemap(check) Exiv2::container_type::iterator pos {
226+
invalidate_iterators(self, $1, $1);
227+
}
228+
%typemap(check) (Exiv2::container_type::iterator beg,
229+
Exiv2::container_type::iterator end) {
230+
invalidate_iterators(self, $1, $2);
231+
}
232+
%typemap(check) Exiv2::container_type::iterator& pos {
233+
invalidate_iterators(self, *$1, arg1->end());
200234
}
201235
#endif // SWIG_VERSION
202236

src/swig-0_27_7/exif_wrap.cxx

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4408,8 +4408,25 @@ class ExifData_iterator {
44084408
return "iterator<end>";
44094409
return "iterator<" + ptr->key() + ": " + ptr->print() + ">";
44104410
}
4411-
// Provide method to invalidate iterator
4411+
// Provide method to invalidate iterator unilaterally
44124412
void _invalidate() { invalidated = true; }
4413+
// Provide method to invalidate iterator if in deleted range
4414+
void _invalidate(Exiv2::ExifData::iterator b,
4415+
Exiv2::ExifData::iterator e) {
4416+
if (b == e) {
4417+
// begin() == end() after clear()
4418+
if (b == ptr || b == end)
4419+
invalidated = true;
4420+
return;
4421+
}
4422+
while (b != e) {
4423+
if (b == ptr) {
4424+
invalidated = true;
4425+
return;
4426+
}
4427+
b++;
4428+
}
4429+
}
44134430
// Provide size() C++ method for buffer size check
44144431
size_t size() {
44154432
if (invalidated || ptr == end)
@@ -5729,34 +5746,6 @@ SWIGINTERN PyObject *_wrap_ExifData_iterator___str__(PyObject *self, PyObject *a
57295746
}
57305747

57315748

5732-
SWIGINTERN PyObject *_wrap_ExifData_iterator__invalidate(PyObject *self, PyObject *args) {
5733-
PyObject *resultobj = 0;
5734-
ExifData_iterator *arg1 = (ExifData_iterator *) 0 ;
5735-
void *argp1 = 0 ;
5736-
int res1 = 0 ;
5737-
5738-
if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, "ExifData_iterator__invalidate takes no arguments");
5739-
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ExifData_iterator, 0 | 0 );
5740-
if (!SWIG_IsOK(res1)) {
5741-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ExifData_iterator__invalidate" "', argument " "1"" of type '" "ExifData_iterator *""'");
5742-
}
5743-
arg1 = reinterpret_cast< ExifData_iterator * >(argp1);
5744-
{
5745-
try {
5746-
(arg1)->_invalidate();
5747-
}
5748-
catch(std::exception const& e) {
5749-
_set_python_exception();
5750-
SWIG_fail;
5751-
}
5752-
}
5753-
resultobj = SWIG_Py_Void();
5754-
return resultobj;
5755-
fail:
5756-
return NULL;
5757-
}
5758-
5759-
57605749
SWIGINTERN PyObject *_wrap_ExifData_iterator___deref__(PyObject *self, PyObject *args) {
57615750
PyObject *resultobj = 0;
57625751
ExifData_iterator *arg1 = (ExifData_iterator *) 0 ;
@@ -10373,7 +10362,6 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__ExifData_iterator_methods[] = {
1037310362
{ "__eq__", _wrap_ExifData_iterator___eq__, METH_VARARGS, "" },
1037410363
{ "__ne__", _wrap_ExifData_iterator___ne__, METH_VARARGS, "" },
1037510364
{ "__str__", _wrap_ExifData_iterator___str__, METH_VARARGS, "" },
10376-
{ "_invalidate", _wrap_ExifData_iterator__invalidate, METH_VARARGS, "" },
1037710365
{ "__deref__", _wrap_ExifData_iterator___deref__, METH_VARARGS, "" },
1037810366
{ "setValue", _wrap_ExifData_iterator_setValue, METH_VARARGS, "" },
1037910367
{ "setDataArea", _wrap_ExifData_iterator_setDataArea, METH_VARARGS, "\n"

src/swig-0_27_7/iptc_wrap.cxx

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4401,8 +4401,25 @@ class IptcData_iterator {
44014401
return "iterator<end>";
44024402
return "iterator<" + ptr->key() + ": " + ptr->print() + ">";
44034403
}
4404-
// Provide method to invalidate iterator
4404+
// Provide method to invalidate iterator unilaterally
44054405
void _invalidate() { invalidated = true; }
4406+
// Provide method to invalidate iterator if in deleted range
4407+
void _invalidate(Exiv2::IptcData::iterator b,
4408+
Exiv2::IptcData::iterator e) {
4409+
if (b == e) {
4410+
// begin() == end() after clear()
4411+
if (b == ptr || b == end)
4412+
invalidated = true;
4413+
return;
4414+
}
4415+
while (b != e) {
4416+
if (b == ptr) {
4417+
invalidated = true;
4418+
return;
4419+
}
4420+
b++;
4421+
}
4422+
}
44064423
// Provide size() C++ method for buffer size check
44074424
size_t size() {
44084425
if (invalidated || ptr == end)
@@ -5669,34 +5686,6 @@ SWIGINTERN PyObject *_wrap_IptcData_iterator___str__(PyObject *self, PyObject *a
56695686
}
56705687

56715688

5672-
SWIGINTERN PyObject *_wrap_IptcData_iterator__invalidate(PyObject *self, PyObject *args) {
5673-
PyObject *resultobj = 0;
5674-
IptcData_iterator *arg1 = (IptcData_iterator *) 0 ;
5675-
void *argp1 = 0 ;
5676-
int res1 = 0 ;
5677-
5678-
if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, "IptcData_iterator__invalidate takes no arguments");
5679-
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_IptcData_iterator, 0 | 0 );
5680-
if (!SWIG_IsOK(res1)) {
5681-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IptcData_iterator__invalidate" "', argument " "1"" of type '" "IptcData_iterator *""'");
5682-
}
5683-
arg1 = reinterpret_cast< IptcData_iterator * >(argp1);
5684-
{
5685-
try {
5686-
(arg1)->_invalidate();
5687-
}
5688-
catch(std::exception const& e) {
5689-
_set_python_exception();
5690-
SWIG_fail;
5691-
}
5692-
}
5693-
resultobj = SWIG_Py_Void();
5694-
return resultobj;
5695-
fail:
5696-
return NULL;
5697-
}
5698-
5699-
57005689
SWIGINTERN PyObject *_wrap_IptcData_iterator___deref__(PyObject *self, PyObject *args) {
57015690
PyObject *resultobj = 0;
57025691
IptcData_iterator *arg1 = (IptcData_iterator *) 0 ;
@@ -9528,7 +9517,6 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__IptcData_iterator_methods[] = {
95289517
{ "__eq__", _wrap_IptcData_iterator___eq__, METH_VARARGS, "" },
95299518
{ "__ne__", _wrap_IptcData_iterator___ne__, METH_VARARGS, "" },
95309519
{ "__str__", _wrap_IptcData_iterator___str__, METH_VARARGS, "" },
9531-
{ "_invalidate", _wrap_IptcData_iterator__invalidate, METH_VARARGS, "" },
95329520
{ "__deref__", _wrap_IptcData_iterator___deref__, METH_VARARGS, "" },
95339521
{ "setValue", _wrap_IptcData_iterator_setValue, METH_VARARGS, "" },
95349522
{ "copy", _wrap_IptcData_iterator_copy, METH_VARARGS, "" },

src/swig-0_27_7/xmp_wrap.cxx

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4403,8 +4403,25 @@ class XmpData_iterator {
44034403
return "iterator<end>";
44044404
return "iterator<" + ptr->key() + ": " + ptr->print() + ">";
44054405
}
4406-
// Provide method to invalidate iterator
4406+
// Provide method to invalidate iterator unilaterally
44074407
void _invalidate() { invalidated = true; }
4408+
// Provide method to invalidate iterator if in deleted range
4409+
void _invalidate(Exiv2::XmpData::iterator b,
4410+
Exiv2::XmpData::iterator e) {
4411+
if (b == e) {
4412+
// begin() == end() after clear()
4413+
if (b == ptr || b == end)
4414+
invalidated = true;
4415+
return;
4416+
}
4417+
while (b != e) {
4418+
if (b == ptr) {
4419+
invalidated = true;
4420+
return;
4421+
}
4422+
b++;
4423+
}
4424+
}
44084425
// Provide size() C++ method for buffer size check
44094426
size_t size() {
44104427
if (invalidated || ptr == end)
@@ -5617,34 +5634,6 @@ SWIGINTERN PyObject *_wrap_XmpData_iterator___str__(PyObject *self, PyObject *ar
56175634
}
56185635

56195636

5620-
SWIGINTERN PyObject *_wrap_XmpData_iterator__invalidate(PyObject *self, PyObject *args) {
5621-
PyObject *resultobj = 0;
5622-
XmpData_iterator *arg1 = (XmpData_iterator *) 0 ;
5623-
void *argp1 = 0 ;
5624-
int res1 = 0 ;
5625-
5626-
if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, "XmpData_iterator__invalidate takes no arguments");
5627-
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_XmpData_iterator, 0 | 0 );
5628-
if (!SWIG_IsOK(res1)) {
5629-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "XmpData_iterator__invalidate" "', argument " "1"" of type '" "XmpData_iterator *""'");
5630-
}
5631-
arg1 = reinterpret_cast< XmpData_iterator * >(argp1);
5632-
{
5633-
try {
5634-
(arg1)->_invalidate();
5635-
}
5636-
catch(std::exception const& e) {
5637-
_set_python_exception();
5638-
SWIG_fail;
5639-
}
5640-
}
5641-
resultobj = SWIG_Py_Void();
5642-
return resultobj;
5643-
fail:
5644-
return NULL;
5645-
}
5646-
5647-
56485637
SWIGINTERN PyObject *_wrap_XmpData_iterator___deref__(PyObject *self, PyObject *args) {
56495638
PyObject *resultobj = 0;
56505639
XmpData_iterator *arg1 = (XmpData_iterator *) 0 ;
@@ -9542,7 +9531,6 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__XmpData_iterator_methods[] = {
95429531
{ "__eq__", _wrap_XmpData_iterator___eq__, METH_VARARGS, "" },
95439532
{ "__ne__", _wrap_XmpData_iterator___ne__, METH_VARARGS, "" },
95449533
{ "__str__", _wrap_XmpData_iterator___str__, METH_VARARGS, "" },
9545-
{ "_invalidate", _wrap_XmpData_iterator__invalidate, METH_VARARGS, "" },
95469534
{ "__deref__", _wrap_XmpData_iterator___deref__, METH_VARARGS, "" },
95479535
{ "setValue", _wrap_XmpData_iterator_setValue, METH_VARARGS, "" },
95489536
{ "copy", _wrap_XmpData_iterator_copy, METH_VARARGS, "Not implemented. Calling this method will raise an exception." },

src/swig-0_28_5/exif_wrap.cxx

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4408,8 +4408,25 @@ class ExifData_iterator {
44084408
return "iterator<end>";
44094409
return "iterator<" + ptr->key() + ": " + ptr->print() + ">";
44104410
}
4411-
// Provide method to invalidate iterator
4411+
// Provide method to invalidate iterator unilaterally
44124412
void _invalidate() { invalidated = true; }
4413+
// Provide method to invalidate iterator if in deleted range
4414+
void _invalidate(Exiv2::ExifData::iterator b,
4415+
Exiv2::ExifData::iterator e) {
4416+
if (b == e) {
4417+
// begin() == end() after clear()
4418+
if (b == ptr || b == end)
4419+
invalidated = true;
4420+
return;
4421+
}
4422+
while (b != e) {
4423+
if (b == ptr) {
4424+
invalidated = true;
4425+
return;
4426+
}
4427+
b++;
4428+
}
4429+
}
44134430
// Provide size() C++ method for buffer size check
44144431
size_t size() {
44154432
if (invalidated || ptr == end)
@@ -5832,34 +5849,6 @@ SWIGINTERN PyObject *_wrap_ExifData_iterator___str__(PyObject *self, PyObject *a
58325849
}
58335850

58345851

5835-
SWIGINTERN PyObject *_wrap_ExifData_iterator__invalidate(PyObject *self, PyObject *args) {
5836-
PyObject *resultobj = 0;
5837-
ExifData_iterator *arg1 = (ExifData_iterator *) 0 ;
5838-
void *argp1 = 0 ;
5839-
int res1 = 0 ;
5840-
5841-
if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, "ExifData_iterator__invalidate takes no arguments");
5842-
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ExifData_iterator, 0 | 0 );
5843-
if (!SWIG_IsOK(res1)) {
5844-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ExifData_iterator__invalidate" "', argument " "1"" of type '" "ExifData_iterator *""'");
5845-
}
5846-
arg1 = reinterpret_cast< ExifData_iterator * >(argp1);
5847-
{
5848-
try {
5849-
(arg1)->_invalidate();
5850-
}
5851-
catch(std::exception const& e) {
5852-
_set_python_exception();
5853-
SWIG_fail;
5854-
}
5855-
}
5856-
resultobj = SWIG_Py_Void();
5857-
return resultobj;
5858-
fail:
5859-
return NULL;
5860-
}
5861-
5862-
58635852
SWIGINTERN PyObject *_wrap_ExifData_iterator___deref__(PyObject *self, PyObject *args) {
58645853
PyObject *resultobj = 0;
58655854
ExifData_iterator *arg1 = (ExifData_iterator *) 0 ;
@@ -10577,7 +10566,6 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__ExifData_iterator_methods[] = {
1057710566
{ "__eq__", _wrap_ExifData_iterator___eq__, METH_VARARGS, "" },
1057810567
{ "__ne__", _wrap_ExifData_iterator___ne__, METH_VARARGS, "" },
1057910568
{ "__str__", _wrap_ExifData_iterator___str__, METH_VARARGS, "" },
10580-
{ "_invalidate", _wrap_ExifData_iterator__invalidate, METH_VARARGS, "" },
1058110569
{ "__deref__", _wrap_ExifData_iterator___deref__, METH_VARARGS, "" },
1058210570
{ "setValue", _wrap_ExifData_iterator_setValue, METH_VARARGS, "" },
1058310571
{ "setDataArea", _wrap_ExifData_iterator_setDataArea, METH_VARARGS, "\n"

0 commit comments

Comments
 (0)