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