/src/xpdf-4.04/xpdf/NameToCharCode.cc
Line | Count | Source (jump to first uncovered line) |
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 "gmempp.h" |
18 | | #include "NameToCharCode.h" |
19 | | |
20 | | //------------------------------------------------------------------------ |
21 | | |
22 | | struct NameToCharCodeEntry { |
23 | | char *name; |
24 | | CharCode c; |
25 | | }; |
26 | | |
27 | | //------------------------------------------------------------------------ |
28 | | |
29 | 4.75k | NameToCharCode::NameToCharCode() { |
30 | 4.75k | int i; |
31 | | |
32 | 4.75k | size = 31; |
33 | 4.75k | len = 0; |
34 | 4.75k | tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); |
35 | 152k | for (i = 0; i < size; ++i) { |
36 | 147k | tab[i].name = NULL; |
37 | 147k | } |
38 | 4.75k | } |
39 | | |
40 | 4.75k | NameToCharCode::~NameToCharCode() { |
41 | 4.75k | int i; |
42 | | |
43 | 40.1M | for (i = 0; i < size; ++i) { |
44 | 40.1M | if (tab[i].name) { |
45 | 10.6M | gfree(tab[i].name); |
46 | 10.6M | } |
47 | 40.1M | } |
48 | 4.75k | gfree(tab); |
49 | 4.75k | } |
50 | | |
51 | 10.6M | void NameToCharCode::add(const char *name, CharCode c) { |
52 | 10.6M | NameToCharCodeEntry *oldTab; |
53 | 10.6M | int h, i, oldSize; |
54 | | |
55 | | // expand the table if necessary |
56 | 10.6M | if (len >= size / 2) { |
57 | 30.8k | oldSize = size; |
58 | 30.8k | oldTab = tab; |
59 | 30.8k | size = 2*size + 1; |
60 | 30.8k | tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); |
61 | 79.9M | for (h = 0; h < size; ++h) { |
62 | 79.9M | tab[h].name = NULL; |
63 | 79.9M | } |
64 | 39.9M | for (i = 0; i < oldSize; ++i) { |
65 | 39.9M | if (oldTab[i].name) { |
66 | 19.9M | h = hash(oldTab[i].name); |
67 | 29.1M | while (tab[h].name) { |
68 | 9.20M | if (++h == size) { |
69 | 0 | h = 0; |
70 | 0 | } |
71 | 9.20M | } |
72 | 19.9M | tab[h] = oldTab[i]; |
73 | 19.9M | } |
74 | 39.9M | } |
75 | 30.8k | gfree(oldTab); |
76 | 30.8k | } |
77 | | |
78 | | // add the new name |
79 | 10.6M | h = hash(name); |
80 | 44.0M | while (tab[h].name && strcmp(tab[h].name, name)) { |
81 | 33.4M | if (++h == size) { |
82 | 7.12k | h = 0; |
83 | 7.12k | } |
84 | 33.4M | } |
85 | 10.6M | if (!tab[h].name) { |
86 | 10.6M | tab[h].name = copyString(name); |
87 | 10.6M | } |
88 | 10.6M | tab[h].c = c; |
89 | | |
90 | 10.6M | ++len; |
91 | 10.6M | } |
92 | | |
93 | 0 | CharCode NameToCharCode::lookup(const char *name) { |
94 | 0 | int h; |
95 | |
|
96 | 0 | h = hash(name); |
97 | 0 | while (tab[h].name) { |
98 | 0 | if (!strcmp(tab[h].name, name)) { |
99 | 0 | return tab[h].c; |
100 | 0 | } |
101 | 0 | if (++h == size) { |
102 | 0 | h = 0; |
103 | 0 | } |
104 | 0 | } |
105 | 0 | return 0; |
106 | 0 | } |
107 | | |
108 | 30.5M | int NameToCharCode::hash(const char *name) { |
109 | 30.5M | const char *p; |
110 | 30.5M | unsigned int h; |
111 | | |
112 | 30.5M | h = 0; |
113 | 359M | for (p = name; *p; ++p) { |
114 | 328M | h = 17 * h + (int)(*p & 0xff); |
115 | 328M | } |
116 | 30.5M | return (int)(h % size); |
117 | 30.5M | } |