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,
61 };
62 
63 // Calculate Operations Strings
64 extern const char sCalc_Add[];
65 extern const char sCalc_Sub[];
66 extern const char sCalc_Mul[];
67 extern const char sCalc_Div[];
68 extern const char sCalc_Phd[];
69 extern const char sCalc_Sqrt[];
70 extern const char sCalc_Pow[];
71 extern const char sCalc_Or[];
72 extern const char sCalc_Xor[];
73 extern const char sCalc_And[];
74 extern const char sCalc_Not[];
75 extern const char sCalc_Eq[];
76 extern const char sCalc_Neq[];
77 extern const char sCalc_Leq[];
78 extern const char sCalc_Geq[];
79 extern const char sCalc_L[];
80 extern const char sCalc_G[];
81 extern const char sCalc_Sum[];
82 extern const char sCalc_Mean[];
83 extern const char sCalc_Average[];
84 extern const char sCalc_Product[];
85 extern const char sCalc_Count[];
86 extern const char sCalc_Min[];
87 extern const char sCalc_Max[];
88 extern const char sCalc_Sin[];
89 extern const char sCalc_Cos[];
90 extern const char sCalc_Tan[];
91 extern const char sCalc_Asin[];
92 extern const char sCalc_Acos[];
93 extern const char sCalc_Atan[];
94 extern const char sCalc_Round[];
95 extern const char sCalc_Date[];
96 extern const char sCalc_Sign[];
97 extern const char sCalc_Abs[];
98 
99 // Calculate ErrorCodes
100 enum class SwCalcError
101 {
102  NONE=0,
103  NaN, // not a number (not an error, used for interoperability)
104  Syntax, // syntax error
105  DivByZero, // division by zero
106  FaultyBrackets, // faulty brackets
107  OverflowInPower, // overflow in power function
108  Overflow, // overflow
109 };
110 
111 class SwSbxValue final : public SbxValue
112 {
113  bool m_bVoid;
115 public:
116  // always default to a number. otherwise it will become a SbxEMPTY
117  SwSbxValue( tools::Long n = 0 ) : m_bVoid(false), m_bDBvalue(false) { PutLong( n ); }
118  SwSbxValue( const double& rD ) : m_bVoid(false), m_bDBvalue(false) { PutDouble( rD ); }
119 
120  bool GetBool() const;
121  double GetDouble() const;
123 
124  bool IsVoidValue() const {return m_bVoid;}
125  void SetVoidValue(bool bSet) {m_bVoid = bSet;}
126 
127  bool IsDBvalue() const {return m_bDBvalue;}
128  void SetDBvalue(bool bSet) {m_bDBvalue = bSet;}
129 };
130 
131 // Calculate HashTables for VarTable and Operations
132 struct SwHash
133 {
134  SwHash( const OUString& rStr );
135  virtual ~SwHash();
136  OUString aStr;
137  std::unique_ptr<SwHash> pNext;
138 };
139 
140 struct SwCalcExp final : public SwHash
141 {
144 
145  SwCalcExp( const OUString& rStr, const SwSbxValue& rVal,
146  const SwFieldType* pFieldType );
147 };
148 
150 template<class T>
152 {
153  std::vector<std::unique_ptr<T>> m_aData;
154 public:
155  SwHashTable(size_t nSize) : m_aData(nSize) {}
156  std::unique_ptr<T> & operator[](size_t idx) { return m_aData[idx]; }
157  std::unique_ptr<T> const & operator[](size_t idx) const { return m_aData[idx]; }
158  void resize(size_t nSize) { m_aData.resize(nSize); }
159 
160  T* Find( const OUString& rStr, sal_uInt16* pPos = nullptr ) const
161  {
162  size_t nTableSize = m_aData.size();
163  sal_uLong ii = 0;
164  for( sal_Int32 n = 0; n < rStr.getLength(); ++n )
165  {
166  ii = ii << 1 ^ rStr[n];
167  }
168  ii %= nTableSize;
169 
170  if( pPos )
171  *pPos = o3tl::narrowing<sal_uInt16>(ii);
172 
173  for( T* pEntry = m_aData[ii].get(); pEntry; pEntry = static_cast<T*>(pEntry->pNext.get()) )
174  {
175  if( rStr == pEntry->aStr )
176  {
177  return pEntry;
178  }
179  }
180  return nullptr;
181  }
182 
183 };
184 
185 
186 // if CalcOp != 0, this is a valid operator
187 struct CalcOp;
188 CalcOp* FindOperator( const OUString& rSearch );
189 
190 extern "C" typedef double (*pfCalc)(double);
191 
192 class SwCalc
193 {
195  OUStringBuffer m_aVarName;
196  OUString m_sCurrSym;
197  OUString m_sCommand;
198  std::vector<const SwUserFieldType*> m_aRekurStack;
202  sal_Int32 m_nCommandPos;
203 
205  std::unique_ptr<LocaleDataWrapper> m_xLocaleDataWrapper;
207 
208  sal_uInt16 m_nListPor;
209  bool m_bHasNumber; // fix COUNT() and AVERAGE(), if all cells are NaN
213 
215  SwSbxValue Expr();
216  SwSbxValue Term();
217  SwSbxValue PrimFunc(bool &rChkPow);
218  SwSbxValue Prim();
219  SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig);
220 
221  static OUString GetColumnName( const OUString& rName );
222  OUString GetDBName( const OUString& rName );
223 
224  SwCalc( const SwCalc& ) = delete;
225  SwCalc& operator=( const SwCalc& ) = delete;
226 
227 public:
228  SwCalc(SwDoc& rD);
229  ~SwCalc() COVERITY_NOEXCEPT_FALSE;
230 
231  SwSbxValue Calculate( const OUString &rStr );
232  OUString GetStrResult( const SwSbxValue& rValue );
233  OUString GetStrResult( double );
234 
235  SwCalcExp* VarInsert( const OUString& r );
236  SwCalcExp* VarLook( const OUString &rStr, bool bIns = false );
237  void VarChange( const OUString& rStr, const SwSbxValue& rValue );
238  void VarChange( const OUString& rStr, double );
240 
241  bool Push(const SwUserFieldType* pUserFieldType);
242  void Pop();
244 
245  void SetCalcError( SwCalcError eErr ) { m_eError = eErr; }
246  bool IsCalcError() const { return SwCalcError::NONE != m_eError && SwCalcError::NaN != m_eError; }
247  bool IsCalcNotANumber() const { return SwCalcError::NaN == m_eError; }
248 
249  static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
250  double& rVal );
251  static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
252  double& rVal, SwDoc const *const pDoc );
253 
254  SW_DLLPUBLIC static bool IsValidVarName( const OUString& rStr,
255  OUString* pValidName = nullptr );
256 };
257 
258 #endif
259 
260 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:240
SwCalcExp(const OUString &rStr, const SwSbxValue &rVal, const SwFieldType *pFieldType)
Definition: calc.cxx:1432
Definition: calc.hxx:192
Definition: calc.hxx:132
std::unique_ptr< T > const & operator[](size_t idx) const
Definition: calc.hxx:157
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:199
const char sCalc_Max[]
Definition: calc.cxx:77
bool m_bHasNumber
Definition: calc.hxx:209
CalcOp * FindOperator(const OUString &rSearch)
Definition: calc.cxx:182
Definition: calc.hxx:48
OUString m_sCommand
Definition: calc.hxx:197
const char sCalc_Add[]
Definition: calc.cxx:57
std::unique_ptr< LocaleDataWrapper > m_xLocaleDataWrapper
Definition: calc.hxx:205
sal_uIntPtr sal_uLong
long Long
SwCalc & operator=(const SwCalc &)=delete
bool IsCalcError() const
Definition: calc.hxx:246
SwCalc(const SwCalc &)=delete
sal_Int64 n
Definition: doc.hxx:188
const SwFieldType * pFieldType
Definition: calc.hxx:143
const char sCalc_Sign[]
Definition: calc.cxx:89
const char sCalc_Sub[]
Definition: calc.cxx:58
CharClass * GetCharClass()
Definition: calc.cxx:624
const char sCalc_Product[]
Definition: calc.cxx:86
bool IsCalcNotANumber() const
Definition: calc.hxx:247
std::unique_ptr< SwHash > pNext
Definition: calc.hxx:137
bool m_bVoid
Definition: calc.hxx:113
SwSbxValue Term()
Definition: calc.cxx:854
const char sCalc_Sin[]
Definition: calc.cxx:78
std::vector< std::unique_ptr< T > > m_aData
Definition: calc.hxx:153
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:617
const char sCalc_Acos[]
Definition: calc.cxx:82
static bool Str2Double(const OUString &rStr, sal_Int32 &rPos, double &rVal)
Definition: calc.cxx:1371
SwCalcError
Definition: calc.hxx:100
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
Definition: calc.cxx:589
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:202
SwCalcOper m_eCurrListOper
Definition: calc.hxx:211
SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig)
Definition: calc.cxx:1035
SwSbxValue & MakeDouble()
Definition: calc.cxx:1465
Definition: calc.cxx:93
double(* pfCalc)(double)
Definition: calc.hxx:190
void SetDBvalue(bool bSet)
Definition: calc.hxx:128
SwSbxValue nValue
Definition: calc.hxx:142
double GetDouble() const
Definition: calc.cxx:1446
SwSbxValue Prim()
Definition: calc.cxx:1250
SwDoc & m_rDoc
Definition: calc.hxx:204
Definition: calc.hxx:48
bool PutLong(sal_Int32)
SwCalcOper GetToken()
Definition: calc.cxx:629
SwSbxValue m_nNumberValue
Definition: calc.hxx:200
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:201
virtual ~SwHash()
Definition: calc.cxx:1428
static OUString GetColumnName(const OUString &rName)
Definition: calc.cxx:1322
bool IsVoidValue() const
Definition: calc.hxx:124
SwCalcOper
Definition: calc.hxx:43
void SetCalcError(SwCalcError eErr)
Definition: calc.hxx:245
const char sCalc_Sum[]
Definition: calc.cxx:74
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:160
SwHash(const OUString &rStr)
Definition: calc.cxx:1423
#define SW_DLLPUBLIC
Definition: swdllapi.h:28
SwHashTable(size_t nSize)
Definition: calc.hxx:155
SwSbxValue(const double &rD)
Definition: calc.hxx:118
const char sCalc_Mean[]
Definition: calc.cxx:75
bool m_bDBvalue
Definition: calc.hxx:114
std::unique_ptr< T > & operator[](size_t idx)
Definition: calc.hxx:156
SwHashTable< SwCalcExp > & GetVarTable()
Definition: calc.hxx:239
static SW_DLLPUBLIC bool IsValidVarName(const OUString &rStr, OUString *pValidName=nullptr)
Definition: calc.cxx:1398
OUStringBuffer m_aVarName
Definition: calc.hxx:195
SwCalcError m_eError
Definition: calc.hxx:212
bool IsDBvalue() const
Definition: calc.hxx:127
void resize(size_t nSize)
Definition: calc.hxx:158
const char sCalc_Eq[]
Definition: calc.cxx:68
SwSbxValue Expr()
Definition: calc.cxx:1287
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:354
sal_uInt16 m_nListPor
Definition: calc.hxx:208
const char sCalc_And[]
Definition: calc.cxx:66
~SwCalc() COVERITY_NOEXCEPT_FALSE
Definition: calc.cxx:348
SwHashTable< SwCalcExp > m_aVarTable
Definition: calc.hxx:194
const char sCalc_Phd[]
Definition: calc.cxx:61
SwSbxValue(tools::Long n=0)
Definition: calc.hxx:117
bool PutDouble(double)
const char sCalc_Not[]
Definition: calc.cxx:67
bool GetBool() const
Definition: calc.cxx:1440
const char sCalc_Abs[]
Definition: calc.cxx:90
OUString GetStrResult(const SwSbxValue &rValue)
Definition: calc.cxx:382
const char sCalc_Geq[]
Definition: calc.cxx:71
CharClass * m_pCharClass
Definition: calc.hxx:206
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
Definition: calc.cxx:420
SwSbxValue PrimFunc(bool &rChkPow)
Definition: calc.cxx:1047
SwCalcOper m_eCurrOper
Definition: calc.hxx:210
const char sCalc_L[]
Definition: calc.cxx:72
SwCalcExp * VarInsert(const OUString &r)
Definition: calc.cxx:414
OUString m_sCurrSym
Definition: calc.hxx:196
const sal_Unicode cListDelim
Definition: calc.hxx:41
OUString GetDBName(const OUString &rName)
Definition: calc.cxx:1335
const char sCalc_Cos[]
Definition: calc.cxx:79
bool Push(const SwUserFieldType *pUserFieldType)
Definition: calc.cxx:608
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:151
OUString aStr
Definition: calc.hxx:136
Definition: calc.hxx:50
std::vector< const SwUserFieldType * > m_aRekurStack
Definition: calc.hxx:198
void SetVoidValue(bool bSet)
Definition: calc.hxx:125
const char sCalc_Mul[]
Definition: calc.cxx:59