/src/xpdf-4.05/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 | | #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 | 5.60k | NameToCharCode::NameToCharCode() { |
26 | 5.60k | int i; |
27 | | |
28 | 5.60k | size = 31; |
29 | 5.60k | len = 0; |
30 | 5.60k | tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); |
31 | 179k | for (i = 0; i < size; ++i) { |
32 | 173k | tab[i].name = NULL; |
33 | 173k | } |
34 | 5.60k | } |
35 | | |
36 | 5.60k | NameToCharCode::~NameToCharCode() { |
37 | 5.60k | int i; |
38 | | |
39 | 47.3M | for (i = 0; i < size; ++i) { |
40 | 47.3M | if (tab[i].name) { |
41 | 12.5M | gfree(tab[i].name); |
42 | 12.5M | } |
43 | 47.3M | } |
44 | 5.60k | gfree(tab); |
45 | 5.60k | } |
46 | | |
47 | 12.5M | void NameToCharCode::add(const char *name, CharCode c) { |
48 | 12.5M | NameToCharCodeEntry *oldTab; |
49 | 12.5M | int h, i, oldSize; |
50 | | |
51 | | // expand the table if necessary |
52 | 12.5M | if (len >= size / 2) { |
53 | 36.4k | oldSize = size; |
54 | 36.4k | oldTab = tab; |
55 | 36.4k | size = 2*size + 1; |
56 | 36.4k | tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); |
57 | 94.3M | for (h = 0; h < size; ++h) { |
58 | 94.2M | tab[h].name = NULL; |
59 | 94.2M | } |
60 | 47.1M | for (i = 0; i < oldSize; ++i) { |
61 | 47.1M | if (oldTab[i].name) { |
62 | 23.5M | h = hash(oldTab[i].name); |
63 | 34.4M | while (tab[h].name) { |
64 | 10.8M | if (++h == size) { |
65 | 0 | h = 0; |
66 | 0 | } |
67 | 10.8M | } |
68 | 23.5M | tab[h] = oldTab[i]; |
69 | 23.5M | } |
70 | 47.1M | } |
71 | 36.4k | gfree(oldTab); |
72 | 36.4k | } |
73 | | |
74 | | // add the new name |
75 | 12.5M | h = hash(name); |
76 | 52.0M | while (tab[h].name && strcmp(tab[h].name, name)) { |
77 | 39.4M | if (++h == size) { |
78 | 8.40k | h = 0; |
79 | 8.40k | } |
80 | 39.4M | } |
81 | 12.5M | if (!tab[h].name) { |
82 | 12.5M | tab[h].name = copyString(name); |
83 | 12.5M | } |
84 | 12.5M | tab[h].c = c; |
85 | | |
86 | 12.5M | ++len; |
87 | 12.5M | } |
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 | 36.0M | int NameToCharCode::hash(const char *name) { |
105 | 36.0M | const char *p; |
106 | 36.0M | unsigned int h; |
107 | | |
108 | 36.0M | h = 0; |
109 | 423M | for (p = name; *p; ++p) { |
110 | 387M | h = 17 * h + (int)(*p & 0xff); |
111 | 387M | } |
112 | 36.0M | return (int)(h % size); |
113 | 36.0M | } |