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