diff options
Diffstat (limited to 'project2/json')
-rw-r--r-- | project2/json/presenter.cpp | 52 | ||||
-rw-r--r-- | project2/json/serialize.cpp | 51 | ||||
-rw-r--r-- | project2/json/transformStream.cpp | 17 |
3 files changed, 109 insertions, 11 deletions
diff --git a/project2/json/presenter.cpp b/project2/json/presenter.cpp new file mode 100644 index 0000000..25849b2 --- /dev/null +++ b/project2/json/presenter.cpp @@ -0,0 +1,52 @@ +#include "pch.hpp" +#include "logger.h" +#include "../common/presenter.h" +#include "json.h" +#include "conversion.h" +#include "transform.h" +#include <stack> + +class JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, public SourceOf<json::Object> { + public: + JsonPresenter(const xmlpp::Element *) : + ContentPresenter("application/json; charset=UTF-8") { + curRowSet.push(&object); + } + void addNamedValue(const Glib::ustring & name, const VariableType & value) const { + (*curRowSet.top())[name] = json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value))); + } + void addNewRow(const Glib::ustring & name) const { + if (!curRowArray.top()) { + json::Value * v = new json::Value(json::Array()); + curRowArray.top() = boost::get<json::Array>(v); + (*curRowSet.top())[name] = json::ValuePtr(v); + } + json::Value * v = new json::Value(json::Object()); + curRowSet.push(boost::get<json::Object>(v)); + curRowArray.top()->push_back(json::ValuePtr(v)); + } + void finishRow() const { + curRowSet.pop(); + } + void addNewRowSet(const Glib::ustring & name) const { + json::Value * v = new json::Value(json::Object()); + (*curRowSet.top())[name] = json::ValuePtr(v); + curRowSet.push(boost::get<json::Object>(v)); + curRowArray.push(NULL); + } + void addNewRowSet(const Glib::ustring & name, const Glib::ustring & ns) const { + addNewRowSet(ns + ":" + name); + } + void finishRowSet() const { + curRowArray.pop(); + curRowSet.pop(); + } + operator const json::Object *() const { + return &object; + } + private: + mutable json::Object object; + mutable std::stack<json::Object *> curRowSet; + mutable std::stack<json::Array *> curRowArray; +}; +DECLARE_COMPONENT_LOADER("json", JsonPresenter, PresenterLoader) diff --git a/project2/json/serialize.cpp b/project2/json/serialize.cpp index f3245e9..5b9deb9 100644 --- a/project2/json/serialize.cpp +++ b/project2/json/serialize.cpp @@ -50,23 +50,52 @@ namespace json { if (&v != &*a.begin()) { s += ','; } - serializeValue(v, s); + serializeValue(*v, s); } s += ']'; } void serializeString(const String & str, Glib::ustring & s) { s += '"'; BOOST_FOREACH(gunichar c, str) { - switch (c) { - case '\\': - s += "\\\\"; - break; - case '"': - s += "\\\""; - break; - default: - s += c; - break; + if (c < 32) { + switch (c) { + case '\f': + s += "\\f"; + break; + case '\t': + s += "\\t"; + break; + case '\n': + s += "\\n"; + break; + case '\b': + s += "\\b"; + break; + case '\r': + s += "\\r"; + break; + default: + char buf[7]; + snprintf(buf, sizeof(buf), "\\u%04x", c); + s += buf; + break; + } + } + else { + switch (c) { + case '/': + s += "\\/"; + break; + case '\\': + s += "\\\\"; + break; + case '"': + s += "\\\""; + break; + default: + s += c; + break; + } } } s += '"'; diff --git a/project2/json/transformStream.cpp b/project2/json/transformStream.cpp new file mode 100644 index 0000000..f9537ea --- /dev/null +++ b/project2/json/transformStream.cpp @@ -0,0 +1,17 @@ +#include <pch.hpp> +#include "transform.h" +#include "logger.h" +#include "json.h" +#include "ostreamWrapper.h" + +class TransformJsonToHttpStream : public TransformImpl<json::Object, ostreamWrapper> { + public: + void transform(const json::Object * obj, ostreamWrapper * o) const + { + Glib::ustring str = json::serializeObject(*obj); + o->strm << str.raw(); + } +}; +DECLARE_TRANSFORM(TransformJsonToHttpStream); + + |