]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLADataTypeVisitor.hxx
hla: Use HLADataElementIndices for HLAInteractionClass.
[simgear.git] / simgear / hla / HLADataTypeVisitor.hxx
1 // Copyright (C) 2009 - 2012  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 //
17
18 #ifndef HLADataTypeVisitor_hxx
19 #define HLADataTypeVisitor_hxx
20
21 #include <cassert>
22 #include <string>
23 #include <simgear/debug/logstream.hxx>
24 #include <simgear/math/SGMath.hxx>
25 #include "HLAArrayDataType.hxx"
26 #include "HLABasicDataType.hxx"
27 #include "HLADataElement.hxx"
28 #include "HLAEnumeratedDataType.hxx"
29 #include "HLAFixedRecordDataType.hxx"
30 #include "HLAVariantRecordDataType.hxx"
31
32 namespace simgear {
33
34 class HLADataTypeVisitor {
35 public:
36     virtual ~HLADataTypeVisitor() {}
37
38     virtual void apply(const HLADataType& dataType)
39     { }
40
41     virtual void apply(const HLABasicDataType& dataType)
42     { apply(static_cast<const HLADataType&>(dataType)); }
43     virtual void apply(const HLAInt8DataType& dataType)
44     { apply(static_cast<const HLABasicDataType&>(dataType)); }
45     virtual void apply(const HLAUInt8DataType& dataType)
46     { apply(static_cast<const HLABasicDataType&>(dataType)); }
47     virtual void apply(const HLAInt16DataType& dataType)
48     { apply(static_cast<const HLABasicDataType&>(dataType)); }
49     virtual void apply(const HLAUInt16DataType& dataType)
50     { apply(static_cast<const HLABasicDataType&>(dataType)); }
51     virtual void apply(const HLAInt32DataType& dataType)
52     { apply(static_cast<const HLABasicDataType&>(dataType)); }
53     virtual void apply(const HLAUInt32DataType& dataType)
54     { apply(static_cast<const HLABasicDataType&>(dataType)); }
55     virtual void apply(const HLAInt64DataType& dataType)
56     { apply(static_cast<const HLABasicDataType&>(dataType)); }
57     virtual void apply(const HLAUInt64DataType& dataType)
58     { apply(static_cast<const HLABasicDataType&>(dataType)); }
59     virtual void apply(const HLAFloat32DataType& dataType)
60     { apply(static_cast<const HLABasicDataType&>(dataType)); }
61     virtual void apply(const HLAFloat64DataType& dataType)
62     { apply(static_cast<const HLABasicDataType&>(dataType)); }
63
64     virtual void apply(const HLAArrayDataType& dataType)
65     { apply(static_cast<const HLADataType&>(dataType)); }
66     virtual void apply(const HLAFixedArrayDataType& dataType)
67     { apply(static_cast<const HLAArrayDataType&>(dataType)); }
68     virtual void apply(const HLAVariableArrayDataType& dataType)
69     { apply(static_cast<const HLAArrayDataType&>(dataType)); }
70
71     virtual void apply(const HLAEnumeratedDataType& dataType)
72     { apply(static_cast<const HLADataType&>(dataType)); }
73
74     virtual void apply(const HLAFixedRecordDataType& dataType)
75     { apply(static_cast<const HLADataType&>(dataType)); }
76
77     virtual void apply(const HLAVariantRecordDataType& dataType)
78     { apply(static_cast<const HLADataType&>(dataType)); }
79 };
80
81 /// Walks the datatype tree and checks if it is completely defined
82 class HLADataTypeCheckVisitor : public HLADataTypeVisitor {
83 public:
84     HLADataTypeCheckVisitor() : _valid(true) {}
85
86     bool valid() const { return _valid; }
87
88     virtual void apply(const HLAInt8DataType& dataType) { }
89     virtual void apply(const HLAUInt8DataType& dataType) { }
90     virtual void apply(const HLAInt16DataType& dataType) { }
91     virtual void apply(const HLAUInt16DataType& dataType) { }
92     virtual void apply(const HLAInt32DataType& dataType) { }
93     virtual void apply(const HLAUInt32DataType& dataType) { }
94     virtual void apply(const HLAInt64DataType& dataType) { }
95     virtual void apply(const HLAUInt64DataType& dataType) { }
96     virtual void apply(const HLAFloat32DataType& dataType) { }
97     virtual void apply(const HLAFloat64DataType& dataType) { }
98
99     virtual void apply(const HLAFixedArrayDataType& dataType)
100     {
101         if (!dataType.getElementDataType())
102             _valid = false;
103         else
104             dataType.getElementDataType()->accept(*this);
105     }
106     virtual void apply(const HLAVariableArrayDataType& dataType)
107     {
108         if (!dataType.getElementDataType())
109             _valid = false;
110         else
111             dataType.getElementDataType()->accept(*this);
112
113         if (!dataType.getSizeDataType())
114             _valid = false;
115         else
116             dataType.getSizeDataType()->accept(*this);
117     }
118
119     virtual void apply(const HLAEnumeratedDataType& dataType)
120     {
121         if (!dataType.getRepresentation())
122             _valid = false;
123         else
124             dataType.getRepresentation()->accept(*this);
125     }
126
127     virtual void apply(const HLAFixedRecordDataType& dataType)
128     {
129         unsigned numFields = dataType.getNumFields();
130         for (unsigned i = 0; i < numFields; ++i) {
131             if (!dataType.getFieldDataType(i))
132                 _valid = false;
133             else
134                 dataType.getFieldDataType(i)->accept(*this);
135         }
136     }
137
138     virtual void apply(const HLAVariantRecordDataType& dataType)
139     { assert(0); }
140
141 protected:
142     bool _valid;
143 };
144
145 class HLADataTypeDecodeVisitor : public HLADataTypeVisitor {
146 public:
147     HLADataTypeDecodeVisitor(HLADecodeStream& stream) : _stream(stream) {}
148     virtual ~HLADataTypeDecodeVisitor() {}
149
150     virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
151     virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
152     virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
153     virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
154     virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
155     virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
156     virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
157     virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
158     virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
159     virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
160
161     virtual void apply(const HLAFixedArrayDataType& dataType)
162     {
163         unsigned numElements = dataType.getNumElements();
164         for (unsigned i = 0; i < numElements; ++i)
165             dataType.getElementDataType()->accept(*this);
166     }
167     virtual void apply(const HLAVariableArrayDataType& dataType);
168
169     virtual void apply(const HLAEnumeratedDataType& dataType)
170     {
171         dataType.getRepresentation()->accept(*this);
172     }
173
174     virtual void apply(const HLAFixedRecordDataType& dataType)
175     {
176         unsigned numFields = dataType.getNumFields();
177         for (unsigned i = 0; i < numFields; ++i)
178             dataType.getFieldDataType(i)->accept(*this);
179     }
180
181     virtual void apply(const HLAVariantRecordDataType& dataType) { assert(0); }
182
183 protected:
184     HLADecodeStream& _stream;
185 };
186
187 class HLADataTypeEncodeVisitor : public HLADataTypeVisitor {
188 public:
189     HLADataTypeEncodeVisitor(HLAEncodeStream& stream) : _stream(stream) {}
190     virtual ~HLADataTypeEncodeVisitor() {}
191
192     virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
193     virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
194     virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
195     virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
196     virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
197     virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
198     virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
199     virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
200     virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
201     virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
202
203     virtual void apply(const HLAFixedArrayDataType& dataType)
204     {
205         /// FIXME, might vanish in this sense ...
206         // dataType.encode(_stream, *this);
207         unsigned numElements = dataType.getNumElements();
208         for (unsigned i = 0; i < numElements; ++i)
209             dataType.getElementDataType()->accept(*this);
210     }
211     virtual void apply(const HLAVariableArrayDataType& dataType);
212
213     virtual void apply(const HLAEnumeratedDataType& dataType)
214     {
215         dataType.getRepresentation()->accept(*this);
216     }
217
218     virtual void apply(const HLAFixedRecordDataType& dataType)
219     {
220         unsigned numFields = dataType.getNumFields();
221         for (unsigned i = 0; i < numFields; ++i)
222             dataType.getFieldDataType(i)->accept(*this);
223     }
224
225     virtual void apply(const HLAVariantRecordDataType& dataType) { assert(0); }
226
227 protected:
228     HLAEncodeStream& _stream;
229 };
230
231 /// Begin implementation of some get/set visitors
232
233 class HLAScalarDecodeVisitor : public HLADataTypeDecodeVisitor {
234 public:
235     HLAScalarDecodeVisitor(HLADecodeStream& stream) :
236         HLADataTypeDecodeVisitor(stream)
237     {}
238
239     virtual void apply(const HLAFixedArrayDataType& dataType)
240     {
241         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
242         HLADataTypeDecodeVisitor::apply(dataType);
243     }
244     virtual void apply(const HLAVariableArrayDataType& dataType)
245     {
246         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
247         HLADataTypeDecodeVisitor::apply(dataType);
248     }
249
250     virtual void apply(const HLAEnumeratedDataType& dataType)
251     {
252         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
253         HLADataTypeDecodeVisitor::apply(dataType);
254     }
255
256     virtual void apply(const HLAFixedRecordDataType& dataType)
257     {
258         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
259         HLADataTypeDecodeVisitor::apply(dataType);
260     }
261
262     virtual void apply(const HLAVariantRecordDataType& dataType)
263     {
264         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
265         HLADataTypeDecodeVisitor::apply(dataType);
266     }
267 };
268
269 class HLAScalarEncodeVisitor : public HLADataTypeEncodeVisitor {
270 public:
271     HLAScalarEncodeVisitor(HLAEncodeStream& stream) :
272         HLADataTypeEncodeVisitor(stream)
273     {}
274
275     virtual void apply(const HLAFixedArrayDataType& dataType)
276     {
277         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
278         HLADataTypeEncodeVisitor::apply(dataType);
279     }
280     virtual void apply(const HLAVariableArrayDataType& dataType)
281     {
282         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
283         HLADataTypeEncodeVisitor::apply(dataType);
284     }
285
286     virtual void apply(const HLAEnumeratedDataType& dataType)
287     {
288         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
289         HLADataTypeEncodeVisitor::apply(dataType);
290     }
291
292     virtual void apply(const HLAFixedRecordDataType& dataType)
293     {
294         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
295         HLADataTypeEncodeVisitor::apply(dataType);
296     }
297
298     virtual void apply(const HLAVariantRecordDataType& dataType)
299     {
300         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
301         HLADataTypeEncodeVisitor::apply(dataType);
302     }
303 };
304
305 class HLAFixedRecordDecodeVisitor : public HLADataTypeDecodeVisitor {
306 public:
307     HLAFixedRecordDecodeVisitor(HLADecodeStream& stream) :
308         HLADataTypeDecodeVisitor(stream)
309     { }
310
311     virtual void apply(const HLAInt8DataType& dataType)
312     {
313         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
314         HLADataTypeDecodeVisitor::apply(dataType);
315     }
316     virtual void apply(const HLAUInt8DataType& dataType)
317     {
318         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
319         HLADataTypeDecodeVisitor::apply(dataType);
320     }
321     virtual void apply(const HLAInt16DataType& dataType)
322     {
323         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
324         HLADataTypeDecodeVisitor::apply(dataType);
325     }
326     virtual void apply(const HLAUInt16DataType& dataType)
327     {
328         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
329         HLADataTypeDecodeVisitor::apply(dataType);
330     }
331     virtual void apply(const HLAInt32DataType& dataType)
332     {
333         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
334         HLADataTypeDecodeVisitor::apply(dataType);
335     }
336     virtual void apply(const HLAUInt32DataType& dataType)
337     {
338         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
339         HLADataTypeDecodeVisitor::apply(dataType);
340     }
341     virtual void apply(const HLAInt64DataType& dataType)
342     {
343         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
344         HLADataTypeDecodeVisitor::apply(dataType);
345     }
346     virtual void apply(const HLAUInt64DataType& dataType)
347     {
348         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
349         HLADataTypeDecodeVisitor::apply(dataType);
350     }
351     virtual void apply(const HLAFloat32DataType& dataType)
352     {
353         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
354         HLADataTypeDecodeVisitor::apply(dataType);
355     }
356     virtual void apply(const HLAFloat64DataType& dataType)
357     {
358         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
359         HLADataTypeDecodeVisitor::apply(dataType);
360     }
361
362     virtual void apply(const HLAFixedArrayDataType& dataType)
363     {
364         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
365         HLADataTypeDecodeVisitor::apply(dataType);
366     }
367     virtual void apply(const HLAVariableArrayDataType& dataType)
368     {
369         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
370         HLADataTypeDecodeVisitor::apply(dataType);
371     }
372
373     virtual void apply(const HLAEnumeratedDataType& dataType)
374     {
375         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
376         HLADataTypeDecodeVisitor::apply(dataType);
377     }
378
379     virtual void apply(const HLAVariantRecordDataType& dataType)
380     {
381         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
382         HLADataTypeDecodeVisitor::apply(dataType);
383     }
384 };
385
386 class HLAFixedRecordEncodeVisitor : public HLADataTypeEncodeVisitor {
387 public:
388     HLAFixedRecordEncodeVisitor(HLAEncodeStream& stream) :
389         HLADataTypeEncodeVisitor(stream)
390     { }
391
392     virtual void apply(const HLAInt8DataType& dataType)
393     {
394         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
395         HLADataTypeEncodeVisitor::apply(dataType);
396     }
397     virtual void apply(const HLAUInt8DataType& dataType)
398     {
399         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
400         HLADataTypeEncodeVisitor::apply(dataType);
401     }
402     virtual void apply(const HLAInt16DataType& dataType)
403     {
404         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
405         HLADataTypeEncodeVisitor::apply(dataType);
406     }
407     virtual void apply(const HLAUInt16DataType& dataType)
408     {
409         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
410         HLADataTypeEncodeVisitor::apply(dataType);
411     }
412     virtual void apply(const HLAInt32DataType& dataType)
413     {
414         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
415         HLADataTypeEncodeVisitor::apply(dataType);
416     }
417     virtual void apply(const HLAUInt32DataType& dataType)
418     {
419         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
420         HLADataTypeEncodeVisitor::apply(dataType);
421     }
422     virtual void apply(const HLAInt64DataType& dataType)
423     {
424         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
425         HLADataTypeEncodeVisitor::apply(dataType);
426     }
427     virtual void apply(const HLAUInt64DataType& dataType)
428     {
429         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
430         HLADataTypeEncodeVisitor::apply(dataType);
431     }
432     virtual void apply(const HLAFloat32DataType& dataType)
433     {
434         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
435         HLADataTypeEncodeVisitor::apply(dataType);
436     }
437     virtual void apply(const HLAFloat64DataType& dataType)
438     {
439         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
440         HLADataTypeEncodeVisitor::apply(dataType);
441     }
442
443     virtual void apply(const HLAFixedArrayDataType& dataType)
444     {
445         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
446         HLADataTypeEncodeVisitor::apply(dataType);
447     }
448     virtual void apply(const HLAVariableArrayDataType& dataType)
449     {
450         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
451         HLADataTypeEncodeVisitor::apply(dataType);
452     }
453
454     virtual void apply(const HLAEnumeratedDataType& dataType)
455     {
456         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
457         HLADataTypeEncodeVisitor::apply(dataType);
458     }
459
460     virtual void apply(const HLAVariantRecordDataType& dataType)
461     {
462         SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
463         HLADataTypeEncodeVisitor::apply(dataType);
464     }
465 };
466
467 template<typename T>
468 class HLATemplateDecodeVisitor : public HLAScalarDecodeVisitor {
469 public:
470     typedef T value_type;
471
472     HLATemplateDecodeVisitor(HLADecodeStream& stream, const value_type& value = value_type()) :
473         HLAScalarDecodeVisitor(stream),
474         _value(value)
475     {}
476
477     void setValue(const value_type& value)
478     { _value = value; }
479     const value_type& getValue() const
480     { return _value; }
481
482     virtual void apply(const HLAInt8DataType& dataType)
483     {
484         int8_t value = 0;
485         dataType.decode(_stream, value);
486         _value = value_type(value);
487     }
488     virtual void apply(const HLAUInt8DataType& dataType)
489     {
490         uint8_t value = 0;
491         dataType.decode(_stream, value);
492         _value = value_type(value);
493     }
494     virtual void apply(const HLAInt16DataType& dataType)
495     {
496         int16_t value = 0;
497         dataType.decode(_stream, value);
498         _value = value_type(value);
499     }
500     virtual void apply(const HLAUInt16DataType& dataType)
501     {
502         uint16_t value = 0;
503         dataType.decode(_stream, value);
504         _value = value_type(value);
505     }
506     virtual void apply(const HLAInt32DataType& dataType)
507     {
508         int32_t value = 0;
509         dataType.decode(_stream, value);
510         _value = value_type(value);
511     }
512     virtual void apply(const HLAUInt32DataType& dataType)
513     {
514         uint32_t value = 0;
515         dataType.decode(_stream, value);
516         _value = value_type(value);
517     }
518     virtual void apply(const HLAInt64DataType& dataType)
519     {
520         int64_t value = 0;
521         dataType.decode(_stream, value);
522         _value = value_type(value);
523     }
524     virtual void apply(const HLAUInt64DataType& dataType)
525     {
526         uint64_t value = 0;
527         dataType.decode(_stream, value);
528         _value = value_type(value);
529     }
530     virtual void apply(const HLAFloat32DataType& dataType)
531     {
532         float value = 0;
533         dataType.decode(_stream, value);
534         _value = value_type(value);
535     }
536     virtual void apply(const HLAFloat64DataType& dataType)
537     {
538         double value = 0;
539         dataType.decode(_stream, value);
540         _value = value_type(value);
541     }
542
543 private:
544     value_type _value;
545 };
546
547 template<typename T>
548 class HLATemplateEncodeVisitor : public HLAScalarEncodeVisitor {
549 public:
550     typedef T value_type;
551
552     HLATemplateEncodeVisitor(HLAEncodeStream& stream, const value_type& value = value_type()) :
553         HLAScalarEncodeVisitor(stream),
554         _value(value)
555     {}
556
557     void setValue(const value_type& value)
558     { _value = value; }
559     const value_type& getValue() const
560     { return _value; }
561
562     virtual void apply(const HLAInt8DataType& dataType)
563     {
564         dataType.encode(_stream, _value);
565     }
566     virtual void apply(const HLAUInt8DataType& dataType)
567     {
568         dataType.encode(_stream, _value);
569     }
570     virtual void apply(const HLAInt16DataType& dataType)
571     {
572         dataType.encode(_stream, _value);
573     }
574     virtual void apply(const HLAUInt16DataType& dataType)
575     {
576         dataType.encode(_stream, _value);
577     }
578     virtual void apply(const HLAInt32DataType& dataType)
579     {
580         dataType.encode(_stream, _value);
581     }
582     virtual void apply(const HLAUInt32DataType& dataType)
583     {
584         dataType.encode(_stream, _value);
585     }
586     virtual void apply(const HLAInt64DataType& dataType)
587     {
588         dataType.encode(_stream, _value);
589     }
590     virtual void apply(const HLAUInt64DataType& dataType)
591     {
592         dataType.encode(_stream, _value);
593     }
594     virtual void apply(const HLAFloat32DataType& dataType)
595     {
596         dataType.encode(_stream, _value);
597     }
598     virtual void apply(const HLAFloat64DataType& dataType)
599     {
600         dataType.encode(_stream, _value);
601     }
602
603 private:
604     value_type _value;
605 };
606
607 inline void HLADataTypeDecodeVisitor::apply(const HLAVariableArrayDataType& dataType)
608 {
609     HLATemplateDecodeVisitor<unsigned> numElementsVisitor(_stream);
610     dataType.getSizeDataType()->accept(numElementsVisitor);
611     unsigned numElements = numElementsVisitor.getValue();
612     for (unsigned i = 0; i < numElements; ++i)
613         dataType.getElementDataType()->accept(*this);
614 }
615
616 inline void HLADataTypeEncodeVisitor::apply(const HLAVariableArrayDataType& dataType)
617 {
618     HLATemplateEncodeVisitor<unsigned> numElementsVisitor(_stream, 0);
619     dataType.getSizeDataType()->accept(numElementsVisitor);
620 }
621
622 /// Generate standard data elements according to the traversed type
623 class HLADataElementFactoryVisitor : public HLADataTypeVisitor {
624 public:
625     virtual ~HLADataElementFactoryVisitor();
626
627     virtual void apply(const HLADataType& dataType);
628
629     virtual void apply(const HLAInt8DataType& dataType);
630     virtual void apply(const HLAUInt8DataType& dataType);
631     virtual void apply(const HLAInt16DataType& dataType);
632     virtual void apply(const HLAUInt16DataType& dataType);
633     virtual void apply(const HLAInt32DataType& dataType);
634     virtual void apply(const HLAUInt32DataType& dataType);
635     virtual void apply(const HLAInt64DataType& dataType);
636     virtual void apply(const HLAUInt64DataType& dataType);
637     virtual void apply(const HLAFloat32DataType& dataType);
638     virtual void apply(const HLAFloat64DataType& dataType);
639
640     virtual void apply(const HLAFixedArrayDataType& dataType);
641     virtual void apply(const HLAVariableArrayDataType& dataType);
642
643     virtual void apply(const HLAEnumeratedDataType& dataType);
644
645     virtual void apply(const HLAFixedRecordDataType& dataType);
646
647     virtual void apply(const HLAVariantRecordDataType& dataType);
648
649     HLADataElement* getDataElement()
650     { return _dataElement.release(); }
651
652 protected:
653     class ArrayDataElementFactory;
654     class VariantRecordDataElementFactory;
655
656     SGSharedPtr<HLADataElement> _dataElement;
657 };
658
659 } // namespace simgear
660
661 #endif