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