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 ) throw( ::com::sun::star::lang::IllegalArgumentException );
66 sal_Int32 GetNullDate( const REF( CSS::beans::XPropertySet )& xOptions ) THROWDEF_RTE;
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 ) THROWDEF_RTE_IAE;
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 ) THROWDEF_RTE_IAE;
83 double GetYearDiff( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode )
84 THROWDEF_RTE_IAE;
85 sal_Int32 GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode ) THROWDEF_RTE_IAE;
86 double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode )
87 THROWDEF_RTE_IAE;
88 inline double GetYearFrac( constREFXPS& xOpt, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode )
89 THROWDEF_RTE_IAE;
90 inline void AlignDate( sal_uInt16& rDay, sal_uInt16 nMonth, sal_uInt16 nYear );
91
92 double Fak( sal_Int32 n );
93 double GetGcd( double f1, double f2 );
94 double ConvertToDec( const STRING& rFromNum, sal_uInt16 nBaseFrom, sal_uInt16 nCharLim ) THROWDEF_RTE_IAE;
95 STRING ConvertFromDec(
96 double fNum, double fMin, double fMax, sal_uInt16 nBase,
97 sal_Int32 nPlaces, sal_Int32 nMaxPlaces, sal_Bool bUsePlaces ) THROWDEF_RTE_IAE;
98 double Erf( double fX );
99 double Erfc( double fX );
100 sal_Bool ParseDouble( const sal_Unicode*& rpDoubleAsString, double& rReturn );
101 STRING GetString( double fNumber, sal_Bool bLeadingSign = sal_False, sal_uInt16 nMaxNumOfDigits = 15 );
102 inline double Exp10( sal_Int16 nPower ); // 10 ^ nPower
103
104 double GetAmordegrc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
105 double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE;
106 double GetAmorlinc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
107 double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE;
108 double GetDuration( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup,
109 double fYield, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
110 double GetYieldmat( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
111 double fRate, double fPrice, sal_Int32 nBase ) THROWDEF_RTE_IAE;
112 double GetOddfprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
113 sal_Int32 nFirstCoup, double fRate, double fYield, double fRedemp,
114 sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
115 double getYield_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice,
116 double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
117 double getPrice_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield,
118 double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
119 double GetOddfyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
120 sal_Int32 nFirstCoup, double fRate, double fPrice, double fRedemp,
121 sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
122 double GetOddlprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest,
123 double fRate, double fYield, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
124 double GetOddlyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest,
125 double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
126 double GetRmz( double fZins, double fZzr, double fBw, double fZw, sal_Int32 nF );
127 double GetZw( double fZins, double fZzr, double fRmz, double fBw, sal_Int32 nF );
128 //double TBillYield( constREFXPS& xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice )THROWDEF_RTE_IAE;
129
130 double GetCouppcd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
131 sal_Int32 nBase ) THROWDEF_RTE_IAE;
132 double GetCoupncd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
133 sal_Int32 nBase ) THROWDEF_RTE_IAE;
134 double GetCoupdaybs( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
135 sal_Int32 nBase ) THROWDEF_RTE_IAE;
136 double GetCoupdaysnc( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
137 sal_Int32 nBase ) THROWDEF_RTE_IAE;
138
139 double GetCoupnum( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat,
140 sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE;
141 double GetCoupdays( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq,
142 sal_Int32 nBase ) THROWDEF_RTE_IAE;
143
144
145
146
147 //-----------------------------------------------------------------------------
148
149
150
151 class MyList
152 {
153 private:
154 static const sal_uInt32 nStartSize;
155 static const sal_uInt32 nIncrSize;
156
157 void** pData; // pointer array
158 sal_uInt32 nSize; // array size
159 sal_uInt32 nNew; // next index to be inserted at
160 sal_uInt32 nAct; // actual for iterations
161
162 void _Grow( void );
163 inline void Grow( void );
164 protected:
165 public:
166 MyList( void );
167 virtual ~MyList();
168
169 inline const void* GetObject( sal_uInt32 nIndex ) const;
170 inline const void* First( void );
171 inline const void* Next( void );
172
173 inline void Append( void* pNewElement );
174 void Insert( void* pNewLement, sal_uInt32 nPlace );
175
176 inline sal_uInt32 Count( void ) const;
177 };
178
179
180
181
182 class StringList : protected MyList
183 {
184 public:
185 virtual ~StringList();
186
187 inline const STRING* First( void );
188 inline const STRING* Next( void );
189 inline const STRING* Get( sal_uInt32 nIndex ) const;
190
191 using MyList::Append;
192 inline void Append( STRING* pNew );
193 inline void Append( const STRING& rNew );
194
195 using MyList::Count;
196 };
197
198
199
200
201 enum FDCategory
202 {
203 FDCat_AddIn,
204 FDCat_DateTime,
205 FDCat_Finance,
206 FDCat_Inf,
207 FDCat_Math,
208 FDCat_Tech
209 };
210
211
212 struct FuncDataBase
213 {
214 const sal_Char* pIntName;
215 sal_uInt16 nUINameID; // resource ID to UI name
216 sal_uInt16 nDescrID; // resource ID to description, parameter names and ~ description
217 sal_Bool bDouble; // name already exist in Calc
218 sal_Bool bWithOpt; // first parameter is internal
219 sal_uInt16 nCompListID; // resource ID to list of valid names
220 sal_uInt16 nNumOfParams; // number of named / described parameters
221 FDCategory eCat; // function category
222 };
223
224
225
226
227 class FuncData
228 {
229 private:
230 ::rtl::OUString aIntName;
231 sal_uInt16 nUINameID;
232 sal_uInt16 nDescrID; // leads also to parameter descriptions!
233 sal_Bool bDouble; // flag for names, which already exists in Calc
234 sal_Bool bWithOpt; // has internal parameter on first position
235
236 sal_uInt16 nParam; // num of parameters
237 sal_uInt16 nCompID;
238 StringList aCompList; // list of all valid names
239 FDCategory eCat; // function category
240 public:
241 FuncData( const FuncDataBase& rBaseData, ResMgr& );
242 virtual ~FuncData();
243
244 inline sal_uInt16 GetUINameID( void ) const;
245 inline sal_uInt16 GetDescrID( void ) const;
246 inline sal_Bool IsDouble( void ) const;
247 inline sal_Bool HasIntParam( void ) const;
248
249 sal_uInt16 GetStrIndex( sal_uInt16 nParamNum ) const;
250 inline sal_Bool Is( const ::rtl::OUString& rCompareTo ) const;
251
252 inline const StringList& GetCompNameList( void ) const;
253
254 inline FDCategory GetCategory( void ) const;
255 };
256
257
258
259
260 class CStrList : private MyList
261 {
262 public:
263 using MyList::Append;
264 inline void Append( const sal_Char* pNew );
265 inline const sal_Char* Get( sal_uInt32 nIndex ) const;
266 using MyList::Count;
267 };
268
269
270
271
272 class FuncDataList : private MyList
273 {
274 ::rtl::OUString aLastName;
275 sal_uInt32 nLast;
276 public:
277 FuncDataList( ResMgr& );
278 virtual ~FuncDataList();
279 using MyList::Append;
280 inline void Append( FuncData* pNew );
281 inline const FuncData* Get( sal_uInt32 nIndex ) const;
282 using MyList::Count;
283
284 const FuncData* Get( const ::rtl::OUString& aProgrammaticName ) const;
285 };
286
287
288
289 class AnalysisResId : public ResId
290 {
291 public:
292 AnalysisResId( sal_uInt16 nId, ResMgr& rResMgr );
293 };
294
295
296
297
298 class AnalysisRscStrLoader : public Resource
299 {
300 private:
301 String aStr;
302 public:
AnalysisRscStrLoader(sal_uInt16 nRsc,sal_uInt16 nStrId,ResMgr & rResMgr)303 AnalysisRscStrLoader( sal_uInt16 nRsc, sal_uInt16 nStrId, ResMgr& rResMgr ) :
304 Resource( AnalysisResId( nRsc, rResMgr ) ),
305 aStr( AnalysisResId( nStrId, rResMgr ) )
306 {
307 FreeResource();
308 }
309
GetString() const310 const String& GetString() const { return aStr; }
311
312 };
313
314
315
316 //-----------------------------------------------------------------------------
317
318 /// sorted list with unique sal_Int32 values
319 class SortedIndividualInt32List : private MyList
320 {
321 protected:
322 using MyList::Insert;
323 void Insert( sal_Int32 nDay );
324 void Insert( sal_Int32 nDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend );
325 void Insert( double fDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend )
326 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
327
328 /** @param rAnyConv must be an initialized ScaAnyConmverter
329 @param bInsertOnWeekend insertion mode: sal_False = holidays on weekend are omitted */
330 void InsertHolidayList(
331 const ScaAnyConverter& rAnyConv,
332 const CSS::uno::Any& rHolAny,
333 sal_Int32 nNullDate,
334 sal_Bool bInsertOnWeekend ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
335
336 public:
337 SortedIndividualInt32List();
338 virtual ~SortedIndividualInt32List();
339
340 using MyList::Count;
341
342 /// @return element on position nIndex or 0 on invalid index
Get(sal_uInt32 nIndex) const343 inline sal_Int32 Get( sal_uInt32 nIndex ) const
344 { return (sal_Int32)(sal_IntPtr) MyList::GetObject( nIndex ); }
345
346 /// @return sal_True if nVal (internal date representation) is contained
347 sal_Bool Find( sal_Int32 nVal ) const;
348
349 /** @param rAnyConv is an initialized or uninitialized ScaAnyConverter
350 @param bInsertOnWeekend insertion mode: sal_False = holidays on weekend are omitted */
351 void InsertHolidayList(
352 ScaAnyConverter& rAnyConv,
353 const CSS::uno::Reference< CSS::beans::XPropertySet >& xOptions,
354 const CSS::uno::Any& rHolAny,
355 sal_Int32 nNullDate,
356 sal_Bool bInsertOnWeekend ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
357 };
358
359
360 //-----------------------------------------------------------------------------
361
362 class ScaDoubleList : protected MyList
363 {
364 protected:
ListAppend(double fValue)365 inline void ListAppend( double fValue ) { MyList::Append( new double( fValue ) ); }
366
367 using MyList::Append;
Append(double fValue)368 inline void Append( double fValue ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException )
369 { if( CheckInsert( fValue ) ) ListAppend( fValue ); }
370
371 /** @param rAnyConv must be an initialized ScaAnyConmverter
372 @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
373 void Append(
374 const ScaAnyConverter& rAnyConv,
375 const CSS::uno::Any& rAny,
376 sal_Bool bIgnoreEmpty ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
377
378 /** @param rAnyConv must be an initialized ScaAnyConmverter
379 @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
380 void Append(
381 const ScaAnyConverter& rAnyConv,
382 const CSS::uno::Sequence< CSS::uno::Any >& rAnySeq,
383 sal_Bool bIgnoreEmpty ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
384
385 /** @param rAnyConv must be an initialized ScaAnyConmverter
386 @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
387 void Append(
388 const ScaAnyConverter& rAnyConv,
389 const CSS::uno::Sequence< CSS::uno::Sequence< CSS::uno::Any > >& rAnySeq,
390 sal_Bool bIgnoreEmpty ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
391
392 public:
393 virtual ~ScaDoubleList();
394
395 using MyList::Count;
Get(sal_uInt32 nIndex) const396 inline const double* Get( sal_uInt32 nIndex ) const
397 { return static_cast< const double* >( MyList::GetObject( nIndex ) ); }
398
First()399 inline const double* First() { return static_cast< const double* >( MyList::First() ); }
Next()400 inline const double* Next() { return static_cast< const double* >( MyList::Next() ); }
401
402 void Append( const CSS::uno::Sequence< CSS::uno::Sequence< double > >& rValueArr )
403 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
404 void Append( const CSS::uno::Sequence< CSS::uno::Sequence< sal_Int32 > >& rValueArr )
405 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
406
407 /** @param rAnyConv is an initialized or uninitialized ScaAnyConverter
408 @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
409 void Append(
410 ScaAnyConverter& rAnyConv,
411 const CSS::uno::Reference< CSS::beans::XPropertySet >& xOpt,
412 const CSS::uno::Sequence< CSS::uno::Any >& rAnySeq,
413 sal_Bool bIgnoreEmpty = sal_True ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
414
415 virtual sal_Bool CheckInsert( double fValue ) const
416 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
417 };
418
419
420 //-----------------------------------------------------------------------------
421
422 /// stores double values >0.0, throws exception for double values <0.0, does nothing for 0.0
423 class ScaDoubleListGT0 : public ScaDoubleList
424 {
425 public:
426 virtual sal_Bool CheckInsert( double fValue ) const
427 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
428 };
429
430
431 //-----------------------------------------------------------------------------
432
433 /// stores double values >=0.0, throws exception for double values <0.0
434 class ScaDoubleListGE0 : public ScaDoubleList
435 {
436 public:
437 virtual sal_Bool CheckInsert( double fValue ) const
438 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException );
439 };
440
441
442 //-----------------------------------------------------------------------------
443
444
445 class Complex
446 {
447 double_complex Num;
448 sal_Unicode c;
449
450 public:
451 inline Complex( double fReal, double fImag = 0.0, sal_Unicode cC = '\0' );
452 Complex( const STRING& rComplexAsString ) THROWDEF_RTE_IAE;
453
454 inline static sal_Bool IsImagUnit( sal_Unicode c );
455 static sal_Bool ParseString( const STRING& rComplexAsString, Complex& rReturn );
456 STRING GetString() const THROWDEF_RTE_IAE;
457
458 inline double Real( void ) const;
459 inline double Imag( void ) const;
460
461 double Arg( void ) const THROWDEF_RTE_IAE;
462 inline double Abs( void ) const;
463
464 // following functions change the complex number itself to avoid unnecessary copy actions!
465 void Power( double fPower ) THROWDEF_RTE_IAE;
466 void Sqrt( void );
467 void Sin( void ) THROWDEF_RTE_IAE;
468 void Cos( void ) THROWDEF_RTE_IAE;
469 void Div( const Complex& rDivisor ) THROWDEF_RTE_IAE;
470 void Exp( void );
471 inline void Conjugate( void );
472 void Ln( void ) THROWDEF_RTE_IAE;
473 void Log10( void ) THROWDEF_RTE_IAE;
474 void Log2( void ) THROWDEF_RTE_IAE;
475 inline void Mult( double fFact );
476 inline void Mult( const Complex& rMult );
477 inline void Sub( const Complex& rMult );
478 inline void Add( const Complex& rAdd );
479 void Tan( void ) THROWDEF_RTE_IAE;
480 void Sec( void ) THROWDEF_RTE_IAE;
481 void Csc( void ) THROWDEF_RTE_IAE;
482 void Cot( void ) THROWDEF_RTE_IAE;
483 void Sinh( void ) THROWDEF_RTE_IAE;
484 void Cosh( void ) THROWDEF_RTE_IAE;
485 void Sech( void ) THROWDEF_RTE_IAE;
486 void Csch( void ) THROWDEF_RTE_IAE;
487
488 };
489
490
491
492
493 enum ComplListAppendHandl
494 {
495 AH_EmptyAsErr,
496 AH_EmpyAs0,
497 AH_IgnoreEmpty
498 };
499
500
501 class ComplexList : protected MyList
502 {
503 public:
504 virtual ~ComplexList();
505
506 inline const Complex* Get( sal_uInt32 nIndex ) const;
507 inline const Complex* First( void );
508 inline const Complex* Next( void );
509
510 using MyList::Count;
511
512 using MyList::Append;
513 inline void Append( Complex* pNew );
514 void Append( const SEQSEQ( STRING )& rComplexNumList, ComplListAppendHandl eAH = AH_EmpyAs0 ) THROWDEF_RTE_IAE;
515 void Append( const SEQ( ANY )& aMultPars,ComplListAppendHandl eAH = AH_EmpyAs0 ) THROWDEF_RTE_IAE;
516 };
517
518
519
520
521 enum ConvertDataClass
522 {
523 CDC_Mass, CDC_Length, CDC_Time, CDC_Pressure, CDC_Force, CDC_Energy, CDC_Power, CDC_Magnetism,
524 CDC_Temperature, CDC_Volume, CDC_Area, CDC_Speed, CDC_Information
525 };
526
527
528 #define INV_MATCHLEV 1764 // guess, what this is... :-)
529
530
531 class ConvertDataList;
532
533
534
535
536 class ConvertData
537 {
538 protected:
539 friend class ConvertDataList;
540 double fConst;
541 STRING aName;
542 ConvertDataClass eClass;
543 sal_Bool bPrefixSupport;
544 public:
545 ConvertData(
546 const sal_Char pUnitName[],
547 double fConvertConstant,
548 ConvertDataClass eClass,
549 sal_Bool bPrefSupport = sal_False );
550
551 virtual ~ConvertData();
552
553 sal_Int16 GetMatchingLevel( const STRING& rRef ) const;
554 // 0.0 = no equality
555 // 1.0 = matches exact
556 // rest = matches without an assumed prefix of one character
557 // rest gives power for 10 represented by the prefix (e.g. 3 for k or -9 for n
558
559 virtual double Convert( double fVal, const ConvertData& rTo,
560 sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const THROWDEF_RTE_IAE;
561 // converts fVal from this unit to rFrom unit
562 // throws exception if not from same class
563 // this implementation is for proportional cases only
564 virtual double ConvertToBase( double fVal, sal_Int16 nMatchLevel ) const;
565 virtual double ConvertFromBase( double fVal, sal_Int16 nMatchLevel ) const;
566
567 inline ConvertDataClass Class( void ) const;
568 inline sal_Bool IsPrefixSupport( void ) const;
569 };
570
571
572
573
574 class ConvertDataLinear : public ConvertData
575 {
576 protected:
577 double fOffs;
578 public:
579 inline ConvertDataLinear(
580 const sal_Char pUnitName[],
581 double fConvertConstant,
582 double fConvertOffset,
583 ConvertDataClass eClass,
584 sal_Bool bPrefSupport = sal_False );
585
586 virtual ~ConvertDataLinear();
587
588 virtual double Convert( double fVal, const ConvertData& rTo,
589 sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const THROWDEF_RTE_IAE;
590 // for cases where f(x) = a + bx applies (e.g. Temperatures)
591
592 virtual double ConvertToBase( double fVal, sal_Int16 nMatchLevel ) const;
593 virtual double ConvertFromBase( double fVal, sal_Int16 nMatchLevel ) const;
594 };
595
596
597
598
599 class ConvertDataList : protected MyList
600 {
601 private:
602 protected:
603 inline ConvertData* First( void );
604 inline ConvertData* Next( void );
605 public:
606 ConvertDataList( void );
607 virtual ~ConvertDataList();
608
609 double Convert( double fVal, const STRING& rFrom, const STRING& rTo ) THROWDEF_RTE_IAE;
610 };
611
612
613
614
IsLeapYear(sal_uInt16 n)615 inline sal_Bool IsLeapYear( sal_uInt16 n )
616 {
617 return ( (( ( n % 4 ) == 0 ) && ( ( n % 100 ) != 0)) || ( ( n % 400 ) == 0 ) );
618 }
619
620
GetDiffDate360(constREFXPS & xOpt,sal_Int32 nDate1,sal_Int32 nDate2,sal_Bool bUSAMethod)621 inline sal_Int32 GetDiffDate360( constREFXPS& xOpt, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod )
622 {
623 return GetDiffDate360( GetNullDate( xOpt ), nDate1, nDate2, bUSAMethod );
624 }
625
626
GetDayOfWeek(sal_Int32 n)627 inline sal_Int16 GetDayOfWeek( sal_Int32 n )
628 { // monday = 0, ..., sunday = 6
629 return static_cast< sal_Int16 >( ( n - 1 ) % 7 );
630 }
631
632
GetYearFrac(constREFXPS & xOpt,sal_Int32 nStartDate,sal_Int32 nEndDate,sal_Int32 nMode)633 inline double GetYearFrac( constREFXPS& xOpt, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
634 {
635 return GetYearFrac( GetNullDate( xOpt ), nStartDate, nEndDate, nMode );
636 }
637
638
AlignDate(sal_uInt16 & rD,sal_uInt16 nM,sal_uInt16 nY)639 inline void AlignDate( sal_uInt16& rD, sal_uInt16 nM, sal_uInt16 nY )
640 {
641 sal_uInt16 nMax = DaysInMonth( nM, nY );
642
643 if( rD > nMax )
644 rD = nMax;
645 }
646
647
Grow(void)648 inline void MyList::Grow( void )
649 {
650 if( nNew >= nSize )
651 _Grow();
652 }
653
654
GetObject(sal_uInt32 n) const655 inline const void* MyList::GetObject( sal_uInt32 n ) const
656 {
657 if( n < nNew )
658 return pData[ n ];
659 else
660 return NULL;
661 }
662
663
First(void)664 inline const void* MyList::First( void )
665 {
666 nAct = 0;
667 if( nNew )
668 return pData[ 0 ];
669 else
670 return NULL;
671 }
672
673
Next(void)674 inline const void* MyList::Next( void )
675 {
676 nAct++;
677 if( nAct < nNew )
678 return pData[ nAct ];
679 else
680 {
681 nAct--;
682 return NULL;
683 }
684 }
685
686
Append(void * p)687 inline void MyList::Append( void* p )
688 {
689 Grow();
690 pData[ nNew ] = p;
691 nNew++;
692 }
693
694
Count(void) const695 inline sal_uInt32 MyList::Count( void ) const
696 {
697 return nNew;
698 }
699
700
701
702
First(void)703 inline const STRING* StringList::First( void )
704 {
705 return ( const STRING* ) MyList::First();
706 }
707
708
Next(void)709 inline const STRING* StringList::Next( void )
710 {
711 return ( const STRING* ) MyList::Next();
712 }
713
714
Get(sal_uInt32 n) const715 inline const STRING* StringList::Get( sal_uInt32 n ) const
716 {
717 return ( const STRING* ) MyList::GetObject( n );
718 }
719
720
Append(STRING * p)721 inline void StringList::Append( STRING* p )
722 {
723 MyList::Append( p );
724 }
725
726
Append(const STRING & r)727 inline void StringList::Append( const STRING& r )
728 {
729 MyList::Append( new STRING( r ) );
730 }
731
732
733
734
GetUINameID(void) const735 inline sal_uInt16 FuncData::GetUINameID( void ) const
736 {
737 return nUINameID;
738 }
739
740
GetDescrID(void) const741 inline sal_uInt16 FuncData::GetDescrID( void ) const
742 {
743 return nDescrID;
744 }
745
746
IsDouble(void) const747 inline sal_Bool FuncData::IsDouble( void ) const
748 {
749 return bDouble;
750 }
751
752
HasIntParam(void) const753 inline sal_Bool FuncData::HasIntParam( void ) const
754 {
755 return bWithOpt;
756 }
757
758
Is(const::rtl::OUString & r) const759 inline sal_Bool FuncData::Is( const ::rtl::OUString& r ) const
760 {
761 return aIntName == r;
762 }
763
764
GetCompNameList(void) const765 inline const StringList& FuncData::GetCompNameList( void ) const
766 {
767 return aCompList;
768 }
769
770
GetCategory(void) const771 inline FDCategory FuncData::GetCategory( void ) const
772 {
773 return eCat;
774 }
775
776
777
778
Append(const sal_Char * p)779 inline void CStrList::Append( const sal_Char* p )
780 {
781 MyList::Append( ( void* ) p );
782 }
783
784
Get(sal_uInt32 n) const785 inline const sal_Char* CStrList::Get( sal_uInt32 n ) const
786 {
787 return ( const sal_Char* ) MyList::GetObject( n );
788 }
789
790
791
792
Append(FuncData * p)793 inline void FuncDataList::Append( FuncData* p )
794 {
795 MyList::Append( p );
796 }
797
798
Get(sal_uInt32 n) const799 inline const FuncData* FuncDataList::Get( sal_uInt32 n ) const
800 {
801 return ( const FuncData* ) MyList::GetObject( n );
802 }
803
804
Complex(double fReal,double fImag,sal_Unicode cC)805 inline Complex::Complex( double fReal, double fImag, sal_Unicode cC ) :
806 Num( fReal, fImag ), c( cC )
807 {
808 }
809
810
Real(void) const811 inline double Complex::Real( void ) const
812 {
813 return Num.real();
814 }
815
816
Imag(void) const817 inline double Complex::Imag( void ) const
818 {
819 return Num.imag();
820 }
821
822
Abs(void) const823 inline double Complex::Abs( void ) const
824 {
825 return std::abs( Num );
826 }
827
828
Conjugate(void)829 void Complex::Conjugate( void )
830 {
831 Num = std::conj( Num );
832 }
833
834
Mult(double f)835 inline void Complex::Mult( double f )
836 {
837 Num = f * Num;
838 }
839
840
Mult(const Complex & rM)841 inline void Complex::Mult( const Complex& rM )
842 {
843 Num = Num * rM.Num;
844
845 if( !c ) c = rM.c;
846 }
847
848
Sub(const Complex & rC)849 inline void Complex::Sub( const Complex& rC )
850 {
851 Num -= rC.Num;
852
853 if( !c ) c = rC.c;
854 }
855
856
Add(const Complex & rAdd)857 inline void Complex::Add( const Complex& rAdd )
858 {
859 Num += rAdd.Num;
860
861 if( !c ) c = rAdd.c;
862 }
863
864
865
866
Get(sal_uInt32 n) const867 inline const Complex* ComplexList::Get( sal_uInt32 n ) const
868 {
869 return ( const Complex* ) MyList::GetObject( n );
870 }
871
872
First(void)873 inline const Complex* ComplexList::First( void )
874 {
875 return ( const Complex* ) MyList::First();
876 }
877
878
Next(void)879 inline const Complex* ComplexList::Next( void )
880 {
881 return ( const Complex* ) MyList::Next();
882 }
883
884
Append(Complex * p)885 inline void ComplexList::Append( Complex* p )
886 {
887 MyList::Append( p );
888 }
889
890
891
892
Class(void) const893 inline ConvertDataClass ConvertData::Class( void ) const
894 {
895 return eClass;
896 }
897
898
899
IsPrefixSupport(void) const900 inline sal_Bool ConvertData::IsPrefixSupport( void ) const
901 {
902 return bPrefixSupport;
903 }
904
ConvertDataLinear(const sal_Char * p,double fC,double fO,ConvertDataClass e,sal_Bool bPrefSupport)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
First(void)915 inline ConvertData* ConvertDataList::First( void )
916 {
917 return ( ConvertData* ) MyList::First();
918 }
919
920
Next(void)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.
getMonth() const972 inline sal_uInt16 getMonth() const { return nMonth; };
973 /// @return the current year.
getYear() const974 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;
operator <=(const ScaDate & rCmp) const990 inline sal_Bool operator<=( const ScaDate& rCmp ) const { return !(rCmp < *this); }
operator >(const ScaDate & rCmp) const991 inline sal_Bool operator>( const ScaDate& rCmp ) const { return rCmp < *this; }
operator >=(const ScaDate & rCmp) const992 inline sal_Bool operator>=( const ScaDate& rCmp ) const { return !(*this < rCmp); }
993 };
994
getDaysInMonth() const995 inline sal_uInt16 ScaDate::getDaysInMonth() const
996 {
997 return getDaysInMonth( nMonth );
998 }
999
getDaysInMonth(sal_uInt16 _nMon) const1000 inline sal_uInt16 ScaDate::getDaysInMonth( sal_uInt16 _nMon ) const
1001 {
1002 return b30Days ? 30 : DaysInMonth( _nMon, nYear );
1003 }
1004
setYear(sal_uInt16 nNewYear)1005 inline void ScaDate::setYear( sal_uInt16 nNewYear )
1006 {
1007 nYear = nNewYear;
1008 setDay();
1009 }
1010
addYears(sal_Int32 nYearCount)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