comparison libnnchat.c @ 103:eaa524e153f9

Initial implementation of functions for implementing tab-completion for user names.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 15 Oct 2010 00:34:25 +0300
parents b096ae97fc7d
children c587a99e2096
comparison
equal deleted inserted replaced
102:b096ae97fc7d 103:eaa524e153f9
548 548
549 return res; 549 return res;
550 } 550 }
551 551
552 552
553 char * nn_editbuf_get_string(nn_editbuf_t *buf, ssize_t start, ssize_t end)
554 {
555 char *str;
556 ssize_t siz;
557
558 if (buf == NULL)
559 return NULL;
560
561 if (start < 0 || end > buf->len || start >= buf->len)
562 return NULL;
563
564 if (end < 0) {
565 siz = buf->len - start + 1;
566 } else if (start <= end) {
567 siz = end - start + 1;
568 } else
569 return NULL;
570
571 str = th_malloc(siz + 1);
572 memcpy(str, buf->data + start, siz);
573 str[siz] = 0;
574 return str;
575 }
576
577
553 void nn_editbuf_setpos(nn_editbuf_t *buf, ssize_t pos) 578 void nn_editbuf_setpos(nn_editbuf_t *buf, ssize_t pos)
554 { 579 {
555 /* Check arguments */ 580 assert(buf != NULL);
581
556 if (pos < 0) 582 if (pos < 0)
557 buf->pos = 0; 583 buf->pos = 0;
558 else if (pos >= buf->len) 584 else if (pos >= buf->len)
559 buf->pos = buf->len; 585 buf->pos = buf->len;
560 else 586 else
562 } 588 }
563 589
564 590
565 static uint8_t nn_hash_user(const char *name) 591 static uint8_t nn_hash_user(const char *name)
566 { 592 {
593 /*
567 int n = 0; 594 int n = 0;
568 const uint8_t *c = (uint8_t *)name; 595 const uint8_t *c = (uint8_t *)name;
569 uint8_t hash = 0xff; 596 uint8_t hash = 0xff;
570 597
571 while (*c && n < 4) { 598 while (*c && n < 4) {
572 hash = (hash << 1) ^ tolower(*c); 599 hash = (hash << 1) ^ tolower(*c);
573 c++; n++; 600 c++; n++;
574 } 601 }
575 602
576 return (hash & 0xff); 603 return (hash & 0xff);
604 */
605 return tolower(name[0]);
577 } 606 }
578 607
579 608
580 static void nn_user_insert(nn_user_t **list, nn_user_t *node) 609 static void nn_user_insert(nn_user_t **list, nn_user_t *node)
581 { 610 {
582 node->next = *list; 611 node->next = *list;
583 *list = node; 612 *list = node;
613 }
614
615
616 nn_user_t *nn_userhash_foreach(const nn_userhash_t *list, int (*func)(const nn_user_t *))
617 {
618 int i;
619
620 if (list == NULL) return NULL;
621
622 for (i = 0; i < NN_NUM_BUCKETS; i++)
623 if (list->buckets[i] != NULL) {
624 nn_user_t *curr = list->buckets[i];
625 while (curr != NULL) {
626 if (func(curr) != 0)
627 return curr;
628 curr = curr->next;
629 }
630 }
631
632 return NULL;
584 } 633 }
585 634
586 635
587 nn_user_t *nn_user_find_enc(const nn_userhash_t *list, const char *encname) 636 nn_user_t *nn_user_find_enc(const nn_userhash_t *list, const char *encname)
588 { 637 {
602 651
603 return NULL; 652 return NULL;
604 } 653 }
605 654
606 655
607 int nn_user_add_to_hash(nn_userhash_t **list, const char *encname) 656 nn_user_t *nn_user_match(const nn_userhash_t *list, const char *str, const char *current)
657 {
658 uint8_t hash;
659
660 if (list == NULL) return NULL;
661
662 hash = nn_hash_user(str);
663 if (list->buckets[hash] != NULL) {
664 nn_user_t *curr = list->buckets[hash];
665 int len = strlen(str);
666
667 if (current != NULL) {
668 nn_user_t *found = NULL;
669 while (curr != NULL) {
670 if (strcasecmp(curr->name, current) == 0) {
671 found = curr->next;
672 break;
673 }
674 curr = curr->next;
675 }
676 if (found != NULL)
677 curr = found;
678 else
679 curr = list->buckets[hash];
680 }
681
682 while (curr != NULL) {
683 if (strncasecmp(curr->name, str, len) == 0)
684 return curr;
685 curr = curr->next;
686 }
687 }
688
689 return NULL;
690 }
691
692
693 nn_userhash_t *nn_userhash_new(void)
694 {
695 return th_calloc(1, sizeof(nn_userhash_t));
696 }
697
698
699 int nn_userhash_insert(nn_userhash_t *list, const char *encname)
608 { 700 {
609 uint8_t hash; 701 uint8_t hash;
610 nn_user_t *user; 702 nn_user_t *user;
611 703
612 /* Check arguments */ 704 /* Check arguments */
613 if (list == NULL || encname == NULL) 705 if (list == NULL || encname == NULL)
614 return -1; 706 return -1;
615 707
616 /* Check if list data exists */
617 if (*list == NULL) {
618 *list = th_calloc(1, sizeof(nn_userhash_t));
619 if (*list == NULL)
620 return -2;
621 }
622
623 /* Check if username is already there */ 708 /* Check if username is already there */
624 if (nn_user_find_enc(*list, encname) != NULL) 709 if (nn_user_find_enc(list, encname) != NULL)
625 return 1; 710 return 1;
626 711
627 /* No, we'll add it */ 712 /* No, we'll add it */
628 if ((user = th_calloc(1, sizeof(nn_user_t))) == NULL) 713 if ((user = th_calloc(1, sizeof(nn_user_t))) == NULL)
629 return -3; 714 return -3;
632 user->name = nn_dbldecode_str(encname); 717 user->name = nn_dbldecode_str(encname);
633 if (user->encname == NULL || user->name == NULL) 718 if (user->encname == NULL || user->name == NULL)
634 return -4; 719 return -4;
635 720
636 hash = nn_hash_user(encname); 721 hash = nn_hash_user(encname);
637 nn_user_insert(&((*list)->buckets[hash]), user); 722 nn_user_insert(&(list->buckets[hash]), user);
723
638 return 0; 724 return 0;
725 }
726
727
728 int nn_userhash_delete(nn_userhash_t *list, const char *encname)
729 {
730 uint8_t hash;
731
732 /* Check arguments */
733 if (list == NULL || encname == NULL)
734 return -1;
735
736 /* Check if username is already there */
737 hash = nn_hash_user(encname);
738 if (list->buckets[hash] != NULL) {
739 nn_user_t *curr, *prev;
740 curr = list->buckets[hash];
741 prev = NULL;
742 while (curr != NULL) {
743 if (strcasecmp(curr->encname, encname) == 0) {
744 if (prev)
745 prev->next = curr->next;
746 else
747 list->buckets[hash] = curr->next;
748
749 nn_user_free(curr);
750
751 return 0;
752 } else {
753 prev = curr;
754 curr = curr->next;
755 }
756 }
757 }
758
759 return 1;
639 } 760 }
640 761
641 762
642 nn_user_t *nn_user_copy(const nn_user_t *src) 763 nn_user_t *nn_user_copy(const nn_user_t *src)
643 { 764 {
656 777
657 return user; 778 return user;
658 } 779 }
659 780
660 781
661 static void nn_user_free(nn_user_t *user) 782 void nn_user_free(nn_user_t *user)
662 { 783 {
663 th_free(user->encname); 784 th_free(user->encname);
664 th_free(user->name); 785 th_free(user->name);
665 th_free(user); 786 th_free(user);
666 } 787 }
674 nn_user_free(curr); 795 nn_user_free(curr);
675 curr = next; 796 curr = next;
676 } 797 }
677 } 798 }
678 799
679 void nn_user_free_hash(nn_userhash_t *hash) 800 void nn_userhash_free(nn_userhash_t *hash)
680 { 801 {
681 int i; 802 int i;
682 if (hash == NULL) 803 if (hash == NULL)
683 return; 804 return;
684 805