Forráskód Böngészése

Make SectionPairSection class serializable

Patrick-Christopher Mattulat 2 éve
szülő
commit
9e8990bdde

+ 1 - 0
CMakeLists.txt

@@ -302,6 +302,7 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/FileWriterTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/StandardOutputWriterTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/StorableFileTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/io/section-pair/SectionPairSectionProvider.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/io/xml/TestDataFactory.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/io/xml/XmlParserTestWrapper.cpp)
 

+ 7 - 1
include/ls-std/io/section-pair/model/SectionPairSection.hpp

@@ -12,13 +12,15 @@
 
 #include <list>
 #include <ls-std/core/Class.hpp>
+#include <ls-std/core/interface/ISerializable.hpp>
 #include <ls-std/io/section-pair/SectionPairTypes.hpp>
 #include <ls-std/io/section-pair/type/SectionPairSectionTypes.hpp>
 #include <ls-std/os/dynamic-goal.hpp>
+#include <memory>
 
 namespace ls::std::io
 {
-  class LS_STD_DYNAMIC_GOAL SectionPairSection : public ls::std::core::Class
+  class LS_STD_DYNAMIC_GOAL SectionPairSection : public ::std::enable_shared_from_this<SectionPairSection>, public ls::std::core::Class, public ls::std::core::interface_type::ISerializable
   {
     public:
 
@@ -30,13 +32,17 @@ namespace ls::std::io
       [[nodiscard]] ls::std::io::section_pair_row_list getList();
       [[nodiscard]] size_t getRowAmount();
       [[nodiscard]] ls::std::io::section_pair_identifier getSectionId();
+      [[nodiscard]] ls::std::core::type::byte_field marshal() override;
       void setSectionId(const ls::std::io::section_pair_identifier &_sectionId);
+      void unmarshal(const ls::std::core::type::byte_field &_data) override;
 
     private:
 
       ls::std::io::section_pair_row_list rows{};
       ls::std::io::section_pair_identifier sectionId{};
+      ::std::shared_ptr<ls::std::core::interface_type::ISerializable> serializable{};
 
+      void _createSerializable();
       [[nodiscard]] bool _hasRow(const ls::std::io::section_pair_identifier &_key);
       void _rowExistenceCheck(const ls::std::io::section_pair_identifier &_key);
       void _setSectionId(const ls::std::io::section_pair_identifier &_sectionId);

+ 19 - 0
source/ls-std/io/section-pair/model/SectionPairSection.cpp

@@ -7,12 +7,14 @@
 *
 * */
 
+#include <ls-std/core/ConditionalFunctionExecutor.hpp>
 #include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
 #include <ls-std/core/evaluator/IndexOutOfBoundsEvaluator.hpp>
 #include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
 #include <ls-std/core/exception/IllegalArgumentException.hpp>
 #include <ls-std/io/section-pair/evaluator/SectionPairIdentifierArgumentEvaluator.hpp>
 #include <ls-std/io/section-pair/model/SectionPairSection.hpp>
+#include <ls-std/io/section-pair/serialization/SerializableSectionPairSection.hpp>
 
 ls::std::io::SectionPairSection::SectionPairSection(const ls::std::io::section_pair_identifier &_sectionId) : ls::std::core::Class("SectionPairSection")
 {
@@ -63,11 +65,28 @@ ls::std::io::section_pair_identifier ls::std::io::SectionPairSection::getSection
   return this->sectionId;
 }
 
+ls::std::core::type::byte_field ls::std::io::SectionPairSection::marshal()
+{
+  ls::std::core::ConditionalFunctionExecutor{this->serializable == nullptr}.execute([this] { _createSerializable(); });
+  return this->serializable->marshal();
+}
+
 void ls::std::io::SectionPairSection::setSectionId(const ls::std::io::section_pair_identifier &_sectionId)
 {
   this->_setSectionId(_sectionId);
 }
 
+void ls::std::io::SectionPairSection::unmarshal(const ls::std::core::type::byte_field &_data)
+{
+  ls::std::core::ConditionalFunctionExecutor{this->serializable == nullptr}.execute([this] { _createSerializable(); });
+  this->serializable->unmarshal(_data);
+}
+
+void ls::std::io::SectionPairSection::_createSerializable()
+{
+  this->serializable = ::std::make_shared<ls::std::io::SerializableSectionPairSection>(shared_from_this());
+}
+
 bool ls::std::io::SectionPairSection::_hasRow(const ls::std::io::section_pair_identifier &_key)
 {
   bool rowExists{};

+ 30 - 0
test/cases/io/section-pair/model/SectionPairSectionTest.cpp

@@ -8,12 +8,15 @@
 * */
 
 #include <gtest/gtest.h>
+#include <ls-std-io-test.hpp>
 #include <ls-std/ls-std-core.hpp>
 #include <ls-std/ls-std-io.hpp>
 
 using namespace ls::std::core;
+using namespace ls::std::core::type;
 using namespace ls::std::io;
 using namespace ::std;
+using namespace test::io;
 
 namespace
 {
@@ -139,6 +142,15 @@ namespace
     ASSERT_STREQ("general", section->getSectionId().c_str());
   }
 
+  TEST_F(SectionPairSectionTest, marshal)
+  {
+    shared_ptr<SectionPairSection> section = SectionPairSectionProvider::createSection();
+    byte_field expected = SectionPairSectionProvider::createSerializedSection();
+    byte_field actual = section->marshal();
+
+    ASSERT_STREQ(expected.c_str(), actual.c_str());
+  }
+
   TEST_F(SectionPairSectionTest, setSectionId)
   {
     shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
@@ -182,4 +194,22 @@ namespace
         },
         IllegalArgumentException);
   }
+
+  TEST_F(SectionPairSectionTest, unmarshal)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("tmp-id");
+    section->unmarshal(SectionPairSectionProvider::createSerializedSection());
+
+    ASSERT_STREQ("general", section->getSectionId().c_str());
+    ASSERT_EQ(3, section->getRowAmount());
+    ASSERT_STREQ("name", section->get(0)->getKey().c_str());
+    ASSERT_STREQ("Tom", dynamic_pointer_cast<SectionPairRowSingleValue>(section->get(0)->getValue())->get().c_str());
+    ASSERT_STREQ("jobs", section->get(1)->getKey().c_str());
+    shared_ptr<SectionPairRowListValue> listRow = dynamic_pointer_cast<SectionPairRowListValue>(section->get(1)->getValue());
+    ASSERT_EQ(2, listRow->getSize());
+    ASSERT_STREQ("Farmer", listRow->get(0).c_str());
+    ASSERT_STREQ("Bounty Hunter", listRow->get(1).c_str());
+    ASSERT_STREQ("age", section->get(2)->getKey().c_str());
+    ASSERT_STREQ("33", dynamic_pointer_cast<SectionPairRowSingleValue>(section->get(2)->getValue())->get().c_str());
+  }
 }

