Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

NameList.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *        $RCSfile: NameList.h,v $
00013  *        $Author: johns $        $Locker:  $                $State: Exp $
00014  *        $Revision: 1.49 $        $Date: 2019/01/17 21:21:00 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * NameList template, which stores a list of unique names indexed in the order
00020  * they are added.  For each name, which acts as a key, there is an associated
00021  * integer value.  NameList string lookups are accelerated through the use of
00022  * an internal hash table.
00023  *
00024  ***************************************************************************/
00025 #ifndef NAMELIST_TEMPLATE_H
00026 #define NAMELIST_TEMPLATE_H
00027 
00028 #include <string.h>
00029 #include "ResizeArray.h" 
00030 #include "utilities.h"   // needed for stringdup()
00031 #include "hash.h"        // needed for hash table functions
00032 
00033 #define NLISTSIZE 64
00034 
00039 template<class T>
00040 class NameList  {
00041 protected:
00042   int Num;                   
00043   ResizeArray<char *> names; 
00044   ResizeArray<T> Data;       
00045   hash_t hash;               
00046  
00047 public:
00049   // starts with no names, which are then added via the 'add_name' routine.  
00050   NameList(void) : names(NLISTSIZE), Data(NLISTSIZE) {
00051     Num = 0;
00052     hash_init(&hash, 127);
00053   }
00054 
00056   virtual ~NameList(void) {
00057     for(int i=0; i < Num; i++) {
00058       if(names[i])
00059         delete [] names[i];
00060     }
00061     hash_destroy(&hash);
00062   }
00063 
00064   int num(void) const { return Num; }    // return number of items
00065 
00066   // clear list. equivalent to running destructor and constructor.
00067   void clear(void) {
00068     for(int i=0; i < Num; i++) {
00069       if(names[i])
00070         delete [] names[i];
00071     }
00072     hash_destroy(&hash);
00073     Data.clear();
00074     names.clear();
00075     // start over.
00076     Num = 0;
00077     hash_init(&hash, 127);
00078   }
00079 
00080   // add a new name to the list, with a given associated value.
00081   // Return the index.  If already in the list, return the current index.
00082   int add_name(const char *nm, const T &val) {
00083     char tmpnm[128]; // temporary storage, spaces stripped from beginning + end
00084     memset(tmpnm, 0, sizeof(tmpnm)); // clear temp storage
00085  
00086     if (!nm)
00087       return (-1);      
00088 
00089     // strip leading and trailing spaces from the name
00090     char *s = tmpnm;
00091     while (*nm && *nm == ' ')           // skip past whitespace
00092       nm++;
00093 
00094     int len = 127;
00095     while (*nm && len--)                // copy the string
00096       *(s++) = *(nm++);
00097 
00098     *s = '\0';                          // terminate the copied string
00099     while(s != tmpnm && *(--s) == ' ')  // remove spaces at end of string
00100       *s = '\0';
00101 
00102     int myindex;  
00103     if ((myindex = hash_lookup(&hash, tmpnm)) != HASH_FAIL) {
00104       return myindex; 
00105     } 
00106 
00107     // if here, string not found; append new one, and return index = Num - 1
00108     names.append(stringdup(tmpnm));
00109 
00110     myindex = hash_insert(&hash, names[Num], Num); 
00111 
00112     Data.append(val);
00113     return Num++;
00114   }
00115 
00116 
00117 
00118   // return the name (null-terminated) for given typecode
00119   const char * name(int a) const {
00120     if (a >= 0 && a < Num) {
00121       return names[a];
00122     }
00123     return NULL;        // not found
00124   }
00125 
00126 
00127   // return the type index for the given name.  If the second argument is
00128   // given and is > 0, it is used as the max length of the names to check
00129   // for a match.  If is is <= 0, an exact match must be found.
00130   //        returns (-1) if no match is found
00131   int typecode(const char *nm) const {
00132     if (!nm)
00133       return -1;
00134 
00135     return hash_lookup(&hash, nm);  // returns -1 (HASH_FAIL) on no entry
00136   }
00137 
00138 
00139   // returns the data for the given name.  If the second argument is
00140   // given and is > 0, it is used as the max length of the names to check
00141   // for a match.  If is is <= 0, an exact match must be found.
00142   T data(const char *nm) const {
00143     if (!nm)
00144       return Data[0];
00145  
00146     int myindex = hash_lookup(&hash, nm);
00147     if (myindex != HASH_FAIL)
00148       return Data[myindex];
00149   
00150     return Data[0];
00151   }
00152 
00153 
00154   // returns the data for the given index
00155   T data(int a) const {
00156     if (a >= 0 && a < Num) {
00157       return Data[a];
00158     }
00159     return Data[0];
00160   }
00161 
00162 
00163   // set the data value for the given index
00164   void set_data(int a, const T &val) {
00165     if(a >= 0 && a < Num) {
00166       Data[a] = val;
00167     }
00168     // else it was an illegal index, therefore do nothing.
00169   }
00170 
00171   // change the name of an entry
00172   void set_name(int a, const char *nm) {
00173     if (a < 0 || a >= Num) 
00174       return;
00175 
00176     // delete the hash table entry...
00177     hash_delete(&hash, names[a]);
00178     delete [] names[a];
00179     names[a] = stringdup(nm);
00180     // and put the pointer in our ResizeArray into the hash table
00181     hash_insert(&hash, names[a], a);
00182   } 
00183 
00184 };
00185 
00186 
00187 // useful typedefs for making NameLists of NameLists
00188 typedef NameList<int>           *NameListIntPtr;
00189 typedef NameList<float>         *NameListFloatPtr;
00190 typedef NameList<char>          *NameListCharPtr;
00191 typedef NameList<char *>        *NameListStringPtr;
00192 
00193 #endif
00194 

Generated on Wed Apr 24 02:42:45 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002