Change implementation of string splitting to support zero-length components 32/122832/2
authorRafal Krypa <r.krypa@samsung.com>
Mon, 3 Apr 2017 10:56:58 +0000 (12:56 +0200)
committerRafal Krypa <r.krypa@samsung.com>
Mon, 3 Apr 2017 18:54:23 +0000 (20:54 +0200)
Previous code responsible from splitting a space-separated string used
stringstream for this purpose. If one of the components used to create such
string was empty, it resulted in two consecutive spaces that were "swallowed"
by stringstream.

Now the string is parsed using std::string::find method to manually detect
locations of delimiting spaces and cut the string to pieces.

Change-Id: I2aa964716f0d41f13807bbef5c8aab6c55715a34
Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
src/common/protocol/channel.cpp
src/common/protocol/channel.h

index fd22201..3b9c46d 100644 (file)
@@ -18,7 +18,6 @@
  * @author      Bartlomiej Grzelewski <b.grzelewski@samsung.com>
  * @brief
  */
-#include <sstream>
 #include <string>
 
 #include <askuser-notification/ask-user-service.h>
@@ -47,6 +46,23 @@ void Channel::init() {
     m_callbacks->updateFd(fd2, FdMask::READ);
 }
 
+void Channel::parse(const std::string &data, std::vector<std::string> &parsedData)
+{
+    size_t begin = 0;
+
+    while (begin < data.size()) {
+        size_t end = data.find(' ', begin);
+
+        if (end == std::string::npos) {
+            parsedData.push_back(data.substr(begin));
+            return;
+        }
+
+        parsedData.push_back(data.substr(begin, end - begin));
+        begin = end + 1;
+    }
+}
+
 void Channel::process(int fd, int mask) {
     try {
         auto it = m_socket.find(fd);
@@ -80,38 +96,31 @@ void Channel::process(int fd, int mask) {
                 return;
             }
 
-            std::string data(desc.input.begin(), desc.input.end());
+            std::vector<std::string> params;
+            parse(std::string(desc.input.begin(), desc.input.end()), params);
             desc.input.clear();
-            std::stringstream ss(data);
 
-            int command;
-            std::string appId, pkgName;
-            uid_t uid;
+            int command = std::stoi(params[0]);
+            std::string &pkgName = params[1];
+            std::string &appName = params[2];
+            uid_t uid = std::stoi(params[3]);
 
-            ss >> command >> pkgName >> appId >> uid;
-
-            switch(command) {
+            switch (command) {
             case MSGID_POPUP:
                 {
-                    PrivilegeVector vect;
-                    std::string privilege;
-                    while(ss) {
-                        ss >> privilege;
-                        vect.push_back(privilege);
-                    }
-                    m_callbacks->popup_launch(fd, pkgName, appId, uid, vect);
+                    PrivilegeVector vect(params.begin() + 4, params.end());
+                    m_callbacks->popup_launch(fd, pkgName, appName, uid, vect);
                     break;
                 }
             case MSGID_TOAST1:
                 {
-                    std::string privilege;
-                    ss >> privilege;
-                    m_callbacks->toast_deny(pkgName, appId, uid, privilege);
+                    std::string &privilege = params[4];
+                    m_callbacks->toast_deny(pkgName, appName, uid, privilege);
                     break;
                 }
             case MSGID_TOAST2:
                 {
-                    m_callbacks->toast_fail_launch(pkgName, appId, uid);
+                    m_callbacks->toast_fail_launch(pkgName, appName, uid);
                     break;
                 }
             }
@@ -146,10 +155,7 @@ void Channel::popupResponse(int requestId, int response) {
 
         auto &desc = it->second;
 
-        std::stringstream ss;
-        ss << response;
-        std::string o = ss.str();
-
+        std::string o = std::to_string(response);
         std::copy(o.begin(), o.end(), std::back_inserter(desc.output));
         m_callbacks->updateFd(requestId, FdMask::READ | FdMask::WRITE);
     } catch (const std::exception &){}
index 627ef11..9ed90aa 100644 (file)
@@ -58,6 +58,8 @@ public:
     virtual ~Channel();
 
 private:
+    virtual void parse(const std::string &data, std::vector<std::string> &parsedData);
+
     ServerCallbacksPtr m_callbacks;
     SocketMap m_socket;
 };