mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-11-04 03:40:05 +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
 |