LCOV - code coverage report
Current view: top level - sax/source/tools - converter.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 907 1130 80.3 %
Date: 2012-08-25 Functions: 38 42 90.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 631 906 69.6 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include <sax/tools/converter.hxx>
      21                 :            : 
      22                 :            : #include <com/sun/star/i18n/UnicodeType.hpp>
      23                 :            : #include <com/sun/star/util/DateTime.hpp>
      24                 :            : #include <com/sun/star/util/Date.hpp>
      25                 :            : #include <com/sun/star/util/Duration.hpp>
      26                 :            : #include <com/sun/star/util/Time.hpp>
      27                 :            : #include <com/sun/star/uno/Sequence.hxx>
      28                 :            : 
      29                 :            : #include <rtl/ustrbuf.hxx>
      30                 :            : #include <rtl/math.hxx>
      31                 :            : 
      32                 :            : using namespace com::sun::star;
      33                 :            : using namespace com::sun::star::uno;
      34                 :            : using namespace com::sun::star::util;
      35                 :            : using namespace ::com::sun::star::i18n;
      36                 :            : 
      37                 :            : using ::rtl::OUString;
      38                 :            : using ::rtl::OUStringBuffer;
      39                 :            : 
      40                 :            : namespace sax {
      41                 :            : 
      42                 :            : static const sal_Char* gpsMM = "mm";
      43                 :            : static const sal_Char* gpsCM = "cm";
      44                 :            : static const sal_Char* gpsPT = "pt";
      45                 :            : static const sal_Char* gpsINCH = "in";
      46                 :            : static const sal_Char* gpsPC = "pc";
      47                 :            : 
      48                 :            : const sal_Int8 XML_MAXDIGITSCOUNT_TIME = 11;
      49                 :            : const sal_Int8 XML_MAXDIGITSCOUNT_DATETIME = 6;
      50                 :            : #define XML_NULLDATE "NullDate"
      51                 :            : 
      52                 :            : /** convert string to measure using optional min and max values*/
      53                 :      19399 : bool Converter::convertMeasure( sal_Int32& rValue,
      54                 :            :                                 const OUString& rString,
      55                 :            :                                 sal_Int16 nTargetUnit /* = MeasureUnit::MM_100TH */,
      56                 :            :                                 sal_Int32 nMin /* = SAL_MIN_INT32 */,
      57                 :            :                                 sal_Int32 nMax /* = SAL_MAX_INT32 */ )
      58                 :            : {
      59                 :      19399 :     bool bNeg = false;
      60                 :      19399 :     double nVal = 0;
      61                 :            : 
      62                 :      19399 :     sal_Int32 nPos = 0;
      63                 :      19399 :     sal_Int32 const nLen = rString.getLength();
      64                 :            : 
      65                 :            :     // skip white space
      66 [ +  + ][ +  + ]:      19420 :     while( (nPos < nLen) && (rString[nPos] <= sal_Unicode(' ')) )
                 [ +  + ]
      67                 :         21 :         nPos++;
      68                 :            : 
      69 [ +  + ][ +  + ]:      19399 :     if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
                 [ +  + ]
      70                 :            :     {
      71                 :        963 :         bNeg = true;
      72                 :        963 :         nPos++;
      73                 :            :     }
      74                 :            : 
      75                 :            :     // get number
      76   [ +  +  +  +  :     115248 :     while( nPos < nLen &&
           +  + ][ +  + ]
      77                 :      43635 :            sal_Unicode('0') <= rString[nPos] &&
      78                 :      27753 :            sal_Unicode('9') >= rString[nPos] )
      79                 :            :     {
      80                 :            :         // TODO: check overflow!
      81                 :      24461 :         nVal *= 10;
      82                 :      24461 :         nVal += (rString[nPos] - sal_Unicode('0'));
      83                 :      24461 :         nPos++;
      84                 :            :     }
      85                 :      19399 :     double nDiv = 1.;
      86 [ +  + ][ +  + ]:      19399 :     if( nPos < nLen && sal_Unicode('.') == rString[nPos] )
                 [ +  + ]
      87                 :            :     {
      88                 :      13183 :         nPos++;
      89                 :            : 
      90   [ +  -  +  -  :     141447 :         while( nPos < nLen &&
           +  + ][ +  + ]
      91                 :      47149 :                sal_Unicode('0') <= rString[nPos] &&
      92                 :      47149 :                sal_Unicode('9') >= rString[nPos] )
      93                 :            :         {
      94                 :            :             // TODO: check overflow!
      95                 :      33966 :             nDiv *= 10;
      96                 :      33966 :             nVal += ( ((double)(rString[nPos] - sal_Unicode('0'))) / nDiv );
      97                 :      33966 :             nPos++;
      98                 :            :         }
      99                 :            :     }
     100                 :            : 
     101                 :            :     // skip white space
     102 [ +  + ][ -  + ]:      19399 :     while( (nPos < nLen) && (rString[nPos] <= sal_Unicode(' ')) )
                 [ -  + ]
     103                 :          0 :         nPos++;
     104                 :            : 
     105         [ +  + ]:      19399 :     if( nPos < nLen )
     106                 :            :     {
     107                 :            : 
     108         [ +  + ]:      19174 :         if( MeasureUnit::PERCENT == nTargetUnit )
     109                 :            :         {
     110         [ +  + ]:       3876 :             if( sal_Unicode('%') != rString[nPos] )
     111                 :       1239 :                 return false;
     112                 :            :         }
     113         [ +  + ]:      15298 :         else if( MeasureUnit::PIXEL == nTargetUnit )
     114                 :            :         {
     115   [ +  -  -  +  :         18 :             if( nPos + 1 >= nLen ||
          #  #  -  +  #  
              # ][ -  + ]
     116                 :          6 :                 (sal_Unicode('p') != rString[nPos] &&
     117                 :          0 :                  sal_Unicode('P') != rString[nPos])||
     118                 :          6 :                 (sal_Unicode('x') != rString[nPos+1] &&
     119                 :          0 :                  sal_Unicode('X') != rString[nPos+1]) )
     120                 :          0 :                 return false;
     121                 :            :         }
     122                 :            :         else
     123                 :            :         {
     124                 :            :             OSL_ENSURE( MeasureUnit::TWIP == nTargetUnit || MeasureUnit::POINT == nTargetUnit ||
     125                 :            :                         MeasureUnit::MM_100TH == nTargetUnit || MeasureUnit::MM_10TH == nTargetUnit, "unit is not supported");
     126                 :      15292 :             const sal_Char *aCmpsL[2] = { 0, 0 };
     127                 :      15292 :             const sal_Char *aCmpsU[2] = { 0, 0 };
     128                 :      15292 :             double aScales[2] = { 1., 1. };
     129                 :            : 
     130         [ +  + ]:      15292 :             if( MeasureUnit::TWIP == nTargetUnit )
     131                 :            :             {
     132   [ +  -  -  -  :        207 :                 switch( rString[nPos] )
                      - ]
     133                 :            :                 {
     134                 :            :                 case sal_Unicode('c'):
     135                 :            :                 case sal_Unicode('C'):
     136                 :        207 :                     aCmpsL[0] = "cm";
     137                 :        207 :                     aCmpsU[0] = "CM";
     138                 :        207 :                     aScales[0] = (72.*20.)/2.54; // twip
     139                 :        207 :                     break;
     140                 :            :                 case sal_Unicode('i'):
     141                 :            :                 case sal_Unicode('I'):
     142                 :          0 :                     aCmpsL[0] = "in";
     143                 :          0 :                     aCmpsU[0] = "IN";
     144                 :          0 :                     aScales[0] = 72.*20.; // twip
     145                 :          0 :                     break;
     146                 :            :                 case sal_Unicode('m'):
     147                 :            :                 case sal_Unicode('M'):
     148                 :          0 :                     aCmpsL[0] = "mm";
     149                 :          0 :                     aCmpsU[0] = "MM";
     150                 :          0 :                     aScales[0] = (72.*20.)/25.4; // twip
     151                 :          0 :                     break;
     152                 :            :                 case sal_Unicode('p'):
     153                 :            :                 case sal_Unicode('P'):
     154                 :          0 :                     aCmpsL[0] = "pt";
     155                 :          0 :                     aCmpsU[0] = "PT";
     156                 :          0 :                     aScales[0] = 20.; // twip
     157                 :            : 
     158                 :          0 :                     aCmpsL[1] = "pc";
     159                 :          0 :                     aCmpsU[1] = "PC";
     160                 :          0 :                     aScales[1] = 12.*20.; // twip
     161                 :        207 :                     break;
     162                 :            :                 }
     163                 :            :             }
     164 [ +  + ][ +  - ]:      15085 :             else if( MeasureUnit::MM_100TH == nTargetUnit || MeasureUnit::MM_10TH == nTargetUnit )
     165                 :            :             {
     166         [ +  + ]:      15085 :                 double nScaleFactor = (MeasureUnit::MM_100TH == nTargetUnit) ? 100.0 : 10.0;
     167   [ +  +  +  +  :      15085 :                 switch( rString[nPos] )
                      + ]
     168                 :            :                 {
     169                 :            :                 case sal_Unicode('c'):
     170                 :            :                 case sal_Unicode('C'):
     171                 :       7532 :                     aCmpsL[0] = "cm";
     172                 :       7532 :                     aCmpsU[0] = "CM";
     173                 :       7532 :                     aScales[0] = 10.0 * nScaleFactor; // mm/100
     174                 :       7532 :                     break;
     175                 :            :                 case sal_Unicode('i'):
     176                 :            :                 case sal_Unicode('I'):
     177                 :       6943 :                     aCmpsL[0] = "in";
     178                 :       6943 :                     aCmpsU[0] = "IN";
     179                 :       6943 :                     aScales[0] = 1000.*2.54; // mm/100
     180                 :       6943 :                     break;
     181                 :            :                 case sal_Unicode('m'):
     182                 :            :                 case sal_Unicode('M'):
     183                 :          9 :                     aCmpsL[0] = "mm";
     184                 :          9 :                     aCmpsU[0] = "MM";
     185                 :          9 :                     aScales[0] = 1.0 * nScaleFactor; // mm/100
     186                 :          9 :                     break;
     187                 :            :                 case sal_Unicode('p'):
     188                 :            :                 case sal_Unicode('P'):
     189                 :        539 :                     aCmpsL[0] = "pt";
     190                 :        539 :                     aCmpsU[0] = "PT";
     191                 :        539 :                     aScales[0] = (10.0 * nScaleFactor*2.54)/72.; // mm/100
     192                 :            : 
     193                 :        539 :                     aCmpsL[1] = "pc";
     194                 :        539 :                     aCmpsU[1] = "PC";
     195                 :        539 :                     aScales[1] = (10.0 * nScaleFactor*2.54)/12.; // mm/100
     196                 :        539 :                     break;
     197                 :      15085 :                 }
     198                 :            :             }
     199         [ #  # ]:          0 :             else if( MeasureUnit::POINT == nTargetUnit )
     200                 :            :             {
     201 [ #  # ][ #  # ]:          0 :                 if( rString[nPos] == 'p' || rString[nPos] == 'P' )
                 [ #  # ]
     202                 :            :                 {
     203                 :          0 :                     aCmpsL[0] = "pt";
     204                 :          0 :                     aCmpsU[0] = "PT";
     205                 :          0 :                     aScales[0] = 1;
     206                 :            :                 }
     207                 :            :             }
     208                 :            : 
     209         [ +  + ]:      15292 :             if( aCmpsL[0] == NULL )
     210                 :         62 :                 return false;
     211                 :            : 
     212                 :      15230 :             double nScale = 0.;
     213         [ +  - ]:      15230 :             for( sal_uInt16 i= 0; i < 2; i++ )
     214                 :            :             {
     215                 :      15230 :                 const sal_Char *pL = aCmpsL[i];
     216         [ +  - ]:      15230 :                 if( pL )
     217                 :            :                 {
     218                 :      15230 :                     const sal_Char *pU = aCmpsU[i];
     219 [ +  + ][ +  - ]:      45690 :                     while( nPos < nLen && *pL )
                 [ +  + ]
     220                 :            :                     {
     221                 :      30460 :                         sal_Unicode c = rString[nPos];
     222 [ #  # ][ -  + ]:      30460 :                         if( c != *pL && c != *pU )
     223                 :          0 :                             break;
     224                 :      30460 :                         pL++;
     225                 :      30460 :                         pU++;
     226                 :      30460 :                         nPos++;
     227                 :            :                     }
     228 [ +  - ][ -  + ]:      15230 :                     if( !*pL && (nPos == nLen || ' ' == rString[nPos]) )
         [ #  # ][ +  - ]
     229                 :            :                     {
     230                 :      15230 :                         nScale = aScales[i];
     231                 :      15230 :                         break;
     232                 :            :                     }
     233                 :            :                 }
     234                 :            :             }
     235                 :            : 
     236         [ -  + ]:      15230 :             if( 0. == nScale )
     237                 :          0 :                 return false;
     238                 :            : 
     239                 :            :             // TODO: check overflow
     240         [ +  - ]:      15230 :             if( nScale != 1. )
     241                 :      15292 :                 nVal *= nScale;
     242                 :            :         }
     243                 :            :     }
     244                 :            : 
     245                 :      18098 :     nVal += .5;
     246         [ +  + ]:      18098 :     if( bNeg )
     247                 :        941 :         nVal = -nVal;
     248                 :            : 
     249         [ +  + ]:      18098 :     if( nVal <= (double)nMin )
     250                 :          6 :         rValue = nMin;
     251         [ +  + ]:      18092 :     else if( nVal >= (double)nMax )
     252                 :          6 :         rValue = nMax;
     253                 :            :     else
     254                 :      18086 :         rValue = (sal_Int32)nVal;
     255                 :            : 
     256                 :      19399 :     return true;
     257                 :            : }
     258                 :            : 
     259                 :            : /** convert measure in given unit to string with given unit */
     260                 :       3576 : void Converter::convertMeasure( OUStringBuffer& rBuffer,
     261                 :            :                                 sal_Int32 nMeasure,
     262                 :            :                                 sal_Int16 nSourceUnit /* = MeasureUnit::MM_100TH */,
     263                 :            :                                 sal_Int16 nTargetUnit /* = MeasureUnit::INCH */  )
     264                 :            : {
     265         [ +  + ]:       3576 :     if( nSourceUnit == MeasureUnit::PERCENT )
     266                 :            :     {
     267                 :            :         OSL_ENSURE( nTargetUnit == MeasureUnit::PERCENT,
     268                 :            :                     "MeasureUnit::PERCENT only maps to MeasureUnit::PERCENT!" );
     269                 :            : 
     270                 :          3 :         rBuffer.append( nMeasure );
     271                 :          3 :         rBuffer.append( sal_Unicode('%' ) );
     272                 :            : 
     273                 :       3576 :         return;
     274                 :            :     }
     275                 :            :     // the sign is processed seperatly
     276         [ +  + ]:       3573 :     if( nMeasure < 0 )
     277                 :            :     {
     278                 :        245 :         nMeasure = -nMeasure;
     279                 :        245 :         rBuffer.append( sal_Unicode('-') );
     280                 :            :     }
     281                 :            : 
     282                 :            :     // The new length is (nVal * nMul)/(nDiv*nFac*10)
     283                 :       3573 :     long nMul = 1000;
     284                 :       3573 :     long nDiv = 1;
     285                 :       3573 :     long nFac = 100;
     286                 :       3573 :     const sal_Char* psUnit = 0;
     287   [ +  -  +  - ]:       3573 :     switch( nSourceUnit )
     288                 :            :     {
     289                 :            :     case MeasureUnit::TWIP:
     290   [ +  +  +  + ]:         12 :         switch( nTargetUnit )
     291                 :            :         {
     292                 :            :         case MeasureUnit::MM_100TH:
     293                 :            :         case MeasureUnit::MM_10TH:
     294                 :            :             OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,"output unit not supported for twip values" );
     295                 :            :         case MeasureUnit::MM:
     296                 :            :             // 0.01mm = 0.57twip (exactly)
     297                 :          3 :             nMul = 25400;   // 25.4 * 1000
     298                 :          3 :             nDiv = 1440;    // 72 * 20;
     299                 :          3 :             nFac = 100;
     300                 :          3 :             psUnit = gpsMM;
     301                 :          3 :             break;
     302                 :            : 
     303                 :            :         case MeasureUnit::CM:
     304                 :            :             // 0.001cm = 0.57twip (exactly)
     305                 :          3 :             nMul = 25400;   // 2.54 * 10000
     306                 :          3 :             nDiv = 1440;    // 72 * 20;
     307                 :          3 :             nFac = 1000;
     308                 :          3 :             psUnit = gpsCM;
     309                 :          3 :             break;
     310                 :            : 
     311                 :            :         case MeasureUnit::POINT:
     312                 :            :             // 0.01pt = 0.2twip (exactly)
     313                 :          3 :             nMul = 1000;
     314                 :          3 :             nDiv = 20;
     315                 :          3 :             nFac = 100;
     316                 :          3 :             psUnit = gpsPT;
     317                 :          3 :             break;
     318                 :            : 
     319                 :            :         case MeasureUnit::INCH:
     320                 :            :         default:
     321                 :            :             OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,
     322                 :            :                         "output unit not supported for twip values" );
     323                 :            :             // 0.0001in = 0.144twip (exactly)
     324                 :          3 :             nMul = 100000;
     325                 :          3 :             nDiv = 1440;    // 72 * 20;
     326                 :          3 :             nFac = 10000;
     327                 :          3 :             psUnit = gpsINCH;
     328                 :          3 :             break;
     329                 :            :         }
     330                 :         12 :         break;
     331                 :            : 
     332                 :            :     case MeasureUnit::POINT:
     333                 :            :         // 1pt = 1pt (exactly)
     334                 :            :         OSL_ENSURE( MeasureUnit::POINT == nTargetUnit,
     335                 :            :                     "output unit not supported for pt values" );
     336                 :          0 :         nMul = 10;
     337                 :          0 :         nDiv = 1;
     338                 :          0 :         nFac = 1;
     339                 :          0 :         psUnit = gpsPT;
     340                 :          0 :         break;
     341                 :            :     case MeasureUnit::MM_10TH:
     342                 :            :     case MeasureUnit::MM_100TH:
     343                 :            :         {
     344         [ +  + ]:       3561 :             long nFac2 = (MeasureUnit::MM_100TH == nSourceUnit) ? 100 : 10;
     345   [ +  +  +  + ]:       3561 :             switch( nTargetUnit )
     346                 :            :             {
     347                 :            :             case MeasureUnit::MM_100TH:
     348                 :            :             case MeasureUnit::MM_10TH:
     349                 :            :                 OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,
     350                 :            :                             "output unit not supported for 1/100mm values" );
     351                 :            :             case MeasureUnit::MM:
     352                 :            :                 // 0.01mm = 1 mm/100 (exactly)
     353                 :          6 :                 nMul = 10;
     354                 :          6 :                 nDiv = 1;
     355                 :          6 :                 nFac = nFac2;
     356                 :          6 :                 psUnit = gpsMM;
     357                 :          6 :                 break;
     358                 :            : 
     359                 :            :             case MeasureUnit::CM:
     360                 :            :                 // 0.001mm = 1 mm/100 (exactly)
     361                 :       2248 :                 nMul = 10;
     362                 :       2248 :                 nDiv = 1;   // 72 * 20;
     363                 :       2248 :                 nFac = 10*nFac2;
     364                 :       2248 :                 psUnit = gpsCM;
     365                 :       2248 :                 break;
     366                 :            : 
     367                 :            :             case MeasureUnit::POINT:
     368                 :            :                 // 0.01pt = 0.35 mm/100 (exactly)
     369                 :         11 :                 nMul = 72000;
     370                 :         11 :                 nDiv = 2540;
     371                 :         11 :                 nFac = nFac2;
     372                 :         11 :                 psUnit = gpsPT;
     373                 :         11 :                 break;
     374                 :            : 
     375                 :            :             case MeasureUnit::INCH:
     376                 :            :             default:
     377                 :            :                 OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,
     378                 :            :                             "output unit not supported for 1/100mm values" );
     379                 :            :                 // 0.0001in = 0.254 mm/100 (exactly)
     380                 :       1296 :                 nMul = 100000;
     381                 :       1296 :                 nDiv = 2540;
     382                 :       1296 :                 nFac = 100*nFac2;
     383                 :       1296 :                 psUnit = gpsINCH;
     384                 :       1296 :                 break;
     385                 :            :             }
     386                 :       3561 :             break;
     387                 :            :         }
     388                 :            :     default:
     389                 :            :         OSL_ENSURE(false, "sax::Converter::convertMeasure(): "
     390                 :            :                 "source unit not supported");
     391                 :          0 :         break;
     392                 :            :     }
     393                 :            : 
     394                 :       3573 :     sal_Int64 nValue = nMeasure;
     395                 :            :     OSL_ENSURE(nValue <= SAL_MAX_INT64 / nMul, "convertMeasure: overflow");
     396                 :       3573 :     nValue *= nMul;
     397                 :       3573 :     nValue /= nDiv;
     398                 :       3573 :     nValue += 5;
     399                 :       3573 :     nValue /= 10;
     400                 :            : 
     401                 :       3573 :     rBuffer.append( static_cast<sal_Int64>(nValue / nFac) );
     402 [ +  + ][ +  - ]:       3573 :     if (nFac > 1 && (nValue % nFac) != 0)
     403                 :            :     {
     404                 :       2948 :         rBuffer.append( sal_Unicode('.') );
     405 [ +  + ][ +  + ]:       9253 :         while (nFac > 1 && (nValue % nFac) != 0)
                 [ +  + ]
     406                 :            :         {
     407                 :       6305 :             nFac /= 10;
     408                 :       6305 :             rBuffer.append( static_cast<sal_Int32>((nValue / nFac) % 10) );
     409                 :            :         }
     410                 :            :     }
     411                 :            : 
     412         [ +  - ]:       3573 :     if( psUnit )
     413                 :       3573 :         rBuffer.appendAscii( psUnit );
     414                 :            : }
     415                 :            : 
     416                 :       5795 : static const OUString& getTrueString()
     417                 :            : {
     418 [ +  + ][ +  - ]:       5795 :     static const OUString sTrue( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
         [ +  - ][ #  # ]
     419                 :       5795 :     return sTrue;
     420                 :            : }
     421                 :            : 
     422                 :       7576 : static const OUString& getFalseString()
     423                 :            : {
     424 [ +  + ][ +  - ]:       7576 :     static const OUString sFalse( RTL_CONSTASCII_USTRINGPARAM( "false" ) );
         [ +  - ][ #  # ]
     425                 :       7576 :     return sFalse;
     426                 :            : }
     427                 :            : 
     428                 :            : /** convert string to boolean */
     429                 :       3015 : bool Converter::convertBool( bool& rBool, const OUString& rString )
     430                 :            : {
     431                 :       3015 :     rBool = rString == getTrueString();
     432                 :            : 
     433 [ +  - ][ +  + ]:       3015 :     return rBool || (rString == getFalseString());
     434                 :            : }
     435                 :            : 
     436                 :            : /** convert boolean to string */
     437                 :       8888 : void Converter::convertBool( OUStringBuffer& rBuffer, bool bValue )
     438                 :            : {
     439         [ +  + ]:       8888 :     rBuffer.append( bValue ? getTrueString() : getFalseString() );
     440                 :       8888 : }
     441                 :            : 
     442                 :            : /** convert string to percent */
     443                 :       3948 : bool Converter::convertPercent( sal_Int32& rPercent, const OUString& rString )
     444                 :            : {
     445                 :       3948 :     return convertMeasure( rPercent, rString, MeasureUnit::PERCENT );
     446                 :            : }
     447                 :            : 
     448                 :            : /** convert percent to string */
     449                 :        426 : void Converter::convertPercent( OUStringBuffer& rBuffer, sal_Int32 nValue )
     450                 :            : {
     451                 :        426 :     rBuffer.append( nValue );
     452                 :        426 :     rBuffer.append( sal_Unicode('%' ) );
     453                 :        426 : }
     454                 :            : 
     455                 :            : /** convert string to pixel measure */
     456                 :          0 : bool Converter::convertMeasurePx( sal_Int32& rPixel, const OUString& rString )
     457                 :            : {
     458                 :          0 :     return convertMeasure( rPixel, rString, MeasureUnit::PIXEL );
     459                 :            : }
     460                 :            : 
     461                 :            : /** convert pixel measure to string */
     462                 :          0 : void Converter::convertMeasurePx( OUStringBuffer& rBuffer, sal_Int32 nValue )
     463                 :            : {
     464                 :          0 :     rBuffer.append( nValue );
     465                 :          0 :     rBuffer.append( sal_Unicode('p' ) );
     466                 :          0 :     rBuffer.append( sal_Unicode('x' ) );
     467                 :          0 : }
     468                 :            : 
     469                 :      90372 : int lcl_gethex( int nChar )
     470                 :            : {
     471 [ +  - ][ +  + ]:      90372 :     if( nChar >= '0' && nChar <= '9' )
     472                 :      61595 :         return nChar - '0';
     473 [ +  + ][ +  - ]:      28777 :     else if( nChar >= 'a' && nChar <= 'f' )
     474                 :      28261 :         return nChar - 'a' + 10;
     475 [ +  - ][ +  - ]:        516 :     else if( nChar >= 'A' && nChar <= 'F' )
     476                 :        516 :         return nChar - 'A' + 10;
     477                 :            :     else
     478                 :      90372 :         return 0;
     479                 :            : }
     480                 :            : 
     481                 :            : /** convert string to color */
     482                 :      15732 : bool Converter::convertColor( sal_Int32& rColor, const OUString& rValue )
     483                 :            : {
     484 [ +  + ][ +  + ]:      15732 :     if( rValue.getLength() != 7 || rValue[0] != '#' )
                 [ +  + ]
     485                 :        670 :         return false;
     486                 :            : 
     487                 :      15062 :     rColor = lcl_gethex( rValue[1] ) * 16 + lcl_gethex( rValue[2] );
     488                 :      15062 :     rColor <<= 8;
     489                 :            : 
     490                 :      15062 :     rColor |= ( lcl_gethex( rValue[3] ) * 16 + lcl_gethex( rValue[4] ) );
     491                 :      15062 :     rColor <<= 8;
     492                 :            : 
     493                 :      15062 :     rColor |= ( lcl_gethex( rValue[5] ) * 16 + lcl_gethex( rValue[6] ) );
     494                 :            : 
     495                 :      15732 :     return true;
     496                 :            : }
     497                 :            : 
     498                 :            : static sal_Char aHexTab[] = "0123456789abcdef";
     499                 :            : 
     500                 :            : /** convert color to string */
     501                 :        432 : void Converter::convertColor( OUStringBuffer& rBuffer, sal_Int32 nColor )
     502                 :            : {
     503                 :        432 :     rBuffer.append( sal_Unicode( '#' ) );
     504                 :            : 
     505                 :        432 :     sal_uInt8 nCol = (sal_uInt8)(nColor >> 16);
     506                 :        432 :     rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
     507                 :        432 :     rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
     508                 :            : 
     509                 :        432 :     nCol = (sal_uInt8)(nColor >> 8);
     510                 :        432 :     rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
     511                 :        432 :     rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
     512                 :            : 
     513                 :        432 :     nCol = (sal_uInt8)nColor;
     514                 :        432 :     rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
     515                 :        432 :     rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
     516                 :        432 : }
     517                 :            : 
     518                 :            : /** convert number to string */
     519                 :      48482 : void Converter::convertNumber( OUStringBuffer& rBuffer, sal_Int32 nNumber )
     520                 :            : {
     521                 :      48482 :     rBuffer.append( nNumber );
     522                 :      48482 : }
     523                 :            : 
     524                 :            : /** convert string to number with optional min and max values */
     525                 :      17371 : bool Converter::convertNumber(  sal_Int32& rValue,
     526                 :            :                                 const OUString& rString,
     527                 :            :                                 sal_Int32 nMin, sal_Int32 nMax )
     528                 :            : {
     529                 :      17371 :     rValue = 0;
     530                 :      17371 :     sal_Int64 nNumber = 0;
     531         [ +  - ]:      17371 :     sal_Bool bRet = convertNumber64(nNumber,rString,nMin,nMax);
     532         [ +  + ]:      17371 :     if ( bRet )
     533                 :      17326 :         rValue = static_cast<sal_Int32>(nNumber);
     534                 :      17371 :     return bRet;
     535                 :            : }
     536                 :            : 
     537                 :            : /** convert string to 64-bit number with optional min and max values */
     538                 :      17375 : bool Converter::convertNumber64( sal_Int64& rValue,
     539                 :            :                                  const OUString& rString,
     540                 :            :                                  sal_Int64 nMin, sal_Int64 nMax )
     541                 :            : {
     542                 :      17375 :     bool bNeg = false;
     543                 :      17375 :     rValue = 0;
     544                 :            : 
     545                 :      17375 :     sal_Int32 nPos = 0;
     546                 :      17375 :     sal_Int32 const nLen = rString.getLength();
     547                 :            : 
     548                 :            :     // skip white space
     549 [ +  + ][ -  + ]:      17375 :     while( (nPos < nLen) && (rString[nPos] <= sal_Unicode(' ')) )
                 [ -  + ]
     550                 :          0 :         nPos++;
     551                 :            : 
     552 [ +  + ][ +  + ]:      17375 :     if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
                 [ +  + ]
     553                 :            :     {
     554                 :        143 :         bNeg = true;
     555                 :        143 :         nPos++;
     556                 :            :     }
     557                 :            : 
     558                 :            :     // get number
     559   [ +  +  +  -  :     154277 :     while( nPos < nLen &&
           +  + ][ +  + ]
     560                 :      45649 :            sal_Unicode('0') <= rString[nPos] &&
     561                 :      45649 :            sal_Unicode('9') >= rString[nPos] )
     562                 :            :     {
     563                 :            :         // TODO: check overflow!
     564                 :      45604 :         rValue *= 10;
     565                 :      45604 :         rValue += (rString[nPos] - sal_Unicode('0'));
     566                 :      45604 :         nPos++;
     567                 :            :     }
     568                 :            : 
     569         [ +  + ]:      17375 :     if( bNeg )
     570                 :        143 :         rValue *= -1;
     571                 :            : 
     572         [ +  + ]:      17375 :     if( rValue < nMin )
     573                 :          3 :         rValue = nMin;
     574         [ +  + ]:      17372 :     else if( rValue > nMax )
     575                 :          6 :         rValue = nMax;
     576                 :            : 
     577 [ +  + ][ +  - ]:      17375 :     return ( nPos == nLen && rValue >= nMin && rValue <= nMax );
                 [ +  - ]
     578                 :            : }
     579                 :            : 
     580                 :            : /** convert double number to string (using ::rtl::math) */
     581                 :       1047 : void Converter::convertDouble(  OUStringBuffer& rBuffer,
     582                 :            :                                 double fNumber,
     583                 :            :                                 bool bWriteUnits,
     584                 :            :                                 sal_Int16 nSourceUnit,
     585                 :            :                                 sal_Int16 nTargetUnit)
     586                 :            : {
     587         [ -  + ]:       1047 :     if(MeasureUnit::PERCENT == nSourceUnit)
     588                 :            :     {
     589                 :            :         OSL_ENSURE( nTargetUnit == MeasureUnit::PERCENT, "MeasureUnit::PERCENT only maps to MeasureUnit::PERCENT!" );
     590                 :          0 :         ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
     591         [ #  # ]:          0 :         if(bWriteUnits)
     592                 :          0 :             rBuffer.append(sal_Unicode('%'));
     593                 :            :     }
     594                 :            :     else
     595                 :            :     {
     596                 :       1047 :         OUStringBuffer sUnit;
     597         [ +  - ]:       1047 :         double fFactor = GetConversionFactor(sUnit, nSourceUnit, nTargetUnit);
     598         [ +  + ]:       1047 :         if(fFactor != 1.0)
     599                 :        123 :             fNumber *= fFactor;
     600                 :       1047 :         ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
     601         [ +  - ]:       1047 :         if(bWriteUnits)
     602 [ +  - ][ +  - ]:       1047 :             rBuffer.append(sUnit.makeStringAndClear());
     603                 :            :     }
     604                 :       1047 : }
     605                 :            : 
     606                 :            : /** convert double number to string (using ::rtl::math) */
     607                 :        178 : void Converter::convertDouble( ::rtl::OUStringBuffer& rBuffer, double fNumber)
     608                 :            : {
     609                 :        178 :     ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
     610                 :        178 : }
     611                 :            : 
     612                 :            : /** convert string to double number (using ::rtl::math) */
     613                 :       2876 : bool Converter::convertDouble(double& rValue,
     614                 :            :     const ::rtl::OUString& rString, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
     615                 :            : {
     616                 :            :     rtl_math_ConversionStatus eStatus;
     617                 :       2876 :     rValue = ::rtl::math::stringToDouble( rString, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
     618                 :            : 
     619         [ +  - ]:       2876 :     if(eStatus == rtl_math_ConversionStatus_Ok)
     620                 :            :     {
     621                 :       2876 :         OUStringBuffer sUnit;
     622                 :            :         // fdo#48969: switch source and target because factor is used to divide!
     623                 :            :         double const fFactor =
     624         [ +  - ]:       2876 :             GetConversionFactor(sUnit, nTargetUnit, nSourceUnit);
     625 [ +  + ][ +  - ]:       2876 :         if(fFactor != 1.0 && fFactor != 0.0)
     626                 :       2876 :             rValue /= fFactor;
     627                 :            :     }
     628                 :            : 
     629                 :       2876 :     return ( eStatus == rtl_math_ConversionStatus_Ok );
     630                 :            : }
     631                 :            : 
     632                 :            : /** convert string to double number (using ::rtl::math) */
     633                 :       6677 : bool Converter::convertDouble(double& rValue, const ::rtl::OUString& rString)
     634                 :            : {
     635                 :            :     rtl_math_ConversionStatus eStatus;
     636                 :       6677 :     rValue = ::rtl::math::stringToDouble( rString, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
     637                 :       6677 :     return ( eStatus == rtl_math_ConversionStatus_Ok );
     638                 :            : }
     639                 :            : 
     640                 :            : /** convert double to ISO "duration" string; negative durations allowed */
     641                 :          0 : void Converter::convertDuration(::rtl::OUStringBuffer& rBuffer,
     642                 :            :                                 const double fTime)
     643                 :            : {
     644                 :          0 :     double fValue = fTime;
     645                 :            : 
     646                 :            :     // take care of negative durations as specified in:
     647                 :            :     // XML Schema, W3C Working Draft 07 April 2000, section 3.2.6.1
     648         [ #  # ]:          0 :     if (fValue < 0.0)
     649                 :            :     {
     650                 :          0 :         rBuffer.append(sal_Unicode('-'));
     651                 :          0 :         fValue = - fValue;
     652                 :            :     }
     653                 :            : 
     654                 :          0 :     rBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM( "PT" ));
     655                 :          0 :     fValue *= 24;
     656                 :          0 :     double fHoursValue = ::rtl::math::approxFloor (fValue);
     657                 :          0 :     fValue -= fHoursValue;
     658                 :          0 :     fValue *= 60;
     659                 :          0 :     double fMinsValue = ::rtl::math::approxFloor (fValue);
     660                 :          0 :     fValue -= fMinsValue;
     661                 :          0 :     fValue *= 60;
     662                 :          0 :     double fSecsValue = ::rtl::math::approxFloor (fValue);
     663                 :          0 :     fValue -= fSecsValue;
     664                 :            :     double f100SecsValue;
     665         [ #  # ]:          0 :     if (fValue > 0.00001)
     666                 :          0 :         f100SecsValue = ::rtl::math::round( fValue, XML_MAXDIGITSCOUNT_TIME - 5);
     667                 :            :     else
     668                 :          0 :         f100SecsValue = 0.0;
     669                 :            : 
     670         [ #  # ]:          0 :     if (f100SecsValue == 1.0)
     671                 :            :     {
     672                 :          0 :         f100SecsValue = 0.0;
     673                 :          0 :         fSecsValue += 1.0;
     674                 :            :     }
     675         [ #  # ]:          0 :     if (fSecsValue >= 60.0)
     676                 :            :     {
     677                 :          0 :         fSecsValue -= 60.0;
     678                 :          0 :         fMinsValue += 1.0;
     679                 :            :     }
     680         [ #  # ]:          0 :     if (fMinsValue >= 60.0)
     681                 :            :     {
     682                 :          0 :         fMinsValue -= 60.0;
     683                 :          0 :         fHoursValue += 1.0;
     684                 :            :     }
     685                 :            : 
     686         [ #  # ]:          0 :     if (fHoursValue < 10)
     687                 :          0 :         rBuffer.append( sal_Unicode('0'));
     688                 :          0 :     rBuffer.append( sal_Int32( fHoursValue));
     689                 :          0 :     rBuffer.append( sal_Unicode('H'));
     690         [ #  # ]:          0 :     if (fMinsValue < 10)
     691                 :          0 :         rBuffer.append( sal_Unicode('0'));
     692                 :          0 :     rBuffer.append( sal_Int32( fMinsValue));
     693                 :          0 :     rBuffer.append( sal_Unicode('M'));
     694         [ #  # ]:          0 :     if (fSecsValue < 10)
     695                 :          0 :         rBuffer.append( sal_Unicode('0'));
     696                 :          0 :     rBuffer.append( sal_Int32( fSecsValue));
     697         [ #  # ]:          0 :     if (f100SecsValue > 0.0)
     698                 :            :     {
     699                 :            :         ::rtl::OUString a100th( ::rtl::math::doubleToUString( fValue,
     700                 :            :                     rtl_math_StringFormat_F, XML_MAXDIGITSCOUNT_TIME - 5, '.',
     701                 :          0 :                     true));
     702         [ #  # ]:          0 :         if ( a100th.getLength() > 2 )
     703                 :            :         {
     704         [ #  # ]:          0 :             rBuffer.append( sal_Unicode('.'));
     705         [ #  # ]:          0 :             rBuffer.append( a100th.copy( 2 ) );     // strip 0.
     706                 :          0 :         }
     707                 :            :     }
     708                 :          0 :     rBuffer.append( sal_Unicode('S'));
     709                 :          0 : }
     710                 :            : 
     711                 :            : /** convert ISO "duration" string to double; negative durations allowed */
     712                 :          3 : bool Converter::convertDuration(double& rfTime,
     713                 :            :                                 const ::rtl::OUString& rString)
     714                 :            : {
     715                 :          3 :     rtl::OUString aTrimmed = rString.trim().toAsciiUpperCase();
     716                 :          3 :     const sal_Unicode* pStr = aTrimmed.getStr();
     717                 :            : 
     718                 :            :     // negative time duration?
     719                 :          3 :     bool bIsNegativeDuration = false;
     720         [ -  + ]:          3 :     if ( sal_Unicode('-') == (*pStr) )
     721                 :            :     {
     722                 :          0 :         bIsNegativeDuration = true;
     723                 :          0 :         pStr++;
     724                 :            :     }
     725                 :            : 
     726         [ -  + ]:          3 :     if ( *(pStr++) != sal_Unicode('P') )            // duration must start with "P"
     727                 :          0 :         return false;
     728                 :            : 
     729                 :          3 :     rtl::OUString sDoubleStr;
     730                 :          3 :     bool bSuccess = true;
     731                 :          3 :     bool bDone = false;
     732                 :          3 :     bool bTimePart = false;
     733                 :          3 :     bool bIsFraction = false;
     734                 :          3 :     sal_Int32 nDays  = 0;
     735                 :          3 :     sal_Int32 nHours = 0;
     736                 :          3 :     sal_Int32 nMins  = 0;
     737                 :          3 :     sal_Int32 nSecs  = 0;
     738                 :          3 :     sal_Int32 nTemp = 0;
     739                 :            : 
     740 [ +  - ][ +  + ]:         42 :     while ( bSuccess && !bDone )
                 [ +  + ]
     741                 :            :     {
     742                 :         39 :         sal_Unicode c = *(pStr++);
     743         [ +  + ]:         39 :         if ( !c )                               // end
     744                 :          3 :             bDone = true;
     745 [ +  + ][ +  + ]:         36 :         else if ( sal_Unicode('0') <= c && sal_Unicode('9') >= c )
     746                 :            :         {
     747         [ -  + ]:         42 :             if ( nTemp >= SAL_MAX_INT32 / 10 )
     748                 :          0 :                 bSuccess = false;
     749                 :            :             else
     750                 :            :             {
     751         [ +  + ]:         21 :                 if ( !bIsFraction )
     752                 :            :                 {
     753                 :         18 :                     nTemp *= 10;
     754                 :         18 :                     nTemp += (c - sal_Unicode('0'));
     755                 :            :                 }
     756                 :            :                 else
     757                 :            :                 {
     758                 :          3 :                     sDoubleStr += OUString::valueOf(c);
     759                 :            :                 }
     760                 :            :             }
     761                 :            :         }
     762         [ +  + ]:         15 :         else if ( bTimePart )
     763                 :            :         {
     764         [ +  + ]:         12 :             if ( c == sal_Unicode('H') )
     765                 :            :             {
     766                 :          3 :                 nHours = nTemp;
     767                 :          3 :                 nTemp = 0;
     768                 :            :             }
     769         [ +  + ]:          9 :             else if ( c == sal_Unicode('M') )
     770                 :            :             {
     771                 :          3 :                 nMins = nTemp;
     772                 :          3 :                 nTemp = 0;
     773                 :            :             }
     774 [ +  - ][ +  + ]:          6 :             else if ( (c == sal_Unicode(',')) || (c == sal_Unicode('.')) )
     775                 :            :             {
     776                 :          3 :                 nSecs = nTemp;
     777                 :          3 :                 nTemp = 0;
     778                 :          3 :                 bIsFraction = true;
     779         [ +  - ]:          3 :                 sDoubleStr = OUString(RTL_CONSTASCII_USTRINGPARAM("0."));
     780                 :            :             }
     781         [ +  - ]:          3 :             else if ( c == sal_Unicode('S') )
     782                 :            :             {
     783         [ -  + ]:          3 :                 if ( !bIsFraction )
     784                 :            :                 {
     785                 :          0 :                     nSecs = nTemp;
     786                 :          0 :                     nTemp = 0;
     787         [ #  # ]:          0 :                     sDoubleStr = OUString(RTL_CONSTASCII_USTRINGPARAM("0.0"));
     788                 :            :                 }
     789                 :            :             }
     790                 :            :             else
     791                 :         12 :                 bSuccess = false;               // invalid character
     792                 :            :         }
     793                 :            :         else
     794                 :            :         {
     795         [ +  - ]:          3 :             if ( c == sal_Unicode('T') )            // "T" starts time part
     796                 :          3 :                 bTimePart = true;
     797         [ #  # ]:          0 :             else if ( c == sal_Unicode('D') )
     798                 :            :             {
     799                 :          0 :                 nDays = nTemp;
     800                 :          0 :                 nTemp = 0;
     801                 :            :             }
     802 [ #  # ][ #  # ]:          0 :             else if ( c == sal_Unicode('Y') || c == sal_Unicode('M') )
     803                 :            :             {
     804                 :            :                 //! how many days is a year or month?
     805                 :            : 
     806                 :            :                 OSL_FAIL( "years or months in duration: not implemented");
     807                 :          0 :                 bSuccess = false;
     808                 :            :             }
     809                 :            :             else
     810                 :          0 :                 bSuccess = false;               // invalid character
     811                 :            :         }
     812                 :            :     }
     813                 :            : 
     814         [ +  - ]:          3 :     if ( bSuccess )
     815                 :            :     {
     816         [ -  + ]:          3 :         if ( nDays )
     817                 :          0 :             nHours += nDays * 24;               // add the days to the hours part
     818                 :          3 :         double fTempTime = 0.0;
     819                 :          3 :         double fHour = nHours;
     820                 :          3 :         double fMin = nMins;
     821                 :          3 :         double fSec = nSecs;
     822                 :          3 :         double fSec100 = 0.0;
     823                 :          3 :         double fFraction = sDoubleStr.toDouble();
     824                 :          3 :         fTempTime = fHour / 24;
     825                 :          3 :         fTempTime += fMin / (24 * 60);
     826                 :          3 :         fTempTime += fSec / (24 * 60 * 60);
     827                 :          3 :         fTempTime += fSec100 / (24 * 60 * 60 * 60);
     828                 :          3 :         fTempTime += fFraction / (24 * 60 * 60);
     829                 :            : 
     830                 :            :         // negative duration?
     831         [ -  + ]:          3 :         if ( bIsNegativeDuration )
     832                 :            :         {
     833                 :          0 :             fTempTime = -fTempTime;
     834                 :            :         }
     835                 :            : 
     836                 :          3 :         rfTime = fTempTime;
     837                 :            :     }
     838                 :          3 :     return bSuccess;
     839                 :            : }
     840                 :            : 
     841                 :            : /** convert util::Duration to ISO "duration" string */
     842                 :        396 : void Converter::convertDuration(::rtl::OUStringBuffer& rBuffer,
     843                 :            :         const ::util::Duration& rDuration)
     844                 :            : {
     845         [ +  + ]:        396 :     if (rDuration.Negative)
     846                 :            :     {
     847                 :          8 :         rBuffer.append(sal_Unicode('-'));
     848                 :            :     }
     849                 :        396 :     rBuffer.append(sal_Unicode('P'));
     850                 :            :     const bool bHaveDate(static_cast<sal_Int32>(rDuration.Years)
     851                 :            :                         +static_cast<sal_Int32>(rDuration.Months)
     852                 :        396 :                         +static_cast<sal_Int32>(rDuration.Days));
     853         [ +  + ]:        396 :     if (rDuration.Years)
     854                 :            :     {
     855                 :          8 :         rBuffer.append(static_cast<sal_Int32>(rDuration.Years));
     856                 :          8 :         rBuffer.append(sal_Unicode('Y'));
     857                 :            :     }
     858         [ +  + ]:        396 :     if (rDuration.Months)
     859                 :            :     {
     860                 :         11 :         rBuffer.append(static_cast<sal_Int32>(rDuration.Months));
     861                 :         11 :         rBuffer.append(sal_Unicode('M'));
     862                 :            :     }
     863         [ +  + ]:        396 :     if (rDuration.Days)
     864                 :            :     {
     865                 :         56 :         rBuffer.append(static_cast<sal_Int32>(rDuration.Days));
     866                 :         56 :         rBuffer.append(sal_Unicode('D'));
     867                 :            :     }
     868                 :            :     const sal_Int32 nMSecs(static_cast<sal_Int32>(rDuration.Seconds)
     869                 :        396 :                          + static_cast<sal_Int32>(rDuration.MilliSeconds));
     870         [ +  + ]:        396 :     if (static_cast<sal_Int32>(rDuration.Hours) +
     871                 :            :         static_cast<sal_Int32>(rDuration.Minutes) + nMSecs)
     872                 :            :     {
     873                 :        227 :         rBuffer.append(sal_Unicode('T')); // time separator
     874         [ +  + ]:        227 :         if (rDuration.Hours)
     875                 :            :         {
     876                 :         72 :             rBuffer.append(static_cast<sal_Int32>(rDuration.Hours));
     877                 :         72 :             rBuffer.append(sal_Unicode('H'));
     878                 :            :         }
     879         [ +  + ]:        227 :         if (rDuration.Minutes)
     880                 :            :         {
     881                 :        149 :             rBuffer.append(static_cast<sal_Int32>(rDuration.Minutes));
     882                 :        149 :             rBuffer.append(sal_Unicode('M'));
     883                 :            :         }
     884         [ +  + ]:        227 :         if (nMSecs)
     885                 :            :         {
     886                 :            :             // seconds must not be omitted (i.e. ".42S" is not valid)
     887                 :        165 :             rBuffer.append(static_cast<sal_Int32>(rDuration.Seconds));
     888         [ +  + ]:        165 :             if (rDuration.MilliSeconds)
     889                 :            :             {
     890                 :         17 :                 rBuffer.append(sal_Unicode('.'));
     891                 :         17 :                 const sal_Int32 nMilliSeconds(rDuration.MilliSeconds % 1000);
     892         [ +  + ]:         17 :                 if (nMilliSeconds < 100)
     893                 :            :                 {
     894                 :          9 :                     rBuffer.append(sal_Unicode('0'));
     895                 :            :                 }
     896         [ +  + ]:         17 :                 if (nMilliSeconds < 10)
     897                 :            :                 {
     898                 :          3 :                     rBuffer.append(sal_Unicode('0'));
     899                 :            :                 }
     900         [ +  + ]:         17 :                 if (0 == (nMilliSeconds % 10))
     901                 :            :                 {
     902         [ -  + ]:          9 :                     if (0 == (nMilliSeconds % 100))
     903                 :            :                     {
     904                 :          0 :                         rBuffer.append(nMilliSeconds / 100);
     905                 :            :                     }
     906                 :            :                     else
     907                 :            :                     {
     908                 :          9 :                         rBuffer.append(nMilliSeconds / 10);
     909                 :            :                     }
     910                 :            :                 }
     911                 :            :                 else
     912                 :            :                 {
     913                 :          8 :                     rBuffer.append(nMilliSeconds);
     914                 :            :                 }
     915                 :            :             }
     916                 :        165 :             rBuffer.append(sal_Unicode('S'));
     917                 :            :         }
     918                 :            :     }
     919         [ +  + ]:        169 :     else if (!bHaveDate)
     920                 :            :     {
     921                 :            :         // zero duration: XMLSchema-2 says there must be at least one component
     922                 :        157 :         rBuffer.append(sal_Unicode('0'));
     923                 :        157 :         rBuffer.append(sal_Unicode('D'));
     924                 :            :     }
     925                 :        396 : }
     926                 :            : 
     927                 :            : enum Result { R_NOTHING, R_OVERFLOW, R_SUCCESS };
     928                 :            : 
     929                 :            : static Result
     930                 :       9071 : readUnsignedNumber(const ::rtl::OUString & rString,
     931                 :            :     sal_Int32 & io_rnPos, sal_Int32 & o_rNumber)
     932                 :            : {
     933                 :       9071 :     bool bOverflow(false);
     934                 :       9071 :     sal_Int32 nTemp(0);
     935                 :       9071 :     sal_Int32 nPos(io_rnPos);
     936                 :            : 
     937         [ +  + ]:      15541 :     while (nPos < rString.getLength())
     938                 :            :     {
     939                 :       8705 :         const sal_Unicode c = rString[nPos];
     940 [ +  + ][ +  + ]:       8705 :         if ((sal_Unicode('0') <= c) && (c <= sal_Unicode('9')))
     941                 :            :         {
     942                 :       6470 :             nTemp *= 10;
     943                 :       6470 :             nTemp += (c - sal_Unicode('0'));
     944         [ +  + ]:       6632 :             if (nTemp >= SAL_MAX_INT16)
     945                 :            :             {
     946                 :        162 :                 bOverflow = true;
     947                 :            :             }
     948                 :            :         }
     949                 :            :         else
     950                 :            :         {
     951                 :       2235 :             break;
     952                 :            :         }
     953                 :       6470 :         ++nPos;
     954                 :            :     }
     955                 :            : 
     956         [ +  + ]:       9071 :     if (io_rnPos == nPos) // read something?
     957                 :            :     {
     958                 :       6422 :         o_rNumber = -1;
     959                 :       6422 :         return R_NOTHING;
     960                 :            :     }
     961                 :            : 
     962                 :       2649 :     io_rnPos = nPos;
     963                 :       2649 :     o_rNumber = nTemp;
     964         [ +  + ]:       9071 :     return (bOverflow) ? R_OVERFLOW : R_SUCCESS;
     965                 :            : }
     966                 :            : 
     967                 :            : static bool
     968                 :       3259 : readDurationT(const ::rtl::OUString & rString, sal_Int32 & io_rnPos)
     969                 :            : {
     970   [ +  +  +  + ]:       3456 :     if ((io_rnPos < rString.getLength()) &&
                 [ +  + ]
     971                 :        197 :         (rString[io_rnPos] == sal_Unicode('T')))
     972                 :            :     {
     973                 :         86 :         ++io_rnPos;
     974                 :         86 :         return true;
     975                 :            :     }
     976                 :       3259 :     return false;
     977                 :            : }
     978                 :            : 
     979                 :            : static bool
     980                 :        403 : readDurationComponent(const ::rtl::OUString & rString,
     981                 :            :     sal_Int32 & io_rnPos, sal_Int32 & io_rnTemp, bool & io_rbTimePart,
     982                 :            :     sal_Int32 & o_rnTarget, const sal_Unicode c)
     983                 :            : {
     984         [ +  + ]:        403 :     if ((io_rnPos < rString.getLength()))
     985                 :            :     {
     986         [ +  + ]:        391 :         if (c == rString[io_rnPos])
     987                 :            :         {
     988                 :        148 :             ++io_rnPos;
     989         [ +  - ]:        148 :             if (-1 != io_rnTemp)
     990                 :            :             {
     991                 :        148 :                 o_rnTarget = io_rnTemp;
     992                 :        148 :                 io_rnTemp = -1;
     993         [ +  + ]:        148 :                 if (!io_rbTimePart)
     994                 :            :                 {
     995                 :         99 :                     io_rbTimePart = readDurationT(rString, io_rnPos);
     996                 :            :                 }
     997                 :            :                 return (R_OVERFLOW !=
     998                 :        148 :                         readUnsignedNumber(rString, io_rnPos, io_rnTemp));
     999                 :            :             }
    1000                 :            :             else
    1001                 :            :             {
    1002                 :          0 :                 return false;
    1003                 :            :             }
    1004                 :            :         }
    1005                 :            :     }
    1006                 :        403 :     return true;
    1007                 :            : }
    1008                 :            : 
    1009                 :            : /** convert ISO "duration" string to util::Duration */
    1010                 :       3163 : bool Converter::convertDuration(util::Duration& rDuration,
    1011                 :            :                                 const ::rtl::OUString& rString)
    1012                 :            : {
    1013                 :       3163 :     const ::rtl::OUString string = rString.trim().toAsciiUpperCase();
    1014                 :       3163 :     sal_Int32 nPos(0);
    1015                 :            : 
    1016                 :       3163 :     bool bIsNegativeDuration(false);
    1017 [ +  + ][ +  + ]:       3163 :     if (!string.isEmpty() && (sal_Unicode('-') == string[0]))
                 [ +  + ]
    1018                 :            :     {
    1019                 :          8 :         bIsNegativeDuration = true;
    1020                 :          8 :         ++nPos;
    1021                 :            :     }
    1022                 :            : 
    1023   [ +  +  +  + ]:       3327 :     if ((nPos < string.getLength())
                 [ +  + ]
    1024                 :        164 :         && (string[nPos] != sal_Unicode('P'))) // duration must start with "P"
    1025                 :            :     {
    1026                 :          3 :         return false;
    1027                 :            :     }
    1028                 :            : 
    1029                 :       3160 :     ++nPos;
    1030                 :            : 
    1031                 :            :     /// last read number; -1 == no valid number! always reset after using!
    1032                 :       3160 :     sal_Int32 nTemp(-1);
    1033                 :       3160 :     bool bTimePart(false); // have we read 'T'?
    1034                 :       3160 :     bool bSuccess(false);
    1035                 :       3160 :     sal_Int32 nYears(0);
    1036                 :       3160 :     sal_Int32 nMonths(0);
    1037                 :       3160 :     sal_Int32 nDays(0);
    1038                 :       3160 :     sal_Int32 nHours(0);
    1039                 :       3160 :     sal_Int32 nMinutes(0);
    1040                 :       3160 :     sal_Int32 nSeconds(0);
    1041                 :       3160 :     sal_Int32 nMilliSeconds(0);
    1042                 :            : 
    1043                 :       3160 :     bTimePart = readDurationT(string, nPos);
    1044                 :       3160 :     bSuccess = (R_SUCCESS == readUnsignedNumber(string, nPos, nTemp));
    1045                 :            : 
    1046 [ +  + ][ +  + ]:       3160 :     if (!bTimePart && bSuccess)
    1047                 :            :     {
    1048                 :            :         bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1049                 :         86 :                      nYears, sal_Unicode('Y'));
    1050                 :            :     }
    1051                 :            : 
    1052 [ +  + ][ +  + ]:       3160 :     if (!bTimePart && bSuccess)
    1053                 :            :     {
    1054                 :            :         bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1055                 :         80 :                      nMonths, sal_Unicode('M'));
    1056                 :            :     }
    1057                 :            : 
    1058 [ +  + ][ +  + ]:       3160 :     if (!bTimePart && bSuccess)
    1059                 :            :     {
    1060                 :            :         bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1061                 :         77 :                      nDays, sal_Unicode('D'));
    1062                 :            :     }
    1063                 :            : 
    1064         [ +  + ]:       3160 :     if (bTimePart)
    1065                 :            :     {
    1066         [ +  + ]:         86 :         if (-1 == nTemp) // a 'T' must be followed by a component
    1067                 :            :         {
    1068                 :          6 :             bSuccess = false;
    1069                 :            :         }
    1070                 :            : 
    1071         [ +  + ]:         86 :         if (bSuccess)
    1072                 :            :         {
    1073                 :            :             bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1074                 :         80 :                          nHours, sal_Unicode('H'));
    1075                 :            :         }
    1076                 :            : 
    1077         [ +  + ]:         86 :         if (bSuccess)
    1078                 :            :         {
    1079                 :            :             bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1080                 :         80 :                          nMinutes, sal_Unicode('M'));
    1081                 :            :         }
    1082                 :            : 
    1083                 :            :         // eeek! seconds are icky.
    1084 [ +  + ][ +  + ]:         86 :         if ((nPos < string.getLength()) && bSuccess)
                 [ +  + ]
    1085                 :            :         {
    1086         [ +  + ]:         66 :             if (sal_Unicode('.') == string[nPos])
    1087                 :            :             {
    1088                 :         37 :                 ++nPos;
    1089         [ +  + ]:         37 :                 if (-1 != nTemp)
    1090                 :            :                 {
    1091                 :         34 :                     nSeconds = nTemp;
    1092                 :         34 :                     nTemp = -1;
    1093                 :         34 :                     const sal_Int32 nStart(nPos);
    1094                 :            :                     bSuccess =
    1095                 :         34 :                         (R_NOTHING != readUnsignedNumber(string, nPos, nTemp));
    1096 [ +  + ][ +  + ]:         34 :                     if ((nPos < string.getLength()) && bSuccess)
                 [ +  - ]
    1097                 :            :                     {
    1098         [ +  - ]:         31 :                         if (-1 != nTemp)
    1099                 :            :                         {
    1100                 :         31 :                             nTemp = -1;
    1101                 :         31 :                             const sal_Int32 nDigits = nPos - nStart;
    1102                 :            :                             OSL_ENSURE(nDigits > 0, "bad code monkey");
    1103                 :         31 :                             const sal_Unicode cZero('0');
    1104                 :         31 :                             nMilliSeconds = 100 * (string[nStart] - cZero);
    1105         [ +  - ]:         31 :                             if (nDigits >= 2)
    1106                 :            :                             {
    1107                 :            :                                 nMilliSeconds += 10 *
    1108                 :         31 :                                     (string[nStart+1] - cZero);
    1109         [ +  + ]:         31 :                                 if (nDigits >= 3)
    1110                 :            :                                 {
    1111                 :          8 :                                     nMilliSeconds += (string[nStart+2] - cZero);
    1112                 :            :                                 }
    1113                 :            :                             }
    1114                 :            : 
    1115         [ +  - ]:         31 :                             if (sal_Unicode('S') == string[nPos])
    1116                 :            :                             {
    1117                 :         31 :                                 ++nPos;
    1118                 :            :                             }
    1119                 :            :                             else
    1120                 :            :                             {
    1121                 :          0 :                                 bSuccess = false;
    1122                 :            :                             }
    1123                 :            :                         }
    1124                 :            :                         else
    1125                 :            :                         {
    1126                 :          0 :                             bSuccess = false;
    1127                 :            :                         }
    1128                 :            :                     }
    1129                 :            :                 }
    1130                 :            :                 else
    1131                 :            :                 {
    1132                 :          3 :                     bSuccess = false;
    1133                 :            :                 }
    1134                 :            :             }
    1135         [ +  + ]:         29 :             else if (sal_Unicode('S') == string[nPos])
    1136                 :            :             {
    1137                 :         23 :                 ++nPos;
    1138         [ +  - ]:         23 :                 if (-1 != nTemp)
    1139                 :            :                 {
    1140                 :         23 :                     nSeconds = nTemp;
    1141                 :         23 :                     nTemp = -1;
    1142                 :            :                 }
    1143                 :            :                 else
    1144                 :            :                 {
    1145                 :          0 :                     bSuccess = false;
    1146                 :            :                 }
    1147                 :            :             }
    1148                 :            :         }
    1149                 :            :     }
    1150                 :            : 
    1151         [ +  + ]:       3160 :     if (nPos != string.getLength()) // string not processed completely?
    1152                 :            :     {
    1153                 :       3026 :         bSuccess = false;
    1154                 :            :     }
    1155                 :            : 
    1156         [ +  + ]:       3160 :     if (nTemp != -1) // unprocessed number?
    1157                 :            :     {
    1158                 :         12 :         bSuccess = false;
    1159                 :            :     }
    1160                 :            : 
    1161         [ +  + ]:       3160 :     if (bSuccess)
    1162                 :            :     {
    1163                 :        131 :         rDuration.Negative      = bIsNegativeDuration;
    1164                 :        131 :         rDuration.Years         = static_cast<sal_Int16>(nYears);
    1165                 :        131 :         rDuration.Months        = static_cast<sal_Int16>(nMonths);
    1166                 :        131 :         rDuration.Days          = static_cast<sal_Int16>(nDays);
    1167                 :        131 :         rDuration.Hours         = static_cast<sal_Int16>(nHours);
    1168                 :        131 :         rDuration.Minutes       = static_cast<sal_Int16>(nMinutes);
    1169                 :        131 :         rDuration.Seconds       = static_cast<sal_Int16>(nSeconds);
    1170                 :        131 :         rDuration.MilliSeconds  = static_cast<sal_Int16>(nMilliSeconds);
    1171                 :            :     }
    1172                 :            : 
    1173                 :       3163 :     return bSuccess;
    1174                 :            : }
    1175                 :            : 
    1176                 :            : 
    1177                 :            : /** convert util::Date to ISO "date" string */
    1178                 :          2 : void Converter::convertDate(
    1179                 :            :         ::rtl::OUStringBuffer& i_rBuffer,
    1180                 :            :         const util::Date& i_rDate)
    1181                 :            : {
    1182                 :            :     const util::DateTime dt(
    1183                 :          2 :             0, 0, 0, 0, i_rDate.Day, i_rDate.Month, i_rDate.Year);
    1184         [ +  - ]:          2 :     convertDateTime(i_rBuffer, dt, false);
    1185                 :          2 : }
    1186                 :            : 
    1187                 :            : /** convert util::DateTime to ISO "date" or "dateTime" string */
    1188                 :       1844 : void Converter::convertDateTime(
    1189                 :            :         ::rtl::OUStringBuffer& i_rBuffer,
    1190                 :            :         const com::sun::star::util::DateTime& i_rDateTime,
    1191                 :            :         bool i_bAddTimeIf0AM )
    1192                 :            : {
    1193                 :       1844 :     const sal_Unicode dash('-');
    1194                 :       1844 :     const sal_Unicode col (':');
    1195                 :       1844 :     const sal_Unicode dot ('.');
    1196                 :       1844 :     const sal_Unicode zero('0');
    1197                 :       1844 :     const sal_Unicode tee ('T');
    1198                 :            : 
    1199         [ +  + ]:       1844 :     if (i_rDateTime.Year < 1000) {
    1200                 :         24 :         i_rBuffer.append(zero);
    1201                 :            :     }
    1202         [ +  + ]:       1844 :     if (i_rDateTime.Year < 100) {
    1203                 :         21 :         i_rBuffer.append(zero);
    1204                 :            :     }
    1205         [ +  + ]:       1844 :     if (i_rDateTime.Year < 10) {
    1206                 :         21 :         i_rBuffer.append(zero);
    1207                 :            :     }
    1208                 :       1844 :     i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Year)  ).append(dash);
    1209         [ +  + ]:       1844 :     if( i_rDateTime.Month < 10 ) {
    1210                 :       1703 :         i_rBuffer.append(zero);
    1211                 :            :     }
    1212                 :       1844 :     i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Month) ).append(dash);
    1213         [ +  + ]:       1844 :     if( i_rDateTime.Day   < 10 ) {
    1214                 :        240 :         i_rBuffer.append(zero);
    1215                 :            :     }
    1216                 :       1844 :     i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Day)   );
    1217                 :            : 
    1218 [ +  + ][ +  + ]:       1844 :     if( i_rDateTime.Seconds != 0 ||
         [ +  + ][ +  + ]
    1219                 :            :         i_rDateTime.Minutes != 0 ||
    1220                 :            :         i_rDateTime.Hours   != 0 ||
    1221                 :            :         i_bAddTimeIf0AM )
    1222                 :            :     {
    1223                 :       1838 :         i_rBuffer.append(tee);
    1224         [ +  + ]:       1838 :         if( i_rDateTime.Hours   < 10 ) {
    1225                 :        180 :             i_rBuffer.append(zero);
    1226                 :            :         }
    1227                 :       1838 :         i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Hours)   )
    1228                 :       1838 :                  .append(col);
    1229         [ +  + ]:       1838 :         if( i_rDateTime.Minutes < 10 ) {
    1230                 :        158 :             i_rBuffer.append(zero);
    1231                 :            :         }
    1232                 :       1838 :         i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Minutes) )
    1233                 :       1838 :                  .append(col);
    1234         [ +  + ]:       1838 :         if( i_rDateTime.Seconds < 10 ) {
    1235                 :        649 :             i_rBuffer.append(zero);
    1236                 :            :         }
    1237                 :       1838 :         i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Seconds) );
    1238         [ +  + ]:       1838 :         if( i_rDateTime.HundredthSeconds > 0 ) {
    1239                 :         12 :             i_rBuffer.append(dot);
    1240         [ -  + ]:         12 :             if( i_rDateTime.HundredthSeconds < 10 ) {
    1241                 :          0 :                 i_rBuffer.append(zero);
    1242                 :            :             }
    1243                 :            :             i_rBuffer.append(
    1244                 :         12 :                 static_cast<sal_Int32>(i_rDateTime.HundredthSeconds) );
    1245                 :            :         }
    1246                 :            :     }
    1247                 :       1844 : }
    1248                 :            : 
    1249                 :            : /** convert ISO "date" or "dateTime" string to util::DateTime */
    1250                 :       3842 : bool Converter::convertDateTime( util::DateTime& rDateTime,
    1251                 :            :                                  const ::rtl::OUString& rString )
    1252                 :            : {
    1253                 :            :     bool isDateTime;
    1254                 :       3842 :     util::Date date;
    1255 [ +  + ][ +  - ]:       3842 :     if (convertDateOrDateTime(date, rDateTime, isDateTime, rString))
    1256                 :            :     {
    1257         [ +  + ]:        413 :         if (!isDateTime)
    1258                 :            :         {
    1259                 :        181 :             rDateTime.Year = date.Year;
    1260                 :        181 :             rDateTime.Month = date.Month;
    1261                 :        181 :             rDateTime.Day = date.Day;
    1262                 :        181 :             rDateTime.Hours = 0;
    1263                 :        181 :             rDateTime.Minutes = 0;
    1264                 :        181 :             rDateTime.Seconds = 0;
    1265                 :        181 :             rDateTime.HundredthSeconds = 0;
    1266                 :            :         }
    1267                 :        413 :         return true;
    1268                 :            :     }
    1269                 :            :     else
    1270                 :            :     {
    1271                 :       3842 :         return false;
    1272                 :            :     }
    1273                 :            : }
    1274                 :            : 
    1275                 :            : static bool
    1276                 :       5699 : readDateTimeComponent(const ::rtl::OUString & rString,
    1277                 :            :     sal_Int32 & io_rnPos, sal_Int32 & o_rnTarget,
    1278                 :            :     const sal_Int32 nMinLength, const bool bExactLength)
    1279                 :            : {
    1280                 :       5699 :     const sal_Int32 nOldPos(io_rnPos);
    1281                 :       5699 :     sal_Int32 nTemp(0);
    1282         [ +  + ]:       5699 :     if (R_SUCCESS != readUnsignedNumber(rString, io_rnPos, nTemp))
    1283                 :            :     {
    1284                 :       3325 :         return false;
    1285                 :            :     }
    1286                 :       2374 :     const sal_Int32 nTokenLength(io_rnPos - nOldPos);
    1287 [ +  + ][ +  + ]:       2374 :     if ((nTokenLength < nMinLength) ||
                 [ -  + ]
    1288                 :            :         (bExactLength && (nTokenLength > nMinLength)))
    1289                 :            :     {
    1290                 :         21 :         return false; // bad length
    1291                 :            :     }
    1292                 :       2353 :     o_rnTarget = nTemp;
    1293                 :       5699 :     return true;
    1294                 :            : }
    1295                 :            : 
    1296                 :         52 : static bool lcl_isLeapYear(const sal_uInt32 nYear)
    1297                 :            : {
    1298                 :            :     return ((nYear % 4) == 0)
    1299 [ +  + ][ +  + ]:         52 :         && (((nYear % 100) != 0) || ((nYear % 400) == 0));
                 [ +  + ]
    1300                 :            : }
    1301                 :            : 
    1302                 :            : static sal_uInt16
    1303                 :        474 : lcl_MaxDaysPerMonth(const sal_Int32 nMonth, const sal_Int32 nYear)
    1304                 :            : {
    1305                 :            :     static sal_uInt16 s_MaxDaysPerMonth[12] =
    1306                 :            :         { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    1307                 :            :     OSL_ASSERT(0 < nMonth && nMonth <= 12);
    1308 [ +  + ][ +  + ]:        474 :     if ((2 == nMonth) && lcl_isLeapYear(nYear))
                 [ +  + ]
    1309                 :            :     {
    1310                 :         44 :         return 29;
    1311                 :            :     }
    1312                 :        474 :     return s_MaxDaysPerMonth[nMonth - 1];
    1313                 :            : }
    1314                 :            : 
    1315                 :            : /** convert ISO "date" or "dateTime" string to util::DateTime or util::Date */
    1316                 :       3848 : bool Converter::convertDateOrDateTime(
    1317                 :            :                 util::Date & rDate, util::DateTime & rDateTime,
    1318                 :            :                 bool & rbDateTime, const ::rtl::OUString & rString )
    1319                 :            : {
    1320                 :       3848 :     bool bSuccess = true;
    1321                 :            : 
    1322                 :       3848 :     const ::rtl::OUString string = rString.trim().toAsciiUpperCase();
    1323                 :       3848 :     sal_Int32 nPos(0);
    1324         [ +  + ]:       3848 :     if (string.getLength() > nPos)
    1325                 :            :     {
    1326         [ -  + ]:        526 :         if (sal_Unicode('-') == string[nPos])
    1327                 :            :         {
    1328                 :            :             //Negative Number
    1329                 :          0 :             ++nPos;
    1330                 :            :         }
    1331                 :            :     }
    1332                 :            : 
    1333                 :       3848 :     sal_Int32 nYear(0);
    1334                 :            :     {
    1335                 :            :         // While W3C XMLSchema specifies years with a minimum of 4 digits, be
    1336                 :            :         // leninent in what we accept for years < 1000. One digit is acceptable
    1337                 :            :         // if the remainders match.
    1338                 :       3848 :         bSuccess = readDateTimeComponent(string, nPos, nYear, 1, false);
    1339                 :       3848 :         bSuccess &= (0 < nYear);
    1340                 :       3848 :         bSuccess &= (nPos < string.getLength()); // not last token
    1341                 :            :     }
    1342 [ -  + ][ -  + ]:       3848 :     if (bSuccess && (sal_Unicode('-') != string[nPos])) // separator
                 [ +  + ]
    1343                 :            :     {
    1344                 :          0 :         bSuccess = false;
    1345                 :            :     }
    1346         [ +  + ]:       3848 :     if (bSuccess)
    1347                 :            :     {
    1348                 :        483 :         ++nPos;
    1349                 :            :     }
    1350                 :            : 
    1351                 :       3848 :     sal_Int32 nMonth(0);
    1352         [ +  + ]:       3848 :     if (bSuccess)
    1353                 :            :     {
    1354                 :        483 :         bSuccess = readDateTimeComponent(string, nPos, nMonth, 2, true);
    1355 [ +  + ][ +  + ]:        483 :         bSuccess &= (0 < nMonth) && (nMonth <= 12);
    1356                 :        483 :         bSuccess &= (nPos < string.getLength()); // not last token
    1357                 :            :     }
    1358 [ +  + ][ -  + ]:       3848 :     if (bSuccess && (sal_Unicode('-') != string[nPos])) // separator
                 [ -  + ]
    1359                 :            :     {
    1360                 :          0 :         bSuccess = false;
    1361                 :            :     }
    1362         [ +  + ]:       3848 :     if (bSuccess)
    1363                 :            :     {
    1364                 :        477 :         ++nPos;
    1365                 :            :     }
    1366                 :            : 
    1367                 :       3848 :     sal_Int32 nDay(0);
    1368         [ +  + ]:       3848 :     if (bSuccess)
    1369                 :            :     {
    1370                 :        477 :         bSuccess = readDateTimeComponent(string, nPos, nDay, 2, true);
    1371 [ +  + ][ +  + ]:        477 :         bSuccess &= (0 < nDay) && (nDay <= lcl_MaxDaysPerMonth(nMonth, nYear));
    1372                 :            :     }
    1373                 :            : 
    1374                 :       3848 :     bool bHaveTime(false);
    1375 [ +  + ][ +  + ]:       3848 :     if (bSuccess && (nPos < string.getLength()))
                 [ +  + ]
    1376                 :            :     {
    1377         [ +  - ]:        282 :         if (sal_Unicode('T') == string[nPos]) // time separator
    1378                 :            :         {
    1379                 :        282 :             bHaveTime = true;
    1380                 :        282 :             ++nPos;
    1381                 :            :         }
    1382                 :            :     }
    1383                 :            : 
    1384                 :       3848 :     sal_Int32 nHours(0);
    1385                 :       3848 :     sal_Int32 nMinutes(0);
    1386                 :       3848 :     sal_Int32 nSeconds(0);
    1387                 :       3848 :     sal_Int32 nMilliSeconds(0);
    1388 [ +  + ][ +  + ]:       3848 :     if (bSuccess && bHaveTime)
    1389                 :            :     {
    1390                 :            :         {
    1391                 :        282 :             bSuccess = readDateTimeComponent(string, nPos, nHours, 2, true);
    1392 [ +  + ][ +  - ]:        282 :             bSuccess &= (0 <= nHours) && (nHours <= 24);
    1393                 :        282 :             bSuccess &= (nPos < string.getLength()); // not last token
    1394                 :            :         }
    1395 [ -  + ][ -  + ]:        282 :         if (bSuccess && (sal_Unicode(':') != string[nPos])) // separator
                 [ +  + ]
    1396                 :            :         {
    1397                 :          0 :             bSuccess = false;
    1398                 :            :         }
    1399         [ +  + ]:        282 :         if (bSuccess)
    1400                 :            :         {
    1401                 :        276 :             ++nPos;
    1402                 :            :         }
    1403                 :            : 
    1404         [ +  + ]:        282 :         if (bSuccess)
    1405                 :            :         {
    1406                 :        276 :             bSuccess = readDateTimeComponent(string, nPos, nMinutes, 2, true);
    1407 [ +  + ][ +  - ]:        276 :             bSuccess &= (0 <= nMinutes) && (nMinutes < 60);
    1408                 :        276 :             bSuccess &= (nPos < string.getLength()); // not last token
    1409                 :            :         }
    1410 [ +  + ][ -  + ]:        282 :         if (bSuccess && (sal_Unicode(':') != string[nPos])) // separator
                 [ -  + ]
    1411                 :            :         {
    1412                 :          0 :             bSuccess = false;
    1413                 :            :         }
    1414         [ +  + ]:        282 :         if (bSuccess)
    1415                 :            :         {
    1416                 :        270 :             ++nPos;
    1417                 :            :         }
    1418                 :            : 
    1419         [ +  + ]:        282 :         if (bSuccess)
    1420                 :            :         {
    1421                 :        270 :             bSuccess = readDateTimeComponent(string, nPos, nSeconds, 2, true);
    1422 [ +  + ][ +  - ]:        270 :             bSuccess &= (0 <= nSeconds) && (nSeconds < 60);
    1423                 :            :         }
    1424         [ +  + ]:        351 :         if (bSuccess && (nPos < string.getLength()) &&
           [ +  +  +  + ]
                 [ +  + ]
    1425                 :         69 :             (sal_Unicode('.') == string[nPos])) // fraction separator
    1426                 :            :         {
    1427                 :         30 :             ++nPos;
    1428                 :         30 :             const sal_Int32 nStart(nPos);
    1429                 :         30 :             sal_Int32 nTemp(0);
    1430         [ +  + ]:         30 :             if (R_NOTHING == readUnsignedNumber(string, nPos, nTemp))
    1431                 :            :             {
    1432                 :          3 :                 bSuccess = false;
    1433                 :            :             }
    1434         [ +  + ]:         30 :             if (bSuccess)
    1435                 :            :             {
    1436                 :            :                 // cannot use nTemp because of possible leading zeros
    1437                 :            :                 // and possible overflow => read digits directly
    1438                 :         27 :                 const sal_Int32 nDigits(nPos - nStart);
    1439                 :            :                 OSL_ENSURE(nDigits > 0, "bad code monkey");
    1440                 :         27 :                 const sal_Unicode cZero('0');
    1441                 :         27 :                 nMilliSeconds = 100 * (string[nStart] - cZero);
    1442         [ +  + ]:         27 :                 if (nDigits >= 2)
    1443                 :            :                 {
    1444                 :         24 :                     nMilliSeconds += 10 * (string[nStart+1] - cZero);
    1445         [ +  + ]:         24 :                     if (nDigits >= 3)
    1446                 :            :                     {
    1447                 :         30 :                         nMilliSeconds += (string[nStart+2] - cZero);
    1448                 :            :                     }
    1449                 :            :                 }
    1450                 :            :             }
    1451                 :            :         }
    1452                 :            : 
    1453 [ +  + ][ +  + ]:        282 :         if (bSuccess && (nHours == 24))
    1454                 :            :         {
    1455 [ +  + ][ +  + ]:         12 :             if (!((0 == nMinutes) && (0 == nSeconds) && (0 == nMilliSeconds)))
                 [ +  + ]
    1456                 :            :             {
    1457                 :          9 :                 bSuccess = false; // only 24:00:00 is valid
    1458                 :            :             }
    1459                 :            :         }
    1460                 :            :     }
    1461                 :            : 
    1462                 :       3848 :     bool bHaveTimezone(false);
    1463                 :       3848 :     bool bHaveTimezonePlus(false);
    1464                 :       3848 :     bool bHaveTimezoneMinus(false);
    1465 [ +  + ][ +  + ]:       3848 :     if (bSuccess && (nPos < string.getLength()))
                 [ +  + ]
    1466                 :            :     {
    1467                 :         45 :         const sal_Unicode c(string[nPos]);
    1468         [ +  + ]:         45 :         if (sal_Unicode('+') == c)
    1469                 :            :         {
    1470                 :         18 :             bHaveTimezone = true;
    1471                 :         18 :             bHaveTimezonePlus = true;
    1472                 :         18 :             ++nPos;
    1473                 :            :         }
    1474         [ +  + ]:         27 :         else if (sal_Unicode('-') == c)
    1475                 :            :         {
    1476                 :         18 :             bHaveTimezone = true;
    1477                 :         18 :             bHaveTimezoneMinus = true;
    1478                 :         18 :             ++nPos;
    1479                 :            :         }
    1480         [ +  - ]:          9 :         else if (sal_Unicode('Z') == c)
    1481                 :            :         {
    1482                 :          9 :             bHaveTimezone = true;
    1483                 :          9 :             ++nPos;
    1484                 :            :         }
    1485                 :            :         else
    1486                 :            :         {
    1487                 :          0 :             bSuccess = false;
    1488                 :            :         }
    1489                 :            :     }
    1490                 :       3848 :     sal_Int32 nTimezoneHours(0);
    1491                 :       3848 :     sal_Int32 nTimezoneMinutes(0);
    1492 [ +  + ][ +  + ]:       3848 :     if (bSuccess && (bHaveTimezonePlus || bHaveTimezoneMinus))
                 [ +  + ]
    1493                 :            :     {
    1494                 :            :         bSuccess = readDateTimeComponent(
    1495                 :         36 :                         string, nPos, nTimezoneHours, 2, true);
    1496 [ +  + ][ +  - ]:         36 :         bSuccess &= (0 <= nTimezoneHours) && (nTimezoneHours <= 14);
    1497                 :         36 :         bSuccess &= (nPos < string.getLength()); // not last token
    1498 [ -  + ][ -  + ]:         36 :         if (bSuccess && (sal_Unicode(':') != string[nPos])) // separator
                 [ +  + ]
    1499                 :            :         {
    1500                 :          0 :             bSuccess = false;
    1501                 :            :         }
    1502         [ +  + ]:         36 :         if (bSuccess)
    1503                 :            :         {
    1504                 :         27 :             ++nPos;
    1505                 :            :         }
    1506         [ +  + ]:         36 :         if (bSuccess)
    1507                 :            :         {
    1508                 :            :             bSuccess = readDateTimeComponent(
    1509                 :         27 :                         string, nPos, nTimezoneMinutes, 2, true);
    1510 [ +  - ][ +  - ]:         27 :             bSuccess &= (0 <= nTimezoneMinutes) && (nTimezoneMinutes < 60);
    1511                 :            :         }
    1512 [ +  + ][ +  + ]:         36 :         if (bSuccess && (nTimezoneHours == 14))
    1513                 :            :         {
    1514         [ +  - ]:          6 :             if (0 != nTimezoneMinutes)
    1515                 :            :             {
    1516                 :          6 :                 bSuccess = false; // only +-14:00 is valid
    1517                 :            :             }
    1518                 :            :         }
    1519                 :            :     }
    1520                 :            : 
    1521                 :       3848 :     bSuccess &= (nPos == string.getLength()); // trailing junk?
    1522                 :            : 
    1523                 :            :     if (bSuccess && bHaveTimezone)
    1524                 :            :     {
    1525                 :            :         // util::DateTime does not support timezones!
    1526                 :            :     }
    1527                 :            : 
    1528         [ +  + ]:       3848 :     if (bSuccess)
    1529                 :            :     {
    1530         [ +  + ]:        417 :         if (bHaveTime) // time is optional
    1531                 :            :         {
    1532                 :            :             // util::DateTime does not support negative years!
    1533                 :        234 :             rDateTime.Year = static_cast<sal_uInt16>(nYear);
    1534                 :        234 :             rDateTime.Month = static_cast<sal_uInt16>(nMonth);
    1535                 :        234 :             rDateTime.Day = static_cast<sal_uInt16>(nDay);
    1536                 :        234 :             rDateTime.Hours = static_cast<sal_uInt16>(nHours);
    1537                 :        234 :             rDateTime.Minutes = static_cast<sal_uInt16>(nMinutes);
    1538                 :        234 :             rDateTime.Seconds = static_cast<sal_uInt16>(nSeconds);
    1539                 :            :             // util::DateTime does not support 3 decimal digits of precision!
    1540                 :            :             rDateTime.HundredthSeconds =
    1541                 :        234 :                 static_cast<sal_uInt16>(nMilliSeconds / 10);
    1542                 :        234 :             rbDateTime = true;
    1543                 :            :         }
    1544                 :            :         else
    1545                 :            :         {
    1546                 :        183 :             rDate.Year = static_cast<sal_uInt16>(nYear);
    1547                 :        183 :             rDate.Month = static_cast<sal_uInt16>(nMonth);
    1548                 :        183 :             rDate.Day = static_cast<sal_uInt16>(nDay);
    1549                 :        183 :             rbDateTime = false;
    1550                 :            :         }
    1551                 :            :     }
    1552                 :       3848 :     return bSuccess;
    1553                 :            : }
    1554                 :            : 
    1555                 :            : 
    1556                 :            : /** gets the position of the first comma after npos in the string
    1557                 :            :     rStr. Commas inside '"' pairs are not matched */
    1558                 :       2517 : sal_Int32 Converter::indexOfComma( const OUString& rStr,
    1559                 :            :                                             sal_Int32 nPos )
    1560                 :            : {
    1561                 :       2517 :     sal_Unicode cQuote = 0;
    1562                 :       2517 :     sal_Int32 nLen = rStr.getLength();
    1563         [ +  + ]:      34642 :     for( ; nPos < nLen; nPos++ )
    1564                 :            :     {
    1565                 :      32331 :         sal_Unicode c = rStr[nPos];
    1566   [ +  -  +  + ]:      32331 :         switch( c )
    1567                 :            :         {
    1568                 :            :         case sal_Unicode('\''):
    1569         [ +  + ]:       2702 :             if( 0 == cQuote )
    1570                 :       1351 :                 cQuote = c;
    1571         [ +  - ]:       1351 :             else if( '\'' == cQuote )
    1572                 :       1351 :                 cQuote = 0;
    1573                 :       2702 :             break;
    1574                 :            : 
    1575                 :            :         case sal_Unicode('"'):
    1576         [ #  # ]:          0 :             if( 0 == cQuote )
    1577                 :          0 :                 cQuote = c;
    1578         [ #  # ]:          0 :             else if( '\"' == cQuote )
    1579                 :          0 :                 cQuote = 0;
    1580                 :          0 :             break;
    1581                 :            : 
    1582                 :            :         case sal_Unicode(','):
    1583         [ +  - ]:        206 :             if( 0 == cQuote )
    1584                 :        206 :                 return nPos;
    1585                 :          0 :             break;
    1586                 :            :         }
    1587                 :            :     }
    1588                 :            : 
    1589                 :       2517 :     return -1;
    1590                 :            : }
    1591                 :            : 
    1592                 :            : const
    1593                 :            :   sal_Char aBase64EncodeTable[] =
    1594                 :            :     { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    1595                 :            :       'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    1596                 :            :       'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    1597                 :            :       'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    1598                 :            :       '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
    1599                 :            : 
    1600                 :            : const
    1601                 :            :   sal_uInt8 aBase64DecodeTable[]  =
    1602                 :            :     {                                            62,255,255,255, 63, // 43-47
    1603                 :            : //                                                +               /
    1604                 :            : 
    1605                 :            :      52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,  0,255,255, // 48-63
    1606                 :            : //    0   1   2   3   4   5   6   7   8   9               =
    1607                 :            : 
    1608                 :            :     255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, // 64-79
    1609                 :            : //        A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
    1610                 :            : 
    1611                 :            :      15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, // 80-95
    1612                 :            : //    P   Q   R   S   T   U   V   W   X   Y   Z
    1613                 :            : 
    1614                 :            :       0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
    1615                 :            : //        a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
    1616                 :            : 
    1617                 :            :      41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; // 112-123
    1618                 :            : //    p   q   r   s   t   u   v   w   x   y   z
    1619                 :            : 
    1620                 :            : 
    1621                 :            : 
    1622                 :        305 : void ThreeByteToFourByte (const sal_Int8* pBuffer, const sal_Int32 nStart, const sal_Int32 nFullLen, rtl::OUStringBuffer& sBuffer)
    1623                 :            : {
    1624                 :        305 :     sal_Int32 nLen(nFullLen - nStart);
    1625         [ +  + ]:        305 :     if (nLen > 3)
    1626                 :        270 :         nLen = 3;
    1627         [ +  - ]:        305 :     if (nLen == 0)
    1628                 :            :     {
    1629                 :        305 :         return;
    1630                 :            :     }
    1631                 :            : 
    1632                 :            :     sal_Int32 nBinaer;
    1633      [ -  +  + ]:        305 :     switch (nLen)
    1634                 :            :     {
    1635                 :            :         case 1:
    1636                 :            :         {
    1637                 :          0 :             nBinaer = ((sal_uInt8)pBuffer[nStart + 0]) << 16;
    1638                 :            :         }
    1639                 :          0 :         break;
    1640                 :            :         case 2:
    1641                 :            :         {
    1642                 :         35 :             nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
    1643                 :         35 :                     (((sal_uInt8)pBuffer[nStart + 1]) <<  8);
    1644                 :            :         }
    1645                 :         35 :         break;
    1646                 :            :         default:
    1647                 :            :         {
    1648                 :        270 :             nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
    1649                 :        270 :                     (((sal_uInt8)pBuffer[nStart + 1]) <<  8) +
    1650                 :        540 :                     ((sal_uInt8)pBuffer[nStart + 2]);
    1651                 :            :         }
    1652                 :        270 :         break;
    1653                 :            :     }
    1654                 :            : 
    1655                 :        305 :     sal_Unicode buf[] = { '=', '=', '=', '=' };
    1656                 :            : 
    1657                 :        305 :     sal_uInt8 nIndex (static_cast<sal_uInt8>((nBinaer & 0xFC0000) >> 18));
    1658                 :        305 :     buf[0] = aBase64EncodeTable [nIndex];
    1659                 :            : 
    1660                 :        305 :     nIndex = static_cast<sal_uInt8>((nBinaer & 0x3F000) >> 12);
    1661                 :        305 :     buf[1] = aBase64EncodeTable [nIndex];
    1662         [ +  - ]:        305 :     if (nLen > 1)
    1663                 :            :     {
    1664                 :        305 :         nIndex = static_cast<sal_uInt8>((nBinaer & 0xFC0) >> 6);
    1665                 :        305 :         buf[2] = aBase64EncodeTable [nIndex];
    1666         [ +  + ]:        305 :         if (nLen > 2)
    1667                 :            :         {
    1668                 :        270 :             nIndex = static_cast<sal_uInt8>((nBinaer & 0x3F));
    1669                 :        270 :             buf[3] = aBase64EncodeTable [nIndex];
    1670                 :            :         }
    1671                 :            :     }
    1672         [ +  - ]:        305 :     sBuffer.append(buf, SAL_N_ELEMENTS(buf));
    1673                 :            : }
    1674                 :            : 
    1675                 :         35 : void Converter::encodeBase64(rtl::OUStringBuffer& aStrBuffer, const uno::Sequence<sal_Int8>& aPass)
    1676                 :            : {
    1677                 :         35 :     sal_Int32 i(0);
    1678                 :         35 :     sal_Int32 nBufferLength(aPass.getLength());
    1679                 :         35 :     const sal_Int8* pBuffer = aPass.getConstArray();
    1680         [ +  + ]:        340 :     while (i < nBufferLength)
    1681                 :            :     {
    1682                 :        305 :         ThreeByteToFourByte (pBuffer, i, nBufferLength, aStrBuffer);
    1683                 :        305 :         i += 3;
    1684                 :            :     }
    1685                 :         35 : }
    1686                 :            : 
    1687                 :        107 : void Converter::decodeBase64(uno::Sequence<sal_Int8>& aBuffer, const rtl::OUString& sBuffer)
    1688                 :            : {
    1689                 :            : #if OSL_DEBUG_LEVEL > 0
    1690                 :            :     sal_Int32 nCharsDecoded =
    1691                 :            : #endif
    1692                 :        107 :     decodeBase64SomeChars( aBuffer, sBuffer );
    1693                 :            :     OSL_ENSURE( nCharsDecoded == sBuffer.getLength(), "some bytes left in base64 decoding!" );
    1694                 :        107 : }
    1695                 :            : 
    1696                 :        151 : sal_Int32 Converter::decodeBase64SomeChars(
    1697                 :            :         uno::Sequence<sal_Int8>& rOutBuffer,
    1698                 :            :         const rtl::OUString& rInBuffer)
    1699                 :            : {
    1700                 :        151 :     sal_Int32 nInBufferLen = rInBuffer.getLength();
    1701                 :        151 :     sal_Int32 nMinOutBufferLen = (nInBufferLen / 4) * 3;
    1702         [ +  + ]:        151 :     if( rOutBuffer.getLength() < nMinOutBufferLen )
    1703         [ +  - ]:        103 :         rOutBuffer.realloc( nMinOutBufferLen );
    1704                 :            : 
    1705                 :        151 :     const sal_Unicode *pInBuffer = rInBuffer.getStr();
    1706         [ +  - ]:        151 :     sal_Int8 *pOutBuffer = rOutBuffer.getArray();
    1707                 :        151 :     sal_Int8 *pOutBufferStart = pOutBuffer;
    1708                 :        151 :     sal_Int32 nCharsDecoded = 0;
    1709                 :            : 
    1710                 :            :     sal_uInt8 aDecodeBuffer[4];
    1711                 :        151 :     sal_Int32 nBytesToDecode = 0;
    1712                 :        151 :     sal_Int32 nBytesGotFromDecoding = 3;
    1713                 :        151 :     sal_Int32 nInBufferPos= 0;
    1714         [ +  + ]:      18235 :     while( nInBufferPos < nInBufferLen )
    1715                 :            :     {
    1716                 :      18084 :         sal_Unicode cChar = *pInBuffer;
    1717 [ +  - ][ +  - ]:      18084 :         if( cChar >= '+' && cChar <= 'z' )
    1718                 :            :         {
    1719                 :      18084 :             sal_uInt8 nByte = aBase64DecodeTable[cChar-'+'];
    1720         [ +  - ]:      18084 :             if( nByte != 255 )
    1721                 :            :             {
    1722                 :            :                 // We have found a valid character!
    1723                 :      18084 :                 aDecodeBuffer[nBytesToDecode++] = nByte;
    1724                 :            : 
    1725                 :            :                 // One '=' character at the end means 2 out bytes
    1726                 :            :                 // Two '=' characters at the end mean 1 out bytes
    1727 [ +  + ][ +  - ]:      18084 :                 if( '=' == cChar && nBytesToDecode > 2 )
    1728                 :        186 :                     nBytesGotFromDecoding--;
    1729         [ +  + ]:      18084 :                 if( 4 == nBytesToDecode )
    1730                 :            :                 {
    1731                 :            :                     // Four characters found, so we may convert now!
    1732                 :       4521 :                     sal_uInt32 nOut = (aDecodeBuffer[0] << 18) +
    1733                 :       4521 :                                       (aDecodeBuffer[1] << 12) +
    1734                 :       4521 :                                       (aDecodeBuffer[2] << 6) +
    1735                 :      13563 :                                        aDecodeBuffer[3];
    1736                 :            : 
    1737                 :       4521 :                     *pOutBuffer++  = (sal_Int8)((nOut & 0xff0000) >> 16);
    1738         [ +  + ]:       4521 :                     if( nBytesGotFromDecoding > 1 )
    1739                 :       4471 :                         *pOutBuffer++  = (sal_Int8)((nOut & 0xff00) >> 8);
    1740         [ +  + ]:       4521 :                     if( nBytesGotFromDecoding > 2 )
    1741                 :       4385 :                         *pOutBuffer++  = (sal_Int8)(nOut & 0xff);
    1742                 :       4521 :                     nCharsDecoded = nInBufferPos + 1;
    1743                 :       4521 :                     nBytesToDecode = 0;
    1744                 :       4521 :                     nBytesGotFromDecoding = 3;
    1745                 :            :                 }
    1746                 :            :             }
    1747                 :            :             else
    1748                 :            :             {
    1749                 :          0 :                 nCharsDecoded++;
    1750                 :      18084 :             }
    1751                 :            :         }
    1752                 :            :         else
    1753                 :            :         {
    1754                 :          0 :             nCharsDecoded++;
    1755                 :            :         }
    1756                 :            : 
    1757                 :      18084 :         nInBufferPos++;
    1758                 :      18084 :         pInBuffer++;
    1759                 :            :     }
    1760         [ +  + ]:        151 :     if( (pOutBuffer - pOutBufferStart) != rOutBuffer.getLength() )
    1761         [ +  - ]:        136 :         rOutBuffer.realloc( pOutBuffer - pOutBufferStart );
    1762                 :            : 
    1763                 :        151 :     return nCharsDecoded;
    1764                 :            : }
    1765                 :            : 
    1766                 :       3926 : double Converter::GetConversionFactor(::rtl::OUStringBuffer& rUnit, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
    1767                 :            : {
    1768                 :       3926 :     double fRetval(1.0);
    1769                 :       3926 :     rUnit.setLength(0L);
    1770                 :            : 
    1771                 :       3926 :     const sal_Char* psUnit = 0;
    1772                 :            : 
    1773         [ +  + ]:       3926 :     if(nSourceUnit != nTargetUnit)
    1774                 :            :     {
    1775   [ +  +  +  +  :        282 :         switch(nSourceUnit)
             +  +  +  - ]
    1776                 :            :         {
    1777                 :            :             case MeasureUnit::TWIP:
    1778                 :            :             {
    1779   [ +  +  +  +  :         60 :                 switch(nTargetUnit)
                   +  + ]
    1780                 :            :                 {
    1781                 :            :                     case MeasureUnit::MM_100TH:
    1782                 :            :                     {
    1783                 :            :                         // 0.01mm = 0.57twip (exactly)
    1784                 :         12 :                         fRetval = ((25400.0 / 1440.0) / 10.0);
    1785                 :         12 :                         break;
    1786                 :            :                     }
    1787                 :            :                     case MeasureUnit::MM_10TH:
    1788                 :            :                     {
    1789                 :            :                         // 0.01mm = 0.57twip (exactly)
    1790                 :         12 :                         fRetval = ((25400.0 / 1440.0) / 100.0);
    1791                 :         12 :                         break;
    1792                 :            :                     }
    1793                 :            :                     case MeasureUnit::MM:
    1794                 :            :                     {
    1795                 :            :                         // 0.01mm = 0.57twip (exactly)
    1796                 :         12 :                         fRetval = ((25400.0 / 1440.0) / 1000.0);
    1797                 :         12 :                         psUnit = gpsMM;
    1798                 :         12 :                         break;
    1799                 :            :                     }
    1800                 :            :                     case MeasureUnit::CM:
    1801                 :            :                     {
    1802                 :            :                         // 0.001cm = 0.57twip (exactly)
    1803                 :         12 :                         fRetval = ((25400.0 / 1440.0) / 10000.0);
    1804                 :         12 :                         psUnit = gpsCM;
    1805                 :         12 :                         break;
    1806                 :            :                     }
    1807                 :            :                     case MeasureUnit::POINT:
    1808                 :            :                     {
    1809                 :            :                         // 0.01pt = 0.2twip (exactly)
    1810                 :          6 :                         fRetval = ((1000.0 / 20.0) / 1000.0);
    1811                 :          6 :                         psUnit = gpsPT;
    1812                 :          6 :                         break;
    1813                 :            :                     }
    1814                 :            :                     case MeasureUnit::INCH:
    1815                 :            :                     default:
    1816                 :            :                     {
    1817                 :            :                         OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for twip values");
    1818                 :            :                         // 0.0001in = 0.144twip (exactly)
    1819                 :          6 :                         fRetval = ((100000.0 / 1440.0) / 100000.0);
    1820                 :          6 :                         psUnit = gpsINCH;
    1821                 :          6 :                         break;
    1822                 :            :                     }
    1823                 :            :                 }
    1824                 :         60 :                 break;
    1825                 :            :             }
    1826                 :            :             case MeasureUnit::POINT:
    1827                 :            :             {
    1828   [ +  +  +  +  :         36 :                 switch(nTargetUnit)
                   +  + ]
    1829                 :            :                 {
    1830                 :            :                     case MeasureUnit::MM_100TH:
    1831                 :            :                     {
    1832                 :            :                         // 1mm = 72 / 25.4 pt (exactly)
    1833                 :          6 :                         fRetval = ( 2540.0 / 72.0 );
    1834                 :          6 :                         break;
    1835                 :            :                     }
    1836                 :            :                     case MeasureUnit::MM_10TH:
    1837                 :            :                     {
    1838                 :            :                         // 1mm = 72 / 25.4 pt (exactly)
    1839                 :          6 :                         fRetval = ( 254.0 / 72.0 );
    1840                 :          6 :                         break;
    1841                 :            :                     }
    1842                 :            :                     case MeasureUnit::MM:
    1843                 :            :                     {
    1844                 :            :                         // 1mm = 72 / 25.4 pt (exactly)
    1845                 :          6 :                         fRetval = ( 25.4 / 72.0 );
    1846                 :          6 :                         psUnit = gpsMM;
    1847                 :          6 :                         break;
    1848                 :            : 
    1849                 :            :                     }
    1850                 :            :                     case MeasureUnit::CM:
    1851                 :            :                     {
    1852                 :            :                         // 1cm = 72 / 2.54 pt (exactly)
    1853                 :          6 :                         fRetval = ( 2.54 / 72.0 );
    1854                 :          6 :                         psUnit = gpsCM;
    1855                 :          6 :                         break;
    1856                 :            :                     }
    1857                 :            :                     case MeasureUnit::TWIP:
    1858                 :            :                     {
    1859                 :            :                         // 1twip = 72 / 1440 pt (exactly)
    1860                 :          6 :                         fRetval = 20.0;     // 1440.0 / 72.0
    1861                 :          6 :                         psUnit = gpsPC;
    1862                 :          6 :                         break;
    1863                 :            :                     }
    1864                 :            :                     case MeasureUnit::INCH:
    1865                 :            :                     default:
    1866                 :            :                     {
    1867                 :            :                         OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for pt values");
    1868                 :            :                         // 1in = 72 pt (exactly)
    1869                 :          6 :                         fRetval = ( 1.0 / 72.0 );
    1870                 :          6 :                         psUnit = gpsINCH;
    1871                 :          6 :                         break;
    1872                 :            :                     }
    1873                 :            :                 }
    1874                 :         36 :                 break;
    1875                 :            :             }
    1876                 :            :             case MeasureUnit::MM_10TH:
    1877                 :            :             {
    1878   [ +  +  +  +  :         36 :                 switch(nTargetUnit)
                   +  + ]
    1879                 :            :                 {
    1880                 :            :                     case MeasureUnit::MM_100TH:
    1881                 :            :                     {
    1882                 :          6 :                         fRetval = 10.0;
    1883                 :          6 :                         break;
    1884                 :            :                     }
    1885                 :            :                     case MeasureUnit::MM:
    1886                 :            :                     {
    1887                 :            :                         // 0.01mm = 1 mm/100 (exactly)
    1888                 :          6 :                         fRetval = ((10.0 / 1.0) / 100.0);
    1889                 :          6 :                         psUnit = gpsMM;
    1890                 :          6 :                         break;
    1891                 :            :                     }
    1892                 :            :                     case MeasureUnit::CM:
    1893                 :            :                     {
    1894                 :          6 :                         fRetval = ((10.0 / 1.0) / 1000.0);
    1895                 :          6 :                         psUnit = gpsCM;
    1896                 :          6 :                         break;
    1897                 :            :                     }
    1898                 :            :                     case MeasureUnit::POINT:
    1899                 :            :                     {
    1900                 :            :                         // 0.01pt = 0.35 mm/100 (exactly)
    1901                 :          6 :                         fRetval = ((72000.0 / 2540.0) / 100.0);
    1902                 :          6 :                         psUnit = gpsPT;
    1903                 :          6 :                         break;
    1904                 :            :                     }
    1905                 :            :                     case MeasureUnit::TWIP:
    1906                 :            :                     {
    1907                 :          6 :                         fRetval = ((20.0 * 72000.0 / 2540.0) / 100.0);
    1908                 :          6 :                         psUnit = gpsPC;
    1909                 :          6 :                         break;
    1910                 :            :                     }
    1911                 :            :                     case MeasureUnit::INCH:
    1912                 :            :                     default:
    1913                 :            :                     {
    1914                 :            :                         OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for 1/10mm values");
    1915                 :            :                         // 0.0001in = 0.254 mm/100 (exactly)
    1916                 :          6 :                         fRetval = ((100000.0 / 2540.0) / 10000.0);
    1917                 :          6 :                         psUnit = gpsINCH;
    1918                 :          6 :                         break;
    1919                 :            :                     }
    1920                 :            :                 }
    1921                 :         36 :                 break;
    1922                 :            :             }
    1923                 :            :             case MeasureUnit::MM_100TH:
    1924                 :            :             {
    1925   [ +  +  +  +  :         72 :                 switch(nTargetUnit)
                   +  + ]
    1926                 :            :                 {
    1927                 :            :                     case MeasureUnit::MM_10TH:
    1928                 :            :                     {
    1929                 :          6 :                         fRetval = ((10.0 / 1.0) / 100.0);
    1930                 :          6 :                         break;
    1931                 :            :                     }
    1932                 :            :                     case MeasureUnit::MM:
    1933                 :            :                     {
    1934                 :            :                         // 0.01mm = 1 mm/100 (exactly)
    1935                 :          6 :                         fRetval = ((10.0 / 1.0) / 1000.0);
    1936                 :          6 :                         psUnit = gpsMM;
    1937                 :          6 :                         break;
    1938                 :            :                     }
    1939                 :            :                     case MeasureUnit::CM:
    1940                 :            :                     {
    1941                 :         42 :                         fRetval = ((10.0 / 1.0) / 10000.0);
    1942                 :         42 :                         psUnit = gpsCM;
    1943                 :         42 :                         break;
    1944                 :            :                     }
    1945                 :            :                     case MeasureUnit::POINT:
    1946                 :            :                     {
    1947                 :            :                         // 0.01pt = 0.35 mm/100 (exactly)
    1948                 :          6 :                         fRetval = ((72000.0 / 2540.0) / 1000.0);
    1949                 :          6 :                         psUnit = gpsPT;
    1950                 :          6 :                         break;
    1951                 :            :                     }
    1952                 :            :                     case MeasureUnit::TWIP:
    1953                 :            :                     {
    1954                 :          6 :                         fRetval = ((20.0 * 72000.0 / 2540.0) / 1000.0);
    1955                 :          6 :                         psUnit = gpsPC;
    1956                 :          6 :                         break;
    1957                 :            :                     }
    1958                 :            :                     case MeasureUnit::INCH:
    1959                 :            :                     default:
    1960                 :            :                     {
    1961                 :            :                         OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for 1/100mm values");
    1962                 :            :                         // 0.0001in = 0.254 mm/100 (exactly)
    1963                 :          6 :                         fRetval = ((100000.0 / 2540.0) / 100000.0);
    1964                 :          6 :                         psUnit = gpsINCH;
    1965                 :          6 :                         break;
    1966                 :            :                     }
    1967                 :            :                 }
    1968                 :         72 :                 break;
    1969                 :            :             }
    1970                 :            :             case MeasureUnit::MM:
    1971                 :            :             {
    1972   [ +  +  +  +  :         36 :                 switch(nTargetUnit)
                   +  + ]
    1973                 :            :                 {
    1974                 :            :                     case MeasureUnit::MM_100TH:
    1975                 :            :                     {
    1976                 :          6 :                         fRetval = 100.0;
    1977                 :          6 :                         break;
    1978                 :            :                     }
    1979                 :            :                     case MeasureUnit::MM_10TH:
    1980                 :            :                     {
    1981                 :          6 :                         fRetval = 10.0;
    1982                 :          6 :                         break;
    1983                 :            :                     }
    1984                 :            :                     case MeasureUnit::CM:
    1985                 :            :                     {
    1986                 :          6 :                         fRetval = 0.1;
    1987                 :          6 :                         psUnit = gpsCM;
    1988                 :          6 :                         break;
    1989                 :            :                     }
    1990                 :            :                     case MeasureUnit::POINT:
    1991                 :            :                     {
    1992                 :          6 :                         fRetval = 72.0 / (2.54 * 10);
    1993                 :          6 :                         psUnit = gpsPT;
    1994                 :          6 :                         break;
    1995                 :            :                     }
    1996                 :            :                     case MeasureUnit::TWIP:
    1997                 :            :                     {
    1998                 :          6 :                         fRetval = (20.0 * 72.0) / (2.54 * 10);
    1999                 :          6 :                         psUnit = gpsPC;
    2000                 :          6 :                         break;
    2001                 :            :                     }
    2002                 :            :                     case MeasureUnit::INCH:
    2003                 :            :                     default:
    2004                 :            :                     {
    2005                 :            :                         OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for cm values");
    2006                 :          6 :                         fRetval = 1 / (2.54 * 10);
    2007                 :          6 :                         psUnit = gpsINCH;
    2008                 :          6 :                         break;
    2009                 :            :                     }
    2010                 :            :                 }
    2011                 :         36 :                 break;
    2012                 :            :             }
    2013                 :            :             case MeasureUnit::CM:
    2014                 :            :             {
    2015   [ -  -  +  -  :         24 :                 switch(nTargetUnit)
                +  +  + ]
    2016                 :            :                 {
    2017                 :            :                     case MeasureUnit::MM_100TH:
    2018                 :            :                     {
    2019                 :          0 :                         fRetval = 1000.0;
    2020                 :          0 :                         break;
    2021                 :            :                     }
    2022                 :            :                     case MeasureUnit::MM_10TH:
    2023                 :            :                     {
    2024                 :          0 :                         fRetval = 100.0;
    2025                 :          0 :                         break;
    2026                 :            :                     }
    2027                 :            :                     case MeasureUnit::MM:
    2028                 :            :                     {
    2029                 :          6 :                         fRetval = 10.0;
    2030                 :          6 :                         psUnit = gpsMM;
    2031                 :          6 :                         break;
    2032                 :            :                     }
    2033                 :            :                     case MeasureUnit::CM:
    2034                 :            :                     {
    2035                 :          0 :                         break;
    2036                 :            :                     }
    2037                 :            :                     case MeasureUnit::POINT:
    2038                 :            :                     {
    2039                 :          6 :                         fRetval = 72.0 / 2.54;
    2040                 :          6 :                         psUnit = gpsPT;
    2041                 :          6 :                         break;
    2042                 :            :                     }
    2043                 :            :                     case MeasureUnit::TWIP:
    2044                 :            :                     {
    2045                 :          6 :                         fRetval = (20.0 * 72.0) / 2.54;
    2046                 :          6 :                         psUnit = gpsPC;
    2047                 :          6 :                         break;
    2048                 :            :                     }
    2049                 :            :                     case MeasureUnit::INCH:
    2050                 :            :                     default:
    2051                 :            :                     {
    2052                 :            :                         OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for cm values");
    2053                 :          6 :                         fRetval = 1 / 2.54;
    2054                 :          6 :                         psUnit = gpsINCH;
    2055                 :          6 :                         break;
    2056                 :            :                     }
    2057                 :            :                 }
    2058                 :         24 :                 break;
    2059                 :            :             }
    2060                 :            :             case MeasureUnit::INCH:
    2061                 :            :             {
    2062   [ -  -  -  +  :         18 :                 switch (nTargetUnit)
                +  +  - ]
    2063                 :            :                 {
    2064                 :            :                     case MeasureUnit::MM_100TH:
    2065                 :            :                     {
    2066                 :          0 :                         fRetval = 2540;
    2067                 :          0 :                         break;
    2068                 :            :                     }
    2069                 :            :                     case MeasureUnit::MM_10TH:
    2070                 :            :                     {
    2071                 :          0 :                         fRetval = 254;
    2072                 :          0 :                         break;
    2073                 :            :                     }
    2074                 :            :                     case MeasureUnit::MM:
    2075                 :            :                     {
    2076                 :          0 :                         fRetval = 25.4;
    2077                 :          0 :                         psUnit = gpsMM;
    2078                 :          0 :                         break;
    2079                 :            :                     }
    2080                 :            :                     case MeasureUnit::CM:
    2081                 :            :                     {
    2082                 :          6 :                         fRetval = 2.54;
    2083                 :          6 :                         psUnit = gpsCM;
    2084                 :          6 :                         break;
    2085                 :            :                     }
    2086                 :            :                     case MeasureUnit::POINT:
    2087                 :            :                     {
    2088                 :          6 :                         fRetval = 72.0;
    2089                 :          6 :                         psUnit = gpsPT;
    2090                 :          6 :                         break;
    2091                 :            :                     }
    2092                 :            :                     case MeasureUnit::TWIP:
    2093                 :            :                     {
    2094                 :          6 :                         fRetval = 72.0 * 20.0;
    2095                 :          6 :                         psUnit = gpsPC;
    2096                 :          6 :                         break;
    2097                 :            :                     }
    2098                 :            :                     default:
    2099                 :            :                     {
    2100                 :            :                         OSL_FAIL("output unit not supported for in values");
    2101                 :          0 :                         fRetval = 1;
    2102                 :          0 :                         psUnit = gpsINCH;
    2103                 :          0 :                         break;
    2104                 :            :                     }
    2105                 :            :                 }
    2106                 :         18 :                 break;
    2107                 :            :             }
    2108                 :            :             default:
    2109                 :            :                 OSL_ENSURE(false, "sax::Converter::GetConversionFactor(): "
    2110                 :            :                         "source unit not supported");
    2111                 :          0 :                 break;
    2112                 :            :         }
    2113                 :            : 
    2114         [ +  + ]:        282 :         if( psUnit )
    2115                 :        222 :             rUnit.appendAscii( psUnit );
    2116                 :            :     }
    2117                 :            : 
    2118                 :       3926 :     return fRetval;
    2119                 :            : }
    2120                 :            : 
    2121                 :       2735 : sal_Int16 Converter::GetUnitFromString(const ::rtl::OUString& rString, sal_Int16 nDefaultUnit)
    2122                 :            : {
    2123                 :       2735 :     sal_Int32 nPos = 0L;
    2124                 :       2735 :     sal_Int32 nLen = rString.getLength();
    2125                 :       2735 :     sal_Int16 nRetUnit = nDefaultUnit;
    2126                 :            : 
    2127                 :            :     // skip white space
    2128 [ +  - ][ -  + ]:       2735 :     while( nPos < nLen && sal_Unicode(' ') == rString[nPos] )
                 [ -  + ]
    2129                 :          0 :         nPos++;
    2130                 :            : 
    2131                 :            :     // skip negative
    2132 [ +  - ][ -  + ]:       2735 :     if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
                 [ -  + ]
    2133                 :          0 :         nPos++;
    2134                 :            : 
    2135                 :            :     // skip number
    2136 [ +  - ][ +  + ]:       8037 :     while( nPos < nLen && sal_Unicode('0') <= rString[nPos] && sal_Unicode('9') >= rString[nPos] )
         [ +  + ][ +  + ]
    2137                 :       5302 :         nPos++;
    2138                 :            : 
    2139 [ +  - ][ +  + ]:       2735 :     if( nPos < nLen && sal_Unicode('.') == rString[nPos] )
                 [ +  + ]
    2140                 :            :     {
    2141                 :        252 :         nPos++;
    2142 [ +  - ][ +  - ]:       2499 :         while( nPos < nLen && sal_Unicode('0') <= rString[nPos] && sal_Unicode('9') >= rString[nPos] )
         [ +  + ][ +  + ]
    2143                 :       2247 :             nPos++;
    2144                 :            :     }
    2145                 :            : 
    2146                 :            :     // skip white space
    2147 [ +  - ][ -  + ]:       2735 :     while( nPos < nLen && sal_Unicode(' ') == rString[nPos] )
                 [ -  + ]
    2148                 :          0 :         nPos++;
    2149                 :            : 
    2150         [ +  - ]:       2735 :     if( nPos < nLen )
    2151                 :            :     {
    2152   [ -  +  -  -  :       2735 :         switch(rString[nPos])
                -  +  - ]
    2153                 :            :         {
    2154                 :            :             case sal_Unicode('%') :
    2155                 :            :             {
    2156                 :          0 :                 nRetUnit = MeasureUnit::PERCENT;
    2157                 :          0 :                 break;
    2158                 :            :             }
    2159                 :            :             case sal_Unicode('c'):
    2160                 :            :             case sal_Unicode('C'):
    2161                 :            :             {
    2162         [ +  - ]:         36 :                 if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('m')
           [ -  +  #  # ]
                 [ +  - ]
    2163                 :          0 :                     || rString[nPos+1] == sal_Unicode('M')))
    2164                 :         36 :                     nRetUnit = MeasureUnit::CM;
    2165                 :         36 :                 break;
    2166                 :            :             }
    2167                 :            :             case sal_Unicode('e'):
    2168                 :            :             case sal_Unicode('E'):
    2169                 :            :             {
    2170                 :            :                 // CSS1_EMS or CSS1_EMX later
    2171                 :          0 :                 break;
    2172                 :            :             }
    2173                 :            :             case sal_Unicode('i'):
    2174                 :            :             case sal_Unicode('I'):
    2175                 :            :             {
    2176         [ #  # ]:          0 :                 if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('n')
           [ #  #  #  # ]
                 [ #  # ]
    2177                 :          0 :                     || rString[nPos+1] == sal_Unicode('n')))
    2178                 :          0 :                     nRetUnit = MeasureUnit::INCH;
    2179                 :          0 :                 break;
    2180                 :            :             }
    2181                 :            :             case sal_Unicode('m'):
    2182                 :            :             case sal_Unicode('M'):
    2183                 :            :             {
    2184         [ #  # ]:          0 :                 if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('m')
           [ #  #  #  # ]
                 [ #  # ]
    2185                 :          0 :                     || rString[nPos+1] == sal_Unicode('M')))
    2186                 :          0 :                     nRetUnit = MeasureUnit::MM;
    2187                 :          0 :                 break;
    2188                 :            :             }
    2189                 :            :             case sal_Unicode('p'):
    2190                 :            :             case sal_Unicode('P'):
    2191                 :            :             {
    2192         [ +  - ]:       2699 :                 if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('t')
           [ -  +  #  # ]
                 [ +  - ]
    2193                 :          0 :                     || rString[nPos+1] == sal_Unicode('T')))
    2194                 :       2699 :                     nRetUnit = MeasureUnit::POINT;
    2195         [ +  - ]:       5398 :                 if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('c')
           [ +  -  -  + ]
                 [ -  + ]
    2196                 :       2699 :                     || rString[nPos+1] == sal_Unicode('C')))
    2197                 :          0 :                     nRetUnit = MeasureUnit::TWIP;
    2198                 :       2735 :                 break;
    2199                 :            :             }
    2200                 :            :         }
    2201                 :            :     }
    2202                 :            : 
    2203                 :       2735 :     return nRetUnit;
    2204                 :            : }
    2205                 :            : 
    2206                 :            : 
    2207                 :          0 : bool Converter::convertAny(::rtl::OUStringBuffer&    rsValue,
    2208                 :            :                            ::rtl::OUStringBuffer&    rsType ,
    2209                 :            :                            const com::sun::star::uno::Any& rValue)
    2210                 :            : {
    2211                 :          0 :     bool bConverted = false;
    2212                 :            : 
    2213                 :          0 :     rsValue.setLength(0);
    2214                 :          0 :     rsType.setLength (0);
    2215                 :            : 
    2216   [ #  #  #  #  :          0 :     switch (rValue.getValueTypeClass())
                   #  # ]
    2217                 :            :     {
    2218                 :            :         case com::sun::star::uno::TypeClass_BYTE :
    2219                 :            :         case com::sun::star::uno::TypeClass_SHORT :
    2220                 :            :         case com::sun::star::uno::TypeClass_UNSIGNED_SHORT :
    2221                 :            :         case com::sun::star::uno::TypeClass_LONG :
    2222                 :            :         case com::sun::star::uno::TypeClass_UNSIGNED_LONG :
    2223                 :            :             {
    2224                 :          0 :                 sal_Int32 nTempValue = 0;
    2225         [ #  # ]:          0 :                 if (rValue >>= nTempValue)
    2226                 :            :                 {
    2227         [ #  # ]:          0 :                     rsType.appendAscii("integer");
    2228                 :          0 :                     bConverted = true;
    2229         [ #  # ]:          0 :                     ::sax::Converter::convertNumber(rsValue, nTempValue);
    2230                 :            :                 }
    2231                 :            :             }
    2232                 :          0 :             break;
    2233                 :            : 
    2234                 :            :         case com::sun::star::uno::TypeClass_BOOLEAN :
    2235                 :            :             {
    2236                 :          0 :                 bool bTempValue = false;
    2237         [ #  # ]:          0 :                 if (rValue >>= bTempValue)
    2238                 :            :                 {
    2239         [ #  # ]:          0 :                     rsType.appendAscii("boolean");
    2240                 :          0 :                     bConverted = true;
    2241         [ #  # ]:          0 :                     ::sax::Converter::convertBool(rsValue, bTempValue);
    2242                 :            :                 }
    2243                 :            :             }
    2244                 :          0 :             break;
    2245                 :            : 
    2246                 :            :         case com::sun::star::uno::TypeClass_FLOAT :
    2247                 :            :         case com::sun::star::uno::TypeClass_DOUBLE :
    2248                 :            :             {
    2249                 :          0 :                 double fTempValue = 0.0;
    2250         [ #  # ]:          0 :                 if (rValue >>= fTempValue)
    2251                 :            :                 {
    2252         [ #  # ]:          0 :                     rsType.appendAscii("float");
    2253                 :          0 :                     bConverted = true;
    2254         [ #  # ]:          0 :                     ::sax::Converter::convertDouble(rsValue, fTempValue);
    2255                 :            :                 }
    2256                 :            :             }
    2257                 :          0 :             break;
    2258                 :            : 
    2259                 :            :         case com::sun::star::uno::TypeClass_STRING :
    2260                 :            :             {
    2261                 :          0 :                 ::rtl::OUString sTempValue;
    2262         [ #  # ]:          0 :                 if (rValue >>= sTempValue)
    2263                 :            :                 {
    2264         [ #  # ]:          0 :                     rsType.appendAscii("string");
    2265                 :          0 :                     bConverted = true;
    2266         [ #  # ]:          0 :                     rsValue.append(sTempValue);
    2267                 :          0 :                 }
    2268                 :            :             }
    2269                 :          0 :             break;
    2270                 :            : 
    2271                 :            :         case com::sun::star::uno::TypeClass_STRUCT :
    2272                 :            :             {
    2273                 :          0 :                 com::sun::star::util::Date     aDate    ;
    2274                 :          0 :                 com::sun::star::util::Time     aTime    ;
    2275                 :          0 :                 com::sun::star::util::DateTime aDateTime;
    2276                 :            : 
    2277 [ #  # ][ #  # ]:          0 :                 if (rValue >>= aDate)
    2278                 :            :                 {
    2279         [ #  # ]:          0 :                     rsType.appendAscii("date");
    2280                 :          0 :                     bConverted = true;
    2281                 :          0 :                     com::sun::star::util::DateTime aTempValue;
    2282                 :          0 :                     aTempValue.Day              = aDate.Day;
    2283                 :          0 :                     aTempValue.Month            = aDate.Month;
    2284                 :          0 :                     aTempValue.Year             = aDate.Year;
    2285                 :          0 :                     aTempValue.HundredthSeconds = 0;
    2286                 :          0 :                     aTempValue.Seconds          = 0;
    2287                 :          0 :                     aTempValue.Minutes          = 0;
    2288                 :          0 :                     aTempValue.Hours            = 0;
    2289         [ #  # ]:          0 :                     ::sax::Converter::convertDateTime(rsValue, aTempValue);
    2290                 :            :                 }
    2291                 :            :                 else
    2292 [ #  # ][ #  # ]:          0 :                 if (rValue >>= aTime)
    2293                 :            :                 {
    2294         [ #  # ]:          0 :                     rsType.appendAscii("time");
    2295                 :          0 :                     bConverted = true;
    2296                 :          0 :                     com::sun::star::util::Duration aTempValue;
    2297                 :          0 :                     aTempValue.Days             = 0;
    2298                 :          0 :                     aTempValue.Months           = 0;
    2299                 :          0 :                     aTempValue.Years            = 0;
    2300                 :          0 :                     aTempValue.MilliSeconds     = aTime.HundredthSeconds * 10;
    2301                 :          0 :                     aTempValue.Seconds          = aTime.Seconds;
    2302                 :          0 :                     aTempValue.Minutes          = aTime.Minutes;
    2303                 :          0 :                     aTempValue.Hours            = aTime.Hours;
    2304         [ #  # ]:          0 :                     ::sax::Converter::convertDuration(rsValue, aTempValue);
    2305                 :            :                 }
    2306                 :            :                 else
    2307 [ #  # ][ #  # ]:          0 :                 if (rValue >>= aDateTime)
    2308                 :            :                 {
    2309         [ #  # ]:          0 :                     rsType.appendAscii("date");
    2310                 :          0 :                     bConverted = true;
    2311         [ #  # ]:          0 :                     ::sax::Converter::convertDateTime(rsValue, aDateTime);
    2312                 :            :                 }
    2313                 :            :             }
    2314                 :          0 :             break;
    2315                 :            :         default:
    2316                 :          0 :             break;
    2317                 :            :     }
    2318                 :            : 
    2319                 :          0 :     return bConverted;
    2320                 :            : }
    2321                 :            : 
    2322                 :            : }
    2323                 :            : 
    2324                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10