supercell-wx/wxdata/source/scwx/wsr88d/rda/rda_prf_data.cpp
2025-05-16 23:51:12 -05:00

120 lines
3.2 KiB
C++

#include <scwx/wsr88d/rda/rda_prf_data.hpp>
#include <scwx/util/logger.hpp>
namespace scwx::wsr88d::rda
{
static const std::string logPrefix_ = "scwx::wsr88d::rda::rda_prf_data";
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
struct RdaPrfWaveformData
{
std::uint16_t waveformType_ {0};
std::uint16_t prfCount_ {0};
std::vector<std::uint32_t> prfValues_ {};
};
class RdaPrfData::Impl
{
public:
explicit Impl() = default;
~Impl() = default;
Impl(const Impl&) = delete;
Impl& operator=(const Impl&) = delete;
Impl(const Impl&&) = delete;
Impl& operator=(const Impl&&) = delete;
std::uint16_t numberOfWaveforms_ {0};
std::vector<RdaPrfWaveformData> waveformData_ {};
};
RdaPrfData::RdaPrfData() : p(std::make_unique<Impl>()) {}
RdaPrfData::~RdaPrfData() = default;
RdaPrfData::RdaPrfData(RdaPrfData&&) noexcept = default;
RdaPrfData& RdaPrfData::operator=(RdaPrfData&&) noexcept = default;
bool RdaPrfData::Parse(std::istream& is)
{
logger_->trace("Parsing RDA PRF Data (Message Type 32)");
bool messageValid = true;
std::size_t bytesRead = 0;
std::streampos isBegin = is.tellg();
is.read(reinterpret_cast<char*>(&p->numberOfWaveforms_), 2); // 1
is.seekg(2, std::ios_base::cur); // 2
bytesRead += 4;
p->numberOfWaveforms_ = ntohs(p->numberOfWaveforms_);
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers): Readability
if (p->numberOfWaveforms_ < 1 || p->numberOfWaveforms_ > 5)
{
logger_->warn("Invalid number of waveforms: {}", p->numberOfWaveforms_);
p->numberOfWaveforms_ = 0;
messageValid = false;
}
p->waveformData_.resize(p->numberOfWaveforms_);
for (std::uint16_t i = 0; i < p->numberOfWaveforms_; ++i)
{
auto& w = p->waveformData_[i];
is.read(reinterpret_cast<char*>(&w.waveformType_), 2); // P1
is.read(reinterpret_cast<char*>(&w.prfCount_), 2); // P2
w.waveformType_ = ntohs(w.waveformType_);
w.prfCount_ = ntohs(w.prfCount_);
bytesRead += 4;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers): Readability
if (w.prfCount_ > 255)
{
logger_->warn("Invalid PRF count: {} (waveform {})", w.prfCount_, i);
w.prfCount_ = 0;
messageValid = false;
break;
}
w.prfValues_.resize(w.prfCount_);
for (std::uint16_t j = 0; j < w.prfCount_; ++j)
{
is.read(reinterpret_cast<char*>(&w.prfValues_[j]), 4);
}
bytesRead += static_cast<std::size_t>(w.prfCount_) * 4;
SwapVector(w.prfValues_);
}
is.seekg(isBegin, std::ios_base::beg);
if (!ValidateMessage(is, bytesRead))
{
messageValid = false;
}
return messageValid;
}
std::shared_ptr<RdaPrfData> RdaPrfData::Create(Level2MessageHeader&& header,
std::istream& is)
{
std::shared_ptr<RdaPrfData> message = std::make_shared<RdaPrfData>();
message->set_header(std::move(header));
if (!message->Parse(is))
{
message.reset();
}
return message;
}
} // namespace scwx::wsr88d::rda