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