X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fxml%2Feasyxml.hxx;h=7f0c916e2e20642a8988dd8ec22d3c5e979c4f5f;hb=819833a56030570718b9cc2aa1a52daa34631e18;hp=ec4d31b167bb99b92b82e7bb3f28acf53de548b8;hpb=60cbe9c1d4e9b4fb56008964eb1a4634046fd2a7;p=simgear.git diff --git a/simgear/xml/easyxml.hxx b/simgear/xml/easyxml.hxx index ec4d31b1..7f0c916e 100644 --- a/simgear/xml/easyxml.hxx +++ b/simgear/xml/easyxml.hxx @@ -1,90 +1,518 @@ +/** + * \file easyxml.hxx + * Declarations for the SimGear XML parser. + * Written by David Megginson, 2000-2001 + * This file is in the Public Domain, and comes with NO WARRANTY of any kind. + */ + #ifndef __EASYXML_HXX #define __EASYXML_HXX +#include +#include + #include #include #include -using std::istream; -using std::string; -using std::vector; - +typedef struct XML_ParserStruct* XML_Parser; /** * Interface for XML attributes. + * + * This interface is used to provide a list of attributes to the + * application. The interface is a pure abstract class so that + * different implementations can be substituted for the sake of + * efficiency. + * + * @see XMLAttributesDefault */ class XMLAttributes { public: + + /** + * Constructor. + */ XMLAttributes (); + + + /** + * Destructor. + */ virtual ~ XMLAttributes (); + + /** + * Get the number of attributes present. + * + * @return The number of attributes in the list (may be 0). + */ virtual int size () const = 0; + + + /** + * Get the name of an attribute by index. + * + * The index must be less than the size of the list and greater + * than or equal to zero. + * + * @param i The index of the attribute (zero-based). + * @see #size + */ virtual const char * getName (int i) const = 0; + + + /** + * Get the string value of an attribute by index. + * + * The index must be less than the size of the list and greater + * than or equal to zero. + * + * @param i The index of the attribute (zero-based). + * @see #size + */ virtual const char * getValue (int i) const = 0; + + /** + * Look up the index of an attribute by name. + * + * Attribute names must be unique. This method will return + * an index that can be used with the {@link #getValue(const char *)} + * method if the attribute is found. + * + * @param name The name of the attribute. + * @return The index of the attribute with the name specified, + * or -1 if no such attribute is present in the list. + */ virtual int findAttribute (const char * name) const; + + + /** + * Test whether an attribute is present. + * + * @param name The name of the attribute. + * @return true if an attribute with the specified name is present + * in the attribute list, false otherwise. + */ virtual bool hasAttribute (const char * name) const; + + + /** + * Look up the value of an attribute by name. + * + * This method provides a convenient short-cut to invoking + * {@link #findAttribute} and {@link #getValue(const char *)}. + * + * @param name The name of the attribute to look up. + * @return The attribute's value as a string, or 0 if no + * attribute was found with the name specified. + */ virtual const char * getValue (const char * name) const; }; /** * Default mutable attributes implementation. + * + * This class provides a default implementation of the {@link + * XMLAttributes} interface. The implementation is mutable, so + * that it is possible to modify the attribute list when necessary. + * This class is particularly useful for taking a snapshot of + * an attribute list during parsing. + * + * @see XMLAttributes */ class XMLAttributesDefault : public XMLAttributes { public: + + /** + * Default constructor. + */ XMLAttributesDefault (); + + + /** + * Copy constructor. + * + * This constructor is especially useful for taking a static + * snapshot of an attribute list for later use. + * + * @param atts The attribute list to copy. + */ XMLAttributesDefault (const XMLAttributes & atts); + + + /** + * Destructor. + */ virtual ~XMLAttributesDefault (); + + /** + * Count the attributes in the list. + */ virtual int size () const; + + + /** + * Get the name of an attribute by index. + */ virtual const char * getName (int i) const; + + + /** + * Get the value of an attribute by index. + */ virtual const char * getValue (int i) const; + + /** + * Add an attribute to an attribute list. + * + * The name is required to be unique in the list; the value is not. + * + * @param name The name of the attribute to add. + * @param value The value of the attribute to add. + */ virtual void addAttribute (const char * name, const char * value); + + + /** + * Set an attribute name by index. + * + * This method will not extend the list; the attribute must + * already exist. + * + * @param i The index of the attribute (zero-based). + * @param name The new name. + */ virtual void setName (int i, const char * name); + + + /** + * Set an attribute value by index. + * + * This method will not extend the list; the attribute must + * already exist. + * + * @param i The index of the attribute (zero-based). + * @param value The new value. + */ virtual void setValue (int i, const char * value); + + + /** + * Set an attribute value by name. + * + * This method will not extend the list; the attribute must + * already exist. + * + * @param name The name of the attribute that will have the new + * value. + * @param value The new value. + */ virtual void setValue (const char * name, const char * value); private: - vector _atts; + std::vector _atts; +}; + +//////////////////////////////////////////////////////////////////////// +// Attribute list wrapper for Expat. +//////////////////////////////////////////////////////////////////////// + +class ExpatAtts : public XMLAttributes +{ +public: + ExpatAtts (const char ** atts) : _atts(atts) {} + + virtual int size () const; + virtual const char * getName (int i) const; + virtual const char * getValue (int i) const; + + virtual const char * getValue (const char * name) const; +private: + const char ** _atts; }; /** * Visitor class for an XML document. * - * To read an XML document, a module must subclass the visitor to do - * something useful for the different XML events. + * This interface uses the Visitor pattern. The XML parser walks + * through the XML document and invokes the appropriate method in + * this visitor for each piece of markup it finds. By default, + * the methods do nothing; the application must subclass the visitor + * and override the methods for the events it's interested in. + * All applications are required to provide an implementation + * for the {@link #error} callback. */ class XMLVisitor { public: - // start an XML document + /// Constructor + XMLVisitor() : parser(0), line(-1), column(-1) {} + + /** + * Virtual destructor. + */ + virtual ~XMLVisitor () {} + + + /** + * Callback for the start of an XML document. + * + * The XML parser will invoke this method once, at the beginning of + * the XML document, before any other methods are invoked. The + * application can use this callback to set up data structures, + * open files, etc. + * + * @see #endXML + */ virtual void startXML () {} - // end an XML document + + + /** + * Callback for the end of an XML document. + * + * The XML parser will invoke this method once, at the end of the + * XML document, after all other methods are invoked, and only + * if there have been no parsing errors. The application can use + * this callback to close or write files, finalize data structures, + * and so on, but the application will need to be prepared to + * clean up any resources without this callback in the event of + * an error. + * + * @see #startXML + * @see #error + */ virtual void endXML () {} - // start an element + + + /** + * Callback for the start of an XML element. + * + * The XML parser will invoke this method at the beginning of every + * XML element. Start and end element calls will be balanced + * and properly nested: every element has both a start and end + * callback (even if it was specified with an XML empty element tag), + * there is exactly one root element, and every element must end + * before its parent does. Elements may not overlap. + * Note that the attribute list provided is volatile; it's contents + * are not guaranteed to persist after the end of the callback. + * If the application needs to keep a copy of the attribute list, + * it can make the copy with the {@link XMLAttributesDefault} class. + * + * @param name The name of the element that is starting (not null). + * @param atts The element's attributes (not null). + * @see #endElement + */ virtual void startElement (const char * name, const XMLAttributes &atts) {} - // end an element + + + /** + * Callback for the end of an XML element. + * + * The XML parser will invoke this method at the end of every XML element. + * + * @param name The name of the element that is ending (not null). + * @see #startElement + */ virtual void endElement (const char * name) {} - // character data + + + /** + * Callback for a chunk of character data. + * + * The XML parser will invoke this method once for every chunk of + * character data in the XML document, including whitespace + * separating elements (as required by the XML recommendation). + * Note that character data may be chunked arbitrarily: the + * character data content of an element may be returned in one + * large chunk or several consecutive smaller chunks. + * + * @param s A pointer to the beginning of the character data (not null). + * @param length The number of characters in the chunk (may + * be zero). + */ virtual void data (const char * s, int length) {} - // processing instruction + + + /** + * Callback for an XML processing instruction. + * + * The XML parser will invoke this method once for every processing + * instruction in the XML document. Note that the XML declaration + * and the Text declaration are NOT PROCESSING INSTRUCTIONS and + * will not be reported through this callback. Processing + * instructions are not all that useful, but the XML recommendation + * requires that they be reported. Most applications can safely + * ignore this callback and use the empty default implementation. + * + * @param target The processing instruction target (not null). + * @param data The processing instruction data (not null). + */ virtual void pi (const char * target, const char * data) {} - // non-fatal warning + + + /** + * Callback for an XML parsing warning. + * + * The XML parser will use this callback to report any non-fatal warnings + * during parsing. It is the responsibility of the application to + * deal with the warning in some appropriate way. + * + * @param message The warning message from the parser. + * @param line The number of the line that generated the warning. + * @param column The character position in the line that generated + * the warning. + */ virtual void warning (const char * message, int line, int column) {} - // fatal error - virtual void error (const char * message, int line, int column) = 0; + + /** Set the path to the file that is parsed. + * + * This method will be called to store the path to the parsed file. Note that + * the XML parser makes no use of this copy of the path. The intent is + * to be capable of refering to the path to the parsed file if needed. + * + * @param _path The path to the parsed file. + * @see #getPath + */ + void setPath(const std::string& _path) { path = _path; } + + /** Get the path to the parsed file. + * + * This method will be called if the application needs to access the path to + * the parsed file. This information is typically needed if an error is found + * so the file where it occurred can be retrieved to help the user locate the + * error. + * + * @return the path to the parsed file. + * @see #setPath + */ + const std::string& getPath(void) const { return path; } + + /** Save the current position in the parsed file. + * + * This method will be called to save the position at which the file is + * currently parsed. Note that the XML parser makes no use of that + * information. The intent is to be capable of refering to the position in + * the parsed file if needed. + * + * @see #getColumn + * @see #getLine + */ + void savePosition(void); + + /** Get the saved column number in the parsed file. + * + * This method will be called if the application needs to get the column + * number that has been saved during the last call to savePosition(). This + * information is typically needed if an error is found so the position at + * which it occurred can be retrieved to help the user locate the error. + * + * @return the save column number. + * @see #savePosition + */ + int getColumn(void) const { return column; } + + /** Get the saved line number in the parsed file. + * + * This method will be called if the application needs to get the line + * number that has been saved during the last call to savePosition(). This + * information is typically needed if an error is found so the position at + * which it occurred can be retrieved to help the user locate the error. + * + * @return the save line number. + * @see #savePosition + */ + int getLine(void) const { return line; } + + /** Set the XML parser. + * + * This method will be called so the #XMLVisitor instance can internally use + * the XML parser for its housekeeping. The intent is that #XMLVisitor will + * only call the reporting functions of the XML parser and will not interfer + * with the XML parser current state. Doing otherwise will result in an + * unpredictable behavior of the XML parser. + * + * @param _parser the XML parser + */ + void setParser(XML_Parser _parser) { parser = _parser; } +private: + XML_Parser parser; + std::string path; + int line, column; }; /** + * @relates XMLVisitor * Read an XML document. + * + * This function reads an XML document from the input stream provided, + * and invokes the callback methods in the visitor object to pass the + * parsing events back to the application. When this function + * returns, the parser will have reported all of the data in the XML + * document to the application through the visitor callback methods, + * and XML processing will be complete. + * + * @param input The byte input stream containing the XML document. + * @param visitor An object that contains callbacks for XML parsing + * events. + * @param path A string describing the original path of the resource. + * @exception Throws sg_io_exception or sg_xml_exception if there + * is a problem reading the file. + * @see XMLVisitor + */ +extern void readXML (std::istream &input, XMLVisitor &visitor, + const std::string &path=""); + + +/** + * @relates XMLVisitor + * Read an XML document. + * + * This function reads an XML document from the input stream provided, + * and invokes the callback methods in the visitor object to pass the + * parsing events back to the application. When this function + * returns, the parser will have reported all of the data in the XML + * document to the application through the visitor callback methods, + * and XML processing will be complete. + * + * @param path The file name of the XML resource. + * @param visitor An object that contains callbacks for XML parsing + * events. + * @exception Throws sg_io_exception or sg_xml_exception if there + * is a problem reading the file. + * @see XMLVisitor + */ +extern void readXML (const std::string &path, XMLVisitor &visitor); + + +/** + * @relates XMLVisitor + * Read an XML document. + * + * This function reads an XML document from the buffer provided, + * and invokes the callback methods in the visitor object to pass the + * parsing events back to the application. When this function + * returns, the parser will have reported all of the data in the XML + * document to the application through the visitor callback methods, + * and XML processing will be complete. + * + * @param buf The xml data buffer. + * @param size The size of the data buffer in bytes + * @param visitor An object that contains callbacks for XML parsing + * events. + * @exception Throws sg_io_exception or sg_xml_exception if there + * is a problem reading the file. + * @see XMLVisitor */ -extern bool readXML (istream &input, XMLVisitor &visitor); +extern void readXML (const char *buf, const int size, XMLVisitor &visitor); #endif // __EASYXML_HXX