#pragma once #include namespace sp { namespace io { template Stream::Stream(IOInterface&& a_Interface) : m_Interface(std::move(a_Interface)) {} template Stream::Stream(Stream&& a_Stream) : m_Dispatcher(std::move(a_Stream.m_Dispatcher)), m_Interface(std::move(a_Stream.m_Interface)) {} template void Stream::SendMessage(const MessageBase& a_Message) { // TODO: process compress + encryption DataBuffer data = a_Message.Write(); DataBuffer dataSize; m_Interface.Write(dataSize << sp::VarInt{data.GetSize()} << data); } template void Stream::RecieveMessages() { // TODO: process compress + encryption while (true) { // reading the first VarInt part byte by byte std::uint64_t lenghtValue = 0; unsigned int readPos = 0; while (true) { static constexpr int SEGMENT_BITS = (1 << 7) - 1; static constexpr int CONTINUE_BIT = 1 << 7; DataBuffer buffer = m_Interface.Read(sizeof(std::uint8_t)); // eof if (buffer.GetSize() == 0) return; std::uint8_t part; buffer >> part; lenghtValue |= static_cast(part & SEGMENT_BITS) << readPos; if ((part & CONTINUE_BIT) == 0) break; readPos += 7; if (readPos >= 8 * sizeof(lenghtValue)) throw std::runtime_error("VarInt is too big"); } // nothing to read if (lenghtValue == 0) return; DataBuffer buffer; buffer = m_Interface.Read(lenghtValue); // TODO: process compress + encryption MsgIdType packetType; buffer >> packetType; static const MessageFactory messageFactory; std::unique_ptr message = messageFactory.CreateMessage(packetType); assert(message != nullptr); message->Read(buffer); GetDispatcher().Dispatch(*message); } } } // namespace io } // namespace sp