assocarray.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2004-2007 University of Southern California
00006 // Rob Peters <rjpeters at usc dot edu>
00007 //
00008 // created: Thu Oct 14 18:42:05 2004
00009 // commit: $Id: assocarray.cc 10097 2007-08-07 19:08:27Z rjpeters $
00010 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/rutz/assocarray.cc $
00011 //
00012 // --------------------------------------------------------------------
00013 //
00014 // This file is part of GroovX.
00015 //   [http://ilab.usc.edu/rjpeters/groovx/]
00016 //
00017 // GroovX is free software; you can redistribute it and/or modify it
00018 // under the terms of the GNU General Public License as published by
00019 // the Free Software Foundation; either version 2 of the License, or
00020 // (at your option) any later version.
00021 //
00022 // GroovX is distributed in the hope that it will be useful, but
00023 // WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025 // General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License
00028 // along with GroovX; if not, write to the Free Software Foundation,
00029 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00030 //
00032 
00033 #ifndef GROOVX_RUTZ_ASSOCARRAY_CC_UTC20050626084020_DEFINED
00034 #define GROOVX_RUTZ_ASSOCARRAY_CC_UTC20050626084020_DEFINED
00035 
00036 #include "assocarray.h"
00037 
00038 #include "rutz/error.h"
00039 #include "rutz/fstring.h"
00040 #include "rutz/sfmt.h"
00041 
00042 #include <algorithm> // for lexicographical_compare()
00043 #include <map>
00044 #include <sstream>
00045 
00046 #include "rutz/trace.h"
00047 
00048 struct rutz::assoc_array_base::impl
00049 {
00050   impl(kill_func_t* f, const char* descr, bool nocase)
00051     :
00052     values(fstring_cmp(nocase)),
00053     kill_func(f),
00054     key_description(descr)
00055   {}
00056 
00057   static bool nocase_char_cmp(char c1, char c2)
00058   {
00059     return toupper(c1) < toupper(c2);
00060   }
00061 
00062   struct fstring_cmp
00063   {
00064     fstring_cmp(bool nocase_) : nocase(nocase_) {}
00065 
00066     const bool nocase;
00067 
00068     bool operator()(const rutz::fstring& s1,
00069                     const rutz::fstring& s2) const
00070     {
00071       if (nocase)
00072         {
00073           return std::lexicographical_compare
00074             (s1.c_str(), s1.c_str() + s1.length(),
00075              s2.c_str(), s2.c_str() + s2.length(),
00076              nocase_char_cmp);
00077         }
00078 
00079       // else...
00080       return (s1 < s2);
00081     }
00082   };
00083 
00084   typedef std::map<rutz::fstring, void*, fstring_cmp> map_t;
00085 
00086   map_t         values;
00087   kill_func_t*  kill_func;
00088   rutz::fstring key_description;
00089 };
00090 
00091 rutz::assoc_array_base::assoc_array_base(kill_func_t* f,
00092                                          const char* descr,
00093                                          bool nocase) :
00094   rep(new impl(f, descr, nocase))
00095 {
00096 GVX_TRACE("rutz::assoc_array_base::assoc_array_base");
00097 }
00098 
00099 rutz::assoc_array_base::~assoc_array_base()
00100 {
00101 GVX_TRACE("rutz::assoc_array_base::~assoc_array_base");
00102   clear();
00103 }
00104 
00105 rutz::fstring rutz::assoc_array_base::
00106 get_known_keys(const char* sep) const
00107 {
00108   std::ostringstream result;
00109 
00110   bool first = true;
00111 
00112   for (impl::map_t::iterator ii = rep->values.begin();
00113        ii != rep->values.end();
00114        ++ii)
00115     {
00116       if (ii->second != 0)
00117         {
00118           if (!first) result << sep;
00119 
00120           result << ii->first;
00121 
00122           first = false;
00123         }
00124     }
00125 
00126   return rutz::fstring(result.str().c_str());
00127 }
00128 
00129 void rutz::assoc_array_base::
00130 throw_for_key(const char* key, const rutz::file_pos& pos) const
00131 {
00132   throw rutz::error(rutz::sfmt("known keys are:\n\t%s\nunknown %s '%s'",
00133                                get_known_keys("\n\t").c_str(),
00134                                rep->key_description.c_str(),
00135                                key),
00136                     pos);
00137 }
00138 
00139 void rutz::assoc_array_base::
00140 throw_for_key(const rutz::fstring& key, const rutz::file_pos& pos) const
00141 {
00142   throw_for_key(key.c_str(), pos);
00143 }
00144 
00145 void rutz::assoc_array_base::clear()
00146 {
00147 GVX_TRACE("rutz::assoc_array_base::clear");
00148   for (impl::map_t::iterator ii = rep->values.begin();
00149        ii != rep->values.end();
00150        ++ii)
00151     {
00152       if (rep->kill_func != 0) rep->kill_func(ii->second);
00153       ii->second = 0;
00154     }
00155 
00156   delete rep;
00157 }
00158 
00159 void* rutz::assoc_array_base::get_value_for_key(const rutz::fstring& key) const
00160 {
00161 GVX_TRACE("rutz::assoc_array_base::get_value_for_key");
00162   return rep->values[key];
00163 }
00164 
00165 void* rutz::assoc_array_base::get_value_for_key(const char* key) const
00166 {
00167   return get_value_for_key(rutz::fstring(key));
00168 }
00169 
00170 void rutz::assoc_array_base::set_value_for_key(const char* key, void* ptr)
00171 {
00172 GVX_TRACE("rutz::assoc_array_base::set_value_for_key");
00173   rutz::fstring skey(key);
00174   void*& ptr_slot = rep->values[skey];
00175   if (rep->kill_func != 0) rep->kill_func(ptr_slot);
00176   ptr_slot = ptr;
00177 }
00178 
00179 static const char __attribute__((used)) vcid_groovx_rutz_assocarray_cc_utc20050626084020[] = "$Id: assocarray.cc 10097 2007-08-07 19:08:27Z rjpeters $ $HeadURL: file:
00180 #endif // !GROOVX_RUTZ_ASSOCARRAY_CC_UTC20050626084020_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:40 2008 by Doxygen version 1.5.5.