]> git.mxchange.org Git - simgear.git/blob - simgear/xml/easyxml.cxx
Fix a build order problem.
[simgear.git] / simgear / xml / easyxml.cxx
1 // easyxml.cxx - implementation of EasyXML interfaces.
2
3 #ifdef HAVE_CONFIG_H
4 #  include <config.h>
5 #endif
6
7 #include <simgear/compiler.h>
8
9 #include <string.h>             // strcmp()
10
11 #include "easyxml.hxx"
12 #include "xmlparse.h"
13
14 \f
15 ////////////////////////////////////////////////////////////////////////
16 // Implementation of XMLAttributes.
17 ////////////////////////////////////////////////////////////////////////
18
19 XMLAttributes::XMLAttributes ()
20 {
21 }
22
23 XMLAttributes::~XMLAttributes ()
24 {
25 }
26
27 int
28 XMLAttributes::findAttribute (const char * name) const
29 {
30   int s = size();
31   for (int i = 0; i < s; i++) {
32     if (strcmp(name, getName(i)) == 0)
33       return i;
34   }
35   return -1;
36 }
37
38 bool
39 XMLAttributes::hasAttribute (const char * name) const
40 {
41   return (findAttribute(name) != -1);
42 }
43
44 const char *
45 XMLAttributes::getValue (const char * name) const
46 {
47   int pos = findAttribute(name);
48   if (pos >= 0)
49     return getValue(pos);
50   else
51     return 0;
52 }
53
54 \f
55 ////////////////////////////////////////////////////////////////////////
56 // Implementation of XMLAttributesDefault.
57 ////////////////////////////////////////////////////////////////////////
58
59 XMLAttributesDefault::XMLAttributesDefault ()
60 {
61 }
62
63 XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
64 {
65   int s = atts.size();
66   for (int i = 0; i < s; i++)
67     addAttribute(atts.getName(i), atts.getValue(i));
68 }
69
70 XMLAttributesDefault::~XMLAttributesDefault ()
71 {
72 }
73
74 int
75 XMLAttributesDefault::size () const
76 {
77   return _atts.size() / 2;
78 }
79
80 const char *
81 XMLAttributesDefault::getName (int i) const
82 {
83   return _atts[i*2].c_str();
84 }
85
86 const char *
87 XMLAttributesDefault::getValue (int i) const
88 {
89   return _atts[i*2+1].c_str();
90 }
91
92 void
93 XMLAttributesDefault::addAttribute (const char * name, const char * value)
94 {
95   _atts.push_back(name);
96   _atts.push_back(value);
97 }
98
99 void
100 XMLAttributesDefault::setName (int i, const char * name)
101 {
102   _atts[i*2] = name;
103 }
104
105 void
106 XMLAttributesDefault::setValue (int i, const char * name)
107 {
108   _atts[i*2+1] = name;
109 }
110
111 void
112 XMLAttributesDefault::setValue (const char * name, const char * value)
113 {
114   int pos = findAttribute(name);
115   if (pos >= 0) {
116     setName(pos, name);
117     setValue(pos, value);
118   } else {
119     addAttribute(name, value);
120   }
121 }
122
123
124 \f
125 ////////////////////////////////////////////////////////////////////////
126 // Attribute list wrapper for Expat.
127 ////////////////////////////////////////////////////////////////////////
128
129 class ExpatAtts : public XMLAttributes
130 {
131 public:
132   ExpatAtts (const char ** atts) : _atts(atts) {}
133   
134   virtual int size () const;
135   virtual const char * getName (int i) const;
136   virtual const char * getValue (int i) const;
137   
138 private:
139   const char ** _atts;
140 };
141
142 int
143 ExpatAtts::size () const
144 {
145   int s = 0;
146   for (int i = 0; _atts[i] != 0; i += 2)
147     s++;
148   return s;
149 }
150
151 const char *
152 ExpatAtts::getName (int i) const
153 {
154   return _atts[i*2];
155 }
156
157 const char *
158 ExpatAtts::getValue (int i) const
159 {
160   return _atts[i*2+1];
161 }
162
163
164 \f
165 ////////////////////////////////////////////////////////////////////////
166 // Static callback functions for Expat.
167 ////////////////////////////////////////////////////////////////////////
168
169 #define VISITOR (*((XMLVisitor*)userData))
170
171 static void
172 start_element (void * userData, const char * name, const char ** atts)
173 {
174   VISITOR.startElement(name, ExpatAtts(atts));
175 }
176
177 static void
178 end_element (void * userData, const char * name)
179 {
180   VISITOR.endElement(name);
181 }
182
183 static void
184 character_data (void * userData, const char * s, int len)
185 {
186   VISITOR.data(s, len);
187 }
188
189 static void
190 processing_instruction (void * userData,
191                         const char * target,
192                         const char * data)
193 {
194   VISITOR.pi(target, data);
195 }
196
197 #undef VISITOR
198
199
200 \f
201 ////////////////////////////////////////////////////////////////////////
202 // Implementation of XMLReader.
203 ////////////////////////////////////////////////////////////////////////
204
205 bool
206 readXML (istream &input, XMLVisitor &visitor)
207 {
208   bool retval = true;
209
210   XML_Parser parser = XML_ParserCreate(0);
211   XML_SetUserData(parser, &visitor);
212   XML_SetElementHandler(parser, start_element, end_element);
213   XML_SetCharacterDataHandler(parser, character_data);
214   XML_SetProcessingInstructionHandler(parser, processing_instruction);
215
216   visitor.startXML();
217
218   char buf[16384];
219   while (!input.eof()) {
220
221     input.read(buf,16384);
222                                 // TODO: deal with bad stream.
223     if (!XML_Parse(parser, buf, input.gcount(), false)) {
224       visitor.error(XML_ErrorString(XML_GetErrorCode(parser)),
225                     XML_GetCurrentColumnNumber(parser),
226                     XML_GetCurrentLineNumber(parser));
227       retval = false;
228     }
229   }
230
231   if (retval)
232     visitor.endXML();
233
234   XML_ParserFree(parser);
235
236   return retval;
237 }
238
239 // end of easyxml.cxx