Branch data Line data Source code
1 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 : :
3 : : Module: easyxml.cxx
4 : : Author: David Megginson
5 : : (slightly re-formatted here by Jon Berndt)
6 : : Date started: 2000
7 : : Purpose: Wraps eXpat
8 : : Called by: classes that read XML data
9 : : Notes: The SimGear exception handling calls have here been removed.
10 : :
11 : : License: David Megginson has placed easyXML into the public domain.
12 : :
13 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14 : : INCLUDES
15 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
16 : :
17 : : #include "../compiler.h"
18 : :
19 : : #include <string.h>
20 : :
21 : : #include "easyxml.hxx"
22 : : #include "expat.h"
23 : :
24 : : #include STL_FSTREAM
25 : : #include STL_IOSTREAM
26 : :
27 : : SG_USING_STD(ifstream);
28 : : SG_USING_STD(cerr);
29 : : SG_USING_STD(endl);
30 : :
31 : : ////////////////////////////////////////////////////////////////////////
32 : : // Implementation of XMLAttributes.
33 : : ////////////////////////////////////////////////////////////////////////
34 : :
35 : 930 : XMLAttributes::XMLAttributes ()
36 : : {
37 : 0 : }
38 : :
39 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 : :
41 : 930 : XMLAttributes::~XMLAttributes ()
42 : : {
43 [ # # ][ # # ]: 930 : }
[ - + ]
44 : :
45 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46 : :
47 : 0 : int XMLAttributes::findAttribute (const char * name) const
48 : : {
49 : 0 : int s = size();
50 [ # # ]: 0 : for (int i = 0; i < s; i++) {
51 [ # # ]: 0 : if (strcmp(name, getName(i)) == 0)
52 : 0 : return i;
53 : : }
54 : 0 : return -1;
55 : : }
56 : :
57 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58 : :
59 : 0 : bool XMLAttributes::hasAttribute (const char * name) const
60 : : {
61 : 0 : return (findAttribute(name) != -1);
62 : : }
63 : :
64 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65 : :
66 : 0 : const char *XMLAttributes::getValue (const char * name) const
67 : : {
68 : 0 : int pos = findAttribute(name);
69 [ # # ]: 0 : if (pos >= 0)
70 : 0 : return getValue(pos);
71 : : else
72 : 0 : return 0;
73 : : }
74 : :
75 : : ////////////////////////////////////////////////////////////////////////
76 : : // Implementation of XMLAttributesDefault.
77 : : ////////////////////////////////////////////////////////////////////////
78 : :
79 : 0 : XMLAttributesDefault::XMLAttributesDefault ()
80 : : {
81 : 0 : }
82 : :
83 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 : :
85 : 0 : XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
86 : : {
87 : 0 : int s = atts.size();
88 [ # # ][ # # ]: 0 : for (int i = 0; i < s; i++)
89 : 0 : addAttribute(atts.getName(i), atts.getValue(i));
90 : 0 : }
91 : :
92 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93 : :
94 : 0 : XMLAttributesDefault::~XMLAttributesDefault ()
95 : : {
96 [ # # ][ # # ]: 0 : }
[ # # ]
97 : :
98 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99 : :
100 : 0 : int XMLAttributesDefault::size () const
101 : : {
102 : 0 : return _atts.size() / 2;
103 : : }
104 : :
105 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 : :
107 : 0 : const char *XMLAttributesDefault::getName (int i) const
108 : : {
109 : 0 : return _atts[i*2].c_str();
110 : : }
111 : :
112 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113 : :
114 : 0 : const char *XMLAttributesDefault::getValue (int i) const
115 : : {
116 : 0 : return _atts[i*2+1].c_str();
117 : : }
118 : :
119 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120 : :
121 : 0 : void XMLAttributesDefault::addAttribute (const char * name, const char * value)
122 : : {
123 : 0 : _atts.push_back(name);
124 : 0 : _atts.push_back(value);
125 : 0 : }
126 : :
127 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 : :
129 : 0 : void XMLAttributesDefault::setName (int i, const char * name)
130 : : {
131 : 0 : _atts[i*2] = name;
132 : 0 : }
133 : :
134 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 : :
136 : 0 : void XMLAttributesDefault::setValue (int i, const char * name)
137 : : {
138 : 0 : _atts[i*2+1] = name;
139 : 0 : }
140 : :
141 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142 : :
143 : 0 : void XMLAttributesDefault::setValue (const char * name, const char * value)
144 : : {
145 : 0 : int pos = findAttribute(name);
146 [ # # ]: 0 : if (pos >= 0) {
147 : 0 : setName(pos, name);
148 : 0 : setValue(pos, value);
149 : : } else {
150 : 0 : addAttribute(name, value);
151 : : }
152 : 0 : }
153 : :
154 : : ////////////////////////////////////////////////////////////////////////
155 : : // Attribute list wrapper for Expat.
156 : : ////////////////////////////////////////////////////////////////////////
157 : :
158 : : class ExpatAtts : public XMLAttributes
159 [ # # ][ - + ]: 930 : {
160 : : public:
161 : 1860 : ExpatAtts (const char ** atts) : _atts(atts) {}
162 : :
163 : : virtual int size () const;
164 : : virtual const char * getName (int i) const;
165 : : virtual const char * getValue (int i) const;
166 : :
167 : : private:
168 : : const char ** _atts;
169 : : };
170 : :
171 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 : :
173 : 1443 : int ExpatAtts::size () const
174 : : {
175 : 1443 : int s = 0;
176 [ + + ]: 2677 : for (int i = 0; _atts[i] != 0; i += 2)
177 : 1234 : s++;
178 : 1443 : return s;
179 : : }
180 : :
181 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 : :
183 : 513 : const char *ExpatAtts::getName (int i) const
184 : : {
185 : 513 : return _atts[i*2];
186 : : }
187 : :
188 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189 : :
190 : 513 : const char *ExpatAtts::getValue (int i) const
191 : : {
192 : 513 : return _atts[i*2+1];
193 : : }
194 : :
195 : : ////////////////////////////////////////////////////////////////////////
196 : : // Static callback functions for Expat.
197 : : ////////////////////////////////////////////////////////////////////////
198 : :
199 : : #define VISITOR (*((XMLVisitor *)userData))
200 : :
201 : 930 : static void start_element (void * userData, const char * name, const char ** atts)
202 : : {
203 : 930 : VISITOR.startElement(name, ExpatAtts(atts));
204 : 930 : }
205 : :
206 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207 : :
208 : 930 : static void end_element (void * userData, const char * name)
209 : : {
210 : 930 : VISITOR.endElement(name);
211 : 930 : }
212 : :
213 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214 : :
215 : 4001 : static void character_data (void * userData, const char * s, int len)
216 : : {
217 : 4001 : VISITOR.data(s, len);
218 : 4001 : }
219 : :
220 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 : :
222 : : static void processing_instruction (void * userData,
223 : : const char * target,
224 : 2 : const char * data)
225 : : {
226 : 2 : VISITOR.pi(target, data);
227 : 2 : }
228 : :
229 : : #undef VISITOR
230 : :
231 : : ////////////////////////////////////////////////////////////////////////
232 : : // Implementation of XMLReader.
233 : : ////////////////////////////////////////////////////////////////////////
234 : :
235 : 31 : void readXML (istream &input, XMLVisitor &visitor, const string &path)
236 : : {
237 : 31 : XML_Parser parser = XML_ParserCreate(0);
238 : 31 : XML_SetUserData(parser, &visitor);
239 : 31 : XML_SetElementHandler(parser, start_element, end_element);
240 : 31 : XML_SetCharacterDataHandler(parser, character_data);
241 : 31 : XML_SetProcessingInstructionHandler(parser, processing_instruction);
242 : :
243 : 31 : visitor.startXML();
244 : :
245 : : char buf[16384];
246 [ + + ]: 63 : while (!input.eof()) {
247 : :
248 [ - + ]: 32 : if (!input.good()) {
249 : 0 : XML_ParserFree(parser);
250 : 0 : cerr << "Problem reading input file" << endl;
251 : 0 : abort();
252 : : }
253 : :
254 : 32 : input.read(buf,16384);
255 [ - + ]: 32 : if (!XML_Parse(parser, buf, input.gcount(), false)) {
256 : 0 : XML_ParserFree(parser);
257 : 0 : cerr << "XML parse error: " << XML_ErrorString(XML_GetErrorCode(parser)) << endl;
258 : 0 : abort();
259 : : }
260 : :
261 : : }
262 : :
263 : : // Verify end of document.
264 [ - + ]: 31 : if (!XML_Parse(parser, buf, 0, true)) {
265 : 0 : XML_ParserFree(parser);
266 : 0 : cerr << "XML parse error: " << XML_ErrorString(XML_GetErrorCode(parser)) << endl;
267 : 0 : abort();
268 : : }
269 : :
270 : 31 : XML_ParserFree(parser);
271 : 31 : }
272 : :
273 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274 : :
275 : 0 : void readXML (const string &path, XMLVisitor &visitor)
276 : : {
277 : 0 : ifstream input(path.c_str());
278 [ # # ]: 0 : if (input.good()) {
279 : : try {
280 : 0 : readXML(input, visitor, path);
281 : 0 : } catch (...) {
282 : 0 : input.close();
283 : 0 : cerr << "Failed to open file" << endl;
284 : 0 : abort();
285 : : }
286 : : } else {
287 : 0 : cerr << "Failed to open file" << endl;
288 : 0 : abort();
289 : : }
290 : 0 : input.close();
291 [ + + ][ + - ]: 12 : }
292 : :
293 : : // end of easyxml.cxx
|