+ 5 - 34
test/cases/io/section-pair/serialization/SerializableSectionPairSectionTest.cpp

@@ -8,6 +8,7 @@
 * */
 
 #include <gtest/gtest.h>
+#include <ls-std-io-test.hpp>
 #include <ls-std/ls-std-core.hpp>
 #include <ls-std/ls-std-io.hpp>
 #include <memory>
@@ -16,6 +17,7 @@ using namespace ls::std::core;
 using namespace ls::std::core::type;
 using namespace ls::std::io;
 using namespace ::std;
+using namespace test::io;
 
 namespace
 {
@@ -31,37 +33,6 @@ namespace
 
       void TearDown() override
       {}
-
-      static shared_ptr<SectionPairSection> createSection()
-      {
-        shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
-
-        shared_ptr<SectionPairRow> name = make_shared<SectionPairRow>("name", SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE);
-        dynamic_pointer_cast<SectionPairRowSingleValue>(name->getValue())->set("Tom");
-        section->add(name);
-
-        shared_ptr<SectionPairRow> jobs = make_shared<SectionPairRow>("jobs", SectionPairRowEnumType::SECTION_PAIR_ROW_LIST_VALUE);
-        shared_ptr<SectionPairRowListValue> jobList = dynamic_pointer_cast<SectionPairRowListValue>(jobs->getValue());
-        jobList->add("Farmer");
-        jobList->add("Bounty Hunter");
-        section->add(jobs);
-
-        shared_ptr<SectionPairRow> age = make_shared<SectionPairRow>("age", SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE);
-        dynamic_pointer_cast<SectionPairRowSingleValue>(age->getValue())->set("33");
-        section->add(age);
-
-        return section;
-      }
-
-      static byte_field createSerializedSection()
-      {
-        byte_field serializedSection = NewLine::get() + "[general]" + NewLine::get();
-        byte_field serializedNameRow = "name=Tom" + NewLine::get();
-        byte_field serializedJobsRow = "jobs:" + NewLine::get() + "  Farmer" + NewLine::get() + "  Bounty Hunter" + NewLine::get();
-        byte_field serializedAgeRow = "age=33" + NewLine::get();
-
-        return serializedSection + serializedNameRow + serializedJobsRow + serializedAgeRow;
-      }
   };
 
   TEST_F(SerializableSectionPairSectionTest, constructor_no_reference)
