Refactoring generic message components to awips namespace

This commit is contained in:
Dan Paulat 2022-01-14 19:34:47 -06:00
parent a76103650e
commit 7a9582a689
14 changed files with 64 additions and 65 deletions

View file

@ -1,7 +1,7 @@
#include <scwx/wsr88d/level3_file.hpp>
#include <scwx/awips/wmo_header.hpp>
#include <scwx/wsr88d/rpg/ccb_header.hpp>
#include <scwx/wsr88d/rpg/level3_message_factory.hpp>
#include <scwx/wsr88d/rpg/wmo_header.hpp>
#include <fstream>
@ -27,9 +27,9 @@ public:
bool DecompressFile(std::istream& is, std::stringstream& ss);
bool LoadFileData(std::istream& is);
std::shared_ptr<rpg::WmoHeader> wmoHeader_;
std::shared_ptr<awips::WmoHeader> wmoHeader_;
std::shared_ptr<rpg::CcbHeader> ccbHeader_;
std::shared_ptr<rpg::WmoHeader> innerHeader_;
std::shared_ptr<awips::WmoHeader> innerHeader_;
std::shared_ptr<rpg::Level3Message> message_;
};
@ -69,7 +69,7 @@ bool Level3File::LoadData(std::istream& is)
{
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Loading Data";
p->wmoHeader_ = std::make_shared<rpg::WmoHeader>();
p->wmoHeader_ = std::make_shared<awips::WmoHeader>();
bool dataValid = p->wmoHeader_->Parse(is);
@ -161,7 +161,7 @@ bool Level3FileImpl::DecompressFile(std::istream& is, std::stringstream& ss)
if (dataValid)
{
innerHeader_ = std::make_shared<rpg::WmoHeader>();
innerHeader_ = std::make_shared<awips::WmoHeader>();
dataValid = innerHeader_->Parse(ss);
}

View file

@ -1,67 +0,0 @@
#include <scwx/wsr88d/message.hpp>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
static const std::string logPrefix_ = "[scwx::wsr88d::message] ";
class MessageImpl
{
public:
explicit MessageImpl() {};
~MessageImpl() = default;
};
Message::Message() : p(std::make_unique<MessageImpl>()) {}
Message::~Message() = default;
Message::Message(Message&&) noexcept = default;
Message& Message::operator=(Message&&) noexcept = default;
bool Message::ValidateMessage(std::istream& is, size_t bytesRead) const
{
bool messageValid = true;
const size_t dataSize = data_size();
if (is.eof())
{
BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Reached end of data stream";
messageValid = false;
}
else if (is.fail())
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Could not read from input stream";
messageValid = false;
}
else if (bytesRead != dataSize)
{
is.seekg(static_cast<std::streamoff>(dataSize) -
static_cast<std::streamoff>(bytesRead),
std::ios_base::cur);
if (bytesRead < dataSize)
{
BOOST_LOG_TRIVIAL(trace)
<< logPrefix_ << "Message contents smaller than size: " << bytesRead
<< " < " << dataSize << " bytes";
}
if (bytesRead > dataSize)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Message contents larger than size: " << bytesRead
<< " > " << dataSize << " bytes";
messageValid = false;
}
}
return messageValid;
}
} // namespace wsr88d
} // namespace scwx

View file

