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

Generated by: LCOV version 1.10