• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

RealmProtocol.h

Go to the documentation of this file.
00001 #ifndef __REALM_PROTOCOL__
00002 #define __REALM_PROTOCOL__
00003 
00004 #include <string>
00005 #include <vector>
00006 #ifdef _MSC_VER
00007 #include "msc_stdint.h"
00008 #else
00009 #include <stdint.h>
00010 #endif
00011 #include <boost/shared_ptr.hpp>
00012 #include <asio.hpp>
00013 
00014 namespace realm {
00015 
00016 namespace protocol {
00017 
00018 enum handshake_response {
00019     HANDSHAKE_RESERVED = 0,             /* 0x00: reserved */
00020     HANDSHAKE_OK,                       /* 0x01: Login OK */
00021     HANDSHAKE_BAD_IDENTIFIER,           /* 0x02: Unrecognized protocol magic */
00022     HANDSHAKE_UNSUPPORTED_PROTOCOL,     /* 0x03: Unsupported protocol version */
00023     HANDSHAKE_INVALID_COOKIE            /* 0x04: Invalid cookie */
00024 };
00025 
00026 }
00027 
00028 namespace protocolv1 {
00029 
00030 class Packet;
00031 typedef boost::shared_ptr<Packet> PacketPtr;
00032 typedef boost::shared_ptr<asio::streambuf> StreamPtr;
00033 
00034 // the packet type values must match up the corresponding body_size in
00035 // RealmProtocol.cpp (ugly, but it's fast)!
00036 enum packet_type {
00037     PACKET_RESERVED = 0x00,
00038     PACKET_ROUTE, // 0x01
00039     PACKET_DELIVER, // 0x02
00040     PACKET_USERJOINED, // 0x03
00041     PACKET_USERLEFT, // 0x04
00042     PACKET_SESSIONTAKEOVER, // 0x05
00043     __LAST_PACKET__
00044 };
00045 
00046 class Packet {
00047 public:
00048     virtual ~Packet() {}
00049 
00050     static PacketPtr construct(uint8_t type);
00051 
00052     static bool s_valid(unsigned char type);
00053     static uint32_t s_body_size(unsigned char type);
00054 
00055     // Should be overwritten when the packet size is variable
00056     // Returns: the minimal number of bytes additionally needed before we can
00057     // re-assess if the packet is complete or not; -1 on error.
00058     // Note that this several complete() calls on the same buffer may return
00059     // several times with a value > 0. Only when complete() returns 0 the
00060     // buffer contains enough information to call parse().
00061     virtual int complete(const char* buf, size_t size);
00062 
00063     // should be overwritten when the packet 'has a body'
00064     // returns: the number of bytes read, -1 on error
00065     virtual int parse(const char* /*buf*/, size_t /*size*/) {
00066         return 0;
00067     }
00068 
00069     const uint8_t & type() const {
00070         return m_type;
00071     }
00072 
00073 protected:
00074     Packet(uint8_t type);
00075 
00076 private:
00077     uint8_t m_type;
00078 };
00079 
00080 class PayloadPacket : public Packet {
00081 public:
00082     virtual int complete(const char* buf, size_t size);
00083     virtual int parse(const char* buf, size_t size);
00084 
00085     const uint32_t& getPayloadSize() const {
00086         return m_payload_size;
00087     }
00088 protected:
00089     PayloadPacket(uint8_t t, uint32_t min_payload_size, uint32_t payload_size)
00090         : Packet(t),
00091         m_min_payload_size(min_payload_size),
00092         m_payload_size(payload_size)
00093     {}
00094     PayloadPacket(uint8_t t, uint32_t min_payload_size)
00095         : Packet(t),
00096         m_min_payload_size(min_payload_size),
00097         m_payload_size(0)
00098     {}
00099 private:
00100     uint32_t m_min_payload_size;
00101     uint32_t m_payload_size;
00102 };
00103 
00104 class RoutingPacket : public PayloadPacket {
00105 public:
00106     RoutingPacket();
00107     RoutingPacket(std::vector<uint8_t>& connection_ids, boost::shared_ptr<std::string> msg);
00108     virtual int parse(const char* buf, size_t size);
00109 
00110     const uint8_t& getAddressCount() const {
00111         return m_address_count;
00112     }
00113 
00114     const std::vector<uint8_t>& getConnectionIds() const {
00115         return m_connection_ids;
00116     }
00117 
00118     boost::shared_ptr<std::string> getMessage() const {
00119         return m_msg;
00120     }
00121 
00122 private:
00123     uint8_t                 m_address_count;    // a bit redundant (as it can be derived from m_connection_ids.size()),
00124                                                 // but it's convenient to be able to get a reference to this value
00125                                                 // when sending this packet
00126     std::vector<uint8_t>    m_connection_ids;
00127     boost::shared_ptr<std::string> m_msg;
00128 };
00129 
00130 class DeliverPacket : public PayloadPacket {
00131 public:
00132     DeliverPacket();
00133     DeliverPacket(uint8_t connection_id, boost::shared_ptr<std::string> msg);
00134     virtual int parse(const char* buf, size_t size);
00135 
00136     const uint8_t& getConnectionId() const {
00137         return m_connection_id;
00138     }
00139 
00140     boost::shared_ptr<std::string> getMessage() const {
00141         return m_msg;
00142     }
00143 
00144 private:
00145     uint8_t         m_connection_id;
00146     boost::shared_ptr<std::string>  m_msg;
00147 };
00148 
00149 class UserJoinedPacket : public PayloadPacket {
00150 public:
00151     UserJoinedPacket();
00152     UserJoinedPacket(uint8_t connection_id, bool master, boost::shared_ptr<std::string> userinfo);
00153     virtual int parse(const char* buf, size_t size);
00154 
00155     const uint8_t& getConnectionId() const {
00156         return m_connection_id;
00157     }
00158 
00159     const uint8_t& isMaster() const {
00160         return m_master;
00161     }
00162 
00163     boost::shared_ptr<std::string> getUserInfo() const {
00164         return m_userinfo;
00165     }
00166 
00167 private:
00168     uint8_t         m_connection_id;
00169     uint8_t         m_master;
00170     boost::shared_ptr<std::string>      m_userinfo;
00171 };
00172 
00173 class UserLeftPacket : public Packet {
00174 public:
00175     UserLeftPacket();
00176     UserLeftPacket(uint8_t connection_id);
00177     virtual int parse(const char* buf, size_t size);
00178 
00179     const uint8_t& getConnectionId() const {
00180         return m_connection_id;
00181     }
00182 
00183 private:
00184     uint8_t m_connection_id;
00185 };
00186 
00187 class SessionTakeOverPacket : public Packet {
00188 public:
00189     SessionTakeOverPacket();
00190 };
00191 
00192 }
00193 }
00194 
00195 #endif /* __REALM_PROTOCOL__ */

Generated on Wed Jun 19 2013 for AbiWord by  doxygen 1.7.1