Add stringfy for type-conversion
authorSangwan Kwon <sangwan.kwon@samsung.com>
Wed, 20 Nov 2019 06:27:18 +0000 (15:27 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Fri, 22 Nov 2019 01:52:17 +0000 (10:52 +0900)
Stringfy provides converion from type to string and vice versa

Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
src/vist/archive.hpp
src/vist/common/CMakeLists.txt
src/vist/common/archive.cpp
src/vist/common/stringfy.cpp [new file with mode: 0644]
src/vist/common/tests/stringfy.cpp [new file with mode: 0644]
src/vist/exception.hpp
src/vist/stringfy.hpp [new file with mode: 0644]

index f1d525a..f1f9d18 100644 (file)
@@ -14,8 +14,6 @@
  *  limitations under the License
  */
 /*
- * @file    archive.hpp
- * @author  Sangwan Kwon (sangwan.kwon@samsung.com)
  * @brief   Define archive interface for serializer and parameter-pack.
  * @details 1. Serializer: Serialize/deserialize below types.
  *             (fundamental types, archival object, unique_ptr, shared_ptr)
@@ -84,8 +82,8 @@ public:
        void reserve(std::size_t size) noexcept;
 
 protected:
-       virtual void save(const void* bytes, std::size_t size);
-       virtual void load(void* bytes, std::size_t size);
+       void save(const void* bytes, std::size_t size);
+       void load(void* bytes, std::size_t size);
 
 private:
        template<typename T>
index 9f0766b..240e1e9 100644 (file)
@@ -17,7 +17,8 @@ PKG_CHECK_MODULES(VIST_COMMON_DEPS REQUIRED gflags klay dlog)
 INCLUDE_DIRECTORIES(SYSTEM . ${VIST_COMMON_DEPS_INCLUDE_DIRS})
 
 ADD_VIST_COMMON_LIBRARY(vist_common archive.cpp
-                                                                       common.cpp)
+                                                                       common.cpp
+                                                                       stringfy.cpp)
 
 FILE(GLOB COMMON_TESTS "tests/*.cpp")
 ADD_VIST_TEST(${COMMON_TESTS})
index 1458309..23b98e9 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-/*
- * @file   archive.cpp
- * @author Sangwan Kwon (sangwan.kwon@samsung.com)
- * @brief  Implementation of archive.
- */
 
 #include <vist/archive.hpp>
 
diff --git a/src/vist/common/stringfy.cpp b/src/vist/common/stringfy.cpp
new file mode 100644 (file)
index 0000000..7f0cce3
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include <vist/stringfy.hpp>
+
+namespace vist {
+
+Stringfy::Stringfy(int origin) noexcept :
+       type(Type::Integer), buffer(convert(origin))
+{
+}
+
+Stringfy::Stringfy(const std::string& origin) noexcept :
+       type(Type::String), buffer(convert(origin))
+{
+}
+
+Stringfy Stringfy::Restore(const std::string& dumped)
+{
+       auto parsed = Stringfy::Parse(dumped);
+       switch (parsed.first) {
+       case Type::Integer:
+               return Stringfy(std::stoi(parsed.second));
+       case Type::String:
+               return Stringfy(parsed.second);
+       case Type::None:
+       default:
+               THROW(ErrCode::LogicError) << "Invalid format.";
+       }
+}
+
+Stringfy::Type Stringfy::GetType(const std::string& dumped)
+{
+       return Stringfy::Parse(dumped).first;
+}
+
+Stringfy::operator std::string() const
+{
+       auto parsed = Stringfy::Parse(this->buffer);
+       if (parsed.first != Type::String)
+               THROW(ErrCode::TypeUnsafed) << "Type is not safed.";
+
+       return parsed.second;
+}
+
+Stringfy::operator int() const
+{
+       auto parsed = Stringfy::Parse(this->buffer);
+       if (parsed.first != Type::Integer)
+               THROW(ErrCode::TypeUnsafed) << "Type is not safed.";
+
+       return std::stoi(parsed.second);
+}
+
+std::pair<Stringfy::Type, std::string> Stringfy::Parse(const std::string& dumped)
+{
+       std::string type = dumped.substr(0, dumped.find('/'));
+       std::string data = dumped.substr(dumped.find('/') + 1);
+       if (type.empty())
+               THROW(ErrCode::LogicError) << "Invalid format.";
+
+       return std::make_pair(static_cast<Type>(type.at(0)), data);
+}
+
+std::string Stringfy::dump() const noexcept
+{
+       return this->buffer;
+}
+
+} // namespace vist
diff --git a/src/vist/common/tests/stringfy.cpp b/src/vist/common/tests/stringfy.cpp
new file mode 100644 (file)
index 0000000..01f5e40
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include <gtest/gtest.h>
+
+#include <vist/stringfy.hpp>
+#include <vist/exception.hpp>
+
+using namespace vist;
+
+TEST(StringfyTests, integer_dump)
+{
+       EXPECT_EQ("I/-11", Stringfy::Dump(-11));
+       EXPECT_EQ("I/-1", Stringfy::Dump(-1));
+       EXPECT_EQ("I/0", Stringfy::Dump(0));
+       EXPECT_EQ("I/1", Stringfy::Dump(1));
+       EXPECT_EQ("I/11", Stringfy::Dump(11));
+}
+
+TEST(StringfyTests, string_dump)
+{
+       EXPECT_EQ("S/", Stringfy::Dump(""));
+       EXPECT_EQ("S/TEXT", Stringfy::Dump("TEXT"));
+}
+
+TEST(StringfyTests, integer_restore)
+{
+       auto dumped = Stringfy::Dump(-1);
+       EXPECT_EQ(-1, Stringfy::Restore(dumped));
+
+       dumped = Stringfy::Dump(0);
+       EXPECT_EQ(0, Stringfy::Restore(dumped));
+
+       dumped = Stringfy::Dump(1);
+       EXPECT_EQ(1, Stringfy::Restore(dumped));
+}
+
+TEST(StringfyTests, string_restore)
+{
+       auto dumped = Stringfy::Dump("");
+       EXPECT_EQ(std::string(""), static_cast<std::string>(Stringfy::Restore(dumped)));
+
+       dumped = Stringfy::Dump("TEXT");
+       EXPECT_EQ(std::string("TEXT"), static_cast<std::string>(Stringfy::Restore(dumped)));
+}
+
+TEST(StringfyTests, get_type)
+{
+       auto dumped = Stringfy::Dump(0);
+       EXPECT_EQ(Stringfy::Type::Integer, Stringfy::GetType(dumped));
+
+       dumped = Stringfy::Dump("Text");
+       EXPECT_EQ(Stringfy::Type::String, Stringfy::GetType(dumped));
+}
+
+TEST(StringfyTests, type_safety)
+{
+       bool raised = false;
+       auto dumped = Stringfy::Dump(1);
+
+       try {
+               auto failed = static_cast<std::string>(Stringfy::Restore(dumped));
+       } catch (const vist::Exception<ErrCode>& e) {
+               raised = true;
+               EXPECT_EQ(e.get(), ErrCode::TypeUnsafed);
+       }
+
+       EXPECT_TRUE(raised);
+}
+
+TEST(StringfyTests, restore_failed)
+{
+       bool raised = false;
+
+       try {
+               auto failed = Stringfy::Restore("Not dumped message");
+       } catch (const vist::Exception<ErrCode>& e) {
+               raised = true;
+               EXPECT_EQ(e.get(), ErrCode::LogicError);
+       }
+
+       EXPECT_TRUE(raised);
+}
index 9fa717e..f3f6931 100644 (file)
@@ -55,7 +55,8 @@ namespace vist {
 enum class ErrCode {
        LogicError = 0, /// Includes invalid_argument
        RuntimeError,
-       BadCast
+       BadCast,
+       TypeUnsafed
 };
 
 template <typename ErrCode>
diff --git a/src/vist/stringfy.hpp b/src/vist/stringfy.hpp
new file mode 100644 (file)
index 0000000..d5b64a5
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @brief  Convert type to string and vice versa.
+ * @usage
+ *  /// type to string
+ *  std::string dumped = Strinfy::Dump(1000);
+ *  EXPECT_EQ(dumped, "I/1000");
+ *
+ *  /// dumped string to origin type
+ *  int origin = Stringfy::Restore(dumped);
+ *  EXPECT_EQ(origin, "1000");
+ */
+
+#pragma once
+
+#include <vist/exception.hpp>
+
+#include <string>
+
+namespace vist {
+
+class Stringfy final {
+public:
+       enum class Type : char {
+               Integer = 'I',
+               String = 'S',
+               None = 'N'
+       };
+
+       template <typename T>
+       static std::string Dump(T origin);
+       static Stringfy Restore(const std::string& dumped);
+
+       static Type GetType(const std::string& dumped);
+
+       operator std::string() const;
+       operator int() const;
+
+private:
+       explicit Stringfy(int origin) noexcept;
+       explicit Stringfy(const std::string& origin) noexcept;
+
+       static std::pair<Type, std::string> Parse(const std::string& dumped);
+
+       template <typename T>
+       std::string convert(const T& origin) const noexcept;
+
+       std::string dump() const noexcept;
+
+       Type type = Type::None;
+       std::string buffer;
+};
+
+template <typename T>
+std::string Stringfy::Dump(T origin)
+{
+       return Stringfy(origin).dump();
+}
+
+template <typename T>
+std::string Stringfy::convert(const T& origin) const noexcept
+{
+       std::stringstream ss;
+       ss << static_cast<char>(this->type) << '/' << origin;
+
+       return ss.str();
+}
+
+} // namespace vist