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