[gexiv2] Issue #60: alt gexiv2_metadata_try_(g|s)et_tag_multiple() with GError.



commit cdac1c7580fc6314ae47a7ddec38f11ea5afc7a8
Author: Jehan <jehan girinstud io>
Date:   Sun Nov 8 18:25:34 2020 +0100

    Issue #60: alt gexiv2_metadata_try_(g|s)et_tag_multiple() with GError.
    
    Raising GLib warning should not be done on tag errors because calling
    applications may prefer handling these errors differently (and adding a
    log handler for every dependency of a software is not flexible).
    It is much better design to return errors as optional GError.

 gexiv2/gexiv2-metadata-iptc.cpp  | 10 ++++---
 gexiv2/gexiv2-metadata-private.h |  8 ++---
 gexiv2/gexiv2-metadata-xmp.cpp   | 10 ++++---
 gexiv2/gexiv2-metadata.cpp       | 63 +++++++++++++++++++++++++++++++---------
 gexiv2/gexiv2-metadata.h         | 34 ++++++++++++++++++++++
 5 files changed, 99 insertions(+), 26 deletions(-)
---
diff --git a/gexiv2/gexiv2-metadata-iptc.cpp b/gexiv2/gexiv2-metadata-iptc.cpp
index 2e36fc8..9814cb7 100644
--- a/gexiv2/gexiv2-metadata-iptc.cpp
+++ b/gexiv2/gexiv2-metadata-iptc.cpp
@@ -164,10 +164,11 @@ gboolean gexiv2_metadata_set_iptc_tag_string (GExiv2Metadata *self, const gchar*
     return FALSE;
 }
 
-gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag) {
+gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::IptcData &iptc_data = self->priv->image->iptcData();
     
@@ -194,7 +195,7 @@ gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar
         
         return values;
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
     }
     
     g_slist_free_full (list, g_free);
@@ -203,11 +204,12 @@ gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar
 }
 
 gboolean gexiv2_metadata_set_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag,
-    const gchar** values) {
+    const gchar** values, GError **error) {
     g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(tag != NULL, FALSE);
     g_return_val_if_fail(values != NULL, FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::IptcData& iptc_data = self->priv->image->iptcData();
     
@@ -235,7 +237,7 @@ gboolean gexiv2_metadata_set_iptc_tag_multiple (GExiv2Metadata *self, const gcha
         
         return TRUE;
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
     }
     
     return FALSE;
diff --git a/gexiv2/gexiv2-metadata-private.h b/gexiv2/gexiv2-metadata-private.h
index 2968d19..fb55e5a 100644
--- a/gexiv2/gexiv2-metadata-private.h
+++ b/gexiv2/gexiv2-metadata-private.h
@@ -64,8 +64,8 @@ G_GNUC_INTERNAL gboolean              gexiv2_metadata_set_xmp_tag_string      
(GExiv2Metadata *se
 G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_xmp_tag_interpreted_string (GExiv2Metadata *self, 
const gchar* tag);
 G_GNUC_INTERNAL glong                  gexiv2_metadata_get_xmp_tag_long        (GExiv2Metadata *self, const 
gchar* tag);
 G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_xmp_tag_long        (GExiv2Metadata *self, const 
gchar* tag, glong value);
-G_GNUC_INTERNAL gchar**                        gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, 
const gchar* tag);
-G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const 
gchar* tag, const gchar** values);
+G_GNUC_INTERNAL gchar**                        gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, 
const gchar* tag, GError **error);
+G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const 
gchar* tag, const gchar** values, GError **error);
 
 G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_xmp_tag_label               (const gchar* tag);
 G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_xmp_tag_description (const gchar* tag);
