diff --git a/src/Server/message.cxx b/src/Server/message.cxx index e06964c5e..1844b434c 100644 --- a/src/Server/message.cxx +++ b/src/Server/message.cxx @@ -22,6 +22,8 @@ #include "message.hxx" +FGMPSInstanceFuncMap FGMPSMessage::funcmap; + FGMPSMessage::FGMPSMessage() { msgid = 0x0000; @@ -30,5 +32,118 @@ FGMPSMessage::FGMPSMessage() } +string FGMPSMessage::encodemsg() +{ + FGMPSMsgElementEntry* ptr = getelements(); + + buf.clr(); + if (msgid > 255) { + buf.put(fgmps_som16, true); + buf.write2(&msgid); + } else { + buf.put(fgmps_som8, true); + buf.write1(&msgid); + } + while (ptr->type != fgmps_null) { + buf.put(ptr->type, true); + //printf ("adding %02x\n", ptr->type); + switch (ptr->type) { + case fgmps_uchar: + case fgmps_char: + buf.write1(ptr->data); + break; + case fgmps_uint: + case fgmps_int: + buf.write2(ptr->data); + break; + case fgmps_ulong: + case fgmps_long: + buf.write4(ptr->data); + break; + case fgmps_float: + buf.writef(*(float*)ptr->data); + break; + case fgmps_double: + buf.writed(*(double*)ptr->data); + break; + case fgmps_string: + buf.writes(*(string*)ptr->data); + break; + } + ptr++; + } + + buf.put(fgmps_eom, true); + + return buf.str(); +} + +FGMPSMessage* FGMPSMessage::decodemsg(string msg) +{ + FGMPSMessageBuf buf; + unsigned char ch; + unsigned int mid; + FGMPSInstanceFuncMap::iterator fmitr; + + buf.set(msg); + buf.ofs(0); + ch = buf.get(true); + if (ch != fgmps_som8 && ch != fgmps_som16) { + throw FGMPSDataException("Invalid start of message"); + } + if (ch == fgmps_som8) { + ch = buf.get(); + mid = ch; + } else { + mid = *(unsigned int *)buf.read2(); + } + + fmitr = funcmap.find(mid); + if (fmitr == funcmap.end()) { + throw FGMPSDataException("MessageID has no registered Message Class"); + } + FGMPSMessage* msgclass = (fmitr->second)(); + FGMPSMsgElementEntry* elements = msgclass->getelements(); + while ((ch = buf.get()) != fgmps_eom) { + //printf("dump: "); + //for (int i=-1; i<16; i++) printf("%02x ", buf.peek(i)); + //printf("\n"); + + if (ch != elements->type) { + delete msgclass; + throw FGMPSDataException("Decode: Message Structure Error"); + } + switch (ch) { + case fgmps_uchar: + case fgmps_char: + memcpy(elements->data, buf.read1(), 1); + break; + case fgmps_uint: + case fgmps_int: + memcpy(elements->data, buf.read2(), 2); + break; + case fgmps_ulong: + case fgmps_long: + memcpy(elements->data, buf.read4(), 4); + break; + case fgmps_float: + *(float*)elements->data = buf.readf(); + break; + case fgmps_double: + *(double*)elements->data = buf.readd(); + break; + case fgmps_string: + ch = buf.get(); + *(string*)elements->data = buf.reads(ch); + break; + default: + delete msgclass; + throw FGMPSDataException("Decode: Unknown data type"); + break; + } + elements++; + } + return msgclass; +} diff --git a/src/Server/message.hxx b/src/Server/message.hxx index 35c7e5111..30daf9f81 100644 --- a/src/Server/message.hxx +++ b/src/Server/message.hxx @@ -27,9 +27,11 @@ #include STL_STRING #include +#include SG_USING_STD(string); SG_USING_STD(invalid_argument); +SG_USING_STD(map); #include "messagebuf.hxx" @@ -62,22 +64,35 @@ typedef struct #define FGMPSMsgElementArrayEnd {fgmps_null, 0} +class FGMPSMessage; + +typedef FGMPSMessage* FGMPSMessagePtr; +typedef FGMPSMessagePtr (*FGMPSMsgInstanceFunc)(void); + +typedef map FGMPSInstanceFuncMap; + class FGMPSMessage { private: + static FGMPSInstanceFuncMap funcmap; FGMPSMsgElementEntry elements[1]; - static unsigned int msgid; protected: - FGMPSMessageBuf msg; + FGMPSMessageBuf buf; + unsigned int msgid; public: + static int registermsg(int msgid, FGMPSMsgInstanceFunc func) + { + funcmap[msgid] = func; + } + FGMPSMessage(); ~FGMPSMessage() {} - virtual string encodemsg() {} - virtual FGMPSMessage* decodemsg(string msg) {} - virtual FGMPSMsgElementEntry* getelements() { return elements; } - virtual unsigned int getmessageid() { return msgid; } + string encodemsg(); + static FGMPSMessage* decodemsg(string msg); + unsigned int getmessageid() { return msgid; } + virtual FGMPSMsgElementEntry* getelements() { return elements; } }; #endif diff --git a/src/Server/msg_0001_hello.cxx b/src/Server/msg_0001_hello.cxx index a0fad4ea9..d2ff50714 100644 --- a/src/Server/msg_0001_hello.cxx +++ b/src/Server/msg_0001_hello.cxx @@ -24,11 +24,11 @@ FGMPSMsg0001Hello::FGMPSMsg0001Hello() { - msgid = 0x0001; - elements[0].type = fgmps_uint; elements[0].data = &this->vermajor; - elements[1].type = fgmps_uint; elements[0].data = &this->verminor; - elements[2].type = fgmps_uint; elements[0].data = &this->verpatch; - elements[3].type = fgmps_string; elements[0].data = &this->servname; + msgid = FGMPSMsg0001HelloID; + elements[0].type = fgmps_uint; elements[0].data = &vermajor; + elements[1].type = fgmps_uint; elements[1].data = &verminor; + elements[2].type = fgmps_uint; elements[2].data = &verpatch; + elements[3].type = fgmps_string; elements[3].data = &servname; elements[4].type = fgmps_null; elements[4].data = NULL; } diff --git a/src/Server/msg_0001_hello.hxx b/src/Server/msg_0001_hello.hxx index 9da5bd323..a1472cbf7 100644 --- a/src/Server/msg_0001_hello.hxx +++ b/src/Server/msg_0001_hello.hxx @@ -25,20 +25,26 @@ #include "message.hxx" -class FGMPSMsg0001Hello +#define FGMPSMsg0001HelloID 0x0001 + +class FGMPSMsg0001Hello: public FGMPSMessage { private: FGMPSMsgElementEntry elements[5]; - unsigned int msgid; public: + + static void registerme() + { + FGMPSMessage::registermsg(FGMPSMsg0001HelloID, &FGMPSMsg0001Hello::instance); + } + + static FGMPSMessage* instance() { return (FGMPSMessage*) new FGMPSMsg0001Hello; } + + virtual FGMPSMsgElementEntry* getelements() { return elements; } + FGMPSMsg0001Hello(); ~FGMPSMsg0001Hello() {} - virtual string encodemsg() {} - virtual FGMPSMessage* decodemsg(string msg) {} - virtual FGMPSMsgElementEntry* getelements() { return elements; } - virtual unsigned int getmessageid() { return msgid; } - unsigned int vermajor; unsigned int verminor; unsigned int verpatch; diff --git a/src/Server/msgtest.cxx b/src/Server/msgtest.cxx index 96248a6fe..6130463a6 100644 --- a/src/Server/msgtest.cxx +++ b/src/Server/msgtest.cxx @@ -1,6 +1,40 @@ -#include "messagebuf.hxx" +#include "msg_0001_hello.hxx" main(int argc, char **argv) { - printf("Hello\n"); + string str; + FGMPSMsg0001Hello msg1, *msg2; + + FGMPSMsg0001Hello::registerme(); + + msg1.vermajor = 3; + msg1.verminor = 7; + msg1.verpatch = 42; + msg1.servname = "test"; + + str = msg1.encodemsg(); + + printf("Message ID = %ui\n", msg1.getmessageid()); + printf("major = %u\n", msg1.vermajor); + printf("minor = %u\n", msg1.verminor); + printf("patch = %u\n", msg1.verpatch); + printf("sname = %s\n", msg1.servname.c_str()); + + printf("dump: "); + for (int i=0; igetmessageid()); + printf("major = %u\n", msg2->vermajor); + printf("minor = %u\n", msg2->verminor); + printf("patch = %u\n", msg2->verpatch); + printf("sname = %s\n", msg2->servname.c_str()); + }