# HG changeset patch # User Matti Hamalainen # Date 1241666061 -10800 # Node ID 6e47426efb6a7a512291a1d087dc52183fd58822 # Parent 7f9f6af26a65e2812adcc105715d6298fecbb56e Add preliminary userlist data handling functions. diff -r 7f9f6af26a65 -r 6e47426efb6a libnnchat.c --- a/libnnchat.c Thu May 07 03:58:42 2009 +0300 +++ b/libnnchat.c Thu May 07 06:14:21 2009 +0300 @@ -561,3 +561,132 @@ buf->pos = pos; } + +static uint8_t hashUserName(char *name) +{ + int n = 0; + uint8_t *c = (uint8_t *)name; + uint8_t hash = 0xff; + + while (*c && n < 4) { + hash = (hash << 1) ^ tolower(*c); + c++; n++; + } + + return (hash & 0xff); +} + + +static void insertUser(nn_user_t **list, nn_user_t *node) +{ + node->next = *list; + *list = node; +} + + +nn_user_t *findUserEnc(nn_userhash_t *list, char *encname) +{ + uint8_t hash; + + if (list == NULL) return NULL; + + hash = hashUserName(encname); + if (list->buckets[hash] != NULL) { + nn_user_t *curr = list->buckets[hash]; + while (curr != NULL) { + if (strcasecmp(curr->encname, encname) == 0) + return curr; + curr = curr->next; + } + } + + return NULL; +} + + +int addUserToHash(nn_userhash_t **list, char *encname) +{ + uint8_t hash; + nn_user_t *user; + + /* Check arguments */ + if (list == NULL || encname == NULL) + return -1; + + /* Check if list data exists */ + if (*list == NULL) { + *list = th_calloc(1, sizeof(nn_userhash_t)); + if (*list == NULL) + return -2; + } + + /* Check if username is already there */ + if (findUserEnc(*list, encname) != NULL) + return 1; + + /* No, we'll add it */ + if ((user = th_calloc(1, sizeof(nn_user_t))) == NULL) + return -3; + + user->encname = th_strdup(encname); + user->name = doubleDecodeStr(encname); + if (user->encname == NULL || user->name == NULL) + return -4; + + hash = hashUserName(encname); + insertUser(&((*list)->buckets[hash]), user); + return 0; +} + + +nn_user_t *copyUser(nn_user_t *src) +{ + nn_user_t *user; + + if (src == NULL) return NULL; + + if ((user = th_calloc(1, sizeof(nn_user_t))) == NULL) + return NULL; + + /* Copy relevant data */ + user->encname = th_strdup(src->encname); + user->name = th_strdup(src->name); + user->lastspoke = src->lastspoke; + user->joined = src->joined; + + return user; +} + + +static void freeUser(nn_user_t *user) +{ + th_free(user->encname); + th_free(user->name); + th_free(user); +} + + +void freeUserList(nn_user_t *list) +{ + nn_user_t *next, *curr = list; + while (curr != NULL) { + next = curr->next; + freeUser(curr); + curr = next; + } +} + +void freeUserHash(nn_userhash_t *hash) +{ + int i; + if (hash == NULL) + return; + + for (i = 0; i < NN_NUM_BUCKETS; i++) { + freeUserList(hash->buckets[i]); + hash->buckets[i] = NULL; + } + + th_free(hash); +} + diff -r 7f9f6af26a65 -r 6e47426efb6a libnnchat.h --- a/libnnchat.h Thu May 07 03:58:42 2009 +0300 +++ b/libnnchat.h Thu May 07 06:14:21 2009 +0300 @@ -34,11 +34,18 @@ char *data; } nn_editbuf_t; -typedef struct { +typedef struct _nn_user_t { char *name, *encname; time_t lastspoke, joined; + struct _nn_user_t *next; } nn_user_t; +#define NN_NUM_BUCKETS (256) + +typedef struct { + nn_user_t *buckets[NN_NUM_BUCKETS]; +} nn_userhash_t; + #ifdef __WIN32 const char *hstrerror(int err); @@ -53,9 +60,12 @@ BOOL sendToSocket(const int sock, char *buf, const size_t bufLen); BOOL sendUserMsg(const int sock, const char *user, const char *fmt, ...); -int addUser(nn_user_t **list, char *encname); -int freeUser(nn_user_t *); -int freeUserList(nn_user_t *); +int addUserToHash(nn_userhash_t **, char *encname); +void freeUserHash(nn_userhash_t *); +void freeUserList(nn_user_t *); +nn_user_t * copyUser(nn_user_t *src); +nn_user_t * findUserEnc(nn_userhash_t *list, char *encname); +nn_user_t * matchUsersEnc(nn_userhash_t *list, char *encname, int index); char * encodeStr1(const char *str); char * decodeStr1(const char *str);