@@ -80,8 +80,8 @@ G_GNUC_INTERNAL gboolean              gexiv2_metadata_has_iptc_tag            
(GExiv2Metadata *self, c
 G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_iptc_tag_string     (GExiv2Metadata *self, const 
gchar* tag);
 G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_iptc_tag_string     (GExiv2Metadata *self, const 
gchar* tag, const gchar* value);
 G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_iptc_tag_interpreted_string (GExiv2Metadata 
*self, const gchar* tag);
-G_GNUC_INTERNAL gchar**                        gexiv2_metadata_get_iptc_tag_multiple   (GExiv2Metadata 
*self, const gchar* tag);
-G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_iptc_tag_multiple   (GExiv2Metadata *self, const 
gchar* tag, const gchar** values);
+G_GNUC_INTERNAL gchar**                        gexiv2_metadata_get_iptc_tag_multiple   (GExiv2Metadata 
*self, const gchar* tag, GError **error);
+G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_iptc_tag_multiple   (GExiv2Metadata *self, const 
gchar* tag, const gchar** values, GError **error);
 
 G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_iptc_tag_label      (const gchar* tag);
 G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_iptc_tag_description        (const gchar* tag);
diff --git a/gexiv2/gexiv2-metadata-xmp.cpp b/gexiv2/gexiv2-metadata-xmp.cpp
index 784ad86..4647d36 100644
--- a/gexiv2/gexiv2-metadata-xmp.cpp
+++ b/gexiv2/gexiv2-metadata-xmp.cpp
@@ -269,10 +269,11 @@ gboolean gexiv2_metadata_set_xmp_tag_long (GExiv2Metadata *self, const gchar* ta
     return FALSE;
 }
 
-gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag) {
+gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
     
@@ -294,7 +295,7 @@ gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar*
             return array;
         }
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
     }
     
     gchar **array = g_new (gchar*, 1);
@@ -304,11 +305,12 @@ gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar*
 }
 
 gboolean gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag, 
