mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-29 22:30:04 +00:00
133 lines
3.1 KiB
C++
133 lines
3.1 KiB
C++
#include <scwx/awips/text_product_file.hpp>
|
|
#include <scwx/util/logger.hpp>
|
|
|
|
#include <fstream>
|
|
|
|
#include <re2/re2.h>
|
|
|
|
namespace scwx::awips
|
|
{
|
|
|
|
static const std::string logPrefix_ = "scwx::awips::text_product_file";
|
|
static const auto logger_ = util::Logger::Create(logPrefix_);
|
|
|
|
class TextProductFile::Impl
|
|
{
|
|
public:
|
|
explicit Impl() : messages_ {} {};
|
|
~Impl() = default;
|
|
|
|
Impl(const Impl&) = delete;
|
|
Impl& operator=(const Impl&) = delete;
|
|
|
|
Impl(Impl&&) = delete;
|
|
Impl& operator=(Impl&&) = delete;
|
|
|
|
std::vector<std::shared_ptr<TextProductMessage>> messages_;
|
|
};
|
|
|
|
TextProductFile::TextProductFile() :
|
|
p(std::make_unique<TextProductFile::Impl>())
|
|
{
|
|
}
|
|
TextProductFile::~TextProductFile() = default;
|
|
|
|
TextProductFile::TextProductFile(TextProductFile&&) noexcept = default;
|
|
TextProductFile&
|
|
TextProductFile::operator=(TextProductFile&&) noexcept = default;
|
|
|
|
size_t TextProductFile::message_count() const
|
|
{
|
|
return p->messages_.size();
|
|
}
|
|
|
|
std::vector<std::shared_ptr<TextProductMessage>>
|
|
TextProductFile::messages() const
|
|
{
|
|
return p->messages_;
|
|
}
|
|
|
|
std::shared_ptr<TextProductMessage> TextProductFile::message(size_t i) const
|
|
{
|
|
return p->messages_[i];
|
|
}
|
|
|
|
bool TextProductFile::LoadFile(const std::string& filename)
|
|
{
|
|
logger_->debug("LoadFile: {}", filename);
|
|
bool fileValid = true;
|
|
|
|
std::ifstream f(filename, std::ios_base::in | std::ios_base::binary);
|
|
if (!f.good())
|
|
{
|
|
logger_->warn("Could not open file for reading: {}", filename);
|
|
fileValid = false;
|
|
}
|
|
|
|
if (fileValid)
|
|
{
|
|
fileValid = LoadData(filename, f);
|
|
}
|
|
|
|
return fileValid;
|
|
}
|
|
|
|
bool TextProductFile::LoadData(const std::string& filename, std::istream& is)
|
|
{
|
|
static constexpr LazyRE2 kDateTimePattern_ = {
|
|
R"(((?:19|20)\d{2}))" // Year (YYYY)
|
|
R"((0[1-9]|1[0-2]))" // Month (MM)
|
|
R"((0[1-9]|[12]\d|3[01]))" // Day (DD)
|
|
R"(_?)" // Optional separator (not captured)
|
|
R"(([01]\d|2[0-3]))" // Hour (HH)
|
|
};
|
|
|
|
logger_->trace("Loading Data");
|
|
|
|
// Attempt to parse the date from the filename
|
|
std::optional<std::chrono::year_month> yearMonth;
|
|
int year {};
|
|
unsigned int month {};
|
|
|
|
if (RE2::PartialMatch(filename, *kDateTimePattern_, &year, &month))
|
|
{
|
|
yearMonth = std::chrono::year {year} / std::chrono::month {month};
|
|
}
|
|
|
|
while (!is.eof())
|
|
{
|
|
std::shared_ptr<TextProductMessage> message =
|
|
TextProductMessage::Create(is);
|
|
bool duplicate = false;
|
|
|
|
if (message != nullptr)
|
|
{
|
|
for (const auto& m : p->messages_)
|
|
{
|
|
if (*m->wmo_header().get() == *message->wmo_header().get())
|
|
{
|
|
duplicate = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!duplicate)
|
|
{
|
|
if (yearMonth.has_value())
|
|
{
|
|
message->wmo_header()->SetDateHint(yearMonth.value());
|
|
}
|
|
|
|
p->messages_.push_back(message);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return !p->messages_.empty();
|
|
}
|
|
|
|
} // namespace scwx::awips
|