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