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