@@ -88,9 +59,9 @@ namespace
 
   TEST_F(SerializableSectionPairSectionTest, marshal)
   {
-    shared_ptr<SectionPairSection> section = SerializableSectionPairSectionTest::createSection();
+    shared_ptr<SectionPairSection> section = SectionPairSectionProvider::createSection();
     SerializableSectionPairSection serializable{section};
-    byte_field expected = SerializableSectionPairSectionTest::createSerializedSection();
+    byte_field expected = SectionPairSectionProvider::createSerializedSection();
     byte_field actual = serializable.marshal();
 
     ASSERT_STREQ(expected.c_str(), actual.c_str());
@@ -100,7 +71,7 @@ namespace
   {
     shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("tmp-id");
     SerializableSectionPairSection serializable{section};
-    serializable.unmarshal(SerializableSectionPairSectionTest::createSerializedSection());
+    serializable.unmarshal(SectionPairSectionProvider::createSerializedSection());
 
     ASSERT_STREQ("general", section->getSectionId().c_str());
     ASSERT_EQ(3, section->getRowAmount());

+ 47 - 0
test/classes/io/section-pair/SectionPairSectionProvider.cpp

@@ -0,0 +1,47 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-02-15
+* Changed:         2023-02-15
+*
+* */
+
+#include "SectionPairSectionProvider.hpp"
+
+test::io::SectionPairSectionProvider::SectionPairSectionProvider() = default;
+
+test::io::SectionPairSectionProvider::~SectionPairSectionProvider() = default;
+
+::std::shared_ptr<ls::std::io::SectionPairSection> test::io::SectionPairSectionProvider::createSection()
+{
+  ::std::shared_ptr<ls::std::io::SectionPairSection> section = ::std::make_shared<ls::std::io::SectionPairSection>("general");
+
+  ::std::shared_ptr<ls::std::io::SectionPairRow> name = ::std::make_shared<ls::std::io::SectionPairRow>("name", ls::std::io::SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE);
+  ::std::dynamic_pointer_cast<ls::std::io::SectionPairRowSingleValue>(name->getValue())->set("Tom");
+  section->add(name);
+
+  ::std::shared_ptr<ls::std::io::SectionPairRow> jobs = ::std::make_shared<ls::std::io::SectionPairRow>("jobs", ls::std::io::SectionPairRowEnumType::SECTION_PAIR_ROW_LIST_VALUE);
+  ::std::shared_ptr<ls::std::io::SectionPairRowListValue> jobList = ::std::dynamic_pointer_cast<ls::std::io::SectionPairRowListValue>(jobs->getValue());
+  jobList->add("Farmer");
+  jobList->add("Bounty Hunter");
+  section->add(jobs);
+
+  ::std::shared_ptr<ls::std::io::SectionPairRow> age = ::std::make_shared<ls::std::io::SectionPairRow>("age", ls::std::io::SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE);
+  ::std::dynamic_pointer_cast<ls::std::io::SectionPairRowSingleValue>(age->getValue())->set("33");
+  section->add(age);
+
+  return section;
+}
+
+ls::std::core::type::byte_field test::io::SectionPairSectionProvider::createSerializedSection()
+{
+  ::std::string newLine = ls::std::io::NewLine::get();
+
+  ls::std::core::type::byte_field serializedSection = newLine + "[general]" + newLine;
+  ls::std::core::type::byte_field serializedNameRow = "name=Tom" + newLine;
+  ls::std::core::type::byte_field serializedJobsRow = "jobs:" + newLine + "  Farmer" + newLine + "  Bounty Hunter" + newLine;
+  ls::std::core::type::byte_field serializedAgeRow = "age=33" + newLine;
+
+  return serializedSection + serializedNameRow + serializedJobsRow + serializedAgeRow;
+}

+ 31 - 0
test/classes/io/section-pair/SectionPairSectionProvider.hpp

@@ -0,0 +1,31 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-02-15
+* Changed:         2023-02-15
+*
+* */
+
+#ifndef LS_STD_SECTION_PAIR_SECTION_PROVIDER_HPP
+#define LS_STD_SECTION_PAIR_SECTION_PROVIDER_HPP
+
+#include <ls-std/ls-std-core.hpp>
+#include <ls-std/ls-std-io.hpp>
+#include <memory>
+
+namespace test::io
+{
+  class SectionPairSectionProvider
+  {
+    public:
+
+      SectionPairSectionProvider();
+      ~SectionPairSectionProvider();
+
+      static ::std::shared_ptr<ls::std::io::SectionPairSection> createSection();
+      static ls::std::core::type::byte_field createSerializedSection();
+  };
+}
+
+#endif

+ 3 - 1
test/ls-std-io-test.hpp

@@ -3,13 +3,15 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2022-05-14
- * Changed:         2023-02-03
+ * Changed:         2023-02-15
  *
  * */
 
 #ifndef LS_STD_LS_STD_IO_TEST_HPP
 #define LS_STD_LS_STD_IO_TEST_HPP
 
+#include <classes/io/section-pair/SectionPairSectionProvider.hpp>
+
 #include <classes/io/xml/TestDataFactory.hpp>
 #include <classes/io/xml/XmlParserTestWrapper.hpp>