@ -190,8 +190,8 @@ bool MomentDataBlock::Parse(std::istream& is)
p->dataMomentRangeSampleInterval_ = ntohs(p->dataMomentRangeSampleInterval_);
p->tover_ = ntohs(p->tover_);
p->snrThreshold_ = ntohs(p->snrThreshold_);
p->scale_ = Message::SwapFloat(p->scale_);
p->offset_ = Message::SwapFloat(p->offset_);
p->scale_ = awips::Message::SwapFloat(p->scale_);
p->offset_ = awips::Message::SwapFloat(p->offset_);
if (p->numberOfDataMomentGates_ >= 0 && p->numberOfDataMomentGates_ <= 1840)
{
@ -206,7 +206,7 @@ bool MomentDataBlock::Parse(std::istream& is)
p->momentGates16_.resize(p->numberOfDataMomentGates_);
is.read(reinterpret_cast<char*>(p->momentGates16_.data()),
p->numberOfDataMomentGates_ * 2);
Message::SwapVector(p->momentGates16_);
awips::Message::SwapVector(p->momentGates16_);
}
else
{
@ -329,17 +329,17 @@ bool VolumeDataBlock::Parse(std::istream& is)
is.read(reinterpret_cast<char*>(&p->processingStatus_), 2); // 42-43
p->lrtup_ = ntohs(p->lrtup_);
p->latitude_ = Message::SwapFloat(p->latitude_);
p->longitude_ = Message::SwapFloat(p->longitude_);
p->latitude_ = awips::Message::SwapFloat(p->latitude_);
p->longitude_ = awips::Message::SwapFloat(p->longitude_);
p->siteHeight_ = ntohs(p->siteHeight_);
p->feedhornHeight_ = ntohs(p->feedhornHeight_);
p->calibrationConstant_ = Message::SwapFloat(p->calibrationConstant_);
p->horizontaShvTxPower_ = Message::SwapFloat(p->horizontaShvTxPower_);
p->verticalShvTxPower_ = Message::SwapFloat(p->verticalShvTxPower_);
p->calibrationConstant_ = awips::Message::SwapFloat(p->calibrationConstant_);
p->horizontaShvTxPower_ = awips::Message::SwapFloat(p->horizontaShvTxPower_);
p->verticalShvTxPower_ = awips::Message::SwapFloat(p->verticalShvTxPower_);
p->systemDifferentialReflectivity_ =
Message::SwapFloat(p->systemDifferentialReflectivity_);
awips::Message::SwapFloat(p->systemDifferentialReflectivity_);
p->initialSystemDifferentialPhase_ =
Message::SwapFloat(p->initialSystemDifferentialPhase_);
awips::Message::SwapFloat(p->initialSystemDifferentialPhase_);
p->volumeCoveragePatternNumber_ = ntohs(p->volumeCoveragePatternNumber_);
p->processingStatus_ = ntohs(p->processingStatus_);
@ -397,7 +397,7 @@ bool ElevationDataBlock::Parse(std::istream& is)
p->lrtup_ = ntohs(p->lrtup_);
p->atmos_ = ntohs(p->atmos_);
p->calibrationConstant_ = Message::SwapFloat(p->calibrationConstant_);
p->calibrationConstant_ = awips::Message::SwapFloat(p->calibrationConstant_);
return dataBlockValid;
}
@ -475,16 +475,17 @@ bool RadialDataBlock::Parse(std::istream& is)
is.read(reinterpret_cast<char*>(&p->calibrationConstantVertical_),
4); // 24-27
p->lrtup_ = ntohs(p->lrtup_);
p->unambigiousRange_ = ntohs(p->unambigiousRange_);
p->noiseLevelHorizontal_ = Message::SwapFloat(p->noiseLevelHorizontal_);
p->noiseLevelVertical_ = Message::SwapFloat(p->noiseLevelVertical_);
p->nyquistVelocity_ = ntohs(p->nyquistVelocity_);
p->radialFlags_ = ntohs(p->radialFlags_);
p->lrtup_ = ntohs(p->lrtup_);
p->unambigiousRange_ = ntohs(p->unambigiousRange_);
p->noiseLevelHorizontal_ =
awips::Message::SwapFloat(p->noiseLevelHorizontal_);
p->noiseLevelVertical_ = awips::Message::SwapFloat(p->noiseLevelVertical_);
p->nyquistVelocity_ = ntohs(p->nyquistVelocity_);
p->radialFlags_ = ntohs(p->radialFlags_);
p->calibrationConstantHorizontal_ =
Message::SwapFloat(p->calibrationConstantHorizontal_);
awips::Message::SwapFloat(p->calibrationConstantHorizontal_);
p->calibrationConstantVertical_ =
Message::SwapFloat(p->calibrationConstantVertical_);
awips::Message::SwapFloat(p->calibrationConstantVertical_);
return dataBlockValid;
}

View file

