mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 21:20:06 +00:00
Standalone tabular alphanumeric product message
This commit is contained in:
parent
0b063f6e8c
commit
235c060b17
3 changed files with 80 additions and 50 deletions
|
|
@ -32,6 +32,7 @@ public:
|
||||||
size_t data_size() const override;
|
size_t data_size() const override;
|
||||||
|
|
||||||
bool Parse(std::istream& is);
|
bool Parse(std::istream& is);
|
||||||
|
bool Parse(std::istream& is, bool skipHeader);
|
||||||
|
|
||||||
static constexpr size_t SIZE = 102u;
|
static constexpr size_t SIZE = 102u;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include <scwx/util/time.hpp>
|
#include <scwx/util/time.hpp>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include <boost/iostreams/copy.hpp>
|
#include <boost/iostreams/copy.hpp>
|
||||||
#include <boost/iostreams/filtering_streambuf.hpp>
|
#include <boost/iostreams/filtering_streambuf.hpp>
|
||||||
|
|
@ -24,6 +25,8 @@ namespace wsr88d
|
||||||
|
|
||||||
static const std::string logPrefix_ = "[scwx::wsr88d::level3_file] ";
|
static const std::string logPrefix_ = "[scwx::wsr88d::level3_file] ";
|
||||||
|
|
||||||
|
static const std::set<int16_t> standaloneTabularProducts_ = {62, 75, 77, 82};
|
||||||
|
|
||||||
class Level3FileImpl
|
class Level3FileImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -259,15 +262,27 @@ bool Level3FileImpl::LoadBlocks(std::istream& is)
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Loading Blocks";
|
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Loading Blocks";
|
||||||
|
|
||||||
|
bool skipTabularHeader = false;
|
||||||
|
|
||||||
std::streampos offsetBasePos = is.tellg();
|
std::streampos offsetBasePos = is.tellg();
|
||||||
|
|
||||||
constexpr size_t offsetBase =
|
constexpr size_t offsetBase =
|
||||||
rpg::Level3MessageHeader::SIZE + rpg::ProductDescriptionBlock::SIZE;
|
rpg::Level3MessageHeader::SIZE + rpg::ProductDescriptionBlock::SIZE;
|
||||||
|
|
||||||
const size_t offsetToSymbology =
|
size_t offsetToSymbology = descriptionBlock_->offset_to_symbology() * 2u;
|
||||||
descriptionBlock_->offset_to_symbology() * 2u;
|
size_t offsetToGraphic = descriptionBlock_->offset_to_graphic() * 2u;
|
||||||
const size_t offsetToGraphic = descriptionBlock_->offset_to_graphic() * 2u;
|
size_t offsetToTabular = descriptionBlock_->offset_to_tabular() * 2u;
|
||||||
const size_t offsetToTabular = descriptionBlock_->offset_to_tabular() * 2u;
|
|
||||||
|
if (standaloneTabularProducts_.contains(messageHeader_->message_code()))
|
||||||
|
{
|
||||||
|
// These products are completely alphanumeric, and do not contain a
|
||||||
|
// symbology block.
|
||||||
|
offsetToTabular = offsetToSymbology;
|
||||||
|
offsetToSymbology = 0;
|
||||||
|
offsetToGraphic = 0;
|
||||||
|
|
||||||
|
skipTabularHeader = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (offsetToSymbology >= offsetBase)
|
if (offsetToSymbology >= offsetBase)
|
||||||
{
|
{
|
||||||
|
|
@ -308,7 +323,7 @@ bool Level3FileImpl::LoadBlocks(std::istream& is)
|
||||||
tabularBlock_ = std::make_shared<rpg::TabularAlphanumericBlock>();
|
tabularBlock_ = std::make_shared<rpg::TabularAlphanumericBlock>();
|
||||||
|
|
||||||
is.seekg(offsetToTabular - offsetBase, std::ios_base::cur);
|
is.seekg(offsetToTabular - offsetBase, std::ios_base::cur);
|
||||||
tabularValid = tabularBlock_->Parse(is);
|
tabularValid = tabularBlock_->Parse(is, skipTabularHeader);
|
||||||
is.seekg(offsetBasePos, std::ios_base::beg);
|
is.seekg(offsetBasePos, std::ios_base::beg);
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug)
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
|
|
|
||||||
|
|
@ -69,66 +69,75 @@ size_t TabularAlphanumericBlock::data_size() const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TabularAlphanumericBlock::Parse(std::istream& is)
|
bool TabularAlphanumericBlock::Parse(std::istream& is)
|
||||||
|
{
|
||||||
|
return Parse(is, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TabularAlphanumericBlock::Parse(std::istream& is, bool skipHeader)
|
||||||
{
|
{
|
||||||
bool blockValid = true;
|
bool blockValid = true;
|
||||||
|
|
||||||
const std::streampos blockStart = is.tellg();
|
const std::streampos blockStart = is.tellg();
|
||||||
|
|
||||||
is.read(reinterpret_cast<char*>(&p->blockDivider1_), 2);
|
if (!skipHeader)
|
||||||
is.read(reinterpret_cast<char*>(&p->blockId_), 2);
|
|
||||||
is.read(reinterpret_cast<char*>(&p->lengthOfBlock_), 4);
|
|
||||||
|
|
||||||
p->blockDivider1_ = ntohs(p->blockDivider1_);
|
|
||||||
p->blockId_ = ntohs(p->blockId_);
|
|
||||||
p->lengthOfBlock_ = ntohl(p->lengthOfBlock_);
|
|
||||||
|
|
||||||
if (is.eof())
|
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file";
|
|
||||||
blockValid = false;
|
is.read(reinterpret_cast<char*>(&p->blockDivider1_), 2);
|
||||||
}
|
is.read(reinterpret_cast<char*>(&p->blockId_), 2);
|
||||||
else
|
is.read(reinterpret_cast<char*>(&p->lengthOfBlock_), 4);
|
||||||
{
|
|
||||||
if (p->blockDivider1_ != -1)
|
p->blockDivider1_ = ntohs(p->blockDivider1_);
|
||||||
|
p->blockId_ = ntohs(p->blockId_);
|
||||||
|
p->lengthOfBlock_ = ntohl(p->lengthOfBlock_);
|
||||||
|
|
||||||
|
if (is.eof())
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(warning)
|
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file";
|
||||||
<< logPrefix_
|
|
||||||
<< "Invalid first block divider: " << p->blockDivider1_;
|
|
||||||
blockValid = false;
|
blockValid = false;
|
||||||
}
|
}
|
||||||
if (p->blockId_ != 3)
|
else
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(warning)
|
if (p->blockDivider1_ != -1)
|
||||||
<< logPrefix_ << "Invalid block ID: " << p->blockId_;
|
{
|
||||||
blockValid = false;
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
<< logPrefix_
|
||||||
|
<< "Invalid first block divider: " << p->blockDivider1_;
|
||||||
|
blockValid = false;
|
||||||
|
}
|
||||||
|
if (p->blockId_ != 3)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
<< logPrefix_ << "Invalid block ID: " << p->blockId_;
|
||||||
|
blockValid = false;
|
||||||
|
}
|
||||||
|
if (p->lengthOfBlock_ < 10)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
<< logPrefix_ << "Invalid block length: " << p->lengthOfBlock_;
|
||||||
|
blockValid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (p->lengthOfBlock_ < 10)
|
|
||||||
|
if (blockValid)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(warning)
|
p->messageHeader_ = std::make_shared<Level3MessageHeader>();
|
||||||
<< logPrefix_ << "Invalid block length: " << p->lengthOfBlock_;
|
blockValid = p->messageHeader_->Parse(is);
|
||||||
blockValid = false;
|
|
||||||
|
if (!blockValid)
|
||||||
|
{
|
||||||
|
p->messageHeader_ = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (blockValid)
|
if (blockValid)
|
||||||
{
|
|
||||||
p->messageHeader_ = std::make_shared<Level3MessageHeader>();
|
|
||||||
blockValid = p->messageHeader_->Parse(is);
|
|
||||||
|
|
||||||
if (!blockValid)
|
|
||||||
{
|
{
|
||||||
p->messageHeader_ = nullptr;
|
p->descriptionBlock_ = std::make_shared<ProductDescriptionBlock>();
|
||||||
}
|
blockValid = p->descriptionBlock_->Parse(is);
|
||||||
}
|
|
||||||
|
|
||||||
if (blockValid)
|
if (!blockValid)
|
||||||
{
|
{
|
||||||
p->descriptionBlock_ = std::make_shared<ProductDescriptionBlock>();
|
p->descriptionBlock_ = nullptr;
|
||||||
blockValid = p->descriptionBlock_->Parse(is);
|
}
|
||||||
|
|
||||||
if (!blockValid)
|
|
||||||
{
|
|
||||||
p->descriptionBlock_ = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,10 +205,15 @@ bool TabularAlphanumericBlock::Parse(std::istream& is)
|
||||||
|
|
||||||
const std::streampos blockEnd = is.tellg();
|
const std::streampos blockEnd = is.tellg();
|
||||||
|
|
||||||
if (!ValidateMessage(is, blockEnd - blockStart))
|
if (!skipHeader && !ValidateMessage(is, blockEnd - blockStart))
|
||||||
{
|
{
|
||||||
blockValid = false;
|
blockValid = false;
|
||||||
}
|
}
|
||||||
|
else if (skipHeader && is.eof())
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file";
|
||||||
|
blockValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
return blockValid;
|
return blockValid;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue