]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAArrayDataElement.cxx
hla: Fix buffer overrun in SGMath vector types.
[simgear.git] / simgear / hla / HLAArrayDataElement.cxx
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 #include "HLAArrayDataElement.hxx"
19
20 #include <simgear/debug/logstream.hxx>
21
22 #include "HLADataElementVisitor.hxx"
23
24 namespace simgear {
25
26 HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) :
27     _dataType(dataType)
28 {
29 }
30
31 HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement()
32 {
33 }
34
35 void
36 HLAAbstractArrayDataElement::accept(HLADataElementVisitor& visitor)
37 {
38     visitor.apply(*this);
39 }
40
41 void
42 HLAAbstractArrayDataElement::accept(HLAConstDataElementVisitor& visitor) const
43 {
44     visitor.apply(*this);
45 }
46
47 bool
48 HLAAbstractArrayDataElement::decode(HLADecodeStream& stream)
49 {
50     if (!_dataType.valid())
51         return false;
52     return _dataType->decode(stream, *this);
53 }
54
55 bool
56 HLAAbstractArrayDataElement::encode(HLAEncodeStream& stream) const
57 {
58     if (!_dataType.valid())
59         return false;
60     return _dataType->encode(stream, *this);
61 }
62
63 const HLAArrayDataType*
64 HLAAbstractArrayDataElement::getDataType() const
65 {
66     return _dataType.get();
67 }
68
69 bool
70 HLAAbstractArrayDataElement::setDataType(const HLADataType* dataType)
71 {
72     const HLAArrayDataType* arrayDataType = dynamic_cast<const HLAArrayDataType*>(dataType);
73     if (!arrayDataType) {
74         SG_LOG(SG_NETWORK, SG_WARN, "HLAArrayDataType: unable to set data type!");
75         return false;
76     }
77     _dataType = arrayDataType;
78     return true;
79 }
80
81 const HLADataType*
82 HLAAbstractArrayDataElement::getElementDataType() const
83 {
84     if (!_dataType.valid())
85         return 0;
86     return _dataType->getElementDataType();
87 }
88
89 ////////////////////////////////////////////////////////////////////////
90
91 HLAArrayDataElement::DataElementFactory::~DataElementFactory()
92 {
93 }
94
95 HLAArrayDataElement::HLAArrayDataElement(const HLAArrayDataType* dataType) :
96     HLAAbstractArrayDataElement(dataType)
97 {
98 }
99
100 HLAArrayDataElement::~HLAArrayDataElement()
101 {
102 }
103
104 bool
105 HLAArrayDataElement::setNumElements(unsigned size)
106 {
107     unsigned oldSize = _elementVector.size();
108     if (size == oldSize)
109         return true;
110     _elementVector.resize(size);
111     for (unsigned i = oldSize; i < size; ++i)
112         _elementVector[i] = newElement(i);
113     return true;
114 }
115
116 bool
117 HLAArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
118 {
119     HLADataElement* dataElement = getElement(i);
120     if (!dataElement)
121         return false;
122     return dataElement->decode(stream);
123 }
124
125 unsigned
126 HLAArrayDataElement::getNumElements() const
127 {
128     return _elementVector.size();
129 }
130
131 bool
132 HLAArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
133 {
134     const HLADataElement* dataElement = getElement(i);
135     if (!dataElement)
136         return false;
137     return dataElement->encode(stream);
138 }
139
140 const HLADataElement*
141 HLAArrayDataElement::getElement(unsigned index) const
142 {
143     if (_elementVector.size() <= index)
144         return 0;
145     return _elementVector[index].get();
146 }
147
148 HLADataElement*
149 HLAArrayDataElement::getElement(unsigned index)
150 {
151     if (_elementVector.size() <= index)
152         return 0;
153     return _elementVector[index].get();
154 }
155
156 HLADataElement*
157 HLAArrayDataElement::getOrCreateElement(unsigned index)
158 {
159     if (_elementVector.size() <= index)
160         if (!setNumElements(index + 1))
161             return 0;
162     return _elementVector[index].get();
163 }
164
165 void
166 HLAArrayDataElement::setElement(unsigned index, HLADataElement* value)
167 {
168     unsigned oldSize = _elementVector.size();
169     if (oldSize <= index) {
170         _elementVector.resize(index + 1);
171         for (unsigned j = oldSize; j < index; ++j)
172             _elementVector[j] = newElement(j);
173     }
174     _elementVector[index] = value;
175 }
176
177 void
178 HLAArrayDataElement::setDataElementFactory(HLAArrayDataElement::DataElementFactory* dataElementFactory)
179 {
180     _dataElementFactory = dataElementFactory;
181 }
182
183 HLAArrayDataElement::DataElementFactory*
184 HLAArrayDataElement::getDataElementFactory()
185 {
186     return _dataElementFactory.get();
187 }
188
189 HLADataElement*
190 HLAArrayDataElement::newElement(unsigned index)
191 {
192     if (!_dataElementFactory.valid())
193         return 0;
194     return _dataElementFactory->createElement(*this, index);
195 }
196
197 ////////////////////////////////////////////////////////////////////////
198
199 HLAVariantArrayDataElement::HLAVariantArrayDataElement() :
200     HLAAbstractArrayDataElement(0)
201 {
202 }
203
204 HLAVariantArrayDataElement::~HLAVariantArrayDataElement()
205 {
206 }
207
208 bool
209 HLAVariantArrayDataElement::setDataType(const HLADataType* dataType)
210 {
211     const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
212     if (!arrayDataType) {
213         SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type, dataType is not an array data type!");
214         return false;
215     }
216     const HLAVariantRecordDataType* variantRecordDataType = arrayDataType->getElementDataType()->toVariantRecordDataType();
217     if (!variantRecordDataType) {
218         SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type: arrayDataTypes element data type is no a variant data type!");
219         return false;
220     }
221     _dataType = arrayDataType;
222     return true;
223 }
224
225 bool
226 HLAVariantArrayDataElement::setNumElements(unsigned size)
227 {
228     unsigned oldSize = _elementVector.size();
229     if (size == oldSize)
230         return true;
231     _elementVector.resize(size);
232     for (unsigned i = oldSize; i < size; ++i)
233         _elementVector[i] = newElement();
234     return true;
235 }
236
237 bool
238 HLAVariantArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
239 {
240     HLAVariantRecordDataElement* dataElement = getElement(i);
241     if (!dataElement)
242         return false;
243     return dataElement->decode(stream);
244 }
245
246 unsigned
247 HLAVariantArrayDataElement::getNumElements() const
248 {
249     return _elementVector.size();
250 }
251
252 bool
253 HLAVariantArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
254 {
255     const HLADataElement* dataElement = getElement(i);
256     if (!dataElement)
257         return false;
258     return dataElement->encode(stream);
259 }
260
261 const HLAVariantRecordDataElement*
262 HLAVariantArrayDataElement::getElement(unsigned index) const
263 {
264     if (_elementVector.size() <= index)
265         return 0;
266     return _elementVector[index].get();
267 }
268
269 HLAVariantRecordDataElement*
270 HLAVariantArrayDataElement::getElement(unsigned index)
271 {
272     if (_elementVector.size() <= index)
273         return 0;
274     return _elementVector[index].get();
275 }
276
277 HLAVariantRecordDataElement*
278 HLAVariantArrayDataElement::getOrCreateElement(unsigned index)
279 {
280     if (_elementVector.size() <= index)
281         if (!setNumElements(index + 1))
282             return 0;
283     return _elementVector[index].get();
284 }
285
286 void
287 HLAVariantArrayDataElement::setElement(unsigned index, HLAVariantRecordDataElement* value)
288 {
289     unsigned oldSize = _elementVector.size();
290     if (oldSize <= index) {
291         _elementVector.resize(index + 1);
292         for (unsigned j = oldSize; j < index; ++j)
293             _elementVector[j] = newElement();
294     }
295     _elementVector[index] = value;
296 }
297
298 void
299 HLAVariantArrayDataElement::setAlternativeDataElementFactory(HLAVariantArrayDataElement::AlternativeDataElementFactory* alternativeDataElementFactory)
300 {
301     _alternativeDataElementFactory = alternativeDataElementFactory;
302 }
303
304 HLAVariantArrayDataElement::AlternativeDataElementFactory*
305 HLAVariantArrayDataElement::getAlternativeDataElementFactory()
306 {
307     return _alternativeDataElementFactory.get();
308 }
309
310 HLAVariantRecordDataElement*
311 HLAVariantArrayDataElement::newElement()
312 {
313     const HLAArrayDataType* arrayDataType = getDataType();
314     if (!arrayDataType)
315         return 0;
316     const HLADataType* elementDataType = arrayDataType->getElementDataType();
317     if (!elementDataType)
318         return 0;
319     const HLAVariantRecordDataType* variantRecordDataType = elementDataType->toVariantRecordDataType();
320     if (!variantRecordDataType)
321         return 0;
322     HLAVariantRecordDataElement* variantRecordDataElement = new HLAVariantRecordDataElement(variantRecordDataType);
323     variantRecordDataElement->setDataElementFactory(_alternativeDataElementFactory.get());
324     return variantRecordDataElement;
325 }
326
327 }