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 
NameToCharCode()39 NameToCharCode::NameToCharCode()
40 {
41     int i;
42 
43     size = 31;
44     len = 0;
45     tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry));
46     for (i = 0; i < size; ++i) {
47         tab[i].name = nullptr;
48     }
49 }
50 
~NameToCharCode()51 NameToCharCode::~NameToCharCode()
52 {
53     int i;
54 
55     for (i = 0; i < size; ++i) {
56         if (tab[i].name) {
57             gfree(tab[i].name);
58         }
59     }
60     gfree(tab);
61 }
62 
add(const char * name,CharCode c)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(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(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(oldTab);
89     }
90 
91     // add the new name
92     h = hash(name);
93     while (tab[h].name && strcmp(tab[h].name, name)) {
94         if (++h == size) {
95             h = 0;
96         }
97     }
98     if (!tab[h].name) {
99         tab[h].name = copyString(name);
100     }
101     tab[h].c = c;
102 
103     ++len;
104 }
105 
lookup(const char * name) const106 CharCode NameToCharCode::lookup(const char *name) const
107 {
108     int h;
109 
110     h = hash(name);
111     while (tab[h].name) {
112         if (!strcmp(tab[h].name, name)) {
113             return tab[h].c;
114         }
115         if (++h == size) {
116             h = 0;
117         }
118     }
119     return 0;
120 }
121 
hash(const char * name) const122 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