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