Bug Summary

File:home/maarten/src/libreoffice/core/include/com/sun/star/uno/Any.hxx
Warning:line 577, column 17
Dereference of null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name analysishelper.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/scaddins/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/comprehensive -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/scaddins/comprehensive -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/comprehensive -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/scaddins/source/analysis/analysishelper.cxx

/home/maarten/src/libreoffice/core/scaddins/source/analysis/analysishelper.cxx

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

/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Any.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#ifndef INCLUDED_COM_SUN_STAR_UNO_ANY_HXX
20#define INCLUDED_COM_SUN_STAR_UNO_ANY_HXX
21
22#include "sal/config.h"
23
24#include <algorithm>
25#include <cassert>
26#include <cstddef>
27#include <iomanip>
28#include <ostream>
29#include <utility>
30
31#include "com/sun/star/uno/Any.h"
32#include "uno/data.h"
33#include "uno/sequence2.h"
34#include "com/sun/star/uno/Type.hxx"
35#include "com/sun/star/uno/Reference.h"
36#include "com/sun/star/uno/genfunc.hxx"
37#include "com/sun/star/uno/RuntimeException.hpp"
38#include "cppu/cppudllapi.h"
39#include "cppu/unotype.hxx"
40
41extern "C" CPPU_DLLPUBLIC__attribute__ ((visibility("default"))) rtl_uString * SAL_CALL cppu_Any_extraction_failure_msg(
42 uno_Any const * pAny, typelib_TypeDescriptionReference * pType )
43 SAL_THROW_EXTERN_C()throw ();
44
45namespace com
46{
47namespace sun
48{
49namespace star
50{
51namespace uno
52{
53
54
55inline Any::Any()
56{
57 ::uno_any_construct( this, NULL__null, NULL__null, cpp_acquire );
58}
59
60
61template <typename T>
62inline Any::Any( T const & value )
63{
64 ::uno_type_any_construct(
65 this, const_cast<T *>(&value),
66 ::cppu::getTypeFavourUnsigned(&value).getTypeLibType(),
67 cpp_acquire );
68}
69
70inline Any::Any( bool value )
71{
72 sal_Bool b = value;
73 ::uno_type_any_construct(
74 this, &b, cppu::UnoType<bool>::get().getTypeLibType(),
75 cpp_acquire );
76}
77
78#if defined LIBO_INTERNAL_ONLY1
79template<typename T1, typename T2>
80Any::Any(rtl::OUStringConcat<T1, T2> && value):
81 Any(rtl::OUString(std::move(value)))
82{}
83#endif
84
85inline Any::Any( const Any & rAny )
86{
87 ::uno_type_any_construct( this, rAny.pData, rAny.pType, cpp_acquire );
88}
89
90inline Any::Any( const void * pData_, const Type & rType )
91{
92 ::uno_type_any_construct(
93 this, const_cast< void * >( pData_ ), rType.getTypeLibType(),
94 cpp_acquire );
95}
96
97inline Any::Any( const void * pData_, typelib_TypeDescription * pTypeDescr )
98{
99 ::uno_any_construct(
100 this, const_cast< void * >( pData_ ), pTypeDescr, cpp_acquire );
101}
102
103inline Any::Any( const void * pData_, typelib_TypeDescriptionReference * pType_ )
104{
105 ::uno_type_any_construct(
106 this, const_cast< void * >( pData_ ), pType_, cpp_acquire );
107}
108
109inline Any::~Any()
110{
111 ::uno_any_destruct(
112 this, cpp_release );
113}
114
115inline Any & Any::operator = ( const Any & rAny )
116{
117 if (this != &rAny)
118 {
119 ::uno_type_any_assign(
120 this, rAny.pData, rAny.pType,
121 cpp_acquire, cpp_release );
122 }
123 return *this;
124}
125
126#if defined LIBO_INTERNAL_ONLY1
127
128namespace detail {
129
130inline void moveAnyInternals(Any & from, Any & to) noexcept {
131 uno_any_construct(&to, nullptr, nullptr, &cpp_acquire);
132 std::swap(from.pType, to.pType);
133 std::swap(from.pData, to.pData);
134 std::swap(from.pReserved, to.pReserved);
135 if (to.pData == &from.pReserved) {
136 to.pData = &to.pReserved;
137 }
138 // This leaves from.pData (where "from" is now VOID) dangling to somewhere (cf.
139 // CONSTRUCT_EMPTY_ANY, cppu/source/uno/prim.hxx), but what's relevant is
140 // only that it isn't a nullptr (as e.g. >>= -> uno_type_assignData ->
141 // _assignData takes a null pSource to mean "construct a default value").
142}
143
144}
145
146Any::Any(Any && other) noexcept {
147 detail::moveAnyInternals(other, *this);
148}
149
150Any & Any::operator =(Any && other) noexcept {
151 uno_any_destruct(this, &cpp_release);
152 detail::moveAnyInternals(other, *this);
153 return *this;
154}
155
156#endif
157
158inline ::rtl::OUString Any::getValueTypeName() const
159{
160 return ::rtl::OUString( pType->pTypeName );
161}
162
163inline void Any::setValue( const void * pData_, const Type & rType )
164{
165 ::uno_type_any_assign(
166 this, const_cast< void * >( pData_ ), rType.getTypeLibType(),
167 cpp_acquire, cpp_release );
168}
169
170inline void Any::setValue( const void * pData_, typelib_TypeDescriptionReference * pType_ )
171{
172 ::uno_type_any_assign(
173 this, const_cast< void * >( pData_ ), pType_,
174 cpp_acquire, cpp_release );
175}
176
177inline void Any::setValue( const void * pData_, typelib_TypeDescription * pTypeDescr )
178{
179 ::uno_any_assign(
180 this, const_cast< void * >( pData_ ), pTypeDescr,
181 cpp_acquire, cpp_release );
182}
183
184inline void Any::clear()
185{
186 ::uno_any_clear(
187 this, cpp_release );
188}
189
190inline bool Any::isExtractableTo( const Type & rType ) const
191{
192 return ::uno_type_isAssignableFromData(
193 rType.getTypeLibType(), pData, pType,
194 cpp_queryInterface, cpp_release );
195}
196
197
198template <typename T>
199inline bool Any::has() const
200{
201 Type const & rType = ::cppu::getTypeFavourUnsigned(static_cast< T * >(0));
202 return ::uno_type_isAssignableFromData(
203 rType.getTypeLibType(), pData, pType,
204 cpp_queryInterface,
205 cpp_release );
206}
207
208#if defined LIBO_INTERNAL_ONLY1
209template<> bool Any::has<Any>() const = delete;
210#endif
211
212inline bool Any::operator == ( const Any & rAny ) const
213{
214 return ::uno_type_equalData(
215 pData, pType, rAny.pData, rAny.pType,
216 cpp_queryInterface, cpp_release );
217}
218
219inline bool Any::operator != ( const Any & rAny ) const
220{
221 return (! ::uno_type_equalData(
222 pData, pType, rAny.pData, rAny.pType,
223 cpp_queryInterface, cpp_release ));
224}
225
226
227template< class C >
228inline Any SAL_CALL makeAny( const C & value )
229{
230 return Any(value);
231}
232
233#if !defined LIBO_INTERNAL_ONLY1
234template<> Any makeAny(sal_uInt16 const & value)
235{ return Any(&value, cppu::UnoType<cppu::UnoUnsignedShortType>::get()); }
236#endif
237
238template<typename T> Any toAny(T const & value) { return makeAny(value); }
239
240template<> Any toAny(Any const & value) { return value; }
241
242#if defined LIBO_INTERNAL_ONLY1
243
244template<typename T1, typename T2>
245Any makeAny(rtl::OUStringConcat<T1, T2> && value)
246{ return Any(std::move(value)); }
247
248template<typename T1, typename T2>
249Any toAny(rtl::OUStringConcat<T1, T2> && value)
250{ return makeAny(std::move(value)); }
251
252template<typename T>
253Any makeAny(rtl::OUStringNumber<T> && value)
254{ return Any(OUString(std::move(value))); }
255
256template<typename T>
257Any toAny(rtl::OUStringNumber<T> && value)
258{ return makeAny(std::move(value)); }
259
260template<typename T> bool fromAny(Any const & any, T * value) {
261 assert(value != nullptr)(static_cast <bool> (value != nullptr) ? void (0) : __assert_fail
("value != nullptr", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Any.hxx"
, 261, __extension__ __PRETTY_FUNCTION__))
;
262 return any >>= *value;
263}
264
265template<> bool fromAny(Any const & any, Any * value) {
266 assert(value != nullptr)(static_cast <bool> (value != nullptr) ? void (0) : __assert_fail
("value != nullptr", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Any.hxx"
, 266, __extension__ __PRETTY_FUNCTION__))
;
267 *value = any;
268 return true;
269}
270
271#endif
272
273template< class C >
274inline void SAL_CALL operator <<= ( Any & rAny, const C & value )
275{
276 const Type & rType = ::cppu::getTypeFavourUnsigned(&value);
277 ::uno_type_any_assign(
278 &rAny, const_cast< C * >( &value ), rType.getTypeLibType(),
279 cpp_acquire, cpp_release );
280}
281
282// additionally for C++ bool:
283
284template<>
285inline void SAL_CALL operator <<= ( Any & rAny, bool const & value )
286{
287 sal_Bool b = value;
288 ::uno_type_any_assign(
289 &rAny, &b, cppu::UnoType<bool>::get().getTypeLibType(),
290 cpp_acquire, cpp_release );
291}
292
293
294#ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING"
295template< class C1, class C2 >
296inline void SAL_CALL operator <<= ( Any & rAny, rtl::OUStringConcat< C1, C2 >&& value )
297{
298 const rtl::OUString str( std::move(value) );
299 const Type & rType = ::cppu::getTypeFavourUnsigned(&str);
300 ::uno_type_any_assign(
301 &rAny, const_cast< rtl::OUString * >( &str ), rType.getTypeLibType(),
302 cpp_acquire, cpp_release );
303}
304template<typename T1, typename T2>
305void operator <<=(Any &, rtl::OUStringConcat<T1, T2> const &) = delete;
306template< class C >
307inline void SAL_CALL operator <<= ( Any & rAny, rtl::OUStringNumber< C >&& value )
308{
309 const rtl::OUString str( std::move(value) );
310 const Type & rType = ::cppu::getTypeFavourUnsigned(&str);
311 ::uno_type_any_assign(
312 &rAny, const_cast< rtl::OUString * >( &str ), rType.getTypeLibType(),
313 cpp_acquire, cpp_release );
314}
315template<typename T>
316void operator <<=(Any &, rtl::OUStringNumber<T> const &) = delete;
317#endif
318
319#if defined LIBO_INTERNAL_ONLY1
320template<> void SAL_CALL operator <<=(Any &, Any const &) = delete;
321#endif
322
323template< class C >
324inline bool SAL_CALL operator >>= ( const Any & rAny, C & value )
325{
326 const Type & rType = ::cppu::getTypeFavourUnsigned(&value);
327 return ::uno_type_assignData(
328 &value, rType.getTypeLibType(),
329 rAny.pData, rAny.pType,
330 cpp_queryInterface,
331 cpp_acquire, cpp_release );
332}
333
334// bool
335
336template<>
337inline bool SAL_CALL operator >>= ( const ::com::sun::star::uno::Any & rAny, sal_Bool & value )
338{
339 if (typelib_TypeClass_BOOLEAN == rAny.pType->eTypeClass)
340 {
341 value = bool(* static_cast< const sal_Bool * >( rAny.pData ));
342 return true;
343 }
344 return false;
345}
346
347template<>
348inline bool SAL_CALL operator == ( const Any & rAny, const sal_Bool & value )
349{
350 return (typelib_TypeClass_BOOLEAN == rAny.pType->eTypeClass &&
351 bool(value) == bool(* static_cast< const sal_Bool * >( rAny.pData )));
352}
353
354
355template<>
356inline bool SAL_CALL operator >>= ( Any const & rAny, bool & value )
357{
358 if (rAny.pType->eTypeClass == typelib_TypeClass_BOOLEAN)
359 {
360 value = *static_cast< sal_Bool const * >( rAny.pData );
361 return true;
362 }
363 return false;
364}
365
366
367template<>
368inline bool SAL_CALL operator == ( Any const & rAny, bool const & value )
369{
370 return (rAny.pType->eTypeClass == typelib_TypeClass_BOOLEAN &&
371 (value ==
372 bool(*static_cast< sal_Bool const * >( rAny.pData ))));
373}
374
375// byte
376
377template<>
378inline bool SAL_CALL operator >>= ( const ::com::sun::star::uno::Any & rAny, sal_Int8 & value )
379{
380 if (typelib_TypeClass_BYTE == rAny.pType->eTypeClass)
381 {
382 value = * static_cast< const sal_Int8 * >( rAny.pData );
383 return true;
384 }
385 return false;
386}
387// short
388
389template<>
390inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int16 & value )
391{
392 switch (rAny.pType->eTypeClass)
393 {
394 case typelib_TypeClass_BYTE:
395 value = * static_cast< const sal_Int8 * >( rAny.pData );
396 return true;
397 case typelib_TypeClass_SHORT:
398 case typelib_TypeClass_UNSIGNED_SHORT:
399 value = * static_cast< const sal_Int16 * >( rAny.pData );
400 return true;
401 default:
402 return false;
403 }
404}
405
406template<>
407inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt16 & value )
408{
409 switch (rAny.pType->eTypeClass)
410 {
411 case typelib_TypeClass_BYTE:
412 value = static_cast<sal_uInt16>( * static_cast< const sal_Int8 * >( rAny.pData ) );
413 return true;
414 case typelib_TypeClass_SHORT:
415 case typelib_TypeClass_UNSIGNED_SHORT:
416 value = * static_cast< const sal_uInt16 * >( rAny.pData );
417 return true;
418 default:
419 return false;
420 }
421}
422// long
423
424template<>
425inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int32 & value )
426{
427 switch (rAny.pType->eTypeClass)
428 {
429 case typelib_TypeClass_BYTE:
430 value = * static_cast< const sal_Int8 * >( rAny.pData );
431 return true;
432 case typelib_TypeClass_SHORT:
433 value = * static_cast< const sal_Int16 * >( rAny.pData );
434 return true;
435 case typelib_TypeClass_UNSIGNED_SHORT:
436 value = * static_cast< const sal_uInt16 * >( rAny.pData );
437 return true;
438 case typelib_TypeClass_LONG:
439 case typelib_TypeClass_UNSIGNED_LONG:
440 value = * static_cast< const sal_Int32 * >( rAny.pData );
441 return true;
442 default:
443 return false;
444 }
445}
446
447template<>
448inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt32 & value )
449{
450 switch (rAny.pType->eTypeClass)
451 {
452 case typelib_TypeClass_BYTE:
453 value = static_cast<sal_uInt32>( * static_cast< const sal_Int8 * >( rAny.pData ) );
454 return true;
455 case typelib_TypeClass_SHORT:
456 value = static_cast<sal_uInt32>( * static_cast< const sal_Int16 * >( rAny.pData ) );
457 return true;
458 case typelib_TypeClass_UNSIGNED_SHORT:
459 value = * static_cast< const sal_uInt16 * >( rAny.pData );
460 return true;
461 case typelib_TypeClass_LONG:
462 case typelib_TypeClass_UNSIGNED_LONG:
463 value = * static_cast< const sal_uInt32 * >( rAny.pData );
464 return true;
465 default:
466 return false;
467 }
468}
469// hyper
470
471template<>
472inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int64 & value )
473{
474 switch (rAny.pType->eTypeClass)
475 {
476 case typelib_TypeClass_BYTE:
477 value = * static_cast< const sal_Int8 * >( rAny.pData );
478 return true;
479 case typelib_TypeClass_SHORT:
480 value = * static_cast< const sal_Int16 * >( rAny.pData );
481 return true;
482 case typelib_TypeClass_UNSIGNED_SHORT:
483 value = * static_cast< const sal_uInt16 * >( rAny.pData );
484 return true;
485 case typelib_TypeClass_LONG:
486 value = * static_cast< const sal_Int32 * >( rAny.pData );
487 return true;
488 case typelib_TypeClass_UNSIGNED_LONG:
489 value = * static_cast< const sal_uInt32 * >( rAny.pData );
490 return true;
491 case typelib_TypeClass_HYPER:
492 case typelib_TypeClass_UNSIGNED_HYPER:
493 value = * static_cast< const sal_Int64 * >( rAny.pData );
494 return true;
495 default:
496 return false;
497 }
498}
499
500template<>
501inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt64 & value )
502{
503 switch (rAny.pType->eTypeClass)
504 {
505 case typelib_TypeClass_BYTE:
506 value = static_cast<sal_uInt64>( * static_cast< const sal_Int8 * >( rAny.pData ) );
507 return true;
508 case typelib_TypeClass_SHORT:
509 value = static_cast<sal_uInt64>( * static_cast< const sal_Int16 * >( rAny.pData ) );
510 return true;
511 case typelib_TypeClass_UNSIGNED_SHORT:
512 value = * static_cast< const sal_uInt16 * >( rAny.pData );
513 return true;
514 case typelib_TypeClass_LONG:
515 value = static_cast<sal_uInt64>( * static_cast< const sal_Int32 * >( rAny.pData ) );
516 return true;
517 case typelib_TypeClass_UNSIGNED_LONG:
518 value = * static_cast< const sal_uInt32 * >( rAny.pData );
519 return true;
520 case typelib_TypeClass_HYPER:
521 case typelib_TypeClass_UNSIGNED_HYPER:
522 value = * static_cast< const sal_uInt64 * >( rAny.pData );
523 return true;
524 default:
525 return false;
526 }
527}
528// float
529
530template<>
531inline bool SAL_CALL operator >>= ( const Any & rAny, float & value )
532{
533 switch (rAny.pType->eTypeClass)
534 {
535 case typelib_TypeClass_BYTE:
536 value = * static_cast< const sal_Int8 * >( rAny.pData );
537 return true;
538 case typelib_TypeClass_SHORT:
539 value = * static_cast< const sal_Int16 * >( rAny.pData );
540 return true;
541 case typelib_TypeClass_UNSIGNED_SHORT:
542 value = * static_cast< const sal_uInt16 * >( rAny.pData );
543 return true;
544 case typelib_TypeClass_FLOAT:
545 value = * static_cast< const float * >( rAny.pData );
546 return true;
547 default:
548 return false;
549 }
550}
551// double
552
553template<>
554inline bool SAL_CALL operator >>= ( const Any & rAny, double & value )
555{
556 switch (rAny.pType->eTypeClass)
10
Control jumps to 'case typelib_TypeClass_DOUBLE:' at line 576
557 {
558 case typelib_TypeClass_BYTE:
559 value = * static_cast< const sal_Int8 * >( rAny.pData );
560 return true;
561 case typelib_TypeClass_SHORT:
562 value = * static_cast< const sal_Int16 * >( rAny.pData );
563 return true;
564 case typelib_TypeClass_UNSIGNED_SHORT:
565 value = * static_cast< const sal_uInt16 * >( rAny.pData );
566 return true;
567 case typelib_TypeClass_LONG:
568 value = * static_cast< const sal_Int32 * >( rAny.pData );
569 return true;
570 case typelib_TypeClass_UNSIGNED_LONG:
571 value = * static_cast< const sal_uInt32 * >( rAny.pData );
572 return true;
573 case typelib_TypeClass_FLOAT:
574 value = * static_cast< const float * >( rAny.pData );
575 return true;
576 case typelib_TypeClass_DOUBLE:
577 value = * static_cast< const double * >( rAny.pData );
11
Dereference of null pointer
578 return true;
579 default:
580 return false;
581 }
582}
583// string
584
585template<>
586inline bool SAL_CALL operator >>= ( const Any & rAny, ::rtl::OUString & value )
587{
588 if (typelib_TypeClass_STRING == rAny.pType->eTypeClass)
589 {
590 value = * static_cast< const ::rtl::OUString * >( rAny.pData );
591 return true;
592 }
593 return false;
594}
595
596template<>
597inline bool SAL_CALL operator == ( const Any & rAny, const ::rtl::OUString & value )
598{
599 return (typelib_TypeClass_STRING == rAny.pType->eTypeClass &&
600 value == * static_cast< const ::rtl::OUString * >( rAny.pData ) );
601}
602// type
603
604template<>
605inline bool SAL_CALL operator >>= ( const Any & rAny, Type & value )
606{
607 if (typelib_TypeClass_TYPE == rAny.pType->eTypeClass)
608 {
609 value = * static_cast< const Type * >( rAny.pData );
610 return true;
611 }
612 return false;
613}
614
615template<>
616inline bool SAL_CALL operator == ( const Any & rAny, const Type & value )
617{
618 return (typelib_TypeClass_TYPE == rAny.pType->eTypeClass &&
619 value.equals( * static_cast< const Type * >( rAny.pData ) ));
620}
621// any
622
623#if defined LIBO_INTERNAL_ONLY1
624template<> bool SAL_CALL operator >>=(Any const &, Any &) = delete;
625#else
626template<>
627inline bool SAL_CALL operator >>= ( const Any & rAny, Any & value )
628{
629 if (&rAny != &value)
630 {
631 ::uno_type_any_assign(
632 &value, rAny.pData, rAny.pType,
633 cpp_acquire, cpp_release );
634 }
635 return true;
636}
637#endif
638// interface
639
640template<>
641inline bool SAL_CALL operator == ( const Any & rAny, const BaseReference & value )
642{
643 if (typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass)
644 {
645 return static_cast< const BaseReference * >( rAny.pData )->operator == ( value );
646 }
647 return false;
648}
649
650// operator to compare to an any.
651
652template< class C >
653inline bool SAL_CALL operator == ( const Any & rAny, const C & value )
654{
655 const Type & rType = ::cppu::getTypeFavourUnsigned(&value);
656 return ::uno_type_equalData(
657 rAny.pData, rAny.pType,
658 const_cast< C * >( &value ), rType.getTypeLibType(),
659 cpp_queryInterface, cpp_release );
660}
661// operator to compare to an any. may use specialized operators ==.
662
663template< class C >
664inline bool SAL_CALL operator != ( const Any & rAny, const C & value )
665{
666 return (! operator == ( rAny, value ));
667}
668
669template <typename T>
670T Any::get() const
671{
672 T value = T();
673 if (! (*this >>= value)) {
674 throw RuntimeException(
675 ::rtl::OUString(
676 cppu_Any_extraction_failure_msg(
677 this,
678 ::cppu::getTypeFavourUnsigned(&value).getTypeLibType() ),
679 SAL_NO_ACQUIRE ) );
680 }
681 return value;
682}
683
684#if defined LIBO_INTERNAL_ONLY1
685template<> Any Any::get() const = delete;
686#endif
687
688/**
689 Support for Any in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO
690 macros, for example).
691
692 @since LibreOffice 4.2
693*/
694template<typename charT, typename traits>
695inline std::basic_ostream<charT, traits> &operator<<(std::basic_ostream<charT, traits> &o, Any const &any) {
696 o << "<Any: (" << any.getValueTypeName() << ')';
697 switch(any.pType->eTypeClass) {
698 case typelib_TypeClass_VOID:
699 break;
700 case typelib_TypeClass_BOOLEAN:
701 o << ' ' << any.get<bool>();
702 break;
703 case typelib_TypeClass_BYTE:
704 case typelib_TypeClass_SHORT:
705 case typelib_TypeClass_LONG:
706 case typelib_TypeClass_HYPER:
707 o << ' ' << any.get<sal_Int64>();
708 break;
709 case typelib_TypeClass_UNSIGNED_SHORT:
710 case typelib_TypeClass_UNSIGNED_LONG:
711 case typelib_TypeClass_UNSIGNED_HYPER:
712 o << ' ' << any.get<sal_uInt64>();
713 break;
714 case typelib_TypeClass_FLOAT:
715 case typelib_TypeClass_DOUBLE:
716 o << ' ' << any.get<double>();
717 break;
718 case typelib_TypeClass_CHAR: {
719 std::ios_base::fmtflags flgs = o.setf(
720 std::ios_base::hex, std::ios_base::basefield);
721 charT fill = o.fill('0');
722 o << " U+" << std::setw(4)
723 << unsigned(*static_cast<sal_Unicode const *>(any.getValue()));
724 o.setf(flgs);
725 o.fill(fill);
726 break;
727 }
728 case typelib_TypeClass_STRING:
729 o << ' ' << any.get<rtl::OUString>();
730 break;
731 case typelib_TypeClass_TYPE:
732 o << ' ' << any.get<css::uno::Type>().getTypeName();
733 break;
734 case typelib_TypeClass_SEQUENCE:
735 o << " len "
736 << ((*static_cast<uno_Sequence * const *>(any.getValue()))->
737 nElements);
738 break;
739 case typelib_TypeClass_ENUM:
740 o << ' ' << *static_cast<sal_Int32 const *>(any.getValue());
741 break;
742 case typelib_TypeClass_STRUCT:
743 case typelib_TypeClass_EXCEPTION:
744 o << ' ' << any.getValue();
745 break;
746 case typelib_TypeClass_INTERFACE:
747 o << ' ' << *static_cast<void * const *>(any.getValue());
748 break;
749 default:
750 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Any.hxx"
, 750, __extension__ __PRETTY_FUNCTION__))
; // this cannot happen
751 break;
752 }
753 o << '>';
754 return o;
755}
756
757}
758}
759}
760}
761
762#endif
763
764/* vim:set shiftwidth=4 softtabstop=4 expandtab: */