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