comparison Resources/CodeGeneration/template.in.h @ 494:fc17251477d6 bgo-commands-codegen

TS and CPP tests OK. Ongoing code for C++ program that reads list of serialized messages in N files. Requires conan
author bgo-osimis
date Sat, 23 Feb 2019 10:18:13 +0100
parents 6470248790db
children 6405435480ae
comparison
equal deleted inserted replaced
493:6fbf2eae7c88 494:fc17251477d6
5 5
6 #include <iostream> 6 #include <iostream>
7 #include <string> 7 #include <string>
8 #include <sstream> 8 #include <sstream>
9 #include <assert.h> 9 #include <assert.h>
10 #include <memory>
11 #include <optional>
10 #include <json/json.h> 12 #include <json/json.h>
11 13 #include <gtest/gtest.h>
12 14
13 namespace VsolStuff 15 //#define STONEGEN_NO_CPP11 1
16
17 #ifdef STONEGEN_NO_CPP11
18 #define StoneSmartPtr std::auto_ptr
19 #else
20 #define StoneSmartPtr std::unique_ptr
21 #endif
22
23 namespace {{rootName}}
14 { 24 {
15 Json::Value StoneSerialize(int32_t value) 25 /** Throws in case of problem */
26 void _StoneDeserializeValue(int32_t& destValue, const Json::Value& jsonValue)
27 {
28 destValue = jsonValue.asInt();
29 }
30
31 Json::Value _StoneSerializeValue(int32_t value)
16 { 32 {
17 Json::Value result(value); 33 Json::Value result(value);
18 return result; 34 return result;
19 } 35 }
20 36
21 Json::Value StoneSerialize(double value) 37 /** Throws in case of problem */
38 void _StoneDeserializeValue(double& destValue, const Json::Value& jsonValue)
39 {
40 destValue = jsonValue.asDouble();
41 }
42
43 Json::Value _StoneSerializeValue(double value)
22 { 44 {
23 Json::Value result(value); 45 Json::Value result(value);
24 return result; 46 return result;
25 } 47 }
26 48
27 Json::Value StoneSerialize(bool value) 49 /** Throws in case of problem */
50 void _StoneDeserializeValue(bool& destValue, const Json::Value& jsonValue)
51 {
52 destValue = jsonValue.asBool();
53 }
54
55 Json::Value _StoneSerializeValue(bool value)
28 { 56 {
29 Json::Value result(value); 57 Json::Value result(value);
30 return result; 58 return result;
31 } 59 }
32 60
33 Json::Value StoneSerialize(const std::string& value) 61 /** Throws in case of problem */
62 void _StoneDeserializeValue(
63 std::string& destValue
64 , const Json::Value& jsonValue)
65 {
66 destValue = jsonValue.asString();
67 }
68
69 Json::Value _StoneSerializeValue(const std::string& value)
34 { 70 {
35 // the following is better than 71 // the following is better than
36 Json::Value result(value.data(),value.data()+value.size()); 72 Json::Value result(value.data(),value.data()+value.size());
37 return result; 73 return result;
38 } 74 }
39 75
40 template<typename T> 76 /** Throws in case of problem */
41 Json::Value StoneSerialize(const std::map<std::string,T>& value) 77 template<typename T>
78 void _StoneDeserializeValue(
79 std::map<std::string, T>& destValue, const Json::Value& jsonValue)
80 {
81 destValue.clear();
82 for (
83 Json::Value::const_iterator itr = jsonValue.begin();
84 itr != jsonValue.end();
85 itr++)
86 {
87 std::string key;
88 _StoneDeserializeValue(key, itr.key());
89
90 T innerDestValue;
91 _StoneDeserializeValue(innerDestValue, *itr);
92
93 destValue[key] = innerDestValue;
94 }
95 }
96
97 template<typename T>
98 Json::Value _StoneSerializeValue(const std::map<std::string,T>& value)
42 { 99 {
43 Json::Value result(Json::objectValue); 100 Json::Value result(Json::objectValue);
44 101
45 for (std::map<std::string, T>::const_iterator it = value.cbegin(); 102 for (std::map<std::string, T>::const_iterator it = value.cbegin();
46 it != value.cend(); ++it) 103 it != value.cend(); ++it)
47 { 104 {
48 // it->first it->second 105 // it->first it->second
49 result[it->first] = StoneSerialize(it->second); 106 result[it->first] = _StoneSerializeValue(it->second);
50 } 107 }
51 return result; 108 return result;
52 } 109 }
53 110
54 template<typename T> 111 /** Throws in case of problem */
55 Json::Value StoneSerialize(const std::vector<T>& value) 112 template<typename T>
113 void _StoneDeserializeValue(
114 std::vector<T>& destValue, const Json::Value& jsonValue)
115 {
116 destValue.clear();
117 destValue.reserve(jsonValue.size());
118 for (Json::Value::ArrayIndex i = 0; i != jsonValue.size(); i++)
119 {
120 T innerDestValue;
121 _StoneDeserializeValue(innerDestValue, jsonValue[i]);
122 destValue.push_back(innerDestValue);
123 }
124 }
125
126 template<typename T>
127 Json::Value _StoneSerializeValue(const std::vector<T>& value)
56 { 128 {
57 Json::Value result(Json::arrayValue); 129 Json::Value result(Json::arrayValue);
58 for (size_t i = 0; i < value.size(); ++i) 130 for (size_t i = 0; i < value.size(); ++i)
59 { 131 {
60 result.append(StoneSerialize(value[i])); 132 result.append(_StoneSerializeValue(value[i]));
61 } 133 }
62 return result; 134 return result;
63 } 135 }
64 136
65 %enumerationscpp% 137 void StoneCheckSerializedValueTypeGeneric(const Json::Value& value)
66 138 {
67 %structscpp% 139 if ((!value.isMember("type")) || (!value["type"].isString()))
68 140 {
141 std::stringstream ss;
142 ss << "Cannot deserialize value ('type' key invalid)";
143 throw std::runtime_error(ss.str());
144 }
145 }
146
147 void StoneCheckSerializedValueType(
148 const Json::Value& value, std::string typeStr)
149 {
150 StoneCheckSerializedValueTypeGeneric(value);
151
152 std::string actTypeStr = value["type"].asString();
153 if (actTypeStr != typeStr)
154 {
155 std::stringstream ss;
156 ss << "Cannot deserialize type" << actTypeStr
157 << "into " << typeStr;
158 throw std::runtime_error(ss.str());
159 }
160 }
161
162 // end of generic methods
163
164 // end of generic methods
165 {% for enum in enums%}
166 enum {{enum['name']}} {
167 {% for key in enum['fields']%} {{key}},
168 {%endfor%} };
169
170 void _StoneDeserializeValue(
171 {{enum['name']}}& destValue, const Json::Value& jsonValue)
172 {
173 destValue = static_cast<{{enum['name']}}>(jsonValue.asInt64());
174 }
175
176 Json::Value _StoneSerializeValue(const {{enum['name']}}& value)
177 {
178 return Json::Value(static_cast<int64_t>(value));
179 }
180 {%endfor%}
181 {% for struct in structs%}
182 #ifdef _MSC_VER
183 #pragma region {{struct['name']}}
184 #endif //_MSC_VER
185
186 struct {{struct['name']}}
187 {
188 {% for key in struct['fields']%} {{CanonToCpp(struct['fields'][key])}} {{key}};
189 {% endfor %}
190 {{struct['name']}}()
191 {
192 {% for key in struct['fields']%} {{key}} = {{CanonToCpp(struct['fields'][key])}}();
193 {% endfor %}
194 }
195 };
196
197 void _StoneDeserializeValue({{struct['name']}}& destValue, const Json::Value& value)
198 {
199 {% for key in struct['fields']%} _StoneDeserializeValue(destValue.{{key}}, value["{{key}}"]);
200 {% endfor %}
201 }
202
203 Json::Value _StoneSerializeValue(const {{struct['name']}}& value)
204 {
205 Json::Value result(Json::objectValue);
206 {% for key in struct['fields']%} result["{{key}}"] = _StoneSerializeValue(value.{{key}});
207 {% endfor %}
208 return result;
209 }
210
211 void StoneDeserialize({{struct['name']}}& destValue, const Json::Value& value)
212 {
213 StoneCheckSerializedValueType(value, "{{rootName}}.{{struct['name']}}");
214 _StoneDeserializeValue(destValue, value["value"]);
215 }
216
217 Json::Value StoneSerialize(const {{struct['name']}}& value)
218 {
219 Json::Value result(Json::objectValue);
220 result["type"] = "{{rootName}}.{{struct['name']}}";
221 result["value"] = _StoneSerializeValue(value);
222 return result;
223 }
224
225 #ifdef _MSC_VER
226 #pragma endregion {{struct['name']}}
227 #endif //_MSC_VER
228 {% endfor %}
229 #ifdef _MSC_VER
230 #pragma region Dispatching code
231 #endif //_MSC_VER
232
233 class IDispatcher
234 {
235 public:
236 {% for struct in structs%} virtual bool Handle(const {{struct['name']}}& value) = 0;
237 {% endfor %} };
238
239 /** Service function for StoneDispatchToHandler */
240 bool StoneDispatchJsonToHandler(
241 const Json::Value& jsonValue, IDispatcher* dispatcher)
242 {
243 StoneCheckSerializedValueTypeGeneric(jsonValue);
244 std::string type = jsonValue["type"].asString();
245 if (type == "")
246 {
247 // this should never ever happen
248 throw std::runtime_error("Caught empty type while dispatching");
249 }
250 {% for struct in structs%} else if (type == "{{rootName}}.{{struct['name']}}")
251 {
252 {{struct['name']}} value;
253 _StoneDeserializeValue(value, jsonValue["value"]);
254 return dispatcher->Handle(value);
255 }
256 {% endfor %} else
257 {
258 return false;
259 }
260 }
261
262 /** Takes a serialized type and passes this to the dispatcher */
263 bool StoneDispatchToHandler(std::string strValue, IDispatcher* dispatcher)
264 {
265 Json::Value readValue;
266
267 Json::CharReaderBuilder builder;
268 Json::CharReader* reader = builder.newCharReader();
269
270 StoneSmartPtr<Json::CharReader> ptr(reader);
271
272 std::string errors;
273
274 bool ok = reader->parse(
275 strValue.c_str(),
276 strValue.c_str() + strValue.size(),
277 &readValue,
278 &errors
279 );
280 if (!ok)
281 {
282 std::stringstream ss;
283 ss << "Jsoncpp parsing error: " << errors;
284 throw std::runtime_error(ss.str());
285 }
286 return StoneDispatchJsonToHandler(readValue, dispatcher);
287 }
288
289 #ifdef _MSC_VER
290 #pragma endregion Dispatching code
291 #endif //_MSC_VER
69 } 292 }