changeset 94:6e47426efb6a

Add preliminary userlist data handling functions.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 07 May 2009 06:14:21 +0300
parents 7f9f6af26a65
children 69f9c46e4a94
files libnnchat.c libnnchat.h
diffstat 2 files changed, 143 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- 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);
+}
+
--- 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);