\r
#include "message.hxx"\r
\r
+FGMPSInstanceFuncMap FGMPSMessage::funcmap;\r
+\r
FGMPSMessage::FGMPSMessage() \r
{\r
msgid = 0x0000;\r
\r
}\r
\r
+string FGMPSMessage::encodemsg()\r
+{\r
+ FGMPSMsgElementEntry* ptr = getelements();\r
+\r
+ buf.clr();\r
+ if (msgid > 255) {\r
+ buf.put(fgmps_som16, true);\r
+ buf.write2(&msgid);\r
+ } else {\r
+ buf.put(fgmps_som8, true);\r
+ buf.write1(&msgid);\r
+ }\r
+ while (ptr->type != fgmps_null) {\r
+ buf.put(ptr->type, true);\r
+ //printf ("adding %02x\n", ptr->type);\r
+ switch (ptr->type) {\r
+ case fgmps_uchar:\r
+ case fgmps_char:\r
+ buf.write1(ptr->data);\r
+ break;\r
+ case fgmps_uint:\r
+ case fgmps_int:\r
+ buf.write2(ptr->data);\r
+ break;\r
+ case fgmps_ulong:\r
+ case fgmps_long:\r
+ buf.write4(ptr->data);\r
+ break;\r
+ case fgmps_float:\r
+ buf.writef(*(float*)ptr->data);\r
+ break;\r
+ case fgmps_double:\r
+ buf.writed(*(double*)ptr->data);\r
+ break;\r
+ case fgmps_string:\r
+ buf.writes(*(string*)ptr->data);\r
+ break;\r
+ }\r
+ ptr++;\r
+ }\r
+\r
+ buf.put(fgmps_eom, true);\r
+\r
+ return buf.str();\r
+}\r
+\r
+FGMPSMessage* FGMPSMessage::decodemsg(string msg)\r
+{\r
+ FGMPSMessageBuf buf;\r
+ unsigned char ch;\r
+ unsigned int mid;\r
+ FGMPSInstanceFuncMap::iterator fmitr;\r
+\r
+ buf.set(msg);\r
+ buf.ofs(0);\r
+ ch = buf.get(true);\r
+ if (ch != fgmps_som8 && ch != fgmps_som16) {\r
+ throw FGMPSDataException("Invalid start of message");\r
+ }\r
+ if (ch == fgmps_som8) {\r
+ ch = buf.get();\r
+ mid = ch;\r
+ } else {\r
+ mid = *(unsigned int *)buf.read2();\r
+ }\r
+ \r
+ fmitr = funcmap.find(mid);\r
+ if (fmitr == funcmap.end()) {\r
+ throw FGMPSDataException("MessageID has no registered Message Class");\r
+ }\r
+ FGMPSMessage* msgclass = (fmitr->second)();\r
+ FGMPSMsgElementEntry* elements = msgclass->getelements();\r
+ while ((ch = buf.get()) != fgmps_eom) {\r
+ //printf("dump: ");\r
+ //for (int i=-1; i<16; i++) printf("%02x ", buf.peek(i));\r
+ //printf("\n");\r
+\r
+ if (ch != elements->type) {\r
+ delete msgclass;\r
+ throw FGMPSDataException("Decode: Message Structure Error");\r
+ }\r
+ switch (ch) {\r
+ case fgmps_uchar:\r
+ case fgmps_char:\r
+ memcpy(elements->data, buf.read1(), 1);\r
+ break;\r
+ case fgmps_uint:\r
+ case fgmps_int:\r
+ memcpy(elements->data, buf.read2(), 2);\r
+ break;\r
+ case fgmps_ulong:\r
+ case fgmps_long:\r
+ memcpy(elements->data, buf.read4(), 4);\r
+ break;\r
+ case fgmps_float:\r
+ *(float*)elements->data = buf.readf();\r
+ break;\r
+ case fgmps_double:\r
+ *(double*)elements->data = buf.readd();\r
+ break;\r
+ case fgmps_string:\r
+ ch = buf.get();\r
+ *(string*)elements->data = buf.reads(ch);\r
+ break;\r
+ default:\r
+ delete msgclass;\r
+ throw FGMPSDataException("Decode: Unknown data type");\r
+ break;\r
+ }\r
+ elements++;\r
+ }\r
+ return msgclass;\r
+}\r
\r
\r
\r
#include STL_STRING\r
#include <stdexcept>\r
+#include <map>\r
\r
SG_USING_STD(string);\r
SG_USING_STD(invalid_argument);\r
+SG_USING_STD(map);\r
\r
#include "messagebuf.hxx"\r
\r
\r
#define FGMPSMsgElementArrayEnd {fgmps_null, 0}\r
\r
+class FGMPSMessage;\r
+\r
+typedef FGMPSMessage* FGMPSMessagePtr;\r
+typedef FGMPSMessagePtr (*FGMPSMsgInstanceFunc)(void);\r
+\r
+typedef map<unsigned int, FGMPSMsgInstanceFunc> FGMPSInstanceFuncMap;\r
+\r
class FGMPSMessage\r
{\r
private:\r
+ static FGMPSInstanceFuncMap funcmap;\r
FGMPSMsgElementEntry elements[1];\r
- static unsigned int msgid;\r
protected:\r
- FGMPSMessageBuf msg;\r
+ FGMPSMessageBuf buf;\r
+ unsigned int msgid;\r
public:\r
+ static int registermsg(int msgid, FGMPSMsgInstanceFunc func)\r
+ {\r
+ funcmap[msgid] = func;\r
+ }\r
+\r
FGMPSMessage();\r
~FGMPSMessage() {}\r
\r
- virtual string encodemsg() {}\r
- virtual FGMPSMessage* decodemsg(string msg) {}\r
- virtual FGMPSMsgElementEntry* getelements() { return elements; }\r
- virtual unsigned int getmessageid() { return msgid; }\r
+ string encodemsg();\r
+ static FGMPSMessage* decodemsg(string msg);\r
+ unsigned int getmessageid() { return msgid; }\r
\r
+ virtual FGMPSMsgElementEntry* getelements() { return elements; }\r
};\r
\r
#endif\r
\r
FGMPSMsg0001Hello::FGMPSMsg0001Hello() \r
{\r
- msgid = 0x0001;\r
- elements[0].type = fgmps_uint; elements[0].data = &this->vermajor; \r
- elements[1].type = fgmps_uint; elements[0].data = &this->verminor; \r
- elements[2].type = fgmps_uint; elements[0].data = &this->verpatch; \r
- elements[3].type = fgmps_string; elements[0].data = &this->servname; \r
+ msgid = FGMPSMsg0001HelloID;\r
+ elements[0].type = fgmps_uint; elements[0].data = &vermajor; \r
+ elements[1].type = fgmps_uint; elements[1].data = &verminor; \r
+ elements[2].type = fgmps_uint; elements[2].data = &verpatch; \r
+ elements[3].type = fgmps_string; elements[3].data = &servname; \r
elements[4].type = fgmps_null; elements[4].data = NULL; \r
}\r
\r
\r
#include "message.hxx"\r
\r
-class FGMPSMsg0001Hello\r
+#define FGMPSMsg0001HelloID 0x0001\r
+\r
+class FGMPSMsg0001Hello: public FGMPSMessage\r
{\r
private:\r
FGMPSMsgElementEntry elements[5];\r
- unsigned int msgid;\r
public:\r
- FGMPSMsg0001Hello();\r
- ~FGMPSMsg0001Hello() {}\r
\r
- virtual string encodemsg() {}\r
- virtual FGMPSMessage* decodemsg(string msg) {}\r
+ static void registerme() \r
+ { \r
+ FGMPSMessage::registermsg(FGMPSMsg0001HelloID, &FGMPSMsg0001Hello::instance);\r
+ }\r
+\r
+ static FGMPSMessage* instance() { return (FGMPSMessage*) new FGMPSMsg0001Hello; }\r
+\r
virtual FGMPSMsgElementEntry* getelements() { return elements; }\r
- virtual unsigned int getmessageid() { return msgid; }\r
+\r
+ FGMPSMsg0001Hello();\r
+ ~FGMPSMsg0001Hello() {}\r
\r
unsigned int vermajor;\r
unsigned int verminor;\r
-#include "messagebuf.hxx"\r
+#include "msg_0001_hello.hxx"\r
\r
main(int argc, char **argv)\r
{\r
- printf("Hello\n");\r
+ string str;\r
+ FGMPSMsg0001Hello msg1, *msg2;\r
+\r
+ FGMPSMsg0001Hello::registerme();\r
+\r
+ msg1.vermajor = 3;\r
+ msg1.verminor = 7;\r
+ msg1.verpatch = 42;\r
+ msg1.servname = "test";\r
+\r
+ str = msg1.encodemsg();\r
+\r
+ printf("Message ID = %ui\n", msg1.getmessageid());\r
+ printf("major = %u\n", msg1.vermajor);\r
+ printf("minor = %u\n", msg1.verminor);\r
+ printf("patch = %u\n", msg1.verpatch);\r
+ printf("sname = %s\n", msg1.servname.c_str());\r
+\r
+ printf("dump: ");\r
+ for (int i=0; i<str.length(); i++) printf("%02x ", (unsigned char)str[i]);\r
+ printf("\n");\r
+\r
+ try {\r
+ msg2 = (FGMPSMsg0001Hello*)FGMPSMessage::decodemsg(str);\r
+ } catch (FGMPSDataException e) {\r
+ printf("Exception: %s\n", e.what());\r
+ exit(1);\r
+ }\r
+\r
+ printf("Message ID = %u\n", msg2->getmessageid());\r
+ printf("major = %u\n", msg2->vermajor);\r
+ printf("minor = %u\n", msg2->verminor);\r
+ printf("patch = %u\n", msg2->verpatch);\r
+ printf("sname = %s\n", msg2->servname.c_str());\r
+ \r
}\r