1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #ifndef ANALYSISHELPER_HXX
28 #define ANALYSISHELPER_HXX
29 
30 
31 #include <com/sun/star/lang/XServiceName.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/util/Date.hpp>
35 #include <com/sun/star/util/XNumberFormatter.hpp>
36 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
37 #include <com/sun/star/sheet/XAddIn.hpp>
38 #include <com/sun/star/sheet/addin/XAnalysis.hpp>
39 
40 #include <math.h>
41 
42 #include <tools/resid.hxx>
43 #include <tools/rc.hxx>
44 
45 #include "analysisdefs.hxx"
46 
47 
48 class ResMgr;
49 class SortedIndividualInt32List;
50 class ScaAnyConverter;
51 
52 
53 #define	PI			3.1415926535897932
54 #define PI_2		(PI/2.0)
55 //#define	EULER		2.7182818284590452
56 #define	EOL			( ( const sal_Char* ) 1 )
57 #define	EOE			( ( const sal_Char* ) 2 )
58 
59 
60 //double				_Test( sal_Int32 nMode, double f1, double f2, double f3 );
61 inline sal_Bool     IsLeapYear( sal_uInt16 nYear );
62 sal_uInt16			DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear );
63 sal_Int32			DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear );
64 void				DaysToDate( sal_Int32 nDays, sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear ) throw( ::com::sun::star::lang::IllegalArgumentException );
65 sal_Int32           GetNullDate( const REF( CSS::beans::XPropertySet )& xOptions ) THROWDEF_RTE;
66 sal_Int32			GetDiffDate360(
67 						sal_uInt16 nDay1, sal_uInt16 nMonth1, sal_uInt16 nYear1, sal_Bool bLeapYear1,
68 						sal_uInt16 nDay2, sal_uInt16 nMonth2, sal_uInt16 nYear2,
69 						sal_Bool bUSAMethod );
70 inline sal_Int32	GetDiffDate360( constREFXPS& xOpt, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod );
71 sal_Int32			GetDiffDate360( sal_Int32 nNullDate, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod );
72 
73 sal_Int32			GetDaysInYears( sal_uInt16 nYear1, sal_uInt16 nYear2 );
74 inline sal_Int16	GetDayOfWeek( sal_Int32 nDate );
75 void				GetDiffParam( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
76 						sal_uInt16& rYears, sal_Int32& rDayDiffPart, sal_Int32& rDaysInYear ) THROWDEF_RTE_IAE;
77 						// rYears = full num of years
78 						// rDayDiffPart = num of days for last year
79 						// rDaysInYear = num of days in first year
80 sal_Int32			GetDiffDate( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
81 								sal_Int32* pOptDaysIn1stYear = NULL ) THROWDEF_RTE_IAE;
82 double				GetYearDiff( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode )
83 								THROWDEF_RTE_IAE;
84 sal_Int32			GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode ) THROWDEF_RTE_IAE;
85 double				GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode )
86 						THROWDEF_RTE_IAE;
87 inline double		GetYearFrac( constREFXPS& xOpt, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode )
88 						THROWDEF_RTE_IAE;
89 inline void			AlignDate( sal_uInt16& rDay, sal_uInt16 nMonth, sal_uInt16 nYear );
90 
91 double				Fak( sal_Int32 n );
92 double				GetGcd( double f1, double f2 );
93 double				ConvertToDec( const STRING& rFromNum, sal_uInt16 nBaseFrom, sal_uInt16 nCharLim ) THROWDEF_RTE_IAE;
94 STRING				ConvertFromDec(
95                         double fNum, double fMin, double fMax, sal_uInt16 nBase,
96                         sal_Int32 nPlaces, sal_Int32 nMaxPlaces, sal_Bool bUsePlaces ) THROWDEF_RTE_IAE;
97 double				Erf( double fX );
98 double				Erfc( double fX );
99 sal_Bool			ParseDouble( const sal_Unicode*& rpDoubleAsString, double& rReturn );
100 STRING				GetString( double fNumber, sal_Bool bLeadingSign = sal_False, sal_uInt16 nMaxNumOfDigits = 15 );
101 inline double		Exp10( sal_Int16 nPower );		// 10 ^ nPower
102 
103 double				GetAmordegrc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
104 								double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE;
105 double				GetAmorlinc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
106 								double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE;
107 double				GetDuration( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup,
108 								double fYield, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
109 double				GetYieldmat( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
110 								double fRate, double fPrice, sal_Int32 nBase ) THROWDEF_RTE_IAE;
111 double				GetOddfprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
112 								sal_Int32 nFirstCoup, double fRate, double fYield, double fRedemp,
113 								sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
114 double				getYield_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice,
115 								double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
116 double				getPrice_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield,
117 								double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
118 double				GetOddfyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
119 								sal_Int32 nFirstCoup, double fRate, double fPrice, double fRedemp,
120 								sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
121 double				GetOddlprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest,
122 								double fRate, double fYield, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
123 double				GetOddlyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest,
124 								double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
125 double				GetRmz( double fZins, double fZzr, double fBw, double fZw, sal_Int32 nF );
126 double				GetZw( double fZins, double fZzr, double fRmz, double fBw, sal_Int32 nF );
127 //double				TBillYield( constREFXPS& xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice )THROWDEF_RTE_IAE;
128 
129 double				GetCouppcd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
130 								sal_Int32 nBase ) THROWDEF_RTE_IAE;
131 double              GetCoupncd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
132 								sal_Int32 nBase ) THROWDEF_RTE_IAE;
133 double              GetCoupdaybs( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
134 								sal_Int32 nBase ) THROWDEF_RTE_IAE;
135 double				GetCoupdaysnc( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
136 								sal_Int32 nBase ) THROWDEF_RTE_IAE;
137 
138 double              GetCoupnum( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat,
139 								sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
140 double				GetCoupdays( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
141 								sal_Int32 nBase ) THROWDEF_RTE_IAE;
142 
143 
144 
145 
146 //-----------------------------------------------------------------------------
147 
148 
149 
150 class MyList
151 {
152 private:
153 	static const sal_uInt32	nStartSize;
154 	static const sal_uInt32	nIncrSize;
155 
156 	void**					pData;			// pointer array
157 	sal_uInt32				nSize;			// array size
158 	sal_uInt32				nNew;			// next index to be inserted at
159 	sal_uInt32				nAct;			// actual for iterations
160 
161 	void					_Grow( void );
162 	inline void				Grow( void );
163 protected:
164 public:
165 							MyList( void );
166 	virtual					~MyList();
167 
168 	inline const void*		GetObject( sal_uInt32 nIndex ) const;
169 	inline const void*		First( void );
170 	inline const void*		Next( void );
171 
172 	inline void				Append( void* pNewElement );
173 	void					Insert( void* pNewLement, sal_uInt32 nPlace );
174 
175 	inline sal_uInt32		Count( void ) const;
176 };
177 
178 
179 
180 
181 class StringList : protected MyList
182 {
183 public:
184 	virtual					~StringList();
185 
186 	inline const STRING*	First( void );
187 	inline const STRING*	Next( void );
188 	inline const STRING*	Get( sal_uInt32 nIndex ) const;
189 
190     using MyList::Append;
191 	inline void				Append( STRING* pNew );
192 	inline void				Append( const STRING& rNew );
193 
194 	using MyList::Count;
195 };
196 
197 
198 
199 
200 enum FDCategory
201 {
202 	FDCat_AddIn,
203 	FDCat_DateTime,
204 	FDCat_Finance,
205 	FDCat_Inf,
206 	FDCat_Math,
207 	FDCat_Tech
208 };
209 
210 
211 struct FuncDataBase
212 {
213 	const sal_Char*			pIntName;
214 	sal_uInt16				nUINameID;			// resource ID to UI name
215 	sal_uInt16				nDescrID;			// resource ID to description, parameter names and ~ description
216 	sal_Bool				bDouble;			// name already exist in Calc
217 	sal_Bool				bWithOpt;			// first parameter is internal
218 	sal_uInt16				nCompListID;		// resource ID to list of valid names
219 	sal_uInt16				nNumOfParams;		// number of named / described parameters
220 	FDCategory				eCat;				// function category
221 };
222 
223 
224 
225 
226 class FuncData
227 {
228 private:
229     ::rtl::OUString         aIntName;
230 	sal_uInt16				nUINameID;
231 	sal_uInt16				nDescrID;			// leads also to parameter descriptions!
232 	sal_Bool				bDouble;			// flag for names, wich already exist in Calc
233 	sal_Bool				bWithOpt;			// has internal parameter on first position
234 
235 	sal_uInt16				nParam;				// num of parameters
236 	sal_uInt16				nCompID;
237 	StringList				aCompList;			// list of all valid names
238 	FDCategory				eCat;				// function category
239 public:
240 							FuncData( const FuncDataBase& rBaseData, ResMgr& );
241 	virtual					~FuncData();
242 
243 	inline sal_uInt16		GetUINameID( void ) const;
244 	inline sal_uInt16		GetDescrID( void ) const;
245 	inline sal_Bool			IsDouble( void ) const;
246 	inline sal_Bool			HasIntParam( void ) const;
247 
248 	sal_uInt16				GetStrIndex( sal_uInt16 nParamNum ) const;
249     inline sal_Bool         Is( const ::rtl::OUString& rCompareTo ) const;
250 
251 	inline const StringList&	GetCompNameList( void ) const;
252 
253 	inline FDCategory		GetCategory( void ) const;
254 };
255 
256 
257 
258 
259 class CStrList : private MyList
260 {
261 public:
262     using MyList::Append;
263 	inline void				Append( const sal_Char* pNew );
264 	inline const sal_Char*	Get( sal_uInt32 nIndex ) const;
265 	using MyList::Count;
266 };
267 
268 
269 
270 
271 class FuncDataList : private MyList
272 {
273     ::rtl::OUString         aLastName;
274 	sal_uInt32				nLast;
275 public:
276 							FuncDataList( ResMgr& );
277 	virtual					~FuncDataList();
278     using MyList::Append;
279 	inline void				Append( FuncData* pNew );
280 	inline const FuncData*	Get( sal_uInt32 nIndex ) const;
281 	using MyList::Count;
282 
283     const FuncData*         Get( const ::rtl::OUString& aProgrammaticName ) const;
284 };
285 
286 
287 
288 class AnalysisResId : public ResId
289 {
290  public:
291 					AnalysisResId( sal_uInt16 nId, ResMgr& rResMgr );
292 };
293 
294 
295 
296 
297 class AnalysisRscStrLoader : public Resource
298 {
299 private:
300 	String			aStr;
301 public:
302 	AnalysisRscStrLoader( sal_uInt16 nRsc, sal_uInt16 nStrId, ResMgr& rResMgr ) :
303 		Resource( AnalysisResId( nRsc, rResMgr ) ),
304 		aStr( AnalysisResId( nStrId, rResMgr ) )
305 	{
306 		FreeResource();
307 	}
308 
309 	const String&	GetString() const { return aStr; }
310 
311 };
312 
313 
314 
315 //-----------------------------------------------------------------------------
316 
317 /// sorted list with unique sal_Int32 values
318 class SortedIndividualInt32List : private MyList
319 {
320 protected:
321     using MyList::Insert;
322     void                        Insert( sal_Int32 nDay );
323     void                        Insert( sal_Int32 nDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend );
324     void                        Insert( double fDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend )
325                                     throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
326 
327                                 /** @param rAnyConv  must be an initialized ScaAnyConmverter
328                                     @param bInsertOnWeekend  insertion mode: sal_False = holidays on weekend are omitted */
329     void                        InsertHolidayList(
330                                     const ScaAnyConverter& rAnyConv,
331                                     const CSS::uno::Any& rHolAny,
332                                     sal_Int32 nNullDate,
333                                     sal_Bool bInsertOnWeekend ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
334 
335 public:
336                                 SortedIndividualInt32List();
337     virtual                     ~SortedIndividualInt32List();
338 
339                                 using MyList::Count;
340 
341                                 /// @return  element on position nIndex or 0 on invalid index
342     inline sal_Int32            Get( sal_uInt32 nIndex ) const
343                                     { return (sal_Int32)(sal_IntPtr) MyList::GetObject( nIndex ); }
344 
345                                 /// @return  sal_True if nVal (internal date representation) is contained
346     sal_Bool                    Find( sal_Int32 nVal ) const;
347 
348                                 /** @param rAnyConv  is an initialized or uninitialized ScaAnyConverter
349                                     @param bInsertOnWeekend  insertion mode: sal_False = holidays on weekend are omitted */
350     void                        InsertHolidayList(
351                                     ScaAnyConverter& rAnyConv,
352                                     const CSS::uno::Reference< CSS::beans::XPropertySet >& xOptions,
353                                     const CSS::uno::Any& rHolAny,
354                                     sal_Int32 nNullDate,
355                                     sal_Bool bInsertOnWeekend ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
356 };
357 
358 
359 //-----------------------------------------------------------------------------
360 
361 class ScaDoubleList : protected MyList
362 {
363 protected:
364     inline void                 ListAppend( double fValue ) { MyList::Append( new double( fValue ) ); }
365 
366     using MyList::Append;
367     inline void                 Append( double fValue ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException )
368                                     { if( CheckInsert( fValue ) ) ListAppend( fValue ); }
369 
370                                 /** @param rAnyConv  must be an initialized ScaAnyConmverter
371                                     @param bIgnoreEmpty  handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
372     void                        Append(
373                                     const ScaAnyConverter& rAnyConv,
374                                     const CSS::uno::Any& rAny,
375                                     sal_Bool bIgnoreEmpty ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
376 
377                                 /** @param rAnyConv  must be an initialized ScaAnyConmverter
378                                     @param bIgnoreEmpty  handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
379     void                        Append(
380                                     const ScaAnyConverter& rAnyConv,
381                                     const CSS::uno::Sequence< CSS::uno::Any >& rAnySeq,
382                                     sal_Bool bIgnoreEmpty ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
383 
384                                 /** @param rAnyConv  must be an initialized ScaAnyConmverter
385                                     @param bIgnoreEmpty  handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
386     void                        Append(
387                                     const ScaAnyConverter& rAnyConv,
388                                     const CSS::uno::Sequence< CSS::uno::Sequence< CSS::uno::Any > >& rAnySeq,
389                                     sal_Bool bIgnoreEmpty ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
390 
391 public:
392     virtual                     ~ScaDoubleList();
393 
394                                 using MyList::Count;
395     inline const double*        Get( sal_uInt32 nIndex ) const
396                                         { return static_cast< const double* >( MyList::GetObject( nIndex ) ); }
397 
398     inline const double*        First() { return static_cast< const double* >( MyList::First() ); }
399     inline const double*        Next()  { return static_cast< const double* >( MyList::Next() ); }
400 
401     void                        Append( const CSS::uno::Sequence< CSS::uno::Sequence< double > >& rValueArr )
402                                     throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
403     void                        Append( const CSS::uno::Sequence< CSS::uno::Sequence< sal_Int32 > >& rValueArr )
404                                     throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
405 
406                                 /** @param rAnyConv  is an initialized or uninitialized ScaAnyConverter
407                                     @param bIgnoreEmpty  handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
408     void                        Append(
409                                     ScaAnyConverter& rAnyConv,
410                                     const CSS::uno::Reference< CSS::beans::XPropertySet >& xOpt,
411                                     const CSS::uno::Sequence< CSS::uno::Any >& rAnySeq,
412                                     sal_Bool bIgnoreEmpty = sal_True ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
413 
414     virtual sal_Bool            CheckInsert( double fValue ) const
415                                     throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
416 };
417 
418 
419 //-----------------------------------------------------------------------------
420 
421 /// stores double values >0.0, throws exception for double values <0.0, does nothing for 0.0
422 class ScaDoubleListGT0 : public ScaDoubleList
423 {
424 public:
425     virtual sal_Bool            CheckInsert( double fValue ) const
426                                     throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
427 };
428 
429 
430 //-----------------------------------------------------------------------------
431 
432 /// stores double values >=0.0, throws exception for double values <0.0
433 class ScaDoubleListGE0 : public ScaDoubleList
434 {
435 public:
436     virtual sal_Bool            CheckInsert( double fValue ) const
437                                     throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
438 };
439 
440 
441 //-----------------------------------------------------------------------------
442 
443 class Complex
444 {
445 	double					r;
446 	double					i;
447     sal_Unicode             c;
448 
449 public:
450     inline                  Complex( double fReal, double fImag = 0.0, sal_Char cC = '\0' );
451 							Complex( const STRING& rComplexAsString ) THROWDEF_RTE_IAE;
452 
453 	inline static sal_Bool	IsImagUnit( sal_Unicode c );
454 	static sal_Bool			ParseString( const STRING& rComplexAsString, Complex& rReturn );
455     STRING                  GetString() const THROWDEF_RTE_IAE;
456 
457 	inline double			Real( void ) const;
458 	inline double			Imag( void ) const;
459 
460 	double					Arg( void ) const THROWDEF_RTE_IAE;
461 	inline double			Abs( void ) const;
462 
463 	// following functions change the complex number itself to avoid unnecessary copy actions!
464 	void					Power( double fPower ) THROWDEF_RTE_IAE;
465 	void					Sqrt( void );
466 	void					Sin( void ) THROWDEF_RTE_IAE;
467 	void					Cos( void ) THROWDEF_RTE_IAE;
468 	void					Div( const Complex& rDivisor ) THROWDEF_RTE_IAE;
469 	void					Exp( void );
470 	inline void				Conjugate( void );
471 	void					Ln( void ) THROWDEF_RTE_IAE;
472 	void					Log10( void ) THROWDEF_RTE_IAE;
473 	void					Log2( void ) THROWDEF_RTE_IAE;
474 	inline void				Mult( double fFact );
475 	inline void				Mult( const Complex& rMult );
476 	inline void				Sub( const Complex& rMult );
477 	inline void				Add( const Complex& rAdd );
478 };
479 
480 
481 
482 
483 enum ComplListAppendHandl
484 {
485 	AH_EmptyAsErr,
486 	AH_EmpyAs0,
487 	AH_IgnoreEmpty
488 };
489 
490 
491 class ComplexList : protected MyList
492 {
493 public:
494 	virtual					~ComplexList();
495 
496 	inline const Complex*	Get( sal_uInt32 nIndex ) const;
497 	inline const Complex*	First( void );
498 	inline const Complex*	Next( void );
499 
500 	using MyList::Count;
501 
502     using MyList::Append;
503 	inline void				Append( Complex* pNew );
504 	void					Append( const SEQSEQ( STRING )& rComplexNumList, ComplListAppendHandl eAH = AH_EmpyAs0 ) THROWDEF_RTE_IAE;
505 	void					Append( const SEQ( ANY )& aMultPars,ComplListAppendHandl eAH = AH_EmpyAs0 ) THROWDEF_RTE_IAE;
506 };
507 
508 
509 
510 
511 enum ConvertDataClass
512 {
513 	CDC_Mass, CDC_Length, CDC_Time, CDC_Pressure, CDC_Force, CDC_Energy, CDC_Power, CDC_Magnetism,
514 	CDC_Temperature, CDC_Volume, CDC_Area, CDC_Speed, CDC_Information
515 };
516 
517 
518 #define	INV_MATCHLEV		1764					// guess, what this is... :-)
519 
520 
521 class ConvertDataList;
522 
523 
524 
525 
526 class ConvertData
527 {
528 protected:
529 	friend class ConvertDataList;
530 	double					fConst;
531 	STRING					aName;
532 	ConvertDataClass		eClass;
533     sal_Bool                bPrefixSupport;
534 public:
535 							ConvertData(
536 								const sal_Char		pUnitName[],
537 								double				fConvertConstant,
538 								ConvertDataClass	eClass,
539                                 sal_Bool            bPrefSupport = sal_False );
540 
541     virtual                 ~ConvertData();
542 
543 	sal_Int16				GetMatchingLevel( const STRING& rRef ) const;
544 									// 0.0 = no equality
545 									// 1.0 = matches exact
546 									// rest = matches without an assumed prefix of one character
547 									//  rest gives power for 10 represented by the prefix (e.g. 3 for k or -9 for n
548 
549 	virtual double			Convert( double fVal, const ConvertData& rTo,
550 								sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const THROWDEF_RTE_IAE;
551 									// converts fVal from this unit to rFrom unit
552 									// throws exception if not from same class
553 									// this implementation is for proportional cases only
554 	virtual double			ConvertToBase( double fVal, sal_Int16 nMatchLevel ) const;
555 	virtual double			ConvertFromBase( double fVal, sal_Int16 nMatchLevel ) const;
556 
557 	inline ConvertDataClass	Class( void ) const;
558     inline sal_Bool         IsPrefixSupport( void ) const;
559 };
560 
561 
562 
563 
564 class ConvertDataLinear : public ConvertData
565 {
566 protected:
567 	double					fOffs;
568 public:
569 	inline					ConvertDataLinear(
570 								const sal_Char		pUnitName[],
571 								double				fConvertConstant,
572 								double				fConvertOffset,
573 								ConvertDataClass	eClass,
574                                 sal_Bool            bPrefSupport = sal_False );
575 
576     virtual                 ~ConvertDataLinear();
577 
578 	virtual double			Convert( double fVal, const ConvertData& rTo,
579 								sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const THROWDEF_RTE_IAE;
580 									// for cases where f(x) = a + bx applies (e.g. Temperatures)
581 
582 	virtual double			ConvertToBase( double fVal, sal_Int16 nMatchLevel ) const;
583 	virtual double			ConvertFromBase( double fVal, sal_Int16 nMatchLevel ) const;
584 };
585 
586 
587 
588 
589 class ConvertDataList : protected MyList
590 {
591 private:
592 protected:
593 	inline ConvertData*		First( void );
594 	inline ConvertData*		Next( void );
595 public:
596 							ConvertDataList( void );
597 	virtual					~ConvertDataList();
598 
599 	double					Convert( double fVal, const STRING& rFrom, const STRING& rTo ) THROWDEF_RTE_IAE;
600 };
601 
602 
603 
604 
605 inline sal_Bool IsLeapYear( sal_uInt16 n )
606 {
607     return ( (( ( n % 4 ) == 0 ) && ( ( n % 100 ) != 0)) || ( ( n % 400 ) == 0 ) );
608 }
609 
610 
611 inline sal_Int32 GetDiffDate360( constREFXPS& xOpt, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod )
612 {
613 	return GetDiffDate360( GetNullDate( xOpt ), nDate1, nDate2, bUSAMethod );
614 }
615 
616 
617 inline sal_Int16 GetDayOfWeek( sal_Int32 n )
618 {	// monday = 0, ..., sunday = 6
619     return static_cast< sal_Int16 >( ( n - 1 ) % 7 );
620 }
621 
622 
623 inline double GetYearFrac( constREFXPS& xOpt, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
624 {
625 	return GetYearFrac( GetNullDate( xOpt ), nStartDate, nEndDate, nMode );
626 }
627 
628 
629 inline void AlignDate( sal_uInt16& rD, sal_uInt16 nM, sal_uInt16 nY )
630 {
631 	sal_uInt16	nMax = DaysInMonth( nM, nY );
632 
633 	if( rD > nMax )
634 		rD = nMax;
635 }
636 
637 
638 inline void MyList::Grow( void )
639 {
640 	if( nNew >= nSize )
641 		_Grow();
642 }
643 
644 
645 inline const void* MyList::GetObject( sal_uInt32 n ) const
646 {
647 	if( n < nNew )
648 		return pData[ n ];
649 	else
650 		return NULL;
651 }
652 
653 
654 inline const void* MyList::First( void )
655 {
656 	nAct = 0;
657 	if( nNew )
658 		return pData[ 0 ];
659 	else
660 		return NULL;
661 }
662 
663 
664 inline const void* MyList::Next( void )
665 {
666 	nAct++;
667 	if( nAct < nNew )
668 		return pData[ nAct ];
669 	else
670 	{
671 		nAct--;
672 		return NULL;
673 	}
674 }
675 
676 
677 inline void MyList::Append( void* p )
678 {
679 	Grow();
680 	pData[ nNew ] = p;
681 	nNew++;
682 }
683 
684 
685 inline sal_uInt32 MyList::Count( void ) const
686 {
687 	return nNew;
688 }
689 
690 
691 
692 
693 inline const STRING* StringList::First( void )
694 {
695 	return ( const STRING* ) MyList::First();
696 }
697 
698 
699 inline const STRING* StringList::Next( void )
700 {
701 	return ( const STRING* ) MyList::Next();
702 }
703 
704 
705 inline const STRING* StringList::Get( sal_uInt32 n ) const
706 {
707 	return ( const STRING* ) MyList::GetObject( n );
708 }
709 
710 
711 inline void StringList::Append( STRING* p )
712 {
713 	MyList::Append( p );
714 }
715 
716 
717 inline void StringList::Append( const STRING& r )
718 {
719 	MyList::Append( new STRING( r ) );
720 }
721 
722 
723 
724 
725 inline sal_uInt16 FuncData::GetUINameID( void ) const
726 {
727 	return nUINameID;
728 }
729 
730 
731 inline sal_uInt16 FuncData::GetDescrID( void ) const
732 {
733 	return nDescrID;
734 }
735 
736 
737 inline sal_Bool FuncData::IsDouble( void ) const
738 {
739 	return bDouble;
740 }
741 
742 
743 inline sal_Bool FuncData::HasIntParam( void ) const
744 {
745 	return bWithOpt;
746 }
747 
748 
749 inline sal_Bool FuncData::Is( const ::rtl::OUString& r ) const
750 {
751 	return aIntName == r;
752 }
753 
754 
755 inline const StringList& FuncData::GetCompNameList( void ) const
756 {
757 	return aCompList;
758 }
759 
760 
761 inline FDCategory FuncData::GetCategory( void ) const
762 {
763 	return eCat;
764 }
765 
766 
767 
768 
769 inline void CStrList::Append( const sal_Char* p )
770 {
771 	MyList::Append( ( void* ) p );
772 }
773 
774 
775 inline const sal_Char* CStrList::Get( sal_uInt32 n ) const
776 {
777 	return ( const sal_Char* ) MyList::GetObject( n );
778 }
779 
780 
781 
782 
783 inline void FuncDataList::Append( FuncData* p )
784 {
785 	MyList::Append( p );
786 }
787 
788 
789 inline const FuncData* FuncDataList::Get( sal_uInt32 n ) const
790 {
791 	return ( const FuncData* ) MyList::GetObject( n );
792 }
793 
794 
795 inline Complex::Complex( double fReal, double fImag, sal_Char cC ) :
796 		r( fReal ), i( fImag ), c( cC )
797 {
798 }
799 
800 
801 inline double Complex::Real( void ) const
802 {
803 	return r;
804 }
805 
806 
807 inline double Complex::Imag( void ) const
808 {
809 	return i;
810 }
811 
812 
813 inline double Complex::Abs( void ) const
814 {
815 	return sqrt( r * r + i * i );
816 }
817 
818 
819 void Complex::Conjugate( void )
820 {
821 	i = -i;
822 }
823 
824 
825 inline void Complex::Mult( double f )
826 {
827 	i *= f;
828 	r *= f;
829 }
830 
831 
832 inline void Complex::Mult( const Complex& rM )
833 {
834 	double	r_ = r;
835 	double	i_ = i;
836 
837 	r = r_ * rM.r - i_ * rM.i;
838 	i = r_ * rM.i + i_ * rM.r;
839 
840     if( !c ) c = rM.c;
841 }
842 
843 
844 inline void Complex::Sub( const Complex& rC )
845 {
846 	r -= rC.r;
847 	i -= rC.i;
848     if( !c ) c = rC.c;
849 }
850 
851 
852 inline void Complex::Add( const Complex& rAdd )
853 {
854 	r += rAdd.r;
855 	i += rAdd.i;
856     if( !c ) c = rAdd.c;
857 }
858 
859 
860 
861 
862 inline const Complex* ComplexList::Get( sal_uInt32 n ) const
863 {
864 	return ( const Complex* ) MyList::GetObject( n );
865 }
866 
867 
868 inline const Complex* ComplexList::First( void )
869 {
870 	return ( const Complex* ) MyList::First();
871 }
872 
873 
874 inline const Complex* ComplexList::Next( void )
875 {
876 	return ( const Complex* ) MyList::Next();
877 }
878 
879 
880 inline void ComplexList::Append( Complex* p )
881 {
882 	MyList::Append( p );
883 }
884 
885 
886 
887 
888 inline ConvertDataClass	ConvertData::Class( void ) const
889 {
890 	return eClass;
891 }
892 
893 
894 
895 inline sal_Bool ConvertData::IsPrefixSupport( void ) const
896 {
897     return bPrefixSupport;
898 }
899 
900 inline ConvertDataLinear::ConvertDataLinear( const sal_Char* p, double fC, double fO, ConvertDataClass e,
901         sal_Bool bPrefSupport ) :
902 	ConvertData( p, fC, e, bPrefSupport ),
903 	fOffs( fO )
904 {
905 }
906 
907 
908 
909 
910 inline ConvertData* ConvertDataList::First( void )
911 {
912 	return ( ConvertData* ) MyList::First();
913 }
914 
915 
916 inline ConvertData* ConvertDataList::Next( void )
917 {
918 	return ( ConvertData* ) MyList::Next();
919 }
920 
921 //-----------------------------------------------------------------------------
922 
923 /// Helper class for date calculation for various financial functions
924 class ScaDate
925 {
926 private:
927     sal_uInt16                  nOrigDay;           /// is the day of the original date.
928     sal_uInt16                  nDay;               /// is the calculated day depending on the current month/year.
929     sal_uInt16                  nMonth;             /// is the current month (one-based).
930     sal_uInt16                  nYear;              /// is the current year.
931     sal_Bool                    bLastDayMode : 1;   /// if sal_True, recalculate nDay after every calculation.
932     sal_Bool                    bLastDay : 1;       /// is sal_True, if original date was the last day in month.
933     sal_Bool                    b30Days : 1;        /// is sal_True, if every month has 30 days in calculations.
934     sal_Bool                    bUSMode : 1;        /// is sal_True, if the US method of 30-day-calculations is used.
935 
936                                 /// Calculates nDay from nOrigDay and current date.
937     void                        setDay();
938 
939                                 /// @return  count of days in current month
940     inline sal_uInt16           getDaysInMonth() const;
941                                 /// @return  count of days in given month
942     inline sal_uInt16           getDaysInMonth( sal_uInt16 _nMon ) const;
943 
944                                 /// @ return  count of days in the given month range
945     sal_Int32                   getDaysInMonthRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const;
946                                 /// @ return  count of days in the given year range
947     sal_Int32                   getDaysInYearRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const;
948 
949                                 /// Adds/subtracts the given count of years, does not adjust day.
950     void                        doAddYears( sal_Int32 nYearCount ) throw( CSS::lang::IllegalArgumentException );
951 
952 public:
953                                 ScaDate();
954                                 /** @param nBase
955                                         date handling mode (days in month / days in year):
956                                         0 = 30 days / 360 days (US NASD)
957                                         1 = exact / exact
958                                         2 = exact / 360
959                                         3 = exact / 365
960                                         4 = 30 days / 360 days (Europe)
961                                         5 = exact / exact (no last day adjustment) */
962                                 ScaDate( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nBase );
963                                 ScaDate( const ScaDate& rCopy );
964     ScaDate&                    operator=( const ScaDate& rCopy );
965 
966                                 /// @return  the current month.
967     inline sal_uInt16           getMonth() const    { return nMonth; };
968                                 /// @return  the current year.
969     inline sal_uInt16           getYear() const     { return nYear; };
970 
971                                 /// adds/subtracts the given count of months, adjusts day
972     void                        addMonths( sal_Int32 nMonthCount ) throw( CSS::lang::IllegalArgumentException );
973 
974                                 /// sets the given year, adjusts day
975     inline void                 setYear( sal_uInt16 nNewYear );
976                                 /// adds/subtracts the given count of years, adjusts day
977     inline void                 addYears( sal_Int32 nYearCount ) throw( CSS::lang::IllegalArgumentException );
978 
979                                 /// @return  the internal number of the current date
980     sal_Int32                   getDate( sal_Int32 nNullDate ) const;
981                                 /// @return  the number of days between the two dates
982     static sal_Int32            getDiff( const ScaDate& rFrom, const ScaDate& rTo ) throw( CSS::lang::IllegalArgumentException );
983 
984     sal_Bool                    operator<( const ScaDate& rCmp ) const;
985     inline sal_Bool             operator<=( const ScaDate& rCmp ) const { return !(rCmp < *this); }
986     inline sal_Bool             operator>( const ScaDate& rCmp ) const  { return rCmp < *this; }
987     inline sal_Bool             operator>=( const ScaDate& rCmp ) const { return !(*this < rCmp); }
988 };
989 
990 inline sal_uInt16 ScaDate::getDaysInMonth() const
991 {
992     return getDaysInMonth( nMonth );
993 }
994 
995 inline sal_uInt16 ScaDate::getDaysInMonth( sal_uInt16 _nMon ) const
996 {
997     return b30Days ? 30 : DaysInMonth( _nMon, nYear );
998 }
999 
1000 inline void ScaDate::setYear( sal_uInt16 nNewYear )
1001 {
1002     nYear = nNewYear;
1003     setDay();
1004 }
1005 
1006 inline void ScaDate::addYears( sal_Int32 nYearCount ) throw( CSS::lang::IllegalArgumentException )
1007 {
1008     doAddYears( nYearCount );
1009     setDay();
1010 }
1011 
1012 
1013 //-----------------------------------------------------------------------------
1014 
1015 /// Helper class for Any->double conversion, using current language settings
1016 class ScaAnyConverter
1017 {
1018 private:
1019     CSS::uno::Reference< CSS::util::XNumberFormatter > xFormatter;
1020     sal_Int32                   nDefaultFormat;
1021     sal_Bool                    bHasValidFormat;
1022 
1023                                 /** Converts a string to double using the number formatter. If the formatter is not
1024                                     valid, ::rtl::math::stringToDouble() with english separators will be used.
1025                                     @throws com::sun::star::lang::IllegalArgumentException
1026                                         on strings not representing any double value.
1027                                     @return  the converted double value. */
1028     double                      convertToDouble(
1029                                     const ::rtl::OUString& rString ) const
1030                                 throw( CSS::lang::IllegalArgumentException );
1031 
1032 public:
1033                                 ScaAnyConverter(
1034                                     const CSS::uno::Reference< CSS::lang::XMultiServiceFactory >& xServiceFact );
1035                                 ~ScaAnyConverter();
1036 
1037                                 /// Initializing with current language settings
1038     void                        init(
1039                                     const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet )
1040                                 throw( CSS::uno::RuntimeException );
1041 
1042                                 /** Converts an Any to double (without initialization).
1043                                     The Any can be empty or contain a double or string.
1044                                     @throws com::sun::star::lang::IllegalArgumentException
1045                                         on other Any types or on invalid strings.
1046                                     @return  sal_True if the Any contains a double or a non-empty valid string,
1047                                              sal_False if the Any is empty or the string is empty */
1048     sal_Bool                    getDouble(
1049                                     double& rfResult,
1050                                     const CSS::uno::Any& rAny ) const
1051                                 throw( CSS::lang::IllegalArgumentException );
1052 
1053                                 /** Converts an Any to double (with initialization).
1054                                     The Any can be empty or contain a double or string.
1055                                     @throws com::sun::star::lang::IllegalArgumentException
1056                                         on other Any types or on invalid strings.
1057                                     @return  sal_True if the Any contains a double or a non-empty valid string,
1058                                              sal_False if the Any is empty or the string is empty */
1059     sal_Bool                    getDouble(
1060                                     double& rfResult,
1061                                     const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet,
1062                                     const CSS::uno::Any& rAny )
1063                                 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
1064 
1065                                 /** Converts an Any to double (with initialization).
1066                                     The Any can be empty or contain a double or string.
1067                                     @throws com::sun::star::lang::IllegalArgumentException
1068                                         on other Any types or on invalid strings.
1069                                     @return  the value of the double or string or fDefault if the Any or string is empty */
1070     double                      getDouble(
1071                                     const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet,
1072                                     const CSS::uno::Any& rAny,
1073                                     double fDefault )
1074                                 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
1075 
1076                                 /** Converts an Any to sal_Int32 (with initialization).
1077                                     The Any can be empty or contain a double or string.
1078                                     @throws com::sun::star::lang::IllegalArgumentException
1079                                         on other Any types or on invalid values or strings.
1080                                     @return  sal_True if the Any contains a double or a non-empty valid string,
1081                                              sal_False if the Any is empty or the string is empty */
1082     sal_Bool                    getInt32(
1083                                     sal_Int32& rnResult,
1084                                     const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet,
1085                                     const CSS::uno::Any& rAny )
1086                                 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
1087 
1088                                 /** Converts an Any to sal_Int32 (with initialization).
1089                                     The Any can be empty or contain a double or string.
1090                                     @throws com::sun::star::lang::IllegalArgumentException
1091                                         on other Any types or on invalid values or strings.
1092                                     @return  the truncated value of the double or string or nDefault if the Any or string is empty */
1093     sal_Int32                   getInt32(
1094                                     const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet,
1095                                     const CSS::uno::Any& rAny,
1096                                     sal_Int32 nDefault )
1097                                 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
1098 };
1099 
1100 
1101 //-----------------------------------------------------------------------------
1102 
1103 
1104 #endif
1105 
1106