nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

constmap.c (2232B)


      1 #include "constmap.h"
      2 
      3 #include "alloc.h"
      4 #include "case.h"
      5 
      6 static constmap_hash hash(char *s, int len)
      7 {
      8 	unsigned char ch;
      9 	constmap_hash h;
     10 	h = 5381;
     11 	while (len > 0) {
     12 		ch = *s++ - 'A';
     13 		if (ch <= 'Z' - 'A')
     14 			ch += 'a' - 'A';
     15 		h = ((h << 5) + h) ^ ch;
     16 		--len;
     17 	}
     18 	return h;
     19 }
     20 
     21 char *constmap(struct constmap *cm, char *s, int len)
     22 {
     23 	constmap_hash h;
     24 	int pos;
     25 	h = hash(s, len);
     26 	pos = cm->first[h & cm->mask];
     27 	while (pos != -1) {
     28 		if (h == cm->hash[pos])
     29 			if (len == cm->inputlen[pos])
     30 				if (!case_diffb(cm->input[pos], len, s))
     31 					return cm->input[pos] + cm->inputlen[pos] + 1;
     32 		pos = cm->next[pos];
     33 	}
     34 	return 0;
     35 }
     36 
     37 int constmap_init(struct constmap *cm, char *s, int len, int flagcolon)
     38 {
     39 	int i;
     40 	int j;
     41 	int k;
     42 	int pos;
     43 	constmap_hash h;
     44 
     45 	cm->num = 0;
     46 	for (j = 0; j < len; ++j)
     47 		if (!s[j])
     48 			++cm->num;
     49 
     50 	h = 64;
     51 	while (h && (h < cm->num))
     52 		h += h;
     53 	cm->mask = h - 1;
     54 
     55 	cm->first = (int *)alloc(sizeof(int) * h);
     56 	if (cm->first) {
     57 		cm->input = (char **)alloc(sizeof(char *) * cm->num);
     58 		if (cm->input) {
     59 			cm->inputlen = (int *)alloc(sizeof(int) * cm->num);
     60 			if (cm->inputlen) {
     61 				cm->hash = (constmap_hash *) alloc(sizeof(constmap_hash) * cm->num);
     62 				if (cm->hash) {
     63 					cm->next = (int *)alloc(sizeof(int) * cm->num);
     64 					if (cm->next) {
     65 						for (h = 0; h <= cm->mask; ++h)
     66 							cm->first[h] = -1;
     67 						pos = 0;
     68 						i = 0;
     69 						for (j = 0; j < len; ++j)
     70 							if (!s[j]) {
     71 								k = j - i;
     72 								if (flagcolon) {
     73 									for (k = i; k < j; ++k)
     74 										if (s[k] == ':')
     75 											break;
     76 									if (k >= j) {
     77 										i = j + 1;
     78 										continue;
     79 									}
     80 									k -= i;
     81 								}
     82 								cm->input[pos] = s + i;
     83 								cm->inputlen[pos] = k;
     84 								h = hash(s + i, k);
     85 								cm->hash[pos] = h;
     86 								h &= cm->mask;
     87 								cm->next[pos] = cm->first[h];
     88 								cm->first[h] = pos;
     89 								++pos;
     90 								i = j + 1;
     91 							}
     92 						return 1;
     93 					}
     94 					alloc_free(cm->hash);
     95 				}
     96 				alloc_free(cm->inputlen);
     97 			}
     98 			alloc_free(cm->input);
     99 		}
    100 		alloc_free(cm->first);
    101 	}
    102 	return 0;
    103 }
    104 
    105 void constmap_free(struct constmap *cm)
    106 {
    107 	alloc_free(cm->next);
    108 	alloc_free(cm->hash);
    109 	alloc_free(cm->inputlen);
    110 	alloc_free(cm->input);
    111 	alloc_free(cm->first);
    112 }