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