00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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>
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
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