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