LibreOffice Module sax (master) 1
fastattribs.cxx
Go to the documentation of this file.
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 <rtl/math.h>
24#include <sax/fastattribs.hxx>
25#include <utility>
26
27using namespace ::com::sun::star::uno;
28using namespace ::com::sun::star::xml;
29using namespace ::com::sun::star::xml::sax;
30namespace sax_fastparser
31{
32
33// wastage to keep MSVC happy vs. an in-line {}
35{
36}
37
38UnknownAttribute::UnknownAttribute( OUString aNamespaceURL, OString aName, OString value )
39 : maNamespaceURL(std::move( aNamespaceURL )), maName(std::move( aName )), maValue(std::move( value ))
40{
41}
42
43UnknownAttribute::UnknownAttribute( OString aName, OString value )
44 : maName(std::move( aName )), maValue(std::move( value ))
45{
46}
47
48void UnknownAttribute::FillAttribute( Attribute* pAttrib ) const
49{
50 if( pAttrib )
51 {
52 pAttrib->Name = OStringToOUString( maName, RTL_TEXTENCODING_UTF8 );
53 pAttrib->NamespaceURL = maNamespaceURL;
54 pAttrib->Value = OStringToOUString( maValue, RTL_TEXTENCODING_UTF8 );
55 }
56}
57
59: mpTokenHandler( pTokenHandler )
60{
61 // random initial size of buffer to store attribute values
62 mnChunkLength = 58;
63 mpChunk = static_cast<char *>(malloc( mnChunkLength ));
64 maAttributeValues.push_back( 0 );
65}
66
67FastAttributeList::FastAttributeList( const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList )
68{
69 const auto& rOther = castToFastAttributeList(xAttrList);
70 mpTokenHandler = rOther.mpTokenHandler;
71 mpChunk = static_cast<char *>(malloc( rOther.mnChunkLength ));
72 mnChunkLength = rOther.mnChunkLength;
73 memcpy(mpChunk, rOther.mpChunk, rOther.mnChunkLength);
74 maAttributeValues = rOther.maAttributeValues;
75 maAttributeTokens = rOther.maAttributeTokens;
76 maUnknownAttributes = rOther.maUnknownAttributes;
77}
78
79css::uno::Reference< ::css::util::XCloneable > FastAttributeList::createClone()
80{
81 return new FastAttributeList(this);
82}
83
85{
86 free( mpChunk );
87}
88
90{
91 maAttributeTokens.clear();
92 maAttributeValues.resize(1);
93 assert(maAttributeValues[0] == 0);
94 maUnknownAttributes.clear();
95}
96
97void FastAttributeList::add( sal_Int32 nToken, std::string_view value )
98{
99 assert(nToken != -1);
100 assert(nToken != 0);
101 assert(value.length() < SAL_MAX_INT32); // protect against absurd values
102 maAttributeTokens.push_back( nToken );
103 sal_Int32 nWritePosition = maAttributeValues.back();
104 maAttributeValues.push_back( maAttributeValues.back() + value.length() + 1 );
105 if (maAttributeValues.back() > mnChunkLength)
106 {
107 const sal_Int32 newLen = std::max(mnChunkLength * 2, maAttributeValues.back());
108 auto p = static_cast<char*>(realloc(mpChunk, newLen));
109 if (!p)
110 throw std::bad_alloc();
111
112 mnChunkLength = newLen;
113 mpChunk = p;
114
115 }
116 memcpy(mpChunk + nWritePosition, value.data(), value.length());
117 mpChunk[nWritePosition + value.length()] = '\0';
118}
119
120void FastAttributeList::add(sal_Int32 nToken, std::u16string_view sValue)
121{
122 add(nToken, OUStringToOString(sValue, RTL_TEXTENCODING_UTF8));
123}
124
125void FastAttributeList::addNS( sal_Int32 nNamespaceToken, sal_Int32 nToken, std::string_view rValue )
126{
127 sal_Int32 nCombinedToken = (nNamespaceToken << 16) | nToken;
128 add( nCombinedToken, rValue );
129}
130
131void FastAttributeList::addNS(sal_Int32 nNamespaceToken, sal_Int32 nToken,
132 std::u16string_view sValue)
133{
134 sal_Int32 nCombinedToken = (nNamespaceToken << 16) | nToken;
135 add(nCombinedToken, sValue);
136}
137
138void FastAttributeList::addUnknown( const OUString& rNamespaceURL, const OString& rName, const OString& value )
139{
140 maUnknownAttributes.emplace_back( rNamespaceURL, rName, value );
141}
142
143void FastAttributeList::addUnknown( const OString& rName, const OString& value )
144{
145 maUnknownAttributes.emplace_back( rName, value );
146}
147
148void FastAttributeList::add( const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList )
149{
150 const auto& rOther = castToFastAttributeList(xAttrList);
151 add(rOther);
152}
153
155{
156 for (size_t i=0; i < rOther.maAttributeTokens.size(); ++i)
157 add(rOther.maAttributeTokens[i], rOther.getAsViewByIndex(i));
158 for (const auto & i : rOther.maUnknownAttributes)
159 addUnknown(i.maNamespaceURL, i.maName, i.maValue);
160}
161
162// XFastAttributeList
164{
165 for (sal_Int32 i : maAttributeTokens)
166 if (i == Token)
167 return true;
168
169 return false;
170}
171
172sal_Int32 FastAttributeList::getValueToken( ::sal_Int32 Token )
173{
174 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
175 if (maAttributeTokens[i] == Token)
179
180 throw SAXException("FastAttributeList::getValueToken: unknown token " + OUString::number(Token), nullptr, Any());
181}
182
183sal_Int32 FastAttributeList::getOptionalValueToken( ::sal_Int32 Token, ::sal_Int32 Default )
184{
185 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
186 if (maAttributeTokens[i] == Token)
190
191 return Default;
192}
193
194// performance sensitive shortcuts to avoid allocation ...
195bool FastAttributeList::getAsInteger( sal_Int32 nToken, sal_Int32 &rInt) const
196{
197 rInt = 0;
198 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
199 if (maAttributeTokens[i] == nToken)
200 {
201 rInt = getAsIntegerByIndex(i);
202 return true;
203 }
204 return false;
205}
206
207bool FastAttributeList::getAsDouble( sal_Int32 nToken, double &rDouble) const
208{
209 rDouble = 0.0;
210 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
211 if (maAttributeTokens[i] == nToken)
212 {
214 return true;
215 }
216 return false;
217}
218
219bool FastAttributeList::getAsView( sal_Int32 nToken, std::string_view& rPos ) const
220{
221 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
222 {
223 if (maAttributeTokens[i] != nToken)
224 continue;
225
226 rPos = getAsViewByIndex(i);
227 return true;
228 }
229
230 return false;
231}
232
233OUString FastAttributeList::getValue( ::sal_Int32 Token )
234{
235 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
236 if (maAttributeTokens[i] == Token)
237 return getValueByIndex(i);
238
239 throw SAXException("FastAttributeList::getValue: unknown token " + OUString::number(Token), nullptr, Any());
240}
241
242OUString FastAttributeList::getOptionalValue( ::sal_Int32 Token )
243{
244 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
245 if (maAttributeTokens[i] == Token)
246 return getValueByIndex(i);
247
248 return OUString();
249}
251{
252 auto nSize = maUnknownAttributes.size();
253 if (nSize == 0)
254 return {};
255 Sequence< Attribute > aSeq( nSize );
256 Attribute* pAttr = aSeq.getArray();
257 for( const auto& rAttr : maUnknownAttributes )
258 rAttr.FillAttribute( pAttr++ );
259 return aSeq;
260}
261Sequence< FastAttribute > FastAttributeList::getFastAttributes( )
262{
263 Sequence< FastAttribute > aSeq( maAttributeTokens.size() );
264 FastAttribute* pAttr = aSeq.getArray();
265 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
266 {
267 pAttr->Token = maAttributeTokens[i];
268 pAttr->Value = getValueByIndex(i);
269 pAttr++;
270 }
271 return aSeq;
272}
273
275{
276 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
277 if( maAttributeTokens[i] == nToken )
278 return FastAttributeIter(*this, i);
279 return end();
280}
281
283 const FastTokenHandlerBase *pTokenHandler,
284 std::string_view token )
285{
286 return pTokenHandler->getTokenDirect(token.data(), token.size());
287}
288
289}
290
291/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString maName
Use for fast iteration and conversion of attributes.
virtual css::uno::Sequence< css::xml::Attribute > SAL_CALL getUnknownAttributes() override
FastAttributeList(FastTokenHandlerBase *pTokenHandler)
Definition: fastattribs.cxx:58
std::vector< sal_Int32 > maAttributeValues
FastAttributeIter find(sal_Int32 nToken) const
void add(const FastAttributeList &)
std::vector< UnknownAttribute > maUnknownAttributes
virtual ::sal_Int32 SAL_CALL getOptionalValueToken(::sal_Int32 Token, ::sal_Int32 Default) override
virtual ::css::uno::Reference< ::css::util::XCloneable > SAL_CALL createClone() override
Definition: fastattribs.cxx:79
OUString getValueByIndex(sal_Int32 nTokenIndex) const
std::string_view getAsViewByIndex(sal_Int32 nTokenIndex) const
bool getAsView(sal_Int32 nToken, std::string_view &rPos) const
char * mpChunk
buffer to store all attribute values - null terminated strings
bool getAsDouble(sal_Int32 nToken, double &rDouble) const
bool getAsInteger(sal_Int32 nToken, sal_Int32 &rInt) const
virtual ::sal_Int32 SAL_CALL getValueToken(::sal_Int32 Token) override
std::vector< sal_Int32 > maAttributeTokens
virtual ~FastAttributeList() override
Definition: fastattribs.cxx:84
virtual css::uno::Sequence< css::xml::FastAttribute > SAL_CALL getFastAttributes() override
FastAttributeIter end() const
sal_Int32 getAsIntegerByIndex(sal_Int32 nTokenIndex) const
virtual OUString SAL_CALL getOptionalValue(::sal_Int32 Token) override
sal_Int32 mnChunkLength
size of allocated memory for mpChunk
virtual OUString SAL_CALL getValue(::sal_Int32 Token) override
virtual sal_Bool SAL_CALL hasAttribute(::sal_Int32 Token) override
void addUnknown(const OUString &rNamespaceURL, const OString &rQName, const OString &value)
FastTokenHandlerBase * mpTokenHandler
void addNS(sal_Int32 nNamespaceToken, sal_Int32 nToken, std::string_view sValue)
A native C++ interface to tokenisation.
Definition: fastattribs.hxx:57
static sal_Int32 getTokenFromChars(const FastTokenHandlerBase *pTokenHandler, std::string_view str)
Client method to attempt the use of this interface if possible.
virtual sal_Int32 getTokenDirect(const char *pToken, sal_Int32 nLength) const =0
Any value
double maValue
OUString aName
void * p
sal_Int64 n
Sequence< sal_Int8 > aSeq
int i
double toDouble(std::u16string_view str)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
DefTokenId nToken
void FillAttribute(css::xml::Attribute *pAttrib) const
Definition: fastattribs.cxx:48
UnknownAttribute(OUString sNamespaceURL, OString aName, OString value)
Definition: fastattribs.cxx:38
#define SAL_MAX_INT32
unsigned char sal_Bool