LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/scaddins/source/analysis - analysishelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 67 1518 4.4 %
Date: 2013-07-09 Functions: 18 147 12.2 %
Legend: Lines: hit not hit

          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             : 
      20             : #include <com/sun/star/util/XNumberFormatTypes.hpp>
      21             : #include <com/sun/star/util/NumberFormatter.hpp>
      22             : 
      23             : #include <string.h>
      24             : #include <stdio.h>
      25             : #include <tools/resary.hxx>
      26             : #include <rtl/math.hxx>
      27             : #include <sal/macros.h>
      28             : #include "analysishelper.hxx"
      29             : #include "analysis.hrc"
      30             : 
      31             : using namespace                 ::com::sun::star;
      32             : 
      33             : 
      34             : 
      35             : #define UNIQUE              sal_False   // function name does not exist in Calc
      36             : #define DOUBLE              sal_True    // function name exists in Calc
      37             : 
      38             : #define STDPAR              sal_False   // all parameters are described
      39             : #define INTPAR              sal_True    // first parameter is internal
      40             : 
      41             : #define FUNCDATA( FUNCNAME, DBL, OPT, NUMOFPAR, CAT ) \
      42             :     { "get" #FUNCNAME, ANALYSIS_FUNCNAME_##FUNCNAME, ANALYSIS_##FUNCNAME, DBL, OPT, ANALYSIS_DEFFUNCNAME_##FUNCNAME, NUMOFPAR, CAT }
      43             : 
      44             : const FuncDataBase pFuncDatas[] =
      45             : {
      46             :     //                          UNIQUE or   INTPAR or
      47             :     //         function name     DOUBLE      STDPAR     # of param  category
      48             :     FUNCDATA( Workday,          UNIQUE,     INTPAR,     3,          FDCat_DateTime ),
      49             :     FUNCDATA( Yearfrac,         UNIQUE,     INTPAR,     3,          FDCat_DateTime ),
      50             :     FUNCDATA( Edate,            UNIQUE,     INTPAR,     2,          FDCat_DateTime ),
      51             :     FUNCDATA( Weeknum,          DOUBLE,     INTPAR,     2,          FDCat_DateTime ),
      52             :     FUNCDATA( Eomonth,          UNIQUE,     INTPAR,     2,          FDCat_DateTime ),
      53             :     FUNCDATA( Networkdays,      UNIQUE,     INTPAR,     3,          FDCat_DateTime ),
      54             :     FUNCDATA( Iseven,           DOUBLE,     STDPAR,     1,          FDCat_Inf ),
      55             :     FUNCDATA( Isodd,            DOUBLE,     STDPAR,     1,          FDCat_Inf ),
      56             :     FUNCDATA( Multinomial,      UNIQUE,     STDPAR,     1,          FDCat_Math ),
      57             :     FUNCDATA( Seriessum,        UNIQUE,     STDPAR,     4,          FDCat_Math ),
      58             :     FUNCDATA( Quotient,         UNIQUE,     STDPAR,     2,          FDCat_Math ),
      59             :     FUNCDATA( Mround,           UNIQUE,     STDPAR,     2,          FDCat_Math ),
      60             :     FUNCDATA( Sqrtpi,           UNIQUE,     STDPAR,     1,          FDCat_Math ),
      61             :     FUNCDATA( Randbetween,      UNIQUE,     STDPAR,     2,          FDCat_Math ),
      62             :     FUNCDATA( Gcd,              DOUBLE,     INTPAR,     1,          FDCat_Math ),
      63             :     FUNCDATA( Lcm,              DOUBLE,     INTPAR,     1,          FDCat_Math ),
      64             :     FUNCDATA( Besseli,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
      65             :     FUNCDATA( Besselj,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
      66             :     FUNCDATA( Besselk,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
      67             :     FUNCDATA( Bessely,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
      68             :     FUNCDATA( Bin2Oct,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      69             :     FUNCDATA( Bin2Dec,          UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      70             :     FUNCDATA( Bin2Hex,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      71             :     FUNCDATA( Oct2Bin,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      72             :     FUNCDATA( Oct2Dec,          UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      73             :     FUNCDATA( Oct2Hex,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      74             :     FUNCDATA( Dec2Bin,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      75             :     FUNCDATA( Dec2Hex,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      76             :     FUNCDATA( Dec2Oct,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      77             :     FUNCDATA( Hex2Bin,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      78             :     FUNCDATA( Hex2Dec,          UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      79             :     FUNCDATA( Hex2Oct,          UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      80             :     FUNCDATA( Delta,            UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      81             :     FUNCDATA( Erf,              UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      82             :     FUNCDATA( Erfc,             UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      83             :     FUNCDATA( Gestep,           UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      84             :     FUNCDATA( Factdouble,       UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      85             :     FUNCDATA( Imabs,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      86             :     FUNCDATA( Imaginary,        UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      87             :     FUNCDATA( Impower,          UNIQUE,     STDPAR,     2,          FDCat_Tech ),
      88             :     FUNCDATA( Imargument,       UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      89             :     FUNCDATA( Imcos,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      90             :     FUNCDATA( Imdiv,            UNIQUE,     STDPAR,     2,          FDCat_Tech ),
      91             :     FUNCDATA( Imexp,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      92             :     FUNCDATA( Imconjugate,      UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      93             :     FUNCDATA( Imln,             UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      94             :     FUNCDATA( Imlog10,          UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      95             :     FUNCDATA( Imlog2,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      96             :     FUNCDATA( Improduct,        UNIQUE,     INTPAR,     2,          FDCat_Tech ),
      97             :     FUNCDATA( Imreal,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      98             :     FUNCDATA( Imsin,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
      99             :     FUNCDATA( Imsub,            UNIQUE,     STDPAR,     2,          FDCat_Tech ),
     100             :     FUNCDATA( Imsqrt,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
     101             :     FUNCDATA( Imsum,            UNIQUE,     INTPAR,     1,          FDCat_Tech ),
     102             :     FUNCDATA( Imtan,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
     103             :     FUNCDATA( Imsec,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
     104             :     FUNCDATA( Imcsc,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
     105             :     FUNCDATA( Imcot,            UNIQUE,     STDPAR,     1,          FDCat_Tech ),
     106             :     FUNCDATA( Imsinh,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
     107             :     FUNCDATA( Imcosh,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
     108             :     FUNCDATA( Imsech,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
     109             :     FUNCDATA( Imcsch,           UNIQUE,     STDPAR,     1,          FDCat_Tech ),
     110             :     FUNCDATA( Complex,          UNIQUE,     STDPAR,     3,          FDCat_Tech ),
     111             :     FUNCDATA( Convert,          DOUBLE,     STDPAR,     3,          FDCat_Tech ),
     112             :     FUNCDATA( Amordegrc,        UNIQUE,     INTPAR,     7,          FDCat_Finance ),
     113             :     FUNCDATA( Amorlinc,         UNIQUE,     INTPAR,     7,          FDCat_Finance ),
     114             :     FUNCDATA( Accrint,          UNIQUE,     INTPAR,     7,          FDCat_Finance ),
     115             :     FUNCDATA( Accrintm,         UNIQUE,     INTPAR,     5,          FDCat_Finance ),
     116             :     FUNCDATA( Received,         UNIQUE,     INTPAR,     5,          FDCat_Finance ),
     117             :     FUNCDATA( Disc,             UNIQUE,     INTPAR,     5,          FDCat_Finance ),
     118             :     FUNCDATA( Duration,         DOUBLE,     INTPAR,     6,          FDCat_Finance ),
     119             :     FUNCDATA( Effect,           DOUBLE,     STDPAR,     2,          FDCat_Finance ),
     120             :     FUNCDATA( Cumprinc,         DOUBLE,     STDPAR,     6,          FDCat_Finance ),
     121             :     FUNCDATA( Cumipmt,          DOUBLE,     STDPAR,     6,          FDCat_Finance ),
     122             :     FUNCDATA( Price,            UNIQUE,     INTPAR,     7,          FDCat_Finance ),
     123             :     FUNCDATA( Pricedisc,        UNIQUE,     INTPAR,     5,          FDCat_Finance ),
     124             :     FUNCDATA( Pricemat,         UNIQUE,     INTPAR,     6,          FDCat_Finance ),
     125             :     FUNCDATA( Mduration,        UNIQUE,     INTPAR,     6,          FDCat_Finance ),
     126             :     FUNCDATA( Nominal,          DOUBLE,     STDPAR,     2,          FDCat_Finance ),
     127             :     FUNCDATA( Dollarfr,         UNIQUE,     STDPAR,     2,          FDCat_Finance ),
     128             :     FUNCDATA( Dollarde,         UNIQUE,     STDPAR,     2,          FDCat_Finance ),
     129             :     FUNCDATA( Yield,            UNIQUE,     INTPAR,     7,          FDCat_Finance ),
     130             :     FUNCDATA( Yielddisc,        UNIQUE,     INTPAR,     5,          FDCat_Finance ),
     131             :     FUNCDATA( Yieldmat,         UNIQUE,     INTPAR,     6,          FDCat_Finance ),
     132             :     FUNCDATA( Tbilleq,          UNIQUE,     INTPAR,     3,          FDCat_Finance ),
     133             :     FUNCDATA( Tbillprice,       UNIQUE,     INTPAR,     3,          FDCat_Finance ),
     134             :     FUNCDATA( Tbillyield,       UNIQUE,     INTPAR,     3,          FDCat_Finance ),
     135             :     FUNCDATA( Oddfprice,        UNIQUE,     INTPAR,     9,          FDCat_Finance ),
     136             :     FUNCDATA( Oddfyield,        UNIQUE,     INTPAR,     9,          FDCat_Finance ),
     137             :     FUNCDATA( Oddlprice,        UNIQUE,     INTPAR,     8,          FDCat_Finance ),
     138             :     FUNCDATA( Oddlyield,        UNIQUE,     INTPAR,     8,          FDCat_Finance ),
     139             :     FUNCDATA( Xirr,             UNIQUE,     INTPAR,     3,          FDCat_Finance ),
     140             :     FUNCDATA( Xnpv,             UNIQUE,     STDPAR,     3,          FDCat_Finance ),
     141             :     FUNCDATA( Intrate,          UNIQUE,     INTPAR,     5,          FDCat_Finance ),
     142             :     FUNCDATA( Coupncd,          UNIQUE,     INTPAR,     4,          FDCat_Finance ),
     143             :     FUNCDATA( Coupdays,         UNIQUE,     INTPAR,     4,          FDCat_Finance ),
     144             :     FUNCDATA( Coupdaysnc,       UNIQUE,     INTPAR,     4,          FDCat_Finance ),
     145             :     FUNCDATA( Coupdaybs,        UNIQUE,     INTPAR,     4,          FDCat_Finance ),
     146             :     FUNCDATA( Couppcd,          UNIQUE,     INTPAR,     4,          FDCat_Finance ),
     147             :     FUNCDATA( Coupnum,          UNIQUE,     INTPAR,     4,          FDCat_Finance ),
     148             :     FUNCDATA( Fvschedule,       UNIQUE,     STDPAR,     2,          FDCat_Finance )
     149             : };
     150             : #undef FUNCDATA
     151             : 
     152             : 
     153           0 : sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
     154             : {
     155           0 :     if( (nMonth == 2) && IsLeapYear( nYear ) )
     156           0 :         return 29;
     157             :     static const sal_uInt16 aDaysInMonth[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
     158           0 :     return aDaysInMonth[ nMonth ];
     159             : }
     160             : 
     161             : 
     162             : /**
     163             :  * Convert a date to a count of days starting from 01/01/0001
     164             :  *
     165             :  * The internal representation of a Date used in this Addin
     166             :  * is the number of days between 01/01/0001 and the date
     167             :  * this function converts a Day , Month, Year representation
     168             :  * to this internal Date value.
     169             :  *
     170             :  */
     171             : 
     172           0 : sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
     173             : {
     174           0 :     sal_Int32 nDays = ((sal_Int32)nYear-1) * 365;
     175           0 :     nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
     176             : 
     177           0 :     for( sal_uInt16 i = 1; i < nMonth; i++ )
     178           0 :         nDays += DaysInMonth(i,nYear);
     179           0 :     nDays += nDay;
     180             : 
     181           0 :     return nDays;
     182             : }
     183             : 
     184             : 
     185             : /**
     186             :  * Convert a count of days starting from 01/01/0001 to a date
     187             :  *
     188             :  * The internal representation of a Date used in this Addin
     189             :  * is the number of days between 01/01/0001 and the date
     190             :  * this function converts this internal Date value
     191             :  * to a Day , Month, Year representation of a Date.
     192             :  *
     193             :  */
     194             : 
     195           0 : void DaysToDate( sal_Int32 nDays, sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear )
     196             :     throw( lang::IllegalArgumentException )
     197             : {
     198           0 :     if( nDays < 0 )
     199           0 :         throw lang::IllegalArgumentException();
     200             : 
     201             :     sal_Int32   nTempDays;
     202           0 :     sal_Int32   i = 0;
     203             :     sal_Bool    bCalc;
     204             : 
     205           0 :     do
     206             :     {
     207           0 :         nTempDays = nDays;
     208           0 :         rYear = (sal_uInt16)((nTempDays / 365) - i);
     209           0 :         nTempDays -= ((sal_Int32) rYear -1) * 365;
     210           0 :         nTempDays -= (( rYear -1) / 4) - (( rYear -1) / 100) + ((rYear -1) / 400);
     211           0 :         bCalc = sal_False;
     212           0 :         if ( nTempDays < 1 )
     213             :         {
     214           0 :             i++;
     215           0 :             bCalc = sal_True;
     216             :         }
     217             :         else
     218             :         {
     219           0 :             if ( nTempDays > 365 )
     220             :             {
     221           0 :                 if ( (nTempDays != 366) || !IsLeapYear( rYear ) )
     222             :                 {
     223           0 :                     i--;
     224           0 :                     bCalc = sal_True;
     225             :                 }
     226             :             }
     227             :         }
     228             :     }
     229             :     while ( bCalc );
     230             : 
     231           0 :     rMonth = 1;
     232           0 :     while ( (sal_Int32)nTempDays > DaysInMonth( rMonth, rYear ) )
     233             :     {
     234           0 :         nTempDays -= DaysInMonth( rMonth, rYear );
     235           0 :         rMonth++;
     236             :     }
     237           0 :     rDay = (sal_uInt16)nTempDays;
     238           0 : }
     239             : 
     240             : 
     241             : /**
     242             :  * Get the null date used by the spreadsheet document
     243             :  *
     244             :  * The internal representation of a Date used in this Addin
     245             :  * is the number of days between 01/01/0001 and the date
     246             :  * this function returns this internal Date value for the document null date
     247             :  *
     248             :  */
     249             : 
     250           0 : sal_Int32 GetNullDate( const uno::Reference< beans::XPropertySet >& xOpt ) throw( uno::RuntimeException )
     251             : {
     252           0 :     if( xOpt.is() )
     253             :     {
     254             :         try
     255             :         {
     256           0 :             uno::Any aAny = xOpt->getPropertyValue( "NullDate" );
     257           0 :             util::Date  aDate;
     258           0 :             if( aAny >>= aDate )
     259           0 :                 return DateToDays( aDate.Day, aDate.Month, aDate.Year );
     260             :         }
     261           0 :         catch( uno::Exception& )
     262             :         {
     263             :         }
     264             :     }
     265             : 
     266             :     // no null date available -> no calculations possible
     267           0 :     throw uno::RuntimeException();
     268             : }
     269             : 
     270             : 
     271           0 : sal_Int32 GetDiffDate360(
     272             :                 sal_uInt16 nDay1, sal_uInt16 nMonth1, sal_uInt16 nYear1, sal_Bool bLeapYear1,
     273             :                 sal_uInt16 nDay2, sal_uInt16 nMonth2, sal_uInt16 nYear2,
     274             :                 sal_Bool bUSAMethod )
     275             : {
     276           0 :     if( nDay1 == 31 )
     277           0 :         nDay1--;
     278           0 :     else if( bUSAMethod && ( nMonth1 == 2 && ( nDay1 == 29 || ( nDay1 == 28 && !bLeapYear1 ) ) ) )
     279           0 :             nDay1 = 30;
     280             : 
     281           0 :     if( nDay2 == 31 )
     282             :     {
     283           0 :         if( bUSAMethod && nDay1 != 30 )
     284             :         {
     285           0 :             nDay2 = 1;
     286           0 :             if( nMonth2 == 12 )
     287             :             {
     288           0 :                 nYear2++;
     289           0 :                 nMonth2 = 1;
     290             :             }
     291             :             else
     292           0 :                 nMonth2++;
     293             :         }
     294             :         else
     295           0 :             nDay2 = 30;
     296             :     }
     297             : 
     298           0 :     return nDay2 + nMonth2 * 30 + nYear2 * 360 - nDay1 - nMonth1 * 30 - nYear1 * 360;
     299             : }
     300             : 
     301             : 
     302           0 : sal_Int32 GetDiffDate360( sal_Int32 nNullDate, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod )
     303             : {
     304           0 :     nDate1 += nNullDate;
     305           0 :     nDate2 += nNullDate;
     306             : 
     307             :     sal_uInt16 nDay1, nMonth1, nYear1, nDay2, nMonth2, nYear2;
     308             : 
     309           0 :     DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
     310           0 :     DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
     311             : 
     312           0 :     return GetDiffDate360( nDay1, nMonth1, nYear1, IsLeapYear( nYear1 ), nDay2, nMonth2, nYear2, bUSAMethod );
     313             : }
     314             : 
     315             : 
     316           0 : sal_Int32 GetDaysInYears( sal_uInt16 nYear1, sal_uInt16 nYear2 )
     317             : {
     318           0 :     sal_uInt16  nLeaps = 0;
     319           0 :     for( sal_uInt16 n = nYear1 ; n <= nYear2 ; n++ )
     320             :     {
     321           0 :         if( IsLeapYear( n ) )
     322           0 :             nLeaps++;
     323             :     }
     324             : 
     325           0 :     sal_uInt32  nSum = 1;
     326           0 :     nSum += nYear2;
     327           0 :     nSum -= nYear1;
     328           0 :     nSum *= 365;
     329           0 :     nSum += nLeaps;
     330             : 
     331           0 :     return nSum;
     332             : }
     333             : 
     334             : 
     335           0 : sal_Int32 GetDiffDate( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
     336             :     sal_Int32* pOptDaysIn1stYear ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     337             : {
     338           0 :     sal_Bool    bNeg = nStartDate > nEndDate;
     339             : 
     340           0 :     if( bNeg )
     341             :     {
     342           0 :         sal_Int32   n = nEndDate;
     343           0 :         nEndDate = nStartDate;
     344           0 :         nStartDate = n;
     345             :     }
     346             : 
     347             :     sal_Int32       nRet;
     348             : 
     349           0 :     switch( nMode )
     350             :     {
     351             :         case 0:         // 0=USA (NASD) 30/360
     352             :         case 4:         // 4=Europe 30/360
     353             :             {
     354             :             sal_uInt16      nD1, nM1, nY1, nD2, nM2, nY2;
     355             : 
     356           0 :             nStartDate += nNullDate;
     357           0 :             nEndDate += nNullDate;
     358             : 
     359           0 :             DaysToDate( nStartDate, nD1, nM1, nY1 );
     360           0 :             DaysToDate( nEndDate, nD2, nM2, nY2 );
     361             : 
     362           0 :             sal_Bool        bLeap = IsLeapYear( nY1 );
     363             :             sal_Int32       nDays, nMonths;
     364             : 
     365           0 :             nMonths = nM2 - nM1;
     366           0 :             nDays = nD2 - nD1;
     367             : 
     368           0 :             nMonths += ( nY2 - nY1 ) * 12;
     369             : 
     370           0 :             nRet = nMonths * 30 + nDays;
     371           0 :             if( nMode == 0 && nM1 == 2 && nM2 != 2 && nY1 == nY2 )
     372           0 :                 nRet -= bLeap? 1 : 2;
     373             : 
     374           0 :             if( pOptDaysIn1stYear )
     375           0 :                 *pOptDaysIn1stYear = 360;
     376             :             }
     377           0 :             break;
     378             :         case 1:         // 1=exact/exact
     379           0 :             if( pOptDaysIn1stYear )
     380             :             {
     381             :                 sal_uInt16      nD, nM, nY;
     382             : 
     383           0 :                 DaysToDate( nStartDate + nNullDate, nD, nM, nY );
     384             : 
     385           0 :                 *pOptDaysIn1stYear = IsLeapYear( nY )? 366 : 365;
     386             :             }
     387           0 :             nRet = nEndDate - nStartDate;
     388           0 :             break;
     389             :         case 2:         // 2=exact/360
     390           0 :             nRet = nEndDate - nStartDate;
     391           0 :             if( pOptDaysIn1stYear )
     392           0 :                 *pOptDaysIn1stYear = 360;
     393           0 :             break;
     394             :         case 3:         //3=exact/365
     395           0 :             nRet = nEndDate - nStartDate;
     396           0 :             if( pOptDaysIn1stYear )
     397           0 :                 *pOptDaysIn1stYear = 365;
     398           0 :             break;
     399             :         default:
     400           0 :             throw lang::IllegalArgumentException();
     401             :     }
     402             : 
     403           0 :     return bNeg? -nRet : nRet;
     404             : }
     405             : 
     406             : 
     407           0 : double GetYearDiff( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     408             : {
     409             :     sal_Int32   nDays1stYear;
     410           0 :     sal_Int32   nTotalDays = GetDiffDate( nNullDate, nStartDate, nEndDate, nMode, &nDays1stYear );
     411             : 
     412           0 :     return double( nTotalDays ) / double( nDays1stYear );
     413             : }
     414             : 
     415             : 
     416           0 : sal_Int32 GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     417             : {
     418           0 :     switch( nMode )
     419             :     {
     420             :         case 0:         // 0=USA (NASD) 30/360
     421             :         case 2:         // 2=exact/360
     422             :         case 4:         // 4=Europe 30/360
     423           0 :             return 360;
     424             :         case 1:         // 1=exact/exact
     425             :             {
     426             :             sal_uInt16  nD, nM, nY;
     427           0 :             nDate += nNullDate;
     428           0 :             DaysToDate( nDate, nD, nM, nY );
     429           0 :             return IsLeapYear( nY )? 366 : 365;
     430             :             }
     431             :         case 3:         //3=exact/365
     432           0 :             return 365;
     433             :         default:
     434           0 :             throw lang::IllegalArgumentException();
     435             :     }
     436             : }
     437             : 
     438             : 
     439             : //fdo40100 toDo: make function fully compliant with ODFF1.2
     440             : /**
     441             :  * Function GetYearFrac implements YEARFRAC as defined in:
     442             :  *   Open Document Format for Office Applications version 1.2 Part 2, par. 6.10.24
     443             :  *   The calculations are defined in:
     444             :  *   Open Document Format for Office Applications version 1.2 Part 2, par. 4.11.7
     445             :  */
     446           0 : double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     447             : {
     448           0 :     if( nStartDate == nEndDate )
     449           0 :         return 0.0;     // nothing to do...
     450             : 
     451           0 :     if( nStartDate > nEndDate )
     452             :     {
     453           0 :         sal_Int32   n = nEndDate;
     454           0 :         nEndDate = nStartDate;
     455           0 :         nStartDate = n;
     456             :     }
     457             : 
     458           0 :     sal_Int32 nDate1 = nStartDate + nNullDate;
     459           0 :     sal_Int32 nDate2 = nEndDate + nNullDate;
     460             : 
     461             :     sal_uInt16  nDay1, nDay2;
     462             :     sal_uInt16  nMonth1, nMonth2;
     463             :     sal_uInt16  nYear1, nYear2;
     464             : 
     465           0 :     DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
     466           0 :     DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
     467             : 
     468             :     // calculate days between nDate1 and nDate2
     469             :     sal_Int32 nDayDiff;
     470           0 :     switch( nMode )
     471             :     {
     472             :         case 0:         // 0=USA (NASD) 30/360
     473           0 :             if ( nDay1 == 31 )
     474             :             {
     475           0 :                 nDay1--;
     476             :             }
     477           0 :             if ( nDay1 == 30 && nDay2 == 31 )
     478             :             {
     479           0 :                 nDay2--;
     480             :             }
     481             :             else
     482             :             {
     483           0 :                 if ( nMonth1 == 2 && nDay1 == ( IsLeapYear( nYear1 ) ? 29 : 28 ) )
     484             :                 {
     485           0 :                     nDay1 = 30;
     486           0 :                     if ( nMonth2 == 2 && nDay2 == ( IsLeapYear( nYear2 ) ? 29 : 28 ) )
     487             :                     {
     488           0 :                         nDay2 = 30;
     489             :                     }
     490             :                 }
     491             :             }
     492           0 :             nDayDiff = ( nYear2 - nYear1 ) * 360 + ( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );
     493           0 :             break;
     494             :         case 1:         // 1=exact/exact
     495             :         case 2:         // 2=exact/360
     496             :         case 3:         // 3=exact/365
     497           0 :             nDayDiff = nDate2 - nDate1;
     498           0 :             break;
     499             :         case 4:         // 4=Europe 30/360
     500           0 :             if ( nDay1 == 31 )
     501             :             {
     502           0 :                 nDay1--;
     503             :             }
     504           0 :             if ( nDay2 == 31 )
     505             :             {
     506           0 :                 nDay2--;
     507             :             }
     508           0 :             nDayDiff = ( nYear2 - nYear1 ) * 360 + ( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );
     509           0 :             break;
     510             :         default:
     511           0 :             throw lang::IllegalArgumentException();
     512             :     }
     513             : 
     514             :     //calculate days in year
     515             :     double nDaysInYear;
     516           0 :     switch( nMode )
     517             :     {
     518             :         case 0:         // 0=USA (NASD) 30/360
     519             :         case 2:         // 2=exact/360
     520             :         case 4:         // 4=Europe 30/360
     521           0 :             nDaysInYear = 360;
     522           0 :             break;
     523             :         case 1:         // 1=exact/exact
     524             :             {
     525           0 :                 bool isYearDifferent = ( nYear1 != nYear2 );
     526           0 :                 if ( isYearDifferent &&
     527           0 :                      ( ( nYear2 != nYear1 + 1 ) ||
     528           0 :                        ( nMonth1 < nMonth2 ) ||
     529           0 :                        ( nMonth1 == nMonth2 && nDay1 < nDay2 ) ) )
     530             :                 {
     531             :                     // return average of days in year between nDate1 and nDate2, inclusive
     532           0 :                     sal_Int32 nDayCount = 0;
     533           0 :                     for ( sal_Int16 i = nYear1; i <= nYear2; i++ )
     534           0 :                         nDayCount += ( IsLeapYear( i ) ? 366 : 365 );
     535             : 
     536           0 :                     nDaysInYear = ( double ) nDayCount / ( double ) ( nYear2 - nYear1 + 1 );
     537             :                 }
     538             :                 else
     539             :                 {
     540           0 :                     if ( isYearDifferent && IsLeapYear( nYear1 ) )
     541             :                     {
     542           0 :                         nDaysInYear = 366;
     543             :                     }
     544             :                     else
     545             :                     {
     546             :                         //if Feb 29 is between nDate1 and ndate2, inclusive
     547           0 :                         if ( ( IsLeapYear( nYear1 ) && nMonth1 <= 2 && nDay1 <= 29 ) ||
     548           0 :                              ( IsLeapYear( nYear2 ) && ( nMonth2 > 3 || ( nMonth2 == 2 && nDay1 == 29 ) ) ) )
     549             :                         {
     550           0 :                             nDaysInYear = 366;
     551             :                         }
     552             :                         else
     553             :                         {
     554           0 :                             nDaysInYear = 365;
     555           0 :                             for ( sal_Int16 i = nYear1; i <= nYear2; i++ )
     556             :                             {
     557           0 :                                 if ( IsLeapYear( i ) )
     558             :                                 {
     559           0 :                                     nDaysInYear = 366;
     560           0 :                                     break;
     561             :                                 }
     562             :                             }
     563             :                         }
     564             :                     }
     565             :                 }
     566             :             }
     567           0 :             break;
     568             :         case 3:         // 3=exact/365
     569           0 :             nDaysInYear = 365;
     570           0 :             break;
     571             :         default:
     572           0 :             throw lang::IllegalArgumentException();
     573             :     }
     574             : 
     575           0 :     return double( nDayDiff ) / nDaysInYear;
     576             : }
     577             : 
     578           0 : double BinomialCoefficient( double n, double k )
     579             : {
     580             :     // This method is a copy of BinomKoeff()
     581             :     // found in sc/source/core/tool/interpr3.cxx
     582             : 
     583           0 :     double nVal = 0.0;
     584           0 :     k = ::rtl::math::approxFloor(k);
     585           0 :     if (n < k)
     586           0 :         nVal = 0.0;
     587           0 :     else if (k == 0.0)
     588           0 :         nVal = 1.0;
     589             :     else
     590             :     {
     591           0 :         nVal = n/k;
     592           0 :         n--;
     593           0 :         k--;
     594           0 :         while (k > 0.0)
     595             :         {
     596           0 :             nVal *= n/k;
     597           0 :             k--;
     598           0 :             n--;
     599             :         }
     600             :     }
     601           0 :     return nVal;
     602             : }
     603             : 
     604           0 : double GetGcd( double f1, double f2 )
     605             : {
     606           0 :     double  f = fmod( f1, f2 );
     607           0 :     while( f > 0.0 )
     608             :     {
     609           0 :         f1 = f2;
     610           0 :         f2 = f;
     611           0 :         f = fmod( f1, f2 );
     612             :     }
     613             : 
     614           0 :     return f2;
     615             : }
     616             : 
     617             : 
     618           0 : double ConvertToDec( const OUString& aStr, sal_uInt16 nBase, sal_uInt16 nCharLim ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     619             : {
     620           0 :     if ( nBase < 2 || nBase > 36 )
     621           0 :         throw lang::IllegalArgumentException();
     622             : 
     623           0 :     sal_uInt32      nStrLen = aStr.getLength();
     624           0 :     if( nStrLen > nCharLim )
     625           0 :         throw lang::IllegalArgumentException();
     626           0 :     else if( !nStrLen )
     627           0 :         return 0.0;
     628             : 
     629           0 :     double          fVal = 0.0;
     630             : 
     631           0 :     register const sal_Unicode* p = aStr.getStr();
     632             : 
     633           0 :     sal_uInt16          nFirstDig = 0;
     634           0 :     sal_Bool            bFirstDig = sal_True;
     635           0 :     double              fBase = nBase;
     636             : 
     637           0 :     while ( *p )
     638             :     {
     639             :         sal_uInt16      n;
     640             : 
     641           0 :         if( '0' <= *p && *p <= '9' )
     642           0 :             n = *p - '0';
     643           0 :         else if( 'A' <= *p && *p <= 'Z' )
     644           0 :             n = 10 + ( *p - 'A' );
     645           0 :         else if ( 'a' <= *p && *p <= 'z' )
     646           0 :             n = 10 + ( *p - 'a' );
     647             :         else
     648           0 :             n = nBase;
     649             : 
     650           0 :         if( n < nBase )
     651             :         {
     652           0 :             if( bFirstDig )
     653             :             {
     654           0 :                 bFirstDig = sal_False;
     655           0 :                 nFirstDig = n;
     656             :             }
     657           0 :             fVal = fVal * fBase + double( n );
     658             :         }
     659             :         else
     660             :             // illegal char!
     661           0 :             throw lang::IllegalArgumentException();
     662             : 
     663           0 :         p++;
     664             : 
     665             :     }
     666             : 
     667           0 :     if( nStrLen == nCharLim && !bFirstDig && (nFirstDig >= nBase / 2) )
     668             :     {   // handling negativ values
     669           0 :         fVal = ( pow( double( nBase ), double( nCharLim ) ) - fVal );   // complement
     670           0 :         fVal *= -1.0;
     671             :     }
     672             : 
     673           0 :     return fVal;
     674             : }
     675             : 
     676             : 
     677           0 : static inline sal_Char GetMaxChar( sal_uInt16 nBase )
     678             : {
     679           0 :     const sal_Char* c = "--123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     680           0 :     return c[ nBase ];
     681             : }
     682             : 
     683             : 
     684           0 : OUString ConvertFromDec( double fNum, double fMin, double fMax, sal_uInt16 nBase,
     685             :     sal_Int32 nPlaces, sal_Int32 nMaxPlaces, sal_Bool bUsePlaces ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     686             : {
     687           0 :     fNum = ::rtl::math::approxFloor( fNum );
     688           0 :     fMin = ::rtl::math::approxFloor( fMin );
     689           0 :     fMax = ::rtl::math::approxFloor( fMax );
     690             : 
     691           0 :     if( fNum < fMin || fNum > fMax || ( bUsePlaces && ( nPlaces <= 0 || nPlaces > nMaxPlaces ) ) )
     692           0 :         throw lang::IllegalArgumentException();
     693             : 
     694           0 :     sal_Int64 nNum = static_cast< sal_Int64 >( fNum );
     695           0 :     sal_Bool        bNeg = nNum < 0;
     696           0 :     if( bNeg )
     697           0 :         nNum = sal_Int64( pow( double( nBase ), double( nMaxPlaces ) ) ) + nNum;
     698             : 
     699           0 :     OUString          aRet( OUString::valueOf( nNum, nBase ).toAsciiUpperCase() );
     700             : 
     701             : 
     702           0 :     if( bUsePlaces )
     703             :     {
     704           0 :         sal_Int32 nLen = aRet.getLength();
     705           0 :         if( !bNeg && nLen > nPlaces )
     706             :         {
     707           0 :             throw lang::IllegalArgumentException();
     708             :         }
     709           0 :         else if( ( bNeg && nLen < nMaxPlaces ) || ( !bNeg && nLen < nPlaces ) )
     710             :         {
     711           0 :             sal_Int32   nLeft = nPlaces - nLen;
     712           0 :             sal_Char*   p = new sal_Char[ nLeft + 1 ];
     713           0 :             memset( p, bNeg? GetMaxChar( nBase ) : '0', nLeft );
     714           0 :             p[ nLeft ] = 0x00;
     715           0 :             OUString  aTmp( p, nLeft, RTL_TEXTENCODING_MS_1252 );
     716           0 :             aTmp += aRet;
     717           0 :             aRet = aTmp;
     718             : 
     719           0 :             delete[] p;
     720             :         }
     721             :     }
     722             : 
     723           0 :     return aRet;
     724             : }
     725             : 
     726             : // implementation moved to module sal, see #i97091#
     727           0 : double Erf( double x )
     728             : {
     729           0 :     return ::rtl::math::erf(x);
     730             : }
     731             : 
     732             : // implementation moved to module sal, see #i97091#
     733           0 : double Erfc( double x )
     734             : {
     735           0 :     return ::rtl::math::erfc(x);
     736             : }
     737             : 
     738           0 : inline sal_Bool IsNum( sal_Unicode c )
     739             : {
     740           0 :     return c >= '0' && c <= '9';
     741             : }
     742             : 
     743             : 
     744           0 : inline sal_Bool IsComma( sal_Unicode c )
     745             : {
     746           0 :     return c == '.' || c == ',';
     747             : }
     748             : 
     749             : 
     750           0 : inline sal_Bool IsExpStart( sal_Unicode c )
     751             : {
     752           0 :     return c == 'e' || c == 'E';
     753             : }
     754             : 
     755             : 
     756           0 : inline sal_Bool IsImagUnit( sal_Unicode c )
     757             : {
     758           0 :     return c == 'i' || c == 'j';
     759             : }
     760             : 
     761             : 
     762           0 : inline sal_uInt16 GetVal( sal_Unicode c )
     763             : {
     764           0 :     return sal_uInt16( c - '0' );
     765             : }
     766             : 
     767             : 
     768           0 : sal_Bool ParseDouble( const sal_Unicode*& rp, double& rRet )
     769             : {
     770           0 :     double              fInt = 0.0;
     771           0 :     double              fFrac = 0.0;
     772           0 :     double              fMult = 0.1;    // multiplier to multiply digits with, when adding fractional ones
     773           0 :     sal_Int32           nExp = 0;
     774           0 :     sal_Int32           nMaxExp = 307;
     775           0 :     sal_uInt16          nDigCnt = 18;   // max. number of digits to read in, rest doesn't matter
     776             : 
     777             :     enum State  { S_End = 0, S_Sign, S_IntStart, S_Int, S_IgnoreIntDigs, S_Frac, S_IgnoreFracDigs, S_ExpSign, S_Exp };
     778             : 
     779           0 :     State           eS = S_Sign;
     780             : 
     781           0 :     sal_Bool            bNegNum = sal_False;
     782           0 :     sal_Bool            bNegExp = sal_False;
     783             : 
     784           0 :     const sal_Unicode*  p = rp;
     785             :     sal_Unicode         c;
     786             : 
     787           0 :     while( eS )
     788             :     {
     789           0 :         c = *p;
     790           0 :         switch( eS )
     791             :         {
     792             :             case S_Sign:
     793           0 :                 if( IsNum( c ) )
     794             :                 {
     795           0 :                     fInt = GetVal( c );
     796           0 :                     nDigCnt--;
     797           0 :                     eS = S_Int;
     798             :                 }
     799           0 :                 else if( c == '-' )
     800             :                 {
     801           0 :                     bNegNum = sal_True;
     802           0 :                     eS = S_IntStart;
     803             :                 }
     804           0 :                 else if( c == '+' )
     805           0 :                     eS = S_IntStart;
     806           0 :                 else if( IsComma( c ) )
     807           0 :                     eS = S_Frac;
     808             :                 else
     809           0 :                     return sal_False;
     810           0 :                 break;
     811             :             case S_IntStart:
     812           0 :                 if( IsNum( c ) )
     813             :                 {
     814           0 :                     fInt = GetVal( c );
     815           0 :                     nDigCnt--;
     816           0 :                     eS = S_Int;
     817             :                 }
     818           0 :                 else if( IsComma( c ) )
     819           0 :                     eS = S_Frac;
     820           0 :                 else if( IsImagUnit( c ) )
     821             :                 {
     822           0 :                     rRet = 0.0;
     823           0 :                     return sal_True;
     824             :                 }
     825             :                 else
     826           0 :                     return sal_False;
     827           0 :                 break;
     828             :             case S_Int:
     829           0 :                 if( IsNum( c ) )
     830             :                 {
     831           0 :                     fInt *= 10.0;
     832           0 :                     fInt += double( GetVal( c ) );
     833           0 :                     nDigCnt--;
     834           0 :                     if( !nDigCnt )
     835           0 :                         eS = S_IgnoreIntDigs;
     836             :                 }
     837           0 :                 else if( IsComma( c ) )
     838           0 :                     eS = S_Frac;
     839           0 :                 else if( IsExpStart( c ) )
     840           0 :                     eS = S_ExpSign;
     841             :                 else
     842           0 :                     eS = S_End;
     843           0 :                 break;
     844             :             case S_IgnoreIntDigs:
     845           0 :                 if( IsNum( c ) )
     846           0 :                     nExp++;         // just multiply num with 10... ;-)
     847           0 :                 else if( IsComma( c ) )
     848           0 :                     eS = S_Frac;
     849           0 :                 else if( IsExpStart( c ) )
     850           0 :                     eS = S_ExpSign;
     851             :                 else
     852           0 :                     eS = S_End;
     853           0 :                 break;
     854             :             case S_Frac:
     855           0 :                 if( IsNum( c ) )
     856             :                 {
     857           0 :                     fFrac += double( GetVal( c ) ) * fMult;
     858           0 :                     nDigCnt--;
     859           0 :                     if( nDigCnt )
     860           0 :                         fMult *= 0.1;
     861             :                     else
     862           0 :                         eS = S_IgnoreFracDigs;
     863             :                 }
     864           0 :                 else if( IsExpStart( c ) )
     865           0 :                     eS = S_ExpSign;
     866             :                 else
     867           0 :                     eS = S_End;
     868           0 :                 break;
     869             :             case S_IgnoreFracDigs:
     870           0 :                 if( IsExpStart( c ) )
     871           0 :                     eS = S_ExpSign;
     872           0 :                 else if( !IsNum( c ) )
     873           0 :                     eS = S_End;
     874           0 :                 break;
     875             :             case S_ExpSign:
     876           0 :                 if( IsNum( c ) )
     877             :                 {
     878           0 :                     nExp = GetVal( c );
     879           0 :                     eS = S_Exp;
     880             :                 }
     881           0 :                 else if( c == '-' )
     882             :                 {
     883           0 :                     bNegExp = sal_True;
     884           0 :                     eS = S_Exp;
     885             :                 }
     886           0 :                 else if( c != '+' )
     887           0 :                     eS = S_End;
     888           0 :                 break;
     889             :             case S_Exp:
     890           0 :                 if( IsNum( c ) )
     891             :                 {
     892           0 :                     nExp *= 10;
     893           0 :                     nExp += GetVal( c );
     894           0 :                     if( nExp > nMaxExp )
     895           0 :                         return sal_False;
     896             :                 }
     897             :                 else
     898           0 :                     eS = S_End;
     899           0 :                 break;
     900             :             case S_End:     // to avoid compiler warning
     901           0 :                 break;      // loop exits anyway
     902             :         }
     903             : 
     904           0 :         p++;
     905             :     }
     906             : 
     907           0 :     p--;        // set pointer back to last
     908           0 :     rp = p;
     909             : 
     910           0 :     fInt += fFrac;
     911           0 :     sal_Int32   nLog10 = sal_Int32( log10( fInt ) );
     912             : 
     913           0 :     if( bNegExp )
     914           0 :         nExp = -nExp;
     915             : 
     916           0 :     if( nLog10 + nExp > nMaxExp )
     917           0 :         return sal_False;
     918             : 
     919           0 :     fInt = ::rtl::math::pow10Exp( fInt, nExp );
     920             : 
     921           0 :     if( bNegNum )
     922           0 :         fInt = -fInt;
     923             : 
     924           0 :     rRet = fInt;
     925             : 
     926           0 :     return sal_True;
     927             : }
     928             : 
     929             : 
     930           0 : OUString GetString( double f, sal_Bool bLeadingSign, sal_uInt16 nMaxDig )
     931             : {
     932           0 :     const int       nBuff = 256;
     933             :     sal_Char        aBuff[ nBuff + 1 ];
     934           0 :     const char*     pFormStr = bLeadingSign? "%+.*g" : "%.*g";
     935           0 :     int             nLen = snprintf( aBuff, nBuff, pFormStr, int( nMaxDig ), f );
     936             :                     // you never know which underlying implementation you get ...
     937           0 :                     aBuff[nBuff] = 0;
     938           0 :                     if ( nLen < 0 || nLen > nBuff )
     939           0 :                         nLen = strlen( aBuff );
     940             : 
     941           0 :     OUString          aRet( aBuff, nLen, RTL_TEXTENCODING_MS_1252 );
     942             : 
     943           0 :     return aRet;
     944             : }
     945             : 
     946             : 
     947           0 : double GetAmordegrc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
     948             :     double fRestVal, double fPer, double fRate, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     949             : {
     950           0 :     if( nBase == 2 )
     951           0 :         throw lang::IllegalArgumentException();
     952             : 
     953           0 :     sal_uInt32  nPer = sal_uInt32( fPer );
     954           0 :     double      fUsePer = 1.0 / fRate;
     955             :     double      fAmorCoeff;
     956             : 
     957           0 :     if( fUsePer < 3.0 )
     958           0 :         fAmorCoeff = 1.0;
     959           0 :     else if( fUsePer < 5.0 )
     960           0 :         fAmorCoeff = 1.5;
     961           0 :     else if( fUsePer <= 6.0 )
     962           0 :         fAmorCoeff = 2.0;
     963             :     else
     964           0 :         fAmorCoeff = 2.5;
     965             : 
     966           0 :     fRate *= fAmorCoeff;
     967           0 :     double      fNRate = ::rtl::math::round( GetYearFrac( nNullDate, nDate, nFirstPer, nBase ) * fRate * fCost, 0 );
     968           0 :     fCost -= fNRate;
     969           0 :     double      fRest = fCost - fRestVal;   // Anschaffungskosten - Restwert - Summe aller Abschreibungen
     970             : 
     971           0 :     for( sal_uInt32 n = 0 ; n < nPer ; n++ )
     972             :     {
     973           0 :         fNRate = ::rtl::math::round( fRate * fCost, 0 );
     974           0 :         fRest -= fNRate;
     975             : 
     976           0 :         if( fRest < 0.0 )
     977             :         {
     978           0 :             switch( nPer - n )
     979             :             {
     980             :                 case 0:
     981             :                 case 1:
     982           0 :                     return ::rtl::math::round( fCost * 0.5, 0 );
     983             :                 default:
     984           0 :                     return 0.0;
     985             :             }
     986             :         }
     987             : 
     988           0 :         fCost -= fNRate;
     989             :     }
     990             : 
     991           0 :     return fNRate;
     992             : }
     993             : 
     994             : 
     995           0 : double GetAmorlinc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer,
     996             :     double fRestVal, double fPer, double fRate, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     997             : {
     998           0 :     if( nBase == 2 )
     999           0 :         throw lang::IllegalArgumentException();
    1000             : 
    1001           0 :     sal_uInt32  nPer = sal_uInt32( fPer );
    1002           0 :     double      fOneRate = fCost * fRate;
    1003           0 :     double      fCostDelta = fCost - fRestVal;
    1004           0 :     double      f0Rate = GetYearFrac( nNullDate, nDate, nFirstPer, nBase ) * fRate * fCost;
    1005           0 :     sal_uInt32  nNumOfFullPeriods = sal_uInt32( ( fCost - fRestVal - f0Rate) / fOneRate );
    1006             : 
    1007           0 :     if( nPer == 0 )
    1008           0 :         return f0Rate;
    1009           0 :     else if( nPer <= nNumOfFullPeriods )
    1010           0 :         return fOneRate;
    1011           0 :     else if( nPer == nNumOfFullPeriods + 1 )
    1012           0 :         return fCostDelta - fOneRate * nNumOfFullPeriods - f0Rate;
    1013             :     else
    1014           0 :         return 0.0;
    1015             : }
    1016             : 
    1017             : 
    1018           0 : double GetDuration( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup,
    1019             :     double fYield, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1020             : {
    1021           0 :     double          fYearfrac = GetYearFrac( nNullDate, nSettle, nMat, nBase );
    1022           0 :     double          fNumOfCoups = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase );
    1023           0 :     double          fDur = 0.0;
    1024           0 :     const double    f100 = 100.0;
    1025           0 :     fCoup *= f100 / double( nFreq );    // fCoup is used as cash flow
    1026           0 :     fYield /= nFreq;
    1027           0 :     fYield += 1.0;
    1028             : 
    1029           0 :     double nDiff = fYearfrac * nFreq - fNumOfCoups;
    1030             : 
    1031             :     double          t;
    1032             : 
    1033           0 :     for( t = 1.0 ; t < fNumOfCoups ; t++ )
    1034           0 :         fDur += ( t + nDiff ) * ( fCoup ) / pow( fYield, t + nDiff );
    1035             : 
    1036           0 :     fDur += ( fNumOfCoups + nDiff ) * ( fCoup + f100 ) / pow( fYield, fNumOfCoups + nDiff );
    1037             : 
    1038           0 :     double          p = 0.0;
    1039           0 :     for( t = 1.0 ; t < fNumOfCoups ; t++ )
    1040           0 :         p += fCoup / pow( fYield, t + nDiff );
    1041             : 
    1042           0 :     p += ( fCoup + f100 ) / pow( fYield, fNumOfCoups + nDiff );
    1043             : 
    1044           0 :     fDur /= p;
    1045           0 :     fDur /= double( nFreq );
    1046             : 
    1047           0 :     return fDur;
    1048             : }
    1049             : 
    1050             : 
    1051           0 : double GetYieldmat( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue,
    1052             :     double fRate, double fPrice, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1053             : {
    1054           0 :     double      fIssMat = GetYearFrac( nNullDate, nIssue, nMat, nBase );
    1055           0 :     double      fIssSet = GetYearFrac( nNullDate, nIssue, nSettle, nBase );
    1056           0 :     double      fSetMat = GetYearFrac( nNullDate, nSettle, nMat, nBase );
    1057             : 
    1058           0 :     double      y = 1.0 + fIssMat * fRate;
    1059           0 :     y /= fPrice / 100.0 + fIssSet * fRate;
    1060           0 :     y--;
    1061           0 :     y /= fSetMat;
    1062             : 
    1063           0 :     return y;
    1064             : }
    1065             : 
    1066             : 
    1067           0 : double GetOddfprice( sal_Int32 /*nNullDate*/, sal_Int32 /*nSettle*/, sal_Int32 /*nMat*/, sal_Int32 /*nIssue*/,
    1068             :     sal_Int32 /*nFirstCoup*/, double /*fRate*/, double /*fYield*/, double /*fRedemp*/, sal_Int32 /*nFreq*/,
    1069             :     sal_Int32 /*nBase*/ ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1070             : {
    1071           0 :     throw uno::RuntimeException();  // #87380#
    1072             : }
    1073             : 
    1074             : 
    1075           0 : double getYield_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice,
    1076             :                     double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1077             : {
    1078           0 :     double      fRate = fCoup;
    1079           0 :     double      fPriceN = 0.0;
    1080           0 :     double      fYield1 = 0.0;
    1081           0 :     double      fYield2 = 1.0;
    1082           0 :     double      fPrice1 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield1, fRedemp, nFreq, nBase );
    1083           0 :     double      fPrice2 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield2, fRedemp, nFreq, nBase );
    1084           0 :     double      fYieldN = ( fYield2 - fYield1 ) * 0.5;
    1085             : 
    1086           0 :     for( sal_uInt32 nIter = 0 ; nIter < 100 && fPriceN != fPrice ; nIter++ )
    1087             :     {
    1088           0 :         fPriceN = getPrice_( nNullDate, nSettle, nMat, fRate, fYieldN, fRedemp, nFreq, nBase );
    1089             : 
    1090           0 :         if( fPrice == fPrice1 )
    1091           0 :             return fYield1;
    1092           0 :         else if( fPrice == fPrice2 )
    1093           0 :             return fYield2;
    1094           0 :         else if( fPrice == fPriceN )
    1095           0 :             return fYieldN;
    1096           0 :         else if( fPrice < fPrice2 )
    1097             :         {
    1098           0 :             fYield2 *= 2.0;
    1099           0 :             fPrice2 = getPrice_( nNullDate, nSettle, nMat, fRate, fYield2, fRedemp, nFreq, nBase );
    1100             : 
    1101           0 :             fYieldN = ( fYield2 - fYield1 ) * 0.5;
    1102             :         }
    1103             :         else
    1104             :         {
    1105           0 :             if( fPrice < fPriceN )
    1106             :             {
    1107           0 :                 fYield1 = fYieldN;
    1108           0 :                 fPrice1 = fPriceN;
    1109             :             }
    1110             :             else
    1111             :             {
    1112           0 :                 fYield2 = fYieldN;
    1113           0 :                 fPrice2 = fPriceN;
    1114             :             }
    1115             : 
    1116           0 :             fYieldN = fYield2 - ( fYield2 - fYield1 ) * ( ( fPrice - fPrice2 ) / ( fPrice1 - fPrice2 ) );
    1117             :         }
    1118             :     }
    1119             : 
    1120           0 :     if( fabs( fPrice - fPriceN ) > fPrice / 100.0 )
    1121           0 :         throw lang::IllegalArgumentException();      // result not precise enough
    1122             : 
    1123           0 :     return fYieldN;
    1124             : }
    1125             : 
    1126             : 
    1127           0 : double getPrice_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield,
    1128             :                     double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1129             : {
    1130           0 :     double      fFreq = nFreq;
    1131             : 
    1132           0 :     double      fE = GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase );
    1133           0 :     double      fDSC_E = GetCoupdaysnc( nNullDate, nSettle, nMat, nFreq, nBase ) / fE;
    1134           0 :     double      fN = GetCoupnum( nNullDate, nSettle, nMat, nFreq, nBase );
    1135           0 :     double      fA = GetCoupdaybs( nNullDate, nSettle, nMat, nFreq, nBase );
    1136             : 
    1137           0 :     double      fRet = fRedemp / ( pow( 1.0 + fYield / fFreq, fN - 1.0 + fDSC_E ) );
    1138           0 :     fRet -= 100.0 * fRate / fFreq * fA / fE;
    1139             : 
    1140           0 :     double      fT1 = 100.0 * fRate / fFreq;
    1141           0 :     double      fT2 = 1.0 + fYield / fFreq;
    1142             : 
    1143           0 :     for( double fK = 0.0 ; fK < fN ; fK++ )
    1144           0 :         fRet += fT1 / pow( fT2, fK + fDSC_E );
    1145             : 
    1146           0 :     return fRet;
    1147             : }
    1148             : 
    1149             : 
    1150           0 : double GetOddfyield( sal_Int32 /*nNullDate*/, sal_Int32 /*nSettle*/, sal_Int32 /*nMat*/, sal_Int32 /*nIssue*/,
    1151             :     sal_Int32 /*nFirstCoup*/, double /*fRate*/, double /*fPrice*/, double /*fRedemp*/, sal_Int32 /*nFreq*/,
    1152             :     sal_Int32 /*nBase*/ ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1153             : {
    1154           0 :     throw uno::RuntimeException();  // #87380#
    1155             : }
    1156             : 
    1157             : 
    1158           0 : double GetOddlprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastCoup,
    1159             :     double fRate, double fYield, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1160             : {
    1161           0 :     double      fFreq = double( nFreq );
    1162           0 :     double      fDCi = GetYearFrac( nNullDate, nLastCoup, nMat, nBase ) * fFreq;
    1163           0 :     double      fDSCi = GetYearFrac( nNullDate, nSettle, nMat, nBase ) * fFreq;
    1164           0 :     double      fAi = GetYearFrac( nNullDate, nLastCoup, nSettle, nBase ) * fFreq;
    1165             : 
    1166           0 :     double      p = fRedemp + fDCi * 100.0 * fRate / fFreq;
    1167           0 :     p /= fDSCi * fYield / fFreq + 1.0;
    1168           0 :     p -= fAi * 100.0 * fRate / fFreq;
    1169             : 
    1170           0 :     return p;
    1171             : }
    1172             : 
    1173             : 
    1174           0 : double GetOddlyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastCoup,
    1175             :     double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1176             : {
    1177           0 :     double      fFreq = double( nFreq );
    1178           0 :     double      fDCi = GetYearFrac( nNullDate, nLastCoup, nMat, nBase ) * fFreq;
    1179           0 :     double      fDSCi = GetYearFrac( nNullDate, nSettle, nMat, nBase ) * fFreq;
    1180           0 :     double      fAi = GetYearFrac( nNullDate, nLastCoup, nSettle, nBase ) * fFreq;
    1181             : 
    1182           0 :     double      y = fRedemp + fDCi * 100.0 * fRate / fFreq;
    1183           0 :     y /= fPrice + fAi * 100.0 * fRate / fFreq;
    1184           0 :     y--;
    1185           0 :     y *= fFreq / fDSCi;
    1186             : 
    1187           0 :     return y;
    1188             : }
    1189             : 
    1190             : 
    1191           0 : double GetRmz( double fZins, double fZzr, double fBw, double fZw, sal_Int32 nF )
    1192             : {
    1193             :     double      fRmz;
    1194           0 :     if( fZins == 0.0 )
    1195           0 :         fRmz = ( fBw + fZw ) / fZzr;
    1196             :     else
    1197             :     {
    1198           0 :         double  fTerm = pow( 1.0 + fZins, fZzr );
    1199           0 :         if( nF > 0 )
    1200           0 :             fRmz = ( fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins / ( 1.0 - 1.0 / fTerm ) ) / ( 1.0 + fZins );
    1201             :         else
    1202           0 :             fRmz = fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins / ( 1.0 - 1.0 / fTerm );
    1203             :     }
    1204             : 
    1205           0 :     return -fRmz;
    1206             : }
    1207             : 
    1208             : 
    1209           0 : double GetZw( double fZins, double fZzr, double fRmz, double fBw, sal_Int32 nF )
    1210             : {
    1211             :     double      fZw;
    1212           0 :     if( fZins == 0.0 )
    1213           0 :         fZw = fBw + fRmz * fZzr;
    1214             :     else
    1215             :     {
    1216           0 :         double  fTerm = pow( 1.0 + fZins, fZzr );
    1217           0 :         if( nF > 0 )
    1218           0 :             fZw = fBw * fTerm + fRmz * ( 1.0 + fZins ) * ( fTerm - 1.0 ) / fZins;
    1219             :         else
    1220           0 :             fZw = fBw * fTerm + fRmz * ( fTerm - 1.0 ) / fZins;
    1221             :     }
    1222             : 
    1223           0 :     return -fZw;
    1224             : }
    1225             : 
    1226             : 
    1227             : //-----------------------------------------------------------------------------
    1228             : // financial functions COUP***
    1229             : 
    1230             : 
    1231             : //-------
    1232             : // COUPPCD: find last coupon date before settlement (can be equal to settlement)
    1233           0 : static void lcl_GetCouppcd( ScaDate& rDate, const ScaDate& rSettle, const ScaDate& rMat, sal_Int32 nFreq )
    1234             :     throw( lang::IllegalArgumentException )
    1235             : {
    1236           0 :     rDate = rMat;
    1237           0 :     rDate.setYear( rSettle.getYear() );
    1238           0 :     if( rDate < rSettle )
    1239           0 :         rDate.addYears( 1 );
    1240           0 :     while( rDate > rSettle )
    1241           0 :         rDate.addMonths( -12 / nFreq );
    1242           0 : }
    1243             : 
    1244           0 : double GetCouppcd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
    1245             :     throw( uno::RuntimeException, lang::IllegalArgumentException )
    1246             : {
    1247           0 :     if( nSettle >= nMat || CHK_Freq )
    1248           0 :         throw lang::IllegalArgumentException();
    1249             : 
    1250           0 :     ScaDate aDate;
    1251           0 :     lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
    1252           0 :     return aDate.getDate( nNullDate );
    1253             : }
    1254             : 
    1255             : 
    1256             : //-------
    1257             : // COUPNCD: find first coupon date after settlement (is never equal to settlement)
    1258           0 : static void lcl_GetCoupncd( ScaDate& rDate, const ScaDate& rSettle, const ScaDate& rMat, sal_Int32 nFreq )
    1259             :     throw( lang::IllegalArgumentException )
    1260             : {
    1261           0 :     rDate = rMat;
    1262           0 :     rDate.setYear( rSettle.getYear() );
    1263           0 :     if( rDate > rSettle )
    1264           0 :         rDate.addYears( -1 );
    1265           0 :     while( rDate <= rSettle )
    1266           0 :         rDate.addMonths( 12 / nFreq );
    1267           0 : }
    1268             : 
    1269           0 : double GetCoupncd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
    1270             :     throw( uno::RuntimeException, lang::IllegalArgumentException )
    1271             : {
    1272           0 :     if( nSettle >= nMat || CHK_Freq )
    1273           0 :         throw lang::IllegalArgumentException();
    1274             : 
    1275           0 :     ScaDate aDate;
    1276           0 :     lcl_GetCoupncd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
    1277           0 :     return aDate.getDate( nNullDate );
    1278             : }
    1279             : 
    1280             : 
    1281             : //-------
    1282             : // COUPDAYBS: get day count: coupon date before settlement <-> settlement
    1283           0 : double GetCoupdaybs( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
    1284             :     throw( uno::RuntimeException, lang::IllegalArgumentException )
    1285             : {
    1286           0 :     if( nSettle >= nMat || CHK_Freq )
    1287           0 :         throw lang::IllegalArgumentException();
    1288             : 
    1289           0 :     ScaDate aSettle( nNullDate, nSettle, nBase );
    1290           0 :     ScaDate aDate;
    1291           0 :     lcl_GetCouppcd( aDate, aSettle, ScaDate( nNullDate, nMat, nBase ), nFreq );
    1292           0 :     return ScaDate::getDiff( aDate, aSettle );
    1293             : }
    1294             : 
    1295             : 
    1296             : //-------
    1297             : // COUPDAYSNC: get day count: settlement <-> coupon date after settlement
    1298           0 : double GetCoupdaysnc( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
    1299             :     throw( uno::RuntimeException, lang::IllegalArgumentException )
    1300             : {
    1301           0 :     if( nSettle >= nMat || CHK_Freq )
    1302           0 :         throw lang::IllegalArgumentException();
    1303             : 
    1304           0 :     if( (nBase != 0) && (nBase != 4) )
    1305             :     {
    1306           0 :         ScaDate aSettle( nNullDate, nSettle, nBase );
    1307           0 :         ScaDate aDate;
    1308           0 :         lcl_GetCoupncd( aDate, aSettle, ScaDate( nNullDate, nMat, nBase ), nFreq );
    1309           0 :         return ScaDate::getDiff( aSettle, aDate );
    1310             :     }
    1311           0 :     return GetCoupdays( nNullDate, nSettle, nMat, nFreq, nBase ) - GetCoupdaybs( nNullDate, nSettle, nMat, nFreq, nBase );
    1312             : }
    1313             : 
    1314             : 
    1315             : //-------
    1316             : // COUPDAYS: get day count: coupon date before settlement <-> coupon date after settlement
    1317           0 : double GetCoupdays( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
    1318             :     throw( uno::RuntimeException, lang::IllegalArgumentException )
    1319             : {
    1320           0 :     if( nSettle >= nMat || CHK_Freq )
    1321           0 :         throw lang::IllegalArgumentException();
    1322             : 
    1323           0 :     if( nBase == 1 )
    1324             :     {
    1325           0 :         ScaDate aDate;
    1326           0 :         lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), ScaDate( nNullDate, nMat, nBase ), nFreq );
    1327           0 :         ScaDate aNextDate( aDate );
    1328           0 :         aNextDate.addMonths( 12 / nFreq );
    1329           0 :         return ScaDate::getDiff( aDate, aNextDate );
    1330             :     }
    1331           0 :     return static_cast< double >( GetDaysInYear( 0, 0, nBase ) ) / nFreq;
    1332             : }
    1333             : 
    1334             : 
    1335             : //-------
    1336             : // COUPNUM: get count of coupon dates
    1337           0 : double GetCoupnum( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase )
    1338             :     throw( uno::RuntimeException, lang::IllegalArgumentException )
    1339             : {
    1340           0 :     if( nSettle >= nMat || CHK_Freq )
    1341           0 :         throw lang::IllegalArgumentException();
    1342             : 
    1343           0 :     ScaDate aMat( nNullDate, nMat, nBase );
    1344           0 :     ScaDate aDate;
    1345           0 :     lcl_GetCouppcd( aDate, ScaDate( nNullDate, nSettle, nBase ), aMat, nFreq );
    1346           0 :     sal_uInt16 nMonths = (aMat.getYear() - aDate.getYear()) * 12 + aMat.getMonth() - aDate.getMonth();
    1347           0 :     return static_cast< double >( nMonths * nFreq / 12 );
    1348             : }
    1349             : 
    1350             : 
    1351             : 
    1352             : 
    1353             : 
    1354             : 
    1355             : 
    1356             : const sal_uInt32 MyList::nStartSize = 16;
    1357             : const sal_uInt32 MyList::nIncrSize = 16;
    1358             : 
    1359             : 
    1360          54 : void MyList::_Grow( void )
    1361             : {
    1362          54 :     nSize += nIncrSize;
    1363             : 
    1364          54 :     void**          pNewData = new void*[ nSize ];
    1365          54 :     memcpy( pNewData, pData, nNew * sizeof( void* ) );
    1366             : 
    1367          54 :     delete[] pData;
    1368          54 :     pData = pNewData;
    1369          54 : }
    1370             : 
    1371             : 
    1372         918 : MyList::MyList( void )
    1373             : {
    1374         918 :     nSize = nStartSize;
    1375         918 :     pData = new void*[ nSize ];
    1376         918 :     nNew = nAct = 0;
    1377         918 : }
    1378             : 
    1379             : 
    1380         408 : MyList::~MyList()
    1381             : {
    1382         408 :     delete[] pData;
    1383         408 : }
    1384             : 
    1385             : 
    1386           0 : void MyList::Insert( void* p, sal_uInt32 n )
    1387             : {
    1388           0 :     if( n >= nNew )
    1389           0 :         Append( p );
    1390             :     else
    1391             :     {
    1392           0 :         Grow();
    1393             : 
    1394           0 :         void**      pIns = pData + n;
    1395           0 :         memmove( pIns + 1, pIns, ( nNew - n ) * sizeof( void* ) );
    1396             : 
    1397           0 :         *pIns = p;
    1398             : 
    1399           0 :         nNew++;
    1400             :     }
    1401           0 : }
    1402             : 
    1403             : 
    1404             : 
    1405             : 
    1406         808 : StringList::~StringList()
    1407             : {
    1408        1212 :     for( OUString* p = ( OUString* ) First() ; p ; p = ( OUString* ) Next() )
    1409         808 :         delete p;
    1410         404 : }
    1411             : 
    1412             : 
    1413         909 : class AnalysisRscStrArrLoader : public Resource
    1414             : {
    1415             : private:
    1416             :     ResStringArray          aStrArray;
    1417             : public:
    1418         909 :                             AnalysisRscStrArrLoader( sal_uInt16 nRsc, sal_uInt16 nArrayId, ResMgr& rResMgr ) :
    1419             :                                 Resource( AnalysisResId( nRsc, rResMgr ) ),
    1420         909 :                                 aStrArray( AnalysisResId( nArrayId, rResMgr ) )
    1421             :                             {
    1422         909 :                                 FreeResource();
    1423         909 :                             }
    1424             : 
    1425         909 :     const ResStringArray&   GetStringArray() const { return aStrArray; }
    1426             : };
    1427             : 
    1428             : 
    1429             : 
    1430             : 
    1431         909 : FuncData::FuncData( const FuncDataBase& r, ResMgr& rResMgr ) :
    1432             :     aIntName( OUString::createFromAscii( r.pIntName ) ),
    1433             :     nUINameID( r.nUINameID ),
    1434             :     nDescrID( r.nDescrID ),
    1435             :     bDouble( r.bDouble ),
    1436             :     bWithOpt( r.bWithOpt ),
    1437             :     nParam( r.nNumOfParams ),
    1438             :     nCompID( r.nCompListID ),
    1439         909 :     eCat( r.eCat )
    1440             : {
    1441         909 :     AnalysisRscStrArrLoader aArrLoader( RID_ANALYSIS_DEFFUNCTION_NAMES, nCompID, rResMgr );
    1442         909 :     const ResStringArray&   rArr = aArrLoader.GetStringArray();
    1443             : 
    1444         909 :     sal_uInt16              nCount = sal::static_int_cast<sal_uInt16>( rArr.Count() );
    1445             :     sal_uInt16              n;
    1446             : 
    1447        2727 :     for( n = 0 ; n < nCount ; n++ )
    1448        2727 :         aCompList.Append( rArr.GetString( n ) );
    1449         909 : }
    1450             : 
    1451             : 
    1452         808 : FuncData::~FuncData()
    1453             : {
    1454         808 : }
    1455             : 
    1456             : 
    1457        5238 : sal_uInt16 FuncData::GetStrIndex( sal_uInt16 nParamNum ) const
    1458             : {
    1459        5238 :     if( !bWithOpt )
    1460        1530 :         nParamNum++;
    1461             : 
    1462        5238 :     if( nParamNum > nParam )
    1463          90 :         return nParam * 2;
    1464             :     else
    1465        5148 :         return nParamNum * 2;
    1466             : }
    1467             : 
    1468             : 
    1469             : 
    1470             : 
    1471           9 : FuncDataList::FuncDataList( ResMgr& rResMgr )
    1472             : {
    1473         918 :     for( sal_uInt16 n = 0 ; n < SAL_N_ELEMENTS(pFuncDatas) ; n++ )
    1474         909 :         Append( new FuncData( pFuncDatas[ n ], rResMgr ) );
    1475           9 : }
    1476             : 
    1477             : 
    1478          12 : FuncDataList::~FuncDataList()
    1479             : {
    1480         408 :     for( FuncData* p = ( FuncData* ) First() ; p ; p = ( FuncData* ) Next() )
    1481         404 :         delete p;
    1482           8 : }
    1483             : 
    1484             : 
    1485        8369 : const FuncData* FuncDataList::Get(  const OUString& aProgrammaticName ) const
    1486             : {
    1487        8369 :     if( aLastName == aProgrammaticName )
    1488        7056 :         return Get( nLast );
    1489             : 
    1490        1313 :     ( ( FuncDataList* ) this )->aLastName = aProgrammaticName;
    1491             : 
    1492        1313 :     sal_uInt32  nE = Count();
    1493       66963 :     for( sal_uInt32 n = 0 ; n < nE ; n++ )
    1494             :     {
    1495       66963 :         const FuncData* p = Get( n );
    1496       66963 :         if( p->Is( aProgrammaticName ) )
    1497             :         {
    1498        1313 :             ( ( FuncDataList* ) this )->nLast = n;
    1499        1313 :             return p;
    1500             :         }
    1501             :     }
    1502             : 
    1503           0 :     ( ( FuncDataList* ) this )->nLast = 0xFFFFFFFF;
    1504           0 :     return NULL;
    1505             : }
    1506             : 
    1507             : 
    1508       22077 : AnalysisResId::AnalysisResId( sal_uInt16 nId, ResMgr& rResMgr ) : ResId( nId, rResMgr )
    1509             : {
    1510       22077 : }
    1511             : 
    1512             : 
    1513             : 
    1514             : 
    1515           0 : SortedIndividualInt32List::SortedIndividualInt32List()
    1516             : {
    1517           0 : }
    1518             : 
    1519             : 
    1520           0 : SortedIndividualInt32List::~SortedIndividualInt32List()
    1521             : {
    1522           0 : }
    1523             : 
    1524             : 
    1525           0 : void SortedIndividualInt32List::Insert( sal_Int32 nDay )
    1526             : {
    1527           0 :     sal_uInt32 nIndex = Count();
    1528           0 :     while( nIndex )
    1529             :     {
    1530           0 :         nIndex--;
    1531           0 :         sal_Int32 nRef = Get( nIndex );
    1532           0 :         if( nDay == nRef )
    1533           0 :             return;
    1534           0 :         else if( nDay > nRef )
    1535             :         {
    1536           0 :             MyList::Insert( (void*)(sal_IntPtr)nDay, nIndex + 1 );
    1537           0 :             return;
    1538             :         }
    1539             :     }
    1540           0 :     MyList::Insert( (void*)(sal_IntPtr)nDay, 0UL );
    1541             : }
    1542             : 
    1543             : 
    1544           0 : void SortedIndividualInt32List::Insert( sal_Int32 nDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend )
    1545             : {
    1546           0 :     if( !nDay )
    1547           0 :         return;
    1548             : 
    1549           0 :     nDay += nNullDate;
    1550           0 :     if( bInsertOnWeekend || (GetDayOfWeek( nDay ) < 5) )
    1551           0 :         Insert( nDay );
    1552             : }
    1553             : 
    1554             : 
    1555           0 : void SortedIndividualInt32List::Insert(
    1556             :         double fDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1557             : {
    1558           0 :     if( (fDay < -2147483648.0) || (fDay > 2147483649.0) )
    1559           0 :         throw lang::IllegalArgumentException();
    1560           0 :     Insert( static_cast< sal_Int32 >( fDay ), nNullDate, bInsertOnWeekend );
    1561           0 : }
    1562             : 
    1563             : 
    1564           0 : sal_Bool SortedIndividualInt32List::Find( sal_Int32 nVal ) const
    1565             : {
    1566           0 :     sal_uInt32  nE = Count();
    1567             : 
    1568           0 :     if( !nE || nVal < Get( 0 ) || nVal > Get( nE - 1 ) )
    1569           0 :         return sal_False;
    1570             : 
    1571             :     // linear search
    1572             : 
    1573           0 :     for( sal_uInt32 n = 0 ; n < nE ; n++ )
    1574             :     {
    1575           0 :         sal_Int32   nRef = Get( n );
    1576             : 
    1577           0 :         if( nRef == nVal )
    1578           0 :             return sal_True;
    1579           0 :         else if( nRef > nVal )
    1580           0 :             return sal_False;
    1581             :     }
    1582           0 :     return sal_False;
    1583             : }
    1584             : 
    1585             : 
    1586           0 : void SortedIndividualInt32List::InsertHolidayList(
    1587             :         const ScaAnyConverter& rAnyConv,
    1588             :         const uno::Any& rHolAny,
    1589             :         sal_Int32 nNullDate,
    1590             :         sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1591             : {
    1592             :     double fDay;
    1593           0 :     if( rAnyConv.getDouble( fDay, rHolAny ) )
    1594           0 :         Insert( fDay, nNullDate, bInsertOnWeekend );
    1595           0 : }
    1596             : 
    1597             : 
    1598           0 : void SortedIndividualInt32List::InsertHolidayList(
    1599             :         ScaAnyConverter& rAnyConv,
    1600             :         const uno::Reference< beans::XPropertySet >& xOptions,
    1601             :         const uno::Any& rHolAny,
    1602             :         sal_Int32 nNullDate,
    1603             :         sal_Bool bInsertOnWeekend ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1604             : {
    1605           0 :     rAnyConv.init( xOptions );
    1606           0 :     if( rHolAny.getValueTypeClass() == uno::TypeClass_SEQUENCE )
    1607             :     {
    1608           0 :         uno::Sequence< uno::Sequence< uno::Any > > aAnySeq;
    1609           0 :         if( rHolAny >>= aAnySeq )
    1610             :         {
    1611           0 :             const uno::Sequence< uno::Any >* pSeqArray = aAnySeq.getConstArray();
    1612           0 :             for( sal_Int32 nIndex1 = 0; nIndex1 < aAnySeq.getLength(); nIndex1++ )
    1613             :             {
    1614           0 :                 const uno::Sequence< uno::Any >& rSubSeq = pSeqArray[ nIndex1 ];
    1615           0 :                 const uno::Any* pAnyArray = rSubSeq.getConstArray();
    1616             : 
    1617           0 :                 for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
    1618           0 :                     InsertHolidayList( rAnyConv, pAnyArray[ nIndex2 ], nNullDate, bInsertOnWeekend );
    1619             :             }
    1620             :         }
    1621             :         else
    1622           0 :             throw lang::IllegalArgumentException();
    1623             :     }
    1624             :     else
    1625           0 :         InsertHolidayList( rAnyConv, rHolAny, nNullDate, bInsertOnWeekend );
    1626           0 : }
    1627             : 
    1628             : 
    1629             : 
    1630             : //-----------------------------------------------------------------------------
    1631             : 
    1632           0 : ScaDoubleList::~ScaDoubleList()
    1633             : {
    1634           0 :     for( double* pDbl = const_cast< double* >( First() ); pDbl; pDbl = const_cast< double* >( Next() ) )
    1635           0 :         delete pDbl;
    1636           0 : }
    1637             : 
    1638             : 
    1639           0 : void ScaDoubleList::Append(
    1640             :         const uno::Sequence< uno::Sequence< double > >& rValueSeq ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1641             : {
    1642           0 :     const uno::Sequence< double >* pSeqArray = rValueSeq.getConstArray();
    1643           0 :     for( sal_Int32 nIndex1 = 0; nIndex1 < rValueSeq.getLength(); nIndex1++ )
    1644             :     {
    1645           0 :         const uno::Sequence< double >& rSubSeq = pSeqArray[ nIndex1 ];
    1646           0 :         const double* pArray = rSubSeq.getConstArray();
    1647           0 :         for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
    1648           0 :             Append( pArray[ nIndex2 ] );
    1649             :     }
    1650           0 : }
    1651             : 
    1652             : 
    1653           0 : void ScaDoubleList::Append(
    1654             :         const uno::Sequence< uno::Sequence< sal_Int32 > >& rValueSeq ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1655             : {
    1656           0 :     const uno::Sequence< sal_Int32 >* pSeqArray = rValueSeq.getConstArray();
    1657           0 :     for( sal_Int32 nIndex1 = 0; nIndex1 < rValueSeq.getLength(); nIndex1++ )
    1658             :     {
    1659           0 :         const uno::Sequence< sal_Int32 >& rSubSeq = pSeqArray[ nIndex1 ];
    1660           0 :         const sal_Int32* pArray = rSubSeq.getConstArray();
    1661           0 :         for( sal_Int32 nIndex2 = 0; nIndex2 < rSubSeq.getLength(); nIndex2++ )
    1662           0 :             Append( pArray[ nIndex2 ] );
    1663             :     }
    1664           0 : }
    1665             : 
    1666             : 
    1667             : 
    1668           0 : void ScaDoubleList::Append(
    1669             :         const ScaAnyConverter& rAnyConv,
    1670             :         const uno::Any& rAny,
    1671             :         sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1672             : {
    1673           0 :     if( rAny.getValueTypeClass() == uno::TypeClass_SEQUENCE )
    1674           0 :         Append( rAnyConv, *static_cast< const uno::Sequence< uno::Sequence< uno::Any > >* >( rAny.getValue() ), bIgnoreEmpty );
    1675             :     else
    1676             :     {
    1677             :         double fValue;
    1678           0 :         if( rAnyConv.getDouble( fValue, rAny ) )
    1679           0 :             Append( fValue );
    1680           0 :         else if( !bIgnoreEmpty )
    1681           0 :             Append( 0.0 );
    1682             :     }
    1683           0 : }
    1684             : 
    1685             : 
    1686           0 : void ScaDoubleList::Append(
    1687             :         const ScaAnyConverter& rAnyConv,
    1688             :         const uno::Sequence< uno::Any >& rAnySeq,
    1689             :         sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1690             : {
    1691           0 :     const uno::Any* pArray = rAnySeq.getConstArray();
    1692           0 :     for( sal_Int32 nIndex = 0; nIndex < rAnySeq.getLength(); nIndex++ )
    1693           0 :         Append( rAnyConv, pArray[ nIndex ], bIgnoreEmpty );
    1694           0 : }
    1695             : 
    1696             : 
    1697           0 : void ScaDoubleList::Append(
    1698             :         const ScaAnyConverter& rAnyConv,
    1699             :         const uno::Sequence< uno::Sequence< uno::Any > >& rAnySeq,
    1700             :         sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1701             : {
    1702           0 :     const uno::Sequence< uno::Any >* pArray = rAnySeq.getConstArray();
    1703           0 :     for( sal_Int32 nIndex = 0; nIndex < rAnySeq.getLength(); nIndex++ )
    1704           0 :         Append( rAnyConv, pArray[ nIndex ], bIgnoreEmpty );
    1705           0 : }
    1706             : 
    1707             : 
    1708             : 
    1709           0 : void ScaDoubleList::Append(
    1710             :         ScaAnyConverter& rAnyConv,
    1711             :         const uno::Reference< beans::XPropertySet >& xOpt,
    1712             :         const uno::Sequence< uno::Any >& rAnySeq,
    1713             :         sal_Bool bIgnoreEmpty ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1714             : {
    1715           0 :     rAnyConv.init( xOpt );
    1716           0 :     Append( rAnyConv, rAnySeq, bIgnoreEmpty );
    1717           0 : }
    1718             : 
    1719             : 
    1720           0 : sal_Bool ScaDoubleList::CheckInsert( double ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
    1721             : {
    1722           0 :     return sal_True;
    1723             : }
    1724             : 
    1725             : 
    1726             : 
    1727             : //-----------------------------------------------------------------------------
    1728             : 
    1729           0 : sal_Bool ScaDoubleListGT0::CheckInsert( double fValue ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
    1730             : {
    1731           0 :     if( fValue < 0.0 )
    1732           0 :         throw lang::IllegalArgumentException();
    1733           0 :     return fValue > 0.0;
    1734             : }
    1735             : 
    1736             : 
    1737             : 
    1738             : //-----------------------------------------------------------------------------
    1739             : 
    1740           0 : sal_Bool ScaDoubleListGE0::CheckInsert( double fValue ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
    1741             : {
    1742           0 :     if( fValue < 0.0 )
    1743           0 :         throw lang::IllegalArgumentException();
    1744           0 :     return sal_True;
    1745             : }
    1746             : 
    1747             : 
    1748             : 
    1749             : //-----------------------------------------------------------------------------
    1750             : 
    1751           0 : Complex::Complex( const OUString& rStr ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1752             : {
    1753           0 :     if( !ParseString( rStr, *this ) )
    1754           0 :         throw lang::IllegalArgumentException();
    1755           0 : }
    1756             : 
    1757             : 
    1758           0 : inline sal_Bool Complex::IsImagUnit( sal_Unicode c )
    1759             : {
    1760           0 :     return c == 'i' || c == 'j';
    1761             : }
    1762             : 
    1763           0 : sal_Bool Complex::ParseString( const OUString& rStr, Complex& rCompl )
    1764             : {
    1765           0 :     rCompl.c = '\0';    // do not force a symbol, if only real part present
    1766             : 
    1767           0 :     const sal_Unicode* pStr = rStr.getStr();
    1768             : 
    1769           0 :     if( IsImagUnit( *pStr ) && rStr.getLength() == 1)
    1770             :     {
    1771           0 :         rCompl.r = 0.0;
    1772           0 :         rCompl.i = 1.0;
    1773           0 :         rCompl.c = *pStr;
    1774           0 :         return sal_True;
    1775             :     }
    1776             : 
    1777             :     double                  f;
    1778             : 
    1779           0 :     if( !ParseDouble( pStr, f ) )
    1780           0 :         return sal_False;
    1781             : 
    1782           0 :     switch( *pStr )
    1783             :     {
    1784             :         case '-':   // imag part follows
    1785             :         case '+':
    1786             :             {
    1787           0 :             double      r = f;
    1788           0 :             if( IsImagUnit( pStr[ 1 ] ) )
    1789             :             {
    1790           0 :                 rCompl.c = pStr[ 1 ];
    1791           0 :                 if( pStr[ 2 ] == 0 )
    1792             :                 {
    1793           0 :                     rCompl.r = f;
    1794           0 :                     rCompl.i = ( *pStr == '+' )? 1.0 : -1.0;
    1795           0 :                     return sal_True;
    1796             :                 }
    1797             :             }
    1798           0 :             else if( ParseDouble( pStr, f ) && IsImagUnit( *pStr ) )
    1799             :             {
    1800           0 :                 rCompl.c = *pStr;
    1801           0 :                 pStr++;
    1802           0 :                 if( *pStr == 0 )
    1803             :                 {
    1804           0 :                     rCompl.r = r;
    1805           0 :                     rCompl.i = f;
    1806           0 :                     return sal_True;
    1807             :                 }
    1808             :             }
    1809             :             }
    1810           0 :             break;
    1811             :         case 'j':
    1812             :         case 'i':
    1813           0 :             rCompl.c = *pStr;
    1814           0 :             pStr++;
    1815           0 :             if( *pStr == 0 )
    1816             :             {
    1817           0 :                 rCompl.i = f;
    1818           0 :                 rCompl.r = 0.0;
    1819           0 :                 return sal_True;
    1820             :             }
    1821           0 :             break;
    1822             :         case 0:     // only real-part
    1823           0 :             rCompl.r = f;
    1824           0 :             rCompl.i = 0.0;
    1825           0 :             return sal_True;
    1826             :     }
    1827             : 
    1828           0 :     return sal_False;
    1829             : }
    1830             : 
    1831             : 
    1832           0 : OUString Complex::GetString() const throw( uno::RuntimeException, lang::IllegalArgumentException )
    1833             : {
    1834           0 :     CHK_FINITE(r);
    1835           0 :     CHK_FINITE(i);
    1836           0 :     OUStringBuffer aRet;
    1837             : 
    1838           0 :     bool bHasImag = i != 0.0;
    1839           0 :     bool bHasReal = !bHasImag || (r != 0.0);
    1840             : 
    1841           0 :     if( bHasReal )
    1842           0 :         aRet.append(::GetString( r ));
    1843           0 :     if( bHasImag )
    1844             :     {
    1845           0 :         if( i == 1.0 )
    1846             :         {
    1847           0 :             if( bHasReal )
    1848           0 :                 aRet.append('+');
    1849             :         }
    1850           0 :         else if( i == -1.0 )
    1851           0 :             aRet.append('-');
    1852             :         else
    1853           0 :             aRet.append(::GetString( i, bHasReal ));
    1854           0 :         aRet.append((c != 'j') ? 'i' : 'j');
    1855             :     }
    1856             : 
    1857           0 :     return aRet.makeStringAndClear();
    1858             : }
    1859             : 
    1860             : 
    1861           0 : double Complex::Arg( void ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
    1862             : {
    1863           0 :     if( r == 0.0 && i == 0.0 )
    1864           0 :         throw lang::IllegalArgumentException();
    1865             : 
    1866           0 :     double  phi = acos( r / Abs() );
    1867             : 
    1868           0 :     if( i < 0.0 )
    1869           0 :         phi = -phi;
    1870             : 
    1871           0 :     return phi;
    1872             : }
    1873             : 
    1874             : 
    1875           0 : void Complex::Power( double fPower ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1876             : {
    1877           0 :     if( r == 0.0 && i == 0.0 )
    1878             :     {
    1879           0 :         if( fPower > 0 )
    1880             :         {
    1881           0 :             r = i = 0.0;
    1882           0 :             return;
    1883             :         }
    1884             :         else
    1885           0 :             throw lang::IllegalArgumentException();
    1886             :     }
    1887             : 
    1888             :     double      p, phi;
    1889             : 
    1890           0 :     p = Abs();
    1891             : 
    1892           0 :     phi = acos( r / p );
    1893           0 :     if( i < 0.0 )
    1894           0 :         phi = -phi;
    1895             : 
    1896           0 :     p = pow( p, fPower );
    1897           0 :     phi *= fPower;
    1898             : 
    1899           0 :     r = cos( phi ) * p;
    1900           0 :     i = sin( phi ) * p;
    1901             : }
    1902             : 
    1903             : 
    1904           0 : void Complex::Sqrt( void )
    1905             : {
    1906             :     static const double fMultConst = 0.7071067811865475;    // ...2440084436210485 = 1/sqrt(2)
    1907           0 :     double  p = Abs();
    1908           0 :     double  i_ = sqrt( p - r ) * fMultConst;
    1909             : 
    1910           0 :     r = sqrt( p + r ) * fMultConst;
    1911           0 :     i = ( i < 0.0 )? -i_ : i_;
    1912           0 : }
    1913             : 
    1914             : 
    1915           0 : void Complex::Sin( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1916             : {
    1917           0 :     if( !::rtl::math::isValidArcArg( r ) )
    1918           0 :         throw lang::IllegalArgumentException();
    1919             : 
    1920           0 :     if( i )
    1921             :     {
    1922             :         double  r_;
    1923             : 
    1924           0 :         r_ = sin( r ) * cosh( i );
    1925           0 :         i = cos( r ) * sinh( i );
    1926           0 :         r = r_;
    1927             :     }
    1928             :     else
    1929           0 :         r = sin( r );
    1930           0 : }
    1931             : 
    1932             : 
    1933           0 : void Complex::Cos( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1934             : {
    1935           0 :         if( !::rtl::math::isValidArcArg( r ) )
    1936           0 :         throw lang::IllegalArgumentException();
    1937             : 
    1938           0 :     if( i )
    1939             :     {
    1940             :         double      r_;
    1941             : 
    1942           0 :         r_ = cos( r ) * cosh( i );
    1943           0 :         i = -( sin( r ) * sinh( i ) );
    1944           0 :         r = r_;
    1945             :     }
    1946             :     else
    1947           0 :         r = cos( r );
    1948           0 : }
    1949             : 
    1950             : 
    1951           0 : void Complex::Div( const Complex& z ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1952             : {
    1953           0 :     if( z.r == 0 && z.i == 0 )
    1954           0 :         throw lang::IllegalArgumentException();
    1955             : 
    1956           0 :     double  a1 = r;
    1957           0 :     double  a2 = z.r;
    1958           0 :     double  b1 = i;
    1959           0 :     double  b2 = z.i;
    1960             : 
    1961           0 :     double  f = 1.0 / ( a2 * a2 + b2 * b2 );
    1962             : 
    1963           0 :     r = ( a1 * a2 + b1 * b2 ) * f;
    1964           0 :     i = ( a2 * b1 - a1 * b2 ) * f;
    1965             : 
    1966           0 :     if( !c ) c = z.c;
    1967           0 : }
    1968             : 
    1969             : 
    1970           0 : void Complex::Exp( void )
    1971             : {
    1972           0 :     double  fE = exp( r );
    1973           0 :     r = fE * cos( i );
    1974           0 :     i = fE * sin( i );
    1975           0 : }
    1976             : 
    1977             : 
    1978           0 : void Complex::Ln( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1979             : {
    1980           0 :     if( r == 0.0 && i == 0.0 )
    1981           0 :         throw lang::IllegalArgumentException();
    1982             : 
    1983           0 :     double      fAbs = Abs();
    1984           0 :     sal_Bool    bNegi = i < 0.0;
    1985             : 
    1986           0 :     i = acos( r / fAbs );
    1987             : 
    1988           0 :     if( bNegi )
    1989           0 :         i = -i;
    1990             : 
    1991           0 :     r = log( fAbs );
    1992           0 : }
    1993             : 
    1994             : 
    1995           0 : void Complex::Log10( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    1996             : {
    1997           0 :     Ln();
    1998           0 :     Mult( 0.434294481903251828 );   // * log10( e )
    1999           0 : }
    2000             : 
    2001             : 
    2002           0 : void Complex::Log2( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2003             : {
    2004           0 :     Ln();
    2005           0 :     Mult( 1.442695040888963407 );   // * log2( e )
    2006           0 : }
    2007             : 
    2008             : 
    2009           0 : void Complex::Tan(void) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2010             : {
    2011           0 :     if ( i )
    2012             :     {
    2013           0 :         if( !::rtl::math::isValidArcArg( 2.0 * r ) )
    2014           0 :             throw lang::IllegalArgumentException();
    2015           0 :         double fScale =1.0 / ( cos( 2.0 * r ) + cosh( 2.0 * i ));
    2016           0 :         r = sin( 2.0 * r ) * fScale;
    2017           0 :         i = sinh( 2.0 * i ) * fScale;
    2018             :     }
    2019             :     else
    2020             :     {
    2021           0 :         if( !::rtl::math::isValidArcArg( r ) )
    2022           0 :             throw lang::IllegalArgumentException();
    2023           0 :         r = tan( r );
    2024             :     }
    2025           0 : }
    2026             : 
    2027             : 
    2028           0 : void Complex::Sec( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2029             : {
    2030           0 :     if( i )
    2031             :     {
    2032           0 :         if( !::rtl::math::isValidArcArg( 2 * r ) )
    2033           0 :             throw lang::IllegalArgumentException();
    2034           0 :         double fScale = 1.0 / (cosh( 2.0 * i) + cos ( 2.0 * r));
    2035             :         double  r_;
    2036           0 :         r_ = 2.0 * cos( r ) * cosh( i ) * fScale;
    2037           0 :         i = 2.0 * sin( r ) * sinh( i ) * fScale;
    2038           0 :         r = r_;
    2039             :     }
    2040             :     else
    2041             :     {
    2042           0 :         if( !::rtl::math::isValidArcArg( r ) )
    2043           0 :             throw lang::IllegalArgumentException();
    2044           0 :         r = 1.0 / cos( r );
    2045             :     }
    2046           0 : }
    2047             : 
    2048             : 
    2049           0 : void Complex::Csc( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2050             : {
    2051           0 :     if( i )
    2052             :     {
    2053           0 :         if( !::rtl::math::isValidArcArg( 2 * r ) )
    2054           0 :             throw lang::IllegalArgumentException();
    2055           0 :         double fScale = 1.0 / (cosh( 2.0 * i) - cos ( 2.0 * r));
    2056             :         double  r_;
    2057           0 :         r_ = 2.0 * sin( r ) * cosh( i ) * fScale;
    2058           0 :         i = -2.0 * cos( r ) * sinh( i ) * fScale;
    2059           0 :         r = r_;
    2060             :     }
    2061             :     else
    2062             :     {
    2063           0 :         if( !::rtl::math::isValidArcArg( r ) )
    2064           0 :             throw lang::IllegalArgumentException();
    2065           0 :         r = 1.0 / sin( r );
    2066             :     }
    2067           0 : }
    2068             : 
    2069             : 
    2070           0 : void Complex::Cot(void) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2071             : {
    2072           0 :     if ( i )
    2073             :     {
    2074           0 :         if( !::rtl::math::isValidArcArg( 2.0 * r ) )
    2075           0 :             throw lang::IllegalArgumentException();
    2076           0 :         double fScale =1.0 / ( cosh( 2.0 * i ) - cos( 2.0 * r ) );
    2077           0 :         r = sin( 2.0 * r ) * fScale;
    2078           0 :         i = - ( sinh( 2.0 * i ) * fScale );
    2079             :     }
    2080             :     else
    2081             :     {
    2082           0 :         if( !::rtl::math::isValidArcArg( r ) )
    2083           0 :             throw lang::IllegalArgumentException();
    2084           0 :         r = 1.0 / tan( r );
    2085             :     }
    2086           0 : }
    2087             : 
    2088             : 
    2089           0 : void Complex::Sinh( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2090             : {
    2091           0 :     if( !::rtl::math::isValidArcArg( r ) )
    2092           0 :         throw lang::IllegalArgumentException();
    2093             : 
    2094           0 :     if( i )
    2095             :     {
    2096             :         double  r_;
    2097           0 :         r_ = sinh( r ) * cos( i );
    2098           0 :                 i = cosh( r ) * sin( i );
    2099           0 :                 r = r_;
    2100             :         }
    2101             :         else
    2102           0 :                 r = sinh( r );
    2103           0 : }
    2104             : 
    2105             : 
    2106           0 : void Complex::Cosh( void ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2107             : {
    2108           0 :     if( !::rtl::math::isValidArcArg( r ) )
    2109           0 :         throw lang::IllegalArgumentException();
    2110             : 
    2111           0 :     if( i )
    2112             :     {
    2113             :         double  r_;
    2114           0 :         r_ = cosh( r ) * cos( i );
    2115           0 :                 i = sinh( r ) * sin( i );
    2116           0 :                 r = r_;
    2117             :         }
    2118             :         else
    2119           0 :                 r = cosh( r );
    2120           0 : }
    2121             : 
    2122             : 
    2123           0 : void Complex::Sech(void) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2124             : {
    2125           0 :     if ( i )
    2126             :     {
    2127           0 :         if( !::rtl::math::isValidArcArg( 2.0 * r ) )
    2128           0 :             throw lang::IllegalArgumentException();
    2129           0 :         double fScale =1.0 / ( cosh( 2.0 * r ) + cos( 2.0 * i ));
    2130             :         double r_;
    2131           0 :         r_ = 2.0 * cosh( r ) * cos( i ) * fScale;
    2132           0 :         i = - (2.0 * sinh( r ) * sin( i ) * fScale );
    2133           0 :         r = r_ ;
    2134             :     }
    2135             :     else
    2136             :     {
    2137           0 :         if( !::rtl::math::isValidArcArg( r ) )
    2138           0 :             throw lang::IllegalArgumentException();
    2139           0 :         r = 1.0 / cosh( r );
    2140             :     }
    2141           0 : }
    2142             : 
    2143             : 
    2144           0 : void Complex::Csch(void) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2145             : {
    2146           0 :     if ( i )
    2147             :     {
    2148           0 :         if( !::rtl::math::isValidArcArg( 2.0 * r ) )
    2149           0 :             throw lang::IllegalArgumentException();
    2150           0 :         double fScale =1.0 / ( cosh( 2.0 * r ) - cos( 2.0 * i ));
    2151             :         double r_;
    2152           0 :         r_ = 2.0 * sinh( r ) * cos( i ) * fScale;
    2153           0 :         i = - ( 2.0 * cosh( r ) * sin( i ) * fScale );
    2154           0 :         r = r_ ;
    2155             :     }
    2156             :     else
    2157             :     {
    2158           0 :         if( !::rtl::math::isValidArcArg( r ) )
    2159           0 :             throw lang::IllegalArgumentException();
    2160           0 :         r = 1.0 / sinh( r );
    2161             :     }
    2162           0 : }
    2163             : 
    2164             : 
    2165           0 : ComplexList::~ComplexList()
    2166             : {
    2167           0 :     for( Complex* p = ( Complex* ) First() ; p ; p = ( Complex* ) Next() )
    2168           0 :         delete p;
    2169           0 : }
    2170             : 
    2171             : 
    2172           0 : void ComplexList::Append( const uno::Sequence< uno::Sequence< OUString > >& r, ComplListAppendHandl eAH ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2173             : {
    2174             :     sal_Int32   n1, n2;
    2175           0 :     sal_Int32   nE1 = r.getLength();
    2176             :     sal_Int32   nE2;
    2177           0 :     sal_Bool    bEmpty0 = eAH == AH_EmpyAs0;
    2178           0 :     sal_Bool    bErrOnEmpty = eAH == AH_EmptyAsErr;
    2179             : 
    2180           0 :     for( n1 = 0 ; n1 < nE1 ; n1++ )
    2181             :     {
    2182           0 :         const uno::Sequence< OUString >&    rList = r[ n1 ];
    2183           0 :         nE2 = rList.getLength();
    2184             : 
    2185           0 :         for( n2 = 0 ; n2 < nE2 ; n2++ )
    2186             :         {
    2187           0 :             const OUString&   rStr = rList[ n2 ];
    2188             : 
    2189           0 :             if( !rStr.isEmpty() )
    2190           0 :                 Append( new Complex( rStr ) );
    2191           0 :             else if( bEmpty0 )
    2192           0 :                 Append( new Complex( 0.0 ) );
    2193           0 :             else if( bErrOnEmpty )
    2194           0 :                 throw lang::IllegalArgumentException();
    2195             :         }
    2196             :     }
    2197           0 : }
    2198             : 
    2199             : 
    2200           0 : void ComplexList::Append( const uno::Sequence< uno::Any >& aMultPars, ComplListAppendHandl eAH ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2201             : {
    2202           0 :     sal_Int32       nEle = aMultPars.getLength();
    2203           0 :     sal_Bool        bEmpty0 = eAH == AH_EmpyAs0;
    2204           0 :     sal_Bool        bErrOnEmpty = eAH == AH_EmptyAsErr;
    2205             : 
    2206           0 :     for( sal_Int32 i = 0 ; i < nEle ; i++ )
    2207             :     {
    2208           0 :         const uno::Any&  r = aMultPars[ i ];
    2209           0 :         switch( r.getValueTypeClass() )
    2210             :         {
    2211           0 :             case uno::TypeClass_VOID:       break;
    2212             :             case uno::TypeClass_STRING:
    2213             :                 {
    2214           0 :                 const OUString*       pStr = ( const OUString* ) r.getValue();
    2215             : 
    2216           0 :                 if( !pStr->isEmpty() )
    2217           0 :                     Append( new Complex( *( OUString* ) r.getValue() ) );
    2218           0 :                 else if( bEmpty0 )
    2219           0 :                     Append( new Complex( 0.0 ) );
    2220           0 :                 else if( bErrOnEmpty )
    2221           0 :                     throw lang::IllegalArgumentException();
    2222             :                 }
    2223           0 :                 break;
    2224             :             case uno::TypeClass_DOUBLE:
    2225           0 :                 Append( new Complex( *( double* ) r.getValue(), 0.0 ) );
    2226           0 :                 break;
    2227             :             case uno::TypeClass_SEQUENCE:
    2228             :                 {
    2229           0 :                 uno::Sequence< uno::Sequence< uno::Any > >           aValArr;
    2230           0 :                 if( r >>= aValArr )
    2231             :                 {
    2232           0 :                     sal_Int32           nE = aValArr.getLength();
    2233           0 :                     const uno::Sequence< uno::Any >*   pArr = aValArr.getConstArray();
    2234           0 :                     for( sal_Int32 n = 0 ; n < nE ; n++ )
    2235           0 :                         Append( pArr[ n ], eAH );
    2236             :                 }
    2237             :                 else
    2238           0 :                     throw lang::IllegalArgumentException();
    2239             :                 }
    2240           0 :                 break;
    2241             :             default:
    2242           0 :                 throw lang::IllegalArgumentException();
    2243             :         }
    2244             :     }
    2245           0 : }
    2246             : 
    2247             : 
    2248             : 
    2249             : 
    2250           0 : ConvertData::ConvertData( const sal_Char p[], double fC, ConvertDataClass e, sal_Bool bPrefSupport ) : aName( p, strlen( p ), RTL_TEXTENCODING_MS_1252 )
    2251             : {
    2252           0 :     fConst = fC;
    2253           0 :     eClass = e;
    2254           0 :     bPrefixSupport = bPrefSupport;
    2255           0 : }
    2256             : 
    2257           0 : ConvertData::~ConvertData()
    2258             : {
    2259           0 : }
    2260             : 
    2261             : 
    2262           0 : sal_Int16 ConvertData::GetMatchingLevel( const OUString& rRef ) const
    2263             : {
    2264           0 :     OUString aStr = rRef;
    2265           0 :     sal_Int32 nLen = rRef.getLength();
    2266           0 :     sal_Int32 nIndex = rRef.lastIndexOf( '^' );
    2267           0 :     if( nIndex > 0 && nIndex  == ( nLen - 2 ) )
    2268             :     {
    2269           0 :         const sal_Unicode*  p = aStr.getStr();
    2270           0 :         aStr = OUString( p, nLen - 2 );
    2271           0 :         aStr += OUString( p[ nLen - 1 ] );
    2272             :     }
    2273           0 :     if( aName.equals( aStr ) )
    2274           0 :         return 0;
    2275             :     else
    2276             :     {
    2277           0 :         const sal_Unicode*  p = aStr.getStr();
    2278             : 
    2279           0 :         nLen = aStr.getLength();
    2280           0 :         bool bPref = IsPrefixSupport();
    2281           0 :         bool bOneChar = (bPref && nLen > 1 && (aName == p + 1));
    2282           0 :         if (bOneChar || (bPref && nLen > 2 && (aName == p + 2) &&
    2283           0 :                     *p == 'd' && *(p+1) == 'a'))
    2284             :         {
    2285             :             sal_Int16       n;
    2286           0 :             switch( *p )
    2287             :             {
    2288           0 :                 case 'y':   n = -24;    break;      // yocto
    2289           0 :                 case 'z':   n = -21;    break;      // zepto
    2290           0 :                 case 'a':   n = -18;    break;
    2291           0 :                 case 'f':   n = -15;    break;
    2292           0 :                 case 'p':   n = -12;    break;
    2293           0 :                 case 'n':   n = -9;     break;
    2294           0 :                 case 'u':   n = -6;     break;
    2295           0 :                 case 'm':   n = -3;     break;
    2296           0 :                 case 'c':   n = -2;     break;
    2297             :                 case 'd':
    2298             :                     {
    2299           0 :                         if ( bOneChar )
    2300           0 :                             n = -1;                 // deci
    2301             :                         else
    2302           0 :                             n = 1;                  // deca
    2303             :                     }
    2304           0 :                     break;
    2305           0 :                 case 'e':   n = 1;      break;
    2306           0 :                 case 'h':   n = 2;      break;
    2307           0 :                 case 'k':   n = 3;      break;
    2308           0 :                 case 'M':   n = 6;      break;
    2309           0 :                 case 'G':   n = 9;      break;
    2310           0 :                 case 'T':   n = 12;     break;
    2311           0 :                 case 'P':   n = 15;     break;
    2312           0 :                 case 'E':   n = 18;     break;
    2313           0 :                 case 'Z':   n = 21;     break;      // zetta
    2314           0 :                 case 'Y':   n = 24;     break;      // yotta
    2315             :                 default:
    2316           0 :                             n = INV_MATCHLEV;
    2317             :             }
    2318             : 
    2319             : // We could weed some nonsense out, ODFF doesn't say so though.
    2320             : #if 0
    2321             :             if (n < 0 && Class() == CDC_Information)
    2322             :                 n = INV_MATCHLEV;   // milli-bits doesn't make sense
    2323             : #endif
    2324             : 
    2325             : //! <HACK> "cm3" is not 10^-2 m^3 but 10^-6 m^3 !!! ------------------
    2326           0 :             if( n != INV_MATCHLEV )
    2327             :             {
    2328           0 :                 sal_Unicode cLast = p[ aStr.getLength() - 1 ];
    2329           0 :                 if( cLast == '2' )
    2330           0 :                     n *= 2;
    2331           0 :                 else if( cLast == '3' )
    2332           0 :                     n *= 3;
    2333             :             }
    2334             : //! </HACK> -------------------------------------------------------------------
    2335             : 
    2336           0 :             return n;
    2337             :         }
    2338           0 :         else if ( nLen > 2 && ( aName == p + 2 ) && ( Class() == CDC_Information ) )
    2339             :         {
    2340           0 :             const sal_Unicode*  pStr = aStr.getStr();
    2341           0 :             if ( *(pStr + 1) != 'i')
    2342           0 :                 return INV_MATCHLEV;
    2343             :             sal_Int16 n;
    2344           0 :             switch( *pStr )
    2345             :             {
    2346           0 :                 case 'k':   n = 10;      break;
    2347           0 :                 case 'M':   n = 20;      break;
    2348           0 :                 case 'G':   n = 30;      break;
    2349           0 :                 case 'T':   n = 40;      break;
    2350           0 :                 case 'P':   n = 50;      break;
    2351           0 :                 case 'E':   n = 60;      break;
    2352           0 :                 case 'Z':   n = 70;      break;
    2353           0 :                 case 'Y':   n = 80;      break;
    2354             :                 default:
    2355           0 :                             n = INV_MATCHLEV;
    2356             :             }
    2357           0 :             return n;
    2358             :         }
    2359             :         else
    2360           0 :             return INV_MATCHLEV;
    2361           0 :     }
    2362             : }
    2363             : 
    2364             : 
    2365           0 : double ConvertData::Convert(
    2366             :     double f, const ConvertData& r, sal_Int16 nLevFrom, sal_Int16 nLevTo ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
    2367             : {
    2368           0 :     if( Class() != r.Class() )
    2369           0 :         throw lang::IllegalArgumentException();
    2370             : 
    2371           0 :     sal_Bool bBinFromLev = ( nLevFrom > 0 && ( nLevFrom % 10 ) == 0 );
    2372           0 :     sal_Bool bBinToLev   = ( nLevTo > 0 && ( nLevTo % 10 ) == 0 );
    2373             : 
    2374           0 :     if ( Class() == CDC_Information && ( bBinFromLev || bBinToLev ) )
    2375             :     {
    2376           0 :         if ( bBinFromLev && bBinToLev )
    2377             :         {
    2378           0 :             nLevFrom = sal::static_int_cast<sal_Int16>( nLevFrom - nLevTo );
    2379           0 :             f *= r.fConst / fConst;
    2380           0 :             if( nLevFrom )
    2381           0 :                 f *= pow( 2.0, nLevFrom );
    2382             :         }
    2383           0 :         else if ( bBinFromLev )
    2384           0 :             f *= ( r.fConst / fConst ) * ( pow( 2.0, nLevFrom ) / pow( 10.0, nLevTo ) );
    2385             :         else
    2386           0 :             f *= ( r.fConst / fConst ) * ( pow( 10.0, nLevFrom ) / pow( 2.0, nLevTo ) );
    2387           0 :         return f;
    2388             :     }
    2389             : 
    2390           0 :     nLevFrom = sal::static_int_cast<sal_Int16>( nLevFrom - nLevTo );    // effective level
    2391             : 
    2392           0 :     f *= r.fConst / fConst;
    2393             : 
    2394           0 :     if( nLevFrom )
    2395           0 :         f = ::rtl::math::pow10Exp( f, nLevFrom );
    2396             : 
    2397           0 :     return f;
    2398             : }
    2399             : 
    2400             : 
    2401           0 : double ConvertData::ConvertToBase( double f, sal_Int16 n ) const
    2402             : {
    2403           0 :     return ::rtl::math::pow10Exp( f / fConst, n );
    2404             : }
    2405             : 
    2406             : 
    2407           0 : double ConvertData::ConvertFromBase( double f, sal_Int16 n ) const
    2408             : {
    2409           0 :     return ::rtl::math::pow10Exp( f * fConst, -n );
    2410             : }
    2411             : 
    2412             : 
    2413             : 
    2414           0 : ConvertDataLinear::~ConvertDataLinear()
    2415             : {
    2416           0 : }
    2417             : 
    2418           0 : double ConvertDataLinear::Convert(
    2419             :     double f, const ConvertData& r, sal_Int16 nLevFrom, sal_Int16 nLevTo ) const throw( uno::RuntimeException, lang::IllegalArgumentException )
    2420             : {
    2421           0 :     if( Class() != r.Class() )
    2422           0 :         throw lang::IllegalArgumentException();
    2423           0 :     return r.ConvertFromBase( ConvertToBase( f, nLevFrom ), nLevTo );
    2424             : }
    2425             : 
    2426             : 
    2427           0 : double ConvertDataLinear::ConvertToBase( double f, sal_Int16 n ) const
    2428             : {
    2429           0 :     if( n )
    2430           0 :         f = ::rtl::math::pow10Exp( f, n );
    2431             : 
    2432           0 :     f /= fConst;
    2433           0 :     f -= fOffs;
    2434             : 
    2435           0 :     return f;
    2436             : }
    2437             : 
    2438             : 
    2439           0 : double ConvertDataLinear::ConvertFromBase( double f, sal_Int16 n ) const
    2440             : {
    2441           0 :     f += fOffs;
    2442           0 :     f *= fConst;
    2443             : 
    2444           0 :     if( n )
    2445           0 :         f = ::rtl::math::pow10Exp( f, -n );
    2446             : 
    2447           0 :     return f;
    2448             : }
    2449             : 
    2450             : 
    2451             : 
    2452             : 
    2453           0 : ConvertDataList::ConvertDataList( void )
    2454             : {
    2455             : #define NEWD(str,unit,cl)   Append(new ConvertData(str,unit,cl))
    2456             : #define NEWDP(str,unit,cl)  Append(new ConvertData(str,unit,cl,sal_True))
    2457             : #define NEWL(str,unit,offs,cl)  Append(new ConvertDataLinear(str,unit,offs,cl))
    2458             : #define NEWLP(str,unit,offs,cl) Append(new ConvertDataLinear(str,unit,offs,cl,sal_True))
    2459             : 
    2460             :     // *** are extra and not standard Excel Analysis Addin!
    2461             : 
    2462             :     // MASS: 1 Gram is...
    2463           0 :     NEWDP( "g",         1.0000000000000000E00,  CDC_Mass ); // Gram
    2464           0 :     NEWD( "sg",         6.8522050005347800E-05, CDC_Mass ); // Pieces
    2465           0 :     NEWD( "lbm",        2.2046229146913400E-03, CDC_Mass ); // Pound (commercial weight)
    2466           0 :     NEWDP( "u",         6.0221370000000000E23,  CDC_Mass ); // U (atomic mass)
    2467           0 :     NEWD( "ozm",        3.5273971800362700E-02, CDC_Mass ); // Ounce (commercial weight)
    2468           0 :     NEWD( "stone",      1.574730e-04,           CDC_Mass ); // *** Stone
    2469           0 :     NEWD( "ton",        1.102311e-06,           CDC_Mass ); // *** Ton
    2470           0 :     NEWD( "grain",      1.543236E01,            CDC_Mass ); // *** Grain
    2471           0 :     NEWD( "pweight",    7.054792E-01,           CDC_Mass ); // *** Pennyweight
    2472           0 :     NEWD( "hweight",    1.968413E-05,           CDC_Mass ); // *** Hundredweight
    2473           0 :     NEWD( "shweight",   2.204623E-05,           CDC_Mass ); // *** Shorthundredweight
    2474           0 :     NEWD( "brton",      9.842065E-07,           CDC_Mass ); // *** Gross Registered Ton
    2475           0 :     NEWD( "cwt",        2.2046226218487758E-05, CDC_Mass ); // U.S. (short) hundredweight
    2476           0 :     NEWD( "shweight",   2.2046226218487758E-05, CDC_Mass ); // U.S. (short) hundredweight also
    2477           0 :     NEWD( "uk_cwt",     1.9684130552221213E-05, CDC_Mass ); // Imperial hundredweight
    2478           0 :     NEWD( "lcwt",       1.9684130552221213E-05, CDC_Mass ); // Imperial hundredweight also
    2479           0 :     NEWD( "hweight",    1.9684130552221213E-05, CDC_Mass ); // Imperial hundredweight also
    2480           0 :     NEWD( "uk_ton",     9.8420652761106063E-07, CDC_Mass ); // Imperial ton
    2481           0 :     NEWD( "LTON",       9.8420652761106063E-07, CDC_Mass ); // Imperial ton also
    2482             : 
    2483             :     // LENGTH: 1 Meter is...
    2484           0 :     NEWDP( "m",         1.0000000000000000E00,  CDC_Length ); // Meter
    2485           0 :     NEWD( "mi",         6.2137119223733397E-04, CDC_Length ); // Britsh Mile        6,21371192237333969617434184363e-4
    2486           0 :     NEWD( "Nmi",        5.3995680345572354E-04, CDC_Length ); // Nautical Mile      5,39956803455723542116630669546e-4
    2487           0 :     NEWD( "in",         3.9370078740157480E01,  CDC_Length ); // Inch               39,37007874015748031496062992126
    2488           0 :     NEWD( "ft",         3.2808398950131234E00,  CDC_Length ); // Foot               3,2808398950131233595800524934383
    2489           0 :     NEWD( "yd",         1.0936132983377078E00,  CDC_Length ); // Yard               1,0936132983377077865266841644794
    2490           0 :     NEWDP( "ang",       1.0000000000000000E10,  CDC_Length ); // Angstroem
    2491           0 :     NEWD( "Pica",       2.8346456692913386E03,  CDC_Length ); // Pica (1/72 Inch)   2834,6456692913385826771653543307
    2492           0 :     NEWD( "ell",        8.748906E-01,           CDC_Length ); // *** Ell
    2493           0 :     NEWDP( "parsec",    3.240779E-17,           CDC_Length ); // *** Parsec
    2494           0 :     NEWDP( "pc",        3.240779E-17,           CDC_Length ); // *** Parsec also
    2495           0 :     NEWDP( "lightyear", 1.0570234557732930E-16, CDC_Length ); // *** Light Year
    2496           0 :     NEWDP( "ly",        1.0570234557732930E-16, CDC_Length ); // *** Light Year also
    2497           0 :     NEWD( "survey_mi",  6.2136994949494949E-04, CDC_Length ); // U.S. survey mile
    2498             : 
    2499             :     // TIME: 1 Second is...
    2500           0 :     NEWD( "yr",     3.1688087814028950E-08, CDC_Time ); // Year
    2501           0 :     NEWD( "day",    1.1574074074074074E-05, CDC_Time ); // Day
    2502           0 :     NEWD( "d",      1.1574074074074074E-05, CDC_Time ); // Day also
    2503           0 :     NEWD( "hr",     2.7777777777777778E-04, CDC_Time ); // Hour
    2504           0 :     NEWD( "mn",     1.6666666666666667E-02, CDC_Time ); // Minute
    2505           0 :     NEWD( "min",    1.6666666666666667E-02, CDC_Time ); // Minute also
    2506           0 :     NEWDP( "sec",   1.0000000000000000E00,  CDC_Time ); // Second
    2507           0 :     NEWDP( "s",     1.0000000000000000E00,  CDC_Time ); // Second also
    2508             : 
    2509             :     // PRESSURE: 1 Pascal is...
    2510           0 :     NEWDP( "Pa",    1.0000000000000000E00,  CDC_Pressure ); // Pascal
    2511           0 :     NEWDP( "atm",   9.8692329999819300E-06, CDC_Pressure ); // Atmosphere
    2512           0 :     NEWDP( "at",    9.8692329999819300E-06, CDC_Pressure ); // Atmosphere also
    2513           0 :     NEWDP( "mmHg",  7.5006170799862700E-03, CDC_Pressure ); // mm Hg (Mercury)
    2514           0 :     NEWD( "Torr",   7.5006380000000000E-03, CDC_Pressure ); // *** Torr
    2515           0 :     NEWD( "psi",    1.4503770000000000E-04, CDC_Pressure ); // *** Psi
    2516             : 
    2517             :     // FORCE: 1 Newton is...
    2518           0 :     NEWDP( "N",     1.0000000000000000E00,  CDC_Force ); // Newton
    2519           0 :     NEWDP( "dyn",   1.0000000000000000E05,  CDC_Force ); // Dyn
    2520           0 :     NEWDP( "dy",    1.0000000000000000E05,  CDC_Force ); // Dyn also
    2521           0 :     NEWD( "lbf",    2.24808923655339E-01,   CDC_Force ); // Pound-Force
    2522           0 :     NEWDP( "pond",  1.019716E02,            CDC_Force ); // *** Pond
    2523             : 
    2524             :     // ENERGY: 1 Joule is...
    2525           0 :     NEWDP( "J",     1.0000000000000000E00,  CDC_Energy ); // Joule
    2526           0 :     NEWDP( "e",     1.0000000000000000E07,  CDC_Energy ); // Erg  -> http://www.chemie.fu-berlin.de/chemistry/general/si.html
    2527           0 :     NEWDP( "c",     2.3900624947346700E-01, CDC_Energy ); // Thermodynamical Calorie
    2528           0 :     NEWDP( "cal",   2.3884619064201700E-01, CDC_Energy ); // Calorie
    2529           0 :     NEWDP( "eV",    6.2414570000000000E18,  CDC_Energy ); // Electronvolt
    2530           0 :     NEWDP( "ev",    6.2414570000000000E18,  CDC_Energy ); // Electronvolt also
    2531           0 :     NEWD( "HPh",    3.7250611111111111E-07, CDC_Energy ); // Horsepower Hours
    2532           0 :     NEWD( "hh",     3.7250611111111111E-07, CDC_Energy ); // Horsepower Hours also
    2533           0 :     NEWDP( "Wh",    2.7777777777777778E-04, CDC_Energy ); // Watt Hours
    2534           0 :     NEWDP( "wh",    2.7777777777777778E-04, CDC_Energy ); // Watt Hours also
    2535           0 :     NEWD( "flb",    2.37304222192651E01,    CDC_Energy ); // Foot Pound
    2536           0 :     NEWD( "BTU",    9.4781506734901500E-04, CDC_Energy ); // British Thermal Unit
    2537           0 :     NEWD( "btu",    9.4781506734901500E-04, CDC_Energy ); // British Thermal Unit also
    2538             : 
    2539             :     // POWER: 1 Watt is...
    2540           0 :     NEWDP( "W",     1.0000000000000000E00,  CDC_Power ); // Watt
    2541           0 :     NEWDP( "w",     1.0000000000000000E00,  CDC_Power ); // Watt also
    2542           0 :     NEWD( "HP",     1.341022E-03,           CDC_Power ); // Horsepower
    2543           0 :     NEWD( "h",      1.341022E-03,           CDC_Power ); // Horsepower also
    2544           0 :     NEWD( "PS",     1.359622E-03,           CDC_Power ); // *** German Pferdestaerke
    2545             : 
    2546             :     // MAGNETISM: 1 Tesla is...
    2547           0 :     NEWDP( "T",     1.0000000000000000E00,  CDC_Magnetism ); // Tesla
    2548           0 :     NEWDP( "ga",    1.0000000000000000E04,  CDC_Magnetism ); // Gauss
    2549             : 
    2550             :     // TEMERATURE: 1 Kelvin is...
    2551           0 :     NEWL( "C",      1.0000000000000000E00,  -2.7315000000000000E02, CDC_Temperature ); // Celsius
    2552           0 :     NEWL( "cel",    1.0000000000000000E00,  -2.7315000000000000E02, CDC_Temperature ); // Celsius also
    2553           0 :     NEWL( "F",      1.8000000000000000E00,  -2.5537222222222222E02, CDC_Temperature ); // Fahrenheit
    2554           0 :     NEWL( "fah",    1.8000000000000000E00,  -2.5537222222222222E02, CDC_Temperature ); // Fahrenheit also
    2555           0 :     NEWLP( "K",     1.0000000000000000E00,  +0.0000000000000000E00, CDC_Temperature ); // Kelvin
    2556           0 :     NEWLP( "kel",   1.0000000000000000E00,  +0.0000000000000000E00, CDC_Temperature ); // Kelvin also
    2557           0 :     NEWL( "Reau",   8.0000000000000000E-01, -2.7315000000000000E02, CDC_Temperature ); // *** Reaumur
    2558           0 :     NEWL( "Rank",   1.8000000000000000E00,  +0.0000000000000000E00, CDC_Temperature ); // *** Rankine
    2559             : 
    2560             :     // VOLUMNE: 1 Liter is...
    2561           0 :     NEWD( "tsp",        2.0288413621105798E02,  CDC_Volume ); // US teaspoon            1/768 gallon
    2562           0 :     NEWD( "tbs",        6.7628045403685994E01,  CDC_Volume ); // US tablespoon          1/256 gallon
    2563           0 :     NEWD( "oz",         3.3814022701842997E01,  CDC_Volume ); // Ounce Liquid           1/128 gallon
    2564           0 :     NEWD( "cup",        4.2267528377303746E00,  CDC_Volume ); // Cup                    1/16 gallon
    2565           0 :     NEWD( "pt",         2.1133764188651873E00,  CDC_Volume ); // US Pint                1/8 gallon
    2566           0 :     NEWD( "us_pt",      2.1133764188651873E00,  CDC_Volume ); // US Pint also
    2567           0 :     NEWD( "uk_pt",      1.7597539863927023E00,  CDC_Volume ); // UK Pint                1/8 imperial gallon
    2568           0 :     NEWD( "qt",         1.0566882094325937E00,  CDC_Volume ); // Quart                  1/4 gallon
    2569           0 :     NEWD( "gal",        2.6417205235814842E-01, CDC_Volume ); // Gallon                 1/3.785411784
    2570           0 :     NEWDP( "l",         1.0000000000000000E00,  CDC_Volume ); // Liter
    2571           0 :     NEWDP( "L",         1.0000000000000000E00,  CDC_Volume ); // Liter also
    2572           0 :     NEWDP( "lt",        1.0000000000000000E00,  CDC_Volume ); // Liter also
    2573           0 :     NEWDP( "m3",        1.0000000000000000E-03, CDC_Volume ); // *** Cubic Meter
    2574           0 :     NEWD( "mi3",        2.3991275857892772E-13, CDC_Volume ); // *** Cubic Britsh Mile
    2575           0 :     NEWD( "Nmi3",       1.5742621468581148E-13, CDC_Volume ); // *** Cubic Nautical Mile
    2576           0 :     NEWD( "in3",        6.1023744094732284E01,  CDC_Volume ); // *** Cubic Inch
    2577           0 :     NEWD( "ft3",        3.5314666721488590E-02, CDC_Volume ); // *** Cubic Foot
    2578           0 :     NEWD( "yd3",        1.3079506193143922E-03, CDC_Volume ); // *** Cubic Yard
    2579           0 :     NEWDP( "ang3",      1.0000000000000000E27,  CDC_Volume ); // *** Cubic Angstroem
    2580           0 :     NEWD( "Pica3",      2.2776990435870636E07,  CDC_Volume ); // *** Cubic Pica
    2581           0 :     NEWD( "barrel",     6.2898107704321051E-03, CDC_Volume ); // *** Barrel (=42gal)
    2582           0 :     NEWD( "bushel",     2.837759E-02,           CDC_Volume ); // *** Bushel
    2583           0 :     NEWD( "regton",     3.531467E-04,           CDC_Volume ); // *** Register ton
    2584           0 :     NEWD( "GRT",        3.531467E-04,           CDC_Volume ); // *** Register ton also
    2585           0 :     NEWD( "Schooner",   2.3529411764705882E00,  CDC_Volume ); // *** austr. Schooner
    2586           0 :     NEWD( "Middy",      3.5087719298245614E00,  CDC_Volume ); // *** austr. Middy
    2587           0 :     NEWD( "Glass",      5.0000000000000000E00,  CDC_Volume ); // *** austr. Glass
    2588           0 :     NEWD( "Sixpack",    0.5,                    CDC_Volume ); // ***
    2589           0 :     NEWD( "Humpen",     2.0,                    CDC_Volume ); // ***
    2590           0 :     NEWD( "ly3",        1.1810108125623799E-51, CDC_Volume ); // *** Cubic light-year
    2591           0 :     NEWD( "MTON",       1.4125866688595436E00,  CDC_Volume ); // *** Measurement ton
    2592           0 :     NEWD( "tspm",       2.0000000000000000E02,  CDC_Volume ); // *** Modern teaspoon
    2593           0 :     NEWD( "uk_gal",     2.1996924829908779E-01,  CDC_Volume ); // U.K. / Imperial gallon        1/4.54609
    2594           0 :     NEWD( "uk_qt",      8.7987699319635115E-01,  CDC_Volume ); // U.K. / Imperial quart         1/4 imperial gallon
    2595             : 
    2596             :     // 1 Square Meter is...
    2597           0 :     NEWDP( "m2",        1.0000000000000000E00,  CDC_Area ); // *** Square Meter
    2598           0 :     NEWD( "mi2",        3.8610215854244585E-07, CDC_Area ); // *** Square Britsh Mile
    2599           0 :     NEWD( "Nmi2",       2.9155334959812286E-07, CDC_Area ); // *** Square Nautical Mile
    2600           0 :     NEWD( "in2",        1.5500031000062000E03,  CDC_Area ); // *** Square Inch
    2601           0 :     NEWD( "ft2",        1.0763910416709722E01,  CDC_Area ); // *** Square Foot
    2602           0 :     NEWD( "yd2",        1.1959900463010803E00,  CDC_Area ); // *** Square Yard
    2603           0 :     NEWDP( "ang2",      1.0000000000000000E20,  CDC_Area ); // *** Square Angstroem
    2604           0 :     NEWD( "Pica2",      8.0352160704321409E06,  CDC_Area ); // *** Square Pica
    2605           0 :     NEWD( "Morgen",     4.0000000000000000E-04, CDC_Area ); // *** Morgen
    2606           0 :     NEWDP( "ar",        1.000000E-02,           CDC_Area ); // *** Ar
    2607           0 :     NEWD( "acre",       2.471053815E-04,        CDC_Area ); // *** Acre
    2608           0 :     NEWD( "uk_acre",    2.4710538146716534E-04, CDC_Area ); // *** International acre
    2609           0 :     NEWD( "us_acre",    2.4710439304662790E-04, CDC_Area ); // *** U.S. survey/statute acre
    2610           0 :     NEWD( "ly2",        1.1172985860549147E-32, CDC_Area ); // *** Square Light-year
    2611           0 :     NEWD( "ha",         1.000000E-04,           CDC_Area ); // *** Hectare
    2612           0 :     NEWD( "Quadratlatschen",5.6689342403628117914,CDC_Area ); // ***
    2613             : 
    2614             :     // SPEED: 1 Meter per Second is...
    2615           0 :     NEWDP( "m/s",   1.0000000000000000E00,  CDC_Speed ); // *** Meters per Second
    2616           0 :     NEWDP( "m/sec", 1.0000000000000000E00,  CDC_Speed ); // *** Meters per Second also
    2617           0 :     NEWDP( "m/h",   3.6000000000000000E03,  CDC_Speed ); // *** Meters per Hour
    2618           0 :     NEWDP( "m/hr",  3.6000000000000000E03,  CDC_Speed ); // *** Meters per Hour also
    2619           0 :     NEWD( "mph",    2.2369362920544023E00,  CDC_Speed ); // *** Britsh Miles per Hour
    2620           0 :     NEWD( "kn",     1.9438444924406048E00,  CDC_Speed ); // *** Knot = Nautical Miles per Hour
    2621           0 :     NEWD( "admkn",  1.9438446603753486E00,  CDC_Speed ); // *** Admiralty Knot
    2622           0 :     NEWD( "wahnsinnige Geschwindigkeit", 2.0494886343432328E-14, CDC_Speed ); // ***
    2623           0 :     NEWD( "ludicrous speed", 2.0494886343432328E-14, CDC_Speed ); // ***
    2624           0 :     NEWD( "laecherliche Geschwindigkeit", 4.0156958471424288E-06, CDC_Speed); // ***
    2625           0 :     NEWD( "ridiculous speed", 4.0156958471424288E-06, CDC_Speed); // ***
    2626             : 
    2627             :     // INFORMATION: 1 Bit is...
    2628           0 :     NEWDP( "bit",   1.00E00,  CDC_Information); // *** Bit
    2629           0 :     NEWDP( "byte",  1.25E-01, CDC_Information); // *** Byte
    2630           0 : }
    2631             : 
    2632             : 
    2633           0 : ConvertDataList::~ConvertDataList()
    2634             : {
    2635           0 :     for( ConvertData* p = First() ; p ; p = Next() )
    2636           0 :         delete p;
    2637           0 : }
    2638             : 
    2639             : 
    2640           0 : double ConvertDataList::Convert( double fVal, const OUString& rFrom, const OUString& rTo ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2641             : {
    2642           0 :     ConvertData*    pFrom = NULL;
    2643           0 :     ConvertData*    pTo = NULL;
    2644           0 :     sal_Bool        bSearchFrom = sal_True;
    2645           0 :     sal_Bool        bSearchTo = sal_True;
    2646           0 :     sal_Int16       nLevelFrom = 0;
    2647           0 :     sal_Int16       nLevelTo = 0;
    2648             : 
    2649           0 :     ConvertData*    p = First();
    2650           0 :     while( p && ( bSearchFrom || bSearchTo ) )
    2651             :     {
    2652           0 :         if( bSearchFrom )
    2653             :         {
    2654           0 :             sal_Int16   n = p->GetMatchingLevel( rFrom );
    2655           0 :             if( n != INV_MATCHLEV )
    2656             :             {
    2657           0 :                 if( n )
    2658             :                 {   // only first match for partial equality rulz a little bit more
    2659           0 :                     pFrom = p;
    2660           0 :                     nLevelFrom = n;
    2661             :                 }
    2662             :                 else
    2663             :                 {   // ... but exact match rulz most
    2664           0 :                     pFrom = p;
    2665           0 :                     bSearchFrom = sal_False;
    2666           0 :                     nLevelFrom = n;
    2667             :                 }
    2668             :             }
    2669             :         }
    2670             : 
    2671           0 :         if( bSearchTo )
    2672             :         {
    2673           0 :             sal_Int16   n = p->GetMatchingLevel( rTo );
    2674           0 :             if( n != INV_MATCHLEV )
    2675             :             {
    2676           0 :                 if( n )
    2677             :                 {   // only first match for partial equality rulz a little bit more
    2678           0 :                     pTo = p;
    2679           0 :                     nLevelTo = n;
    2680             :                 }
    2681             :                 else
    2682             :                 {   // ... but exact match rulz most
    2683           0 :                     pTo = p;
    2684           0 :                     bSearchTo = sal_False;
    2685           0 :                     nLevelTo = n;
    2686             :                 }
    2687             :             }
    2688             :         }
    2689             : 
    2690           0 :         p = Next();
    2691             :     }
    2692             : 
    2693           0 :     if( pFrom && pTo )
    2694           0 :         return pFrom->Convert( fVal, *pTo, nLevelFrom, nLevelTo );
    2695             :     else
    2696           0 :         throw lang::IllegalArgumentException();
    2697             : }
    2698             : 
    2699             : 
    2700             : 
    2701             : //-----------------------------------------------------------------------------
    2702             : 
    2703           0 : ScaDate::ScaDate() :
    2704             :     nOrigDay( 1 ),
    2705             :     nDay( 1 ),
    2706             :     nMonth( 1 ),
    2707             :     nYear( 1900 ),
    2708             :     bLastDayMode( sal_True ),
    2709             :     bLastDay( sal_False ),
    2710             :     b30Days( sal_False ),
    2711           0 :     bUSMode( sal_False )
    2712             : {
    2713           0 : }
    2714             : 
    2715           0 : ScaDate::ScaDate( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nBase )
    2716             : {
    2717           0 :     DaysToDate( nNullDate + nDate, nOrigDay, nMonth, nYear );
    2718           0 :     bLastDayMode = (nBase != 5);
    2719           0 :     bLastDay = (nOrigDay >= ::DaysInMonth( nMonth, nYear ));
    2720           0 :     b30Days = (nBase == 0) || (nBase == 4);
    2721           0 :     bUSMode = (nBase == 0);
    2722           0 :     setDay();
    2723           0 : }
    2724             : 
    2725           0 : ScaDate::ScaDate( const ScaDate& rCopy ) :
    2726             :     nOrigDay( rCopy.nOrigDay ),
    2727             :     nDay( rCopy.nDay ),
    2728             :     nMonth( rCopy.nMonth ),
    2729             :     nYear( rCopy.nYear ),
    2730             :     bLastDayMode( rCopy.bLastDayMode ),
    2731             :     bLastDay( rCopy.bLastDay ),
    2732             :     b30Days( rCopy.b30Days ),
    2733           0 :     bUSMode( rCopy.bUSMode )
    2734             : {
    2735           0 : }
    2736             : 
    2737           0 : ScaDate& ScaDate::operator=( const ScaDate& rCopy )
    2738             : {
    2739           0 :     if( this != &rCopy )
    2740             :     {
    2741           0 :         nOrigDay = rCopy.nOrigDay;
    2742           0 :         nDay = rCopy.nDay;
    2743           0 :         nMonth = rCopy.nMonth;
    2744           0 :         nYear = rCopy.nYear;
    2745           0 :         bLastDayMode = rCopy.bLastDayMode;
    2746           0 :         bLastDay = rCopy.bLastDay;
    2747           0 :         b30Days = rCopy.b30Days;
    2748           0 :         bUSMode = rCopy.bUSMode;
    2749             :     }
    2750           0 :     return *this;
    2751             : }
    2752             : 
    2753           0 : void ScaDate::setDay()
    2754             : {
    2755           0 :     if( b30Days )
    2756             :     {
    2757             :         // 30-days-mode: set nDay to 30 if original was last day in month
    2758           0 :         nDay = std::min( nOrigDay, static_cast< sal_uInt16 >( 30 ) );
    2759           0 :         if( bLastDay || (nDay >= ::DaysInMonth( nMonth, nYear )) )
    2760           0 :             nDay = 30;
    2761             :     }
    2762             :     else
    2763             :     {
    2764             :         // set nDay to last day in this month if original was last day
    2765           0 :         sal_uInt16 nLastDay = ::DaysInMonth( nMonth, nYear );
    2766           0 :         nDay = bLastDay ? nLastDay : std::min( nOrigDay, nLastDay );
    2767             :     }
    2768           0 : }
    2769             : 
    2770           0 : sal_Int32 ScaDate::getDaysInMonthRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const
    2771             : {
    2772           0 :     if( nFrom > nTo )
    2773           0 :         return 0;
    2774             : 
    2775           0 :     sal_Int32 nRet = 0;
    2776           0 :     if( b30Days )
    2777           0 :         nRet = (nTo - nFrom + 1) * 30;
    2778             :     else
    2779             :     {
    2780           0 :         for( sal_uInt16 nMonthIx = nFrom; nMonthIx <= nTo; ++nMonthIx )
    2781           0 :             nRet += getDaysInMonth( nMonthIx );
    2782             :     }
    2783           0 :     return nRet;
    2784             : }
    2785             : 
    2786           0 : sal_Int32 ScaDate::getDaysInYearRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const
    2787             : {
    2788           0 :     if( nFrom > nTo )
    2789           0 :         return 0;
    2790             : 
    2791           0 :     return b30Days ? ((nTo - nFrom + 1) * 360) : ::GetDaysInYears( nFrom, nTo );
    2792             : }
    2793             : 
    2794           0 : void ScaDate::doAddYears( sal_Int32 nYearCount ) throw( lang::IllegalArgumentException )
    2795             : {
    2796           0 :     sal_Int32 nNewYear = nYearCount + nYear;
    2797           0 :     if( (nNewYear < 0) || (nNewYear > 0x7FFF) )
    2798           0 :         throw lang::IllegalArgumentException();
    2799           0 :     nYear = static_cast< sal_uInt16 >( nNewYear );
    2800           0 : }
    2801             : 
    2802           0 : void ScaDate::addMonths( sal_Int32 nMonthCount ) throw( lang::IllegalArgumentException )
    2803             : {
    2804           0 :     sal_Int32 nNewMonth = nMonthCount + nMonth;
    2805           0 :     if( nNewMonth > 12 )
    2806             :     {
    2807           0 :         --nNewMonth;
    2808           0 :         doAddYears( nNewMonth / 12 );
    2809           0 :         nMonth = static_cast< sal_uInt16 >( nNewMonth % 12 ) + 1;
    2810             :     }
    2811           0 :     else if( nNewMonth < 1 )
    2812             :     {
    2813           0 :         doAddYears( nNewMonth / 12 - 1 );
    2814           0 :         nMonth = static_cast< sal_uInt16 >( nNewMonth % 12 + 12 );
    2815             :     }
    2816             :     else
    2817           0 :         nMonth = static_cast< sal_uInt16 >( nNewMonth );
    2818           0 :     setDay();
    2819           0 : }
    2820             : 
    2821           0 : sal_Int32 ScaDate::getDate( sal_Int32 nNullDate ) const
    2822             : {
    2823           0 :     sal_uInt16 nLastDay = ::DaysInMonth( nMonth, nYear );
    2824           0 :     sal_uInt16 nRealDay = (bLastDayMode && bLastDay) ? nLastDay : std::min( nLastDay, nOrigDay );
    2825           0 :     return ::DateToDays( nRealDay, nMonth, nYear ) - nNullDate;
    2826             : }
    2827             : 
    2828           0 : sal_Int32 ScaDate::getDiff( const ScaDate& rFrom, const ScaDate& rTo ) throw( lang::IllegalArgumentException )
    2829             : {
    2830           0 :     if( rFrom > rTo )
    2831           0 :         return getDiff( rTo, rFrom );
    2832             : 
    2833           0 :     sal_Int32 nDiff = 0;
    2834           0 :     ScaDate aFrom( rFrom );
    2835           0 :     ScaDate aTo( rTo );
    2836             : 
    2837           0 :     if( rTo.b30Days )
    2838             :     {
    2839             :         // corrections for base 0 (US NASD)
    2840           0 :         if( rTo.bUSMode )
    2841             :         {
    2842           0 :             if( ((rFrom.nMonth == 2) || (rFrom.nDay < 30)) && (aTo.nOrigDay == 31) )
    2843           0 :                 aTo.nDay = 31;
    2844           0 :             else if( (aTo.nMonth == 2) && aTo.bLastDay )
    2845           0 :                 aTo.nDay = ::DaysInMonth( 2, aTo.nYear );
    2846             :         }
    2847             :         // corrections for base 4 (Europe)
    2848             :         else
    2849             :         {
    2850           0 :             if( (aFrom.nMonth == 2) && (aFrom.nDay == 30) )
    2851           0 :                 aFrom.nDay = ::DaysInMonth( 2, aFrom.nYear );
    2852           0 :             if( (aTo.nMonth == 2) && (aTo.nDay == 30) )
    2853           0 :                 aTo.nDay = ::DaysInMonth( 2, aTo.nYear );
    2854             :         }
    2855             :     }
    2856             : 
    2857           0 :     if( (aFrom.nYear < aTo.nYear) || ((aFrom.nYear == aTo.nYear) && (aFrom.nMonth < aTo.nMonth)) )
    2858             :     {
    2859             :         // move aFrom to 1st day of next month
    2860           0 :         nDiff = aFrom.getDaysInMonth() - aFrom.nDay + 1;
    2861           0 :         aFrom.nOrigDay = aFrom.nDay = 1;
    2862           0 :         aFrom.bLastDay = sal_False;
    2863           0 :         aFrom.addMonths( 1 );
    2864             : 
    2865           0 :         if( aFrom.nYear < aTo.nYear )
    2866             :         {
    2867             :             // move aFrom to 1st day of next year
    2868           0 :             nDiff += aFrom.getDaysInMonthRange( aFrom.nMonth, 12 );
    2869           0 :             aFrom.addMonths( 13 - aFrom.nMonth );
    2870             : 
    2871             :             // move aFrom to 1st day of this year
    2872           0 :             nDiff += aFrom.getDaysInYearRange( aFrom.nYear, aTo.nYear - 1 );
    2873           0 :             aFrom.addYears( aTo.nYear - aFrom.nYear );
    2874             :         }
    2875             : 
    2876             :         // move aFrom to 1st day of this month
    2877           0 :         nDiff += aFrom.getDaysInMonthRange( aFrom.nMonth, aTo.nMonth - 1 );
    2878           0 :         aFrom.addMonths( aTo.nMonth - aFrom.nMonth );
    2879             :     }
    2880             :     // finally add remaining days in this month
    2881           0 :     nDiff += aTo.nDay - aFrom.nDay;
    2882           0 :     return nDiff > 0 ? nDiff : 0;
    2883             : }
    2884             : 
    2885           0 : sal_Bool ScaDate::operator<( const ScaDate& rCmp ) const
    2886             : {
    2887           0 :     if( nYear != rCmp.nYear )
    2888           0 :         return nYear < rCmp.nYear;
    2889           0 :     if( nMonth != rCmp.nMonth )
    2890           0 :         return nMonth < rCmp.nMonth;
    2891           0 :     if( nDay != rCmp.nDay )
    2892           0 :         return nDay < rCmp.nDay;
    2893           0 :     if( bLastDay || rCmp.bLastDay )
    2894           0 :         return !bLastDay && rCmp.bLastDay;
    2895           0 :     return nOrigDay < rCmp.nOrigDay;
    2896             : }
    2897             : 
    2898             : 
    2899             : 
    2900             : //-----------------------------------------------------------------------------
    2901             : 
    2902           9 : ScaAnyConverter::ScaAnyConverter( const uno::Reference< uno::XComponentContext >& xContext ) :
    2903           9 :     bHasValidFormat( sal_False )
    2904             : {
    2905           9 :     xFormatter = util::NumberFormatter::create(xContext);
    2906           9 : }
    2907             : 
    2908           4 : ScaAnyConverter::~ScaAnyConverter()
    2909             : {
    2910           4 : }
    2911             : 
    2912           0 : void ScaAnyConverter::init( const uno::Reference< beans::XPropertySet >& xPropSet ) throw( uno::RuntimeException )
    2913             : {
    2914             :     // try to get default number format
    2915           0 :     bHasValidFormat = sal_False;
    2916           0 :     if( xFormatter.is() )
    2917             :     {
    2918             :         // get XFormatsSupplier from outer XPropertySet
    2919           0 :         uno::Reference< util::XNumberFormatsSupplier > xFormatsSupp( xPropSet, uno::UNO_QUERY );
    2920           0 :         if( xFormatsSupp.is() )
    2921             :         {
    2922             :             // get XNumberFormatTypes from XNumberFormatsSupplier to get standard index
    2923           0 :             uno::Reference< util::XNumberFormats > xFormats( xFormatsSupp->getNumberFormats() );
    2924           0 :             uno::Reference< util::XNumberFormatTypes > xFormatTypes( xFormats, uno::UNO_QUERY );
    2925           0 :             if( xFormatTypes.is() )
    2926             :             {
    2927           0 :                 lang::Locale eLocale;
    2928           0 :                 nDefaultFormat = xFormatTypes->getStandardIndex( eLocale );
    2929           0 :                 xFormatter->attachNumberFormatsSupplier( xFormatsSupp );
    2930           0 :                 bHasValidFormat = sal_True;
    2931           0 :             }
    2932           0 :         }
    2933             :     }
    2934           0 : }
    2935             : 
    2936           0 : double ScaAnyConverter::convertToDouble( const OUString& rString ) const throw( lang::IllegalArgumentException )
    2937             : {
    2938           0 :     double fValue = 0.0;
    2939           0 :     if( bHasValidFormat )
    2940             :     {
    2941             :         try
    2942             :         {
    2943           0 :             fValue = xFormatter->convertStringToNumber( nDefaultFormat, rString );
    2944             :         }
    2945           0 :         catch( uno::Exception& )
    2946             :         {
    2947           0 :             throw lang::IllegalArgumentException();
    2948             :         }
    2949             :     }
    2950             :     else
    2951             :     {
    2952             :         rtl_math_ConversionStatus eStatus;
    2953             :         sal_Int32 nEnd;
    2954           0 :         fValue = ::rtl::math::stringToDouble( rString, '.', ',', &eStatus, &nEnd );
    2955           0 :         if( (eStatus != rtl_math_ConversionStatus_Ok) || (nEnd < rString.getLength()) )
    2956           0 :             throw lang::IllegalArgumentException();
    2957             :     }
    2958           0 :     return fValue;
    2959             : }
    2960             : 
    2961           0 : sal_Bool ScaAnyConverter::getDouble(
    2962             :         double& rfResult,
    2963             :         const uno::Any& rAny ) const throw( lang::IllegalArgumentException )
    2964             : {
    2965           0 :     rfResult = 0.0;
    2966           0 :     sal_Bool bContainsVal = sal_True;
    2967           0 :     switch( rAny.getValueTypeClass() )
    2968             :     {
    2969             :         case uno::TypeClass_VOID:
    2970           0 :             bContainsVal = sal_False;
    2971           0 :         break;
    2972             :         case uno::TypeClass_DOUBLE:
    2973           0 :             rAny >>= rfResult;
    2974           0 :         break;
    2975             :         case uno::TypeClass_STRING:
    2976             :         {
    2977           0 :             const OUString* pString = static_cast< const OUString* >( rAny.getValue() );
    2978           0 :             if( !pString->isEmpty() )
    2979           0 :                 rfResult = convertToDouble( *pString );
    2980             :             else
    2981           0 :                 bContainsVal = sal_False;
    2982             :         }
    2983           0 :         break;
    2984             :         default:
    2985           0 :             throw lang::IllegalArgumentException();
    2986             :     }
    2987           0 :     return bContainsVal;
    2988             : }
    2989             : 
    2990           0 : sal_Bool ScaAnyConverter::getDouble(
    2991             :         double& rfResult,
    2992             :         const uno::Reference< beans::XPropertySet >& xPropSet,
    2993             :         const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    2994             : {
    2995           0 :     init( xPropSet );
    2996           0 :     return getDouble( rfResult, rAny );
    2997             : }
    2998             : 
    2999           0 : double ScaAnyConverter::getDouble(
    3000             :         const uno::Reference< beans::XPropertySet >& xPropSet,
    3001             :         const uno::Any& rAny,
    3002             :         double fDefault ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    3003             : {
    3004             :     double fResult;
    3005           0 :     if( !getDouble( fResult, xPropSet, rAny ) )
    3006           0 :         fResult = fDefault;
    3007           0 :     return fResult;
    3008             : }
    3009             : 
    3010           0 : sal_Bool ScaAnyConverter::getInt32(
    3011             :         sal_Int32& rnResult,
    3012             :         const uno::Reference< beans::XPropertySet >& xPropSet,
    3013             :         const uno::Any& rAny ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    3014             : {
    3015             :     double fResult;
    3016           0 :     sal_Bool bContainsVal = getDouble( fResult, xPropSet, rAny );
    3017           0 :     if( (fResult <= -2147483649.0) || (fResult >= 2147483648.0) )
    3018           0 :         throw lang::IllegalArgumentException();
    3019             : 
    3020           0 :     rnResult = static_cast< sal_Int32 >( fResult );
    3021           0 :     return bContainsVal;
    3022             : }
    3023             : 
    3024           0 : sal_Int32 ScaAnyConverter::getInt32(
    3025             :         const uno::Reference< beans::XPropertySet >& xPropSet,
    3026             :         const uno::Any& rAny,
    3027             :         sal_Int32 nDefault ) throw( uno::RuntimeException, lang::IllegalArgumentException )
    3028             : {
    3029             :     sal_Int32 nResult;
    3030           0 :     if( !getInt32( nResult, xPropSet, rAny ) )
    3031           0 :         nResult = nDefault;
    3032           0 :     return nResult;
    3033             : }
    3034             : 
    3035             : 
    3036             : 
    3037             : //-----------------------------------------------------------------------------
    3038             : 
    3039             : 
    3040             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10