Mercurial > hg > orthanc-stone
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 } |