FlightGear next
xmlloader.cxx
Go to the documentation of this file.
1// This program is free software; you can redistribute it and/or
2// modify it under the terms of the GNU General Public License as
3// published by the Free Software Foundation; either version 2 of the
4// License, or (at your option) any later version.
5//
6// This program is distributed in the hope that it will be useful, but
7// WITHOUT ANY WARRANTY; without even the implied warranty of
8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9// General Public License for more details.
10//
11// You should have received a copy of the GNU General Public License
12// along with this program; if not, write to the Free Software
13// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14//
15
16#ifdef HAVE_CONFIG_H
17# include "config.h"
18#endif
19
20#include <cstdio>
21#include <utility>
22
23#include <simgear/misc/sg_path.hxx>
24#include <simgear/xml/easyxml.hxx>
25#include <simgear/misc/strutils.hxx>
26#include <simgear/timing/timestamp.hxx>
27
28#include <Main/globals.hxx>
29#include <Main/fg_props.hxx>
30
31#include "xmlloader.hxx"
32#include "dynamicloader.hxx"
33#include "runwayprefloader.hxx"
34
35#include "dynamics.hxx"
36#include "airport.hxx"
37#include "runwayprefs.hxx"
38
41
42using std::string;
43
46
48{
49 SGPath path;
50 if (!findAirportData(net->airport()->ident(), "groundnet", path)) {
51 return;
52 }
53
54 SG_LOG(SG_NAVAID, SG_DEBUG, "reading groundnet data from " << path);
55 SGTimeStamp t;
56 t.stamp();
57 try {
58 FGGroundNetXMLLoader visitor(net);
59 readXML(path, visitor);
60
61 if (visitor.hasErrors() && fgGetBool("/sim/terrasync/enabled")) {
62 flightgear::updateSentryTag("ground-net", net->airport()->ident());
63 flightgear::sentryReportException("Ground-net load error", path.utf8Str());
64 }
65 } catch (sg_exception& e) {
66 SG_LOG(SG_NAVAID, SG_DEV_WARN, "parsing groundnet XML failed:" << e.getFormattedMessage());
67 }
68
69 SG_LOG(SG_NAVAID, SG_DEBUG, "parsing groundnet XML took " << t.elapsedMSec());
70}
71
72void XMLLoader::loadFromStream(FGGroundNetwork* net, std::istream& inData)
73{
74 try {
75 FGGroundNetXMLLoader visitor(net);
76 readXML(inData, visitor);
77
78 if (visitor.hasErrors()) {
79 flightgear::sentryReportException("Ground-net load error", {});
80 }
81 } catch (sg_exception& e) {
82 SG_LOG(SG_NAVAID, SG_DEV_WARN, "parsing groundnet XML failed:" << e.getFormattedMessage());
83 }
84}
85
86void XMLLoader::loadFromPath(FGGroundNetwork* net, const SGPath& path)
87{
88 try {
89 FGGroundNetXMLLoader visitor(net);
90 readXML(path, visitor);
91
92 if (visitor.hasErrors() && fgGetBool("/sim/terrasync/enabled")) {
93 flightgear::updateSentryTag("ground-net", net->airport()->ident());
94 flightgear::sentryReportException("Ground-net load error", path.utf8Str());
95 }
96 } catch (sg_exception& e) {
97 SG_LOG(SG_NAVAID, SG_DEV_WARN, "parsing groundnet XML failed:" << e.getFormattedMessage());
98 }
99}
100
103 loadAirportXMLDataIntoVisitor(p->getId(), "rwyuse", visitor);
104}
105
106bool XMLLoader::findAirportData(const std::string& aICAO,
107 const std::string& aFileName, SGPath& aPath)
108{
109 FGAirportRef airport = FGAirport::findByIdent(aICAO);
110 if (!airport) {
111 return false;
112 }
113
114 string fileName(aFileName);
115 if (!simgear::strutils::ends_with(aFileName, ".xml")) {
116 fileName.append(".xml");
117 }
118
119 const bool performFullTraversal = airport->sceneryPath().isNull() ||
120 !fileName.compare("procedures.xml");
121
122 PathList sc = globals->get_fg_scenery();
123 char buffer[128];
124 ::snprintf(buffer, 128, "%c/%c/%c/%s.%s",
125 aICAO[0], aICAO[1], aICAO[2],
126 aICAO.c_str(), fileName.c_str());
127
128 for (PathList::const_iterator it = sc.begin(); it != sc.end(); ++it) {
129 // fg_senery contains empty strings as "markers" (see FGGlobals::set_fg_scenery)
130 if (!it->isNull()) {
131 const SGPath path = *it / "Airports" / buffer;
132 if (path.exists()) {
133 aPath = std::move(path);
134 return true;
135 } // of path exists
136
137 // Unless we are in “full traversal mode”, don't look in scenery paths
138 // that come after the one which contributed the apt.dat file for the
139 // airport.
140 if (!performFullTraversal && *it == airport->sceneryPath()) {
141 return false;
142 }
143 }
144 } // of scenery path iteration
145 return false;
146}
147
149 const string& aFileName, XMLVisitor& aVisitor)
150{
151 SGPath path;
152 if (!findAirportData(aICAO, aFileName, path)) {
153 SG_LOG(SG_NAVAID, SG_DEBUG, "loadAirportXMLDataIntoVisitor: failed to find data for " << aICAO << "/" << aFileName);
154 return false;
155 }
156
157 bool readXMLOk = true;
158 try {
159 SG_LOG(SG_NAVAID, SG_DEBUG, "loadAirportXMLDataIntoVisitor: loading from " << path);
160 readXML(path, aVisitor);
161 } catch (sg_exception& e) {
162 readXMLOk = false;
163 SG_LOG(SG_NAVAID, SG_WARN, "XML errors trying to read:" << path);
164 }
165
166 return readXMLOk;
167}
168
#define p(x)
SGSharedPtr< FGAirport > FGAirportRef
static FGAirportRef findByIdent(const std::string &aIdent)
Helper to look up an FGAirport instance by unique ident.
Definition airport.cxx:489
FGAirport * airport() const
const std::string & ident() const
static void loadFromPath(FGGroundNetwork *net, const SGPath &path)
Definition xmlloader.cxx:86
static void load(FGRunwayPreference *p)
static void loadFromStream(FGGroundNetwork *net, std::istream &inData)
Definition xmlloader.cxx:72
static bool loadAirportXMLDataIntoVisitor(const std::string &aICAO, const std::string &aFileName, XMLVisitor &aVisitor)
Search the scenery for a file name of the form: I/C/A/ICAO.filename.xml and parse it as an XML proper...
static bool findAirportData(const std::string &aICAO, const std::string &aFileName, SGPath &aPath)
Search the scenery for a file name of the form: I/C/A/ICAO.filename.xml and return the corresponding ...
FGGlobals * globals
Definition globals.cxx:142
std::vector< SGPath > PathList
Definition globals.hxx:37
void updateSentryTag(const std::string &, const std::string &)
void sentryReportException(const std::string &, const std::string &)
bool fgGetBool(char const *name, bool def)
Get a bool value for a property.
Definition proptest.cpp:25