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