Back to index

tetex-bin  3.0
NameToCharCode.cc
Go to the documentation of this file.
00001 //========================================================================
00002 //
00003 // NameToCharCode.cc
00004 //
00005 // Copyright 2001-2003 Glyph & Cog, LLC
00006 //
00007 //========================================================================
00008 
00009 #include <aconf.h>
00010 
00011 #ifdef USE_GCC_PRAGMAS
00012 #pragma implementation
00013 #endif
00014 
00015 #include <string.h>
00016 #include "gmem.h"
00017 #include "NameToCharCode.h"
00018 
00019 //------------------------------------------------------------------------
00020 
00021 struct NameToCharCodeEntry {
00022   char *name;
00023   CharCode c;
00024 };
00025 
00026 //------------------------------------------------------------------------
00027 
00028 NameToCharCode::NameToCharCode() {
00029   int i;
00030 
00031   size = 31;
00032   len = 0;
00033   tab = (NameToCharCodeEntry *)gmalloc(size * sizeof(NameToCharCodeEntry));
00034   for (i = 0; i < size; ++i) {
00035     tab[i].name = NULL;
00036   }
00037 }
00038 
00039 NameToCharCode::~NameToCharCode() {
00040   int i;
00041 
00042   for (i = 0; i < size; ++i) {
00043     if (tab[i].name) {
00044       gfree(tab[i].name);
00045     }
00046   }
00047   gfree(tab);
00048 }
00049 
00050 void NameToCharCode::add(char *name, CharCode c) {
00051   NameToCharCodeEntry *oldTab;
00052   int h, i, oldSize;
00053 
00054   // expand the table if necessary
00055   if (len >= size / 2) {
00056     oldSize = size;
00057     oldTab = tab;
00058     size = 2*size + 1;
00059     tab = (NameToCharCodeEntry *)gmalloc(size * sizeof(NameToCharCodeEntry));
00060     for (h = 0; h < size; ++h) {
00061       tab[h].name = NULL;
00062     }
00063     for (i = 0; i < oldSize; ++i) {
00064       if (oldTab[i].name) {
00065        h = hash(oldTab[i].name);
00066        while (tab[h].name) {
00067          if (++h == size) {
00068            h = 0;
00069          }
00070        }
00071        tab[h] = oldTab[i];
00072       }
00073     }
00074     gfree(oldTab);
00075   }
00076 
00077   // add the new name
00078   h = hash(name);
00079   while (tab[h].name && strcmp(tab[h].name, name)) {
00080     if (++h == size) {
00081       h = 0;
00082     }
00083   }
00084   if (!tab[h].name) {
00085     tab[h].name = copyString(name);
00086   }
00087   tab[h].c = c;
00088 
00089   ++len;
00090 }
00091 
00092 CharCode NameToCharCode::lookup(char *name) {
00093   int h;
00094 
00095   h = hash(name);
00096   while (tab[h].name) {
00097     if (!strcmp(tab[h].name, name)) {
00098       return tab[h].c;
00099     }
00100     if (++h == size) {
00101       h = 0;
00102     }
00103   }
00104   return 0;
00105 }
00106 
00107 int NameToCharCode::hash(char *name) {
00108   char *p;
00109   unsigned int h;
00110 
00111   h = 0;
00112   for (p = name; *p; ++p) {
00113     h = 17 * h + (int)(*p & 0xff);
00114   }
00115   return (int)(h % size);
00116 }