1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 15 */ 16 17 #pragma once 18 19 #include "typedefs.h" 20 21 namespace dcpp { 22 23 class InputStream; 24 25 class SimpleXMLReader { 26 public: 27 struct CallBack : private boost::noncopyable { ~CallBackCallBack28 virtual ~CallBack() { } 29 virtual void startTag(const std::string& name, StringPairList& attribs, bool simple) = 0; 30 virtual void endTag(const std::string& name, const std::string& data) = 0; 31 32 protected: 33 static const std::string& getAttrib(dcpp::StringPairList& attribs, const std::string& name, size_t hint); 34 }; 35 36 SimpleXMLReader(CallBack* callback); ~SimpleXMLReader()37 virtual ~SimpleXMLReader() { } 38 39 void parse(InputStream& is, size_t maxSize = 0); 40 bool parse(const char* data, size_t len, bool more); 41 private: 42 43 static const size_t MAX_NAME_SIZE = 256; 44 static const size_t MAX_VALUE_SIZE = 64*1024; 45 static const size_t MAX_NESTING = 32; 46 47 enum ParseState { 48 /// Start of document 49 STATE_START, 50 51 /// In <?xml declaration, expect version 52 STATE_DECL_VERSION, 53 54 /// In <?xml declaration, expect = 55 STATE_DECL_VERSION_EQ, 56 57 /// In <?xml declaration, expect version number 58 STATE_DECL_VERSION_NUM, 59 60 /// In <?xml declaration, expect encoding 61 STATE_DECL_ENCODING, 62 63 /// In <?xml declaration, expect = 64 STATE_DECL_ENCODING_EQ, 65 66 /// In <?xml declaration, expect encoding name 67 STATE_DECL_ENCODING_NAME, 68 69 STATE_DECL_ENCODING_NAME_APOS, 70 71 STATE_DECL_ENCODING_NAME_QUOT, 72 73 /// in <?xml declaration, expect standalone 74 STATE_DECL_STANDALONE, 75 76 /// in <?xml declaration, expect = 77 STATE_DECL_STANDALONE_EQ, 78 79 /// in <?xml declaration, expect standalone yes 80 STATE_DECL_STANDALONE_YES, 81 82 /// In <?xml declaration, expect %> 83 STATE_DECL_END, 84 85 /// In < element, expect element name 86 STATE_ELEMENT_NAME, 87 88 /// In < element, expect attribute or element end 89 STATE_ELEMENT_ATTR, 90 91 /// In < element, in attribute name 92 STATE_ELEMENT_ATTR_NAME, 93 94 /// In < element, expect % 95 STATE_ELEMENT_ATTR_EQ, 96 97 /// In < element, waiting for attribute value start 98 STATE_ELEMENT_ATTR_VALUE, 99 100 STATE_ELEMENT_ATTR_VALUE_QUOT, 101 102 STATE_ELEMENT_ATTR_VALUE_APOS, 103 104 STATE_ELEMENT_END_SIMPLE, 105 106 STATE_ELEMENT_END, 107 108 STATE_ELEMENT_END_END, 109 110 /// In <!-- comment field 111 STATE_COMMENT, 112 113 STATE_CONTENT, 114 115 STATE_END 116 }; 117 118 119 std::string buf; 120 std::string::size_type bufPos; 121 uint64_t pos; 122 123 dcpp::StringPairList attribs; 124 std::string value; 125 126 CallBack* cb; 127 std::string encoding; 128 129 ParseState state; 130 131 dcpp::StringList elements; 132 133 void append(std::string& str, size_t maxLen, int c); 134 void append(std::string& str, size_t maxLen, std::string::const_iterator begin, std::string::const_iterator end); 135 136 bool needChars(size_t n) const; 137 int charAt(size_t n) const; 138 bool skipSpace(bool store = false); 139 void advancePos(size_t n = 1); 140 std::string::size_type bufSize() const; 141 142 bool literal(const char* lit, size_t len, bool withSpace, ParseState newState); 143 bool character(int c, ParseState newState); 144 145 bool declVersionNum(); 146 bool declEncodingValue(); 147 148 bool element(); 149 bool elementName(); 150 bool elementEnd(); 151 bool elementEndEnd(); 152 bool elementEndSimple(); 153 bool elementEndComplex(); 154 bool elementAttr(); 155 bool elementAttrName(); 156 bool elementAttrValue(); 157 158 bool comment(); 159 160 bool content(); 161 162 bool entref(std::string& d); 163 164 bool process(); 165 bool spaceOrError(const char* error); 166 167 bool error(const char* message); 168 }; 169 170 } 171