RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
soa/service/json_codec.h
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
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator