2525
2626METADATUM_WRAPPERS(base_class, datum_type)
2727
28- // Turn off exception checking for methods that are guaranteed not to throw
29- %noexception Exiv2::base_class::begin;
30- %noexception Exiv2::base_class::end;
31- %noexception Exiv2::base_class::clear;
32- %noexception Exiv2::base_class::count;
33- %noexception Exiv2::base_class::empty;
34- // Add dict-like behaviour
35- %feature(" python:slot" , " tp_iter" , functype=" getiterfunc" )
36- Exiv2::base_class::begin;
37- %feature(" python:slot" , " mp_length" , functype=" lenfunc" )
38- Exiv2::base_class::count;
39- MP_SUBSCRIPT (Exiv2::base_class, Exiv2::datum_type&, (*self)[key])
40- %feature(" python:slot" , " mp_ass_subscript" , functype=" objobjargproc" )
41- Exiv2::base_class::__setitem__;
42- %feature(" python:slot" , " sq_contains" , functype=" objobjproc" )
43- Exiv2::base_class::__contains__;
44- %extend Exiv2::base_class {
45- %fragment (" get_type_id" {Exiv2::datum_type});
46- PyObject* __setitem__ (const std::string& key, Exiv2::Value* value) {
47- Exiv2::datum_type* datum = &(*$self)[key];
48- datum->setValue (value);
49- return SWIG_Py_Void ();
50- }
51- PyObject* __setitem__ (const std::string& key, const std::string& value) {
52- Exiv2::datum_type* datum = &(*$self)[key];
28+ /* Set a datum's value from a Python object. String or Exiv2::Value objects
29+ * are used directly. Other objects are used in the constructor of a Python
30+ * Exiv2::Value using the datum's current or default type.
31+ */
32+ %ignore Exiv2::datum_type::setValue(const Value*);
33+ %ignore Exiv2::datum_type::setValue (const std::string&);
34+ %fragment(" set_value_from_py" {Exiv2::datum_type}, " header" ,
35+ fragment=" get_type_object" ,
36+ fragment=" get_type_id" {Exiv2::datum_type}) {
37+ static PyObject* set_value_from_py (Exiv2::datum_type* datum,
38+ PyObject* py_value) {
39+ // Try std::string value
40+ if (PyUnicode_Check (py_value)) {
41+ std::string value = PyUnicode_AsUTF8 (py_value);
5342 Exiv2::TypeId old_type = get_type_id (datum);
5443 if (datum->setValue (value) != 0 )
5544 return PyErr_Format (PyExc_ValueError,
@@ -58,36 +47,14 @@ MP_SUBSCRIPT(Exiv2::base_class, Exiv2::datum_type&, (*self)[key])
5847 value.c_str ());
5948 return SWIG_Py_Void ();
6049 }
61- #if SWIG_VERSION >= 0x040400
62- PyObject* __setitem__ (PyObject* py_self, const std::string& key) {
63- #else
64- PyObject* __setitem__ (const std::string& key) {
65- #endif
66- Exiv2::base_class::iterator pos = $self->findKey (
67- Exiv2::key_type (key));
68- if (pos == $self->end ()) {
69- PyErr_SetString (PyExc_KeyError, key.c_str ());
70- return NULL ;
71- }
72- #if SWIG_VERSION >= 0x040400
73- invalidate_pointers (py_self, pos);
74- #endif
75- $self->erase (pos);
50+ // Try Exiv2::Value value
51+ Exiv2::Value* value = NULL ;
52+ if (SWIG_IsOK (SWIG_ConvertPtr (
53+ py_value, (void **)&value, $descriptor (Exiv2::Value*), 0 ))) {
54+ datum->setValue (value);
7655 return SWIG_Py_Void ();
7756 }
78- bool __contains__ (const std::string& key) {
79- return $self->findKey (Exiv2::key_type (key)) != $self->end ();
80- }
81- }
82-
83- // Set the datum's value from a Python object. The datum's current or default
84- // type is used to create an Exiv2::Value object (via Python) from the Python
85- // object.
86- %fragment (" set_value_from_py" {Exiv2::datum_type}, " header" ,
87- fragment=" get_type_object" ,
88- fragment=" get_type_id" {Exiv2::datum_type}) {
89- static PyObject* set_value_from_py (Exiv2::datum_type* datum,
90- PyObject* py_value) {
57+ // Try converting Python object to a value
9158 swig_type_info* ty_info = get_type_object.at (get_type_id (datum));
9259 SwigPyClientData *cl_data = (SwigPyClientData*)ty_info->clientdata ;
9360 // Call type object to invoke constructor
@@ -96,7 +63,6 @@ static PyObject* set_value_from_py(Exiv2::datum_type* datum,
9663 if (!swig_obj)
9764 return NULL ;
9865 // Convert constructed object to Exiv2::Value
99- Exiv2::Value* value = 0 ;
10066 if (!SWIG_IsOK (SWIG_ConvertPtr (swig_obj, (void **)&value, ty_info, 0 ))) {
10167 PyErr_SetString (
10268 PyExc_RuntimeError, " set_value_from_py: invalid conversion" );
@@ -109,17 +75,41 @@ static PyObject* set_value_from_py(Exiv2::datum_type* datum,
10975 return SWIG_Py_Void ();
11076};
11177}
78+
79+ // Turn off exception checking for methods that are guaranteed not to throw
80+ %noexception Exiv2::base_class::begin;
81+ %noexception Exiv2::base_class::end;
82+ %noexception Exiv2::base_class::clear;
83+ %noexception Exiv2::base_class::count;
84+ %noexception Exiv2::base_class::empty;
85+ // Add dict-like behaviour
86+ %feature(" python:slot" , " tp_iter" , functype=" getiterfunc" )
87+ Exiv2::base_class::begin;
88+ %feature(" python:slot" , " mp_length" , functype=" lenfunc" )
89+ Exiv2::base_class::count;
90+ MP_SUBSCRIPT (Exiv2::base_class, Exiv2::datum_type&, (*self)[key])
91+ %fragment(" set_value_from_py" {Exiv2::datum_type});
92+ MP_ASS_SUBSCRIPT (Exiv2::base_class, PyObject*,
93+ // setfunc
94+ return set_value_from_py(&(*self)[key], value),
95+ // delfunc
96+ auto pos = self->findKey(Exiv2::key_type(key));
97+ if (pos == self->end ())
98+ return PyErr_Format(PyExc_KeyError, " '%s'" , key);
99+ self->erase (pos))
100+ %feature(" python:slot" , " sq_contains" , functype=" objobjproc" )
101+ Exiv2::base_class::__contains__;
102+ %extend Exiv2::base_class {
103+ %fragment (" get_type_id" {Exiv2::datum_type});
104+ bool __contains__ (const std::string& key) {
105+ return $self->findKey (Exiv2::key_type (key)) != $self->end ();
106+ }
107+ }
108+
112109%extend Exiv2::datum_type {
113110 %fragment (" set_value_from_py" {Exiv2::datum_type});
114111 PyObject* setValue (PyObject* py_value) {
115112 return set_value_from_py ($self, py_value);
116113 }
117114}
118- %extend Exiv2::base_class {
119- %fragment (" set_value_from_py" {Exiv2::datum_type});
120- PyObject* __setitem__ (const std::string& key, PyObject* py_value) {
121- Exiv2::datum_type* datum = &(*$self)[key];
122- return set_value_from_py (datum, py_value);
123- }
124- }
125115%enddef // DATA_CONTAINER
0 commit comments