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