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