Annotation of libwww/Library/src/HTAtom.c, revision 2.30

2.8       frystyk     1: /*                                                                    HTAtom.c
                      2: **     ATOMS: STRINSGS TO NUMBERS
                      3: **
2.14      frystyk     4: **     (c) COPYRIGHT MIT 1995.
2.8       frystyk     5: **     Please first read the full copyright statement in the file COPYRIGH.
2.30    ! frystyk     6: **     @(#) $Id: HTAtom.c,v 2.29 1999/02/07 18:20:31 frystyk Exp $
1.1       timbl       7: **
                      8: **     Atoms are names which are given representative pointer values
                      9: **     so that they can be stored more efficiently, and comparisons
                     10: **     for equality done more efficiently.
                     11: **
                     12: **     Atoms are kept in a hash table consisting of an array of linked lists.
                     13: **
                     14: ** Authors:
                     15: **     TBL     Tim Berners-Lee, WorldWideWeb project, CERN
                     16: **
                     17: */
2.10      roeber     18: 
2.11      frystyk    19: /* Library include files */
2.27      frystyk    20: #include "wwwsys.h"
2.11      frystyk    21: #include "HTUtils.h"
                     22: #include "HTString.h"
                     23: #include "HTList.h"
                     24: #include "HTAtom.h"
2.10      roeber     25: 
2.29      frystyk    26: PRIVATE HTAtom * hash_table[HT_XL_HASH_SIZE];
1.1       timbl      27: PRIVATE BOOL initialised = NO;
                     28: 
2.9       frystyk    29: /*
                     30: **     Finds an atom representation for a string. The atom doesn't have to be
                     31: **     a new one but can be an already existing atom.
                     32: */
2.21      frystyk    33: PUBLIC HTAtom * HTAtom_for (const char * string)
1.1       timbl      34: {
                     35:     int hash;
2.26      frystyk    36:     const unsigned char * p;
1.1       timbl      37:     HTAtom * a;
2.24      frystyk    38: 
                     39:     if (!string) return NULL;                  /* prevent core dumps */
1.1       timbl      40:     
                     41:     /*         First time around, clear hash table
                     42:     */
                     43:     if (!initialised) {
2.29      frystyk    44:         memset((void *) hash_table, '\0', sizeof(HTAtom *) * HT_XL_HASH_SIZE);
1.1       timbl      45:        initialised = YES;
                     46:     }
                     47:     
                     48:     /*         Generate hash function
                     49:     */
2.23      eric       50:     for (p=string, hash=0; *p; p++) {
2.29      frystyk    51:         hash = (hash * 3 + TOLOWER(*p)) % HT_XL_HASH_SIZE;
1.1       timbl      52:     }
                     53:     
                     54:     /*         Search for the string in the list
                     55:     */
                     56:     for (a=hash_table[hash]; a; a=a->next) {
                     57:        if (0==strcmp(a->name, string)) {
2.30    ! frystyk    58:            /* if (UTIL_TRACE) HTTrace(
1.2       timbl      59:                "HTAtom: Old atom %p for `%s'\n", a, string); */
1.1       timbl      60:            return a;                           /* Found: return it */
                     61:        }
                     62:     }
                     63:     
                     64:     /*         Generate a new entry
                     65:     */
2.19      frystyk    66:     if ((a = (HTAtom  *) HT_MALLOC(sizeof(*a))) == NULL)
                     67:         HT_OUTOFMEM("HTAtom_for");
                     68:     if ((a->name = (char  *) HT_MALLOC(strlen(string)+1)) == NULL)
                     69:         HT_OUTOFMEM("HTAtom_for");
1.1       timbl      70:     strcpy(a->name, string);
                     71:     a->next = hash_table[hash];                /* Put onto the head of list */
                     72:     hash_table[hash] = a;
2.30    ! frystyk    73: /*    if (UTIL_TRACE) HTTrace("HTAtom: New atom %p for `%s'\n", a, string); */
1.1       timbl      74:     return a;
2.9       frystyk    75: }
                     76: 
                     77: 
                     78: /*
2.12      frystyk    79: **     CASE INSENSITIVE VERSION OF HTAtom_for()
                     80: **     Finds an atom representation for a string. The atom doesn't have to be
                     81: **     a new one but can be an already existing atom.
                     82: */
