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 <com/sun/star/util/XNumberFormatTypes.hpp>
21 : #include <com/sun/star/util/NumberFormatter.hpp>
22 :
23 : #include <string.h>
24 : #include <stdio.h>
25 : #include <tools/resary.hxx>
26 : #include <rtl/math.hxx>
27 : #include <sal/macros.h>
28 : #include "analysishelper.hxx"
29 : #include "analysis.hrc"
30 :
31 : using namespace ::com::sun::star;
32 :
33 :
34 :
35 : #define UNIQUE sal_False // function name does not exist in Calc
36 : #define DOUBLE sal_True // function name exists in Calc
37 :
38 : #define STDPAR sal_False // all parameters are described
39 : #define INTPAR sal_True // first parameter is internal
40 :
41 : #define FUNCDATA( FUNCNAME, DBL, OPT, NUMOFPAR, CAT ) \
42 : { "get" #FUNCNAME, ANALYSIS_FUNCNAME_##FUNCNAME, ANALYSIS_##FUNCNAME, DBL, OPT, ANALYSIS_DEFFUNCNAME_##FUNCNAME, NUMOFPAR, CAT }
43 :
44 : const FuncDataBase pFuncDatas[] =
45 : {
46 : // UNIQUE or INTPAR or
47 : // function name DOUBLE STDPAR # of param category
48 : FUNCDATA( Workday, UNIQUE, INTPAR, 3, FDCat_DateTime ),
49 : FUNCDATA( Yearfrac, UNIQUE, INTPAR, 3, FDCat_DateTime ),
50 : FUNCDATA( Edate, UNIQUE, INTPAR, 2, FDCat_DateTime ),
51 : FUNCDATA( Weeknum, DOUBLE, INTPAR, 2, FDCat_DateTime ),
52 : FUNCDATA( Eomonth, UNIQUE, INTPAR, 2, FDCat_DateTime ),
53 : FUNCDATA( Networkdays, UNIQUE, INTPAR, 3, FDCat_DateTime ),
54 : FUNCDATA( Iseven, DOUBLE, STDPAR, 1, FDCat_Inf ),
55 : FUNCDATA( Isodd, DOUBLE, STDPAR, 1, FDCat_Inf ),
56 : FUNCDATA( Multinomial, UNIQUE, STDPAR, 1, FDCat_Math ),
57 : FUNCDATA( Seriessum, UNIQUE, STDPAR, 4, FDCat_Math ),
58 : FUNCDATA( Quotient, UNIQUE, STDPAR, 2, FDCat_Math ),
59 : FUNCDATA( Mround, UNIQUE, STDPAR, 2, FDCat_Math ),
60 : FUNCDATA( Sqrtpi, UNIQUE, STDPAR, 1, FDCat_Math ),
61 : FUNCDATA( Randbetween, UNIQUE, STDPAR, 2, FDCat_Math ),
62 : FUNCDATA( Gcd, DOUBLE, INTPAR, 1, FDCat_Math ),
63 : FUNCDATA( Lcm, DOUBLE, INTPAR, 1, FDCat_Math ),
64 : FUNCDATA( Besseli, UNIQUE, STDPAR, 2, FDCat_Tech ),
65 : FUNCDATA( Besselj, UNIQUE, STDPAR, 2, FDCat_Tech ),
66 : FUNCDATA( Besselk, UNIQUE, STDPAR, 2, FDCat_Tech ),
67 : FUNCDATA( Bessely, UNIQUE, STDPAR, 2, FDCat_Tech ),
68 : FUNCDATA( Bin2Oct, UNIQUE, INTPAR, 2, FDCat_Tech ),
69 : FUNCDATA( Bin2Dec, UNIQUE, STDPAR, 1, FDCat_Tech ),
70 : FUNCDATA( Bin2Hex, UNIQUE, INTPAR, 2, FDCat_Tech ),
71 : FUNCDATA( Oct2Bin, UNIQUE, INTPAR, 2, FDCat_Tech ),
72 : FUNCDATA( Oct2Dec, UNIQUE, STDPAR, 1, FDCat_Tech ),
73 : FUNCDATA( Oct2Hex, UNIQUE, INTPAR, 2, FDCat_Tech ),
74 : FUNCDATA( Dec2Bin, UNIQUE, INTPAR, 2, FDCat_Tech ),
75 : FUNCDATA( Dec2Hex, UNIQUE, INTPAR, 2, FDCat_Tech ),
76 : FUNCDATA( Dec2Oct, UNIQUE, INTPAR, 2, FDCat_Tech ),
77 : FUNCDATA( Hex2Bin, UNIQUE, INTPAR, 2, FDCat_Tech ),
78 : FUNCDATA( Hex2Dec, UNIQUE, STDPAR, 1, FDCat_Tech ),
79 : FUNCDATA( Hex2Oct, UNIQUE, INTPAR, 2, FDCat_Tech ),
80 : FUNCDATA( Delta, UNIQUE, INTPAR, 2, FDCat_Tech ),
81 : FUNCDATA( Erf, UNIQUE, INTPAR, 2, FDCat_Tech ),
82 : FUNCDATA( Erfc, UNIQUE, STDPAR, 1, FDCat_Tech ),
83 : FUNCDATA( Gestep, UNIQUE, INTPAR, 2, FDCat_Tech ),
84 : FUNCDATA( Factdouble, UNIQUE, STDPAR, 1, FDCat_Tech ),
85 : FUNCDATA( Imabs, UNIQUE, STDPAR, 1, FDCat_Tech ),
86 : FUNCDATA( Imaginary, UNIQUE, STDPAR, 1, FDCat_Tech ),
87 : FUNCDATA( Impower, UNIQUE, STDPAR, 2, FDCat_Tech ),
88 : FUNCDATA( Imargument, UNIQUE, STDPAR, 1, FDCat_Tech ),
89 : FUNCDATA( Imcos, UNIQUE, STDPAR, 1, FDCat_Tech ),
90 : FUNCDATA( Imdiv, UNIQUE, STDPAR, 2, FDCat_Tech ),
91 : FUNCDATA( Imexp, UNIQUE, STDPAR, 1, FDCat_Tech ),
92 : FUNCDATA( Imconjugate, UNIQUE, STDPAR, 1, FDCat_Tech ),
93 : FUNCDATA( Imln, UNIQUE, STDPAR, 1, FDCat_Tech ),
94 : FUNCDATA( Imlog10, UNIQUE, STDPAR, 1, FDCat_Tech ),
95 : FUNCDATA( Imlog2, UNIQUE, STDPAR, 1, FDCat_Tech ),
96 : FUNCDATA( Improduct, UNIQUE, INTPAR, 2, FDCat_Tech ),
97 : FUNCDATA( Imreal, UNIQUE, STDPAR, 1, FDCat_Tech ),
98 : FUNCDATA( Imsin, UNIQUE, STDPAR, 1, FDCat_Tech ),
99 : FUNCDATA( Imsub, UNIQUE, STDPAR, 2, FDCat_Tech ),
100 : FUNCDATA( Imsqrt, UNIQUE, STDPAR, 1, FDCat_Tech ),
101 : FUNCDATA( Imsum, UNIQUE, INTPAR, 1, FDCat_Tech ),
102 : FUNCDATA( Imtan, UNIQUE, STDPAR, 1, FDCat_Tech ),
103 : FUNCDATA( Imsec, UNIQUE, STDPAR, 1, FDCat_Tech ),
104 : FUNCDATA( Imcsc, UNIQUE, STDPAR, 1, FDCat_Tech ),
105 : FUNCDATA( Imcot, UNIQUE, STDPAR, 1, FDCat_Tech ),
106 : FUNCDATA( Imsinh, UNIQUE, STDPAR, 1, FDCat_Tech ),
107 : FUNCDATA( Imcosh, UNIQUE, STDPAR, 1, FDCat_Tech ),
108 : FUNCDATA( Imsech, UNIQUE, STDPAR, 1, FDCat_Tech ),
109 : FUNCDATA( Imcsch, UNIQUE, STDPAR, 1, FDCat_Tech ),
110 : FUNCDATA( Complex, UNIQUE, STDPAR, 3, FDCat_Tech ),
111 : FUNCDATA( Convert, DOUBLE, STDPAR, 3, FDCat_Tech ),
112 : FUNCDATA( Amordegrc, UNIQUE, INTPAR, 7, FDCat_Finance ),
113 : FUNCDATA( Amorlinc, UNIQUE, INTPAR, 7, FDCat_Finance ),
114 : FUNCDATA( Accrint, UNIQUE, INTPAR, 7, FDCat_Finance ),
115 : FUNCDATA( Accrintm, UNIQUE, INTPAR, 5, FDCat_Finance ),
116 : FUNCDATA( Received, UNIQUE, INTPAR, 5, FDCat_Finance ),
117 : FUNCDATA( Disc, UNIQUE, INTPAR, 5, FDCat_Finance ),
118 : FUNCDATA( Duration, DOUBLE, INTPAR, 6, FDCat_Finance ),
119 : FUNCDATA( Effect, DOUBLE, STDPAR, 2, FDCat_Finance ),
120 : FUNCDATA( Cumprinc, DOUBLE, STDPAR, 6, FDCat_Finance ),
121 : FUNCDATA( Cumipmt, DOUBLE, STDPAR, 6, FDCat_Finance ),
122 : FUNCDATA( Price, UNIQUE, INTPAR, 7, FDCat_Finance ),
123 : FUNCDATA( Pricedisc, UNIQUE, INTPAR, 5, FDCat_Finance ),
124 : FUNCDATA( Pricemat, UNIQUE, INTPAR, 6, FDCat_Finance ),
125 : FUNCDATA( Mduration, UNIQUE, INTPAR, 6, FDCat_Finance ),
126 : FUNCDATA( Nominal, DOUBLE, STDPAR, 2, FDCat_Finance ),
127 : FUNCDATA( Dollarfr, UNIQUE, STDPAR, 2, FDCat_Finance ),
128 : FUNCDATA( Dollarde, UNIQUE, STDPAR, 2, FDCat_Finance ),
129 : FUNCDATA( Yield, UNIQUE, INTPAR, 7, FDCat_Finance ),
130 : FUNCDATA( Yielddisc, UNIQUE, INTPAR, 5, FDCat_Finance ),
131 : FUNCDATA( Yieldmat, UNIQUE, INTPAR, 6, FDCat_Finance ),
132 : FUNCDATA( Tbilleq, UNIQUE, INTPAR, 3, FDCat_Finance ),
133 : FUNCDATA( Tbillprice, UNIQUE, INTPAR, 3, FDCat_Finance ),
134 : FUNCDATA( Tbillyield, UNIQUE, INTPAR, 3, FDCat_Finance ),
135 : FUNCDATA( Oddfprice, UNIQUE, INTPAR, 9, FDCat_Finance ),
136 : FUNCDATA( Oddfyield, UNIQUE, INTPAR, 9, FDCat_Finance ),
137 : FUNCDATA( Oddlprice, UNIQUE, INTPAR, 8, FDCat_Finance ),
138 : FUNCDATA( Oddlyield, UNIQUE, INTPAR, 8, FDCat_Finance ),
139 : FUNCDATA( Xirr, UNIQUE, INTPAR, 3, FDCat_Finance ),
140 : FUNCDATA( Xnpv, UNIQUE, STDPAR, 3, FDCat_Finance ),
141 : FUNCDATA( Intrate, UNIQUE, INTPAR, 5, FDCat_Finance ),
142 : FUNCDATA( Coupncd, UNIQUE, INTPAR, 4, FDCat_Finance ),
143 : FUNCDATA( Coupdays, UNIQUE, INTPAR, 4, FDCat_Finance ),
144 : FUNCDATA( Coupdaysnc, UNIQUE, INTPAR, 4, FDCat_Finance ),
145 : FUNCDATA( Coupdaybs, UNIQUE, INTPAR, 4, FDCat_Finance ),
146 : FUNCDATA( Couppcd, UNIQUE, INTPAR, 4, FDCat_Finance ),
147 : FUNCDATA( Coupnum, UNIQUE, INTPAR, 4, FDCat_Finance ),
148 : FUNCDATA( Fvschedule, UNIQUE, STDPAR, 2, FDCat_Finance )
149 : };
150 : #undef FUNCDATA
151 :
152 :
153 0 : sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
154 : {
155 0 : if( (nMonth == 2) && IsLeapYear( nYear ) )
156 0 : return 29;
157 : static const sal_uInt16 aDaysInMonth[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
158 0 : return aDaysInMonth[ nMonth ];
159 : }
160 :
161 :
162 : /**
163 : * Convert a date to a count of days starting from 01/01/0001
164 : *
165 : * The internal representation of a Date used in this Addin
166 : * is the number of days between 01/01/0001 and the date
167 : * this function converts a Day , Month, Year representation
168 : * to this internal Date value.
169 : *
170 : */
171 :
172 0 : sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
173 : {
174 0 : sal_Int32 nDays = ((sal_Int32)nYear-1) * 365;
175 0 : nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
176 :
177 0 : for( sal_uInt16 i = 1; i < nMonth; i++ )
178 0 : nDays += DaysInMonth(i,nYear);
179 0 : nDays += nDay;
180 :
181 0 : return nDays;
182 : }
183 :
184 :
185 : /**
186 : * Convert a count of days starting from 01/01/0001 to a date
187 : *
188 : * The internal representation of a Date used in this Addin
189 : * is the number of days between 01/01/0001 and the date
190 : * this function converts this internal Date value
191 : * to a Day , Month, Year representation of a Date.
192 : *
193 : */
194 :
195 0 : void DaysToDate( sal_Int32 nDays, sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear )
196 : throw( lang::IllegalArgumentException )
197 : {
198 0 : if( nDays < 0 )
199 0 : throw lang::IllegalArgumentException();
200 :
201 : sal_Int32 nTempDays;
202 0 : sal_Int32 i = 0;
203 : sal_Bool bCalc;
204 :
205 0 : do
206 : {
207 0 : nTempDays = nDays;
208 0 : rYear = (sal_uInt16)((nTempDays / 365) - i);
209 0 : nTempDays -= ((sal_Int32) rYear -1) * 365;
210 0 : nTempDays -= (( rYear -1) / 4) - (( rYear -1) / 100) + ((rYear -1) / 400);
211 0 : bCalc = sal_False;
212 0 : if ( nTempDays < 1 )
213 : {
214 0 : i++;
215 0 : bCalc = sal_True;
216 : }
217 : else
218 : {
219 0 : if ( nTempDays > 365 )
220 : {
221 0 : if ( (nTempDays != 366) || !IsLeapYear( rYear ) )
222 : {
223 0 : i--;
224 0 : bCalc = sal_True;
225 : }
226 : }
227 : }
228 : }
229 : while ( bCalc );
230 :
231 0 : rMonth = 1;
232 0 : while ( (sal_Int32)nTempDays > DaysInMonth( rMonth, rYear ) )
233 : {
234 0 : nTempDays -= DaysInMonth( rMonth, rYear );
235 0 : rMonth++;
236 : }
237 0 : rDay = (sal_uInt16)nTempDays;
238 0 : }
239 :
240 :
241 : /**
242 : * Get the null date used by the spreadsheet document
243 : *
244 : * The internal representation of a Date used in this Addin
245 : * is the number of days between 01/01/0001 and the date
246 : * this function returns this internal Date value for the document null date
247 : *
248 : */
249 :
250 0 : sal_Int32 GetNullDate( const uno::Reference< beans::XPropertySet >& xOpt ) throw( uno::RuntimeException )
251 : {
252 0 : if( xOpt.is() )
253 : {
254 : try
255 : {
256 0 : uno::Any aAny = xOpt->getPropertyValue( "NullDate" );
257 0 : util::Date aDate;
258 0 : if( aAny >>= aDate )
259 0 : return DateToDays( aDate.Day, aDate.Month, aDate.Year );
260 : }
261 0 : catch( uno::Exception& )
262 : {
263 : }
264 : }
265 :
266 : // no null date available -> no calculations possible
267 0 : throw uno::RuntimeException();
268 : }
269 :
270 :
271 0 : sal_Int32 GetDiffDate360(
272 : sal_uInt16 nDay1, sal_uInt16 nMonth1, sal_uInt16 nYear1, sal_Bool bLeapYear1,
273 : sal_uInt16 nDay2, sal_uInt16 nMonth2, sal_uInt16 nYear2,
274 : sal_Bool bUSAMethod )
275 : {
276 0 : if( nDay1 == 31 )
277 0 : nDay1--;
278 0 : else if( bUSAMethod && ( nMonth1 == 2 && ( nDay1 == 29 || ( nDay1 == 28 && !bLeapYear1 ) ) ) )
279 0 : nDay1 = 30;
280 :
281 0 : if( nDay2 == 31 )
282 : {
283 0 : if( bUSAMethod && nDay1 != 30 )
284 : {
285 0 : nDay2 = 1;
286 0 : if( nMonth2 == 12 )
287 : {
288 0 : nYear2++;
289 0 : nMonth2 = 1;
290 : }
291 : else
292 0 : nMonth2++;
293 : }
294 : else
295 0 : nDay2 = 30;
296 : }
297 :
298 0 : return nDay2 + nMonth2 * 30 + nYear2 * 360 - nDay1 - nMonth1 * 30 - nYear1 * 360;
299 : }
300 :
301 :
302 0 : sal_Int32 GetDiffDate360( sal_Int32 nNullDate, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod )
303 : {
304 0 : nDate1 += nNullDate;
305 0 : nDate2 += nNullDate;
306 :
307 : sal_uInt16 nDay1, nMonth1, nYear1, nDay2, nMonth2, nYear2;
308 :
309 0 : DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
310 0 : DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
311 :
312 0 : return GetDiffDate360( nDay1, nMonth1, nYear1, IsLeapYear( nYear1 ), nDay2, nMonth2, nYear2, bUSAMethod );
313 : }
314 :
315 :
316 0 : sal_Int32 GetDaysInYears( sal_uInt16 nYear1, sal_uInt16 nYear2 )
317 : {
318 0 : sal_uInt16 nLeaps = 0;
319 0 : for( sal_uInt16 n = nYear1 ; n <= nYear2 ; n++ )
320 : {
321 0 : if( IsLeapYear( n ) )
322 0 : nLeaps++;
323 : }
324 :
325 0 : sal_uInt32 nSum = 1;
326 0 : nSum += nYear2;
327 0 : nSum -= nYear1;
328 0 : nSum *= 365;
329 0 : nSum += nLeaps;
330 :
331 0 : return nSum;
332 : }
333 :
334 :
335 0 : sal_Int32 GetDiffDate( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
336 : sal_Int32* pOptDaysIn1stYear ) throw( uno::RuntimeException, lang::IllegalArgumentException )
337 : {
338 0 : sal_Bool bNeg = nStartDate > nEndDate;
339 :
340 0 : if( bNeg )
341 : {
342 0 : sal_Int32 n = nEndDate;
343 0 : nEndDate = nStartDate;
344 0 : nStartDate = n;
345 : }
346 :
347 : sal_Int32 nRet;
348 :
349 0 : switch( nMode )
350 : {
351 : case 0: // 0=USA (NASD) 30/360
352 : case 4: // 4=Europe 30/360
353 : {
354 : sal_uInt16 nD1, nM1, nY1, nD2, nM2, nY2;
355 :
356 0 : nStartDate += nNullDate;
357 0 : nEndDate += nNullDate;
358 :
359 0 : DaysToDate( nStartDate, nD1, nM1, nY1 );
360 0 : DaysToDate( nEndDate, nD2, nM2, nY2 );
361 :
362 0 : sal_Bool bLeap = IsLeapYear( nY1 );
363 : sal_Int32 nDays, nMonths;
364 :
365 0 : nMonths = nM2 - nM1;
366 0 : nDays = nD2 - nD1;
367 :
368 0 : nMonths += ( nY2 - nY1 ) * 12;
369 :
370 0 : nRet = nMonths * 30 + nDays;
371 0 : if( nMode == 0 && nM1 == 2 && nM2 != 2 && nY1 == nY2 )
372 0 : nRet -= bLeap? 1 : 2;
373 :
374 0 : if( pOptDaysIn1stYear )
375 0 : *pOptDaysIn1stYear = 360;
376 : }
377 0 : break;
378 : case 1: // 1=exact/exact
379 0 : if( pOptDaysIn1stYear )
380 : {
381 : sal_uInt16 nD, nM, nY;
382 :
383 0 : DaysToDate( nStartDate + nNullDate, nD, nM, nY );
384 :
385 0 : *pOptDaysIn1stYear = IsLeapYear( nY )? 366 : 365;
386 : }
387 0 : nRet = nEndDate - nStartDate;
388 0 : break;
389 : case 2: // 2=exact/360
390 0 : nRet = nEndDate - nStartDate;
391 0 : if( pOptDaysIn1stYear )
392 0 : *pOptDaysIn1stYear = 360;
393 0 : break;
394 : case 3: //3=exact/365
395 0 : nRet = nEndDate - nStartDate;
396 0 : if( pOptDaysIn1stYear )
397 0 : *pOptDaysIn1stYear = 365;
398 0 : break;
399 : default:
400 0 : throw lang::IllegalArgumentException();
401 : }
402 :
403 0 : return bNeg? -nRet : nRet;
404 : }
405 :
406 :
407 0 : double GetYearDiff( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
408 : {
409 : sal_Int32 nDays1stYear;
410 0 : sal_Int32 nTotalDays = GetDiffDate( nNullDate, nStartDate, nEndDate, nMode, &nDays1stYear );
411 :
412 0 : return double( nTotalDays ) / double( nDays1stYear );
413 : }
414 :
415 :
416 0 : sal_Int32 GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
417 : {
418 0 : switch( nMode )
419 : {
420 : case 0: // 0=USA (NASD) 30/360
421 : case 2: // 2=exact/360
422 : case 4: // 4=Europe 30/360
423 0 : return 360;
424 : case 1: // 1=exact/exact
425 : {
426 : sal_uInt16 nD, nM, nY;
427 0 : nDate += nNullDate;
428 0 : DaysToDate( nDate, nD, nM, nY );
429 0 : return IsLeapYear( nY )? 366 : 365;
430 : }
431 : case 3: //3=exact/365
432 0 : return 365;
433 : default:
434 0 : throw lang::IllegalArgumentException();
435 : }
436 : }
437 :
438 :
439 : //fdo40100 toDo: make function fully compliant with ODFF1.2
440 : /**
441 : * Function GetYearFrac implements YEARFRAC as defined in:
442 : * Open Document Format for Office Applications version 1.2 Part 2, par. 6.10.24
443 : * The calculations are defined in:
444 : * Open Document Format for Office Applications version 1.2 Part 2, par. 4.11.7
445 : */
446 0 : double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
447 : {
448 0 : if( nStartDate == nEndDate )
449 0 : return 0.0; // nothing to do...
450 :
451 0 : if( nStartDate > nEndDate )
452 : {
453 0 : sal_Int32 n = nEndDate;
454 0 : nEndDate = nStartDate;
455 0 : nStartDate = n;
456 : }
457 :
458 0 : sal_Int32 nDate1 = nStartDate + nNullDate;
459 0 : sal_Int32 nDate2 = nEndDate + nNullDate;
460 :
461 : sal_uInt16 nDay1, nDay2;
462 : sal_uInt16 nMonth1, nMonth2;
463 : sal_uInt16 nYear1, nYear2;
464 :
465 0 : DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
466 0 : DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
467 :
468 : // calculate days between nDate1 and nDate2
469 : sal_Int32 nDayDiff;
470 0 : switch( nMode )
471 : {
472 : case 0: // 0=USA (NASD) 30/360
473 0 : if ( nDay1 == 31 )
474 : {
475 0 : nDay1--;
476 : }
477 0 : if ( nDay1 == 30 && nDay2 == 31 )
478 : {
479 0 : nDay2--;
480 : }
481 : else
482 : {
483 0 : if ( nMonth1 == 2 && nDay1 == ( IsLeapYear( nYear1 ) ? 29 : 28 ) )
484 : {
485 0 : nDay1 = 30;
486 0 : if ( nMonth2 == 2 && nDay2 == ( IsLeapYear( nYear2 ) ? 29 : 28 ) )
487 : {
488 0 : nDay2 = 30;
489 : }
490 : }
491 : }
492 0 : nDayDiff = ( nYear2 - nYear1 ) * 360 + ( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );
493 0 : break;
494 : case 1: // 1=exact/exact
495 : case 2: // 2=exact/360
496 : case 3: // 3=exact/365
497 0 : nDayDiff = nDate2 - nDate1;
498 0 : break;
499 : case 4: // 4=Europe 30/360
500 0 : if ( nDay1 == 31 )
501 : {
502 0 : nDay1--;
503 : }
504 0 : if ( nDay2 == 31 )
505 : {
506 0 : nDay2--;
507 : }
508 0 : nDayDiff = ( nYear2 - nYear1 ) * 360 + ( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );
509 0 : break;
510 : default:
511 0 : throw lang::IllegalArgumentException();
512 : }
513 :
514 : //calculate days in year
515 : double nDaysInYear;
516 0 : switch( nMode )
517 : {
518 : case 0: // 0=USA (NASD) 30/360
519 : case 2: // 2=exact/360
520 : case 4: // 4=Europe 30/360
521 0 : nDaysInYear = 360;
522 0 : break;
523 : case 1: // 1=exact/exact
524 : {
525 0 : bool isYearDifferent = ( nYear1 != nYear2 );
526 0 : if ( isYearDifferent &&
527 0 : ( ( nYear2 != nYear1 + 1 ) ||
528 0 : ( nMonth1 < nMonth2 ) ||
529 0 : ( nMonth1 == nMonth2 && nDay1 < nDay2 ) ) )
530 : {
531 : // return average of days in year between nDate1 and nDate2, inclusive
532 0 : sal_Int32 nDayCount = 0;
533 0 : for ( sal_Int16 i = nYear1; i <= nYear2; i++ )
534 0 : nDayCount += ( IsLeapYear( i ) ? 366 : 365 );
535 :
536 0 : nDaysInYear = ( double ) nDayCount / ( double ) ( nYear2 - nYear1 + 1 );
537 : }
538 : else
539 : {
540 0 : if ( isYearDifferent && IsLeapYear( nYear1 ) )
541 : {
542 0 : nDaysInYear = 366;
543 : }
544 : else
545 : {
546 : //if Feb 29 is between nDate1 and ndate2, inclusive
547 0 : if ( ( IsLeapYear( nYear1 ) && nMonth1 <= 2 && nDay1 <= 29 ) ||
548 0 : ( IsLeapYear( nYear2 ) && ( nMonth2 > 3 || ( nMonth2 == 2 && nDay1 == 29 ) ) ) )
549 : {
550 0 : nDaysInYear = 366;
551 : }
552 : else
553 : {
554 0 : nDaysInYear = 365;
555 0 : for ( sal_Int16 i = nYear1; i <= nYear2; i++ )
556 : {
557 0 : if ( IsLeapYear( i ) )
558 : {
559 0 : nDaysInYear = 366;
560 0 : break;
561 : }
562 : }
563 : }
564 : }
565 : }
566 : }
567 0 : break;
568 : case 3: // 3=exact/365
569 0 : nDaysInYear = 365;
570 0 : break;
571 : default:
572 0 : throw lang::IllegalArgumentException();
573 : }
574 :
575 0 : return double( nDayDiff ) / nDaysInYear;
576 : }
577 :
578 0 : double BinomialCoefficient( double n, double k )
579 : {
580 : // This method is a copy of BinomKoeff()
581 : // found in sc/source/core/tool/interpr3.cxx
582 :
583 0 : double nVal = 0.0;
584 0 : k = ::rtl::math::approxFloor(k);
585 0 : if (n < k)
586 0 : nVal = 0.0;
587 0 : else if (k == 0.0)
588 0 : nVal = 1.0;
589 : else
590 : {
591 0 : nVal = n/k;
592 0 : n--;
593 0 : k--;
594 0 : while (k > 0.0)
595 : {
596 0 : nVal *= n/k;
597 0 : k--;
598 0 : n--;
599 : }
600 : }
601 0 : return nVal;
602 : }
603 :
604 0 : double GetGcd( double f1, double f2 )
605 : {
606 0 : double f = fmod( f1, f2 );
607 0 : while( f > 0.0 )
608 : {
609 0 : f1 = f2;
610 0 : f2 = f;
611 0 : f = fmod( f1, f2 );
612 : }
613 :
614 0 : return f2;
615 : }
616 :
617 :
618 0 : double ConvertToDec( const OUString& aStr, sal_uInt16 nBase, sal_uInt16 nCharLim ) throw( uno::RuntimeException, lang::IllegalArgumentException )
619 : {
620 0 : if ( nBase < 2 || nBase > 36 )
621 0 : throw lang::IllegalArgumentException();
622 :
623 0 : sal_uInt32 nStrLen = aStr.getLength();
624 0 : if( nStrLen > nCharLim )
625 0 : throw lang::IllegalArgumentException();
626 0 : else if( !nStrLen )
627 0 : return 0.0;
628 :
629 0 : double fVal = 0.0;
630 :
631 0 : register const sal_Unicode* p = aStr.getStr();
632 :
633 0 : sal_uInt16 nFirstDig = 0;
634 0 : sal_Bool bFirstDig = sal_True;
635 0 : double fBase = nBase;
636 :
637 0 : while ( *p )
638 : {
639 : sal_uInt16 n;
640 :
641 0 : if( '0' <= *p && *p <= '9' )
642 0 : n = *p - '0';
643 0 : else if( 'A' <= *p && *p <= 'Z' )
644 0 : n = 10 + ( *p - 'A' );
645 0 : else if ( 'a' <= *p && *p <= 'z' )
646 0 : n = 10 + ( *p - 'a' );
647 : else
648 0 : n = nBase;
649 :
650 0 : if( n < nBase )
651 : {
652 0 : if( bFirstDig )
653 : {
654 0 : bFirstDig = sal_False;
655 0 : nFirstDig = n;
656 : }
657 0 : fVal = fVal * fBase + double( n );
658 : }
659 : else
660 : // illegal char!
661 0 : throw lang::IllegalArgumentException();
662 :
663 0 : p++;
664 :
665 : }
666 :
667 0 : if( nStrLen == nCharLim && !bFirstDig && (nFirstDig >= nBase / 2) )
668 : { // handling negativ values
669 0 : fVal = ( pow( double( nBase ), double( nCharLim ) ) - fVal ); // complement
670 0 : fVal *= -1.0;
671 : }
672 :
673 0 : return fVal;
674 : }
675 :
676 :
677 0 : static inline sal_Char GetMaxChar( sal_uInt16 nBase )
678 : {
679 0 : const sal_Char* c = "--123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
680 0 : return c[ nBase ];
681 : }
682 :
683 :
684 0 : OUString ConvertFromDec( double fNum, double fMin, double fMax, sal_uInt16 nBase,
685 : sal_Int32 nPlaces, sal_Int32 nMaxPlaces, sal_Bool bUsePlaces ) throw( uno::RuntimeException, lang::IllegalArgumentException )
686 : {
687 0 : fNum = ::rtl::math::approxFloor( fNum );
688 0 : fMin = ::rtl::math::approxFloor( fMin );
689 0 : fMax = ::rtl::math::approxFloor( fMax );
690 :
691 0 : if( fNum < fMin || fNum > fMax || ( bUsePlaces && ( nPlaces <= 0 || nPlaces > nMaxPlaces ) ) )
692 0 : throw lang::IllegalArgumentException();
693 :
694 0 : sal_Int64 nNum = static_cast< sal_Int64 >( fNum );
695 0 : sal_Bool bNeg = nNum < 0;
696 0 : if( bNeg )
697 0 : nNum = sal_Int64( pow( double( nBase ), double( nMaxPlaces ) ) ) + nNum;
698 :
699 0 : OUString aRet( OUString::valueOf( nNum, nBase ).toAsciiUpperCase() );
700 :
701 :
702 0 : if( bUsePlaces )
703 : {
704 0 : sal_Int32 nLen = aRet.getLength();
705 0 : if( !bNeg && nLen > nPlaces )
706 : {
707 0 : throw lang::IllegalArgumentException();
708 : }
709 0 : else if( ( bNeg && nLen < nMaxPlaces ) || ( !bNeg && nLen < nPlaces ) )
710 : {
711 0 : sal_Int32 nLeft = nPlaces - nLen;
712 0 : sal_Char* p = new sal_Char[ nLeft + 1 ];
713 0 : memset( p, bNeg? GetMaxChar( nBase ) : '0', nLeft );
714 0 : p[ nLeft ] = 0x00;
715 0 : OUString aTmp( p, nLeft, RTL_TEXTENCODING_MS_1252 );
716 0 : aTmp += aRet;
717 0 : aRet = aTmp;
718 :
719 0 : delete[] p;
720 : }
721 : }
722 :
723 0 : return aRet;
724 : }
725 :
726 : // implementation moved to module sal, see #i97091#
727 0 : double Erf( double x )
728 : {
729 0 : return ::rtl::math::erf(x);
730 : }
731 :
732 : // implementation moved to module sal, see #i97091#
733 0 : double Erfc( double x )
734 : {
735 0 : return ::rtl::math::erfc(x);
736 : }
737 :
738 0 : inline sal_Bool IsNum( sal_Unicode c )
739 : {
740 0 : return c >= '0' && c <= '9';
741 : }
742 :
743 :
744 0 : inline sal_Bool IsComma( sal_Unicode c )
745 : {
746 0 : return c == '.' || c == ',';
747 : }
748 :
749 :
750 0 : inline sal_Bool IsExpStart( sal_Unicode c )
751 : {
752 0 : return c == 'e' || c == 'E';
753 : }
754 :
755 :
756 0 : inline sal_Bool IsImagUnit( sal_Unicode c )
757 : {
758 0 : return c == 'i' || c == 'j';
759 : }
760 :
761 :
762 0 : inline sal_uInt16 GetVal( sal_Unicode c )
763 : {
764 0 : return sal_uInt16( c - '0' );
765 : }
766 :
767 :
768 0 : sal_Bool ParseDouble( const sal_Unicode*& rp, double& rRet )
769 : {
770 0 : double fInt = 0.0;
771 0 : double fFrac = 0.0;
772 0 : double fMult = 0.1; // multiplier to multiply digits with, when adding fractional ones
773 0 : sal_Int32 nExp = 0;
774 0 : sal_Int32 nMaxExp = 307;
775 0 : sal_uInt16 nDigCnt = 18; // max. number of digits to read in, rest doesn't matter
776 :
777 : enum State { S_End = 0, S_Sign, S_IntStart, S_Int, S_IgnoreIntDigs, S_Frac, S_IgnoreFracDigs, S_ExpSign, S_Exp };
778 :
779 0 : State eS = S_Sign;
780 :
781 0 : sal_Bool bNegNum = sal_False;
782 0 : sal_Bool bNegExp = sal_False;
783 :
784 0 : const sal_Unicode* p = rp;
785 : sal_Unicode c;
786 :
787 0 : while( eS )
788 : {
789 0 : c = *p;
790 0 : switch( eS )
791 : {
792 : case S_Sign:
793 0 : if( IsNum( c ) )
794 : {
795 0 : fInt = GetVal( c );
796 0 : nDigCnt--;
797 0 : eS = S_Int;
798 : }
799 0 : else if( c == '-' )
800 : {
801 0 : bNegNum = sal_True;
802 0 : eS = S_IntStart;
803 : }
804 0 : else if( c == '+' )
805 0 : eS = S_IntStart;
806 0 : else if( IsComma( c ) )
807 0 : eS = S_Frac;
808 : else
809 0 : return sal_False;
810 0 : break;
811 : case S_IntStart:
812 0 : if( IsNum( c ) )
813 : {
814 0 : fInt = GetVal( c );
815 0 : nDigCnt--;
816 0 : eS = S_Int;
817 : }
818 0 : else if( IsComma( c ) )
819 0 : eS = S_Frac;
820 0 : else if( IsImagUnit( c ) )
821 : {
822 0 : rRet = 0.0;
823 0 : return sal_True;
824 : }
825 : else
826 0 : return sal_False;
827 0 : break;
828 : case S_Int:
829 0 : if( IsNum( c ) )
830 : {
831 0 : fInt *= 10.0;
832 0 : fInt += double( GetVal( c ) );
833 0 : nDigCnt--;
834 0 : if( !nDigCnt )
835 0 : eS = S_IgnoreIntDigs;
836 : }
837 0 : else if( IsComma( c ) )
838 0 : eS = S_Frac;
839 0 : else if( IsExpStart( c ) )
840 0 : eS = S_ExpSign;
841 : else
842 0 : eS = S_End;
843 0 : break;
844 : case S_IgnoreIntDigs:
845 0 : if( IsNum( c ) )
846 0 : nExp++; // just multiply num with 10... ;-)
847 0 : else if( IsComma( c ) )
848 0 : eS = S_Frac;
849 0 : else if( IsExpStart( c ) )
850 0 : eS = S_ExpSign;
851 : else
852 0 : eS = S_End;
853 0 : break;
854 : case S_Frac:
855 0 : if( IsNum( c ) )
856 : {
857 0 : fFrac += double( GetVal( c ) ) * fMult;
858 0 : nDigCnt--;
859 0 : if( nDigCnt )
860 0 : fMult *= 0.1;
861 : else
862 0 : eS = S_IgnoreFracDigs;
863 : }
864 0 : else if( IsExpStart( c ) )
865 0 : eS = S_ExpSign;
866 : else
867 0 : eS = S_End;
868 0 : break;
869 : case S_IgnoreFracDigs:
870 0 : if( IsExpStart( c ) )
871 0 : eS = S_ExpSign;
872 0 : else if( !IsNum( c ) )
873 0 : eS = S_End;
874 0 : break;
875 : case S_ExpSign:
876 0 : if( IsNum( c ) )
877 : {
878 0 : nExp = GetVal( c );
879 0 : eS = S_Exp;
880 : }
881 0 : else if( c == '-' )
882 : {
883 0 : bNegExp = sal_True;
884 0 : eS = S_Exp;
885 : }
886 0 : else if( c != '+' )
887 0 : eS = S_End;
888 0 : break;
889 : case S_Exp:
890 0 : if( IsNum( c ) )
891 : {
892 0 : nExp *= 10;
893 0 : nExp += GetVal( c );
894 0 : if( nExp > nMaxExp )
895 0 : return sal_False;
896 : }
897 : else
898 0 : eS = S_End;
899 0 : break;
900 : case S_End: // to avoid compiler warning
901 0 : break; // loop exits anyway
902 : }
903 :
904 0 : p++;
905 : }
906 :
907 0 : p--; // set pointer back to last
908 0 : rp = p;
909 :
910 0 : fInt += fFrac;
911 0 : sal_Int32 nLog10 = sal_Int32( log10( fInt ) );
912 :
913 0 : if( bNegExp )
914 0 : nExp = -nExp;
915 :
916 0 : if( nLog10 + nExp > nMaxExp )
917 0 : return sal_False;
918 :
919 0 : fInt = ::rtl::math::pow10Exp( fInt, nExp );
920 :
921 0 : if( bNegNum )
922 0 : fInt = -fInt;
923 :
924 0 : rRet = fInt;
925 :
926 0 : return sal_True;
927 : }
928 :
929 :
930 0 : OUString GetString( double f, sal_Bool bLeadingSign, sal_uInt16 nMaxDig )
931 : {
932 0 : const int nBuff = 256;
933 : sal_Char aBuff[ nBuff + 1 ];
934 0 : const char* pFormStr = bLeadingSign? "%+.*g" : "%.*g";
935 0 : int nLen = snprintf( aBuff, nBuff, pFormStr, int( nMaxDig ), f );
936 : // you never know which underlying implementation you get ...
937 0 : aBuff[nBuff] = 0;
938 0 : if ( nLen < 0 || nLen > nBuff )
939 0 : nLen = strlen( aBuff );
940 :
941 0 : OUString aRet( aBuff, nLen, RTL_TEXTENCODING_MS_1252 );
942 :
943 0 : return aRet;
944 : }
945 :
946 :
947 0 : double GetAmordegrc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
948 : double fRestVal, double fPer, double fRate, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
949 : {
950 0 : if( nBase == 2 )
951 0 : throw lang::IllegalArgumentException();
952 :
953 0 : sal_uInt32 nPer = sal_uInt32( fPer );
954 0 : double fUsePer = 1.0 / fRate;
955 : double fAmorCoeff;
956 :
957 0 : if( fUsePer < 3.0 )
958 0 : fAmorCoeff = 1.0;
959 0 : else if( fUsePer < 5.0 )
960 0 : fAmorCoeff = 1.5;
961 0 : else if( fUsePer <= 6.0 )
962 0 : fAmorCoeff = 2.0;
963 : else
964 0 : fAmorCoeff = 2.5;
965 :
966 0 : fRate *= fAmorCoeff;
967 0 : double fNRate = ::rtl::math::round( GetYearFrac( nNullDate, nDate, nFirstPer, nBase ) * fRate * fCost, 0 );
968 0 : fCost -= fNRate;
969 0 : double fRest = fCost - fRestVal; // Anschaffungskosten - Restwert - Summe aller Abschreibungen
970 :
971 0 : for( sal_uInt32 n = 0 ; n < nPer ; n++ )
972 : {
973 0 : fNRate = ::rtl::math::round( fRate * fCost, 0 );
974 0 : fRest -= fNRate;
975 :
976 0 : if( fRest < 0.0 )
977 : {
978 0 : switch( nPer - n )
979 : {
980 : case 0:
981 : case 1:
982 0 : return ::rtl::math::round( fCost * 0.5, 0 );
983 : default:
984 0 : return 0.0;
985 : }
986 : }
987 :
988 0 : fCost -= fNRate;
989 : }
990 :
991 0 : return fNRate;
992 : }
993 :
994 :
995 0 : double GetAmorlinc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
996 : double fRestVal, double fPer, double fRate, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
997 : {
998 0 : if( nBase == 2 )
999 0 : throw lang::IllegalArgumentException();
1000 :
1001 0 : sal_uInt32 nPer = sal_uInt32( fPer );
1002 0 : double fOneRate = fCost * fRate;
1003 0 : double fCostDelta = fCost - fRestVal;
1004 0 : double f0Rate = GetYearFrac( nNullDate, nDate, nFirstPer, nBase ) * fRate * fCost;
1005 0 : sal_uInt32 nNumOfFullPeriods = sal_uInt32( ( fCost - fRestVal - f0Rate) / fOneRate );
1006 :
1007 0 : if( nPer == 0 )
1008 0 : return f0Rate;
1009 0 : else if( nPer <= nNumOfFullPeriods )
1010 0 : return fOneRate;
1011 0 : else if( nPer == nNumOfFullPeriods + 1 )
1012 0 : return fCostDelta - fOneRate * nNumOfFullPeriods - f0Rate;
1013 : else
1014 0 : return 0.0;
1015 : }
1016 :
1017 :
1018 0 : double GetDuration( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup,
1019 : double fYield, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1020 : {
1021 0 : double fYearfrac = GetYearFrac( nNullDate, nSettle, nMat, nBase );
1022 0 : double fNumOfCoups = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase );
1023 0 : double fDur = 0.0;
1024 0 : const double f100 = 100.0;
1025 0 : fCoup *= f100 / double( nFreq ); // fCoup is used as cash flow
1026 0 : fYield /= nFreq;
1027 0 : fYield += 1.0;
1028 :
1029 0 : double nDiff = fYearfrac * nFreq - fNumOfCoups;
1030 :
1031 : double t;
1032 :
1033 0 : for( t = 1.0 ; t < fNumOfCoups ; t++ )
1034 0 : fDur += ( t + nDiff ) * ( fCoup ) / pow( fYield, t + nDiff );
1035 :
1036 0 : fDur += ( fNumOfCoups + nDiff ) * ( fCoup + f100 ) / pow( fYield, fNumOfCoups + nDiff );
1037 :
1038 0 : double p = 0.0;
1039 0 : for( t = 1.0 ; t < fNumOfCoups ; t++ )
1040 0 : p += fCoup / pow( fYield, t + nDiff );
1041 :
1042 0 : p += ( fCoup + f100 ) / pow( fYield, fNumOfCoups + nDiff );
1043 :
1044 0 : fDur /= p;
1045 0 : fDur /= double( nFreq );
1046 :
1047 0 : return fDur;
1048 : }
1049 :
1050 :
1051 0 : double GetYieldmat( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
1052 : double fRate, double fPrice, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1053 : {
1054 0 : double fIssMat = GetYearFrac( nNullDate, nIssue, nMat, nBase );
1055 0 : double fIssSet = GetYearFrac( nNullDate, nIssue, nSettle, nBase );
1056 0 : double fSetMat = GetYearFrac( nNullDate, nSettle, nMat, nBase );
1057 :
1058 0 : double y = 1.0 + fIssMat * fRate;
1059 0 : y /= fPrice / 100.0 + fIssSet * fRate;
1060 0 : y--;
1061 0 : y /= fSetMat;
1062 :
1063 0 : return y;
1064 : }
1065 :
1066 :
1067 0 : double GetOddfprice( sal_Int32 /*nNullDate*/, sal_Int32 /*nSettle*/, sal_Int32 /*nMat*/, sal_Int32 /*nIssue*/,
1068 : sal_Int32 /*nFirstCoup*/, double /*fRate*/, double /*fYield*/, double /*fRedemp*/, sal_Int32 /*nFreq*/,
1069 : sal_Int32 /*nBase*/ ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1070 : {
1071 0 : throw uno::RuntimeException(); // #87380#
1072 : }
1073 :
1074 :
1075 0 : double getYield_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice,
1076 : double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1077 : {
1078 0 : double fRate = fCoup;
1079 0 : double fPriceN = 0.0;
1080 0 : double fYield1 = 0.0;
1081 0 : double fYield2 = 1.0;
1082 0 : double fPrice1 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield1, fRedemp, nFreq, nBase );
1083 0 : double fPrice2 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield2, fRedemp, nFreq, nBase );
1084 0 : double fYieldN = ( fYield2 - fYield1 ) * 0.5;
1085 :
1086 0 : for( sal_uInt32 nIter = 0 ; nIter < 100 && fPriceN != fPrice ; nIter++ )
1087 : {
1088 0 : fPriceN = getPrice_( nNullDate, nSettle, nMat, fRate, fYieldN, fRedemp, nFreq, nBase );
1089 :
1090 0 : if( fPrice == fPrice1 )
1091 0 : return fYield1;
1092 0 : else if( fPrice == fPrice2 )
1093 0 : return fYield2;
1094 0 : else if( fPrice == fPriceN )
1095 0 : return fYieldN;
1096 0 : else if( fPrice < fPrice2 )
1097 : {
1098 0 : fYield2 *= 2.0;
1099 0 : fPrice2 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield2, fRedemp, nFreq, nBase );
1100 :
1101 0 : fYieldN = ( fYield2 - fYield1 ) * 0.5;
1102 : }
1103 : else
1104 : {
1105 0 : if( fPrice < fPriceN )
1106 : {
1107 0 : fYield1 = fYieldN;
1108 0 : fPrice1 = fPriceN;
1109 : }
1110 : else
1111 : {
1112 0 : fYield2 = fYieldN;
1113 0 : fPrice2 = fPriceN;
1114 : }
1115 :
1116 0 : fYieldN = fYield2 - ( fYield2 - fYield1 ) * ( ( fPrice - fPrice2 ) / ( fPrice1 - fPrice2 ) );
1117 : }
1118 : }
1119 :
1120 0 : if( fabs( fPrice - fPriceN ) > fPrice / 100.0 )
1121 0 : throw lang::IllegalArgumentException(); // result not precise enough
1122 :
1123 0 : return fYieldN;
1124 : }
1125 :
1126 :
1127 0 : double getPrice_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield,
1128 : double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1129 : {
1130 0 : double fFreq = nFreq;
1131 :
1132 0 : double fE = GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase );
1133 0 : double fDSC_E = GetCoupdaysnc( nNullDate, nSettle, nMat, nFreq, nBase ) / fE;
1134 0 : double fN = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase );
1135 0 : double fA = GetCoupdaybs( nNullDate, nSettle, nMat, nFreq, nBase );
1136 :
1137 0 : double fRet = fRedemp / ( pow( 1.0 + fYield / fFreq, fN - 1.0 + fDSC_E ) );
1138 0 : fRet -= 100.0 * fRate / fFreq * fA / fE;
1139 :
1140 0 : double fT1 = 100.0 * fRate / fFreq;
1141 0 : double fT2 = 1.0 + fYield / fFreq;
1142 :
1143 0 : for( double fK = 0.0 ; fK < fN ; fK++ )
1144 0 : fRet += fT1 / pow( fT2, fK + fDSC_E );
1145 :
1146 0 : return fRet;
1147 : }
1148 :
1149 :
1150 0 : double GetOddfyield( sal_Int32 /*nNullDate*/, sal_Int32 /*nSettle*/, sal_Int32 /*nMat*/, sal_Int32 /*nIssue*/,
1151 : sal_Int32 /*nFirstCoup*/, double /*fRate*/, double /*fPrice*/, double /*fRedemp*/, sal_Int32 /*nFreq*/,
1152 : sal_Int32 /*nBase*/ ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1153 : {
1154 0 : throw uno::RuntimeException(); // #87380#
1155 : }
1156 :
1157 :
1158 0 : double GetOddlprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastCoup,
1159 : double fRate, double fYield, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1160 : {
1161 0 : double fFreq = double( nFreq );
1162 0 : double fDCi = GetYearFrac( nNullDate, nLastCoup, nMat, nBase ) * fFreq;
1163 0 : double fDSCi = GetYearFrac( nNullDate, nSettle, nMat, nBase ) * fFreq;
1164 0 : double fAi = GetYearFrac( nNullDate, nLastCoup, nSettle, nBase ) * fFreq;
1165 :
1166 0 : double p = fRedemp + fDCi * 100.0 * fRate / fFreq;
1167 0 : p /= fDSCi * fYield / fFreq + 1.0;
1168 0 : p -= fAi * 100.0 * fRate / fFreq;
1169 :
1170 0 : return p;
1171 : }
1172 :
1173 :
1174 0 : double GetOddlyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastCoup,
1175 : double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1176 : {
1177 0 : double fFreq = double( nFreq );
1178 0 : double fDCi = GetYearFrac( nNullDate, nLastCoup, nMat, nBase ) * fFreq;
1179 0 : double fDSCi = GetYearFrac( nNullDate, nSettle, nMat, nBase ) * fFreq;
1180 0 : double fAi = GetYearFrac( nNullDate, nLastCoup, nSettle, nBase ) * fFreq;
1181 :
1182 0 : double y = fRedemp + fDCi * 100.0 * fRate / fFreq;
1183 0 : y /= fPrice + fAi * 100.0 * fRate / fFreq;
1184 0 : y--;
1185 0 : y *= fFreq / fDSCi;
1186 :
1187 0 : return y;
1188 : }
1189 :
1190 :
1191 0 : double GetRmz( double fZins, double fZzr, double fBw, double fZw, sal_Int32 nF )
1192 : {
1193 : double fRmz;
1194 0 : if( fZins == 0.0 )
1195 0 : fRmz = ( fBw + fZw ) / fZzr;
1196 : else
1197 : {
1198 0 : double fTerm = pow( 1.0 + fZins, fZzr );
1199 0 : if( nF > 0 )
1200 0 : fRmz = ( fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins / ( 1.0 - 1.0 / fTerm ) ) / ( 1.0 + fZins );
1201 : else
1202 0 : fRmz = fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins / ( 1.0 - 1.0 / fTerm );
1203 : }
1204 :
1205 0 : return -fRmz;
1206 : }
1207 :
1208 :
1209 0 : double GetZw( double fZins, double fZzr, double fRmz, double fBw, sal_Int32 nF )
1210 : {
1211 : double fZw;
1212 0 : if( fZins == 0.0 )
1213 0 : fZw = fBw + fRmz * fZzr;
1214 : else
1215 : {
1216 0 : double fTerm = pow( 1.0 + fZins, fZzr );
1217 0 : if( nF > 0 )
1218 0 : fZw = fBw * fTerm + fRmz * ( 1.0 + fZins ) * ( fTerm - 1.0 ) / fZins;
1219 : else
1220 0 : fZw = fBw * fTerm + fRmz * ( fTerm - 1.0 ) / fZins;
1221 : }
1222 :
1223 0 : return -fZw;
1224 : }
1225 :
1226 :
1227 : //-----------------------------------------------------------------------------
1228 : // financial functions COUP***
1229 :
1230 :
1231 : //-------
1232 : // COUPPCD: find last coupon date before settlement (can be equal to settlement)
1233 0 : static void lcl_GetCouppcd( ScaDate& rDate, const ScaDate& rSettle, const ScaDate& rMat, sal_Int32 nFreq )
1234 : throw( lang::IllegalArgumentException )
1235 : {
1236 0 : rDate = rMat;
1237 0 : rDate.setYear( rSettle.getYear() );
1238 0 : if( rDate < rSettle )
1239 0 : rDate.addYears( 1 );
1240 0 : while( rDate > rSettle )
1241 0 : rDate.addMonths( -12 / nFreq );
1242 0 : }
1243 :
1244 0 : double GetCouppcd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1245 : throw( uno::RuntimeException, lang::IllegalArgumentException )
1246 : {
1247 0 : if( nSettle >= nMat || CHK_Freq )
1248 0 : throw lang::IllegalArgumentException();
1249 :
1250 0 : ScaDate aDate;
1251 0 : lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
1252 0 : return aDate.getDate( nNullDate );
1253 : }
1254 :
1255 :
1256 : //-------
1257 : // COUPNCD: find first coupon date after settlement (is never equal to settlement)
1258 0 : static void lcl_GetCoupncd( ScaDate& rDate, const ScaDate& rSettle, const ScaDate& rMat, sal_Int32 nFreq )
1259 : throw( lang::IllegalArgumentException )
1260 : {
1261 0 : rDate = rMat;
1262 0 : rDate.setYear( rSettle.getYear() );
1263 0 : if( rDate > rSettle )
1264 0 : rDate.addYears( -1 );
1265 0 : while( rDate <= rSettle )
1266 0 : rDate.addMonths( 12 / nFreq );
1267 0 : }
1268 :
1269 0 : double GetCoupncd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1270 : throw( uno::RuntimeException, lang::IllegalArgumentException )
1271 : {
1272 0 : if( nSettle >= nMat || CHK_Freq )
1273 0 : throw lang::IllegalArgumentException();
1274 :
1275 0 : ScaDate aDate;
1276 0 : lcl_GetCoupncd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
1277 0 : return aDate.getDate( nNullDate );
1278 : }
1279 :
1280 :
1281 : //-------
1282 : // COUPDAYBS: get day count: coupon date before settlement <-> settlement
1283 0 : double GetCoupdaybs( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1284 : throw( uno::RuntimeException, lang::IllegalArgumentException )
1285 : {
1286 0 : if( nSettle >= nMat || CHK_Freq )
1287 0 : throw lang::IllegalArgumentException();
1288 :
1289 0 : ScaDate aSettle( nNullDate, nSettle, nBase );
1290 0 : ScaDate aDate;
1291 0 : lcl_GetCouppcd( aDate, aSettle, ScaDate( nNullDate, nMat, nBase ), nFreq );
1292 0 : return ScaDate::getDiff( aDate, aSettle );
1293 : }
1294 :
1295 :
1296 : //-------
1297 : // COUPDAYSNC: get day count: settlement <-> coupon date after settlement
1298 0 : double GetCoupdaysnc( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1299 : throw( uno::RuntimeException, lang::IllegalArgumentException )
1300 : {
1301 0 : if( nSettle >= nMat || CHK_Freq )
1302 0 : throw lang::IllegalArgumentException();
1303 :
1304 0 : if( (nBase != 0) && (nBase != 4) )
1305 : {
1306 0 : ScaDate aSettle( nNullDate, nSettle, nBase );
1307 0 : ScaDate aDate;
1308 0 : lcl_GetCoupncd( aDate, aSettle, ScaDate( nNullDate, nMat, nBase ), nFreq );
1309 0 : return ScaDate::getDiff( aSettle, aDate );
1310 : }
1311 0 : return GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase ) - GetCoupdaybs( nNullDate, nSettle, nMat, nFreq, nBase );
1312 : }
1313 :
1314 :
1315 : //-------
1316 : // COUPDAYS: get day count: coupon date before settlement <-> coupon date after settlement
1317 0 : double GetCoupdays( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1318 : throw( uno::RuntimeException, lang::IllegalArgumentException )
1319 : {
1320 0 : if( nSettle >= nMat || CHK_Freq )
1321 0 : throw lang::IllegalArgumentException();
1322 :
1323 0 : if( nBase == 1 )
1324 : {
1325 0 : ScaDate aDate;
1326 0 : lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
1327 0 : ScaDate aNextDate( aDate );
1328 0 : aNextDate.addMonths( 12 / nFreq );
1329 0 : return ScaDate::getDiff( aDate, aNextDate );
1330 : }
1331 0 : return static_cast< double >( GetDaysInYear( 0, 0, nBase ) ) / nFreq;
1332 : }
1333 :
1334 :
1335 : //-------
1336 : // COUPNUM: get count of coupon dates
1337 0 : double GetCoupnum( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
1338 : throw( uno::RuntimeException, lang::IllegalArgumentException )
1339 : {
1340 0 : if( nSettle >= nMat || CHK_Freq )
1341 0 : throw lang::IllegalArgumentException();
1342 :
1343 0 : ScaDate aMat( nNullDate, nMat, nBase );
1344 0 : ScaDate aDate;
1345 0 : lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), aMat, nFreq );
1346 0 : sal_uInt16 nMonths = (aMat.getYear() - aDate.getYear()) * 12 + aMat.getMonth() - aDate.getMonth();
1347 0 : return static_cast< double >( nMonths * nFreq / 12 );
1348 : }
1349 :
1350 :
1351 :
1352 :
1353 :
1354 :
1355 :
1356 : const sal_uInt32 MyList::nStartSize = 16;
1357 : const sal_uInt32 MyList::nIncrSize = 16;
1358 :
1359 :
1360 54 : void MyList::_Grow( void )
1361 : {
1362 54 : nSize += nIncrSize;
1363 :
1364 54 : void** pNewData = new void*[ nSize ];
1365 54 : memcpy( pNewData, pData, nNew * sizeof( void* ) );
1366 :
1367 54 : delete[] pData;
1368 54 : pData = pNewData;
1369 54 : }
1370 :
1371 :
1372 918 : MyList::MyList( void )
1373 : {
1374 918 : nSize = nStartSize;
1375 918 : pData = new void*[ nSize ];
1376 918 : nNew = nAct = 0;
1377 918 : }
1378 :
1379 :
1380 408 : MyList::~MyList()
1381 : {
1382 408 : delete[] pData;
1383 408 : }
1384 :
1385 :
1386 0 : void MyList::Insert( void* p, sal_uInt32 n )
1387 : {
1388 0 : if( n >= nNew )
1389 0 : Append( p );
1390 : else
1391 : {
1392 0 : Grow();
1393 :
1394 0 : void** pIns = pData + n;
1395 0 : memmove( pIns + 1, pIns, ( nNew - n ) * sizeof( void* ) );
1396 :
1397 0 : *pIns = p;
1398 :
1399 0 : nNew++;
1400 : }
1401 0 : }
1402 :
1403 :
1404 :
1405 :
1406 808 : StringList::~StringList()
1407 : {
1408 1212 : for( OUString* p = ( OUString* ) First() ; p ; p = ( OUString* ) Next() )
1409 808 : delete p;
1410 404 : }
1411 :
1412 :
1413 909 : class AnalysisRscStrArrLoader : public Resource
1414 : {
1415 : private:
1416 : ResStringArray aStrArray;
1417 : public:
1418 909 : AnalysisRscStrArrLoader( sal_uInt16 nRsc, sal_uInt16 nArrayId, ResMgr& rResMgr ) :
1419 : Resource( AnalysisResId( nRsc, rResMgr ) ),
1420 909 : aStrArray( AnalysisResId( nArrayId, rResMgr ) )
1421 : {
1422 909 : FreeResource();
1423 909 : }
1424 :
1425 909 : const ResStringArray& GetStringArray() const { return aStrArray; }
1426 : };
1427 :
1428 :
1429 :
1430 :
1431 909 : FuncData::FuncData( const FuncDataBase& r, ResMgr& rResMgr ) :
1432 : aIntName( OUString::createFromAscii( r.pIntName ) ),
1433 : nUINameID( r.nUINameID ),
1434 : nDescrID( r.nDescrID ),
1435 : bDouble( r.bDouble ),
1436 : bWithOpt( r.bWithOpt ),
1437 : nParam( r.nNumOfParams ),
1438 : nCompID( r.nCompListID ),
1439 909 : eCat( r.eCat )
1440 : {
1441 909 : AnalysisRscStrArrLoader aArrLoader( RID_ANALYSIS_DEFFUNCTION_NAMES, nCompID, rResMgr );
1442 909 : const ResStringArray& rArr = aArrLoader.GetStringArray();
1443 :
1444 909 : sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( rArr.Count() );
1445 : sal_uInt16 n;
1446 :
1447 2727 : for( n = 0 ; n < nCount ; n++ )
1448 2727 : aCompList.Append( rArr.GetString( n ) );
1449 909 : }
1450 :
1451 :
1452 808 : FuncData::~FuncData()
1453 : {
1454 808 : }
1455 :
1456 :
1457 5238 : sal_uInt16 FuncData::GetStrIndex( sal_uInt16 nParamNum ) const
1458 : {
1459 5238 : if( !bWithOpt )
1460 1530 : nParamNum++;
1461 :
1462 5238 : if( nParamNum > nParam )
1463 90 : return nParam * 2;
1464 : else
1465 5148 : return nParamNum * 2;
1466 : }
1467 :
1468 :
1469 :
1470 :
1471 9 : FuncDataList::FuncDataList( ResMgr& rResMgr )
1472 : {
1473 918 : for( sal_uInt16 n = 0 ; n < SAL_N_ELEMENTS(pFuncDatas) ; n++ )
1474 909 : Append( new FuncData( pFuncDatas[ n ], rResMgr ) );
1475 9 : }
1476 :
1477 :
1478 12 : FuncDataList::~FuncDataList()
1479 : {
1480 408 : for( FuncData* p = ( FuncData* ) First() ; p ; p = ( FuncData* ) Next() )
1481 404 : delete p;
1482 8 : }
1483 :
1484 :
1485 8369 : const FuncData* FuncDataList::Get( const OUString& aProgrammaticName ) const
1486 : {
1487 8369 : if( aLastName == aProgrammaticName )
1488 7056 : return Get( nLast );
1489 :
1490 1313 : ( ( FuncDataList* ) this )->aLastName = aProgrammaticName;
1491 :
1492 1313 : sal_uInt32 nE = Count();
1493 66963 : for( sal_uInt32 n = 0 ; n < nE ; n++ )
1494 : {
1495 66963 : const FuncData* p = Get( n );
1496 66963 : if( p->Is( aProgrammaticName ) )
1497 : {
1498 1313 : ( ( FuncDataList* ) this )->nLast = n;
1499 1313 : return p;
1500 : }
1501 : }
1502 :
1503 0 : ( ( FuncDataList* ) this )->nLast = 0xFFFFFFFF;
1504 0 : return NULL;
1505 : }
1506 :
1507 :
1508 22077 : AnalysisResId::AnalysisResId( sal_uInt16 nId, ResMgr& rResMgr ) : ResId( nId, rResMgr )
1509 : {
1510 22077 : }
1511 :
1512 :
1513 :
1514 :
1515 0 : SortedIndividualInt32List::SortedIndividualInt32List()
1516 : {
1517 0 : }
1518 :
1519 :
1520 0 : SortedIndividualInt32List::~SortedIndividualInt32List()
1521 : {
1522 0 : }
1523 :
1524 :
1525 0 : void SortedIndividualInt32List::Insert( sal_Int32 nDay )
1526 : {
1527 0 : sal_uInt32 nIndex = Count();
1528 0 : while( nIndex )
1529 : {
1530 0 : nIndex--;
1531 0 : sal_Int32 nRef = Get( nIndex );
1532 0 : if( nDay == nRef )
1533 0 : return;
1534 0 : else if( nDay > nRef )
1535 : {
1536 0 : MyList::Insert( (void*)(sal_IntPtr)nDay, nIndex + 1 );
1537 0 : return;
1538 : }
1539 : }
1540 0 : MyList::Insert( (void*)(sal_IntPtr)nDay, 0UL );
1541 : }
1542 :
1543 :
1544 0 : void SortedIndividualInt32List::Insert( sal_Int32 nDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend )
1545 : {
1546 0 : if( !nDay )
1547 0 : return;
1548 :
1549 0 : nDay += nNullDate;
1550 0 : if( bInsertOnWeekend || (GetDayOfWeek( nDay ) < 5) )
1551 0 : Insert( nDay );
1552 : }
1553 :
1554 :
1555 0 : void SortedIndividualInt32List::Insert(
1556 : double fDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1557 : {
1558 0 : if( (fDay < -2147483648.0) || (fDay > 2147483649.0) )
1559 0 : throw lang::IllegalArgumentException();
1560 0 : Insert( static_cast< sal_Int32 >( fDay ), nNullDate, bInsertOnWeekend );
1561 0 : }
1562 :
1563 :
1564 0 : sal_Bool SortedIndividualInt32List::Find( sal_Int32 nVal ) const
1565 : {
1566 0 : sal_uInt32 nE = Count();
1567 :
1568 0 : if( !nE || nVal < Get( 0 ) || nVal > Get( nE - 1 ) )
1569 0 : return sal_False;
1570 :
1571 : // linear search
1572 :
1573 0 : for( sal_uInt32 n = 0 ; n < nE ; n++ )
1574 : {
1575 0 : sal_Int32 nRef = Get( n );
1576 :
1577 0 : if( nRef == nVal )
1578 0 : return sal_True;
1579 0 : else if( nRef > nVal )
1580 0 : return sal_False;
1581 : }
1582 0 : return sal_False;
1583 : }
1584 :
1585 :
1586 0 : void SortedIndividualInt32List::InsertHolidayList(
1587 : const ScaAnyConverter& rAnyConv,
1588 : const uno::Any& rHolAny,
1589 : sal_Int32 nNullDate,
1590 : sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1591 : {
1592 : double fDay;
1593 0 : if( rAnyConv.getDouble( fDay, rHolAny ) )
1594 0 : Insert( fDay, nNullDate, bInsertOnWeekend );
1595 0 : }
1596 :
1597 :
1598 0 : void SortedIndividualInt32List::InsertHolidayList(
1599 : ScaAnyConverter& rAnyConv,
1600 : const uno::Reference< beans::XPropertySet >& xOptions,
1601 : const uno::Any& rHolAny,
1602 : sal_Int32 nNullDate,
1603 : sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1604 : {
1605 0 : rAnyConv.init( xOptions );
1606 0 : if( rHolAny.getValueTypeClass() == uno::TypeClass_SEQUENCE )
1607 : {
1608 0 : uno::Sequence< uno::Sequence< uno::Any > > aAnySeq;
1609 0 : if( rHolAny >>= aAnySeq )
1610 : {
1611 0 : const uno::Sequence< uno::Any >* pSeqArray = aAnySeq.getConstArray();
1612 0 : for( sal_Int32 nIndex1 = 0; nIndex1 < aAnySeq.getLength(); nIndex1++ )
1613 : {
1614 0 : const uno::Sequence< uno::Any >& rSubSeq = pSeqArray[ nIndex1 ];
1615 0 : const uno::Any* pAnyArray = rSubSeq.getConstArray();
1616 :
1617 0 : for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
1618 0 : InsertHolidayList( rAnyConv, pAnyArray[ nIndex2 ], nNullDate, bInsertOnWeekend );
1619 : }
1620 : }
1621 : else
1622 0 : throw lang::IllegalArgumentException();
1623 : }
1624 : else
1625 0 : InsertHolidayList( rAnyConv, rHolAny, nNullDate, bInsertOnWeekend );
1626 0 : }
1627 :
1628 :
1629 :
1630 : //-----------------------------------------------------------------------------
1631 :
1632 0 : ScaDoubleList::~ScaDoubleList()
1633 : {
1634 0 : for( double* pDbl = const_cast< double* >( First() ); pDbl; pDbl = const_cast< double* >( Next() ) )
1635 0 : delete pDbl;
1636 0 : }
1637 :
1638 :
1639 0 : void ScaDoubleList::Append(
1640 : const uno::Sequence< uno::Sequence< double > >& rValueSeq ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1641 : {
1642 0 : const uno::Sequence< double >* pSeqArray = rValueSeq.getConstArray();
1643 0 : for( sal_Int32 nIndex1 = 0; nIndex1 < rValueSeq.getLength(); nIndex1++ )
1644 : {
1645 0 : const uno::Sequence< double >& rSubSeq = pSeqArray[ nIndex1 ];
1646 0 : const double* pArray = rSubSeq.getConstArray();
1647 0 : for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
1648 0 : Append( pArray[ nIndex2 ] );
1649 : }
1650 0 : }
1651 :
1652 :
1653 0 : void ScaDoubleList::Append(
1654 : const uno::Sequence< uno::Sequence< sal_Int32 > >& rValueSeq ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1655 : {
1656 0 : const uno::Sequence< sal_Int32 >* pSeqArray = rValueSeq.getConstArray();
1657 0 : for( sal_Int32 nIndex1 = 0; nIndex1 < rValueSeq.getLength(); nIndex1++ )
1658 : {
1659 0 : const uno::Sequence< sal_Int32 >& rSubSeq = pSeqArray[ nIndex1 ];
1660 0 : const sal_Int32* pArray = rSubSeq.getConstArray();
1661 0 : for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
1662 0 : Append( pArray[ nIndex2 ] );
1663 : }
1664 0 : }
1665 :
1666 :
1667 :
1668 0 : void ScaDoubleList::Append(
1669 : const ScaAnyConverter& rAnyConv,
1670 : const uno::Any& rAny,
1671 : sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1672 : {
1673 0 : if( rAny.getValueTypeClass() == uno::TypeClass_SEQUENCE )
1674 0 : Append( rAnyConv, *static_cast< const uno::Sequence< uno::Sequence< uno::Any > >* >( rAny.getValue() ), bIgnoreEmpty );
1675 : else
1676 : {
1677 : double fValue;
1678 0 : if( rAnyConv.getDouble( fValue, rAny ) )
1679 0 : Append( fValue );
1680 0 : else if( !bIgnoreEmpty )
1681 0 : Append( 0.0 );
1682 : }
1683 0 : }
1684 :
1685 :
1686 0 : void ScaDoubleList::Append(
1687 : const ScaAnyConverter& rAnyConv,
1688 : const uno::Sequence< uno::Any >& rAnySeq,
1689 : sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1690 : {
1691 0 : const uno::Any* pArray = rAnySeq.getConstArray();
1692 0 : for( sal_Int32 nIndex = 0; nIndex < rAnySeq.getLength(); nIndex++ )
1693 0 : Append( rAnyConv, pArray[ nIndex ], bIgnoreEmpty );
1694 0 : }
1695 :
1696 :
1697 0 : void ScaDoubleList::Append(
1698 : const ScaAnyConverter& rAnyConv,
1699 : const uno::Sequence< uno::Sequence< uno::Any > >& rAnySeq,
1700 : sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1701 : {
1702 0 : const uno::Sequence< uno::Any >* pArray = rAnySeq.getConstArray();
1703 0 : for( sal_Int32 nIndex = 0; nIndex < rAnySeq.getLength(); nIndex++ )
1704 0 : Append( rAnyConv, pArray[ nIndex ], bIgnoreEmpty );
1705 0 : }
1706 :
1707 :
1708 :
1709 0 : void ScaDoubleList::Append(
1710 : ScaAnyConverter& rAnyConv,
1711 : const uno::Reference< beans::XPropertySet >& xOpt,
1712 : const uno::Sequence< uno::Any >& rAnySeq,
1713 : sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1714 : {
1715 0 : rAnyConv.init( xOpt );
1716 0 : Append( rAnyConv, rAnySeq, bIgnoreEmpty );
1717 0 : }
1718 :
1719 :
1720 0 : sal_Bool ScaDoubleList::CheckInsert( double ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
1721 : {
1722 0 : return sal_True;
1723 : }
1724 :
1725 :
1726 :
1727 : //-----------------------------------------------------------------------------
1728 :
1729 0 : sal_Bool ScaDoubleListGT0::CheckInsert( double fValue ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
1730 : {
1731 0 : if( fValue < 0.0 )
1732 0 : throw lang::IllegalArgumentException();
1733 0 : return fValue > 0.0;
1734 : }
1735 :
1736 :
1737 :
1738 : //-----------------------------------------------------------------------------
1739 :
1740 0 : sal_Bool ScaDoubleListGE0::CheckInsert( double fValue ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
1741 : {
1742 0 : if( fValue < 0.0 )
1743 0 : throw lang::IllegalArgumentException();
1744 0 : return sal_True;
1745 : }
1746 :
1747 :
1748 :
1749 : //-----------------------------------------------------------------------------
1750 :
1751 0 : Complex::Complex( const OUString& rStr ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1752 : {
1753 0 : if( !ParseString( rStr, *this ) )
1754 0 : throw lang::IllegalArgumentException();
1755 0 : }
1756 :
1757 :
1758 0 : inline sal_Bool Complex::IsImagUnit( sal_Unicode c )
1759 : {
1760 0 : return c == 'i' || c == 'j';
1761 : }
1762 :
1763 0 : sal_Bool Complex::ParseString( const OUString& rStr, Complex& rCompl )
1764 : {
1765 0 : rCompl.c = '\0'; // do not force a symbol, if only real part present
1766 :
1767 0 : const sal_Unicode* pStr = rStr.getStr();
1768 :
1769 0 : if( IsImagUnit( *pStr ) && rStr.getLength() == 1)
1770 : {
1771 0 : rCompl.r = 0.0;
1772 0 : rCompl.i = 1.0;
1773 0 : rCompl.c = *pStr;
1774 0 : return sal_True;
1775 : }
1776 :
1777 : double f;
1778 :
1779 0 : if( !ParseDouble( pStr, f ) )
1780 0 : return sal_False;
1781 :
1782 0 : switch( *pStr )
1783 : {
1784 : case '-': // imag part follows
1785 : case '+':
1786 : {
1787 0 : double r = f;
1788 0 : if( IsImagUnit( pStr[ 1 ] ) )
1789 : {
1790 0 : rCompl.c = pStr[ 1 ];
1791 0 : if( pStr[ 2 ] == 0 )
1792 : {
1793 0 : rCompl.r = f;
1794 0 : rCompl.i = ( *pStr == '+' )? 1.0 : -1.0;
1795 0 : return sal_True;
1796 : }
1797 : }
1798 0 : else if( ParseDouble( pStr, f ) && IsImagUnit( *pStr ) )
1799 : {
1800 0 : rCompl.c = *pStr;
1801 0 : pStr++;
1802 0 : if( *pStr == 0 )
1803 : {
1804 0 : rCompl.r = r;
1805 0 : rCompl.i = f;
1806 0 : return sal_True;
1807 : }
1808 : }
1809 : }
1810 0 : break;
1811 : case 'j':
1812 : case 'i':
1813 0 : rCompl.c = *pStr;
1814 0 : pStr++;
1815 0 : if( *pStr == 0 )
1816 : {
1817 0 : rCompl.i = f;
1818 0 : rCompl.r = 0.0;
1819 0 : return sal_True;
1820 : }
1821 0 : break;
1822 : case 0: // only real-part
1823 0 : rCompl.r = f;
1824 0 : rCompl.i = 0.0;
1825 0 : return sal_True;
1826 : }
1827 :
1828 0 : return sal_False;
1829 : }
1830 :
1831 :
1832 0 : OUString Complex::GetString() const throw( uno::RuntimeException, lang::IllegalArgumentException )
1833 : {
1834 0 : CHK_FINITE(r);
1835 0 : CHK_FINITE(i);
1836 0 : OUStringBuffer aRet;
1837 :
1838 0 : bool bHasImag = i != 0.0;
1839 0 : bool bHasReal = !bHasImag || (r != 0.0);
1840 :
1841 0 : if( bHasReal )
1842 0 : aRet.append(::GetString( r ));
1843 0 : if( bHasImag )
1844 : {
1845 0 : if( i == 1.0 )
1846 : {
1847 0 : if( bHasReal )
1848 0 : aRet.append('+');
1849 : }
1850 0 : else if( i == -1.0 )
1851 0 : aRet.append('-');
1852 : else
1853 0 : aRet.append(::GetString( i, bHasReal ));
1854 0 : aRet.append((c != 'j') ? 'i' : 'j');
1855 : }
1856 :
1857 0 : return aRet.makeStringAndClear();
1858 : }
1859 :
1860 :
1861 0 : double Complex::Arg( void ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
1862 : {
1863 0 : if( r == 0.0 && i == 0.0 )
1864 0 : throw lang::IllegalArgumentException();
1865 :
1866 0 : double phi = acos( r / Abs() );
1867 :
1868 0 : if( i < 0.0 )
1869 0 : phi = -phi;
1870 :
1871 0 : return phi;
1872 : }
1873 :
1874 :
1875 0 : void Complex::Power( double fPower ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1876 : {
1877 0 : if( r == 0.0 && i == 0.0 )
1878 : {
1879 0 : if( fPower > 0 )
1880 : {
1881 0 : r = i = 0.0;
1882 0 : return;
1883 : }
1884 : else
1885 0 : throw lang::IllegalArgumentException();
1886 : }
1887 :
1888 : double p, phi;
1889 :
1890 0 : p = Abs();
1891 :
1892 0 : phi = acos( r / p );
1893 0 : if( i < 0.0 )
1894 0 : phi = -phi;
1895 :
1896 0 : p = pow( p, fPower );
1897 0 : phi *= fPower;
1898 :
1899 0 : r = cos( phi ) * p;
1900 0 : i = sin( phi ) * p;
1901 : }
1902 :
1903 :
1904 0 : void Complex::Sqrt( void )
1905 : {
1906 : static const double fMultConst = 0.7071067811865475; // ...2440084436210485 = 1/sqrt(2)
1907 0 : double p = Abs();
1908 0 : double i_ = sqrt( p - r ) * fMultConst;
1909 :
1910 0 : r = sqrt( p + r ) * fMultConst;
1911 0 : i = ( i < 0.0 )? -i_ : i_;
1912 0 : }
1913 :
1914 :
1915 0 : void Complex::Sin( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1916 : {
1917 0 : if( !::rtl::math::isValidArcArg( r ) )
1918 0 : throw lang::IllegalArgumentException();
1919 :
1920 0 : if( i )
1921 : {
1922 : double r_;
1923 :
1924 0 : r_ = sin( r ) * cosh( i );
1925 0 : i = cos( r ) * sinh( i );
1926 0 : r = r_;
1927 : }
1928 : else
1929 0 : r = sin( r );
1930 0 : }
1931 :
1932 :
1933 0 : void Complex::Cos( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1934 : {
1935 0 : if( !::rtl::math::isValidArcArg( r ) )
1936 0 : throw lang::IllegalArgumentException();
1937 :
1938 0 : if( i )
1939 : {
1940 : double r_;
1941 :
1942 0 : r_ = cos( r ) * cosh( i );
1943 0 : i = -( sin( r ) * sinh( i ) );
1944 0 : r = r_;
1945 : }
1946 : else
1947 0 : r = cos( r );
1948 0 : }
1949 :
1950 :
1951 0 : void Complex::Div( const Complex& z ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1952 : {
1953 0 : if( z.r == 0 && z.i == 0 )
1954 0 : throw lang::IllegalArgumentException();
1955 :
1956 0 : double a1 = r;
1957 0 : double a2 = z.r;
1958 0 : double b1 = i;
1959 0 : double b2 = z.i;
1960 :
1961 0 : double f = 1.0 / ( a2 * a2 + b2 * b2 );
1962 :
1963 0 : r = ( a1 * a2 + b1 * b2 ) * f;
1964 0 : i = ( a2 * b1 - a1 * b2 ) * f;
1965 :
1966 0 : if( !c ) c = z.c;
1967 0 : }
1968 :
1969 :
1970 0 : void Complex::Exp( void )
1971 : {
1972 0 : double fE = exp( r );
1973 0 : r = fE * cos( i );
1974 0 : i = fE * sin( i );
1975 0 : }
1976 :
1977 :
1978 0 : void Complex::Ln( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1979 : {
1980 0 : if( r == 0.0 && i == 0.0 )
1981 0 : throw lang::IllegalArgumentException();
1982 :
1983 0 : double fAbs = Abs();
1984 0 : sal_Bool bNegi = i < 0.0;
1985 :
1986 0 : i = acos( r / fAbs );
1987 :
1988 0 : if( bNegi )
1989 0 : i = -i;
1990 :
1991 0 : r = log( fAbs );
1992 0 : }
1993 :
1994 :
1995 0 : void Complex::Log10( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
1996 : {
1997 0 : Ln();
1998 0 : Mult( 0.434294481903251828 ); // * log10( e )
1999 0 : }
2000 :
2001 :
2002 0 : void Complex::Log2( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
2003 : {
2004 0 : Ln();
2005 0 : Mult( 1.442695040888963407 ); // * log2( e )
2006 0 : }
2007 :
2008 :
2009 0 : void Complex::Tan(void) throw( uno::RuntimeException, lang::IllegalArgumentException )
2010 : {
2011 0 : if ( i )
2012 : {
2013 0 : if( !::rtl::math::isValidArcArg( 2.0 * r ) )
2014 0 : throw lang::IllegalArgumentException();
2015 0 : double fScale =1.0 / ( cos( 2.0 * r ) + cosh( 2.0 * i ));
2016 0 : r = sin( 2.0 * r ) * fScale;
2017 0 : i = sinh( 2.0 * i ) * fScale;
2018 : }
2019 : else
2020 : {
2021 0 : if( !::rtl::math::isValidArcArg( r ) )
2022 0 : throw lang::IllegalArgumentException();
2023 0 : r = tan( r );
2024 : }
2025 0 : }
2026 :
2027 :
2028 0 : void Complex::Sec( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
2029 : {
2030 0 : if( i )
2031 : {
2032 0 : if( !::rtl::math::isValidArcArg( 2 * r ) )
2033 0 : throw lang::IllegalArgumentException();
2034 0 : double fScale = 1.0 / (cosh( 2.0 * i) + cos ( 2.0 * r));
2035 : double r_;
2036 0 : r_ = 2.0 * cos( r ) * cosh( i ) * fScale;
2037 0 : i = 2.0 * sin( r ) * sinh( i ) * fScale;
2038 0 : r = r_;
2039 : }
2040 : else
2041 : {
2042 0 : if( !::rtl::math::isValidArcArg( r ) )
2043 0 : throw lang::IllegalArgumentException();
2044 0 : r = 1.0 / cos( r );
2045 : }
2046 0 : }
2047 :
2048 :
2049 0 : void Complex::Csc( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
2050 : {
2051 0 : if( i )
2052 : {
2053 0 : if( !::rtl::math::isValidArcArg( 2 * r ) )
2054 0 : throw lang::IllegalArgumentException();
2055 0 : double fScale = 1.0 / (cosh( 2.0 * i) - cos ( 2.0 * r));
2056 : double r_;
2057 0 : r_ = 2.0 * sin( r ) * cosh( i ) * fScale;
2058 0 : i = -2.0 * cos( r ) * sinh( i ) * fScale;
2059 0 : r = r_;
2060 : }
2061 : else
2062 : {
2063 0 : if( !::rtl::math::isValidArcArg( r ) )
2064 0 : throw lang::IllegalArgumentException();
2065 0 : r = 1.0 / sin( r );
2066 : }
2067 0 : }
2068 :
2069 :
2070 0 : void Complex::Cot(void) throw( uno::RuntimeException, lang::IllegalArgumentException )
2071 : {
2072 0 : if ( i )
2073 : {
2074 0 : if( !::rtl::math::isValidArcArg( 2.0 * r ) )
2075 0 : throw lang::IllegalArgumentException();
2076 0 : double fScale =1.0 / ( cosh( 2.0 * i ) - cos( 2.0 * r ) );
2077 0 : r = sin( 2.0 * r ) * fScale;
2078 0 : i = - ( sinh( 2.0 * i ) * fScale );
2079 : }
2080 : else
2081 : {
2082 0 : if( !::rtl::math::isValidArcArg( r ) )
2083 0 : throw lang::IllegalArgumentException();
2084 0 : r = 1.0 / tan( r );
2085 : }
2086 0 : }
2087 :
2088 :
2089 0 : void Complex::Sinh( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
2090 : {
2091 0 : if( !::rtl::math::isValidArcArg( r ) )
2092 0 : throw lang::IllegalArgumentException();
2093 :
2094 0 : if( i )
2095 : {
2096 : double r_;
2097 0 : r_ = sinh( r ) * cos( i );
2098 0 : i = cosh( r ) * sin( i );
2099 0 : r = r_;
2100 : }
2101 : else
2102 0 : r = sinh( r );
2103 0 : }
2104 :
2105 :
2106 0 : void Complex::Cosh( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
2107 : {
2108 0 : if( !::rtl::math::isValidArcArg( r ) )
2109 0 : throw lang::IllegalArgumentException();
2110 :
2111 0 : if( i )
2112 : {
2113 : double r_;
2114 0 : r_ = cosh( r ) * cos( i );
2115 0 : i = sinh( r ) * sin( i );
2116 0 : r = r_;
2117 : }
2118 : else
2119 0 : r = cosh( r );
2120 0 : }
2121 :
2122 :
2123 0 : void Complex::Sech(void) throw( uno::RuntimeException, lang::IllegalArgumentException )
2124 : {
2125 0 : if ( i )
2126 : {
2127 0 : if( !::rtl::math::isValidArcArg( 2.0 * r ) )
2128 0 : throw lang::IllegalArgumentException();
2129 0 : double fScale =1.0 / ( cosh( 2.0 * r ) + cos( 2.0 * i ));
2130 : double r_;
2131 0 : r_ = 2.0 * cosh( r ) * cos( i ) * fScale;
2132 0 : i = - (2.0 * sinh( r ) * sin( i ) * fScale );
2133 0 : r = r_ ;
2134 : }
2135 : else
2136 : {
2137 0 : if( !::rtl::math::isValidArcArg( r ) )
2138 0 : throw lang::IllegalArgumentException();
2139 0 : r = 1.0 / cosh( r );
2140 : }
2141 0 : }
2142 :
2143 :
2144 0 : void Complex::Csch(void) throw( uno::RuntimeException, lang::IllegalArgumentException )
2145 : {
2146 0 : if ( i )
2147 : {
2148 0 : if( !::rtl::math::isValidArcArg( 2.0 * r ) )
2149 0 : throw lang::IllegalArgumentException();
2150 0 : double fScale =1.0 / ( cosh( 2.0 * r ) - cos( 2.0 * i ));
2151 : double r_;
2152 0 : r_ = 2.0 * sinh( r ) * cos( i ) * fScale;
2153 0 : i = - ( 2.0 * cosh( r ) * sin( i ) * fScale );
2154 0 : r = r_ ;
2155 : }
2156 : else
2157 : {
2158 0 : if( !::rtl::math::isValidArcArg( r ) )
2159 0 : throw lang::IllegalArgumentException();
2160 0 : r = 1.0 / sinh( r );
2161 : }
2162 0 : }
2163 :
2164 :
2165 0 : ComplexList::~ComplexList()
2166 : {
2167 0 : for( Complex* p = ( Complex* ) First() ; p ; p = ( Complex* ) Next() )
2168 0 : delete p;
2169 0 : }
2170 :
2171 :
2172 0 : void ComplexList::Append( const uno::Sequence< uno::Sequence< OUString > >& r, ComplListAppendHandl eAH ) throw( uno::RuntimeException, lang::IllegalArgumentException )
2173 : {
2174 : sal_Int32 n1, n2;
2175 0 : sal_Int32 nE1 = r.getLength();
2176 : sal_Int32 nE2;
2177 0 : sal_Bool bEmpty0 = eAH == AH_EmpyAs0;
2178 0 : sal_Bool bErrOnEmpty = eAH == AH_EmptyAsErr;
2179 :
2180 0 : for( n1 = 0 ; n1 < nE1 ; n1++ )
2181 : {
2182 0 : const uno::Sequence< OUString >& rList = r[ n1 ];
2183 0 : nE2 = rList.getLength();
2184 :
2185 0 : for( n2 = 0 ; n2 < nE2 ; n2++ )
2186 : {
2187 0 : const OUString& rStr = rList[ n2 ];
2188 :
2189 0 : if( !rStr.isEmpty() )
2190 0 : Append( new Complex( rStr ) );
2191 0 : else if( bEmpty0 )
2192 0 : Append( new Complex( 0.0 ) );
2193 0 : else if( bErrOnEmpty )
2194 0 : throw lang::IllegalArgumentException();
2195 : }
2196 : }
2197 0 : }
2198 :
2199 :
2200 0 : void ComplexList::Append( const uno::Sequence< uno::Any >& aMultPars, ComplListAppendHandl eAH ) throw( uno::RuntimeException, lang::IllegalArgumentException )
2201 : {
2202 0 : sal_Int32 nEle = aMultPars.getLength();
2203 0 : sal_Bool bEmpty0 = eAH == AH_EmpyAs0;
2204 0 : sal_Bool bErrOnEmpty = eAH == AH_EmptyAsErr;
2205 :
2206 0 : for( sal_Int32 i = 0 ; i < nEle ; i++ )
2207 : {
2208 0 : const uno::Any& r = aMultPars[ i ];
2209 0 : switch( r.getValueTypeClass() )
2210 : {
2211 0 : case uno::TypeClass_VOID: break;
2212 : case uno::TypeClass_STRING:
2213 : {
2214 0 : const OUString* pStr = ( const OUString* ) r.getValue();
2215 :
2216 0 : if( !pStr->isEmpty() )
2217 0 : Append( new Complex( *( OUString* ) r.getValue() ) );
2218 0 : else if( bEmpty0 )
2219 0 : Append( new Complex( 0.0 ) );
2220 0 : else if( bErrOnEmpty )
2221 0 : throw lang::IllegalArgumentException();
2222 : }
2223 0 : break;
2224 : case uno::TypeClass_DOUBLE:
2225 0 : Append( new Complex( *( double* ) r.getValue(), 0.0 ) );
2226 0 : break;
2227 : case uno::TypeClass_SEQUENCE:
2228 : {
2229 0 : uno::Sequence< uno::Sequence< uno::Any > > aValArr;
2230 0 : if( r >>= aValArr )
2231 : {
2232 0 : sal_Int32 nE = aValArr.getLength();
2233 0 : const uno::Sequence< uno::Any >* pArr = aValArr.getConstArray();
2234 0 : for( sal_Int32 n = 0 ; n < nE ; n++ )
2235 0 : Append( pArr[ n ], eAH );
2236 : }
2237 : else
2238 0 : throw lang::IllegalArgumentException();
2239 : }
2240 0 : break;
2241 : default:
2242 0 : throw lang::IllegalArgumentException();
2243 : }
2244 : }
2245 0 : }
2246 :
2247 :
2248 :
2249 :
2250 0 : ConvertData::ConvertData( const sal_Char p[], double fC, ConvertDataClass e, sal_Bool bPrefSupport ) : aName( p, strlen( p ), RTL_TEXTENCODING_MS_1252 )
2251 : {
2252 0 : fConst = fC;
2253 0 : eClass = e;
2254 0 : bPrefixSupport = bPrefSupport;
2255 0 : }
2256 :
2257 0 : ConvertData::~ConvertData()
2258 : {
2259 0 : }
2260 :
2261 :
2262 0 : sal_Int16 ConvertData::GetMatchingLevel( const OUString& rRef ) const
2263 : {
2264 0 : OUString aStr = rRef;
2265 0 : sal_Int32 nLen = rRef.getLength();
2266 0 : sal_Int32 nIndex = rRef.lastIndexOf( '^' );
2267 0 : if( nIndex > 0 && nIndex == ( nLen - 2 ) )
2268 : {
2269 0 : const sal_Unicode* p = aStr.getStr();
2270 0 : aStr = OUString( p, nLen - 2 );
2271 0 : aStr += OUString( p[ nLen - 1 ] );
2272 : }
2273 0 : if( aName.equals( aStr ) )
2274 0 : return 0;
2275 : else
2276 : {
2277 0 : const sal_Unicode* p = aStr.getStr();
2278 :
2279 0 : nLen = aStr.getLength();
2280 0 : bool bPref = IsPrefixSupport();
2281 0 : bool bOneChar = (bPref && nLen > 1 && (aName == p + 1));
2282 0 : if (bOneChar || (bPref && nLen > 2 && (aName == p + 2) &&
2283 0 : *p == 'd' && *(p+1) == 'a'))
2284 : {
2285 : sal_Int16 n;
2286 0 : switch( *p )
2287 : {
2288 0 : case 'y': n = -24; break; // yocto
2289 0 : case 'z': n = -21; break; // zepto
2290 0 : case 'a': n = -18; break;
2291 0 : case 'f': n = -15; break;
2292 0 : case 'p': n = -12; break;
2293 0 : case 'n': n = -9; break;
2294 0 : case 'u': n = -6; break;
2295 0 : case 'm': n = -3; break;
2296 0 : case 'c': n = -2; break;
2297 : case 'd':
2298 : {
2299 0 : if ( bOneChar )
2300 0 : n = -1; // deci
2301 : else
2302 0 : n = 1; // deca
2303 : }
2304 0 : break;
2305 0 : case 'e': n = 1; break;
2306 0 : case 'h': n = 2; break;
2307 0 : case 'k': n = 3; break;
2308 0 : case 'M': n = 6; break;
2309 0 : case 'G': n = 9; break;
2310 0 : case 'T': n = 12; break;
2311 0 : case 'P': n = 15; break;
2312 0 : case 'E': n = 18; break;
2313 0 : case 'Z': n = 21; break; // zetta
2314 0 : case 'Y': n = 24; break; // yotta
2315 : default:
2316 0 : n = INV_MATCHLEV;
2317 : }
2318 :
2319 : // We could weed some nonsense out, ODFF doesn't say so though.
2320 : #if 0
2321 : if (n < 0 && Class() == CDC_Information)
2322 : n = INV_MATCHLEV; // milli-bits doesn't make sense
2323 : #endif
2324 :
2325 : //! <HACK> "cm3" is not 10^-2 m^3 but 10^-6 m^3 !!! ------------------
2326 0 : if( n != INV_MATCHLEV )
2327 : {
2328 0 : sal_Unicode cLast = p[ aStr.getLength() - 1 ];
2329 0 : if( cLast == '2' )
2330 0 : n *= 2;
2331 0 : else if( cLast == '3' )
2332 0 : n *= 3;
2333 : }
2334 : //! </HACK> -------------------------------------------------------------------
2335 :
2336 0 : return n;
2337 : }
2338 0 : else if ( nLen > 2 && ( aName == p + 2 ) && ( Class() == CDC_Information ) )
2339 : {
2340 0 : const sal_Unicode* pStr = aStr.getStr();
2341 0 : if ( *(pStr + 1) != 'i')
2342 0 : return INV_MATCHLEV;
2343 : sal_Int16 n;
2344 0 : switch( *pStr )
2345 : {
2346 0 : case 'k': n = 10; break;
2347 0 : case 'M': n = 20; break;
2348 0 : case 'G': n = 30; break;
2349 0 : case 'T': n = 40; break;
2350 0 : case 'P': n = 50; break;
2351 0 : case 'E': n = 60; break;
2352 0 : case 'Z': n = 70; break;
2353 0 : case 'Y': n = 80; break;
2354 : default:
2355 0 : n = INV_MATCHLEV;
2356 : }
2357 0 : return n;
2358 : }
2359 : else
2360 0 : return INV_MATCHLEV;
2361 0 : }
2362 : }
2363 :
2364 :
2365 0 : double ConvertData::Convert(
2366 : double f, const ConvertData& r, sal_Int16 nLevFrom, sal_Int16 nLevTo ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
2367 : {
2368 0 : if( Class() != r.Class() )
2369 0 : throw lang::IllegalArgumentException();
2370 :
2371 0 : sal_Bool bBinFromLev = ( nLevFrom > 0 && ( nLevFrom % 10 ) == 0 );
2372 0 : sal_Bool bBinToLev = ( nLevTo > 0 && ( nLevTo % 10 ) == 0 );
2373 :
2374 0 : if ( Class() == CDC_Information && ( bBinFromLev || bBinToLev ) )
2375 : {
2376 0 : if ( bBinFromLev && bBinToLev )
2377 : {
2378 0 : nLevFrom = sal::static_int_cast<sal_Int16>( nLevFrom - nLevTo );
2379 0 : f *= r.fConst / fConst;
2380 0 : if( nLevFrom )
2381 0 : f *= pow( 2.0, nLevFrom );
2382 : }
2383 0 : else if ( bBinFromLev )
2384 0 : f *= ( r.fConst / fConst ) * ( pow( 2.0, nLevFrom ) / pow( 10.0, nLevTo ) );
2385 : else
2386 0 : f *= ( r.fConst / fConst ) * ( pow( 10.0, nLevFrom ) / pow( 2.0, nLevTo ) );
2387 0 : return f;
2388 : }
2389 :
2390 0 : nLevFrom = sal::static_int_cast<sal_Int16>( nLevFrom - nLevTo ); // effective level
2391 :
2392 0 : f *= r.fConst / fConst;
2393 :
2394 0 : if( nLevFrom )
2395 0 : f = ::rtl::math::pow10Exp( f, nLevFrom );
2396 :
2397 0 : return f;
2398 : }
2399 :
2400 :
2401 0 : double ConvertData::ConvertToBase( double f, sal_Int16 n ) const
2402 : {
2403 0 : return ::rtl::math::pow10Exp( f / fConst, n );
2404 : }
2405 :
2406 :
2407 0 : double ConvertData::ConvertFromBase( double f, sal_Int16 n ) const
2408 : {
2409 0 : return ::rtl::math::pow10Exp( f * fConst, -n );
2410 : }
2411 :
2412 :
2413 :
2414 0 : ConvertDataLinear::~ConvertDataLinear()
2415 : {
2416 0 : }
2417 :
2418 0 : double ConvertDataLinear::Convert(
2419 : double f, const ConvertData& r, sal_Int16 nLevFrom, sal_Int16 nLevTo ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
2420 : {
2421 0 : if( Class() != r.Class() )
2422 0 : throw lang::IllegalArgumentException();
2423 0 : return r.ConvertFromBase( ConvertToBase( f, nLevFrom ), nLevTo );
2424 : }
2425 :
2426 :
2427 0 : double ConvertDataLinear::ConvertToBase( double f, sal_Int16 n ) const
2428 : {
2429 0 : if( n )
2430 0 : f = ::rtl::math::pow10Exp( f, n );
2431 :
2432 0 : f /= fConst;
2433 0 : f -= fOffs;
2434 :
2435 0 : return f;
2436 : }
2437 :
2438 :
2439 0 : double ConvertDataLinear::ConvertFromBase( double f, sal_Int16 n ) const
2440 : {
2441 0 : f += fOffs;
2442 0 : f *= fConst;
2443 :
2444 0 : if( n )
2445 0 : f = ::rtl::math::pow10Exp( f, -n );
2446 :
2447 0 : return f;
2448 : }
2449 :
2450 :
2451 :
2452 :
2453 0 : ConvertDataList::ConvertDataList( void )
2454 : {
2455 : #define NEWD(str,unit,cl) Append(new ConvertData(str,unit,cl))
2456 : #define NEWDP(str,unit,cl) Append(new ConvertData(str,unit,cl,sal_True))
2457 : #define NEWL(str,unit,offs,cl) Append(new ConvertDataLinear(str,unit,offs,cl))
2458 : #define NEWLP(str,unit,offs,cl) Append(new ConvertDataLinear(str,unit,offs,cl,sal_True))
2459 :
2460 : // *** are extra and not standard Excel Analysis Addin!
2461 :
2462 : // MASS: 1 Gram is...
2463 0 : NEWDP( "g", 1.0000000000000000E00, CDC_Mass ); // Gram
2464 0 : NEWD( "sg", 6.8522050005347800E-05, CDC_Mass ); // Pieces
2465 0 : NEWD( "lbm", 2.2046229146913400E-03, CDC_Mass ); // Pound (commercial weight)
2466 0 : NEWDP( "u", 6.0221370000000000E23, CDC_Mass ); // U (atomic mass)
2467 0 : NEWD( "ozm", 3.5273971800362700E-02, CDC_Mass ); // Ounce (commercial weight)
2468 0 : NEWD( "stone", 1.574730e-04, CDC_Mass ); // *** Stone
2469 0 : NEWD( "ton", 1.102311e-06, CDC_Mass ); // *** Ton
2470 0 : NEWD( "grain", 1.543236E01, CDC_Mass ); // *** Grain
2471 0 : NEWD( "pweight", 7.054792E-01, CDC_Mass ); // *** Pennyweight
2472 0 : NEWD( "hweight", 1.968413E-05, CDC_Mass ); // *** Hundredweight
2473 0 : NEWD( "shweight", 2.204623E-05, CDC_Mass ); // *** Shorthundredweight
2474 0 : NEWD( "brton", 9.842065E-07, CDC_Mass ); // *** Gross Registered Ton
2475 0 : NEWD( "cwt", 2.2046226218487758E-05, CDC_Mass ); // U.S. (short) hundredweight
2476 0 : NEWD( "shweight", 2.2046226218487758E-05, CDC_Mass ); // U.S. (short) hundredweight also
2477 0 : NEWD( "uk_cwt", 1.9684130552221213E-05, CDC_Mass ); // Imperial hundredweight
2478 0 : NEWD( "lcwt", 1.9684130552221213E-05, CDC_Mass ); // Imperial hundredweight also
2479 0 : NEWD( "hweight", 1.9684130552221213E-05, CDC_Mass ); // Imperial hundredweight also
2480 0 : NEWD( "uk_ton", 9.8420652761106063E-07, CDC_Mass ); // Imperial ton
2481 0 : NEWD( "LTON", 9.8420652761106063E-07, CDC_Mass ); // Imperial ton also
2482 :
2483 : // LENGTH: 1 Meter is...
2484 0 : NEWDP( "m", 1.0000000000000000E00, CDC_Length ); // Meter
2485 0 : NEWD( "mi", 6.2137119223733397E-04, CDC_Length ); // Britsh Mile 6,21371192237333969617434184363e-4
2486 0 : NEWD( "Nmi", 5.3995680345572354E-04, CDC_Length ); // Nautical Mile 5,39956803455723542116630669546e-4
2487 0 : NEWD( "in", 3.9370078740157480E01, CDC_Length ); // Inch 39,37007874015748031496062992126
2488 0 : NEWD( "ft", 3.2808398950131234E00, CDC_Length ); // Foot 3,2808398950131233595800524934383
2489 0 : NEWD( "yd", 1.0936132983377078E00, CDC_Length ); // Yard 1,0936132983377077865266841644794
2490 0 : NEWDP( "ang", 1.0000000000000000E10, CDC_Length ); // Angstroem
2491 0 : NEWD( "Pica", 2.8346456692913386E03, CDC_Length ); // Pica (1/72 Inch) 2834,6456692913385826771653543307
2492 0 : NEWD( "ell", 8.748906E-01, CDC_Length ); // *** Ell
2493 0 : NEWDP( "parsec", 3.240779E-17, CDC_Length ); // *** Parsec
2494 0 : NEWDP( "pc", 3.240779E-17, CDC_Length ); // *** Parsec also
2495 0 : NEWDP( "lightyear", 1.0570234557732930E-16, CDC_Length ); // *** Light Year
2496 0 : NEWDP( "ly", 1.0570234557732930E-16, CDC_Length ); // *** Light Year also
2497 0 : NEWD( "survey_mi", 6.2136994949494949E-04, CDC_Length ); // U.S. survey mile
2498 :
2499 : // TIME: 1 Second is...
2500 0 : NEWD( "yr", 3.1688087814028950E-08, CDC_Time ); // Year
2501 0 : NEWD( "day", 1.1574074074074074E-05, CDC_Time ); // Day
2502 0 : NEWD( "d", 1.1574074074074074E-05, CDC_Time ); // Day also
2503 0 : NEWD( "hr", 2.7777777777777778E-04, CDC_Time ); // Hour
2504 0 : NEWD( "mn", 1.6666666666666667E-02, CDC_Time ); // Minute
2505 0 : NEWD( "min", 1.6666666666666667E-02, CDC_Time ); // Minute also
2506 0 : NEWDP( "sec", 1.0000000000000000E00, CDC_Time ); // Second
2507 0 : NEWDP( "s", 1.0000000000000000E00, CDC_Time ); // Second also
2508 :
2509 : // PRESSURE: 1 Pascal is...
2510 0 : NEWDP( "Pa", 1.0000000000000000E00, CDC_Pressure ); // Pascal
2511 0 : NEWDP( "atm", 9.8692329999819300E-06, CDC_Pressure ); // Atmosphere
2512 0 : NEWDP( "at", 9.8692329999819300E-06, CDC_Pressure ); // Atmosphere also
2513 0 : NEWDP( "mmHg", 7.5006170799862700E-03, CDC_Pressure ); // mm Hg (Mercury)
2514 0 : NEWD( "Torr", 7.5006380000000000E-03, CDC_Pressure ); // *** Torr
2515 0 : NEWD( "psi", 1.4503770000000000E-04, CDC_Pressure ); // *** Psi
2516 :
2517 : // FORCE: 1 Newton is...
2518 0 : NEWDP( "N", 1.0000000000000000E00, CDC_Force ); // Newton
2519 0 : NEWDP( "dyn", 1.0000000000000000E05, CDC_Force ); // Dyn
2520 0 : NEWDP( "dy", 1.0000000000000000E05, CDC_Force ); // Dyn also
2521 0 : NEWD( "lbf", 2.24808923655339E-01, CDC_Force ); // Pound-Force
2522 0 : NEWDP( "pond", 1.019716E02, CDC_Force ); // *** Pond
2523 :
2524 : // ENERGY: 1 Joule is...
2525 0 : NEWDP( "J", 1.0000000000000000E00, CDC_Energy ); // Joule
2526 0 : NEWDP( "e", 1.0000000000000000E07, CDC_Energy ); // Erg -> http://www.chemie.fu-berlin.de/chemistry/general/si.html
2527 0 : NEWDP( "c", 2.3900624947346700E-01, CDC_Energy ); // Thermodynamical Calorie
2528 0 : NEWDP( "cal", 2.3884619064201700E-01, CDC_Energy ); // Calorie
2529 0 : NEWDP( "eV", 6.2414570000000000E18, CDC_Energy ); // Electronvolt
2530 0 : NEWDP( "ev", 6.2414570000000000E18, CDC_Energy ); // Electronvolt also
2531 0 : NEWD( "HPh", 3.7250611111111111E-07, CDC_Energy ); // Horsepower Hours
2532 0 : NEWD( "hh", 3.7250611111111111E-07, CDC_Energy ); // Horsepower Hours also
2533 0 : NEWDP( "Wh", 2.7777777777777778E-04, CDC_Energy ); // Watt Hours
2534 0 : NEWDP( "wh", 2.7777777777777778E-04, CDC_Energy ); // Watt Hours also
2535 0 : NEWD( "flb", 2.37304222192651E01, CDC_Energy ); // Foot Pound
2536 0 : NEWD( "BTU", 9.4781506734901500E-04, CDC_Energy ); // British Thermal Unit
2537 0 : NEWD( "btu", 9.4781506734901500E-04, CDC_Energy ); // British Thermal Unit also
2538 :
2539 : // POWER: 1 Watt is...
2540 0 : NEWDP( "W", 1.0000000000000000E00, CDC_Power ); // Watt
2541 0 : NEWDP( "w", 1.0000000000000000E00, CDC_Power ); // Watt also
2542 0 : NEWD( "HP", 1.341022E-03, CDC_Power ); // Horsepower
2543 0 : NEWD( "h", 1.341022E-03, CDC_Power ); // Horsepower also
2544 0 : NEWD( "PS", 1.359622E-03, CDC_Power ); // *** German Pferdestaerke
2545 :
2546 : // MAGNETISM: 1 Tesla is...
2547 0 : NEWDP( "T", 1.0000000000000000E00, CDC_Magnetism ); // Tesla
2548 0 : NEWDP( "ga", 1.0000000000000000E04, CDC_Magnetism ); // Gauss
2549 :
2550 : // TEMERATURE: 1 Kelvin is...
2551 0 : NEWL( "C", 1.0000000000000000E00, -2.7315000000000000E02, CDC_Temperature ); // Celsius
2552 0 : NEWL( "cel", 1.0000000000000000E00, -2.7315000000000000E02, CDC_Temperature ); // Celsius also
2553 0 : NEWL( "F", 1.8000000000000000E00, -2.5537222222222222E02, CDC_Temperature ); // Fahrenheit
2554 0 : NEWL( "fah", 1.8000000000000000E00, -2.5537222222222222E02, CDC_Temperature ); // Fahrenheit also
2555 0 : NEWLP( "K", 1.0000000000000000E00, +0.0000000000000000E00, CDC_Temperature ); // Kelvin
2556 0 : NEWLP( "kel", 1.0000000000000000E00, +0.0000000000000000E00, CDC_Temperature ); // Kelvin also
2557 0 : NEWL( "Reau", 8.0000000000000000E-01, -2.7315000000000000E02, CDC_Temperature ); // *** Reaumur
2558 0 : NEWL( "Rank", 1.8000000000000000E00, +0.0000000000000000E00, CDC_Temperature ); // *** Rankine
2559 :
2560 : // VOLUMNE: 1 Liter is...
2561 0 : NEWD( "tsp", 2.0288413621105798E02, CDC_Volume ); // US teaspoon 1/768 gallon
2562 0 : NEWD( "tbs", 6.7628045403685994E01, CDC_Volume ); // US tablespoon 1/256 gallon
2563 0 : NEWD( "oz", 3.3814022701842997E01, CDC_Volume ); // Ounce Liquid 1/128 gallon
2564 0 : NEWD( "cup", 4.2267528377303746E00, CDC_Volume ); // Cup 1/16 gallon
2565 0 : NEWD( "pt", 2.1133764188651873E00, CDC_Volume ); // US Pint 1/8 gallon
2566 0 : NEWD( "us_pt", 2.1133764188651873E00, CDC_Volume ); // US Pint also
2567 0 : NEWD( "uk_pt", 1.7597539863927023E00, CDC_Volume ); // UK Pint 1/8 imperial gallon
2568 0 : NEWD( "qt", 1.0566882094325937E00, CDC_Volume ); // Quart 1/4 gallon
2569 0 : NEWD( "gal", 2.6417205235814842E-01, CDC_Volume ); // Gallon 1/3.785411784
2570 0 : NEWDP( "l", 1.0000000000000000E00, CDC_Volume ); // Liter
2571 0 : NEWDP( "L", 1.0000000000000000E00, CDC_Volume ); // Liter also
2572 0 : NEWDP( "lt", 1.0000000000000000E00, CDC_Volume ); // Liter also
2573 0 : NEWDP( "m3", 1.0000000000000000E-03, CDC_Volume ); // *** Cubic Meter
2574 0 : NEWD( "mi3", 2.3991275857892772E-13, CDC_Volume ); // *** Cubic Britsh Mile
2575 0 : NEWD( "Nmi3", 1.5742621468581148E-13, CDC_Volume ); // *** Cubic Nautical Mile
2576 0 : NEWD( "in3", 6.1023744094732284E01, CDC_Volume ); // *** Cubic Inch
2577 0 : NEWD( "ft3", 3.5314666721488590E-02, CDC_Volume ); // *** Cubic Foot
2578 0 : NEWD( "yd3", 1.3079506193143922E-03, CDC_Volume ); // *** Cubic Yard
2579 0 : NEWDP( "ang3", 1.0000000000000000E27, CDC_Volume ); // *** Cubic Angstroem
2580 0 : NEWD( "Pica3", 2.2776990435870636E07, CDC_Volume ); // *** Cubic Pica
2581 0 : NEWD( "barrel", 6.2898107704321051E-03, CDC_Volume ); // *** Barrel (=42gal)
2582 0 : NEWD( "bushel", 2.837759E-02, CDC_Volume ); // *** Bushel
2583 0 : NEWD( "regton", 3.531467E-04, CDC_Volume ); // *** Register ton
2584 0 : NEWD( "GRT", 3.531467E-04, CDC_Volume ); // *** Register ton also
2585 0 : NEWD( "Schooner", 2.3529411764705882E00, CDC_Volume ); // *** austr. Schooner
2586 0 : NEWD( "Middy", 3.5087719298245614E00, CDC_Volume ); // *** austr. Middy
2587 0 : NEWD( "Glass", 5.0000000000000000E00, CDC_Volume ); // *** austr. Glass
2588 0 : NEWD( "Sixpack", 0.5, CDC_Volume ); // ***
2589 0 : NEWD( "Humpen", 2.0, CDC_Volume ); // ***
2590 0 : NEWD( "ly3", 1.1810108125623799E-51, CDC_Volume ); // *** Cubic light-year
2591 0 : NEWD( "MTON", 1.4125866688595436E00, CDC_Volume ); // *** Measurement ton
2592 0 : NEWD( "tspm", 2.0000000000000000E02, CDC_Volume ); // *** Modern teaspoon
2593 0 : NEWD( "uk_gal", 2.1996924829908779E-01, CDC_Volume ); // U.K. / Imperial gallon 1/4.54609
2594 0 : NEWD( "uk_qt", 8.7987699319635115E-01, CDC_Volume ); // U.K. / Imperial quart 1/4 imperial gallon
2595 :
2596 : // 1 Square Meter is...
2597 0 : NEWDP( "m2", 1.0000000000000000E00, CDC_Area ); // *** Square Meter
2598 0 : NEWD( "mi2", 3.8610215854244585E-07, CDC_Area ); // *** Square Britsh Mile
2599 0 : NEWD( "Nmi2", 2.9155334959812286E-07, CDC_Area ); // *** Square Nautical Mile
2600 0 : NEWD( "in2", 1.5500031000062000E03, CDC_Area ); // *** Square Inch
2601 0 : NEWD( "ft2", 1.0763910416709722E01, CDC_Area ); // *** Square Foot
2602 0 : NEWD( "yd2", 1.1959900463010803E00, CDC_Area ); // *** Square Yard
2603 0 : NEWDP( "ang2", 1.0000000000000000E20, CDC_Area ); // *** Square Angstroem
2604 0 : NEWD( "Pica2", 8.0352160704321409E06, CDC_Area ); // *** Square Pica
2605 0 : NEWD( "Morgen", 4.0000000000000000E-04, CDC_Area ); // *** Morgen
2606 0 : NEWDP( "ar", 1.000000E-02, CDC_Area ); // *** Ar
2607 0 : NEWD( "acre", 2.471053815E-04, CDC_Area ); // *** Acre
2608 0 : NEWD( "uk_acre", 2.4710538146716534E-04, CDC_Area ); // *** International acre
2609 0 : NEWD( "us_acre", 2.4710439304662790E-04, CDC_Area ); // *** U.S. survey/statute acre
2610 0 : NEWD( "ly2", 1.1172985860549147E-32, CDC_Area ); // *** Square Light-year
2611 0 : NEWD( "ha", 1.000000E-04, CDC_Area ); // *** Hectare
2612 0 : NEWD( "Quadratlatschen",5.6689342403628117914,CDC_Area ); // ***
2613 :
2614 : // SPEED: 1 Meter per Second is...
2615 0 : NEWDP( "m/s", 1.0000000000000000E00, CDC_Speed ); // *** Meters per Second
2616 0 : NEWDP( "m/sec", 1.0000000000000000E00, CDC_Speed ); // *** Meters per Second also
2617 0 : NEWDP( "m/h", 3.6000000000000000E03, CDC_Speed ); // *** Meters per Hour
2618 0 : NEWDP( "m/hr", 3.6000000000000000E03, CDC_Speed ); // *** Meters per Hour also
2619 0 : NEWD( "mph", 2.2369362920544023E00, CDC_Speed ); // *** Britsh Miles per Hour
2620 0 : NEWD( "kn", 1.9438444924406048E00, CDC_Speed ); // *** Knot = Nautical Miles per Hour
2621 0 : NEWD( "admkn", 1.9438446603753486E00, CDC_Speed ); // *** Admiralty Knot
2622 0 : NEWD( "wahnsinnige Geschwindigkeit", 2.0494886343432328E-14, CDC_Speed ); // ***
2623 0 : NEWD( "ludicrous speed", 2.0494886343432328E-14, CDC_Speed ); // ***
2624 0 : NEWD( "laecherliche Geschwindigkeit", 4.0156958471424288E-06, CDC_Speed); // ***
2625 0 : NEWD( "ridiculous speed", 4.0156958471424288E-06, CDC_Speed); // ***
2626 :
2627 : // INFORMATION: 1 Bit is...
2628 0 : NEWDP( "bit", 1.00E00, CDC_Information); // *** Bit
2629 0 : NEWDP( "byte", 1.25E-01, CDC_Information); // *** Byte
2630 0 : }
2631 :
2632 :
2633 0 : ConvertDataList::~ConvertDataList()
2634 : {
2635 0 : for( ConvertData* p = First() ; p ; p = Next() )
2636 0 : delete p;
2637 0 : }
2638 :
2639 :
2640 0 : double ConvertDataList::Convert( double fVal, const OUString& rFrom, const OUString& rTo ) throw( uno::RuntimeException, lang::IllegalArgumentException )
2641 : {
2642 0 : ConvertData* pFrom = NULL;
2643 0 : ConvertData* pTo = NULL;
2644 0 : sal_Bool bSearchFrom = sal_True;
2645 0 : sal_Bool bSearchTo = sal_True;
2646 0 : sal_Int16 nLevelFrom = 0;
2647 0 : sal_Int16 nLevelTo = 0;
2648 :
2649 0 : ConvertData* p = First();
2650 0 : while( p && ( bSearchFrom || bSearchTo ) )
2651 : {
2652 0 : if( bSearchFrom )
2653 : {
2654 0 : sal_Int16 n = p->GetMatchingLevel( rFrom );
2655 0 : if( n != INV_MATCHLEV )
2656 : {
2657 0 : if( n )
2658 : { // only first match for partial equality rulz a little bit more
2659 0 : pFrom = p;
2660 0 : nLevelFrom = n;
2661 : }
2662 : else
2663 : { // ... but exact match rulz most
2664 0 : pFrom = p;
2665 0 : bSearchFrom = sal_False;
2666 0 : nLevelFrom = n;
2667 : }
2668 : }
2669 : }
2670 :
2671 0 : if( bSearchTo )
2672 : {
2673 0 : sal_Int16 n = p->GetMatchingLevel( rTo );
2674 0 : if( n != INV_MATCHLEV )
2675 : {
2676 0 : if( n )
2677 : { // only first match for partial equality rulz a little bit more
2678 0 : pTo = p;
2679 0 : nLevelTo = n;
2680 : }
2681 : else
2682 : { // ... but exact match rulz most
2683 0 : pTo = p;
2684 0 : bSearchTo = sal_False;
2685 0 : nLevelTo = n;
2686 : }
2687 : }
2688 : }
2689 :
2690 0 : p = Next();
2691 : }
2692 :
2693 0 : if( pFrom && pTo )
2694 0 : return pFrom->Convert( fVal, *pTo, nLevelFrom, nLevelTo );
2695 : else
2696 0 : throw lang::IllegalArgumentException();
2697 : }
2698 :
2699 :
2700 :
2701 : //-----------------------------------------------------------------------------
2702 :
2703 0 : ScaDate::ScaDate() :
2704 : nOrigDay( 1 ),
2705 : nDay( 1 ),
2706 : nMonth( 1 ),
2707 : nYear( 1900 ),
2708 : bLastDayMode( sal_True ),
2709 : bLastDay( sal_False ),
2710 : b30Days( sal_False ),
2711 0 : bUSMode( sal_False )
2712 : {
2713 0 : }
2714 :
2715 0 : ScaDate::ScaDate( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nBase )
2716 : {
2717 0 : DaysToDate( nNullDate + nDate, nOrigDay, nMonth, nYear );
2718 0 : bLastDayMode = (nBase != 5);
2719 0 : bLastDay = (nOrigDay >= ::DaysInMonth( nMonth, nYear ));
2720 0 : b30Days = (nBase == 0) || (nBase == 4);
2721 0 : bUSMode = (nBase == 0);
2722 0 : setDay();
2723 0 : }
2724 :
2725 0 : ScaDate::ScaDate( const ScaDate& rCopy ) :
2726 : nOrigDay( rCopy.nOrigDay ),
2727 : nDay( rCopy.nDay ),
2728 : nMonth( rCopy.nMonth ),
2729 : nYear( rCopy.nYear ),
2730 : bLastDayMode( rCopy.bLastDayMode ),
2731 : bLastDay( rCopy.bLastDay ),
2732 : b30Days( rCopy.b30Days ),
2733 0 : bUSMode( rCopy.bUSMode )
2734 : {
2735 0 : }
2736 :
2737 0 : ScaDate& ScaDate::operator=( const ScaDate& rCopy )
2738 : {
2739 0 : if( this != &rCopy )
2740 : {
2741 0 : nOrigDay = rCopy.nOrigDay;
2742 0 : nDay = rCopy.nDay;
2743 0 : nMonth = rCopy.nMonth;
2744 0 : nYear = rCopy.nYear;
2745 0 : bLastDayMode = rCopy.bLastDayMode;
2746 0 : bLastDay = rCopy.bLastDay;
2747 0 : b30Days = rCopy.b30Days;
2748 0 : bUSMode = rCopy.bUSMode;
2749 : }
2750 0 : return *this;
2751 : }
2752 :
2753 0 : void ScaDate::setDay()
2754 : {
2755 0 : if( b30Days )
2756 : {
2757 : // 30-days-mode: set nDay to 30 if original was last day in month
2758 0 : nDay = std::min( nOrigDay, static_cast< sal_uInt16 >( 30 ) );
2759 0 : if( bLastDay || (nDay >= ::DaysInMonth( nMonth, nYear )) )
2760 0 : nDay = 30;
2761 : }
2762 : else
2763 : {
2764 : // set nDay to last day in this month if original was last day
2765 0 : sal_uInt16 nLastDay = ::DaysInMonth( nMonth, nYear );
2766 0 : nDay = bLastDay ? nLastDay : std::min( nOrigDay, nLastDay );
2767 : }
2768 0 : }
2769 :
2770 0 : sal_Int32 ScaDate::getDaysInMonthRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const
2771 : {
2772 0 : if( nFrom > nTo )
2773 0 : return 0;
2774 :
2775 0 : sal_Int32 nRet = 0;
2776 0 : if( b30Days )
2777 0 : nRet = (nTo - nFrom + 1) * 30;
2778 : else
2779 : {
2780 0 : for( sal_uInt16 nMonthIx = nFrom; nMonthIx <= nTo; ++nMonthIx )
2781 0 : nRet += getDaysInMonth( nMonthIx );
2782 : }
2783 0 : return nRet;
2784 : }
2785 :
2786 0 : sal_Int32 ScaDate::getDaysInYearRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const
2787 : {
2788 0 : if( nFrom > nTo )
2789 0 : return 0;
2790 :
2791 0 : return b30Days ? ((nTo - nFrom + 1) * 360) : ::GetDaysInYears( nFrom, nTo );
2792 : }
2793 :
2794 0 : void ScaDate::doAddYears( sal_Int32 nYearCount ) throw( lang::IllegalArgumentException )
2795 : {
2796 0 : sal_Int32 nNewYear = nYearCount + nYear;
2797 0 : if( (nNewYear < 0) || (nNewYear > 0x7FFF) )
2798 0 : throw lang::IllegalArgumentException();
2799 0 : nYear = static_cast< sal_uInt16 >( nNewYear );
2800 0 : }
2801 :
2802 0 : void ScaDate::addMonths( sal_Int32 nMonthCount ) throw( lang::IllegalArgumentException )
2803 : {
2804 0 : sal_Int32 nNewMonth = nMonthCount + nMonth;
2805 0 : if( nNewMonth > 12 )
2806 : {
2807 0 : --nNewMonth;
2808 0 : doAddYears( nNewMonth / 12 );
2809 0 : nMonth = static_cast< sal_uInt16 >( nNewMonth % 12 ) + 1;
2810 : }
2811 0 : else if( nNewMonth < 1 )
2812 : {
2813 0 : doAddYears( nNewMonth / 12 - 1 );
2814 0 : nMonth = static_cast< sal_uInt16 >( nNewMonth % 12 + 12 );
2815 : }
2816 : else
2817 0 : nMonth = static_cast< sal_uInt16 >( nNewMonth );
2818 0 : setDay();
2819 0 : }
2820 :
2821 0 : sal_Int32 ScaDate::getDate( sal_Int32 nNullDate ) const
2822 : {
2823 0 : sal_uInt16 nLastDay = ::DaysInMonth( nMonth, nYear );
2824 0 : sal_uInt16 nRealDay = (bLastDayMode && bLastDay) ? nLastDay : std::min( nLastDay, nOrigDay );
2825 0 : return ::DateToDays( nRealDay, nMonth, nYear ) - nNullDate;
2826 : }
2827 :
2828 0 : sal_Int32 ScaDate::getDiff( const ScaDate& rFrom, const ScaDate& rTo ) throw( lang::IllegalArgumentException )
2829 : {
2830 0 : if( rFrom > rTo )
2831 0 : return getDiff( rTo, rFrom );
2832 :
2833 0 : sal_Int32 nDiff = 0;
2834 0 : ScaDate aFrom( rFrom );
2835 0 : ScaDate aTo( rTo );
2836 :
2837 0 : if( rTo.b30Days )
2838 : {
2839 : // corrections for base 0 (US NASD)
2840 0 : if( rTo.bUSMode )
2841 : {
2842 0 : if( ((rFrom.nMonth == 2) || (rFrom.nDay < 30)) && (aTo.nOrigDay == 31) )
2843 0 : aTo.nDay = 31;
2844 0 : else if( (aTo.nMonth == 2) && aTo.bLastDay )
2845 0 : aTo.nDay = ::DaysInMonth( 2, aTo.nYear );
2846 : }
2847 : // corrections for base 4 (Europe)
2848 : else
2849 : {
2850 0 : if( (aFrom.nMonth == 2) && (aFrom.nDay == 30) )
2851 0 : aFrom.nDay = ::DaysInMonth( 2, aFrom.nYear );
2852 0 : if( (aTo.nMonth == 2) && (aTo.nDay == 30) )
2853 0 : aTo.nDay = ::DaysInMonth( 2, aTo.nYear );
2854 : }
2855 : }
2856 :
2857 0 : if( (aFrom.nYear < aTo.nYear) || ((aFrom.nYear == aTo.nYear) && (aFrom.nMonth < aTo.nMonth)) )
2858 : {
2859 : // move aFrom to 1st day of next month
2860 0 : nDiff = aFrom.getDaysInMonth() - aFrom.nDay + 1;
2861 0 : aFrom.nOrigDay = aFrom.nDay = 1;
2862 0 : aFrom.bLastDay = sal_False;
2863 0 : aFrom.addMonths( 1 );
2864 :
2865 0 : if( aFrom.nYear < aTo.nYear )
2866 : {
2867 : // move aFrom to 1st day of next year
2868 0 : nDiff += aFrom.getDaysInMonthRange( aFrom.nMonth, 12 );
2869 0 : aFrom.addMonths( 13 - aFrom.nMonth );
2870 :
2871 : // move aFrom to 1st day of this year
2872 0 : nDiff += aFrom.getDaysInYearRange( aFrom.nYear, aTo.nYear - 1 );
2873 0 : aFrom.addYears( aTo.nYear - aFrom.nYear );
2874 : }
2875 :
2876 : // move aFrom to 1st day of this month
2877 0 : nDiff += aFrom.getDaysInMonthRange( aFrom.nMonth, aTo.nMonth - 1 );
2878 0 : aFrom.addMonths( aTo.nMonth - aFrom.nMonth );
2879 : }
2880 : // finally add remaining days in this month
2881 0 : nDiff += aTo.nDay - aFrom.nDay;
2882 0 : return nDiff > 0 ? nDiff : 0;
2883 : }
2884 :
2885 0 : sal_Bool ScaDate::operator<( const ScaDate& rCmp ) const
2886 : {
2887 0 : if( nYear != rCmp.nYear )
2888 0 : return nYear < rCmp.nYear;
2889 0 : if( nMonth != rCmp.nMonth )
2890 0 : return nMonth < rCmp.nMonth;
2891 0 : if( nDay != rCmp.nDay )
2892 0 : return nDay < rCmp.nDay;
2893 0 : if( bLastDay || rCmp.bLastDay )
2894 0 : return !bLastDay && rCmp.bLastDay;
2895 0 : return nOrigDay < rCmp.nOrigDay;
2896 : }
2897 :
2898 :
2899 :
2900 : //-----------------------------------------------------------------------------
2901 :
2902 9 : ScaAnyConverter::ScaAnyConverter( const uno::Reference< uno::XComponentContext >& xContext ) :
2903 9 : bHasValidFormat( sal_False )
2904 : {
2905 9 : xFormatter = util::NumberFormatter::create(xContext);
2906 9 : }
2907 :
2908 4 : ScaAnyConverter::~ScaAnyConverter()
2909 : {
2910 4 : }
2911 :
2912 0 : void ScaAnyConverter::init( const uno::Reference< beans::XPropertySet >& xPropSet ) throw( uno::RuntimeException )
2913 : {
2914 : // try to get default number format
2915 0 : bHasValidFormat = sal_False;
2916 0 : if( xFormatter.is() )
2917 : {
2918 : // get XFormatsSupplier from outer XPropertySet
2919 0 : uno::Reference< util::XNumberFormatsSupplier > xFormatsSupp( xPropSet, uno::UNO_QUERY );
2920 0 : if( xFormatsSupp.is() )
2921 : {
2922 : // get XNumberFormatTypes from XNumberFormatsSupplier to get standard index
2923 0 : uno::Reference< util::XNumberFormats > xFormats( xFormatsSupp->getNumberFormats() );
2924 0 : uno::Reference< util::XNumberFormatTypes > xFormatTypes( xFormats, uno::UNO_QUERY );
2925 0 : if( xFormatTypes.is() )
2926 : {
2927 0 : lang::Locale eLocale;
2928 0 : nDefaultFormat = xFormatTypes->getStandardIndex( eLocale );
2929 0 : xFormatter->attachNumberFormatsSupplier( xFormatsSupp );
2930 0 : bHasValidFormat = sal_True;
2931 0 : }
2932 0 : }
2933 : }
2934 0 : }
2935 :
2936 0 : double ScaAnyConverter::convertToDouble( const OUString& rString ) const throw( lang::IllegalArgumentException )
2937 : {
2938 0 : double fValue = 0.0;
2939 0 : if( bHasValidFormat )
2940 : {
2941 : try
2942 : {
2943 0 : fValue = xFormatter->convertStringToNumber( nDefaultFormat, rString );
2944 : }
2945 0 : catch( uno::Exception& )
2946 : {
2947 0 : throw lang::IllegalArgumentException();
2948 : }
2949 : }
2950 : else
2951 : {
2952 : rtl_math_ConversionStatus eStatus;
2953 : sal_Int32 nEnd;
2954 0 : fValue = ::rtl::math::stringToDouble( rString, '.', ',', &eStatus, &nEnd );
2955 0 : if( (eStatus != rtl_math_ConversionStatus_Ok) || (nEnd < rString.getLength()) )
2956 0 : throw lang::IllegalArgumentException();
2957 : }
2958 0 : return fValue;
2959 : }
2960 :
2961 0 : sal_Bool ScaAnyConverter::getDouble(
2962 : double& rfResult,
2963 : const uno::Any& rAny ) const throw( lang::IllegalArgumentException )
2964 : {
2965 0 : rfResult = 0.0;
2966 0 : sal_Bool bContainsVal = sal_True;
2967 0 : switch( rAny.getValueTypeClass() )
2968 : {
2969 : case uno::TypeClass_VOID:
2970 0 : bContainsVal = sal_False;
2971 0 : break;
2972 : case uno::TypeClass_DOUBLE:
2973 0 : rAny >>= rfResult;
2974 0 : break;
2975 : case uno::TypeClass_STRING:
2976 : {
2977 0 : const OUString* pString = static_cast< const OUString* >( rAny.getValue() );
2978 0 : if( !pString->isEmpty() )
2979 0 : rfResult = convertToDouble( *pString );
2980 : else
2981 0 : bContainsVal = sal_False;
2982 : }
2983 0 : break;
2984 : default:
2985 0 : throw lang::IllegalArgumentException();
2986 : }
2987 0 : return bContainsVal;
2988 : }
2989 :
2990 0 : sal_Bool ScaAnyConverter::getDouble(
2991 : double& rfResult,
2992 : const uno::Reference< beans::XPropertySet >& xPropSet,
2993 : const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
2994 : {
2995 0 : init( xPropSet );
2996 0 : return getDouble( rfResult, rAny );
2997 : }
2998 :
2999 0 : double ScaAnyConverter::getDouble(
3000 : const uno::Reference< beans::XPropertySet >& xPropSet,
3001 : const uno::Any& rAny,
3002 : double fDefault ) throw( uno::RuntimeException, lang::IllegalArgumentException )
3003 : {
3004 : double fResult;
3005 0 : if( !getDouble( fResult, xPropSet, rAny ) )
3006 0 : fResult = fDefault;
3007 0 : return fResult;
3008 : }
3009 :
3010 0 : sal_Bool ScaAnyConverter::getInt32(
3011 : sal_Int32& rnResult,
3012 : const uno::Reference< beans::XPropertySet >& xPropSet,
3013 : const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
3014 : {
3015 : double fResult;
3016 0 : sal_Bool bContainsVal = getDouble( fResult, xPropSet, rAny );
3017 0 : if( (fResult <= -2147483649.0) || (fResult >= 2147483648.0) )
3018 0 : throw lang::IllegalArgumentException();
3019 :
3020 0 : rnResult = static_cast< sal_Int32 >( fResult );
3021 0 : return bContainsVal;
3022 : }
3023 :
3024 0 : sal_Int32 ScaAnyConverter::getInt32(
3025 : const uno::Reference< beans::XPropertySet >& xPropSet,
3026 : const uno::Any& rAny,
3027 : sal_Int32 nDefault ) throw( uno::RuntimeException, lang::IllegalArgumentException )
3028 : {
3029 : sal_Int32 nResult;
3030 0 : if( !getInt32( nResult, xPropSet, rAny ) )
3031 0 : nResult = nDefault;
3032 0 : return nResult;
3033 : }
3034 :
3035 :
3036 :
3037 : //-----------------------------------------------------------------------------
3038 :
3039 :
3040 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|