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

Generated by: LCOV version 1.10