Use hb_array_t for hb_language_t mapping

This commit is contained in:
Behdad Esfahbod 2011-05-05 15:00:43 -04:00
parent 21d2c92fdf
commit b45f32ee4e
3 changed files with 39 additions and 32 deletions

View File

@ -136,40 +136,36 @@ lang_hash (const void *key)
#endif #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_t
hb_language_from_string (const char *str) hb_language_from_string (const char *str)
{ {
static unsigned int num_langs; static hb_set_t<hb_language_item_t> langs;
static unsigned int num_alloced;
static hb_language_t *langs;
unsigned int i;
unsigned char *p;
/* TODO Use a hash table or something */
if (!str || !*str) if (!str || !*str)
return NULL; return NULL;
for (i = 0; i < num_langs; i++) hb_language_item_t *item = langs.find_or_insert (str);
if (lang_equal (str, langs[i]->s))
return langs[i];
if (unlikely (num_langs == num_alloced)) { return likely (item) ? item->lang : NULL;
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++;
return langs[i];
} }
const char * const char *

View File

@ -132,11 +132,11 @@ struct hb_user_data_array_t {
return true; return true;
} }
hb_user_data_item_t item = {key, data, destroy}; 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) { 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; return item ? item->data : NULL;
} }

View File

@ -327,16 +327,16 @@ struct hb_set_t
public: public:
template <typename T> template <typename T>
inline bool insert (T v) inline item_t *insert (T v)
{ {
item_t *item = items.find (v); item_t *item = items.find (v);
if (item) if (item)
item->finish (); item->finish ();
else else
item = items.push (); item = items.push ();
if (unlikely (!item)) return false; if (unlikely (!item)) return NULL;
*item = v; *item = v;
return true; return item;
} }
template <typename T> template <typename T>
@ -351,11 +351,22 @@ struct hb_set_t
} }
template <typename T> template <typename T>
inline item_t *get (T v) inline item_t *find (T v)
{ {
return items.find (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) { void finish (void) {
for (unsigned i = 0; i < items.len; i++) for (unsigned i = 0; i < items.len; i++)
items[i].finish (); items[i].finish ();