]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAArrayDataElement.hxx
hla: Fix buffer overrun in SGMath vector types.
[simgear.git] / simgear / hla / HLAArrayDataElement.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 HLAArrayDataElement_hxx
19 #define HLAArrayDataElement_hxx
20
21 #include <string>
22 #include <vector>
23 #include <simgear/math/SGMath.hxx>
24 #include "HLAArrayDataType.hxx"
25 #include "HLADataElement.hxx"
26 #include "HLAVariantRecordDataElement.hxx"
27 #include "HLADataTypeVisitor.hxx"
28
29 namespace simgear {
30
31 class HLAAbstractArrayDataElement : public HLADataElement {
32 public:
33     HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
34     virtual ~HLAAbstractArrayDataElement();
35
36     virtual void accept(HLADataElementVisitor& visitor);
37     virtual void accept(HLAConstDataElementVisitor& visitor) const;
38
39     virtual bool decode(HLADecodeStream& stream);
40     virtual bool encode(HLAEncodeStream& stream) const;
41
42     virtual const HLAArrayDataType* getDataType() const;
43     virtual bool setDataType(const HLADataType* dataType);
44
45     const HLADataType* getElementDataType() const;
46
47     virtual bool setNumElements(unsigned count) = 0;
48     virtual bool decodeElement(HLADecodeStream& stream, unsigned i) = 0;
49
50     virtual unsigned getNumElements() const = 0;
51     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const = 0;
52
53 protected:
54     SGSharedPtr<const HLAArrayDataType> _dataType;
55 };
56
57 class HLAArrayDataElement : public HLAAbstractArrayDataElement {
58 public:
59     HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
60     virtual ~HLAArrayDataElement();
61
62     virtual bool setNumElements(unsigned size);
63     virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
64     virtual unsigned getNumElements() const;
65     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
66
67     const HLADataElement* getElement(unsigned index) const;
68     HLADataElement* getElement(unsigned index);
69     HLADataElement* getOrCreateElement(unsigned index);
70     void setElement(unsigned i, HLADataElement* value);
71
72     class DataElementFactory : public SGReferenced {
73     public:
74         virtual ~DataElementFactory();
75         virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
76     };
77
78     void setDataElementFactory(DataElementFactory* dataElementFactory);
79     DataElementFactory* getDataElementFactory();
80
81 private:
82     HLADataElement* newElement(unsigned index);
83
84     typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
85     ElementVector _elementVector;
86
87     SGSharedPtr<DataElementFactory> _dataElementFactory;
88 };
89
90 // Holds an array of variants.
91 // Factors out common code for that use case.
92 class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
93 public:
94     HLAVariantArrayDataElement();
95     virtual ~HLAVariantArrayDataElement();
96
97     // Overwrite this from the abstract class, need some more checks here
98     virtual bool setDataType(const HLADataType* dataType);
99
100     virtual bool setNumElements(unsigned size);
101     virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
102     virtual unsigned getNumElements() const;
103     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
104
105     const HLAVariantRecordDataElement* getElement(unsigned index) const;
106     HLAVariantRecordDataElement* getElement(unsigned index);
107     HLAVariantRecordDataElement* getOrCreateElement(unsigned index);
108     void setElement(unsigned index, HLAVariantRecordDataElement* value);
109
110     typedef HLAVariantRecordDataElement::DataElementFactory AlternativeDataElementFactory;
111
112     void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
113     AlternativeDataElementFactory* getAlternativeDataElementFactory();
114
115 private:
116     HLAVariantRecordDataElement* newElement();
117
118     typedef std::vector<SGSharedPtr<HLAVariantRecordDataElement> > ElementVector;
119     ElementVector _elementVector;
120
121     SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
122 };
123
124 class HLAStringDataElement : public HLAAbstractArrayDataElement {
125 public:
126     HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
127         HLAAbstractArrayDataElement(dataType)
128     {}
129     HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
130         HLAAbstractArrayDataElement(dataType),
131         _value(value)
132     {}
133     const std::string& getValue() const
134     { return _value; }
135     void setValue(const std::string& value)
136     { _value = value; }
137
138     virtual bool setNumElements(unsigned count)
139     {
140         _value.resize(count);
141         return true;
142     }
143     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
144     {
145         HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
146         getElementDataType()->accept(visitor);
147         _value[i] = visitor.getValue();
148         return true;
149     }
150
151     virtual unsigned getNumElements() const
152     {
153         return _value.size();
154     }
155     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
156     {
157         HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
158         getElementDataType()->accept(visitor);
159         return true;
160     }
161
162 private:
163     std::string _value;
164 };
165
166 class HLAStringData {
167 public:
168     HLAStringData() :
169         _value(new HLAStringDataElement(0))
170     { }
171     HLAStringData(const std::string& value) :
172         _value(new HLAStringDataElement(0))
173     { _value->setValue(value); }
174
175     operator const std::string&() const
176     { return _value->getValue(); }
177     HLAStringData& operator=(const std::string& value)
178     { _value->setValue(value); return *this; }
179
180     const std::string& getValue() const
181     { return _value->getValue(); }
182     void setValue(const std::string& value)
183     { _value->setValue(value); }
184
185     const HLAStringDataElement* getDataElement() const
186     { return _value.get(); }
187     HLAStringDataElement* getDataElement()
188     { return _value.get(); }
189
190     const HLAArrayDataType* getDataType() const
191     { return _value->getDataType(); }
192     void setDataType(const HLAArrayDataType* dataType)
193     { _value->setDataType(dataType); }
194
195 private:
196     SGSharedPtr<HLAStringDataElement> _value;
197 };
198
199 template<typename T>
200 class HLAVec2DataElement : public HLAAbstractArrayDataElement {
201 public:
202     HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
203         HLAAbstractArrayDataElement(dataType),
204         _value(SGVec2<T>::zeros())
205     {}
206     HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
207         HLAAbstractArrayDataElement(dataType),
208         _value(value)
209     {}
210     const SGVec2<T>& getValue() const
211     { return _value; }
212     void setValue(const SGVec2<T>& value)
213     { _value = value; }
214
215     virtual bool setNumElements(unsigned count)
216     {
217         for (unsigned i = count; i < 2; ++i)
218             _value[i] = 0;
219         return true;
220     }
221     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
222     {
223         if (i < 2) {
224             HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
225             getElementDataType()->accept(visitor);
226             _value[i] = visitor.getValue();
227         } else {
228             HLADataTypeDecodeVisitor visitor(stream);
229             getElementDataType()->accept(visitor);
230         }
231         return true;
232     }
233
234     virtual unsigned getNumElements() const
235     {
236         return 2;
237     }
238     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
239     {
240         if (i < 2) {
241             HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
242             getElementDataType()->accept(visitor);
243         } else {
244             HLADataTypeEncodeVisitor visitor(stream);
245             getElementDataType()->accept(visitor);
246         }
247         return true;
248     }
249
250 private:
251     SGVec2<T> _value;
252 };
253
254 template<typename T>
255 class HLAVec2Data {
256 public:
257     HLAVec2Data() :
258         _value(new HLAVec2DataElement<T>(0))
259     { }
260     HLAVec2Data(const SGVec2<T>& value) :
261         _value(new HLAVec2DataElement<T>(0, value))
262     { }
263
264     operator const SGVec2<T>&() const
265     { return _value->getValue(); }
266     HLAVec2Data& operator=(const SGVec2<T>& value)
267     { _value->setValue(value); return *this; }
268
269     const SGVec2<T>& getValue() const
270     { return _value->getValue(); }
271     void setValue(const SGVec2<T>& value)
272     { _value->setValue(value); }
273
274     const HLAVec2DataElement<T>* getDataElement() const
275     { return _value.get(); }
276     HLAVec2DataElement<T>* getDataElement()
277     { return _value.get(); }
278
279     const HLAArrayDataType* getDataType() const
280     { return _value->getDataType(); }
281     void setDataType(const HLAArrayDataType* dataType)
282     { _value->setDataType(dataType); }
283
284 private:
285     SGSharedPtr<HLAVec2DataElement<T> > _value;
286 };
287
288 typedef HLAVec2Data<float> HLAVec2fData;
289 typedef HLAVec2Data<double> HLAVec2dData;
290
291 template<typename T>
292 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
293 public:
294     HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
295         HLAAbstractArrayDataElement(dataType),
296         _value(SGVec3<T>::zeros())
297     {}
298     HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
299         HLAAbstractArrayDataElement(dataType),
300         _value(value)
301     {}
302     const SGVec3<T>& getValue() const
303     { return _value; }
304     void setValue(const SGVec3<T>& value)
305     { _value = value; }
306
307     virtual bool setNumElements(unsigned count)
308     {
309         for (unsigned i = count; i < 3; ++i)
310             _value[i] = 0;
311         return true;
312     }
313     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
314     {
315         if (i < 3) {
316             HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
317             getElementDataType()->accept(visitor);
318             _value[i] = visitor.getValue();
319         } else {
320             HLADataTypeDecodeVisitor visitor(stream);
321             getElementDataType()->accept(visitor);
322         }
323         return true;
324     }
325
326     virtual unsigned getNumElements() const
327     {
328         return 3;
329     }
330     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
331     {
332         if (i < 3) {
333             HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
334             getElementDataType()->accept(visitor);
335         } else {
336             HLADataTypeEncodeVisitor visitor(stream);
337             getElementDataType()->accept(visitor);
338         }
339         return true;
340     }
341
342 private:
343     SGVec3<T> _value;
344 };
345
346 template<typename T>
347 class HLAVec3Data {
348 public:
349     HLAVec3Data() :
350         _value(new HLAVec3DataElement<T>(0))
351     { }
352     HLAVec3Data(const SGVec3<T>& value) :
353         _value(new HLAVec3DataElement<T>(0, value))
354     { }
355
356     operator const SGVec3<T>&() const
357     { return _value->getValue(); }
358     HLAVec3Data& operator=(const SGVec3<T>& value)
359     { _value->setValue(value); return *this; }
360
361     const SGVec3<T>& getValue() const
362     { return _value->getValue(); }
363     void setValue(const SGVec3<T>& value)
364     { _value->setValue(value); }
365
366     const HLAVec3DataElement<T>* getDataElement() const
367     { return _value.get(); }
368     HLAVec3DataElement<T>* getDataElement()
369     { return _value.get(); }
370
371     const HLAArrayDataType* getDataType() const
372     { return _value->getDataType(); }
373     void setDataType(const HLAArrayDataType* dataType)
374     { _value->setDataType(dataType); }
375
376 private:
377     SGSharedPtr<HLAVec3DataElement<T> > _value;
378 };
379
380 typedef HLAVec3Data<float> HLAVec3fData;
381 typedef HLAVec3Data<double> HLAVec3dData;
382
383 template<typename T>
384 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
385 public:
386     HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
387         HLAAbstractArrayDataElement(dataType),
388         _value(SGVec4<T>::zeros())
389     {}
390     HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
391         HLAAbstractArrayDataElement(dataType),
392         _value(value)
393     {}
394     const SGVec4<T>& getValue() const
395     { return _value; }
396     void setValue(const SGVec4<T>& value)
397     { _value = value; }
398
399     virtual bool setNumElements(unsigned count)
400     {
401         for (unsigned i = count; i < 4; ++i)
402             _value[i] = 0;
403         return true;
404     }
405     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
406     {
407         if (i < 4) {
408             HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
409             getElementDataType()->accept(visitor);
410             _value[i] = visitor.getValue();
411         } else {
412             HLADataTypeDecodeVisitor visitor(stream);
413             getElementDataType()->accept(visitor);
414         }
415         return true;
416     }
417
418     virtual unsigned getNumElements() const
419     {
420         return 4;
421     }
422     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
423     {
424         if (i < 4) {
425             HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
426             getElementDataType()->accept(visitor);
427         } else {
428             HLADataTypeEncodeVisitor visitor(stream);
429             getElementDataType()->accept(visitor);
430         }
431         return true;
432     }
433
434 private:
435     SGVec4<T> _value;
436 };
437
438 template<typename T>
439 class HLAVec4Data {
440 public:
441     HLAVec4Data() :
442         _value(new HLAVec4DataElement<T>(0))
443     { }
444     HLAVec4Data(const SGVec4<T>& value) :
445         _value(new HLAVec4DataElement<T>(0, value))
446     { }
447
448     operator const SGVec4<T>&() const
449     { return _value->getValue(); }
450     HLAVec4Data& operator=(const SGVec4<T>& value)
451     { _value->setValue(value); return *this; }
452
453     const SGVec4<T>& getValue() const
454     { return _value->getValue(); }
455     void setValue(const SGVec4<T>& value)
456     { _value->setValue(value); }
457
458     const HLAVec4DataElement<T>* getDataElement() const
459     { return _value.get(); }
460     HLAVec4DataElement<T>* getDataElement()
461     { return _value.get(); }
462
463     const HLAArrayDataType* getDataType() const
464     { return _value->getDataType(); }
465     void setDataType(const HLAArrayDataType* dataType)
466     { _value->setDataType(dataType); }
467
468 private:
469     SGSharedPtr<HLAVec4DataElement<T> > _value;
470 };
471
472 typedef HLAVec4Data<float> HLAVec4fData;
473 typedef HLAVec4Data<double> HLAVec4dData;
474
475 template<typename T>
476 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
477 public:
478     HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
479         HLAAbstractArrayDataElement(dataType),
480         _value(SGQuat<T>::zeros())
481     {}
482     HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
483         HLAAbstractArrayDataElement(dataType),
484         _value(value)
485     {}
486     const SGQuat<T>& getValue() const
487     { return _value; }
488     void setValue(const SGQuat<T>& value)
489     { _value = value; }
490
491     virtual bool setNumElements(unsigned count)
492     {
493         for (unsigned i = count; i < 4; ++i)
494             _value[i] = 0;
495         return true;
496     }
497     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
498     {
499         if (i < 4) {
500             HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
501             getElementDataType()->accept(visitor);
502             _value[i] = visitor.getValue();
503         } else {
504             HLADataTypeDecodeVisitor visitor(stream);
505             getElementDataType()->accept(visitor);
506         }
507         return true;
508     }
509
510     virtual unsigned getNumElements() const
511     {
512         return 4;
513     }
514     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
515     {
516         if (i < 4) {
517             HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
518             getElementDataType()->accept(visitor);
519         } else {
520             HLADataTypeEncodeVisitor visitor(stream);
521             getElementDataType()->accept(visitor);
522         }
523         return true;
524     }
525
526 private:
527     SGQuat<T> _value;
528 };
529
530 }
531
532 #endif