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 <sstream>
21
22
23namespace Poco {
24namespace XML {
25
26
27const XMLString SAXParser::FEATURE_PARTIAL_READS = toXMLString("http://www.appinf.com/features/enable-partial-reads");
28
29
30SAXParser::SAXParser():
31 _namespaces(true),
32 _namespacePrefixes(false)
33{
34}
35
36
37SAXParser::SAXParser(const XMLString& encoding):
38 _engine(encoding),
39 _namespaces(true),
40 _namespacePrefixes(false)
41{
42}
43
44
45SAXParser::~SAXParser()
46{
47}
48
49
50void SAXParser::setEncoding(const XMLString& encoding)
51{
52 _engine.setEncoding(encoding);
53}
54
55
56const XMLString& SAXParser::getEncoding() const
57{
58 return _engine.getEncoding();
59}
60
61
62void SAXParser::addEncoding(const XMLString& name, Poco::TextEncoding* pEncoding)
63{
64 _engine.addEncoding(name, pEncoding);
65}
66
67
68void SAXParser::setEntityResolver(EntityResolver* pResolver)
69{
70 _engine.setEntityResolver(pResolver);
71}
72
73
74EntityResolver* SAXParser::getEntityResolver() const
75{
76 return _engine.getEntityResolver();
77}
78
79
80void SAXParser::setDTDHandler(DTDHandler* pDTDHandler)
81{
82 _engine.setDTDHandler(pDTDHandler);
83}
84
85
86DTDHandler* SAXParser::getDTDHandler() const
87{
88 return _engine.getDTDHandler();
89}
90
91
92void SAXParser::setContentHandler(ContentHandler* pContentHandler)
93{
94 _engine.setContentHandler(pContentHandler);
95}
96
97
98ContentHandler* SAXParser::getContentHandler() const
99{
100 return _engine.getContentHandler();
101}
102
103
104void SAXParser::setErrorHandler(ErrorHandler* pErrorHandler)
105{
106 _engine.setErrorHandler(pErrorHandler);
107}
108
109
110ErrorHandler* SAXParser::getErrorHandler() const
111{
112 return _engine.getErrorHandler();
113}
114
115
116void SAXParser::setFeature(const XMLString& featureId, bool state)
117{
118 if (featureId == XMLReader::FEATURE_VALIDATION || featureId == XMLReader::FEATURE_STRING_INTERNING)
119 throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_VALIDATION));
120 else if (featureId == XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES)
121 _engine.setExternalGeneralEntities(state);
122 else if (featureId == XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES)
123 _engine.setExternalParameterEntities(state);
124 else if (featureId == XMLReader::FEATURE_NAMESPACES)
125 _namespaces = state;
126 else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES)
127 _namespacePrefixes = state;
128 else if (featureId == FEATURE_PARTIAL_READS)
129 _engine.setEnablePartialReads(state);
130 else throw SAXNotRecognizedException(fromXMLString(featureId));
131}
132
133
134bool SAXParser::getFeature(const XMLString& featureId) const
135{
136 if (featureId == XMLReader::FEATURE_VALIDATION || featureId == XMLReader::FEATURE_STRING_INTERNING)
137 throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_VALIDATION));
138 else if (featureId == XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES)
139 return _engine.getExternalGeneralEntities();
140 else if (featureId == XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES)
141 return _engine.getExternalParameterEntities();
142 else if (featureId == XMLReader::FEATURE_NAMESPACES)
143 return _namespaces;
144 else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES)
145 return _namespacePrefixes;
146 else if (featureId == FEATURE_PARTIAL_READS)
147 return _engine.getEnablePartialReads();
148 else throw SAXNotRecognizedException(fromXMLString(featureId));
149}
150
151
152void SAXParser::setProperty(const XMLString& propertyId, const XMLString& value)
153{
154 if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER || propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER)
155 throw SAXNotSupportedException(std::string("property does not take a string value: ") + fromXMLString(propertyId));
156 else
157 throw SAXNotRecognizedException(fromXMLString(propertyId));
158}
159
160
161void SAXParser::setProperty(const XMLString& propertyId, void* value)
162{
163 if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER)
164 _engine.setDeclHandler(reinterpret_cast<DeclHandler*>(value));
165 else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER)
166 _engine.setLexicalHandler(reinterpret_cast<LexicalHandler*>(value));
167 else throw SAXNotRecognizedException(fromXMLString(propertyId));
168}
169
170
171void* SAXParser::getProperty(const XMLString& propertyId) const
172{
173 if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER)
174 return _engine.getDeclHandler();
175 else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER)
176 return _engine.getLexicalHandler();
177 else throw SAXNotSupportedException(fromXMLString(propertyId));
178}
179
180
181void SAXParser::parse(InputSource* pInputSource)
182{
183 if (pInputSource->getByteStream() || pInputSource->getCharacterStream())
184 {
185 setupParse();
186 _engine.parse(pInputSource);
187 }
188 else parse(pInputSource->getSystemId());
189}
190
191
192void SAXParser::parse(const XMLString& systemId)
193{
194 setupParse();
195 EntityResolverImpl entityResolver;
196 InputSource* pInputSource = entityResolver.resolveEntity(0, systemId);
197 if (pInputSource)
198 {
199 try
200 {
201 _engine.parse(pInputSource);
202 }
203 catch (...)
204 {
205 entityResolver.releaseInputSource(pInputSource);
206 throw;
207 }
208 entityResolver.releaseInputSource(pInputSource);
209 }
210 else throw XMLException("Cannot resolve system identifier", fromXMLString(systemId));
211}
212
213
214void SAXParser::parseString(const std::string& xml)
215{
216 parseMemoryNP(xml.data(), xml.size());
217}
218
219
220void SAXParser::parseMemoryNP(const char* xml, std::size_t size)
221{
222 setupParse();
223 _engine.parse(xml, size);
224}
225
226
227void SAXParser::setupParse()
228{
229 if (_namespaces && !_namespacePrefixes)
230 _engine.setNamespaceStrategy(new NoNamespacePrefixesStrategy);
231 else if (_namespaces && _namespacePrefixes)
232 _engine.setNamespaceStrategy(new NamespacePrefixesStrategy);
233 else
234 _engine.setNamespaceStrategy(new NoNamespacesStrategy);
235}
236
237
238} } // namespace Poco::XML
239