mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-11-04 14:40:04 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			120 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			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;
 | 
						|
 | 
						|
   const 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
 |