diff options
author | Florent Le Coz <louiz@louiz.org> | 2014-02-28 01:14:38 +0100 |
---|---|---|
committer | Florent Le Coz <louiz@louiz.org> | 2014-02-28 01:14:38 +0100 |
commit | 86d4347af8532ef85472e47c01d645fa5ad1b3b1 (patch) | |
tree | ddc9e019b89b216bed33911a2e2aeb03c668443c /src/xmpp | |
parent | df774d45a9754274a1701d801e4a42e71d38c97c (diff) | |
download | biboumi-86d4347af8532ef85472e47c01d645fa5ad1b3b1.tar.gz biboumi-86d4347af8532ef85472e47c01d645fa5ad1b3b1.tar.bz2 biboumi-86d4347af8532ef85472e47c01d645fa5ad1b3b1.tar.xz biboumi-86d4347af8532ef85472e47c01d645fa5ad1b3b1.zip |
Avoid unnecessary copies by recv()ing data directly into the expat buffer
Diffstat (limited to 'src/xmpp')
-rw-r--r-- | src/xmpp/xmpp_component.cpp | 21 | ||||
-rw-r--r-- | src/xmpp/xmpp_component.hpp | 8 | ||||
-rw-r--r-- | src/xmpp/xmpp_parser.cpp | 22 | ||||
-rw-r--r-- | src/xmpp/xmpp_parser.hpp | 10 |
4 files changed, 53 insertions, 8 deletions
diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index 9b73626..cd424ed 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -89,10 +89,20 @@ void XmppComponent::on_connection_close() log_info("XMPP server closed connection"); } -void XmppComponent::parse_in_buffer() +void XmppComponent::parse_in_buffer(const size_t size) { - this->parser.feed(this->in_buf.data(), this->in_buf.size(), false); - this->in_buf.clear(); + if (!this->in_buf.empty()) + { // This may happen if the parser could not allocate enough space for + // us. We try to feed it the data that was read into our in_buf + // instead. If this fails again we are in trouble. + this->parser.feed(this->in_buf.data(), this->in_buf.size(), false); + this->in_buf.clear(); + } + else + { // Just tell the parser to parse the data that was placed into the + // buffer it provided to us with GetBuffer + this->parser.parse(size, false); + } } void XmppComponent::shutdown() @@ -308,6 +318,11 @@ Bridge* XmppComponent::get_user_bridge(const std::string& user_jid) } } +void* XmppComponent::get_receive_buffer(const size_t size) const +{ + return this->parser.get_buffer(size); +} + void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, const std::string& to) { XmlNode node("message"); diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index bc2b518..0c040f4 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -23,7 +23,7 @@ public: void on_connection_failed(const std::string& reason) override final; void on_connected() override final; void on_connection_close() override final; - void parse_in_buffer() override final; + void parse_in_buffer(const size_t size) override final; /** * Send a "close" message to all our connected peers. That message * depends on the protocol used (this may be a QUIT irc message, or a @@ -142,7 +142,11 @@ private: * if none already exist. */ Bridge* get_user_bridge(const std::string& user_jid); - + /** + * Return a buffer provided by the XML parser, to read data directly into + * it, and avoiding some unnecessary copy. + */ + void* get_receive_buffer(const size_t size) const override final; XmppParser parser; std::string stream_id; std::string served_hostname; diff --git a/src/xmpp/xmpp_parser.cpp b/src/xmpp/xmpp_parser.cpp index 6e4809d..9fcc16c 100644 --- a/src/xmpp/xmpp_parser.cpp +++ b/src/xmpp/xmpp_parser.cpp @@ -1,6 +1,8 @@ #include <xmpp/xmpp_parser.hpp> #include <xmpp/xmpp_stanza.hpp> +#include <logger/logger.hpp> + /** * Expat handlers. Called by the Expat library, never by ourself. * They just forward the call to the XmppParser corresponding methods. @@ -45,9 +47,25 @@ XmppParser::~XmppParser() XML_ParserFree(this->parser); } -void XmppParser::feed(const char* data, const int len, const bool is_final) +int XmppParser::feed(const char* data, const int len, const bool is_final) +{ + int res = XML_Parse(this->parser, data, len, is_final); + if (res == 0) + log_error("Xml_Parse encountered an error"); + return res; +} + +int XmppParser::parse(const int len, const bool is_final) +{ + int res = XML_ParseBuffer(this->parser, len, is_final); + if (res == 0) + log_error("Xml_Parsebuffer encountered an error"); + return res; +} + +void* XmppParser::get_buffer(const size_t size) const { - XML_Parse(this->parser, data, len, is_final); + return XML_GetBuffer(this->parser, static_cast<int>(size)); } void XmppParser::start_element(const XML_Char* name, const XML_Char** attribute) diff --git a/src/xmpp/xmpp_parser.hpp b/src/xmpp/xmpp_parser.hpp index afdfdfa..df9cda7 100644 --- a/src/xmpp/xmpp_parser.hpp +++ b/src/xmpp/xmpp_parser.hpp @@ -37,7 +37,15 @@ public: /** * Feed the parser with some XML data */ - void feed(const char* data, const int len, const bool is_final); + int feed(const char* data, const int len, const bool is_final); + /** + * Parse the data placed in the parser buffer + */ + int parse(const int size, const bool is_final); + /** + * Get a buffer provided by the xml parser. + */ + void* get_buffer(const size_t size) const; /** * Add one callback for the various events that this parser can spawn. */ |