-    const gchar** values) {
+    const gchar** values, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(tag != NULL, FALSE);
     g_return_val_if_fail(values != NULL, FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
     
@@ -330,7 +332,7 @@ gboolean gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const gchar
         
         return TRUE;
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
     }
     
     return FALSE;
diff --git a/gexiv2/gexiv2-metadata.cpp b/gexiv2/gexiv2-metadata.cpp
index 48b11d4..c85966f 100644
--- a/gexiv2/gexiv2-metadata.cpp
+++ b/gexiv2/gexiv2-metadata.cpp
@@ -1015,43 +1015,78 @@ gchar* gexiv2_metadata_get_tag_interpreted_string (GExiv2Metadata *self, const g
     return NULL;
 }
 
-gchar** gexiv2_metadata_get_tag_multiple(GExiv2Metadata* self, const gchar* tag) {
-    g_return_val_if_fail(GEXIV2_IS_METADATA(self), NULL);
-    g_return_val_if_fail(tag != NULL, NULL);
-    g_return_val_if_fail(self->priv != NULL, FALSE);
-    g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+gchar** gexiv2_metadata_try_get_tag_multiple(GExiv2Metadata *self, const gchar* tag, GError **error) {
+    g_return_val_if_fail(GEXIV2_IS_METADATA(self), nullptr);
+    g_return_val_if_fail(tag != nullptr, nullptr);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
 
     if (gexiv2_metadata_is_xmp_tag(tag))
-        return gexiv2_metadata_get_xmp_tag_multiple(self, tag);
+        return gexiv2_metadata_get_xmp_tag_multiple(self, tag, error);
 
     if (gexiv2_metadata_is_exif_tag(tag))
         return gexiv2_metadata_get_exif_tag_multiple(self, tag);
 
     if (gexiv2_metadata_is_iptc_tag(tag))
-        return gexiv2_metadata_get_iptc_tag_multiple(self, tag);
+        return gexiv2_metadata_get_iptc_tag_multiple(self, tag, error);
 
     return NULL;
 }
 
-gboolean gexiv2_metadata_set_tag_multiple(GExiv2Metadata* self, const gchar* tag, const gchar** values) {
+gboolean gexiv2_metadata_try_set_tag_multiple(GExiv2Metadata *self, const gchar* tag, const gchar** values, 
GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
-    g_return_val_if_fail(tag != NULL, FALSE);
-    g_return_val_if_fail(values != NULL, FALSE);
-    g_return_val_if_fail(self->priv != NULL, FALSE);
-    g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(tag != nullptr, FALSE);
+    g_return_val_if_fail(values != nullptr, FALSE);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, FALSE);
 
     if (gexiv2_metadata_is_xmp_tag(tag))
-        return gexiv2_metadata_set_xmp_tag_multiple(self, tag, values);
+        return gexiv2_metadata_set_xmp_tag_multiple(self, tag, values, error);
 
     if (gexiv2_metadata_is_exif_tag(tag))
         return gexiv2_metadata_set_exif_tag_multiple(self, tag, values);
 
     if (gexiv2_metadata_is_iptc_tag(tag))
-        return gexiv2_metadata_set_iptc_tag_multiple(self, tag, values);
+        return gexiv2_metadata_set_iptc_tag_multiple(self, tag, values, error);
 
     return FALSE;
 }
 
+gchar** gexiv2_metadata_get_tag_multiple(GExiv2Metadata *self, const gchar* tag) {
+    gchar  **tags  = nullptr;
+    GError  *error = nullptr;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA(self), nullptr);
+    g_return_val_if_fail(tag != nullptr, nullptr);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
+
+    tags = gexiv2_metadata_try_get_tag_multiple(self, tag, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return tags;
+}
+
+gboolean gexiv2_metadata_set_tag_multiple(GExiv2Metadata *self, const gchar* tag, const gchar** values) {
+    GError   *error   = nullptr;
+    gboolean  success = FALSE;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
+    g_return_val_if_fail(tag != nullptr, FALSE);
+    g_return_val_if_fail(values != nullptr, FALSE);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, FALSE);
+
+    success = gexiv2_metadata_try_set_tag_multiple(self, tag, values, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
 glong gexiv2_metadata_get_tag_long(GExiv2Metadata *self, const gchar* tag) {
     g_return_val_if_fail(GEXIV2_IS_METADATA(self), 0);
     g_return_val_if_fail(tag != NULL, 0);
diff --git a/gexiv2/gexiv2-metadata.h b/gexiv2/gexiv2-metadata.h
index 8eb18ed..a7bf588 100644
--- a/gexiv2/gexiv2-metadata.h
+++ b/gexiv2/gexiv2-metadata.h
@@ -562,6 +562,32 @@ glong                      gexiv2_metadata_get_tag_long            (GExiv2Metadata 
*self, const gchar* tag);
 gboolean               gexiv2_metadata_set_tag_long            (GExiv2Metadata *self, const gchar* tag, 
glong value);
 
 
+/**
+ * gexiv2_metadata_try_get_tag_multiple:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: (transfer full) (allow-none) (array zero-terminated=1): The multiple string values of
+ * the tag
+ */
+gchar**                        gexiv2_metadata_try_get_tag_multiple    (GExiv2Metadata *self, const gchar* 
tag, GError **error);
+
+/**
+ * gexiv2_metadata_try_set_tag_multiple:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @values: (array zero-terminated=1): An array of values to set or replace the existing value(s)
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: Boolean success value
+ */
+gboolean               gexiv2_metadata_try_set_tag_multiple    (GExiv2Metadata *self, const gchar* tag, 
const gchar** values, GError **error);
+
 /**
  * gexiv2_metadata_get_tag_multiple:
  * @self: An instance of #GExiv2Metadata
@@ -569,6 +595,10 @@ gboolean           gexiv2_metadata_set_tag_long            (GExiv2Metadata *self, const 
gchar* tag,
  *
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
+ * In case of error, a GLib warning will be logged. Use instead
+ * gexiv2_metadata_try_get_tag_multiple() if you want to avoid this and
+ * control if and how the error is outputted.
+ *
  * Returns: (transfer full) (allow-none) (array zero-terminated=1): The multiple string values of
  * the tag
  */
@@ -582,6 +612,10 @@ gchar**                    gexiv2_metadata_get_tag_multiple        (GExiv2Metadata 
*self, const gchar* t
  *
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
+ * In case of error, a GLib warning will be logged. Use instead
+ * gexiv2_metadata_try_set_tag_multiple() if you want to avoid this and
+ * control if and how the error is outputted.
+ *
  * Returns: Boolean success value
  */
 gboolean               gexiv2_metadata_set_tag_multiple        (GExiv2Metadata *self, const gchar* tag, 
const gchar** values);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]