Annotation of libwww/Library/src/HTMIMPrs.c, revision 2.11
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.11 ! kahan 6: ** @(#) $Id: HTMIMPrs.c,v 2.10 2000/01/04 20:25:32 kahan 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 */
2.7 frystyk 16: #include "wwwsys.h"
2.1 eric 17: #include "HTUtils.h"
18: #include "HTString.h"
19: #include "HTMIMPrs.h"
20:
21: struct _HTMIMEParseEl{
2.4 frystyk 22: HTMIMEParseEl * next;
2.10 kahan 23: char * token;
24: BOOL caseSensitive;
2.4 frystyk 25: HTParserCallback * pFunk;
2.1 eric 26: };
27:
28: PRIVATE HTMIMEParseEl * HTMIMEParseEl_new(HTMIMEParseEl ** pBefore,
29: const char * token,
30: BOOL caseSensitive,
31: HTParserCallback * callback)
32: {
33: HTMIMEParseEl * ret;
34: if ((ret = (HTMIMEParseEl *) HT_MALLOC(sizeof(HTMIMEParseEl))) == NULL)
35: HT_OUTOFMEM("HTMIMEParseEl");
36: ret->next = *pBefore;
37: *pBefore = ret;
38: if ((ret->token = (char *) HT_MALLOC(strlen(token)+1)) == NULL)
39: HT_OUTOFMEM("token");
2.2 eric 40: strcpy((char *)ret->token, token);
2.1 eric 41: ret->caseSensitive = caseSensitive;
42: ret->pFunk = callback;
43:
44: return ret;
45: }
46:
47: PRIVATE int HTMIMEParseEl_delete(HTMIMEParseEl * me, HTMIMEParseEl ** pBefore)
48: {
49: *pBefore = me->next;
2.11 ! kahan 50: HT_FREE(me->token);
2.1 eric 51: HT_FREE(me);
52: return HT_OK;
53: }
54:
55: PRIVATE int HTMIMEParseSet_hash(HTMIMEParseSet * me, const char * token)
56: {
57: int ret;
58: const char * p;
59:
60: for (p=token, ret=0; *p; p++) {
61: char ch;
62: ch = *(unsigned char *) p;
2.8 frystyk 63: ch = TOLOWER(ch);
2.1 eric 64: ret = (ret * 3 +(ch)) % me->size;
65: }
66: return ret;
67: }
68:
69: PUBLIC HTMIMEParseSet * HTMIMEParseSet_new(int hashSize)
70: {
71: HTMIMEParseSet * me;
72:
73: if ((me = (HTMIMEParseSet *) HT_CALLOC(1, sizeof(HTMIMEParseSet))) == NULL)
74: HT_OUTOFMEM("HTMIMEParseSet");
75: me->size = hashSize;
76: return me;
77: }
78:
2.2 eric 79: PUBLIC int HTMIMEParseSet_deleteAll (HTMIMEParseSet * me)
2.1 eric 80: {
2.2 eric 81: int i;
82: HTMIMEParseEl * pEl, * next;
2.10 kahan 83:
84: if (me && me->parsers) {
85: for (i=0; i<me->size; i++) {
86: for (pEl = me->parsers[i]; pEl; pEl = next) {
87: next = pEl->next;
88: HT_FREE(pEl->token);
89: HT_FREE(pEl);
90: }
2.2 eric 91: }
2.10 kahan 92: HT_FREE(me->parsers);
93: HT_FREE(me);
2.2 eric 94: }
2.1 eric 95: return HT_OK;
96: }
97:
98: PUBLIC HTMIMEParseEl * HTMIMEParseSet_add (HTMIMEParseSet * me,
99: const char * token,
100: BOOL caseSensitive,
101: HTParserCallback * callback)
102: {
103: int hash;
104:
105: /* Insure hash list
106: */
107: if (!me->parsers) {
108: if (!me->size)
2.9 frystyk 109: me->size = HT_S_HASH_SIZE;
2.1 eric 110: if ((me->parsers = (HTMIMEParseEl **) HT_CALLOC(me->size, sizeof(HTMIMEParseEl *))) == NULL)
111: HT_OUTOFMEM("HTMIME parsers");
112: }
113: hash = HTMIMEParseSet_hash(me, token);
114:
115: /* Add a new entry
116: */
117: return HTMIMEParseEl_new(&me->parsers[hash], token,
118: caseSensitive, callback);
119: }
120:
121:
122: PUBLIC HTMIMEParseEl * HTMIMEParseSet_addRegex (HTMIMEParseSet * me,
123: const char * token,
124: BOOL caseSensitive,
125: HTParserCallback * callback)
126: {
127: return HTMIMEParseEl_new(&me->regexParsers, token,
128: caseSensitive, callback);
129: }
130:
2.2 eric 131: PUBLIC int HTMIMEParseSet_delete (HTMIMEParseSet * me, const char * token)
2.1 eric 132: {
133: int hash, i;
134: HTMIMEParseEl * pEl, ** last;
135:
136: hash = HTMIMEParseSet_hash(me, token);
137:
138: pEl = me->parsers[hash];
139: last = &me->parsers[hash];
140: for (i = 0; i < 2; i++) { /* do both */
141: for (; pEl; last = &pEl->next, pEl = pEl->next) {
142: if ((pEl->caseSensitive && !strcmp(pEl->token, token)) ||
143: (!pEl->caseSensitive && !strcasecomp(pEl->token, token))) {
144: return HTMIMEParseEl_delete(pEl, last);
145: }
146: }
147: pEl = me->regexParsers;
148: last = &me->regexParsers;
149: }
150: return HT_ERROR;
151: }
152:
153: /*
154: ** Search registered parsers to find suitable one for this token
155: ** If a parser isn't found, the function returns HT_OK
156: */
157: PUBLIC int HTMIMEParseSet_dispatch (HTMIMEParseSet * me, HTRequest * request,
2.6 frystyk 158: char * token, char * value, BOOL * pFound)
2.1 eric 159: {
2.2 eric 160: int hash;
2.6 frystyk 161: HTResponse * response = HTRequest_response(request);
2.1 eric 162: HTMIMEParseEl * pEl;
163:
164: if (pFound) *pFound = NO;
2.2 eric 165:
2.4 frystyk 166: /*
2.6 frystyk 167: ** Get a hash value for this token. This has is a function of the hash
168: ** size given when the MIME header parse set was created.
2.4 frystyk 169: */
2.1 eric 170: hash = HTMIMEParseSet_hash(me, token);
2.4 frystyk 171:
172: /*
2.6 frystyk 173: ** Search for an exact match
2.4 frystyk 174: */
2.2 eric 175: for (pEl = me->parsers[hash]; pEl; pEl = pEl->next) {
176: if ((pEl->caseSensitive && !strcmp(pEl->token, token)) ||
177: (!pEl->caseSensitive && !strcasecomp(pEl->token, token))) {
178: if (pFound) *pFound = YES;
179: if (!pEl->pFunk) return HT_OK; /* registered with no callback*/
2.6 frystyk 180: return (*pEl->pFunk)(request, response, token, value);
2.2 eric 181: }
182: }
2.1 eric 183:
2.6 frystyk 184: /*
185: ** Search for best match using regular expressions.
186: */
2.2 eric 187: for (pEl = me->regexParsers; pEl; pEl = pEl->next) {
2.3 eric 188: if ((pEl->caseSensitive && HTStrMatch(pEl->token, token)) ||
189: (!pEl->caseSensitive && HTStrCaseMatch(pEl->token, token))) {
2.2 eric 190: if (pFound) *pFound = YES;
191: if (!pEl->pFunk) return HT_OK; /* registered with no callback*/
2.6 frystyk 192: return (*pEl->pFunk)(request, response, token, value);
2.1 eric 193: }
194: }
2.2 eric 195:
2.1 eric 196: return HT_OK;
197: }
198:
Webmaster