Annotation of libwww/Library/src/HTMIMPrs.c, revision 2.3
2.1 eric 1: /* HTAtom.c
2: ** HTHashList: hash indexed array of MIME header parsers
3: **
4: ** (c) COPYRIGHT MIT 1996.
5: ** Please first read the full copyright statement in the file COPYRIGH.
2.3 ! eric 6: ** @(#) $Id: HTMIMPrs.c,v 2.2 1996/06/06 18:57:06 eric Exp $
2.1 eric 7: **
8: ** See HTHshLst.html for a description of HashLists.
9: **
10: ** Authors:
11: ** EGP Eric Prud'hommeaux w3
12: **
13: */
14:
15: /* Library include files */
16: #include "sysdep.h"
17: #include "HTUtils.h"
18: #include "HTString.h"
19: #include "HTMIMPrs.h"
20:
21: struct _HTMIMEParseEl{
22: HTMIMEParseEl * next;
23: const char * token;
24: BOOL caseSensitive;
25: HTParserCallback * pFunk;
26: };
27:
28: #define DEFAULT_HASH_SIZE 11
29:
30:
31: PRIVATE HTMIMEParseEl * HTMIMEParseEl_new(HTMIMEParseEl ** pBefore,
32: const char * token,
33: BOOL caseSensitive,
34: HTParserCallback * callback)
35: {
36: HTMIMEParseEl * ret;
37: if ((ret = (HTMIMEParseEl *) HT_MALLOC(sizeof(HTMIMEParseEl))) == NULL)
38: HT_OUTOFMEM("HTMIMEParseEl");
39: ret->next = *pBefore;
40: *pBefore = ret;
41: if ((ret->token = (char *) HT_MALLOC(strlen(token)+1)) == NULL)
42: HT_OUTOFMEM("token");
2.2 eric 43: strcpy((char *)ret->token, token);
2.1 eric 44: ret->caseSensitive = caseSensitive;
45: ret->pFunk = callback;
46:
47: return ret;
48: }
49:
50: PRIVATE int HTMIMEParseEl_delete(HTMIMEParseEl * me, HTMIMEParseEl ** pBefore)
51: {
52: *pBefore = me->next;
53: HT_FREE(me);
54: return HT_OK;
55: }
56:
57: PRIVATE int HTMIMEParseSet_hash(HTMIMEParseSet * me, const char * token)
58: {
59: int ret;
60: const char * p;
61:
62: for (p=token, ret=0; *p; p++) {
63: char ch;
64: ch = *(unsigned char *) p;
65: ch = tolower(ch);
66: ret = (ret * 3 +(ch)) % me->size;
67: }
68: return ret;
69: }
70:
71: PUBLIC HTMIMEParseSet * HTMIMEParseSet_new(int hashSize)
72: {
73: HTMIMEParseSet * me;
74:
75: if ((me = (HTMIMEParseSet *) HT_CALLOC(1, sizeof(HTMIMEParseSet))) == NULL)
76: HT_OUTOFMEM("HTMIMEParseSet");
77: me->size = hashSize;
78: return me;
79: }
80:
2.2 eric 81: PUBLIC int HTMIMEParseSet_deleteAll (HTMIMEParseSet * me)
2.1 eric 82: {
2.2 eric 83: int i;
84: HTMIMEParseEl * pEl, * next;
85:
86: for (i=0; i<me->size; i++)
87: for (pEl = me->parsers[i]; pEl; pEl = next) {
88: next = pEl->next;
89: HT_FREE(pEl);
90: }
91:
92: for (pEl = me->parsers[i]; pEl; pEl = next) {
93: next = pEl->next;
94: HT_FREE(pEl);
95: }
2.1 eric 96: HT_FREE(me);
97: return HT_OK;
98: }
99:
100: PUBLIC HTMIMEParseEl * HTMIMEParseSet_add (HTMIMEParseSet * me,
101: const char * token,
102: BOOL caseSensitive,
103: HTParserCallback * callback)
104: {
105: int hash;
106:
107: /* Insure hash list
108: */
109: if (!me->parsers) {
110: if (!me->size)
111: me->size = DEFAULT_HASH_SIZE;
112: if ((me->parsers = (HTMIMEParseEl **) HT_CALLOC(me->size, sizeof(HTMIMEParseEl *))) == NULL)
113: HT_OUTOFMEM("HTMIME parsers");
114: }
115: hash = HTMIMEParseSet_hash(me, token);
116:
117: /* Add a new entry
118: */
119: return HTMIMEParseEl_new(&me->parsers[hash], token,
120: caseSensitive, callback);
121: }
122:
123:
124: PUBLIC HTMIMEParseEl * HTMIMEParseSet_addRegex (HTMIMEParseSet * me,
125: const char * token,
126: BOOL caseSensitive,
127: HTParserCallback * callback)
128: {
129: return HTMIMEParseEl_new(&me->regexParsers, token,
130: caseSensitive, callback);
131: }
132:
2.2 eric 133: PUBLIC int HTMIMEParseSet_delete (HTMIMEParseSet * me, const char * token)
2.1 eric 134: {
135: int hash, i;
136: HTMIMEParseEl * pEl, ** last;
137:
138: hash = HTMIMEParseSet_hash(me, token);
139:
140: pEl = me->parsers[hash];
141: last = &me->parsers[hash];
142: for (i = 0; i < 2; i++) { /* do both */
143: for (; pEl; last = &pEl->next, pEl = pEl->next) {
144: if ((pEl->caseSensitive && !strcmp(pEl->token, token)) ||
145: (!pEl->caseSensitive && !strcasecomp(pEl->token, token))) {
146: return HTMIMEParseEl_delete(pEl, last);
147: }
148: }
149: pEl = me->regexParsers;
150: last = &me->regexParsers;
151: }
152: return HT_ERROR;
153: }
154:
155: /*
156: ** Search registered parsers to find suitable one for this token
157: ** If a parser isn't found, the function returns HT_OK
158: */
159: PUBLIC int HTMIMEParseSet_dispatch (HTMIMEParseSet * me, HTRequest * request,
160: char * token, char * value, BOOL * pFound)
161: {
2.2 eric 162: int hash;
2.1 eric 163: HTMIMEParseEl * pEl;
164:
165: if (pFound) *pFound = NO;
2.2 eric 166:
2.1 eric 167: hash = HTMIMEParseSet_hash(me, token);
2.2 eric 168: for (pEl = me->parsers[hash]; pEl; pEl = pEl->next) {
169: if ((pEl->caseSensitive && !strcmp(pEl->token, token)) ||
170: (!pEl->caseSensitive && !strcasecomp(pEl->token, token))) {
171: if (pFound) *pFound = YES;
172: if (!pEl->pFunk) return HT_OK; /* registered with no callback*/
173: return (*pEl->pFunk)(request, token, value);
174: }
175: }
2.1 eric 176:
2.2 eric 177: for (pEl = me->regexParsers; pEl; pEl = pEl->next) {
2.3 ! eric 178: if ((pEl->caseSensitive && HTStrMatch(pEl->token, token)) ||
! 179: (!pEl->caseSensitive && HTStrCaseMatch(pEl->token, token))) {
2.2 eric 180: if (pFound) *pFound = YES;
181: if (!pEl->pFunk) return HT_OK; /* registered with no callback*/
182: return (*pEl->pFunk)(request, token, value);
2.1 eric 183: }
184: }
2.2 eric 185:
2.1 eric 186: return HT_OK;
187: }
188:
Webmaster