summaryrefslogtreecommitdiff
path: root/common/connectionbase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/connectionbase.cpp')
-rw-r--r--common/connectionbase.cpp184
1 files changed, 133 insertions, 51 deletions
diff --git a/common/connectionbase.cpp b/common/connectionbase.cpp
index a113e6a..75a9a9a 100644
--- a/common/connectionbase.cpp
+++ b/common/connectionbase.cpp
@@ -1,6 +1,15 @@
#include "connectionbase.h"
+#include <boost/serialization/vector.hpp>
+#include <boost/serialization/string.hpp>
+#include <boost/serialization/shared_ptr.hpp>
+#include <boost/archive/binary_oarchive.hpp>
+#include <boost/archive/binary_iarchive.hpp>
+
+#include <cstring>
+#include <sstream>
#include <exception>
+#include <stdexcept>
#include <iostream>
@@ -35,73 +44,146 @@ void ConnectionBase::got_data(uint8_t* data, std::size_t bytes) {
pending_size = 0;
- Message::p m;
+ try {
+ // Create Boost.Serialization archive of data.
+ std::istringstream is(std::string((char*)data, bytes));
+ boost::archive::binary_iarchive ia(is);
+
+ switch(pending_type) {
+ case Message::Types::Hello: {
+ Message::Hello::p m = make_shared<Message::Hello>();
+ ia & m;
+ got_message(m);
+ } break;
+
+ case Message::Types::Login: {
+ Message::Login::p m = make_shared<Message::Login>();
+ ia & m;
+ got_message(m);
+ } break;
+
+ case Message::Types::LoginResponse: {
+ Message::LoginResponse::p m = make_shared<Message::LoginResponse>();
+ ia & m;
+ got_message(m);
+ } break;
+
+ case Message::Types::GameStart: {
+ Message::GameStart::p m = make_shared<Message::GameStart>();
+ ia & m;
+ got_message(m);
+ } break;
+
+ case Message::Types::Ready: {
+ Message::Ready::p m = make_shared<Message::Ready>();
+ ia & m;
+ got_message(m);
+ } break;
+
+ case Message::Types::RoundStart: {
+ Message::RoundStart::p m = make_shared<Message::RoundStart>();
+ ia & m;
+ got_message(m);
+ } break;
+
+ case Message::Types::RoundState: {
+ Message::RoundState::p m = make_shared<Message::RoundState>();
+ ia & m;
+ got_message(m);
+ } break;
+
+ case Message::Types::RoundAction: {
+ Message::RoundAction::p m = make_shared<Message::RoundAction>();
+ ia & m;
+ got_message(m);
+ } break;
+
+ case Message::Types::RoundEnd: {
+ Message::RoundEnd::p m = make_shared<Message::RoundEnd>();
+ ia & m;
+ got_message(m);
+ } break;
+
+ default:
+ throw std::runtime_error("Deserialization attempted on unknown message type.");
+ }
+
+ } catch(std::exception& e) {
+ error(std::string("Deserialization failed: ") + e.what());
+ }
+}
+
+void ConnectionBase::send(const Message::p& msg) {
+ // Create Boost.Serialization archive.
+ std::ostringstream os;
+ boost::archive::binary_oarchive oa(os);
- switch(pending_type) {
- case Message::Types::Hello:
- m = make_shared<Message::Hello>();
- break;
+ switch(msg->type) {
+ case Message::Types::Hello: {
+ Message::Hello::p m = dynamic_pointer_cast<Message::Hello>(msg);
+ oa & m;
+ } break;
- case Message::Types::Login:
- m = make_shared<Message::Login>();
- break;
+ case Message::Types::Login: {
+ Message::Login::p m = dynamic_pointer_cast<Message::Login>(msg);
+ oa & m;
+ } break;
- case Message::Types::LoginResponse:
- m = make_shared<Message::LoginResponse>();
- break;
+ case Message::Types::LoginResponse: {
+ Message::LoginResponse::p m = dynamic_pointer_cast<Message::LoginResponse>(msg);
+ oa & m;
+ } break;
- case Message::Types::GameStart:
- m = make_shared<Message::GameStart>();
- break;
+ case Message::Types::GameStart: {
+ Message::GameStart::p m = dynamic_pointer_cast<Message::GameStart>(msg);
+ oa & m;
+ } break;
- case Message::Types::Ready:
- m = make_shared<Message::Ready>();
- break;
+ case Message::Types::Ready: {
+ Message::Ready::p m = dynamic_pointer_cast<Message::Ready>(msg);
+ oa & m;
+ } break;
- case Message::Types::RoundStart:
- m = make_shared<Message::RoundStart>();
- break;
+ case Message::Types::RoundStart: {
+ Message::RoundStart::p m = dynamic_pointer_cast<Message::RoundStart>(msg);
+ oa & m;
+ } break;
- case Message::Types::RoundState:
- m = make_shared<Message::RoundState>();
- break;
+ case Message::Types::RoundState: {
+ Message::RoundState::p m = dynamic_pointer_cast<Message::RoundState>(msg);
+ oa & m;
+ } break;
- case Message::Types::RoundAction:
- m = make_shared<Message::RoundAction>();
- break;
-
- case Message::Types::RoundEnd:
- m = make_shared<Message::RoundEnd>();
- break;
+ case Message::Types::RoundAction: {
+ Message::RoundAction::p m = dynamic_pointer_cast<Message::RoundAction>(msg);
+ oa & m;
+ } break;
- default:
- error("Deserialization attempted on unknown message type.");
- }
-
- if(bytes) {
- try {
- m->deserialize(data, bytes);
+ case Message::Types::RoundEnd: {
+ Message::RoundEnd::p m = dynamic_pointer_cast<Message::RoundEnd>(msg);
+ oa & m;
+ } break;
- } catch(std::exception& e) {
- error(std::string("Deserialization failed: ") + e.what());
- }
+ default:
+ throw std::runtime_error("Serialization attempted on unknown message type.");
}
- got_message(m);
-}
-
-void ConnectionBase::send(const Message::p& msg) {
- uint16_t* header = new uint16_t[2];
+ // Extract data.
+ std::string s = os.str();
- std::pair<uint8_t*, std::size_t> smsg = msg->serialize();
+ // Allocate buffer.
+ uint8_t* buf = new uint8_t[4 + s.size()];
+ // Write header.
+ uint16_t* header = (uint16_t*)buf;
header[0] = uint16_t(msg->type);
- header[1] = uint16_t(smsg.second);
+ header[1] = uint16_t(s.size());
- write_data((uint8_t*)header, 4);
- if(smsg.second) {
- write_data(smsg.first, smsg.second);
- }
+ // Copy data.
+ memcpy(buf + 4, s.c_str(), s.size());
+
+ // Send buffer.
+ write_data(buf, 4 + s.size());
}
ConnectionBase::ConnectionBase() {