mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 11:20:05 +00:00 
			
		
		
		
	Load packets using a packet factory
This commit is contained in:
		
							parent
							
								
									0ef21fd609
								
							
						
					
					
						commit
						ae7baf0980
					
				
					 4 changed files with 155 additions and 14 deletions
				
			
		
							
								
								
									
										30
									
								
								wxdata/include/scwx/wsr88d/rpg/packet_factory.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								wxdata/include/scwx/wsr88d/rpg/packet_factory.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/wsr88d/rpg/packet.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace wsr88d | ||||
| { | ||||
| namespace rpg | ||||
| { | ||||
| 
 | ||||
| class PacketFactory | ||||
| { | ||||
| private: | ||||
|    explicit PacketFactory() = delete; | ||||
|    ~PacketFactory()         = delete; | ||||
| 
 | ||||
|    PacketFactory(const PacketFactory&) = delete; | ||||
|    PacketFactory& operator=(const PacketFactory&) = delete; | ||||
| 
 | ||||
|    PacketFactory(PacketFactory&&) noexcept = delete; | ||||
|    PacketFactory& operator=(PacketFactory&&) noexcept = delete; | ||||
| 
 | ||||
| public: | ||||
|    static std::shared_ptr<Packet> Create(std::istream& is); | ||||
| }; | ||||
| 
 | ||||
| } // namespace rpg
 | ||||
| } // namespace wsr88d
 | ||||
| } // namespace scwx
 | ||||
|  | @ -32,7 +32,7 @@ public: | |||
|        tabularBlock_ {} {}; | ||||
|    ~Level3FileImpl() = default; | ||||
| 
 | ||||
|    void LoadBlocks(std::istream& is); | ||||
|    bool LoadBlocks(std::istream& is); | ||||
| 
 | ||||
|    rpg::WmoHeader               wmoHeader_; | ||||
|    rpg::Level3MessageHeader     messageHeader_; | ||||
|  | @ -123,7 +123,7 @@ bool Level3File::LoadData(std::istream& is) | |||
|                << logPrefix_ << "Decompressed data size = " << bytesCopied | ||||
|                << " bytes"; | ||||
| 
 | ||||
|             p->LoadBlocks(ss); | ||||
|             dataValid = p->LoadBlocks(ss); | ||||
|          } | ||||
|          catch (const boost::iostreams::bzip2_error& ex) | ||||
|          { | ||||
|  | @ -136,15 +136,19 @@ bool Level3File::LoadData(std::istream& is) | |||
|       } | ||||
|       else | ||||
|       { | ||||
|          p->LoadBlocks(is); | ||||
|          dataValid = p->LoadBlocks(is); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    return dataValid; | ||||
| } | ||||
| 
 | ||||
| void Level3FileImpl::LoadBlocks(std::istream& is) | ||||
| bool Level3FileImpl::LoadBlocks(std::istream& is) | ||||
| { | ||||
|    bool symbologyValid = true; | ||||
|    bool graphicValid   = true; | ||||
|    bool tabularValid   = true; | ||||
| 
 | ||||
|    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Loading Blocks"; | ||||
| 
 | ||||
|    std::streampos offsetBasePos = is.tellg(); | ||||
|  | @ -159,8 +163,6 @@ void Level3FileImpl::LoadBlocks(std::istream& is) | |||
| 
 | ||||
|    if (offsetToSymbology >= offsetBase) | ||||
|    { | ||||
|       bool symbologyValid; | ||||
| 
 | ||||
|       symbologyBlock_ = std::make_shared<rpg::ProductSymbologyBlock>(); | ||||
| 
 | ||||
|       is.seekg(offsetToSymbology - offsetBase, std::ios_base::cur); | ||||
|  | @ -197,6 +199,8 @@ void Level3FileImpl::LoadBlocks(std::istream& is) | |||
|          << logPrefix_ | ||||
|          << "Tabular alphanumeric block found: " << offsetToTabular; | ||||
|    } | ||||
| 
 | ||||
|    return (symbologyValid && graphicValid && tabularValid); | ||||
| } | ||||
| 
 | ||||
| } // namespace wsr88d
 | ||||
|  |  | |||
							
								
								
									
										73
									
								
								wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,73 @@ | |||
| #include <scwx/wsr88d/rpg/packet_factory.hpp> | ||||
| 
 | ||||
| #include <scwx/wsr88d/rpg/linked_contour_vector_packet.hpp> | ||||
| #include <scwx/wsr88d/rpg/linked_vector_packet.hpp> | ||||
| #include <scwx/wsr88d/rpg/set_color_level_packet.hpp> | ||||
| #include <scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp> | ||||
| #include <scwx/wsr88d/rpg/unlinked_contour_vector_packet.hpp> | ||||
| #include <scwx/wsr88d/rpg/unlinked_vector_packet.hpp> | ||||
| 
 | ||||
