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