- Main Page
- Namespaces
- Classes
- Files

# proto/Source/strings.h

Go to the documentation of this file.

    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 // Memory pool needed.
    00019 #include "pool.h"
    00020
    00021 namespace ace {
    00022
    00023 // Forward declaration needed.
    00024 template<class _IndType>
    00025 class StringStoreLessComparator;
    00026
    00027 // Forward declaration needed.
    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         // We can't compare just the indices, because newly stored string must be first
    00141         // inserted into store, then compared (and eventually popped out, if founded).
    00142         return strcmp(_table[lhs], _table[rhs]) == 0;
    00143     }
    00144 };
    00145
    00146
    00148
    00149 /*  Interface item definition.
    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 /*  Interface item definition.
    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 /*  Interface item definition.
    00164  */
    00165 template <class _IndType>
    00166 _IndType StringStore<_IndType>::store(const char *str) {
    00167
    00168     // String must be stored to be comparable.
    00169     _IndType index = static_cast<_IndType>(_strings_table.size());
    00170     _strings_table.push_back(str);
    00171
    00172     // Search for given string in string index.
    00173     typename _index_t::iterator i_str = _strings_index.lower_bound(index);
    00174     if ( i_str != _strings_index.end() ) {
    00175         // Compare strings for equality.
    00176         if ( _str_equal_comp(static_cast<_IndType>(*i_str), index) ) {
    00177             // Already exists. Pop string back.
    00178             _strings_table.pop_back();
    00179             return static_cast<_IndType>(*i_str);
    00180         }
    00181     }
    00182
    00183     if ( this->is_full() ) {
    00184         // No index left to spend...
    00185         throw index_overflow("String store overflow!");
    00186     }
    00187
    00188     // New object - new memory needed...
    00189     size_t memory_needed = strlen(str) + 1;
    00190     char* mem = _memory_pool.get_memory(memory_needed); // This may throw!
    00191
    00192     // Copy passed string into brand new memory.
    00193     memcpy(mem, str, memory_needed);
    00194     // Store pointer between strings (overwrite temporary stored param).
    00195     _strings_table[index] = mem;
    00196     // Insert and return dereferenced iterator.
    00197     return static_cast<_IndType>(*_strings_index.insert(i_str, index));
    00198 }
    00199
    00200 } // namespace ace
    00201
    00202 #endif