From 3ae8eb24ab2e00fb4e6e1347784b860c833fe8f3 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Fri, 18 Jun 2021 21:54:05 -0500 Subject: [PATCH] Parse RDA Adaptation Data (Message Type 18) --- wxdata/include/scwx/util/vectorbuf.hpp | 7 + .../scwx/wsr88d/rda/rda_adaptation_data.hpp | 42 + wxdata/source/scwx/util/vectorbuf.cpp | 71 ++ .../scwx/wsr88d/rda/message_factory.cpp | 5 +- .../scwx/wsr88d/rda/rda_adaptation_data.cpp | 946 ++++++++++++++++++ wxdata/wxdata.cmake | 6 +- 6 files changed, 1074 insertions(+), 3 deletions(-) create mode 100644 wxdata/include/scwx/wsr88d/rda/rda_adaptation_data.hpp create mode 100644 wxdata/source/scwx/wsr88d/rda/rda_adaptation_data.cpp diff --git a/wxdata/include/scwx/util/vectorbuf.hpp b/wxdata/include/scwx/util/vectorbuf.hpp index 6673f97a..3aac753d 100644 --- a/wxdata/include/scwx/util/vectorbuf.hpp +++ b/wxdata/include/scwx/util/vectorbuf.hpp @@ -19,6 +19,13 @@ public: void update_read_pointers(size_t size); +protected: + pos_type + seekoff(std::streamoff off, + std::ios_base::seekdir way, + std::ios_base::openmode which = std::ios_base::in | + std::ios_base::out) override; + private: std::vector& v_; }; diff --git a/wxdata/include/scwx/wsr88d/rda/rda_adaptation_data.hpp b/wxdata/include/scwx/wsr88d/rda/rda_adaptation_data.hpp new file mode 100644 index 00000000..d682afee --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rda/rda_adaptation_data.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rda +{ + +class RdaAdaptationDataImpl; + +class RdaAdaptationData : public Message +{ +public: + explicit RdaAdaptationData(); + ~RdaAdaptationData(); + + RdaAdaptationData(const Message&) = delete; + RdaAdaptationData& operator=(const RdaAdaptationData&) = delete; + + RdaAdaptationData(RdaAdaptationData&&) noexcept; + RdaAdaptationData& operator=(RdaAdaptationData&&) noexcept; + + const std::string& adap_file_name() const; + const std::string& adap_format() const; + + bool Parse(std::istream& is); + + static std::unique_ptr Create(MessageHeader&& header, + std::istream& is); + +private: + std::unique_ptr p; +}; + +} // namespace rda +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/source/scwx/util/vectorbuf.cpp b/wxdata/source/scwx/util/vectorbuf.cpp index 2149e299..8e764a5b 100644 --- a/wxdata/source/scwx/util/vectorbuf.cpp +++ b/wxdata/source/scwx/util/vectorbuf.cpp @@ -15,5 +15,76 @@ void vectorbuf::update_read_pointers(size_t size) setg(v_.data(), v_.data(), v_.data() + size); } +vectorbuf::pos_type vectorbuf::seekoff(std::streamoff off, + std::ios_base::seekdir way, + std::ios_base::openmode which) +{ + // Adapted from Microsoft stringbuf reference implementation + // Copyright (c) Microsoft Corporation. + // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + + // Change position by off, according to way, which + const auto gptrOld = gptr(); + const auto pptrOld = pptr(); + const auto seekHigh = (pptrOld == nullptr) ? egptr() : pptr(); + + const auto seekLow = eback(); + const auto seekDist = seekHigh - seekLow; + off_type newOffset; + switch (way) + { + case std::ios_base::beg: newOffset = 0; break; + case std::ios_base::end: newOffset = seekDist; break; + case std::ios_base::cur: + { + constexpr auto BOTH = std::ios_base::in | std::ios_base::out; + if ((which & BOTH) != BOTH) + { + if (which & std::ios_base::in) + { + if (gptrOld || !seekLow) + { + newOffset = gptrOld - seekLow; + break; + } + } + else if ((which & std::ios_base::out) && (pptrOld || !seekLow)) + { + newOffset = pptrOld - seekLow; + break; + } + } + } + + default: return pos_type(off_type(-1)); + } + + if (static_cast(off) + newOffset > + static_cast(seekDist)) + { + return pos_type(off_type(-1)); + } + + off += newOffset; + if (off != 0 && (((which & std::ios_base::in) && !gptrOld) || + ((which & std::ios_base::out) && !pptrOld))) + { + return pos_type(off_type(-1)); + } + + const auto next = seekLow + off; + if ((which & std::ios_base::in) && gptrOld) + { + setg(seekLow, next, seekHigh); + } + + if ((which & std::ios_base::out) && pptrOld) + { + setp(seekLow, next, epptr()); + } + + return pos_type(off); +} + } // namespace util } // namespace scwx diff --git a/wxdata/source/scwx/wsr88d/rda/message_factory.cpp b/wxdata/source/scwx/wsr88d/rda/message_factory.cpp index dae208d4..d059799c 100644 --- a/wxdata/source/scwx/wsr88d/rda/message_factory.cpp +++ b/wxdata/source/scwx/wsr88d/rda/message_factory.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -22,7 +23,7 @@ typedef std::function(MessageHeader&&, std::istream&)> CreateMessageFunction; static const std::unordered_map create_ { - {15, ClutterFilterMap::Create}}; + {15, ClutterFilterMap::Create}, {18, RdaAdaptationData::Create}}; static std::vector messageData_; static size_t bufferedSize_; @@ -70,6 +71,7 @@ MessageInfo MessageFactory::Create(std::istream& is) { // Estimate total message size messageData_.reserve(dataSize * totalSegments); + messageBufferStream_.clear(); bufferedSize_ = 0; } @@ -112,6 +114,7 @@ MessageInfo MessageFactory::Create(std::istream& is) info.message = create_.at(messageType)(std::move(header), *messageStream); messageData_.shrink_to_fit(); + messageBufferStream_.clear(); bufferedSize_ = 0; } } diff --git a/wxdata/source/scwx/wsr88d/rda/rda_adaptation_data.cpp b/wxdata/source/scwx/wsr88d/rda/rda_adaptation_data.cpp new file mode 100644 index 00000000..2344aa5c --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rda/rda_adaptation_data.cpp @@ -0,0 +1,946 @@ +#include + +#include +#include +#include +#include + +#include + +#ifdef WIN32 +# include +#else +# include +#endif + +namespace scwx +{ +namespace wsr88d +{ +namespace rda +{ + +static const std::string logPrefix_ = + "[scwx::wsr88d::rda::rda_adaptation_data] "; + +static void ReadBoolean(std::istream& is, bool& value); +static void ReadChar(std::istream& is, char& value); +static float SwapFloat(float f); +template +static void SwapFloatArray(std::array& arr); +template +static void SwapFloatMap(std::map& m); + +struct AntManualSetup +{ + int32_t ielmin_; + int32_t ielmax_; + uint32_t fazvelmax_; + uint32_t felvelmax_; + int32_t igndHgt_; + uint32_t iradHgt_; + + AntManualSetup() : + ielmin_ {0}, + ielmax_ {0}, + fazvelmax_ {0}, + felvelmax_ {0}, + igndHgt_ {0}, + iradHgt_ {0} + { + } +}; + +class RdaAdaptationDataImpl +{ +public: + explicit RdaAdaptationDataImpl() : + adapFileName_ {}, + adapFormat_ {}, + adapRevision_ {}, + adapDate_ {}, + adapTime_ {}, + lowerPreLimit_ {0.0f}, + azLat_ {0.0f}, + upperPreLimit_ {0.0f}, + elLat_ {0.0f}, + parkaz_ {0.0f}, + parkel_ {0.0f}, + aFuelConv_ {0.0f}, + aMinShelterTemp_ {0.0f}, + aMaxShelterTemp_ {0.0f}, + aMinShelterAcTempDiff_ {0.0f}, + aMaxXmtrAirTemp_ {0.0f}, + aMaxRadTemp_ {0.0f}, + aMaxRadTempRise_ {0.0f}, + lowerDeadLimit_ {0.0f}, + upperDeadLimit_ {0.0f}, + aMinGenRoomTemp_ {0.0f}, + aMaxGenRoomTemp_ {0.0f}, + spip5VRegLim_ {0.0f}, + spip15VRegLim_ {0.0f}, + rpgCoLocated_ {false}, + specFilterInstalled_ {false}, + tpsInstalled_ {false}, + rmsInstalled_ {false}, + aHvdlTstInt_ {0}, + aRpgLtInt_ {0}, + aMinStabUtilPwrTime_ {0}, + aGenAutoExerInterval_ {0}, + aUtilPwrSwReqInterval_ {0}, + aLowFuelLevel_ {0.0f}, + configChanNumber_ {0}, + redundantChanConfig_ {0}, + attenTable_ {0.0f}, + pathLosses_ {}, + vTsCw_ {0.0f}, + hRnscale_ {0.0f}, + atmos_ {0.0f}, + elIndex_ {0.0f}, + tfreqMhz_ {0}, + baseDataTcn_ {0.0f}, + reflDataTover_ {0.0f}, + tarHDbz0Lp_ {0.0f}, + tarVDbz0Lp_ {0.0f}, + initPhiDp_ {0}, + normInitPhiDp_ {0}, + lxLp_ {0.0f}, + lxSp_ {0.0f}, + meteorParam_ {0.0f}, + antennaGain_ {0.0f}, + velDegradLimit_ {0.0f}, + wthDegradLimit_ {0.0f}, + hNoisetempDgradLimit_ {0.0f}, + hMinNoisetemp_ {0}, + vNoisetempDgradLimit_ {0.0f}, + vMinNoisetemp_ {0}, + klyDegradeLimit_ {0.0f}, + tsCoho_ {0.0f}, + hTsCw_ {0.0f}, + tsStalo_ {0.0f}, + ameHNoiseEnr_ {0.0f}, + xmtrPeakPwrHighLimit_ {0.0f}, + xmtrPeakPwrLowLimit_ {0.0f}, + hDbz0DeltaLimit_ {0.0f}, + threshold1_ {0.0f}, + threshold2_ {0.0f}, + clutSuppDgradLim_ {0.0f}, + range0Value_ {0.0f}, + xmtrPwrMtrScale_ {0.0f}, + vDbz0DeltaLimit_ {0.0f}, + tarHDbz0Sp_ {0.0f}, + tarVDbz0Sp_ {0.0f}, + deltaprf_ {0}, + tauSp_ {0}, + tauLp_ {0}, + ncDeadValue_ {0}, + tauRfSp_ {0}, + tauRfLp_ {0}, + seg1Lim_ {0.0f}, + slatsec_ {0.0f}, + slonsec_ {0.0f}, + slatdeg_ {0}, + slatmin_ {0}, + slondeg_ {0}, + slonmin_ {0}, + slatdir_ {0}, + slondir_ {0}, + azCorrectionFactor_ {0.0f}, + elCorrectionFactor_ {0.0f}, + siteName_ {}, + antManualSetup_(), + azPosSustainDrive_ {0.0f}, + azNegSustainDrive_ {0.0f}, + azNomPosDriveSlope_ {0.0f}, + azNomNegDriveSlope_ {0.0f}, + azFeedbackSlope_ {0.0f}, + elPosSustainDrive_ {0.0f}, + elNegSustainDrive_ {0.0f}, + elNomPosDriveSlope_ {0.0f}, + elNomNegDriveSlope_ {0.0f}, + elFeedbackSlope_ {0.0f}, + elFirstSlope_ {0.0f}, + elSecondSlope_ {0.0f}, + elThirdSlope_ {0.0f}, + elDroopPos_ {0.0f}, + elOffNeutralDrive_ {0.0f}, + azIntertia_ {0.0f}, + elInertia_ {0.0f}, + rvp8nvIwaveguideLength_ {0}, + vRnscale_ {0.0f}, + velDataTover_ {0.0f}, + widthDataTover_ {0.0f}, + dopplerRangeStart_ {0.0f}, + maxElIndex_ {0}, + seg2Lim_ {0.0f}, + seg3Lim_ {0.0f}, + seg4Lim_ {0.0f}, + nbrElSegments_ {0}, + hNoiseLong_ {0.0f}, + antNoiseTemp_ {0.0f}, + hNoiseShort_ {0.0f}, + hNoiseTolerance_ {0.0f}, + minHDynRange_ {0.0f}, + genInstalled_ {false}, + genExercise_ {false}, + vNoiseTolerance_ {0.0f}, + minVDynRange_ {0.0f}, + zdrBiasDgradLim_ {0.0f}, + baselineZdrBias_ {0.0f}, + vNoiseLong_ {0.0f}, + vNoiseShort_ {0.0f}, + zdrDataTover_ {0.0f}, + phiDataTover_ {0.0f}, + rhoDataTover_ {0.0f}, + staloPowerDgradLimit_ {0.0f}, + staloPowerMaintLimit_ {0.0f}, + minHPwrSense_ {0.0f}, + minVPwrSense_ {0.0f}, + hPwrSenseOffset_ {0.0f}, + vPwrSenseOffset_ {0.0f}, + psGainRef_ {0.0f}, + rfPalletBroadLoss_ {0.0f}, + amePsTolerance_ {0.0f}, + ameMaxTemp_ {0.0f}, + ameMinTemp_ {0.0f}, + rcvrModMaxTemp_ {0.0f}, + rcvrModMinTemp_ {0.0f}, + biteModMaxTemp_ {0.0f}, + biteModMinTemp_ {0.0f}, + defaultPolarization_ {0}, + trLimitDgradLimit_ {0.0f}, + trLimitFailLimit_ {0.0f}, + rfpStepperEnabled_ {false}, + ameCurrentTolerance_ {0.0f}, + hOnlyPolarization_ {0}, + vOnlyPolarization_ {0}, + sunBias_ {0.0f}, + aMinShelterTempWarn_ {0.0f}, + powerMeterZero_ {0.0f}, + txbBaseline_ {0.0f}, + txbAlarmThresh_ {0.0f} {}; + ~RdaAdaptationDataImpl() = default; + + std::string adapFileName_; + std::string adapFormat_; + std::string adapRevision_; + std::string adapDate_; + std::string adapTime_; + float lowerPreLimit_; + float azLat_; + float upperPreLimit_; + float elLat_; + float parkaz_; + float parkel_; + std::array aFuelConv_; + float aMinShelterTemp_; + float aMaxShelterTemp_; + float aMinShelterAcTempDiff_; + float aMaxXmtrAirTemp_; + float aMaxRadTemp_; + float aMaxRadTempRise_; + float lowerDeadLimit_; + float upperDeadLimit_; + float aMinGenRoomTemp_; + float aMaxGenRoomTemp_; + float spip5VRegLim_; + float spip15VRegLim_; + bool rpgCoLocated_; + bool specFilterInstalled_; + bool tpsInstalled_; + bool rmsInstalled_; + uint32_t aHvdlTstInt_; + uint32_t aRpgLtInt_; + uint32_t aMinStabUtilPwrTime_; + uint32_t aGenAutoExerInterval_; + uint32_t aUtilPwrSwReqInterval_; + float aLowFuelLevel_; + uint32_t configChanNumber_; + uint32_t redundantChanConfig_; + std::array attenTable_; + std::map pathLosses_; + float vTsCw_; + std::array hRnscale_; + std::array atmos_; + std::array elIndex_; + uint32_t tfreqMhz_; + float baseDataTcn_; + float reflDataTover_; + float tarHDbz0Lp_; + float tarVDbz0Lp_; + uint32_t initPhiDp_; + uint32_t normInitPhiDp_; + float lxLp_; + float lxSp_; + float meteorParam_; + float antennaGain_; + float velDegradLimit_; + float wthDegradLimit_; + float hNoisetempDgradLimit_; + uint32_t hMinNoisetemp_; + float vNoisetempDgradLimit_; + uint32_t vMinNoisetemp_; + float klyDegradeLimit_; + float tsCoho_; + float hTsCw_; + float tsStalo_; + float ameHNoiseEnr_; + float xmtrPeakPwrHighLimit_; + float xmtrPeakPwrLowLimit_; + float hDbz0DeltaLimit_; + float threshold1_; + float threshold2_; + float clutSuppDgradLim_; + float range0Value_; + float xmtrPwrMtrScale_; + float vDbz0DeltaLimit_; + float tarHDbz0Sp_; + float tarVDbz0Sp_; + uint32_t deltaprf_; + uint32_t tauSp_; + uint32_t tauLp_; + uint32_t ncDeadValue_; + uint32_t tauRfSp_; + uint32_t tauRfLp_; + float seg1Lim_; + float slatsec_; + float slonsec_; + uint32_t slatdeg_; + uint32_t slatmin_; + uint32_t slondeg_; + uint32_t slonmin_; + char slatdir_; + char slondir_; + float azCorrectionFactor_; + float elCorrectionFactor_; + std::string siteName_; + AntManualSetup antManualSetup_; + float azPosSustainDrive_; + float azNegSustainDrive_; + float azNomPosDriveSlope_; + float azNomNegDriveSlope_; + float azFeedbackSlope_; + float elPosSustainDrive_; + float elNegSustainDrive_; + float elNomPosDriveSlope_; + float elNomNegDriveSlope_; + float elFeedbackSlope_; + float elFirstSlope_; + float elSecondSlope_; + float elThirdSlope_; + float elDroopPos_; + float elOffNeutralDrive_; + float azIntertia_; + float elInertia_; + uint32_t rvp8nvIwaveguideLength_; + std::array vRnscale_; + float velDataTover_; + float widthDataTover_; + float dopplerRangeStart_; + uint32_t maxElIndex_; + float seg2Lim_; + float seg3Lim_; + float seg4Lim_; + uint32_t nbrElSegments_; + float hNoiseLong_; + float antNoiseTemp_; + float hNoiseShort_; + float hNoiseTolerance_; + float minHDynRange_; + bool genInstalled_; + bool genExercise_; + float vNoiseTolerance_; + float minVDynRange_; + float zdrBiasDgradLim_; + float baselineZdrBias_; + float vNoiseLong_; + float vNoiseShort_; + float zdrDataTover_; + float phiDataTover_; + float rhoDataTover_; + float staloPowerDgradLimit_; + float staloPowerMaintLimit_; + float minHPwrSense_; + float minVPwrSense_; + float hPwrSenseOffset_; + float vPwrSenseOffset_; + float psGainRef_; + float rfPalletBroadLoss_; + float amePsTolerance_; + float ameMaxTemp_; + float ameMinTemp_; + float rcvrModMaxTemp_; + float rcvrModMinTemp_; + float biteModMaxTemp_; + float biteModMinTemp_; + uint32_t defaultPolarization_; + float trLimitDgradLimit_; + float trLimitFailLimit_; + bool rfpStepperEnabled_; + float ameCurrentTolerance_; + uint32_t hOnlyPolarization_; + uint32_t vOnlyPolarization_; + float sunBias_; + float aMinShelterTempWarn_; + float powerMeterZero_; + float txbBaseline_; + float txbAlarmThresh_; +}; + +RdaAdaptationData::RdaAdaptationData() : + Message(), p(std::make_unique()) +{ +} +RdaAdaptationData::~RdaAdaptationData() = default; + +RdaAdaptationData::RdaAdaptationData(RdaAdaptationData&&) noexcept = default; +RdaAdaptationData& +RdaAdaptationData::operator=(RdaAdaptationData&&) noexcept = default; + +const std::string& RdaAdaptationData::adap_file_name() const +{ + return p->adapFileName_; +} + +const std::string& RdaAdaptationData::adap_format() const +{ + return p->adapFormat_; +} + +bool RdaAdaptationData::Parse(std::istream& is) +{ + BOOST_LOG_TRIVIAL(debug) + << logPrefix_ << "Parsing RDA Adaptation Data (Message Type 18)"; + + bool messageValid = true; + size_t bytesRead = 0; + + p->adapFileName_.resize(12); + p->adapFormat_.resize(4); + p->adapRevision_.resize(4); + p->adapDate_.resize(12); + p->adapTime_.resize(12); + p->siteName_.resize(4); + + is.read(&p->adapFileName_[0], 12); // 0-11 + is.read(&p->adapFormat_[0], 4); // 12-15 + is.read(&p->adapRevision_[0], 4); // 16-19 + is.read(&p->adapDate_[0], 12); // 20-31 + is.read(&p->adapTime_[0], 12); // 32-43 + + is.read(reinterpret_cast(&p->lowerPreLimit_), 4); // 44-47 + is.read(reinterpret_cast(&p->azLat_), 4); // 48-51 + is.read(reinterpret_cast(&p->upperPreLimit_), 4); // 52-55 + is.read(reinterpret_cast(&p->elLat_), 4); // 56-59 + is.read(reinterpret_cast(&p->parkaz_), 4); // 60-63 + is.read(reinterpret_cast(&p->parkel_), 4); // 64-67 + + is.read(reinterpret_cast(&p->aFuelConv_[0]), + p->aFuelConv_.size() * 4); // 68-111 + + is.read(reinterpret_cast(&p->aMinShelterTemp_), 4); // 112-115 + is.read(reinterpret_cast(&p->aMaxShelterTemp_), 4); // 116-119 + is.read(reinterpret_cast(&p->aMinShelterAcTempDiff_), 4); // 120-123 + is.read(reinterpret_cast(&p->aMaxXmtrAirTemp_), 4); // 124-127 + is.read(reinterpret_cast(&p->aMaxRadTemp_), 4); // 128-131 + is.read(reinterpret_cast(&p->aMaxRadTempRise_), 4); // 132-135 + is.read(reinterpret_cast(&p->lowerDeadLimit_), 4); // 136-139 + is.read(reinterpret_cast(&p->upperDeadLimit_), 4); // 140-143 + + is.seekg(4, std::ios_base::cur); // 144-147 + + is.read(reinterpret_cast(&p->aMinGenRoomTemp_), 4); // 148-151 + is.read(reinterpret_cast(&p->aMaxGenRoomTemp_), 4); // 152-155 + is.read(reinterpret_cast(&p->spip5VRegLim_), 4); // 156-159 + is.read(reinterpret_cast(&p->spip15VRegLim_), 4); // 160-163 + + is.seekg(12, std::ios_base::cur); // 164-175 + + ReadBoolean(is, p->rpgCoLocated_); // 176-179 + ReadBoolean(is, p->specFilterInstalled_); // 180-183 + ReadBoolean(is, p->tpsInstalled_); // 184-187 + ReadBoolean(is, p->rmsInstalled_); // 188-191 + + is.read(reinterpret_cast(&p->aHvdlTstInt_), 4); // 192-195 + is.read(reinterpret_cast(&p->aRpgLtInt_), 4); // 196-199 + is.read(reinterpret_cast(&p->aMinStabUtilPwrTime_), 4); // 200-203 + is.read(reinterpret_cast(&p->aGenAutoExerInterval_), 4); // 204-207 + is.read(reinterpret_cast(&p->aUtilPwrSwReqInterval_), 4); // 208-211 + is.read(reinterpret_cast(&p->aLowFuelLevel_), 4); // 212-215 + is.read(reinterpret_cast(&p->configChanNumber_), 4); // 216-219 + + is.seekg(4, std::ios_base::cur); // 220-223 + + is.read(reinterpret_cast(&p->redundantChanConfig_), 4); // 224-227 + + is.read(reinterpret_cast(&p->attenTable_[0]), + p->attenTable_.size() * 4); // 228-643 + + is.seekg(24, std::ios_base::cur); // 644-667 + is.read(reinterpret_cast(&p->pathLosses_[7]), 4); // 668-671 + is.seekg(20, std::ios_base::cur); // 672-691 + is.read(reinterpret_cast(&p->pathLosses_[13]), 4); // 692-695 + is.seekg(56, std::ios_base::cur); // 696-751 + is.read(reinterpret_cast(&p->pathLosses_[28]), 4); // 752-755 + is.read(reinterpret_cast(&p->pathLosses_[29]), 4); // 756-759 + is.seekg(8, std::ios_base::cur); // 760-767 + is.read(reinterpret_cast(&p->pathLosses_[32]), 4); // 768-771 + is.read(reinterpret_cast(&p->pathLosses_[33]), 4); // 772-775 + is.seekg(4, std::ios_base::cur); // 776-779 + is.read(reinterpret_cast(&p->pathLosses_[35]), 4); // 780-783 + is.seekg(12, std::ios_base::cur); // 784-795 + is.read(reinterpret_cast(&p->pathLosses_[39]), 4); // 796-799 + is.read(reinterpret_cast(&p->pathLosses_[40]), 4); // 800-803 + is.seekg(4, std::ios_base::cur); // 804-807 + is.read(reinterpret_cast(&p->pathLosses_[42]), 4); // 808-811 + is.read(reinterpret_cast(&p->pathLosses_[43]), 4); // 812-815 + is.read(reinterpret_cast(&p->pathLosses_[44]), 4); // 816-819 + is.read(reinterpret_cast(&p->pathLosses_[45]), 4); // 820-823 + is.read(reinterpret_cast(&p->pathLosses_[46]), 4); // 824-827 + is.read(reinterpret_cast(&p->pathLosses_[47]), 4); // 828-831 + is.read(reinterpret_cast(&p->pathLosses_[48]), 4); // 832-835 + is.read(reinterpret_cast(&p->pathLosses_[49]), 4); // 836-839 + is.seekg(4, std::ios_base::cur); // 840-843 + is.read(reinterpret_cast(&p->pathLosses_[51]), 4); // 844-847 + is.read(reinterpret_cast(&p->pathLosses_[52]), 4); // 848-851 + is.read(reinterpret_cast(&p->pathLosses_[53]), 4); // 852-855 + is.seekg(8, std::ios_base::cur); // 856-863 + is.read(reinterpret_cast(&p->pathLosses_[56]), 4); // 864-867 + is.read(reinterpret_cast(&p->pathLosses_[57]), 4); // 868-871 + is.read(reinterpret_cast(&p->pathLosses_[58]), 4); // 872-875 + is.read(reinterpret_cast(&p->pathLosses_[59]), 4); // 876-879 + is.read(reinterpret_cast(&p->pathLosses_[60]), 4); // 880-883 + is.read(reinterpret_cast(&p->pathLosses_[61]), 4); // 884-887 + is.seekg(4, std::ios_base::cur); // 888-891 + is.read(reinterpret_cast(&p->pathLosses_[63]), 4); // 892-895 + is.read(reinterpret_cast(&p->pathLosses_[64]), 4); // 896-899 + is.read(reinterpret_cast(&p->pathLosses_[65]), 4); // 900-903 + is.read(reinterpret_cast(&p->pathLosses_[66]), 4); // 904-907 + is.read(reinterpret_cast(&p->pathLosses_[67]), 4); // 908-911 + is.read(reinterpret_cast(&p->pathLosses_[68]), 4); // 912-915 + is.seekg(4, std::ios_base::cur); // 916-919 + is.read(reinterpret_cast(&p->pathLosses_[70]), 4); // 920-923 + is.read(reinterpret_cast(&p->pathLosses_[71]), 4); // 924-927 + + is.seekg(8, std::ios_base::cur); // 928-935 + + is.read(reinterpret_cast(&p->vTsCw_), 4); // 936-939 + + is.read(reinterpret_cast(&p->hRnscale_[0]), + p->hRnscale_.size() * 4); // 940-991 + + is.read(reinterpret_cast(&p->atmos_[0]), + p->atmos_.size() * 4); // 992-1043 + + is.read(reinterpret_cast(&p->elIndex_[0]), + p->elIndex_.size() * 4); // 1044-1091 + + is.read(reinterpret_cast(&p->tfreqMhz_), 4); // 1092-1095 + is.read(reinterpret_cast(&p->baseDataTcn_), 4); // 1096-1099 + is.read(reinterpret_cast(&p->reflDataTover_), 4); // 1100-1103 + is.read(reinterpret_cast(&p->tarHDbz0Lp_), 4); // 1104-1107 + is.read(reinterpret_cast(&p->tarVDbz0Lp_), 4); // 1108-1111 + is.read(reinterpret_cast(&p->initPhiDp_), 4); // 1112-1115 + is.read(reinterpret_cast(&p->normInitPhiDp_), 4); // 1116-1119 + is.read(reinterpret_cast(&p->lxLp_), 4); // 1120-1123 + is.read(reinterpret_cast(&p->lxSp_), 4); // 1124-1127 + is.read(reinterpret_cast(&p->meteorParam_), 4); // 1128-1131 + + is.seekg(4, std::ios_base::cur); // 1132-1135 + + is.read(reinterpret_cast(&p->antennaGain_), 4); // 1136-1139 + + is.seekg(12, std::ios_base::cur); // 1140-1151 + + is.read(reinterpret_cast(&p->velDegradLimit_), 4); // 1152-1155 + is.read(reinterpret_cast(&p->wthDegradLimit_), 4); // 1156-1159 + is.read(reinterpret_cast(&p->hNoisetempDgradLimit_), 4); // 1160-1163 + is.read(reinterpret_cast(&p->hMinNoisetemp_), 4); // 1164-1167 + is.read(reinterpret_cast(&p->vNoisetempDgradLimit_), 4); // 1168-1171 + is.read(reinterpret_cast(&p->vMinNoisetemp_), 4); // 1172-1175 + is.read(reinterpret_cast(&p->klyDegradeLimit_), 4); // 1176-1179 + is.read(reinterpret_cast(&p->tsCoho_), 4); // 1180-1183 + is.read(reinterpret_cast(&p->hTsCw_), 4); // 1184-1187 + + is.seekg(8, std::ios_base::cur); // 1188-1195 + + is.read(reinterpret_cast(&p->tsStalo_), 4); // 1196-1199 + is.read(reinterpret_cast(&p->ameHNoiseEnr_), 4); // 1200-1203 + is.read(reinterpret_cast(&p->xmtrPeakPwrHighLimit_), 4); // 1204-1207 + is.read(reinterpret_cast(&p->xmtrPeakPwrLowLimit_), 4); // 1208-1211 + is.read(reinterpret_cast(&p->hDbz0DeltaLimit_), 4); // 1212-1215 + is.read(reinterpret_cast(&p->threshold1_), 4); // 1216-1219 + is.read(reinterpret_cast(&p->threshold2_), 4); // 1220-1223 + is.read(reinterpret_cast(&p->clutSuppDgradLim_), 4); // 1224-1227 + + is.seekg(4, std::ios_base::cur); // 1228-1231 + + is.read(reinterpret_cast(&p->range0Value_), 4); // 1232-1235 + is.read(reinterpret_cast(&p->xmtrPwrMtrScale_), 4); // 1236-1239 + is.read(reinterpret_cast(&p->vDbz0DeltaLimit_), 4); // 1240-1243 + is.read(reinterpret_cast(&p->tarHDbz0Sp_), 4); // 1244-1247 + is.read(reinterpret_cast(&p->tarVDbz0Sp_), 4); // 1248-1251 + is.read(reinterpret_cast(&p->deltaprf_), 4); // 1252-1255 + + is.seekg(8, std::ios_base::cur); // 1256-1263 + + is.read(reinterpret_cast(&p->tauSp_), 4); // 1264-1267 + is.read(reinterpret_cast(&p->tauLp_), 4); // 1268-1271 + is.read(reinterpret_cast(&p->ncDeadValue_), 4); // 1272-1275 + is.read(reinterpret_cast(&p->tauRfSp_), 4); // 1276-1279 + is.read(reinterpret_cast(&p->tauRfLp_), 4); // 1280-1283 + is.read(reinterpret_cast(&p->seg1Lim_), 4); // 1284-1287 + is.read(reinterpret_cast(&p->slatsec_), 4); // 1288-1291 + is.read(reinterpret_cast(&p->slonsec_), 4); // 1292-1295 + + is.seekg(4, std::ios_base::cur); // 1296-1299 + + is.read(reinterpret_cast(&p->slatdeg_), 4); // 1300-1303 + is.read(reinterpret_cast(&p->slatmin_), 4); // 1304-1307 + is.read(reinterpret_cast(&p->slondeg_), 4); // 1308-1311 + is.read(reinterpret_cast(&p->slonmin_), 4); // 1312-1315 + ReadChar(is, p->slatdir_); // 1316-1319 + ReadChar(is, p->slondir_); // 1320-1323 + + is.seekg(7036, std::ios_base::cur); // 1324-8359 + + is.read(reinterpret_cast(&p->azCorrectionFactor_), 4); // 8360-8363 + is.read(reinterpret_cast(&p->elCorrectionFactor_), 4); // 8364-8367 + is.read(&p->siteName_[0], 4); // 8368-8371 + is.read(reinterpret_cast(&p->antManualSetup_.ielmin_), + 4); // 8372-8375 + is.read(reinterpret_cast(&p->antManualSetup_.ielmax_), + 4); // 8376-8379 + is.read(reinterpret_cast(&p->antManualSetup_.fazvelmax_), + 4); // 8380-8383 + is.read(reinterpret_cast(&p->antManualSetup_.felvelmax_), + 4); // 8384-8387 + is.read(reinterpret_cast(&p->antManualSetup_.igndHgt_), + 4); // 8388-8391 + is.read(reinterpret_cast(&p->antManualSetup_.iradHgt_), + 4); // 8392-8395 + is.read(reinterpret_cast(&p->azPosSustainDrive_), 4); // 8396-8399 + is.read(reinterpret_cast(&p->azNegSustainDrive_), 4); // 8400-8403 + is.read(reinterpret_cast(&p->azNomPosDriveSlope_), 4); // 8404-8407 + is.read(reinterpret_cast(&p->azNomNegDriveSlope_), 4); // 8408-8411 + is.read(reinterpret_cast(&p->azFeedbackSlope_), 4); // 8412-8415 + is.read(reinterpret_cast(&p->elPosSustainDrive_), 4); // 8416-8419 + is.read(reinterpret_cast(&p->elNegSustainDrive_), 4); // 8420-8423 + is.read(reinterpret_cast(&p->elNomPosDriveSlope_), 4); // 8424-8427 + is.read(reinterpret_cast(&p->elNomNegDriveSlope_), 4); // 8428-8431 + is.read(reinterpret_cast(&p->elFeedbackSlope_), 4); // 8432-8435 + is.read(reinterpret_cast(&p->elFirstSlope_), 4); // 8436-8439 + is.read(reinterpret_cast(&p->elSecondSlope_), 4); // 8440-8443 + is.read(reinterpret_cast(&p->elThirdSlope_), 4); // 8444-8447 + is.read(reinterpret_cast(&p->elDroopPos_), 4); // 8448-8451 + is.read(reinterpret_cast(&p->elOffNeutralDrive_), 4); // 8452-8455 + is.read(reinterpret_cast(&p->azIntertia_), 4); // 8456-8459 + is.read(reinterpret_cast(&p->elInertia_), 4); // 8460-8463 + + is.seekg(232, std::ios_base::cur); // 8464-8695 + + is.read(reinterpret_cast(&p->rvp8nvIwaveguideLength_), + 4); // 8696-8699 + + is.read(reinterpret_cast(&p->vRnscale_[0]), + 11 * 4); // 8700-8743 + + is.read(reinterpret_cast(&p->velDataTover_), 4); // 8744-8747 + is.read(reinterpret_cast(&p->widthDataTover_), 4); // 8748-8751 + is.read(reinterpret_cast(&p->vRnscale_[11]), 2 * 4); // 8752-8759 + + is.seekg(4, std::ios_base::cur); // 8760-8763 + + is.read(reinterpret_cast(&p->dopplerRangeStart_), 4); // 8764-8767 + is.read(reinterpret_cast(&p->maxElIndex_), 4); // 8768-8771 + is.read(reinterpret_cast(&p->seg2Lim_), 4); // 8772-8775 + is.read(reinterpret_cast(&p->seg3Lim_), 4); // 8776-8779 + is.read(reinterpret_cast(&p->seg4Lim_), 4); // 8780-8783 + is.read(reinterpret_cast(&p->nbrElSegments_), 4); // 8784-8787 + is.read(reinterpret_cast(&p->hNoiseLong_), 4); // 8788-8791 + is.read(reinterpret_cast(&p->antNoiseTemp_), 4); // 8792-8795 + is.read(reinterpret_cast(&p->hNoiseShort_), 4); // 8796-8799 + is.read(reinterpret_cast(&p->hNoiseTolerance_), 4); // 8800-8803 + is.read(reinterpret_cast(&p->minHDynRange_), 4); // 8804-8807 + ReadBoolean(is, p->genInstalled_); // 8808-8811 + ReadBoolean(is, p->genExercise_); // 8812-8815 + is.read(reinterpret_cast(&p->vNoiseTolerance_), 4); // 8816-8819 + is.read(reinterpret_cast(&p->minVDynRange_), 4); // 8820-8823 + is.read(reinterpret_cast(&p->zdrBiasDgradLim_), 4); // 8824-8827 + is.read(reinterpret_cast(&p->baselineZdrBias_), 4); // 8828-8831 + + is.seekg(12, std::ios_base::cur); // 8832-8843 + + is.read(reinterpret_cast(&p->vNoiseLong_), 4); // 8844-8847 + is.read(reinterpret_cast(&p->vNoiseShort_), 4); // 8848-8851 + is.read(reinterpret_cast(&p->zdrDataTover_), 4); // 8852-8855 + is.read(reinterpret_cast(&p->phiDataTover_), 4); // 8856-8859 + is.read(reinterpret_cast(&p->rhoDataTover_), 4); // 8860-8863 + is.read(reinterpret_cast(&p->staloPowerDgradLimit_), 4); // 8864-8867 + is.read(reinterpret_cast(&p->staloPowerMaintLimit_), 4); // 8868-8871 + is.read(reinterpret_cast(&p->minHPwrSense_), 4); // 8872-8875 + is.read(reinterpret_cast(&p->minVPwrSense_), 4); // 8876-8879 + is.read(reinterpret_cast(&p->hPwrSenseOffset_), 4); // 8880-8883 + is.read(reinterpret_cast(&p->vPwrSenseOffset_), 4); // 8884-8887 + is.read(reinterpret_cast(&p->psGainRef_), 4); // 8888-8891 + is.read(reinterpret_cast(&p->rfPalletBroadLoss_), 4); // 8892-8895 + + is.seekg(64, std::ios_base::cur); // 8896-8959 + + is.read(reinterpret_cast(&p->amePsTolerance_), 4); // 8960-8963 + is.read(reinterpret_cast(&p->ameMaxTemp_), 4); // 8964-8967 + is.read(reinterpret_cast(&p->ameMinTemp_), 4); // 8968-8971 + is.read(reinterpret_cast(&p->rcvrModMaxTemp_), 4); // 8972-8975 + is.read(reinterpret_cast(&p->rcvrModMinTemp_), 4); // 8976-8979 + is.read(reinterpret_cast(&p->biteModMaxTemp_), 4); // 8980-8983 + is.read(reinterpret_cast(&p->biteModMinTemp_), 4); // 8984-8987 + is.read(reinterpret_cast(&p->defaultPolarization_), 4); // 8988-8991 + is.read(reinterpret_cast(&p->trLimitDgradLimit_), 4); // 8992-8995 + is.read(reinterpret_cast(&p->trLimitFailLimit_), 4); // 8996-8999 + ReadBoolean(is, p->rfpStepperEnabled_); // 9000-9003 + + is.seekg(4, std::ios_base::cur); // 9004-9007 + + is.read(reinterpret_cast(&p->ameCurrentTolerance_), 4); // 9008-9011 + is.read(reinterpret_cast(&p->hOnlyPolarization_), 4); // 9012-9015 + is.read(reinterpret_cast(&p->vOnlyPolarization_), 4); // 9016-9019 + + is.seekg(8, std::ios_base::cur); // 9020-9027 + + is.read(reinterpret_cast(&p->sunBias_), 4); // 9028-9031 + is.read(reinterpret_cast(&p->aMinShelterTempWarn_), 4); // 9032-9035 + is.read(reinterpret_cast(&p->powerMeterZero_), 4); // 9036-9039 + is.read(reinterpret_cast(&p->txbBaseline_), 4); // 9040-9043 + is.read(reinterpret_cast(&p->txbAlarmThresh_), 4); // 9044-9047 + + is.seekg(420, std::ios_base::cur); // 9048-9467 + + bytesRead += 9468; + + p->lowerPreLimit_ = SwapFloat(p->lowerPreLimit_); + p->azLat_ = SwapFloat(p->azLat_); + p->upperPreLimit_ = SwapFloat(p->upperPreLimit_); + p->elLat_ = SwapFloat(p->elLat_); + p->parkaz_ = SwapFloat(p->parkaz_); + p->parkel_ = SwapFloat(p->parkel_); + + SwapFloatArray(p->aFuelConv_); + + p->aMinShelterTemp_ = SwapFloat(p->aMinShelterTemp_); + p->aMaxShelterTemp_ = SwapFloat(p->aMaxShelterTemp_); + p->aMinShelterAcTempDiff_ = SwapFloat(p->aMinShelterAcTempDiff_); + p->aMaxXmtrAirTemp_ = SwapFloat(p->aMaxXmtrAirTemp_); + p->aMaxRadTemp_ = SwapFloat(p->aMaxRadTemp_); + p->aMaxRadTempRise_ = SwapFloat(p->aMaxRadTempRise_); + p->lowerDeadLimit_ = SwapFloat(p->lowerDeadLimit_); + p->upperDeadLimit_ = SwapFloat(p->upperDeadLimit_); + p->aMinGenRoomTemp_ = SwapFloat(p->aMinGenRoomTemp_); + p->aMaxGenRoomTemp_ = SwapFloat(p->aMaxGenRoomTemp_); + p->spip5VRegLim_ = SwapFloat(p->spip5VRegLim_); + p->spip15VRegLim_ = SwapFloat(p->spip15VRegLim_); + p->aHvdlTstInt_ = ntohl(p->aHvdlTstInt_); + p->aRpgLtInt_ = ntohl(p->aRpgLtInt_); + p->aMinStabUtilPwrTime_ = ntohl(p->aMinStabUtilPwrTime_); + p->aGenAutoExerInterval_ = ntohl(p->aGenAutoExerInterval_); + p->aUtilPwrSwReqInterval_ = ntohl(p->aUtilPwrSwReqInterval_); + p->aLowFuelLevel_ = SwapFloat(p->aLowFuelLevel_); + p->configChanNumber_ = ntohl(p->configChanNumber_); + p->redundantChanConfig_ = ntohl(p->redundantChanConfig_); + + SwapFloatArray(p->attenTable_); + SwapFloatMap(p->pathLosses_); + + p->vTsCw_ = SwapFloat(p->vTsCw_); + + SwapFloatArray(p->hRnscale_); + SwapFloatArray(p->atmos_); + SwapFloatArray(p->elIndex_); + + p->tfreqMhz_ = ntohl(p->tfreqMhz_); + p->baseDataTcn_ = SwapFloat(p->baseDataTcn_); + p->reflDataTover_ = SwapFloat(p->reflDataTover_); + p->tarHDbz0Lp_ = SwapFloat(p->tarHDbz0Lp_); + p->tarVDbz0Lp_ = SwapFloat(p->tarVDbz0Lp_); + p->initPhiDp_ = ntohl(p->initPhiDp_); + p->normInitPhiDp_ = ntohl(p->normInitPhiDp_); + p->lxLp_ = SwapFloat(p->lxLp_); + p->lxSp_ = SwapFloat(p->lxSp_); + p->meteorParam_ = SwapFloat(p->meteorParam_); + p->antennaGain_ = SwapFloat(p->antennaGain_); + p->velDegradLimit_ = SwapFloat(p->velDegradLimit_); + p->wthDegradLimit_ = SwapFloat(p->wthDegradLimit_); + p->hNoisetempDgradLimit_ = SwapFloat(p->hNoisetempDgradLimit_); + p->hMinNoisetemp_ = ntohl(p->hMinNoisetemp_); + p->vNoisetempDgradLimit_ = SwapFloat(p->vNoisetempDgradLimit_); + p->vMinNoisetemp_ = ntohl(p->vMinNoisetemp_); + p->klyDegradeLimit_ = SwapFloat(p->klyDegradeLimit_); + p->tsCoho_ = SwapFloat(p->tsCoho_); + p->hTsCw_ = SwapFloat(p->hTsCw_); + p->tsStalo_ = SwapFloat(p->tsStalo_); + p->ameHNoiseEnr_ = SwapFloat(p->ameHNoiseEnr_); + p->xmtrPeakPwrHighLimit_ = SwapFloat(p->xmtrPeakPwrHighLimit_); + p->xmtrPeakPwrLowLimit_ = SwapFloat(p->xmtrPeakPwrLowLimit_); + p->hDbz0DeltaLimit_ = SwapFloat(p->hDbz0DeltaLimit_); + p->threshold1_ = SwapFloat(p->threshold1_); + p->threshold2_ = SwapFloat(p->threshold2_); + p->clutSuppDgradLim_ = SwapFloat(p->clutSuppDgradLim_); + p->range0Value_ = SwapFloat(p->range0Value_); + p->xmtrPwrMtrScale_ = SwapFloat(p->xmtrPwrMtrScale_); + p->vDbz0DeltaLimit_ = SwapFloat(p->vDbz0DeltaLimit_); + p->tarHDbz0Sp_ = SwapFloat(p->tarHDbz0Sp_); + p->tarVDbz0Sp_ = SwapFloat(p->tarVDbz0Sp_); + p->deltaprf_ = ntohl(p->deltaprf_); + p->tauSp_ = ntohl(p->tauSp_); + p->tauLp_ = ntohl(p->tauLp_); + p->ncDeadValue_ = ntohl(p->ncDeadValue_); + p->tauRfSp_ = ntohl(p->tauRfSp_); + p->tauRfLp_ = ntohl(p->tauRfLp_); + p->seg1Lim_ = SwapFloat(p->seg1Lim_); + p->slatsec_ = SwapFloat(p->slatsec_); + p->slonsec_ = SwapFloat(p->slonsec_); + p->slatdeg_ = ntohl(p->slatdeg_); + p->slatmin_ = ntohl(p->slatmin_); + p->slondeg_ = ntohl(p->slondeg_); + p->slonmin_ = ntohl(p->slonmin_); + p->azCorrectionFactor_ = SwapFloat(p->azCorrectionFactor_); + p->elCorrectionFactor_ = SwapFloat(p->elCorrectionFactor_); + p->antManualSetup_.ielmin_ = ntohl(p->antManualSetup_.ielmin_); + p->antManualSetup_.ielmax_ = ntohl(p->antManualSetup_.ielmax_); + p->antManualSetup_.fazvelmax_ = ntohl(p->antManualSetup_.fazvelmax_); + p->antManualSetup_.felvelmax_ = ntohl(p->antManualSetup_.felvelmax_); + p->antManualSetup_.igndHgt_ = ntohl(p->antManualSetup_.igndHgt_); + p->antManualSetup_.iradHgt_ = ntohl(p->antManualSetup_.iradHgt_); + p->azPosSustainDrive_ = SwapFloat(p->azPosSustainDrive_); + p->azNegSustainDrive_ = SwapFloat(p->azNegSustainDrive_); + p->azNomPosDriveSlope_ = SwapFloat(p->azNomPosDriveSlope_); + p->azNomNegDriveSlope_ = SwapFloat(p->azNomNegDriveSlope_); + p->azFeedbackSlope_ = SwapFloat(p->azFeedbackSlope_); + p->elPosSustainDrive_ = SwapFloat(p->elPosSustainDrive_); + p->elNegSustainDrive_ = SwapFloat(p->elNegSustainDrive_); + p->elNomPosDriveSlope_ = SwapFloat(p->elNomPosDriveSlope_); + p->elNomNegDriveSlope_ = SwapFloat(p->elNomNegDriveSlope_); + p->elFeedbackSlope_ = SwapFloat(p->elFeedbackSlope_); + p->elFirstSlope_ = SwapFloat(p->elFirstSlope_); + p->elSecondSlope_ = SwapFloat(p->elSecondSlope_); + p->elThirdSlope_ = SwapFloat(p->elThirdSlope_); + p->elDroopPos_ = SwapFloat(p->elDroopPos_); + p->elOffNeutralDrive_ = SwapFloat(p->elOffNeutralDrive_); + p->azIntertia_ = SwapFloat(p->azIntertia_); + p->elInertia_ = SwapFloat(p->elInertia_); + p->rvp8nvIwaveguideLength_ = ntohl(p->rvp8nvIwaveguideLength_); + + SwapFloatArray(p->vRnscale_); + + p->velDataTover_ = SwapFloat(p->velDataTover_); + p->widthDataTover_ = SwapFloat(p->widthDataTover_); + p->dopplerRangeStart_ = SwapFloat(p->dopplerRangeStart_); + p->maxElIndex_ = ntohl(p->maxElIndex_); + p->seg2Lim_ = SwapFloat(p->seg2Lim_); + p->seg3Lim_ = SwapFloat(p->seg3Lim_); + p->seg4Lim_ = SwapFloat(p->seg4Lim_); + p->nbrElSegments_ = ntohl(p->nbrElSegments_); + p->hNoiseLong_ = SwapFloat(p->hNoiseLong_); + p->antNoiseTemp_ = SwapFloat(p->antNoiseTemp_); + p->hNoiseShort_ = SwapFloat(p->hNoiseShort_); + p->hNoiseTolerance_ = SwapFloat(p->hNoiseTolerance_); + p->minHDynRange_ = SwapFloat(p->minHDynRange_); + p->vNoiseTolerance_ = SwapFloat(p->vNoiseTolerance_); + p->minVDynRange_ = SwapFloat(p->minVDynRange_); + p->zdrBiasDgradLim_ = SwapFloat(p->zdrBiasDgradLim_); + p->baselineZdrBias_ = SwapFloat(p->baselineZdrBias_); + p->vNoiseLong_ = SwapFloat(p->vNoiseLong_); + p->vNoiseShort_ = SwapFloat(p->vNoiseShort_); + p->zdrDataTover_ = SwapFloat(p->zdrDataTover_); + p->phiDataTover_ = SwapFloat(p->phiDataTover_); + p->rhoDataTover_ = SwapFloat(p->rhoDataTover_); + p->staloPowerDgradLimit_ = SwapFloat(p->staloPowerDgradLimit_); + p->staloPowerMaintLimit_ = SwapFloat(p->staloPowerMaintLimit_); + p->minHPwrSense_ = SwapFloat(p->minHPwrSense_); + p->minVPwrSense_ = SwapFloat(p->minVPwrSense_); + p->hPwrSenseOffset_ = SwapFloat(p->hPwrSenseOffset_); + p->vPwrSenseOffset_ = SwapFloat(p->vPwrSenseOffset_); + p->psGainRef_ = SwapFloat(p->psGainRef_); + p->rfPalletBroadLoss_ = SwapFloat(p->rfPalletBroadLoss_); + p->amePsTolerance_ = SwapFloat(p->amePsTolerance_); + p->ameMaxTemp_ = SwapFloat(p->ameMaxTemp_); + p->ameMinTemp_ = SwapFloat(p->ameMinTemp_); + p->rcvrModMaxTemp_ = SwapFloat(p->rcvrModMaxTemp_); + p->rcvrModMinTemp_ = SwapFloat(p->rcvrModMinTemp_); + p->biteModMaxTemp_ = SwapFloat(p->biteModMaxTemp_); + p->biteModMinTemp_ = SwapFloat(p->biteModMinTemp_); + p->defaultPolarization_ = ntohl(p->defaultPolarization_); + p->trLimitDgradLimit_ = SwapFloat(p->trLimitDgradLimit_); + p->trLimitFailLimit_ = SwapFloat(p->trLimitFailLimit_); + p->ameCurrentTolerance_ = SwapFloat(p->ameCurrentTolerance_); + p->hOnlyPolarization_ = ntohl(p->hOnlyPolarization_); + p->vOnlyPolarization_ = ntohl(p->vOnlyPolarization_); + p->sunBias_ = SwapFloat(p->sunBias_); + p->aMinShelterTempWarn_ = SwapFloat(p->aMinShelterTempWarn_); + p->powerMeterZero_ = SwapFloat(p->powerMeterZero_); + p->txbBaseline_ = SwapFloat(p->txbBaseline_); + p->txbAlarmThresh_ = SwapFloat(p->txbAlarmThresh_); + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Reached end of file (1)"; + messageValid = false; + } + + if (!ValidateSize(is, bytesRead)) + { + messageValid = false; + } + + return messageValid; +} + +std::unique_ptr +RdaAdaptationData::Create(MessageHeader&& header, std::istream& is) +{ + std::unique_ptr message = + std::make_unique(); + message->set_header(std::move(header)); + message->Parse(is); + return message; +} + +static void ReadBoolean(std::istream& is, bool& value) +{ + std::string data(4, ' '); + is.read(reinterpret_cast(&data[0]), 4); + value = (data.at(0) == 'T'); +} + +static void ReadChar(std::istream& is, char& value) +{ + std::string data(4, ' '); + is.read(reinterpret_cast(&data[0]), 4); + value = data.at(0); +} + +static float SwapFloat(float f) +{ + return ntohf(*reinterpret_cast(&f)); +} + +template +static void SwapFloatArray(std::array& arr) +{ + std::transform(std::execution::par_unseq, + arr.begin(), + arr.end(), + arr.begin(), + [](float f) { return SwapFloat(f); }); +} + +template +static void SwapFloatMap(std::map& m) +{ + std::for_each(std::execution::par_unseq, m.begin(), m.end(), [](auto& p) { + p.second = SwapFloat(p.second); + }); +} + +} // namespace rda +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/wxdata.cmake b/wxdata/wxdata.cmake index 7c153faa..7b99e88f 100644 --- a/wxdata/wxdata.cmake +++ b/wxdata/wxdata.cmake @@ -11,11 +11,13 @@ set(SRC_WSR88D source/scwx/wsr88d/ar2v_file.cpp) set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_map.hpp include/scwx/wsr88d/rda/message.hpp include/scwx/wsr88d/rda/message_factory.hpp - include/scwx/wsr88d/rda/message_header.hpp) + include/scwx/wsr88d/rda/message_header.hpp + include/scwx/wsr88d/rda/rda_adaptation_data.hpp) set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_map.cpp source/scwx/wsr88d/rda/message.cpp source/scwx/wsr88d/rda/message_factory.cpp - source/scwx/wsr88d/rda/message_header.cpp) + source/scwx/wsr88d/rda/message_header.cpp + source/scwx/wsr88d/rda/rda_adaptation_data.cpp) add_library(wxdata OBJECT ${HDR_UTIL} ${SRC_UTIL}