#include <cstring>
#include <string>
+#include <msp/core/maputils.h>
#include <msp/strings/lexicalcast.h>
#include "protocol.h"
namespace {
+using Msp::Net::buffer_error;
+
template<typename T>
class Assembler
{
char *Assembler<T>::assemble(const T &v, char *data, char *end)
{
// XXX Assumes little-endian
- const char *ptr=reinterpret_cast<const char *>(&v)+sizeof(T);
+ const char *ptr = reinterpret_cast<const char *>(&v)+sizeof(T);
for(unsigned i=0; i<sizeof(T); ++i)
{
if(data==end)
- throw Msp::Exception("Out of buffer space");
- *data++=*--ptr;
+ throw buffer_error("overflow");
+ *data++ = *--ptr;
}
return data;
}
template<>
char *Assembler<string>::assemble(const string &v, char *data, char *end)
{
- data=Assembler<unsigned short>::assemble(v.size(), data, end);
+ data = Assembler<unsigned short>::assemble(v.size(), data, end);
if(end-data<static_cast<int>(v.size()))
- throw Msp::Exception("Out of buffer space");
+ throw buffer_error("overflow");
memcpy(data, v.data(), v.size());
return data+v.size();
}
template<typename T>
char *Assembler<vector<T> >::assemble(const vector<T> &v, char *data, char *end)
{
- data=Assembler<unsigned short>::assemble(v.size(), data, end);
+ data = Assembler<unsigned short>::assemble(v.size(), data, end);
for(typename vector<T>::const_iterator i=v.begin(); i!=v.end(); ++i)
- data=Assembler<T>::assemble(*i, data, end);
+ data = Assembler<T>::assemble(*i, data, end);
return data;
}
template<typename T>
const char *Assembler<T>::disassemble(T &v, const char *data, const char *end)
{
- char *ptr=reinterpret_cast<char *>(&v)+sizeof(T);
+ char *ptr = reinterpret_cast<char *>(&v)+sizeof(T);
for(unsigned i=0; i<sizeof(T); ++i)
{
if(data==end)
- throw Msp::Exception("Premature end of data");
- *--ptr=*data++;
+ throw buffer_error("underflow");
+ *--ptr = *data++;
}
return data;
}
const char *Assembler<string>::disassemble(string &v, const char *data, const char *end)
{
unsigned short size;
- data=Assembler<unsigned short>::disassemble(size, data, end);
+ data = Assembler<unsigned short>::disassemble(size, data, end);
if(end-data<size)
- throw Msp::Exception("Premature end of data");
+ throw buffer_error("underflow");
v.assign(data, data+size);
return data+size;
}
only code path leading here is from PacketDef<P>::disassemble, which creates
a new packet. */
unsigned short size;
- data=Assembler<unsigned short>::disassemble(size, data, end);
+ data = Assembler<unsigned short>::disassemble(size, data, end);
for(unsigned i=0; i<size; ++i)
{
T u;
- data=Assembler<T>::disassemble(u, data, end);
+ data = Assembler<T>::disassemble(u, data, end);
v.push_back(u);
}
return data;
void Protocol::add_packet(PacketDefBase &pdef)
{
- PacketDefBase *&ptr=packet_class_defs[pdef.get_class_id()];
+ PacketDefBase *&ptr = packet_class_defs[pdef.get_class_id()];
if(ptr)
delete ptr;
- ptr=&pdef;
- packet_id_defs[pdef.get_id()]=&pdef;
+ ptr = &pdef;
+ packet_id_defs[pdef.get_id()] = &pdef;
}
const Protocol::PacketDefBase &Protocol::get_packet_by_class(unsigned id) const
{
- PacketMap::const_iterator i=packet_class_defs.find(id);
- if(i==packet_class_defs.end())
- throw KeyError("Unknown packet class", lexical_cast(id));
- return *i->second;
+ return *get_item(packet_class_defs, id);
}
const Protocol::PacketDefBase &Protocol::get_packet_by_id(unsigned id) const
{
- PacketMap::const_iterator i=packet_id_defs.find(id);
- if(i==packet_id_defs.end())
- throw KeyError("Unknown packet ID", lexical_cast(id));
- return *i->second;
+ return *get_item(packet_id_defs, id);
}
unsigned Protocol::disassemble(ReceiverBase &rcv, const char *data, unsigned size) const
{
- const unsigned char *udata=reinterpret_cast<const unsigned char *>(data);
- unsigned id=(udata[0]<<8)+udata[1];
- unsigned psz=(udata[2]<<8)+udata[3];
+ const unsigned char *udata = reinterpret_cast<const unsigned char *>(data);
+ unsigned id = (udata[0]<<8)+udata[1];
+ unsigned psz = (udata[2]<<8)+udata[3];
if(psz>size)
- throw InvalidParameterValue("Not enough data for packet");
- const PacketDefBase &pdef=get_packet_by_id(id);
- const char *ptr=pdef.disassemble(rcv, data+4, data+psz);
+ throw bad_packet("truncated");
+ const PacketDefBase &pdef = get_packet_by_id(id);
+ const char *ptr = pdef.disassemble(rcv, data+4, data+psz);
return ptr-data;
}
{
if(size<4)
return 0;
- const unsigned char *udata=reinterpret_cast<const unsigned char *>(data);
+ const unsigned char *udata = reinterpret_cast<const unsigned char *>(data);
return (udata[2]<<8)+udata[3];
}
void Protocol::assemble_header(char *buf, unsigned id, unsigned size)
{
- buf[0]=(id>>8)&0xFF;
- buf[1]=id&0xFF;
- buf[2]=(size>>8)&0xFF;
- buf[3]=size&0xFF;
+ buf[0] = (id>>8)&0xFF;
+ buf[1] = id&0xFF;
+ buf[2] = (size>>8)&0xFF;
+ buf[3] = size&0xFF;
}
template<typename T>
template const char *Protocol::disassemble_field<>(vector<double> &v, const char *d, const char *e);
template const char *Protocol::disassemble_field<>(vector<string> &v, const char *d, const char *e);
-unsigned Protocol::PacketDefBase::next_class_id=1;
+unsigned Protocol::PacketDefBase::next_class_id = 1;
} // namespace Net
} // namespace Msp