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>
26 #include <unotools/syslocale.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 
33 class CharClass;
34 class LocaleDataWrapper;
35 class SwFieldType;
36 class SwDoc;
37 class SwUserFieldType;
38 
39 #define TBLSZ 47 // should be a prime, because of hash table
40 
41 const sal_Unicode cListDelim = '|';
42 
44 {
46  CALC_PLUS='+', CALC_MINUS='-', CALC_MUL='*',
48  CALC_LP='(', CALC_RP=')', CALC_PHD='%',
49  CALC_POW='^',
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,
53  CALC_GRE=265, CALC_SUM=266, CALC_MEAN=267,
55  CALC_MAX=271, CALC_MAX_IN=272, CALC_SIN=273,
56  CALC_COS=274, CALC_TAN=275, CALC_ASIN=276,
57  CALC_ACOS=278, CALC_ATAN=279, CALC_TDIF=280,
60  CALC_COUNT=287, CALC_SIGN=288, CALC_ABS=289,
62 };
63 
64 // Calculate Operations Strings
65 extern const char sCalc_Add[];
66 extern const char sCalc_Sub[];
67 extern const char sCalc_Mul[];
68 extern const char sCalc_Div[];
69 extern const char sCalc_Phd[];
70 extern const char sCalc_Sqrt[];
71 extern const char sCalc_Pow[];
72 extern const char sCalc_Or[];
73 extern const char sCalc_Xor[];
74 extern const char sCalc_And[];
75 extern const char sCalc_Not[];
76 extern const char sCalc_Eq[];
77 extern const char sCalc_Neq[];
78 extern const char sCalc_Leq[];
79 extern const char sCalc_Geq[];
80 extern const char sCalc_L[];
81 extern const char sCalc_G[];
82 extern const char sCalc_Sum[];
83 extern const char sCalc_Mean[];
84 extern const char sCalc_Average[];
85 extern const char sCalc_Product[];
86 extern const char sCalc_Count[];
87 extern const char sCalc_Min[];
88 extern const char sCalc_Max[];
89 extern const char sCalc_Sin[];
90 extern const char sCalc_Cos[];
91 extern const char sCalc_Tan[];
92 extern const char sCalc_Asin[];
93 extern const char sCalc_Acos[];
94 extern const char sCalc_Atan[];
95 extern const char sCalc_Round[];
96 extern const char sCalc_Date[];
97 extern const char sCalc_Sign[];
98 extern const char sCalc_Abs[];
99 extern const char sCalc_Int[];
100 
101 // Calculate ErrorCodes
102 enum 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 
113 class SwSbxValue final : public SbxValue
114 {
115  bool m_bVoid;
117 public:
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
134 struct SwHash
135 {
136  SwHash( const OUString& rStr );
137  virtual ~SwHash();
138  OUString aStr;
139  std::unique_ptr<SwHash> pNext;
140 };
141 
142 struct SwCalcExp final : public SwHash
143 {
146 
147  SwCalcExp( const OUString& rStr, const SwSbxValue& rVal,
148  const SwFieldType* pFieldType );
149 };
150 
152 template<class T>
154 {
155  std::vector<std::unique_ptr<T>> m_aData;
156 public:
157  SwHashTable(size_t nSize) : m_aData(nSize) {}
158  std::unique_ptr<T> & operator[](size_t idx) { return m_aData[idx]; }
159  std::unique_ptr<T> const & operator[](size_t idx) const { return m_aData[idx]; }
160  void resize(size_t nSize) { m_aData.resize(nSize); }
161 
162  T* Find( const OUString& rStr, sal_uInt16* pPos = nullptr ) const
163  {
164  size_t nTableSize = m_aData.size();
165  sal_uLong ii = 0;
166  for( sal_Int32 n = 0; n < rStr.getLength(); ++n )
167  {
168  ii = ii << 1 ^ rStr[n];
169  }
170  ii %= nTableSize;
171 
172  if( pPos )
173  *pPos = o3tl::narrowing<sal_uInt16>(ii);
174 
175  for( T* pEntry = m_aData[ii].get(); pEntry; pEntry = static_cast<T*>(pEntry->pNext.get()) )
176  {
177  if( rStr == pEntry->aStr )
178  {
179  return pEntry;
180  }
181  }
182  return nullptr;
183  }
184 
185 };
186 
187 
188 // if CalcOp != 0, this is a valid operator
189 struct CalcOp;
190 CalcOp* FindOperator( const OUString& rSearch );
191 
192 extern "C" typedef double (*pfCalc)(double);
193 
194 class SwCalc
195 {
197  OUStringBuffer m_aVarName;
198  OUString m_sCurrSym;
199  OUString m_sCommand;
200  std::vector<const SwUserFieldType*> m_aRekurStack;
204  sal_Int32 m_nCommandPos;
205 
207  std::unique_ptr<LocaleDataWrapper> m_xLocaleDataWrapper;
209 
210  sal_uInt16 m_nListPor;
211  bool m_bHasNumber; // fix COUNT() and AVERAGE(), if all cells are NaN
215 
217  SwSbxValue Expr();
218  SwSbxValue Term();
219  SwSbxValue PrimFunc(bool &rChkPow);
220  SwSbxValue Prim();
221  SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig);
222 
223  static OUString GetColumnName( const OUString& rName );
224  OUString GetDBName( std::u16string_view rName );
225 
226  SwCalc( const SwCalc& ) = delete;
227  SwCalc& operator=( const SwCalc& ) = delete;
228 
229 public:
230  SwCalc(SwDoc& rD);
231  ~SwCalc() COVERITY_NOEXCEPT_FALSE;
232 
233  SwSbxValue Calculate( const OUString &rStr );
234  OUString GetStrResult( const SwSbxValue& rValue );
235  OUString GetStrResult( double );
236 
237  SwCalcExp* VarInsert( const OUString& r );
238  SwCalcExp* VarLook( const OUString &rStr, bool bIns = false );
239  void VarChange( const OUString& rStr, const SwSbxValue& rValue );
240  void VarChange( const OUString& rStr, double );
242 
243  bool Push(const SwUserFieldType* pUserFieldType);
244  void Pop();
245  const CharClass* GetCharClass() const;
246  void SetCharClass(const LanguageTag& rLanguageTag);
247 
248  void SetCalcError( SwCalcError eErr ) { m_eError = eErr; }
249  bool IsCalcError() const { return SwCalcError::NONE != m_eError && SwCalcError::NaN != m_eError; }
250  bool IsCalcNotANumber() const { return SwCalcError::NaN == m_eError; }
251 
252  static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
253  double& rVal );
254  static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
255  double& rVal, SwDoc const *const pDoc );
256 
257  SW_DLLPUBLIC static bool IsValidVarName( const OUString& rStr,
258  OUString* pValidName = nullptr );
259 };
260 
261 #endif
262 
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:241
SwCalcExp(const OUString &rStr, const SwSbxValue &rVal, const SwFieldType *pFieldType)
Definition: calc.cxx:1447
Definition: calc.hxx:194
Definition: calc.hxx:134
std::unique_ptr< T > const & operator[](size_t idx) const
Definition: calc.hxx:159
const char sCalc_Atan[]
Definition: calc.cxx:83
const char sCalc_Sqrt[]
Definition: calc.cxx:62
The shared part of a user field.
Definition: usrfld.hxx:34
const char sCalc_Count[]
Definition: calc.cxx:88
SwSbxValue m_nLastLeft
Definition: calc.hxx:201
const char sCalc_Max[]
Definition: calc.cxx:77
bool m_bHasNumber
Definition: calc.hxx:211
CalcOp * FindOperator(const OUString &rSearch)
Definition: calc.cxx:184
Definition: calc.hxx:48
OUString m_sCommand
Definition: calc.hxx:199
const char sCalc_Add[]
Definition: calc.cxx:57
std::unique_ptr< LocaleDataWrapper > m_xLocaleDataWrapper
Definition: calc.hxx:207
sal_uIntPtr sal_uLong
long Long
SwCalc & operator=(const SwCalc &)=delete
bool IsCalcError() const
Definition: calc.hxx:249
SwCalc(const SwCalc &)=delete
sal_Int64 n
Definition: doc.hxx:187
const SwFieldType * pFieldType
Definition: calc.hxx:145
const char sCalc_Sign[]
Definition: calc.cxx:89
const char sCalc_Sub[]
Definition: calc.cxx:58
const char sCalc_Product[]
Definition: calc.cxx:86
bool IsCalcNotANumber() const
Definition: calc.hxx:250
std::unique_ptr< SwHash > pNext
Definition: calc.hxx:139
bool m_bVoid
Definition: calc.hxx:115
SwSbxValue Term()
Definition: calc.cxx:860
const char sCalc_Sin[]
Definition: calc.cxx:78
std::vector< std::unique_ptr< T > > m_aData
Definition: calc.hxx:155
const char sCalc_Leq[]
Definition: calc.cxx:70
const char sCalc_Date[]
Definition: calc.cxx:85
const char sCalc_Div[]
Definition: calc.cxx:60
sal_uInt16 sal_Unicode
void Pop()
Definition: calc.cxx:618
const char sCalc_Acos[]
Definition: calc.cxx:82
void SetCharClass(const LanguageTag &rLanguageTag)
Definition: calc.cxx:630
static bool Str2Double(const OUString &rStr, sal_Int32 &rPos, double &rVal)
Definition: calc.cxx:1386
SwCalcError
Definition: calc.hxx:102
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
Definition: calc.cxx:590
const char sCalc_Tan[]
Definition: calc.cxx:80
const char sCalc_Xor[]
Definition: calc.cxx:65
Definition: calc.hxx:51
sal_Int32 m_nCommandPos
Definition: calc.hxx:204
SwCalcOper m_eCurrListOper
Definition: calc.hxx:213
OUString GetDBName(std::u16string_view rName)
Definition: calc.cxx:1350
SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig)
Definition: calc.cxx:1041
SwSbxValue & MakeDouble()
Definition: calc.cxx:1480
Definition: calc.cxx:94
double(* pfCalc)(double)
Definition: calc.hxx:192
void SetDBvalue(bool bSet)
Definition: calc.hxx:130
SwSbxValue nValue
Definition: calc.hxx:144
double GetDouble() const
Definition: calc.cxx:1461
SwSbxValue Prim()
Definition: calc.cxx:1265
SwDoc & m_rDoc
Definition: calc.hxx:206
Definition: calc.hxx:48
bool PutLong(sal_Int32)
SwCalcOper GetToken()
Definition: calc.cxx:635
SwSbxValue m_nNumberValue
Definition: calc.hxx:202
const char sCalc_G[]
Definition: calc.cxx:73
const char sCalc_Asin[]
Definition: calc.cxx:81
const char sCalc_Min[]
Definition: calc.cxx:76
SwCalcExp m_aErrExpr
Definition: calc.hxx:203
virtual ~SwHash()
Definition: calc.cxx:1443
static OUString GetColumnName(const OUString &rName)
Definition: calc.cxx:1337
bool IsVoidValue() const
Definition: calc.hxx:126
SwCalcOper
Definition: calc.hxx:43
void SetCalcError(SwCalcError eErr)
Definition: calc.hxx:248
const char sCalc_Sum[]
Definition: calc.cxx:74
const char sCalc_Int[]
Definition: calc.cxx:91
const char sCalc_Or[]
Definition: calc.cxx:64
const char sCalc_Round[]
Definition: calc.cxx:84
T * Find(const OUString &rStr, sal_uInt16 *pPos=nullptr) const
Definition: calc.hxx:162
SwHash(const OUString &rStr)
Definition: calc.cxx:1438
#define SW_DLLPUBLIC
Definition: swdllapi.h:28
SwHashTable(size_t nSize)
Definition: calc.hxx:157
SwSbxValue(const double &rD)
Definition: calc.hxx:120
const char sCalc_Mean[]
Definition: calc.cxx:75
bool m_bDBvalue
Definition: calc.hxx:116
std::unique_ptr< T > & operator[](size_t idx)
Definition: calc.hxx:158
SwHashTable< SwCalcExp > & GetVarTable()
Definition: calc.hxx:241
static SW_DLLPUBLIC bool IsValidVarName(const OUString &rStr, OUString *pValidName=nullptr)
Definition: calc.cxx:1413
OUStringBuffer m_aVarName
Definition: calc.hxx:197
SwCalcError m_eError
Definition: calc.hxx:214
bool IsDBvalue() const
Definition: calc.hxx:129
void resize(size_t nSize)
Definition: calc.hxx:160
const char sCalc_Eq[]
Definition: calc.cxx:68
SwSbxValue Expr()
Definition: calc.cxx:1302
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:356
sal_uInt16 m_nListPor
Definition: calc.hxx:210
const char sCalc_And[]
Definition: calc.cxx:66
~SwCalc() COVERITY_NOEXCEPT_FALSE
Definition: calc.cxx:350
SwHashTable< SwCalcExp > m_aVarTable
Definition: calc.hxx:196
const char sCalc_Phd[]
Definition: calc.cxx:61
SwSbxValue(tools::Long n=0)
Definition: calc.hxx:119
bool PutDouble(double)
const char sCalc_Not[]
Definition: calc.cxx:67
bool GetBool() const
Definition: calc.cxx:1455
const char sCalc_Abs[]
Definition: calc.cxx:90
OUString GetStrResult(const SwSbxValue &rValue)
Definition: calc.cxx:384
const char sCalc_Geq[]
Definition: calc.cxx:71
CharClass * m_pCharClass
Definition: calc.hxx:208
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
Definition: calc.cxx:422
SwSbxValue PrimFunc(bool &rChkPow)
Definition: calc.cxx:1053
SwCalcOper m_eCurrOper
Definition: calc.hxx:212
const char sCalc_L[]
Definition: calc.cxx:72
const CharClass * GetCharClass() const
Definition: calc.cxx:625
SwCalcExp * VarInsert(const OUString &r)
Definition: calc.cxx:416
OUString m_sCurrSym
Definition: calc.hxx:198
const sal_Unicode cListDelim
Definition: calc.hxx:41
const char sCalc_Cos[]
Definition: calc.cxx:79
bool Push(const SwUserFieldType *pUserFieldType)
Definition: calc.cxx:609
const char sCalc_Average[]
Definition: calc.cxx:87
const char sCalc_Neq[]
Definition: calc.cxx:69
const char sCalc_Pow[]
Definition: calc.cxx:63
T should be a subclass of SwHash.
Definition: calc.hxx:153
OUString aStr
Definition: calc.hxx:138
Definition: calc.hxx:50
std::vector< const SwUserFieldType * > m_aRekurStack
Definition: calc.hxx:200
void SetVoidValue(bool bSet)
Definition: calc.hxx:127
bool m_bDetectedRangeSegmentation false
const char sCalc_Mul[]
Definition: calc.cxx:59