LibreOffice Module sw (master) 1
calc.hxx
Go to the documentation of this file.
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#ifndef INCLUDED_SW_INC_CALC_HXX
21#define INCLUDED_SW_INC_CALC_HXX
22
23#include <memory>
24#include <vector>
25#include <basic/sbxvar.hxx>
27#include <rtl/ustrbuf.hxx>
28#include <tools/solar.h>
29#include <tools/long.hxx>
30#include <o3tl/safeint.hxx>
31#include "swdllapi.h"
32
33class CharClass;
35class SwFieldType;
36class SwDoc;
37class SwUserFieldType;
38
39#define TBLSZ 47 // should be a prime, because of hash table
40
42
44{
48 CALC_LP='(', CALC_RP=')', CALC_PHD='%',
50 CALC_NOT=256, CALC_AND=257, CALC_OR=258,
51 CALC_XOR=259, CALC_EQ=260, CALC_NEQ=261,
52 CALC_LEQ=262, CALC_GEQ=263, CALC_LES=264,
61 CALC_INT=290
62};
63
64// Calculate Operations Strings
65extern const char sCalc_Add[];
66extern const char sCalc_Sub[];
67extern const char sCalc_Mul[];
68extern const char sCalc_Div[];
69extern const char sCalc_Phd[];
70extern const char sCalc_Sqrt[];
71extern const char sCalc_Pow[];
72extern const char sCalc_Or[];
73extern const char sCalc_Xor[];
74extern const char sCalc_And[];
75extern const char sCalc_Not[];
76extern const char sCalc_Eq[];
77extern const char sCalc_Neq[];
78extern const char sCalc_Leq[];
79extern const char sCalc_Geq[];
80extern const char sCalc_L[];
81extern const char sCalc_G[];
82extern const char sCalc_Sum[];
83extern const char sCalc_Mean[];
84extern const char sCalc_Average[];
85extern const char sCalc_Product[];
86extern const char sCalc_Count[];
87extern const char sCalc_Min[];
88extern const char sCalc_Max[];
89extern const char sCalc_Sin[];
90extern const char sCalc_Cos[];
91extern const char sCalc_Tan[];
92extern const char sCalc_Asin[];
93extern const char sCalc_Acos[];
94extern const char sCalc_Atan[];
95extern const char sCalc_Round[];
96extern const char sCalc_Date[];
97extern const char sCalc_Sign[];
98extern const char sCalc_Abs[];
99extern const char sCalc_Int[];
100
101// Calculate ErrorCodes
102enum class SwCalcError
103{
104 NONE=0,
105 NaN, // not a number (not an error, used for interoperability)
106 Syntax, // syntax error
107 DivByZero, // division by zero
108 FaultyBrackets, // faulty brackets
109 OverflowInPower, // overflow in power function
110 Overflow, // overflow
111};
112
113class SwSbxValue final : public SbxValue
114{
117public:
118 // always default to a number. otherwise it will become a SbxEMPTY
119 SwSbxValue( tools::Long n = 0 ) : m_bVoid(false), m_bDBvalue(false) { PutLong( n ); }
120 SwSbxValue( const double& rD ) : m_bVoid(false), m_bDBvalue(false) { PutDouble( rD ); }
121
122 bool GetBool() const;
123 double GetDouble() const;
125
126 bool IsVoidValue() const {return m_bVoid;}
127 void SetVoidValue(bool bSet) {m_bVoid = bSet;}
128
129 bool IsDBvalue() const {return m_bDBvalue;}
130 void SetDBvalue(bool bSet) {m_bDBvalue = bSet;}
131};
132
133// Calculate HashTables for VarTable and Operations
134struct SwHash
135{
136 SwHash( OUString aStr );
137 virtual ~SwHash();
138 OUString aStr;
139 std::unique_ptr<SwHash> pNext;
140};
141
142struct SwCalcExp final : public SwHash
143{
146
147 SwCalcExp( const OUString& rStr, SwSbxValue aVal,
148 const SwFieldType* pFieldType );
149};
150
152template<class T>
154{
155 std::vector<std::unique_ptr<T>> m_aData;
156public:
157 SwHashTable(size_t nSize) : m_aData(nSize)
158 {
159 assert(nSize < SAL_MAX_UINT32);
160 }
161 std::unique_ptr<T> & operator[](size_t idx) { return m_aData[idx]; }
162 std::unique_ptr<T> const & operator[](size_t idx) const { return m_aData[idx]; }
163 void resize(size_t nSize) { m_aData.resize(nSize); }
164
165 T* Find( std::u16string_view aStr, sal_uInt32* pPos = nullptr ) const
166 {
167 size_t nTableSize = m_aData.size();
168 assert(nTableSize < SAL_MAX_UINT32);
169 sal_uInt32 ii = 0;
170 for( size_t n = 0; n < aStr.size(); ++n )
171 {
172 ii = ii << 1 ^ aStr[n];
173 }
174 ii %= nTableSize;
175
176 if( pPos )
177 *pPos = ii;
178
179 for( T* pEntry = m_aData[ii].get(); pEntry; pEntry = static_cast<T*>(pEntry->pNext.get()) )
180 {
181 if( aStr == pEntry->aStr )
182 {
183 return pEntry;
184 }
185 }
186 return nullptr;
187 }
188
189};
190
191
192// if CalcOp != 0, this is a valid operator
193struct CalcOp;
194CalcOp* FindOperator( const OUString& rSearch );
195
196extern "C" typedef double (*pfCalc)(double);
197
199{
201 OUStringBuffer m_aVarName;
202 OUString m_sCurrSym;
203 OUString m_sCommand;
204 std::vector<const SwUserFieldType*> m_aRekurStack;
208 sal_Int32 m_nCommandPos;
209
211 std::unique_ptr<LocaleDataWrapper> m_xLocaleDataWrapper;
213
214 sal_uInt16 m_nListPor;
215 bool m_bHasNumber; // fix COUNT() and AVERAGE(), if all cells are NaN
219
223 SwSbxValue PrimFunc(bool &rChkPow);
225 SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig);
226
227 static OUString GetColumnName( const OUString& rName );
228 OUString GetDBName( std::u16string_view rName );
229
230 SwCalc( const SwCalc& ) = delete;
231 SwCalc& operator=( const SwCalc& ) = delete;
232
233 void ImplDestroy();
234
235public:
236 SwCalc(SwDoc& rD);
237 ~SwCalc();
238
239 SwSbxValue Calculate( const OUString &rStr );
240 OUString GetStrResult( const SwSbxValue& rValue );
241 OUString GetStrResult( double );
242
243 SwCalcExp* VarInsert( const OUString& r );
244 SwCalcExp* VarLook( const OUString &rStr, bool bIns = false );
245 void VarChange( const OUString& rStr, const SwSbxValue& rValue );
246 void VarChange( const OUString& rStr, double );
248
249 bool Push(const SwUserFieldType* pUserFieldType);
250 void Pop();
251 const CharClass* GetCharClass() const;
252 void SetCharClass(const LanguageTag& rLanguageTag);
253
254 void SetCalcError( SwCalcError eErr ) { m_eError = eErr; }
256 bool IsCalcNotANumber() const { return SwCalcError::NaN == m_eError; }
257
258 static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
259 double& rVal );
260 static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
261 double& rVal, SwDoc const *const pDoc );
262
263 SW_DLLPUBLIC static bool IsValidVarName( const OUString& rStr,
264 OUString* pValidName = nullptr );
265};
266
267#endif
268
269/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const char sCalc_Sub[]
Definition: calc.cxx:59
const char sCalc_Abs[]
Definition: calc.cxx:91
const char sCalc_Leq[]
Definition: calc.cxx:71
const char sCalc_L[]
Definition: calc.cxx:73
const char sCalc_Mul[]
Definition: calc.cxx:60
const char sCalc_Add[]
Definition: calc.cxx:58
const char sCalc_Neq[]
Definition: calc.cxx:70
const char sCalc_Int[]
Definition: calc.cxx:92
const char sCalc_Min[]
Definition: calc.cxx:77
const char sCalc_Acos[]
Definition: calc.cxx:83
double(* pfCalc)(double)
Definition: calc.hxx:196
const sal_Unicode cListDelim
Definition: calc.hxx:41
const char sCalc_Not[]
Definition: calc.cxx:68
const char sCalc_Eq[]
Definition: calc.cxx:69
const char sCalc_Date[]
Definition: calc.cxx:86
const char sCalc_Sqrt[]
Definition: calc.cxx:63
SwCalcError
Definition: calc.hxx:103
const char sCalc_Sin[]
Definition: calc.cxx:79
const char sCalc_Round[]
Definition: calc.cxx:85
const char sCalc_Asin[]
Definition: calc.cxx:82
const char sCalc_Max[]
Definition: calc.cxx:78
const char sCalc_Count[]
Definition: calc.cxx:89
const char sCalc_And[]
Definition: calc.cxx:67
const char sCalc_Sign[]
Definition: calc.cxx:90
const char sCalc_Sum[]
Definition: calc.cxx:75
const char sCalc_Xor[]
Definition: calc.cxx:66
const char sCalc_Pow[]
Definition: calc.cxx:64
CalcOp * FindOperator(const OUString &rSearch)
Definition: calc.cxx:185
const char sCalc_Or[]
Definition: calc.cxx:65
const char sCalc_Mean[]
Definition: calc.cxx:76
const char sCalc_Div[]
Definition: calc.cxx:61
const char sCalc_Product[]
Definition: calc.cxx:87
const char sCalc_Atan[]
Definition: calc.cxx:84
const char sCalc_Cos[]
Definition: calc.cxx:80
const char sCalc_Tan[]
Definition: calc.cxx:81
const char sCalc_G[]
Definition: calc.cxx:74
SwCalcOper
Definition: calc.hxx:44
@ CALC_SIN
Definition: calc.hxx:55
@ CALC_ACOS
Definition: calc.hxx:57
@ CALC_OR
Definition: calc.hxx:50
@ CALC_TDIF
Definition: calc.hxx:57
@ CALC_ENDCALC
Definition: calc.hxx:45
@ CALC_GEQ
Definition: calc.hxx:52
@ CALC_NOT
Definition: calc.hxx:50
@ CALC_DAY
Definition: calc.hxx:59
@ CALC_PRINT
Definition: calc.hxx:47
@ CALC_PRODUCT
Definition: calc.hxx:59
@ CALC_AND
Definition: calc.hxx:50
@ CALC_NEQ
Definition: calc.hxx:51
@ CALC_MUL
Definition: calc.hxx:46
@ CALC_MAX
Definition: calc.hxx:55
@ CALC_EQ
Definition: calc.hxx:51
@ CALC_ASSIGN
Definition: calc.hxx:47
@ CALC_ROUND
Definition: calc.hxx:58
@ CALC_ATAN
Definition: calc.hxx:57
@ CALC_RP
Definition: calc.hxx:48
@ CALC_XOR
Definition: calc.hxx:51
@ CALC_MIN_IN
Definition: calc.hxx:54
@ CALC_MONTH
Definition: calc.hxx:58
@ CALC_INT
Definition: calc.hxx:61
@ CALC_SIGN
Definition: calc.hxx:60
@ CALC_DATE
Definition: calc.hxx:58
@ CALC_COUNT
Definition: calc.hxx:60
@ CALC_MIN
Definition: calc.hxx:54
@ CALC_SUM
Definition: calc.hxx:53
@ CALC_NAME
Definition: calc.hxx:45
@ CALC_COS
Definition: calc.hxx:56
@ CALC_ASIN
Definition: calc.hxx:56
@ CALC_MAX_IN
Definition: calc.hxx:55
@ CALC_ABS
Definition: calc.hxx:60
@ CALC_GRE
Definition: calc.hxx:53
@ CALC_PHD
Definition: calc.hxx:48
@ CALC_LES
Definition: calc.hxx:52
@ CALC_PLUS
Definition: calc.hxx:46
@ CALC_POW
Definition: calc.hxx:49
@ CALC_AVERAGE
Definition: calc.hxx:59
@ CALC_LEQ
Definition: calc.hxx:52
@ CALC_DIV
Definition: calc.hxx:47
@ CALC_MINUS
Definition: calc.hxx:46
@ CALC_NUMBER
Definition: calc.hxx:45
@ CALC_MEAN
Definition: calc.hxx:53
@ CALC_SQRT
Definition: calc.hxx:54
@ CALC_TAN
Definition: calc.hxx:56
@ CALC_LP
Definition: calc.hxx:48
const char sCalc_Geq[]
Definition: calc.cxx:72
const char sCalc_Phd[]
Definition: calc.cxx:62
const char sCalc_Average[]
Definition: calc.cxx:88
bool PutDouble(double)
bool PutLong(sal_Int32)
Definition: calc.hxx:199
OUString GetStrResult(const SwSbxValue &rValue)
Definition: calc.cxx:390
void SetCalcError(SwCalcError eErr)
Definition: calc.hxx:254
static SW_DLLPUBLIC bool IsValidVarName(const OUString &rStr, OUString *pValidName=nullptr)
Definition: calc.cxx:1419
OUStringBuffer m_aVarName
Definition: calc.hxx:201
void Pop()
Definition: calc.cxx:624
SwSbxValue Prim()
Definition: calc.cxx:1271
OUString m_sCurrSym
Definition: calc.hxx:202
const CharClass * GetCharClass() const
Definition: calc.cxx:631
SwCalcOper GetToken()
Definition: calc.cxx:641
std::vector< const SwUserFieldType * > m_aRekurStack
Definition: calc.hxx:204
~SwCalc()
Definition: calc.cxx:357
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
Definition: calc.cxx:596
SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig)
Definition: calc.cxx:1047
SwHashTable< SwCalcExp > & GetVarTable()
Definition: calc.hxx:247
SwDoc & m_rDoc
Definition: calc.hxx:210
SwCalcExp * VarInsert(const OUString &r)
Definition: calc.cxx:422
SwCalcError m_eError
Definition: calc.hxx:218
SwSbxValue Expr()
Definition: calc.cxx:1308
SwCalc(const SwCalc &)=delete
void SetCharClass(const LanguageTag &rLanguageTag)
Definition: calc.cxx:636
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:362
SwSbxValue PrimFunc(bool &rChkPow)
Definition: calc.cxx:1059
OUString m_sCommand
Definition: calc.hxx:203
bool Push(const SwUserFieldType *pUserFieldType)
Definition: calc.cxx:615
SwCalcOper m_eCurrOper
Definition: calc.hxx:216
SwCalc & operator=(const SwCalc &)=delete
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
Definition: calc.cxx:428
SwSbxValue m_nLastLeft
Definition: calc.hxx:205
static OUString GetColumnName(const OUString &rName)
Definition: calc.cxx:1343
bool IsCalcError() const
Definition: calc.hxx:255
bool m_bHasNumber
Definition: calc.hxx:215
SwHashTable< SwCalcExp > m_aVarTable
Definition: calc.hxx:200
OUString GetDBName(std::u16string_view rName)
Definition: calc.cxx:1356
static bool Str2Double(const OUString &rStr, sal_Int32 &rPos, double &rVal)
Definition: calc.cxx:1392
SwCalcExp m_aErrExpr
Definition: calc.hxx:207
SwSbxValue m_nNumberValue
Definition: calc.hxx:206
bool IsCalcNotANumber() const
Definition: calc.hxx:256
sal_Int32 m_nCommandPos
Definition: calc.hxx:208
CharClass * m_pCharClass
Definition: calc.hxx:212
SwSbxValue Term()
Definition: calc.cxx:866
sal_uInt16 m_nListPor
Definition: calc.hxx:214
std::unique_ptr< LocaleDataWrapper > m_xLocaleDataWrapper
Definition: calc.hxx:211
SwCalcOper m_eCurrListOper
Definition: calc.hxx:217
void ImplDestroy()
Definition: calc.cxx:351
Definition: doc.hxx:194
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:242
T should be a subclass of SwHash.
Definition: calc.hxx:154
std::unique_ptr< T > const & operator[](size_t idx) const
Definition: calc.hxx:162
T * Find(std::u16string_view aStr, sal_uInt32 *pPos=nullptr) const
Definition: calc.hxx:165
void resize(size_t nSize)
Definition: calc.hxx:163
std::vector< std::unique_ptr< T > > m_aData
Definition: calc.hxx:155
std::unique_ptr< T > & operator[](size_t idx)
Definition: calc.hxx:161
SwHashTable(size_t nSize)
Definition: calc.hxx:157
bool m_bDBvalue
Definition: calc.hxx:116
bool m_bVoid
Definition: calc.hxx:115
bool IsDBvalue() const
Definition: calc.hxx:129
bool IsVoidValue() const
Definition: calc.hxx:126
bool GetBool() const
Definition: calc.cxx:1461
void SetVoidValue(bool bSet)
Definition: calc.hxx:127
double GetDouble() const
Definition: calc.cxx:1467
SwSbxValue & MakeDouble()
Definition: calc.cxx:1486
SwSbxValue(tools::Long n=0)
Definition: calc.hxx:119
void SetDBvalue(bool bSet)
Definition: calc.hxx:130
SwSbxValue(const double &rD)
Definition: calc.hxx:120
The shared part of a user field.
Definition: usrfld.hxx:35
const sal_uInt16 idx[]
sal_Int64 n
aStr
NONE
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
Definition: calc.cxx:96
SwSbxValue nValue
Definition: calc.hxx:144
SwCalcExp(const OUString &rStr, SwSbxValue aVal, const SwFieldType *pFieldType)
Definition: calc.cxx:1453
const SwFieldType * pFieldType
Definition: calc.hxx:145
Definition: calc.hxx:135
SwHash(OUString aStr)
Definition: calc.cxx:1444
OUString aStr
Definition: calc.hxx:138
std::unique_ptr< SwHash > pNext
Definition: calc.hxx:139
virtual ~SwHash()
Definition: calc.cxx:1449
#define SW_DLLPUBLIC
Definition: swdllapi.h:28
sal_uInt16 sal_Unicode
#define SAL_MAX_UINT32