Преглед изворни кода

Make SectionPairDocument serializable

Patrick-Christopher Mattulat пре 2 година
родитељ
комит
1ed8267132

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

@@ -11,13 +11,15 @@
 #define LS_STD_SECTION_PAIR_DOCUMENT_HPP
 
 #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/SectionPairDocumentTypes.hpp>
 #include <ls-std/os/dynamic-goal.hpp>
+#include <memory>
 
 namespace ls::std::io
 {
-  class LS_STD_DYNAMIC_GOAL SectionPairDocument : public ls::std::core::Class
+  class LS_STD_DYNAMIC_GOAL SectionPairDocument : public ::std::enable_shared_from_this<SectionPairDocument>, public ls::std::core::Class, public ls::std::core::interface_type::ISerializable
   {
     public:
 
@@ -29,13 +31,17 @@ namespace ls::std::io
       [[nodiscard]] size_t getAmountOfSections();
       [[nodiscard]] ::std::string getHeader();
       [[nodiscard]] section_pair_document_section_list getSectionList();
+      [[nodiscard]] ls::std::core::type::byte_field marshal() override;
+      void unmarshal(const ls::std::core::type::byte_field &_data) override;
 
     private:
 
       const ::std::string header = "# section-pair document";
       ls::std::io::section_pair_document_section_list sections{};
+      ::std::shared_ptr<ls::std::core::interface_type::ISerializable> serializable{};
 
       void _checkSectionExistence(const ls::std::io::section_pair_identifier &_sectionId);
+      void _createSerializable();
       [[nodiscard]] bool _hasSection(const ls::std::io::section_pair_identifier &_identifier);
   };
 }

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

@@ -7,10 +7,12 @@
 *
 * */
 
+#include <ls-std/core/ConditionalFunctionExecutor.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/model/SectionPairDocument.hpp>
+#include <ls-std/io/section-pair/serialization/SerializableSectionPairDocument.hpp>
 
 ls::std::io::SectionPairDocument::SectionPairDocument() : ls::std::core::Class("SectionPairDocument")
 {}
@@ -60,6 +62,18 @@ ls::std::io::section_pair_document_section_list ls::std::io::SectionPairDocument
   return this->sections;
 }
 
+ls::std::core::type::byte_field ls::std::io::SectionPairDocument::marshal()
+{
+  ls::std::core::ConditionalFunctionExecutor{this->serializable == nullptr}.execute([this] { _createSerializable(); });
+  return this->serializable->marshal();
+}
+
+void ls::std::io::SectionPairDocument::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::SectionPairDocument::_checkSectionExistence(const ls::std::io::section_pair_identifier &_sectionId)
 {
   if (this->_hasSection(_sectionId))
@@ -68,6 +82,11 @@ void ls::std::io::SectionPairDocument::_checkSectionExistence(const ls::std::io:
   }
 }
 
+void ls::std::io::SectionPairDocument::_createSerializable()
+{
+  this->serializable = ::std::make_shared<ls::std::io::SerializableSectionPairDocument>(shared_from_this());
+}
+
 bool ls::std::io::SectionPairDocument::_hasSection(const ls::std::io::section_pair_identifier &_identifier)
 {
   bool sectionExists{};

+ 52 - 0
test/cases/io/section-pair/model/SectionPairDocumentTest.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
 {
@@ -106,4 +108,54 @@ namespace
     shared_ptr<SectionPairDocument> document = make_shared<SectionPairDocument>();
     ASSERT_TRUE(document->getSectionList().empty());
   }
+
+  TEST_F(SectionPairDocumentTest, marshal)
+  {
+    shared_ptr<SectionPairDocument> document = SectionPairDocumentProvider::createDocument();
+    byte_field expected = SectionPairDocumentProvider::createSerializedDocument();
+
+    ASSERT_STREQ(expected.c_str(), document->marshal().c_str());
+  }
+
+  TEST_F(SectionPairDocumentTest, unmarshal)
+  {
+    shared_ptr<SectionPairDocument> document = make_shared<SectionPairDocument>();
+    document->unmarshal(SectionPairDocumentProvider::createSerializedDocument());
+
+    ASSERT_EQ(2, document->getAmountOfSections());
+
+    // check general section
+
+    shared_ptr<SectionPairSection> general = document->get(0);
+    ASSERT_STREQ("general", general->getSectionId().c_str());
+    ASSERT_EQ(3, general->getRowAmount());
+
+    ASSERT_STREQ("name", general->get(0)->getKey().c_str());
+    ASSERT_STREQ("Sandra", dynamic_pointer_cast<SectionPairRowSingleValue>(general->get(0)->getValue())->get().c_str());
+
+    ASSERT_STREQ("age", general->get(1)->getKey().c_str());
+    ASSERT_STREQ("24", dynamic_pointer_cast<SectionPairRowSingleValue>(general->get(1)->getValue())->get().c_str());
+
+    ASSERT_STREQ("hobbies", general->get(2)->getKey().c_str());
+    shared_ptr<SectionPairRowListValue> hobbies = dynamic_pointer_cast<SectionPairRowListValue>(general->get(2)->getValue());
+    ASSERT_EQ(3, hobbies->getSize());
+    ASSERT_STREQ("swimming", hobbies->get(0).c_str());
+    ASSERT_STREQ("cycling", hobbies->get(1).c_str());
+    ASSERT_STREQ("singing", hobbies->get(2).c_str());
+
+    // check physical section
+
+    shared_ptr<SectionPairSection> physical = document->get(1);
+    ASSERT_STREQ("physical", physical->getSectionId().c_str());
+    ASSERT_EQ(3, physical->getRowAmount());
+
+    ASSERT_STREQ("eye-color", physical->get(0)->getKey().c_str());
+    ASSERT_STREQ("blue", dynamic_pointer_cast<SectionPairRowSingleValue>(physical->get(0)->getValue())->get().c_str());
+
+    ASSERT_STREQ("hair-color", physical->get(1)->getKey().c_str());
+    ASSERT_STREQ("red", dynamic_pointer_cast<SectionPairRowSingleValue>(physical->get(1)->getValue())->get().c_str());
+
+    ASSERT_STREQ("height", physical->get(2)->getKey().c_str());
+    ASSERT_STREQ("167", dynamic_pointer_cast<SectionPairRowSingleValue>(physical->get(2)->getValue())->get().c_str());
+  }
 }

