]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/input_output/FGXMLElement.cpp
sync. with JSBSim v. 2.0
[flightgear.git] / src / FDM / JSBSim / input_output / FGXMLElement.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Author:       Jon Berndt
4  Date started: 09/28/2004
5  Purpose:      XML element class
6  Called by:    FGXMLParse
7
8 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9 INCLUDES
10 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
11
12 #include "FGXMLElement.h"
13 #ifdef FGFS
14 #  ifndef __BORLANDC__
15 #    include <simgear/compiler.h>
16 #  endif
17 #  ifdef SG_HAVE_STD_INCLUDES
18 #    include <cmath>
19 #    include <cstdlib>
20 #  else
21 #    include <math.h>
22 #    include <stdlib.h>
23 #  endif
24 #else
25 #  if defined (sgi) && !defined(__GNUC__)
26 #    include <math.h>
27 #    include <stdlib.h>
28 #  else
29 #    include <cmath>
30 #    include <cstdlib>
31 #  endif
32 #endif
33
34 #include <stdlib.h>
35 #include <math.h>
36
37 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 FORWARD DECLARATIONS
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40
41 namespace JSBSim {
42
43 static const char *IdSrc = "$Id$";
44 static const char *IdHdr = ID_XMLELEMENT;
45
46 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 CLASS IMPLEMENTATION
48 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
49
50 Element::Element(string nm)
51 {
52   name   = nm;
53   parent = 0L;
54   element_index = 0;
55
56   // convert ["from"]["to"] = factor, so: from * factor = to
57   convert["M"]["FT"] = 3.2808399;
58   convert["FT"]["M"] = 1.0/convert["M"]["FT"];
59   convert["M2"]["FT2"] = convert["M"]["FT"]*convert["M"]["FT"];
60   convert["FT2"]["M2"] = 1.0/convert["M2"]["FT2"];
61   convert["FT"]["IN"] = 12.0;
62   convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
63   convert["LBS"]["KG"] = 0.45359237;
64   convert["KG"]["LBS"] = 1.0/convert["LBS"]["KG"];
65   convert["SLUG*FT2"]["KG*M2"] = 1.35594;
66   convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
67   convert["RAD"]["DEG"] = 360.0/(2.0*3.1415926);
68   convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
69   convert["LBS/FT"]["N/M"] = 14.5939;
70   convert["LBS/FT/SEC"]["N/M/SEC"] = 14.5939;
71   convert["N/M"]["LBS/FT"] = 1.0/convert["LBS/FT"]["N/M"];
72   convert["N/M/SEC"]["LBS/FT/SEC"] = 1.0/convert["LBS/FT/SEC"]["N/M/SEC"];
73   convert["WATTS"]["HP"] = 0.001341022;
74   convert["HP"]["WATTS"] = 1.0/convert["WATTS"]["HP"];
75   convert["N"]["LBS"] = 0.22482;
76   convert["LBS"]["N"] = 1.0/convert["N"]["LBS"];
77   convert["KTS"]["FT/SEC"] = 1.68781;
78   convert["FT/SEC"]["KTS"] = 1.0/convert["KTS"]["FT/SEC"];
79   convert["FT*LBS"]["N*M"] = 1.35581795;
80   convert["N*M"]["FT*LBS"] = 1/convert["FT*LBS"]["N*M"];
81
82   convert["M"]["M"] = 1.00;
83   convert["FT"]["FT"] = 1.00;
84   convert["IN"]["IN"] = 1.00;
85   convert["IN3"]["IN3"] = 1.00;
86   convert["DEG"]["DEG"] = 1.00;
87   convert["RAD"]["RAD"] = 1.00;
88   convert["M2"]["M2"] = 1.00;
89   convert["FT2"]["FT2"] = 1.00;
90   convert["KG*M2"]["KG*M2"] = 1.00;
91   convert["SLUG*FT2"]["SLUG*FT2"] = 1.00;
92   convert["KG"]["KG"] = 1.00;
93   convert["LBS"]["LBS"] = 1.00;
94   convert["LBS/FT"]["LBS/FT"] = 1.00;
95   convert["LBS/SEC"]["LBS/SEC"] = 1.00;
96   convert["LBS/FT/SEC"]["LBS/FT/SEC"] = 1.00;
97   convert["N/M"]["N/M"] = 1.00;
98   convert["N/M/SEC"]["N/M/SEC"] = 1.00;
99   convert["PSI"]["PSI"] = 1.00;
100   convert["PSF"]["PSF"] = 1.00;
101   convert["INHG"]["INHG"] = 1.00;
102   convert["HP"]["HP"] = 1.00;
103   convert["N"]["N"] = 1.00;
104   convert["WATTS"]["WATTS"] = 1.00;
105   convert["LBS/SEC"]["LBS/SEC"] = 1.00;
106   convert["FT/SEC"]["FT/SEC"] = 1.00;
107   convert["KTS"]["KTS"] = 1.00;
108   convert["FT*LBS"]["FT*LBS"] = 1.00;
109   convert["N*M"]["N*M"] = 1.00;
110 }
111
112 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113
114 Element::~Element(void)
115 {
116   for (int i=0; i<children.size(); i++) delete children[i];
117   data_lines.clear();
118   attributes.clear();
119   attribute_key.clear();
120 }
121
122 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123
124 string Element::GetAttributeValue(string attr)
125 {
126   int select=-1;
127   for (int i=0; i<attribute_key.size(); i++) {
128     if (attribute_key[i] == attr) select = i;
129   }
130   if (select < 0) return string("");
131   else return attributes[attr];
132 }
133
134 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135
136 double Element::GetAttributeValueAsNumber(string attr)
137 {
138   string attribute = GetAttributeValue(attr);
139
140   if (attribute.empty()) return 99e99;
141   else return (atof(attribute.c_str()));
142 }
143
144 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145
146 Element* Element::GetElement(int el)
147 {
148   if (children.size() > el) {
149     element_index = el;
150     return children[el];
151   }
152   else {
153     element_index = 0;
154     return 0L;
155   }
156 }
157
158 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159
160 Element* Element::GetNextElement(void)
161 {
162   if (children.size() > element_index+1) {
163     element_index++;
164     return children[element_index];
165   } else {
166     element_index = 0;
167     return 0L;
168   }
169 }
170
171 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172
173 string Element::GetDataLine(int i)
174 {
175   if (data_lines.size() > 0) return data_lines[i];
176   else return string("");
177 }
178
179 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180
181 double Element::GetDataAsNumber(void)
182 {
183   if (data_lines.size() == 1) {
184     return atof(data_lines[0].c_str());
185   } else {
186     return 99e99;
187   }
188 }
189
190 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191
192 int Element::GetNumElements(string element_name)
193 {
194   int number_of_elements=0;
195   Element* el=FindElement(element_name);
196   while (el) {
197     number_of_elements++;
198     el=FindNextElement(element_name);
199   }
200   return number_of_elements;
201 }
202
203 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204
205 Element* Element::FindElement(string el)
206 {
207   if (el.empty() && children.size() >= 1) {
208     element_index = 1;
209     return children[0];
210   }
211   for (int i=0; i<children.size(); i++) {
212     if (el == children[i]->GetName()) {
213       element_index = i+1;
214       return children[i];
215     }
216   }
217   element_index = 0;
218   return 0L;
219 }
220
221 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222
223 Element* Element::FindNextElement(string el)
224 {
225   if (el.empty()) {
226     if (element_index < children.size()) {
227       return children[element_index++];
228     } else {
229       element_index = 0;
230       return 0L;
231     }
232   }
233   for (int i=element_index; i<children.size(); i++) {
234     if (el == children[i]->GetName()) {
235       element_index = i+1;
236       return children[i];
237     }
238   }
239   element_index = 0;
240   return 0L;
241 }
242
243 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244
245 double Element::FindElementValueAsNumber(string el)
246 {
247   Element* element = FindElement(el);
248   if (element) {
249     return element->GetDataAsNumber();
250   } else {
251     return 99e99;
252   }
253 }
254
255 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
256
257 string Element::FindElementValue(string el)
258 {
259   Element* element = FindElement(el);
260   if (element) {
261     return element->GetDataLine();
262   } else {
263     return "";
264   }
265 }
266
267 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
268
269 double Element::FindElementValueAsNumberConvertTo(string el, string target_units)
270 {
271   Element* element = FindElement(el);
272   double value;
273   string supplied_units="";
274
275   if (element) {
276      value = element->GetDataAsNumber();
277      supplied_units = element->GetAttributeValue("unit");
278      if (!supplied_units.empty()) {
279        if (convert.find(supplied_units) != convert.end()) {
280          if (convert[supplied_units].find(target_units) != convert[supplied_units].end()) {
281            value *= convert[supplied_units][target_units];
282          } else {
283            cerr << endl << "Target unit: \"" << target_units << "\" does not exist (typo?). Add new unit"
284                 << " conversion in FGXMLElement.cpp." << endl;
285            exit(-1);
286          }
287        } else {
288          cerr << endl << "Supplied unit: \"" << supplied_units << "\" does not exist (typo?). Add new unit"
289               << " conversion in FGXMLElement.cpp." << endl;
290          exit(-1);
291        }
292      }
293   } else {
294     return 99e99;
295   }
296   return value;
297 }
298
299 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
300
301 double Element::FindElementValueAsNumberConvertFromTo( string el,
302                                                        string supplied_units,
303                                                        string target_units)
304 {
305   Element* element = FindElement(el);
306   double value;
307
308   if (element) {
309      value = element->GetDataAsNumber();
310      if (!supplied_units.empty()) {
311        if (convert.find(supplied_units) != convert.end()) {
312          if (convert[supplied_units].find(target_units) != convert[supplied_units].end()) {
313            value *= convert[supplied_units][target_units];
314          } else {
315            cerr << endl << "Target unit: \"" << target_units << "\" does not exist (typo?). Add new unit"
316                 << " conversion in FGXMLElement.cpp." << endl;
317            exit(-1);
318          }
319        } else {
320          cerr << endl << "Supplied unit: \"" << supplied_units << "\" does not exist (typo?). Add new unit"
321               << " conversion in FGXMLElement.cpp." << endl;
322          exit(-1);
323        }
324      }
325   } else {
326     return 99e99;
327   }
328   return value;
329 }
330
331 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332
333 FGColumnVector3 Element::FindElementTripletConvertTo( string target_units)
334 {
335   FGColumnVector3 triplet;
336   Element* item;
337   double value=0.0;
338   string supplied_units = GetAttributeValue("unit");
339
340   item = FindElement("x");
341   if (!item) item = FindElement("roll");
342   if (item) {
343     value = item->GetDataAsNumber();
344     if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
345   } else {
346     value = 0.0;
347     cerr << "Could not find an X triplet item for this column vector." << endl;
348   }
349   triplet(1) = value;
350
351   item = FindElement("y");
352   if (!item) item = FindElement("pitch");
353   if (item) {
354     value = item->GetDataAsNumber();
355     if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
356   } else {
357     value = 0.0;
358     cerr << "Could not find a Y triplet item for this column vector." << endl;
359   }
360   triplet(2) = value;
361
362   item = FindElement("z");
363   if (!item) item = FindElement("yaw");
364   if (item) {
365     value = item->GetDataAsNumber();
366     if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
367   } else {
368     value = 0.0;
369     cerr << "Could not find a Z triplet item for this column vector." << endl;
370   }
371   triplet(3) = value;
372
373   return triplet;
374 }
375
376 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377
378 void Element::Print(int level)
379 {
380   int i, spaces;
381
382   level+=2;
383   for (int spaces=0; spaces<=level; spaces++) cout << " "; // format output
384   cout << "Element Name: " << name;
385   for (int i=0; i<attributes.size(); i++) {
386     cout << "  " << attribute_key[i] << " = " << attributes[attribute_key[i]];
387   }
388   cout << endl;
389   for (i=0; i<data_lines.size(); i++) {
390     for (spaces=0; spaces<=level; spaces++) cout << " "; // format output
391     cout << data_lines[i] << endl;
392   }
393   for (i=0; i<children.size(); i++) {
394     children[i]->Print(level);
395   }
396 }
397
398 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399
400 void Element::AddAttribute(string name, string value)
401 {
402   attribute_key.push_back(name);
403   attributes[name] = value;
404 }
405
406 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
407
408 void Element::AddData(string d)
409 {
410   int string_start = d.find_first_not_of(" ");
411   if (string_start > 0) d.erase(0,string_start-1);
412   data_lines.push_back(d);
413 }
414
415 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
416
417 } // end namespace JSBSim