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

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

Webmaster