[Libreoffice-commits] online.git: common/Protocol.hpp test/WhiteBoxTests.cpp wsd/SenderQueue.hpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Mon Dec 19 05:52:08 UTC 2016


 common/Protocol.hpp    |   43 +++++++++++++++++++++++++++++++++
 test/WhiteBoxTests.cpp |   63 +++++++++++++++++++++++++++++++++++++++++++++++++
 wsd/SenderQueue.hpp    |   11 ++++++++
 3 files changed, 117 insertions(+)

New commits:
commit 7e1529af319bf57ecca61c656ebfe97d44d4e109
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
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 <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

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;
 };
 


More information about the Libreoffice-commits mailing list