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