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 <sal/log.hxx>
34 : #include <osl/time.h>
35 : #include <osl/diagnose.h>
36 :
37 : #include <algorithm>
38 :
39 : using namespace com::sun::star;
40 : using namespace com::sun::star::uno;
41 : using namespace com::sun::star::util;
42 : using namespace ::com::sun::star::i18n;
43 :
44 :
45 : namespace sax {
46 :
47 : static const sal_Char* gpsMM = "mm";
48 : static const sal_Char* gpsCM = "cm";
49 : static const sal_Char* gpsPT = "pt";
50 : static const sal_Char* gpsINCH = "in";
51 : static const sal_Char* gpsPC = "pc";
52 :
53 : const sal_Int8 XML_MAXDIGITSCOUNT_TIME = 14;
54 :
55 : /** convert string to measure using optional min and max values*/
56 98339 : bool Converter::convertMeasure( sal_Int32& rValue,
57 : const OUString& rString,
58 : sal_Int16 nTargetUnit /* = MeasureUnit::MM_100TH */,
59 : sal_Int32 nMin /* = SAL_MIN_INT32 */,
60 : sal_Int32 nMax /* = SAL_MAX_INT32 */ )
61 : {
62 98339 : bool bNeg = false;
63 98339 : double nVal = 0;
64 :
65 98339 : sal_Int32 nPos = 0;
66 98339 : sal_Int32 const nLen = rString.getLength();
67 :
68 : // skip white space
69 196987 : while( (nPos < nLen) && (rString[nPos] <= ' ') )
70 309 : nPos++;
71 :
72 98339 : if( nPos < nLen && '-' == rString[nPos] )
73 : {
74 4626 : bNeg = true;
75 4626 : nPos++;
76 : }
77 :
78 : // get number
79 543553 : while( nPos < nLen &&
80 363416 : '0' <= rString[nPos] &&
81 140647 : '9' >= rString[nPos] )
82 : {
83 : // TODO: check overflow!
84 124430 : nVal *= 10;
85 124430 : nVal += (rString[nPos] - '0');
86 124430 : nPos++;
87 : }
88 98339 : if( nPos < nLen && '.' == rString[nPos] )
89 : {
90 69209 : nPos++;
91 69209 : double nDiv = 1.;
92 :
93 596033 : while( nPos < nLen &&
94 526125 : '0' <= rString[nPos] &&
95 262712 : '9' >= rString[nPos] )
96 : {
97 : // TODO: check overflow!
98 194204 : nDiv *= 10;
99 194204 : nVal += ( ((double)(rString[nPos] - '0')) / nDiv );
100 194204 : nPos++;
101 : }
102 : }
103 :
104 : // skip white space
105 196678 : while( (nPos < nLen) && (rString[nPos] <= ' ') )
106 0 : nPos++;
107 :
108 98339 : if( nPos < nLen )
109 : {
110 :
111 98013 : if( MeasureUnit::PERCENT == nTargetUnit )
112 : {
113 23399 : if( '%' != rString[nPos] )
114 10129 : return false;
115 : }
116 74614 : else if( MeasureUnit::PIXEL == nTargetUnit )
117 : {
118 6 : if( nPos + 1 >= nLen ||
119 2 : ('p' != rString[nPos] &&
120 4 : 'P' != rString[nPos])||
121 2 : ('x' != rString[nPos+1] &&
122 0 : 'X' != rString[nPos+1]) )
123 0 : return false;
124 : }
125 : else
126 : {
127 : OSL_ENSURE( MeasureUnit::TWIP == nTargetUnit || MeasureUnit::POINT == nTargetUnit ||
128 : MeasureUnit::MM_100TH == nTargetUnit || MeasureUnit::MM_10TH == nTargetUnit, "unit is not supported");
129 74612 : const sal_Char *aCmpsL[2] = { 0, 0 };
130 74612 : const sal_Char *aCmpsU[2] = { 0, 0 };
131 74612 : double aScales[2] = { 1., 1. };
132 :
133 74612 : if( MeasureUnit::TWIP == nTargetUnit )
134 : {
135 1781 : switch( rString[nPos] )
136 : {
137 : case sal_Unicode('c'):
138 : case sal_Unicode('C'):
139 1051 : aCmpsL[0] = "cm";
140 1051 : aCmpsU[0] = "CM";
141 1051 : aScales[0] = (72.*20.)/2.54; // twip
142 1051 : break;
143 : case sal_Unicode('i'):
144 : case sal_Unicode('I'):
145 40 : aCmpsL[0] = "in";
146 40 : aCmpsU[0] = "IN";
147 40 : aScales[0] = 72.*20.; // twip
148 40 : break;
149 : case sal_Unicode('m'):
150 : case sal_Unicode('M'):
151 0 : aCmpsL[0] = "mm";
152 0 : aCmpsU[0] = "MM";
153 0 : aScales[0] = (72.*20.)/25.4; // twip
154 0 : break;
155 : case sal_Unicode('p'):
156 : case sal_Unicode('P'):
157 690 : aCmpsL[0] = "pt";
158 690 : aCmpsU[0] = "PT";
159 690 : aScales[0] = 20.; // twip
160 :
161 690 : aCmpsL[1] = "pc";
162 690 : aCmpsU[1] = "PC";
163 690 : aScales[1] = 12.*20.; // twip
164 690 : break;
165 : }
166 : }
167 72831 : else if( MeasureUnit::MM_100TH == nTargetUnit || MeasureUnit::MM_10TH == nTargetUnit )
168 : {
169 72831 : double nScaleFactor = (MeasureUnit::MM_100TH == nTargetUnit) ? 100.0 : 10.0;
170 72831 : switch( rString[nPos] )
171 : {
172 : case sal_Unicode('c'):
173 : case sal_Unicode('C'):
174 44711 : aCmpsL[0] = "cm";
175 44711 : aCmpsU[0] = "CM";
176 44711 : aScales[0] = 10.0 * nScaleFactor; // mm/100
177 44711 : break;
178 : case sal_Unicode('i'):
179 : case sal_Unicode('I'):
180 22422 : aCmpsL[0] = "in";
181 22422 : aCmpsU[0] = "IN";
182 22422 : aScales[0] = 1000.*2.54; // mm/100
183 22422 : break;
184 : case sal_Unicode('m'):
185 : case sal_Unicode('M'):
186 679 : aCmpsL[0] = "mm";
187 679 : aCmpsU[0] = "MM";
188 679 : aScales[0] = 1.0 * nScaleFactor; // mm/100
189 679 : break;
190 : case sal_Unicode('p'):
191 : case sal_Unicode('P'):
192 5001 : aCmpsL[0] = "pt";
193 5001 : aCmpsU[0] = "PT";
194 5001 : aScales[0] = (10.0 * nScaleFactor*2.54)/72.; // mm/100
195 :
196 5001 : aCmpsL[1] = "pc";
197 5001 : aCmpsU[1] = "PC";
198 5001 : aScales[1] = (10.0 * nScaleFactor*2.54)/12.; // mm/100
199 5001 : break;
200 72831 : }
201 : }
202 0 : else if( MeasureUnit::POINT == nTargetUnit )
203 : {
204 0 : if( rString[nPos] == 'p' || rString[nPos] == 'P' )
205 : {
206 0 : aCmpsL[0] = "pt";
207 0 : aCmpsU[0] = "PT";
208 0 : aScales[0] = 1;
209 : }
210 : }
211 :
212 74612 : if( aCmpsL[0] == NULL )
213 38 : return false;
214 :
215 74594 : double nScale = 0.;
216 74598 : for( sal_uInt16 i= 0; i < 2; i++ )
217 : {
218 74596 : const sal_Char *pL = aCmpsL[i];
219 74596 : if( pL )
220 : {
221 74594 : const sal_Char *pU = aCmpsU[i];
222 298376 : while( nPos < nLen && *pL )
223 : {
224 149188 : sal_Unicode c = rString[nPos];
225 149188 : if( c != *pL && c != *pU )
226 0 : break;
227 149188 : pL++;
228 149188 : pU++;
229 149188 : nPos++;
230 : }
231 74594 : if( !*pL && (nPos == nLen || ' ' == rString[nPos]) )
232 : {
233 74592 : nScale = aScales[i];
234 74592 : break;
235 : }
236 : }
237 : }
238 :
239 74594 : if( 0. == nScale )
240 2 : return false;
241 :
242 : // TODO: check overflow
243 74592 : if( nScale != 1. )
244 74592 : nVal *= nScale;
245 : }
246 : }
247 :
248 88190 : nVal += .5;
249 88190 : if( bNeg )
250 4347 : nVal = -nVal;
251 :
252 88190 : if( nVal <= (double)nMin )
253 4 : rValue = nMin;
254 88186 : else if( nVal >= (double)nMax )
255 2 : rValue = nMax;
256 : else
257 88184 : rValue = (sal_Int32)nVal;
258 :
259 88190 : return true;
260 : }
261 :
262 : /** convert measure in given unit to string with given unit */
263 18161 : void Converter::convertMeasure( OUStringBuffer& rBuffer,
264 : sal_Int32 nMeasure,
265 : sal_Int16 nSourceUnit /* = MeasureUnit::MM_100TH */,
266 : sal_Int16 nTargetUnit /* = MeasureUnit::INCH */ )
267 : {
268 18161 : if( nSourceUnit == MeasureUnit::PERCENT )
269 : {
270 : OSL_ENSURE( nTargetUnit == MeasureUnit::PERCENT,
271 : "MeasureUnit::PERCENT only maps to MeasureUnit::PERCENT!" );
272 :
273 1 : rBuffer.append( nMeasure );
274 1 : rBuffer.append( '%' );
275 :
276 18162 : return;
277 : }
278 : // the sign is processed separately
279 18160 : if( nMeasure < 0 )
280 : {
281 1495 : nMeasure = -nMeasure;
282 1495 : rBuffer.append( '-' );
283 : }
284 :
285 : // The new length is (nVal * nMul)/(nDiv*nFac*10)
286 18160 : long nMul = 1000;
287 18160 : long nDiv = 1;
288 18160 : long nFac = 100;
289 18160 : const sal_Char* psUnit = 0;
290 18160 : switch( nSourceUnit )
291 : {
292 : case MeasureUnit::TWIP:
293 206 : switch( nTargetUnit )
294 : {
295 : case MeasureUnit::MM_100TH:
296 : case MeasureUnit::MM_10TH:
297 : OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,"output unit not supported for twip values" );
298 : //fall-through
299 : case MeasureUnit::MM:
300 : // 0.01mm = 0.57twip (exactly)
301 1 : nMul = 25400; // 25.4 * 1000
302 1 : nDiv = 1440; // 72 * 20;
303 1 : nFac = 100;
304 1 : psUnit = gpsMM;
305 1 : break;
306 :
307 : case MeasureUnit::CM:
308 : // 0.001cm = 0.57twip (exactly)
309 1 : nMul = 25400; // 2.54 * 10000
310 1 : nDiv = 1440; // 72 * 20;
311 1 : nFac = 1000;
312 1 : psUnit = gpsCM;
313 1 : break;
314 :
315 : case MeasureUnit::POINT:
316 : // 0.01pt = 0.2twip (exactly)
317 43 : nMul = 1000;
318 43 : nDiv = 20;
319 43 : nFac = 100;
320 43 : psUnit = gpsPT;
321 43 : break;
322 :
323 : case MeasureUnit::INCH:
324 : default:
325 : OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,
326 : "output unit not supported for twip values" );
327 : // 0.0001in = 0.144twip (exactly)
328 161 : nMul = 100000;
329 161 : nDiv = 1440; // 72 * 20;
330 161 : nFac = 10000;
331 161 : psUnit = gpsINCH;
332 161 : break;
333 : }
334 206 : break;
335 :
336 : case MeasureUnit::POINT:
337 : // 1pt = 1pt (exactly)
338 : OSL_ENSURE( MeasureUnit::POINT == nTargetUnit,
339 : "output unit not supported for pt values" );
340 0 : nMul = 10;
341 0 : nDiv = 1;
342 0 : nFac = 1;
343 0 : psUnit = gpsPT;
344 0 : break;
345 : case MeasureUnit::MM_10TH:
346 : case MeasureUnit::MM_100TH:
347 : {
348 17954 : long nFac2 = (MeasureUnit::MM_100TH == nSourceUnit) ? 100 : 10;
349 17954 : switch( nTargetUnit )
350 : {
351 : case MeasureUnit::MM_100TH:
352 : case MeasureUnit::MM_10TH:
353 : OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,
354 : "output unit not supported for 1/100mm values" );
355 : //fall-through
356 : case MeasureUnit::MM:
357 : // 0.01mm = 1 mm/100 (exactly)
358 2 : nMul = 10;
359 2 : nDiv = 1;
360 2 : nFac = nFac2;
361 2 : psUnit = gpsMM;
362 2 : break;
363 :
364 : case MeasureUnit::CM:
365 : // 0.001mm = 1 mm/100 (exactly)
366 8050 : nMul = 10;
367 8050 : nDiv = 1; // 72 * 20;
368 8050 : nFac = 10*nFac2;
369 8050 : psUnit = gpsCM;
370 8050 : break;
371 :
372 : case MeasureUnit::POINT:
373 : // 0.01pt = 0.35 mm/100 (exactly)
374 913 : nMul = 72000;
375 913 : nDiv = 2540;
376 913 : nFac = nFac2;
377 913 : psUnit = gpsPT;
378 913 : break;
379 :
380 : case MeasureUnit::INCH:
381 : default:
382 : OSL_ENSURE( MeasureUnit::INCH == nTargetUnit,
383 : "output unit not supported for 1/100mm values" );
384 : // 0.0001in = 0.254 mm/100 (exactly)
385 8989 : nMul = 100000;
386 8989 : nDiv = 2540;
387 8989 : nFac = 100*nFac2;
388 8989 : psUnit = gpsINCH;
389 8989 : break;
390 : }
391 17954 : break;
392 : }
393 : default:
394 : OSL_ENSURE(false, "sax::Converter::convertMeasure(): "
395 : "source unit not supported");
396 0 : break;
397 : }
398 :
399 18160 : sal_Int64 nValue = nMeasure;
400 : OSL_ENSURE(nValue <= SAL_MAX_INT64 / nMul, "convertMeasure: overflow");
401 18160 : nValue *= nMul;
402 18160 : nValue /= nDiv;
403 18160 : nValue += 5;
404 18160 : nValue /= 10;
405 :
406 18160 : rBuffer.append( static_cast<sal_Int64>(nValue / nFac) );
407 18160 : if (nFac > 1 && (nValue % nFac) != 0)
408 : {
409 15386 : rBuffer.append( '.' );
410 71118 : while (nFac > 1 && (nValue % nFac) != 0)
411 : {
412 40346 : nFac /= 10;
413 40346 : rBuffer.append( static_cast<sal_Int32>((nValue / nFac) % 10) );
414 : }
415 : }
416 :
417 18160 : if( psUnit )
418 18160 : rBuffer.appendAscii( psUnit );
419 : }
420 :
421 28687 : static OUString getTrueString()
422 : {
423 28687 : return OUString( "true" );
424 : }
425 :
426 36895 : static OUString getFalseString()
427 : {
428 36895 : return OUString( "false" );
429 : }
430 :
431 : /** convert string to boolean */
432 15597 : bool Converter::convertBool( bool& rBool, const OUString& rString )
433 : {
434 15597 : rBool = rString == getTrueString();
435 :
436 15597 : return rBool || (rString == getFalseString());
437 : }
438 :
439 : /** convert boolean to string */
440 39947 : void Converter::convertBool( OUStringBuffer& rBuffer, bool bValue )
441 : {
442 39947 : rBuffer.append( bValue ? getTrueString() : getFalseString() );
443 39947 : }
444 :
445 : /** convert string to percent */
446 23455 : bool Converter::convertPercent( sal_Int32& rPercent, const OUString& rString )
447 : {
448 23455 : return convertMeasure( rPercent, rString, MeasureUnit::PERCENT );
449 : }
450 :
451 : /** convert percent to string */
452 5409 : void Converter::convertPercent( OUStringBuffer& rBuffer, sal_Int32 nValue )
453 : {
454 5409 : rBuffer.append( nValue );
455 5409 : rBuffer.append( '%' );
456 5409 : }
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 83640 : int lcl_gethex( int nChar )
473 : {
474 83640 : if( nChar >= '0' && nChar <= '9' )
475 64809 : return nChar - '0';
476 18831 : else if( nChar >= 'a' && nChar <= 'f' )
477 18831 : return nChar - 'a' + 10;
478 0 : else if( nChar >= 'A' && nChar <= 'F' )
479 0 : return nChar - 'A' + 10;
480 : else
481 0 : return 0;
482 : }
483 :
484 : /** convert string to rgb color */
485 16272 : bool Converter::convertColor( sal_Int32& rColor, const OUString& rValue )
486 : {
487 16272 : if( rValue.getLength() != 7 || rValue[0] != '#' )
488 2332 : return false;
489 :
490 13940 : rColor = lcl_gethex( rValue[1] ) * 16 + lcl_gethex( rValue[2] );
491 13940 : rColor <<= 8;
492 :
493 13940 : rColor |= ( lcl_gethex( rValue[3] ) * 16 + lcl_gethex( rValue[4] ) );
494 13940 : rColor <<= 8;
495 :
496 13940 : rColor |= ( lcl_gethex( rValue[5] ) * 16 + lcl_gethex( rValue[6] ) );
497 :
498 13940 : return true;
499 : }
500 :
501 : static const sal_Char aHexTab[] = "0123456789abcdef";
502 :
503 : /** convert color to string */
504 7758 : void Converter::convertColor( OUStringBuffer& rBuffer, sal_Int32 nColor )
505 : {
506 7758 : rBuffer.append( '#' );
507 :
508 7758 : sal_uInt8 nCol = (sal_uInt8)(nColor >> 16);
509 7758 : rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
510 7758 : rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
511 :
512 7758 : nCol = (sal_uInt8)(nColor >> 8);
513 7758 : rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
514 7758 : rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
515 :
516 7758 : nCol = (sal_uInt8)nColor;
517 7758 : rBuffer.append( sal_Unicode( aHexTab[ nCol >> 4 ] ) );
518 7758 : rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
519 7758 : }
520 :
521 : /** convert number to string */
522 49906 : void Converter::convertNumber( OUStringBuffer& rBuffer, sal_Int32 nNumber )
523 : {
524 49906 : rBuffer.append( nNumber );
525 49906 : }
526 :
527 : /** convert string to number with optional min and max values */
528 54860 : bool Converter::convertNumber( sal_Int32& rValue,
529 : const OUString& rString,
530 : sal_Int32 nMin, sal_Int32 nMax )
531 : {
532 54860 : rValue = 0;
533 54860 : sal_Int64 nNumber = 0;
534 54860 : bool bRet = convertNumber64(nNumber,rString,nMin,nMax);
535 54860 : if ( bRet )
536 54576 : rValue = static_cast<sal_Int32>(nNumber);
537 54860 : return bRet;
538 : }
539 :
540 : /** convert string to 64-bit number with optional min and max values */
541 54956 : bool Converter::convertNumber64( sal_Int64& rValue,
542 : const OUString& rString,
543 : sal_Int64 nMin, sal_Int64 nMax )
544 : {
545 54956 : bool bNeg = false;
546 54956 : rValue = 0;
547 :
548 54956 : sal_Int32 nPos = 0;
549 54956 : sal_Int32 const nLen = rString.getLength();
550 :
551 : // skip white space
552 109912 : while( (nPos < nLen) && (rString[nPos] <= ' ') )
553 0 : nPos++;
554 :
555 54956 : if( nPos < nLen && '-' == rString[nPos] )
556 : {
557 890 : bNeg = true;
558 890 : nPos++;
559 : }
560 :
561 : // get number
562 355236 : while( nPos < nLen &&
563 300233 : '0' <= rString[nPos] &&
564 122757 : '9' >= rString[nPos] )
565 : {
566 : // TODO: check overflow!
567 122520 : rValue *= 10;
568 122520 : rValue += (rString[nPos] - sal_Unicode('0'));
569 122520 : nPos++;
570 : }
571 :
572 54956 : if( bNeg )
573 890 : rValue *= -1;
574 :
575 54956 : if( rValue < nMin )
576 1 : rValue = nMin;
577 54955 : else if( rValue > nMax )
578 2 : rValue = nMax;
579 :
580 54956 : return ( nPos == nLen && rValue >= nMin && rValue <= nMax );
581 : }
582 :
583 : /** convert double number to string (using ::rtl::math) */
584 7896 : void Converter::convertDouble( OUStringBuffer& rBuffer,
585 : double fNumber,
586 : bool bWriteUnits,
587 : sal_Int16 nSourceUnit,
588 : sal_Int16 nTargetUnit)
589 : {
590 7896 : 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 7896 : OUStringBuffer sUnit;
600 7896 : double fFactor = GetConversionFactor(sUnit, nSourceUnit, nTargetUnit);
601 7896 : if(fFactor != 1.0)
602 351 : fNumber *= fFactor;
603 7896 : ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
604 7896 : if(bWriteUnits)
605 7896 : rBuffer.append(sUnit.makeStringAndClear());
606 : }
607 7896 : }
608 :
609 : /** convert double number to string (using ::rtl::math) */
610 9082 : void Converter::convertDouble( OUStringBuffer& rBuffer, double fNumber)
611 : {
612 9082 : ::rtl::math::doubleToUStringBuffer( rBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
613 9082 : }
614 :
615 : /** convert string to double number (using ::rtl::math) */
616 18377 : bool Converter::convertDouble(double& rValue,
617 : const OUString& rString, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
618 : {
619 : rtl_math_ConversionStatus eStatus;
620 18377 : rValue = ::rtl::math::stringToDouble( rString, '.', ',', &eStatus, NULL );
621 :
622 18377 : if(eStatus == rtl_math_ConversionStatus_Ok)
623 : {
624 18377 : OUStringBuffer sUnit;
625 : // fdo#48969: switch source and target because factor is used to divide!
626 : double const fFactor =
627 18377 : GetConversionFactor(sUnit, nTargetUnit, nSourceUnit);
628 18377 : if(fFactor != 1.0 && fFactor != 0.0)
629 235 : rValue /= fFactor;
630 : }
631 :
632 18377 : return ( eStatus == rtl_math_ConversionStatus_Ok );
633 : }
634 :
635 : /** convert string to double number (using ::rtl::math) */
636 13935 : bool Converter::convertDouble(double& rValue, const OUString& rString)
637 : {
638 : rtl_math_ConversionStatus eStatus;
639 13935 : rValue = ::rtl::math::stringToDouble( rString, '.', ',', &eStatus, NULL );
640 13935 : return ( eStatus == rtl_math_ConversionStatus_Ok );
641 : }
642 :
643 : /** convert double to ISO "duration" string; negative durations allowed */
644 1 : void Converter::convertDuration(OUStringBuffer& rBuffer,
645 : const double fTime)
646 : {
647 1 : 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 1 : if (fValue < 0.0)
652 : {
653 0 : rBuffer.append('-');
654 0 : fValue = - fValue;
655 : }
656 :
657 1 : rBuffer.append( "PT" );
658 1 : fValue *= 24;
659 1 : double fHoursValue = ::rtl::math::approxFloor (fValue);
660 1 : fValue -= fHoursValue;
661 1 : fValue *= 60;
662 1 : double fMinsValue = ::rtl::math::approxFloor (fValue);
663 1 : fValue -= fMinsValue;
664 1 : fValue *= 60;
665 1 : double fSecsValue = ::rtl::math::approxFloor (fValue);
666 1 : fValue -= fSecsValue;
667 : double fNanoSecsValue;
668 1 : if (fValue > 0.00000000001)
669 1 : fNanoSecsValue = ::rtl::math::round( fValue, XML_MAXDIGITSCOUNT_TIME - 5);
670 : else
671 0 : fNanoSecsValue = 0.0;
672 :
673 1 : if (fNanoSecsValue == 1.0)
674 : {
675 0 : fNanoSecsValue = 0.0;
676 0 : fSecsValue += 1.0;
677 : }
678 1 : if (fSecsValue >= 60.0)
679 : {
680 0 : fSecsValue -= 60.0;
681 0 : fMinsValue += 1.0;
682 : }
683 1 : if (fMinsValue >= 60.0)
684 : {
685 0 : fMinsValue -= 60.0;
686 0 : fHoursValue += 1.0;
687 : }
688 :
689 1 : if (fHoursValue < 10)
690 1 : rBuffer.append( '0');
691 1 : rBuffer.append( sal_Int32( fHoursValue));
692 1 : rBuffer.append( 'H');
693 1 : if (fMinsValue < 10)
694 0 : rBuffer.append( '0');
695 1 : rBuffer.append( sal_Int32( fMinsValue));
696 1 : rBuffer.append( 'M');
697 1 : if (fSecsValue < 10)
698 0 : rBuffer.append( '0');
699 1 : rBuffer.append( sal_Int32( fSecsValue));
700 1 : if (fNanoSecsValue > 0.0)
701 : {
702 : OUString aNS( ::rtl::math::doubleToUString( fValue,
703 : rtl_math_StringFormat_F, XML_MAXDIGITSCOUNT_TIME - 5, '.',
704 1 : true));
705 1 : if ( aNS.getLength() > 2 )
706 : {
707 1 : rBuffer.append( '.');
708 1 : rBuffer.append( aNS.copy( 2 ) ); // strip "0."
709 1 : }
710 : }
711 1 : rBuffer.append( 'S');
712 1 : }
713 :
714 : /** convert ISO "duration" string to double; negative durations allowed */
715 220 : bool Converter::convertDuration(double& rfTime,
716 : const OUString& rString)
717 : {
718 220 : OUString aTrimmed = rString.trim().toAsciiUpperCase();
719 220 : const sal_Unicode* pStr = aTrimmed.getStr();
720 :
721 : // negative time duration?
722 220 : bool bIsNegativeDuration = false;
723 220 : if ( '-' == (*pStr) )
724 : {
725 0 : bIsNegativeDuration = true;
726 0 : pStr++;
727 : }
728 :
729 220 : if ( *(pStr++) != 'P' ) // duration must start with "P"
730 0 : return false;
731 :
732 440 : OUString sDoubleStr;
733 220 : bool bSuccess = true;
734 220 : bool bDone = false;
735 220 : bool bTimePart = false;
736 220 : bool bIsFraction = false;
737 220 : sal_Int32 nDays = 0;
738 220 : sal_Int32 nHours = 0;
739 220 : sal_Int32 nMins = 0;
740 220 : sal_Int32 nSecs = 0;
741 220 : sal_Int32 nTemp = 0;
742 :
743 2868 : while ( bSuccess && !bDone )
744 : {
745 2428 : sal_Unicode c = *(pStr++);
746 2428 : if ( !c ) // end
747 220 : bDone = true;
748 2208 : else if ( '0' <= c && '9' >= c )
749 : {
750 2650 : if ( nTemp >= SAL_MAX_INT32 / 10 )
751 0 : bSuccess = false;
752 : else
753 : {
754 1325 : if ( !bIsFraction )
755 : {
756 1322 : nTemp *= 10;
757 1322 : nTemp += (c - sal_Unicode('0'));
758 : }
759 : else
760 : {
761 3 : sDoubleStr += OUString(c);
762 : }
763 : }
764 : }
765 883 : else if ( bTimePart )
766 : {
767 663 : if ( c == 'H' )
768 : {
769 220 : nHours = nTemp;
770 220 : nTemp = 0;
771 : }
772 443 : else if ( c == 'M' )
773 : {
774 220 : nMins = nTemp;
775 220 : nTemp = 0;
776 : }
777 223 : else if ( (c == ',') || (c == '.') )
778 : {
779 3 : nSecs = nTemp;
780 3 : nTemp = 0;
781 3 : bIsFraction = true;
782 3 : sDoubleStr = "0.";
783 : }
784 220 : else if ( c == 'S' )
785 : {
786 220 : if ( !bIsFraction )
787 : {
788 217 : nSecs = nTemp;
789 217 : nTemp = 0;
790 217 : sDoubleStr = "0.0";
791 : }
792 : }
793 : else
794 0 : bSuccess = false; // invalid character
795 : }
796 : else
797 : {
798 220 : if ( c == 'T' ) // "T" starts time part
799 220 : 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 220 : if ( bSuccess )
818 : {
819 220 : if ( nDays )
820 0 : nHours += nDays * 24; // add the days to the hours part
821 220 : double fTempTime = 0.0;
822 220 : double fHour = nHours;
823 220 : double fMin = nMins;
824 220 : double fSec = nSecs;
825 220 : double fFraction = sDoubleStr.toDouble();
826 220 : fTempTime = fHour / 24;
827 220 : fTempTime += fMin / (24 * 60);
828 220 : fTempTime += fSec / (24 * 60 * 60);
829 220 : fTempTime += fFraction / (24 * 60 * 60);
830 :
831 : // negative duration?
832 220 : if ( bIsNegativeDuration )
833 : {
834 0 : fTempTime = -fTempTime;
835 : }
836 :
837 220 : rfTime = fTempTime;
838 : }
839 440 : return bSuccess;
840 : }
841 :
842 : /** convert util::Duration to ISO8601 "duration" string */
843 1911 : void Converter::convertDuration(OUStringBuffer& rBuffer,
844 : const ::util::Duration& rDuration)
845 : {
846 1911 : if (rDuration.Negative)
847 : {
848 3 : rBuffer.append('-');
849 : }
850 1911 : rBuffer.append('P');
851 3819 : const bool bHaveDate(rDuration.Years != 0 ||
852 3817 : rDuration.Months != 0 ||
853 3817 : rDuration.Days != 0);
854 1911 : if (rDuration.Years)
855 : {
856 3 : rBuffer.append(static_cast<sal_Int32>(rDuration.Years));
857 3 : rBuffer.append('Y');
858 : }
859 1911 : if (rDuration.Months)
860 : {
861 4 : rBuffer.append(static_cast<sal_Int32>(rDuration.Months));
862 4 : rBuffer.append('M');
863 : }
864 1911 : if (rDuration.Days)
865 : {
866 49 : rBuffer.append(static_cast<sal_Int32>(rDuration.Days));
867 49 : rBuffer.append('D');
868 : }
869 1911 : if ( rDuration.Hours != 0
870 1705 : || rDuration.Minutes != 0
871 765 : || rDuration.Seconds != 0
872 724 : || rDuration.NanoSeconds != 0 )
873 : {
874 1193 : rBuffer.append('T'); // time separator
875 1193 : if (rDuration.Hours)
876 : {
877 206 : rBuffer.append(static_cast<sal_Int32>(rDuration.Hours));
878 206 : rBuffer.append('H');
879 : }
880 1193 : if (rDuration.Minutes)
881 : {
882 1144 : rBuffer.append(static_cast<sal_Int32>(rDuration.Minutes));
883 1144 : rBuffer.append('M');
884 : }
885 1193 : if (rDuration.Seconds != 0 || rDuration.NanoSeconds != 0)
886 : {
887 : // seconds must not be omitted (i.e. ".42S" is not valid)
888 160 : rBuffer.append(static_cast<sal_Int32>(rDuration.Seconds));
889 160 : if (rDuration.NanoSeconds)
890 : {
891 : OSL_ENSURE(rDuration.NanoSeconds < 1000000000,"NanoSeconds cannot be more than 999 999 999");
892 9 : rBuffer.append('.');
893 9 : std::ostringstream ostr;
894 9 : ostr.fill('0');
895 9 : ostr.width(9);
896 9 : ostr << rDuration.NanoSeconds;
897 9 : rBuffer.append(OUString::createFromAscii(ostr.str().c_str()));
898 : }
899 160 : rBuffer.append('S');
900 1193 : }
901 : }
902 718 : else if (!bHaveDate)
903 : {
904 : // zero duration: XMLSchema-2 says there must be at least one component
905 714 : rBuffer.append('0');
906 714 : rBuffer.append('D');
907 : }
908 1911 : }
909 :
910 : enum Result { R_NOTHING, R_OVERFLOW, R_SUCCESS };
911 :
912 : static Result
913 36294 : readUnsignedNumber(const OUString & rString,
914 : sal_Int32 & io_rnPos, sal_Int32 & o_rNumber)
915 : {
916 36294 : bool bOverflow(false);
917 36294 : sal_Int64 nTemp(0);
918 36294 : sal_Int32 nPos(io_rnPos);
919 :
920 104376 : while (nPos < rString.getLength())
921 : {
922 43779 : const sal_Unicode c = rString[nPos];
923 43779 : if (('0' <= c) && (c <= '9'))
924 : {
925 31788 : nTemp *= 10;
926 31788 : nTemp += (c - sal_Unicode('0'));
927 31788 : if (nTemp >= SAL_MAX_INT32)
928 : {
929 2 : bOverflow = true;
930 : }
931 : }
932 : else
933 : {
934 : break;
935 : }
936 31788 : ++nPos;
937 : }
938 :
939 36294 : if (io_rnPos == nPos) // read something?
940 : {
941 22396 : o_rNumber = -1;
942 22396 : return R_NOTHING;
943 : }
944 :
945 13898 : io_rnPos = nPos;
946 13898 : o_rNumber = nTemp;
947 13898 : return (bOverflow) ? R_OVERFLOW : R_SUCCESS;
948 : }
949 :
950 : static Result
951 482 : readUnsignedNumberMaxDigits(int maxDigits,
952 : const ::rtl::OUString & rString, sal_Int32 & io_rnPos,
953 : sal_Int32 & o_rNumber)
954 : {
955 482 : bool bOverflow(false);
956 482 : sal_Int64 nTemp(0);
957 482 : sal_Int32 nPos(io_rnPos);
958 : OSL_ENSURE(maxDigits >= 0, "negative amount of digits makes no sense");
959 :
960 5109 : while (nPos < rString.getLength())
961 : {
962 4176 : const sal_Unicode c = rString[nPos];
963 4176 : if (('0' <= c) && (c <= '9'))
964 : {
965 4145 : if (maxDigits > 0)
966 : {
967 4012 : nTemp *= 10;
968 4012 : nTemp += (c - sal_Unicode('0'));
969 4012 : if (nTemp >= SAL_MAX_INT32)
970 : {
971 0 : bOverflow = true;
972 : }
973 4012 : --maxDigits;
974 : }
975 : }
976 : else
977 : {
978 : break;
979 : }
980 4145 : ++nPos;
981 : }
982 :
983 482 : if (io_rnPos == nPos) // read something?
984 : {
985 4 : o_rNumber = -1;
986 4 : return R_NOTHING;
987 : }
988 :
989 478 : io_rnPos = nPos;
990 478 : o_rNumber = nTemp;
991 478 : return (bOverflow) ? R_OVERFLOW : R_SUCCESS;
992 : }
993 :
994 : static bool
995 11459 : readDurationT(const OUString & rString, sal_Int32 & io_rnPos)
996 : {
997 12197 : if ((io_rnPos < rString.getLength()) &&
998 738 : (rString[io_rnPos] == 'T'))
999 : {
1000 492 : ++io_rnPos;
1001 492 : return true;
1002 : }
1003 10967 : return false;
1004 : }
1005 :
1006 : static bool
1007 1686 : 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 1686 : if ((io_rnPos < rString.getLength()))
1012 : {
1013 1682 : if (c == rString[io_rnPos])
1014 : {
1015 756 : ++io_rnPos;
1016 756 : if (-1 != io_rnTemp)
1017 : {
1018 756 : o_rnTarget = io_rnTemp;
1019 756 : io_rnTemp = -1;
1020 756 : if (!io_rbTimePart)
1021 : {
1022 242 : io_rbTimePart = readDurationT(rString, io_rnPos);
1023 : }
1024 : return (R_OVERFLOW !=
1025 756 : readUnsignedNumber(rString, io_rnPos, io_rnTemp));
1026 : }
1027 : else
1028 : {
1029 0 : return false;
1030 : }
1031 : }
1032 : }
1033 930 : return true;
1034 : }
1035 :
1036 : /** convert ISO8601 "duration" string to util::Duration */
1037 11218 : bool Converter::convertDuration(util::Duration& rDuration,
1038 : const OUString& rString)
1039 : {
1040 11218 : const OUString string = rString.trim().toAsciiUpperCase();
1041 11218 : sal_Int32 nPos(0);
1042 :
1043 11218 : bool bIsNegativeDuration(false);
1044 11218 : if (!string.isEmpty() && ('-' == string[0]))
1045 : {
1046 3 : bIsNegativeDuration = true;
1047 3 : ++nPos;
1048 : }
1049 :
1050 22436 : if ((nPos < string.getLength())
1051 11218 : && (string[nPos] != 'P')) // duration must start with "P"
1052 : {
1053 1 : return false;
1054 : }
1055 :
1056 11217 : ++nPos;
1057 :
1058 : /// last read number; -1 == no valid number! always reset after using!
1059 11217 : sal_Int32 nTemp(-1);
1060 11217 : bool bTimePart(false); // have we read 'T'?
1061 11217 : bool bSuccess(false);
1062 11217 : sal_Int32 nYears(0);
1063 11217 : sal_Int32 nMonths(0);
1064 11217 : sal_Int32 nDays(0);
1065 11217 : sal_Int32 nHours(0);
1066 11217 : sal_Int32 nMinutes(0);
1067 11217 : sal_Int32 nSeconds(0);
1068 11217 : sal_Int32 nNanoSeconds(0);
1069 :
1070 11217 : bTimePart = readDurationT(string, nPos);
1071 11217 : bSuccess = (R_SUCCESS == readUnsignedNumber(string, nPos, nTemp));
1072 :
1073 11217 : if (!bTimePart && bSuccess)
1074 : {
1075 : bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
1076 237 : nYears, 'Y');
1077 : }
1078 :
1079 11217 : if (!bTimePart && bSuccess)
1080 : {
1081 : bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
1082 235 : nMonths, 'M');
1083 : }
1084 :
1085 11217 : if (!bTimePart && bSuccess)
1086 : {
1087 : bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
1088 234 : nDays, 'D');
1089 : }
1090 :
1091 11217 : if (bTimePart)
1092 : {
1093 492 : if (-1 == nTemp) // a 'T' must be followed by a component
1094 : {
1095 2 : bSuccess = false;
1096 : }
1097 :
1098 492 : if (bSuccess)
1099 : {
1100 : bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
1101 490 : nHours, 'H');
1102 : }
1103 :
1104 492 : if (bSuccess)
1105 : {
1106 : bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
1107 490 : nMinutes, 'M');
1108 : }
1109 :
1110 : // eeek! seconds are icky.
1111 492 : if ((nPos < string.getLength()) && bSuccess)
1112 : {
1113 318 : if (string[nPos] == '.' ||
1114 149 : string[nPos] == ',')
1115 : {
1116 20 : ++nPos;
1117 20 : if (-1 != nTemp)
1118 : {
1119 19 : nSeconds = nTemp;
1120 19 : nTemp = -1;
1121 19 : const sal_Int32 nStart(nPos);
1122 19 : bSuccess = readUnsignedNumberMaxDigits(9, string, nPos, nTemp) == R_SUCCESS;
1123 19 : if ((nPos < string.getLength()) && bSuccess)
1124 : {
1125 18 : if (-1 != nTemp)
1126 : {
1127 18 : nNanoSeconds = nTemp;
1128 18 : sal_Int32 nDigits = nPos - nStart;
1129 : assert(nDigits >= 0);
1130 63 : for (; nDigits < 9; ++nDigits)
1131 : {
1132 45 : nNanoSeconds *= 10;
1133 : }
1134 18 : nTemp=-1;
1135 18 : if ('S' == string[nPos])
1136 : {
1137 18 : ++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 1 : bSuccess = false;
1153 : }
1154 : }
1155 149 : else if ('S' == string[nPos])
1156 : {
1157 147 : ++nPos;
1158 147 : if (-1 != nTemp)
1159 : {
1160 147 : nSeconds = nTemp;
1161 147 : nTemp = -1;
1162 : }
1163 : else
1164 : {
1165 0 : bSuccess = false;
1166 : }
1167 : }
1168 : }
1169 : }
1170 :
1171 11217 : if (nPos != string.getLength()) // string not processed completely?
1172 : {
1173 10520 : bSuccess = false;
1174 : }
1175 :
1176 11217 : if (nTemp != -1) // unprocessed number?
1177 : {
1178 4 : bSuccess = false;
1179 : }
1180 :
1181 11217 : if (bSuccess)
1182 : {
1183 696 : rDuration.Negative = bIsNegativeDuration;
1184 696 : rDuration.Years = static_cast<sal_Int16>(nYears);
1185 696 : rDuration.Months = static_cast<sal_Int16>(nMonths);
1186 696 : rDuration.Days = static_cast<sal_Int16>(nDays);
1187 696 : rDuration.Hours = static_cast<sal_Int16>(nHours);
1188 696 : rDuration.Minutes = static_cast<sal_Int16>(nMinutes);
1189 696 : rDuration.Seconds = static_cast<sal_Int16>(nSeconds);
1190 696 : rDuration.NanoSeconds = static_cast<sal_Int32>(nNanoSeconds);
1191 : }
1192 :
1193 11217 : return bSuccess;
1194 : }
1195 :
1196 :
1197 : static void
1198 24 : lcl_AppendTimezone(OUStringBuffer & i_rBuffer, sal_Int16 const nOffset)
1199 : {
1200 24 : if (0 == nOffset)
1201 : {
1202 24 : 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 24 : }
1231 :
1232 : /** convert util::Date to ISO "date" string */
1233 1 : 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 1 : i_rDate.Day, i_rDate.Month, i_rDate.Year, false);
1240 1 : convertDateTime(i_rBuffer, dt, pTimeZoneOffset, false);
1241 1 : }
1242 :
1243 4995 : static void convertTime(
1244 : OUStringBuffer& i_rBuffer,
1245 : const com::sun::star::util::DateTime& i_rDateTime)
1246 : {
1247 4995 : if (i_rDateTime.Hours < 10) {
1248 2049 : i_rBuffer.append('0');
1249 : }
1250 4995 : i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Hours) )
1251 4995 : .append(':');
1252 4995 : if (i_rDateTime.Minutes < 10) {
1253 1245 : i_rBuffer.append('0');
1254 : }
1255 4995 : i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Minutes) )
1256 4995 : .append(':');
1257 4995 : if (i_rDateTime.Seconds < 10) {
1258 3603 : i_rBuffer.append('0');
1259 : }
1260 4995 : i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Seconds) );
1261 4995 : if (i_rDateTime.NanoSeconds > 0) {
1262 : OSL_ENSURE(i_rDateTime.NanoSeconds < 1000000000,"NanoSeconds cannot be more than 999 999 999");
1263 833 : i_rBuffer.append('.');
1264 833 : std::ostringstream ostr;
1265 833 : ostr.fill('0');
1266 833 : ostr.width(9);
1267 833 : ostr << i_rDateTime.NanoSeconds;
1268 833 : i_rBuffer.append(OUString::createFromAscii(ostr.str().c_str()));
1269 : }
1270 4995 : }
1271 :
1272 5026 : static void convertTimeZone(
1273 : OUStringBuffer& i_rBuffer,
1274 : const com::sun::star::util::DateTime& i_rDateTime,
1275 : sal_Int16 const* pTimeZoneOffset)
1276 : {
1277 5026 : if (pTimeZoneOffset)
1278 : {
1279 0 : lcl_AppendTimezone(i_rBuffer, *pTimeZoneOffset);
1280 : }
1281 5026 : else if (i_rDateTime.IsUTC)
1282 : {
1283 24 : lcl_AppendTimezone(i_rBuffer, 0);
1284 : }
1285 5026 : }
1286 :
1287 : /** convert util::DateTime to ISO "time" or "dateTime" string */
1288 86 : void Converter::convertTimeOrDateTime(
1289 : OUStringBuffer& i_rBuffer,
1290 : const com::sun::star::util::DateTime& i_rDateTime,
1291 : sal_Int16 const* pTimeZoneOffset)
1292 : {
1293 131 : if (i_rDateTime.Year == 0 ||
1294 135 : i_rDateTime.Month < 1 || i_rDateTime.Month > 12 ||
1295 90 : i_rDateTime.Day < 1 || i_rDateTime.Day > 31)
1296 : {
1297 41 : convertTime(i_rBuffer, i_rDateTime);
1298 41 : convertTimeZone(i_rBuffer, i_rDateTime, pTimeZoneOffset);
1299 : }
1300 : else
1301 : {
1302 45 : convertDateTime(i_rBuffer, i_rDateTime, pTimeZoneOffset, true);
1303 : }
1304 86 : }
1305 :
1306 : /** convert util::DateTime to ISO "date" or "dateTime" string */
1307 4985 : 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 4985 : const sal_Unicode dash('-');
1314 4985 : const sal_Unicode zero('0');
1315 :
1316 4985 : sal_Int32 const nYear(abs(i_rDateTime.Year));
1317 4985 : if (i_rDateTime.Year < 0) {
1318 6 : i_rBuffer.append(dash); // negative
1319 : }
1320 4985 : if (nYear < 1000) {
1321 23 : i_rBuffer.append(zero);
1322 : }
1323 4985 : if (nYear < 100) {
1324 19 : i_rBuffer.append(zero);
1325 : }
1326 4985 : if (nYear < 10) {
1327 19 : i_rBuffer.append(zero);
1328 : }
1329 4985 : i_rBuffer.append(nYear).append(dash);
1330 4985 : if( i_rDateTime.Month < 10 ) {
1331 3879 : i_rBuffer.append(zero);
1332 : }
1333 4985 : i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Month) ).append(dash);
1334 4985 : if( i_rDateTime.Day < 10 ) {
1335 1291 : i_rBuffer.append(zero);
1336 : }
1337 4985 : i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Day) );
1338 :
1339 8377 : if( i_rDateTime.Seconds != 0 ||
1340 3533 : i_rDateTime.Minutes != 0 ||
1341 222 : i_rDateTime.Hours != 0 ||
1342 : i_bAddTimeIf0AM )
1343 : {
1344 4954 : i_rBuffer.append('T');
1345 4954 : convertTime(i_rBuffer, i_rDateTime);
1346 : }
1347 :
1348 4985 : convertTimeZone(i_rBuffer, i_rDateTime, pTimeZoneOffset);
1349 4985 : }
1350 :
1351 : /** convert ISO "date" or "dateTime" string to util::DateTime */
1352 13603 : 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 13603 : rString);
1359 : }
1360 :
1361 248 : static bool lcl_isLeapYear(const sal_uInt32 nYear)
1362 : {
1363 248 : return ((nYear % 4) == 0)
1364 248 : && (((nYear % 100) != 0) || ((nYear % 400) == 0));
1365 : }
1366 :
1367 : static sal_uInt16
1368 2288 : 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 2288 : if ((2 == nMonth) && lcl_isLeapYear(nYear))
1374 : {
1375 15 : return 29;
1376 : }
1377 2273 : return s_MaxDaysPerMonth[nMonth - 1];
1378 : }
1379 :
1380 31 : 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 31 : sal_Int16 nOffsetHours(abs(nSourceOffset) / 60);
1386 31 : sal_Int16 const nOffsetMinutes(abs(nSourceOffset) % 60);
1387 31 : o_rMinutes += nOffsetMinutes;
1388 31 : if (nSourceOffset < 0)
1389 : {
1390 3 : o_rMinutes += nOffsetMinutes;
1391 3 : if (60 <= o_rMinutes)
1392 : {
1393 0 : o_rMinutes -= 60;
1394 0 : ++nOffsetHours;
1395 : }
1396 3 : o_rHours += nOffsetHours;
1397 3 : if (o_rHours < 24)
1398 : {
1399 3 : 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 28 : else if (0 < nSourceOffset)
1427 : {
1428 : // argh everything is unsigned
1429 5 : if (o_rMinutes < nOffsetMinutes)
1430 : {
1431 0 : o_rMinutes += 60;
1432 0 : ++nOffsetHours;
1433 : }
1434 5 : o_rMinutes -= nOffsetMinutes;
1435 5 : sal_Int16 nDaySubtract(0);
1436 12 : while (o_rHours < nOffsetHours)
1437 : {
1438 2 : o_rHours += 24;
1439 2 : ++nDaySubtract;
1440 : }
1441 5 : o_rHours -= nOffsetHours;
1442 5 : if (o_rDay == 0)
1443 : {
1444 1 : return; // handle time without date - don't adjust what isn't there
1445 : }
1446 4 : if (nDaySubtract < o_rDay)
1447 : {
1448 4 : o_rDay -= nDaySubtract;
1449 4 : 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 24321 : readDateTimeComponent(const OUString & rString,
1466 : sal_Int32 & io_rnPos, sal_Int32 & o_rnTarget,
1467 : const sal_Int32 nMinLength, const bool bExactLength)
1468 : {
1469 24321 : const sal_Int32 nOldPos(io_rnPos);
1470 24321 : sal_Int32 nTemp(0);
1471 24321 : if (R_SUCCESS != readUnsignedNumber(rString, io_rnPos, nTemp))
1472 : {
1473 11349 : return false;
1474 : }
1475 12972 : const sal_Int32 nTokenLength(io_rnPos - nOldPos);
1476 12972 : if ((nTokenLength < nMinLength) ||
1477 10620 : (bExactLength && (nTokenLength > nMinLength)))
1478 : {
1479 19 : return false; // bad length
1480 : }
1481 12953 : o_rnTarget = nTemp;
1482 12953 : return true;
1483 : }
1484 :
1485 : /** convert ISO "date" or "dateTime" string to util::DateTime or util::Date */
1486 13681 : 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 13681 : bool bSuccess = true;
1495 :
1496 13681 : if (string.getLength() > nPos)
1497 : {
1498 2336 : if ('-' == string[nPos])
1499 : {
1500 6 : isNegative = true;
1501 6 : ++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 13681 : bSuccess = readDateTimeComponent(string, nPos, nYear, 1, false);
1510 13681 : if (!bIgnoreInvalidOrMissingDate)
1511 : {
1512 13607 : bSuccess &= (0 < nYear);
1513 : }
1514 13681 : bSuccess &= (nPos < string.getLength()); // not last token
1515 : }
1516 13681 : if (bSuccess && ('-' != string[nPos])) // separator
1517 : {
1518 0 : bSuccess = false;
1519 : }
1520 13681 : if (bSuccess)
1521 : {
1522 2325 : ++nPos;
1523 : }
1524 :
1525 13681 : if (bSuccess)
1526 : {
1527 2325 : bSuccess = readDateTimeComponent(string, nPos, nMonth, 2, true);
1528 2325 : if (!bIgnoreInvalidOrMissingDate)
1529 : {
1530 2252 : bSuccess &= (0 < nMonth);
1531 : }
1532 2325 : bSuccess &= (nMonth <= 12);
1533 2325 : bSuccess &= (nPos < string.getLength()); // not last token
1534 : }
1535 13681 : if (bSuccess && ('-' != string[nPos])) // separator
1536 : {
1537 0 : bSuccess = false;
1538 : }
1539 13681 : if (bSuccess)
1540 : {
1541 2321 : ++nPos;
1542 : }
1543 :
1544 13681 : if (bSuccess)
1545 : {
1546 2321 : bSuccess = readDateTimeComponent(string, nPos, nDay, 2, true);
1547 2321 : if (!bIgnoreInvalidOrMissingDate)
1548 : {
1549 2250 : bSuccess &= (0 < nDay);
1550 : }
1551 2321 : if (nMonth > 0) // not possible to check if month was missing
1552 : {
1553 2288 : bSuccess &= (nDay <= lcl_MaxDaysPerMonth(nMonth, nYear));
1554 : }
1555 : else assert(bIgnoreInvalidOrMissingDate);
1556 : }
1557 :
1558 13681 : if (bSuccess && (nPos < string.getLength()))
1559 : {
1560 1895 : if ('T' == string[nPos]) // time separator
1561 : {
1562 1895 : bHaveTime = true;
1563 1895 : ++nPos;
1564 : }
1565 : }
1566 :
1567 13681 : return bSuccess;
1568 : }
1569 :
1570 : /** convert ISO "date" or "dateTime" string to util::DateTime or util::Date */
1571 13771 : 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 13771 : bool bSuccess = true;
1579 :
1580 13771 : const OUString string = rString.trim().toAsciiUpperCase();
1581 :
1582 13771 : bool isNegative(false);
1583 13771 : sal_Int32 nYear(0);
1584 13771 : sal_Int32 nMonth(0);
1585 13771 : sal_Int32 nDay(0);
1586 13771 : sal_Int32 nPos(0);
1587 13771 : bool bHaveTime(false);
1588 :
1589 27542 : if ( !bIgnoreInvalidOrMissingDate
1590 164 : || string.indexOf(':') == -1 // no time?
1591 27613 : || (string.indexOf('-') != -1
1592 74 : && string.indexOf('-') < string.indexOf(':')))
1593 : {
1594 : bSuccess &= lcl_parseDate(isNegative, nYear, nMonth, nDay,
1595 13681 : bHaveTime, nPos, string, bIgnoreInvalidOrMissingDate);
1596 : }
1597 : else
1598 : {
1599 90 : bHaveTime = true;
1600 : }
1601 :
1602 13771 : sal_Int32 nHours(0);
1603 13771 : sal_Int32 nMinutes(0);
1604 13771 : sal_Int32 nSeconds(0);
1605 13771 : sal_Int32 nNanoSeconds(0);
1606 13771 : if (bSuccess && bHaveTime)
1607 : {
1608 : {
1609 1985 : bSuccess = readDateTimeComponent(string, nPos, nHours, 2, true);
1610 1985 : bSuccess &= (0 <= nHours) && (nHours <= 24);
1611 1985 : bSuccess &= (nPos < string.getLength()); // not last token
1612 : }
1613 1985 : if (bSuccess && (':' != string[nPos])) // separator
1614 : {
1615 0 : bSuccess = false;
1616 : }
1617 1985 : if (bSuccess)
1618 : {
1619 1978 : ++nPos;
1620 : }
1621 :
1622 1985 : if (bSuccess)
1623 : {
1624 1978 : bSuccess = readDateTimeComponent(string, nPos, nMinutes, 2, true);
1625 1978 : bSuccess &= (0 <= nMinutes) && (nMinutes < 60);
1626 1978 : bSuccess &= (nPos < string.getLength()); // not last token
1627 : }
1628 1985 : if (bSuccess && (':' != string[nPos])) // separator
1629 : {
1630 0 : bSuccess = false;
1631 : }
1632 1985 : if (bSuccess)
1633 : {
1634 1972 : ++nPos;
1635 : }
1636 :
1637 1985 : if (bSuccess)
1638 : {
1639 1972 : bSuccess = readDateTimeComponent(string, nPos, nSeconds, 2, true);
1640 1972 : bSuccess &= (0 <= nSeconds) && (nSeconds < 60);
1641 : }
1642 2948 : if (bSuccess && (nPos < string.getLength()) &&
1643 537 : ('.' == string[nPos] || ',' == string[nPos])) // fraction separator
1644 : {
1645 463 : ++nPos;
1646 463 : const sal_Int32 nStart(nPos);
1647 463 : sal_Int32 nTemp(0);
1648 463 : if (R_NOTHING == readUnsignedNumberMaxDigits(9, string, nPos, nTemp))
1649 : {
1650 3 : bSuccess = false;
1651 : }
1652 463 : if (bSuccess)
1653 : {
1654 460 : sal_Int32 nDigits = std::min<sal_Int32>(nPos - nStart, 9);
1655 : assert(nDigits > 0);
1656 705 : for (; nDigits < 9; ++nDigits)
1657 : {
1658 245 : nTemp *= 10;
1659 : }
1660 460 : nNanoSeconds = nTemp;
1661 : }
1662 : }
1663 :
1664 1985 : if (bSuccess && (nHours == 24))
1665 : {
1666 12 : if (!((0 == nMinutes) && (0 == nSeconds) && (0 == nNanoSeconds)))
1667 : {
1668 9 : bSuccess = false; // only 24:00:00 is valid
1669 : }
1670 : }
1671 : }
1672 :
1673 13771 : bool bHaveTimezone(false);
1674 13771 : bool bHaveTimezonePlus(false);
1675 13771 : bool bHaveTimezoneMinus(false);
1676 13771 : if (bSuccess && (nPos < string.getLength()))
1677 : {
1678 49 : const sal_Unicode c(string[nPos]);
1679 49 : if ('+' == c)
1680 : {
1681 19 : bHaveTimezone = true;
1682 19 : bHaveTimezonePlus = true;
1683 19 : ++nPos;
1684 : }
1685 30 : else if ('-' == c)
1686 : {
1687 15 : bHaveTimezone = true;
1688 15 : bHaveTimezoneMinus = true;
1689 15 : ++nPos;
1690 : }
1691 15 : else if ('Z' == c)
1692 : {
1693 15 : bHaveTimezone = true;
1694 15 : ++nPos;
1695 : }
1696 : else
1697 : {
1698 0 : bSuccess = false;
1699 : }
1700 : }
1701 13771 : sal_Int32 nTimezoneHours(0);
1702 13771 : sal_Int32 nTimezoneMinutes(0);
1703 13771 : if (bSuccess && (bHaveTimezonePlus || bHaveTimezoneMinus))
1704 : {
1705 : bSuccess = readDateTimeComponent(
1706 34 : string, nPos, nTimezoneHours, 2, true);
1707 34 : bSuccess &= (0 <= nTimezoneHours) && (nTimezoneHours <= 14);
1708 34 : bSuccess &= (nPos < string.getLength()); // not last token
1709 34 : if (bSuccess && (':' != string[nPos])) // separator
1710 : {
1711 0 : bSuccess = false;
1712 : }
1713 34 : if (bSuccess)
1714 : {
1715 25 : ++nPos;
1716 : }
1717 34 : if (bSuccess)
1718 : {
1719 : bSuccess = readDateTimeComponent(
1720 25 : string, nPos, nTimezoneMinutes, 2, true);
1721 25 : bSuccess &= (0 <= nTimezoneMinutes) && (nTimezoneMinutes < 60);
1722 : }
1723 34 : if (bSuccess && (nTimezoneHours == 14))
1724 : {
1725 6 : if (0 != nTimezoneMinutes)
1726 : {
1727 6 : bSuccess = false; // only +-14:00 is valid
1728 : }
1729 : }
1730 : }
1731 :
1732 13771 : bSuccess &= (nPos == string.getLength()); // trailing junk?
1733 :
1734 13771 : if (bSuccess)
1735 : {
1736 : sal_Int16 const nTimezoneOffset = ((bHaveTimezoneMinus) ? (-1) : (+1))
1737 2354 : * ((nTimezoneHours * 60) + nTimezoneMinutes);
1738 2354 : if (!pDate || bHaveTime) // time is optional
1739 : {
1740 : rDateTime.Year =
1741 2353 : ((isNegative) ? (-1) : (+1)) * static_cast<sal_Int16>(nYear);
1742 2353 : rDateTime.Month = static_cast<sal_uInt16>(nMonth);
1743 2353 : rDateTime.Day = static_cast<sal_uInt16>(nDay);
1744 2353 : rDateTime.Hours = static_cast<sal_uInt16>(nHours);
1745 2353 : rDateTime.Minutes = static_cast<sal_uInt16>(nMinutes);
1746 2353 : rDateTime.Seconds = static_cast<sal_uInt16>(nSeconds);
1747 2353 : rDateTime.NanoSeconds = static_cast<sal_uInt32>(nNanoSeconds);
1748 2353 : if (bHaveTimezone)
1749 : {
1750 31 : 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 31 : nTimezoneOffset);
1760 31 : rDateTime.IsUTC = true;
1761 : }
1762 : }
1763 : else
1764 : {
1765 2322 : if (pTimeZoneOffset)
1766 : {
1767 3 : pTimeZoneOffset->reset();
1768 : }
1769 2322 : rDateTime.IsUTC = false;
1770 : }
1771 2353 : rbDateTime = bHaveTime;
1772 : }
1773 : else
1774 : {
1775 : pDate->Year =
1776 1 : ((isNegative) ? (-1) : (+1)) * static_cast<sal_Int16>(nYear);
1777 1 : pDate->Month = static_cast<sal_uInt16>(nMonth);
1778 1 : pDate->Day = static_cast<sal_uInt16>(nDay);
1779 1 : 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 1 : if (pTimeZoneOffset)
1794 : {
1795 1 : pTimeZoneOffset->reset();
1796 : }
1797 : }
1798 1 : rbDateTime = false;
1799 : }
1800 : }
1801 13771 : return bSuccess;
1802 : }
1803 :
1804 : /** convert ISO "time" or "dateTime" string to util::DateTime */
1805 164 : 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 164 : 0, rDateTime, dummy, pTimeZoneOffset, rString, true);
1813 : }
1814 :
1815 : /** convert ISO "date" or "dateTime" string to util::DateTime or util::Date */
1816 13607 : 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 13607 : 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 11798 : sal_Int32 Converter::indexOfComma( const OUString& rStr,
1830 : sal_Int32 nPos )
1831 : {
1832 11798 : sal_Unicode cQuote = 0;
1833 11798 : sal_Int32 nLen = rStr.getLength();
1834 167362 : for( ; nPos < nLen; nPos++ )
1835 : {
1836 155717 : sal_Unicode c = rStr[nPos];
1837 155717 : switch( c )
1838 : {
1839 : case sal_Unicode('\''):
1840 12122 : if( 0 == cQuote )
1841 6061 : cQuote = c;
1842 6061 : else if( '\'' == cQuote )
1843 6061 : cQuote = 0;
1844 12122 : 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 153 : if( 0 == cQuote )
1855 153 : return nPos;
1856 0 : break;
1857 : }
1858 : }
1859 :
1860 11645 : 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 6275 : void ThreeByteToFourByte (const sal_Int8* pBuffer, const sal_Int32 nStart, const sal_Int32 nFullLen, OUStringBuffer& sBuffer)
1894 : {
1895 6275 : sal_Int32 nLen(nFullLen - nStart);
1896 6275 : if (nLen > 3)
1897 6204 : nLen = 3;
1898 6275 : if (nLen == 0)
1899 : {
1900 6275 : return;
1901 : }
1902 :
1903 : sal_Int32 nBinaer;
1904 6275 : switch (nLen)
1905 : {
1906 : case 1:
1907 : {
1908 41 : nBinaer = ((sal_uInt8)pBuffer[nStart + 0]) << 16;
1909 : }
1910 41 : break;
1911 : case 2:
1912 : {
1913 30 : nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
1914 30 : (((sal_uInt8)pBuffer[nStart + 1]) << 8);
1915 : }
1916 30 : break;
1917 : default:
1918 : {
1919 12408 : nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
1920 12408 : (((sal_uInt8)pBuffer[nStart + 1]) << 8) +
1921 12408 : ((sal_uInt8)pBuffer[nStart + 2]);
1922 : }
1923 6204 : break;
1924 : }
1925 :
1926 6275 : sal_Unicode buf[] = { '=', '=', '=', '=' };
1927 :
1928 6275 : sal_uInt8 nIndex (static_cast<sal_uInt8>((nBinaer & 0xFC0000) >> 18));
1929 6275 : buf[0] = aBase64EncodeTable [nIndex];
1930 :
1931 6275 : nIndex = static_cast<sal_uInt8>((nBinaer & 0x3F000) >> 12);
1932 6275 : buf[1] = aBase64EncodeTable [nIndex];
1933 6275 : if (nLen > 1)
1934 : {
1935 6234 : nIndex = static_cast<sal_uInt8>((nBinaer & 0xFC0) >> 6);
1936 6234 : buf[2] = aBase64EncodeTable [nIndex];
1937 6234 : if (nLen > 2)
1938 : {
1939 6204 : nIndex = static_cast<sal_uInt8>((nBinaer & 0x3F));
1940 6204 : buf[3] = aBase64EncodeTable [nIndex];
1941 : }
1942 : }
1943 6275 : sBuffer.append(buf, SAL_N_ELEMENTS(buf));
1944 : }
1945 :
1946 72 : void Converter::encodeBase64(OUStringBuffer& aStrBuffer, const uno::Sequence<sal_Int8>& aPass)
1947 : {
1948 72 : sal_Int32 i(0);
1949 72 : sal_Int32 nBufferLength(aPass.getLength());
1950 72 : const sal_Int8* pBuffer = aPass.getConstArray();
1951 6419 : while (i < nBufferLength)
1952 : {
1953 6275 : ThreeByteToFourByte (pBuffer, i, nBufferLength, aStrBuffer);
1954 6275 : i += 3;
1955 : }
1956 72 : }
1957 :
1958 317 : 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 317 : decodeBase64SomeChars( aBuffer, sBuffer );
1964 : OSL_ENSURE( nCharsDecoded == sBuffer.getLength(), "some bytes left in base64 decoding!" );
1965 317 : }
1966 :
1967 1036 : sal_Int32 Converter::decodeBase64SomeChars(
1968 : uno::Sequence<sal_Int8>& rOutBuffer,
1969 : const OUString& rInBuffer)
1970 : {
1971 1036 : sal_Int32 nInBufferLen = rInBuffer.getLength();
1972 1036 : sal_Int32 nMinOutBufferLen = (nInBufferLen / 4) * 3;
1973 1036 : if( rOutBuffer.getLength() < nMinOutBufferLen )
1974 319 : rOutBuffer.realloc( nMinOutBufferLen );
1975 :
1976 1036 : const sal_Unicode *pInBuffer = rInBuffer.getStr();
1977 1036 : sal_Int8 *pOutBuffer = rOutBuffer.getArray();
1978 1036 : sal_Int8 *pOutBufferStart = pOutBuffer;
1979 1036 : sal_Int32 nCharsDecoded = 0;
1980 :
1981 : sal_uInt8 aDecodeBuffer[4];
1982 1036 : sal_Int32 nBytesToDecode = 0;
1983 1036 : sal_Int32 nBytesGotFromDecoding = 3;
1984 1036 : sal_Int32 nInBufferPos= 0;
1985 16774940 : while( nInBufferPos < nInBufferLen )
1986 : {
1987 16772868 : sal_Unicode cChar = *pInBuffer;
1988 16772868 : if( cChar >= '+' && cChar <= 'z' )
1989 : {
1990 16758782 : sal_uInt8 nByte = aBase64DecodeTable[cChar-'+'];
1991 16758782 : if( nByte != 255 )
1992 : {
1993 : // We have found a valid character!
1994 16758782 : 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 16758782 : if( '=' == cChar && nBytesToDecode > 2 )
1999 815 : nBytesGotFromDecoding--;
2000 16758782 : if( 4 == nBytesToDecode )
2001 : {
2002 : // Four characters found, so we may convert now!
2003 8379388 : sal_uInt32 nOut = (aDecodeBuffer[0] << 18) +
2004 8379388 : (aDecodeBuffer[1] << 12) +
2005 8379388 : (aDecodeBuffer[2] << 6) +
2006 8379388 : aDecodeBuffer[3];
2007 :
2008 4189694 : *pOutBuffer++ = (sal_Int8)((nOut & 0xff0000) >> 16);
2009 4189694 : if( nBytesGotFromDecoding > 1 )
2010 4189439 : *pOutBuffer++ = (sal_Int8)((nOut & 0xff00) >> 8);
2011 4189694 : if( nBytesGotFromDecoding > 2 )
2012 4189136 : *pOutBuffer++ = (sal_Int8)(nOut & 0xff);
2013 4189694 : nCharsDecoded = nInBufferPos + 1;
2014 4189694 : nBytesToDecode = 0;
2015 4189694 : nBytesGotFromDecoding = 3;
2016 : }
2017 : }
2018 : else
2019 : {
2020 0 : nCharsDecoded++;
2021 16758782 : }
2022 : }
2023 : else
2024 : {
2025 14086 : nCharsDecoded++;
2026 : }
2027 :
2028 16772868 : nInBufferPos++;
2029 16772868 : pInBuffer++;
2030 : }
2031 1036 : if( (pOutBuffer - pOutBufferStart) != rOutBuffer.getLength() )
2032 650 : rOutBuffer.realloc( pOutBuffer - pOutBufferStart );
2033 :
2034 1036 : return nCharsDecoded;
2035 : }
2036 :
2037 26274 : double Converter::GetConversionFactor(OUStringBuffer& rUnit, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
2038 : {
2039 26274 : double fRetval(1.0);
2040 26274 : rUnit.setLength(0L);
2041 :
2042 26274 : const sal_Char* psUnit = 0;
2043 :
2044 26274 : if(nSourceUnit != nTargetUnit)
2045 : {
2046 587 : switch(nSourceUnit)
2047 : {
2048 : case MeasureUnit::TWIP:
2049 : {
2050 20 : switch(nTargetUnit)
2051 : {
2052 : case MeasureUnit::MM_100TH:
2053 : {
2054 : // 0.01mm = 0.57twip (exactly)
2055 4 : fRetval = ((25400.0 / 1440.0) / 10.0);
2056 4 : break;
2057 : }
2058 : case MeasureUnit::MM_10TH:
2059 : {
2060 : // 0.01mm = 0.57twip (exactly)
2061 4 : fRetval = ((25400.0 / 1440.0) / 100.0);
2062 4 : break;
2063 : }
2064 : case MeasureUnit::MM:
2065 : {
2066 : // 0.01mm = 0.57twip (exactly)
2067 4 : fRetval = ((25400.0 / 1440.0) / 1000.0);
2068 4 : psUnit = gpsMM;
2069 4 : break;
2070 : }
2071 : case MeasureUnit::CM:
2072 : {
2073 : // 0.001cm = 0.57twip (exactly)
2074 4 : fRetval = ((25400.0 / 1440.0) / 10000.0);
2075 4 : psUnit = gpsCM;
2076 4 : break;
2077 : }
2078 : case MeasureUnit::POINT:
2079 : {
2080 : // 0.01pt = 0.2twip (exactly)
2081 2 : fRetval = ((1000.0 / 20.0) / 1000.0);
2082 2 : psUnit = gpsPT;
2083 2 : 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 2 : fRetval = ((100000.0 / 1440.0) / 100000.0);
2091 2 : psUnit = gpsINCH;
2092 2 : break;
2093 : }
2094 : }
2095 20 : break;
2096 : }
2097 : case MeasureUnit::POINT:
2098 : {
2099 105 : switch(nTargetUnit)
2100 : {
2101 : case MeasureUnit::MM_100TH:
2102 : {
2103 : // 1mm = 72 / 25.4 pt (exactly)
2104 2 : fRetval = ( 2540.0 / 72.0 );
2105 2 : break;
2106 : }
2107 : case MeasureUnit::MM_10TH:
2108 : {
2109 : // 1mm = 72 / 25.4 pt (exactly)
2110 2 : fRetval = ( 254.0 / 72.0 );
2111 2 : break;
2112 : }
2113 : case MeasureUnit::MM:
2114 : {
2115 : // 1mm = 72 / 25.4 pt (exactly)
2116 2 : fRetval = ( 25.4 / 72.0 );
2117 2 : psUnit = gpsMM;
2118 2 : break;
2119 :
2120 : }
2121 : case MeasureUnit::CM:
2122 : {
2123 : // 1cm = 72 / 2.54 pt (exactly)
2124 2 : fRetval = ( 2.54 / 72.0 );
2125 2 : psUnit = gpsCM;
2126 2 : break;
2127 : }
2128 : case MeasureUnit::TWIP:
2129 : {
2130 : // 1twip = 72 / 1440 pt (exactly)
2131 2 : fRetval = 20.0; // 1440.0 / 72.0
2132 2 : psUnit = gpsPC;
2133 2 : 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 95 : fRetval = ( 1.0 / 72.0 );
2141 95 : psUnit = gpsINCH;
2142 95 : break;
2143 : }
2144 : }
2145 105 : break;
2146 : }
2147 : case MeasureUnit::MM_10TH:
2148 : {
2149 12 : switch(nTargetUnit)
2150 : {
2151 : case MeasureUnit::MM_100TH:
2152 : {
2153 2 : fRetval = 10.0;
2154 2 : break;
2155 : }
2156 : case MeasureUnit::MM:
2157 : {
2158 : // 0.01mm = 1 mm/100 (exactly)
2159 2 : fRetval = ((10.0 / 1.0) / 100.0);
2160 2 : psUnit = gpsMM;
2161 2 : break;
2162 : }
2163 : case MeasureUnit::CM:
2164 : {
2165 2 : fRetval = ((10.0 / 1.0) / 1000.0);
2166 2 : psUnit = gpsCM;
2167 2 : break;
2168 : }
2169 : case MeasureUnit::POINT:
2170 : {
2171 : // 0.01pt = 0.35 mm/100 (exactly)
2172 2 : fRetval = ((72000.0 / 2540.0) / 100.0);
2173 2 : psUnit = gpsPT;
2174 2 : break;
2175 : }
2176 : case MeasureUnit::TWIP:
2177 : {
2178 2 : fRetval = ((20.0 * 72000.0 / 2540.0) / 100.0);
2179 2 : psUnit = gpsPC;
2180 2 : 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 2 : fRetval = ((100000.0 / 2540.0) / 10000.0);
2188 2 : psUnit = gpsINCH;
2189 2 : break;
2190 : }
2191 : }
2192 12 : break;
2193 : }
2194 : case MeasureUnit::MM_100TH:
2195 : {
2196 424 : switch(nTargetUnit)
2197 : {
2198 : case MeasureUnit::MM_10TH:
2199 : {
2200 2 : fRetval = ((10.0 / 1.0) / 100.0);
2201 2 : break;
2202 : }
2203 : case MeasureUnit::MM:
2204 : {
2205 : // 0.01mm = 1 mm/100 (exactly)
2206 8 : fRetval = ((10.0 / 1.0) / 1000.0);
2207 8 : psUnit = gpsMM;
2208 8 : break;
2209 : }
2210 : case MeasureUnit::CM:
2211 : {
2212 396 : fRetval = ((10.0 / 1.0) / 10000.0);
2213 396 : psUnit = gpsCM;
2214 396 : break;
2215 : }
2216 : case MeasureUnit::POINT:
2217 : {
2218 : // 0.01pt = 0.35 mm/100 (exactly)
2219 10 : fRetval = ((72000.0 / 2540.0) / 1000.0);
2220 10 : psUnit = gpsPT;
2221 10 : break;
2222 : }
2223 : case MeasureUnit::TWIP:
2224 : {
2225 2 : fRetval = ((20.0 * 72000.0 / 2540.0) / 1000.0);
2226 2 : psUnit = gpsPC;
2227 2 : 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 6 : fRetval = ((100000.0 / 2540.0) / 100000.0);
2235 6 : psUnit = gpsINCH;
2236 6 : break;
2237 : }
2238 : }
2239 424 : break;
2240 : }
2241 : case MeasureUnit::MM:
2242 : {
2243 12 : switch(nTargetUnit)
2244 : {
2245 : case MeasureUnit::MM_100TH:
2246 : {
2247 2 : fRetval = 100.0;
2248 2 : break;
2249 : }
2250 : case MeasureUnit::MM_10TH:
2251 : {
2252 2 : fRetval = 10.0;
2253 2 : break;
2254 : }
2255 : case MeasureUnit::CM:
2256 : {
2257 2 : fRetval = 0.1;
2258 2 : psUnit = gpsCM;
2259 2 : break;
2260 : }
2261 : case MeasureUnit::POINT:
2262 : {
2263 2 : fRetval = 72.0 / (2.54 * 10);
2264 2 : psUnit = gpsPT;
2265 2 : break;
2266 : }
2267 : case MeasureUnit::TWIP:
2268 : {
2269 2 : fRetval = (20.0 * 72.0) / (2.54 * 10);
2270 2 : psUnit = gpsPC;
2271 2 : break;
2272 : }
2273 : case MeasureUnit::INCH:
2274 : default:
2275 : {
2276 : OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for cm values");
2277 2 : fRetval = 1 / (2.54 * 10);
2278 2 : psUnit = gpsINCH;
2279 2 : break;
2280 : }
2281 : }
2282 12 : break;
2283 : }
2284 : case MeasureUnit::CM:
2285 : {
2286 8 : 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 2 : fRetval = 10.0;
2301 2 : psUnit = gpsMM;
2302 2 : break;
2303 : }
2304 : case MeasureUnit::CM:
2305 : {
2306 0 : break;
2307 : }
2308 : case MeasureUnit::POINT:
2309 : {
2310 2 : fRetval = 72.0 / 2.54;
2311 2 : psUnit = gpsPT;
2312 2 : break;
2313 : }
2314 : case MeasureUnit::TWIP:
2315 : {
2316 2 : fRetval = (20.0 * 72.0) / 2.54;
2317 2 : psUnit = gpsPC;
2318 2 : break;
2319 : }
2320 : case MeasureUnit::INCH:
2321 : default:
2322 : {
2323 : OSL_ENSURE( MeasureUnit::INCH == nTargetUnit, "output unit not supported for cm values");
2324 2 : fRetval = 1 / 2.54;
2325 2 : psUnit = gpsINCH;
2326 2 : break;
2327 : }
2328 : }
2329 8 : break;
2330 : }
2331 : case MeasureUnit::INCH:
2332 : {
2333 6 : 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 2 : fRetval = 2.54;
2354 2 : psUnit = gpsCM;
2355 2 : break;
2356 : }
2357 : case MeasureUnit::POINT:
2358 : {
2359 2 : fRetval = 72.0;
2360 2 : psUnit = gpsPT;
2361 2 : break;
2362 : }
2363 : case MeasureUnit::TWIP:
2364 : {
2365 2 : fRetval = 72.0 * 20.0;
2366 2 : psUnit = gpsPC;
2367 2 : 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 6 : break;
2378 : }
2379 : default:
2380 : OSL_ENSURE(false, "sax::Converter::GetConversionFactor(): "
2381 : "source unit not supported");
2382 0 : break;
2383 : }
2384 :
2385 587 : if( psUnit )
2386 567 : rUnit.appendAscii( psUnit );
2387 : }
2388 :
2389 26274 : return fRetval;
2390 : }
2391 :
2392 18330 : sal_Int16 Converter::GetUnitFromString(const OUString& rString, sal_Int16 nDefaultUnit)
2393 : {
2394 18330 : sal_Int32 nPos = 0L;
2395 18330 : sal_Int32 nLen = rString.getLength();
2396 18330 : sal_Int16 nRetUnit = nDefaultUnit;
2397 :
2398 : // skip white space
2399 36660 : while( nPos < nLen && ' ' == rString[nPos] )
2400 0 : nPos++;
2401 :
2402 : // skip negative
2403 18330 : if( nPos < nLen && '-' == rString[nPos] )
2404 0 : nPos++;
2405 :
2406 : // skip number
2407 71530 : while( nPos < nLen && '0' <= rString[nPos] && '9' >= rString[nPos] )
2408 34870 : nPos++;
2409 :
2410 18330 : if( nPos < nLen && '.' == rString[nPos] )
2411 : {
2412 4718 : nPos++;
2413 27839 : while( nPos < nLen && '0' <= rString[nPos] && '9' >= rString[nPos] )
2414 18403 : nPos++;
2415 : }
2416 :
2417 : // skip white space
2418 36660 : while( nPos < nLen && ' ' == rString[nPos] )
2419 0 : nPos++;
2420 :
2421 18330 : if( nPos < nLen )
2422 : {
2423 18324 : 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 176 : if(nPos+1 < nLen && (rString[nPos+1] == 'm'
2434 0 : || rString[nPos+1] == 'M'))
2435 88 : nRetUnit = MeasureUnit::CM;
2436 88 : 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 194 : if(nPos+1 < nLen && (rString[nPos+1] == 'n'
2448 0 : || rString[nPos+1] == 'N'))
2449 97 : nRetUnit = MeasureUnit::INCH;
2450 97 : break;
2451 : }
2452 : case sal_Unicode('m'):
2453 : case sal_Unicode('M'):
2454 : {
2455 12 : if(nPos+1 < nLen && (rString[nPos+1] == 'm'
2456 0 : || rString[nPos+1] == 'M'))
2457 6 : nRetUnit = MeasureUnit::MM;
2458 6 : break;
2459 : }
2460 : case sal_Unicode('p'):
2461 : case sal_Unicode('P'):
2462 : {
2463 36266 : if(nPos+1 < nLen && (rString[nPos+1] == 't'
2464 0 : || rString[nPos+1] == 'T'))
2465 18133 : nRetUnit = MeasureUnit::POINT;
2466 18133 : if(nPos+1 < nLen && (rString[nPos+1] == 'c'
2467 18133 : || rString[nPos+1] == 'C'))
2468 0 : nRetUnit = MeasureUnit::TWIP;
2469 18133 : break;
2470 : }
2471 : }
2472 : }
2473 :
2474 18330 : 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: */
|