This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| String Table Submitted by

The description is part of the code listing.

Download Associated File: stable.h (4,339 bytes)

    #ifndef STABLE_H

    #define STABLE_H

    // This class implements a 'stringtable'.  It is being released into
    // the public domain on September 27, 2000 by John W. Ratcliff
    // jratcliff@verant.com for FlipCode.com as part of the 'code of they day'
    // project.
    //
    // What the heck does a 'StringTable' class do for me?  What a StringTable
    // is used for is to manage a collection of shared strings across a package.
    // It is primarily used for tokens, keywords, asset names, etc.  You do
    // *NOT* want to use the StringTable for any cases which could produce
    // an infinite number of strings.  This is only for managing a finite list
    // of keywords.
    //
    // The reason you use a string table is so that you can keep track of items
    // by ASCII name instead of some non-intutitive and arbritrary id number.
    // Normally it is not practical to make a container class who's key is
    // an STL string.  First of all there is a memory overhead, and additionally
    // there is a serious peformance penalty.  However, with the StringTable
    // class, instead you can keep track of a list of items where the key is
    // a pointer to the string, instead of the string itself.  Now you can
    // compare if 'two strings are equal' simply by comparing if their address
    // is the same.  Remember that any container class which uses this pointer as
    // a key is *NOT* in alphabetical order!!  It's ordered based on the address
    // in memory of the string itself.  But that doesn't matter, because the
    // purpose of the container is not to maintain an alphabetical list of
    // items but rather to simply locate items *BY NAME* extremely quickly.
    //
    // Using a stringtable makes it trivial to keep ASCII names and descriptions
    // as member variables in all of your classes.  This makes debugging and
    // debug output vastly simpler.
    //
    // Example: Say you contruct a new intance of a Vehicle class.  In it's
    // constructor you might have something like:
    //
    // mObjectName = gStringTable.Get("vehicle");
    //
    // Where mObjectName is a member variable of type 'const char *' and
    // gStringTable is some global instance of a shared string table across
    // your application.  Now, you can compare whether or not an object is of
    // type 'vehicle' simply by comparing it's name to anybody else's name
    // with the two pointers allocated with the same string table.
    //
    // This is extremely convenient for debugging, logging, etc.
    //
    // To create an STL map where you access every item *by name* all you
    // have to do is:
    //
    // typedef std::map< const char * , Texture *> TextureMap;
    //
    // This would create an STL map that would allow you to quickly look
    // up any texture by name.  A fairly useful data structure.
    //
    // Example of how to locate a texture by name:
    //
    // **NOTE* texname must have been created by the same StringTable
    //
    // Texture * FindTexture(const char *texname)
    // {
    //   TextureMap::iterator found; // STL map iterator to find item.
    //   found = mTextures.find( texname ); // search red/black tree
    //   if ( found != mTextures.end() ) return (*found).second;
    //   return 0; // no texture of this name found.
    // }
    //
    // The string table implementation uses STL to maintain the collection
    // of strings.  If you change the comparator function in CharPtrLess
    // from strcmp to stricmp then all of your strings will be created without
    // case sensitivity, which is often the behavior you want for tokens and
    // keywords.

    #include <string.h>
    #include <string>
    #include <set>

    typedef std::string String;

    class CharPtrLess
    {
    public:
    	bool operator()(const char *v1,const char *v2) const
      {
        int v = strcmp(v1,v2);
        if ( v < 0 ) return true;
        return false;
      };
    };

    typedef std::set< const char *, CharPtrLess > CharPtrSet;

    class StringTable
    {
    public:
      StringTable(void)
      {
      };

      ~StringTable(void)
      {
        CharPtrSet::iterator i;
        for (i=mStrings.begin(); i!=mStrings.end(); i++)
        {
          char *str = (char *)(*i);
          delete str;
        }
      }

      const char * Get(const char *str)
      {
        CharPtrSet::iterator found;
        found = mStrings.find( str );
        if ( found != mStrings.end() ) return (*found);
        int l = strlen(str);
        char *mem = new char[l+1];
        strcpy(mem,str);
        mStrings.insert( mem );
        return mem;
      };

      const char * Get(const String &str)
      {
        return Get( str.c_str() );
      };

    private:
      CharPtrSet mStrings;
    };

    #endif

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.