comparison Resources/CodeGeneration/template.in.h.j2 @ 515:1dbf2d9ed1e4 bgo-commands-codegen

Added .j2 extension to the Jinja2 template files to allow for a better syntax highlighting experience (a.o. in vscode)
author Benjamin Golinvaux <bgo@osimis.io>
date Mon, 11 Mar 2019 14:39:31 +0100
parents Resources/CodeGeneration/template.in.h@381144d2434f
children 17106b29ed6d
comparison
equal deleted inserted replaced
514:381144d2434f 515:1dbf2d9ed1e4
1 /*
2 1 2 3 4 5 6 7
3 12345678901234567890123456789012345678901234567890123456789012345678901234567890
4
5 Generated on {{currentDatetime}} by stonegentool
6
7 */
8 #pragma once
9
10 #include <exception>
11 #include <iostream>
12 #include <string>
13 #include <sstream>
14 #include <assert.h>
15 #include <memory>
16 #include <json/json.h>
17
18 //#define STONEGEN_NO_CPP11 1
19
20 #ifdef STONEGEN_NO_CPP11
21 #define StoneSmartPtr std::auto_ptr
22 #else
23 #define StoneSmartPtr std::unique_ptr
24 #endif
25
26 namespace {{rootName}}
27 {
28 /** Throws in case of problem */
29 inline void _StoneDeserializeValue(int32_t& destValue, const Json::Value& jsonValue)
30 {
31 destValue = jsonValue.asInt();
32 }
33
34 inline Json::Value _StoneSerializeValue(int32_t value)
35 {
36 Json::Value result(value);
37 return result;
38 }
39
40 inline void _StoneDeserializeValue(Json::Value& destValue, const Json::Value& jsonValue)
41 {
42 destValue = jsonValue;
43 }
44
45 inline Json::Value _StoneSerializeValue(Json::Value value)
46 {
47 return value;
48 }
49
50 /** Throws in case of problem */
51 inline void _StoneDeserializeValue(double& destValue, const Json::Value& jsonValue)
52 {
53 destValue = jsonValue.asDouble();
54 }
55
56 inline Json::Value _StoneSerializeValue(double value)
57 {
58 Json::Value result(value);
59 return result;
60 }
61
62 /** Throws in case of problem */
63 inline void _StoneDeserializeValue(bool& destValue, const Json::Value& jsonValue)
64 {
65 destValue = jsonValue.asBool();
66 }
67
68 inline Json::Value _StoneSerializeValue(bool value)
69 {
70 Json::Value result(value);
71 return result;
72 }
73
74 /** Throws in case of problem */
75 inline void _StoneDeserializeValue(
76 std::string& destValue
77 , const Json::Value& jsonValue)
78 {
79 destValue = jsonValue.asString();
80 }
81
82 inline Json::Value _StoneSerializeValue(const std::string& value)
83 {
84 // the following is better than
85 Json::Value result(value.data(),value.data()+value.size());
86 return result;
87 }
88
89 inline std::string MakeIndent(int indent)
90 {
91 char* txt = reinterpret_cast<char*>(malloc(indent+1)); // NO EXCEPTION BELOW!!!!!!!!!!!!
92 for(size_t i = 0; i < indent; ++i)
93 txt[i] = ' ';
94 txt[indent] = 0;
95 std::string retVal(txt);
96 free(txt); // NO EXCEPTION ABOVE !!!!!!!!!!
97 return retVal;
98 }
99
100 // generic dumper
101 template<typename T>
102 std::ostream& StoneDumpValue(std::ostream& out, const T& value, int indent)
103 {
104 out << MakeIndent(indent) << value;
105 return out;
106 }
107
108 // string dumper
109 inline std::ostream& StoneDumpValue(std::ostream& out, const std::string& value, int indent)
110 {
111 out << MakeIndent(indent) << "\"" << value << "\"";
112 return out;
113 }
114
115 /** Throws in case of problem */
116 template<typename T>
117 void _StoneDeserializeValue(
118 std::map<std::string, T>& destValue, const Json::Value& jsonValue)
119 {
120 destValue.clear();
121 for (
122 Json::Value::const_iterator itr = jsonValue.begin();
123 itr != jsonValue.end();
124 itr++)
125 {
126 std::string key;
127 _StoneDeserializeValue(key, itr.key());
128
129 T innerDestValue;
130 _StoneDeserializeValue(innerDestValue, *itr);
131
132 destValue[key] = innerDestValue;
133 }
134 }
135
136 template<typename T>
137 Json::Value _StoneSerializeValue(const std::map<std::string,T>& value)
138 {
139 Json::Value result(Json::objectValue);
140
141 for (typename std::map<std::string, T>::const_iterator it = value.cbegin();
142 it != value.cend(); ++it)
143 {
144 // it->first it->second
145 result[it->first] = _StoneSerializeValue(it->second);
146 }
147 return result;
148 }
149
150 template<typename T>
151 std::ostream& StoneDumpValue(std::ostream& out, const std::map<std::string,T>& value, int indent)
152 {
153 out << MakeIndent(indent) << "{\n";
154 for (typename std::map<std::string, T>::const_iterator it = value.cbegin();
155 it != value.cend(); ++it)
156 {
157 out << MakeIndent(indent+2) << "\"" << it->first << "\" : ";
158 StoneDumpValue(out, it->second, indent+2);
159 }
160 out << MakeIndent(indent) << "}\n";
161 return out;
162 }
163
164 /** Throws in case of problem */
165 template<typename T>
166 void _StoneDeserializeValue(
167 std::vector<T>& destValue, const Json::Value& jsonValue)
168 {
169 destValue.clear();
170 destValue.reserve(jsonValue.size());
171 for (Json::Value::ArrayIndex i = 0; i != jsonValue.size(); i++)
172 {
173 T innerDestValue;
174 _StoneDeserializeValue(innerDestValue, jsonValue[i]);
175 destValue.push_back(innerDestValue);
176 }
177 }
178
179 template<typename T>
180 Json::Value _StoneSerializeValue(const std::vector<T>& value)
181 {
182 Json::Value result(Json::arrayValue);
183 for (size_t i = 0; i < value.size(); ++i)
184 {
185 result.append(_StoneSerializeValue(value[i]));
186 }
187 return result;
188 }
189
190 template<typename T>
191 std::ostream& StoneDumpValue(std::ostream& out, const std::vector<T>& value, int indent)
192 {
193 out << MakeIndent(indent) << "[\n";
194 for (size_t i = 0; i < value.size(); ++i)
195 {
196 StoneDumpValue(out, value[i], indent+2);
197 }
198 out << MakeIndent(indent) << "]\n";
199 return out;
200 }
201
202 inline void StoneCheckSerializedValueTypeGeneric(const Json::Value& value)
203 {
204 if ((!value.isMember("type")) || (!value["type"].isString()))
205 {
206 std::stringstream ss;
207 ss << "Cannot deserialize value ('type' key invalid)";
208 throw std::runtime_error(ss.str());
209 }
210 }
211
212 inline void StoneCheckSerializedValueType(
213 const Json::Value& value, std::string typeStr)
214 {
215 StoneCheckSerializedValueTypeGeneric(value);
216
217 std::string actTypeStr = value["type"].asString();
218 if (actTypeStr != typeStr)
219 {
220 std::stringstream ss;
221 ss << "Cannot deserialize type" << actTypeStr
222 << "into " << typeStr;
223 throw std::runtime_error(ss.str());
224 }
225 }
226
227 // end of generic methods
228
229 // end of generic methods
230 {% for enum in enums%}
231 enum {{enum['name']}} {
232 {% for key in enum['fields']%} {{enum['name']}}_{{key}},
233 {%endfor%} };
234
235 inline void _StoneDeserializeValue(
236 {{enum['name']}}& destValue, const Json::Value& jsonValue)
237 {
238 destValue = static_cast<{{enum['name']}}>(jsonValue.asInt64());
239 }
240
241 inline Json::Value _StoneSerializeValue(const {{enum['name']}}& value)
242 {
243 return Json::Value(static_cast<int64_t>(value));
244 }
245
246 inline std::string ToString(const {{enum['name']}}& value)
247 {
248 {% for key in enum['fields']%} if( value == {{enum['name']}}_{{key}})
249 {
250 return std::string("{{key}}");
251 }
252 {%endfor%} std::stringstream ss;
253 ss << "Value \"" << value << "\" cannot be converted to {{enum['name']}}. Possible values are: "
254 {% for key in enum['fields']%} << " {{key}} = " << static_cast<int64_t>({{enum['name']}}_{{key}}) << ", "
255 {% endfor %} << std::endl;
256 std::string msg = ss.str();
257 throw std::runtime_error(msg);
258 }
259
260 inline void FromString({{enum['name']}}& value, std::string strValue)
261 {
262 {% for key in enum['fields']%} if( strValue == std::string("{{key}}") )
263 {
264 value = {{enum['name']}}_{{key}};
265 }
266 {%endfor%}
267 std::stringstream ss;
268 ss << "String \"" << strValue << "\" cannot be converted to {{enum['name']}}. Possible values are: {% for key in enum['fields']%}{{key}}{% endfor %}";
269 std::string msg = ss.str();
270 throw std::runtime_error(msg);
271 }
272
273 inline std::ostream& StoneDumpValue(std::ostream& out, const {{enum['name']}}& value, int indent = 0)
274 {
275 {% for key in enum['fields']%} if( value == {{enum['name']}}_{{key}})
276 {
277 out << MakeIndent(indent) << "{{key}}" << std::endl;
278 }
279 {%endfor%} return out;
280 }
281
282 {%endfor%}
283 {% for struct in structs%}
284 #ifdef _MSC_VER
285 #pragma region {{struct['name']}}
286 #endif //_MSC_VER
287
288 struct {{struct['name']}}
289 {
290 {% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} {{CanonToCpp(struct['fields'][key])}} {{key}};
291 {% endfor %}{% endif %}{% endif %}
292 {{struct['name']}}({% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%}{{CanonToCpp(struct['fields'][key])}} {{key}} = {{CanonToCpp(struct['fields'][key])}}(){{ ", " if not loop.last }}{% endfor %}{% endif %}{% endif %})
293 {
294 {% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} this->{{key}} = {{key}};
295 {% endfor %}{% endif %}{% endif %} }
296 };
297
298 inline void _StoneDeserializeValue({{struct['name']}}& destValue, const Json::Value& value)
299 {
300 {% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} _StoneDeserializeValue(destValue.{{key}}, value["{{key}}"]);
301 {% endfor %}{% endif %}{% endif %} }
302
303 inline Json::Value _StoneSerializeValue(const {{struct['name']}}& value)
304 {
305 Json::Value result(Json::objectValue);
306 {% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} result["{{key}}"] = _StoneSerializeValue(value.{{key}});
307 {% endfor %}{% endif %}{% endif %}
308 return result;
309 }
310
311 inline std::ostream& StoneDumpValue(std::ostream& out, const {{struct['name']}}& value, int indent = 0)
312 {
313 out << MakeIndent(indent) << "{\n";
314 {% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} out << MakeIndent(indent) << "{{key}}:\n";
315 StoneDumpValue(out, value.{{key}},indent+2);
316 out << "\n";
317 {% endfor %}{% endif %}{% endif %}
318 out << MakeIndent(indent) << "}\n";
319 return out;
320 }
321
322 inline void StoneDeserialize({{struct['name']}}& destValue, const Json::Value& value)
323 {
324 StoneCheckSerializedValueType(value, "{{rootName}}.{{struct['name']}}");
325 _StoneDeserializeValue(destValue, value["value"]);
326 }
327
328 inline Json::Value StoneSerializeToJson(const {{struct['name']}}& value)
329 {
330 Json::Value result(Json::objectValue);
331 result["type"] = "{{rootName}}.{{struct['name']}}";
332 result["value"] = _StoneSerializeValue(value);
333 return result;
334 }
335
336 inline std::string StoneSerialize(const {{struct['name']}}& value)
337 {
338 Json::Value resultJson = StoneSerializeToJson(value);
339 std::string resultStr = resultJson.toStyledString();
340 return resultStr;
341 }
342
343 #ifdef _MSC_VER
344 #pragma endregion {{struct['name']}}
345 #endif //_MSC_VER
346 {% endfor %}
347 #ifdef _MSC_VER
348 #pragma region Dispatching code
349 #endif //_MSC_VER
350
351 class IHandler
352 {
353 public:
354 {% for struct in structs%}{% if struct['__meta__'].handleInCpp %} virtual bool Handle(const {{struct['name']}}& value) = 0;
355 {% endif %}{% endfor %} };
356
357 /** Service function for StoneDispatchToHandler */
358 inline bool StoneDispatchJsonToHandler(
359 const Json::Value& jsonValue, IHandler* handler)
360 {
361 StoneCheckSerializedValueTypeGeneric(jsonValue);
362 std::string type = jsonValue["type"].asString();
363 if (type == "")
364 {
365 // this should never ever happen
366 throw std::runtime_error("Caught empty type while dispatching");
367 }
368 {% for struct in structs%}{% if struct['__meta__'].handleInCpp %} else if (type == "{{rootName}}.{{struct['name']}}")
369 {
370 {{struct['name']}} value;
371 _StoneDeserializeValue(value, jsonValue["value"]);
372 return handler->Handle(value);
373 }
374 {% endif %}{% endfor %} else
375 {
376 return false;
377 }
378 }
379
380 /** Takes a serialized type and passes this to the handler */
381 inline bool StoneDispatchToHandler(std::string strValue, IHandler* handler)
382 {
383 Json::Value readValue;
384
385 Json::CharReaderBuilder builder;
386 Json::CharReader* reader = builder.newCharReader();
387
388 StoneSmartPtr<Json::CharReader> ptr(reader);
389
390 std::string errors;
391
392 bool ok = reader->parse(
393 strValue.c_str(),
394 strValue.c_str() + strValue.size(),
395 &readValue,
396 &errors
397 );
398 if (!ok)
399 {
400 std::stringstream ss;
401 ss << "Jsoncpp parsing error: " << errors;
402 throw std::runtime_error(ss.str());
403 }
404 return StoneDispatchJsonToHandler(readValue, handler);
405 }
406
407 #ifdef _MSC_VER
408 #pragma endregion Dispatching code
409 #endif //_MSC_VER
410 }