mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 19:10:06 +00:00
Fixing concurrency issue when parsing level 2 data
This commit is contained in:
parent
078b9c407c
commit
be2f9fe674
3 changed files with 48 additions and 22 deletions
|
|
@ -34,7 +34,11 @@ private:
|
||||||
Level2MessageFactory& operator=(Level2MessageFactory&&) noexcept = delete;
|
Level2MessageFactory& operator=(Level2MessageFactory&&) noexcept = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Level2MessageInfo Create(std::istream& is);
|
struct Context;
|
||||||
|
|
||||||
|
static std::shared_ptr<Context> CreateContext();
|
||||||
|
static Level2MessageInfo Create(std::istream& is,
|
||||||
|
std::shared_ptr<Context> ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace rda
|
} // namespace rda
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,8 @@ void Ar2vFileImpl::ParseLDMRecords()
|
||||||
|
|
||||||
void Ar2vFileImpl::ParseLDMRecord(std::istream& is)
|
void Ar2vFileImpl::ParseLDMRecord(std::istream& is)
|
||||||
{
|
{
|
||||||
|
auto ctx = rda::Level2MessageFactory::CreateContext();
|
||||||
|
|
||||||
// The communications manager inserts an extra 12 bytes at the beginning
|
// The communications manager inserts an extra 12 bytes at the beginning
|
||||||
// of each record
|
// of each record
|
||||||
is.seekg(12, std::ios_base::cur);
|
is.seekg(12, std::ios_base::cur);
|
||||||
|
|
@ -343,7 +345,8 @@ void Ar2vFileImpl::ParseLDMRecord(std::istream& is)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rda::Level2MessageInfo msgInfo = rda::Level2MessageFactory::Create(is);
|
rda::Level2MessageInfo msgInfo =
|
||||||
|
rda::Level2MessageFactory::Create(is, ctx);
|
||||||
if (!msgInfo.headerValid)
|
if (!msgInfo.headerValid)
|
||||||
{
|
{
|
||||||
// Invalid message
|
// Invalid message
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,30 @@ static const std::unordered_map<uint8_t, CreateLevel2MessageFunction> create_ {
|
||||||
{18, RdaAdaptationData::Create},
|
{18, RdaAdaptationData::Create},
|
||||||
{31, DigitalRadarData::Create}};
|
{31, DigitalRadarData::Create}};
|
||||||
|
|
||||||
static std::vector<char> messageData_;
|
struct Level2MessageFactory::Context
|
||||||
static size_t bufferedSize_;
|
{
|
||||||
static util::vectorbuf messageBuffer_(messageData_);
|
Context() :
|
||||||
static std::istream messageBufferStream_(&messageBuffer_);
|
messageData_ {},
|
||||||
|
bufferedSize_ {},
|
||||||
|
messageBuffer_ {messageData_},
|
||||||
|
messageBufferStream_ {&messageBuffer_}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Level2MessageInfo Level2MessageFactory::Create(std::istream& is)
|
std::vector<char> messageData_;
|
||||||
|
size_t bufferedSize_;
|
||||||
|
util::vectorbuf messageBuffer_;
|
||||||
|
std::istream messageBufferStream_;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<Level2MessageFactory::Context>
|
||||||
|
Level2MessageFactory::CreateContext()
|
||||||
|
{
|
||||||
|
return std::make_shared<Context>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Level2MessageInfo Level2MessageFactory::Create(std::istream& is,
|
||||||
|
std::shared_ptr<Context> ctx)
|
||||||
{
|
{
|
||||||
Level2MessageInfo info;
|
Level2MessageInfo info;
|
||||||
Level2MessageHeader header;
|
Level2MessageHeader header;
|
||||||
|
|
@ -80,12 +98,12 @@ Level2MessageInfo Level2MessageFactory::Create(std::istream& is)
|
||||||
if (segment == 1)
|
if (segment == 1)
|
||||||
{
|
{
|
||||||
// Estimate total message size
|
// Estimate total message size
|
||||||
messageData_.resize(dataSize * totalSegments);
|
ctx->messageData_.resize(dataSize * totalSegments);
|
||||||
messageBufferStream_.clear();
|
ctx->messageBufferStream_.clear();
|
||||||
bufferedSize_ = 0;
|
ctx->bufferedSize_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageData_.capacity() < bufferedSize_ + dataSize)
|
if (ctx->messageData_.capacity() < ctx->bufferedSize_ + dataSize)
|
||||||
{
|
{
|
||||||
logger_->debug("Bad size estimate, increasing size");
|
logger_->debug("Bad size estimate, increasing size");
|
||||||
|
|
||||||
|
|
@ -94,26 +112,26 @@ Level2MessageInfo Level2MessageFactory::Create(std::istream& is)
|
||||||
std::max<uint16_t>(totalSegments - segment + 1, 100u);
|
std::max<uint16_t>(totalSegments - segment + 1, 100u);
|
||||||
size_t remainingSize = remainingSegments * dataSize;
|
size_t remainingSize = remainingSegments * dataSize;
|
||||||
|
|
||||||
messageData_.resize(bufferedSize_ + remainingSize);
|
ctx->messageData_.resize(ctx->bufferedSize_ + remainingSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
is.read(messageData_.data() + bufferedSize_, dataSize);
|
is.read(ctx->messageData_.data() + ctx->bufferedSize_, dataSize);
|
||||||
bufferedSize_ += dataSize;
|
ctx->bufferedSize_ += dataSize;
|
||||||
|
|
||||||
if (is.eof())
|
if (is.eof())
|
||||||
{
|
{
|
||||||
logger_->warn("End of file reached trying to buffer message");
|
logger_->warn("End of file reached trying to buffer message");
|
||||||
info.messageValid = false;
|
info.messageValid = false;
|
||||||
messageData_.shrink_to_fit();
|
ctx->messageData_.shrink_to_fit();
|
||||||
bufferedSize_ = 0;
|
ctx->bufferedSize_ = 0;
|
||||||
}
|
}
|
||||||
else if (segment == totalSegments)
|
else if (segment == totalSegments)
|
||||||
{
|
{
|
||||||
messageBuffer_.update_read_pointers(bufferedSize_);
|
ctx->messageBuffer_.update_read_pointers(ctx->bufferedSize_);
|
||||||
header.set_message_size(static_cast<uint16_t>(
|
header.set_message_size(static_cast<uint16_t>(
|
||||||
bufferedSize_ / 2 + Level2MessageHeader::SIZE));
|
ctx->bufferedSize_ / 2 + Level2MessageHeader::SIZE));
|
||||||
|
|
||||||
messageStream = &messageBufferStream_;
|
messageStream = &ctx->messageBufferStream_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,9 +139,10 @@ Level2MessageInfo Level2MessageFactory::Create(std::istream& is)
|
||||||
{
|
{
|
||||||
info.message =
|
info.message =
|
||||||
create_.at(messageType)(std::move(header), *messageStream);
|
create_.at(messageType)(std::move(header), *messageStream);
|
||||||
messageData_.shrink_to_fit();
|
ctx->messageData_.resize(0);
|
||||||
messageBufferStream_.clear();
|
ctx->messageData_.shrink_to_fit();
|
||||||
bufferedSize_ = 0;
|
ctx->messageBufferStream_.clear();
|
||||||
|
ctx->bufferedSize_ = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (info.headerValid)
|
else if (info.headerValid)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue