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