Line data Source code
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 <sax/fastattribs.hxx>
23 :
24 : using namespace ::com::sun::star::uno;
25 : using namespace ::com::sun::star::xml;
26 : using namespace ::com::sun::star::xml::sax;
27 : namespace sax_fastparser
28 : {
29 :
30 : // wasteage to keep MSVC happy vs. an in-line {}
31 0 : FastTokenHandlerBase::~FastTokenHandlerBase()
32 : {
33 0 : }
34 :
35 0 : UnknownAttribute::UnknownAttribute( const OUString& rNamespaceURL, const OString& rName, const sal_Char* pValue )
36 0 : : maNamespaceURL( rNamespaceURL ), maName( rName ), maValue( pValue )
37 : {
38 0 : }
39 :
40 0 : UnknownAttribute::UnknownAttribute( const OString& rName, const sal_Char* pValue )
41 0 : : maName( rName ), maValue( pValue )
42 : {
43 0 : }
44 :
45 0 : void UnknownAttribute::FillAttribute( Attribute* pAttrib ) const
46 : {
47 0 : if( pAttrib )
48 : {
49 0 : pAttrib->Name = OStringToOUString( maName, RTL_TEXTENCODING_UTF8 );
50 0 : pAttrib->NamespaceURL = maNamespaceURL;
51 0 : pAttrib->Value = OStringToOUString( maValue, RTL_TEXTENCODING_UTF8 );
52 : }
53 0 : }
54 :
55 0 : FastAttributeList::FastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xTokenHandler,
56 : sax_fastparser::FastTokenHandlerBase *pTokenHandler)
57 : : mxTokenHandler( xTokenHandler ),
58 0 : mpTokenHandler( pTokenHandler )
59 : {
60 : // random initial size of buffer to store attribute values
61 0 : mnChunkLength = 58;
62 0 : mpChunk = (sal_Char *) malloc( mnChunkLength );
63 0 : maAttributeValues.push_back( 0 );
64 0 : }
65 :
66 0 : FastAttributeList::~FastAttributeList()
67 : {
68 0 : free( mpChunk );
69 0 : }
70 :
71 0 : void FastAttributeList::clear()
72 : {
73 0 : maAttributeTokens.clear();
74 0 : maAttributeValues.clear();
75 0 : maAttributeValues.push_back( 0 );
76 0 : maUnknownAttributes.clear();
77 0 : }
78 :
79 0 : void FastAttributeList::add( sal_Int32 nToken, const sal_Char* pValue, size_t nValueLength )
80 : {
81 0 : maAttributeTokens.push_back( nToken );
82 0 : if (nValueLength == 0)
83 0 : nValueLength = strlen(pValue);
84 0 : sal_Int32 nWritePosition = maAttributeValues.back();
85 0 : maAttributeValues.push_back( maAttributeValues.back() + nValueLength + 1 );
86 0 : if (maAttributeValues.back() > mnChunkLength)
87 : {
88 0 : mnChunkLength = maAttributeValues.back();
89 0 : mpChunk = (sal_Char *) realloc( mpChunk, mnChunkLength );
90 : }
91 0 : strncpy(mpChunk + nWritePosition, pValue, nValueLength);
92 0 : mpChunk[nWritePosition + nValueLength] = '\0';
93 0 : }
94 :
95 0 : void FastAttributeList::add( sal_Int32 nToken, const OString& rValue )
96 : {
97 0 : add( nToken, rValue.getStr(), rValue.getLength() );
98 0 : }
99 :
100 0 : void FastAttributeList::addNS( sal_Int32 nNamespaceToken, sal_Int32 nToken, const OString& rValue )
101 : {
102 0 : sal_Int32 nCombinedToken = (nNamespaceToken << 16) | nToken;
103 0 : add( nCombinedToken, rValue );
104 0 : }
105 :
106 0 : void FastAttributeList::addUnknown( const OUString& rNamespaceURL, const OString& rName, const sal_Char* pValue )
107 : {
108 0 : maUnknownAttributes.push_back( UnknownAttribute( rNamespaceURL, rName, pValue ) );
109 0 : }
110 :
111 0 : void FastAttributeList::addUnknown( const OString& rName, const sal_Char* pValue )
112 : {
113 0 : maUnknownAttributes.push_back( UnknownAttribute( rName, pValue ) );
114 0 : }
115 :
116 : // XFastAttributeList
117 0 : sal_Bool FastAttributeList::hasAttribute( ::sal_Int32 Token ) throw (RuntimeException, std::exception)
118 : {
119 0 : for (size_t i = 0; i < maAttributeTokens.size(); ++i)
120 0 : if (maAttributeTokens[i] == Token)
121 0 : return sal_True;
122 :
123 0 : return sal_False;
124 : }
125 :
126 0 : sal_Int32 FastAttributeList::getValueToken( ::sal_Int32 Token ) throw (SAXException, RuntimeException, std::exception)
127 : {
128 0 : for (size_t i = 0; i < maAttributeTokens.size(); ++i)
129 0 : if (maAttributeTokens[i] == Token)
130 : return maTokenLookup.getTokenFromChars( mxTokenHandler, mpTokenHandler,
131 0 : mpChunk + maAttributeValues[ i ],
132 0 : AttributeValueLength( i ) );
133 :
134 0 : throw SAXException();
135 : }
136 :
137 0 : sal_Int32 FastAttributeList::getOptionalValueToken( ::sal_Int32 Token, ::sal_Int32 Default ) throw (RuntimeException, std::exception)
138 : {
139 0 : for (size_t i = 0; i < maAttributeTokens.size(); ++i)
140 0 : if (maAttributeTokens[i] == Token)
141 : return maTokenLookup.getTokenFromChars( mxTokenHandler, mpTokenHandler,
142 0 : mpChunk + maAttributeValues[ i ],
143 0 : AttributeValueLength( i ) );
144 :
145 0 : return Default;
146 : }
147 :
148 : // performance sensitive shortcuts to avoid allocation ...
149 0 : bool FastAttributeList::getAsInteger( sal_Int32 nToken, sal_Int32 &rInt)
150 : {
151 0 : rInt = 0;
152 0 : for (size_t i = 0; i < maAttributeTokens.size(); ++i)
153 0 : if (maAttributeTokens[i] == nToken)
154 : {
155 0 : rInt = rtl_str_toInt32( mpChunk + maAttributeValues[i], 10 );
156 0 : return true;
157 : }
158 0 : return false;
159 : }
160 :
161 0 : bool FastAttributeList::getAsDouble( sal_Int32 nToken, double &rDouble)
162 : {
163 0 : rDouble = 0.0;
164 0 : for (size_t i = 0; i < maAttributeTokens.size(); ++i)
165 0 : if (maAttributeTokens[i] == nToken)
166 : {
167 0 : rDouble = rtl_str_toDouble( mpChunk + maAttributeValues[i] );
168 0 : return true;
169 : }
170 0 : return false;
171 : }
172 :
173 0 : bool FastAttributeList::getAsChar( sal_Int32 nToken, const char*& rPos ) const
174 : {
175 0 : for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
176 : {
177 0 : if (maAttributeTokens[i] != nToken)
178 0 : continue;
179 :
180 0 : sal_Int32 nOffset = maAttributeValues[i];
181 0 : rPos = mpChunk + nOffset;
182 0 : return true;
183 : }
184 :
185 0 : return false;
186 : }
187 :
188 0 : OUString FastAttributeList::getValue( ::sal_Int32 Token ) throw (SAXException, RuntimeException, std::exception)
189 : {
190 0 : for (size_t i = 0; i < maAttributeTokens.size(); ++i)
191 0 : if (maAttributeTokens[i] == Token)
192 0 : return OUString( mpChunk + maAttributeValues[i], AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
193 :
194 0 : throw SAXException();
195 : }
196 :
197 0 : OUString FastAttributeList::getOptionalValue( ::sal_Int32 Token ) throw (RuntimeException, std::exception)
198 : {
199 0 : for (size_t i = 0; i < maAttributeTokens.size(); ++i)
200 0 : if (maAttributeTokens[i] == Token)
201 0 : return OUString( mpChunk + maAttributeValues[i], AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
202 :
203 0 : return OUString();
204 : }
205 0 : Sequence< Attribute > FastAttributeList::getUnknownAttributes( ) throw (RuntimeException, std::exception)
206 : {
207 0 : Sequence< Attribute > aSeq( maUnknownAttributes.size() );
208 0 : Attribute* pAttr = aSeq.getArray();
209 0 : for( UnknownAttributeList::iterator attrIter = maUnknownAttributes.begin(); attrIter != maUnknownAttributes.end(); ++attrIter )
210 0 : (*attrIter).FillAttribute( pAttr++ );
211 0 : return aSeq;
212 : }
213 0 : Sequence< FastAttribute > FastAttributeList::getFastAttributes( ) throw (RuntimeException, std::exception)
214 : {
215 0 : Sequence< FastAttribute > aSeq( maAttributeTokens.size() );
216 0 : FastAttribute* pAttr = aSeq.getArray();
217 0 : for (size_t i = 0; i < maAttributeTokens.size(); ++i)
218 : {
219 0 : pAttr->Token = maAttributeTokens[i];
220 0 : pAttr->Value = OUString( mpChunk + maAttributeValues[i], AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
221 0 : pAttr++;
222 : }
223 0 : return aSeq;
224 : }
225 :
226 0 : sal_Int32 FastAttributeList::AttributeValueLength(sal_Int32 i)
227 : {
228 : // Pointers to null terminated strings
229 0 : return maAttributeValues[i + 1] - maAttributeValues[i] - 1;
230 : }
231 :
232 0 : FastTokenLookup::FastTokenLookup()
233 : {
234 0 : maUtf8Buffer.realloc( mnUtf8BufferSize );
235 0 : }
236 :
237 : /**
238 : * Avoid doing any memory allocation if we can, instead keep a
239 : * pet sequence around and do some heavy petting on it.
240 : */
241 0 : sal_Int32 FastTokenLookup::getTokenFromChars(
242 : const ::css::uno::Reference< ::css::xml::sax::XFastTokenHandler > &xTokenHandler,
243 : FastTokenHandlerBase *pTokenHandler,
244 : const char *pToken, size_t nLen /* = 0 */ )
245 : {
246 : sal_Int32 nRet;
247 :
248 0 : if( !nLen )
249 0 : nLen = strlen( pToken );
250 :
251 0 : if( pTokenHandler )
252 0 : nRet = pTokenHandler->getTokenDirect( pToken, (sal_Int32) nLen );
253 : else
254 : {
255 : // heap allocate, copy & then free
256 0 : Sequence< sal_Int8 > aSeq( (sal_Int8*)pToken, nLen );
257 0 : nRet = xTokenHandler->getTokenFromUTF8( aSeq );
258 : }
259 :
260 0 : return nRet;
261 : }
262 :
263 : }
264 :
265 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|