]> git.mxchange.org Git - simgear.git/blob - simgear/xml/easyxml.hxx
Merge branch 'next' of git.mxchange.org:/var/cache/git/repos/simgear into next
[simgear.git] / simgear / xml / easyxml.hxx
1 /**
2  * \file easyxml.hxx
3  * Declarations for the SimGear XML parser.
4  * Written by David Megginson, 2000-2001
5  * This file is in the Public Domain, and comes with NO WARRANTY of any kind.
6  */
7
8 #ifndef __EASYXML_HXX
9 #define __EASYXML_HXX
10
11 #include <simgear/compiler.h>
12 #include <simgear/structure/exception.hxx>
13
14 #include <iosfwd>
15 #include <string>
16 #include <vector>
17
18 class SGPath;
19
20 typedef struct XML_ParserStruct* XML_Parser;
21
22 /**
23  * Interface for XML attributes.
24  *
25  * This interface is used to provide a list of attributes to the
26  * application.  The interface is a pure abstract class so that
27  * different implementations can be substituted for the sake of
28  * efficiency.
29  *
30  * @see XMLAttributesDefault
31  */
32 class XMLAttributes
33 {
34 public:
35
36   /**
37    * Constructor.
38    */
39   XMLAttributes ();
40
41
42   /**
43    * Destructor.
44    */
45   virtual ~ XMLAttributes ();
46
47
48   /**
49    * Get the number of attributes present.
50    *
51    * @return The number of attributes in the list (may be 0).
52    */
53   virtual int size () const = 0;
54
55
56   /**
57    * Get the name of an attribute by index.
58    *
59    * The index must be less than the size of the list and greater
60    * than or equal to zero.
61    *
62    * @param i The index of the attribute (zero-based).
63    * @see #size
64    */
65   virtual const char * getName (int i) const = 0;
66
67
68   /**
69    * Get the string value of an attribute by index.
70    *
71    * The index must be less than the size of the list and greater
72    * than or equal to zero.
73    *
74    * @param i The index of the attribute (zero-based).
75    * @see #size
76    */
77   virtual const char * getValue (int i) const = 0;
78
79
80   /**
81    * Look up the index of an attribute by name.
82    *
83    * Attribute names must be unique.  This method will return
84    * an index that can be used with the {@link #getValue(const char *)}
85    * method if the attribute is found.
86    *
87    * @param name The name of the attribute.
88    * @return The index of the attribute with the name specified,
89    * or -1 if no such attribute is present in the list.
90    */
91   virtual int findAttribute (const char * name) const;
92
93
94   /**
95    * Test whether an attribute is present.
96    *
97    * @param name The name of the attribute.
98    * @return true if an attribute with the specified name is present
99    * in the attribute list, false otherwise.
100    */
101   virtual bool hasAttribute (const char * name) const;
102
103
104   /**
105    * Look up the value of an attribute by name.
106    *
107    * This method provides a convenient short-cut to invoking
108    * {@link #findAttribute} and {@link #getValue(const char *)}.
109    *
110    * @param name The name of the attribute to look up.
111    * @return The attribute's value as a string, or 0 if no
112    * attribute was found with the name specified.
113    */
114   virtual const char * getValue (const char * name) const;
115 };
116
117
118 /**
119  * Default mutable attributes implementation.
120  *
121  * This class provides a default implementation of the {@link
122  * XMLAttributes} interface.  The implementation is mutable, so
123  * that it is possible to modify the attribute list when necessary.
124  * This class is particularly useful for taking a snapshot of
125  * an attribute list during parsing.
126  *
127  * @see XMLAttributes
128  */
129 class XMLAttributesDefault : public XMLAttributes
130 {
131 public:
132
133   /**
134    * Default constructor.
135    */
136   XMLAttributesDefault ();
137
138
139   /**
140    * Copy constructor.
141    *
142    * This constructor is especially useful for taking a static
143    * snapshot of an attribute list for later use.
144    *
145    * @param atts The attribute list to copy.
146    */
147   XMLAttributesDefault (const XMLAttributes & atts);
148
149
150   /**
151    * Destructor.
152    */
153   virtual ~XMLAttributesDefault ();
154
155
156   /**
157    * Count the attributes in the list.
158    */
159   virtual int size () const;
160
161
162   /**
163    * Get the name of an attribute by index.
164    */
165   virtual const char * getName (int i) const;
166
167
168   /**
169    * Get the value of an attribute by index.
170    */
171   virtual const char * getValue (int i) const;
172
173
174   /**
175    * Add an attribute to an attribute list.
176    *
177    * The name is required to be unique in the list; the value is not.
178    *
179    * @param name The name of the attribute to add.
180    * @param value The value of the attribute to add.
181    */
182   virtual void addAttribute (const char * name, const char * value);
183
184
185   /**
186    * Set an attribute name by index.
187    *
188    * This method will not extend the list; the attribute must
189    * already exist.
190    *
191    * @param i The index of the attribute (zero-based).
192    * @param name The new name.
193    */
194   virtual void setName (int i, const char * name);
195
196
197   /**
198    * Set an attribute value by index.
199    *
200    * This method will not extend the list; the attribute must
201    * already exist.
202    *
203    * @param i The index of the attribute (zero-based).
204    * @param value The new value.
205    */
206   virtual void setValue (int i, const char * value);
207
208
209   /**
210    * Set an attribute value by name.
211    *
212    * This method will not extend the list; the attribute must
213    * already exist.
214    *
215    * @param name The name of the attribute that will have the new
216    * value.
217    * @param value The new value.
218    */
219   virtual void setValue (const char * name, const char * value);
220
221 private:
222   std::vector<std::string> _atts;
223 };
224
225 ////////////////////////////////////////////////////////////////////////
226 // Attribute list wrapper for Expat.
227 ////////////////////////////////////////////////////////////////////////
228
229 class ExpatAtts : public XMLAttributes
230 {
231 public:
232   ExpatAtts (const char ** atts) : _atts(atts) {}
233
234   virtual int size () const;
235   virtual const char * getName (int i) const;
236   virtual const char * getValue (int i) const;
237
238   virtual const char * getValue (const char * name) const;
239 private:
240   const char ** _atts;
241 };
242
243
244 /**
245  * Visitor class for an XML document.
246  *
247  * This interface uses the Visitor pattern.  The XML parser walks
248  * through the XML document and invokes the appropriate method in
249  * this visitor for each piece of markup it finds.  By default,
250  * the methods do nothing; the application must subclass the visitor
251  * and override the methods for the events it's interested in.
252  * All applications are required to provide an implementation
253  * for the {@link #error} callback.
254  */
255 class XMLVisitor
256 {
257 public:
258   /// Constructor
259   XMLVisitor() : parser(0), line(-1), column(-1) {}
260
261   /**
262    * Virtual destructor.
263    */
264   virtual ~XMLVisitor () {}
265
266
267   /**
268    * Callback for the start of an XML document.
269    *
270    * The XML parser will invoke this method once, at the beginning of
271    * the XML document, before any other methods are invoked.  The
272    * application can use this callback to set up data structures,
273    * open files, etc.
274    *
275    * @see #endXML
276    */
277   virtual void startXML () {}
278
279
280   /**
281    * Callback for the end of an XML document.
282    *
283    * The XML parser will invoke this method once, at the end of the
284    * XML document, after all other methods are invoked, and only
285    * if there have been no parsing errors.  The application can use
286    * this callback to close or write files, finalize data structures,
287    * and so on, but the application will need to be prepared to
288    * clean up any resources without this callback in the event of
289    * an error.
290    *
291    * @see #startXML
292    * @see #error
293    */
294   virtual void endXML () {}
295
296
297   /**
298    * Callback for the start of an XML element.
299    *
300    * The XML parser will invoke this method at the beginning of every
301    * XML element.  Start and end element calls will be balanced
302    * and properly nested: every element has both a start and end
303    * callback (even if it was specified with an XML empty element tag),
304    * there is exactly one root element, and every element must end
305    * before its parent does.  Elements may not overlap.
306    * Note that the attribute list provided is volatile; it's contents
307    * are not guaranteed to persist after the end of the callback.
308    * If the application needs to keep a copy of the attribute list,
309    * it can make the copy with the {@link XMLAttributesDefault} class.
310    *
311    * @param name The name of the element that is starting (not null).
312    * @param atts The element's attributes (not null).
313    * @see #endElement
314    */
315   virtual void startElement (const char * name, const XMLAttributes &atts) {}
316
317
318   /**
319    * Callback for the end of an XML element.
320    *
321    * The XML parser will invoke this method at the end of every XML element.
322    *
323    * @param name The name of the element that is ending (not null).
324    * @see #startElement
325    */
326   virtual void endElement (const char * name) {}
327
328
329   /**
330    * Callback for a chunk of character data.
331    *
332    * The XML parser will invoke this method once for every chunk of
333    * character data in the XML document, including whitespace
334    * separating elements (as required by the XML recommendation).
335    * Note that character data may be chunked arbitrarily: the
336    * character data content of an element may be returned in one
337    * large chunk or several consecutive smaller chunks.
338    *
339    * @param s A pointer to the beginning of the character data (not null).
340    * @param length The number of characters in the chunk (may
341    * be zero).
342    */
343   virtual void data (const char * s, int length) {}
344
345
346   /**
347    * Callback for an XML processing instruction.
348    *
349    * The XML parser will invoke this method once for every processing
350    * instruction in the XML document.  Note that the XML declaration
351    * and the Text declaration are NOT PROCESSING INSTRUCTIONS and
352    * will not be reported through this callback.  Processing
353    * instructions are not all that useful, but the XML recommendation
354    * requires that they be reported.  Most applications can safely
355    * ignore this callback and use the empty default implementation.
356    *
357    * @param target The processing instruction target (not null).
358    * @param data The processing instruction data (not null).
359    */
360   virtual void pi (const char * target, const char * data) {}
361
362
363   /**
364    * Callback for an XML parsing warning.
365    *
366    * The XML parser will use this callback to report any non-fatal warnings
367    * during parsing.  It is the responsibility of the application to
368    * deal with the warning in some appropriate way.
369    *
370    * @param message The warning message from the parser.
371    * @param line The number of the line that generated the warning.
372    * @param column The character position in the line that generated
373    * the warning.
374    */
375   virtual void warning (const char * message, int line, int column) {}
376
377   /** Set the path to the file that is parsed.
378    *
379    * This method will be called to store the path to the parsed file. Note that
380    * the XML parser makes no use of this copy of the path. The intent is
381    * to be capable of refering to the path to the parsed file if needed.
382    *
383    * @param _path The path to the parsed file.
384    * @see #getPath
385    */
386   void setPath(const std::string& _path) { path = _path; }
387
388   /** Get the path to the parsed file.
389    *
390    * This method will be called if the application needs to access the path to
391    * the parsed file. This information is typically needed if an error is found
392    * so the file where it occurred can be retrieved to help the user locate the
393    * error.
394    *
395    * @return the path to the parsed file.
396    * @see #setPath
397    */
398   const std::string& getPath(void) const { return path; }
399
400   /** Save the current position in the parsed file.
401    *
402    * This method will be called to save the position at which the file is
403    * currently parsed. Note that the XML parser makes no use of that
404    * information. The intent is to be capable of refering to the position in
405    * the parsed file if needed.
406    *
407    * @see #getColumn
408    * @see #getLine
409    */
410   void savePosition(void);
411
412   /** Get the saved column number in the parsed file.
413    *
414    * This method will be called if the application needs to get the column
415    * number that has been saved during the last call to savePosition(). This
416    * information is typically needed if an error is found so the position at
417    * which it occurred can be retrieved to help the user locate the error.
418    *
419    * @return the save column number.
420    * @see #savePosition
421    */
422   int getColumn(void) const { return column; }
423
424   /** Get the saved line number in the parsed file.
425    *
426    * This method will be called if the application needs to get the line
427    * number that has been saved during the last call to savePosition(). This
428    * information is typically needed if an error is found so the position at
429    * which it occurred can be retrieved to help the user locate the error.
430    *
431    * @return the save line number.
432    * @see #savePosition
433    */
434   int getLine(void) const { return line; }
435
436   /** Set the XML parser.
437    *
438    * This method will be called so the #XMLVisitor instance can internally use
439    * the XML parser for its housekeeping. The intent is that #XMLVisitor will
440    * only call the reporting functions of the XML parser and will not interfer
441    * with the XML parser current state. Doing otherwise will result in an
442    * unpredictable behavior of the XML parser.
443    *
444    * @param _parser the XML parser
445    */
446   void setParser(XML_Parser _parser) { parser = _parser; }
447 private:
448   XML_Parser parser;
449   std::string path;
450   int line, column;
451 };
452
453
454 /**
455  * @relates XMLVisitor
456  * Read an XML document.
457  *
458  * This function reads an XML document from the input stream provided,
459  * and invokes the callback methods in the visitor object to pass the
460  * parsing events back to the application.  When this function
461  * returns, the parser will have reported all of the data in the XML
462  * document to the application through the visitor callback methods,
463  * and XML processing will be complete.
464  *
465  * @param input The byte input stream containing the XML document.
466  * @param visitor An object that contains callbacks for XML parsing
467  * events.
468  * @param path A string describing the original path of the resource.
469  * @exception Throws sg_io_exception or sg_xml_exception if there
470  * is a problem reading the file.
471  * @see XMLVisitor
472  */
473 extern void readXML (std::istream &input, XMLVisitor &visitor,
474                      const std::string &path="");
475
476
477 /**
478  * @relates XMLVisitor
479  * Read an XML document.
480  *
481  * This function reads an XML document from the input stream provided,
482  * and invokes the callback methods in the visitor object to pass the
483  * parsing events back to the application.  When this function
484  * returns, the parser will have reported all of the data in the XML
485  * document to the application through the visitor callback methods,
486  * and XML processing will be complete.
487  *
488  * @param path The file name of the XML resource.
489  * @param visitor An object that contains callbacks for XML parsing
490  * events.
491  * @exception Throws sg_io_exception or sg_xml_exception if there
492  * is a problem reading the file.
493  * @see XMLVisitor
494  */
495 extern void readXML (const SGPath &path, XMLVisitor &visitor);
496
497
498 /**
499  * @relates XMLVisitor
500  * Read an XML document.
501  *
502  * This function reads an XML document from the buffer provided,
503  * and invokes the callback methods in the visitor object to pass the
504  * parsing events back to the application.  When this function
505  * returns, the parser will have reported all of the data in the XML
506  * document to the application through the visitor callback methods,
507  * and XML processing will be complete.
508  *
509  * @param buf The xml data buffer.
510  * @param size The size of the data buffer in bytes
511  * @param visitor An object that contains callbacks for XML parsing
512  * events.
513  * @exception Throws sg_io_exception or sg_xml_exception if there
514  * is a problem reading the file.
515  * @see XMLVisitor
516  */
517 extern void readXML (const char *buf, const int size, XMLVisitor &visitor);
518
519
520 #endif // __EASYXML_HXX