1 #ifndef MSP_NET_PROTOCOL_H_
2 #define MSP_NET_PROTOCOL_H_
12 class bad_packet: public std::runtime_error
15 bad_packet(const std::string &w): std::runtime_error(w) { }
16 virtual ~bad_packet() throw() { }
20 class buffer_error: public std::runtime_error
23 buffer_error(const std::string &w): std::runtime_error(w) { }
24 virtual ~buffer_error() throw() { }
36 PacketDefBase(unsigned i): id(i) { }
38 virtual ~PacketDefBase() { }
39 virtual unsigned get_class_id() const = 0;
40 unsigned get_id() const { return id; }
41 virtual const char *disassemble(ReceiverBase &, const char *, const char *) const = 0;
43 static unsigned next_class_id;
52 virtual ~FieldBase() { }
53 virtual char *assemble(const P &, char *, char *) const = 0;
54 virtual const char *disassemble(P &, const char *, const char *) const = 0;
57 template<typename P, typename T>
58 class Field: public FieldBase<P>
64 Field(T P::*p): ptr(p) { }
66 virtual char *assemble(const P &p, char *d, char *e) const
67 { return assemble_field(p.*ptr, d, e); }
69 virtual const char *disassemble(P &p, const char *d, const char *e) const
70 { return disassemble_field(p.*ptr, d, e); }
75 class PacketDef: public PacketDefBase
78 std::vector<FieldBase<P> *> fields;
81 PacketDef(unsigned i): PacketDefBase(i)
82 { if(!class_id) class_id = next_class_id++; }
86 for(typename std::vector<FieldBase<P> *>::const_iterator i=fields.begin(); i!=fields.end(); ++i)
90 virtual unsigned get_class_id() const { return class_id; }
93 PacketDef &operator()(T P::*p)
94 { fields.push_back(new Field<P, T>(p)); return *this; }
96 char *assemble(const P &p, char *d, char *e) const
98 for(typename std::vector<FieldBase<P> *>::const_iterator i=fields.begin(); i!=fields.end(); ++i)
99 d = (*i)->assemble(p, d, e);
103 const char *disassemble(ReceiverBase &r, const char *d, const char *e) const
105 PacketReceiver<P> *prcv = dynamic_cast<PacketReceiver<P> *>(&r);
107 throw bad_packet("unsupported");
109 for(typename std::vector<FieldBase<P> *>::const_iterator i=fields.begin(); i!=fields.end(); ++i)
110 d = (*i)->disassemble(pkt, d, e);
115 static unsigned class_id;
118 typedef std::map<unsigned, PacketDefBase *> PacketMap;
120 unsigned next_packet_id;
121 PacketMap packet_class_defs;
122 PacketMap packet_id_defs;
124 Protocol(unsigned = 1);
129 void add_packet(PacketDefBase &);
135 PacketDef<P> *pdef = new PacketDef<P>(next_packet_id++);
140 const PacketDefBase &get_packet_by_class(unsigned) const;
141 const PacketDefBase &get_packet_by_id(unsigned) const;
145 unsigned assemble(const P &pkt, char *buf, unsigned size) const
147 unsigned id = PacketDef<P>::class_id;
148 const PacketDef<P> &pdef = static_cast<const PacketDef<P> &>(get_packet_by_class(id));
149 char *ptr = pdef.assemble(pkt, buf+4, buf+size);
150 assemble_header(buf, pdef.get_id(), (size = ptr-buf));
154 unsigned disassemble(ReceiverBase &, const char *, unsigned) const;
156 unsigned get_packet_size(const char *, unsigned) const;
158 unsigned get_hash() const;
161 static void assemble_header(char *, unsigned, unsigned);
164 static char *assemble_field(const T &, char *, char *);
167 static const char *disassemble_field(T &, const char *, const char *);
171 unsigned Protocol::PacketDef<P>::class_id = 0;