summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2010-11-30 23:44:26 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2010-11-30 23:44:26 +0100
commitbf3b20f58d400c3961ce4d162cf314ff3ed4895e (patch)
tree939511ef19f27cf73143c18e619d2fb333d5af49
parent0599d5beb9d6d37394441fec55a592767a143be0 (diff)
Simplified Message API. All messages are now serialized by Boost.Serialize.
-rw-r--r--common/connectionbase.cpp184
-rw-r--r--common/message.cpp148
-rw-r--r--common/message.h113
3 files changed, 189 insertions, 256 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() {
diff --git a/common/message.cpp b/common/message.cpp
deleted file mode 100644
index 5c5ab50..0000000
--- a/common/message.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "message.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>
-
-Message::Base::Base(Type t) : type(t) {
-
-}
-
-Message::NullBase::NullBase(Type t) : Base(t) {
-
-}
-
-std::pair<uint8_t*, std::size_t> Message::NullBase::serialize() {
- return std::pair<uint8_t*, std::size_t>(0, 0);
-}
-
-void Message::NullBase::deserialize(uint8_t* data, std::size_t bytes) {
-
-}
-
-template<class Sub>
-Message::BoostBase<Sub>::BoostBase(Type t) : Base(t) {
-
-}
-
-template<class Sub>
-std::pair<uint8_t*, std::size_t> Message::BoostBase<Sub>::serialize() {
- std::ostringstream os;
- boost::archive::binary_oarchive oa(os);
-
- oa & *this;
-
- std::size_t s = os.str().size();
- uint8_t* buf = new uint8_t[s];
-
- memcpy(buf, os.str().c_str(), s);
-
- return std::pair<uint8_t*, std::size_t>(buf, s);
-}
-
-template<class Sub>
-void Message::BoostBase<Sub>::deserialize(uint8_t* data, std::size_t bytes) {
- std::istringstream is(std::string((char*)data, bytes));
- boost::archive::binary_iarchive ia(is);
-
- ia & *this;
-}
-
-Message::Hello::Hello() : Base(Types::Hello) {
-
-}
-
-Message::Hello::Hello(const std::string& v) : Base(Types::Hello), version(v) {
-
-}
-
-std::pair<uint8_t*, std::size_t> Message::Hello::serialize() {
- std::size_t s = version.size();
- uint8_t* buf = new uint8_t[s];
-
- memcpy(buf, version.c_str(), version.size());
-
- return std::pair<uint8_t*, std::size_t>(buf, s);
-}
-
-void Message::Hello::deserialize(uint8_t* data, std::size_t bytes) {
- version = std::string((char*)data, bytes);
-}
-
-Message::Login::Login() : Base(Types::Login) {
-
-}
-
-Message::Login::Login(const std::string& n) : Base(Types::Login), nick(n) {
-
-}
-
-std::pair<uint8_t*, std::size_t> Message::Login::serialize() {
- std::size_t s = nick.size();
- uint8_t* buf = new uint8_t[s];
-
- memcpy(buf, nick.c_str(), nick.size());
-
- return std::pair<uint8_t*, std::size_t>(buf, s);
-}
-
-void Message::Login::deserialize(uint8_t* data, std::size_t bytes) {
- nick = std::string((char*)data, bytes);
-}
-
-Message::LoginResponse::LoginResponse() : Base(Types::LoginResponse) {
-
-}
-
-Message::LoginResponse::LoginResponse(bool ok) : Base(Types::LoginResponse), login_ok(ok) {
-
-}
-
-std::pair<uint8_t*, std::size_t> Message::LoginResponse::serialize() {
- uint8_t* buf = new uint8_t[1];
-
- buf[0] = uint8_t(login_ok);
-
- return std::pair<uint8_t*, std::size_t>(buf, 1);
-}
-
-void Message::LoginResponse::deserialize(uint8_t* data, std::size_t bytes) {
- login_ok = bool(data[0]);
-}
-
-Message::GameStart::GameStart() : BoostBase<GameStart>(Types::GameStart) {
-
-}
-
-Message::Ready::Ready() : NullBase(Types::Ready) {
-
-}
-
-Message::RoundStart::RoundStart() : NullBase(Types::RoundStart) {
-
-}
-
-Message::RoundState::RoundState() : BoostBase<RoundState>(Types::RoundState) {
-
-}
-
-Message::RoundState::RoundState(const Player& pl_d, const Player& pl_r, const Player& pl_u, const Player& pl_l, const Tiles& d, const Actions& a)
- : BoostBase<RoundState>(Types::RoundState), dora(d), possible_actions(a) {
- players[0] = pl_d;
- players[1] = pl_r;
- players[2] = pl_u;
- players[3] = pl_l;
-}
-
-Message::RoundAction::RoundAction() : BoostBase<RoundAction>(Types::RoundAction) {
-
-}
-
-Message::RoundEnd::RoundEnd() : NullBase(Types::RoundEnd) {
-
-}
diff --git a/common/message.h b/common/message.h
index 1c9276d..d2eb5d7 100644
--- a/common/message.h
+++ b/common/message.h
@@ -36,109 +36,96 @@ namespace Message {
class Base {
protected:
- Base(Type t);
+ Base(Type t) : type(t) {}
+ virtual ~Base() {}
public:
const Type type;
-
- virtual std::pair<uint8_t*, std::size_t> serialize() = 0;
- virtual void deserialize(uint8_t* data, std::size_t bytes) = 0;
- };
-
- class NullBase : public Base {
- protected:
- NullBase(Type t);
-
- public:
- virtual std::pair<uint8_t*, std::size_t> serialize();
- virtual void deserialize(uint8_t* data, std::size_t bytes);
- };
-
- template<class Sub>
- class BoostBase : public Base {
- protected:
- BoostBase(Type t);
-
- public:
- virtual std::pair<uint8_t*, std::size_t> serialize();
- virtual void deserialize(uint8_t* data, std::size_t bytes);
-
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version) {
- ar & dynamic_cast<Sub&>(*this);
- }
};
class Hello : public Base {
public:
typedef boost::shared_ptr<Hello> p;
- Hello();
- Hello(const std::string& v);
+ Hello(const std::string& v = "") : Base(Types::Hello), version(v) {}
std::string version;
- virtual std::pair<uint8_t*, std::size_t> serialize();
- virtual void deserialize(uint8_t* data, std::size_t bytes);
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int v) {
+ ar & version;
+ }
};
class Login : public Base {
public:
typedef boost::shared_ptr<Login> p;
- Login();
- Login(const std::string& n);
+ Login(const std::string& n = "") : Base(Types::Login), nick(n) {}
std::string nick;
- virtual std::pair<uint8_t*, std::size_t> serialize();
- virtual void deserialize(uint8_t* data, std::size_t bytes);
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int v) {
+ ar & nick;
+ }
};
class LoginResponse : public Base {
public:
typedef boost::shared_ptr<LoginResponse> p;
- LoginResponse();
- LoginResponse(bool ok);
+ LoginResponse(bool ok = false) : Base(Types::LoginResponse), login_ok(ok) {}
bool login_ok;
- virtual std::pair<uint8_t*, std::size_t> serialize();
- virtual void deserialize(uint8_t* data, std::size_t bytes);
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int v) {
+ ar & login_ok;
+ }
};
- class GameStart : public BoostBase<GameStart> {
+ class GameStart : public Base {
public:
typedef boost::shared_ptr<GameStart> p;
- GameStart();
+ GameStart() : Base(Types::GameStart) {}
std::vector<std::string> players;
int player_id;
template<class Archive>
- void serialize(Archive & ar, const unsigned int version) {
+ void serialize(Archive & ar, const unsigned int v) {
ar & players;
ar & player_id;
}
};
- class Ready : public NullBase {
+ class Ready : public Base {
public:
typedef boost::shared_ptr<Ready> p;
- Ready();
+ Ready() : Base(Types::Ready) {}
+
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int v) {
+
+ }
};
- class RoundStart : public NullBase {
+ class RoundStart : public Base {
public:
typedef boost::shared_ptr<RoundStart> p;
- RoundStart();
+ RoundStart() : Base(Types::RoundStart) {}
+
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int v) {
+
+ }
};
- class RoundState : public BoostBase<RoundState> {
+ class RoundState : public Base {
public:
typedef boost::shared_ptr<RoundState> p;
@@ -152,15 +139,21 @@ namespace Message {
Tiles pond;
template<class Archive>
- void serialize(Archive & ar, const unsigned int version) {
+ void serialize(Archive & ar, const unsigned int v) {
ar & hand;
ar & open;
ar & pond;
}
};
- RoundState();
- RoundState(const Player& pl_d, const Player& pl_r, const Player& pl_u, const Player& pl_l, const Tiles& d, const Actions& a);
+ RoundState() : Base(Types::RoundState) {}
+ RoundState(const Player& pl_d, const Player& pl_r, const Player& pl_u, const Player& pl_l, const Tiles& d, const Actions& a)
+ : Base(Types::RoundState), dora(d), possible_actions(a) {
+ players[0] = pl_d;
+ players[1] = pl_r;
+ players[2] = pl_u;
+ players[3] = pl_l;
+ }
Player players[4];
@@ -169,33 +162,39 @@ namespace Message {
Actions possible_actions;
template<class Archive>
- void serialize(Archive & ar, const unsigned int version) {
+ void serialize(Archive & ar, const unsigned int v) {
ar & players;
ar & dora;
ar & possible_actions;
}
};
- class RoundAction : public BoostBase<RoundAction> {
+ class RoundAction : public Base {
public:
typedef boost::shared_ptr<RoundAction> p;
- RoundAction();
+ RoundAction() : Base(Types::RoundAction) {}
Action action;
template<class Archive>
- void serialize(Archive & ar, const unsigned int version) {
+ void serialize(Archive & ar, const unsigned int v) {
ar & action;
}
};
- class RoundEnd : public NullBase {
+ class RoundEnd : public Base {
public:
typedef boost::shared_ptr<RoundEnd> p;
- RoundEnd();
+ RoundEnd() : Base(Types::RoundEnd) {}
+
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int v) {
+
+ }
};
+
typedef boost::shared_ptr<Base> p;
};