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