]> git.mxchange.org Git - flightgear.git/blob - src/Server/message.cxx
Frederic Bouvier:
[flightgear.git] / src / Server / message.cxx
1 // message.hxx -- Multiplayer Client/Server message base class\r
2 //\r
3 // Written by John Barrett, started November 2003.\r
4 //\r
5 // Copyright (C) 2003  John R. Barrett - jbarrett@accesshosting.com\r
6 //\r
7 // This program is free software; you can redistribute it and/or\r
8 // modify it under the terms of the GNU General Public License as\r
9 // published by the Free Software Foundation; either version 2 of the\r
10 // License, or (at your option) any later version.\r
11 //\r
12 // This program is distributed in the hope that it will be useful, but\r
13 // WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
15 // General Public License for more details.\r
16 //\r
17 // You should have received a copy of the GNU General Public License\r
18 // along with this program; if not, write to the Free Software\r
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
20 //\r
21 \r
22 \r
23 #include "message.hxx"\r
24 \r
25 FGMPSInstanceFuncMap    FGMPSMessage::funcmap;\r
26 \r
27 FGMPSMessage::FGMPSMessage() \r
28 {\r
29         msgid = 0x0000;\r
30         elements[0].type = fgmps_null;\r
31         elements[0].data = NULL;        \r
32         \r
33 }\r
34 \r
35 string FGMPSMessage::encodemsg()\r
36 {\r
37         FGMPSMsgElementEntry* ptr = getelements();\r
38 \r
39         buf.clr();\r
40         if (msgid > 255) {\r
41                 buf.put(fgmps_som16, true);\r
42                 buf.write2(&msgid);\r
43         } else {\r
44                 buf.put(fgmps_som8, true);\r
45                 buf.write1(&msgid);\r
46         }\r
47         while (ptr->type != fgmps_null) {\r
48                 buf.put(ptr->type, true);\r
49                 //printf ("adding %02x\n", ptr->type);\r
50                 switch (ptr->type) {\r
51                 case fgmps_uchar:\r
52                 case fgmps_char:\r
53                         buf.write1(ptr->data);\r
54                         break;\r
55                 case fgmps_uint:\r
56                 case fgmps_int:\r
57                         buf.write2(ptr->data);\r
58                         break;\r
59                 case fgmps_ulong:\r
60                 case fgmps_long:\r
61                         buf.write4(ptr->data);\r
62                         break;\r
63                 case fgmps_float:\r
64                         buf.writef(*(float*)ptr->data);\r
65                         break;\r
66                 case fgmps_double:\r
67                         buf.writed(*(double*)ptr->data);\r
68                         break;\r
69                 case fgmps_string:\r
70                         buf.writes(*(string*)ptr->data);\r
71                         break;\r
72                 }\r
73                 ptr++;\r
74         }\r
75 \r
76         buf.put(fgmps_eom, true);\r
77 \r
78         return buf.str();\r
79 }\r
80 \r
81 FGMPSMessage* FGMPSMessage::decodemsg(string msg)\r
82 {\r
83         FGMPSMessageBuf                 buf;\r
84         unsigned char                   ch;\r
85         unsigned int                    mid;\r
86         FGMPSInstanceFuncMap::iterator  fmitr;\r
87 \r
88         buf.set(msg);\r
89         buf.ofs(0);\r
90         ch = buf.get(true);\r
91         if (ch != fgmps_som8 && ch != fgmps_som16) {\r
92                 throw FGMPSDataException("Invalid start of message");\r
93         }\r
94         if (ch == fgmps_som8) {\r
95                 ch = buf.get();\r
96                 mid = ch;\r
97         } else {\r
98                 mid = *(unsigned int *)buf.read2();\r
99         }\r
100         \r
101         fmitr = funcmap.find(mid);\r
102         if (fmitr == funcmap.end()) {\r
103                 throw FGMPSDataException("MessageID has no registered Message Class");\r
104         }\r
105         FGMPSMessage* msgclass = (fmitr->second)();\r
106         FGMPSMsgElementEntry* elements = msgclass->getelements();\r
107         while ((ch = buf.get()) != fgmps_eom) {\r
108                 //printf("dump: ");\r
109                 //for (int i=-1; i<16; i++) printf("%02x ", buf.peek(i));\r
110                 //printf("\n");\r
111 \r
112                 if (ch != elements->type) {\r
113                         delete msgclass;\r
114                         throw FGMPSDataException("Decode: Message Structure Error");\r
115                 }\r
116                 switch (ch) {\r
117                 case fgmps_uchar:\r
118                 case fgmps_char:\r
119                         memcpy(elements->data, buf.read1(), 1);\r
120                         break;\r
121                 case fgmps_uint:\r
122                 case fgmps_int:\r
123                         memcpy(elements->data, buf.read2(), 2);\r
124                         break;\r
125                 case fgmps_ulong:\r
126                 case fgmps_long:\r
127                         memcpy(elements->data, buf.read4(), 4);\r
128                         break;\r
129                 case fgmps_float:\r
130                         *(float*)elements->data = buf.readf();\r
131                         break;\r
132                 case fgmps_double:\r
133                         *(double*)elements->data = buf.readd();\r
134                         break;\r
135                 case fgmps_string:\r
136                         ch = buf.get();\r
137                         *(string*)elements->data = buf.reads(ch);\r
138                         break;\r
139                 default:\r
140                         delete msgclass;\r
141                         throw FGMPSDataException("Decode: Unknown data type");\r
142                         break;\r
143                 }\r
144                 elements++;\r
145         }\r
146         return msgclass;\r
147 }\r
148 \r
149 \r