str_map::key_cmp -> str_map::key_xfrm

It seemed to be almost too easy to be true, and it actually was.

Now it should work.
This commit is contained in:
Přemysl Eric Janouch 2014-07-16 21:23:30 +02:00
parent 996e0912c2
commit d28b722489
2 changed files with 45 additions and 13 deletions

View File

@ -578,10 +578,9 @@ struct str_map
size_t len; ///< Number of entries in the table size_t len; ///< Number of entries in the table
void (*free) (void *); ///< Callback to destruct the payload void (*free) (void *); ///< Callback to destruct the payload
/// Callback to compare keys for equivalence /// Callback that transforms all key values for storage and comparison;
// FIXME: they may still end up on a different index, and actually should; /// has to behave exactly like strxfrm().
// delete this callback and put strxfrm() in its place size_t (*key_xfrm) (char *dest, const char *src, size_t n);
int (*key_cmp) (const char *, const char *);
}; };
// As long as you don't remove the current entry, you can modify the map. // As long as you don't remove the current entry, you can modify the map.
@ -604,7 +603,7 @@ str_map_init (struct str_map *self)
self->alloc = STR_MAP_MIN_ALLOC; self->alloc = STR_MAP_MIN_ALLOC;
self->len = 0; self->len = 0;
self->free = NULL; self->free = NULL;
self->key_cmp = strcmp; self->key_xfrm = NULL;
self->map = xcalloc (self->alloc, sizeof *self->map); self->map = xcalloc (self->alloc, sizeof *self->map);
} }
@ -698,13 +697,13 @@ str_map_resize (struct str_map *self, size_t new_size)
} }
static void static void
str_map_set (struct str_map *self, const char *key, void *value) str_map_set_real (struct str_map *self, const char *key, void *value)
{ {
uint64_t pos = str_map_pos (self, key); uint64_t pos = str_map_pos (self, key);
struct str_map_link *iter = self->map[pos]; struct str_map_link *iter = self->map[pos];
for (; iter; iter = iter->next) for (; iter; iter = iter->next)
{ {
if (self->key_cmp (key, iter->key)) if (strcmp (key, iter->key))
continue; continue;
// Storing the same data doesn't destroy it // Storing the same data doesn't destroy it
@ -748,16 +747,40 @@ str_map_set (struct str_map *self, const char *key, void *value)
self->len++; self->len++;
} }
static void
str_map_set (struct str_map *self, const char *key, void *value)
{
if (!self->key_xfrm)
{
str_map_set_real (self, key, value);
return;
}
char tmp[self->key_xfrm (NULL, key, 0) + 1];
self->key_xfrm (tmp, key, sizeof tmp);
str_map_set_real (self, tmp, value);
}
static void * static void *
str_map_find (struct str_map *self, const char *key) str_map_find_real (struct str_map *self, const char *key)
{ {
struct str_map_link *iter = self->map[str_map_pos (self, key)]; struct str_map_link *iter = self->map[str_map_pos (self, key)];
for (; iter; iter = iter->next) for (; iter; iter = iter->next)
if (!self->key_cmp (key, (const char *) iter + sizeof *iter)) if (!strcmp (key, (const char *) iter + sizeof *iter))
return iter->data; return iter->data;
return NULL; return NULL;
} }
static void *
str_map_find (struct str_map *self, const char *key)
{
if (!self->key_xfrm)
return str_map_find_real (self, key);
char tmp[self->key_xfrm (NULL, key, 0) + 1];
self->key_xfrm (tmp, key, sizeof tmp);
return str_map_find_real (self, tmp);
}
// --- File descriptor utilities ----------------------------------------------- // --- File descriptor utilities -----------------------------------------------
static void static void
@ -1727,7 +1750,7 @@ irc_process_buffer (struct str *buf,
} }
static int static int
irc_tolower (char c) irc_tolower (int c)
{ {
if (c == '[') return '{'; if (c == '[') return '{';
if (c == ']') return '}'; if (c == ']') return '}';
@ -1736,6 +1759,15 @@ irc_tolower (char c)
return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c; return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c;
} }
static size_t
irc_strxfrm (char *dest, const char *src, size_t n)
{
size_t len = strlen (src);
while (n-- && (*dest++ = irc_tolower (*src++)))
;
return len;
}
static int static int
irc_strcmp (const char *a, const char *b) irc_strcmp (const char *a, const char *b)
{ {

View File

@ -378,12 +378,12 @@ server_context_init (struct server_context *self)
self->server_name = NULL; self->server_name = NULL;
str_map_init (&self->users); str_map_init (&self->users);
self->users.key_cmp = irc_strcmp; self->users.key_xfrm = irc_strxfrm;
// TODO: set channel_free() as the free function? // TODO: set channel_free() as the free function?
str_map_init (&self->channels); str_map_init (&self->channels);
self->channels.key_cmp = irc_strcmp; self->channels.key_xfrm = irc_strxfrm;
str_map_init (&self->handlers); str_map_init (&self->handlers);
self->handlers.key_cmp = irc_strcmp; self->handlers.key_xfrm = irc_strxfrm;
poller_init (&self->poller); poller_init (&self->poller);
self->quitting = false; self->quitting = false;