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 "swdllapi.h"
31 
32 class CharClass;
33 class LocaleDataWrapper;
34 class SwFieldType;
35 class SwDoc;
36 class SwUserFieldType;
37 
38 #define TBLSZ 47 // should be a prime, because of hash table
39 
40 const sal_Unicode cListDelim = '|';
41 
43 {
45  CALC_PLUS='+', CALC_MINUS='-', CALC_MUL='*',
47  CALC_LP='(', CALC_RP=')', CALC_PHD='%',
48  CALC_POW='^',
49  CALC_NOT=256, CALC_AND=257, CALC_OR=258,
50  CALC_XOR=259, CALC_EQ=260, CALC_NEQ=261,
51  CALC_LEQ=262, CALC_GEQ=263, CALC_LES=264,
52  CALC_GRE=265, CALC_SUM=266, CALC_MEAN=267,
54  CALC_MAX=271, CALC_MAX_IN=272, CALC_SIN=273,
55  CALC_COS=274, CALC_TAN=275, CALC_ASIN=276,
56  CALC_ACOS=278, CALC_ATAN=279, CALC_TDIF=280,
60 };
61 
62 // Calculate Operations Strings
63 extern const char sCalc_Add[];
64 extern const char sCalc_Sub[];
65 extern const char sCalc_Mul[];
66 extern const char sCalc_Div[];
67 extern const char sCalc_Phd[];
68 extern const char sCalc_Sqrt[];
69 extern const char sCalc_Pow[];
70 extern const char sCalc_Or[];
71 extern const char sCalc_Xor[];
72 extern const char sCalc_And[];
73 extern const char sCalc_Not[];
74 extern const char sCalc_Eq[];
75 extern const char sCalc_Neq[];
76 extern const char sCalc_Leq[];
77 extern const char sCalc_Geq[];
78 extern const char sCalc_L[];
79 extern const char sCalc_G[];
80 extern const char sCalc_Sum[];
81 extern const char sCalc_Mean[];
82 extern const char sCalc_Average[];
83 extern const char sCalc_Product[];
84 extern const char sCalc_Count[];
85 extern const char sCalc_Min[];
86 extern const char sCalc_Max[];
87 extern const char sCalc_Sin[];
88 extern const char sCalc_Cos[];
89 extern const char sCalc_Tan[];
90 extern const char sCalc_Asin[];
91 extern const char sCalc_Acos[];
92 extern const char sCalc_Atan[];
93 extern const char sCalc_Round[];
94 extern const char sCalc_Date[];
95 extern const char sCalc_Sign[];
96 extern const char sCalc_Abs[];
97 
98 // Calculate ErrorCodes
99 enum class SwCalcError
100 {
101  NONE=0,
102  NaN, // not a number (not an error, used for interoperability)
103  Syntax, // syntax error
104  DivByZero, // division by zero
105  FaultyBrackets, // faulty brackets
106  OverflowInPower, // overflow in power function
107  Overflow, // overflow
108 };
109 
110 class SwSbxValue final : public SbxValue
111 {
112  bool m_bVoid;
114 public:
115  // always default to a number. otherwise it will become a SbxEMPTY
116  SwSbxValue( tools::Long n = 0 ) : m_bVoid(false), m_bDBvalue(false) { PutLong( n ); }
117  SwSbxValue( const double& rD ) : m_bVoid(false), m_bDBvalue(false) { PutDouble( rD ); }
118 
119  bool GetBool() const;
120  double GetDouble() const;
122 
123  bool IsVoidValue() const {return m_bVoid;}
124  void SetVoidValue(bool bSet) {m_bVoid = bSet;}
125 
126  bool IsDBvalue() const {return m_bDBvalue;}
127  void SetDBvalue(bool bSet) {m_bDBvalue = bSet;}
128 };
129 
130 // Calculate HashTables for VarTable and Operations
131 struct SwHash
132 {
133  SwHash( const OUString& rStr );
134  virtual ~SwHash();
135  OUString aStr;
136  std::unique_ptr<SwHash> pNext;
137 };
138 
139 struct SwCalcExp final : public SwHash
140 {
143 
144  SwCalcExp( const OUString& rStr, const SwSbxValue& rVal,
145  const SwFieldType* pFieldType );
146 };
147 
149 template<class T>
151 {
152  std::vector<std::unique_ptr<T>> m_aData;
153 public:
154  SwHashTable(size_t nSize) : m_aData(nSize) {}
155  std::unique_ptr<T> & operator[](size_t idx) { return m_aData[idx]; }
156  std::unique_ptr<T> const & operator[](size_t idx) const { return m_aData[idx]; }
157  void resize(size_t nSize) { m_aData.resize(nSize); }
158 
159  T* Find( const OUString& rStr, sal_uInt16* pPos = nullptr ) const
160  {
161  size_t nTableSize = m_aData.size();
162  sal_uLong ii = 0;
163  for( sal_Int32 n = 0; n < rStr.getLength(); ++n )
164  {
165  ii = ii << 1 ^ rStr[n];
166  }
167  ii %= nTableSize;
168 
169  if( pPos )
170  *pPos = static_cast<sal_uInt16>(ii);
171 
172  for( T* pEntry = m_aData[ii].get(); pEntry; pEntry = static_cast<T*>(pEntry->pNext.get()) )
173  {
174  if( rStr == pEntry->aStr )
175  {
176  return pEntry;
177  }
178  }
179  return nullptr;
180  }
181 
182 };
183 
184 
185 // if CalcOp != 0, this is a valid operator
186 struct CalcOp;
187 CalcOp* FindOperator( const OUString& rSearch );
188 
189 extern "C" typedef double (*pfCalc)(double);
190 
191 class SwCalc
192 {
194  OUStringBuffer m_aVarName;
195  OUString m_sCurrSym;
196  OUString m_sCommand;
197  std::vector<const SwUserFieldType*> m_aRekurStack;
201  sal_Int32 m_nCommandPos;
202 
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:1454
Definition: calc.hxx:191
Definition: calc.hxx:131
std::unique_ptr< T > const & operator[](size_t idx) const
Definition: calc.hxx:156
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:35
const char sCalc_Count[]
Definition: calc.cxx:88
SwSbxValue m_nLastLeft
Definition: calc.hxx:198
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:47
OUString m_sCommand
Definition: calc.hxx:196
const char sCalc_Add[]
Definition: calc.cxx:57
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:184
const SwFieldType * pFieldType
Definition: calc.hxx:142
const char sCalc_Sign[]
Definition: calc.cxx:89
const char sCalc_Sub[]
Definition: calc.cxx:58
CharClass * GetCharClass()
Definition: calc.cxx:628
const char sCalc_Product[]
Definition: calc.cxx:86
bool IsCalcNotANumber() const
Definition: calc.hxx:247
std::unique_ptr< SwHash > pNext
Definition: calc.hxx:136
bool m_bVoid
Definition: calc.hxx:112
SwSbxValue Term()
Definition: calc.cxx:858
const char sCalc_Sin[]
Definition: calc.cxx:78
std::vector< std::unique_ptr< T > > m_aData
Definition: calc.hxx:152
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:621
const char sCalc_Acos[]
Definition: calc.cxx:82
static bool Str2Double(const OUString &rStr, sal_Int32 &rPos, double &rVal)
Definition: calc.cxx:1393
SwCalcError
Definition: calc.hxx:99
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
Definition: calc.cxx:593
const char sCalc_Tan[]
Definition: calc.cxx:80
const char sCalc_Xor[]
Definition: calc.cxx:65
Definition: calc.hxx:50
sal_Int32 m_nCommandPos
Definition: calc.hxx:201
SwCalcOper m_eCurrListOper
Definition: calc.hxx:211
SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig)
Definition: calc.cxx:1039
SwSbxValue & MakeDouble()
Definition: calc.cxx:1487
Definition: calc.cxx:93
double(* pfCalc)(double)
Definition: calc.hxx:189
void SetDBvalue(bool bSet)
Definition: calc.hxx:127
SwSbxValue nValue
Definition: calc.hxx:141
double GetDouble() const
Definition: calc.cxx:1468
SwSbxValue Prim()
Definition: calc.cxx:1272
SwDoc & m_rDoc
Definition: calc.hxx:203
Definition: calc.hxx:47
bool PutLong(sal_Int32)
SwCalcOper GetToken()
Definition: calc.cxx:633
SwSbxValue m_nNumberValue
Definition: calc.hxx:199
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:200
virtual ~SwHash()
Definition: calc.cxx:1450
static OUString GetColumnName(const OUString &rName)
Definition: calc.cxx:1344
bool IsVoidValue() const
Definition: calc.hxx:123
SwCalcOper
Definition: calc.hxx:42
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:159
SwHash(const OUString &rStr)
Definition: calc.cxx:1445
#define SW_DLLPUBLIC
Definition: swdllapi.h:28
SwHashTable(size_t nSize)
Definition: calc.hxx:154
SwSbxValue(const double &rD)
Definition: calc.hxx:117
const char sCalc_Mean[]
Definition: calc.cxx:75
bool m_bDBvalue
Definition: calc.hxx:113
std::unique_ptr< T > & operator[](size_t idx)
Definition: calc.hxx:155
SwHashTable< SwCalcExp > & GetVarTable()
Definition: calc.hxx:239
static SW_DLLPUBLIC bool IsValidVarName(const OUString &rStr, OUString *pValidName=nullptr)
Definition: calc.cxx:1420
OUStringBuffer m_aVarName
Definition: calc.hxx:194
SwCalcError m_eError
Definition: calc.hxx:212
bool IsDBvalue() const
Definition: calc.hxx:126
void resize(size_t nSize)
Definition: calc.hxx:157
const char sCalc_Eq[]
Definition: calc.cxx:68
SwSbxValue Expr()
Definition: calc.cxx:1309
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:358
sal_uInt16 m_nListPor
Definition: calc.hxx:208
const char sCalc_And[]
Definition: calc.cxx:66
~SwCalc() COVERITY_NOEXCEPT_FALSE
Definition: calc.cxx:350
SwHashTable< SwCalcExp > m_aVarTable
Definition: calc.hxx:193
const char sCalc_Phd[]
Definition: calc.cxx:61
SwSbxValue(tools::Long n=0)
Definition: calc.hxx:116
bool PutDouble(double)
const char sCalc_Not[]
Definition: calc.cxx:67
bool GetBool() const
Definition: calc.cxx:1462
const char sCalc_Abs[]
Definition: calc.cxx:90
OUString GetStrResult(const SwSbxValue &rValue)
Definition: calc.cxx:386
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:424
SwSbxValue PrimFunc(bool &rChkPow)
Definition: calc.cxx:1051
SwCalcOper m_eCurrOper
Definition: calc.hxx:210
const LocaleDataWrapper * m_pLocaleDataWrapper
Definition: calc.hxx:205
const char sCalc_L[]
Definition: calc.cxx:72
SwCalcExp * VarInsert(const OUString &r)
Definition: calc.cxx:418
SvtSysLocale m_aSysLocale
Definition: calc.hxx:204
OUString m_sCurrSym
Definition: calc.hxx:195
const sal_Unicode cListDelim
Definition: calc.hxx:40
OUString GetDBName(const OUString &rName)
Definition: calc.cxx:1357
const char sCalc_Cos[]
Definition: calc.cxx:79
bool Push(const SwUserFieldType *pUserFieldType)
Definition: calc.cxx:612
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:150
OUString aStr
Definition: calc.hxx:135
Definition: calc.hxx:49
std::vector< const SwUserFieldType * > m_aRekurStack
Definition: calc.hxx:197
void SetVoidValue(bool bSet)
Definition: calc.hxx:124
const char sCalc_Mul[]
Definition: calc.cxx:59