[folks/perf2: 1/2] wip




commit 6cec0dee5c98fb80ee776f75f153dc30efc05b3d
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Sat Oct 17 19:30:59 2020 +0200

    wip

 backends/eds/lib/edsf-persona-store.vala |   2 +-
 folks/abstract-field-details.vala        |   6 +-
 folks/individual.vala                    | 134 +++++++++++++++++++------------
 folks/name-details.vala                  |   6 +-
 folks/persona.vala                       |   6 +-
 folks/phone-details.vala                 |   8 +-
 folks/postal-address-details.vala        |   2 +-
 folks/utils.vala                         |  20 +++++
 8 files changed, 118 insertions(+), 66 deletions(-)
---
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index 4cac5620..f558a5f2 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -861,7 +861,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
                * here because it fails to null-terminate the array. Sigh. */
               this._always_writeable_properties = new string[prop_set.size];
               uint i = 0;
-              foreach (var final_prop in prop_set)
+              foreach (unowned string final_prop in prop_set)
                 {
                   this._always_writeable_properties[i++] = final_prop;
                 }
diff --git a/folks/abstract-field-details.vala b/folks/abstract-field-details.vala
index ed28cd22..1bfa7802 100644
--- a/folks/abstract-field-details.vala
+++ b/folks/abstract-field-details.vala
@@ -292,8 +292,8 @@ public abstract class Folks.AbstractFieldDetails<T> : Object
       GLib.return_val_if_fail (left != null, false);
       GLib.return_val_if_fail (right != null, false);
 
-      AbstractFieldDetails left_details = (AbstractFieldDetails) left;
-      AbstractFieldDetails right_details = (AbstractFieldDetails) right;
+      unowned var left_details = (AbstractFieldDetails) left;
+      unowned var right_details = (AbstractFieldDetails) right;
       return left_details.equal (right_details);
     }
 
@@ -446,7 +446,7 @@ public abstract class Folks.AbstractFieldDetails<T> : Object
     {
       GLib.return_val_if_fail (value != null, 0);
 
-      AbstractFieldDetails details = (AbstractFieldDetails) value;
+      unowned var details = (AbstractFieldDetails) value;
       return details.hash ();
     }
 }
