common/Protocol.hpp | 43 +++++++++++++++++++++++++++++++++ test/WhiteBoxTests.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ wsd/SenderQueue.hpp | 11 ++++++++ 3 files changed, 117 insertions(+)
New commits: commit 7e1529af319bf57ecca61c656ebfe97d44d4e109 Author: Ashod Nakashian <[email protected]> Date: Sat Dec 17 21:54:34 2016 -0500 loolwsd: add tokenization to MessagePayload Change-Id: I39135b2ad65da5abce93848a68faffc93906a0c0 Reviewed-on: https://gerrit.libreoffice.org/32157 Reviewed-by: Ashod Nakashian <[email protected]> Tested-by: Ashod Nakashian <[email protected]> diff --git a/common/Protocol.hpp b/common/Protocol.hpp index d69c14a..31cb16e 100644 --- a/common/Protocol.hpp +++ b/common/Protocol.hpp @@ -77,6 +77,49 @@ namespace LOOLProtocol // Functions that parse messages. All return false if parsing fails bool parseStatus(const std::string& message, LibreOfficeKitDocumentType& type, int& nParts, int& currentPart, int& width, int& height); + /// Tokenize space-delimited values until we hit new-line or the end. + inline + std::vector<std::string> tokenize(const char* data, const size_t size) + { + std::vector<std::string> tokens; + if (size == 0 || data == nullptr) + { + return tokens; + } + + const char* start = data; + const char* end = data; + for (size_t i = 0; i < size && data[i] != '\n'; ++i, ++end) + { + if (data[i] == ' ') + { + if (start != end && *start != ' ') + { + tokens.emplace_back(start, end); + } + + start = end; + } + else if (*start == ' ') + { + ++start; + } + } + + if (start != end && *start != ' ' && *start != '\n') + { + tokens.emplace_back(start, end); + } + + return tokens; + } + + inline + std::vector<std::string> tokenize(const std::string& s) + { + return tokenize(s.data(), s.size()); + } + inline std::string getDelimitedInitialSubstring(const char *message, const int length, const char delim) { diff --git a/test/WhiteBoxTests.cpp b/test/WhiteBoxTests.cpp index 0b9620a..03cf59b 100644 --- a/test/WhiteBoxTests.cpp +++ b/test/WhiteBoxTests.cpp @@ -24,6 +24,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture CPPUNIT_TEST_SUITE(WhiteBoxTests); CPPUNIT_TEST(testLOOLProtocolFunctions); + CPPUNIT_TEST(testTokenizer); CPPUNIT_TEST(testRegexListMatcher); CPPUNIT_TEST(testRegexListMatcher_Init); CPPUNIT_TEST(testEmptyCellCursor); @@ -31,6 +32,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture CPPUNIT_TEST_SUITE_END(); void testLOOLProtocolFunctions(); + void testTokenizer(); void testRegexListMatcher(); void testRegexListMatcher_Init(); void testEmptyCellCursor(); @@ -124,6 +126,67 @@ void WhiteBoxTests::testLOOLProtocolFunctions() CPPUNIT_ASSERT_EQUAL(std::string(""), Util::trim(s)); } +void WhiteBoxTests::testTokenizer() +{ + std::vector<std::string> tokens; + + tokens = LOOLProtocol::tokenize(""); + CPPUNIT_ASSERT_EQUAL(0UL, tokens.size()); + + tokens = LOOLProtocol::tokenize(" "); + CPPUNIT_ASSERT_EQUAL(0UL, tokens.size()); + + tokens = LOOLProtocol::tokenize("A"); + CPPUNIT_ASSERT_EQUAL(1UL, tokens.size()); + CPPUNIT_ASSERT_EQUAL(std::string("A"), tokens[0]); + + tokens = LOOLProtocol::tokenize(" A"); + CPPUNIT_ASSERT_EQUAL(1UL, tokens.size()); + CPPUNIT_ASSERT_EQUAL(std::string("A"), tokens[0]); + + tokens = LOOLProtocol::tokenize("A "); + CPPUNIT_ASSERT_EQUAL(1UL, tokens.size()); + CPPUNIT_ASSERT_EQUAL(std::string("A"), tokens[0]); + + tokens = LOOLProtocol::tokenize(" A "); + CPPUNIT_ASSERT_EQUAL(1UL, tokens.size()); + CPPUNIT_ASSERT_EQUAL(std::string("A"), tokens[0]); + + tokens = LOOLProtocol::tokenize(" A Z "); + CPPUNIT_ASSERT_EQUAL(2UL, tokens.size()); + CPPUNIT_ASSERT_EQUAL(std::string("A"), tokens[0]); + CPPUNIT_ASSERT_EQUAL(std::string("Z"), tokens[1]); + + tokens = LOOLProtocol::tokenize("\n"); + CPPUNIT_ASSERT_EQUAL(0UL, tokens.size()); + + tokens = LOOLProtocol::tokenize(" A \nZ "); + CPPUNIT_ASSERT_EQUAL(1UL, tokens.size()); + CPPUNIT_ASSERT_EQUAL(std::string("A"), tokens[0]); + + tokens = LOOLProtocol::tokenize(" A Z\n "); + CPPUNIT_ASSERT_EQUAL(2UL, tokens.size()); + CPPUNIT_ASSERT_EQUAL(std::string("A"), tokens[0]); + CPPUNIT_ASSERT_EQUAL(std::string("Z"), tokens[1]); + + tokens = LOOLProtocol::tokenize(" A Z \n "); + CPPUNIT_ASSERT_EQUAL(2UL, tokens.size()); + CPPUNIT_ASSERT_EQUAL(std::string("A"), tokens[0]); + CPPUNIT_ASSERT_EQUAL(std::string("Z"), tokens[1]); + + tokens = LOOLProtocol::tokenize("tile part=0 width=256 height=256 tileposx=0 tileposy=0 tilewidth=3840 tileheight=3840 ver=-1"); + CPPUNIT_ASSERT_EQUAL(9UL, tokens.size()); + CPPUNIT_ASSERT_EQUAL(std::string("tile"), tokens[0]); + CPPUNIT_ASSERT_EQUAL(std::string("part=0"), tokens[1]); + CPPUNIT_ASSERT_EQUAL(std::string("width=256"), tokens[2]); + CPPUNIT_ASSERT_EQUAL(std::string("height=256"), tokens[3]); + CPPUNIT_ASSERT_EQUAL(std::string("tileposx=0"), tokens[4]); + CPPUNIT_ASSERT_EQUAL(std::string("tileposy=0"), tokens[5]); + CPPUNIT_ASSERT_EQUAL(std::string("tilewidth=3840"), tokens[6]); + CPPUNIT_ASSERT_EQUAL(std::string("tileheight=3840"), tokens[7]); + CPPUNIT_ASSERT_EQUAL(std::string("ver=-1"), tokens[8]); +} + void WhiteBoxTests::testRegexListMatcher() { Util::RegexListMatcher matcher; diff --git a/wsd/SenderQueue.hpp b/wsd/SenderQueue.hpp index d9aff9a..eb8ae8d 100644 --- a/wsd/SenderQueue.hpp +++ b/wsd/SenderQueue.hpp @@ -28,28 +28,35 @@ public: enum class Type { Text, Binary }; /// Construct a text message. + /// message must include the full first-line. MessagePayload(const std::string& message) : _data(message.data(), message.data() + message.size()), + _tokens(LOOLProtocol::tokenize(_data.data(), _data.size())), _type(Type::Text) { } /// Construct a message from a string with type and /// reserve extra space (total, including message). + /// message must include the full first-line. MessagePayload(const std::string& message, const enum Type type, const size_t reserve = 0) : _data(reserve), + _tokens(LOOLProtocol::tokenize(_data.data(), _data.size())), _type(type) { _data.resize(message.size()); std::memcpy(_data.data(), message.data(), message.size()); } + /// Construct a message from a character array with type. + /// data must be include the full first-line. MessagePayload(const char* data, const size_t size, const enum Type type) : _data(data, data + size), + _tokens(LOOLProtocol::tokenize(_data.data(), _data.size())), _type(type) { } @@ -57,6 +64,9 @@ public: size_t size() const { return _data.size(); } const std::vector<char>& data() const { return _data; } + const std::vector<std::string>& tokens() const { return _tokens; } + const std::string& firstToken() const { return _tokens[0]; } + /// Append more data to the message. void append(const char* data, const size_t size) { @@ -70,6 +80,7 @@ public: private: std::vector<char> _data; + const std::vector<std::string> _tokens; const Type _type; }; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
