forked from open-dis/xmlpg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathXMLPG.html
513 lines (513 loc) · 25.5 KB
/
XMLPG.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
<title>XMLPG</title>
</head>
<body>
<div style="text-align: center;">XML Multi-Language Protocol Generator<br>
</div>
<br>
<span style="font-weight: bold;">Introduction</span><br>
<br>
XML Multi-Language Protocol Generator uses an abstract, XML language
description of Protocol Data Units to quickly generate Java and C++
language protocol implementations that can match existing binary
protocols. <br>
<br>
The user writes a simple, XML-based description of the protocol data
units, including the names and types of the protocol elements. XMLPG
generates Java and C++ language classes with getters, setters,
constructors, and marshaling and unmarshaling code.<br>
<br>
The XML fragment below provides an abstract definition of a protocol
class:<br>
<br>
<div style="margin-left: 40px;"><small><span
style="font-family: courier;"><class name="EntityID"
inheritsFrom="root" comment="The identifier for entities in a DIS
world. It consists of three unsigned short values, which together are
unique."></span></small><br style="font-family: courier;">
<br style="font-family: courier;">
<small><span style="font-family: courier;"> <attribute
name="application" comment="The application ID"></span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> <primitive
type="unsigned short"/></span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> </attribute></span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> </span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> <attribute
name="site" comment="The site ID"></span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> <primitive
type="unsigned short"/></span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> </attribute></span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> </span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> <attribute
name="entity" comment="the entity ID"></span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> <primitive
type="unsigned short"/></span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> </attribute></span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"> </span></small><br
style="font-family: courier;">
<small><span style="font-family: courier;"></class></span></small><br>
</div>
<br>
<div style="text-align: center;"><span style="font-weight: bold;">Figure
1. XML Protocol Class Description</span><br>
</div>
<br>
XMLPG reads this XML and generates an abstract description of the
class. This abstract description is compiled to Java and C++ classes. A
fragment of the Java class generated is below in Figure 2:<br>
<br>
<div style="margin-left: 40px;"><small><span
style="font-family: courier new,courier,monospace;">/**</span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;"> *
The
identifier for entities in a DIS world. It consists of three unsigned
short values, which together are unique.</span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">*/</span></small><br>
</div>
<div style="margin-left: 40px;"><small><span
style="font-family: courier new,courier,monospace;">public class
EntityID extends Object</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">{</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
/** The application ID */</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
protected int application; </span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
/** The site ID */</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
protected int site; </span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
/** the entity ID */</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
protected int entity; </span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">public void
setApplication(int pApplication)</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">{ application
= pApplication;</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">}</span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">public int
getApplication()</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">{ return
application; }</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">}</span></small><br>
</div>
<br>
<div style="text-align: center;"><span style="font-weight: bold;">Figure
2. Java Language Class Created by XMLPG</span><br>
</div>
<br>
A fragment of the C++ header file generated is below in Figure 3:<br>
<br>
<div style="margin-left: 40px;"><small><span
style="font-family: courier new,courier,monospace;">class
XML_DIS_EXPORT EntityID</span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">{</span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">public:</span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">
unsigned short application; // The application ID</span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">
unsigned short site; // The site ID</span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">
unsigned short entity; // the entity ID</span></small><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;"> public:</span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">
EntityID();</span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">
~EntityID();</span></small><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">
unsigned short getApplication() const; </span></small><br
style="font-family: courier new,courier,monospace;">
<small><span style="font-family: courier new,courier,monospace;">
void setApplication(unsigned short x); </span></small><br>
</div>
<br>
<div style="text-align: center;"><span style="font-weight: bold;">Figure
3. C++ Language Class Generated by XMLPG</span><br>
</div>
<br>
As can be seen, the XML description acts as a template for the
generation of the Java and C++ programming language classes. The code
appropriate to each language, including marshaling and unmarshaling
code, is generated by XMLPG. The programmer can then compile the
generated code.<br>
<br>
XMLPG is an open source project with a BSD license.<br>
<br>
<span style="font-weight: bold;">XML Description Language</span><br>
<br>
The XML syntax used to describe the protocol is relatively simple. The
objective is to be able to describe either completly new protocols, or
match an existing binary protocol, such as Distributed Interactive
Simulation (DIS). The abstract XML description should be much easier,
faster, and with generate fewer errors than writing the code to
implement the protocol from scratch. New languages, if desired, can be
added fairly easily.<br>
<br>
The <span style="font-family: courier new,courier,monospace;"><classes></span>
tag encloses one or more class descriptions.<br>
<br>
The <span style="font-family: courier new,courier,monospace;"><class>
</span>tag is used to describe one class in the protocol.<br>
<br>
<span style="font-family: courier new,courier,monospace;"><class
name="Pdu" inheritsFrom="root" comment="The superclass for all PDUs"></span><br>
<br>
In this case the Java and C++ class generated will be named Pdu and
inherit from Object in the case of Java and nothing in the case of C++.
A class can also inherit from another class defined in the XML file:<br>
<br>
<span style="font-family: courier new,courier,monospace;"><class
name="FirePdu" inheritsFrom="Pdu" comment="Information about someone
firing something"></span><br>
<br>
In this case the FirePdu will inherit from Pdu. The comment tag is
optional; it will be included as a javadoc class comment or C++ comment.<br>
<br>
The class tag contains one or more attribute tags. The attribute tags
describe one field of the PDU. The simplest sort of attribute is a
primitive, which corresponds to a programming language primitive type.<br>
<br>
<span
style="font-family: courier new,courier,monospace;"><attribute
name="quantity" comment="how many"></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
<primitive type="unsigned short"/></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
</attribute></span><br>
<br>
The attribute will cause a programming language instance variable to be
created in the class. The ivar will appear in the same order as which
it appears in the XML document. This is important for marshaling and
unmarshaling. If you are reverse-engineering an existing protocol you
should have attribute tags in exactly the same order in which the
appear in the protocol.<br>
<br>
There are four basic types of attributes: primitives, references to
other classes defined in the same document, fixed lists (or arrays),
and variable lists. Each of these are described below.<br>
<br>
<span style="font-weight: bold;">Primitive Types.</span> These
correspond to programming language primitive types. Legal values
for these programming types include unsigned byte, unsigned short,
unsigned int, long, byte, short, int, float, and double. The syntax for
a primitive attribute description is as above.<br>
<br>
<span style="font-weight: bold;">Class References</span>. A class may
include other classes, for example an EntityStatePdu including a
EntityID object as one of its attributes. This is very similar to
describing a primitive type:<br>
<br>
<span style="font-family: courier new,courier,monospace;"><attribute
name="entityID" comment="Uniquely identifies an entity in the world"></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
<classRef name="EntityID"/></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
</attribute></span><br>
<br>
The name attribute must contain the name of another class defined in
the XML file. Getter and setter methods will be generated for the
attribute, and the attribute will be marshaled and unmarshaled. In this
case the name of the attribute is "entityID" and the class is of the
type is "EntityID" (note capitalization). The C++ ivar, getter
and setter declarations look like this:<br>
<br>
<span
style="font-family: courier new,courier,monospace;"> EntityID
entityID; // Uniquely identifies an entity in the world</span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
EntityID& getEntityID(); </span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
const EntityID& getEntityID() const; </span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
void setEntityID(EntityID &x);</span><br>
<br>
The java code generated looks like this:<br>
<br>
<span style="font-family: courier new,courier,monospace;">/** Uniquely
identifies an entity in the world */</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
protected EntityID entityID = new EntityID(); </span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">public void
setEntityID(EntityID pEntityID)</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">{ entityID =
pEntityID;</span><br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">}</span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">public
EntityID getEntityID()</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">{ return
entityID; }</span><br>
<br>
<br>
<br>
<span style="font-weight: bold;">Fixed List.</span> This
corresponds to an array. The tags are as below:<br>
<br>
<span style="font-family: courier new,courier,monospace;"><attribute
name="marking"></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
<list type="fixed" length="12"></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
<primitive type="byte"/></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
</list></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;"> </attribute></span><br>
<br>
The list tag defines a fixed length, which is used to generate an array
in the source code. The list tag encloses either a primitive type or a
classref field.<br>
<br>
The C++ code generated looks like this:<br>
<br>
<span style="font-family: courier new,courier,monospace;">
char marking[12];</span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
char* getMarking(); </span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
const char* getMarking() const; </span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
void setMarking( char* x);</span><br>
<br>
And the Java code like this:<br>
<br>
<span style="font-family: courier new,courier,monospace;">protected
byte[] marking = new byte[12]; </span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">public void
setMarking(byte[] pMarking)</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">{ marking =
pMarking;</span><br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">}</span><br
style="font-family: courier new,courier,monospace;">
<br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">public byte[]
getMarking()</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">{ return
marking; }</span><br>
<br>
<br>
<span style="font-weight: bold;">Variable List</span> While fixed
lists are always the same length, variable lists may have
more or fewer list elements, and are implemented as vectors that can
grow or shrink. Variable lists must be tied to an attribute field that
is used to determine how many elements are in the lists. This is needed
for unmarshaling; when processing a binary format packet we must know
how many elements of the list to read.<br>
<br>
<span style="font-family: courier new,courier,monospace;"><attribute
name="articulationParameters" comment="variable length list of
articulation parameters"></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
<list type="variable" countFieldName="articulationParameterCount"></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
<classRef name="ArticulationParameter"/></span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
</list> </span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;"></attribute></span><br>
<br>
<br>
This specifies a field called "articulationParameters" that has a
variable number of ArticulationParameter objects in it. The number of
objects should be held in the field called
"articulationParameterCount". During the unmarshaling process that
field will be read and the value used to read that many
ArticulationParameter objects. This means that the number of
articulation parameters specified in articulationParameterCount should
be current at the time the PDU is marshaled.<br>
<br>
<span style="font-weight: bold;">Marshaling and Unmarshaling</span><br>
<br>
The classes with get and set methods implements much of the code.
However, a network protocol requires that these classes be able to
marshal and unmarshal (aka serialize and deserialize) themselves to the
network as PDUs. XMLPG is able to do this automatically. The order in
which the ivars are marshaled and unmarshaled is determined by the
order in which they appear in the XML description document. An example
marshal method for the DIS Entity State PDU is shown below. All this
code is generated automatically. Note that because ESPDU inherits from
PDU the marshal method in the superclass is called first. Then each of
the ivars is marshaled, in order. Primitive types are written directly,
and embedded objects have their marshal method called. A similar
method is generated to unmarshal the class from the network.<br>
<br>
<div style="margin-left: 40px;"><span
style="font-family: courier new,courier,monospace;">public void
marshal(DataOutputStream dos)</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">{</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
super.marshal(dos);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;"> try </span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
{</span><br style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
entityID.marshal(dos);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
dos.writeByte( (byte)forceId);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
dos.writeByte( (byte)articulationParameterCount);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
entityType.marshal(dos);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
alternativeEntityType.marshal(dos);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
entityLinearVelocity.marshal(dos);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
entityLocation.marshal(dos);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
entityOrientation.marshal(dos);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
dos.writeInt( (int)entityAppearance);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
deadReckoningParameters.marshal(dos);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
for(int idx = 0; idx < marking.length; idx++)</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
{</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
dos.writeByte(marking[idx]);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
} // end of array marshaling</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
dos.writeInt( (int)capabilities);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
for(int idx = 0; idx <
articulationParameters.size(); idx++)</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
{</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
ArticulationParameter aArticulationParameter =
(ArticulationParameter)articulationParameters.get(idx);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
aArticulationParameter.marshal(dos);</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
} // end of list marshalling</span><br
style="font-family: courier new,courier,monospace;">
<span style="font-family: courier new,courier,monospace;">
} // end try <br>
<br>
</span></div>
Similar code is generated for the C++ implementation.<br>
<br>
<br>
<span style="font-weight: bold;">Example: Distributed Interactive
Simulation</span><br>
<br>
As a test case parts of the IEEE DIS standard have been described using
XMLPG. This is in the file DIS.xml. Using this XML file java and
C++ language files were generated and placed in the cpp and java
directories of DIS. The Java source code is compiled via the ant build
file with the <span style="font-family: Courier New,Courier,monospace;">ant
compileDis</span> command.<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>