| #include <unordered_map> | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace wsr88d | ||||
| { | ||||
| namespace rpg | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "[scwx::wsr88d::rpg::packet_factory] "; | ||||
| 
 | ||||
| typedef std::function<std::shared_ptr<Packet>(std::istream&)> | ||||
|    CreateMessageFunction; | ||||
| 
 | ||||
| static const std::unordered_map<uint16_t, CreateMessageFunction> create_ { | ||||
|    {1, TextAndSpecialSymbolPacket::Create}, | ||||
|    {2, TextAndSpecialSymbolPacket::Create}, | ||||
|    {6, LinkedVectorPacket::Create}, | ||||
|    {7, UnlinkedVectorPacket::Create}, | ||||
|    {8, TextAndSpecialSymbolPacket::Create}, | ||||
|    {9, LinkedVectorPacket::Create}, | ||||
|    {10, UnlinkedVectorPacket::Create}, | ||||
|    {0x0802, SetColorLevelPacket::Create}, | ||||
|    {0x0E03, LinkedContourVectorPacket::Create}, | ||||
|    {0x3501, UnlinkedContourVectorPacket::Create}}; | ||||
| 
 | ||||
| std::shared_ptr<Packet> PacketFactory::Create(std::istream& is) | ||||
| { | ||||
|    std::shared_ptr<Packet> packet      = nullptr; | ||||
|    bool                    packetValid = true; | ||||
| 
 | ||||
|    uint16_t packetCode; | ||||
| 
 | ||||
|    is.read(reinterpret_cast<char*>(&packetCode), 2); | ||||
|    packetCode = ntohs(packetCode); | ||||
| 
 | ||||
|    if (is.eof()) | ||||
|    { | ||||
|       packetValid = false; | ||||
|    } | ||||
| 
 | ||||
|    is.seekg(-2, std::ios_base::cur); | ||||
| 
 | ||||
|    if (packetValid && create_.find(packetCode) == create_.end()) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ << "Unknown packet code: " << packetCode << " (0x" | ||||
|          << std::hex << packetCode << std::dec << ")"; | ||||
|       packetValid = false; | ||||
|    } | ||||
| 
 | ||||
|    if (packetValid) | ||||
|    { | ||||
|       packet = create_.at(packetCode)(is); | ||||
|    } | ||||
| 
 | ||||
|    return packet; | ||||
| } | ||||
| 
 | ||||
| } // namespace rpg
 | ||||
| } // namespace wsr88d
 | ||||
| } // namespace scwx
 | ||||
|  | @ -1,4 +1,5 @@ | |||
| #include <scwx/wsr88d/rpg/product_symbology_block.hpp> | ||||
| #include <scwx/wsr88d/rpg/packet_factory.hpp> | ||||
| 
 | ||||
| #include <istream> | ||||
| #include <string> | ||||
|  | @ -26,6 +27,8 @@ public: | |||
|    int16_t  blockId_; | ||||
|    uint32_t lengthOfBlock_; | ||||
|    uint16_t numberOfLayers_; | ||||
| 
 | ||||
|    std::vector<std::vector<std::shared_ptr<Packet>>> layerList_; | ||||
| }; | ||||
| 
 | ||||
| ProductSymbologyBlock::ProductSymbologyBlock() : | ||||
|  | @ -102,25 +105,56 @@ bool ProductSymbologyBlock::Parse(std::istream& is) | |||
|    { | ||||
|       int16_t  layerDivider; | ||||
|       uint32_t lengthOfDataLayer; | ||||
|       uint16_t packetCode; | ||||
|       uint32_t bytesRead = 0; | ||||
| 
 | ||||
|       for (uint16_t i = 0; i < p->numberOfLayers_; i++) | ||||
|       { | ||||
|          std::vector<std::shared_ptr<Packet>> packetList; | ||||
| 
 | ||||
|          is.read(reinterpret_cast<char*>(&layerDivider), 2); | ||||
|          is.read(reinterpret_cast<char*>(&lengthOfDataLayer), 4); | ||||
| 
 | ||||
|          layerDivider      = ntohs(layerDivider); | ||||
|          lengthOfDataLayer = ntohl(lengthOfDataLayer); | ||||
| 
 | ||||
|          is.read(reinterpret_cast<char*>(&packetCode), 2); | ||||
|          packetCode = ntohs(packetCode); | ||||
|          is.seekg(-2, std::ios_base::cur); | ||||
|          std::streampos layerStart = is.tellg(); | ||||
|          std::streampos layerEnd = | ||||
|             layerStart + static_cast<std::streamoff>(lengthOfDataLayer); | ||||
| 
 | ||||
|          BOOST_LOG_TRIVIAL(debug) | ||||
|             << logPrefix_ << "Reading packet: " << packetCode; | ||||
|          while (bytesRead < lengthOfDataLayer) | ||||
|          { | ||||
|             std::shared_ptr<Packet> packet = PacketFactory::Create(is); | ||||
|             if (packet != nullptr) | ||||
|             { | ||||
|                packetList.push_back(packet); | ||||
|                bytesRead += static_cast<uint32_t>(packet->data_size()); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                break; | ||||
|             } | ||||
|          } | ||||
| 
 | ||||
|          // TODO: Read packets
 | ||||
|          is.seekg(lengthOfDataLayer, std::ios_base::cur); | ||||
|          if (bytesRead < lengthOfDataLayer) | ||||
|          { | ||||
|             BOOST_LOG_TRIVIAL(trace) | ||||
|                << logPrefix_ | ||||
|                << "Layer bytes read smaller than size: " << bytesRead << " < " | ||||
|                << lengthOfDataLayer << " bytes"; | ||||
|             blockValid = false; | ||||
|             is.seekg(layerEnd, std::ios_base::beg); | ||||
|          } | ||||
|          if (bytesRead > lengthOfDataLayer) | ||||
|          { | ||||
|             BOOST_LOG_TRIVIAL(warning) | ||||
|                << logPrefix_ | ||||
|                << "Layer bytes read larger than size: " << bytesRead << " > " | ||||
|                << lengthOfDataLayer << " bytes"; | ||||
|             blockValid = false; | ||||
|             is.seekg(layerEnd, std::ios_base::beg); | ||||
|          } | ||||
| 
 | ||||
|          p->layerList_.push_back(std::move(packetList)); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat