Annotation of libwww/Library/src/HTAtom.c, revision 2.17
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.15 frystyk 43: memset((void *) 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.17 ! frystyk 57: /* if (WWWTRACE) TTYPrint(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.17 ! frystyk 72: /* if (WWWTRACE) TTYPrint(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) {
2.15 frystyk 91: memset((void *) hash_table, '\0', sizeof(HTAtom *) * HASH_SIZE);
2.12 frystyk 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