File: | home/maarten/src/libreoffice/core/include/com/sun/star/uno/Any.hxx |
Warning: | line 577, column 17 Dereference of null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
36 | using namespace ::com::sun::star; | |||
37 | using 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 | ||||
51 | const 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 | ||||
159 | namespace sca::analysis { | |||
160 | ||||
161 | sal_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 | ||||
180 | sal_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 | ||||
203 | void 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 | ||||
257 | sal_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 | ||||
278 | sal_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 | ||||
309 | sal_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 | ||||
323 | sal_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 | ||||
342 | sal_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 | ||||
414 | double 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 | ||||
423 | sal_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 | */ | |||
453 | double 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 | ||||
594 | double 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 | ||||
620 | double 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 | ||||
634 | double 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 | ||||
690 | static char GetMaxChar( sal_uInt16 nBase ) | |||
691 | { | |||
692 | const char* const c = "--123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |||
693 | return c[ nBase ]; | |||
694 | } | |||
695 | ||||
696 | ||||
697 | OUString 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# | |||
736 | double Erf( double x ) | |||
737 | { | |||
738 | return ::rtl::math::erf(x); | |||
739 | } | |||
740 | ||||
741 | // implementation moved to module sal, see #i97091# | |||
742 | double Erfc( double x ) | |||
743 | { | |||
744 | return ::rtl::math::erfc(x); | |||
745 | } | |||
746 | ||||
747 | static bool IsNum( sal_Unicode c ) | |||
748 | { | |||
749 | return c >= '0' && c <= '9'; | |||
750 | } | |||
751 | ||||
752 | ||||
753 | static bool IsComma( sal_Unicode c ) | |||
754 | { | |||
755 | return c == '.' || c == ','; | |||
756 | } | |||
757 | ||||
758 | ||||
759 | static bool IsExpStart( sal_Unicode c ) | |||
760 | { | |||
761 | return c == 'e' || c == 'E'; | |||
762 | } | |||
763 | ||||
764 | ||||
765 | static bool IsImagUnit( sal_Unicode c ) | |||
766 | { | |||
767 | return c == 'i' || c == 'j'; | |||
768 | } | |||
769 | ||||
770 | ||||
771 | static sal_uInt16 GetVal( sal_Unicode c ) | |||
772 | { | |||
773 | return sal_uInt16( c - '0' ); | |||
774 | } | |||
775 | ||||
776 | ||||
777 | bool 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 | ||||
944 | OUString 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 | ||||
961 | double 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 | ||||
1006 | double 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 | ||||
1030 | double 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 | ||||
1063 | double 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 | ||||
1079 | double 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 | ||||
1090 | double 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 | ||||
1142 | double 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 | ||||
1165 | double 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 | ||||
1176 | double 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 | ||||
1192 | double 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 | ||||
1209 | double 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 | ||||
1227 | double 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 | |||
1248 | static 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 | ||||
1258 | double 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 | |||
1270 | static 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 | ||||
1280 | double 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 | |||
1291 | double 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 | |||
1303 | double 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 | |||
1319 | double 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 | |||
1336 | double 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 | ||||
1348 | FuncData::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 | ||||
1365 | sal_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 | ||||
1376 | void InitFuncDataList(FuncDataList& rList) | |||
1377 | { | |||
1378 | for(const auto & rFuncData : pFuncDatas) | |||
1379 | rList.push_back(FuncData(rFuncData)); | |||
1380 | } | |||
1381 | ||||
1382 | SortedIndividualInt32List::SortedIndividualInt32List() | |||
1383 | { | |||
1384 | } | |||
1385 | ||||
1386 | ||||
1387 | SortedIndividualInt32List::~SortedIndividualInt32List() | |||
1388 | { | |||
1389 | } | |||
1390 | ||||
1391 | ||||
1392 | void 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 | ||||
1411 | void 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 | ||||
1422 | void 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 | ||||
1431 | bool 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 | ||||
1453 | void 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 | ||||
1465 | void 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 | ||||
1489 | void 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 | ||||
1500 | void 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 | ||||
1510 | void ScaDoubleList::Append( | |||
1511 | const ScaAnyConverter& rAnyConv, | |||
1512 | const uno::Any& rAny, | |||
1513 | bool bIgnoreEmpty ) | |||
1514 | { | |||
1515 | if( auto s = o3tl::tryAccess< | |||
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 ) ) | |||
1522 | Append( fValue ); | |||
1523 | else if( !bIgnoreEmpty ) | |||
1524 | Append( 0.0 ); | |||
1525 | } | |||
1526 | } | |||
1527 | ||||
1528 | ||||
1529 | void ScaDoubleList::Append( | |||
1530 | const ScaAnyConverter& rAnyConv, | |||
1531 | const uno::Sequence< uno::Any >& rAnySeq, | |||
1532 | bool bIgnoreEmpty ) | |||
1533 | { | |||
1534 | for( const uno::Any& rAny : rAnySeq ) | |||
1535 | Append( rAnyConv, rAny, bIgnoreEmpty ); | |||
1536 | } | |||
1537 | ||||
1538 | ||||
1539 | void 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 | ||||
1548 | void 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*/ ); | |||
| ||||
1555 | } | |||
1556 | ||||
1557 | ||||
1558 | bool ScaDoubleList::CheckInsert( double ) const | |||
1559 | { | |||
1560 | return true; | |||
1561 | } | |||
1562 | ||||
1563 | ||||
1564 | bool ScaDoubleListGT0::CheckInsert( double fValue ) const | |||
1565 | { | |||
1566 | if( fValue < 0.0 ) | |||
1567 | throw lang::IllegalArgumentException(); | |||
1568 | return fValue > 0.0; | |||
1569 | } | |||
1570 | ||||
1571 | ||||
1572 | bool ScaDoubleListGE0::CheckInsert( double fValue ) const | |||
1573 | { | |||
1574 | if( fValue < 0.0 ) | |||
1575 | throw lang::IllegalArgumentException(); | |||
1576 | return true; | |||
1577 | } | |||
1578 | ||||
1579 | ||||
1580 | Complex::Complex( const OUString& rStr ) | |||
1581 | { | |||
1582 | if( !ParseString( rStr, *this ) ) | |||
1583 | throw lang::IllegalArgumentException(); | |||
1584 | } | |||
1585 | ||||
1586 | ||||
1587 | inline bool Complex::IsImagUnit( sal_Unicode c ) | |||
1588 | { | |||
1589 | return c == 'i' || c == 'j'; | |||
1590 | } | |||
1591 | ||||
1592 | bool 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 | ||||
1661 | OUString 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 | ||||
1690 | double 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 | ||||
1704 | void 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 | ||||
1730 | void 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 | ||||
1741 | void 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 | ||||
1759 | void 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 | ||||
1777 | void 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 | ||||
1796 | void Complex::Exp() | |||
1797 | { | |||
1798 | double fE = exp( r ); | |||
1799 | r = fE * cos( i ); | |||
1800 | i = fE * sin( i ); | |||
1801 | } | |||
1802 | ||||
1803 | ||||
1804 | void 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 | ||||
1821 | void Complex::Log10() | |||
1822 | { | |||
1823 | Ln(); | |||
1824 | Mult( 0.434294481903251828 ); // * log10( e ) | |||
1825 | } | |||
1826 | ||||
1827 | ||||
1828 | void Complex::Log2() | |||
1829 | { | |||
1830 | Ln(); | |||
1831 | Mult( 1.442695040888963407 ); // * log2( e ) | |||
1832 | } | |||
1833 | ||||
1834 | ||||
1835 | void 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 | ||||
1854 | void 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 | ||||
1875 | void 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 | ||||
1896 | void 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 | ||||
1915 | void 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 | ||||
1932 | void 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 | ||||
1949 | void 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 | ||||
1970 | void 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 | ||||
1991 | ComplexList::~ComplexList() | |||
1992 | { | |||
1993 | } | |||
1994 | ||||
1995 | ||||
1996 | void 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 | ||||
2009 | void 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 | ||||
2043 | ConvertData::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 | ||||
2051 | ConvertData::~ConvertData() | |||
2052 | { | |||
2053 | } | |||
2054 | ||||
2055 | sal_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 | ||||
2154 | double 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 | ||||
2190 | double ConvertData::ConvertFromBase( double f, sal_Int16 n ) const | |||
2191 | { | |||
2192 | return ::rtl::math::pow10Exp( f * fConst, -n ); | |||
2193 | } | |||
2194 | ||||
2195 | ConvertDataLinear::~ConvertDataLinear() | |||
2196 | { | |||
2197 | } | |||
2198 | ||||
2199 | double 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 | ||||
2208 | double 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 | ||||
2220 | double 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 | ||||
2232 | ConvertDataList::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 | ||||
2415 | ConvertDataList::~ConvertDataList() | |||
2416 | { | |||
2417 | } | |||
2418 | ||||
2419 | ||||
2420 | double 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 | ||||
2481 | ScaDate::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 | ||||
2493 | ScaDate::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 | ||||
2503 | ScaDate::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 | ||||
2515 | ScaDate& 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 | ||||
2531 | void 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 | ||||
2548 | sal_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 | ||||
2564 | sal_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 | ||||
2572 | void 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 | ||||
2580 | void 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 | ||||
2599 | sal_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 | ||||
2606 | sal_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 | ||||
2663 | bool 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 | ||||
2677 | ScaAnyConverter::ScaAnyConverter( const uno::Reference< uno::XComponentContext >& xContext ) | |||
2678 | : nDefaultFormat(0) | |||
2679 | , bHasValidFormat(false) | |||
2680 | { | |||
2681 | xFormatter = util::NumberFormatter::create(xContext); | |||
2682 | } | |||
2683 | ||||
2684 | ScaAnyConverter::~ScaAnyConverter() | |||
2685 | { | |||
2686 | } | |||
2687 | ||||
2688 | void 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 | ||||
2712 | double 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 | ||||
2737 | bool ScaAnyConverter::getDouble( | |||
2738 | double& rfResult, | |||
2739 | const uno::Any& rAny ) const | |||
2740 | { | |||
2741 | rfResult = 0.0; | |||
2742 | bool bContainsVal = true; | |||
2743 | switch( rAny.getValueTypeClass() ) | |||
2744 | { | |||
2745 | case uno::TypeClass_VOID: | |||
2746 | bContainsVal = false; | |||
2747 | break; | |||
2748 | case uno::TypeClass_DOUBLE: | |||
2749 | rAny >>= rfResult; | |||
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 | ||||
2766 | bool 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 | ||||
2775 | double 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 | ||||
2786 | bool 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 | ||||
2800 | sal_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: */ |
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 | ||||
41 | extern "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 | ||||
45 | namespace com | |||
46 | { | |||
47 | namespace sun | |||
48 | { | |||
49 | namespace star | |||
50 | { | |||
51 | namespace uno | |||
52 | { | |||
53 | ||||
54 | ||||
55 | inline Any::Any() | |||
56 | { | |||
57 | ::uno_any_construct( this, NULL__null, NULL__null, cpp_acquire ); | |||
58 | } | |||
59 | ||||
60 | ||||
61 | template <typename T> | |||
62 | inline 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 | ||||
70 | inline 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 | |||
79 | template<typename T1, typename T2> | |||
80 | Any::Any(rtl::OUStringConcat<T1, T2> && value): | |||
81 | Any(rtl::OUString(std::move(value))) | |||
82 | {} | |||
83 | #endif | |||
84 | ||||
85 | inline Any::Any( const Any & rAny ) | |||
86 | { | |||
87 | ::uno_type_any_construct( this, rAny.pData, rAny.pType, cpp_acquire ); | |||
88 | } | |||
89 | ||||
90 | inline 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 | ||||
97 | inline Any::Any( const void * pData_, typelib_TypeDescription * pTypeDescr ) | |||
98 | { | |||
99 | ::uno_any_construct( | |||
100 | this, const_cast< void * >( pData_ ), pTypeDescr, cpp_acquire ); | |||
101 | } | |||
102 | ||||
103 | inline 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 | ||||
109 | inline Any::~Any() | |||
110 | { | |||
111 | ::uno_any_destruct( | |||
112 | this, cpp_release ); | |||
113 | } | |||
114 | ||||
115 | inline 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 | ||||
128 | namespace detail { | |||
129 | ||||
130 | inline 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 | ||||
146 | Any::Any(Any && other) noexcept { | |||
147 | detail::moveAnyInternals(other, *this); | |||
148 | } | |||
149 | ||||
150 | Any & 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 | ||||
158 | inline ::rtl::OUString Any::getValueTypeName() const | |||
159 | { | |||
160 | return ::rtl::OUString( pType->pTypeName ); | |||
161 | } | |||
162 | ||||
163 | inline 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 | ||||
170 | inline 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 | ||||
177 | inline 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 | ||||
184 | inline void Any::clear() | |||
185 | { | |||
186 | ::uno_any_clear( | |||
187 | this, cpp_release ); | |||
188 | } | |||
189 | ||||
190 | inline 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 | ||||
198 | template <typename T> | |||
199 | inline 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 | |||
209 | template<> bool Any::has<Any>() const = delete; | |||
210 | #endif | |||
211 | ||||
212 | inline 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 | ||||
219 | inline 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 | ||||
227 | template< class C > | |||
228 | inline Any SAL_CALL makeAny( const C & value ) | |||
229 | { | |||
230 | return Any(value); | |||
231 | } | |||
232 | ||||
233 | #if !defined LIBO_INTERNAL_ONLY1 | |||
234 | template<> Any makeAny(sal_uInt16 const & value) | |||
235 | { return Any(&value, cppu::UnoType<cppu::UnoUnsignedShortType>::get()); } | |||
236 | #endif | |||
237 | ||||
238 | template<typename T> Any toAny(T const & value) { return makeAny(value); } | |||
239 | ||||
240 | template<> Any toAny(Any const & value) { return value; } | |||
241 | ||||
242 | #if defined LIBO_INTERNAL_ONLY1 | |||
243 | ||||
244 | template<typename T1, typename T2> | |||
245 | Any makeAny(rtl::OUStringConcat<T1, T2> && value) | |||
246 | { return Any(std::move(value)); } | |||
247 | ||||
248 | template<typename T1, typename T2> | |||
249 | Any toAny(rtl::OUStringConcat<T1, T2> && value) | |||
250 | { return makeAny(std::move(value)); } | |||
251 | ||||
252 | template<typename T> | |||
253 | Any makeAny(rtl::OUStringNumber<T> && value) | |||
254 | { return Any(OUString(std::move(value))); } | |||
255 | ||||
256 | template<typename T> | |||
257 | Any toAny(rtl::OUStringNumber<T> && value) | |||
258 | { return makeAny(std::move(value)); } | |||
259 | ||||
260 | template<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 | ||||
265 | template<> 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 | ||||
273 | template< class C > | |||
274 | inline 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 | ||||
284 | template<> | |||
285 | inline 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" | |||
295 | template< class C1, class C2 > | |||
296 | inline 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 | } | |||
304 | template<typename T1, typename T2> | |||
305 | void operator <<=(Any &, rtl::OUStringConcat<T1, T2> const &) = delete; | |||
306 | template< class C > | |||
307 | inline 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 | } | |||
315 | template<typename T> | |||
316 | void operator <<=(Any &, rtl::OUStringNumber<T> const &) = delete; | |||
317 | #endif | |||
318 | ||||
319 | #if defined LIBO_INTERNAL_ONLY1 | |||
320 | template<> void SAL_CALL operator <<=(Any &, Any const &) = delete; | |||
321 | #endif | |||
322 | ||||
323 | template< class C > | |||
324 | inline 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 | ||||
336 | template<> | |||
337 | inline 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 | ||||
347 | template<> | |||
348 | inline 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 | ||||
355 | template<> | |||
356 | inline 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 | ||||
367 | template<> | |||
368 | inline 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 | ||||
377 | template<> | |||
378 | inline 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 | ||||
389 | template<> | |||
390 | inline 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 | ||||
406 | template<> | |||
407 | inline 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 | ||||
424 | template<> | |||
425 | inline 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 | ||||
447 | template<> | |||
448 | inline 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 | ||||
471 | template<> | |||
472 | inline 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 | ||||
500 | template<> | |||
501 | inline 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 | ||||
530 | template<> | |||
531 | inline 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 | ||||
553 | template<> | |||
554 | inline bool SAL_CALL operator >>= ( const Any & rAny, double & value ) | |||
555 | { | |||
556 | switch (rAny.pType->eTypeClass) | |||
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 ); | |||
| ||||
578 | return true; | |||
579 | default: | |||
580 | return false; | |||
581 | } | |||
582 | } | |||
583 | // string | |||
584 | ||||
585 | template<> | |||
586 | inline 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 | ||||
596 | template<> | |||
597 | inline 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 | ||||
604 | template<> | |||
605 | inline 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 | ||||
615 | template<> | |||
616 | inline 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 | |||
624 | template<> bool SAL_CALL operator >>=(Any const &, Any &) = delete; | |||
625 | #else | |||
626 | template<> | |||
627 | inline 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 | ||||
640 | template<> | |||
641 | inline 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 | ||||
652 | template< class C > | |||
653 | inline 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 | ||||
663 | template< class C > | |||
664 | inline bool SAL_CALL operator != ( const Any & rAny, const C & value ) | |||
665 | { | |||
666 | return (! operator == ( rAny, value )); | |||
667 | } | |||
668 | ||||
669 | template <typename T> | |||
670 | T 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 | |||
685 | template<> 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 | */ | |||
694 | template<typename charT, typename traits> | |||
695 | inline 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: */ |