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

NameList.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 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.46 $        $Date: 2011/03/07 16:07:15 $
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     
00085     if (!nm)
00086       return (-1);      
00087 
00088     // strip leading and trailing spaces from the name
00089     char *s = tmpnm;
00090     while (*nm && *nm == ' ')           // skip past whitespace
00091       nm++;
00092 
00093     int len = 127;
00094     while (*nm && len--)                // copy the string
00095       *(s++) = *(nm++);
00096 
00097     *s = 0;                             // terminate the copied string
00098     while(s != tmpnm && *(--s) == ' ')  // remove spaces at end of string
00099       *s = '\0';
00100 
00101     int myindex;  
00102     if ((myindex = hash_lookup(&hash, tmpnm)) != HASH_FAIL) {
00103       return myindex; 
00104     } 
00105 
00106     // if here, string not found; append new one, and return index = Num - 1
00107     names.append(stringdup(tmpnm));
00108 
00109     myindex = hash_insert(&hash, names[Num], Num); 
00110 
00111     Data.append(val);
00112     return Num++;
00113   }
00114 
00115 
00116 
00117   // return the name (null-terminated) for given typecode
00118   const char * name(int a) const {
00119     if (a >= 0 && a < Num) {
00120       return names[a];
00121     }
00122     return NULL;        // not found
00123   }
00124 
00125 
00126   // return the type index for the given name.  If the second argument is
00127   // given and is > 0, it is used as the max length of the names to check
00128   // for a match.  If is is <= 0, an exact match must be found.
00129   //        returns (-1) if no match is found
00130   int typecode(const char *nm) const {
00131     if (!nm)
00132       return -1;
00133 
00134     return hash_lookup(&hash, nm);  // returns -1 (HASH_FAIL) on no entry
00135   }
00136 
00137 
00138   // returns the data for the given name.  If the second argument is
00139   // given and is > 0, it is used as the max length of the names to check
00140   // for a match.  If is is <= 0, an exact match must be found.
00141   T data(const char *nm) const {
00142     if (!nm)
00143       return Data[0];
00144  
00145     int myindex = hash_lookup(&hash, nm);
00146     if (myindex != HASH_FAIL)
00147       return Data[myindex];
00148   
00149     return Data[0];
00150   }
00151 
00152 
00153   // returns the data for the given index
00154   T data(int a) const {
00155     if (a >= 0 && a < Num) {
00156       return Data[a];
00157     }
00158     return Data[0];
00159   }
00160 
00161 
00162   // set the data value for the given index
00163   void set_data(int a, const T &val) {
00164     if(a >= 0 && a < Num) {
00165       Data[a] = val;
00166     }
00167     // else it was an illegal index, therefore do nothing.
00168   }
00169 
00170   // change the name of an entry
00171   void set_name(int a, const char *nm) {
00172     if (a < 0 || a >= Num) 
00173       return;
00174 
00175     // delete the hash table entry...
00176     hash_delete(&hash, names[a]);
00177     delete [] names[a];
00178     names[a] = stringdup(nm);
00179     // and put the pointer in our ResizeArray into the hash table
00180     hash_insert(&hash, names[a], a);
00181   } 
00182 
00183 };
00184 
00185 
00186 // useful typedefs for making NameLists of NameLists
00187 typedef NameList<int>           *NameListIntPtr;
00188 typedef NameList<float>         *NameListFloatPtr;
00189 typedef NameList<char>          *NameListCharPtr;
00190 typedef NameList<char *>        *NameListStringPtr;
00191 
00192 #endif
00193 

Generated on Mon May 21 01:51:05 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002