mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 01:20:06 +00:00 
			
		
		
		
	Support zlib compressed level 3 files
This commit is contained in:
		
							parent
							
								
									b2687c2258
								
							
						
					
					
						commit
						01d24d70b8
					
				
					 6 changed files with 377 additions and 13 deletions
				
			
		|  | @ -1 +1 @@ | ||||||
| Subproject commit 4e9a2804d977acebbebdcfb73efa9dec190b28e5 | Subproject commit 5de70eccee20d5d8358acb4ebcc209259658fddd | ||||||
|  | @ -73,6 +73,7 @@ INSTANTIATE_TEST_SUITE_P( | ||||||
|       std::pair<int16_t, std::string> {176, "KLSX_SDUS83_DPRLSX_202112110140"}, |       std::pair<int16_t, std::string> {176, "KLSX_SDUS83_DPRLSX_202112110140"}, | ||||||
|       std::pair<int16_t, std::string> {177, "KLSX_SDUS83_HHCLSX_202112110140"}, |       std::pair<int16_t, std::string> {177, "KLSX_SDUS83_HHCLSX_202112110140"}, | ||||||
|       std::pair<int16_t, std::string> {99, "Level3_LSX_N1U_20211228_0446.nids"}, |       std::pair<int16_t, std::string> {99, "Level3_LSX_N1U_20211228_0446.nids"}, | ||||||
|  |       std::pair<int16_t, std::string> {37, "Level3_STL_NCR_20211211_0200.nids"}, | ||||||
|       std::pair<int16_t, std::string> {180, |       std::pair<int16_t, std::string> {180, | ||||||
|                                        "Level3_STL_TZ0_20211211_0200.nids"}, |                                        "Level3_STL_TZ0_20211211_0200.nids"}, | ||||||
|       std::pair<int16_t, std::string> {182, |       std::pair<int16_t, std::string> {182, | ||||||
|  |  | ||||||
							
								
								
									
										60
									
								
								wxdata/include/scwx/wsr88d/rpg/ccb_header.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								wxdata/include/scwx/wsr88d/rpg/ccb_header.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,60 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace wsr88d | ||||||
|  | { | ||||||
|  | namespace rpg | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class CcbHeaderImpl; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief The Communication Control Block Header is defined in the Interface | ||||||
|  |  * Control Document (ICD) for the National Weather Service Telecommunications | ||||||
|  |  * Gateway (NWSTG). | ||||||
|  |  * | ||||||
|  |  * <https://web.archive.org/web/20010706211204/http://www.nws.noaa.gov/pub/noaaport/nwstgicd.pdf>
 | ||||||
|  |  */ | ||||||
|  | class CcbHeader | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit CcbHeader(); | ||||||
|  |    ~CcbHeader(); | ||||||
|  | 
 | ||||||
|  |    CcbHeader(const CcbHeader&) = delete; | ||||||
|  |    CcbHeader& operator=(const CcbHeader&) = delete; | ||||||
|  | 
 | ||||||
|  |    CcbHeader(CcbHeader&&) noexcept; | ||||||
|  |    CcbHeader& operator=(CcbHeader&&) noexcept; | ||||||
|  | 
 | ||||||
|  |    uint16_t    ff() const; | ||||||
|  |    uint16_t    ccb_length() const; | ||||||
|  |    uint8_t     mode() const; | ||||||
|  |    uint8_t     submode() const; | ||||||
|  |    char        precedence() const; | ||||||
|  |    char        classification() const; | ||||||
|  |    std::string message_originator() const; | ||||||
|  |    uint8_t     category() const; | ||||||
|  |    uint8_t     subcategory() const; | ||||||
|  |    uint16_t    user_defined() const; | ||||||
|  |    uint8_t     year() const; | ||||||
|  |    uint8_t     month() const; | ||||||
|  |    uint8_t     tor_day() const; | ||||||
|  |    uint8_t     tor_hour() const; | ||||||
|  |    uint8_t     tor_minute() const; | ||||||
|  |    uint8_t     number_of_destinations() const; | ||||||
|  |    std::string message_destination(uint8_t i) const; | ||||||
|  | 
 | ||||||
|  |    bool Parse(std::istream& is); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    std::unique_ptr<CcbHeaderImpl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace rpg
 | ||||||
|  | } // namespace wsr88d
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #include <scwx/wsr88d/level3_file.hpp> | #include <scwx/wsr88d/level3_file.hpp> | ||||||
|  | #include <scwx/wsr88d/rpg/ccb_header.hpp> | ||||||
| #include <scwx/wsr88d/rpg/level3_message_header.hpp> | #include <scwx/wsr88d/rpg/level3_message_header.hpp> | ||||||
| #include <scwx/wsr88d/rpg/product_description_block.hpp> | #include <scwx/wsr88d/rpg/product_description_block.hpp> | ||||||
| #include <scwx/wsr88d/rpg/product_symbology_block.hpp> | #include <scwx/wsr88d/rpg/product_symbology_block.hpp> | ||||||
|  | @ -11,6 +12,7 @@ | ||||||
| #include <boost/iostreams/copy.hpp> | #include <boost/iostreams/copy.hpp> | ||||||
| #include <boost/iostreams/filtering_streambuf.hpp> | #include <boost/iostreams/filtering_streambuf.hpp> | ||||||
| #include <boost/iostreams/filter/bzip2.hpp> | #include <boost/iostreams/filter/bzip2.hpp> | ||||||
|  | #include <boost/iostreams/filter/zlib.hpp> | ||||||
| #include <boost/log/trivial.hpp> | #include <boost/log/trivial.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
|  | @ -25,6 +27,7 @@ class Level3FileImpl | ||||||
| public: | public: | ||||||
|    explicit Level3FileImpl() : |    explicit Level3FileImpl() : | ||||||
|        wmoHeader_ {}, |        wmoHeader_ {}, | ||||||
|  |        ccbHeader_ {}, | ||||||
|        messageHeader_ {}, |        messageHeader_ {}, | ||||||
|        descriptionBlock_ {}, |        descriptionBlock_ {}, | ||||||
|        symbologyBlock_ {}, |        symbologyBlock_ {}, | ||||||
|  | @ -32,9 +35,13 @@ public: | ||||||
|        tabularBlock_ {} {}; |        tabularBlock_ {} {}; | ||||||
|    ~Level3FileImpl() = default; |    ~Level3FileImpl() = default; | ||||||
| 
 | 
 | ||||||
|  |    bool DecompressFile(std::istream& is, std::stringstream& ss); | ||||||
|  |    bool LoadFileData(std::istream& is); | ||||||
|    bool LoadBlocks(std::istream& is); |    bool LoadBlocks(std::istream& is); | ||||||
| 
 | 
 | ||||||
|    rpg::WmoHeader                  wmoHeader_; |    rpg::WmoHeader                  wmoHeader_; | ||||||
|  |    std::shared_ptr<rpg::CcbHeader> ccbHeader_; | ||||||
|  |    std::shared_ptr<rpg::WmoHeader> innerHeader_; | ||||||
|    rpg::Level3MessageHeader        messageHeader_; |    rpg::Level3MessageHeader        messageHeader_; | ||||||
|    rpg::ProductDescriptionBlock    descriptionBlock_; |    rpg::ProductDescriptionBlock    descriptionBlock_; | ||||||
| 
 | 
 | ||||||
|  | @ -89,22 +96,107 @@ bool Level3File::LoadData(std::istream& is) | ||||||
|       BOOST_LOG_TRIVIAL(debug) |       BOOST_LOG_TRIVIAL(debug) | ||||||
|          << logPrefix_ << "Category:  " << p->wmoHeader_.product_category(); |          << logPrefix_ << "Category:  " << p->wmoHeader_.product_category(); | ||||||
| 
 | 
 | ||||||
|       dataValid = p->messageHeader_.Parse(is); |       // If the header is compressed
 | ||||||
|  |       if (is.peek() == 0x78) | ||||||
|  |       { | ||||||
|  |          std::stringstream ss; | ||||||
|  | 
 | ||||||
|  |          dataValid = p->DecompressFile(is, ss); | ||||||
|  | 
 | ||||||
|  |          if (dataValid) | ||||||
|  |          { | ||||||
|  |             dataValid = p->LoadFileData(ss); | ||||||
|          } |          } | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          dataValid = p->LoadFileData(is); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return dataValid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool Level3FileImpl::DecompressFile(std::istream& is, std::stringstream& ss) | ||||||
|  | { | ||||||
|  |    bool dataValid = true; | ||||||
|  | 
 | ||||||
|  |    std::streampos  dataStart          = is.tellg(); | ||||||
|  |    std::streamsize totalBytesCopied   = 0; | ||||||
|  |    int             totalBytesConsumed = 0; | ||||||
|  | 
 | ||||||
|  |    while (dataValid && is.peek() == 0x78) | ||||||
|  |       try | ||||||
|  |       { | ||||||
|  |          boost::iostreams::filtering_streambuf<boost::iostreams::input> in; | ||||||
|  |          boost::iostreams::zlib_decompressor zlibDecompressor; | ||||||
|  |          in.push(zlibDecompressor); | ||||||
|  |          in.push(is); | ||||||
|  | 
 | ||||||
|  |          std::streamsize bytesCopied   = boost::iostreams::copy(in, ss); | ||||||
|  |          int             bytesConsumed = zlibDecompressor.filter().total_in(); | ||||||
|  | 
 | ||||||
|  |          totalBytesCopied += bytesCopied; | ||||||
|  |          totalBytesConsumed += bytesConsumed; | ||||||
|  | 
 | ||||||
|  |          is.seekg(dataStart + static_cast<std::streamoff>(totalBytesConsumed), | ||||||
|  |                   std::ios_base::beg); | ||||||
|  | 
 | ||||||
|  |          if (bytesConsumed <= 0) | ||||||
|  |          { | ||||||
|  |             // Not sure this will ever occur, but will prevent an infinite loop
 | ||||||
|  |             break; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |       catch (const boost::iostreams::zlib_error& ex) | ||||||
|  |       { | ||||||
|  |          int error = ex.error(); | ||||||
|  | 
 | ||||||
|  |          BOOST_LOG_TRIVIAL(warning) | ||||||
|  |             << logPrefix_ << "Error decompressing data: " << ex.what(); | ||||||
|  | 
 | ||||||
|  |          dataValid = false; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |    if (dataValid) | ||||||
|  |    { | ||||||
|  |       BOOST_LOG_TRIVIAL(trace) | ||||||
|  |          << logPrefix_ << "Input data consumed = " << totalBytesCopied | ||||||
|  |          << " bytes"; | ||||||
|  |       BOOST_LOG_TRIVIAL(trace) | ||||||
|  |          << logPrefix_ << "Decompressed data size = " << totalBytesConsumed | ||||||
|  |          << " bytes"; | ||||||
|  | 
 | ||||||
|  |       ccbHeader_ = std::make_shared<rpg::CcbHeader>(); | ||||||
|  |       dataValid  = ccbHeader_->Parse(ss); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (dataValid) | ||||||
|  |    { | ||||||
|  |       innerHeader_ = std::make_shared<rpg::WmoHeader>(); | ||||||
|  |       dataValid    = innerHeader_->Parse(ss); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return dataValid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool Level3FileImpl::LoadFileData(std::istream& is) | ||||||
|  | { | ||||||
|  |    bool dataValid = messageHeader_.Parse(is); | ||||||
| 
 | 
 | ||||||
|    if (dataValid) |    if (dataValid) | ||||||
|    { |    { | ||||||
|       BOOST_LOG_TRIVIAL(debug) |       BOOST_LOG_TRIVIAL(debug) | ||||||
|          << logPrefix_ << "Code:      " << p->messageHeader_.message_code(); |          << logPrefix_ << "Code:      " << messageHeader_.message_code(); | ||||||
| 
 | 
 | ||||||
|       dataValid = p->descriptionBlock_.Parse(is); |       dataValid = descriptionBlock_.Parse(is); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    if (dataValid) |    if (dataValid) | ||||||
|    { |    { | ||||||
|       if (p->descriptionBlock_.IsCompressionEnabled()) |       if (descriptionBlock_.IsCompressionEnabled()) | ||||||
|       { |       { | ||||||
|          size_t messageLength = p->messageHeader_.length_of_message(); |          size_t messageLength = messageHeader_.length_of_message(); | ||||||
|          size_t prefixLength = |          size_t prefixLength = | ||||||
|             rpg::Level3MessageHeader::SIZE + rpg::ProductDescriptionBlock::SIZE; |             rpg::Level3MessageHeader::SIZE + rpg::ProductDescriptionBlock::SIZE; | ||||||
|          size_t recordSize = |          size_t recordSize = | ||||||
|  | @ -123,7 +215,7 @@ bool Level3File::LoadData(std::istream& is) | ||||||
|                << logPrefix_ << "Decompressed data size = " << bytesCopied |                << logPrefix_ << "Decompressed data size = " << bytesCopied | ||||||
|                << " bytes"; |                << " bytes"; | ||||||
| 
 | 
 | ||||||
|             dataValid = p->LoadBlocks(ss); |             dataValid = LoadBlocks(ss); | ||||||
|          } |          } | ||||||
|          catch (const boost::iostreams::bzip2_error& ex) |          catch (const boost::iostreams::bzip2_error& ex) | ||||||
|          { |          { | ||||||
|  | @ -136,7 +228,7 @@ bool Level3File::LoadData(std::istream& is) | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          dataValid = p->LoadBlocks(is); |          dataValid = LoadBlocks(is); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										209
									
								
								wxdata/source/scwx/wsr88d/rpg/ccb_header.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								wxdata/source/scwx/wsr88d/rpg/ccb_header.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,209 @@ | ||||||
|  | #include <scwx/wsr88d/rpg/ccb_header.hpp> | ||||||
|  | #include <scwx/util/streams.hpp> | ||||||
|  | 
 | ||||||
|  | #include <istream> | ||||||
|  | #include <sstream> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <boost/log/trivial.hpp> | ||||||
|  | 
 | ||||||
|  | #ifdef WIN32 | ||||||
|  | #   include <WinSock2.h> | ||||||
|  | #else | ||||||
|  | #   include <arpa/inet.h> | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace wsr88d | ||||||
|  | { | ||||||
|  | namespace rpg | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = "[scwx::wsr88d::rpg::ccb_header] "; | ||||||
|  | 
 | ||||||
|  | class CcbHeaderImpl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit CcbHeaderImpl() : | ||||||
|  |        ff_ {0}, | ||||||
|  |        ccbLength_ {0}, | ||||||
|  |        mode_ {0}, | ||||||
|  |        submode_ {0}, | ||||||
|  |        precedence_ {0}, | ||||||
|  |        classification_ {0}, | ||||||
|  |        messageOriginator_ {}, | ||||||
|  |        category_ {0}, | ||||||
|  |        subcategory_ {0}, | ||||||
|  |        userDefined_ {0}, | ||||||
|  |        year_ {0}, | ||||||
|  |        month_ {0}, | ||||||
|  |        torDay_ {0}, | ||||||
|  |        torHour_ {0}, | ||||||
|  |        torMinute_ {0}, | ||||||
|  |        numberOfDestinations_ {0}, | ||||||
|  |        messageDestination_ {} | ||||||
|  |    { | ||||||
|  |    } | ||||||
|  |    ~CcbHeaderImpl() = default; | ||||||
|  | 
 | ||||||
|  |    uint16_t                 ff_; | ||||||
|  |    uint16_t                 ccbLength_; | ||||||
|  |    uint8_t                  mode_; | ||||||
|  |    uint8_t                  submode_; | ||||||
|  |    char                     precedence_; | ||||||
|  |    char                     classification_; | ||||||
|  |    std::string              messageOriginator_; | ||||||
|  |    uint8_t                  category_; | ||||||
|  |    uint8_t                  subcategory_; | ||||||
|  |    uint16_t                 userDefined_; | ||||||
|  |    uint8_t                  year_; | ||||||
|  |    uint8_t                  month_; | ||||||
|  |    uint8_t                  torDay_; | ||||||
|  |    uint8_t                  torHour_; | ||||||
|  |    uint8_t                  torMinute_; | ||||||
|  |    uint8_t                  numberOfDestinations_; | ||||||
|  |    std::vector<std::string> messageDestination_; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | CcbHeader::CcbHeader() : p(std::make_unique<CcbHeaderImpl>()) {} | ||||||
|  | CcbHeader::~CcbHeader() = default; | ||||||
|  | 
 | ||||||
|  | CcbHeader::CcbHeader(CcbHeader&&) noexcept = default; | ||||||
|  | CcbHeader& CcbHeader::operator=(CcbHeader&&) noexcept = default; | ||||||
|  | 
 | ||||||
|  | uint16_t CcbHeader::ff() const | ||||||
|  | { | ||||||
|  |    return p->ff_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint16_t CcbHeader::ccb_length() const | ||||||
|  | { | ||||||
|  |    return p->ccbLength_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::mode() const | ||||||
|  | { | ||||||
|  |    return p->mode_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::submode() const | ||||||
|  | { | ||||||
|  |    return p->submode_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char CcbHeader::precedence() const | ||||||
|  | { | ||||||
|  |    return p->precedence_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char CcbHeader::classification() const | ||||||
|  | { | ||||||
|  |    return p->classification_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::string CcbHeader::message_originator() const | ||||||
|  | { | ||||||
|  |    return p->messageOriginator_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::category() const | ||||||
|  | { | ||||||
|  |    return p->category_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::subcategory() const | ||||||
|  | { | ||||||
|  |    return p->subcategory_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint16_t CcbHeader::user_defined() const | ||||||
|  | { | ||||||
|  |    return p->userDefined_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::year() const | ||||||
|  | { | ||||||
|  |    return p->year_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::month() const | ||||||
|  | { | ||||||
|  |    return p->month_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::tor_day() const | ||||||
|  | { | ||||||
|  |    return p->torDay_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::tor_hour() const | ||||||
|  | { | ||||||
|  |    return p->torHour_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::tor_minute() const | ||||||
|  | { | ||||||
|  |    return p->torMinute_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CcbHeader::number_of_destinations() const | ||||||
|  | { | ||||||
|  |    return p->numberOfDestinations_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::string CcbHeader::message_destination(uint8_t i) const | ||||||
|  | { | ||||||
|  |    return p->messageDestination_[i]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool CcbHeader::Parse(std::istream& is) | ||||||
|  | { | ||||||
|  |    bool headerValid = true; | ||||||
|  | 
 | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->ccbLength_), 2); | ||||||
|  | 
 | ||||||
|  |    p->ccbLength_ = ntohs(p->ccbLength_); | ||||||
|  | 
 | ||||||
|  |    p->ff_        = p->ccbLength_ >> 14; | ||||||
|  |    p->ccbLength_ = p->ccbLength_ & 0x3fff; | ||||||
|  | 
 | ||||||
|  |    p->messageOriginator_.resize(4); | ||||||
|  | 
 | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->mode_), 1); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->submode_), 1); | ||||||
|  |    is.read(&p->precedence_, 1); | ||||||
|  |    is.read(&p->classification_, 1); | ||||||
|  |    is.read(p->messageOriginator_.data(), 4); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->category_), 1); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->subcategory_), 1); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->userDefined_), 2); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->year_), 1); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->month_), 1); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->torDay_), 1); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->torHour_), 1); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->torMinute_), 1); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->numberOfDestinations_), 1); | ||||||
|  | 
 | ||||||
|  |    p->userDefined_ = ntohs(p->userDefined_); | ||||||
|  | 
 | ||||||
|  |    p->messageDestination_.resize(p->numberOfDestinations_); | ||||||
|  | 
 | ||||||
|  |    for (uint8_t d = 0; d < p->numberOfDestinations_; d++) | ||||||
|  |    { | ||||||
|  |       p->messageDestination_[d].resize(4); | ||||||
|  |       is.read(p->messageDestination_[d].data(), 4); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (is.eof()) | ||||||
|  |    { | ||||||
|  |       BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; | ||||||
|  |       headerValid = false; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return headerValid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace rpg
 | ||||||
|  | } // namespace wsr88d
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -46,7 +46,8 @@ set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_map.cpp | ||||||
|                    source/scwx/wsr88d/rda/rda_adaptation_data.cpp |                    source/scwx/wsr88d/rda/rda_adaptation_data.cpp | ||||||
|                    source/scwx/wsr88d/rda/rda_status_data.cpp |                    source/scwx/wsr88d/rda/rda_status_data.cpp | ||||||
|                    source/scwx/wsr88d/rda/volume_coverage_pattern_data.cpp) |                    source/scwx/wsr88d/rda/volume_coverage_pattern_data.cpp) | ||||||
| set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp | set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/ccb_header.hpp | ||||||
|  |                    include/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp | ||||||
|                    include/scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp |                    include/scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp | ||||||
|                    include/scwx/wsr88d/rpg/generic_data_packet.hpp |                    include/scwx/wsr88d/rpg/generic_data_packet.hpp | ||||||
|                    include/scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp |                    include/scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp | ||||||
|  | @ -74,7 +75,8 @@ set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/digital_precipitation_data_array_pack | ||||||
|                    include/scwx/wsr88d/rpg/vector_arrow_data_packet.hpp |                    include/scwx/wsr88d/rpg/vector_arrow_data_packet.hpp | ||||||
|                    include/scwx/wsr88d/rpg/wind_barb_data_packet.hpp |                    include/scwx/wsr88d/rpg/wind_barb_data_packet.hpp | ||||||
|                    include/scwx/wsr88d/rpg/wmo_header.hpp) |                    include/scwx/wsr88d/rpg/wmo_header.hpp) | ||||||
| set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.cpp | set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/ccb_header.cpp | ||||||
|  |                    source/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.cpp | ||||||
|                    source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp |                    source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp | ||||||
|                    source/scwx/wsr88d/rpg/generic_data_packet.cpp |                    source/scwx/wsr88d/rpg/generic_data_packet.cpp | ||||||
|                    source/scwx/wsr88d/rpg/hda_hail_symbol_packet.cpp |                    source/scwx/wsr88d/rpg/hda_hail_symbol_packet.cpp | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat