LCOV - code coverage report
Current view: top level - libreoffice/sax/source/tools - converter.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 900 1130 79.6 %
Date: 2012-12-17 Functions: 37 42 88.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #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        8964 : 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        8964 :     bool bNeg = false;
      60        8964 :     double nVal = 0;
      61             : 
      62        8964 :     sal_Int32 nPos = 0;
      63        8964 :     sal_Int32 const nLen = rString.getLength();
      64             : 
      65             :     // skip white space
      66       17940 :     while( (nPos < nLen) && (rString[nPos] <= sal_Unicode(' ')) )
      67          12 :         nPos++;
      68             : 
      69        8964 :     if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
      70             :     {
      71         555 :         bNeg = true;
      72         555 :         nPos++;
      73             :     }
      74             : 
      75             :     // get number
      76       58423 :     while( nPos < nLen &&
      77       18719 :            sal_Unicode('0') <= rString[nPos] &&
      78       11815 :            sal_Unicode('9') >= rString[nPos] )
      79             :     {
      80             :         // TODO: check overflow!
      81        9961 :         nVal *= 10;
      82        9961 :         nVal += (rString[nPos] - sal_Unicode('0'));
      83        9961 :         nPos++;
      84             :     }
      85        8964 :     double nDiv = 1.;
      86        8964 :     if( nPos < nLen && sal_Unicode('.') == rString[nPos] )
      87             :     {
      88        6421 :         nPos++;
      89             : 
      90       75475 :         while( nPos < nLen &&
      91       23018 :                sal_Unicode('0') <= rString[nPos] &&
      92       23018 :                sal_Unicode('9') >= rString[nPos] )
      93             :         {
      94             :             // TODO: check overflow!
      95       16597 :             nDiv *= 10;
      96       16597 :             nVal += ( ((double)(rString[nPos] - sal_Unicode('0'))) / nDiv );
      97       16597 :             nPos++;
      98             :         }
      99             :     }
     100             : 
     101             :     // skip white space
     102       17928 :     while( (nPos < nLen) && (rString[nPos] <= sal_Unicode(' ')) )
     103           0 :         nPos++;
     104             : 
     105        8964 :     if( nPos < nLen )
     106             :     {
     107             : 
     108        8758 :         if( MeasureUnit::PERCENT == nTargetUnit )
     109             :         {
     110        1111 :             if( sal_Unicode('%') != rString[nPos] )
     111         662 :                 return false;
     112             :         }
     113        7647 :         else if( MeasureUnit::PIXEL == nTargetUnit )
     114             :         {
     115          12 :             if( nPos + 1 >= nLen ||
     116           4 :                 (sal_Unicode('p') != rString[nPos] &&
     117           0 :                  sal_Unicode('P') != rString[nPos])||
     118           4 :                 (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        7643 :             const sal_Char *aCmpsL[2] = { 0, 0 };
     127        7643 :             const sal_Char *aCmpsU[2] = { 0, 0 };
     128        7643 :             double aScales[2] = { 1., 1. };
     129             : 
     130        7643 :             if( MeasureUnit::TWIP == nTargetUnit )
     131             :             {
     132         138 :                 switch( rString[nPos] )
     133             :                 {
     134             :                 case sal_Unicode('c'):
     135             :                 case sal_Unicode('C'):
     136         138 :                     aCmpsL[0] = "cm";
     137         138 :                     aCmpsU[0] = "CM";
     138         138 :                     aScales[0] = (72.*20.)/2.54; // twip
     139         138 :                     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           0 :                     break;
     162             :                 }
     163             :             }
     164        7505 :             else if( MeasureUnit::MM_100TH == nTargetUnit || MeasureUnit::MM_10TH == nTargetUnit )
     165             :             {
     166        7505 :                 double nScaleFactor = (MeasureUnit::MM_100TH == nTargetUnit) ? 100.0 : 10.0;
     167        7505 :                 switch( rString[nPos] )
     168             :                 {
     169             :                 case sal_Unicode('c'):
     170             :                 case sal_Unicode('C'):
     171        4029 :                     aCmpsL[0] = "cm";
     172        4029 :                     aCmpsU[0] = "CM";
     173        4029 :                     aScales[0] = 10.0 * nScaleFactor; // mm/100
     174        4029 :                     break;
     175             :                 case sal_Unicode('i'):
     176             :                 case sal_Unicode('I'):
     177        2874 :                     aCmpsL[0] = "in";
     178        2874 :                     aCmpsU[0] = "IN";
     179        2874 :                     aScales[0] = 1000.*2.54; // mm/100
     180        2874 :                     break;
     181             :                 case sal_Unicode('m'):
     182             :                 case sal_Unicode('M'):
     183           6 :                     aCmpsL[0] = "mm";
     184           6 :                     aCmpsU[0] = "MM";
     185           6 :                     aScales[0] = 1.0 * nScaleFactor; // mm/100
     186           6 :                     break;
     187             :                 case sal_Unicode('p'):
     188             :                 case sal_Unicode('P'):
     189         562 :                     aCmpsL[0] = "pt";
     190         562 :                     aCmpsU[0] = "PT";
     191         562 :                     aScales[0] = (10.0 * nScaleFactor*2.54)/72.; // mm/100
     192             : 
     193         562 :                     aCmpsL[1] = "pc";
     194         562 :                     aCmpsU[1] = "PC";
     195         562 :                     aScales[1] = (10.0 * nScaleFactor*2.54)/12.; // mm/100
     196         562 :                     break;
     197        7505 :                 }
     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        7643 :             if( aCmpsL[0] == NULL )
     210          34 :                 return false;
     211             : 
     212        7609 :             double nScale = 0.;
     213        7609 :             for( sal_uInt16 i= 0; i < 2; i++ )
     214             :             {
     215        7609 :                 const sal_Char *pL = aCmpsL[i];
     216        7609 :                 if( pL )
     217             :                 {
     218        7609 :                     const sal_Char *pU = aCmpsU[i];
     219       30436 :                     while( nPos < nLen && *pL )
     220             :                     {
     221       15218 :                         sal_Unicode c = rString[nPos];
     222       15218 :                         if( c != *pL && c != *pU )
     223           0 :                             break;
     224       15218 :                         pL++;
     225       15218 :                         pU++;
     226       15218 :                         nPos++;
     227             :                     }
     228        7609 :                     if( !*pL && (nPos == nLen || ' ' == rString[nPos]) )
     229             :                     {
     230        7609 :                         nScale = aScales[i];
     231        7609 :                         break;
     232             :                     }
     233             :                 }
     234             :             }
     235             : 
     236        7609 :             if( 0. == nScale )
     237           0 :                 return false;
     238             : 
     239             :             // TODO: check overflow
     240        7609 :             if( nScale != 1. )
     241        7609 :                 nVal *= nScale;
     242             :         }
     243             :     }
     244             : 
     245        8268 :     nVal += .5;
     246        8268 :     if( bNeg )
     247         541 :         nVal = -nVal;
     248             : 
     249        8268 :     if( nVal <= (double)nMin )
     250           4 :         rValue = nMin;
     251        8264 :     else if( nVal >= (double)nMax )
     252           4 :         rValue = nMax;
     253             :     else
     254        8260 :         rValue = (sal_Int32)nVal;
     255             : 
     256        8268 :     return true;
     257             : }
     258             : 
     259             : /** convert measure in given unit to string with given unit */
     260         426 : void Converter::convertMeasure( OUStringBuffer& rBuffer,
     261             :                                 sal_Int32 nMeasure,
     262             :                                 sal_Int16 nSourceUnit /* = MeasureUnit::MM_100TH */,
     263             :                                 sal_Int16 nTargetUnit /* = MeasureUnit::INCH */  )
     264             : {
     265         426 :     if( nSourceUnit == MeasureUnit::PERCENT )
     266             :     {
     267             :         OSL_ENSURE( nTargetUnit == MeasureUnit::PERCENT,
     268             :                     "MeasureUnit::PERCENT only maps to MeasureUnit::PERCENT!" );
     269             : 
     270           2 :         rBuffer.append( nMeasure );
     271           2 :         rBuffer.append( sal_Unicode('%' ) );
     272             : 
     273         428 :         return;
     274             :     }
     275             :     // the sign is processed seperatly
     276         424 :     if( nMeasure < 0 )
     277             :     {
     278          42 :         nMeasure = -nMeasure;
     279          42 :         rBuffer.append( sal_Unicode('-') );
     280             :     }
     281             : 
     282             :     // The new length is (nVal * nMul)/(nDiv*nFac*10)
     283         424 :     long nMul = 1000;
     284         424 :     long nDiv = 1;
     285         424 :     long nFac = 100;
     286         424 :     const sal_Char* psUnit = 0;
     287         424 :     switch( nSourceUnit )
     288             :     {
     289             :     case MeasureUnit::TWIP:
     290           8 :         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           2 :             nMul = 25400;   // 25.4 * 1000
     298           2 :             nDiv = 1440;    // 72 * 20;
     299           2 :             nFac = 100;
     300           2 :             psUnit = gpsMM;
     301           2 :             break;
     302             : 
     303             :         case MeasureUnit::CM:
     304             :             // 0.001cm = 0.57twip (exactly)
     305           2 :             nMul = 25400;   // 2.54 * 10000
     306           2 :             nDiv = 1440;    // 72 * 20;
     307           2 :             nFac = 1000;
     308           2 :             psUnit = gpsCM;
     309           2 :             break;
     310             : 
     311             :         case MeasureUnit::POINT:
     312             :             // 0.01pt = 0.2twip (exactly)
     313           2 :             nMul = 1000;
     314           2 :             nDiv = 20;
     315           2 :             nFac = 100;
     316           2 :             psUnit = gpsPT;
     317           2 :             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           2 :             nMul = 100000;
     325           2 :             nDiv = 1440;    // 72 * 20;
     326           2 :             nFac = 10000;
     327           2 :             psUnit = gpsINCH;
     328           2 :             break;
     329             :         }
     330           8 :         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         416 :             long nFac2 = (MeasureUnit::MM_100TH == nSourceUnit) ? 100 : 10;
     345         416 :             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           4 :                 nMul = 10;
     354           4 :                 nDiv = 1;
     355           4 :                 nFac = nFac2;
     356           4 :                 psUnit = gpsMM;
     357           4 :                 break;
     358             : 
     359             :             case MeasureUnit::CM:
     360             :                 // 0.001mm = 1 mm/100 (exactly)
     361           4 :                 nMul = 10;
     362           4 :                 nDiv = 1;   // 72 * 20;
     363           4 :                 nFac = 10*nFac2;
     364           4 :                 psUnit = gpsCM;
     365           4 :                 break;
     366             : 
     367             :             case MeasureUnit::POINT:
     368             :                 // 0.01pt = 0.35 mm/100 (exactly)
     369          10 :                 nMul = 72000;
     370          10 :                 nDiv = 2540;
     371          10 :                 nFac = nFac2;
     372          10 :                 psUnit = gpsPT;
     373          10 :                 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         398 :                 nMul = 100000;
     381         398 :                 nDiv = 2540;
     382         398 :                 nFac = 100*nFac2;
     383         398 :                 psUnit = gpsINCH;
     384         398 :                 break;
     385             :             }
     386         416 :             break;
     387             :         }
     388             :     default:
     389             :         OSL_ENSURE(false, "sax::Converter::convertMeasure(): "
     390             :                 "source unit not supported");
     391           0 :         break;
     392             :     }
     393             : 
     394         424 :     sal_Int64 nValue = nMeasure;
     395             :     OSL_ENSURE(nValue <= SAL_MAX_INT64 / nMul, "convertMeasure: overflow");
     396         424 :     nValue *= nMul;
     397         424 :     nValue /= nDiv;
     398         424 :     nValue += 5;
     399         424 :     nValue /= 10;
     400             : 
     401         424 :     rBuffer.append( static_cast<sal_Int64>(nValue / nFac) );
     402         424 :     if (nFac > 1 && (nValue % nFac) != 0)
     403             :     {
     404         316 :         rBuffer.append( sal_Unicode('.') );
     405        1482 :         while (nFac > 1 && (nValue % nFac) != 0)
     406             :         {
     407         850 :             nFac /= 10;
     408         850 :             rBuffer.append( static_cast<sal_Int32>((nValue / nFac) % 10) );
     409             :         }
     410             :     }
     411             : 
     412         424 :     if( psUnit )
     413         424 :         rBuffer.appendAscii( psUnit );
     414             : }
     415             : 
     416        3220 : static const OUString& getTrueString()
     417             : {
     418        3220 :     static const OUString sTrue( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
     419        3220 :     return sTrue;
     420             : }
     421             : 
     422        4253 : static const OUString& getFalseString()
     423             : {
     424        4253 :     static const OUString sFalse( RTL_CONSTASCII_USTRINGPARAM( "false" ) );
     425        4253 :     return sFalse;
     426             : }
     427             : 
     428             : /** convert string to boolean */
     429        1720 : bool Converter::convertBool( bool& rBool, const OUString& rString )
     430             : {
     431        1720 :     rBool = rString == getTrueString();
     432             : 
     433        1720 :     return rBool || (rString == getFalseString());
     434             : }
     435             : 
     436             : /** convert boolean to string */
     437        4978 : void Converter::convertBool( OUStringBuffer& rBuffer, bool bValue )
     438             : {
     439        4978 :     rBuffer.append( bValue ? getTrueString() : getFalseString() );
     440        4978 : }
     441             : 
     442             : /** convert string to percent */
     443        1195 : bool Converter::convertPercent( sal_Int32& rPercent, const OUString& rString )
     444             : {
     445        1195 :     return convertMeasure( rPercent, rString, MeasureUnit::PERCENT );
     446             : }
     447             : 
     448             : /** convert percent to string */
     449          24 : void Converter::convertPercent( OUStringBuffer& rBuffer, sal_Int32 nValue )
     450             : {
     451          24 :     rBuffer.append( nValue );
     452          24 :     rBuffer.append( sal_Unicode('%' ) );
     453          24 : }
     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        7830 : int lcl_gethex( int nChar )
     470             : {
     471        7830 :     if( nChar >= '0' && nChar <= '9' )
     472        6642 :         return nChar - '0';
     473        1188 :     else if( nChar >= 'a' && nChar <= 'f' )
     474        1188 :         return nChar - 'a' + 10;
     475           0 :     else if( nChar >= 'A' && nChar <= 'F' )
     476           0 :         return nChar - 'A' + 10;
     477             :     else
     478           0 :         return 0;
     479             : }
     480             : 
     481             : /** convert string to color */
     482        1949 : bool Converter::convertColor( sal_Int32& rColor, const OUString& rValue )
     483             : {
     484        1949 :     if( rValue.getLength() != 7 || rValue[0] != '#' )
     485         644 :         return false;
     486             : 
     487        1305 :     rColor = lcl_gethex( rValue[1] ) * 16 + lcl_gethex( rValue[2] );
     488        1305 :     rColor <<= 8;
     489             : 
     490        1305 :     rColor |= ( lcl_gethex( rValue[3] ) * 16 + lcl_gethex( rValue[4] ) );
     491        1305 :     rColor <<= 8;
     492             : 
     493        1305 :     rColor |= ( lcl_gethex( rValue[5] ) * 16 + lcl_gethex( rValue[6] ) );
     494             : 
     495        1305 :     return true;
     496             : }
     497             : 
     498             : static sal_Char aHexTab[] = "0123456789abcdef";
     499             : 
     500             : /** convert color to string */
     501          52 : void Converter::convertColor( OUStringBuffer& rBuffer, sal_Int32 nColor )
     502             : {
     503          52 :     rBuffer.append( sal_Unicode( '#' ) );
     504             : 
     505          52 :     sal_uInt8 nCol = (sal_uInt8)(nColor >> 16);
     506          52 :     rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
     507          52 :     rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
     508             : 
     509          52 :     nCol = (sal_uInt8)(nColor >> 8);
     510          52 :     rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
     511          52 :     rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
     512             : 
     513          52 :     nCol = (sal_uInt8)nColor;
     514          52 :     rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
     515          52 :     rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
     516          52 : }
     517             : 
     518             : /** convert number to string */
     519       24103 : void Converter::convertNumber( OUStringBuffer& rBuffer, sal_Int32 nNumber )
     520             : {
     521       24103 :     rBuffer.append( nNumber );
     522       24103 : }
     523             : 
     524             : /** convert string to number with optional min and max values */
     525       11778 : bool Converter::convertNumber(  sal_Int32& rValue,
     526             :                                 const OUString& rString,
     527             :                                 sal_Int32 nMin, sal_Int32 nMax )
     528             : {
     529       11778 :     rValue = 0;
     530       11778 :     sal_Int64 nNumber = 0;
     531       11778 :     sal_Bool bRet = convertNumber64(nNumber,rString,nMin,nMax);
     532       11778 :     if ( bRet )
     533       11744 :         rValue = static_cast<sal_Int32>(nNumber);
     534       11778 :     return bRet;
     535             : }
     536             : 
     537             : /** convert string to 64-bit number with optional min and max values */
     538       11784 : bool Converter::convertNumber64( sal_Int64& rValue,
     539             :                                  const OUString& rString,
     540             :                                  sal_Int64 nMin, sal_Int64 nMax )
     541             : {
     542       11784 :     bool bNeg = false;
     543       11784 :     rValue = 0;
     544             : 
     545       11784 :     sal_Int32 nPos = 0;
     546       11784 :     sal_Int32 const nLen = rString.getLength();
     547             : 
     548             :     // skip white space
     549       23568 :     while( (nPos < nLen) && (rString[nPos] <= sal_Unicode(' ')) )
     550           0 :         nPos++;
     551             : 
     552       11784 :     if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
     553             :     {
     554          98 :         bNeg = true;
     555          98 :         nPos++;
     556             :     }
     557             : 
     558             :     // get number
     559      116201 :     while( nPos < nLen &&
     560       30889 :            sal_Unicode('0') <= rString[nPos] &&
     561       30889 :            sal_Unicode('9') >= rString[nPos] )
     562             :     {
     563             :         // TODO: check overflow!
     564       30855 :         rValue *= 10;
     565       30855 :         rValue += (rString[nPos] - sal_Unicode('0'));
     566       30855 :         nPos++;
     567             :     }
     568             : 
     569       11784 :     if( bNeg )
     570          98 :         rValue *= -1;
     571             : 
     572       11784 :     if( rValue < nMin )
     573           2 :         rValue = nMin;
     574       11782 :     else if( rValue > nMax )
     575           4 :         rValue = nMax;
     576             : 
     577       11784 :     return ( nPos == nLen && rValue >= nMin && rValue <= nMax );
     578             : }
     579             : 
     580             : /** convert double number to string (using ::rtl::math) */
     581         186 : void Converter::convertDouble(  OUStringBuffer& rBuffer,
     582             :                                 double fNumber,
     583             :                                 bool bWriteUnits,
     584             :                                 sal_Int16 nSourceUnit,
     585             :                                 sal_Int16 nTargetUnit)
     586             : {
     587         186 :     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         186 :         OUStringBuffer sUnit;
     597         186 :         double fFactor = GetConversionFactor(sUnit, nSourceUnit, nTargetUnit);
     598         186 :         if(fFactor != 1.0)
     599          82 :             fNumber *= fFactor;
     600         186 :         ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
     601         186 :         if(bWriteUnits)
     602         186 :             rBuffer.append(sUnit.makeStringAndClear());
     603             :     }
     604         186 : }
     605             : 
     606             : /** convert double number to string (using ::rtl::math) */
     607          16 : void Converter::convertDouble( ::rtl::OUStringBuffer& rBuffer, double fNumber)
     608             : {
     609          16 :     ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
     610          16 : }
     611             : 
     612             : /** convert string to double number (using ::rtl::math) */
     613        1351 : bool Converter::convertDouble(double& rValue,
     614             :     const ::rtl::OUString& rString, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
     615             : {
     616             :     rtl_math_ConversionStatus eStatus;
     617        1351 :     rValue = ::rtl::math::stringToDouble( rString, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
     618             : 
     619        1351 :     if(eStatus == rtl_math_ConversionStatus_Ok)
     620             :     {
     621        1351 :         OUStringBuffer sUnit;
     622             :         // fdo#48969: switch source and target because factor is used to divide!
     623             :         double const fFactor =
     624        1351 :             GetConversionFactor(sUnit, nTargetUnit, nSourceUnit);
     625        1351 :         if(fFactor != 1.0 && fFactor != 0.0)
     626         124 :             rValue /= fFactor;
     627             :     }
     628             : 
     629        1351 :     return ( eStatus == rtl_math_ConversionStatus_Ok );
     630             : }
     631             : 
     632             : /** convert string to double number (using ::rtl::math) */
     633        4067 : bool Converter::convertDouble(double& rValue, const ::rtl::OUString& rString)
     634             : {
     635             :     rtl_math_ConversionStatus eStatus;
     636        4067 :     rValue = ::rtl::math::stringToDouble( rString, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
     637        4067 :     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           2 : bool Converter::convertDuration(double& rfTime,
     713             :                                 const ::rtl::OUString& rString)
     714             : {
     715           2 :     rtl::OUString aTrimmed = rString.trim().toAsciiUpperCase();
     716           2 :     const sal_Unicode* pStr = aTrimmed.getStr();
     717             : 
     718             :     // negative time duration?
     719           2 :     bool bIsNegativeDuration = false;
     720           2 :     if ( sal_Unicode('-') == (*pStr) )
     721             :     {
     722           0 :         bIsNegativeDuration = true;
     723           0 :         pStr++;
     724             :     }
     725             : 
     726           2 :     if ( *(pStr++) != sal_Unicode('P') )            // duration must start with "P"
     727           0 :         return false;
     728             : 
     729           2 :     rtl::OUString sDoubleStr;
     730           2 :     bool bSuccess = true;
     731           2 :     bool bDone = false;
     732           2 :     bool bTimePart = false;
     733           2 :     bool bIsFraction = false;
     734           2 :     sal_Int32 nDays  = 0;
     735           2 :     sal_Int32 nHours = 0;
     736           2 :     sal_Int32 nMins  = 0;
     737           2 :     sal_Int32 nSecs  = 0;
     738           2 :     sal_Int32 nTemp = 0;
     739             : 
     740          30 :     while ( bSuccess && !bDone )
     741             :     {
     742          26 :         sal_Unicode c = *(pStr++);
     743          26 :         if ( !c )                               // end
     744           2 :             bDone = true;
     745          24 :         else if ( sal_Unicode('0') <= c && sal_Unicode('9') >= c )
     746             :         {
     747          28 :             if ( nTemp >= SAL_MAX_INT32 / 10 )
     748           0 :                 bSuccess = false;
     749             :             else
     750             :             {
     751          14 :                 if ( !bIsFraction )
     752             :                 {
     753          12 :                     nTemp *= 10;
     754          12 :                     nTemp += (c - sal_Unicode('0'));
     755             :                 }
     756             :                 else
     757             :                 {
     758           2 :                     sDoubleStr += OUString::valueOf(c);
     759             :                 }
     760             :             }
     761             :         }
     762          10 :         else if ( bTimePart )
     763             :         {
     764           8 :             if ( c == sal_Unicode('H') )
     765             :             {
     766           2 :                 nHours = nTemp;
     767           2 :                 nTemp = 0;
     768             :             }
     769           6 :             else if ( c == sal_Unicode('M') )
     770             :             {
     771           2 :                 nMins = nTemp;
     772           2 :                 nTemp = 0;
     773             :             }
     774           4 :             else if ( (c == sal_Unicode(',')) || (c == sal_Unicode('.')) )
     775             :             {
     776           2 :                 nSecs = nTemp;
     777           2 :                 nTemp = 0;
     778           2 :                 bIsFraction = true;
     779           2 :                 sDoubleStr = OUString(RTL_CONSTASCII_USTRINGPARAM("0."));
     780             :             }
     781           2 :             else if ( c == sal_Unicode('S') )
     782             :             {
     783           2 :                 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           0 :                 bSuccess = false;               // invalid character
     792             :         }
     793             :         else
     794             :         {
     795           2 :             if ( c == sal_Unicode('T') )            // "T" starts time part
     796           2 :                 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           2 :     if ( bSuccess )
     815             :     {
     816           2 :         if ( nDays )
     817           0 :             nHours += nDays * 24;               // add the days to the hours part
     818           2 :         double fTempTime = 0.0;
     819           2 :         double fHour = nHours;
     820           2 :         double fMin = nMins;
     821           2 :         double fSec = nSecs;
     822           2 :         double fSec100 = 0.0;
     823           2 :         double fFraction = sDoubleStr.toDouble();
     824           2 :         fTempTime = fHour / 24;
     825           2 :         fTempTime += fMin / (24 * 60);
     826           2 :         fTempTime += fSec / (24 * 60 * 60);
     827           2 :         fTempTime += fSec100 / (24 * 60 * 60 * 60);
     828           2 :         fTempTime += fFraction / (24 * 60 * 60);
     829             : 
     830             :         // negative duration?
     831           2 :         if ( bIsNegativeDuration )
     832             :         {
     833           0 :             fTempTime = -fTempTime;
     834             :         }
     835             : 
     836           2 :         rfTime = fTempTime;
     837             :     }
     838           2 :     return bSuccess;
     839             : }
     840             : 
     841             : /** convert util::Duration to ISO "duration" string */
     842         318 : void Converter::convertDuration(::rtl::OUStringBuffer& rBuffer,
     843             :         const ::util::Duration& rDuration)
     844             : {
     845         318 :     if (rDuration.Negative)
     846             :     {
     847           4 :         rBuffer.append(sal_Unicode('-'));
     848             :     }
     849         318 :     rBuffer.append(sal_Unicode('P'));
     850             :     const bool bHaveDate(static_cast<sal_Int32>(rDuration.Years)
     851             :                         +static_cast<sal_Int32>(rDuration.Months)
     852         318 :                         +static_cast<sal_Int32>(rDuration.Days));
     853         318 :     if (rDuration.Years)
     854             :     {
     855           4 :         rBuffer.append(static_cast<sal_Int32>(rDuration.Years));
     856           4 :         rBuffer.append(sal_Unicode('Y'));
     857             :     }
     858         318 :     if (rDuration.Months)
     859             :     {
     860           6 :         rBuffer.append(static_cast<sal_Int32>(rDuration.Months));
     861           6 :         rBuffer.append(sal_Unicode('M'));
     862             :     }
     863         318 :     if (rDuration.Days)
     864             :     {
     865          38 :         rBuffer.append(static_cast<sal_Int32>(rDuration.Days));
     866          38 :         rBuffer.append(sal_Unicode('D'));
     867             :     }
     868             :     const sal_Int32 nMSecs(static_cast<sal_Int32>(rDuration.Seconds)
     869         318 :                          + static_cast<sal_Int32>(rDuration.MilliSeconds));
     870         318 :     if (static_cast<sal_Int32>(rDuration.Hours) +
     871             :         static_cast<sal_Int32>(rDuration.Minutes) + nMSecs)
     872             :     {
     873         196 :         rBuffer.append(sal_Unicode('T')); // time separator
     874         196 :         if (rDuration.Hours)
     875             :         {
     876          46 :             rBuffer.append(static_cast<sal_Int32>(rDuration.Hours));
     877          46 :             rBuffer.append(sal_Unicode('H'));
     878             :         }
     879         196 :         if (rDuration.Minutes)
     880             :         {
     881         106 :             rBuffer.append(static_cast<sal_Int32>(rDuration.Minutes));
     882         106 :             rBuffer.append(sal_Unicode('M'));
     883             :         }
     884         196 :         if (nMSecs)
     885             :         {
     886             :             // seconds must not be omitted (i.e. ".42S" is not valid)
     887         150 :             rBuffer.append(static_cast<sal_Int32>(rDuration.Seconds));
     888         150 :             if (rDuration.MilliSeconds)
     889             :             {
     890          10 :                 rBuffer.append(sal_Unicode('.'));
     891          10 :                 const sal_Int32 nMilliSeconds(rDuration.MilliSeconds % 1000);
     892          10 :                 if (nMilliSeconds < 100)
     893             :                 {
     894           6 :                     rBuffer.append(sal_Unicode('0'));
     895             :                 }
     896          10 :                 if (nMilliSeconds < 10)
     897             :                 {
     898           2 :                     rBuffer.append(sal_Unicode('0'));
     899             :                 }
     900          10 :                 if (0 == (nMilliSeconds % 10))
     901             :                 {
     902           6 :                     if (0 == (nMilliSeconds % 100))
     903             :                     {
     904           0 :                         rBuffer.append(nMilliSeconds / 100);
     905             :                     }
     906             :                     else
     907             :                     {
     908           6 :                         rBuffer.append(nMilliSeconds / 10);
     909             :                     }
     910             :                 }
     911             :                 else
     912             :                 {
     913           4 :                     rBuffer.append(nMilliSeconds);
     914             :                 }
     915             :             }
     916         150 :             rBuffer.append(sal_Unicode('S'));
     917             :         }
     918             :     }
     919         122 :     else if (!bHaveDate)
     920             :     {
     921             :         // zero duration: XMLSchema-2 says there must be at least one component
     922         114 :         rBuffer.append(sal_Unicode('0'));
     923         114 :         rBuffer.append(sal_Unicode('D'));
     924             :     }
     925         318 : }
     926             : 
     927             : enum Result { R_NOTHING, R_OVERFLOW, R_SUCCESS };
     928             : 
     929             : static Result
     930        6816 : readUnsignedNumber(const ::rtl::OUString & rString,
     931             :     sal_Int32 & io_rnPos, sal_Int32 & o_rNumber)
     932             : {
     933        6816 :     bool bOverflow(false);
     934        6816 :     sal_Int32 nTemp(0);
     935        6816 :     sal_Int32 nPos(io_rnPos);
     936             : 
     937       17980 :     while (nPos < rString.getLength())
     938             :     {
     939        5838 :         const sal_Unicode c = rString[nPos];
     940        5838 :         if ((sal_Unicode('0') <= c) && (c <= sal_Unicode('9')))
     941             :         {
     942        4348 :             nTemp *= 10;
     943        4348 :             nTemp += (c - sal_Unicode('0'));
     944        8696 :             if (nTemp >= SAL_MAX_INT16)
     945             :             {
     946         108 :                 bOverflow = true;
     947             :             }
     948             :         }
     949             :         else
     950             :         {
     951        1490 :             break;
     952             :         }
     953        4348 :         ++nPos;
     954             :     }
     955             : 
     956        6816 :     if (io_rnPos == nPos) // read something?
     957             :     {
     958        5038 :         o_rNumber = -1;
     959        5038 :         return R_NOTHING;
     960             :     }
     961             : 
     962        1778 :     io_rnPos = nPos;
     963        1778 :     o_rNumber = nTemp;
     964        1778 :     return (bOverflow) ? R_OVERFLOW : R_SUCCESS;
     965             : }
     966             : 
     967             : static bool
     968        2533 : readDurationT(const ::rtl::OUString & rString, sal_Int32 & io_rnPos)
     969             : {
     970        2659 :     if ((io_rnPos < rString.getLength()) &&
     971         126 :         (rString[io_rnPos] == sal_Unicode('T')))
     972             :     {
     973          54 :         ++io_rnPos;
     974          54 :         return true;
     975             :     }
     976        2479 :     return false;
     977             : }
     978             : 
     979             : static bool
     980         264 : 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         264 :     if ((io_rnPos < rString.getLength()))
     985             :     {
     986         256 :         if (c == rString[io_rnPos])
     987             :         {
     988          90 :             ++io_rnPos;
     989          90 :             if (-1 != io_rnTemp)
     990             :             {
     991          90 :                 o_rnTarget = io_rnTemp;
     992          90 :                 io_rnTemp = -1;
     993          90 :                 if (!io_rbTimePart)
     994             :                 {
     995          64 :                     io_rbTimePart = readDurationT(rString, io_rnPos);
     996             :                 }
     997             :                 return (R_OVERFLOW !=
     998          90 :                         readUnsignedNumber(rString, io_rnPos, io_rnTemp));
     999             :             }
    1000             :             else
    1001             :             {
    1002           0 :                 return false;
    1003             :             }
    1004             :         }
    1005             :     }
    1006         174 :     return true;
    1007             : }
    1008             : 
    1009             : /** convert ISO "duration" string to util::Duration */
    1010        2471 : bool Converter::convertDuration(util::Duration& rDuration,
    1011             :                                 const ::rtl::OUString& rString)
    1012             : {
    1013        2471 :     const ::rtl::OUString string = rString.trim().toAsciiUpperCase();
    1014        2471 :     sal_Int32 nPos(0);
    1015             : 
    1016        2471 :     bool bIsNegativeDuration(false);
    1017        2471 :     if (!string.isEmpty() && (sal_Unicode('-') == string[0]))
    1018             :     {
    1019           4 :         bIsNegativeDuration = true;
    1020           4 :         ++nPos;
    1021             :     }
    1022             : 
    1023        2579 :     if ((nPos < string.getLength())
    1024         108 :         && (string[nPos] != sal_Unicode('P'))) // duration must start with "P"
    1025             :     {
    1026           2 :         return false;
    1027             :     }
    1028             : 
    1029        2469 :     ++nPos;
    1030             : 
    1031             :     /// last read number; -1 == no valid number! always reset after using!
    1032        2469 :     sal_Int32 nTemp(-1);
    1033        2469 :     bool bTimePart(false); // have we read 'T'?
    1034        2469 :     bool bSuccess(false);
    1035        2469 :     sal_Int32 nYears(0);
    1036        2469 :     sal_Int32 nMonths(0);
    1037        2469 :     sal_Int32 nDays(0);
    1038        2469 :     sal_Int32 nHours(0);
    1039        2469 :     sal_Int32 nMinutes(0);
    1040        2469 :     sal_Int32 nSeconds(0);
    1041        2469 :     sal_Int32 nMilliSeconds(0);
    1042             : 
    1043        2469 :     bTimePart = readDurationT(string, nPos);
    1044        2469 :     bSuccess = (R_SUCCESS == readUnsignedNumber(string, nPos, nTemp));
    1045             : 
    1046        2469 :     if (!bTimePart && bSuccess)
    1047             :     {
    1048             :         bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1049          58 :                      nYears, sal_Unicode('Y'));
    1050             :     }
    1051             : 
    1052        2469 :     if (!bTimePart && bSuccess)
    1053             :     {
    1054             :         bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1055          54 :                      nMonths, sal_Unicode('M'));
    1056             :     }
    1057             : 
    1058        2469 :     if (!bTimePart && bSuccess)
    1059             :     {
    1060             :         bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1061          52 :                      nDays, sal_Unicode('D'));
    1062             :     }
    1063             : 
    1064        2469 :     if (bTimePart)
    1065             :     {
    1066          54 :         if (-1 == nTemp) // a 'T' must be followed by a component
    1067             :         {
    1068           4 :             bSuccess = false;
    1069             :         }
    1070             : 
    1071          54 :         if (bSuccess)
    1072             :         {
    1073             :             bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1074          50 :                          nHours, sal_Unicode('H'));
    1075             :         }
    1076             : 
    1077          54 :         if (bSuccess)
    1078             :         {
    1079             :             bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
    1080          50 :                          nMinutes, sal_Unicode('M'));
    1081             :         }
    1082             : 
    1083             :         // eeek! seconds are icky.
    1084          54 :         if ((nPos < string.getLength()) && bSuccess)
    1085             :         {
    1086          40 :             if (sal_Unicode('.') == string[nPos])
    1087             :             {
    1088          18 :                 ++nPos;
    1089          18 :                 if (-1 != nTemp)
    1090             :                 {
    1091          16 :                     nSeconds = nTemp;
    1092          16 :                     nTemp = -1;
    1093          16 :                     const sal_Int32 nStart(nPos);
    1094             :                     bSuccess =
    1095          16 :                         (R_NOTHING != readUnsignedNumber(string, nPos, nTemp));
    1096          16 :                     if ((nPos < string.getLength()) && bSuccess)
    1097             :                     {
    1098          14 :                         if (-1 != nTemp)
    1099             :                         {
    1100          14 :                             nTemp = -1;
    1101          14 :                             const sal_Int32 nDigits = nPos - nStart;
    1102             :                             OSL_ENSURE(nDigits > 0, "bad code monkey");
    1103          14 :                             const sal_Unicode cZero('0');
    1104          14 :                             nMilliSeconds = 100 * (string[nStart] - cZero);
    1105          14 :                             if (nDigits >= 2)
    1106             :                             {
    1107             :                                 nMilliSeconds += 10 *
    1108          14 :                                     (string[nStart+1] - cZero);
    1109          14 :                                 if (nDigits >= 3)
    1110             :                                 {
    1111           4 :                                     nMilliSeconds += (string[nStart+2] - cZero);
    1112             :                                 }
    1113             :                             }
    1114             : 
    1115          14 :                             if (sal_Unicode('S') == string[nPos])
    1116             :                             {
    1117          14 :                                 ++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           2 :                     bSuccess = false;
    1133             :                 }
    1134             :             }
    1135          22 :             else if (sal_Unicode('S') == string[nPos])
    1136             :             {
    1137          18 :                 ++nPos;
    1138          18 :                 if (-1 != nTemp)
    1139             :                 {
    1140          18 :                     nSeconds = nTemp;
    1141          18 :                     nTemp = -1;
    1142             :                 }
    1143             :                 else
    1144             :                 {
    1145           0 :                     bSuccess = false;
    1146             :                 }
    1147             :             }
    1148             :         }
    1149             :     }
    1150             : 
    1151        2469 :     if (nPos != string.getLength()) // string not processed completely?
    1152             :     {
    1153        2381 :         bSuccess = false;
    1154             :     }
    1155             : 
    1156        2469 :     if (nTemp != -1) // unprocessed number?
    1157             :     {
    1158           8 :         bSuccess = false;
    1159             :     }
    1160             : 
    1161        2469 :     if (bSuccess)
    1162             :     {
    1163          86 :         rDuration.Negative      = bIsNegativeDuration;
    1164          86 :         rDuration.Years         = static_cast<sal_Int16>(nYears);
    1165          86 :         rDuration.Months        = static_cast<sal_Int16>(nMonths);
    1166          86 :         rDuration.Days          = static_cast<sal_Int16>(nDays);
    1167          86 :         rDuration.Hours         = static_cast<sal_Int16>(nHours);
    1168          86 :         rDuration.Minutes       = static_cast<sal_Int16>(nMinutes);
    1169          86 :         rDuration.Seconds       = static_cast<sal_Int16>(nSeconds);
    1170          86 :         rDuration.MilliSeconds  = static_cast<sal_Int16>(nMilliSeconds);
    1171             :     }
    1172             : 
    1173        2469 :     return bSuccess;
    1174             : }
    1175             : 
    1176             : 
    1177             : /** convert util::Date to ISO "date" string */
    1178           0 : void Converter::convertDate(
    1179             :         ::rtl::OUStringBuffer& i_rBuffer,
    1180             :         const util::Date& i_rDate)
    1181             : {
    1182             :     const util::DateTime dt(
    1183           0 :             0, 0, 0, 0, i_rDate.Day, i_rDate.Month, i_rDate.Year);
    1184           0 :     convertDateTime(i_rBuffer, dt, false);
    1185           0 : }
    1186             : 
    1187             : /** convert util::DateTime to ISO "date" or "dateTime" string */
    1188         659 : void Converter::convertDateTime(
    1189             :         ::rtl::OUStringBuffer& i_rBuffer,
    1190             :         const com::sun::star::util::DateTime& i_rDateTime,
    1191             :         bool i_bAddTimeIf0AM )
    1192             : {
    1193         659 :     const sal_Unicode dash('-');
    1194         659 :     const sal_Unicode col (':');
    1195         659 :     const sal_Unicode dot ('.');
    1196         659 :     const sal_Unicode zero('0');
    1197         659 :     const sal_Unicode tee ('T');
    1198             : 
    1199         659 :     if (i_rDateTime.Year < 1000) {
    1200          16 :         i_rBuffer.append(zero);
    1201             :     }
    1202         659 :     if (i_rDateTime.Year < 100) {
    1203          14 :         i_rBuffer.append(zero);
    1204             :     }
    1205         659 :     if (i_rDateTime.Year < 10) {
    1206          14 :         i_rBuffer.append(zero);
    1207             :     }
    1208         659 :     i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Year)  ).append(dash);
    1209         659 :     if( i_rDateTime.Month < 10 ) {
    1210         488 :         i_rBuffer.append(zero);
    1211             :     }
    1212         659 :     i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Month) ).append(dash);
    1213         659 :     if( i_rDateTime.Day   < 10 ) {
    1214         188 :         i_rBuffer.append(zero);
    1215             :     }
    1216         659 :     i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Day)   );
    1217             : 
    1218         659 :     if( i_rDateTime.Seconds != 0 ||
    1219             :         i_rDateTime.Minutes != 0 ||
    1220             :         i_rDateTime.Hours   != 0 ||
    1221             :         i_bAddTimeIf0AM )
    1222             :     {
    1223         655 :         i_rBuffer.append(tee);
    1224         655 :         if( i_rDateTime.Hours   < 10 ) {
    1225         142 :             i_rBuffer.append(zero);
    1226             :         }
    1227         655 :         i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Hours)   )
    1228         655 :                  .append(col);
    1229         655 :         if( i_rDateTime.Minutes < 10 ) {
    1230          90 :             i_rBuffer.append(zero);
    1231             :         }
    1232         655 :         i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Minutes) )
    1233         655 :                  .append(col);
    1234         655 :         if( i_rDateTime.Seconds < 10 ) {
    1235         443 :             i_rBuffer.append(zero);
    1236             :         }
    1237         655 :         i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Seconds) );
    1238         655 :         if( i_rDateTime.HundredthSeconds > 0 ) {
    1239           8 :             i_rBuffer.append(dot);
    1240           8 :             if( i_rDateTime.HundredthSeconds < 10 ) {
    1241           0 :                 i_rBuffer.append(zero);
    1242             :             }
    1243             :             i_rBuffer.append(
    1244           8 :                 static_cast<sal_Int32>(i_rDateTime.HundredthSeconds) );
    1245             :         }
    1246             :     }
    1247         659 : }
    1248             : 
    1249             : /** convert ISO "date" or "dateTime" string to util::DateTime */
    1250        2953 : bool Converter::convertDateTime( util::DateTime& rDateTime,
    1251             :                                  const ::rtl::OUString& rString )
    1252             : {
    1253             :     bool isDateTime;
    1254        2953 :     util::Date date;
    1255        2953 :     if (convertDateOrDateTime(date, rDateTime, isDateTime, rString))
    1256             :     {
    1257         290 :         if (!isDateTime)
    1258             :         {
    1259         132 :             rDateTime.Year = date.Year;
    1260         132 :             rDateTime.Month = date.Month;
    1261         132 :             rDateTime.Day = date.Day;
    1262         132 :             rDateTime.Hours = 0;
    1263         132 :             rDateTime.Minutes = 0;
    1264         132 :             rDateTime.Seconds = 0;
    1265         132 :             rDateTime.HundredthSeconds = 0;
    1266             :         }
    1267         290 :         return true;
    1268             :     }
    1269             :     else
    1270             :     {
    1271        2663 :         return false;
    1272             :     }
    1273             : }
    1274             : 
    1275             : static bool
    1276        4217 : readDateTimeComponent(const ::rtl::OUString & rString,
    1277             :     sal_Int32 & io_rnPos, sal_Int32 & o_rnTarget,
    1278             :     const sal_Int32 nMinLength, const bool bExactLength)
    1279             : {
    1280        4217 :     const sal_Int32 nOldPos(io_rnPos);
    1281        4217 :     sal_Int32 nTemp(0);
    1282        4217 :     if (R_SUCCESS != readUnsignedNumber(rString, io_rnPos, nTemp))
    1283             :     {
    1284        2607 :         return false;
    1285             :     }
    1286        1610 :     const sal_Int32 nTokenLength(io_rnPos - nOldPos);
    1287        1610 :     if ((nTokenLength < nMinLength) ||
    1288             :         (bExactLength && (nTokenLength > nMinLength)))
    1289             :     {
    1290          14 :         return false; // bad length
    1291             :     }
    1292        1596 :     o_rnTarget = nTemp;
    1293        1596 :     return true;
    1294             : }
    1295             : 
    1296          32 : static bool lcl_isLeapYear(const sal_uInt32 nYear)
    1297             : {
    1298             :     return ((nYear % 4) == 0)
    1299          32 :         && (((nYear % 100) != 0) || ((nYear % 400) == 0));
    1300             : }
    1301             : 
    1302             : static sal_uInt16
    1303         328 : 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         328 :     if ((2 == nMonth) && lcl_isLeapYear(nYear))
    1309             :     {
    1310          28 :         return 29;
    1311             :     }
    1312         300 :     return s_MaxDaysPerMonth[nMonth - 1];
    1313             : }
    1314             : 
    1315             : /** convert ISO "date" or "dateTime" string to util::DateTime or util::Date */
    1316        2953 : bool Converter::convertDateOrDateTime(
    1317             :                 util::Date & rDate, util::DateTime & rDateTime,
    1318             :                 bool & rbDateTime, const ::rtl::OUString & rString )
    1319             : {
    1320        2953 :     bool bSuccess = true;
    1321             : 
    1322        2953 :     const ::rtl::OUString string = rString.trim().toAsciiUpperCase();
    1323        2953 :     sal_Int32 nPos(0);
    1324        2953 :     if (string.getLength() > nPos)
    1325             :     {
    1326         348 :         if (sal_Unicode('-') == string[nPos])
    1327             :         {
    1328             :             //Negative Number
    1329           0 :             ++nPos;
    1330             :         }
    1331             :     }
    1332             : 
    1333        2953 :     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        2953 :         bSuccess = readDateTimeComponent(string, nPos, nYear, 1, false);
    1339        2953 :         bSuccess &= (0 < nYear);
    1340        2953 :         bSuccess &= (nPos < string.getLength()); // not last token
    1341             :     }
    1342        2953 :     if (bSuccess && (sal_Unicode('-') != string[nPos])) // separator
    1343             :     {
    1344           0 :         bSuccess = false;
    1345             :     }
    1346        2953 :     if (bSuccess)
    1347             :     {
    1348         334 :         ++nPos;
    1349             :     }
    1350             : 
    1351        2953 :     sal_Int32 nMonth(0);
    1352        2953 :     if (bSuccess)
    1353             :     {
    1354         334 :         bSuccess = readDateTimeComponent(string, nPos, nMonth, 2, true);
    1355         334 :         bSuccess &= (0 < nMonth) && (nMonth <= 12);
    1356         334 :         bSuccess &= (nPos < string.getLength()); // not last token
    1357             :     }
    1358        2953 :     if (bSuccess && (sal_Unicode('-') != string[nPos])) // separator
    1359             :     {
    1360           0 :         bSuccess = false;
    1361             :     }
    1362        2953 :     if (bSuccess)
    1363             :     {
    1364         330 :         ++nPos;
    1365             :     }
    1366             : 
    1367        2953 :     sal_Int32 nDay(0);
    1368        2953 :     if (bSuccess)
    1369             :     {
    1370         330 :         bSuccess = readDateTimeComponent(string, nPos, nDay, 2, true);
    1371         330 :         bSuccess &= (0 < nDay) && (nDay <= lcl_MaxDaysPerMonth(nMonth, nYear));
    1372             :     }
    1373             : 
    1374        2953 :     bool bHaveTime(false);
    1375        2953 :     if (bSuccess && (nPos < string.getLength()))
    1376             :     {
    1377         190 :         if (sal_Unicode('T') == string[nPos]) // time separator
    1378             :         {
    1379         190 :             bHaveTime = true;
    1380         190 :             ++nPos;
    1381             :         }
    1382             :     }
    1383             : 
    1384        2953 :     sal_Int32 nHours(0);
    1385        2953 :     sal_Int32 nMinutes(0);
    1386        2953 :     sal_Int32 nSeconds(0);
    1387        2953 :     sal_Int32 nMilliSeconds(0);
    1388        2953 :     if (bSuccess && bHaveTime)
    1389             :     {
    1390             :         {
    1391         190 :             bSuccess = readDateTimeComponent(string, nPos, nHours, 2, true);
    1392         190 :             bSuccess &= (0 <= nHours) && (nHours <= 24);
    1393         190 :             bSuccess &= (nPos < string.getLength()); // not last token
    1394             :         }
    1395         190 :         if (bSuccess && (sal_Unicode(':') != string[nPos])) // separator
    1396             :         {
    1397           0 :             bSuccess = false;
    1398             :         }
    1399         190 :         if (bSuccess)
    1400             :         {
    1401         186 :             ++nPos;
    1402             :         }
    1403             : 
    1404         190 :         if (bSuccess)
    1405             :         {
    1406         186 :             bSuccess = readDateTimeComponent(string, nPos, nMinutes, 2, true);
    1407         186 :             bSuccess &= (0 <= nMinutes) && (nMinutes < 60);
    1408         186 :             bSuccess &= (nPos < string.getLength()); // not last token
    1409             :         }
    1410         190 :         if (bSuccess && (sal_Unicode(':') != string[nPos])) // separator
    1411             :         {
    1412           0 :             bSuccess = false;
    1413             :         }
    1414         190 :         if (bSuccess)
    1415             :         {
    1416         182 :             ++nPos;
    1417             :         }
    1418             : 
    1419         190 :         if (bSuccess)
    1420             :         {
    1421         182 :             bSuccess = readDateTimeComponent(string, nPos, nSeconds, 2, true);
    1422         182 :             bSuccess &= (0 <= nSeconds) && (nSeconds < 60);
    1423             :         }
    1424         240 :         if (bSuccess && (nPos < string.getLength()) &&
    1425          50 :             (sal_Unicode('.') == string[nPos])) // fraction separator
    1426             :         {
    1427          24 :             ++nPos;
    1428          24 :             const sal_Int32 nStart(nPos);
    1429          24 :             sal_Int32 nTemp(0);
    1430          24 :             if (R_NOTHING == readUnsignedNumber(string, nPos, nTemp))
    1431             :             {
    1432           2 :                 bSuccess = false;
    1433             :             }
    1434          24 :             if (bSuccess)
    1435             :             {
    1436             :                 // cannot use nTemp because of possible leading zeros
    1437             :                 // and possible overflow => read digits directly
    1438          22 :                 const sal_Int32 nDigits(nPos - nStart);
    1439             :                 OSL_ENSURE(nDigits > 0, "bad code monkey");
    1440          22 :                 const sal_Unicode cZero('0');
    1441          22 :                 nMilliSeconds = 100 * (string[nStart] - cZero);
    1442          22 :                 if (nDigits >= 2)
    1443             :                 {
    1444          20 :                     nMilliSeconds += 10 * (string[nStart+1] - cZero);
    1445          20 :                     if (nDigits >= 3)
    1446             :                     {
    1447           4 :                         nMilliSeconds += (string[nStart+2] - cZero);
    1448             :                     }
    1449             :                 }
    1450             :             }
    1451             :         }
    1452             : 
    1453         190 :         if (bSuccess && (nHours == 24))
    1454             :         {
    1455           8 :             if (!((0 == nMinutes) && (0 == nSeconds) && (0 == nMilliSeconds)))
    1456             :             {
    1457           6 :                 bSuccess = false; // only 24:00:00 is valid
    1458             :             }
    1459             :         }
    1460             :     }
    1461             : 
    1462        2953 :     bool bHaveTimezone(false);
    1463        2953 :     bool bHaveTimezonePlus(false);
    1464        2953 :     bool bHaveTimezoneMinus(false);
    1465        2953 :     if (bSuccess && (nPos < string.getLength()))
    1466             :     {
    1467          30 :         const sal_Unicode c(string[nPos]);
    1468          30 :         if (sal_Unicode('+') == c)
    1469             :         {
    1470          12 :             bHaveTimezone = true;
    1471          12 :             bHaveTimezonePlus = true;
    1472          12 :             ++nPos;
    1473             :         }
    1474          18 :         else if (sal_Unicode('-') == c)
    1475             :         {
    1476          12 :             bHaveTimezone = true;
    1477          12 :             bHaveTimezoneMinus = true;
    1478          12 :             ++nPos;
    1479             :         }
    1480           6 :         else if (sal_Unicode('Z') == c)
    1481             :         {
    1482           6 :             bHaveTimezone = true;
    1483           6 :             ++nPos;
    1484             :         }
    1485             :         else
    1486             :         {
    1487           0 :             bSuccess = false;
    1488             :         }
    1489             :     }
    1490        2953 :     sal_Int32 nTimezoneHours(0);
    1491        2953 :     sal_Int32 nTimezoneMinutes(0);
    1492        2953 :     if (bSuccess && (bHaveTimezonePlus || bHaveTimezoneMinus))
    1493             :     {
    1494             :         bSuccess = readDateTimeComponent(
    1495          24 :                         string, nPos, nTimezoneHours, 2, true);
    1496          24 :         bSuccess &= (0 <= nTimezoneHours) && (nTimezoneHours <= 14);
    1497          24 :         bSuccess &= (nPos < string.getLength()); // not last token
    1498          24 :         if (bSuccess && (sal_Unicode(':') != string[nPos])) // separator
    1499             :         {
    1500           0 :             bSuccess = false;
    1501             :         }
    1502          24 :         if (bSuccess)
    1503             :         {
    1504          18 :             ++nPos;
    1505             :         }
    1506          24 :         if (bSuccess)
    1507             :         {
    1508             :             bSuccess = readDateTimeComponent(
    1509          18 :                         string, nPos, nTimezoneMinutes, 2, true);
    1510          18 :             bSuccess &= (0 <= nTimezoneMinutes) && (nTimezoneMinutes < 60);
    1511             :         }
    1512          24 :         if (bSuccess && (nTimezoneHours == 14))
    1513             :         {
    1514           4 :             if (0 != nTimezoneMinutes)
    1515             :             {
    1516           4 :                 bSuccess = false; // only +-14:00 is valid
    1517             :             }
    1518             :         }
    1519             :     }
    1520             : 
    1521        2953 :     bSuccess &= (nPos == string.getLength()); // trailing junk?
    1522             : 
    1523             :     if (bSuccess && bHaveTimezone)
    1524             :     {
    1525             :         // util::DateTime does not support timezones!
    1526             :     }
    1527             : 
    1528        2953 :     if (bSuccess)
    1529             :     {
    1530         290 :         if (bHaveTime) // time is optional
    1531             :         {
    1532             :             // util::DateTime does not support negative years!
    1533         158 :             rDateTime.Year = static_cast<sal_uInt16>(nYear);
    1534         158 :             rDateTime.Month = static_cast<sal_uInt16>(nMonth);
    1535         158 :             rDateTime.Day = static_cast<sal_uInt16>(nDay);
    1536         158 :             rDateTime.Hours = static_cast<sal_uInt16>(nHours);
    1537         158 :             rDateTime.Minutes = static_cast<sal_uInt16>(nMinutes);
    1538         158 :             rDateTime.Seconds = static_cast<sal_uInt16>(nSeconds);
    1539             :             // util::DateTime does not support 3 decimal digits of precision!
    1540             :             rDateTime.HundredthSeconds =
    1541         158 :                 static_cast<sal_uInt16>(nMilliSeconds / 10);
    1542         158 :             rbDateTime = true;
    1543             :         }
    1544             :         else
    1545             :         {
    1546         132 :             rDate.Year = static_cast<sal_uInt16>(nYear);
    1547         132 :             rDate.Month = static_cast<sal_uInt16>(nMonth);
    1548         132 :             rDate.Day = static_cast<sal_uInt16>(nDay);
    1549         132 :             rbDateTime = false;
    1550             :         }
    1551             :     }
    1552        2953 :     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        1342 : sal_Int32 Converter::indexOfComma( const OUString& rStr,
    1559             :                                             sal_Int32 nPos )
    1560             : {
    1561        1342 :     sal_Unicode cQuote = 0;
    1562        1342 :     sal_Int32 nLen = rStr.getLength();
    1563       18672 :     for( ; nPos < nLen; nPos++ )
    1564             :     {
    1565       17402 :         sal_Unicode c = rStr[nPos];
    1566       17402 :         switch( c )
    1567             :         {
    1568             :         case sal_Unicode('\''):
    1569        1540 :             if( 0 == cQuote )
    1570         770 :                 cQuote = c;
    1571         770 :             else if( '\'' == cQuote )
    1572         770 :                 cQuote = 0;
    1573        1540 :             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          72 :             if( 0 == cQuote )
    1584          72 :                 return nPos;
    1585           0 :             break;
    1586             :         }
    1587             :     }
    1588             : 
    1589        1270 :     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         202 : void ThreeByteToFourByte (const sal_Int8* pBuffer, const sal_Int32 nStart, const sal_Int32 nFullLen, rtl::OUStringBuffer& sBuffer)
    1623             : {
    1624         202 :     sal_Int32 nLen(nFullLen - nStart);
    1625         202 :     if (nLen > 3)
    1626         172 :         nLen = 3;
    1627         202 :     if (nLen == 0)
    1628             :     {
    1629         202 :         return;
    1630             :     }
    1631             : 
    1632             :     sal_Int32 nBinaer;
    1633         202 :     switch (nLen)
    1634             :     {
    1635             :         case 1:
    1636             :         {
    1637          16 :             nBinaer = ((sal_uInt8)pBuffer[nStart + 0]) << 16;
    1638             :         }
    1639          16 :         break;
    1640             :         case 2:
    1641             :         {
    1642          14 :             nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
    1643          14 :                     (((sal_uInt8)pBuffer[nStart + 1]) <<  8);
    1644             :         }
    1645          14 :         break;
    1646             :         default:
    1647             :         {
    1648         172 :             nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
    1649         172 :                     (((sal_uInt8)pBuffer[nStart + 1]) <<  8) +
    1650         344 :                     ((sal_uInt8)pBuffer[nStart + 2]);
    1651             :         }
    1652         172 :         break;
    1653             :     }
    1654             : 
    1655         202 :     sal_Unicode buf[] = { '=', '=', '=', '=' };
    1656             : 
    1657         202 :     sal_uInt8 nIndex (static_cast<sal_uInt8>((nBinaer & 0xFC0000) >> 18));
    1658         202 :     buf[0] = aBase64EncodeTable [nIndex];
    1659             : 
    1660         202 :     nIndex = static_cast<sal_uInt8>((nBinaer & 0x3F000) >> 12);
    1661         202 :     buf[1] = aBase64EncodeTable [nIndex];
    1662         202 :     if (nLen > 1)
    1663             :     {
    1664         186 :         nIndex = static_cast<sal_uInt8>((nBinaer & 0xFC0) >> 6);
    1665         186 :         buf[2] = aBase64EncodeTable [nIndex];
    1666         186 :         if (nLen > 2)
    1667             :         {
    1668         172 :             nIndex = static_cast<sal_uInt8>((nBinaer & 0x3F));
    1669         172 :             buf[3] = aBase64EncodeTable [nIndex];
    1670             :         }
    1671             :     }
    1672         202 :     sBuffer.append(buf, SAL_N_ELEMENTS(buf));
    1673             : }
    1674             : 
    1675          30 : void Converter::encodeBase64(rtl::OUStringBuffer& aStrBuffer, const uno::Sequence<sal_Int8>& aPass)
    1676             : {
    1677          30 :     sal_Int32 i(0);
    1678          30 :     sal_Int32 nBufferLength(aPass.getLength());
    1679          30 :     const sal_Int8* pBuffer = aPass.getConstArray();
    1680         262 :     while (i < nBufferLength)
    1681             :     {
    1682         202 :         ThreeByteToFourByte (pBuffer, i, nBufferLength, aStrBuffer);
    1683         202 :         i += 3;
    1684             :     }
    1685          30 : }
    1686             : 
    1687          90 : 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          90 :     decodeBase64SomeChars( aBuffer, sBuffer );
    1693             :     OSL_ENSURE( nCharsDecoded == sBuffer.getLength(), "some bytes left in base64 decoding!" );
    1694          90 : }
    1695             : 
    1696         108 : sal_Int32 Converter::decodeBase64SomeChars(
    1697             :         uno::Sequence<sal_Int8>& rOutBuffer,
    1698             :         const rtl::OUString& rInBuffer)
    1699             : {
    1700         108 :     sal_Int32 nInBufferLen = rInBuffer.getLength();
    1701         108 :     sal_Int32 nMinOutBufferLen = (nInBufferLen / 4) * 3;
    1702         108 :     if( rOutBuffer.getLength() < nMinOutBufferLen )
    1703          90 :         rOutBuffer.realloc( nMinOutBufferLen );
    1704             : 
    1705         108 :     const sal_Unicode *pInBuffer = rInBuffer.getStr();
    1706         108 :     sal_Int8 *pOutBuffer = rOutBuffer.getArray();
    1707         108 :     sal_Int8 *pOutBufferStart = pOutBuffer;
    1708         108 :     sal_Int32 nCharsDecoded = 0;
    1709             : 
    1710             :     sal_uInt8 aDecodeBuffer[4];
    1711         108 :     sal_Int32 nBytesToDecode = 0;
    1712         108 :     sal_Int32 nBytesGotFromDecoding = 3;
    1713         108 :     sal_Int32 nInBufferPos= 0;
    1714        8624 :     while( nInBufferPos < nInBufferLen )
    1715             :     {
    1716        8408 :         sal_Unicode cChar = *pInBuffer;
    1717        8408 :         if( cChar >= '+' && cChar <= 'z' )
    1718             :         {
    1719        8408 :             sal_uInt8 nByte = aBase64DecodeTable[cChar-'+'];
    1720        8408 :             if( nByte != 255 )
    1721             :             {
    1722             :                 // We have found a valid character!
    1723        8408 :                 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        8408 :                 if( '=' == cChar && nBytesToDecode > 2 )
    1728         154 :                     nBytesGotFromDecoding--;
    1729        8408 :                 if( 4 == nBytesToDecode )
    1730             :                 {
    1731             :                     // Four characters found, so we may convert now!
    1732        2102 :                     sal_uInt32 nOut = (aDecodeBuffer[0] << 18) +
    1733        2102 :                                       (aDecodeBuffer[1] << 12) +
    1734        2102 :                                       (aDecodeBuffer[2] << 6) +
    1735        6306 :                                        aDecodeBuffer[3];
    1736             : 
    1737        2102 :                     *pOutBuffer++  = (sal_Int8)((nOut & 0xff0000) >> 16);
    1738        2102 :                     if( nBytesGotFromDecoding > 1 )
    1739        2052 :                         *pOutBuffer++  = (sal_Int8)((nOut & 0xff00) >> 8);
    1740        2102 :                     if( nBytesGotFromDecoding > 2 )
    1741        1998 :                         *pOutBuffer++  = (sal_Int8)(nOut & 0xff);
    1742        2102 :                     nCharsDecoded = nInBufferPos + 1;
    1743        2102 :                     nBytesToDecode = 0;
    1744        2102 :                     nBytesGotFromDecoding = 3;
    1745             :                 }
    1746             :             }
    1747             :             else
    1748             :             {
    1749           0 :                 nCharsDecoded++;
    1750        8408 :             }
    1751             :         }
    1752             :         else
    1753             :         {
    1754           0 :             nCharsDecoded++;
    1755             :         }
    1756             : 
    1757        8408 :         nInBufferPos++;
    1758        8408 :         pInBuffer++;
    1759             :     }
    1760         108 :     if( (pOutBuffer - pOutBufferStart) != rOutBuffer.getLength() )
    1761         104 :         rOutBuffer.realloc( pOutBuffer - pOutBufferStart );
    1762             : 
    1763         108 :     return nCharsDecoded;
    1764             : }
    1765             : 
    1766        1539 : double Converter::GetConversionFactor(::rtl::OUStringBuffer& rUnit, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
    1767             : {
    1768        1539 :     double fRetval(1.0);
    1769        1539 :     rUnit.setLength(0L);
    1770             : 
    1771        1539 :     const sal_Char* psUnit = 0;
    1772             : 
    1773        1539 :     if(nSourceUnit != nTargetUnit)
    1774             :     {
    1775         208 :         switch(nSourceUnit)
    1776             :         {
    1777             :             case MeasureUnit::TWIP:
    1778             :             {
    1779          40 :                 switch(nTargetUnit)
    1780             :                 {
    1781             :                     case MeasureUnit::MM_100TH:
    1782             :                     {
    1783             :                         // 0.01mm = 0.57twip (exactly)
    1784           8 :                         fRetval = ((25400.0 / 1440.0) / 10.0);
    1785           8 :                         break;
    1786             :                     }
    1787             :                     case MeasureUnit::MM_10TH:
    1788             :                     {
    1789             :                         // 0.01mm = 0.57twip (exactly)
    1790           8 :                         fRetval = ((25400.0 / 1440.0) / 100.0);
    1791           8 :                         break;
    1792             :                     }
    1793             :                     case MeasureUnit::MM:
    1794             :                     {
    1795             :                         // 0.01mm = 0.57twip (exactly)
    1796           8 :                         fRetval = ((25400.0 / 1440.0) / 1000.0);
    1797           8 :                         psUnit = gpsMM;
    1798           8 :                         break;
    1799             :                     }
    1800             :                     case MeasureUnit::CM:
    1801             :                     {
    1802             :                         // 0.001cm = 0.57twip (exactly)
    1803           8 :                         fRetval = ((25400.0 / 1440.0) / 10000.0);
    1804           8 :                         psUnit = gpsCM;
    1805           8 :                         break;
    1806             :                     }
    1807             :                     case MeasureUnit::POINT:
    1808             :                     {
    1809             :                         // 0.01pt = 0.2twip (exactly)
    1810           4 :                         fRetval = ((1000.0 / 20.0) / 1000.0);
    1811           4 :                         psUnit = gpsPT;
    1812           4 :                         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           4 :                         fRetval = ((100000.0 / 1440.0) / 100000.0);
    1820           4 :                         psUnit = gpsINCH;
    1821           4 :                         break;
    1822             :                     }
    1823             :                 }
    1824          40 :                 break;
    1825             :             }
    1826             :             case MeasureUnit::POINT:
    1827             :             {
    1828          24 :                 switch(nTargetUnit)
    1829             :                 {
    1830             :                     case MeasureUnit::MM_100TH:
    1831             :                     {
    1832             :                         // 1mm = 72 / 25.4 pt (exactly)
    1833           4 :                         fRetval = ( 2540.0 / 72.0 );
    1834           4 :                         break;
    1835             :                     }
    1836             :                     case MeasureUnit::MM_10TH:
    1837             :                     {
    1838             :                         // 1mm = 72 / 25.4 pt (exactly)
    1839           4 :                         fRetval = ( 254.0 / 72.0 );
    1840           4 :                         break;
    1841             :                     }
    1842             :                     case MeasureUnit::MM:
    1843             :                     {
    1844             :                         // 1mm = 72 / 25.4 pt (exactly)
    1845           4 :                         fRetval = ( 25.4 / 72.0 );
    1846           4 :                         psUnit = gpsMM;
    1847           4 :                         break;
    1848             : 
    1849             :                     }
    1850             :                     case MeasureUnit::CM:
    1851             :                     {
    1852             :                         // 1cm = 72 / 2.54 pt (exactly)
    1853           4 :                         fRetval = ( 2.54 / 72.0 );
    1854           4 :                         psUnit = gpsCM;
    1855           4 :                         break;
    1856             :                     }
    1857             :                     case MeasureUnit::TWIP:
    1858             :                     {
    1859             :                         // 1twip = 72 / 1440 pt (exactly)
    1860           4 :                         fRetval = 20.0;     // 1440.0 / 72.0
    1861           4 :                         psUnit = gpsPC;
    1862           4 :                         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           4 :                         fRetval = ( 1.0 / 72.0 );
    1870           4 :                         psUnit = gpsINCH;
    1871           4 :                         break;
    1872             :                     }
    1873             :                 }
    1874          24 :                 break;
    1875             :             }
    1876             :             case MeasureUnit::MM_10TH:
    1877             :             {
    1878          24 :                 switch(nTargetUnit)
    1879             :                 {
    1880             :                     case MeasureUnit::MM_100TH:
    1881             :                     {
    1882           4 :                         fRetval = 10.0;
    1883           4 :                         break;
    1884             :                     }
    1885             :                     case MeasureUnit::MM:
    1886             :                     {
    1887             :                         // 0.01mm = 1 mm/100 (exactly)
    1888           4 :                         fRetval = ((10.0 / 1.0) / 100.0);
    1889           4 :                         psUnit = gpsMM;
    1890           4 :                         break;
    1891             :                     }
    1892             :                     case MeasureUnit::CM:
    1893             :                     {
    1894           4 :                         fRetval = ((10.0 / 1.0) / 1000.0);
    1895           4 :                         psUnit = gpsCM;
    1896           4 :                         break;
    1897             :                     }
    1898             :                     case MeasureUnit::POINT:
    1899             :                     {
    1900             :                         // 0.01pt = 0.35 mm/100 (exactly)
    1901           4 :                         fRetval = ((72000.0 / 2540.0) / 100.0);
    1902           4 :                         psUnit = gpsPT;
    1903           4 :                         break;
    1904             :                     }
    1905             :                     case MeasureUnit::TWIP:
    1906             :                     {
    1907           4 :                         fRetval = ((20.0 * 72000.0 / 2540.0) / 100.0);
    1908           4 :                         psUnit = gpsPC;
    1909           4 :                         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           4 :                         fRetval = ((100000.0 / 2540.0) / 10000.0);
    1917           4 :                         psUnit = gpsINCH;
    1918           4 :                         break;
    1919             :                     }
    1920             :                 }
    1921          24 :                 break;
    1922             :             }
    1923             :             case MeasureUnit::MM_100TH:
    1924             :             {
    1925          68 :                 switch(nTargetUnit)
    1926             :                 {
    1927             :                     case MeasureUnit::MM_10TH:
    1928             :                     {
    1929           4 :                         fRetval = ((10.0 / 1.0) / 100.0);
    1930           4 :                         break;
    1931             :                     }
    1932             :                     case MeasureUnit::MM:
    1933             :                     {
    1934             :                         // 0.01mm = 1 mm/100 (exactly)
    1935           4 :                         fRetval = ((10.0 / 1.0) / 1000.0);
    1936           4 :                         psUnit = gpsMM;
    1937           4 :                         break;
    1938             :                     }
    1939             :                     case MeasureUnit::CM:
    1940             :                     {
    1941          48 :                         fRetval = ((10.0 / 1.0) / 10000.0);
    1942          48 :                         psUnit = gpsCM;
    1943          48 :                         break;
    1944             :                     }
    1945             :                     case MeasureUnit::POINT:
    1946             :                     {
    1947             :                         // 0.01pt = 0.35 mm/100 (exactly)
    1948           4 :                         fRetval = ((72000.0 / 2540.0) / 1000.0);
    1949           4 :                         psUnit = gpsPT;
    1950           4 :                         break;
    1951             :                     }
    1952             :                     case MeasureUnit::TWIP:
    1953             :                     {
    1954           4 :                         fRetval = ((20.0 * 72000.0 / 2540.0) / 1000.0);
    1955           4 :                         psUnit = gpsPC;
    1956           4 :                         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           4 :                         fRetval = ((100000.0 / 2540.0) / 100000.0);
    1964           4 :                         psUnit = gpsINCH;
    1965           4 :                         break;
    1966             :                     }
    1967             :                 }
    1968          68 :                 break;
    1969             :             }
    1970             :             case MeasureUnit::MM:
    1971             :             {
    1972          24 :                 switch(nTargetUnit)
    1973             :                 {
    1974             :                     case MeasureUnit::MM_100TH:
    1975             :                     {
    1976           4 :                         fRetval = 100.0;
    1977           4 :                         break;
    1978             :                     }
    1979             :                     case MeasureUnit::MM_10TH:
    1980             :                     {
    1981           4 :                         fRetval = 10.0;
    1982           4 :                         break;
    1983             :                     }
    1984             :                     case MeasureUnit::CM:
    1985             :                     {
    1986           4 :                         fRetval = 0.1;
    1987           4 :                         psUnit = gpsCM;
    1988           4 :                         break;
    1989             :                     }
    1990             :                     case MeasureUnit::POINT:
    1991             :                     {
    1992           4 :                         fRetval = 72.0 / (2.54 * 10);
    1993           4 :                         psUnit = gpsPT;
    1994           4 :                         break;
    1995             :                     }
    1996             :                     case MeasureUnit::TWIP:
    1997             :                     {
    1998           4 :                         fRetval = (20.0 * 72.0) / (2.54 * 10);
    1999           4 :                         psUnit = gpsPC;
    2000           4 :                         break;
    2001             :                     }
    2002             :                     case MeasureUnit::INCH:
    2003             :                     default:
    2004             :                     {
    2005             :                         OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for cm values");
    2006           4 :                         fRetval = 1 / (2.54 * 10);
    2007           4 :                         psUnit = gpsINCH;
    2008           4 :                         break;
    2009             :                     }
    2010             :                 }
    2011          24 :                 break;
    2012             :             }
    2013             :             case MeasureUnit::CM:
    2014             :             {
    2015          16 :                 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           4 :                         fRetval = 10.0;
    2030           4 :                         psUnit = gpsMM;
    2031           4 :                         break;
    2032             :                     }
    2033             :                     case MeasureUnit::CM:
    2034             :                     {
    2035           0 :                         break;
    2036             :                     }
    2037             :                     case MeasureUnit::POINT:
    2038             :                     {
    2039           4 :                         fRetval = 72.0 / 2.54;
    2040           4 :                         psUnit = gpsPT;
    2041           4 :                         break;
    2042             :                     }
    2043             :                     case MeasureUnit::TWIP:
    2044             :                     {
    2045           4 :                         fRetval = (20.0 * 72.0) / 2.54;
    2046           4 :                         psUnit = gpsPC;
    2047           4 :                         break;
    2048             :                     }
    2049             :                     case MeasureUnit::INCH:
    2050             :                     default:
    2051             :                     {
    2052             :                         OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for cm values");
    2053           4 :                         fRetval = 1 / 2.54;
    2054           4 :                         psUnit = gpsINCH;
    2055           4 :                         break;
    2056             :                     }
    2057             :                 }
    2058          16 :                 break;
    2059             :             }
    2060             :             case MeasureUnit::INCH:
    2061             :             {
    2062          12 :                 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           4 :                         fRetval = 2.54;
    2083           4 :                         psUnit = gpsCM;
    2084           4 :                         break;
    2085             :                     }
    2086             :                     case MeasureUnit::POINT:
    2087             :                     {
    2088           4 :                         fRetval = 72.0;
    2089           4 :                         psUnit = gpsPT;
    2090           4 :                         break;
    2091             :                     }
    2092             :                     case MeasureUnit::TWIP:
    2093             :                     {
    2094           4 :                         fRetval = 72.0 * 20.0;
    2095           4 :                         psUnit = gpsPC;
    2096           4 :                         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          12 :                 break;
    2107             :             }
    2108             :             default:
    2109             :                 OSL_ENSURE(false, "sax::Converter::GetConversionFactor(): "
    2110             :                         "source unit not supported");
    2111           0 :                 break;
    2112             :         }
    2113             : 
    2114         208 :         if( psUnit )
    2115         168 :             rUnit.appendAscii( psUnit );
    2116             :     }
    2117             : 
    2118        1539 :     return fRetval;
    2119             : }
    2120             : 
    2121        1257 : sal_Int16 Converter::GetUnitFromString(const ::rtl::OUString& rString, sal_Int16 nDefaultUnit)
    2122             : {
    2123        1257 :     sal_Int32 nPos = 0L;
    2124        1257 :     sal_Int32 nLen = rString.getLength();
    2125        1257 :     sal_Int16 nRetUnit = nDefaultUnit;
    2126             : 
    2127             :     // skip white space
    2128        2514 :     while( nPos < nLen && sal_Unicode(' ') == rString[nPos] )
    2129           0 :         nPos++;
    2130             : 
    2131             :     // skip negative
    2132        1257 :     if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
    2133           0 :         nPos++;
    2134             : 
    2135             :     // skip number
    2136        4928 :     while( nPos < nLen && sal_Unicode('0') <= rString[nPos] && sal_Unicode('9') >= rString[nPos] )
    2137        2414 :         nPos++;
    2138             : 
    2139        1257 :     if( nPos < nLen && sal_Unicode('.') == rString[nPos] )
    2140             :     {
    2141         102 :         nPos++;
    2142         498 :         while( nPos < nLen && sal_Unicode('0') <= rString[nPos] && sal_Unicode('9') >= rString[nPos] )
    2143         294 :             nPos++;
    2144             :     }
    2145             : 
    2146             :     // skip white space
    2147        2514 :     while( nPos < nLen && sal_Unicode(' ') == rString[nPos] )
    2148           0 :         nPos++;
    2149             : 
    2150        1257 :     if( nPos < nLen )
    2151             :     {
    2152        1257 :         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          44 :                 if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('m')
    2163           0 :                     || rString[nPos+1] == sal_Unicode('M')))
    2164          44 :                     nRetUnit = MeasureUnit::CM;
    2165          44 :                 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        1213 :                 if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('t')
    2193           0 :                     || rString[nPos+1] == sal_Unicode('T')))
    2194        1213 :                     nRetUnit = MeasureUnit::POINT;
    2195        2426 :                 if(nPos+1 < nLen && (rString[nPos+1] == sal_Unicode('c')
    2196        1213 :                     || rString[nPos+1] == sal_Unicode('C')))
    2197           0 :                     nRetUnit = MeasureUnit::TWIP;
    2198        1213 :                 break;
    2199             :             }
    2200             :         }
    2201             :     }
    2202             : 
    2203        1257 :     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