Browse Source

Add serializable for SectionPairRow class

Patrick-Christopher Mattulat 2 years ago
parent
commit
059aa5d9bd

+ 2 - 0
CMakeLists.txt

@@ -182,6 +182,7 @@ set(SOURCE_FILES_IO
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/model/SectionPairRowValue.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/validator/SectionPairIdentifierValidator.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/validator/SectionPairRowValueValidator.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/serialization/SerializableSectionPairRow.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/serialization/SerializableSectionPairRowListValue.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/serialization/SerializableSectionPairRowSingleValue.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/xml/XmlAttribute.cpp
@@ -277,6 +278,7 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/model/SectionPairRowTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/serialization/SerializableSectionPairRowListValueTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/serialization/SerializableSectionPairRowSingleValueTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/serialization/SerializableSectionPairRowTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/xml/XmlAttributeTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/xml/XmlDeclarationTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/xml/XmlDocumentTest.cpp

+ 42 - 0
include/ls-std/io/section-pair/serialization/SerializableSectionPairRow.hpp

@@ -0,0 +1,42 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-02-11
+* Changed:         2023-02-12
+*
+* */
+
+#ifndef LS_STD_SERIALIZABLE_SECTION_PAIR_ROW_HPP
+#define LS_STD_SERIALIZABLE_SECTION_PAIR_ROW_HPP
+
+#include <ls-std/core/interface/ISerializable.hpp>
+#include <ls-std/io/section-pair/model/SectionPairRow.hpp>
+#include <memory>
+#include <string>
+
+namespace ls::std::io
+{
+  class SerializableSectionPairRow : public ls::std::core::interface_type::ISerializable
+  {
+    public:
+
+      explicit SerializableSectionPairRow(const ::std::shared_ptr<ls::std::io::SectionPairRow> &_value);
+      ~SerializableSectionPairRow() override;
+
+      [[nodiscard]] ::std::shared_ptr<ls::std::io::SectionPairRow> getValue();
+      [[nodiscard]] ls::std::core::type::byte_field marshal() override;
+      void unmarshal(const ls::std::core::type::byte_field &_data) override;
+
+    private:
+
+      ::std::shared_ptr<ls::std::io::SectionPairRow> value{};
+
+      [[nodiscard]] ::std::string _marshalKey();
+      void _setValue(const ::std::shared_ptr<ls::std::io::SectionPairRow> &_value);
+      void _unmarshalListValue(const ls::std::core::type::byte_field &_data);
+      void _unmarshalSingleValue(const ls::std::core::type::byte_field &_data);
+  };
+}
+
+#endif

+ 3 - 2
include/ls-std/ls-std-io.hpp

@@ -2,8 +2,8 @@
  * Author:          Patrick-Christopher Mattulat
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
- * Created:         2022-05-14
- * Changed:         2023-02-11
+ * Created:         2023-02-11
+ * Changed:         2023-02-12
  *
  * */
 
@@ -28,6 +28,7 @@
 #include <ls-std/io/section-pair/model/SectionPairRowListValue.hpp>
 #include <ls-std/io/section-pair/model/SectionPairRowSingleValue.hpp>
 #include <ls-std/io/section-pair/model/SectionPairRowValue.hpp>
+#include <ls-std/io/section-pair/serialization/SerializableSectionPairRow.hpp>
 #include <ls-std/io/section-pair/serialization/SerializableSectionPairRowListValue.hpp>
 #include <ls-std/io/section-pair/serialization/SerializableSectionPairRowSingleValue.hpp>
 #include <ls-std/io/section-pair/validator/SectionPairIdentifierValidator.hpp>

+ 93 - 0
source/ls-std/io/section-pair/serialization/SerializableSectionPairRow.cpp

@@ -0,0 +1,93 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-02-11
+* Changed:         2023-02-12
+*
+* */
+
+#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
+#include <ls-std/io/NewLine.hpp>
+#include <ls-std/io/section-pair/model/SectionPairRowListValue.hpp>
+#include <ls-std/io/section-pair/model/SectionPairRowSingleValue.hpp>
+#include <ls-std/io/section-pair/serialization/SerializableSectionPairRow.hpp>
+
+ls::std::io::SerializableSectionPairRow::SerializableSectionPairRow(const ::std::shared_ptr<ls::std::io::SectionPairRow> &_value)
+{
+  this->_setValue(_value);
+}
+
+ls::std::io::SerializableSectionPairRow::~SerializableSectionPairRow() = default;
+
+::std::shared_ptr<ls::std::io::SectionPairRow> ls::std::io::SerializableSectionPairRow::getValue()
+{
+  return this->value;
+}
+
+ls::std::core::type::byte_field ls::std::io::SerializableSectionPairRow::marshal()
+{
+  ls::std::core::type::byte_field data = this->_marshalKey();
+  return data + this->value->getValue()->marshal();
+}
+
+void ls::std::io::SerializableSectionPairRow::unmarshal(const ls::std::core::type::byte_field &_data)
+{
+  if (this->value->isSingleValue())
+  {
+    this->_unmarshalSingleValue(_data);
+  }
+
+  if (this->value->isList())
+  {
+    this->_unmarshalListValue(_data);
+  }
+}
+
+::std::string ls::std::io::SerializableSectionPairRow::_marshalKey()
+{
+  ::std::string serializedKey{};
+
+  if (this->value->isSingleValue())
+  {
+    serializedKey = this->value->getKey() + "=";
+  }
+
+  if (this->value->isList())
+  {
+    serializedKey = this->value->getKey() + ":" + ls::std::io::NewLine::get();
+  }
+
+  return serializedKey;
+}
+
+void ls::std::io::SerializableSectionPairRow::_setValue(const ::std::shared_ptr<ls::std::io::SectionPairRow> &_value)
+{
+  ls::std::core::NullPointerArgumentEvaluator{_value}.evaluate();
+  this->value = _value;
+}
+
+void ls::std::io::SerializableSectionPairRow::_unmarshalListValue(const ls::std::core::type::byte_field &_data)
+{
+  ::std::string::size_type separatorPosition = _data.find(':');
+  ls::std::io::section_pair_identifier identifier{};
+
+  if (separatorPosition != ::std::string::npos)
+  {
+    this->value->setKey(_data.substr(0, separatorPosition));
+    ::std::string::size_type newLinePosition = _data.find(NewLine::get()) + (NewLine::get().size() - 1);
+    ::std::dynamic_pointer_cast<ls::std::io::SectionPairRowListValue>(this->value->getValue())->unmarshal(_data.substr(newLinePosition + 1));
+  }
+}
+
+void ls::std::io::SerializableSectionPairRow::_unmarshalSingleValue(const ls::std::core::type::byte_field &_data)
+{
+  ::std::string::size_type position = _data.find('=');
+  ls::std::io::section_pair_identifier identifier{};
+
+  if (position != ::std::string::npos)
+  {
+    this->value->setKey(_data.substr(0, position));
+    ::std::dynamic_pointer_cast<ls::std::io::SectionPairRowSingleValue>(this->value->getValue())->unmarshal(_data.substr(position + 1));
+  }
+}

+ 112 - 0
test/cases/io/section-pair/serialization/SerializableSectionPairRowTest.cpp

@@ -0,0 +1,112 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-02-12
+* Changed:         2023-02-12
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-core.hpp>
+#include <ls-std/ls-std-io.hpp>
+#include <memory>
+
+using namespace ls::std::core;
+using namespace ls::std::io;
+using namespace ::std;
+
+namespace
+{
+  class SerializableSectionPairRowTest : public ::testing::Test
+  {
+    protected:
+
+      SerializableSectionPairRowTest() = default;
+      ~SerializableSectionPairRowTest() override = default;
+
+      void SetUp() override
+      {}
+
+      void TearDown() override
+      {}
+  };
+
+  TEST_F(SerializableSectionPairRowTest, constructor_no_reference)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            SerializableSectionPairRow serializable(nullptr);
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(SerializableSectionPairRowTest, getValue)
+  {
+    SerializableSectionPairRow serializable{make_shared<SectionPairRow>("tmp-key", SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE)};
+    ASSERT_TRUE(serializable.getValue() != nullptr);
+  }
+
+  TEST_F(SerializableSectionPairRowTest, marshal_single_value)
+  {
+    shared_ptr<SectionPairRow> row = make_shared<SectionPairRow>("favourite-color", SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE);
+    shared_ptr<SectionPairRowSingleValue> singleValue = ::std::dynamic_pointer_cast<SectionPairRowSingleValue>(row->getValue());
+    singleValue->set("blue");
+    singleValue->setSerializable(make_shared<SerializableSectionPairRowSingleValue>(singleValue));
+    SerializableSectionPairRow serializable{row};
+
+    ASSERT_STREQ("favourite-color=blue", serializable.marshal().c_str());
+  }
+
+  TEST_F(SerializableSectionPairRowTest, marshal_list_value)
+  {
+    shared_ptr<SectionPairRow> row = make_shared<SectionPairRow>("favourite-colors", SectionPairRowEnumType::SECTION_PAIR_ROW_LIST_VALUE);
+    shared_ptr<SectionPairRowListValue> listValue = ::std::dynamic_pointer_cast<SectionPairRowListValue>(row->getValue());
+    listValue->add("blue");
+    listValue->add("red");
+    listValue->add("purple");
+    listValue->setSerializable(make_shared<SerializableSectionPairRowListValue>(listValue));
+    SerializableSectionPairRow serializable{row};
+
+    string expected = "favourite-colors:" + NewLine::get() + "  blue" + NewLine::get() + "  red" + NewLine::get() + "  purple" + NewLine::get();
+
+    ASSERT_STREQ(expected.c_str(), serializable.marshal().c_str());
+  }
+
+  TEST_F(SerializableSectionPairRowTest, unmarshal_single_value)
+  {
+    shared_ptr<SectionPairRow> row = make_shared<SectionPairRow>("tmp-key", SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE);
+    shared_ptr<SectionPairRowSingleValue> singleValue = ::std::dynamic_pointer_cast<SectionPairRowSingleValue>(row->getValue());
+    singleValue->setSerializable(make_shared<SerializableSectionPairRowSingleValue>(singleValue));
+    SerializableSectionPairRow serializable{row};
+
+    serializable.unmarshal("favourite-color=blue");
+
+    ASSERT_STREQ("favourite-color", row->getKey().c_str());
+    ASSERT_STREQ("blue", singleValue->get().c_str());
+  }
+
+  TEST_F(SerializableSectionPairRowTest, unmarshal_list_value)
+  {
+    shared_ptr<SectionPairRow> row = make_shared<SectionPairRow>("tmp-key", SectionPairRowEnumType::SECTION_PAIR_ROW_LIST_VALUE);
+    shared_ptr<SectionPairRowListValue> listValue = ::std::dynamic_pointer_cast<SectionPairRowListValue>(row->getValue());
+    listValue->setSerializable(make_shared<SerializableSectionPairRowListValue>(listValue));
+    SerializableSectionPairRow serializable{row};
+
+    string data = "favourite-colors:" + NewLine::get() + "  blue" + NewLine::get() + "  red" + NewLine::get() + "  purple" + NewLine::get();
+    serializable.unmarshal(data);
+
+    ASSERT_STREQ("favourite-colors", row->getKey().c_str());
+    ASSERT_EQ(3, listValue->getSize());
+    ASSERT_STREQ("blue", listValue->get(0).c_str());
+    ASSERT_STREQ("red", listValue->get(1).c_str());
+    ASSERT_STREQ("purple", listValue->get(2).c_str());
+  }
+}