/*- * Copyright (c) 2004 Jacques A. Vidrine * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #ifndef CELABO_20040211_PARSER_HH #define CELABO_20040211_PARSER_HH #if defined(HAVE_BSDXML) #include #else #include #endif namespace vuxml { class Element { public: Element(std::string &xmlns, std::string &name); inline int id() const { return id_; } inline const std::string &xmlns() const { return xmlns_; } inline const std::string &name() const { return name_; } private: int id_; std::string xmlns_; std::string name_; }; class Parser; class XMLHandler { public: XMLHandler() {} virtual ~XMLHandler() {} virtual void setParser(Parser &p) = 0; virtual void startElement(std::string &xmlns, std::string &name, Attributes &attr) = 0; virtual void endElement(std::string &xmlns, std::string &name) = 0; virtual void characters(std::string &pcdata) = 0; }; class Parser { public: Parser(); ~Parser(); void signalError(const std::string &serr); bool fail() const; const std::string &getErrorString() const; unsigned int getLine() const; void *getBuffer(size_t n); bool parseBuffer(size_t n, bool last); void parseStream(std::istream &is); void setHandler(XMLHandler &h); XMLHandler &getHandler(); static void charactersDispatcher(void *data, const char *s, int len); static void startElementDispatcher(void *data, const char *name, const char **atts); static void endElementDispatcher(void *data, const char *name); private: XML_Parser parser_; XMLHandler *handler_; bool fail_; unsigned int line_; std::string serr_; static Parser *dispatcherSetup(void *data); }; class XMLState { public: virtual XMLState *child(const Element &element) = 0; virtual void start(const Element &element, Attributes &attr) = 0; virtual void characters(std::string &pcdata) = 0; virtual XMLState *end(const Element &element) = 0; }; template class XMLStateFacet : public XMLState { public: typedef XMLState *(T::*FnChild)(const Element &element); typedef void (T::*FnStart)(const Element &element, Attributes &attr); typedef void (T::*FnCharacters)(std::string &pcdata); typedef XMLState *(T::*FnEnd)(const Element &element); XMLStateFacet(T &t, FnChild a, FnStart b, FnCharacters c, FnEnd d) : t_(t), child_(a), start_(b), characters_(c), end_(d) {} XMLState *child(const Element &element) { return (t_.*child_)(element); } void start(const Element &element, Attributes &attr) { (t_.*start_)(element, attr); } void characters(std::string &pcdata) { (t_.*characters_)(pcdata); } XMLState *end(const Element &element) { return (t_.*end_)(element); } private: T &t_; FnChild child_; FnStart start_; FnCharacters characters_; FnEnd end_; }; } #endif