]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLADataElement.cxx
hla: Fix buffer overrun in SGMath vector types.
[simgear.git] / simgear / hla / HLADataElement.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 "HLADataElement.hxx"
19
20 #include <simgear/debug/logstream.hxx>
21
22 #include "HLADataElementVisitor.hxx"
23
24 namespace simgear {
25
26 HLADataElement::PathElement::Data::~Data()
27 {
28 }
29
30 const HLADataElement::PathElement::FieldData*
31 HLADataElement::PathElement::Data::toFieldData() const
32 {
33     return 0;
34 }
35
36 const HLADataElement::PathElement::IndexData*
37 HLADataElement::PathElement::Data::toIndexData() const
38 {
39     return 0;
40 }
41
42 HLADataElement::PathElement::FieldData::FieldData(const std::string& name) :
43     _name(name)
44 {
45 }
46
47 HLADataElement::PathElement::FieldData::~FieldData()
48 {
49 }
50
51 const HLADataElement::PathElement::FieldData*
52 HLADataElement::PathElement::FieldData::toFieldData() const
53 {
54     return this;
55 }
56
57 bool
58 HLADataElement::PathElement::FieldData::less(const Data* data) const
59 {
60     const FieldData* fieldData = data->toFieldData();
61     // IndexData is allways smaller than FieldData
62     if (!fieldData)
63         return false;
64     return _name < fieldData->_name;
65 }
66
67 bool
68 HLADataElement::PathElement::FieldData::equal(const Data* data) const
69 {
70     const FieldData* fieldData = data->toFieldData();
71     // IndexData is allways smaller than FieldData
72     if (!fieldData)
73         return false;
74     return _name == fieldData->_name;
75 }
76
77 void
78 HLADataElement::PathElement::FieldData::append(std::string& s) const
79 {
80     s.append(1, std::string::value_type('.'));
81     s.append(_name);
82 }
83
84 HLADataElement::PathElement::IndexData::IndexData(unsigned index) :
85     _index(index)
86 {
87 }
88
89 HLADataElement::PathElement::IndexData::~IndexData()
90 {
91 }
92
93 const HLADataElement::PathElement::IndexData*
94 HLADataElement::PathElement::IndexData::toIndexData() const
95 {
96     return this;
97 }
98
99 bool
100 HLADataElement::PathElement::IndexData::less(const Data* data) const
101 {
102     const IndexData* indexData = data->toIndexData();
103     // IndexData is allways smaller than FieldData
104     if (!indexData)
105         return true;
106     return _index < indexData->_index;
107 }
108
109 bool
110 HLADataElement::PathElement::IndexData::equal(const Data* data) const
111 {
112     const IndexData* indexData = data->toIndexData();
113     // IndexData is allways smaller than FieldData
114     if (!indexData)
115         return false;
116     return _index == indexData->_index;
117 }
118
119 void
120 HLADataElement::PathElement::IndexData::append(std::string& s) const
121 {
122     s.append(1, std::string::value_type('['));
123     unsigned value = _index;
124     do {
125         s.append(1, std::string::value_type('0' + value % 10));
126     } while (value /= 10);
127     s.append(1, std::string::value_type(']'));
128 }
129
130 HLADataElement::~HLADataElement()
131 {
132 }
133
134 void
135 HLADataElement::accept(HLADataElementVisitor& visitor)
136 {
137     visitor.apply(*this);
138 }
139
140 void
141 HLADataElement::accept(HLAConstDataElementVisitor& visitor) const
142 {
143     visitor.apply(*this);
144 }
145
146 std::string
147 HLADataElement::toString(const Path& path)
148 {
149     std::string s;
150     for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
151         i->append(s);
152     return s;
153 }
154
155 HLADataElement::StringPathPair
156 HLADataElement::toStringPathPair(const std::string& s)
157 {
158     Path path;
159     // Skip the initial attribute/parameter name if given
160     std::string::size_type i = s.find_first_of("[.");
161     std::string attribute = s.substr(0, i);
162     while (i < s.size()) {
163         if (s[i] == '[') {
164             ++i;
165             unsigned index = 0;
166             while (i < s.size()) {
167                 if (s[i] == ']')
168                     break;
169                 unsigned v = s[i] - '0';
170                 // Error, no number
171                 if (10 <= v) {
172                     SG_LOG(SG_NETWORK, SG_WARN, "HLADataElement: invalid character in array subscript for \""
173                            << s << "\" at \"" << attribute << toString(path) << "\"!");
174                     return StringPathPair();
175                 }
176                 index *= 10;
177                 index += v;
178                 ++i;
179             }
180             path.push_back(index);
181             ++i;
182             continue;
183         }
184         if (s[i] == '.') {
185             // Error, . cannot be last
186             if (s.size() <= ++i) {
187                 SG_LOG(SG_NETWORK, SG_WARN, "HLADataElement: invalid terminating '.' for \""
188                        << s << "\"!");
189                 return StringPathPair();
190             }
191             std::string::size_type e = s.find_first_of("[.", i);
192             path.push_back(s.substr(i, e - i));
193             i = e;
194             continue;
195         }
196     }
197
198     return StringPathPair(attribute, path);
199 }
200
201 }