fehQlibs 27
Qlibs
Loading...
Searching...
No Matches
constmap.c
Go to the documentation of this file.
1#include "constmap.h"
2#include "alloc.h"
3#include "case.h"
4
12
13
14static constmap_hash hash(char *s,int len)
15{
16 unsigned char ch;
18 h = 5381;
19 while (len > 0) {
20 ch = *s++ - 'A';
21 if (ch <= 'Z' - 'A') ch += 'a' - 'A';
22 h = ((h << 5) + h) ^ ch;
23 --len;
24 }
25 return h;
26}
27
34
35int constmap_index(struct constmap *cm,const char *s,int len)
36{
38 int pos;
39 h = hash(s,len);
40 pos = cm->first[h & cm->mask];
41 while (pos != -1) {
42 if (h == cm->hash[pos])
43 if (len == cm->inputlen[pos])
44 if (!case_diffb(cm->input[pos],len,s))
45 return pos + 1;
46 pos = cm->next[pos];
47 }
48 return 0;
49}
50
56
57char *constmap_get(struct constmap *cm,int idx)
58{
59 if (idx <= 0 || idx > cm->num)
60 return 0;
61 else
62 return cm->input[idx - 1];
63}
64
65char *constmap(struct constmap *cm,const char *s,int len)
66{
68 int pos;
69 h = hash(s,len);
70 pos = cm->first[h & cm->mask];
71 while (pos != -1) {
72 if (h == cm->hash[pos])
73 if (len == cm->inputlen[pos])
74 if (!case_diffb(cm->input[pos],len,s))
75 return cm->input[pos] + cm->inputlen[pos] + 1;
76 pos = cm->next[pos];
77 }
78 return 0;
79}
80
81int constmap_init(struct constmap *cm,const char *s,int len,int flagcolon)
82{
83 int i;
84 int j;
85 int k;
86 int pos;
88
89 cm->num = 0;
90 for (j = 0; j < len; ++j) if (!s[j]) ++cm->num;
91
92 h = 64;
93 while (h && (h < cm->num)) h += h;
94 cm->mask = h - 1;
95
96 cm->first = (int *) alloc(sizeof(int) * h);
97 if (cm->first) {
98 cm->input = (char **) alloc(sizeof(char *) * cm->num);
99 if (cm->input) {
100 cm->inputlen = (int *) alloc(sizeof(int) * cm->num);
101 if (cm->inputlen) {
102 cm->hash = (constmap_hash *) alloc(sizeof(constmap_hash) * cm->num);
103 if (cm->hash) {
104 cm->next = (int *) alloc(sizeof(int) * cm->num);
105 if (cm->next) {
106 for (h = 0; h <= cm->mask; ++h)
107 cm->first[h] = -1;
108 pos = 0;
109 i = 0;
110 for (j = 0; j < len; ++j)
111 if (!s[j]) {
112 k = j - i;
113 if (flagcolon) {
114 for (k = i; k < j; ++k)
115 if (s[k] == ':') break;
116 if (k >= j) { i = j + 1; continue; }
117 k -= i;
118 }
119 cm->input[pos] = s + i;
120 cm->inputlen[pos] = k;
121 h = hash(s + i,k);
122 cm->hash[pos] = h;
123 h &= cm->mask;
124 cm->next[pos] = cm->first[h];
125 cm->first[h] = pos;
126 ++pos;
127 i = j + 1;
128 }
129 return 1;
130 }
131 alloc_free(cm->hash);
132 }
133 alloc_free(cm->inputlen);
134 }
135 alloc_free(cm->input);
136 }
137 alloc_free(cm->first);
138 }
139 return 0;
140}
141
142int constmap_init_char(struct constmap *cm,const char *s,int len,int flagcolon,char flagchar)
143{
144 int i;
145 int j;
146 int k;
147 int pos;
149
150 if (!flagchar || flagchar == 0 || flagchar == '\0') {
151 flagchar = ':';
152 }
153
154 cm->num = 0;
155 for (j = 0; j < len; ++j) if (!s[j]) ++cm->num;
156
157 h = 64;
158 while (h && (h < cm->num)) h += h;
159 cm->mask = h - 1;
160
161 cm->first = (int *) alloc(sizeof(int) * h);
162 if (cm->first) {
163 cm->input = (char **) alloc(sizeof(char *) * cm->num);
164 if (cm->input) {
165 cm->inputlen = (int *) alloc(sizeof(int) * cm->num);
166 if (cm->inputlen) {
167 cm->hash = (constmap_hash *) alloc(sizeof(constmap_hash) * cm->num);
168 if (cm->hash) {
169 cm->next = (int *) alloc(sizeof(int) * cm->num);
170 if (cm->next) {
171 for (h = 0; h <= cm->mask; ++h)
172 cm->first[h] = -1;
173 pos = 0;
174 i = 0;
175 for (j = 0; j < len; ++j) {
176 if (!s[j]) {
177 k = j - i;
178 if (flagcolon) {
179 for (k = i; k < j; ++k)
180 if (s[k] == flagchar) break;
181 if (k >= j) { i = j + 1; continue; }
182 k -= i;
183 }
184 cm->input[pos] = s + i;
185 cm->inputlen[pos] = k;
186 h = hash(s + i,k);
187 cm->hash[pos] = h;
188 h &= cm->mask;
189 cm->next[pos] = cm->first[h];
190 cm->first[h] = pos;
191 ++pos;
192 i = j + 1;
193 }
194 }
195 return 1;
196 }
197 alloc_free(cm->hash);
198 }
199 alloc_free(cm->inputlen);
200 }
201 alloc_free(cm->input);
202 }
203 alloc_free(cm->first);
204 }
205 return 0;
206}
207
208void constmap_free(struct constmap *cm)
209{
210 alloc_free(cm->next);
211 alloc_free(cm->hash);
212 alloc_free(cm->inputlen);
213 alloc_free(cm->input);
214 alloc_free(cm->first);
215}
void alloc_free(void *)
Definition alloc.c:45
void * alloc(unsigned int)
Definition alloc.c:27
unsigned long constmap_hash
Definition constmap.h:4
int case_diffb(char *, unsigned int, char *)
Definition case.c:10
int constmap_index(struct constmap *cm, const char *s, int len)
Definition constmap.c:35
char * constmap(struct constmap *cm, const char *s, int len)
Definition constmap.c:65
void constmap_free(struct constmap *cm)
Definition constmap.c:208
int constmap_init(struct constmap *cm, const char *s, int len, int flagcolon)
Definition constmap.c:81
char * constmap_get(struct constmap *cm, int idx)
Definition constmap.c:57
int constmap_init_char(struct constmap *cm, const char *s, int len, int flagcolon, char flagchar)
Definition constmap.c:142
int * first
Definition constmap.h:10
constmap_hash * hash
Definition constmap.h:9
constmap_hash mask
Definition constmap.h:8
char ** input
Definition constmap.h:12
int * next
Definition constmap.h:11
int * inputlen
Definition constmap.h:13
int num
Definition constmap.h:7