2.21      frystyk    83: PUBLIC HTAtom * HTAtom_caseFor (const char * string)
2.12      frystyk    84: {
                     85:     int hash;
2.26      frystyk    86:     const unsigned char * p;
2.12      frystyk    87:     HTAtom * a;
2.24      frystyk    88: 
                     89:     if (!string) return NULL;                  /* prevent core dumps */
2.12      frystyk    90:     
                     91:     /*         First time around, clear hash table
                     92:     */
                     93:     if (!initialised) {
2.29      frystyk    94:         memset((void *) hash_table, '\0', sizeof(HTAtom *) * HT_XL_HASH_SIZE);
2.12      frystyk    95:        initialised = YES;
                     96:     }
                     97:     
                     98:     /*         Generate hash function
                     99:     */
                    100:     for(p=string, hash=0; *p; p++) {
2.29      frystyk   101:         hash = (hash * 3 + TOLOWER(*p)) % HT_XL_HASH_SIZE;
2.12      frystyk   102:     }
                    103:     
                    104:     /*         Search for the string in the list
                    105:     */
                    106:     for (a=hash_table[hash]; a; a=a->next) {
                    107:        if (!strcasecomp(a->name, string)) {
                    108:            return a;                                   /* Found: return it */
                    109:        }
                    110:     }
                    111:     
                    112:     /*         Generate a new entry
                    113:     */
2.19      frystyk   114:     if ((a = (HTAtom  *) HT_MALLOC(sizeof(*a))) == NULL)
                    115:         HT_OUTOFMEM("HTAtom_for");
                    116:     if ((a->name = (char  *) HT_MALLOC(strlen(string)+1)) == NULL)
                    117:         HT_OUTOFMEM("HTAtom_for");
2.12      frystyk   118:     strcpy(a->name, string);
                    119:     a->next = hash_table[hash];                /* Put onto the head of list */
                    120:     hash_table[hash] = a;
                    121:     return a;
                    122: }
                    123: 
                    124: 
                    125: /*
2.9       frystyk   126: **     This function cleans up the memory used by atoms.
                    127: **     Written by Eric Sink, eric@spyglass.com
                    128: */
2.18      frystyk   129: PUBLIC void HTAtom_deleteAll (void)
2.9       frystyk   130: {
                    131:     int i;
                    132:     HTAtom *cur;
                    133:     HTAtom *next;
                    134:     
2.29      frystyk   135:     for (i=0; i<HT_XL_HASH_SIZE; i++) {
2.9       frystyk   136:        if (hash_table[i]) {
                    137:            cur = hash_table[i];
                    138:            while (cur) {
                    139:                next = cur->next;
2.19      frystyk   140:                HT_FREE(cur->name);
                    141:                HT_FREE(cur);
2.9       frystyk   142:                cur = next;     
                    143:            }   
                    144:        }
                    145:     }
2.12      frystyk   146:     initialised = NO;
1.1       timbl     147: }
                    148: 
2.6       luotonen  149: 
2.21      frystyk   150: PRIVATE BOOL mime_match (const char * name, const char * templ)
2.6       luotonen  151: {
                    152:     if (name && templ) {
                    153:        static char *n1 = NULL;
                    154:        static char *t1 = NULL;
                    155:        char *n2;
                    156:        char *t2;
                    157: 
2.21      frystyk   158:        StrAllocCopy(n1, name);         /* These also HT_FREE the ones  */
2.6       luotonen  159:        StrAllocCopy(t1, templ);        /* from previous call.          */
                    160: 
                    161:        if (!(n2 = strchr(n1, '/'))  ||  !(t2 = strchr(t1, '/')))
                    162:            return NO;
                    163: 
                    164:        *(n2++) = (char)0;
                    165:        *(t2++) = (char)0;
                    166: 
                    167:        if ((0==strcmp(t1, "*") || 0==strcmp(t1, n1)) &&
                    168:            (0==strcmp(t2, "*") || 0==strcmp(t2, n2)))
                    169:            return YES;
                    170:     }
                    171:     return NO;
                    172: }
                    173:        
                    174: 
2.21      frystyk   175: PUBLIC HTList *HTAtom_templateMatches (const char * templ)
2.6       luotonen  176: {
                    177:     HTList *matches = HTList_new();
                    178: 
                    179:     if (initialised && templ) {
                    180:        int i;
                    181:        HTAtom *cur;
                    182: 
2.29      frystyk   183:        for (i=0; i<HT_XL_HASH_SIZE; i++) {
2.6       luotonen  184:            for (cur = hash_table[i];  cur;  cur=cur->next) {
                    185:                if (mime_match(cur->name, templ))
                    186:                    HTList_addObject(matches, (void*)cur);
                    187:            }
                    188:        }
                    189:     }
                    190:     return matches;
                    191: }
1.1       timbl     192: 

Webmaster