]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLADataElement.hxx
hla: Fix buffer overrun in SGMath vector types.
[simgear.git] / simgear / hla / HLADataElement.hxx
1 // Copyright (C) 2009 - 2011  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 HLADataElement_hxx
19 #define HLADataElement_hxx
20
21 #include <list>
22 #include <map>
23 #include <simgear/structure/SGReferenced.hxx>
24 #include <simgear/structure/SGSharedPtr.hxx>
25 #include <simgear/timing/timestamp.hxx>
26 #include "RTIData.hxx"
27 #include "HLADataType.hxx"
28
29 class SGTimeStamp;
30
31 namespace simgear {
32
33 class HLADataElementVisitor;
34 class HLAConstDataElementVisitor;
35
36 class HLADataElement : public SGReferenced {
37 public:
38     virtual ~HLADataElement();
39
40     virtual void accept(HLADataElementVisitor& visitor) = 0;
41     virtual void accept(HLAConstDataElementVisitor& visitor) const = 0;
42
43     virtual bool encode(HLAEncodeStream& stream) const = 0;
44     virtual bool decode(HLADecodeStream& stream) = 0;
45
46     virtual const HLADataType* getDataType() const = 0;
47     virtual bool setDataType(const HLADataType* dataType) = 0;
48
49     // Container for the timestamp the originating attribute was last updated for
50     // class TimeStamp : public SGReferenced {
51     // public:
52     //     const SGTimeStamp& getTimeStamp() const
53     //     { return _timeStamp; }
54     //     void setTimeStamp(const SGTimeStamp& timeStamp)
55     //     { _timeStamp = timeStamp; }
56     // private:
57     //     SGTimeStamp _timeStamp;
58     // };
59
60     // const TimeStamp* getTimeStamp() const
61     // { return _timeStamp.get(); }
62     // void setTimeStamp(const TimeStamp* timeStamp)
63     // { _timeStamp = timeStamp; }
64
65     // struct ChangeCount : public SGReferenced {
66     //     ChangeCount() : _value(0) {}
67     //     unsigned _value;
68     // };
69     // SGSharedPtr<ChangeCount> _changeCount;
70     // unsigned getChangeCount() const
71     // {
72     //     // If we don't have return allways the same
73     //     if (!_changeCount.valid())
74     //         return 0;
75     //     return _changeCount->_value;
76     // }
77
78     /// HLADataElements could be identified by path
79     /// These paths are composed of structure field names and array indices in the
80     /// order they appear while walking to the data element.
81     /// So provide here some tool functions to access these elements
82     /// Note that these functions are relatively expensive in execution time.
83     /// So only use them once at object creation time and store direct references to the values
84
85     class PathElement {
86     public:
87         PathElement(unsigned index) : _data(new IndexData(index)) {}
88         PathElement(const std::string& name) : _data(new FieldData(name)) {}
89
90         bool isFieldValue() const
91         { return _data->toFieldData(); }
92         bool isIndexValue() const
93         { return _data->toIndexData(); }
94
95         unsigned getIndexValue() const
96         {
97             const IndexData* indexData = _data->toIndexData();
98             if (!indexData)
99                 return ~unsigned(0);
100             return indexData->_index;
101         }
102
103         std::string getFieldValue() const
104         {
105             const FieldData* fieldData = _data->toFieldData();
106             if (!fieldData)
107                 return std::string();
108             return fieldData->_name;
109         }
110
111         // Want to be able to use that in std::map and std::set
112         bool operator<(const PathElement& pathElement) const
113         { return _data->less(pathElement._data.get()); }
114         bool operator==(const PathElement& pathElement) const
115         { return _data->equal(pathElement._data.get()); }
116
117         void append(std::string& s) const
118         { _data->append(s); }
119
120     private:
121         struct FieldData;
122         struct IndexData;
123         struct Data : public SGReferenced {
124             virtual ~Data();
125             virtual const FieldData* toFieldData() const;
126             virtual const IndexData* toIndexData() const;
127             virtual bool less(const Data*) const = 0;
128             virtual bool equal(const Data*) const = 0;
129             virtual void append(std::string&) const = 0;
130         };
131         struct FieldData : public Data {
132             FieldData(const std::string& name);
133             virtual ~FieldData();
134             virtual const FieldData* toFieldData() const;
135             virtual bool less(const Data* data) const;
136             virtual bool equal(const Data* data) const;
137             virtual void append(std::string& s) const;
138             std::string _name;
139         };
140         struct IndexData : public Data {
141             IndexData(unsigned index);
142             virtual ~IndexData();
143             virtual const IndexData* toIndexData() const;
144             virtual bool less(const Data* data) const;
145             virtual bool equal(const Data* data) const;
146             virtual void append(std::string& s) const;
147             unsigned _index;
148         };
149
150         SGSharedPtr<Data> _data;
151     };
152     typedef std::list<PathElement> Path;
153     typedef std::pair<std::string, Path> StringPathPair;
154     typedef StringPathPair AttributePathPair; // deprecated
155     typedef std::pair<unsigned, Path> IndexPathPair;
156
157     static std::string toString(const Path& path);
158     static std::string toString(const StringPathPair& path)
159     { return path.first + toString(path.second); }
160     static StringPathPair toStringPathPair(const std::string& s);
161     static AttributePathPair toAttributePathPair(const std::string& s) // deprecated
162     { return toStringPathPair(s); }
163     static Path toPath(const std::string& s)
164     { return toStringPathPair(s).second; }
165
166 private:
167     // SGSharedPtr<const TimeStamp> _timeStamp;
168 };
169
170 class HLADataElementProvider {
171 public:
172     class AbstractProvider : public SGReferenced {
173     public:
174         virtual ~AbstractProvider() { }
175         virtual HLADataElement* getDataElement(const HLADataElement::Path& path) = 0;
176         // virtual HLADataElement* getDataElement(const HLADataElement::Path& path, const HLADataType* dataType)
177         // {
178         //     SGSharedPtr<HLADataElement> dataElement = getDataElement(path);
179         //     if (!dataElement.valid())
180         //         return 0;
181         //     if (!dataElement->setDataType(dataType))
182         //         return 0;
183         //     return dataElement.release();
184         // }
185     };
186
187     HLADataElementProvider()
188     { }
189     HLADataElementProvider(HLADataElement* dataElement) :
190         _provider(new ConcreteProvider(dataElement))
191     { }
192     HLADataElementProvider(const SGSharedPtr<HLADataElement>& dataElement) :
193         _provider(new ConcreteProvider(dataElement))
194     { }
195     HLADataElementProvider(AbstractProvider* provider) :
196         _provider(provider)
197     { }
198
199     HLADataElement* getDataElement(const HLADataElement::Path& path) const
200     {
201         if (!_provider.valid())
202             return 0;
203         return _provider->getDataElement(path);
204     }
205
206 private:
207     class ConcreteProvider : public AbstractProvider {
208     public:
209         ConcreteProvider(const SGSharedPtr<HLADataElement>& dataElement) :
210             _dataElement(dataElement)
211         { }
212         virtual HLADataElement* getDataElement(const HLADataElement::Path&)
213         { return _dataElement.get(); }
214     private:
215         SGSharedPtr<HLADataElement> _dataElement;
216     };
217
218     SGSharedPtr<AbstractProvider> _provider;
219 };
220
221 typedef std::map<HLADataElement::Path, HLADataElementProvider> HLAPathElementMap;
222 typedef std::map<unsigned, HLAPathElementMap> HLAAttributePathElementMap;
223
224 }
225
226 #endif