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

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.24    ! frystyk     6: **     @(#) $Id: HTAtom.c,v 2.23 1996/06/03 19:25:06 eric 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.21      frystyk    20: #include "sysdep.h"
2.11      frystyk    21: #include "HTUtils.h"
                     22: #include "HTString.h"
                     23: #include "HTList.h"
                     24: #include "HTAtom.h"
2.10      roeber     25: 
1.1       timbl      26: #define HASH_SIZE      101             /* Tunable */
                     27: 
                     28: PRIVATE HTAtom * hash_table[HASH_SIZE];
                     29: PRIVATE BOOL initialised = NO;
                     30: 
2.9       frystyk    31: /*
                     32: **     Finds an atom representation for a string. The atom doesn't have to be
                     33: **     a new one but can be an already existing atom.
                     34: */
2.21      frystyk    35: PUBLIC HTAtom * HTAtom_for (const char * string)
1.1       timbl      36: {
                     37:     int hash;
2.21      frystyk    38:     const char * p;
1.1       timbl      39:     HTAtom * a;
2.24    ! frystyk    40: 
        !            41:     if (!string) return NULL;                  /* prevent core dumps */
1.1       timbl      42:     
                     43:     /*         First time around, clear hash table
                     44:     */
                     45:     if (!initialised) {
2.15      frystyk    46:         memset((void *) hash_table, '\0', sizeof(HTAtom *) * HASH_SIZE);
1.1       timbl      47:        initialised = YES;
                     48:     }
                     49:     
                     50:     /*         Generate hash function
                     51:     */
2.23      eric       52:     for (p=string, hash=0; *p; p++) {
2.13      frystyk    53:         hash = (hash * 3 +(*(unsigned char *) p)) % HASH_SIZE;
1.1       timbl      54:     }
                     55:     
                     56:     /*         Search for the string in the list
                     57:     */
                     58:     for (a=hash_table[hash]; a; a=a->next) {
                     59:        if (0==strcmp(a->name, string)) {
2.20      eric       60:            /* if (WWWTRACE) HTTrace(
1.2       timbl      61:                "HTAtom: Old atom %p for `%s'\n", a, string); */
1.1       timbl      62:            return a;                           /* Found: return it */
                     63:        }
                     64:     }
                     65:     
                     66:     /*         Generate a new entry
                     67:     */
2.19      frystyk    68:     if ((a = (HTAtom  *) HT_MALLOC(sizeof(*a))) == NULL)
                     69:         HT_OUTOFMEM("HTAtom_for");
                     70:     if ((a->name = (char  *) HT_MALLOC(strlen(string)+1)) == NULL)
                     71:         HT_OUTOFMEM("HTAtom_for");
1.1       timbl      72:     strcpy(a->name, string);
                     73:     a->next = hash_table[hash];                /* Put onto the head of list */
                     74:     hash_table[hash] = a;
2.20      eric       75: /*    if (WWWTRACE) HTTrace("HTAtom: New atom %p for `%s'\n", a, string); */
1.1       timbl      76:     return a;
2.9       frystyk    77: }
                     78: 
                     79: 
                     80: /*
2.12      frystyk    81: **     CASE INSENSITIVE VERSION OF HTAtom_for()
                     82: **     Finds an atom representation for a string. The atom doesn't have to be
                     83: **     a new one but can be an already existing atom.
                     84: */
2.21      frystyk    85: PUBLIC HTAtom * HTAtom_caseFor (const char * string)
2.12      frystyk    86: {
                     87:     int hash;
2.21      frystyk    88:     const char * p;
2.12      frystyk    89:     HTAtom * a;
2.24    ! frystyk    90: 
        !            91:     if (!string) return NULL;                  /* prevent core dumps */
2.12      frystyk    92:     
                     93:     /*         First time around, clear hash table
                     94:     */
                     95:     if (!initialised) {
2.15      frystyk    96:         memset((void *) hash_table, '\0', sizeof(HTAtom *) * HASH_SIZE);
2.12      frystyk    97:        initialised = YES;
                     98:     }
                     99:     
                    100:     /*         Generate hash function
                    101:     */
                    102:     for(p=string, hash=0; *p; p++) {
                    103:         hash = (hash * 3 + *p) % HASH_SIZE;
                    104:     }
                    105:     
                    106:     /*         Search for the string in the list
                    107:     */
                    108:     for (a=hash_table[hash]; a; a=a->next) {
                    109:        if (!strcasecomp(a->name, string)) {
                    110:            return a;                                   /* Found: return it */
                    111:        }
                    112:     }
                    113:     
                    114:     /*         Generate a new entry
                    115:     */
2.19      frystyk   116:     if ((a = (HTAtom  *) HT_MALLOC(sizeof(*a))) == NULL)
                    117:         HT_OUTOFMEM("HTAtom_for");
                    118:     if ((a->name = (char  *) HT_MALLOC(strlen(string)+1)) == NULL)
                    119:         HT_OUTOFMEM("HTAtom_for");
2.12      frystyk   120:     strcpy(a->name, string);
                    121:     a->next = hash_table[hash];                /* Put onto the head of list */
                    122:     hash_table[hash] = a;
                    123:     return a;
                    124: }
                    125: 
                    126: 
                    127: /*
2.9       frystyk   128: **     This function cleans up the memory used by atoms.
                    129: **     Written by Eric Sink, eric@spyglass.com
                    130: */
2.18      frystyk   131: PUBLIC void HTAtom_deleteAll (void)
2.9       frystyk   132: {
                    133:     int i;
                    134:     HTAtom *cur;
                    135:     HTAtom *next;
                    136:     
                    137:     for (i=0; i<HASH_SIZE; i++) {
                    138:        if (hash_table[i]) {
                    139:            cur = hash_table[i];
                    140:            while (cur) {
                    141:                next = cur->next;
2.19      frystyk   142:                HT_FREE(cur->name);
                    143:                HT_FREE(cur);
2.9       frystyk   144:                cur = next;     
                    145:            }   
                    146:        }
                    147:     }
2.12      frystyk   148:     initialised = NO;
1.1       timbl     149: }
                    150: 
2.6       luotonen  151: 
2.21      frystyk   152: PRIVATE BOOL mime_match (const char * name, const char * templ)
2.6       luotonen  153: {
                    154:     if (name && templ) {
                    155:        static char *n1 = NULL;
                    156:        static char *t1 = NULL;
                    157:        char *n2;
                    158:        char *t2;
                    159: 
2.21      frystyk   160:        StrAllocCopy(n1, name);         /* These also HT_FREE the ones  */
2.6       luotonen  161:        StrAllocCopy(t1, templ);        /* from previous call.          */
                    162: 
                    163:        if (!(n2 = strchr(n1, '/'))  ||  !(t2 = strchr(t1, '/')))
                    164:            return NO;
                    165: 
                    166:        *(n2++) = (char)0;
                    167:        *(t2++) = (char)0;
                    168: 
                    169:        if ((0==strcmp(t1, "*") || 0==strcmp(t1, n1)) &&
                    170:            (0==strcmp(t2, "*") || 0==strcmp(t2, n2)))
                    171:            return YES;
                    172:     }
                    173:     return NO;
                    174: }
                    175:        
                    176: 
2.21      frystyk   177: PUBLIC HTList *HTAtom_templateMatches (const char * templ)
2.6       luotonen  178: {
                    179:     HTList *matches = HTList_new();
                    180: 
                    181:     if (initialised && templ) {
                    182:        int i;
                    183:        HTAtom *cur;
                    184: 
                    185:        for (i=0; i<HASH_SIZE; i++) {
                    186:            for (cur = hash_table[i];  cur;  cur=cur->next) {
                    187:                if (mime_match(cur->name, templ))
                    188:                    HTList_addObject(matches, (void*)cur);
                    189:            }
                    190:        }
                    191:     }
                    192:     return matches;
                    193: }
1.1       timbl     194: 

Webmaster