diff libnnchat.c @ 94:6e47426efb6a

Add preliminary userlist data handling functions.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 07 May 2009 06:14:21 +0300
parents acfc4b4bc180
children 69f9c46e4a94
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);
+}
+