#include #include #include #include #include #include namespace scwx { namespace wsr88d { namespace rpg { static const std::string logPrefix_ = "scwx::wsr88d::rpg::scit_data_packet"; static const auto logger_ = util::Logger::Create(logPrefix_); static const std::set packetCodes_ = {23, 24}; class ScitDataPacket::Impl { public: explicit Impl() {} ~Impl() = default; std::vector> packetList_ {}; }; ScitDataPacket::ScitDataPacket() : p(std::make_unique()) {} ScitDataPacket::~ScitDataPacket() = default; ScitDataPacket::ScitDataPacket(ScitDataPacket&&) noexcept = default; ScitDataPacket& ScitDataPacket::operator=(ScitDataPacket&&) noexcept = default; std::vector> ScitDataPacket::packet_list() const { return p->packetList_; } size_t ScitDataPacket::RecordCount() const { return p->packetList_.size(); } bool ScitDataPacket::ParseData(std::istream& is) { bool blockValid = true; if (!packetCodes_.contains(packet_code())) { logger_->warn("Invalid packet code: {}", packet_code()); blockValid = false; } if (blockValid) { std::uint32_t bytesRead = 0; std::uint32_t lengthOfBlock = length_of_block(); std::streampos dataStart = is.tellg(); std::streampos dataEnd = dataStart + static_cast(lengthOfBlock); while (bytesRead < lengthOfBlock) { std::shared_ptr packet = PacketFactory::Create(is); if (packet != nullptr) { p->packetList_.push_back(packet); bytesRead += static_cast(packet->data_size()); } else { break; } } if (bytesRead < lengthOfBlock) { logger_->trace("Block bytes read smaller than size: {} < {} bytes", bytesRead, lengthOfBlock); blockValid = false; is.seekg(dataEnd, std::ios_base::beg); } if (bytesRead > lengthOfBlock) { logger_->warn("Block bytes read larger than size: {} > {} bytes", bytesRead, lengthOfBlock); blockValid = false; is.seekg(dataEnd, std::ios_base::beg); } } return blockValid; } std::shared_ptr ScitDataPacket::Create(std::istream& is) { std::shared_ptr packet = std::make_shared(); if (!packet->Parse(is)) { packet.reset(); } return packet; } } // namespace rpg } // namespace wsr88d } // namespace scwx