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