mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 06:20:06 +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_ {} {}; |        tabularBlock_ {} {}; | ||||||
|    ~Level3FileImpl() = default; |    ~Level3FileImpl() = default; | ||||||
| 
 | 
 | ||||||
|    void LoadBlocks(std::istream& is); |    bool LoadBlocks(std::istream& is); | ||||||
| 
 | 
 | ||||||
|    rpg::WmoHeader               wmoHeader_; |    rpg::WmoHeader               wmoHeader_; | ||||||
|    rpg::Level3MessageHeader     messageHeader_; |    rpg::Level3MessageHeader     messageHeader_; | ||||||
|  | @ -123,7 +123,7 @@ bool Level3File::LoadData(std::istream& is) | ||||||
|                << logPrefix_ << "Decompressed data size = " << bytesCopied |                << logPrefix_ << "Decompressed data size = " << bytesCopied | ||||||
|                << " bytes"; |                << " bytes"; | ||||||
| 
 | 
 | ||||||
|             p->LoadBlocks(ss); |             dataValid = p->LoadBlocks(ss); | ||||||
|          } |          } | ||||||
|          catch (const boost::iostreams::bzip2_error& ex) |          catch (const boost::iostreams::bzip2_error& ex) | ||||||
|          { |          { | ||||||
|  | @ -136,15 +136,19 @@ bool Level3File::LoadData(std::istream& is) | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          p->LoadBlocks(is); |          dataValid = p->LoadBlocks(is); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return dataValid; |    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"; |    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Loading Blocks"; | ||||||
| 
 | 
 | ||||||
|    std::streampos offsetBasePos = is.tellg(); |    std::streampos offsetBasePos = is.tellg(); | ||||||
|  | @ -159,8 +163,6 @@ void Level3FileImpl::LoadBlocks(std::istream& is) | ||||||
| 
 | 
 | ||||||
|    if (offsetToSymbology >= offsetBase) |    if (offsetToSymbology >= offsetBase) | ||||||
|    { |    { | ||||||
|       bool symbologyValid; |  | ||||||
| 
 |  | ||||||
|       symbologyBlock_ = std::make_shared<rpg::ProductSymbologyBlock>(); |       symbologyBlock_ = std::make_shared<rpg::ProductSymbologyBlock>(); | ||||||
| 
 | 
 | ||||||
|       is.seekg(offsetToSymbology - offsetBase, std::ios_base::cur); |       is.seekg(offsetToSymbology - offsetBase, std::ios_base::cur); | ||||||
|  | @ -197,6 +199,8 @@ void Level3FileImpl::LoadBlocks(std::istream& is) | ||||||
|          << logPrefix_ |          << logPrefix_ | ||||||
|          << "Tabular alphanumeric block found: " << offsetToTabular; |          << "Tabular alphanumeric block found: " << offsetToTabular; | ||||||
|    } |    } | ||||||
|  | 
 | ||||||
|  |    return (symbologyValid && graphicValid && tabularValid); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace wsr88d
 | } // 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/product_symbology_block.hpp> | ||||||
|  | #include <scwx/wsr88d/rpg/packet_factory.hpp> | ||||||
| 
 | 
 | ||||||
| #include <istream> | #include <istream> | ||||||
| #include <string> | #include <string> | ||||||
|  | @ -26,6 +27,8 @@ public: | ||||||
|    int16_t  blockId_; |    int16_t  blockId_; | ||||||
|    uint32_t lengthOfBlock_; |    uint32_t lengthOfBlock_; | ||||||
|    uint16_t numberOfLayers_; |    uint16_t numberOfLayers_; | ||||||
|  | 
 | ||||||
|  |    std::vector<std::vector<std::shared_ptr<Packet>>> layerList_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ProductSymbologyBlock::ProductSymbologyBlock() : | ProductSymbologyBlock::ProductSymbologyBlock() : | ||||||
|  | @ -102,25 +105,56 @@ bool ProductSymbologyBlock::Parse(std::istream& is) | ||||||
|    { |    { | ||||||
|       int16_t  layerDivider; |       int16_t  layerDivider; | ||||||
|       uint32_t lengthOfDataLayer; |       uint32_t lengthOfDataLayer; | ||||||
|       uint16_t packetCode; |       uint32_t bytesRead = 0; | ||||||
| 
 | 
 | ||||||
|       for (uint16_t i = 0; i < p->numberOfLayers_; i++) |       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*>(&layerDivider), 2); | ||||||
|          is.read(reinterpret_cast<char*>(&lengthOfDataLayer), 4); |          is.read(reinterpret_cast<char*>(&lengthOfDataLayer), 4); | ||||||
| 
 | 
 | ||||||
|          layerDivider      = ntohs(layerDivider); |          layerDivider      = ntohs(layerDivider); | ||||||
|          lengthOfDataLayer = ntohl(lengthOfDataLayer); |          lengthOfDataLayer = ntohl(lengthOfDataLayer); | ||||||
| 
 | 
 | ||||||
|          is.read(reinterpret_cast<char*>(&packetCode), 2); |          std::streampos layerStart = is.tellg(); | ||||||
|          packetCode = ntohs(packetCode); |          std::streampos layerEnd = | ||||||
|          is.seekg(-2, std::ios_base::cur); |             layerStart + static_cast<std::streamoff>(lengthOfDataLayer); | ||||||
| 
 | 
 | ||||||
|          BOOST_LOG_TRIVIAL(debug) |          while (bytesRead < lengthOfDataLayer) | ||||||
|             << logPrefix_ << "Reading packet: " << packetCode; |          { | ||||||
|  |             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
 |          if (bytesRead < lengthOfDataLayer) | ||||||
|          is.seekg(lengthOfDataLayer, std::ios_base::cur); |          { | ||||||
|  |             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