#include "connectionbase.h" #include #include void ConnectionBase::start_recv() { request_data(4); } void ConnectionBase::got_data(uint8_t* data, std::size_t bytes) { if(pending_size == 0) { if(bytes != 4) { throw std::runtime_error("Deserialization header error."); } uint16_t* header = (uint16_t*)data; pending_type = (Message::Type)header[0]; pending_size = (std::size_t)header[1]; if(pending_size) { request_data(pending_size); return; } bytes = 0; } if(bytes != pending_size) { std::cout << "Bytes: " << bytes << " Pending size: " << pending_size << std::endl; throw std::runtime_error("Deserialization attempted with incomplete data."); // TODO: Calling got_data() with incomplete data should be allowed. } pending_size = 0; Message::p m; switch(pending_type) { case Message::Types::Hello: m = make_shared(); break; case Message::Types::Login: m = make_shared(); break; case Message::Types::LoginResponse: m = make_shared(); break; case Message::Types::GameStart: m = make_shared(); break; case Message::Types::Ready: m = make_shared(); break; case Message::Types::RoundStart: m = make_shared(); break; case Message::Types::RoundState: m = make_shared(); break; case Message::Types::RoundAction: m = make_shared(); break; case Message::Types::RoundEnd: m = make_shared(); break; default: throw std::runtime_error("Deserialization attempted on unknown message type."); } if(bytes) { m->deserialize(data, bytes); } got_message(m); } void ConnectionBase::send(const Message::p& msg) { uint16_t* header = new uint16_t[2]; std::pair smsg = msg->serialize(); header[0] = uint16_t(msg->type); header[1] = uint16_t(smsg.second); write_data((uint8_t*)header, 4); if(smsg.second) { write_data(smsg.first, smsg.second); } } ConnectionBase::ConnectionBase() { pending_size = 0; } ConnectionBase::~ConnectionBase() { std::cout << "Connection destroyed." << std::endl; }