1ca5ec200SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file
5ca5ec200SAndrew Rist * distributed with this work for additional information
6ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the
8ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance
9ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at
10ca5ec200SAndrew Rist *
11ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12ca5ec200SAndrew Rist *
13ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing,
14ca5ec200SAndrew Rist * software distributed under the License is distributed on an
15ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the
17ca5ec200SAndrew Rist * specific language governing permissions and limitations
18ca5ec200SAndrew Rist * under the License.
19ca5ec200SAndrew Rist *
20ca5ec200SAndrew Rist *************************************************************/
21ca5ec200SAndrew Rist
22ca5ec200SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "oox/helper/attributelist.hxx"
25*f42644c3SDamjan Jovanovic #include "oox/helper/datetimehelper.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include <osl/diagnose.h>
28cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
29cdf0e10cSrcweir #include "oox/token/tokenmap.hxx"
30cdf0e10cSrcweir
31cdf0e10cSrcweir namespace oox {
32cdf0e10cSrcweir
33cdf0e10cSrcweir // ============================================================================
34cdf0e10cSrcweir
35cdf0e10cSrcweir using namespace ::com::sun::star::uno;
36cdf0e10cSrcweir using namespace ::com::sun::star::util;
37cdf0e10cSrcweir using namespace ::com::sun::star::xml::sax;
38cdf0e10cSrcweir
39cdf0e10cSrcweir using ::rtl::OUString;
40cdf0e10cSrcweir using ::rtl::OUStringBuffer;
41cdf0e10cSrcweir
42cdf0e10cSrcweir // ============================================================================
43cdf0e10cSrcweir
44cdf0e10cSrcweir namespace {
45cdf0e10cSrcweir
46cdf0e10cSrcweir const sal_Int32 XSTRING_ENCCHAR_LEN = 7;
47cdf0e10cSrcweir
lclAddHexDigit(sal_Unicode & orcChar,sal_Unicode cDigit,int nBitShift)48cdf0e10cSrcweir bool lclAddHexDigit( sal_Unicode& orcChar, sal_Unicode cDigit, int nBitShift )
49cdf0e10cSrcweir {
50cdf0e10cSrcweir if( ('0' <= cDigit) && (cDigit <= '9') ) { orcChar |= ((cDigit - '0') << nBitShift); return true; }
51cdf0e10cSrcweir if( ('a' <= cDigit) && (cDigit <= 'f') ) { orcChar |= ((cDigit - 'a' + 10) << nBitShift); return true; }
52cdf0e10cSrcweir if( ('A' <= cDigit) && (cDigit <= 'F') ) { orcChar |= ((cDigit - 'A' + 10) << nBitShift); return true; }
53cdf0e10cSrcweir return false;
54cdf0e10cSrcweir }
55cdf0e10cSrcweir
lclGetXChar(const sal_Unicode * & rpcStr,const sal_Unicode * pcEnd)56cdf0e10cSrcweir sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd )
57cdf0e10cSrcweir {
58cdf0e10cSrcweir sal_Unicode cChar = 0;
59cdf0e10cSrcweir if( (pcEnd - rpcStr >= XSTRING_ENCCHAR_LEN) &&
60cdf0e10cSrcweir (rpcStr[ 0 ] == '_') &&
61cdf0e10cSrcweir (rpcStr[ 1 ] == 'x') &&
62cdf0e10cSrcweir (rpcStr[ 6 ] == '_') &&
63cdf0e10cSrcweir lclAddHexDigit( cChar, rpcStr[ 2 ], 12 ) &&
64cdf0e10cSrcweir lclAddHexDigit( cChar, rpcStr[ 3 ], 8 ) &&
65cdf0e10cSrcweir lclAddHexDigit( cChar, rpcStr[ 4 ], 4 ) &&
66cdf0e10cSrcweir lclAddHexDigit( cChar, rpcStr[ 5 ], 0 ) )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir rpcStr += XSTRING_ENCCHAR_LEN;
69cdf0e10cSrcweir return cChar;
70cdf0e10cSrcweir }
71cdf0e10cSrcweir return *rpcStr++;
72cdf0e10cSrcweir }
73cdf0e10cSrcweir
74cdf0e10cSrcweir } // namespace
75cdf0e10cSrcweir
76cdf0e10cSrcweir // ----------------------------------------------------------------------------
77cdf0e10cSrcweir
decodeToken(const OUString & rValue)78cdf0e10cSrcweir sal_Int32 AttributeConversion::decodeToken( const OUString& rValue )
79cdf0e10cSrcweir {
80cdf0e10cSrcweir return StaticTokenMap::get().getTokenFromUnicode( rValue );
81cdf0e10cSrcweir }
82cdf0e10cSrcweir
decodeXString(const OUString & rValue)83cdf0e10cSrcweir OUString AttributeConversion::decodeXString( const OUString& rValue )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir // string shorter than one encoded character - no need to decode
86cdf0e10cSrcweir if( rValue.getLength() < XSTRING_ENCCHAR_LEN )
87cdf0e10cSrcweir return rValue;
88cdf0e10cSrcweir OUStringBuffer aBuffer;
89cdf0e10cSrcweir const sal_Unicode* pcStr = rValue.getStr();
90cdf0e10cSrcweir const sal_Unicode* pcEnd = pcStr + rValue.getLength();
91cdf0e10cSrcweir while( pcStr < pcEnd )
92cdf0e10cSrcweir aBuffer.append( lclGetXChar( pcStr, pcEnd ) );
93cdf0e10cSrcweir return aBuffer.makeStringAndClear();
94cdf0e10cSrcweir }
95cdf0e10cSrcweir
decodeDouble(const OUString & rValue)96cdf0e10cSrcweir double AttributeConversion::decodeDouble( const OUString& rValue )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir return rValue.toDouble();
99cdf0e10cSrcweir }
100cdf0e10cSrcweir
decodeInteger(const OUString & rValue)101cdf0e10cSrcweir sal_Int32 AttributeConversion::decodeInteger( const OUString& rValue )
102cdf0e10cSrcweir {
103cdf0e10cSrcweir return rValue.toInt32();
104cdf0e10cSrcweir }
105cdf0e10cSrcweir
decodeUnsigned(const OUString & rValue)106cdf0e10cSrcweir sal_uInt32 AttributeConversion::decodeUnsigned( const OUString& rValue )
107cdf0e10cSrcweir {
108cdf0e10cSrcweir return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64(), 0, SAL_MAX_UINT32 );
109cdf0e10cSrcweir }
110cdf0e10cSrcweir
decodeHyper(const OUString & rValue)111cdf0e10cSrcweir sal_Int64 AttributeConversion::decodeHyper( const OUString& rValue )
112cdf0e10cSrcweir {
113cdf0e10cSrcweir return rValue.toInt64();
114cdf0e10cSrcweir }
115cdf0e10cSrcweir
decodeIntegerHex(const OUString & rValue)116cdf0e10cSrcweir sal_Int32 AttributeConversion::decodeIntegerHex( const OUString& rValue )
117cdf0e10cSrcweir {
118cdf0e10cSrcweir return rValue.toInt32( 16 );
119cdf0e10cSrcweir }
120cdf0e10cSrcweir
decodeUnsignedHex(const OUString & rValue)121cdf0e10cSrcweir sal_uInt32 AttributeConversion::decodeUnsignedHex( const OUString& rValue )
122cdf0e10cSrcweir {
123cdf0e10cSrcweir return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64( 16 ), 0, SAL_MAX_UINT32 );
124cdf0e10cSrcweir }
125cdf0e10cSrcweir
decodeHyperHex(const OUString & rValue)126cdf0e10cSrcweir sal_Int64 AttributeConversion::decodeHyperHex( const OUString& rValue )
127cdf0e10cSrcweir {
128cdf0e10cSrcweir return rValue.toInt64( 16 );
129cdf0e10cSrcweir }
130cdf0e10cSrcweir
131cdf0e10cSrcweir // ============================================================================
132cdf0e10cSrcweir
AttributeList(const Reference<XFastAttributeList> & rxAttribs)133cdf0e10cSrcweir AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) :
134cdf0e10cSrcweir mxAttribs( rxAttribs )
135cdf0e10cSrcweir {
136cdf0e10cSrcweir OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" );
137cdf0e10cSrcweir }
138cdf0e10cSrcweir
hasAttribute(sal_Int32 nAttrToken) const139cdf0e10cSrcweir bool AttributeList::hasAttribute( sal_Int32 nAttrToken ) const
140cdf0e10cSrcweir {
141cdf0e10cSrcweir return mxAttribs->hasAttribute( nAttrToken );
142cdf0e10cSrcweir }
143cdf0e10cSrcweir
144cdf0e10cSrcweir // optional return values -----------------------------------------------------
145cdf0e10cSrcweir
getToken(sal_Int32 nAttrToken) const146cdf0e10cSrcweir OptValue< sal_Int32 > AttributeList::getToken( sal_Int32 nAttrToken ) const
147cdf0e10cSrcweir {
148cdf0e10cSrcweir sal_Int32 nToken = mxAttribs->getOptionalValueToken( nAttrToken, XML_TOKEN_INVALID );
149cdf0e10cSrcweir return OptValue< sal_Int32 >( nToken != XML_TOKEN_INVALID, nToken );
150cdf0e10cSrcweir }
151cdf0e10cSrcweir
getString(sal_Int32 nAttrToken) const152cdf0e10cSrcweir OptValue< OUString > AttributeList::getString( sal_Int32 nAttrToken ) const
153cdf0e10cSrcweir {
154cdf0e10cSrcweir // check if the attribute exists (empty string may be different to missing attribute)
155cdf0e10cSrcweir if( mxAttribs->hasAttribute( nAttrToken ) )
156cdf0e10cSrcweir return OptValue< OUString >( mxAttribs->getOptionalValue( nAttrToken ) );
157cdf0e10cSrcweir return OptValue< OUString >();
158cdf0e10cSrcweir }
159cdf0e10cSrcweir
getXString(sal_Int32 nAttrToken) const160cdf0e10cSrcweir OptValue< OUString > AttributeList::getXString( sal_Int32 nAttrToken ) const
161cdf0e10cSrcweir {
162cdf0e10cSrcweir // check if the attribute exists (empty string may be different to missing attribute)
163cdf0e10cSrcweir if( mxAttribs->hasAttribute( nAttrToken ) )
164cdf0e10cSrcweir return OptValue< OUString >( AttributeConversion::decodeXString( mxAttribs->getOptionalValue( nAttrToken ) ) );
165cdf0e10cSrcweir return OptValue< OUString >();
166cdf0e10cSrcweir }
167cdf0e10cSrcweir
getDouble(sal_Int32 nAttrToken) const168cdf0e10cSrcweir OptValue< double > AttributeList::getDouble( sal_Int32 nAttrToken ) const
169cdf0e10cSrcweir {
170cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
171cdf0e10cSrcweir bool bValid = aValue.getLength() > 0;
172cdf0e10cSrcweir return OptValue< double >( bValid, bValid ? AttributeConversion::decodeDouble( aValue ) : 0.0 );
173cdf0e10cSrcweir }
174cdf0e10cSrcweir
getInteger(sal_Int32 nAttrToken) const175cdf0e10cSrcweir OptValue< sal_Int32 > AttributeList::getInteger( sal_Int32 nAttrToken ) const
176cdf0e10cSrcweir {
177cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
178cdf0e10cSrcweir bool bValid = aValue.getLength() > 0;
179cdf0e10cSrcweir return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeInteger( aValue ) : 0 );
180cdf0e10cSrcweir }
181cdf0e10cSrcweir
getUnsigned(sal_Int32 nAttrToken) const182cdf0e10cSrcweir OptValue< sal_uInt32 > AttributeList::getUnsigned( sal_Int32 nAttrToken ) const
183cdf0e10cSrcweir {
184cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
185cdf0e10cSrcweir bool bValid = aValue.getLength() > 0;
186cdf0e10cSrcweir return OptValue< sal_uInt32 >( bValid, AttributeConversion::decodeUnsigned( aValue ) );
187cdf0e10cSrcweir }
188cdf0e10cSrcweir
getHyper(sal_Int32 nAttrToken) const189cdf0e10cSrcweir OptValue< sal_Int64 > AttributeList::getHyper( sal_Int32 nAttrToken ) const
190cdf0e10cSrcweir {
191cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
192cdf0e10cSrcweir bool bValid = aValue.getLength() > 0;
193cdf0e10cSrcweir return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyper( aValue ) : 0 );
194cdf0e10cSrcweir }
195cdf0e10cSrcweir
getIntegerHex(sal_Int32 nAttrToken) const196cdf0e10cSrcweir OptValue< sal_Int32 > AttributeList::getIntegerHex( sal_Int32 nAttrToken ) const
197cdf0e10cSrcweir {
198cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
199cdf0e10cSrcweir bool bValid = aValue.getLength() > 0;
200cdf0e10cSrcweir return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeIntegerHex( aValue ) : 0 );
201cdf0e10cSrcweir }
202cdf0e10cSrcweir
getUnsignedHex(sal_Int32 nAttrToken) const203cdf0e10cSrcweir OptValue< sal_uInt32 > AttributeList::getUnsignedHex( sal_Int32 nAttrToken ) const
204cdf0e10cSrcweir {
205cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
206cdf0e10cSrcweir bool bValid = aValue.getLength() > 0;
207cdf0e10cSrcweir return OptValue< sal_uInt32 >( bValid, bValid ? AttributeConversion::decodeUnsignedHex( aValue ) : 0 );
208cdf0e10cSrcweir }
209cdf0e10cSrcweir
getHyperHex(sal_Int32 nAttrToken) const210cdf0e10cSrcweir OptValue< sal_Int64 > AttributeList::getHyperHex( sal_Int32 nAttrToken ) const
211cdf0e10cSrcweir {
212cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
213cdf0e10cSrcweir bool bValid = aValue.getLength() > 0;
214cdf0e10cSrcweir return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyperHex( aValue ) : 0 );
215cdf0e10cSrcweir }
216cdf0e10cSrcweir
getBool(sal_Int32 nAttrToken) const217cdf0e10cSrcweir OptValue< bool > AttributeList::getBool( sal_Int32 nAttrToken ) const
218cdf0e10cSrcweir {
219cdf0e10cSrcweir // boolean attributes may be "t", "f", "true", "false", "on", "off", "1", or "0"
220cdf0e10cSrcweir switch( getToken( nAttrToken, XML_TOKEN_INVALID ) )
221cdf0e10cSrcweir {
222cdf0e10cSrcweir case XML_t: return OptValue< bool >( true ); // used in VML
223cdf0e10cSrcweir case XML_true: return OptValue< bool >( true );
224cdf0e10cSrcweir case XML_on: return OptValue< bool >( true );
225cdf0e10cSrcweir case XML_f: return OptValue< bool >( false ); // used in VML
226cdf0e10cSrcweir case XML_false: return OptValue< bool >( false );
227cdf0e10cSrcweir case XML_off: return OptValue< bool >( false );
228cdf0e10cSrcweir }
229cdf0e10cSrcweir OptValue< sal_Int32 > onValue = getInteger( nAttrToken );
230cdf0e10cSrcweir return OptValue< bool >( onValue.has(), onValue.get() != 0 );
231cdf0e10cSrcweir }
232cdf0e10cSrcweir
getDateTime(sal_Int32 nAttrToken) const233cdf0e10cSrcweir OptValue< DateTime > AttributeList::getDateTime( sal_Int32 nAttrToken ) const
234cdf0e10cSrcweir {
235cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
236cdf0e10cSrcweir DateTime aDateTime;
237*f42644c3SDamjan Jovanovic bool bValid = parseISO8601DateTime( aValue, aDateTime );
238cdf0e10cSrcweir return OptValue< DateTime >( bValid, aDateTime );
239cdf0e10cSrcweir }
240cdf0e10cSrcweir
241cdf0e10cSrcweir // defaulted return values ----------------------------------------------------
242cdf0e10cSrcweir
getToken(sal_Int32 nAttrToken,sal_Int32 nDefault) const243cdf0e10cSrcweir sal_Int32 AttributeList::getToken( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
244cdf0e10cSrcweir {
245cdf0e10cSrcweir return mxAttribs->getOptionalValueToken( nAttrToken, nDefault );
246cdf0e10cSrcweir }
247cdf0e10cSrcweir
getString(sal_Int32 nAttrToken,const OUString & rDefault) const248cdf0e10cSrcweir OUString AttributeList::getString( sal_Int32 nAttrToken, const OUString& rDefault ) const
249cdf0e10cSrcweir {
250cdf0e10cSrcweir try
251cdf0e10cSrcweir {
252cdf0e10cSrcweir return mxAttribs->getValue( nAttrToken );
253cdf0e10cSrcweir }
254cdf0e10cSrcweir catch( Exception& )
255cdf0e10cSrcweir {
256cdf0e10cSrcweir }
257cdf0e10cSrcweir return rDefault;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir
getXString(sal_Int32 nAttrToken,const OUString & rDefault) const260cdf0e10cSrcweir OUString AttributeList::getXString( sal_Int32 nAttrToken, const OUString& rDefault ) const
261cdf0e10cSrcweir {
262cdf0e10cSrcweir return getXString( nAttrToken ).get( rDefault );
263cdf0e10cSrcweir }
264cdf0e10cSrcweir
getDouble(sal_Int32 nAttrToken,double fDefault) const265cdf0e10cSrcweir double AttributeList::getDouble( sal_Int32 nAttrToken, double fDefault ) const
266cdf0e10cSrcweir {
267cdf0e10cSrcweir return getDouble( nAttrToken ).get( fDefault );
268cdf0e10cSrcweir }
269cdf0e10cSrcweir
getInteger(sal_Int32 nAttrToken,sal_Int32 nDefault) const270cdf0e10cSrcweir sal_Int32 AttributeList::getInteger( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
271cdf0e10cSrcweir {
272cdf0e10cSrcweir return getInteger( nAttrToken ).get( nDefault );
273cdf0e10cSrcweir }
274cdf0e10cSrcweir
getUnsigned(sal_Int32 nAttrToken,sal_uInt32 nDefault) const275cdf0e10cSrcweir sal_uInt32 AttributeList::getUnsigned( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const
276cdf0e10cSrcweir {
277cdf0e10cSrcweir return getUnsigned( nAttrToken ).get( nDefault );
278cdf0e10cSrcweir }
279cdf0e10cSrcweir
getHyper(sal_Int32 nAttrToken,sal_Int64 nDefault) const280cdf0e10cSrcweir sal_Int64 AttributeList::getHyper( sal_Int32 nAttrToken, sal_Int64 nDefault ) const
281cdf0e10cSrcweir {
282cdf0e10cSrcweir return getHyper( nAttrToken ).get( nDefault );
283cdf0e10cSrcweir }
284cdf0e10cSrcweir
getIntegerHex(sal_Int32 nAttrToken,sal_Int32 nDefault) const285cdf0e10cSrcweir sal_Int32 AttributeList::getIntegerHex( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
286cdf0e10cSrcweir {
287cdf0e10cSrcweir return getIntegerHex( nAttrToken ).get( nDefault );
288cdf0e10cSrcweir }
289cdf0e10cSrcweir
getUnsignedHex(sal_Int32 nAttrToken,sal_uInt32 nDefault) const290cdf0e10cSrcweir sal_uInt32 AttributeList::getUnsignedHex( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const
291cdf0e10cSrcweir {
292cdf0e10cSrcweir return getUnsignedHex( nAttrToken ).get( nDefault );
293cdf0e10cSrcweir }
294cdf0e10cSrcweir
getHyperHex(sal_Int32 nAttrToken,sal_Int64 nDefault) const295cdf0e10cSrcweir sal_Int64 AttributeList::getHyperHex( sal_Int32 nAttrToken, sal_Int64 nDefault ) const
296cdf0e10cSrcweir {
297cdf0e10cSrcweir return getHyperHex( nAttrToken ).get( nDefault );
298cdf0e10cSrcweir }
299cdf0e10cSrcweir
getBool(sal_Int32 nAttrToken,bool bDefault) const300cdf0e10cSrcweir bool AttributeList::getBool( sal_Int32 nAttrToken, bool bDefault ) const
301cdf0e10cSrcweir {
302cdf0e10cSrcweir return getBool( nAttrToken ).get( bDefault );
303cdf0e10cSrcweir }
304cdf0e10cSrcweir
getDateTime(sal_Int32 nAttrToken,const DateTime & rDefault) const305cdf0e10cSrcweir DateTime AttributeList::getDateTime( sal_Int32 nAttrToken, const DateTime& rDefault ) const
306cdf0e10cSrcweir {
307cdf0e10cSrcweir return getDateTime( nAttrToken ).get( rDefault );
308cdf0e10cSrcweir }
309cdf0e10cSrcweir
310cdf0e10cSrcweir // ============================================================================
311cdf0e10cSrcweir
312cdf0e10cSrcweir } // namespace oox
313