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:
~HLADataTypeVisitor()36     virtual ~HLADataTypeVisitor() {}
37 
apply(const HLADataType & dataType)38     virtual void apply(const HLADataType& dataType)
39     { }
40 
apply(const HLABasicDataType & dataType)41     virtual void apply(const HLABasicDataType& dataType)
42     { apply(static_cast<const HLADataType&>(dataType)); }
apply(const HLAInt8DataType & dataType)43     virtual void apply(const HLAInt8DataType& dataType)
44     { apply(static_cast<const HLABasicDataType&>(dataType)); }
apply(const HLAUInt8DataType & dataType)45     virtual void apply(const HLAUInt8DataType& dataType)
46     { apply(static_cast<const HLABasicDataType&>(dataType)); }
apply(const HLAInt16DataType & dataType)47     virtual void apply(const HLAInt16DataType& dataType)
48     { apply(static_cast<const HLABasicDataType&>(dataType)); }
apply(const HLAUInt16DataType & dataType)49     virtual void apply(const HLAUInt16DataType& dataType)
50     { apply(static_cast<const HLABasicDataType&>(dataType)); }
apply(const HLAInt32DataType & dataType)51     virtual void apply(const HLAInt32DataType& dataType)
52     { apply(static_cast<const HLABasicDataType&>(dataType)); }
apply(const HLAUInt32DataType & dataType)53     virtual void apply(const HLAUInt32DataType& dataType)
54     { apply(static_cast<const HLABasicDataType&>(dataType)); }
apply(const HLAInt64DataType & dataType)55     virtual void apply(const HLAInt64DataType& dataType)
56     { apply(static_cast<const HLABasicDataType&>(dataType)); }
apply(const HLAUInt64DataType & dataType)57     virtual void apply(const HLAUInt64DataType& dataType)
58     { apply(static_cast<const HLABasicDataType&>(dataType)); }
apply(const HLAFloat32DataType & dataType)59     virtual void apply(const HLAFloat32DataType& dataType)
60     { apply(static_cast<const HLABasicDataType&>(dataType)); }
apply(const HLAFloat64DataType & dataType)61     virtual void apply(const HLAFloat64DataType& dataType)
62     { apply(static_cast<const HLABasicDataType&>(dataType)); }
63 
apply(const HLAArrayDataType & dataType)64     virtual void apply(const HLAArrayDataType& dataType)
65     { apply(static_cast<const HLADataType&>(dataType)); }
apply(const HLAFixedArrayDataType & dataType)66     virtual void apply(const HLAFixedArrayDataType& dataType)
67     { apply(static_cast<const HLAArrayDataType&>(dataType)); }
apply(const HLAVariableArrayDataType & dataType)68     virtual void apply(const HLAVariableArrayDataType& dataType)
69     { apply(static_cast<const HLAArrayDataType&>(dataType)); }
70 
apply(const HLAEnumeratedDataType & dataType)71     virtual void apply(const HLAEnumeratedDataType& dataType)
72     { apply(static_cast<const HLADataType&>(dataType)); }
73 
apply(const HLAFixedRecordDataType & dataType)74     virtual void apply(const HLAFixedRecordDataType& dataType)
75     { apply(static_cast<const HLADataType&>(dataType)); }
76 
apply(const HLAVariantRecordDataType & dataType)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:
HLADataTypeCheckVisitor()84     HLADataTypeCheckVisitor() : _valid(true) {}
85 
valid() const86     bool valid() const { return _valid; }
87 
apply(const HLAInt8DataType & dataType)88     virtual void apply(const HLAInt8DataType& dataType) { }
apply(const HLAUInt8DataType & dataType)89     virtual void apply(const HLAUInt8DataType& dataType) { }
apply(const HLAInt16DataType & dataType)90     virtual void apply(const HLAInt16DataType& dataType) { }
apply(const HLAUInt16DataType & dataType)91     virtual void apply(const HLAUInt16DataType& dataType) { }
apply(const HLAInt32DataType & dataType)92     virtual void apply(const HLAInt32DataType& dataType) { }
apply(const HLAUInt32DataType & dataType)93     virtual void apply(const HLAUInt32DataType& dataType) { }
apply(const HLAInt64DataType & dataType)94     virtual void apply(const HLAInt64DataType& dataType) { }
apply(const HLAUInt64DataType & dataType)95     virtual void apply(const HLAUInt64DataType& dataType) { }
apply(const HLAFloat32DataType & dataType)96     virtual void apply(const HLAFloat32DataType& dataType) { }
apply(const HLAFloat64DataType & dataType)97     virtual void apply(const HLAFloat64DataType& dataType) { }
98 
apply(const HLAFixedArrayDataType & dataType)99     virtual void apply(const HLAFixedArrayDataType& dataType)
100     {
101         if (!dataType.getElementDataType())
102             _valid = false;
103         else
104             dataType.getElementDataType()->accept(*this);
105     }
apply(const HLAVariableArrayDataType & dataType)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 
apply(const HLAEnumeratedDataType & dataType)119     virtual void apply(const HLAEnumeratedDataType& dataType)
120     {
121         if (!dataType.getRepresentation())
122             _valid = false;
123         else
124             dataType.getRepresentation()->accept(*this);
125     }
126 
apply(const HLAFixedRecordDataType & dataType)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 
apply(const HLAVariantRecordDataType & dataType)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:
HLADataTypeDecodeVisitor(HLADecodeStream & stream)147     HLADataTypeDecodeVisitor(HLADecodeStream& stream) : _stream(stream) {}
~HLADataTypeDecodeVisitor()148     virtual ~HLADataTypeDecodeVisitor() {}
149 
apply(const HLAInt8DataType & dataType)150     virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
apply(const HLAUInt8DataType & dataType)151     virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
apply(const HLAInt16DataType & dataType)152     virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
apply(const HLAUInt16DataType & dataType)153     virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
apply(const HLAInt32DataType & dataType)154     virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
apply(const HLAUInt32DataType & dataType)155     virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
apply(const HLAInt64DataType & dataType)156     virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
apply(const HLAUInt64DataType & dataType)157     virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
apply(const HLAFloat32DataType & dataType)158     virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
apply(const HLAFloat64DataType & dataType)159     virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
160 
apply(const HLAFixedArrayDataType & dataType)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 
apply(const HLAEnumeratedDataType & dataType)169     virtual void apply(const HLAEnumeratedDataType& dataType)
170     {
171         dataType.getRepresentation()->accept(*this);
172     }
173 
apply(const HLAFixedRecordDataType & dataType)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 
apply(const HLAVariantRecordDataType & dataType)181     virtual void apply(const HLAVariantRecordDataType& dataType) { assert(0); }
182 
183 protected:
184     HLADecodeStream& _stream;
185 };
186 
187 class HLADataTypeEncodeVisitor : public HLADataTypeVisitor {
188 public:
HLADataTypeEncodeVisitor(HLAEncodeStream & stream)189     HLADataTypeEncodeVisitor(HLAEncodeStream& stream) : _stream(stream) {}
~HLADataTypeEncodeVisitor()190     virtual ~HLADataTypeEncodeVisitor() {}
191 
apply(const HLAInt8DataType & dataType)192     virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
apply(const HLAUInt8DataType & dataType)193     virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
apply(const HLAInt16DataType & dataType)194     virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
apply(const HLAUInt16DataType & dataType)195     virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
apply(const HLAInt32DataType & dataType)196     virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
apply(const HLAUInt32DataType & dataType)197     virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
apply(const HLAInt64DataType & dataType)198     virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
apply(const HLAUInt64DataType & dataType)199     virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
apply(const HLAFloat32DataType & dataType)200     virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
apply(const HLAFloat64DataType & dataType)201     virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
202 
apply(const HLAFixedArrayDataType & dataType)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 
apply(const HLAEnumeratedDataType & dataType)213     virtual void apply(const HLAEnumeratedDataType& dataType)
214     {
215         dataType.getRepresentation()->accept(*this);
216     }
217 
apply(const HLAFixedRecordDataType & dataType)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 
apply(const HLAVariantRecordDataType & dataType)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:
HLAScalarDecodeVisitor(HLADecodeStream & stream)235     HLAScalarDecodeVisitor(HLADecodeStream& stream) :
236         HLADataTypeDecodeVisitor(stream)
237     {}
238 
apply(const HLAFixedArrayDataType & dataType)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     }
apply(const HLAVariableArrayDataType & dataType)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 
apply(const HLAEnumeratedDataType & dataType)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 
apply(const HLAFixedRecordDataType & dataType)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 
apply(const HLAVariantRecordDataType & dataType)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:
HLAScalarEncodeVisitor(HLAEncodeStream & stream)271     HLAScalarEncodeVisitor(HLAEncodeStream& stream) :
272         HLADataTypeEncodeVisitor(stream)
273     {}
274 
apply(const HLAFixedArrayDataType & dataType)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     }
apply(const HLAVariableArrayDataType & dataType)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 
apply(const HLAEnumeratedDataType & dataType)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 
apply(const HLAFixedRecordDataType & dataType)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 
apply(const HLAVariantRecordDataType & dataType)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:
HLAFixedRecordDecodeVisitor(HLADecodeStream & stream)307     HLAFixedRecordDecodeVisitor(HLADecodeStream& stream) :
308         HLADataTypeDecodeVisitor(stream)
309     { }
310 
apply(const HLAInt8DataType & dataType)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     }
apply(const HLAUInt8DataType & dataType)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     }
apply(const HLAInt16DataType & dataType)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     }
apply(const HLAUInt16DataType & dataType)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     }
apply(const HLAInt32DataType & dataType)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     }
apply(const HLAUInt32DataType & dataType)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     }
apply(const HLAInt64DataType & dataType)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     }
apply(const HLAUInt64DataType & dataType)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     }
apply(const HLAFloat32DataType & dataType)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     }
apply(const HLAFloat64DataType & dataType)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 
apply(const HLAFixedArrayDataType & dataType)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     }
apply(const HLAVariableArrayDataType & dataType)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 
apply(const HLAEnumeratedDataType & dataType)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 
apply(const HLAVariantRecordDataType & dataType)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:
HLAFixedRecordEncodeVisitor(HLAEncodeStream & stream)388     HLAFixedRecordEncodeVisitor(HLAEncodeStream& stream) :
389         HLADataTypeEncodeVisitor(stream)
390     { }
391 
apply(const HLAInt8DataType & dataType)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     }
apply(const HLAUInt8DataType & dataType)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     }
apply(const HLAInt16DataType & dataType)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     }
apply(const HLAUInt16DataType & dataType)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     }
apply(const HLAInt32DataType & dataType)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     }
apply(const HLAUInt32DataType & dataType)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     }
apply(const HLAInt64DataType & dataType)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     }
apply(const HLAUInt64DataType & dataType)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     }
apply(const HLAFloat32DataType & dataType)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     }
apply(const HLAFloat64DataType & dataType)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 
apply(const HLAFixedArrayDataType & dataType)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     }
apply(const HLAVariableArrayDataType & dataType)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 
apply(const HLAEnumeratedDataType & dataType)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 
apply(const HLAVariantRecordDataType & dataType)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 
HLATemplateDecodeVisitor(HLADecodeStream & stream,const value_type & value=value_type ())472     HLATemplateDecodeVisitor(HLADecodeStream& stream, const value_type& value = value_type()) :
473         HLAScalarDecodeVisitor(stream),
474         _value(value)
475     {}
476 
setValue(const value_type & value)477     void setValue(const value_type& value)
478     { _value = value; }
getValue() const479     const value_type& getValue() const
480     { return _value; }
481 
apply(const HLAInt8DataType & dataType)482     virtual void apply(const HLAInt8DataType& dataType)
483     {
484         int8_t value = 0;
485         dataType.decode(_stream, value);
486         _value = value_type(value);
487     }
apply(const HLAUInt8DataType & dataType)488     virtual void apply(const HLAUInt8DataType& dataType)
489     {
490         uint8_t value = 0;
491         dataType.decode(_stream, value);
492         _value = value_type(value);
493     }
apply(const HLAInt16DataType & dataType)494     virtual void apply(const HLAInt16DataType& dataType)
495     {
496         int16_t value = 0;
497         dataType.decode(_stream, value);
498         _value = value_type(value);
499     }
apply(const HLAUInt16DataType & dataType)500     virtual void apply(const HLAUInt16DataType& dataType)
501     {
502         uint16_t value = 0;
503         dataType.decode(_stream, value);
504         _value = value_type(value);
505     }
apply(const HLAInt32DataType & dataType)506     virtual void apply(const HLAInt32DataType& dataType)
507     {
508         int32_t value = 0;
509         dataType.decode(_stream, value);
510         _value = value_type(value);
511     }
apply(const HLAUInt32DataType & dataType)512     virtual void apply(const HLAUInt32DataType& dataType)
513     {
514         uint32_t value = 0;
515         dataType.decode(_stream, value);
516         _value = value_type(value);
517     }
apply(const HLAInt64DataType & dataType)518     virtual void apply(const HLAInt64DataType& dataType)
519     {
520         int64_t value = 0;
521         dataType.decode(_stream, value);
522         _value = value_type(value);
523     }
apply(const HLAUInt64DataType & dataType)524     virtual void apply(const HLAUInt64DataType& dataType)
525     {
526         uint64_t value = 0;
527         dataType.decode(_stream, value);
528         _value = value_type(value);
529     }
apply(const HLAFloat32DataType & dataType)530     virtual void apply(const HLAFloat32DataType& dataType)
531     {
532         float value = 0;
533         dataType.decode(_stream, value);
534         _value = value_type(value);
535     }
apply(const HLAFloat64DataType & dataType)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 
HLATemplateEncodeVisitor(HLAEncodeStream & stream,const value_type & value=value_type ())552     HLATemplateEncodeVisitor(HLAEncodeStream& stream, const value_type& value = value_type()) :
553         HLAScalarEncodeVisitor(stream),
554         _value(value)
555     {}
556 
setValue(const value_type & value)557     void setValue(const value_type& value)
558     { _value = value; }
getValue() const559     const value_type& getValue() const
560     { return _value; }
561 
apply(const HLAInt8DataType & dataType)562     virtual void apply(const HLAInt8DataType& dataType)
563     {
564         dataType.encode(_stream, _value);
565     }
apply(const HLAUInt8DataType & dataType)566     virtual void apply(const HLAUInt8DataType& dataType)
567     {
568         dataType.encode(_stream, _value);
569     }
apply(const HLAInt16DataType & dataType)570     virtual void apply(const HLAInt16DataType& dataType)
571     {
572         dataType.encode(_stream, _value);
573     }
apply(const HLAUInt16DataType & dataType)574     virtual void apply(const HLAUInt16DataType& dataType)
575     {
576         dataType.encode(_stream, _value);
577     }
apply(const HLAInt32DataType & dataType)578     virtual void apply(const HLAInt32DataType& dataType)
579     {
580         dataType.encode(_stream, _value);
581     }
apply(const HLAUInt32DataType & dataType)582     virtual void apply(const HLAUInt32DataType& dataType)
583     {
584         dataType.encode(_stream, _value);
585     }
apply(const HLAInt64DataType & dataType)586     virtual void apply(const HLAInt64DataType& dataType)
587     {
588         dataType.encode(_stream, _value);
589     }
apply(const HLAUInt64DataType & dataType)590     virtual void apply(const HLAUInt64DataType& dataType)
591     {
592         dataType.encode(_stream, _value);
593     }
apply(const HLAFloat32DataType & dataType)594     virtual void apply(const HLAFloat32DataType& dataType)
595     {
596         dataType.encode(_stream, _value);
597     }
apply(const HLAFloat64DataType & dataType)598     virtual void apply(const HLAFloat64DataType& dataType)
599     {
600         dataType.encode(_stream, _value);
601     }
602 
603 private:
604     value_type _value;
605 };
606 
apply(const HLAVariableArrayDataType & dataType)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 
apply(const HLAVariableArrayDataType & dataType)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 
getDataElement()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
662