From 798b348d8b7cd2465462f91724a16d4e6c02a19e Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Wed, 12 Jan 2022 00:25:47 -0600 Subject: [PATCH] Cell trend volume scan times --- .../rpg/cell_trend_volume_scan_times.hpp | 48 ++++++ .../rpg/cell_trend_volume_scan_times.cpp | 151 ++++++++++++++++++ .../source/scwx/wsr88d/rpg/packet_factory.cpp | 2 + wxdata/wxdata.cmake | 2 + 4 files changed, 203 insertions(+) create mode 100644 wxdata/include/scwx/wsr88d/rpg/cell_trend_volume_scan_times.hpp create mode 100644 wxdata/source/scwx/wsr88d/rpg/cell_trend_volume_scan_times.cpp diff --git a/wxdata/include/scwx/wsr88d/rpg/cell_trend_volume_scan_times.hpp b/wxdata/include/scwx/wsr88d/rpg/cell_trend_volume_scan_times.hpp new file mode 100644 index 00000000..0ae11183 --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rpg/cell_trend_volume_scan_times.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include + +#include +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +class CellTrendVolumeScanTimesImpl; + +class CellTrendVolumeScanTimes : public Packet +{ +public: + explicit CellTrendVolumeScanTimes(); + ~CellTrendVolumeScanTimes(); + + CellTrendVolumeScanTimes(const CellTrendVolumeScanTimes&) = delete; + CellTrendVolumeScanTimes& + operator=(const CellTrendVolumeScanTimes&) = delete; + + CellTrendVolumeScanTimes(CellTrendVolumeScanTimes&&) noexcept; + CellTrendVolumeScanTimes& operator=(CellTrendVolumeScanTimes&&) noexcept; + + uint16_t packet_code() const; + uint16_t length_of_block() const; + uint16_t number_of_volumes() const; + uint16_t latest_volume_pointer() const; + uint16_t volume_time(uint16_t v) 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/cell_trend_volume_scan_times.cpp b/wxdata/source/scwx/wsr88d/rpg/cell_trend_volume_scan_times.cpp new file mode 100644 index 00000000..811e62ee --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rpg/cell_trend_volume_scan_times.cpp @@ -0,0 +1,151 @@ +#include + +#include +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +static const std::string logPrefix_ = + "[scwx::wsr88d::rpg::cell_trend_volume_scan_times] "; + +class CellTrendVolumeScanTimesImpl +{ +public: + explicit CellTrendVolumeScanTimesImpl() : + packetCode_ {0}, + lengthOfBlock_ {0}, + numberOfVolumes_ {0}, + latestVolumePointer_ {0}, + volumeTime_ {} + { + } + ~CellTrendVolumeScanTimesImpl() = default; + + uint16_t packetCode_; + uint16_t lengthOfBlock_; + uint16_t numberOfVolumes_; + uint16_t latestVolumePointer_; + + std::vector volumeTime_; +}; + +CellTrendVolumeScanTimes::CellTrendVolumeScanTimes() : + p(std::make_unique()) +{ +} +CellTrendVolumeScanTimes::~CellTrendVolumeScanTimes() = default; + +CellTrendVolumeScanTimes::CellTrendVolumeScanTimes( + CellTrendVolumeScanTimes&&) noexcept = default; +CellTrendVolumeScanTimes& CellTrendVolumeScanTimes::operator=( + CellTrendVolumeScanTimes&&) noexcept = default; + +uint16_t CellTrendVolumeScanTimes::packet_code() const +{ + return p->packetCode_; +} + +uint16_t CellTrendVolumeScanTimes::length_of_block() const +{ + return p->lengthOfBlock_; +} + +uint16_t CellTrendVolumeScanTimes::number_of_volumes() const +{ + return p->numberOfVolumes_; +} + +uint16_t CellTrendVolumeScanTimes::latest_volume_pointer() const +{ + return p->latestVolumePointer_; +} + +uint16_t CellTrendVolumeScanTimes::volume_time(uint16_t v) const +{ + return p->volumeTime_[v]; +} + +size_t CellTrendVolumeScanTimes::data_size() const +{ + return p->lengthOfBlock_ + 4u; +} + +bool CellTrendVolumeScanTimes::Parse(std::istream& is) +{ + bool blockValid = true; + + std::streampos isBegin = is.tellg(); + + is.read(reinterpret_cast(&p->packetCode_), 2); + is.read(reinterpret_cast(&p->lengthOfBlock_), 2); + is.read(reinterpret_cast(&p->numberOfVolumes_), 2); + + p->packetCode_ = ntohs(p->packetCode_); + p->lengthOfBlock_ = ntohs(p->lengthOfBlock_); + p->numberOfVolumes_ = ntohs(p->numberOfVolumes_); + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; + blockValid = false; + } + else + { + if (p->packetCode_ != 22) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid packet code: " << p->packetCode_; + blockValid = false; + } + else if (p->lengthOfBlock_ < 4 || p->lengthOfBlock_ > 22) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid length of block: " << p->packetCode_; + blockValid = false; + } + } + + if (blockValid) + { + p->volumeTime_.resize(p->numberOfVolumes_); + + is.read(reinterpret_cast(p->volumeTime_.data()), + p->numberOfVolumes_ * 2u); + + SwapVector(p->volumeTime_); + } + + std::streampos isEnd = is.tellg(); + + if (!ValidateMessage(is, isEnd - isBegin)) + { + blockValid = false; + } + + return blockValid; +} + +std::shared_ptr +CellTrendVolumeScanTimes::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 cdaa0e17..8641aa81 100644 --- a/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp +++ b/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -61,6 +62,7 @@ static const std::unordered_map create_ { {19, HdaHailSymbolPacket::Create}, {20, PointFeatureSymbolPacket::Create}, {21, CellTrendDataPacket::Create}, + {22, CellTrendVolumeScanTimes::Create}, {23, ScitForecastDataPacket::Create}, {24, ScitForecastDataPacket::Create}, {25, StiCircleSymbolPacket::Create}, diff --git a/wxdata/wxdata.cmake b/wxdata/wxdata.cmake index 95263135..f19daa30 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/ccb_header.hpp include/scwx/wsr88d/rpg/cell_trend_data_packet.hpp + include/scwx/wsr88d/rpg/cell_trend_volume_scan_times.hpp 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 @@ -78,6 +79,7 @@ set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/ccb_header.hpp include/scwx/wsr88d/rpg/wmo_header.hpp) set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/ccb_header.cpp source/scwx/wsr88d/rpg/cell_trend_data_packet.cpp + source/scwx/wsr88d/rpg/cell_trend_volume_scan_times.cpp 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