1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
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
64 mpChunk
= static_cast<sal_Char
*>(malloc( mnChunkLength
));
65 maAttributeValues
.push_back( 0 );
68 FastAttributeList::~FastAttributeList()
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
)
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
;
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
)
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
) );
162 // performance sensitive shortcuts to avoid allocation ...
163 bool FastAttributeList::getAsInteger( sal_Int32 nToken
, sal_Int32
&rInt
) const
166 for (size_t i
= 0; i
< maAttributeTokens
.size(); ++i
)
167 if (maAttributeTokens
[i
] == nToken
)
169 rInt
= rtl_str_toInt32( getFastAttributeValue(i
), 10 );
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
183 for (size_t i
= 0; i
< maAttributeTokens
.size(); ++i
)
184 if (maAttributeTokens
[i
] == nToken
)
186 rDouble
= rtl_str_toDouble( getFastAttributeValue(i
) );
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
)
199 sal_Int32 nOffset
= maAttributeValues
[i
];
200 rPos
= mpChunk
+ nOffset
;
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
);
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
++ );
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
);
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
);
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 */ )
272 nLen
= strlen( pToken
);
275 nRet
= pTokenHandler
->getTokenDirect( pToken
, static_cast<sal_Int32
>(nLen
) );
278 // heap allocate, copy & then free
279 Sequence
< sal_Int8
> aSeq( reinterpret_cast<sal_Int8
const *>(pToken
), nLen
);
280 nRet
= xTokenHandler
->getTokenFromUTF8( aSeq
);
288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */