+ PING,
+ PONG,
+ DATA
+};
+
+std::map<std::string, Packet> packetCodes;
+std::map<std::string, bool> resultCodes;
+
+class PacketParser : public EnumParser<Packet>
+{
+ public:
+ PacketParser(NodeParser* next, Packet& packet, std::string& packetStr)
+ : EnumParser(next, packet, packetStr, packetCodes)
+ {
+ if (!packetCodes.empty())
+ return;
+ packetCodes["ping"] = PING;
+ packetCodes["pong"] = PONG;
+ packetCodes["data"] = DATA;
+ }
+};
+
+class ResultParser : public EnumParser<bool>
+{
+ public:
+ ResultParser(NodeParser* next, bool& result, std::string& resultStr)
+ : EnumParser(next, result, resultStr, resultCodes)
+ {
+ if (!resultCodes.empty())
+ return;
+ resultCodes["no"] = false;
+ resultCodes["ok"] = true;
+ }
+};
+
+class TopParser : public NodeParser
+{
+ public:
+ typedef void (*Callback) (void* /*data*/);
+ TopParser(Callback callback, void* data)
+ : m_packetParser(this, m_packet, m_packetStr),
+ m_resultParser(this, m_result, m_resultStr),
+ m_replyParser(this, m_reply),
+ m_modifyParser(this, m_modify),
+ m_callback(callback), m_data(data)
+ {}
+
+ virtual NodeParser* parseStartMap() { return this; }
+ virtual NodeParser* parseMapKey(const std::string& value)
+ {
+ std::string key = ToLower(value);
+
+ if (key == "packet")
+ return &m_packetParser;
+ else if (key == "result")
+ return &m_resultParser;
+ else if (key == "reply")
+ return &m_replyParser;
+ else if (key == "modify")
+ return &m_modifyParser;
+
+ return this;
+ }
+ virtual NodeParser* parseEndMap() { m_callback(m_data); return this; }
+
+ const std::string& packetStr() const { return m_packetStr; }
+ Packet packet() const { return m_packet; }
+ const std::string& resultStr() const { return m_resultStr; }
+ bool result() const { return m_result; }
+ const PairsParser::Pairs& reply() const { return m_reply; }
+ const PairsParser::Pairs& modify() const { return m_modify; }
+
+ private:
+ std::string m_packetStr;
+ Packet m_packet;
+ std::string m_resultStr;
+ bool m_result;
+ PairsParser::Pairs m_reply;
+ PairsParser::Pairs m_modify;
+
+ PacketParser m_packetParser;
+ ResultParser m_resultParser;
+ PairsParser m_replyParser;
+ PairsParser m_modifyParser;
+
+ Callback m_callback;
+ void* m_data;
+};
+
+class ProtoParser : public Parser
+{
+ public:
+ ProtoParser(TopParser::Callback callback, void* data)
+ : Parser( &m_topParser ),
+ m_topParser(callback, data)
+ {}
+
+ const std::string& packetStr() const { return m_topParser.packetStr(); }
+ Packet packet() const { return m_topParser.packet(); }
+ const std::string& resultStr() const { return m_topParser.resultStr(); }
+ bool result() const { return m_topParser.result(); }
+ const PairsParser::Pairs& reply() const { return m_topParser.reply(); }
+ const PairsParser::Pairs& modify() const { return m_topParser.modify(); }
+
+ private:
+ TopParser m_topParser;
+};
+
+class PacketGen : public Gen
+{
+ public:
+ PacketGen(const std::string& type)
+ : m_type(type)
+ {
+ m_gen.add("packet", m_type);
+ }
+ void run(yajl_gen_t* handle) const
+ {
+ m_gen.run(handle);
+ }
+ PacketGen& add(const std::string& key, const std::string& value)
+ {
+ m_gen.add(key, new StringGen(value));
+ return *this;
+ }
+ PacketGen& add(const std::string& key, MapGen& map)
+ {
+ m_gen.add(key, map);
+ return *this;
+ }
+ private:
+ MapGen m_gen;
+ StringGen m_type;
+};