#include #include #include #include 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> messages_; }; TextProductFile::TextProductFile() : p(std::make_unique()) { } 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> TextProductFile::messages() const { return p->messages_; } std::shared_ptr 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 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 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