loplugin:constvars in package..sc
[LibreOffice.git] / sax / source / tools / fastattribs.cxx
blob6175c7873882222ba990d0554f3c885373f2b1c2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <algorithm>
22 #include <com/sun/star/xml/sax/SAXException.hpp>
23 #include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
24 #include <sax/fastattribs.hxx>
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
32 // wastage to keep MSVC happy vs. an in-line {}
33 FastTokenHandlerBase::~FastTokenHandlerBase()
37 UnknownAttribute::UnknownAttribute( const OUString& rNamespaceURL, const OString& rName, const OString& value )
38 : maNamespaceURL( rNamespaceURL ), maName( rName ), maValue( value )
42 UnknownAttribute::UnknownAttribute( const OString& rName, const OString& value )
43 : maName( rName ), maValue( value )
47 void UnknownAttribute::FillAttribute( Attribute* pAttrib ) const
49 if( pAttrib )
51 pAttrib->Name = OStringToOUString( maName, RTL_TEXTENCODING_UTF8 );
52 pAttrib->NamespaceURL = maNamespaceURL;
53 pAttrib->Value = OStringToOUString( maValue, RTL_TEXTENCODING_UTF8 );
57 FastAttributeList::FastAttributeList( const css::uno::Reference< css::xml::sax::XFastTokenHandler >& xTokenHandler,
58 sax_fastparser::FastTokenHandlerBase *pTokenHandler)
59 : mxTokenHandler( xTokenHandler ),
60 mpTokenHandler( pTokenHandler )
62 // random initial size of buffer to store attribute values
63 mnChunkLength = 58;
64 mpChunk = static_cast<sal_Char *>(malloc( mnChunkLength ));
65 maAttributeValues.push_back( 0 );
68 FastAttributeList::~FastAttributeList()
70 free( mpChunk );
73 void FastAttributeList::clear()
75 maAttributeTokens.clear();
76 maAttributeValues.resize(1);
77 assert(maAttributeValues[0] == 0);
78 maUnknownAttributes.clear();
81 void FastAttributeList::add( sal_Int32 nToken, const sal_Char* pValue, size_t nValueLength )
83 assert(nToken != -1);
84 maAttributeTokens.push_back( nToken );
85 sal_Int32 nWritePosition = maAttributeValues.back();
86 maAttributeValues.push_back( maAttributeValues.back() + nValueLength + 1 );
87 if (maAttributeValues.back() > mnChunkLength)
89 const sal_Int32 newLen = std::max(mnChunkLength * 2, maAttributeValues.back());
90 if (auto p = static_cast<sal_Char*>(realloc(mpChunk, newLen)))
92 mnChunkLength = newLen;
93 mpChunk = p;
95 else
96 throw std::bad_alloc();
98 strncpy(mpChunk + nWritePosition, pValue, nValueLength);
99 mpChunk[nWritePosition + nValueLength] = '\0';
102 void FastAttributeList::add( sal_Int32 nToken, const sal_Char* pValue )
104 add( nToken, pValue, strlen( pValue ));
107 void FastAttributeList::add( sal_Int32 nToken, const OString& rValue )
109 add( nToken, rValue.getStr(), rValue.getLength() );
112 void FastAttributeList::addNS( sal_Int32 nNamespaceToken, sal_Int32 nToken, const OString& rValue )
114 sal_Int32 nCombinedToken = (nNamespaceToken << 16) | nToken;
115 add( nCombinedToken, rValue );
118 void FastAttributeList::addUnknown( const OUString& rNamespaceURL, const OString& rName, const OString& value )
120 maUnknownAttributes.emplace_back( rNamespaceURL, rName, value );
123 void FastAttributeList::addUnknown( const OString& rName, const OString& value )
125 maUnknownAttributes.emplace_back( rName, value );
128 // XFastAttributeList
129 sal_Bool FastAttributeList::hasAttribute( ::sal_Int32 Token )
131 for (sal_Int32 i : maAttributeTokens)
132 if (i == Token)
133 return true;
135 return false;
138 sal_Int32 FastAttributeList::getValueToken( ::sal_Int32 Token )
140 for (size_t i = 0; i < maAttributeTokens.size(); ++i)
141 if (maAttributeTokens[i] == Token)
142 return FastTokenHandlerBase::getTokenFromChars(
143 mxTokenHandler, mpTokenHandler,
144 getFastAttributeValue(i),
145 AttributeValueLength( i ) );
147 throw SAXException();
150 sal_Int32 FastAttributeList::getOptionalValueToken( ::sal_Int32 Token, ::sal_Int32 Default )
152 for (size_t i = 0; i < maAttributeTokens.size(); ++i)
153 if (maAttributeTokens[i] == Token)
154 return FastTokenHandlerBase::getTokenFromChars(
155 mxTokenHandler, mpTokenHandler,
156 getFastAttributeValue(i),
157 AttributeValueLength( i ) );
159 return Default;
162 // performance sensitive shortcuts to avoid allocation ...
163 bool FastAttributeList::getAsInteger( sal_Int32 nToken, sal_Int32 &rInt) const
165 rInt = 0;
166 for (size_t i = 0; i < maAttributeTokens.size(); ++i)
167 if (maAttributeTokens[i] == nToken)
169 rInt = rtl_str_toInt32( getFastAttributeValue(i), 10 );
170 return true;
172 return false;
175 sal_Int32 FastAttributeList::getAsIntegerByIndex( sal_Int32 nTokenIndex ) const
177 return rtl_str_toInt32( getFastAttributeValue(nTokenIndex), 10 );
180 bool FastAttributeList::getAsDouble( sal_Int32 nToken, double &rDouble) const
182 rDouble = 0.0;
183 for (size_t i = 0; i < maAttributeTokens.size(); ++i)
184 if (maAttributeTokens[i] == nToken)
186 rDouble = rtl_str_toDouble( getFastAttributeValue(i) );
187 return true;
189 return false;
192 bool FastAttributeList::getAsChar( sal_Int32 nToken, const char*& rPos ) const
194 for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
196 if (maAttributeTokens[i] != nToken)
197 continue;
199 sal_Int32 nOffset = maAttributeValues[i];
200 rPos = mpChunk + nOffset;
201 return true;
204 return false;
207 const char* FastAttributeList::getAsCharByIndex( sal_Int32 nTokenIndex ) const
209 sal_Int32 nOffset = maAttributeValues[nTokenIndex];
210 return mpChunk + nOffset;
213 OUString FastAttributeList::getValue( ::sal_Int32 Token )
215 for (size_t i = 0; i < maAttributeTokens.size(); ++i)
216 if (maAttributeTokens[i] == Token)
217 return OUString( getFastAttributeValue(i), AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
219 throw SAXException();
222 OUString FastAttributeList::getValueByIndex( ::sal_Int32 nTokenIndex ) const
224 return OUString( getFastAttributeValue(nTokenIndex), AttributeValueLength(nTokenIndex), RTL_TEXTENCODING_UTF8 );
227 OUString FastAttributeList::getOptionalValue( ::sal_Int32 Token )
229 for (size_t i = 0; i < maAttributeTokens.size(); ++i)
230 if (maAttributeTokens[i] == Token)
231 return OUString( getFastAttributeValue(i), AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
233 return OUString();
235 Sequence< Attribute > FastAttributeList::getUnknownAttributes( )
237 Sequence< Attribute > aSeq( maUnknownAttributes.size() );
238 Attribute* pAttr = aSeq.getArray();
239 for( const auto& rAttr : maUnknownAttributes )
240 rAttr.FillAttribute( pAttr++ );
241 return aSeq;
243 Sequence< FastAttribute > FastAttributeList::getFastAttributes( )
245 Sequence< FastAttribute > aSeq( maAttributeTokens.size() );
246 FastAttribute* pAttr = aSeq.getArray();
247 for (size_t i = 0; i < maAttributeTokens.size(); ++i)
249 pAttr->Token = maAttributeTokens[i];
250 pAttr->Value = OUString( getFastAttributeValue(i), AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
251 pAttr++;
253 return aSeq;
256 const FastAttributeList::FastAttributeIter FastAttributeList::find( sal_Int32 nToken ) const
258 for (size_t i = 0; i < maAttributeTokens.size(); ++i)
259 if( maAttributeTokens[i] == nToken )
260 return FastAttributeIter(*this, i);
261 return end();
264 sal_Int32 FastTokenHandlerBase::getTokenFromChars(
265 const css::uno::Reference< css::xml::sax::XFastTokenHandler > &xTokenHandler,
266 const FastTokenHandlerBase *pTokenHandler,
267 const char *pToken, size_t nLen /* = 0 */ )
269 sal_Int32 nRet;
271 if( !nLen )
272 nLen = strlen( pToken );
274 if( pTokenHandler )
275 nRet = pTokenHandler->getTokenDirect( pToken, static_cast<sal_Int32>(nLen) );
276 else
278 // heap allocate, copy & then free
279 Sequence< sal_Int8 > aSeq( reinterpret_cast<sal_Int8 const *>(pToken), nLen );
280 nRet = xTokenHandler->getTokenFromUTF8( aSeq );
283 return nRet;
288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */