]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | //======================================================================== |
2 | // | |
3 | // NameToCharCode.cc | |
4 | // | |
5 | // Copyright 2001-2003 Glyph & Cog, LLC | |
6 | // | |
7 | //======================================================================== | |
8 | ||
9 | #include <config.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 | ||
28 | NameToCharCode::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 | ||
39 | NameToCharCode::~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 | ||
50 | void 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 | ||
92 | CharCode 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 | ||
107 | int 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 | } |