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