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
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];
hb_language_item_t *item = langs.find_or_insert (str);
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++;
return langs[i];
return likely (item) ? item->lang : NULL;
}
const char *

View 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;
}

View 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 ();