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 <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( OUString aNamespaceURL
, OString aName
, OString value
)
38 : maNamespaceURL(std::move( aNamespaceURL
)), maName(std::move( aName
)), maValue(std::move( value
))
42 UnknownAttribute::UnknownAttribute( OString aName
, OString value
)
43 : maName(std::move( aName
)), maValue(std::move( 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( sax_fastparser::FastTokenHandlerBase
*pTokenHandler
)
58 : mpTokenHandler( pTokenHandler
)
60 // random initial size of buffer to store attribute values
62 mpChunk
= static_cast<char *>(malloc( mnChunkLength
));
63 maAttributeValues
.push_back( 0 );
66 FastAttributeList::FastAttributeList( const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & xAttrList
)
68 const auto& rOther
= castToFastAttributeList(xAttrList
);
69 mpTokenHandler
= rOther
.mpTokenHandler
;
70 mpChunk
= static_cast<char *>(malloc( rOther
.mnChunkLength
));
71 mnChunkLength
= rOther
.mnChunkLength
;
72 memcpy(mpChunk
, rOther
.mpChunk
, rOther
.mnChunkLength
);
73 maAttributeValues
= rOther
.maAttributeValues
;
74 maAttributeTokens
= rOther
.maAttributeTokens
;
75 maUnknownAttributes
= rOther
.maUnknownAttributes
;
78 css::uno::Reference
< ::css::util::XCloneable
> FastAttributeList::createClone()
80 return new FastAttributeList(this);
83 FastAttributeList::~FastAttributeList()
88 void FastAttributeList::clear()
90 maAttributeTokens
.clear();
91 maAttributeValues
.resize(1);
92 assert(maAttributeValues
[0] == 0);
93 maUnknownAttributes
.clear();
96 void FastAttributeList::add( sal_Int32 nToken
, std::string_view value
)
100 assert(value
.length() < SAL_MAX_INT32
); // protect against absurd values
101 maAttributeTokens
.push_back( nToken
);
102 sal_Int32 nWritePosition
= maAttributeValues
.back();
103 maAttributeValues
.push_back( maAttributeValues
.back() + value
.length() + 1 );
104 if (maAttributeValues
.back() > mnChunkLength
)
106 const sal_Int32 newLen
= std::max(mnChunkLength
* 2, maAttributeValues
.back());
107 auto p
= static_cast<char*>(realloc(mpChunk
, newLen
));
109 throw std::bad_alloc();
111 mnChunkLength
= newLen
;
115 memcpy(mpChunk
+ nWritePosition
, value
.data(), value
.length());
116 mpChunk
[nWritePosition
+ value
.length()] = '\0';
119 void FastAttributeList::add(sal_Int32 nToken
, std::u16string_view sValue
)
121 add(nToken
, OUStringToOString(sValue
, RTL_TEXTENCODING_UTF8
));
124 void FastAttributeList::addNS( sal_Int32 nNamespaceToken
, sal_Int32 nToken
, std::string_view rValue
)
126 sal_Int32 nCombinedToken
= (nNamespaceToken
<< 16) | nToken
;
127 add( nCombinedToken
, rValue
);
130 void FastAttributeList::addNS(sal_Int32 nNamespaceToken
, sal_Int32 nToken
,
131 std::u16string_view sValue
)
133 sal_Int32 nCombinedToken
= (nNamespaceToken
<< 16) | nToken
;
134 add(nCombinedToken
, sValue
);
137 void FastAttributeList::addUnknown( const OUString
& rNamespaceURL
, const OString
& rName
, const OString
& value
)
139 maUnknownAttributes
.emplace_back( rNamespaceURL
, rName
, value
);
142 void FastAttributeList::addUnknown( const OString
& rName
, const OString
& value
)
144 maUnknownAttributes
.emplace_back( rName
, value
);
147 void FastAttributeList::add( const css::uno::Reference
<css::xml::sax::XFastAttributeList
>& xAttrList
)
149 const auto& rOther
= castToFastAttributeList(xAttrList
);
153 void FastAttributeList::add( const FastAttributeList
& rOther
)
155 for (size_t i
=0; i
< rOther
.maAttributeTokens
.size(); ++i
)
156 add(rOther
.maAttributeTokens
[i
], rOther
.getAsViewByIndex(i
));
157 for (const auto & i
: rOther
.maUnknownAttributes
)
158 addUnknown(i
.maNamespaceURL
, i
.maName
, i
.maValue
);
161 // XFastAttributeList
162 sal_Bool
FastAttributeList::hasAttribute( ::sal_Int32 Token
)
164 for (sal_Int32 i
: maAttributeTokens
)
171 sal_Int32
FastAttributeList::getValueToken( ::sal_Int32 Token
)
173 for (size_t i
= 0, n
= maAttributeTokens
.size(); i
< n
; ++i
)
174 if (maAttributeTokens
[i
] == Token
)
175 return getValueTokenByIndex(i
);
177 throw SAXException("FastAttributeList::getValueToken: unknown token " + OUString::number(Token
), nullptr, Any());
180 sal_Int32
FastAttributeList::getOptionalValueToken( ::sal_Int32 Token
, ::sal_Int32 Default
)
182 for (size_t i
= 0, n
= maAttributeTokens
.size(); i
< n
; ++i
)
183 if (maAttributeTokens
[i
] == Token
)
184 return getValueTokenByIndex(i
);
189 // performance sensitive shortcuts to avoid allocation ...
190 bool FastAttributeList::getAsInteger( sal_Int32 nToken
, sal_Int32
&rInt
) const
193 for (size_t i
= 0, n
= maAttributeTokens
.size(); i
< n
; ++i
)
194 if (maAttributeTokens
[i
] == nToken
)
196 rInt
= getAsIntegerByIndex(i
);
202 bool FastAttributeList::getAsDouble( sal_Int32 nToken
, double &rDouble
) const
205 for (size_t i
= 0, n
= maAttributeTokens
.size(); i
< n
; ++i
)
206 if (maAttributeTokens
[i
] == nToken
)
208 rDouble
= o3tl::toDouble(getAsViewByIndex(i
));
214 bool FastAttributeList::getAsView( sal_Int32 nToken
, std::string_view
& rPos
) const
216 for (size_t i
= 0, n
= maAttributeTokens
.size(); i
< n
; ++i
)
218 if (maAttributeTokens
[i
] != nToken
)
221 rPos
= getAsViewByIndex(i
);
228 OUString
FastAttributeList::getValue( ::sal_Int32 Token
)
230 for (size_t i
= 0, n
= maAttributeTokens
.size(); i
< n
; ++i
)
231 if (maAttributeTokens
[i
] == Token
)
232 return getValueByIndex(i
);
234 throw SAXException("FastAttributeList::getValue: unknown token " + OUString::number(Token
), nullptr, Any());
237 OUString
FastAttributeList::getOptionalValue( ::sal_Int32 Token
)
239 for (size_t i
= 0, n
= maAttributeTokens
.size(); i
< n
; ++i
)
240 if (maAttributeTokens
[i
] == Token
)
241 return getValueByIndex(i
);
246 sal_Int32
FastAttributeList::getValueTokenByIndex(sal_Int32 nTokenIndex
) const
248 return FastTokenHandlerBase::getTokenFromChars(mpTokenHandler
, getAsViewByIndex(nTokenIndex
));
251 Sequence
< Attribute
> FastAttributeList::getUnknownAttributes( )
253 auto nSize
= maUnknownAttributes
.size();
256 Sequence
< Attribute
> aSeq( nSize
);
257 Attribute
* pAttr
= aSeq
.getArray();
258 for( const auto& rAttr
: maUnknownAttributes
)
259 rAttr
.FillAttribute( pAttr
++ );
262 Sequence
< FastAttribute
> FastAttributeList::getFastAttributes( )
264 Sequence
< FastAttribute
> aSeq( maAttributeTokens
.size() );
265 FastAttribute
* pAttr
= aSeq
.getArray();
266 for (size_t i
= 0, n
= maAttributeTokens
.size(); i
< n
; ++i
)
268 pAttr
->Token
= maAttributeTokens
[i
];
269 pAttr
->Value
= getValueByIndex(i
);
275 FastAttributeList::FastAttributeIter
FastAttributeList::find( sal_Int32 nToken
) const
277 for (size_t i
= 0, n
= maAttributeTokens
.size(); i
< n
; ++i
)
278 if( maAttributeTokens
[i
] == nToken
)
279 return FastAttributeIter(*this, i
);
283 sal_Int32
FastTokenHandlerBase::getTokenFromChars(
284 const FastTokenHandlerBase
*pTokenHandler
,
285 std::string_view token
)
287 return pTokenHandler
->getTokenDirect(token
);
292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */