[folks] Add equal() and hash() functions to AbstractFieldDetails.



commit 8b08293c7037fffa5a46c540b46900e83d549cfb
Author: Travis Reitter <travis reitter collabora co uk>
Date:   Mon Jul 11 17:20:54 2011 -0700

    Add equal() and hash() functions to AbstractFieldDetails.
    
    Helps: bgo#653679 - Change PostalAddressDetails.postal_addresses to
    support vCard-like arbitrary parameters

 NEWS                              |    2 +
 folks/abstract-field-details.vala |   88 +++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 0 deletions(-)
---
diff --git a/NEWS b/NEWS
index c18e01d..3f7f08e 100644
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,8 @@ API changes:
 * Add RoleDetails:role property
 * Rebase FieldDetails upon AbstractFieldDetails (requiring the use of the
   equivalent AbstractFieldDetails functions in place of the FieldDetails ones).
+* Add AbstractFieldDetails.equal() and hash() for better matching on structures
+  which will store derived objects.
 
 Overview of changes from libfolks 0.5.1 to libfolks 0.5.2
 =========================================================
diff --git a/folks/abstract-field-details.vala b/folks/abstract-field-details.vala
index 123da61..fc9943f 100644
--- a/folks/abstract-field-details.vala
+++ b/folks/abstract-field-details.vala
@@ -168,4 +168,92 @@ public abstract class Folks.AbstractFieldDetails<T> : Object
     {
       this.parameters.remove_all (parameter_name);
     }
+
+  /**
+   * An equality function for { link AbstractFieldDetails}.
+   *
+   * This defaults to string comparison of the
+   * { link AbstractFieldDetails.value}s if the generic type is string;
+   * otherwise, direct pointer comparison of the
+   * { link AbstractFieldDetails.value}s.
+   *
+   * @param that another { link AbstractFieldDetails}
+   *
+   * @return whether the elements are equal
+   *
+   * @since UNRELEASED
+   */
+  public virtual bool equal (AbstractFieldDetails<T> that)
+    {
+      EqualFunc equal_func = direct_equal;
+
+      if (typeof (T) == typeof (string))
+        equal_func = str_equal;
+
+      if ((this.get_type () != that.get_type ()) ||
+          !equal_func (this.value, that.value))
+        {
+          return false;
+        }
+
+      /* Check that the parameter names and their values match exactly in both
+       * AbstractFieldDetails objects. */
+      if (this.parameters.size != that.parameters.size)
+        return false;
+
+      foreach (var param in this.parameters.get_keys ())
+        {
+          /* Since these parameters are meant to model vCard parameters, we
+           * should compare on a case-insensitive basis. However, this leads to
+           * ambiguity in the case:
+           *
+           *   this.parameters = {"foo": {"bar"}}
+           *   that.parameters = {"foo": {"bar"}, "FOO": {"qux"}}
+           *
+           * So parameter names should normalised elsewhere (either in the
+           * insertion functions (with a big warning for the clients) or in the
+           * clients themselves).
+           *
+           * Note that parameter values can't be normalised in general, since
+           * they can be user-set labels.
+           */
+          if (!that.parameters.contains (param))
+            return false;
+
+          var this_param_values = this.parameters.get_values ();
+          var that_param_values = that.parameters.get_values ();
+
+          if (this_param_values.size != that_param_values.size)
+            return false;
+
+          foreach (var param_val in this.parameters.get_values ())
+            {
+              if (!that_param_values.contains (param_val))
+                return false;
+            }
+        }
+
+      return true;
+    }
+
+  /**
+   * A hash function for the { link AbstractFieldDetails}.
+   *
+   * This defaults to a string hash of the
+   * { link AbstractFieldDetails.value} if the generic type is string;
+   * otherwise, direct hash of the { link AbstractFieldDetails.value}.
+   *
+   * @return the hash value
+   *
+   * @since UNRELEASED
+   */
+  public virtual uint hash ()
+    {
+      HashFunc hash_func = direct_hash;
+
+      if (typeof (T) == typeof (string))
+        hash_func = str_hash;
+
+      return hash_func (this.value);
+    }
 }



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