RTBKit
0.9
Open-source framework to create real-time ad bidding systems.
|
00001 /* json_codec.h -*- C++ -*- 00002 Jeremy Banres, 26 November 2012 00003 Copyright (c) 2012 Datacratic. All rights reserved. 00004 00005 JSON encoding/decodign code. 00006 */ 00007 00008 #pragma once 00009 00010 #include "soa/jsoncpp/json.h" 00011 #include <vector> 00012 #include <map> 00013 #include <unordered_map> 00014 #include "jml/utils/exc_assert.h" 00015 00016 namespace Datacratic { 00017 00018 // Define JSON encodability for default types 00019 00020 #define DO_JSON_ENCODABLE(T, extract) \ 00021 inline Json::Value jsonEncode(const T & obj) { return Json::Value(obj); } \ 00022 inline T jsonDecode(const Json::Value & j, T * = 0) { return j.extract(); } 00023 00024 DO_JSON_ENCODABLE(std::string, asString); 00025 DO_JSON_ENCODABLE(unsigned int, asInt); 00026 DO_JSON_ENCODABLE(signed int, asUInt); 00027 DO_JSON_ENCODABLE(short unsigned int, asInt); 00028 DO_JSON_ENCODABLE(short signed int, asUInt); 00029 DO_JSON_ENCODABLE(long unsigned int, asInt); 00030 DO_JSON_ENCODABLE(long signed int, asUInt); 00031 DO_JSON_ENCODABLE(long long unsigned int, asInt); 00032 DO_JSON_ENCODABLE(long long signed int, asUInt); 00033 DO_JSON_ENCODABLE(bool, asBool); 00034 DO_JSON_ENCODABLE(double, asDouble); 00035 DO_JSON_ENCODABLE(float, asDouble); 00036 00037 inline Json::Value jsonEncode(Json::Value v) 00038 { 00039 return v; 00040 } 00041 00042 inline Json::Value jsonDecode(Json::Value v, Json::Value * = 0) 00043 { 00044 return v; 00045 } 00046 00047 // Anything with a toJson() method gets to be jsonEncoded 00048 template<typename T> 00049 Json::Value jsonEncode(const T & obj, 00050 decltype(std::declval<T>().toJson()) * = 0) 00051 { 00052 return obj.toJson(); 00053 } 00054 00055 // Anything with a static fromJson() method gets to be jsonDecoded 00056 template<typename T> 00057 T jsonDecode(const Json::Value & json, T * = 0, 00058 decltype(T::fromJson(std::declval<Json::Value>())) * = 0) 00059 { 00060 return T::fromJson(json); 00061 } 00062 00063 template<typename T> 00064 Json::Value jsonEncode(const std::vector<T> & vec) 00065 { 00066 Json::Value result(Json::arrayValue); 00067 for (unsigned i = 0; i < vec.size(); ++i) 00068 result[i] = jsonEncode(vec[i]); 00069 return result; 00070 } 00071 00072 template<typename T> 00073 std::vector<T> jsonDecode(const Json::Value & val, std::vector<T> *) 00074 { 00075 ExcAssert(val.isArray()); 00076 std::vector<T> res; 00077 res.reserve(val.size()); 00078 for (unsigned i = 0; i < val.size(); ++i) 00079 res.push_back(jsonDecode(val[i], (T*)0)); 00080 return res; 00081 } 00082 00083 template<typename T> 00084 Json::Value jsonEncode(const std::map<std::string, T> & m) 00085 { 00086 Json::Value result(Json::objectValue); 00087 for (auto & e: m) 00088 result[m.first] = jsonEncode(m.second); 00089 return result; 00090 } 00091 00092 template<typename T> 00093 std::map<std::string, T> 00094 jsonDecode(const Json::Value & val, std::map<std::string, T> *) 00095 { 00096 std::map<std::string, T> res; 00097 if (val.isNull()) 00098 return res; 00099 00100 ExcAssert(val.isObject()); 00101 00102 for (auto it = val.begin(), end = val.end(); it != end; ++it) 00103 res.emplace(it.memberName(), jsonDecode(*it, (T *)0)); 00104 00105 return res; 00106 } 00107 00108 template<typename T> 00109 Json::Value jsonEncode(const std::unordered_map<std::string, T> & m) 00110 { 00111 Json::Value result(Json::objectValue); 00112 for (auto & e: m) 00113 result[m.first] = jsonEncode(m.second); 00114 return result; 00115 } 00116 00117 template<typename T> 00118 std::unordered_map<std::string, T> 00119 jsonDecode(const Json::Value & val, std::unordered_map<std::string, T> *) 00120 { 00121 std::unordered_map<std::string, T> res; 00122 if (val.isNull()) 00123 return res; 00124 00125 ExcAssert(val.isObject()); 00126 00127 for (auto it = val.begin(), end = val.end(); it != end; ++it) 00128 res.insert(std::make_pair(it.memberName(), jsonDecode(*it, (T *)0))); 00129 00130 return res; 00131 } 00132 00133 template<typename T, typename Enable = void> 00134 struct JsonCodec { 00135 static T decode(const Json::Value & val) 00136 { 00137 return jsonDecode(val, (T *)0); 00138 } 00139 00140 static Json::Value encode(const T & val) 00141 { 00142 return jsonEncode(val); 00143 } 00144 }; 00145 00146 template<typename T> 00147 void getParam(const Json::Value & parameters, 00148 T & val, 00149 const std::string & name) 00150 { 00151 if (parameters.isMember(name)) { 00152 Json::Value j = parameters[name]; 00153 if (j.isNull()) 00154 return; 00155 val = jsonDecode(j, &val); 00156 } 00157 } 00158 00159 // In place JSON decoding 00160 template<typename T> 00161 void jsonDecode(const Json::Value & json, T & val) 00162 { 00163 val = jsonDecode(json, (T *)0); 00164 } 00165 00166 00167 } // namespace Datacratic