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 "swdllapi.h"
30 
31 class CharClass;
32 class LocaleDataWrapper;
33 class SwFieldType;
34 class SwDoc;
35 class SwUserFieldType;
36 
37 #define TBLSZ 47 // should be a prime, because of hash table
38 
39 const sal_Unicode cListDelim = '|';
40 
42 {
44  CALC_PLUS='+', CALC_MINUS='-', CALC_MUL='*',
46  CALC_LP='(', CALC_RP=')', CALC_PHD='%',
47  CALC_POW='^',
48  CALC_NOT=256, CALC_AND=257, CALC_OR=258,
49  CALC_XOR=259, CALC_EQ=260, CALC_NEQ=261,
50  CALC_LEQ=262, CALC_GEQ=263, CALC_LES=264,
51  CALC_GRE=265, CALC_SUM=266, CALC_MEAN=267,
53  CALC_MAX=271, CALC_MAX_IN=272, CALC_SIN=273,
54  CALC_COS=274, CALC_TAN=275, CALC_ASIN=276,
55  CALC_ACOS=278, CALC_ATAN=279, CALC_TDIF=280,
58 };
59 
60 // Calculate Operations Strings
61 extern const sal_Char sCalc_Add[];
62 extern const sal_Char sCalc_Sub[];
63 extern const sal_Char sCalc_Mul[];
64 extern const sal_Char sCalc_Div[];
65 extern const sal_Char sCalc_Phd[];
66 extern const sal_Char sCalc_Sqrt[];
67 extern const sal_Char sCalc_Pow[];
68 extern const sal_Char sCalc_Or[];
69 extern const sal_Char sCalc_Xor[];
70 extern const sal_Char sCalc_And[];
71 extern const sal_Char sCalc_Not[];
72 extern const sal_Char sCalc_Eq[];
73 extern const sal_Char sCalc_Neq[];
74 extern const sal_Char sCalc_Leq[];
75 extern const sal_Char sCalc_Geq[];
76 extern const sal_Char sCalc_L[];
77 extern const sal_Char sCalc_G[];
78 extern const sal_Char sCalc_Sum[];
79 extern const sal_Char sCalc_Mean[];
80 extern const sal_Char sCalc_Min[];
81 extern const sal_Char sCalc_Max[];
82 extern const sal_Char sCalc_Sin[];
83 extern const sal_Char sCalc_Cos[];
84 extern const sal_Char sCalc_Tan[];
85 extern const sal_Char sCalc_Asin[];
86 extern const sal_Char sCalc_Acos[];
87 extern const sal_Char sCalc_Atan[];
88 extern const sal_Char sCalc_Tdif[];
89 extern const sal_Char sCalc_Round[];
90 extern const sal_Char sCalc_Date[];
91 
92 // Calculate ErrorCodes
93 enum class SwCalcError
94 {
95  NONE=0,
96  Syntax, // syntax error
97  DivByZero, // division by zero
98  FaultyBrackets, // faulty brackets
99  OverflowInPower, // overflow in power function
100  Overflow, // overflow
101 };
102 
103 class SwSbxValue : public SbxValue
104 {
105  bool m_bVoid;
107 public:
108  // always default to a number. otherwise it will become a SbxEMPTY
109  SwSbxValue( long n = 0 ) : m_bVoid(false), m_bDBvalue(false) { PutLong( n ); }
110  SwSbxValue( const double& rD ) : m_bVoid(false), m_bDBvalue(false) { PutDouble( rD ); }
111 
112  bool GetBool() const;
113  double GetDouble() const;
115 
116  bool IsVoidValue() {return m_bVoid;}
117  void SetVoidValue(bool bSet) {m_bVoid = bSet;}
118 
119  bool IsDBvalue() {return m_bDBvalue;}
120  void SetDBvalue(bool bSet) {m_bDBvalue = bSet;}
121 };
122 
123 // Calculate HashTables for VarTable and Operations
124 struct SwHash
125 {
126  SwHash( const OUString& rStr );
127  virtual ~SwHash();
128  OUString aStr;
129  std::unique_ptr<SwHash> pNext;
130 };
131 
132 struct SwCalcExp : public SwHash
133 {
136 
137  SwCalcExp( const OUString& rStr, const SwSbxValue& rVal,
138  const SwFieldType* pFieldType );
139 };
140 
142 template<class T>
144 {
145  std::vector<std::unique_ptr<T>> m_aData;
146 public:
147  SwHashTable(size_t nSize) : m_aData(nSize) {}
148  std::unique_ptr<T> & operator[](size_t idx) { return m_aData[idx]; }
149  std::unique_ptr<T> const & operator[](size_t idx) const { return m_aData[idx]; }
150  void resize(size_t nSize) { m_aData.resize(nSize); }
151 
152  T* Find( const OUString& rStr, sal_uInt16* pPos = nullptr ) const
153  {
154  size_t nTableSize = m_aData.size();
155  sal_uLong ii = 0;
156  for( sal_Int32 n = 0; n < rStr.getLength(); ++n )
157  {
158  ii = ii << 1 ^ rStr[n];
159  }
160  ii %= nTableSize;
161 
162  if( pPos )
163  *pPos = static_cast<sal_uInt16>(ii);
164 
165  for( T* pEntry = m_aData[ii].get(); pEntry; pEntry = static_cast<T*>(pEntry->pNext.get()) )
166  {
167  if( rStr == pEntry->aStr )
168  {
169  return pEntry;
170  }
171  }
172  return nullptr;
173  }
174 
175 };
176 
177 
178 // if CalcOp != 0, this is a valid operator
179 struct CalcOp;
180 CalcOp* FindOperator( const OUString& rSearch );
181 
182 extern "C" typedef double (*pfCalc)(double);
183 
184 class SwCalc
185 {
187  OUStringBuffer m_aVarName;
188  OUString m_sCurrSym;
189  OUString m_sCommand;
190  std::vector<const SwUserFieldType*> m_aRekurStack;
194  sal_Int32 m_nCommandPos;
195 
200 
201  sal_uInt16 m_nListPor;
205 
207  SwSbxValue Expr();
208  SwSbxValue Term();
209  SwSbxValue PrimFunc(bool &rChkPow);
210  SwSbxValue Prim();
211  SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig);
212 
213  static OUString GetColumnName( const OUString& rName );
214  OUString GetDBName( const OUString& rName );
215 
216  SwCalc( const SwCalc& ) = delete;
217  SwCalc& operator=( const SwCalc& ) = delete;
218 
219 public:
220  SwCalc(SwDoc& rD);
221  ~SwCalc() COVERITY_NOEXCEPT_FALSE;
222 
223  SwSbxValue Calculate( const OUString &rStr );
224  OUString GetStrResult( const SwSbxValue& rValue );
225  OUString GetStrResult( double );
226 
227  SwCalcExp* VarInsert( const OUString& r );
228  SwCalcExp* VarLook( const OUString &rStr, bool bIns = false );
229  void VarChange( const OUString& rStr, const SwSbxValue& rValue );
230  void VarChange( const OUString& rStr, double );
232 
233  bool Push(const SwUserFieldType* pUserFieldType);
234  void Pop();
236 
237  void SetCalcError( SwCalcError eErr ) { m_eError = eErr; }
238  bool IsCalcError() const { return SwCalcError::NONE != m_eError; }
239 
240  static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
241  double& rVal );
242  static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
243  double& rVal, SwDoc const *const pDoc );
244 
245  SW_DLLPUBLIC static bool IsValidVarName( const OUString& rStr,
246  OUString* pValidName = nullptr );
247 };
248 
249 #endif
250 
251 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:233
SwCalcExp(const OUString &rStr, const SwSbxValue &rVal, const SwFieldType *pFieldType)
Definition: calc.cxx:1396
Definition: calc.hxx:184
Definition: calc.hxx:124
std::unique_ptr< T > const & operator[](size_t idx) const
Definition: calc.hxx:149
The shared part of a user field.
Definition: usrfld.hxx:35
SwSbxValue m_nLastLeft
Definition: calc.hxx:191
const sal_Char sCalc_Tdif[]
const sal_Char sCalc_Geq[]
Definition: calc.cxx:71
CalcOp * FindOperator(const OUString &rSearch)
Definition: calc.cxx:172
Definition: calc.hxx:46
OUString m_sCommand
Definition: calc.hxx:189
sal_uIntPtr sal_uLong
SwCalc & operator=(const SwCalc &)=delete
bool IsCalcError() const
Definition: calc.hxx:238
SwCalc(const SwCalc &)=delete
Definition: doc.hxx:185
const sal_Char sCalc_Add[]
Definition: calc.cxx:57
const SwFieldType * pFieldType
Definition: calc.hxx:135
CharClass * GetCharClass()
Definition: calc.cxx:610
const sal_Char sCalc_G[]
Definition: calc.cxx:73
std::unique_ptr< SwHash > pNext
Definition: calc.hxx:129
const sal_Char sCalc_Min[]
Definition: calc.cxx:76
bool m_bVoid
Definition: calc.hxx:105
const sal_Char sCalc_Sqrt[]
Definition: calc.cxx:62
const sal_Char sCalc_L[]
Definition: calc.cxx:72
SwSbxValue Term()
Definition: calc.cxx:832
std::vector< std::unique_ptr< T > > m_aData
Definition: calc.hxx:145
const sal_Char sCalc_Atan[]
Definition: calc.cxx:83
sal_uInt16 sal_Unicode
void Pop()
Definition: calc.cxx:603
const sal_Char sCalc_Date[]
Definition: calc.cxx:85
static bool Str2Double(const OUString &rStr, sal_Int32 &rPos, double &rVal)
Definition: calc.cxx:1335
SwCalcError
Definition: calc.hxx:93
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
Definition: calc.cxx:575
char sal_Char
Definition: calc.hxx:49
sal_Int32 m_nCommandPos
Definition: calc.hxx:194
SwCalcOper m_eCurrListOper
Definition: calc.hxx:203
SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig)
Definition: calc.cxx:1013
const sal_Char sCalc_Not[]
Definition: calc.cxx:67
SwSbxValue & MakeDouble()
Definition: calc.cxx:1429
Definition: calc.cxx:88
double(* pfCalc)(double)
Definition: calc.hxx:182
const sal_Char sCalc_Sum[]
Definition: calc.cxx:74
const sal_Char sCalc_Mean[]
Definition: calc.cxx:75
void SetDBvalue(bool bSet)
Definition: calc.hxx:120
SwSbxValue nValue
Definition: calc.hxx:134
const sal_Char sCalc_Sin[]
Definition: calc.cxx:78
double GetDouble() const
Definition: calc.cxx:1410
SwSbxValue Prim()
Definition: calc.cxx:1214
SwDoc & m_rDoc
Definition: calc.hxx:196
Definition: calc.hxx:46
bool PutLong(sal_Int32)
SwCalcOper GetToken()
Definition: calc.cxx:615
SwSbxValue m_nNumberValue
Definition: calc.hxx:192
const sal_Char sCalc_Leq[]
Definition: calc.cxx:70
SvtSysLocale const m_aSysLocale
Definition: calc.hxx:197
SwCalcExp m_aErrExpr
Definition: calc.hxx:193
const sal_Char sCalc_Acos[]
Definition: calc.cxx:82
virtual ~SwHash()
Definition: calc.cxx:1392
static OUString GetColumnName(const OUString &rName)
Definition: calc.cxx:1286
SwCalcOper
Definition: calc.hxx:41
void SetCalcError(SwCalcError eErr)
Definition: calc.hxx:237
T * Find(const OUString &rStr, sal_uInt16 *pPos=nullptr) const
Definition: calc.hxx:152
SwHash(const OUString &rStr)
Definition: calc.cxx:1387
bool IsVoidValue()
Definition: calc.hxx:116
#define SW_DLLPUBLIC
Definition: swdllapi.h:28
const sal_Char sCalc_Pow[]
Definition: calc.cxx:63
SwHashTable(size_t nSize)
Definition: calc.hxx:147
SwSbxValue(const double &rD)
Definition: calc.hxx:110
bool m_bDBvalue
Definition: calc.hxx:106
std::unique_ptr< T > & operator[](size_t idx)
Definition: calc.hxx:148
SwSbxValue(long n=0)
Definition: calc.hxx:109
SwHashTable< SwCalcExp > & GetVarTable()
Definition: calc.hxx:231
static SW_DLLPUBLIC bool IsValidVarName(const OUString &rStr, OUString *pValidName=nullptr)
Definition: calc.cxx:1362
OUStringBuffer m_aVarName
Definition: calc.hxx:187
SwCalcError m_eError
Definition: calc.hxx:204
void resize(size_t nSize)
Definition: calc.hxx:150
const sal_Char sCalc_Phd[]
Definition: calc.cxx:61
SwSbxValue Expr()
Definition: calc.cxx:1251
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:347
const sal_Char sCalc_Mul[]
Definition: calc.cxx:59
sal_uInt16 m_nListPor
Definition: calc.hxx:201
const sal_Char sCalc_Neq[]
Definition: calc.cxx:69
~SwCalc() COVERITY_NOEXCEPT_FALSE
Definition: calc.cxx:339
SwHashTable< SwCalcExp > m_aVarTable
Definition: calc.hxx:186
const sal_Char sCalc_Cos[]
Definition: calc.cxx:79
const sal_Char sCalc_Sub[]
Definition: calc.cxx:58
bool PutDouble(double)
const sal_Char sCalc_Xor[]
Definition: calc.cxx:65
bool GetBool() const
Definition: calc.cxx:1404
OUString GetStrResult(const SwSbxValue &rValue)
Definition: calc.cxx:370
const sal_Char sCalc_Round[]
Definition: calc.cxx:84
CharClass * m_pCharClass
Definition: calc.hxx:199
const sal_Char sCalc_Tan[]
Definition: calc.cxx:80
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
Definition: calc.cxx:408
SwSbxValue PrimFunc(bool &rChkPow)
Definition: calc.cxx:1025
SwCalcOper m_eCurrOper
Definition: calc.hxx:202
const sal_Char sCalc_And[]
Definition: calc.cxx:66
const LocaleDataWrapper * m_pLocaleDataWrapper
Definition: calc.hxx:198
const sal_Char sCalc_Asin[]
Definition: calc.cxx:81
const sal_Char sCalc_Or[]
Definition: calc.cxx:64
bool IsDBvalue()
Definition: calc.hxx:119
const sal_Char sCalc_Max[]
Definition: calc.cxx:77
SwCalcExp * VarInsert(const OUString &r)
Definition: calc.cxx:402
const sal_Char sCalc_Eq[]
Definition: calc.cxx:68
OUString m_sCurrSym
Definition: calc.hxx:188
const sal_Char sCalc_Div[]
Definition: calc.cxx:60
const sal_Unicode cListDelim
Definition: calc.hxx:39
OUString GetDBName(const OUString &rName)
Definition: calc.cxx:1299
bool Push(const SwUserFieldType *pUserFieldType)
Definition: calc.cxx:594
T should be a subclass of SwHash.
Definition: calc.hxx:143
OUString aStr
Definition: calc.hxx:128
Definition: calc.hxx:48
std::vector< const SwUserFieldType * > m_aRekurStack
Definition: calc.hxx:190
void SetVoidValue(bool bSet)
Definition: calc.hxx:117