]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/input_output/FGPropertyManager.cpp
Fix for bug 1304 - crash loading XML route
[flightgear.git] / src / FDM / JSBSim / input_output / FGPropertyManager.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Header:       FGPropertyManager.cpp
4  Author:       Tony Peden
5                Based on work originally by David Megginson
6  Date:         2/2002
7
8  ------------- Copyright (C) 2002 -------------
9
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU Lesser General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
18  details.
19
20  You should have received a copy of the GNU Lesser General Public License along with
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22  Place - Suite 330, Boston, MA  02111-1307, USA.
23
24  Further information about the GNU Lesser General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26
27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28 INCLUDES
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
30
31 #include "FGPropertyManager.h"
32
33 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 DEFINITIONS
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
36
37
38 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 FORWARD DECLARATIONS
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41
42 using namespace std;
43
44 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
45 COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
46 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 */
48
49 namespace JSBSim {
50
51 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52
53 void FGPropertyManager::Unbind(void)
54 {
55     vector<SGPropertyNode_ptr>::iterator it;
56
57     for (it = tied_properties.begin();it < tied_properties.end();it++)
58         (*it)->untie();
59
60     tied_properties.clear();
61 }
62
63 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64
65 string FGPropertyManager::mkPropertyName(string name, bool lowercase) {
66
67   /* do this two pass to avoid problems with characters getting skipped
68      because the index changed */
69   unsigned i;
70   for(i=0;i<name.length();i++) {
71     if( lowercase && isupper(name[i]) )
72       name[i]=tolower(name[i]);
73     else if( isspace(name[i]) )
74       name[i]='-';
75   }
76   
77   return name;
78 }
79
80 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81
82 FGPropertyNode*
83 FGPropertyNode::GetNode (const string &path, bool create)
84 {
85   SGPropertyNode* node = getNode(path.c_str(), create);
86   if (node == 0) {
87     cerr << "FGPropertyManager::GetNode() No node found for " << path << endl;
88   }
89   return (FGPropertyNode*)node;
90 }
91
92 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93
94 FGPropertyNode*
95 FGPropertyNode::GetNode (const string &relpath, int index, bool create)
96 {
97   SGPropertyNode* node = getNode(relpath.c_str(), index, create);
98   if (node == 0) {
99     cerr << "FGPropertyManager::GetNode() No node found for " << relpath
100          << "[" << index << "]" << endl;
101   }
102   return (FGPropertyNode*)node;
103 }
104
105 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106
107 bool FGPropertyNode::HasNode (const string &path)
108 {
109   const SGPropertyNode* node = getNode(path.c_str(), false);
110   return (node != 0);
111 }
112
113 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114
115 string FGPropertyNode::GetName( void ) const
116 {
117   return string( getName() );
118 }
119
120 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121
122 string FGPropertyNode::GetPrintableName( void ) const
123 {
124   string temp_string(getName());
125   size_t initial_location=0;
126   size_t found_location;
127
128   found_location = temp_string.rfind("/");
129   if (found_location != string::npos)
130   temp_string = temp_string.substr(found_location);
131
132   found_location = temp_string.find('_',initial_location);
133   while (found_location != string::npos) {
134     temp_string.replace(found_location,1," ");
135     initial_location = found_location+1;
136     found_location = temp_string.find('_',initial_location);
137   }
138   return temp_string;
139 }
140
141 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142
143 string FGPropertyNode::GetFullyQualifiedName(void) const
144 {
145     vector<string> stack;
146     stack.push_back( getDisplayName(true) );
147     const SGPropertyNode* tmpn=getParent();
148     bool atroot=false;
149     while( !atroot ) {
150      stack.push_back( tmpn->getDisplayName(true) );
151      if( !tmpn->getParent() )
152       atroot=true;
153      else
154       tmpn=tmpn->getParent();
155     }
156
157     string fqname="";
158     for(unsigned i=stack.size()-1;i>0;i--) {
159       fqname+= stack[i];
160       fqname+= "/";
161     }
162     fqname+= stack[0];
163     return fqname;
164
165 }
166
167 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
168
169 string FGPropertyNode::GetRelativeName( const string &path ) const
170 {
171   string temp_string = GetFullyQualifiedName();
172   size_t len = path.length();
173   if ( (len > 0) && (temp_string.substr(0,len) == path) ) {
174     temp_string = temp_string.erase(0,len);
175   }
176   return temp_string;
177 }
178
179
180
181 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182
183 bool FGPropertyNode::GetBool (const string &name, bool defaultValue) const
184 {
185   return getBoolValue(name.c_str(), defaultValue);
186 }
187
188 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189
190 int FGPropertyNode::GetInt (const string &name, int defaultValue ) const
191 {
192   return getIntValue(name.c_str(), defaultValue);
193 }
194
195 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
196
197 int FGPropertyNode::GetLong (const string &name, long defaultValue ) const
198 {
199   return getLongValue(name.c_str(), defaultValue);
200 }
201
202 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203
204 float FGPropertyNode::GetFloat (const string &name, float defaultValue ) const
205 {
206   return getFloatValue(name.c_str(), defaultValue);
207 }
208
209 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210
211 double FGPropertyNode::GetDouble (const string &name, double defaultValue ) const
212 {
213   return getDoubleValue(name.c_str(), defaultValue);
214 }
215
216 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217
218 string FGPropertyNode::GetString (const string &name, string defaultValue ) const
219 {
220   return string(getStringValue(name.c_str(), defaultValue.c_str()));
221 }
222
223 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224
225 bool FGPropertyNode::SetBool (const string &name, bool val)
226 {
227   return setBoolValue(name.c_str(), val);
228 }
229
230 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231
232 bool FGPropertyNode::SetInt (const string &name, int val)
233 {
234   return setIntValue(name.c_str(), val);
235 }
236
237 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238
239 bool FGPropertyNode::SetLong (const string &name, long val)
240 {
241   return setLongValue(name.c_str(), val);
242 }
243
244 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245
246 bool FGPropertyNode::SetFloat (const string &name, float val)
247 {
248   return setFloatValue(name.c_str(), val);
249 }
250
251 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252
253 bool FGPropertyNode::SetDouble (const string &name, double val)
254 {
255   return setDoubleValue(name.c_str(), val);
256 }
257
258 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
259
260 bool FGPropertyNode::SetString (const string &name, const string &val)
261 {
262   return setStringValue(name.c_str(), val.c_str());
263 }
264
265 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266
267 void FGPropertyNode::SetArchivable (const string &name, bool state )
268 {
269   SGPropertyNode * node = getNode(name.c_str());
270   if (node == 0)
271     cerr <<
272            "Attempt to set archive flag for non-existent property "
273            << name << endl;
274   else
275     node->setAttribute(SGPropertyNode::ARCHIVE, state);
276 }
277
278 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279
280 void FGPropertyNode::SetReadable (const string &name, bool state )
281 {
282   SGPropertyNode * node = getNode(name.c_str());
283   if (node == 0)
284     cerr <<
285            "Attempt to set read flag for non-existant property "
286            << name << endl;
287   else
288     node->setAttribute(SGPropertyNode::READ, state);
289 }
290
291 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292
293 void FGPropertyNode::SetWritable (const string &name, bool state )
294 {
295   SGPropertyNode * node = getNode(name.c_str());
296   if (node == 0)
297     cerr <<
298            "Attempt to set write flag for non-existant property "
299            << name << endl;
300   else
301     node->setAttribute(SGPropertyNode::WRITE, state);
302 }
303
304 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305
306 void FGPropertyManager::Untie (const string &name)
307 {
308   SGPropertyNode* property = root->getNode(name.c_str());
309   if (!property) {
310     cerr << "Attempt to untie a non-existant property." << name << endl;
311     return;
312   }
313
314   vector <SGPropertyNode_ptr>::iterator it;
315   for (it = tied_properties.begin(); it != tied_properties.end(); ++it) {
316     if (*it == property) {
317       property->untie();
318       tied_properties.erase(it);
319       if (FGJSBBase::debug_lvl & 0x20) cout << "Untied " << name << endl;
320       return;
321     }
322   }
323
324   cerr << "Failed to untie property " << name << endl
325        << "JSBSim is not the owner of this property." << endl;
326 }
327
328 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329
330 void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
331 {
332   SGPropertyNode* property = root->getNode(name.c_str(), true);
333   if (!property) {
334     cerr << "Could not get or create property " << name << endl;
335     return;
336   }
337
338   if (!property->tie(SGRawValuePointer<bool>(pointer), useDefault))
339     cerr << "Failed to tie property " << name << " to a pointer" << endl;
340   else {
341     tied_properties.push_back(property);
342     if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
343   }
344 }
345
346 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347
348 void FGPropertyManager::Tie (const string &name, int *pointer,
349                                           bool useDefault )
350 {
351   SGPropertyNode* property = root->getNode(name.c_str(), true);
352   if (!property) {
353     cerr << "Could not get or create property " << name << endl;
354     return;
355   }
356
357   if (!property->tie(SGRawValuePointer<int>(pointer), useDefault))
358     cerr << "Failed to tie property " << name << " to a pointer" << endl;
359   else {
360     tied_properties.push_back(property);
361     if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
362   }
363 }
364
365 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366
367 void FGPropertyManager::Tie (const string &name, long *pointer,
368                                           bool useDefault )
369 {
370   SGPropertyNode* property = root->getNode(name.c_str(), true);
371   if (!property) {
372     cerr << "Could not get or create property " << name << endl;
373     return;
374   }
375
376   if (!property->tie(SGRawValuePointer<long>(pointer), useDefault))
377     cerr << "Failed to tie property " << name << " to a pointer" << endl;
378   else {
379     tied_properties.push_back(property);
380     if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
381   }
382 }
383
384 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385
386 void FGPropertyManager::Tie (const string &name, float *pointer,
387                                           bool useDefault )
388 {
389   SGPropertyNode* property = root->getNode(name.c_str(), true);
390   if (!property) {
391     cerr << "Could not get or create property " << name << endl;
392     return;
393   }
394
395   if (!property->tie(SGRawValuePointer<float>(pointer), useDefault))
396     cerr << "Failed to tie property " << name << " to a pointer" << endl;
397   else {
398     tied_properties.push_back(property);
399     if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
400   }
401 }
402
403 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404
405 void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault)
406 {
407   SGPropertyNode* property = root->getNode(name.c_str(), true);
408   if (!property) {
409     cerr << "Could not get or create property " << name << endl;
410     return;
411   }
412
413   if (!property->tie(SGRawValuePointer<double>(pointer), useDefault))
414     cerr << "Failed to tie property " << name << " to a pointer" << endl;
415   else {
416     tied_properties.push_back(property);
417     if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
418   }
419 }
420
421 } // namespace JSBSim