utils: Add split method

Add the method of splitting the string, split the string according to
the special identifier and return a vector.

Tested: Add Unit Test and test passes.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I0a4474cef53fed4a629e3faa9db44dbf3bf432d8
diff --git a/common/test/pldm_utils_test.cpp b/common/test/pldm_utils_test.cpp
index 006d065..0014bb5 100644
--- a/common/test/pldm_utils_test.cpp
+++ b/common/test/pldm_utils_test.cpp
@@ -930,4 +930,39 @@
     buffer.length = bufferArr2.size();
     auto returnStr3 = toString(buffer);
     EXPECT_EQ(returnStr3, str3);
+}
+
+TEST(Split, allTestCases)
+{
+    std::string s1 = "aa,bb,cc,dd";
+    auto results1 = split(s1, ",");
+    EXPECT_EQ(results1[0], "aa");
+    EXPECT_EQ(results1[1], "bb");
+    EXPECT_EQ(results1[2], "cc");
+    EXPECT_EQ(results1[3], "dd");
+
+    std::string s2 = "aa||bb||cc||dd";
+    auto results2 = split(s2, "||");
+    EXPECT_EQ(results2[0], "aa");
+    EXPECT_EQ(results2[1], "bb");
+    EXPECT_EQ(results2[2], "cc");
+    EXPECT_EQ(results2[3], "dd");
+
+    std::string s3 = " aa || bb||cc|| dd";
+    auto results3 = split(s3, "||", " ");
+    EXPECT_EQ(results3[0], "aa");
+    EXPECT_EQ(results3[1], "bb");
+    EXPECT_EQ(results3[2], "cc");
+    EXPECT_EQ(results3[3], "dd");
+
+    std::string s4 = "aa\\\\bb\\cc\\dd";
+    auto results4 = split(s4, "\\");
+    EXPECT_EQ(results4[0], "aa");
+    EXPECT_EQ(results4[1], "bb");
+    EXPECT_EQ(results4[2], "cc");
+    EXPECT_EQ(results4[3], "dd");
+
+    std::string s5 = "aa\\";
+    auto results5 = split(s5, "\\");
+    EXPECT_EQ(results5[0], "aa");
 }
\ No newline at end of file
diff --git a/common/utils.cpp b/common/utils.cpp
index 89b55d1..ac19896 100644
--- a/common/utils.cpp
+++ b/common/utils.cpp
@@ -541,5 +541,32 @@
     return str;
 }
 
+std::vector<std::string> split(std::string_view srcStr, std::string_view delim,
+                               std::string_view trimStr)
+{
+    std::vector<std::string> out;
+    size_t start;
+    size_t end = 0;
+
+    while ((start = srcStr.find_first_not_of(delim, end)) != std::string::npos)
+    {
+        end = srcStr.find(delim, start);
+        std::string_view dstStr = srcStr.substr(start, end - start);
+        if (!trimStr.empty())
+        {
+            dstStr.remove_prefix(dstStr.find_first_not_of(trimStr));
+            dstStr.remove_suffix(dstStr.size() - 1 -
+                                 dstStr.find_last_not_of(trimStr));
+        }
+
+        if (!dstStr.empty())
+        {
+            out.push_back(std::string(dstStr));
+        }
+    }
+
+    return out;
+}
+
 } // namespace utils
 } // namespace pldm
diff --git a/common/utils.hpp b/common/utils.hpp
index c7c63ef..464816a 100644
--- a/common/utils.hpp
+++ b/common/utils.hpp
@@ -389,5 +389,19 @@
  */
 std::string toString(const struct variable_field& var);
 
+/** @brief Split strings according to special identifiers
+ *
+ *  We can split the string according to the custom identifier(';', ',', '&' or
+ *  others) and store it to vector.
+ *
+ *  @param[in] srcStr       - The string to be split
+ *  @param[in] delim        - The custom identifier
+ *  @param[in] trimStr      - The first and last string to be trimmed
+ *
+ *  @return std::vector<std::string> Vectors are used to store strings
+ */
+std::vector<std::string> split(std::string_view srcStr, std::string_view delim,
+                               std::string_view trimStr = "");
+
 } // namespace utils
 } // namespace pldm