Annotation of libwww/Library/src/HTMIMPrs.c, revision 2.1
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.
! 6: ** @(#) $Id: Date Author State $
! 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");
! 43: strcpy(ret->token, token);
! 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:
! 81: PUBLIC int HTMIMEParseSet_delete (HTMIMEParseSet * me)
! 82: {
! 83: HTMIMEParseSet_empty(me);
! 84: HT_FREE(me);
! 85: return HT_OK;
! 86: }
! 87:
! 88: PUBLIC HTMIMEParseEl * HTMIMEParseSet_add (HTMIMEParseSet * me,
! 89: const char * token,
! 90: BOOL caseSensitive,
! 91: HTParserCallback * callback)
! 92: {
! 93: int hash;
! 94:
! 95: /* Insure hash list
! 96: */
! 97: if (!me->parsers) {
! 98: if (!me->size)
! 99: me->size = DEFAULT_HASH_SIZE;
! 100: if ((me->parsers = (HTMIMEParseEl **) HT_CALLOC(me->size, sizeof(HTMIMEParseEl *))) == NULL)
! 101: HT_OUTOFMEM("HTMIME parsers");
! 102: }
! 103: hash = HTMIMEParseSet_hash(me, token);
! 104:
! 105: /* Add a new entry
! 106: */
! 107: return HTMIMEParseEl_new(&me->parsers[hash], token,
! 108: caseSensitive, callback);
! 109: }
! 110:
! 111:
! 112: PUBLIC HTMIMEParseEl * HTMIMEParseSet_addRegex (HTMIMEParseSet * me,
! 113: const char * token,
! 114: BOOL caseSensitive,
! 115: HTParserCallback * callback)
! 116: {
! 117: return HTMIMEParseEl_new(&me->regexParsers, token,
! 118: caseSensitive, callback);
! 119: }
! 120:
! 121: PUBLIC int HTMIMEParseSet_deleteToken (HTMIMEParseSet * me, const char * token)
! 122: {
! 123: int hash, i;
! 124: HTMIMEParseEl * pEl, ** last;
! 125:
! 126: hash = HTMIMEParseSet_hash(me, token);
! 127:
! 128: pEl = me->parsers[hash];
! 129: last = &me->parsers[hash];
! 130: for (i = 0; i < 2; i++) { /* do both */
! 131: for (; pEl; last = &pEl->next, pEl = pEl->next) {
! 132: if ((pEl->caseSensitive && !strcmp(pEl->token, token)) ||
! 133: (!pEl->caseSensitive && !strcasecomp(pEl->token, token))) {
! 134: return HTMIMEParseEl_delete(pEl, last);
! 135: }
! 136: }
! 137: pEl = me->regexParsers;
! 138: last = &me->regexParsers;
! 139: }
! 140: return HT_ERROR;
! 141: }
! 142:
! 143: PUBLIC int HTMIMEParseSet_empty (HTMIMEParseSet * me)
! 144: {
! 145: int i;
! 146: HTMIMEParseEl * pEl, * next;
! 147:
! 148: for (i=0; i<me->size; i++)
! 149: for (pEl = me->parsers[i]; pEl; pEl = next) {
! 150: next = pEl->next;
! 151: HT_FREE(pEl);
! 152: }
! 153:
! 154: for (pEl = me->parsers[i]; pEl; pEl = next) {
! 155: next = pEl->next;
! 156: HT_FREE(pEl);
! 157: }
! 158: return HT_OK;
! 159: }
! 160:
! 161: /*
! 162: ** Search registered parsers to find suitable one for this token
! 163: ** If a parser isn't found, the function returns HT_OK
! 164: */
! 165: PUBLIC int HTMIMEParseSet_dispatch (HTMIMEParseSet * me, HTRequest * request,
! 166: char * token, char * value, BOOL * pFound)
! 167: {
! 168: int hash, i;
! 169: HTMIMEParseEl * pEl;
! 170:
! 171: if (pFound) *pFound = NO;
! 172: hash = HTMIMEParseSet_hash(me, token);
! 173:
! 174: for (i = 0, pEl = me->parsers[hash]; i < 2; i++, pEl = me->regexParsers) {
! 175: for (; 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*/
! 180: return (*pEl->pFunk)(request, token, value);
! 181: }
! 182: }
! 183: }
! 184: return HT_OK;
! 185: }
! 186:
Webmaster