Use hb_array_t for hb_language_t mapping
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 5 May 2011 19:00:43 +0000 (15:00 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 5 May 2011 19:00:43 +0000 (15:00 -0400)
src/hb-common.cc
src/hb-object-private.hh
src/hb-private.hh

index b75146d..67988c3 100644 (file)
@@ -136,40 +136,36 @@ lang_hash (const void *key)
 #endif
 
 
+struct hb_language_item_t {
+
+  hb_language_t lang;
+
+  inline bool operator == (const char *s) const {
+    return lang_equal (lang, s);
+  }
+
+  inline hb_language_item_t & operator = (const char *s) {
+    lang = (hb_language_t) strdup (s);
+    for (unsigned char *p = (unsigned char *) lang; *p; p++)
+      *p = canon_map[*p];
+
+    return *this;
+  }
+
+  void finish (void) { free (lang); }
+};
+
 hb_language_t
 hb_language_from_string (const char *str)
 {
-  static unsigned int num_langs;
-  static unsigned int num_alloced;
-  static hb_language_t *langs;
-  unsigned int i;
-  unsigned char *p;
-
-  /* TODO Use a hash table or something */
+  static hb_set_t<hb_language_item_t> langs;
 
   if (!str || !*str)
     return NULL;
 
-  for (i = 0; i < num_langs; i++)
-    if (lang_equal (str, langs[i]->s))
-      return langs[i];
-
-  if (unlikely (num_langs == num_alloced)) {
-    unsigned int new_alloced = 2 * (8 + num_alloced);
-    hb_language_t *new_langs = (hb_language_t *) realloc (langs, new_alloced * sizeof (langs[0]));
-    if (!new_langs)
-      return NULL;
-    num_alloced = new_alloced;
-    langs = new_langs;
-  }
-
-  langs[i] = (hb_language_t) strdup (str);
-  for (p = (unsigned char *) langs[i]->s; *p; p++)
-    *p = canon_map[*p];
-
-  num_langs++;
+  hb_language_item_t *item = langs.find_or_insert (str);
 
-  return langs[i];
+  return likely (item) ? item->lang : NULL;
 }
 
 const char *
index 1add2e7..dc7dba9 100644 (file)
@@ -132,11 +132,11 @@ struct hb_user_data_array_t {
       return true;
     }
     hb_user_data_item_t item = {key, data, destroy};
-    return items.insert (item);
+    return !!items.insert (item);
   }
 
   inline void *get (hb_user_data_key_t *key) {
-    hb_user_data_item_t *item = items.get (key);
+    hb_user_data_item_t *item = items.find (key);
     return item ? item->data : NULL;
   }
 
index c37518d..d31e014 100644 (file)
@@ -327,16 +327,16 @@ struct hb_set_t
   public:
 
   template <typename T>
-  inline bool insert (T v)
+  inline item_t *insert (T v)
   {
     item_t *item = items.find (v);
     if (item)
       item->finish ();
     else
       item = items.push ();
-    if (unlikely (!item)) return false;
+    if (unlikely (!item)) return NULL;
     *item = v;
-    return true;
+    return item;
   }
 
   template <typename T>
@@ -351,11 +351,22 @@ struct hb_set_t
   }
 
   template <typename T>
-  inline item_t *get (T v)
+  inline item_t *find (T v)
   {
     return items.find (v);
   }
 
+  template <typename T>
+  inline item_t *find_or_insert (T v) {
+    item_t *item = find (v);
+    if (!item) {
+      item = items.push ();
+      if (likely (item))
+        *item = v;
+    }
+    return item;
+  }
+
   void finish (void) {
     for (unsigned i = 0; i < items.len; i++)
       items[i].finish ();