/* */ #include "RpcResponse.h" #include #include #include "util.h" #include "json.h" #ifdef HAVE_ZLIB # include "GZipEncoder.h" #endif // HAVE_ZLIB namespace aria2 { namespace rpc { namespace { template void encodeValue(const SharedHandle& value, OutputStream& o) { class XmlValueBaseVisitor:public ValueBaseVisitor { private: OutputStream& o_; public: XmlValueBaseVisitor(OutputStream& o):o_(o) {} virtual ~XmlValueBaseVisitor() {} virtual void visit(const String& v) { o_ << "" << util::htmlEscape(v.s()) << ""; } virtual void visit(const Integer& v) { o_ << "" << v.i() << ""; } virtual void visit(const Bool& boolValue) {} virtual void visit(const Null& nullValue) {} virtual void visit(const List& v) { o_ << ""; for(List::ValueType::const_iterator i = v.begin(), eoi = v.end(); i != eoi; ++i) { (*i)->accept(*this); } o_ << ""; } virtual void visit(const Dict& v) { o_ << ""; for(Dict::ValueType::const_iterator i = v.begin(), eoi = v.end(); i != eoi; ++i) { o_ << "" << util::htmlEscape((*i).first) << ""; (*i).second->accept(*this); o_ << ""; } o_ << ""; } }; XmlValueBaseVisitor visitor(o); value->accept(visitor); } } // namespace namespace { template std::string encodeAll (OutputStream& o, int code, const SharedHandle& param) { o << "" << ""; if(code == 0) { o << "" << ""; encodeValue(param, o); o << "" << ""; } else { o << ""; encodeValue(param, o); o << ""; } o << ""; return o.str(); } } // namespace RpcResponse::RpcResponse (int code, const SharedHandle& param, const SharedHandle& id) : code(code), param(param), id(id) {} RpcResponse::RpcResponse(const RpcResponse& c) : code(c.code), param(c.param), id(c.id) {} RpcResponse::~RpcResponse() {} RpcResponse& RpcResponse::operator=(const RpcResponse& c) { if(this != &c) { code = c.code; param = c.param; } return *this; } std::string toXml(const RpcResponse& res, bool gzip) { if(gzip) { #ifdef HAVE_ZLIB GZipEncoder o; o.init(); return encodeAll(o, res.code, res.param); #else // !HAVE_ZLIB abort(); #endif // !HAVE_ZLIB } else { std::stringstream o; return encodeAll(o, res.code, res.param); } } namespace { template OutputStream& encodeJsonAll (OutputStream& o, int code, const SharedHandle& param, const SharedHandle& id, const std::string& callback = A2STR::NIL) { if(!callback.empty()) { o << callback << "("; } SharedHandle dict = Dict::g(); dict->put("jsonrpc", "2.0"); dict->put("id", id); if(code == 0) { dict->put("result", param); } else { dict->put("error", param); } json::encode(o, dict); if(!callback.empty()) { o << ")"; } return o; } } // namespace std::string toJson (const RpcResponse& res, const std::string& callback, bool gzip) { if(gzip) { #ifdef HAVE_ZLIB GZipEncoder o; o.init(); return encodeJsonAll(o, res.code, res.param, res.id, callback).str(); #else // !HAVE_ZLIB abort(); #endif // !HAVE_ZLIB } else { std::stringstream o; return encodeJsonAll(o, res.code, res.param, res.id, callback).str(); } } namespace { template OutputStream& encodeJsonBatchAll (OutputStream& o, const std::vector& results, const std::string& callback) { if(!callback.empty()) { o << callback << "("; } o << "["; if(!results.empty()) { encodeJsonAll(o, results[0].code, results[0].param, results[0].id); } for(std::vector::const_iterator i = results.begin()+1, eoi = results.end(); i != eoi; ++i) { o << ","; encodeJsonAll(o, (*i).code, (*i).param, (*i).id); } o << "]"; if(!callback.empty()) { o << ")"; } return o; } } // namespace std::string toJsonBatch (const std::vector& results, const std::string& callback, bool gzip) { if(gzip) { #ifdef HAVE_ZLIB GZipEncoder o; o.init(); return encodeJsonBatchAll(o, results, callback).str(); #else // !HAVE_ZLIB abort(); #endif // !HAVE_ZLIB } else { std::stringstream o; return encodeJsonBatchAll(o, results, callback).str(); } } } // namespace rpc } // namespace aria2