@ -1,254 +0,0 @@
#include <scwx/wsr88d/rpg/wmo_header.hpp>
#include <scwx/util/streams.hpp>
#include <istream>
#include <sstream>
#include <string>
#include <boost/log/trivial.hpp>
#ifdef WIN32
# include <WinSock2.h>
#else
# include <arpa/inet.h>
#endif
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ = "[scwx::wsr88d::rpg::wmo_header] ";
class WmoHeaderImpl
{
public:
explicit WmoHeaderImpl() :
sequenceNumber_ {},
dataType_ {},
geographicDesignator_ {},
bulletinId_ {},
icao_ {},
dateTime_ {},
bbbIndicator_ {},
productCategory_ {},
productDesignator_ {}
{
}
~WmoHeaderImpl() = default;
std::string sequenceNumber_;
std::string dataType_;
std::string geographicDesignator_;
std::string bulletinId_;
std::string icao_;
std::string dateTime_;
std::string bbbIndicator_;
std::string productCategory_;
std::string productDesignator_;
};
WmoHeader::WmoHeader() : p(std::make_unique<WmoHeaderImpl>()) {}
WmoHeader::~WmoHeader() = default;
WmoHeader::WmoHeader(WmoHeader&&) noexcept = default;
WmoHeader& WmoHeader::operator=(WmoHeader&&) noexcept = default;
const std::string& WmoHeader::sequence_number() const
{
return p->sequenceNumber_;
}
const std::string& WmoHeader::data_type() const
{
return p->dataType_;
}
const std::string& WmoHeader::geographic_designator() const
{
return p->geographicDesignator_;
}
const std::string& WmoHeader::bulletin_id() const
{
return p->bulletinId_;
}
const std::string& WmoHeader::icao() const
{
return p->icao_;
}
const std::string& WmoHeader::date_time() const
{
return p->dateTime_;
}
const std::string& WmoHeader::bbb_indicator() const
{
return p->bbbIndicator_;
}
const std::string& WmoHeader::product_category() const
{
return p->productCategory_;
}
const std::string& WmoHeader::product_designator() const
{
return p->productDesignator_;
}
bool WmoHeader::Parse(std::istream& is)
{
bool headerValid = true;
std::string sohLine;
std::string sequenceLine;
std::string wmoLine;
std::string awipsLine;
if (is.peek() == 0x01)
{
std::getline(is, sohLine);
std::getline(is, sequenceLine);
}
std::getline(is, wmoLine);
std::getline(is, awipsLine);
if (is.eof())
{
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file";
headerValid = false;
}
else if (!sohLine.empty() && !sohLine.ends_with("\r\r"))
{
BOOST_LOG_TRIVIAL(debug)
<< logPrefix_ << "Start of Heading Line is malformed";
headerValid = false;
}
else if (!sequenceLine.empty() && !sequenceLine.ends_with(" \r\r"))
{
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Sequence Line is malformed";
headerValid = false;
}
else if (!wmoLine.ends_with("\r\r"))
{
BOOST_LOG_TRIVIAL(debug)
<< logPrefix_ << "WMO Abbreviated Heading Line is malformed";
headerValid = false;
}
else if (!awipsLine.ends_with("\r\r"))
{
BOOST_LOG_TRIVIAL(debug)
<< logPrefix_ << "AWIPS Identifier Line is malformed";
headerValid = false;
}
else
{
// Remove delimiters from the end of the line
if (!sequenceLine.empty())
{
sequenceLine.erase(sequenceLine.length() - 3);
}
wmoLine.erase(wmoLine.length() - 2);
awipsLine.erase(awipsLine.length() - 2);
}
// Transmission Header:
// [SOH]
// nnn
if (headerValid && !sequenceLine.empty())
{
p->sequenceNumber_ = sequenceLine;
}
// WMO Abbreviated Heading Line:
// T1T2A1A2ii CCCC YYGGgg (BBB)
if (headerValid)
{
std::string token;
std::istringstream wmoTokens(wmoLine);
std::vector<std::string> wmoTokenList;
while (wmoTokens >> token)
{
wmoTokenList.push_back(std::move(token));
}
if (wmoTokenList.size() < 3 || wmoTokenList.size() > 4)
{
BOOST_LOG_TRIVIAL(debug)
<< logPrefix_ << "Invalid number of WMO tokens";
headerValid = false;
}
else if (wmoTokenList[0].size() != 6)
{
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "WMO identifier malformed";
headerValid = false;
}
else if (wmoTokenList[1].size() != 4)
{
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "ICAO malformed";
headerValid = false;
}
else if (wmoTokenList[2].size() != 6)
{
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Date/time malformed";
headerValid = false;
}
else if (wmoTokenList.size() == 4 && wmoTokenList[3].size() != 3)
{
// BBB indicator is optional
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "BBB indicator malformed";
headerValid = false;
}
else
{
p->dataType_ = wmoTokenList[0].substr(0, 2);
p->geographicDesignator_ = wmoTokenList[0].substr(2, 2);
p->bulletinId_ = wmoTokenList[0].substr(4, 2);
p->icao_ = wmoTokenList[1];
p->dateTime_ = wmoTokenList[2];
if (wmoTokenList.size() == 4)
{
p->bbbIndicator_ = wmoTokenList[3];
}
else
{
p->bbbIndicator_ = "";
}
}
}
// AWIPS Identifer Line:
// NNNxxx
if (headerValid)
{
if (awipsLine.size() != 6)
{
BOOST_LOG_TRIVIAL(debug)
<< logPrefix_ << "AWIPS Identifier Line bad size";
headerValid = false;
}
else
{
p->productCategory_ = awipsLine.substr(0, 3);
p->productDesignator_ = awipsLine.substr(3, 3);
}
}
return headerValid;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx