HTAtom.c
上传用户:zlh9724
上传日期:2007-01-04
资源大小:1991k
文件大小:4k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /*        HTAtom.c
  2. ** ATOMS: STRINSGS TO NUMBERS
  3. **
  4. ** (c) COPYRIGHT MIT 1995.
  5. ** Please first read the full copyright statement in the file COPYRIGH.
  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. */
  17. /* Library include files */
  18. #include "tcp.h"
  19. #include "HTUtils.h"
  20. #include "HTString.h"
  21. #include "HTList.h"
  22. #include "HTAtom.h"
  23. #define HASH_SIZE 101 /* Tunable */
  24. PRIVATE HTAtom * hash_table[HASH_SIZE];
  25. PRIVATE BOOL initialised = NO;
  26. /*
  27. ** Finds an atom representation for a string. The atom doesn't have to be
  28. ** a new one but can be an already existing atom.
  29. */
  30. PUBLIC HTAtom * HTAtom_for (CONST char * string)
  31. {
  32.     int hash;
  33.     CONST char * p;
  34.     HTAtom * a;
  35.     
  36.     /* First time around, clear hash table
  37.     */
  38.     if (!initialised) {
  39.         memset((void *) hash_table, '', sizeof(HTAtom *) * HASH_SIZE);
  40. initialised = YES;
  41.     }
  42.     
  43.     /* Generate hash function
  44.     */
  45.     for(p=string, hash=0; *p; p++) {
  46.         hash = (hash * 3 +(*(unsigned char *) p)) % HASH_SIZE;
  47.     }
  48.     
  49.     /* Search for the string in the list
  50.     */
  51.     for (a=hash_table[hash]; a; a=a->next) {
  52. if (0==strcmp(a->name, string)) {
  53.          /* if (WWWTRACE) TTYPrint(TDEST,
  54.      "HTAtom: Old atom %p for `%s'n", a, string); */
  55.     return a; /* Found: return it */
  56. }
  57.     }
  58.     
  59.     /* Generate a new entry
  60.     */
  61.     if ((a = (HTAtom  *) HT_MALLOC(sizeof(*a))) == NULL)
  62.         HT_OUTOFMEM("HTAtom_for");
  63.     if ((a->name = (char  *) HT_MALLOC(strlen(string)+1)) == NULL)
  64.         HT_OUTOFMEM("HTAtom_for");
  65.     strcpy(a->name, string);
  66.     a->next = hash_table[hash]; /* Put onto the head of list */
  67.     hash_table[hash] = a;
  68. /*    if (WWWTRACE) TTYPrint(TDEST, "HTAtom: New atom %p for `%s'n", a, string); */
  69.     return a;
  70. }
  71. /*
  72. ** CASE INSENSITIVE VERSION OF HTAtom_for()
  73. ** Finds an atom representation for a string. The atom doesn't have to be
  74. ** a new one but can be an already existing atom.
  75. */
  76. PUBLIC HTAtom * HTAtom_caseFor (CONST char * string)
  77. {
  78.     int hash;
  79.     CONST char * p;
  80.     HTAtom * a;
  81.     
  82.     /* First time around, clear hash table
  83.     */
  84.     if (!initialised) {
  85.         memset((void *) hash_table, '', sizeof(HTAtom *) * HASH_SIZE);
  86. initialised = YES;
  87.     }
  88.     
  89.     /* Generate hash function
  90.     */
  91.     for(p=string, hash=0; *p; p++) {
  92.         hash = (hash * 3 + *p) % HASH_SIZE;
  93.     }
  94.     
  95.     /* Search for the string in the list
  96.     */
  97.     for (a=hash_table[hash]; a; a=a->next) {
  98. if (!strcasecomp(a->name, string)) {
  99.     return a; /* Found: return it */
  100. }
  101.     }
  102.     
  103.     /* Generate a new entry
  104.     */
  105.     if ((a = (HTAtom  *) HT_MALLOC(sizeof(*a))) == NULL)
  106.         HT_OUTOFMEM("HTAtom_for");
  107.     if ((a->name = (char  *) HT_MALLOC(strlen(string)+1)) == NULL)
  108.         HT_OUTOFMEM("HTAtom_for");
  109.     strcpy(a->name, string);
  110.     a->next = hash_table[hash]; /* Put onto the head of list */
  111.     hash_table[hash] = a;
  112.     return a;
  113. }
  114. /*
  115. ** This function cleans up the memory used by atoms.
  116. ** Written by Eric Sink, eric@spyglass.com
  117. */
  118. PUBLIC void HTAtom_deleteAll (void)
  119. {
  120.     int i;
  121.     HTAtom *cur;
  122.     HTAtom *next;
  123.     
  124.     for (i=0; i<HASH_SIZE; i++) {
  125. if (hash_table[i]) {
  126.     cur = hash_table[i];
  127.     while (cur) {
  128. next = cur->next;
  129. HT_FREE(cur->name);
  130. HT_FREE(cur);
  131. cur = next;
  132.     }
  133. }
  134.     }
  135.     initialised = NO;
  136. }
  137. PRIVATE BOOL mime_match (CONST char * name, CONST char * templ)
  138. {
  139.     if (name && templ) {
  140. static char *n1 = NULL;
  141. static char *t1 = NULL;
  142. char *n2;
  143. char *t2;
  144. StrAllocCopy(n1, name); /* These also free the ones */
  145. StrAllocCopy(t1, templ); /* from previous call. */
  146. if (!(n2 = strchr(n1, '/'))  ||  !(t2 = strchr(t1, '/')))
  147.     return NO;
  148. *(n2++) = (char)0;
  149. *(t2++) = (char)0;
  150. if ((0==strcmp(t1, "*") || 0==strcmp(t1, n1)) &&
  151.     (0==strcmp(t2, "*") || 0==strcmp(t2, n2)))
  152.     return YES;
  153.     }
  154.     return NO;
  155. }
  156. PUBLIC HTList *HTAtom_templateMatches (CONST char * templ)
  157. {
  158.     HTList *matches = HTList_new();
  159.     if (initialised && templ) {
  160. int i;
  161. HTAtom *cur;
  162. for (i=0; i<HASH_SIZE; i++) {
  163.     for (cur = hash_table[i];  cur;  cur=cur->next) {
  164. if (mime_match(cur->name, templ))
  165.     HTList_addObject(matches, (void*)cur);
  166.     }
  167. }
  168.     }
  169.     return matches;
  170. }