Browse files

Added functionality so a class can be serialized as either an Array o…

…r Map
  • Loading branch information...
1 parent 50c50ff commit 9678569c65f3a0c6e502055e1342733d76fc0eff @martin-seomoz martin-seomoz committed Apr 24, 2012
Showing with 68 additions and 14 deletions.
  1. +9 −5 Json/ScannerSax.cpp
  2. +12 −2 Json/ScannerSax.h
  3. +19 −6 Json/test/ScannerSaxTest.cpp
  4. +28 −1 Serialize/JsonSerializer.h
View
14 Json/ScannerSax.cpp
@@ -72,19 +72,23 @@ ActionRefNote ScannerSax::registerActionOnAllMapItems(std::auto_ptr<SaxAction> a
ActionRefNote ScannerSax::registerAction(std::string const& mapItem, std::auto_ptr<SaxAction> action)
{
SaxAction*& location = mapActions.front()[mapItem];
- delete location; // If we are overwriting an old value make sure we delete it
+ std::auto_ptr<SaxAction> oldLocation(location);
location = action.release();
return &location;
}
ActionRefNote ScannerSax::registerActionOnAllArrItems(std::auto_ptr<SaxAction> action)
{
- return registerAction(-1, action);
+ SaxAction*& location = arrActions.front().map[-1];
+ std::auto_ptr<SaxAction> oldLocation(location);
+ location = action.release();
+ return &location;
}
-ActionRefNote ScannerSax::registerAction(int index, std::auto_ptr<SaxAction> action)
+ActionRefNote ScannerSax::registerActionNext(std::auto_ptr<SaxAction> action)
{
- SaxAction*& location = arrActions.front()[index];
- delete location; // If we are overwriting an old value make sure we delete it
+ int index = arrActions.front().max++;
+ SaxAction*& location = arrActions.front().map[index];
+ std::auto_ptr<SaxAction> oldLocation(location);
location = action.release();
return &location;
}
View
14 Json/ScannerSax.h
@@ -62,7 +62,17 @@ class ScannerSax
};
typedef PtrMap<std::string> ScannerMapActionMap;
typedef std::list<ScannerMapActionMap> ScannerMapActionList;
- typedef PtrMap<int> ScannerArrActionMap;
+ struct ScannerArrActionMap
+ {
+ typedef PtrMap<int>::const_iterator const_iterator;
+
+ ScannerArrActionMap() : max(0) {}
+ void clear() { max = 0; map.clear();}
+ const_iterator find(int index) const {return map.find(index);}
+ const_iterator end() const {return map.end();}
+ int max;
+ PtrMap<int> map;
+ };
typedef std::list<ScannerArrActionMap> ScannerArrActionList;
ScannerMapActionList mapActions;
@@ -77,7 +87,7 @@ class ScannerSax
template<typename Parser>
void parse(std::istream& src);
ActionRefNote registerAction(std::string const& mapItem, std::auto_ptr<SaxAction> action);
- ActionRefNote registerAction(int index, std::auto_ptr<SaxAction> action);
+ ActionRefNote registerActionNext(std::auto_ptr<SaxAction> action);
ActionRefNote registerActionOnAllMapItems(std::auto_ptr<SaxAction> action);
ActionRefNote registerActionOnAllArrItems(std::auto_ptr<SaxAction> action);
void replaceAction(ActionRefNote oldActionRef, std::auto_ptr<SaxAction> action);
View
25 Json/test/ScannerSaxTest.cpp
@@ -112,11 +112,14 @@ TEST(ScannerSax, ShiftReduceScanArrayMiss)
bool preAction;
bool action;
bool value;
+ std::auto_ptr<ThorsAnvil::Json::SaxAction> emptyAction;
std::auto_ptr<ThorsAnvil::Json::SaxAction> saxAction(new TestAction<bool>(count, preAction, action, value));
std::stringstream json("[ true ]");
ThorsAnvil::Json::ScannerSax scanner;
- scanner.registerAction(2, saxAction);
+ scanner.registerActionNext(emptyAction);
+ scanner.registerActionNext(emptyAction);
+ scanner.registerActionNext(saxAction);
scanner.parse<yy::ParserShiftReduce>(json);
ASSERT_TRUE(preAction == false);
@@ -129,11 +132,13 @@ TEST(ScannerSax, ShiftReduceScanArrayHit)
bool preAction;
bool action;
bool value;
+ std::auto_ptr<ThorsAnvil::Json::SaxAction> emptyAction;
std::auto_ptr<ThorsAnvil::Json::SaxAction> saxAction(new TestAction<bool>(count, preAction, action, value));
std::stringstream json("[ 512, true ]");
ThorsAnvil::Json::ScannerSax scanner;
- scanner.registerAction(1, saxAction);
+ scanner.registerActionNext(emptyAction);
+ scanner.registerActionNext(saxAction);
scanner.parse<yy::ParserShiftReduce>(json);
ASSERT_TRUE(count == 1);
@@ -222,11 +227,14 @@ TEST(ScannerSax, RecursiveScanArrayMiss)
bool preAction;
bool action;
bool value;
+ std::auto_ptr<ThorsAnvil::Json::SaxAction> emptyAction;
std::auto_ptr<ThorsAnvil::Json::SaxAction> saxAction(new TestAction<bool>(count, preAction, action, value));
std::stringstream json("[ false ]");
ThorsAnvil::Json::ScannerSax scanner;
- scanner.registerAction(2, saxAction);
+ scanner.registerActionNext(emptyAction);
+ scanner.registerActionNext(emptyAction);
+ scanner.registerActionNext(saxAction);
scanner.parse<ThorsAnvil::Json::ParserRecursive>(json);
ASSERT_TRUE(count == 0);
@@ -240,11 +248,13 @@ TEST(ScannerSax, RecursiveScanArrayHit)
bool preAction;
bool action;
bool value;
+ std::auto_ptr<ThorsAnvil::Json::SaxAction> emptyAction;
std::auto_ptr<ThorsAnvil::Json::SaxAction> saxAction(new TestAction<bool>(count, preAction, action, value));
std::stringstream json("[ 512, false ]");
ThorsAnvil::Json::ScannerSax scanner;
- scanner.registerAction(1, saxAction);
+ scanner.registerActionNext(emptyAction);
+ scanner.registerActionNext(saxAction);
scanner.parse<ThorsAnvil::Json::ParserRecursive>(json);
ASSERT_TRUE(count == 1);
@@ -270,7 +280,10 @@ TEST(ScannerSax, ReplaceAction)
ThorsAnvil::Json::ScannerSax scanner;
- ThorsAnvil::Json::ActionRefNote actNote = scanner.registerAction(1, saxAction);
+ std::auto_ptr<ThorsAnvil::Json::SaxAction> emptyAction;
+ scanner.registerActionNext(emptyAction);
+
+ ThorsAnvil::Json::ActionRefNote actNote = scanner.registerActionNext(saxAction);
scanner.replaceAction(actNote, saxAction2);
std::stringstream json("[ 512, 567 ]");
@@ -296,7 +309,7 @@ TEST(ScannerSax, DefaultArrayAction)
ThorsAnvil::Json::ScannerSax scanner;
- ThorsAnvil::Json::ActionRefNote actNote = scanner.registerAction(-1, saxAction);
+ ThorsAnvil::Json::ActionRefNote actNote = scanner.registerActionOnAllArrItems(saxAction);
std::stringstream json("[ 512, 567 ]");
scanner.parse<ThorsAnvil::Json::ParserRecursive>(json);
View
29 Serialize/JsonSerializer.h
@@ -11,6 +11,8 @@
* I: The type of the member
* MP: The type of the member pointer
*
+ * S: Source type (std::ostream output) (ThorsAnvil::Json::ScannerSax input)
+ *
* Every type that is serializeable has a class JsonSerializeTraits.
* For basic types (int/float etc) no definition is required and the default template version works
* For compound types you need to define the type SerializeInfo.
@@ -241,19 +243,44 @@ struct JsonSerialize<C, A, RegisterKey, Array>
// Generic serialization of a JSON array
static void activate(JsonSerializeItem<C, A, RegisterKey> const& item, std::ostream& stream, C const& src)
{
+ if (!item.first)
+ { stream << ',';
+ }
item.accessor.serialize(src, stream);
}
};
template<typename T, typename A,typename RegisterKey, JsonSerializeType type = JsonSerializeTraits<T>::type>
-struct JsonDeSerialize
+struct JsonDeSerialize;
+
+template<typename T, typename A,typename RegisterKey>
+struct JsonDeSerialize<T, A, RegisterKey, Map>
{
static void activate(JsonSerializeItem<T, A, RegisterKey> const& item, ThorsAnvil::Json::ScannerSax& parser, T& dst)
{
std::auto_ptr<ThorsAnvil::Json::SaxAction> action(item.accessor.action(dst));
parser.registerAction(item.memberName, action);
}
};
+template<typename T, typename A>
+struct JsonDeSerialize<T, A, int, Array>
+{
+ static void activate(JsonSerializeItem<T, A, int> const& item, ThorsAnvil::Json::ScannerSax& parser, T& dst)
+ {
+ std::auto_ptr<ThorsAnvil::Json::SaxAction> action(item.accessor.action(dst));
+ parser.registerActionOnAllArrItems(action);
+ }
+};
+
+template<typename T, typename A>
+struct JsonDeSerialize<T, A, std::string, Array>
+{
+ static void activate(JsonSerializeItem<T, A, std::string> const& item, ThorsAnvil::Json::ScannerSax& parser, T& dst)
+ {
+ std::auto_ptr<ThorsAnvil::Json::SaxAction> action(item.accessor.action(dst));
+ parser.registerActionNext(action);
+ }
+};
/*
* A type holder object that picks up the correct versions of JsonSerialize and JsonDeSerialize

0 comments on commit 9678569

Please sign in to comment.