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()39NameToCharCode::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()51NameToCharCode::~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)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(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) const106CharCode 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) const122int 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