/src/poco/XML/src/SAXParser.cpp
Line | Count | Source |
1 | | // |
2 | | // SAXParser.cpp |
3 | | // |
4 | | // Library: XML |
5 | | // Package: SAX |
6 | | // Module: SAX |
7 | | // |
8 | | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
9 | | // and Contributors. |
10 | | // |
11 | | // SPDX-License-Identifier: BSL-1.0 |
12 | | // |
13 | | |
14 | | |
15 | | #include "Poco/SAX/SAXParser.h" |
16 | | #include "Poco/SAX/SAXException.h" |
17 | | #include "Poco/SAX/EntityResolverImpl.h" |
18 | | #include "Poco/SAX/InputSource.h" |
19 | | #include "Poco/XML/NamespaceStrategy.h" |
20 | | #include "Poco/NumberParser.h" |
21 | | #include "ParserEngine.h" |
22 | | #include <sstream> |
23 | | |
24 | | |
25 | | namespace Poco { |
26 | | namespace XML { |
27 | | |
28 | | |
29 | | const XMLString SAXParser::FEATURE_PARTIAL_READS = toXMLString("http://www.appinf.com/features/enable-partial-reads"); |
30 | | const XMLString SAXParser::PROPERTY_BLA_MAXIMUM_AMPLIFICATION = toXMLString("http://www.appinf.com/properties/bla-maximum-amplification"); |
31 | | const XMLString SAXParser::PROPERTY_BLA_ACTIVATION_THRESHOLD = toXMLString("http://www.appinf.com/properties/bla-activation-threshold"); |
32 | | |
33 | | |
34 | | SAXParser::SAXParser(): |
35 | 61.1k | _namespaces(true), |
36 | 61.1k | _namespacePrefixes(false) |
37 | 61.1k | { |
38 | 61.1k | _engine = new ParserEngine; |
39 | 61.1k | } |
40 | | |
41 | | |
42 | | SAXParser::SAXParser(const XMLString& encoding): |
43 | 0 | _namespaces(true), |
44 | 0 | _namespacePrefixes(false) |
45 | 0 | { |
46 | 0 | _engine = new ParserEngine(encoding); |
47 | 0 | } |
48 | | |
49 | | |
50 | | SAXParser::~SAXParser() |
51 | 61.1k | { |
52 | 61.1k | delete _engine; |
53 | 61.1k | } |
54 | | |
55 | | |
56 | | void SAXParser::setEncoding(const XMLString& encoding) |
57 | 0 | { |
58 | 0 | _engine->setEncoding(encoding); |
59 | 0 | } |
60 | | |
61 | | |
62 | | const XMLString& SAXParser::getEncoding() const |
63 | 0 | { |
64 | 0 | return _engine->getEncoding(); |
65 | 0 | } |
66 | | |
67 | | |
68 | | void SAXParser::addEncoding(const XMLString& name, Poco::TextEncoding* pEncoding) |
69 | 0 | { |
70 | 0 | _engine->addEncoding(name, pEncoding); |
71 | 0 | } |
72 | | |
73 | | |
74 | | void SAXParser::setEntityResolver(EntityResolver* pResolver) |
75 | 45.9k | { |
76 | 45.9k | _engine->setEntityResolver(pResolver); |
77 | 45.9k | } |
78 | | |
79 | | |
80 | | EntityResolver* SAXParser::getEntityResolver() const |
81 | 0 | { |
82 | 0 | return _engine->getEntityResolver(); |
83 | 0 | } |
84 | | |
85 | | |
86 | | void SAXParser::setDTDHandler(DTDHandler* pDTDHandler) |
87 | 61.1k | { |
88 | 61.1k | _engine->setDTDHandler(pDTDHandler); |
89 | 61.1k | } |
90 | | |
91 | | |
92 | | DTDHandler* SAXParser::getDTDHandler() const |
93 | 0 | { |
94 | 0 | return _engine->getDTDHandler(); |
95 | 0 | } |
96 | | |
97 | | |
98 | | void SAXParser::setContentHandler(ContentHandler* pContentHandler) |
99 | 61.1k | { |
100 | 61.1k | _engine->setContentHandler(pContentHandler); |
101 | 61.1k | } |
102 | | |
103 | | |
104 | | ContentHandler* SAXParser::getContentHandler() const |
105 | 0 | { |
106 | 0 | return _engine->getContentHandler(); |
107 | 0 | } |
108 | | |
109 | | |
110 | | void SAXParser::setErrorHandler(ErrorHandler* pErrorHandler) |
111 | 45.9k | { |
112 | 45.9k | _engine->setErrorHandler(pErrorHandler); |
113 | 45.9k | } |
114 | | |
115 | | |
116 | | ErrorHandler* SAXParser::getErrorHandler() const |
117 | 0 | { |
118 | 0 | return _engine->getErrorHandler(); |
119 | 0 | } |
120 | | |
121 | | |
122 | | void SAXParser::setFeature(const XMLString& featureId, bool state) |
123 | 336k | { |
124 | 336k | if (featureId == XMLReader::FEATURE_VALIDATION || featureId == XMLReader::FEATURE_STRING_INTERNING) |
125 | 0 | throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_VALIDATION)); |
126 | 336k | else if (featureId == XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES) |
127 | 61.1k | _engine->setExternalGeneralEntities(state); |
128 | 275k | else if (featureId == XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES) |
129 | 61.1k | _engine->setExternalParameterEntities(state); |
130 | 213k | else if (featureId == XMLReader::FEATURE_NAMESPACES) |
131 | 91.7k | _namespaces = state; |
132 | 122k | else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES) |
133 | 91.7k | _namespacePrefixes = state; |
134 | 30.5k | else if (featureId == FEATURE_PARTIAL_READS) |
135 | 30.5k | _engine->setEnablePartialReads(state); |
136 | 0 | else throw SAXNotRecognizedException(fromXMLString(featureId)); |
137 | 336k | } |
138 | | |
139 | | |
140 | | bool SAXParser::getFeature(const XMLString& featureId) const |
141 | 30.5k | { |
142 | 30.5k | if (featureId == XMLReader::FEATURE_VALIDATION || featureId == XMLReader::FEATURE_STRING_INTERNING) |
143 | 0 | throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_VALIDATION)); |
144 | 30.5k | else if (featureId == XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES) |
145 | 0 | return _engine->getExternalGeneralEntities(); |
146 | 30.5k | else if (featureId == XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES) |
147 | 0 | return _engine->getExternalParameterEntities(); |
148 | 30.5k | else if (featureId == XMLReader::FEATURE_NAMESPACES) |
149 | 30.5k | return _namespaces; |
150 | 0 | else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES) |
151 | 0 | return _namespacePrefixes; |
152 | 0 | else if (featureId == FEATURE_PARTIAL_READS) |
153 | 0 | return _engine->getEnablePartialReads(); |
154 | 0 | else throw SAXNotRecognizedException(fromXMLString(featureId)); |
155 | 30.5k | } |
156 | | |
157 | | |
158 | | void SAXParser::setProperty(const XMLString& propertyId, const XMLString& value) |
159 | 0 | { |
160 | 0 | if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER || propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) |
161 | 0 | throw SAXNotSupportedException(std::string("property does not take a string value: ") + fromXMLString(propertyId)); |
162 | 0 | else if (propertyId == PROPERTY_BLA_MAXIMUM_AMPLIFICATION) |
163 | 0 | _engine->setBillionLaughsAttackProtectionMaximumAmplification(static_cast<float>(Poco::NumberParser::parseFloat(value))); |
164 | 0 | else if (propertyId == PROPERTY_BLA_ACTIVATION_THRESHOLD) |
165 | 0 | _engine->setBillionLaughsAttackProtectionActivationThreshold(Poco::NumberParser::parseUnsigned64(value)); |
166 | 0 | else |
167 | 0 | throw SAXNotRecognizedException(fromXMLString(propertyId)); |
168 | 0 | } |
169 | | |
170 | | |
171 | | void SAXParser::setProperty(const XMLString& propertyId, void* value) |
172 | 30.5k | { |
173 | 30.5k | if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER) |
174 | 0 | _engine->setDeclHandler(reinterpret_cast<DeclHandler*>(value)); |
175 | 30.5k | else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) |
176 | 30.5k | _engine->setLexicalHandler(reinterpret_cast<LexicalHandler*>(value)); |
177 | 0 | else throw SAXNotRecognizedException(fromXMLString(propertyId)); |
178 | 30.5k | } |
179 | | |
180 | | |
181 | | void* SAXParser::getProperty(const XMLString& propertyId) const |
182 | 0 | { |
183 | 0 | if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER) |
184 | 0 | return _engine->getDeclHandler(); |
185 | 0 | else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) |
186 | 0 | return _engine->getLexicalHandler(); |
187 | 0 | else throw SAXNotSupportedException(fromXMLString(propertyId)); |
188 | 0 | } |
189 | | |
190 | | |
191 | | void SAXParser::parse(InputSource* pInputSource) |
192 | 0 | { |
193 | 0 | if (pInputSource->getByteStream() || pInputSource->getCharacterStream()) |
194 | 0 | { |
195 | 0 | setupParse(); |
196 | 0 | _engine->parse(pInputSource); |
197 | 0 | } |
198 | 0 | else parse(pInputSource->getSystemId()); |
199 | 0 | } |
200 | | |
201 | | |
202 | | void SAXParser::parse(const XMLString& systemId) |
203 | 0 | { |
204 | 0 | setupParse(); |
205 | 0 | EntityResolverImpl entityResolver; |
206 | 0 | InputSource* pInputSource = entityResolver.resolveEntity(nullptr, systemId); |
207 | 0 | if (pInputSource) |
208 | 0 | { |
209 | 0 | try |
210 | 0 | { |
211 | 0 | _engine->parse(pInputSource); |
212 | 0 | } |
213 | 0 | catch (...) |
214 | 0 | { |
215 | 0 | entityResolver.releaseInputSource(pInputSource); |
216 | 0 | throw; |
217 | 0 | } |
218 | 0 | entityResolver.releaseInputSource(pInputSource); |
219 | 0 | } |
220 | 0 | else throw XMLException("Cannot resolve system identifier", fromXMLString(systemId)); |
221 | 0 | } |
222 | | |
223 | | |
224 | | void SAXParser::parseString(const std::string& xml) |
225 | 30.5k | { |
226 | 30.5k | parseMemoryNP(xml.data(), xml.size()); |
227 | 30.5k | } |
228 | | |
229 | | |
230 | | void SAXParser::parseMemoryNP(const char* xml, std::size_t size) |
231 | 61.1k | { |
232 | 61.1k | setupParse(); |
233 | 61.1k | _engine->parse(xml, size); |
234 | 61.1k | } |
235 | | |
236 | | |
237 | | void SAXParser::setupParse() |
238 | 61.1k | { |
239 | 61.1k | if (_namespaces && !_namespacePrefixes) |
240 | 7.45k | _engine->setNamespaceStrategy(new NoNamespacePrefixesStrategy); |
241 | 53.6k | else if (_namespaces && _namespacePrefixes) |
242 | 20.2k | _engine->setNamespaceStrategy(new NamespacePrefixesStrategy); |
243 | 33.4k | else |
244 | 33.4k | _engine->setNamespaceStrategy(new NoNamespacesStrategy); |
245 | 61.1k | } |
246 | | |
247 | | |
248 | | } } // namespace Poco::XML |