#pragma once #include #include #include #include #include #ifdef WIN32 # include #else # include #endif namespace scwx { namespace wsr88d { class MessageImpl; class Message { protected: explicit Message(); Message(const Message&) = delete; Message& operator=(const Message&) = delete; Message(Message&&) noexcept; Message& operator=(Message&&) noexcept; virtual bool ValidateMessage(std::istream& is, size_t bytesRead) const = 0; public: virtual ~Message(); virtual bool Parse(std::istream& is) = 0; static void ReadBoolean(std::istream& is, bool& value) { std::string data(4, ' '); is.read(reinterpret_cast(&data[0]), 4); value = (data.at(0) == 'T'); } static void ReadChar(std::istream& is, char& value) { std::string data(4, ' '); is.read(reinterpret_cast(&data[0]), 4); value = data.at(0); } static float SwapFloat(float f) { return ntohf(*reinterpret_cast(&f)); } template static void SwapArray(std::array& arr, size_t size = _Size) { std::transform(std::execution::par_unseq, arr.begin(), arr.begin() + size, arr.begin(), [](float f) { return SwapFloat(f); }); } template static void SwapArray(std::array& arr, size_t size = _Size) { std::transform(std::execution::par_unseq, arr.begin(), arr.begin() + size, arr.begin(), [](uint16_t u) { return ntohs(u); }); } template static void SwapArray(std::array& arr, size_t size = _Size) { std::transform(std::execution::par_unseq, arr.begin(), arr.begin() + size, arr.begin(), [](uint32_t u) { return ntohl(u); }); } template static void SwapMap(std::map& m) { std::for_each(std::execution::par_unseq, m.begin(), m.end(), [](auto& p) { p.second = SwapFloat(p.second); }); } static void SwapVector(std::vector& v) { std::transform(std::execution::par_unseq, v.begin(), v.end(), v.begin(), [](uint16_t u) { return ntohs(u); }); } private: std::unique_ptr p; }; } // namespace wsr88d } // namespace scwx