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