Special graphic symbol packet

This commit is contained in:
Dan Paulat 2022-01-09 15:03:31 -06:00
parent 6d4428b8e0
commit cbb3ec0368
18 changed files with 1380 additions and 0 deletions

View file

@ -0,0 +1,140 @@
#include <scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp>
#include <istream>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::hda_hail_symbol_packet] ";
struct HdaHailSymbol
{
int16_t iPosition_;
int16_t jPosition_;
int16_t probabilityOfHail_;
int16_t probabilityOfSevereHail_;
uint16_t maxHailSize_;
HdaHailSymbol() :
iPosition_ {0},
jPosition_ {0},
probabilityOfHail_ {0},
probabilityOfSevereHail_ {0},
maxHailSize_ {0}
{
}
};
class HdaHailSymbolPacketImpl
{
public:
explicit HdaHailSymbolPacketImpl() : symbol_ {}, recordCount_ {0} {}
~HdaHailSymbolPacketImpl() = default;
std::vector<HdaHailSymbol> symbol_;
size_t recordCount_;
};
HdaHailSymbolPacket::HdaHailSymbolPacket() :
p(std::make_unique<HdaHailSymbolPacketImpl>())
{
}
HdaHailSymbolPacket::~HdaHailSymbolPacket() = default;
HdaHailSymbolPacket::HdaHailSymbolPacket(HdaHailSymbolPacket&&) noexcept =
default;
HdaHailSymbolPacket&
HdaHailSymbolPacket::operator=(HdaHailSymbolPacket&&) noexcept = default;
int16_t HdaHailSymbolPacket::i_position(size_t i) const
{
return p->symbol_[i].iPosition_;
}
int16_t HdaHailSymbolPacket::j_position(size_t i) const
{
return p->symbol_[i].jPosition_;
}
int16_t HdaHailSymbolPacket::probability_of_hail(size_t i) const
{
return p->symbol_[i].probabilityOfHail_;
}
int16_t HdaHailSymbolPacket::probability_of_severe_hail(size_t i) const
{
return p->symbol_[i].probabilityOfSevereHail_;
}
uint16_t HdaHailSymbolPacket::max_hail_size(size_t i) const
{
return p->symbol_[i].maxHailSize_;
}
size_t HdaHailSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool HdaHailSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (packet_code() != 19)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 10;
p->symbol_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
HdaHailSymbol& s = p->symbol_[i];
is.read(reinterpret_cast<char*>(&s.iPosition_), 2);
is.read(reinterpret_cast<char*>(&s.jPosition_), 2);
is.read(reinterpret_cast<char*>(&s.probabilityOfHail_), 2);
is.read(reinterpret_cast<char*>(&s.probabilityOfSevereHail_), 2);
is.read(reinterpret_cast<char*>(&s.maxHailSize_), 2);
s.iPosition_ = ntohs(s.iPosition_);
s.jPosition_ = ntohs(s.jPosition_);
s.probabilityOfHail_ = ntohs(s.probabilityOfHail_);
s.probabilityOfSevereHail_ = ntohs(s.probabilityOfSevereHail_);
s.maxHailSize_ = ntohs(s.maxHailSize_);
}
}
return blockValid;
}
std::shared_ptr<HdaHailSymbolPacket>
HdaHailSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<HdaHailSymbolPacket> packet =
std::make_shared<HdaHailSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,123 @@
#include <scwx/wsr88d/rpg/mesocyclone_symbol_packet.hpp>
#include <istream>
#include <set>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::mesocyclone_symbol_packet] ";
static const std::set<uint16_t> packetCodes_ = {3, 11};
struct MesocycloneSymbol
{
int16_t iPosition_;
int16_t jPosition_;
int16_t radiusOfMesocyclone_;
MesocycloneSymbol() :
iPosition_ {0}, jPosition_ {0}, radiusOfMesocyclone_ {0}
{
}
};
class MesocycloneSymbolPacketImpl
{
public:
explicit MesocycloneSymbolPacketImpl() : symbol_ {}, recordCount_ {0} {}
~MesocycloneSymbolPacketImpl() = default;
std::vector<MesocycloneSymbol> symbol_;
size_t recordCount_;
};
MesocycloneSymbolPacket::MesocycloneSymbolPacket() :
p(std::make_unique<MesocycloneSymbolPacketImpl>())
{
}
MesocycloneSymbolPacket::~MesocycloneSymbolPacket() = default;
MesocycloneSymbolPacket::MesocycloneSymbolPacket(
MesocycloneSymbolPacket&&) noexcept = default;
MesocycloneSymbolPacket& MesocycloneSymbolPacket::operator=(
MesocycloneSymbolPacket&&) noexcept = default;
int16_t MesocycloneSymbolPacket::i_position(size_t i) const
{
return p->symbol_[i].iPosition_;
}
int16_t MesocycloneSymbolPacket::j_position(size_t i) const
{
return p->symbol_[i].jPosition_;
}
int16_t MesocycloneSymbolPacket::radius_of_mesocyclone(size_t i) const
{
return p->symbol_[i].radiusOfMesocyclone_;
}
size_t MesocycloneSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool MesocycloneSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (!packetCodes_.contains(packet_code()))
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 6;
p->symbol_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
MesocycloneSymbol& s = p->symbol_[i];
is.read(reinterpret_cast<char*>(&s.iPosition_), 2);
is.read(reinterpret_cast<char*>(&s.jPosition_), 2);
is.read(reinterpret_cast<char*>(&s.radiusOfMesocyclone_), 2);
s.iPosition_ = ntohs(s.iPosition_);
s.jPosition_ = ntohs(s.jPosition_);
s.radiusOfMesocyclone_ = ntohs(s.radiusOfMesocyclone_);
}
}
return blockValid;
}
std::shared_ptr<MesocycloneSymbolPacket>
MesocycloneSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<MesocycloneSymbolPacket> packet =
std::make_shared<MesocycloneSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -2,12 +2,19 @@
#include <scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp>
#include <scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp>
#include <scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/linked_contour_vector_packet.hpp>
#include <scwx/wsr88d/rpg/linked_vector_packet.hpp>
#include <scwx/wsr88d/rpg/mesocyclone_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/point_feature_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/point_graphic_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/precipitation_rate_data_array_packet.hpp>
#include <scwx/wsr88d/rpg/radial_data_packet.hpp>
#include <scwx/wsr88d/rpg/raster_data_packet.hpp>
#include <scwx/wsr88d/rpg/scit_forecast_data_packet.hpp>
#include <scwx/wsr88d/rpg/set_color_level_packet.hpp>
#include <scwx/wsr88d/rpg/sti_circle_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/storm_id_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/unlinked_contour_vector_packet.hpp>
#include <scwx/wsr88d/rpg/unlinked_vector_packet.hpp>
@ -33,6 +40,7 @@ typedef std::function<std::shared_ptr<Packet>(std::istream&)>
static const std::unordered_map<uint16_t, CreateMessageFunction> create_ {
{1, TextAndSpecialSymbolPacket::Create},
{2, TextAndSpecialSymbolPacket::Create},
{3, MesocycloneSymbolPacket::Create},
{4, WindBarbDataPacket::Create},
{5, VectorArrowDataPacket::Create},
{6, LinkedVectorPacket::Create},
@ -40,9 +48,20 @@ static const std::unordered_map<uint16_t, CreateMessageFunction> create_ {
{8, TextAndSpecialSymbolPacket::Create},
{9, LinkedVectorPacket::Create},
{10, UnlinkedVectorPacket::Create},
{11, MesocycloneSymbolPacket::Create},
{12, PointGraphicSymbolPacket::Create},
{13, PointGraphicSymbolPacket::Create},
{14, PointGraphicSymbolPacket::Create},
{15, StormIdSymbolPacket::Create},
{16, DigitalRadialDataArrayPacket::Create},
{17, DigitalPrecipitationDataArrayPacket::Create},
{18, PrecipitationRateDataArrayPacket::Create},
{19, HdaHailSymbolPacket::Create},
{20, PointFeatureSymbolPacket::Create},
{23, ScitForecastDataPacket::Create},
{24, ScitForecastDataPacket::Create},
{25, StiCircleSymbolPacket::Create},
{26, PointGraphicSymbolPacket::Create},
{0x0802, SetColorLevelPacket::Create},
{0x0E03, LinkedContourVectorPacket::Create},
{0x3501, UnlinkedContourVectorPacket::Create},

View file

@ -0,0 +1,143 @@
#include <scwx/wsr88d/rpg/point_feature_symbol_packet.hpp>
#include <istream>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::point_feature_symbol_packet] ";
struct PointFeature
{
int16_t iPosition_;
int16_t jPosition_;
uint16_t pointFeatureType_;
uint16_t pointFeatureAttribute_;
PointFeature() :
iPosition_ {0},
jPosition_ {0},
pointFeatureType_ {0},
pointFeatureAttribute_ {0}
{
}
};
class PointFeatureSymbolPacketImpl
{
public:
explicit PointFeatureSymbolPacketImpl() : pointFeature_ {}, recordCount_ {0}
{
}
~PointFeatureSymbolPacketImpl() = default;
std::vector<PointFeature> pointFeature_;
size_t recordCount_;
};
PointFeatureSymbolPacket::PointFeatureSymbolPacket() :
p(std::make_unique<PointFeatureSymbolPacketImpl>())
{
}
PointFeatureSymbolPacket::~PointFeatureSymbolPacket() = default;
PointFeatureSymbolPacket::PointFeatureSymbolPacket(
PointFeatureSymbolPacket&&) noexcept = default;
PointFeatureSymbolPacket& PointFeatureSymbolPacket::operator=(
PointFeatureSymbolPacket&&) noexcept = default;
size_t PointFeatureSymbolPacket::MinBlockLength() const
{
return 8;
}
size_t PointFeatureSymbolPacket::MaxBlockLength() const
{
return 32760;
}
int16_t PointFeatureSymbolPacket::i_position(size_t i) const
{
return p->pointFeature_[i].iPosition_;
}
int16_t PointFeatureSymbolPacket::j_position(size_t i) const
{
return p->pointFeature_[i].jPosition_;
}
uint16_t PointFeatureSymbolPacket::point_feature_type(size_t i) const
{
return p->pointFeature_[i].pointFeatureType_;
}
uint16_t PointFeatureSymbolPacket::point_feature_attribute(size_t i) const
{
return p->pointFeature_[i].pointFeatureAttribute_;
}
size_t PointFeatureSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool PointFeatureSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (packet_code() != 20)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 8;
p->pointFeature_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
PointFeature& f = p->pointFeature_[i];
is.read(reinterpret_cast<char*>(&f.iPosition_), 2);
is.read(reinterpret_cast<char*>(&f.jPosition_), 2);
is.read(reinterpret_cast<char*>(&f.pointFeatureType_), 2);
is.read(reinterpret_cast<char*>(&f.pointFeatureAttribute_), 2);
f.iPosition_ = ntohs(f.iPosition_);
f.jPosition_ = ntohs(f.jPosition_);
f.pointFeatureType_ = ntohs(f.pointFeatureType_);
f.pointFeatureAttribute_ = ntohs(f.pointFeatureAttribute_);
}
}
return blockValid;
}
std::shared_ptr<PointFeatureSymbolPacket>
PointFeatureSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<PointFeatureSymbolPacket> packet =
std::make_shared<PointFeatureSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,114 @@
#include <scwx/wsr88d/rpg/point_graphic_symbol_packet.hpp>
#include <istream>
#include <set>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::point_graphic_symbol_packet] ";
static const std::set<uint16_t> packetCodes_ = {12, 13, 14, 26};
struct PointGraphic
{
int16_t iPosition_;
int16_t jPosition_;
PointGraphic() : iPosition_ {0}, jPosition_ {0} {}
};
class PointGraphicSymbolPacketImpl
{
public:
explicit PointGraphicSymbolPacketImpl() : pointGraphic_ {}, recordCount_ {0}
{
}
~PointGraphicSymbolPacketImpl() = default;
std::vector<PointGraphic> pointGraphic_;
size_t recordCount_;
};
PointGraphicSymbolPacket::PointGraphicSymbolPacket() :
p(std::make_unique<PointGraphicSymbolPacketImpl>())
{
}
PointGraphicSymbolPacket::~PointGraphicSymbolPacket() = default;
PointGraphicSymbolPacket::PointGraphicSymbolPacket(
PointGraphicSymbolPacket&&) noexcept = default;
PointGraphicSymbolPacket& PointGraphicSymbolPacket::operator=(
PointGraphicSymbolPacket&&) noexcept = default;
int16_t PointGraphicSymbolPacket::i_position(size_t i) const
{
return p->pointGraphic_[i].iPosition_;
}
int16_t PointGraphicSymbolPacket::j_position(size_t i) const
{
return p->pointGraphic_[i].jPosition_;
}
size_t PointGraphicSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool PointGraphicSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (!packetCodes_.contains(packet_code()))
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 4;
p->pointGraphic_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
PointGraphic& f = p->pointGraphic_[i];
is.read(reinterpret_cast<char*>(&f.iPosition_), 2);
is.read(reinterpret_cast<char*>(&f.jPosition_), 2);
f.iPosition_ = ntohs(f.iPosition_);
f.jPosition_ = ntohs(f.jPosition_);
}
}
return blockValid;
}
std::shared_ptr<PointGraphicSymbolPacket>
PointGraphicSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<PointGraphicSymbolPacket> packet =
std::make_shared<PointGraphicSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,89 @@
#include <scwx/wsr88d/rpg/scit_forecast_data_packet.hpp>
#include <istream>
#include <set>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::scit_forecast_data_packet] ";
static const std::set<uint16_t> packetCodes_ = {23, 24};
class ScitForecastDataPacketImpl
{
public:
explicit ScitForecastDataPacketImpl() : data_ {}, recordCount_ {0} {}
~ScitForecastDataPacketImpl() = default;
std::vector<uint8_t> data_;
size_t recordCount_;
};
ScitForecastDataPacket::ScitForecastDataPacket() :
p(std::make_unique<ScitForecastDataPacketImpl>())
{
}
ScitForecastDataPacket::~ScitForecastDataPacket() = default;
ScitForecastDataPacket::ScitForecastDataPacket(
ScitForecastDataPacket&&) noexcept = default;
ScitForecastDataPacket&
ScitForecastDataPacket::operator=(ScitForecastDataPacket&&) noexcept = default;
const std::vector<uint8_t>& ScitForecastDataPacket::data() const
{
return p->data_;
}
size_t ScitForecastDataPacket::RecordCount() const
{
return p->recordCount_;
}
bool ScitForecastDataPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (!packetCodes_.contains(packet_code()))
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block();
p->data_.resize(p->recordCount_);
is.read(reinterpret_cast<char*>(p->data_.data()), p->recordCount_);
}
return blockValid;
}
std::shared_ptr<ScitForecastDataPacket>
ScitForecastDataPacket::Create(std::istream& is)
{
std::shared_ptr<ScitForecastDataPacket> packet =
std::make_shared<ScitForecastDataPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,125 @@
#include <scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp>
#include <istream>
#include <set>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::special_graphic_symbol_packet] ";
static const std::set<uint16_t> packetCodes_ = {
3, 11, 12, 13, 14, 15, 19, 20, 23, 24, 25, 26};
class SpecialGraphicSymbolPacketImpl
{
public:
explicit SpecialGraphicSymbolPacketImpl() :
packetCode_ {0}, lengthOfBlock_ {0}
{
}
~SpecialGraphicSymbolPacketImpl() = default;
uint16_t packetCode_;
uint16_t lengthOfBlock_;
};
SpecialGraphicSymbolPacket::SpecialGraphicSymbolPacket() :
p(std::make_unique<SpecialGraphicSymbolPacketImpl>())
{
}
SpecialGraphicSymbolPacket::~SpecialGraphicSymbolPacket() = default;
SpecialGraphicSymbolPacket::SpecialGraphicSymbolPacket(
SpecialGraphicSymbolPacket&&) noexcept = default;
SpecialGraphicSymbolPacket& SpecialGraphicSymbolPacket::operator=(
SpecialGraphicSymbolPacket&&) noexcept = default;
uint16_t SpecialGraphicSymbolPacket::packet_code() const
{
return p->packetCode_;
}
uint16_t SpecialGraphicSymbolPacket::length_of_block() const
{
return p->lengthOfBlock_;
}
size_t SpecialGraphicSymbolPacket::data_size() const
{
return p->lengthOfBlock_ + 4u;
}
bool SpecialGraphicSymbolPacket::Parse(std::istream& is)
{
bool blockValid = true;
std::streampos isBegin = is.tellg();
is.read(reinterpret_cast<char*>(&p->packetCode_), 2);
is.read(reinterpret_cast<char*>(&p->lengthOfBlock_), 2);
p->packetCode_ = ntohs(p->packetCode_);
p->lengthOfBlock_ = ntohs(p->lengthOfBlock_);
if (is.eof())
{
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file";
blockValid = false;
}
else
{
const size_t minBlockLength = MinBlockLength();
const size_t maxBlockLength = MaxBlockLength();
if (!packetCodes_.contains(p->packetCode_))
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << p->packetCode_;
blockValid = false;
}
else if (p->lengthOfBlock_ < minBlockLength ||
p->lengthOfBlock_ > maxBlockLength)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid length of block: " << p->packetCode_;
blockValid = false;
}
}
if (blockValid)
{
blockValid = ParseData(is);
}
std::streampos isEnd = is.tellg();
if (!ValidateMessage(is, isEnd - isBegin))
{
blockValid = false;
}
return blockValid;
}
size_t SpecialGraphicSymbolPacket::MinBlockLength() const
{
return 1;
}
size_t SpecialGraphicSymbolPacket::MaxBlockLength() const
{
return 32767;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,117 @@
#include <scwx/wsr88d/rpg/sti_circle_symbol_packet.hpp>
#include <istream>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::sti_circle_symbol_packet] ";
struct StiCircleSymbol
{
int16_t iPosition_;
int16_t jPosition_;
uint16_t radiusOfCircle_;
StiCircleSymbol() : iPosition_ {0}, jPosition_ {0}, radiusOfCircle_ {0} {}
};
class StiCircleSymbolPacketImpl
{
public:
explicit StiCircleSymbolPacketImpl() : symbol_ {}, recordCount_ {0} {}
~StiCircleSymbolPacketImpl() = default;
std::vector<StiCircleSymbol> symbol_;
size_t recordCount_;
};
StiCircleSymbolPacket::StiCircleSymbolPacket() :
p(std::make_unique<StiCircleSymbolPacketImpl>())
{
}
StiCircleSymbolPacket::~StiCircleSymbolPacket() = default;
StiCircleSymbolPacket::StiCircleSymbolPacket(StiCircleSymbolPacket&&) noexcept =
default;
StiCircleSymbolPacket&
StiCircleSymbolPacket::operator=(StiCircleSymbolPacket&&) noexcept = default;
int16_t StiCircleSymbolPacket::i_position(size_t i) const
{
return p->symbol_[i].iPosition_;
}
int16_t StiCircleSymbolPacket::j_position(size_t i) const
{
return p->symbol_[i].jPosition_;
}
uint16_t StiCircleSymbolPacket::radius_of_circle(size_t i) const
{
return p->symbol_[i].radiusOfCircle_;
}
size_t StiCircleSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool StiCircleSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (packet_code() != 25)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 6;
p->symbol_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
StiCircleSymbol& s = p->symbol_[i];
is.read(reinterpret_cast<char*>(&s.iPosition_), 2);
is.read(reinterpret_cast<char*>(&s.jPosition_), 2);
is.read(reinterpret_cast<char*>(&s.radiusOfCircle_), 2);
s.iPosition_ = ntohs(s.iPosition_);
s.jPosition_ = ntohs(s.jPosition_);
s.radiusOfCircle_ = ntohs(s.radiusOfCircle_);
}
}
return blockValid;
}
std::shared_ptr<StiCircleSymbolPacket>
StiCircleSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<StiCircleSymbolPacket> packet =
std::make_shared<StiCircleSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,116 @@
#include <scwx/wsr88d/rpg/storm_id_symbol_packet.hpp>
#include <istream>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::storm_id_symbol_packet] ";
struct StormIdSymbol
{
int16_t iPosition_;
int16_t jPosition_;
std::array<char, 2> character_;
StormIdSymbol() : iPosition_ {0}, jPosition_ {0}, character_ {0} {}
};
class StormIdSymbolPacketImpl
{
public:
explicit StormIdSymbolPacketImpl() : symbol_ {}, recordCount_ {0} {}
~StormIdSymbolPacketImpl() = default;
std::vector<StormIdSymbol> symbol_;
size_t recordCount_;
};
StormIdSymbolPacket::StormIdSymbolPacket() :
p(std::make_unique<StormIdSymbolPacketImpl>())
{
}
StormIdSymbolPacket::~StormIdSymbolPacket() = default;
StormIdSymbolPacket::StormIdSymbolPacket(StormIdSymbolPacket&&) noexcept =
default;
StormIdSymbolPacket&
StormIdSymbolPacket::operator=(StormIdSymbolPacket&&) noexcept = default;
int16_t StormIdSymbolPacket::i_position(size_t i) const
{
return p->symbol_[i].iPosition_;
}
int16_t StormIdSymbolPacket::j_position(size_t i) const
{
return p->symbol_[i].jPosition_;
}
const std::array<char, 2>& StormIdSymbolPacket::character(size_t i) const
{
return p->symbol_[i].character_;
}
size_t StormIdSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool StormIdSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (packet_code() != 15)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 6;
p->symbol_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
StormIdSymbol& s = p->symbol_[i];
is.read(reinterpret_cast<char*>(&s.iPosition_), 2);
is.read(reinterpret_cast<char*>(&s.jPosition_), 2);
is.read(reinterpret_cast<char*>(s.character_.data()), 2);
s.iPosition_ = ntohs(s.iPosition_);
s.jPosition_ = ntohs(s.jPosition_);
}
}
return blockValid;
}
std::shared_ptr<StormIdSymbolPacket>
StormIdSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<StormIdSymbolPacket> packet =
std::make_shared<StormIdSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx