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
31struct NameToCharCodeEntry
32{
33 char *name;
34 CharCode c;
35};
36
37//------------------------------------------------------------------------
38
39NameToCharCode::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
51NameToCharCode::~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
63void 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
106CharCode 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
122int 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

source code of poppler/poppler/NameToCharCode.cc