+ 35 - 2
test/cases/io/section-pair/serialization/SerializableSectionPairDocumentTest.cpp

@@ -69,9 +69,42 @@ namespace
   {
     SerializableSectionPairDocument serializable(make_shared<SectionPairDocument>());
     serializable.unmarshal(SectionPairDocumentProvider::createSerializedDocument());
+    shared_ptr<SectionPairDocument> document = dynamic_pointer_cast<SectionPairDocument>(serializable.getValue());
 
-    shared_ptr<SectionPairDocument> expected = SectionPairDocumentProvider::createDocument();
+    ASSERT_EQ(2, document->getAmountOfSections());
 
-    ASSERT_EQ(2, expected->getAmountOfSections());
+    // check general section
+
+    shared_ptr<SectionPairSection> general = document->get(0);
+    ASSERT_STREQ("general", general->getSectionId().c_str());
+    ASSERT_EQ(3, general->getRowAmount());
+
+    ASSERT_STREQ("name", general->get(0)->getKey().c_str());
+    ASSERT_STREQ("Sandra", dynamic_pointer_cast<SectionPairRowSingleValue>(general->get(0)->getValue())->get().c_str());
+
+    ASSERT_STREQ("age", general->get(1)->getKey().c_str());
+    ASSERT_STREQ("24", dynamic_pointer_cast<SectionPairRowSingleValue>(general->get(1)->getValue())->get().c_str());
+
+    ASSERT_STREQ("hobbies", general->get(2)->getKey().c_str());
+    shared_ptr<SectionPairRowListValue> hobbies = dynamic_pointer_cast<SectionPairRowListValue>(general->get(2)->getValue());
+    ASSERT_EQ(3, hobbies->getSize());
+    ASSERT_STREQ("swimming", hobbies->get(0).c_str());
+    ASSERT_STREQ("cycling", hobbies->get(1).c_str());
+    ASSERT_STREQ("singing", hobbies->get(2).c_str());
+
+    // check physical section
+
+    shared_ptr<SectionPairSection> physical = document->get(1);
+    ASSERT_STREQ("physical", physical->getSectionId().c_str());
+    ASSERT_EQ(3, physical->getRowAmount());
+
+    ASSERT_STREQ("eye-color", physical->get(0)->getKey().c_str());
+    ASSERT_STREQ("blue", dynamic_pointer_cast<SectionPairRowSingleValue>(physical->get(0)->getValue())->get().c_str());
+
+    ASSERT_STREQ("hair-color", physical->get(1)->getKey().c_str());
+    ASSERT_STREQ("red", dynamic_pointer_cast<SectionPairRowSingleValue>(physical->get(1)->getValue())->get().c_str());
+
+    ASSERT_STREQ("height", physical->get(2)->getKey().c_str());
+    ASSERT_STREQ("167", dynamic_pointer_cast<SectionPairRowSingleValue>(physical->get(2)->getValue())->get().c_str());
   }
 }