diff --git a/wxdata/include/scwx/wsr88d/rpg/generic_data_packet.hpp b/wxdata/include/scwx/wsr88d/rpg/generic_data_packet.hpp new file mode 100644 index 00000000..15cddff5 --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rpg/generic_data_packet.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +class GenericDataPacketImpl; + +class GenericDataPacket : public Packet +{ +public: + explicit GenericDataPacket(); + ~GenericDataPacket(); + + GenericDataPacket(const GenericDataPacket&) = delete; + GenericDataPacket& operator=(const GenericDataPacket&) = delete; + + GenericDataPacket(GenericDataPacket&&) noexcept; + GenericDataPacket& operator=(GenericDataPacket&&) noexcept; + + uint16_t packet_code() const; + uint32_t length_of_block() const; + + size_t data_size() const override; + + bool Parse(std::istream& is) override; + + static std::shared_ptr Create(std::istream& is); + +private: + std::unique_ptr p; +}; + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/source/scwx/wsr88d/rpg/generic_data_packet.cpp b/wxdata/source/scwx/wsr88d/rpg/generic_data_packet.cpp new file mode 100644 index 00000000..322b56ae --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rpg/generic_data_packet.cpp @@ -0,0 +1,114 @@ +#include + +#include +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +static const std::string logPrefix_ = + "[scwx::wsr88d::rpg::generic_data_packet] "; + +class GenericDataPacketImpl +{ +public: + explicit GenericDataPacketImpl() : + packetCode_ {0}, lengthOfBlock_ {0}, data_ {} + { + } + ~GenericDataPacketImpl() = default; + + uint16_t packetCode_; + uint32_t lengthOfBlock_; + + std::vector data_; +}; + +GenericDataPacket::GenericDataPacket() : + p(std::make_unique()) +{ +} +GenericDataPacket::~GenericDataPacket() = default; + +GenericDataPacket::GenericDataPacket(GenericDataPacket&&) noexcept = default; +GenericDataPacket& +GenericDataPacket::operator=(GenericDataPacket&&) noexcept = default; + +uint16_t GenericDataPacket::packet_code() const +{ + return p->packetCode_; +} + +uint32_t GenericDataPacket::length_of_block() const +{ + return p->lengthOfBlock_; +} + +size_t GenericDataPacket::data_size() const +{ + return p->lengthOfBlock_ + 8u; +} + +bool GenericDataPacket::Parse(std::istream& is) +{ + bool blockValid = true; + + std::streampos isBegin = is.tellg(); + + is.read(reinterpret_cast(&p->packetCode_), 2); + is.seekg(2, std::ios_base::cur); + is.read(reinterpret_cast(&p->lengthOfBlock_), 4); + + p->packetCode_ = ntohs(p->packetCode_); + p->lengthOfBlock_ = ntohl(p->lengthOfBlock_); + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; + blockValid = false; + } + else + { + if (p->packetCode_ != 28 && p->packetCode_ != 29) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid packet code: " << p->packetCode_; + blockValid = false; + } + } + + p->data_.resize(p->lengthOfBlock_); + is.read(reinterpret_cast(p->data_.data()), p->lengthOfBlock_); + + std::streampos isEnd = is.tellg(); + + if (!ValidateMessage(is, isEnd - isBegin)) + { + blockValid = false; + } + + return blockValid; +} + +std::shared_ptr GenericDataPacket::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 diff --git a/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp b/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp index 400abc86..074888c6 100644 --- a/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp +++ b/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -62,6 +63,8 @@ static const std::unordered_map create_ { {24, ScitForecastDataPacket::Create}, {25, StiCircleSymbolPacket::Create}, {26, PointGraphicSymbolPacket::Create}, + {28, GenericDataPacket::Create}, + {29, GenericDataPacket::Create}, {0x0802, SetColorLevelPacket::Create}, {0x0E03, LinkedContourVectorPacket::Create}, {0x3501, UnlinkedContourVectorPacket::Create}, diff --git a/wxdata/wxdata.cmake b/wxdata/wxdata.cmake index 35608977..524fb462 100644 --- a/wxdata/wxdata.cmake +++ b/wxdata/wxdata.cmake @@ -48,6 +48,7 @@ set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_map.cpp source/scwx/wsr88d/rda/volume_coverage_pattern_data.cpp) set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp include/scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp + include/scwx/wsr88d/rpg/generic_data_packet.hpp include/scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp include/scwx/wsr88d/rpg/level3_message_header.hpp include/scwx/wsr88d/rpg/linked_contour_vector_packet.hpp @@ -75,6 +76,7 @@ set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/digital_precipitation_data_array_pack include/scwx/wsr88d/rpg/wmo_header.hpp) set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.cpp source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp + source/scwx/wsr88d/rpg/generic_data_packet.cpp source/scwx/wsr88d/rpg/hda_hail_symbol_packet.cpp source/scwx/wsr88d/rpg/level3_message_header.cpp source/scwx/wsr88d/rpg/linked_contour_vector_packet.cpp