Branch data 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 "oox/helper/attributelist.hxx"
21 : :
22 : : #include <osl/diagnose.h>
23 : : #include <rtl/ustrbuf.hxx>
24 : : #include "oox/token/tokenmap.hxx"
25 : :
26 : : namespace oox {
27 : :
28 : : // ============================================================================
29 : :
30 : : using namespace ::com::sun::star::uno;
31 : : using namespace ::com::sun::star::util;
32 : : using namespace ::com::sun::star::xml::sax;
33 : :
34 : : using ::rtl::OUString;
35 : : using ::rtl::OUStringBuffer;
36 : :
37 : : // ============================================================================
38 : :
39 : : namespace {
40 : :
41 : : const sal_Int32 XSTRING_ENCCHAR_LEN = 7;
42 : :
43 : 471 : bool lclAddHexDigit( sal_Unicode& orcChar, sal_Unicode cDigit, int nBitShift )
44 : : {
45 [ + - ][ + + ]: 471 : if( ('0' <= cDigit) && (cDigit <= '9') ) { orcChar |= ((cDigit - '0') << nBitShift); return true; }
46 [ + - ][ - + ]: 3 : if( ('a' <= cDigit) && (cDigit <= 'f') ) { orcChar |= ((cDigit - 'a' + 10) << nBitShift); return true; }
47 [ + - ][ - + ]: 3 : if( ('A' <= cDigit) && (cDigit <= 'F') ) { orcChar |= ((cDigit - 'A' + 10) << nBitShift); return true; }
48 : 471 : return false;
49 : : }
50 : :
51 : 2340 : sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd )
52 : : {
53 : 2340 : sal_Unicode cChar = 0;
54 [ + + ][ + + ]: 2811 : if( (pcEnd - rpcStr >= XSTRING_ENCCHAR_LEN) &&
[ + + ][ + -
+ + + - +
- + - ]
[ + + ]
55 : 834 : (rpcStr[ 0 ] == '_') &&
56 : 123 : (rpcStr[ 1 ] == 'x') &&
57 : 120 : (rpcStr[ 6 ] == '_') &&
58 : 120 : lclAddHexDigit( cChar, rpcStr[ 2 ], 12 ) &&
59 : 117 : lclAddHexDigit( cChar, rpcStr[ 3 ], 8 ) &&
60 : 117 : lclAddHexDigit( cChar, rpcStr[ 4 ], 4 ) &&
61 : 117 : lclAddHexDigit( cChar, rpcStr[ 5 ], 0 ) )
62 : : {
63 : 117 : rpcStr += XSTRING_ENCCHAR_LEN;
64 : 117 : return cChar;
65 : : }
66 : 2340 : return *rpcStr++;
67 : : }
68 : :
69 : : } // namespace
70 : :
71 : : // ----------------------------------------------------------------------------
72 : :
73 : 48 : sal_Int32 AttributeConversion::decodeToken( const OUString& rValue )
74 : : {
75 : 48 : return StaticTokenMap::get().getTokenFromUnicode( rValue );
76 : : }
77 : :
78 : 519 : OUString AttributeConversion::decodeXString( const OUString& rValue )
79 : : {
80 : : // string shorter than one encoded character - no need to decode
81 [ + + ]: 519 : if( rValue.getLength() < XSTRING_ENCCHAR_LEN )
82 : 234 : return rValue;
83 : 285 : OUStringBuffer aBuffer;
84 : 285 : const sal_Unicode* pcStr = rValue.getStr();
85 : 285 : const sal_Unicode* pcEnd = pcStr + rValue.getLength();
86 [ + + ]: 2625 : while( pcStr < pcEnd )
87 [ + - ]: 2340 : aBuffer.append( lclGetXChar( pcStr, pcEnd ) );
88 [ + - ]: 519 : return aBuffer.makeStringAndClear();
89 : : }
90 : :
91 : 984 : double AttributeConversion::decodeDouble( const OUString& rValue )
92 : : {
93 : 984 : return rValue.toDouble();
94 : : }
95 : :
96 : 6447 : sal_Int32 AttributeConversion::decodeInteger( const OUString& rValue )
97 : : {
98 : 6447 : return rValue.toInt32();
99 : : }
100 : :
101 : 3 : sal_uInt32 AttributeConversion::decodeUnsigned( const OUString& rValue )
102 : : {
103 : 3 : return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64(), 0, SAL_MAX_UINT32 );
104 : : }
105 : :
106 : 0 : sal_Int64 AttributeConversion::decodeHyper( const OUString& rValue )
107 : : {
108 : 0 : return rValue.toInt64();
109 : : }
110 : :
111 : 231 : sal_Int32 AttributeConversion::decodeIntegerHex( const OUString& rValue )
112 : : {
113 : 231 : return rValue.toInt32( 16 );
114 : : }
115 : :
116 : : // ============================================================================
117 : :
118 : 19506 : AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) :
119 : 19506 : mxAttribs( rxAttribs )
120 : : {
121 : : OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" );
122 : 19506 : }
123 : :
124 : 4740 : bool AttributeList::hasAttribute( sal_Int32 nAttrToken ) const
125 : : {
126 : 4740 : return mxAttribs->hasAttribute( nAttrToken );
127 : : }
128 : :
129 : : // optional return values -----------------------------------------------------
130 : :
131 : 771 : OptValue< sal_Int32 > AttributeList::getToken( sal_Int32 nAttrToken ) const
132 : : {
133 [ + - ][ + - ]: 771 : sal_Int32 nToken = mxAttribs->getOptionalValueToken( nAttrToken, XML_TOKEN_INVALID );
134 : 771 : return OptValue< sal_Int32 >( nToken != XML_TOKEN_INVALID, nToken );
135 : : }
136 : :
137 : 1257 : OptValue< OUString > AttributeList::getString( sal_Int32 nAttrToken ) const
138 : : {
139 : : // check if the attribute exists (empty string may be different to missing attribute)
140 [ + + ]: 1257 : if( mxAttribs->hasAttribute( nAttrToken ) )
141 : 438 : return OptValue< OUString >( mxAttribs->getOptionalValue( nAttrToken ) );
142 : 1257 : return OptValue< OUString >();
143 : : }
144 : :
145 : 537 : OptValue< OUString > AttributeList::getXString( sal_Int32 nAttrToken ) const
146 : : {
147 : : // check if the attribute exists (empty string may be different to missing attribute)
148 [ + + ]: 537 : if( mxAttribs->hasAttribute( nAttrToken ) )
149 [ + - ]: 519 : return OptValue< OUString >( AttributeConversion::decodeXString( mxAttribs->getOptionalValue( nAttrToken ) ) );
150 : 537 : return OptValue< OUString >();
151 : : }
152 : :
153 : 1065 : OptValue< double > AttributeList::getDouble( sal_Int32 nAttrToken ) const
154 : : {
155 [ + - ][ + - ]: 1065 : OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
156 : 1065 : bool bValid = !aValue.isEmpty();
157 [ + - ][ + + ]: 1065 : return OptValue< double >( bValid, bValid ? AttributeConversion::decodeDouble( aValue ) : 0.0 );
158 : : }
159 : :
160 : 14850 : OptValue< sal_Int32 > AttributeList::getInteger( sal_Int32 nAttrToken ) const
161 : : {
162 [ + - ][ + - ]: 14850 : OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
163 : 14850 : bool bValid = !aValue.isEmpty();
164 [ + - ][ + + ]: 14850 : return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeInteger( aValue ) : 0 );
165 : : }
166 : :
167 : 3 : OptValue< sal_uInt32 > AttributeList::getUnsigned( sal_Int32 nAttrToken ) const
168 : : {
169 [ + - ][ + - ]: 3 : OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
170 : 3 : bool bValid = !aValue.isEmpty();
171 [ + - ]: 3 : return OptValue< sal_uInt32 >( bValid, AttributeConversion::decodeUnsigned( aValue ) );
172 : : }
173 : :
174 : 0 : OptValue< sal_Int64 > AttributeList::getHyper( sal_Int32 nAttrToken ) const
175 : : {
176 [ # # ][ # # ]: 0 : OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
177 : 0 : bool bValid = !aValue.isEmpty();
178 [ # # ][ # # ]: 0 : return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyper( aValue ) : 0 );
179 : : }
180 : :
181 : 231 : OptValue< sal_Int32 > AttributeList::getIntegerHex( sal_Int32 nAttrToken ) const
182 : : {
183 [ + - ][ + - ]: 231 : OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
184 : 231 : bool bValid = !aValue.isEmpty();
185 [ + - ][ + - ]: 231 : return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeIntegerHex( aValue ) : 0 );
186 : : }
187 : :
188 : 8910 : OptValue< bool > AttributeList::getBool( sal_Int32 nAttrToken ) const
189 : : {
190 : : // boolean attributes may be "t", "f", "true", "false", "on", "off", "1", or "0"
191 [ + - ][ - + : 8910 : switch( getToken( nAttrToken, XML_TOKEN_INVALID ) )
- - + -
+ ]
192 : : {
193 : 0 : case XML_t: return OptValue< bool >( true ); // used in VML
194 : 837 : case XML_true: return OptValue< bool >( true );
195 : 0 : case XML_on: return OptValue< bool >( true );
196 : 0 : case XML_f: return OptValue< bool >( false ); // used in VML
197 : 2979 : case XML_false: return OptValue< bool >( false );
198 : 0 : case XML_off: return OptValue< bool >( false );
199 : : }
200 [ + - ]: 5094 : OptValue< sal_Int32 > onValue = getInteger( nAttrToken );
201 : 8910 : return OptValue< bool >( onValue.has(), onValue.get() != 0 );
202 : : }
203 : :
204 : 0 : OptValue< DateTime > AttributeList::getDateTime( sal_Int32 nAttrToken ) const
205 : : {
206 [ # # ][ # # ]: 0 : OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
207 : 0 : DateTime aDateTime;
208 : 0 : bool bValid = (aValue.getLength() == 19) && (aValue[ 4 ] == '-') && (aValue[ 7 ] == '-') &&
209 [ # # ][ # # ]: 0 : (aValue[ 10 ] == 'T') && (aValue[ 13 ] == ':') && (aValue[ 16 ] == ':');
[ # # ][ # #
# # # # ]
210 [ # # ]: 0 : if( bValid )
211 : : {
212 : 0 : aDateTime.Year = static_cast< sal_uInt16 >( aValue.copy( 0, 4 ).toInt32() );
213 : 0 : aDateTime.Month = static_cast< sal_uInt16 >( aValue.copy( 5, 2 ).toInt32() );
214 : 0 : aDateTime.Day = static_cast< sal_uInt16 >( aValue.copy( 8, 2 ).toInt32() );
215 : 0 : aDateTime.Hours = static_cast< sal_uInt16 >( aValue.copy( 11, 2 ).toInt32() );
216 : 0 : aDateTime.Minutes = static_cast< sal_uInt16 >( aValue.copy( 14, 2 ).toInt32() );
217 : 0 : aDateTime.Seconds = static_cast< sal_uInt16 >( aValue.copy( 17, 2 ).toInt32() );
218 : : }
219 : 0 : return OptValue< DateTime >( bValid, aDateTime );
220 : : }
221 : :
222 : : // defaulted return values ----------------------------------------------------
223 : :
224 : 15696 : sal_Int32 AttributeList::getToken( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
225 : : {
226 : 15696 : return mxAttribs->getOptionalValueToken( nAttrToken, nDefault );
227 : : }
228 : :
229 : 8312 : OUString AttributeList::getString( sal_Int32 nAttrToken, const OUString& rDefault ) const
230 : : {
231 : : try
232 : : {
233 [ + - ][ + + ]: 10247 : return mxAttribs->getValue( nAttrToken );
[ - + ]
234 : : }
235 : 1935 : catch( Exception& )
236 : : {
237 : : }
238 : 1935 : return rDefault;
239 : : }
240 : :
241 : 531 : OUString AttributeList::getXString( sal_Int32 nAttrToken, const OUString& rDefault ) const
242 : : {
243 : 531 : return getXString( nAttrToken ).get( rDefault );
244 : : }
245 : :
246 : 1065 : double AttributeList::getDouble( sal_Int32 nAttrToken, double fDefault ) const
247 : : {
248 : 1065 : return getDouble( nAttrToken ).get( fDefault );
249 : : }
250 : :
251 : 9150 : sal_Int32 AttributeList::getInteger( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
252 : : {
253 : 9150 : return getInteger( nAttrToken ).get( nDefault );
254 : : }
255 : :
256 : 3 : sal_uInt32 AttributeList::getUnsigned( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const
257 : : {
258 : 3 : return getUnsigned( nAttrToken ).get( nDefault );
259 : : }
260 : :
261 : 0 : sal_Int64 AttributeList::getHyper( sal_Int32 nAttrToken, sal_Int64 nDefault ) const
262 : : {
263 : 0 : return getHyper( nAttrToken ).get( nDefault );
264 : : }
265 : :
266 : 231 : sal_Int32 AttributeList::getIntegerHex( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
267 : : {
268 : 231 : return getIntegerHex( nAttrToken ).get( nDefault );
269 : : }
270 : :
271 : 8775 : bool AttributeList::getBool( sal_Int32 nAttrToken, bool bDefault ) const
272 : : {
273 : 8775 : return getBool( nAttrToken ).get( bDefault );
274 : : }
275 : :
276 : 0 : DateTime AttributeList::getDateTime( sal_Int32 nAttrToken, const DateTime& rDefault ) const
277 : : {
278 : 0 : return getDateTime( nAttrToken ).get( rDefault );
279 : : }
280 : :
281 : : // ============================================================================
282 : :
283 : : } // namespace oox
284 : :
285 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|