00001
00009 #ifndef _STRINGS_H
00010 #define _STRINGS_H
00011
00012 #include <limits>
00013 #include <set>
00014 #include <vector>
00015
00016
00017 #include "exceptions.h"
00018
00019 #include "pool.h"
00020
00021 namespace ace {
00022
00023
00024 template<class _IndType>
00025 class StringStoreLessComparator;
00026
00027
00028 template<class _IndType>
00029 class StringStoreEqualComparator;
00030
00045 template<class _IndType>
00046 class StringStore {
00047 public:
00051 typedef std::vector<const char *> table_t;
00052
00053 private:
00056 typedef typename std::set<_IndType, StringStoreLessComparator<_IndType> > _index_t;
00057
00060 RandomSizedMemoryPool<char> _memory_pool;
00061
00064 table_t _strings_table;
00065
00068 _index_t _strings_index;
00069
00072 StringStoreEqualComparator<_IndType> _str_equal_comp;
00073
00074 public:
00078 StringStore(size_t max_string_length);
00081 void clear(void);
00084 inline bool is_full(void) const { return _strings_table.size() == std::numeric_limits<_IndType>::max(); }
00090 inline const char * get(_IndType index) const { return _strings_table[index]; }
00097 _IndType store(const char *str);
00100 inline size_t size(void) const { return _strings_table.size(); }
00101 };
00102
00103
00108 template <class _IndType>
00109 class StringStoreLessComparator: public std::binary_function<_IndType, _IndType, bool> {
00112 const typename StringStore<_IndType>::table_t& _table;
00113 public:
00116 StringStoreLessComparator(const typename StringStore<_IndType>::table_t& table): _table(table) {}
00119 inline bool operator()(_IndType lhs, _IndType rhs) const {
00120 return strcmp(_table[lhs], _table[rhs]) == -1;
00121 }
00122 };
00123
00128 template <class _IndType>
00129 class StringStoreEqualComparator: public std::binary_function<_IndType, _IndType, bool> {
00132 const typename StringStore<_IndType>::table_t& _table;
00133 public:
00136 StringStoreEqualComparator(const typename StringStore<_IndType>::table_t& table): _table(table) {}
00139 inline bool operator()(_IndType lhs, _IndType rhs) const {
00140
00141
00142 return strcmp(_table[lhs], _table[rhs]) == 0;
00143 }
00144 };
00145
00146
00148
00149
00150
00151 template <class _IndType>
00152 StringStore<_IndType>::StringStore(size_t max_string_length): _memory_pool(max_string_length + 1), _strings_table(), _strings_index(StringStoreLessComparator<_IndType>(_strings_table)), _str_equal_comp(_strings_table) {}
00153
00154
00155
00156 template <class _IndType>
00157 void StringStore<_IndType>::clear(void) {
00158 _strings_index.clear();
00159 _strings_table.clear();
00160 _memory_pool.clear();
00161 }
00162
00163
00164
00165 template <class _IndType>
00166 _IndType StringStore<_IndType>::store(const char *str) {
00167
00168
00169 _IndType index = static_cast<_IndType>(_strings_table.size());
00170 _strings_table.push_back(str);
00171
00172
00173 typename _index_t::iterator i_str = _strings_index.lower_bound(index);
00174 if ( i_str != _strings_index.end() ) {
00175
00176 if ( _str_equal_comp(static_cast<_IndType>(*i_str), index) ) {
00177
00178 _strings_table.pop_back();
00179 return static_cast<_IndType>(*i_str);
00180 }
00181 }
00182
00183 if ( this->is_full() ) {
00184
00185 throw index_overflow("String store overflow!");
00186 }
00187
00188
00189 size_t memory_needed = strlen(str) + 1;
00190 char* mem = _memory_pool.get_memory(memory_needed);
00191
00192
00193 memcpy(mem, str, memory_needed);
00194
00195 _strings_table[index] = mem;
00196
00197 return static_cast<_IndType>(*_strings_index.insert(i_str, index));
00198 }
00199
00200 }
00201
00202 #endif