/src/libreoffice/sax/source/tools/fastattribs.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <algorithm> |
21 | | |
22 | | #include <com/sun/star/xml/sax/SAXException.hpp> |
23 | | #include <sax/fastattribs.hxx> |
24 | | #include <utility> |
25 | | |
26 | | using namespace ::com::sun::star::uno; |
27 | | using namespace ::com::sun::star::xml; |
28 | | using namespace ::com::sun::star::xml::sax; |
29 | | namespace sax_fastparser |
30 | | { |
31 | | |
32 | | // wastage to keep MSVC happy vs. an in-line {} |
33 | | FastTokenHandlerBase::~FastTokenHandlerBase() |
34 | 194k | { |
35 | 194k | } |
36 | | |
37 | | UnknownAttribute::UnknownAttribute( OUString aNamespaceURL, OString aName, OString value ) |
38 | 1.18M | : maNamespaceURL(std::move( aNamespaceURL )), maName(std::move( aName )), maValue(std::move( value )) |
39 | 1.18M | { |
40 | 1.18M | } |
41 | | |
42 | | UnknownAttribute::UnknownAttribute( OString aName, OString value ) |
43 | 1.51M | : maName(std::move( aName )), maValue(std::move( value )) |
44 | 1.51M | { |
45 | 1.51M | } |
46 | | |
47 | | void UnknownAttribute::FillAttribute( Attribute* pAttrib ) const |
48 | 1.34M | { |
49 | 1.34M | if( pAttrib ) |
50 | 1.34M | { |
51 | 1.34M | pAttrib->Name = OStringToOUString( maName, RTL_TEXTENCODING_UTF8 ); |
52 | 1.34M | pAttrib->NamespaceURL = maNamespaceURL; |
53 | 1.34M | pAttrib->Value = OStringToOUString( maValue, RTL_TEXTENCODING_UTF8 ); |
54 | 1.34M | } |
55 | 1.34M | } |
56 | | |
57 | | FastAttributeList::FastAttributeList( sax_fastparser::FastTokenHandlerBase *pTokenHandler) |
58 | 288k | : mpTokenHandler( pTokenHandler ) |
59 | 288k | { |
60 | | // random initial size of buffer to store attribute values |
61 | 288k | mnChunkLength = 58; |
62 | 288k | mpChunk = static_cast<char *>(malloc( mnChunkLength )); |
63 | 288k | maAttributeValues.push_back( 0 ); |
64 | 288k | } |
65 | | |
66 | | FastAttributeList::FastAttributeList( const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) |
67 | 98.3k | { |
68 | 98.3k | const auto& rOther = castToFastAttributeList(xAttrList); |
69 | 98.3k | mpTokenHandler = rOther.mpTokenHandler; |
70 | 98.3k | mpChunk = static_cast<char *>(malloc( rOther.mnChunkLength )); |
71 | 98.3k | mnChunkLength = rOther.mnChunkLength; |
72 | 98.3k | memcpy(mpChunk, rOther.mpChunk, rOther.mnChunkLength); |
73 | 98.3k | maAttributeValues = rOther.maAttributeValues; |
74 | 98.3k | maAttributeTokens = rOther.maAttributeTokens; |
75 | 98.3k | maUnknownAttributes = rOther.maUnknownAttributes; |
76 | 98.3k | } |
77 | | |
78 | | css::uno::Reference< ::css::util::XCloneable > FastAttributeList::createClone() |
79 | 7.81k | { |
80 | 7.81k | return new FastAttributeList(this); |
81 | 7.81k | } |
82 | | |
83 | | FastAttributeList::~FastAttributeList() |
84 | 387k | { |
85 | 387k | free( mpChunk ); |
86 | 387k | } |
87 | | |
88 | | void FastAttributeList::clear() |
89 | 55.1M | { |
90 | 55.1M | maAttributeTokens.clear(); |
91 | 55.1M | maAttributeValues.resize(1); |
92 | 55.1M | assert(maAttributeValues[0] == 0); |
93 | 55.1M | maUnknownAttributes.clear(); |
94 | 55.1M | } |
95 | | |
96 | | void FastAttributeList::add( sal_Int32 nToken, std::string_view value ) |
97 | 18.7M | { |
98 | 18.7M | assert(nToken != -1); |
99 | 18.7M | assert(nToken != 0); |
100 | 18.7M | assert(value.length() < SAL_MAX_INT32); // protect against absurd values |
101 | 18.7M | maAttributeTokens.push_back( nToken ); |
102 | 18.7M | sal_Int32 nWritePosition = maAttributeValues.back(); |
103 | 18.7M | maAttributeValues.push_back( maAttributeValues.back() + value.length() + 1 ); |
104 | 18.7M | if (maAttributeValues.back() > mnChunkLength) |
105 | 102k | { |
106 | 102k | const sal_Int32 newLen = std::max(mnChunkLength * 2, maAttributeValues.back()); |
107 | 102k | auto p = static_cast<char*>(realloc(mpChunk, newLen)); |
108 | 102k | if (!p) |
109 | 0 | throw std::bad_alloc(); |
110 | | |
111 | 102k | mnChunkLength = newLen; |
112 | 102k | mpChunk = p; |
113 | | |
114 | 102k | } |
115 | 18.7M | memcpy(mpChunk + nWritePosition, value.data(), value.length()); |
116 | 18.7M | mpChunk[nWritePosition + value.length()] = '\0'; |
117 | 18.7M | } |
118 | | |
119 | | void FastAttributeList::add(sal_Int32 nToken, std::u16string_view sValue) |
120 | 0 | { |
121 | 0 | add(nToken, OUStringToOString(sValue, RTL_TEXTENCODING_UTF8)); |
122 | 0 | } |
123 | | |
124 | | void FastAttributeList::addNS( sal_Int32 nNamespaceToken, sal_Int32 nToken, std::string_view rValue ) |
125 | 0 | { |
126 | 0 | sal_Int32 nCombinedToken = (nNamespaceToken << 16) | nToken; |
127 | 0 | add( nCombinedToken, rValue ); |
128 | 0 | } |
129 | | |
130 | | void FastAttributeList::addNS(sal_Int32 nNamespaceToken, sal_Int32 nToken, |
131 | | std::u16string_view sValue) |
132 | 0 | { |
133 | 0 | sal_Int32 nCombinedToken = (nNamespaceToken << 16) | nToken; |
134 | 0 | add(nCombinedToken, sValue); |
135 | 0 | } |
136 | | |
137 | | void FastAttributeList::addUnknown( const OUString& rNamespaceURL, const OString& rName, const OString& value ) |
138 | 1.18M | { |
139 | 1.18M | maUnknownAttributes.emplace_back( rNamespaceURL, rName, value ); |
140 | 1.18M | } |
141 | | |
142 | | void FastAttributeList::addUnknown( const OString& rName, const OString& value ) |
143 | 1.51M | { |
144 | 1.51M | maUnknownAttributes.emplace_back( rName, value ); |
145 | 1.51M | } |
146 | | |
147 | | void FastAttributeList::add( const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) |
148 | 9.69k | { |
149 | 9.69k | const auto& rOther = castToFastAttributeList(xAttrList); |
150 | 9.69k | add(rOther); |
151 | 9.69k | } |
152 | | |
153 | | void FastAttributeList::add( const FastAttributeList& rOther ) |
154 | 9.69k | { |
155 | 39.5k | for (size_t i=0; i < rOther.maAttributeTokens.size(); ++i) |
156 | 29.8k | add(rOther.maAttributeTokens[i], rOther.getAsViewByIndex(i)); |
157 | 9.69k | for (const auto & i : rOther.maUnknownAttributes) |
158 | 31.1k | addUnknown(i.maNamespaceURL, i.maName, i.maValue); |
159 | 9.69k | } |
160 | | |
161 | | // XFastAttributeList |
162 | | sal_Bool FastAttributeList::hasAttribute( ::sal_Int32 Token ) |
163 | 10.6M | { |
164 | 10.6M | for (sal_Int32 i : maAttributeTokens) |
165 | 18.8M | if (i == Token) |
166 | 1.90M | return true; |
167 | | |
168 | 8.69M | return false; |
169 | 10.6M | } |
170 | | |
171 | | sal_Int32 FastAttributeList::getValueToken( ::sal_Int32 Token ) |
172 | 0 | { |
173 | 0 | for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i) |
174 | 0 | if (maAttributeTokens[i] == Token) |
175 | 0 | return getValueTokenByIndex(i); |
176 | | |
177 | 0 | throw SAXException("FastAttributeList::getValueToken: unknown token " + OUString::number(Token), nullptr, Any()); |
178 | 0 | } |
179 | | |
180 | | sal_Int32 FastAttributeList::getOptionalValueToken( ::sal_Int32 Token, ::sal_Int32 Default ) |
181 | 11.7M | { |
182 | 26.7M | for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i) |
183 | 17.2M | if (maAttributeTokens[i] == Token) |
184 | 2.18M | return getValueTokenByIndex(i); |
185 | | |
186 | 9.52M | return Default; |
187 | 11.7M | } |
188 | | |
189 | | // performance sensitive shortcuts to avoid allocation ... |
190 | | bool FastAttributeList::getAsInteger( sal_Int32 nToken, sal_Int32 &rInt) const |
191 | 6.40M | { |
192 | 6.40M | rInt = 0; |
193 | 16.2M | for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i) |
194 | 13.7M | if (maAttributeTokens[i] == nToken) |
195 | 3.95M | { |
196 | 3.95M | rInt = getAsIntegerByIndex(i); |
197 | 3.95M | return true; |
198 | 3.95M | } |
199 | 2.44M | return false; |
200 | 6.40M | } |
201 | | |
202 | | bool FastAttributeList::getAsDouble( sal_Int32 nToken, double &rDouble) const |
203 | 530k | { |
204 | 530k | rDouble = 0.0; |
205 | 1.35M | for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i) |
206 | 1.14M | if (maAttributeTokens[i] == nToken) |
207 | 319k | { |
208 | 319k | rDouble = o3tl::toDouble(getAsViewByIndex(i)); |
209 | 319k | return true; |
210 | 319k | } |
211 | 210k | return false; |
212 | 530k | } |
213 | | |
214 | | bool FastAttributeList::getAsView( sal_Int32 nToken, std::string_view& rPos ) const |
215 | 1.66M | { |
216 | 1.85M | for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i) |
217 | 1.79M | { |
218 | 1.79M | if (maAttributeTokens[i] != nToken) |
219 | 188k | continue; |
220 | | |
221 | 1.60M | rPos = getAsViewByIndex(i); |
222 | 1.60M | return true; |
223 | 1.79M | } |
224 | | |
225 | 65.7k | return false; |
226 | 1.66M | } |
227 | | |
228 | | OUString FastAttributeList::getValue( ::sal_Int32 Token ) |
229 | 33.3k | { |
230 | 37.1k | for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i) |
231 | 35.9k | if (maAttributeTokens[i] == Token) |
232 | 32.1k | return getValueByIndex(i); |
233 | | |
234 | 1.21k | throw SAXException("FastAttributeList::getValue: unknown token " + OUString::number(Token), nullptr, Any()); |
235 | 33.3k | } |
236 | | |
237 | | OUString FastAttributeList::getOptionalValue( ::sal_Int32 Token ) |
238 | 4.09M | { |
239 | 8.00M | for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i) |
240 | 6.77M | if (maAttributeTokens[i] == Token) |
241 | 2.86M | return getValueByIndex(i); |
242 | | |
243 | 1.22M | return OUString(); |
244 | 4.09M | } |
245 | | |
246 | | sal_Int32 FastAttributeList::getValueTokenByIndex(sal_Int32 nTokenIndex) const |
247 | 2.82M | { |
248 | 2.82M | return FastTokenHandlerBase::getTokenFromChars(mpTokenHandler, getAsViewByIndex(nTokenIndex)); |
249 | 2.82M | } |
250 | | |
251 | | Sequence< Attribute > FastAttributeList::getUnknownAttributes( ) |
252 | 23.7M | { |
253 | 23.7M | auto nSize = maUnknownAttributes.size(); |
254 | 23.7M | if (nSize == 0) |
255 | 23.2M | return {}; |
256 | 414k | Sequence< Attribute > aSeq( nSize ); |
257 | 414k | Attribute* pAttr = aSeq.getArray(); |
258 | 414k | for( const auto& rAttr : maUnknownAttributes ) |
259 | 1.34M | rAttr.FillAttribute( pAttr++ ); |
260 | 414k | return aSeq; |
261 | 23.7M | } |
262 | | Sequence< FastAttribute > FastAttributeList::getFastAttributes( ) |
263 | 20.2k | { |
264 | 20.2k | Sequence< FastAttribute > aSeq( maAttributeTokens.size() ); |
265 | 20.2k | FastAttribute* pAttr = aSeq.getArray(); |
266 | 32.5k | for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i) |
267 | 12.3k | { |
268 | 12.3k | pAttr->Token = maAttributeTokens[i]; |
269 | 12.3k | pAttr->Value = getValueByIndex(i); |
270 | 12.3k | pAttr++; |
271 | 12.3k | } |
272 | 20.2k | return aSeq; |
273 | 20.2k | } |
274 | | |
275 | | FastAttributeList::FastAttributeIter FastAttributeList::find( sal_Int32 nToken ) const |
276 | 2.89M | { |
277 | 3.38M | for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i) |
278 | 512k | if( maAttributeTokens[i] == nToken ) |
279 | 23.0k | return FastAttributeIter(*this, i); |
280 | 2.87M | return end(); |
281 | 2.89M | } |
282 | | |
283 | | sal_Int32 FastTokenHandlerBase::getTokenFromChars( |
284 | | const FastTokenHandlerBase *pTokenHandler, |
285 | | std::string_view token ) |
286 | 53.5M | { |
287 | 53.5M | return pTokenHandler->getTokenDirect(token); |
288 | 53.5M | } |
289 | | |
290 | | } |
291 | | |
292 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |