1 //======================================================================== 2 // 3 // NameToCharCode.cc 4 // 5 // Copyright 2001-2003 Glyph & Cog, LLC 6 // 7 //======================================================================== 8 9 #include <aconf.h> 10 11 #ifdef USE_GCC_PRAGMAS 12 #pragma implementation 13 #endif 14 15 #include <string.h> 16 #include "gmem.h" 17 #include "NameToCharCode.h" 18 19 //------------------------------------------------------------------------ 20 21 struct NameToCharCodeEntry { 22 char *name; 23 CharCode c; 24 }; 25 26 //------------------------------------------------------------------------ 27 NameToCharCode()28NameToCharCode::NameToCharCode() { 29 int i; 30 31 size = 31; 32 len = 0; 33 tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); 34 for (i = 0; i < size; ++i) { 35 tab[i].name = NULL; 36 } 37 } 38 ~NameToCharCode()39NameToCharCode::~NameToCharCode() { 40 int i; 41 42 for (i = 0; i < size; ++i) { 43 if (tab[i].name) { 44 gfree(tab[i].name); 45 } 46 } 47 gfree(tab); 48 } 49 add(char * name,CharCode c)50void NameToCharCode::add(char *name, CharCode c) { 51 NameToCharCodeEntry *oldTab; 52 int h, i, oldSize; 53 54 // expand the table if necessary 55 if (len >= size / 2) { 56 oldSize = size; 57 oldTab = tab; 58 size = 2*size + 1; 59 tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); 60 for (h = 0; h < size; ++h) { 61 tab[h].name = NULL; 62 } 63 for (i = 0; i < oldSize; ++i) { 64 if (oldTab[i].name) { 65 h = hash(oldTab[i].name); 66 while (tab[h].name) { 67 if (++h == size) { 68 h = 0; 69 } 70 } 71 tab[h] = oldTab[i]; 72 } 73 } 74 gfree(oldTab); 75 } 76 77 // add the new name 78 h = hash(name); 79 while (tab[h].name && strcmp(tab[h].name, name)) { 80 if (++h == size) { 81 h = 0; 82 } 83 } 84 if (!tab[h].name) { 85 tab[h].name = copyString(name); 86 } 87 tab[h].c = c; 88 89 ++len; 90 } 91 lookup(char * name)92CharCode NameToCharCode::lookup(char *name) { 93 int h; 94 95 h = hash(name); 96 while (tab[h].name) { 97 if (!strcmp(tab[h].name, name)) { 98 return tab[h].c; 99 } 100 if (++h == size) { 101 h = 0; 102 } 103 } 104 return 0; 105 } 106 hash(char * name)107int NameToCharCode::hash(char *name) { 108 char *p; 109 unsigned int h; 110 111 h = 0; 112 for (p = name; *p; ++p) { 113 h = 17 * h + (int)(*p & 0xff); 114 } 115 return (int)(h % size); 116 } 117