1 /*- 2 * Copyright (c) 2004 Jacques A. Vidrine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 #ifndef CELABO_20040211_PARSER_HH 28 #define CELABO_20040211_PARSER_HH 29 30 #if defined(HAVE_BSDXML) 31 #include <bsdxml.h> 32 #else 33 #include <expat.h> 34 #endif 35 36 namespace vuxml { 37 38 39 class Element { 40 public: 41 Element(std::string &xmlns, std::string &name); id() const42 inline int id() const { return id_; } xmlns() const43 inline const std::string &xmlns() const { return xmlns_; } name() const44 inline const std::string &name() const { return name_; } 45 private: 46 int id_; 47 std::string xmlns_; 48 std::string name_; 49 }; 50 51 52 class Parser; 53 54 55 class XMLHandler { 56 public: 57 XMLHandler()58 XMLHandler() {} ~XMLHandler()59 virtual ~XMLHandler() {} 60 61 virtual void setParser(Parser &p) = 0; 62 63 virtual void startElement(std::string &xmlns, std::string &name, 64 Attributes &attr) = 0; 65 virtual void endElement(std::string &xmlns, std::string &name) = 0; 66 virtual void characters(std::string &pcdata) = 0; 67 }; 68 69 70 class Parser { 71 public: 72 Parser(); 73 ~Parser(); 74 75 void signalError(const std::string &serr); 76 bool fail() const; 77 const std::string &getErrorString() const; 78 unsigned int getLine() const; 79 80 void *getBuffer(size_t n); 81 bool parseBuffer(size_t n, bool last); 82 void parseStream(std::istream &is); 83 84 void setHandler(XMLHandler &h); 85 XMLHandler &getHandler(); 86 87 static void charactersDispatcher(void *data, const char *s, int len); 88 static void startElementDispatcher(void *data, const char *name, 89 const char **atts); 90 static void endElementDispatcher(void *data, const char *name); 91 92 private: 93 XML_Parser parser_; 94 XMLHandler *handler_; 95 bool fail_; 96 unsigned int line_; 97 std::string serr_; 98 99 static Parser *dispatcherSetup(void *data); 100 }; 101 102 103 class XMLState { 104 public: 105 virtual XMLState *child(const Element &element) = 0; 106 virtual void start(const Element &element, 107 Attributes &attr) = 0; 108 virtual void characters(std::string &pcdata) = 0; 109 virtual XMLState *end(const Element &element) = 0; 110 }; 111 112 113 template<class T> 114 class XMLStateFacet : public XMLState { 115 public: 116 typedef XMLState *(T::*FnChild)(const Element &element); 117 typedef void (T::*FnStart)(const Element &element, Attributes &attr); 118 typedef void (T::*FnCharacters)(std::string &pcdata); 119 typedef XMLState *(T::*FnEnd)(const Element &element); 120 XMLStateFacet(T & t,FnChild a,FnStart b,FnCharacters c,FnEnd d)121 XMLStateFacet(T &t, FnChild a, FnStart b, FnCharacters c, FnEnd d) : 122 t_(t), child_(a), start_(b), characters_(c), end_(d) {} 123 child(const Element & element)124 XMLState *child(const Element &element) { return (t_.*child_)(element); } start(const Element & element,Attributes & attr)125 void start(const Element &element, 126 Attributes &attr) { (t_.*start_)(element, attr); } characters(std::string & pcdata)127 void characters(std::string &pcdata) { (t_.*characters_)(pcdata); } end(const Element & element)128 XMLState *end(const Element &element) { return (t_.*end_)(element); } 129 130 private: 131 T &t_; 132 FnChild child_; 133 FnStart start_; 134 FnCharacters characters_; 135 FnEnd end_; 136 }; 137 138 139 } 140 #endif 141