diff options
Diffstat (limited to 'src/libjin/common/stringmap.hpp')
-rw-r--r-- | src/libjin/common/stringmap.hpp | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/src/libjin/common/stringmap.hpp b/src/libjin/common/stringmap.hpp new file mode 100644 index 0000000..1db798e --- /dev/null +++ b/src/libjin/common/stringmap.hpp @@ -0,0 +1,145 @@ +#ifndef __JE_COMMON_SREINGMAP_H__ +#define __JE_COMMON_SREINGMAP_H__ + +#include "object.h" + +namespace JinEngine +{ + + template<typename T, unsigned SIZE> + class StringMap : public Object + { + private: + + struct Record + { + const char * key; + T value; + bool set; + Record() : set(false) {} + }; + + const static unsigned MAX = SIZE * 2; + + Record records[MAX]; + const char * reverse[SIZE]; + + public: + + struct Entry + { + const char * key; + T value; + }; + + StringMap(Entry * entries, unsigned num) + { + + for (unsigned i = 0; i < SIZE; ++i) + reverse[i] = 0; + + unsigned n = num / sizeof(Entry); + + for (unsigned i = 0; i < n; ++i) + { + add(entries[i].key, entries[i].value); + } + } + + bool streq(const char * a, const char * b) + { + while (*a != 0 && *b != 0) + { + if (*a != *b) + return false; + ++a; + ++b; + } + + return (*a == 0 && *b == 0); + } + + bool find(const char * key, T & t) + { + //unsigned str_hash = djb2(key); + + for (unsigned i = 0; i < MAX; ++i) + { + //unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional? + + if (records[i].set && streq(records[i].key, key)) + { + t = records[i].value; + return true; + } + } + + return false; + } + + bool find(T key, const char *& str) + { + unsigned index = (unsigned)key; + + if (index >= SIZE) + return false; + + if (reverse[index] != 0) + { + str = reverse[index]; + return true; + } + else + { + return false; + } + } + + bool add(const char * key, T value) + { + unsigned str_hash = djb2(key); + bool inserted = false; + + for (unsigned i = 0; i < MAX; ++i) + { + unsigned str_i = (str_hash + i) % MAX; + + if (!records[str_i].set) + { + inserted = true; + records[str_i].set = true; + records[str_i].key = key; + records[str_i].value = value; + break; + } + } + + unsigned index = (unsigned)value; + + if (index >= SIZE) + { + printf("\nConstant %s out of bounds with %i!\n", key, index); + return false; + } + + reverse[index] = key; + + return inserted; + } + + unsigned djb2(const char * key) + { + unsigned hash = 5381; + int c; + + while ((c = *key++)) + hash = ((hash << 5) + hash) + c; + + return hash; + } + + }; // StringMap + +} // namespace JinEngine + +#endif
\ No newline at end of file |