1 | // |
2 | // WhitespaceFilter.cpp |
3 | // |
4 | // Library: XML |
5 | // Package: SAX |
6 | // Module: WhitespaceFilter |
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/WhitespaceFilter.h" |
16 | #include "Poco/SAX/SAXException.h" |
17 | |
18 | |
19 | namespace Poco { |
20 | namespace XML { |
21 | |
22 | |
23 | WhitespaceFilter::WhitespaceFilter(): |
24 | _pLexicalHandler(0), |
25 | _filter(true) |
26 | { |
27 | } |
28 | |
29 | |
30 | WhitespaceFilter::WhitespaceFilter(XMLReader* pReader): |
31 | XMLFilterImpl(pReader), |
32 | _pLexicalHandler(0), |
33 | _filter(true) |
34 | { |
35 | } |
36 | |
37 | |
38 | WhitespaceFilter::~WhitespaceFilter() |
39 | { |
40 | } |
41 | |
42 | |
43 | void WhitespaceFilter::setProperty(const XMLString& propertyId, const XMLString& value) |
44 | { |
45 | if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) |
46 | throw SAXNotSupportedException(std::string("property does not take a string value: " ) + fromXMLString(propertyId)); |
47 | else |
48 | XMLFilterImpl::setProperty(propertyId, value); |
49 | |
50 | } |
51 | |
52 | |
53 | void WhitespaceFilter::setProperty(const XMLString& propertyId, void* value) |
54 | { |
55 | if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) |
56 | _pLexicalHandler = reinterpret_cast<LexicalHandler*>(value); |
57 | else |
58 | XMLFilterImpl::setProperty(propertyId, value); |
59 | } |
60 | |
61 | |
62 | void* WhitespaceFilter::getProperty(const XMLString& propertyId) const |
63 | { |
64 | if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) |
65 | return _pLexicalHandler; |
66 | else |
67 | return XMLFilterImpl::getProperty(propertyId); |
68 | } |
69 | |
70 | |
71 | void WhitespaceFilter::startDocument() |
72 | { |
73 | XMLFilterImpl::startDocument(); |
74 | _filter = true; |
75 | _data.clear(); |
76 | } |
77 | |
78 | |
79 | void WhitespaceFilter::endDocument() |
80 | { |
81 | XMLFilterImpl::endDocument(); |
82 | _filter = true; |
83 | _data.clear(); |
84 | } |
85 | |
86 | |
87 | void WhitespaceFilter::startElement(const XMLString& uri, const XMLString& localName, const XMLString& qname, const Attributes& attrList) |
88 | { |
89 | XMLFilterImpl::startElement(uri, localName, qname, attrList); |
90 | _filter = true; |
91 | _data.clear(); |
92 | } |
93 | |
94 | |
95 | void WhitespaceFilter::endElement(const XMLString& uri, const XMLString& localName, const XMLString& qname) |
96 | { |
97 | XMLFilterImpl::endElement(uri, localName, qname); |
98 | _filter = true; |
99 | _data.clear(); |
100 | } |
101 | |
102 | |
103 | void WhitespaceFilter::characters(const XMLChar ch[], int start, int length) |
104 | { |
105 | if (_filter) |
106 | { |
107 | bool ws = true; |
108 | const XMLChar* it = ch + start; |
109 | const XMLChar* end = ch + start + length; |
110 | _data.append(it, end); |
111 | while (it != end) |
112 | { |
113 | if (*it != '\r' && *it != '\n' && *it != '\t' && *it != ' ') |
114 | { |
115 | ws = false; |
116 | break; |
117 | } |
118 | ++it; |
119 | } |
120 | if (!ws) |
121 | { |
122 | XMLFilterImpl::characters(_data.data(), 0, (int) _data.length()); |
123 | _filter = false; |
124 | _data.clear(); |
125 | } |
126 | } |
127 | else XMLFilterImpl::characters(ch, start, length); |
128 | } |
129 | |
130 | |
131 | void WhitespaceFilter::ignorableWhitespace(const XMLChar /*ch*/[], int /*start*/, int /*length*/) |
132 | { |
133 | // the handler name already says that this data can be ignored |
134 | } |
135 | |
136 | |
137 | void WhitespaceFilter::processingInstruction(const XMLString& target, const XMLString& data) |
138 | { |
139 | XMLFilterImpl::processingInstruction(target, data); |
140 | _filter = true; |
141 | _data.clear(); |
142 | } |
143 | |
144 | |
145 | void WhitespaceFilter::startDTD(const XMLString& name, const XMLString& publicId, const XMLString& systemId) |
146 | { |
147 | if (_pLexicalHandler) |
148 | _pLexicalHandler->startDTD(name, publicId, systemId); |
149 | } |
150 | |
151 | |
152 | void WhitespaceFilter::endDTD() |
153 | { |
154 | if (_pLexicalHandler) |
155 | _pLexicalHandler->endDTD(); |
156 | } |
157 | |
158 | |
159 | void WhitespaceFilter::startEntity(const XMLString& name) |
160 | { |
161 | if (_pLexicalHandler) |
162 | _pLexicalHandler->startEntity(name); |
163 | _filter = true; |
164 | _data.clear(); |
165 | } |
166 | |
167 | |
168 | void WhitespaceFilter::endEntity(const XMLString& name) |
169 | { |
170 | if (_pLexicalHandler) |
171 | _pLexicalHandler->endEntity(name); |
172 | _filter = true; |
173 | _data.clear(); |
174 | } |
175 | |
176 | |
177 | void WhitespaceFilter::startCDATA() |
178 | { |
179 | if (_pLexicalHandler) |
180 | _pLexicalHandler->startCDATA(); |
181 | _filter = false; |
182 | _data.clear(); |
183 | } |
184 | |
185 | |
186 | void WhitespaceFilter::endCDATA() |
187 | { |
188 | if (_pLexicalHandler) |
189 | _pLexicalHandler->endCDATA(); |
190 | _filter = true; |
191 | _data.clear(); |
192 | } |
193 | |
194 | |
195 | void WhitespaceFilter::(const XMLChar ch[], int start, int length) |
196 | { |
197 | if (_pLexicalHandler) |
198 | _pLexicalHandler->comment(ch, start, length); |
199 | _filter = true; |
200 | _data.clear(); |
201 | } |
202 | |
203 | |
204 | void WhitespaceFilter::setupParse() |
205 | { |
206 | XMLFilterImpl::setupParse(); |
207 | |
208 | parent()->setProperty(XMLReader::PROPERTY_LEXICAL_HANDLER, static_cast<LexicalHandler*>(this)); |
209 | } |
210 | |
211 | |
212 | } } // namespace Poco::XML |
213 | |