aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/common/stringmap.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/common/stringmap.hpp')
-rw-r--r--src/libjin/common/stringmap.hpp145
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