return get(key, val, STASH_ITEM_TYPE_STRING);
}
+bool FlowStash::get(const std::string& key, StashGenericObject* &val)
+{
+ return get(key, val, STASH_ITEM_TYPE_GENERIC_OBJECT);
+}
+
void FlowStash::store(const string& key, int32_t val)
{
store(key, val, STASH_ITEM_TYPE_INT32);
store(key, val, STASH_ITEM_TYPE_STRING);
}
-void FlowStash::store(const std::string& key, std::string* val)
+void FlowStash::store(const std::string& key, StashGenericObject* val)
{
+ store(key, val, STASH_ITEM_TYPE_GENERIC_OBJECT);
+}
+
+void FlowStash::store(const string& key, StashGenericObject* &val, StashItemType type)
+{
+#ifdef NDEBUG
+ UNUSED(type);
+#endif
auto item = new StashItem(val);
auto it_and_status = container.emplace(make_pair(key, item));
if (!it_and_status.second)
{
- assert(it_and_status.first->second->get_type() == STASH_ITEM_TYPE_STRING);
+ StashGenericObject* stored_object;
+ assert(it_and_status.first->second->get_type() == type);
+ it_and_status.first->second->get_val(stored_object);
+ assert(stored_object->get_object_type() == val->get_object_type());
delete it_and_status.first->second;
it_and_status.first->second = item;
}
}
+void FlowStash::store(const std::string& key, std::string* val)
+{
+ store(key, val, STASH_ITEM_TYPE_STRING);
+}
+
template<typename T>
bool FlowStash::get(const string& key, T& val, StashItemType type)
{
#include "stash_item.h"
-namespace snort {
+namespace snort
+{
-class FlowStash {
+class FlowStash
+{
public:
~FlowStash();
void reset();
bool get(const std::string& key, int32_t& val);
bool get(const std::string& key, std::string& val);
+ bool get(const std::string& key, StashGenericObject* &val);
void store(const std::string& key, int32_t val);
void store(const std::string& key, const std::string& val);
void store(const std::string& key, std::string* val);
+ void store(const std::string& key, StashGenericObject* val);
private:
std::map<std::string, StashItem*> container;
bool get(const std::string& key, T& val, StashItemType type);
template<typename T>
void store(const std::string& key, T& val, StashItemType type);
+ void store(const std::string& key, StashGenericObject* &val, StashItemType type);
};
}
#include <cstdint>
#include <string>
-namespace snort {
+namespace snort
+{
-enum StashItemType {
+class StashGenericObject
+{
+public:
+ StashGenericObject(int type) : object_type(type)
+ {
+
+ }
+
+ int get_object_type()
+ {
+ return object_type;
+ }
+private:
+ int object_type;
+};
+
+enum StashItemType
+{
STASH_ITEM_TYPE_INT32,
- STASH_ITEM_TYPE_STRING
+ STASH_ITEM_TYPE_STRING,
+ STASH_ITEM_TYPE_GENERIC_OBJECT
};
-union StashItemVal {
+union StashItemVal
+{
int32_t int32_val;
std::string* str_val;
+ StashGenericObject* generic_obj_val;
};
-class StashItem {
-private:
- StashItemType type;
- StashItemVal val;
-
+class StashItem
+{
public:
StashItem(int32_t int32_val)
{
val.str_val = str_val;
}
+ StashItem(StashGenericObject* obj)
+ {
+ type = STASH_ITEM_TYPE_GENERIC_OBJECT;
+ val.generic_obj_val = obj;
+ }
+
~StashItem()
{
switch (type)
case STASH_ITEM_TYPE_STRING:
delete val.str_val;
break;
+ case STASH_ITEM_TYPE_GENERIC_OBJECT:
+ delete val.generic_obj_val;
default:
break;
}
void get_val(std::string& str_val) const
{ str_val = *(val.str_val); }
+
+ void get_val(StashGenericObject* &obj_val) const
+ { obj_val = val.generic_obj_val; }
+
+private:
+ StashItemType type;
+ StashItemVal val;
};
}
using namespace snort;
using namespace std;
-TEST_GROUP(stash_tests)
+class TestStashObject : public StashGenericObject
{
- void setup()
+public:
+ TestStashObject(int type) : StashGenericObject(type)
{
- }
- void teardown()
- {
}
};
+TEST_GROUP(stash_tests)
+{
+
+};
+
TEST(stash_tests, new_int32_item)
{
FlowStash stash;
CHECK_FALSE(stash.get("item_2", val));
}
+TEST(stash_tests, new_generic_object)
+{
+ FlowStash stash;
+ TestStashObject *test_object = new TestStashObject(111);
+
+ stash.store("item_1", test_object);
+
+ StashGenericObject *retrieved_object;
+ CHECK(stash.get("item_1", retrieved_object));
+ POINTERS_EQUAL(test_object, retrieved_object);
+ CHECK_EQUAL(test_object->get_object_type(), ((TestStashObject*)retrieved_object)->get_object_type());
+}
+
+TEST(stash_tests, update_generic_object)
+{
+ FlowStash stash;
+ TestStashObject *test_object = new TestStashObject(111);
+ stash.store("item_1", test_object);
+
+ TestStashObject *new_test_object = new TestStashObject(111);
+ stash.store("item_1", new_test_object);
+
+ StashGenericObject *retrieved_object;
+ CHECK(stash.get("item_1", retrieved_object));
+ POINTERS_EQUAL(new_test_object, retrieved_object);
+}
+
+TEST(stash_tests, non_existent_generic_object)
+{
+ FlowStash stash;
+ StashGenericObject *retrieved_object;
+ CHECK_FALSE(stash.get("item_1", retrieved_object));
+}
+
TEST(stash_tests, mixed_items)
{
FlowStash stash;
+ TestStashObject *test_object = new TestStashObject(111);
stash.store("item_1", 10);
stash.store("item_2", "value_2");
stash.store("item_3", 30);
+ stash.store("item_4", test_object);
int32_t int32_val;
string str_val;
STRCMP_EQUAL(str_val.c_str(), "value_2");
CHECK(stash.get("item_3", int32_val));
CHECK_EQUAL(int32_val, 30);
+
+ StashGenericObject *retrieved_object;
+ CHECK(stash.get("item_4", retrieved_object));
+ POINTERS_EQUAL(test_object, retrieved_object);
+ CHECK_EQUAL(test_object->get_object_type(), ((TestStashObject*)retrieved_object)->get_object_type());
}
int main(int argc, char** argv)