![]() |
RTBKit
0.9
Open-source framework to create real-time ad bidding systems.
|
00001 /* json_printing.h -*- C++ -*- 00002 Jeremy Barnes, 26 February 2013 00003 Copyright (c) 2013 Datacratic Inc. All rights reserved. 00004 00005 Context to print out JSON. 00006 */ 00007 00008 #pragma once 00009 00010 #include "json_parsing.h" 00011 #include "jml/utils/exc_assert.h" 00012 #include <boost/algorithm/string.hpp> 00013 #include <string> 00014 00015 00016 namespace Datacratic { 00017 00018 00019 /*****************************************************************************/ 00020 /* JSON PRINTING CONTEXT */ 00021 /*****************************************************************************/ 00022 00023 struct JsonPrintingContext { 00024 00025 virtual ~JsonPrintingContext() 00026 { 00027 } 00028 00029 virtual void startObject() = 0; 00030 virtual void startMember(const std::string & memberName) = 0; 00031 virtual void endObject() = 0; 00032 00033 virtual void startArray(int knownSize = -1) = 0; 00034 virtual void newArrayElement() = 0; 00035 virtual void endArray() = 0; 00036 00037 virtual void writeInt(int i) = 0; 00038 virtual void writeFloat(float f) = 0; 00039 virtual void writeDouble(double d) = 0; 00040 virtual void writeString(const std::string & s) = 0; 00041 virtual void writeStringUtf8(const Utf8String & s) = 0; 00042 virtual void writeBool(bool b) = 0; 00043 virtual void writeNull() = 0; 00044 00045 virtual void writeJson(const Json::Value & val) = 0; 00046 virtual void skip() = 0; 00047 }; 00048 00049 00050 /*****************************************************************************/ 00051 /* STREAM JSON PRINTING CONTEXT */ 00052 /*****************************************************************************/ 00053 00054 struct StreamJsonPrintingContext 00055 : public JsonPrintingContext { 00056 00057 StreamJsonPrintingContext(std::ostream & stream) 00058 : stream(stream), writeUtf8(true) 00059 { 00060 } 00061 00062 std::ostream & stream; 00063 bool writeUtf8; 00064 00065 struct PathEntry { 00066 PathEntry(bool isObject) 00067 : isObject(isObject), memberNum(-1) 00068 { 00069 } 00070 00071 bool isObject; 00072 std::string memberName; 00073 int memberNum; 00074 }; 00075 00076 std::vector<PathEntry> path; 00077 00078 virtual void startObject() 00079 { 00080 path.push_back(true /* isObject */); 00081 stream << "{"; 00082 } 00083 00084 virtual void startMember(const std::string & memberName) 00085 { 00086 ExcAssert(path.back().isObject); 00087 //path.back().memberName = memberName; 00088 ++path.back().memberNum; 00089 if (path.back().memberNum != 0) 00090 stream << ","; 00091 stream << '\"'; 00092 ML::jsonEscape(memberName, stream); 00093 stream << "\":"; 00094 } 00095 00096 virtual void endObject() 00097 { 00098 ExcAssert(path.back().isObject); 00099 path.pop_back(); 00100 stream << "}"; 00101 } 00102 00103 virtual void startArray(int knownSize = -1) 00104 { 00105 path.push_back(false /* isObject */); 00106 stream << "["; 00107 } 00108 00109 virtual void newArrayElement() 00110 { 00111 ExcAssert(!path.back().isObject); 00112 ++path.back().memberNum; 00113 if (path.back().memberNum != 0) 00114 stream << ","; 00115 } 00116 00117 virtual void endArray() 00118 { 00119 ExcAssert(!path.back().isObject); 00120 path.pop_back(); 00121 stream << "]"; 00122 } 00123 00124 virtual void skip() 00125 { 00126 stream << "null"; 00127 } 00128 00129 virtual void writeNull() 00130 { 00131 stream << "null"; 00132 } 00133 00134 virtual void writeInt(int i) 00135 { 00136 stream << i; 00137 } 00138 00139 virtual void writeFloat(float f) 00140 { 00141 stream << f; 00142 } 00143 00144 virtual void writeDouble(double d) 00145 { 00146 stream << d; 00147 } 00148 00149 virtual void writeString(const std::string & s) 00150 { 00151 stream << '\"'; 00152 ML::jsonEscape(s, stream); 00153 stream << '\"'; 00154 } 00155 00156 virtual void writeStringUtf8(const Utf8String & s); 00157 00158 virtual void writeJson(const Json::Value & val) 00159 { 00160 stream << boost::trim_copy(val.toString()); 00161 } 00162 00163 virtual void writeBool(bool b) 00164 { 00165 stream << (b ? "true": "false"); 00166 } 00167 00168 }; 00169 00170 00171 /*****************************************************************************/ 00172 /* STRUCTURED JSON PRINTING CONTEXT */ 00173 /*****************************************************************************/ 00174 00177 struct StructuredJsonPrintingContext 00178 : public JsonPrintingContext { 00179 00180 Json::Value output; 00181 Json::Value * current; 00182 00183 StructuredJsonPrintingContext() 00184 : current(&output) 00185 { 00186 } 00187 00188 std::vector<Json::Value *> path; 00189 00190 virtual void startObject() 00191 { 00192 *current = Json::Value(Json::objectValue); 00193 path.push_back(current); 00194 } 00195 00196 virtual void startMember(const std::string & memberName) 00197 { 00198 current = &(*path.back())[memberName]; 00199 } 00200 00201 virtual void endObject() 00202 { 00203 path.pop_back(); 00204 } 00205 00206 virtual void startArray(int knownSize = -1) 00207 { 00208 *current = Json::Value(Json::arrayValue); 00209 path.push_back(current); 00210 } 00211 00212 virtual void newArrayElement() 00213 { 00214 Json::Value & b = *path.back(); 00215 current = &b[b.size()]; 00216 } 00217 00218 virtual void endArray() 00219 { 00220 path.pop_back(); 00221 } 00222 00223 virtual void skip() 00224 { 00225 *current = Json::Value(); 00226 } 00227 00228 virtual void writeNull() 00229 { 00230 *current = Json::Value(); 00231 } 00232 00233 virtual void writeInt(int i) 00234 { 00235 *current = i; 00236 } 00237 00238 virtual void writeFloat(float f) 00239 { 00240 *current = f; 00241 } 00242 00243 virtual void writeDouble(double d) 00244 { 00245 *current = d; 00246 } 00247 00248 virtual void writeString(const std::string & s) 00249 { 00250 *current = s; 00251 } 00252 00253 virtual void writeStringUtf8(const Utf8String & s) 00254 { 00255 *current = s; 00256 } 00257 00258 virtual void writeJson(const Json::Value & val) 00259 { 00260 *current = val; 00261 } 00262 00263 virtual void writeBool(bool b) 00264 { 00265 *current = b; 00266 } 00267 }; 00268 00269 } // namespace Datacratic 00270