diff --git a/folks/individual.vala b/folks/individual.vala
index bc63dc11..d5daa146 100644
--- a/folks/individual.vala
+++ b/folks/individual.vala
@@ -178,8 +178,9 @@ public class Folks.Individual : Object,
 
       /* Try to write it to only the writeable Personas which have the
        * "avatar" property as writeable. */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           unowned var _a = p as AvatarDetails;
           if (_a == null)
             {
@@ -365,8 +366,9 @@ public class Folks.Individual : Object,
 
       /* Try to write it to only the writeable Personas which have "alias"
        * as a writeable property. */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           unowned var _a = p as AliasDetails;
           if (_a == null)
             {
@@ -474,8 +476,9 @@ public class Folks.Individual : Object,
 
       /* Try to write it to only the writeable Personas which have "nickname"
        * as a writeable property. */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           unowned var _n = p as NameDetails;
           if (_n == null)
             {
@@ -725,8 +728,9 @@ public class Folks.Individual : Object,
        * NOTE: We don't check whether the persona's store is writeable, as we
        * want is-favourite status to propagate to all stores, if possible. This
        * is one property which is harmless to propagate. */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           unowned var _a = p as FavouriteDetails;
           if (_a == null)
             {
@@ -803,8 +807,9 @@ public class Folks.Individual : Object,
 
       /* Try to write it to only the Personas which have "groups" as a
        * writeable property. */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           unowned var _g = p as GroupDetails;
           if (_g == null)
             {
@@ -890,8 +895,9 @@ public class Folks.Individual : Object,
         {
           uint counter = 0;
           /* Iterate over all personas and sum up their IM interaction counts*/
-          foreach (var persona in this._persona_set)
+          for (int i = 0; i < this._persona_set.size; i++)
             {
+              unowned var persona = this._persona_set[i];
               unowned var my_interaction_details = persona as InteractionDetails;
               if (my_interaction_details != null)
                 {
@@ -914,8 +920,9 @@ public class Folks.Individual : Object,
           if (this._last_im_interaction_datetime == null)
             {
               /* Iterate over all personas and get the latest IM interaction datetime */
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
+                  unowned var persona = this._persona_set[i];
                   unowned var my_interaction_details = persona as InteractionDetails;
                   if (my_interaction_details != null &&
                       my_interaction_details.last_im_interaction_datetime != null)
@@ -942,8 +949,9 @@ public class Folks.Individual : Object,
         {
           uint counter = 0;
           /* Iterate over all personas and sum up their call interaction counts*/
-          foreach (var persona in this._persona_set)
+          for (int i = 0; i < this._persona_set.size; i++)
             {
+              unowned var persona = this._persona_set[i];
               unowned var my_interaction_details = persona as InteractionDetails;
               if (my_interaction_details != null)
                 {
@@ -966,9 +974,10 @@ public class Folks.Individual : Object,
           if (this._last_call_interaction_datetime == null)
             {
               /* Iterate over all personas and get the latest IM interaction datetime */
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
-                  var my_interaction_details = persona as InteractionDetails;
+                  unowned var persona = this._persona_set[i];
+                  unowned var my_interaction_details = persona as InteractionDetails;
                   if (my_interaction_details != null &&
                       my_interaction_details.last_call_interaction_datetime != null)
                     {
@@ -996,8 +1005,9 @@ public class Folks.Individual : Object,
 
       /* Try to get it from the writeable Personas which have "extended-info"
        * as a writeable property. */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           if ("extended-info" in p.writeable_properties)
             {
               unowned var e = p as ExtendedInfo;
@@ -1027,8 +1037,9 @@ public class Folks.Individual : Object,
 
       /* Try to write it to only the writeable Personas which have "extended-info"
        * as a writeable property. */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           if ("extended-info" in p.writeable_properties)
             {
               unowned var e = p as ExtendedInfo;
@@ -1077,8 +1088,9 @@ public class Folks.Individual : Object,
       PropertyError? persona_error = null;
 
       /* Try to remove it from all writeable Personas. */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           if ("extended-info" in p.writeable_properties)
             {
               unowned var e = p as ExtendedInfo;
@@ -1239,8 +1251,9 @@ public class Folks.Individual : Object,
    */
   public async void change_group (string group, bool is_member)
     {
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           if (p is GroupDetails)
             ((GroupDetails) p).change_group.begin (group, is_member);
         }
@@ -1459,8 +1472,9 @@ public class Folks.Individual : Object,
 
       /* Build a set of the remaining personas (those which weren't in the
        * removed store. */
-      foreach (var persona in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var persona = this._persona_set[i];
           if (persona.store != store)
             {
               remaining_personas.add (persona);
@@ -1481,8 +1495,9 @@ public class Folks.Individual : Object,
 
       /* Build a set of the remaining personas (those which aren't in the
        * set of removed personas). */
-      foreach (var persona in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var persona = this._persona_set[i];
           if (!removed.contains (persona))
             {
               remaining_personas.add (persona);
@@ -1619,8 +1634,9 @@ public class Folks.Individual : Object,
 
       unowned Persona? candidate_p = null;
 
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           /* We only care about personas implementing the given interface. */
           if (p.get_type ().is_a (interface_type))
             {
@@ -1771,8 +1787,9 @@ public class Folks.Individual : Object,
        * "groups-changed" on the store (with the set of personas), to allow the
        * back-end to optimize it (like Telepathy will for MembersChanged for the
        * groups channel list) */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           if (p is GroupDetails)
             {
               unowned var persona = (GroupDetails) p;
@@ -1989,8 +2006,9 @@ public class Folks.Individual : Object,
 
       /* Find the primary persona first. The primary persona's values will be
        * preferred in every case where they're set. */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           if (p.store.is_primary_store)
             {
               primary_persona = p;
@@ -2001,8 +2019,9 @@ public class Folks.Individual : Object,
       /* See if any persona has an alias set. */
       new_display_name = this._look_up_alias_for_display_name (primary_persona);
 
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           if (new_display_name != "")
             {
               break;
@@ -2017,8 +2036,9 @@ public class Folks.Individual : Object,
           new_display_name =
               this._look_up_name_details_for_display_name (primary_persona);
 
-          foreach (var p in this._persona_set)
+          for (int i = 0; i < this._persona_set.size; i++)
             {
+              unowned var p = this._persona_set[i];
               if (new_display_name != "")
                 {
                   break;
@@ -2035,8 +2055,9 @@ public class Folks.Individual : Object,
           new_display_name =
               this._look_up_email_address_for_display_name (primary_persona);
 
-          foreach (var p in this._persona_set)
+          for (int i = 0; i < this._persona_set.size; i++)
             {
+              unowned var p = this._persona_set[i];
               if (new_display_name != "")
                 {
                   break;
@@ -2053,8 +2074,9 @@ public class Folks.Individual : Object,
           new_display_name =
               this._look_up_phone_number_for_display_name (primary_persona);
 
-          foreach (var p in this._persona_set)
+          for (int i = 0; i < this._persona_set.size; i++)
             {
+              unowned var p = this._persona_set[i];
               if (new_display_name != "")
                 {
                   break;
@@ -2071,13 +2093,14 @@ public class Folks.Individual : Object,
           new_display_name =
               this._look_up_display_id_for_display_name (primary_persona);
 
-          foreach (var p in this._persona_set)
+          for (int i = 0; i < this._persona_set.size; i++)
             {
               if (new_display_name != "")
                 {
                   break;
                 }
 
+              unowned var p = this._persona_set[i];
               new_display_name =
                   this._look_up_display_id_for_display_name (p);
             }
@@ -2089,8 +2112,9 @@ public class Folks.Individual : Object,
           new_display_name =
               this._look_up_postal_address_for_display_name (primary_persona);
 
-          foreach (var p in this._persona_set)
+          for (int i = 0; i < this._persona_set.size; i++)
             {
+              unowned var p = this._persona_set[i];
               if (new_display_name != "")
                 {
                   break;
@@ -2112,7 +2136,7 @@ public class Folks.Individual : Object,
 
       if (new_display_name != this._display_name)
         {
-          this._display_name = new_display_name;
+          this._display_name = (owned) new_display_name;
           debug ("Setting display name ā€˜%sā€™", new_display_name);
           this.notify_property ("display-name");
         }
@@ -2125,7 +2149,7 @@ public class Folks.Individual : Object,
           unowned var alias = ((AliasDetails) p).alias;
           return_val_if_fail (alias != null, false);
 
-          return (alias.strip () != ""); /* empty aliases are unset */
+          return !Utils.is_string_empty (alias); /* empty aliases are unset */
         }, (a, b) =>
         {
           unowned var a_alias = ((AliasDetails) a).alias;
@@ -2134,8 +2158,8 @@ public class Folks.Individual : Object,
           return_val_if_fail (a_alias != null, 0);
           return_val_if_fail (b_alias != null, 0);
 
-          var a_is_empty = (a_alias.strip () == "") ? 1 : 0;
-          var b_is_empty = (b_alias.strip () == "") ? 1 : 0;
+          var a_is_empty = Utils.is_string_empty (a_alias) ? 1 : 0;
+          var b_is_empty = Utils.is_string_empty (b_alias) ? 1 : 0;
 
           /* We prefer to not have an alias which is the same as the Persona's
            * display-id, since having such an alias implies that it's the
@@ -2203,8 +2227,9 @@ public class Folks.Individual : Object,
     {
       var trust_level = TrustLevel.PERSONAS;
 
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           if (p.is_user == false &&
               p.store.trust_level == PersonaStoreTrust.NONE)
             trust_level = TrustLevel.NONE;
@@ -2231,10 +2256,10 @@ public class Folks.Individual : Object,
                   null, null, AbstractFieldDetails<string>.hash_static,
                   AbstractFieldDetails<string>.equal_static);
 
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
                   /* We only care about personas implementing the given interface. */
-                  unowned var im_details = persona as ImDetails;
+                  unowned var im_details = this._persona_set[i] as ImDetails;
                   if (im_details != null)
                     {
                       var iter = im_details.im_addresses.map_iterator ();
@@ -2275,8 +2300,9 @@ public class Folks.Individual : Object,
                       AbstractFieldDetails<string>.hash_static,
                       AbstractFieldDetails<string>.equal_static);
 
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
+                  unowned var persona = this._persona_set[i];
                   /* We only care about personas implementing the given interface. */
                   unowned var web_service_details = persona as WebServiceDetails;
                   if (web_service_details != null)
@@ -2368,7 +2394,7 @@ public class Folks.Individual : Object,
           unowned var name = ((NameDetails) p).full_name;
           return_val_if_fail (name != null, false);
 
-          return (name.strip () != ""); /* empty names are unset */
+          return !Utils.is_string_empty (name); /* empty names are unset */
         }, (a, b) =>
         {
           /* Can't compare two set names. */
@@ -2384,7 +2410,7 @@ public class Folks.Individual : Object,
 
           if (new_full_name != this._full_name)
             {
-              this._full_name = new_full_name;
+              this._full_name = (owned) new_full_name;
               this.notify_property ("full-name");
 
               this._update_display_name ();
@@ -2399,7 +2425,7 @@ public class Folks.Individual : Object,
           unowned var nickname = ((NameDetails) p).nickname;
           return_val_if_fail (nickname != null, false);
 
-          return (nickname.strip () != ""); /* empty names are unset */
+          return !Utils.is_string_empty (nickname); /* empty names are unset */
         }, (a, b) =>
         {
           /* Can't compare two set names. */
@@ -2415,7 +2441,7 @@ public class Folks.Individual : Object,
 
           if (new_nickname != this._nickname)
             {
-              this._nickname = new_nickname;
+              this._nickname = (owned) new_nickname;
               this.notify_property ("nickname");
 
               this._update_display_name ();
@@ -2508,12 +2534,12 @@ public class Folks.Individual : Object,
                   unowned UrlFieldDetails> (
                     null, null,  AbstractFieldDetails<string>.equal_static);
 
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
                   /* We only care about personas implementing the given
                    * interface. If the same URL exists multiple times we merge
                    * the parameters. */
-                  unowned var url_details = persona as UrlDetails;
+                  unowned var url_details = this._persona_set[i] as UrlDetails;
                   if (url_details != null)
                     {
                       foreach (var url_fd in ((!) url_details).urls)
@@ -2565,12 +2591,12 @@ public class Folks.Individual : Object,
               var phone_numbers_set = new HashMap<string, PhoneFieldDetails> (
                   null, null, AbstractFieldDetails<string>.equal_static);
 
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
                   /* We only care about personas implementing the given
                    * interface. If the same phone number exists multiple times
                    * we merge the parameters. */
-                  unowned var phone_details = persona as PhoneDetails;
+                  unowned var phone_details = this._persona_set[i] as PhoneDetails;
                   if (phone_details != null)
                     {
                       foreach (var phone_fd in ((!) phone_details).phone_numbers)
@@ -2622,8 +2648,10 @@ public class Folks.Individual : Object,
               var emails_set = new HashMap<string, EmailFieldDetails> (
                   null, null, AbstractFieldDetails<string>.equal_static);
 
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
+                  unowned var persona = this._persona_set[i];
+
                   /* We only care about personas implementing the given
                    * interface. If the same e-mail address exists multiple times
                    * we merge the parameters. */
@@ -2678,9 +2706,9 @@ public class Folks.Individual : Object,
                   AbstractFieldDetails<Role>.hash_static,
                   AbstractFieldDetails<Role>.equal_static);
 
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
-                  var role_details = persona as RoleDetails;
+                  unowned var role_details = this._persona_set[i] as RoleDetails;
                   if (role_details != null)
                     {
                       foreach (var role_fd in ((!) role_details).roles)
@@ -2714,8 +2742,9 @@ public class Folks.Individual : Object,
             {
               var new_local_ids = new SmallSet<string> ();
 
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
+                  unowned var persona = this._persona_set[i];
                   unowned var local_id_details = persona as LocalIdDetails;
                   if (local_id_details != null)
                     {
@@ -2784,8 +2813,9 @@ public class Folks.Individual : Object,
                       AbstractFieldDetails<PostalAddress>.hash_static,
                       AbstractFieldDetails<PostalAddress>.equal_static);
 
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
+                  unowned var persona = this._persona_set[i];
                   unowned var postal_address_details = persona as PostalAddressDetails;
                   if (postal_address_details != null)
                     {
@@ -2879,8 +2909,9 @@ public class Folks.Individual : Object,
                   AbstractFieldDetails<string>.hash_static,
                   AbstractFieldDetails<string>.equal_static);
 
-              foreach (var persona in this._persona_set)
+              for (int i = 0; i < this._persona_set.size; i++)
                 {
+                  unowned var persona = this._persona_set[i];
                   unowned var note_details = persona as NoteDetails;
                   if (note_details != null)
                     {
@@ -2947,8 +2978,9 @@ public class Folks.Individual : Object,
         }
 
       /* Determine which Personas have been removed */
-      foreach (var p in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var p = this._persona_set[i];
           if (personas == null || !((!) personas).contains (p))
             {
               /* Keep track of how many Personas are users */
@@ -3022,8 +3054,9 @@ public class Folks.Individual : Object,
         {
           unowned Persona? chosen_persona = null;
 
-          foreach (var persona in this._persona_set)
+          for (int i = 0; i < this._persona_set.size; i++)
             {
+              unowned var persona = this._persona_set[i];
               if (chosen_persona == null)
                 {
                   chosen_persona = persona;
@@ -3096,8 +3129,9 @@ public class Folks.Individual : Object,
     {
       unowned var al = p as AntiLinkable;
 
-      foreach (var persona in this._persona_set)
+      for (int i = 0; i < this._persona_set.size; i++)
         {
+          unowned var persona = this._persona_set[i];
           unowned var pl = persona as AntiLinkable;
 
           if ((al != null && ((!) al).has_anti_link_with_persona (persona)) ||
diff --git a/folks/name-details.vala b/folks/name-details.vala
index d5fb1415..ee72e7d2 100644
--- a/folks/name-details.vala
+++ b/folks/name-details.vala
@@ -214,7 +214,7 @@ public class Folks.StructuredName : Object
             }
         }
 
-      return output.str;
+      return (owned) output.str;
     }
 
   /**
@@ -265,7 +265,7 @@ public class Folks.StructuredName : Object
        * punctuation, please file a bug against libfolks:
        *   https://gitlab.gnome.org/GNOME/folks/issues
        */
-      var name_fmt = _("%g%t%m%t%f");
+      unowned var name_fmt = _("%g%t%m%t%f");
 
       return this.to_string_with_format (name_fmt);
     }
@@ -372,7 +372,7 @@ public class Folks.StructuredName : Object
             }
         }
 
-      return output.str;
+      return (owned) output.str;
     }
 }
 
diff --git a/folks/persona.vala b/folks/persona.vala
index ecbadb9f..add9be12 100644
--- a/folks/persona.vala
+++ b/folks/persona.vala
@@ -283,7 +283,7 @@ public abstract class Folks.Persona : Object
       assert_not_reached ();
     }
 
-  private static string _add_escaped_uid_component (StringBuilder uid, string component)
+  private static void _add_escaped_uid_component (StringBuilder uid, string component)
     {
       /* Escape colons with backslashes */
       for (int i = 0; i < component.length; i++)
@@ -295,8 +295,6 @@ public abstract class Folks.Persona : Object
             }
           uid.append_c (c);
         }
-
-      return uid.str;
     }
 
   private static string _unescape_uid_component (string component)
@@ -338,7 +336,7 @@ public abstract class Folks.Persona : Object
       uid.append_c (':');
       Persona._add_escaped_uid_component (uid, persona_id);
 
-      return uid.str;
+      return (owned) uid.str;
     }
 
   /**
diff --git a/folks/phone-details.vala b/folks/phone-details.vala
index 141ac073..9e97eb3b 100644
--- a/folks/phone-details.vala
+++ b/folks/phone-details.vala
@@ -91,10 +91,10 @@ public class Folks.PhoneFieldDetails : AbstractFieldDetails<string>
    */
   public override bool values_equal (AbstractFieldDetails<string> that)
     {
-      var _that_fd = that as PhoneFieldDetails;
+      unowned var _that_fd = that as PhoneFieldDetails;
       if (_that_fd == null)
         return false;
-      PhoneFieldDetails that_fd = (!) _that_fd;
+      unowned PhoneFieldDetails that_fd = (!) _that_fd;
 
       var n1 = PhoneFieldDetails._drop_extension (this.get_normalised ());
       var n2 = PhoneFieldDetails._drop_extension (that_fd.get_normalised ());
@@ -185,7 +185,7 @@ public class Folks.PhoneFieldDetails : AbstractFieldDetails<string>
          builder.append_c (digit);
        }
 
-      return builder.str;
+      return (owned) builder.str;
     }
 
   /**
@@ -214,7 +214,7 @@ public class Folks.PhoneFieldDetails : AbstractFieldDetails<string>
           builder.append_c (digit);
         }
 
-      return builder.str;
+      return (owned) builder.str;
     }
 }
 
diff --git a/folks/postal-address-details.vala b/folks/postal-address-details.vala
index f08d874e..d40bd1a7 100644
--- a/folks/postal-address-details.vala
+++ b/folks/postal-address-details.vala
@@ -229,7 +229,7 @@ public class Folks.PostalAddress : Object
    */
   public string to_string ()
     {
-      var str = _("%s, %s, %s, %s, %s, %s, %s");
+      unowned var str = _("%s, %s, %s, %s, %s, %s, %s");
       return str.printf (this.po_box, this.extension, this.street,
           this.locality, this.region, this.postal_code, this.country);
     }
diff --git a/folks/utils.vala b/folks/utils.vala
index 2339e273..a69086a9 100644
--- a/folks/utils.vala
+++ b/folks/utils.vala
@@ -273,4 +273,24 @@ public class Folks.Utils : Object
 
       return true;
     }
+
+  /**
+   * Checks whether the given string is empty, ignoring any trailing or leading
+   * whitespace. Basically, it's the same as executing (str.strip() != ""), but
+   * without unnecessarily creating a string copy.
+   *
+   * @param str The string to check for
+   * @since 0.14.1
+   */
+  public static bool is_string_empty (string str)
+    {
+      int length = str.length;
+      for (int i = 0; i < length; i++)
+        {
+          if (! str[i].isspace ())
+            return false;
+        }
+
+      return true;
+    }
 }


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