Mercurial > hg > orthanc-stone
diff Deprecated/Resources/CodeGeneration/template.in.h.j2 @ 1401:f6a2d46d2b76
moved CodeGeneration into Deprecated
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Wed, 29 Apr 2020 20:48:18 +0200 |
parents | Resources/CodeGeneration/template.in.h.j2@8a0a62189f46 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Deprecated/Resources/CodeGeneration/template.in.h.j2 Wed Apr 29 20:48:18 2020 +0200 @@ -0,0 +1,551 @@ +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 + +Generated on {{currentDatetime}} by stonegentool + +*/ +#pragma once + +#include <exception> +#include <iostream> +#include <string> +#include <sstream> +#include <assert.h> +#include <memory> +#include <set> +#include <json/json.h> + +//#define STONEGEN_NO_CPP11 1 + +#ifdef STONEGEN_NO_CPP11 +#define StoneSmartPtr std::unique_ptr +#else +#define StoneSmartPtr std::unique_ptr +#endif + +namespace {{rootName}} +{ + /** Throws in case of problem */ + inline void _StoneDeserializeValue(int32_t& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + destValue = jsonValue.asInt(); + } + } + + inline Json::Value _StoneSerializeValue(int32_t value) + { + Json::Value result(value); + return result; + } + + inline void _StoneDeserializeValue(int64_t& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + destValue = jsonValue.asInt64(); + } + } + + inline Json::Value _StoneSerializeValue(int64_t value) + { + Json::Value result(static_cast<Json::Value::Int64>(value)); + return result; + } + + inline void _StoneDeserializeValue(uint32_t& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + destValue = jsonValue.asUInt(); + } + } + + inline Json::Value _StoneSerializeValue(uint32_t value) + { + Json::Value result(value); + return result; + } + + inline void _StoneDeserializeValue(uint64_t& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + destValue = jsonValue.asUInt64(); + } + } + + inline Json::Value _StoneSerializeValue(uint64_t value) + { + Json::Value result(static_cast<Json::Value::UInt64>(value)); + return result; + } + + inline void _StoneDeserializeValue(Json::Value& destValue, const Json::Value& jsonValue) + { + destValue = jsonValue; + } + + inline Json::Value _StoneSerializeValue(Json::Value value) + { + return value; + } + + /** Throws in case of problem */ + inline void _StoneDeserializeValue(double& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + destValue = jsonValue.asDouble(); + } + } + + inline Json::Value _StoneSerializeValue(double value) + { + Json::Value result(value); + return result; + } + + /** Throws in case of problem */ + inline void _StoneDeserializeValue(float& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + destValue = jsonValue.asFloat(); + } + } + + inline Json::Value _StoneSerializeValue(float value) + { + Json::Value result(value); + return result; + } + + /** Throws in case of problem */ + inline void _StoneDeserializeValue(bool& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + destValue = jsonValue.asBool(); + } + } + + inline Json::Value _StoneSerializeValue(bool value) + { + Json::Value result(value); + return result; + } + + /** Throws in case of problem */ + inline void _StoneDeserializeValue( + std::string& destValue + , const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + destValue = jsonValue.asString(); + } + } + + inline Json::Value _StoneSerializeValue(const std::string& value) + { + // the following is better than + Json::Value result(value.data(),value.data()+value.size()); + return result; + } + + inline std::string MakeIndent(size_t indent) + { + char* txt = reinterpret_cast<char*>(malloc(indent+1)); // NO EXCEPTION BELOW!!!!!!!!!!!! + for(size_t i = 0; i < indent; ++i) + txt[i] = ' '; + txt[indent] = 0; + std::string retVal(txt); + free(txt); // NO EXCEPTION ABOVE !!!!!!!!!! + return retVal; + } + + // generic dumper + template<typename T> + std::ostream& StoneDumpValue(std::ostream& out, const T& value, size_t indent) + { + out << MakeIndent(indent) << value; + return out; + } + + // string dumper + inline std::ostream& StoneDumpValue(std::ostream& out, const std::string& value, size_t indent) + { + out << MakeIndent(indent) << "\"" << value << "\""; + return out; + } + + inline std::string ToString(const std::string& str) + { + return str; + } + + inline void FromString(std::string& value, std::string strValue) + { + value = strValue; + } + + + /** Throws in case of problem */ + template<typename TK, typename TV> + void _StoneDeserializeValue( + std::map<TK, TV>& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + destValue.clear(); + for ( + Json::Value::const_iterator itr = jsonValue.begin(); + itr != jsonValue.end(); + itr++) + { + std::string strKey; + _StoneDeserializeValue(strKey, itr.key()); + TK key; + FromString(key, strKey); // if you have a compile error here, it means that your type is not suitable to be the key of a map (or you should overwrite the FromString/ToString in template.in.h.j2) + + TV innerDestValue; + _StoneDeserializeValue(innerDestValue, *itr); + + destValue[key] = innerDestValue; + } + } + } + + template<typename TK, typename TV> + Json::Value _StoneSerializeValue(const std::map<TK, TV>& value) + { + Json::Value result(Json::objectValue); + + for (typename std::map<TK, TV>::const_iterator it = value.cbegin(); + it != value.cend(); ++it) + { + // it->first it->second + result[ToString(it->first)] = _StoneSerializeValue(it->second); + } + return result; + } + + template<typename TK, typename TV> + std::ostream& StoneDumpValue(std::ostream& out, const std::map<TK, TV>& value, size_t indent) + { + out << MakeIndent(indent) << "{\n"; + for (typename std::map<TK, TV>::const_iterator it = value.cbegin(); + it != value.cend(); ++it) + { + out << MakeIndent(indent+2) << "\"" << it->first << "\" : "; + StoneDumpValue(out, it->second, indent+2); + out << ", \n"; + } + out << MakeIndent(indent) << "}\n"; + return out; + } + + /** Throws in case of problem */ + template<typename T> + void _StoneDeserializeValue( + std::vector<T>& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull() && jsonValue.isArray()) + { + destValue.clear(); + destValue.reserve(jsonValue.size()); + for (Json::Value::ArrayIndex i = 0; i != jsonValue.size(); i++) + { + T innerDestValue; + _StoneDeserializeValue(innerDestValue, jsonValue[i]); + destValue.push_back(innerDestValue); + } + } + } + + template<typename T> + Json::Value _StoneSerializeValue(const std::vector<T>& value) + { + Json::Value result(Json::arrayValue); + for (size_t i = 0; i < value.size(); ++i) + { + result.append(_StoneSerializeValue(value[i])); + } + return result; + } + + template<typename T> + std::ostream& StoneDumpValue(std::ostream& out, const std::vector<T>& value, size_t indent) + { + out << MakeIndent(indent) << "[\n"; + for (size_t i = 0; i < value.size(); ++i) + { + StoneDumpValue(out, value[i], indent+2); + out << ", \n"; + } + out << MakeIndent(indent) << "]\n"; + return out; + } + + /** Throws in case of problem */ + template<typename T> + void _StoneDeserializeValue( + std::set<T>& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull() && jsonValue.isArray()) + { + destValue.clear(); + for (Json::Value::ArrayIndex i = 0; i != jsonValue.size(); i++) + { + T innerDestValue; + _StoneDeserializeValue(innerDestValue, jsonValue[i]); + destValue.insert(innerDestValue); + } + } + } + + template<typename T> + Json::Value _StoneSerializeValue(const std::set<T>& value) + { + Json::Value result(Json::arrayValue); + for (typename std::set<T>::const_iterator it = value.begin(); it != value.end(); ++it) + { + result.append(_StoneSerializeValue(*it)); + } + return result; + } + + template<typename T> + std::ostream& StoneDumpValue(std::ostream& out, const std::set<T>& value, size_t indent) + { + out << MakeIndent(indent) << "[\n"; + for (typename std::set<T>::const_iterator it = value.begin(); it != value.end(); ++it) + { + StoneDumpValue(out, *it, indent+2); + out << ", \n"; + } + out << MakeIndent(indent) << "]\n"; + return out; + } + + inline void StoneCheckSerializedValueTypeGeneric(const Json::Value& value) + { + if ((!value.isMember("type")) || (!value["type"].isString())) + { + std::stringstream ss; + ss << "Cannot deserialize value ('type' key invalid)"; + throw std::runtime_error(ss.str()); + } + } + + inline void StoneCheckSerializedValueType( + const Json::Value& value, std::string typeStr) + { + StoneCheckSerializedValueTypeGeneric(value); + + std::string actTypeStr = value["type"].asString(); + if (actTypeStr != typeStr) + { + std::stringstream ss; + ss << "Cannot deserialize type" << actTypeStr + << "into " << typeStr; + throw std::runtime_error(ss.str()); + } + } + + // end of generic methods + +// end of generic methods +{% for enum in enums%} + enum {{enum['name']}} { +{% for key in enum['fields']%} {{enum['name']}}_{{key}}, +{%endfor%} }; + + inline std::string ToString(const {{enum['name']}}& value) + { +{% for key in enum['fields']%} if( value == {{enum['name']}}_{{key}}) + { + return std::string("{{key}}"); + } +{%endfor%} std::stringstream ss; + ss << "Value \"" << value << "\" cannot be converted to {{enum['name']}}. Possible values are: " +{% for key in enum['fields']%} << " {{key}} = " << static_cast<int64_t>({{enum['name']}}_{{key}}) << ", " +{% endfor %} << std::endl; + std::string msg = ss.str(); + throw std::runtime_error(msg); + } + + inline void FromString({{enum['name']}}& value, std::string strValue) + { +{% for key in enum['fields']%} if( strValue == std::string("{{key}}") ) + { + value = {{enum['name']}}_{{key}}; + return; + } +{%endfor%} + std::stringstream ss; + ss << "String \"" << strValue << "\" cannot be converted to {{enum['name']}}. Possible values are: {% for key in enum['fields']%}{{key}} {% endfor %}"; + std::string msg = ss.str(); + throw std::runtime_error(msg); + } + + + inline void _StoneDeserializeValue( + {{enum['name']}}& destValue, const Json::Value& jsonValue) + { + if (!jsonValue.isNull()) + { + FromString(destValue, jsonValue.asString()); + } + } + + inline Json::Value _StoneSerializeValue(const {{enum['name']}}& value) + { + std::string strValue = ToString(value); + return Json::Value(strValue); + } + + inline std::ostream& StoneDumpValue(std::ostream& out, const {{enum['name']}}& value, size_t indent = 0) + { +{% for key in enum['fields']%} if( value == {{enum['name']}}_{{key}}) + { + out << MakeIndent(indent) << "{{key}}"; + } +{%endfor%} return out; + } + +{%endfor%} +{% for struct in structs%} +#ifdef _MSC_VER +#pragma region {{struct['name']}} +#endif //_MSC_VER + + struct {{struct['name']}} + { +{% if struct %}{% if struct['fields'] %}{% for key in struct['fields'] %} {{CanonToCpp(struct['fields'][key]['type'])}} {{key}}; +{% endfor %}{% endif %}{% endif %} + {{struct['name']}}({% if struct %}{% if struct['fields'] %}{% for key in struct['fields'] %}{{CanonToCpp(struct['fields'][key]['type'])}} {{key}} = {% if struct['fields'][key]['defaultValue'] %}{{DefaultValueToCpp(rootName,enums,struct['fields'][key])}} {%else%} {{CanonToCpp(struct['fields'][key]['type'])}}() {%endif%} {{ ", " if not loop.last }}{% endfor %}{% endif %}{% endif %}) + { +{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} this->{{key}} = {{key}}; +{% endfor %}{% endif %}{% endif %} } + }; + + inline void _StoneDeserializeValue({{struct['name']}}& destValue, const Json::Value& value) + { + if (!value.isNull()) + { +{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} _StoneDeserializeValue(destValue.{{key}}, value["{{key}}"]); +{% endfor %}{% endif %}{% endif %} } + } + + inline Json::Value _StoneSerializeValue(const {{struct['name']}}& value) + { + Json::Value result(Json::objectValue); +{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} result["{{key}}"] = _StoneSerializeValue(value.{{key}}); +{% endfor %}{% endif %}{% endif %} + return result; + } + + inline std::ostream& StoneDumpValue(std::ostream& out, const {{struct['name']}}& value, size_t indent = 0) + { + out << MakeIndent(indent) << "{\n"; +{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} out << MakeIndent(indent+2) << "{{key}}: "; + StoneDumpValue(out, value.{{key}},indent+2); + out << ", \n"; +{% endfor %}{% endif %}{% endif %} + out << MakeIndent(indent) << "}"; + return out; + } + + inline void StoneDeserialize({{struct['name']}}& destValue, const Json::Value& value) + { + StoneCheckSerializedValueType(value, "{{rootName}}.{{struct['name']}}"); + _StoneDeserializeValue(destValue, value["value"]); + } + + inline Json::Value StoneSerializeToJson(const {{struct['name']}}& value) + { + Json::Value result(Json::objectValue); + result["type"] = "{{rootName}}.{{struct['name']}}"; + result["value"] = _StoneSerializeValue(value); + return result; + } + + inline std::string StoneSerialize(const {{struct['name']}}& value) + { + Json::Value resultJson = StoneSerializeToJson(value); + std::string resultStr = resultJson.toStyledString(); + return resultStr; + } + +#ifdef _MSC_VER +#pragma endregion {{struct['name']}} +#endif //_MSC_VER +{% endfor %} +#ifdef _MSC_VER +#pragma region Dispatching code +#endif //_MSC_VER + + class IHandler + { + public: +{% for struct in structs%}{% if struct['__meta__'].handleInCpp %} virtual bool Handle(const {{struct['name']}}& value) = 0; +{% endif %}{% endfor %} }; + + /** Service function for StoneDispatchToHandler */ + inline bool StoneDispatchJsonToHandler( + const Json::Value& jsonValue, IHandler* handler) + { + StoneCheckSerializedValueTypeGeneric(jsonValue); + std::string type = jsonValue["type"].asString(); + if (type == "") + { + // this should never ever happen + throw std::runtime_error("Caught empty type while dispatching"); + } +{% for struct in structs%}{% if struct['__meta__'].handleInCpp %} else if (type == "{{rootName}}.{{struct['name']}}") + { + {{struct['name']}} value; + _StoneDeserializeValue(value, jsonValue["value"]); + return handler->Handle(value); + } +{% endif %}{% endfor %} else + { + return false; + } + } + + /** Takes a serialized type and passes this to the handler */ + inline bool StoneDispatchToHandler(std::string strValue, IHandler* handler) + { + Json::Value readValue; + + Json::CharReaderBuilder builder; + Json::CharReader* reader = builder.newCharReader(); + + StoneSmartPtr<Json::CharReader> ptr(reader); + + std::string errors; + + bool ok = reader->parse( + strValue.c_str(), + strValue.c_str() + strValue.size(), + &readValue, + &errors + ); + if (!ok) + { + std::stringstream ss; + ss << "Jsoncpp parsing error: " << errors; + throw std::runtime_error(ss.str()); + } + return StoneDispatchJsonToHandler(readValue, handler); + } + +#ifdef _MSC_VER +#pragma endregion Dispatching code +#endif //_MSC_VER +}