1 | //======================================================================== |
---|---|
2 | // |
3 | // NameToCharCode.cc |
4 | // |
5 | // Copyright 2001-2003 Glyph & Cog, LLC |
6 | // |
7 | //======================================================================== |
8 | |
9 | //======================================================================== |
10 | // |
11 | // Modified under the Poppler project - http://poppler.freedesktop.org |
12 | // |
13 | // All changes made under the Poppler project to this file are licensed |
14 | // under GPL version 2 or later |
15 | // |
16 | // Copyright (C) 2019 Albert Astals Cid <aacid@kde.org> |
17 | // |
18 | // To see a description of the changes please see the Changelog file that |
19 | // came with your tarball or type make ChangeLog if you are building from git |
20 | // |
21 | //======================================================================== |
22 | |
23 | #include <config.h> |
24 | |
25 | #include <cstring> |
26 | #include "goo/gmem.h" |
27 | #include "NameToCharCode.h" |
28 | |
29 | //------------------------------------------------------------------------ |
30 | |
31 | struct NameToCharCodeEntry |
32 | { |
33 | char *name; |
34 | CharCode c; |
35 | }; |
36 | |
37 | //------------------------------------------------------------------------ |
38 | |
39 | NameToCharCode::NameToCharCode() |
40 | { |
41 | int i; |
42 | |
43 | size = 31; |
44 | len = 0; |
45 | tab = (NameToCharCodeEntry *)gmallocn(count: size, size: sizeof(NameToCharCodeEntry)); |
46 | for (i = 0; i < size; ++i) { |
47 | tab[i].name = nullptr; |
48 | } |
49 | } |
50 | |
51 | NameToCharCode::~NameToCharCode() |
52 | { |
53 | int i; |
54 | |
55 | for (i = 0; i < size; ++i) { |
56 | if (tab[i].name) { |
57 | gfree(p: tab[i].name); |
58 | } |
59 | } |
60 | gfree(p: tab); |
61 | } |
62 | |
63 | void NameToCharCode::add(const char *name, CharCode c) |
64 | { |
65 | NameToCharCodeEntry *oldTab; |
66 | int h, i, oldSize; |
67 | |
68 | // expand the table if necessary |
69 | if (len >= size / 2) { |
70 | oldSize = size; |
71 | oldTab = tab; |
72 | size = 2 * size + 1; |
73 | tab = (NameToCharCodeEntry *)gmallocn(count: size, size: sizeof(NameToCharCodeEntry)); |
74 | for (h = 0; h < size; ++h) { |
75 | tab[h].name = nullptr; |
76 | } |
77 | for (i = 0; i < oldSize; ++i) { |
78 | if (oldTab[i].name) { |
79 | h = hash(name: oldTab[i].name); |
80 | while (tab[h].name) { |
81 | if (++h == size) { |
82 | h = 0; |
83 | } |
84 | } |
85 | tab[h] = oldTab[i]; |
86 | } |
87 | } |
88 | gfree(p: oldTab); |
89 | } |
90 | |
91 | // add the new name |
92 | h = hash(name); |
93 | while (tab[h].name && strcmp(s1: tab[h].name, s2: name)) { |
94 | if (++h == size) { |
95 | h = 0; |
96 | } |
97 | } |
98 | if (!tab[h].name) { |
99 | tab[h].name = copyString(s: name); |
100 | } |
101 | tab[h].c = c; |
102 | |
103 | ++len; |
104 | } |
105 | |
106 | CharCode NameToCharCode::lookup(const char *name) const |
107 | { |
108 | int h; |
109 | |
110 | h = hash(name); |
111 | while (tab[h].name) { |
112 | if (!strcmp(s1: tab[h].name, s2: name)) { |
113 | return tab[h].c; |
114 | } |
115 | if (++h == size) { |
116 | h = 0; |
117 | } |
118 | } |
119 | return 0; |
120 | } |
121 | |
122 | int NameToCharCode::hash(const char *name) const |
123 | { |
124 | const char *p; |
125 | unsigned int h; |
126 | |
127 | h = 0; |
128 | for (p = name; *p; ++p) { |
129 | h = 17 * h + (int)(*p & 0xff); |
130 | } |
131 | return (int)(h % size); |
132 | } |
133 |