diff options
author | randomdan <randomdan@localhost> | 2011-11-29 10:50:18 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2011-11-29 10:50:18 +0000 |
commit | 35278c38ab37293164cb195a3983b1568c07f8ef (patch) | |
tree | 4c732ea449b2f56514a0a8c735cbce9fda6b00c3 | |
parent | Add missing type changes (diff) | |
download | project2-35278c38ab37293164cb195a3983b1568c07f8ef.tar.bz2 project2-35278c38ab37293164cb195a3983b1568c07f8ef.tar.xz project2-35278c38ab37293164cb195a3983b1568c07f8ef.zip |
Make ContentPresenter a mix-in
Add a JSON presenter
Fix minor bugs in JSON serializer highlighter by new presenter
-rw-r--r-- | project2/cgi/cgiStagePresent.cpp | 4 | ||||
-rw-r--r-- | project2/common/presenter.h | 2 | ||||
-rw-r--r-- | project2/json/presenter.cpp | 52 | ||||
-rw-r--r-- | project2/json/serialize.cpp | 51 | ||||
-rw-r--r-- | project2/json/transformStream.cpp | 17 | ||||
-rw-r--r-- | project2/xml/xmlPresenter.h | 2 |
6 files changed, 113 insertions, 15 deletions
diff --git a/project2/cgi/cgiStagePresent.cpp b/project2/cgi/cgiStagePresent.cpp index f1fd5e3..d8af5d9 100644 --- a/project2/cgi/cgiStagePresent.cpp +++ b/project2/cgi/cgiStagePresent.cpp @@ -37,8 +37,8 @@ CgiApplicationEngine::ResponseStage::ResponseStage(const CgiEnvironment * e) : CgiApplicationEngine::HttpHeaderPtr CgiApplicationEngine::PresentStage::getHeader() const { - ContentPresenter * cp = boost::dynamic_pointer_cast<ContentPresenter>(presenter).get(); - Project2HttpHeader * header = new Project2HttpHeader("200 OK", cp ? cp->contentType : "text/plain"); + const ContentPresenter * cp = dynamic_cast<const ContentPresenter *>(presenter.get()); + Project2HttpHeader * header = new Project2HttpHeader("200 OK", cp ? cp->contentType : "text/plain; charset=UTF-8"); header->addHeader("Cache-control", "no-cache"); return HttpHeaderPtr(header); } diff --git a/project2/common/presenter.h b/project2/common/presenter.h index f7f447e..6a72495 100644 --- a/project2/common/presenter.h +++ b/project2/common/presenter.h @@ -62,7 +62,7 @@ class Presenter : public MultiRowSetPresenter { void finishRowSet() const; }; -class ContentPresenter : public Presenter { +class ContentPresenter { public: ContentPresenter(const Glib::ustring & contentType); const Glib::ustring contentType; 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); + + diff --git a/project2/xml/xmlPresenter.h b/project2/xml/xmlPresenter.h index bfb3375..4f3fdbb 100644 --- a/project2/xml/xmlPresenter.h +++ b/project2/xml/xmlPresenter.h @@ -8,7 +8,7 @@ namespace xmlpp { class Document; } -class XmlPresenter : public ContentPresenter, public SourceOf<xmlpp::Document>, public SourceOf<xmlDoc>, public SourceOf<boost::shared_ptr<xmlpp::Document> > { +class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf<xmlpp::Document>, public SourceOf<xmlDoc>, public SourceOf<boost::shared_ptr<xmlpp::Document> > { public: typedef boost::shared_ptr<xmlpp::Document> XmlDocumentPtr; XmlPresenter(const Glib::ustring & responseRootNodeName, const Glib::ustring & responseStyle, const Glib::ustring & contentType); |