]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAPropertyDataElement.cxx
hla: Provide a directly property based api for property data element.
[simgear.git] / simgear / hla / HLAPropertyDataElement.cxx
1 // Copyright (C) 2009 - 2010  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 "HLAPropertyDataElement.hxx"
19
20 #include "HLADataTypeVisitor.hxx"
21
22 namespace simgear {
23
24 class HLAPropertyDataElement::DecodeVisitor : public HLADataTypeDecodeVisitor {
25 public:
26     DecodeVisitor(HLADecodeStream& stream, SGPropertyNode& propertyNode) :
27         HLADataTypeDecodeVisitor(stream),
28         _propertyNode(propertyNode)
29     { }
30
31     virtual void apply(const HLAInt8DataType& dataType)
32     {
33         int8_t value = 0;
34         dataType.decode(_stream, value);
35         _propertyNode.setIntValue(value);
36     }
37     virtual void apply(const HLAUInt8DataType& dataType)
38     {
39         uint8_t value = 0;
40         dataType.decode(_stream, value);
41         _propertyNode.setIntValue(value);
42     }
43     virtual void apply(const HLAInt16DataType& dataType)
44     {
45         int16_t value = 0;
46         dataType.decode(_stream, value);
47         _propertyNode.setIntValue(value);
48     }
49     virtual void apply(const HLAUInt16DataType& dataType)
50     {
51         uint16_t value = 0;
52         dataType.decode(_stream, value);
53         _propertyNode.setIntValue(value);
54     }
55     virtual void apply(const HLAInt32DataType& dataType)
56     {
57         int32_t value = 0;
58         dataType.decode(_stream, value);
59         _propertyNode.setIntValue(value);
60     }
61     virtual void apply(const HLAUInt32DataType& dataType)
62     {
63         uint32_t value = 0;
64         dataType.decode(_stream, value);
65         _propertyNode.setIntValue(value);
66     }
67     virtual void apply(const HLAInt64DataType& dataType)
68     {
69         int64_t value = 0;
70         dataType.decode(_stream, value);
71         _propertyNode.setLongValue(value);
72     }
73     virtual void apply(const HLAUInt64DataType& dataType)
74     {
75         uint64_t value = 0;
76         dataType.decode(_stream, value);
77         _propertyNode.setLongValue(value);
78     }
79     virtual void apply(const HLAFloat32DataType& dataType)
80     {
81         float value = 0;
82         dataType.decode(_stream, value);
83         _propertyNode.setFloatValue(value);
84     }
85     virtual void apply(const HLAFloat64DataType& dataType)
86     {
87         double value = 0;
88         dataType.decode(_stream, value);
89         _propertyNode.setDoubleValue(value);
90     }
91
92     virtual void apply(const HLAFixedArrayDataType& dataType)
93     {
94         unsigned numElements = dataType.getNumElements();
95         std::string value;
96         value.reserve(numElements);
97         for (unsigned i = 0; i < numElements; ++i) {
98             HLATemplateDecodeVisitor<char> visitor(_stream);
99             dataType.getElementDataType()->accept(visitor);
100             value.push_back(visitor.getValue());
101         }
102         _propertyNode.setStringValue(value);
103     }
104     virtual void apply(const HLAVariableArrayDataType& dataType)
105     {
106         HLATemplateDecodeVisitor<unsigned> numElementsVisitor(_stream);
107         dataType.getSizeDataType()->accept(numElementsVisitor);
108         unsigned numElements = numElementsVisitor.getValue();
109         std::string value;
110         value.reserve(numElements);
111         for (unsigned i = 0; i < numElements; ++i) {
112             HLATemplateDecodeVisitor<char> visitor(_stream);
113             dataType.getElementDataType()->accept(visitor);
114             value.push_back(visitor.getValue());
115         }
116         _propertyNode.setStringValue(value);
117     }
118
119 protected:
120     SGPropertyNode& _propertyNode;
121 };
122
123 class HLAPropertyDataElement::EncodeVisitor : public HLADataTypeEncodeVisitor {
124 public:
125     EncodeVisitor(HLAEncodeStream& stream, const SGPropertyNode& propertyNode) :
126         HLADataTypeEncodeVisitor(stream),
127         _propertyNode(propertyNode)
128     { }
129
130     virtual void apply(const HLAInt8DataType& dataType)
131     {
132         dataType.encode(_stream, _propertyNode.getIntValue());
133     }
134     virtual void apply(const HLAUInt8DataType& dataType)
135     {
136         dataType.encode(_stream, _propertyNode.getIntValue());
137     }
138     virtual void apply(const HLAInt16DataType& dataType)
139     {
140         dataType.encode(_stream, _propertyNode.getIntValue());
141     }
142     virtual void apply(const HLAUInt16DataType& dataType)
143     {
144         dataType.encode(_stream, _propertyNode.getIntValue());
145     }
146     virtual void apply(const HLAInt32DataType& dataType)
147     {
148         dataType.encode(_stream, _propertyNode.getIntValue());
149     }
150     virtual void apply(const HLAUInt32DataType& dataType)
151     {
152         dataType.encode(_stream, _propertyNode.getIntValue());
153     }
154     virtual void apply(const HLAInt64DataType& dataType)
155     {
156         dataType.encode(_stream, _propertyNode.getLongValue());
157     }
158     virtual void apply(const HLAUInt64DataType& dataType)
159     {
160         dataType.encode(_stream, _propertyNode.getLongValue());
161     }
162     virtual void apply(const HLAFloat32DataType& dataType)
163     {
164         dataType.encode(_stream, _propertyNode.getFloatValue());
165     }
166     virtual void apply(const HLAFloat64DataType& dataType)
167     {
168         dataType.encode(_stream, _propertyNode.getDoubleValue());
169     }
170
171     virtual void apply(const HLAFixedArrayDataType& dataType)
172     {
173         unsigned numElements = dataType.getNumElements();
174         std::string value = _propertyNode.getStringValue();
175         for (unsigned i = 0; i < numElements; ++i) {
176             if (i < value.size()) {
177                 HLATemplateEncodeVisitor<char> visitor(_stream, value[i]);
178                 dataType.getElementDataType()->accept(visitor);
179             } else {
180                 HLADataTypeEncodeVisitor visitor(_stream);
181                 dataType.getElementDataType()->accept(visitor);
182             }
183         }
184     }
185
186     virtual void apply(const HLAVariableArrayDataType& dataType)
187     {
188         std::string value = _propertyNode.getStringValue();
189         HLATemplateEncodeVisitor<std::string::size_type> numElementsVisitor(_stream, value.size());
190         dataType.getSizeDataType()->accept(numElementsVisitor);
191         for (unsigned i = 0; i < value.size(); ++i) {
192             HLATemplateEncodeVisitor<char> visitor(_stream, value[i]);
193             dataType.getElementDataType()->accept(visitor);
194         }
195     }
196
197 protected:
198     const SGPropertyNode& _propertyNode;
199 };
200
201 HLAPropertyDataElement::HLAPropertyDataElement(HLAPropertyReference* propertyReference) :
202     _propertyReference(propertyReference)
203 {
204 }
205
206 HLAPropertyDataElement::HLAPropertyDataElement(const HLADataType* dataType, HLAPropertyReference* propertyReference) :
207     _dataType(dataType),
208     _propertyReference(propertyReference)
209 {
210 }
211
212 HLAPropertyDataElement::HLAPropertyDataElement()
213 {
214 }
215
216 HLAPropertyDataElement::HLAPropertyDataElement(SGPropertyNode* propertyNode)
217 {
218     setPropertyNode(propertyNode);
219 }
220
221 HLAPropertyDataElement::HLAPropertyDataElement(const HLADataType* dataType, SGPropertyNode* propertyNode) :
222     _dataType(dataType)
223 {
224     setPropertyNode(propertyNode);
225 }
226
227 HLAPropertyDataElement::~HLAPropertyDataElement()
228 {
229 }
230
231 bool
232 HLAPropertyDataElement::encode(HLAEncodeStream& stream) const
233 {
234     if (!_dataType.valid())
235         return false;
236     if (const SGPropertyNode* propertyNode = getPropertyNode()) {
237         EncodeVisitor visitor(stream, *propertyNode);
238         _dataType->accept(visitor);
239     } else {
240         HLADataTypeEncodeVisitor visitor(stream);
241         _dataType->accept(visitor);
242     }
243     return true;
244 }
245
246 bool
247 HLAPropertyDataElement::decode(HLADecodeStream& stream)
248 {
249     if (!_dataType.valid())
250         return false;
251     if (SGPropertyNode* propertyNode = getPropertyNode()) {
252         DecodeVisitor visitor(stream, *propertyNode);
253         _dataType->accept(visitor);
254     } else {
255         HLADataTypeDecodeVisitor visitor(stream);
256         _dataType->accept(visitor);
257     }
258     return true;
259 }
260
261 const HLADataType*
262 HLAPropertyDataElement::getDataType() const
263 {
264     return _dataType.get();
265 }
266
267 bool
268 HLAPropertyDataElement::setDataType(const HLADataType* dataType)
269 {
270     if (dataType->toBasicDataType()) {
271         _dataType = dataType;
272         return true;
273     } else {
274         const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
275         if (arrayDataType && arrayDataType->getElementDataType() &&
276             arrayDataType->getElementDataType()->toBasicDataType()) {
277             _dataType = dataType;
278             return true;
279         }
280     }
281     return false;
282 }
283
284 void
285 HLAPropertyDataElement::setPropertyNode(SGPropertyNode* propertyNode)
286 {
287     _propertyReference = new HLAPropertyReference;
288     _propertyReference->setRootNode(propertyNode);
289 }
290
291 SGPropertyNode*
292 HLAPropertyDataElement::getPropertyNode()
293 {
294     if (!_propertyReference.valid())
295         return 0;
296     return _propertyReference->getPropertyNode();
297 }
298
299 const SGPropertyNode*
300 HLAPropertyDataElement::getPropertyNode() const
301 {
302     if (!_propertyReference.valid())
303         return 0;
304     return _propertyReference->getPropertyNode();
305 }
306
307 } // namespace simgear