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