SerializableSectionPairSection.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Author: Patrick-Christopher Mattulat
  3. * Company: Lynar Studios
  4. * E-Mail: webmaster@lynarstudios.com
  5. * Created: 2023-02-14
  6. * Changed: 2023-02-20
  7. *
  8. * */
  9. #include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
  10. #include <ls-std/core/exception/IllegalArgumentException.hpp>
  11. #include <ls-std/io/section-pair/evaluator/SectionPairSectionArgumentEvaluator.hpp>
  12. #include <ls-std/io/section-pair/model/SectionPairRow.hpp>
  13. #include <ls-std/io/section-pair/model/SectionPairSection.hpp>
  14. #include <ls-std/io/section-pair/serialization/SerializableSectionPairSection.hpp>
  15. #include <ls-std/io/section-pair/validator/SectionPairSectionIdUnmarshalValidator.hpp>
  16. ls::std::io::SerializableSectionPairSection::SerializableSectionPairSection(const ls::std::io::SerializableSectionPairParameter &_parameter) : ls::std::core::Class("SerializableSectionPairSection")
  17. {
  18. ::std::string message = this->getClassName() + ": model reference is null!";
  19. ls::std::core::NullPointerArgumentEvaluator(_parameter.getValue(), message).evaluate();
  20. this->parameter = _parameter;
  21. }
  22. ls::std::io::SerializableSectionPairSection::~SerializableSectionPairSection() = default;
  23. ::std::shared_ptr<ls::std::core::Class> ls::std::io::SerializableSectionPairSection::getValue()
  24. {
  25. return this->parameter.getValue();
  26. }
  27. ls::std::core::type::byte_field ls::std::io::SerializableSectionPairSection::marshal()
  28. {
  29. ls::std::core::type::byte_field serializedSection{};
  30. serializedSection += this->_marshalSectionId();
  31. serializedSection += this->_marshalRows();
  32. return serializedSection;
  33. }
  34. void ls::std::io::SerializableSectionPairSection::unmarshal(const ls::std::core::type::byte_field &_data)
  35. {
  36. ls::std::io::SectionPairSectionArgumentEvaluator{_data}.evaluate();
  37. size_t sectionHeaderSize = this->_unmarshalSectionHeader(_data);
  38. this->_unmarshalRows(_data.substr(sectionHeaderSize));
  39. }
  40. void ls::std::io::SerializableSectionPairSection::_checkSectionHeader(const ls::std::core::type::byte_field &_sectionHeader)
  41. {
  42. if (!ls::std::io::SectionPairSectionIdUnmarshalValidator{_sectionHeader, this->parameter.getNewLine()}.isValid())
  43. {
  44. throw ls::std::core::IllegalArgumentException{"serialized section header is not valid!"};
  45. }
  46. }
  47. ls::std::core::type::byte_field ls::std::io::SerializableSectionPairSection::_collectSectionRow(const ls::std::core::type::byte_field &_currentRows, ls::std::io::SectionPairRowEnumType &_type)
  48. {
  49. ::std::string row{};
  50. ::std::string newLine = this->parameter.getNewLine();
  51. ::std::string firstRow = _currentRows.substr(0, _currentRows.find(newLine) + newLine.size());
  52. if (ls::std::io::SerializableSectionPairSection::_isSingleValueRow(firstRow))
  53. {
  54. row = ls::std::io::SerializableSectionPairSection::_collectSectionSingleValueRow(firstRow, _type);
  55. }
  56. if (ls::std::io::SerializableSectionPairSection::_isListValueRow(firstRow))
  57. {
  58. row = this->_collectSectionListValueRow(_currentRows, _type);
  59. }
  60. return row;
  61. }
  62. ls::std::core::type::byte_field ls::std::io::SerializableSectionPairSection::_collectSectionListValueRow(const ls::std::core::type::byte_field &_currentRows, ls::std::io::SectionPairRowEnumType &_type)
  63. {
  64. ls::std::core::type::byte_field currentRows = _currentRows;
  65. ls::std::core::type::byte_field currentRow{}, row{};
  66. ::std::string newLine = this->parameter.getNewLine();
  67. _type = SectionPairRowEnumType::SECTION_PAIR_ROW_LIST_VALUE;
  68. size_t iterations{};
  69. bool isStillListRow{};
  70. do
  71. {
  72. if (currentRows.empty() && iterations > 1)
  73. {
  74. break;
  75. }
  76. ++iterations;
  77. currentRow = currentRows.substr(0, currentRows.find(newLine) + newLine.size());
  78. currentRows = currentRows.substr(currentRow.size());
  79. isStillListRow = !ls::std::io::SerializableSectionPairSection::_isStartingValueRow(currentRow) || iterations == 1;
  80. if (isStillListRow)
  81. {
  82. row += currentRow;
  83. }
  84. } while (isStillListRow);
  85. return row;
  86. }
  87. ls::std::core::type::byte_field ls::std::io::SerializableSectionPairSection::_collectSectionSingleValueRow(const ls::std::core::type::byte_field &_firstRow, ls::std::io::SectionPairRowEnumType &_type)
  88. {
  89. _type = SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE;
  90. return _firstRow;
  91. }
  92. size_t ls::std::io::SerializableSectionPairSection::_getNthSubStringPosition(const ls::std::core::type::byte_field &_text, const ls::std::core::type::byte_field &_subText)
  93. {
  94. size_t position = -1;
  95. size_t amount{};
  96. for (int index = 0; index < (_text.size() - _subText.size()); index++)
  97. {
  98. if (_text.substr(index, _subText.size()) == _subText)
  99. {
  100. ++amount;
  101. }
  102. if (amount == 2)
  103. {
  104. position = index;
  105. break;
  106. }
  107. }
  108. return position;
  109. }
  110. ls::std::core::type::byte_field ls::std::io::SerializableSectionPairSection::_getSectionHeader(const ls::std::core::type::byte_field &_data)
  111. {
  112. ls::std::core::type::byte_field sectionHeader{};
  113. ::std::string newLine = this->parameter.getNewLine();
  114. size_t position = ls::std::io::SerializableSectionPairSection::_getNthSubStringPosition(_data, newLine);
  115. if (position != -1)
  116. {
  117. sectionHeader = _data.substr(0, position + 2 * newLine.size());
  118. }
  119. return sectionHeader;
  120. }
  121. ls::std::core::type::byte_field ls::std::io::SerializableSectionPairSection::_getSectionId(const ls::std::core::type::byte_field &_sectionHeader)
  122. {
  123. ls::std::core::type::byte_field sectionId = _sectionHeader.substr(_sectionHeader.find('[') + 1);
  124. return sectionId.substr(0, sectionId.find(']'));
  125. }
  126. bool ls::std::io::SerializableSectionPairSection::_isListValueRow(const ::std::string &_currentRow)
  127. {
  128. return _currentRow.find(':') != ::std::string::npos;
  129. }
  130. bool ls::std::io::SerializableSectionPairSection::_isStartingValueRow(const ::std::string &_currentRow)
  131. {
  132. bool isSingleValue = ls::std::io::SerializableSectionPairSection::_isSingleValueRow(_currentRow);
  133. bool isListValue = ls::std::io::SerializableSectionPairSection::_isListValueRow(_currentRow);
  134. return isSingleValue || isListValue;
  135. }
  136. bool ls::std::io::SerializableSectionPairSection::_isSingleValueRow(const ::std::string &_currentRow)
  137. {
  138. return _currentRow.find('=') != ::std::string::npos;
  139. }
  140. ls::std::core::type::byte_field ls::std::io::SerializableSectionPairSection::_marshalRows()
  141. {
  142. ls::std::core::type::byte_field serializedSectionRows{};
  143. for (const auto &_row : ::std::dynamic_pointer_cast<ls::std::io::SectionPairSection>(this->parameter.getValue())->getList())
  144. {
  145. _row->reserveNewLine(this->parameter.getNewLine());
  146. serializedSectionRows += _row->marshal();
  147. }
  148. return serializedSectionRows;
  149. }
  150. ls::std::core::type::byte_field ls::std::io::SerializableSectionPairSection::_marshalSectionId()
  151. {
  152. ::std::string newLine = this->parameter.getNewLine();
  153. return newLine + "[" + ::std::dynamic_pointer_cast<ls::std::io::SectionPairSection>(this->parameter.getValue())->getSectionId() + "]" + newLine + newLine;
  154. }
  155. void ls::std::io::SerializableSectionPairSection::_unmarshalRow(const ::std::string &_sectionRow, ls::std::io::SectionPairRowEnumType _type)
  156. {
  157. ls::std::io::section_pair_row_list_element row = ::std::make_shared<ls::std::io::SectionPairRow>("tmp-dir", _type);
  158. row->reserveNewLine(this->parameter.getNewLine());
  159. row->unmarshal(_sectionRow);
  160. ::std::dynamic_pointer_cast<ls::std::io::SectionPairSection>(this->parameter.getValue())->add(row);
  161. }
  162. void ls::std::io::SerializableSectionPairSection::_unmarshalRows(const ls::std::core::type::byte_field &_serializedRows)
  163. {
  164. ::std::string currentRows = _serializedRows;
  165. ls::std::io::SectionPairRowEnumType type{};
  166. ::std::dynamic_pointer_cast<ls::std::io::SectionPairSection>(this->parameter.getValue());
  167. while (!currentRows.empty())
  168. {
  169. ::std::string sectionRow = this->_collectSectionRow(currentRows, type);
  170. this->_unmarshalRow(sectionRow, type);
  171. currentRows = currentRows.substr(sectionRow.size());
  172. }
  173. }
  174. size_t ls::std::io::SerializableSectionPairSection::_unmarshalSectionHeader(const ls::std::core::type::byte_field &_data)
  175. {
  176. ls::std::core::type::byte_field sectionHeader = this->_getSectionHeader(_data);
  177. this->_checkSectionHeader(sectionHeader);
  178. ::std::dynamic_pointer_cast<ls::std::io::SectionPairSection>(this->parameter.getValue())->setSectionId(ls::std::io::SerializableSectionPairSection::_getSectionId(sectionHeader));
  179. return sectionHeader.size();
  180. }