LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/xmloff/source/core - xmluconv.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 232 418 55.5 %
Date: 2013-07-09 Functions: 32 39 82.1 %
Legend: Lines: hit not hit

          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             : 
      21             : #include <xmloff/xmluconv.hxx>
      22             : 
      23             : #include <com/sun/star/util/DateTime.hpp>
      24             : #include <com/sun/star/util/Date.hpp>
      25             : #include <tools/debug.hxx>
      26             : #include <rtl/ustrbuf.hxx>
      27             : #include <xmloff/xmlement.hxx>
      28             : #include <xmloff/xmltoken.hxx>
      29             : #include <rtl/math.hxx>
      30             : #include <rtl/logfile.hxx>
      31             : 
      32             : #include <tools/date.hxx>
      33             : #include <tools/time.hxx>
      34             : #include <tools/fldunit.hxx>
      35             : 
      36             : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
      37             : #include <com/sun/star/style/NumberingType.hpp>
      38             : #include <com/sun/star/text/DefaultNumberingProvider.hpp>
      39             : #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
      40             : #include <com/sun/star/text/XNumberingTypeInfo.hpp>
      41             : #include <com/sun/star/i18n/CharacterClassification.hpp>
      42             : #include <com/sun/star/i18n/UnicodeType.hpp>
      43             : #include <basegfx/vector/b3dvector.hxx>
      44             : #include <comphelper/processfactory.hxx>
      45             : 
      46             : #include <sax/tools/converter.hxx>
      47             : 
      48             : 
      49             : using namespace com::sun::star;
      50             : using namespace com::sun::star::uno;
      51             : using namespace com::sun::star::lang;
      52             : using namespace com::sun::star::text;
      53             : using namespace com::sun::star::style;
      54             : using namespace ::com::sun::star::i18n;
      55             : using namespace ::xmloff::token;
      56             : 
      57             : 
      58             : const sal_Int8 XML_MAXDIGITSCOUNT_TIME = 11;
      59             : const sal_Int8 XML_MAXDIGITSCOUNT_DATETIME = 6;
      60             : #define XML_NULLDATE "NullDate"
      61             : 
      62        2116 : struct SvXMLUnitConverter::Impl
      63             : {
      64             :     sal_Int16 m_eCoreMeasureUnit;
      65             :     sal_Int16 m_eXMLMeasureUnit;
      66             :     util::Date m_aNullDate;
      67             :     mutable uno::Reference< text::XNumberingTypeInfo > m_xNumTypeInfo;
      68             :     mutable uno::Reference< i18n::XCharacterClassification > m_xCharClass;
      69             :     uno::Reference< uno::XComponentContext > m_xContext;
      70             : 
      71        2116 :     Impl(uno::Reference<uno::XComponentContext> const& xContext,
      72             :             sal_Int16 const eCoreMeasureUnit,
      73             :             sal_Int16 const eXMLMeasureUnit)
      74             :         : m_eCoreMeasureUnit(eCoreMeasureUnit)
      75             :         , m_eXMLMeasureUnit(eXMLMeasureUnit)
      76             :         , m_aNullDate(30, 12, 1899)
      77        2116 :         , m_xContext(xContext)
      78             :     {
      79             :         OSL_ENSURE( m_xContext.is(), "got no service manager" );
      80        2116 :     }
      81             : 
      82             :     void createNumTypeInfo() const;
      83             : };
      84             : 
      85             : 
      86           0 : void SvXMLUnitConverter::Impl::createNumTypeInfo() const
      87             : {
      88           0 :     Reference<XDefaultNumberingProvider> xDefNum = DefaultNumberingProvider::create(m_xContext);
      89           0 :     m_xNumTypeInfo = Reference<XNumberingTypeInfo>(xDefNum, uno::UNO_QUERY);
      90           0 : }
      91             : 
      92             : const uno::Reference< text::XNumberingTypeInfo >&
      93           0 : SvXMLUnitConverter::getNumTypeInfo() const
      94             : {
      95           0 :     if (!m_pImpl->m_xNumTypeInfo.is())
      96             :     {
      97           0 :         m_pImpl->createNumTypeInfo();
      98             :     }
      99           0 :     return m_pImpl->m_xNumTypeInfo;
     100             : }
     101             : 
     102         183 : void SvXMLUnitConverter::SetCoreMeasureUnit(sal_Int16 const eCoreMeasureUnit)
     103             : {
     104         183 :     m_pImpl->m_eCoreMeasureUnit = eCoreMeasureUnit;
     105         183 : }
     106             : 
     107         183 : void SvXMLUnitConverter::SetXMLMeasureUnit(sal_Int16 const eXMLMeasureUnit)
     108             : {
     109         183 :     m_pImpl->m_eXMLMeasureUnit = eXMLMeasureUnit;
     110         183 : }
     111             : 
     112         130 : sal_Int16 SvXMLUnitConverter::GetXMLMeasureUnit() const
     113             : {
     114         130 :     return m_pImpl->m_eXMLMeasureUnit;
     115             : }
     116             : 
     117             : /** constructs a SvXMLUnitConverter. The core measure unit is the
     118             :     default unit for numerical measures, the XML measure unit is
     119             :     the default unit for textual measures
     120             : */
     121             : 
     122        2116 : SvXMLUnitConverter::SvXMLUnitConverter(
     123             :     const uno::Reference<uno::XComponentContext>& xContext,
     124             :     sal_Int16 const eCoreMeasureUnit,
     125             :     sal_Int16 const eXMLMeasureUnit)
     126        2116 : : m_pImpl(new Impl(xContext, eCoreMeasureUnit, eXMLMeasureUnit))
     127             : {
     128        2116 : }
     129             : 
     130        4232 : SvXMLUnitConverter::~SvXMLUnitConverter()
     131             : {
     132        4232 : }
     133             : 
     134          96 : sal_Int16 SvXMLUnitConverter::GetMeasureUnit(sal_Int16 const nFieldUnit)
     135             : {
     136          96 :     sal_Int16 eUnit = util::MeasureUnit::INCH;
     137          96 :     switch( nFieldUnit )
     138             :     {
     139             :     case FUNIT_MM:
     140           0 :         eUnit = util::MeasureUnit::MM;
     141           0 :         break;
     142             :     case FUNIT_CM:
     143             :     case FUNIT_M:
     144             :     case FUNIT_KM:
     145           0 :         eUnit = util::MeasureUnit::CM;
     146           0 :         break;
     147             :     case FUNIT_TWIP:
     148           0 :         eUnit = util::MeasureUnit::TWIP;
     149           0 :         break;
     150             :     case FUNIT_POINT:
     151             :     case FUNIT_PICA:
     152           0 :         eUnit = util::MeasureUnit::POINT;
     153           0 :         break;
     154             :     case FUNIT_100TH_MM:
     155           0 :         eUnit = util::MeasureUnit::MM_100TH;
     156           0 :         break;
     157             :     }
     158          96 :     return eUnit;
     159             : }
     160             : 
     161             : /** convert string to measure using optional min and max values*/
     162       10740 : bool SvXMLUnitConverter::convertMeasureToCore( sal_Int32& nValue,
     163             :                                          const OUString& rString,
     164             :                                          sal_Int32 nMin, sal_Int32 nMax ) const
     165             : {
     166             :     return ::sax::Converter::convertMeasure( nValue, rString,
     167       10740 :                                                m_pImpl->m_eCoreMeasureUnit,
     168       10740 :                                                nMin, nMax );
     169             : }
     170             : 
     171             : /** convert measure to string */
     172        3339 : void SvXMLUnitConverter::convertMeasureToXML( OUStringBuffer& rString,
     173             :                                          sal_Int32 nMeasure ) const
     174             : {
     175             :     ::sax::Converter::convertMeasure( rString, nMeasure,
     176        3339 :                                         m_pImpl->m_eCoreMeasureUnit,
     177        6678 :                                         m_pImpl->m_eXMLMeasureUnit );
     178        3339 : }
     179             : 
     180             : /** convert string to enum using given enum map, if the enum is
     181             :     not found in the map, this method will return false
     182             : */
     183        1151 : sal_Bool SvXMLUnitConverter::convertEnum( sal_uInt16& rEnum,
     184             :                                       const OUString& rValue,
     185             :                                       const SvXMLEnumStringMapEntry *pMap )
     186             : {
     187       10906 :     while( pMap->pName )
     188             :     {
     189        9755 :         if( rValue.equalsAsciiL( pMap->pName, pMap->nNameLength ) )
     190             :         {
     191        1151 :             rEnum = pMap->nValue;
     192        1151 :             return sal_True;
     193             :         }
     194        8604 :         ++pMap;
     195             :     }
     196             : 
     197           0 :     return sal_False;
     198             : }
     199             : 
     200             : /** convert string to enum using given token map, if the enum is
     201             :     not found in the map, this method will return false */
     202       10868 : sal_Bool SvXMLUnitConverter::convertEnum(
     203             :     sal_uInt16& rEnum,
     204             :     const OUString& rValue,
     205             :     const SvXMLEnumMapEntry *pMap )
     206             : {
     207       59722 :     while( pMap->eToken != XML_TOKEN_INVALID )
     208             :     {
     209       47746 :         if( IsXMLToken( rValue, pMap->eToken ) )
     210             :         {
     211        9760 :             rEnum = pMap->nValue;
     212        9760 :             return sal_True;
     213             :         }
     214       37986 :         ++pMap;
     215             :     }
     216        1108 :     return sal_False;
     217             : }
     218             : 
     219             : /** convert enum to string using given token map with an optional
     220             :     default token. If the enum is not found in the map,
     221             :     this method will either use the given default or return
     222             :     false if no default is set */
     223        4717 : sal_Bool SvXMLUnitConverter::convertEnum(
     224             :     OUStringBuffer& rBuffer,
     225             :     unsigned int nValue,
     226             :     const SvXMLEnumMapEntry *pMap,
     227             :     enum XMLTokenEnum eDefault)
     228             : {
     229        4717 :     enum XMLTokenEnum eTok = eDefault;
     230             : 
     231       13948 :     while( pMap->eToken != XML_TOKEN_INVALID )
     232             :     {
     233        9230 :         if( pMap->nValue == nValue )
     234             :         {
     235        4716 :             eTok = pMap->eToken;
     236        4716 :             break;
     237             :         }
     238        4514 :         ++pMap;
     239             :     }
     240             : 
     241             :     // the map may have contained XML_TOKEN_INVALID
     242        4717 :     if( eTok == XML_TOKEN_INVALID )
     243           0 :         eTok = eDefault;
     244             : 
     245        4717 :     if( eTok != XML_TOKEN_INVALID )
     246        4717 :         rBuffer.append( GetXMLToken(eTok) );
     247             : 
     248        4717 :     return (eTok != XML_TOKEN_INVALID);
     249             : }
     250             : 
     251         336 : static int lcl_gethex( int nChar )
     252             : {
     253         336 :     if( nChar >= '0' && nChar <= '9' )
     254         227 :         return nChar - '0';
     255         109 :     else if( nChar >= 'a' && nChar <= 'f' )
     256         109 :         return nChar - 'a' + 10;
     257           0 :     else if( nChar >= 'A' && nChar <= 'F' )
     258           0 :         return nChar - 'A' + 10;
     259             :     else
     260           0 :         return 0;
     261             : }
     262             : 
     263             : static sal_Char aHexTab[] = "0123456789abcdef";
     264             : 
     265             : 
     266             : /** convert double number to string (using ::rtl::math) */
     267           4 : void SvXMLUnitConverter::convertDouble(OUStringBuffer& rBuffer,
     268             :     double fNumber, sal_Bool bWriteUnits) const
     269             : {
     270             :     ::sax::Converter::convertDouble(rBuffer, fNumber,
     271           4 :         bWriteUnits, m_pImpl->m_eCoreMeasureUnit, m_pImpl->m_eXMLMeasureUnit);
     272           4 : }
     273             : 
     274             : /** convert string to double number (using ::rtl::math) */
     275          31 : sal_Bool SvXMLUnitConverter::convertDouble(double& rValue,
     276             :     const OUString& rString, sal_Bool bLookForUnits) const
     277             : {
     278          31 :     if(bLookForUnits)
     279             :     {
     280             :         sal_Int16 const eSrcUnit = ::sax::Converter::GetUnitFromString(
     281          31 :                 rString, m_pImpl->m_eCoreMeasureUnit);
     282             : 
     283             :         return ::sax::Converter::convertDouble(rValue, rString,
     284          31 :             eSrcUnit, m_pImpl->m_eCoreMeasureUnit);
     285             :     }
     286             :     else
     287             :     {
     288           0 :         return ::sax::Converter::convertDouble(rValue, rString);
     289             :     }
     290             : }
     291             : 
     292             : /** get the Null Date of the XModel and set it to the UnitConverter */
     293           2 : sal_Bool SvXMLUnitConverter::setNullDate(const com::sun::star::uno::Reference <com::sun::star::frame::XModel>& xModel)
     294             : {
     295           2 :     com::sun::star::uno::Reference <com::sun::star::util::XNumberFormatsSupplier> xNumberFormatsSupplier (xModel, com::sun::star::uno::UNO_QUERY);
     296           2 :     if (xNumberFormatsSupplier.is())
     297             :     {
     298           2 :         const com::sun::star::uno::Reference <com::sun::star::beans::XPropertySet> xPropertySet = xNumberFormatsSupplier->getNumberFormatSettings();
     299           2 :         return xPropertySet.is() && (xPropertySet->getPropertyValue(OUString(XML_NULLDATE)) >>= m_pImpl->m_aNullDate);
     300             :     }
     301           0 :     return sal_False;
     302             : }
     303             : 
     304             : /** convert double to ISO Date Time String */
     305           0 : void SvXMLUnitConverter::convertDateTime(OUStringBuffer& rBuffer,
     306             :                      const double& fDateTime, bool const bAddTimeIf0AM)
     307             : {
     308           0 :     convertDateTime(rBuffer, fDateTime, m_pImpl->m_aNullDate, bAddTimeIf0AM);
     309           0 : }
     310             : 
     311             : /** convert ISO Date Time String to double */
     312         124 : bool SvXMLUnitConverter::convertDateTime(double& fDateTime,
     313             :                      const OUString& rString)
     314             : {
     315         124 :     return convertDateTime(fDateTime, rString, m_pImpl->m_aNullDate);
     316             : }
     317             : 
     318             : /** convert double to ISO Date Time String */
     319           0 : void SvXMLUnitConverter::convertDateTime( OUStringBuffer& rBuffer,
     320             :         const double& fDateTime,
     321             :         const com::sun::star::util::Date& aTempNullDate,
     322             :         sal_Bool bAddTimeIf0AM )
     323             : {
     324           0 :     double fValue = fDateTime;
     325           0 :     sal_Int32 nValue = static_cast <sal_Int32> (::rtl::math::approxFloor (fValue));
     326           0 :     Date aDate (aTempNullDate.Day, aTempNullDate.Month, aTempNullDate.Year);
     327           0 :     aDate += nValue;
     328           0 :     fValue -= nValue;
     329             :     double fCount;
     330           0 :     if (nValue > 0)
     331           0 :          fCount = ::rtl::math::approxFloor (log10((double)nValue)) + 1;
     332           0 :     else if (nValue < 0)
     333           0 :          fCount = ::rtl::math::approxFloor (log10((double)(nValue * -1))) + 1;
     334             :     else
     335           0 :         fCount = 0.0;
     336           0 :     sal_Int16 nCount = sal_Int16(fCount);
     337           0 :     sal_Bool bHasTime(sal_False);
     338           0 :     double fHoursValue = 0;
     339           0 :     double fMinsValue = 0;
     340           0 :     double fSecsValue = 0;
     341           0 :     double f100SecsValue = 0;
     342           0 :     if (fValue > 0.0)
     343             :     {
     344           0 :         bHasTime = sal_True;
     345           0 :         fValue *= 24;
     346           0 :         fHoursValue = ::rtl::math::approxFloor (fValue);
     347           0 :         fValue -= fHoursValue;
     348           0 :         fValue *= 60;
     349           0 :         fMinsValue = ::rtl::math::approxFloor (fValue);
     350           0 :         fValue -= fMinsValue;
     351           0 :         fValue *= 60;
     352           0 :         fSecsValue = ::rtl::math::approxFloor (fValue);
     353           0 :         fValue -= fSecsValue;
     354           0 :         if (fValue > 0.0)
     355           0 :             f100SecsValue = ::rtl::math::round( fValue, XML_MAXDIGITSCOUNT_TIME - nCount);
     356             :         else
     357           0 :             f100SecsValue = 0.0;
     358             : 
     359           0 :         if (f100SecsValue == 1.0)
     360             :         {
     361           0 :             f100SecsValue = 0.0;
     362           0 :             fSecsValue += 1.0;
     363             :         }
     364           0 :         if (fSecsValue >= 60.0)
     365             :         {
     366           0 :             fSecsValue -= 60.0;
     367           0 :             fMinsValue += 1.0;
     368             :         }
     369           0 :         if (fMinsValue >= 60.0)
     370             :         {
     371           0 :             fMinsValue -= 60.0;
     372           0 :             fHoursValue += 1.0;
     373             :         }
     374           0 :         if (fHoursValue >= 24.0)
     375             :         {
     376           0 :             fHoursValue -= 24.0;
     377           0 :             aDate += 1;
     378             :         }
     379             :     }
     380           0 :     sal_uInt16 nTemp = aDate.GetYear();
     381           0 :     if (nTemp < 1000)
     382           0 :         rBuffer.append( sal_Unicode('0'));
     383           0 :     if (nTemp < 100)
     384           0 :         rBuffer.append( sal_Unicode('0'));
     385           0 :     if (nTemp < 10)
     386           0 :         rBuffer.append( sal_Unicode('0'));
     387           0 :     rBuffer.append( sal_Int32( nTemp));
     388           0 :     rBuffer.append( sal_Unicode('-'));
     389           0 :     nTemp = aDate.GetMonth();
     390           0 :     if (nTemp < 10)
     391           0 :         rBuffer.append( sal_Unicode('0'));
     392           0 :     rBuffer.append( sal_Int32( nTemp));
     393           0 :     rBuffer.append( sal_Unicode('-'));
     394           0 :     nTemp = aDate.GetDay();
     395           0 :     if (nTemp < 10)
     396           0 :         rBuffer.append( sal_Unicode('0'));
     397           0 :     rBuffer.append( sal_Int32( nTemp));
     398           0 :     if(bHasTime || bAddTimeIf0AM)
     399             :     {
     400           0 :         rBuffer.append( sal_Unicode('T'));
     401           0 :         if (fHoursValue < 10)
     402           0 :             rBuffer.append( sal_Unicode('0'));
     403           0 :         rBuffer.append( sal_Int32( fHoursValue));
     404           0 :         rBuffer.append( sal_Unicode(':'));
     405           0 :         if (fMinsValue < 10)
     406           0 :             rBuffer.append( sal_Unicode('0'));
     407           0 :         rBuffer.append( sal_Int32( fMinsValue));
     408           0 :         rBuffer.append( sal_Unicode(':'));
     409           0 :         if (fSecsValue < 10)
     410           0 :             rBuffer.append( sal_Unicode('0'));
     411           0 :         rBuffer.append( sal_Int32( fSecsValue));
     412           0 :         if (f100SecsValue > 0.0)
     413             :         {
     414             :             OUString a100th( ::rtl::math::doubleToUString( fValue,
     415             :                         rtl_math_StringFormat_F,
     416           0 :                         XML_MAXDIGITSCOUNT_TIME - nCount, '.', sal_True));
     417           0 :             if ( a100th.getLength() > 2 )
     418             :             {
     419           0 :                 rBuffer.append( sal_Unicode('.'));
     420           0 :                 rBuffer.append( a100th.copy( 2 ) );     // strip 0.
     421           0 :             }
     422             :         }
     423             :     }
     424           0 : }
     425             : 
     426             : /** convert ISO Date Time String to double */
     427         124 : sal_Bool SvXMLUnitConverter::convertDateTime( double& fDateTime,
     428             :                             const OUString& rString, const com::sun::star::util::Date& aTempNullDate)
     429             : {
     430         124 :     com::sun::star::util::DateTime aDateTime;
     431         124 :     sal_Bool bSuccess = ::sax::Converter::convertDateTime(aDateTime, rString);
     432             : 
     433         124 :     if (bSuccess)
     434             :     {
     435          94 :         const Date aTmpNullDate(aTempNullDate.Day, aTempNullDate.Month, aTempNullDate.Year);
     436          94 :         const Date aTempDate((sal_uInt16)aDateTime.Day, (sal_uInt16)aDateTime.Month, (sal_uInt16)aDateTime.Year);
     437          94 :         const sal_Int32 nTage = aTempDate - aTmpNullDate;
     438          94 :         double fTempDateTime = nTage;
     439          94 :         double Hour = aDateTime.Hours;
     440          94 :         double Min = aDateTime.Minutes;
     441          94 :         double Sec = aDateTime.Seconds;
     442          94 :         double NanoSec = aDateTime.NanoSeconds;
     443          94 :         fTempDateTime += Hour    / ::Time::hourPerDay;
     444          94 :         fTempDateTime += Min     / ::Time::minutePerDay;
     445          94 :         fTempDateTime += Sec     / ::Time::secondPerDay;
     446          94 :         fTempDateTime += NanoSec / ::Time::nanoSecPerDay;
     447          94 :         fDateTime = fTempDateTime;
     448             :     }
     449         124 :     return bSuccess;
     450             : }
     451             : 
     452             : 
     453         784 : SvXMLTokenEnumerator::SvXMLTokenEnumerator( const OUString& rString, sal_Unicode cSeparator /* = sal_Unicode(' ') */ )
     454         784 : : maTokenString( rString ), mnNextTokenPos(0), mcSeparator( cSeparator )
     455             : {
     456         784 : }
     457             : 
     458        2443 : sal_Bool SvXMLTokenEnumerator::getNextToken( OUString& rToken )
     459             : {
     460        2443 :     if( -1 == mnNextTokenPos )
     461         665 :         return sal_False;
     462             : 
     463        1778 :     int nTokenEndPos = maTokenString.indexOf( mcSeparator, mnNextTokenPos );
     464        1778 :     if( nTokenEndPos != -1 )
     465             :     {
     466        2050 :         rToken = maTokenString.copy( mnNextTokenPos,
     467        1025 :                                      nTokenEndPos - mnNextTokenPos );
     468        1025 :         mnNextTokenPos = nTokenEndPos + 1;
     469             : 
     470             :         // if the mnNextTokenPos is at the end of the string, we have
     471             :         // to deliver an empty token
     472        1025 :         if( mnNextTokenPos > maTokenString.getLength() )
     473           0 :             mnNextTokenPos = -1;
     474             :     }
     475             :     else
     476             :     {
     477         753 :         rToken = maTokenString.copy( mnNextTokenPos );
     478         753 :         mnNextTokenPos = -1;
     479             :     }
     480             : 
     481        1778 :     return sal_True;
     482             : }
     483             : 
     484           1 : static bool lcl_getPositions(const OUString& _sValue,OUString& _rContentX,OUString& _rContentY,OUString& _rContentZ)
     485             : {
     486           1 :     if(_sValue.isEmpty() || _sValue[0] != '(')
     487           0 :         return false;
     488             : 
     489           1 :     sal_Int32 nPos(1L);
     490           1 :     sal_Int32 nFound = _sValue.indexOf(sal_Unicode(' '), nPos);
     491             : 
     492           1 :     if(nFound == -1 || nFound <= nPos)
     493           0 :         return false;
     494             : 
     495           1 :     _rContentX = _sValue.copy(nPos, nFound - nPos);
     496             : 
     497           1 :     nPos = nFound + 1;
     498           1 :     nFound = _sValue.indexOf(sal_Unicode(' '), nPos);
     499             : 
     500           1 :     if(nFound == -1 || nFound <= nPos)
     501           0 :         return false;
     502             : 
     503           1 :     _rContentY = _sValue.copy(nPos, nFound - nPos);
     504             : 
     505           1 :     nPos = nFound + 1;
     506           1 :     nFound = _sValue.indexOf(sal_Unicode(')'), nPos);
     507             : 
     508           1 :     if(nFound == -1 || nFound <= nPos)
     509           0 :         return false;
     510             : 
     511           1 :     _rContentZ = _sValue.copy(nPos, nFound - nPos);
     512           1 :     return true;
     513             : 
     514             : }
     515             : /** convert string to ::basegfx::B3DVector */
     516           0 : sal_Bool SvXMLUnitConverter::convertB3DVector( ::basegfx::B3DVector& rVector, const OUString& rValue )
     517             : {
     518           0 :     OUString aContentX,aContentY,aContentZ;
     519           0 :     if ( !lcl_getPositions(rValue,aContentX,aContentY,aContentZ) )
     520           0 :         return sal_False;
     521             : 
     522             :     rtl_math_ConversionStatus eStatus;
     523             : 
     524             :     rVector.setX(::rtl::math::stringToDouble(aContentX, sal_Unicode('.'),
     525           0 :             sal_Unicode(','), &eStatus, NULL));
     526             : 
     527           0 :     if( eStatus != rtl_math_ConversionStatus_Ok )
     528           0 :         return sal_False;
     529             : 
     530             :     rVector.setY(::rtl::math::stringToDouble(aContentY, sal_Unicode('.'),
     531           0 :             sal_Unicode(','), &eStatus, NULL));
     532             : 
     533           0 :     if( eStatus != rtl_math_ConversionStatus_Ok )
     534           0 :         return sal_False;
     535             : 
     536             :     rVector.setZ(::rtl::math::stringToDouble(aContentZ, sal_Unicode('.'),
     537           0 :             sal_Unicode(','), &eStatus, NULL));
     538             : 
     539             : 
     540           0 :     return ( eStatus == rtl_math_ConversionStatus_Ok );
     541             : }
     542             : 
     543             : /** convert ::basegfx::B3DVector to string */
     544           0 : void SvXMLUnitConverter::convertB3DVector( OUStringBuffer &rBuffer, const ::basegfx::B3DVector& rVector )
     545             : {
     546           0 :     rBuffer.append(sal_Unicode('('));
     547           0 :     ::sax::Converter::convertDouble(rBuffer, rVector.getX());
     548           0 :     rBuffer.append(sal_Unicode(' '));
     549           0 :     ::sax::Converter::convertDouble(rBuffer, rVector.getY());
     550           0 :     rBuffer.append(sal_Unicode(' '));
     551           0 :     ::sax::Converter::convertDouble(rBuffer, rVector.getZ());
     552           0 :     rBuffer.append(sal_Unicode(')'));
     553           0 : }
     554             : 
     555             : /** convert string to Position3D */
     556           1 : sal_Bool SvXMLUnitConverter::convertPosition3D( drawing::Position3D& rPosition,
     557             :     const OUString& rValue )
     558             : {
     559           2 :     OUString aContentX,aContentY,aContentZ;
     560           1 :     if ( !lcl_getPositions(rValue,aContentX,aContentY,aContentZ) )
     561           0 :         return sal_False;
     562             : 
     563           1 :     if ( !convertDouble( rPosition.PositionX, aContentX, sal_True ) )
     564           0 :         return sal_False;
     565           1 :     if ( !convertDouble( rPosition.PositionY, aContentY, sal_True ) )
     566           0 :         return sal_False;
     567           2 :     return convertDouble( rPosition.PositionZ, aContentZ, sal_True );
     568             : }
     569             : 
     570             : /** convert Position3D to string */
     571           0 : void SvXMLUnitConverter::convertPosition3D( OUStringBuffer &rBuffer,
     572             :                                            const drawing::Position3D& rPosition )
     573             : {
     574           0 :     rBuffer.append( sal_Unicode('(') );
     575           0 :     convertDouble( rBuffer, rPosition.PositionX, sal_True );
     576           0 :     rBuffer.append( sal_Unicode(' ') );
     577           0 :     convertDouble( rBuffer, rPosition.PositionY, sal_True );
     578           0 :     rBuffer.append( sal_Unicode(' ') );
     579           0 :     convertDouble( rBuffer, rPosition.PositionZ, sal_True );
     580           0 :     rBuffer.append( sal_Unicode(')') );
     581           0 : }
     582             : 
     583        1023 : sal_Bool SvXMLUnitConverter::convertNumFormat(
     584             :         sal_Int16& rType,
     585             :         const OUString& rNumFmt,
     586             :         const OUString& rNumLetterSync,
     587             :         sal_Bool bNumberNone ) const
     588             : {
     589        1023 :     sal_Bool bRet = sal_True;
     590        1023 :     sal_Bool bExt = sal_False;
     591             : 
     592        1023 :     sal_Int32 nLen = rNumFmt.getLength();
     593        1023 :     if( 0 == nLen )
     594             :     {
     595         519 :         if( bNumberNone )
     596         519 :             rType = NumberingType::NUMBER_NONE;
     597             :         else
     598           0 :             bRet = sal_False;
     599             :     }
     600         504 :     else if( 1 == nLen )
     601             :     {
     602         504 :         switch( rNumFmt[0] )
     603             :         {
     604         344 :         case sal_Unicode('1'):  rType = NumberingType::ARABIC;          break;
     605          55 :         case sal_Unicode('a'):  rType = NumberingType::CHARS_LOWER_LETTER;  break;
     606           3 :         case sal_Unicode('A'):  rType = NumberingType::CHARS_UPPER_LETTER;  break;
     607         101 :         case sal_Unicode('i'):  rType = NumberingType::ROMAN_LOWER; break;
     608           1 :         case sal_Unicode('I'):  rType = NumberingType::ROMAN_UPPER; break;
     609           0 :         default:                bExt = sal_True; break;
     610             :         }
     611         504 :         if( !bExt && IsXMLToken( rNumLetterSync, XML_TRUE ) )
     612             :         {
     613           0 :             switch( rType )
     614             :             {
     615             :             case NumberingType::CHARS_LOWER_LETTER:
     616           0 :                 rType = NumberingType::CHARS_LOWER_LETTER_N;
     617           0 :                 break;
     618             :             case NumberingType::CHARS_UPPER_LETTER:
     619           0 :                 rType = NumberingType::CHARS_UPPER_LETTER_N;
     620           0 :                 break;
     621             :             }
     622             :         }
     623             :     }
     624             :     else
     625             :     {
     626           0 :         bExt = sal_True;
     627             :     }
     628        1023 :     if( bExt )
     629             :     {
     630           0 :         Reference < XNumberingTypeInfo > xInfo = getNumTypeInfo();
     631           0 :         if( xInfo.is() && xInfo->hasNumberingType( rNumFmt ) )
     632             :         {
     633           0 :             rType = xInfo->getNumberingType( rNumFmt );
     634             :         }
     635             :         else
     636             :         {
     637           0 :             rType = NumberingType::ARABIC;
     638           0 :         }
     639             :     }
     640             : 
     641        1023 :     return bRet;
     642             : }
     643             : 
     644         577 : void SvXMLUnitConverter::convertNumFormat( OUStringBuffer& rBuffer,
     645             :                            sal_Int16 nType ) const
     646             : {
     647         577 :     enum XMLTokenEnum eFormat = XML_TOKEN_INVALID;
     648         577 :     switch( nType )
     649             :     {
     650          20 :     case NumberingType::CHARS_UPPER_LETTER:     eFormat = XML_A_UPCASE; break;
     651          96 :     case NumberingType::CHARS_LOWER_LETTER:     eFormat = XML_A; break;
     652           0 :     case NumberingType::ROMAN_UPPER:            eFormat = XML_I_UPCASE; break;
     653         111 :     case NumberingType::ROMAN_LOWER:            eFormat = XML_I; break;
     654         200 :     case NumberingType::ARABIC:                 eFormat = XML_1; break;
     655           0 :     case NumberingType::CHARS_UPPER_LETTER_N:   eFormat = XML_A_UPCASE; break;
     656           0 :     case NumberingType::CHARS_LOWER_LETTER_N:   eFormat = XML_A; break;
     657         150 :     case NumberingType::NUMBER_NONE:            eFormat = XML__EMPTY; break;
     658             : 
     659             :     case NumberingType::CHAR_SPECIAL:
     660             :     case NumberingType::PAGE_DESCRIPTOR:
     661             :     case NumberingType::BITMAP:
     662             :         DBG_ASSERT( eFormat != XML_TOKEN_INVALID, "invalid number format" );
     663           0 :         break;
     664             :     default:
     665           0 :         break;
     666             :     }
     667             : 
     668         577 :     if( eFormat != XML_TOKEN_INVALID )
     669             :     {
     670         577 :         rBuffer.append( GetXMLToken(eFormat) );
     671             :     }
     672             :     else
     673             :     {
     674           0 :         Reference < XNumberingTypeInfo > xInfo = getNumTypeInfo();
     675           0 :         if( xInfo.is() )
     676           0 :             rBuffer.append( xInfo->getNumberingIdentifier( nType ) );
     677             :     }
     678         577 : }
     679             : 
     680         577 : void SvXMLUnitConverter::convertNumLetterSync( OUStringBuffer& rBuffer,
     681             :                                sal_Int16 nType ) const
     682             : {
     683         577 :     enum XMLTokenEnum eSync = XML_TOKEN_INVALID;
     684         577 :     switch( nType )
     685             :     {
     686             :     case NumberingType::CHARS_UPPER_LETTER:
     687             :     case NumberingType::CHARS_LOWER_LETTER:
     688             :     case NumberingType::ROMAN_UPPER:
     689             :     case NumberingType::ROMAN_LOWER:
     690             :     case NumberingType::ARABIC:
     691             :     case NumberingType::NUMBER_NONE:
     692         577 :         break;
     693             : 
     694             :     case NumberingType::CHARS_UPPER_LETTER_N:
     695             :     case NumberingType::CHARS_LOWER_LETTER_N:
     696           0 :         eSync = XML_TRUE;
     697           0 :         break;
     698             : 
     699             :     case NumberingType::CHAR_SPECIAL:
     700             :     case NumberingType::PAGE_DESCRIPTOR:
     701             :     case NumberingType::BITMAP:
     702             :         DBG_ASSERT( eSync != XML_TOKEN_INVALID, "invalid number format" );
     703           0 :         break;
     704             :     }
     705         577 :     if( eSync != XML_TOKEN_INVALID )
     706           0 :         rBuffer.append( GetXMLToken(eSync) );
     707         577 : }
     708             : 
     709          29 : void SvXMLUnitConverter::convertPropertySet(uno::Sequence<beans::PropertyValue>& rProps,
     710             :                     const uno::Reference<beans::XPropertySet>& aProperties)
     711             : {
     712          29 :     uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = aProperties->getPropertySetInfo();
     713          29 :     if (xPropertySetInfo.is())
     714             :     {
     715          29 :         uno::Sequence< beans::Property > aProps = xPropertySetInfo->getProperties();
     716          29 :         const sal_Int32 nCount(aProps.getLength());
     717          29 :         if (nCount)
     718             :         {
     719          29 :             rProps.realloc(nCount);
     720          29 :             beans::PropertyValue* pProps = rProps.getArray();
     721        1643 :             for (sal_Int32 i = 0; i < nCount; i++, ++pProps)
     722             :             {
     723        1614 :                 pProps->Name = aProps[i].Name;
     724        1614 :                 pProps->Value = aProperties->getPropertyValue(aProps[i].Name);
     725             :             }
     726          29 :         }
     727          29 :     }
     728          29 : }
     729             : 
     730          75 : void SvXMLUnitConverter::convertPropertySet(uno::Reference<beans::XPropertySet>& rProperties,
     731             :                     const uno::Sequence<beans::PropertyValue>& aProps)
     732             : {
     733          75 :     sal_Int32 nCount(aProps.getLength());
     734          75 :     if (nCount)
     735             :     {
     736          75 :         uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = rProperties->getPropertySetInfo();
     737          75 :         if (xPropertySetInfo.is())
     738             :         {
     739        2108 :             for (sal_Int32 i = 0; i < nCount; i++)
     740             :             {
     741        2033 :                 if (xPropertySetInfo->hasPropertyByName(aProps[i].Name))
     742        2033 :                     rProperties->setPropertyValue(aProps[i].Name, aProps[i].Value);
     743             :             }
     744          75 :         }
     745             :     }
     746          75 : }
     747             : 
     748             : 
     749        1241 : OUString SvXMLUnitConverter::encodeStyleName(
     750             :         const OUString& rName,
     751             :         sal_Bool *pEncoded ) const
     752             : {
     753        1241 :     if( pEncoded )
     754         473 :         *pEncoded = sal_False;
     755             : 
     756        1241 :     sal_Int32 nLen = rName.getLength();
     757        1241 :     OUStringBuffer aBuffer( nLen );
     758             : 
     759       12464 :     for( sal_Int32 i = 0; i < nLen; i++ )
     760             :     {
     761       11223 :         sal_Unicode c = rName[i];
     762       11223 :         sal_Bool bValidChar = sal_False;
     763       11223 :         if( c < 0x00ffU )
     764             :         {
     765             :             bValidChar =
     766        9891 :                 (c >= 0x0041 && c <= 0x005a) ||
     767        8538 :                 (c >= 0x0061 && c <= 0x007a) ||
     768           0 :                 (c >= 0x00c0 && c <= 0x00d6) ||
     769           0 :                 (c >= 0x00d8 && c <= 0x00f6) ||
     770       21455 :                 (c >= 0x00f8 && c <= 0x00ff) ||
     771        1042 :                 ( i > 0 && ( (c >= 0x0030 && c <= 0x0039) ||
     772       11384 :                              c == 0x00b7 || c == '-' || c == '.') );
     773             :         }
     774             :         else
     775             :         {
     776         300 :             if( (c >= 0xf900U && c <= 0xfffeU) ||
     777           0 :                  (c >= 0x20ddU && c <= 0x20e0U))
     778             :             {
     779           0 :                 bValidChar = sal_False;
     780             :             }
     781         300 :             else if( (c >= 0x02bbU && c <= 0x02c1U) || c == 0x0559 ||
     782         300 :                      c == 0x06e5 || c == 0x06e6 )
     783             :             {
     784           0 :                 bValidChar = sal_True;
     785             :             }
     786         300 :             else if( c == 0x0387 )
     787             :             {
     788           0 :                 bValidChar = i > 0;
     789             :             }
     790             :             else
     791             :             {
     792         300 :                 if (!m_pImpl->m_xCharClass.is())
     793             :                 {
     794           2 :                     this->m_pImpl->m_xCharClass = CharacterClassification::create( m_pImpl->m_xContext );
     795             :                 }
     796         300 :                 sal_Int16 nType = m_pImpl->m_xCharClass->getType(rName, i);
     797             : 
     798         300 :                 switch( nType )
     799             :                 {
     800             :                 case UnicodeType::UPPERCASE_LETTER:     // Lu
     801             :                 case UnicodeType::LOWERCASE_LETTER:     // Ll
     802             :                 case UnicodeType::TITLECASE_LETTER:     // Lt
     803             :                 case UnicodeType::OTHER_LETTER:         // Lo
     804             :                 case UnicodeType::LETTER_NUMBER:        // Nl
     805         300 :                     bValidChar = sal_True;
     806         300 :                     break;
     807             :                 case UnicodeType::NON_SPACING_MARK:     // Ms
     808             :                 case UnicodeType::ENCLOSING_MARK:       // Me
     809             :                 case UnicodeType::COMBINING_SPACING_MARK:   //Mc
     810             :                 case UnicodeType::MODIFIER_LETTER:      // Lm
     811             :                 case UnicodeType::DECIMAL_DIGIT_NUMBER: // Nd
     812           0 :                     bValidChar = i > 0;
     813           0 :                     break;
     814             :                 }
     815             :             }
     816             :         }
     817       11223 :         if( bValidChar )
     818             :         {
     819       10832 :             aBuffer.append( c );
     820             :         }
     821             :         else
     822             :         {
     823         391 :             aBuffer.append( static_cast< sal_Unicode >( '_' ) );
     824         391 :             if( c > 0x0fff )
     825             :                 aBuffer.append( static_cast< sal_Unicode >(
     826           0 :                             aHexTab[ (c >> 12) & 0x0f ]  ) );
     827         391 :             if( c > 0x00ff )
     828             :                 aBuffer.append( static_cast< sal_Unicode >(
     829           0 :                         aHexTab[ (c >> 8) & 0x0f ] ) );
     830         391 :             if( c > 0x000f )
     831             :                 aBuffer.append( static_cast< sal_Unicode >(
     832         391 :                         aHexTab[ (c >> 4) & 0x0f ] ) );
     833             :             aBuffer.append( static_cast< sal_Unicode >(
     834         391 :                         aHexTab[ c & 0x0f ] ) );
     835         391 :             aBuffer.append( static_cast< sal_Unicode >( '_' ) );
     836         391 :             if( pEncoded )
     837         155 :                 *pEncoded = sal_True;
     838             :         }
     839             :     }
     840             : 
     841             :     // check for length
     842        1241 :     if( aBuffer.getLength() > ((1<<15)-1) )
     843             :     {
     844           0 :         aBuffer = rName;
     845           0 :         if( pEncoded )
     846           0 :             *pEncoded = sal_False;
     847             :     }
     848             : 
     849             : 
     850        1241 :     return aBuffer.makeStringAndClear();
     851             : }
     852             : 
     853             : /** convert string (hex) to number (sal_uInt32) */
     854          42 : sal_Bool SvXMLUnitConverter::convertHex( sal_uInt32& nVal,
     855             :                                        const OUString& rValue )
     856             : {
     857          42 :     if( rValue.getLength() != 8 )
     858           0 :         return sal_False;
     859             : 
     860          42 :     nVal = 0;
     861         378 :     for ( int i = 0; i < 8; i++ )
     862             :     {
     863         336 :         nVal = ( nVal << 4 )
     864         336 :             | sal::static_int_cast< sal_uInt32 >( lcl_gethex( rValue[i] ) );
     865             :     }
     866             : 
     867          42 :     return sal_True;
     868             : }
     869             : 
     870             : /** convert number (sal_uInt32) to string (hex) */
     871           2 : void SvXMLUnitConverter::convertHex( OUStringBuffer& rBuffer,
     872             :                                         sal_uInt32 nVal )
     873             : {
     874          18 :     for ( int i = 0; i < 8; i++ )
     875             :     {
     876          16 :         rBuffer.append( sal_Unicode( aHexTab[ nVal >> 28 ] ) );
     877          16 :         nVal <<= 4;
     878             :     }
     879           2 : }
     880             : 
     881             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10