Use hb_array_t for hb_language_t mapping
This commit is contained in:
parent
21d2c92fdf
commit
b45f32ee4e
|
@ -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 *
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
Loading…
Reference in New Issue