/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 | 22.6k | NameToCharCode::NameToCharCode() { |
26 | 22.6k | int i; |
27 | | |
28 | 22.6k | size = 31; |
29 | 22.6k | len = 0; |
30 | 22.6k | tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); |
31 | 726k | for (i = 0; i < size; ++i) { |
32 | 703k | tab[i].name = NULL; |
33 | 703k | } |
34 | 22.6k | } |
35 | | |
36 | 22.6k | NameToCharCode::~NameToCharCode() { |
37 | 22.6k | int i; |
38 | | |
39 | 191M | for (i = 0; i < size; ++i) { |
40 | 191M | if (tab[i].name) { |
41 | 50.6M | gfree(tab[i].name); |
42 | 50.6M | } |
43 | 191M | } |
44 | 22.6k | gfree(tab); |
45 | 22.6k | } |
46 | | |
47 | 50.6M | void NameToCharCode::add(const char *name, CharCode c) { |
48 | 50.6M | NameToCharCodeEntry *oldTab; |
49 | 50.6M | int h, i, oldSize; |
50 | | |
51 | | // expand the table if necessary |
52 | 50.6M | if (len >= size / 2) { |
53 | 147k | oldSize = size; |
54 | 147k | oldTab = tab; |
55 | 147k | size = 2*size + 1; |
56 | 147k | tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); |
57 | 382M | for (h = 0; h < size; ++h) { |
58 | 381M | tab[h].name = NULL; |
59 | 381M | } |
60 | 191M | for (i = 0; i < oldSize; ++i) { |
61 | 190M | if (oldTab[i].name) { |
62 | 95.3M | h = hash(oldTab[i].name); |
63 | 139M | while (tab[h].name) { |
64 | 43.9M | if (++h == size) { |
65 | 0 | h = 0; |
66 | 0 | } |
67 | 43.9M | } |
68 | 95.3M | tab[h] = oldTab[i]; |
69 | 95.3M | } |
70 | 190M | } |
71 | 147k | gfree(oldTab); |
72 | 147k | } |
73 | | |
74 | | // add the new name |
75 | 50.6M | h = hash(name); |
76 | 210M | while (tab[h].name && strcmp(tab[h].name, name)) { |
77 | 159M | if (++h == size) { |
78 | 34.0k | h = 0; |
79 | 34.0k | } |
80 | 159M | } |
81 | 50.6M | if (!tab[h].name) { |
82 | 50.6M | tab[h].name = copyString(name); |
83 | 50.6M | } |
84 | 50.6M | tab[h].c = c; |
85 | | |
86 | 50.6M | ++len; |
87 | 50.6M | } |
88 | | |
89 | 0 | CharCode NameToCharCode::lookup(const char *name) { |
90 | 0 | int h; |
91 | |
|
92 | 0 | h = hash(name); |
93 | 0 | while (tab[h].name) { |
94 | 0 | if (!strcmp(tab[h].name, name)) { |
95 | 0 | return tab[h].c; |
96 | 0 | } |
97 | 0 | if (++h == size) { |
98 | 0 | h = 0; |
99 | 0 | } |
100 | 0 | } |
101 | 0 | return 0; |
102 | 0 | } |
103 | | |
104 | 146M | int NameToCharCode::hash(const char *name) { |
105 | 146M | const char *p; |
106 | 146M | unsigned int h; |
107 | | |
108 | 146M | h = 0; |
109 | 1.71G | for (p = name; *p; ++p) { |
110 | 1.57G | h = 17 * h + (int)(*p & 0xff); |
111 | 1.57G | } |
112 | 146M | return (int)(h % size); |
113 | 146M | } |