LibreOffice Module sc (master) 1
tokstack.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#pragma once
21
22#include <tokenarray.hxx>
23#include <refdata.hxx>
24#include <sal/log.hxx>
25
26#include <memory>
27#include <utility>
28#include <vector>
29
30namespace svl {
31
32class SharedStringPool;
33
34}
35
37// in PRODUCT version: ambiguity between OpCode (being sal_uInt16) and UINT16
38// Unfortunately a typedef is just a dumb alias and not a real type ...
39//typedef sal_uInt16 TokenId;
40struct TokenId
41{
42 sal_uInt16 nId;
43
44 TokenId() : nId( 0 ) {}
45 TokenId( sal_uInt16 n ) : nId( n ) {}
46 TokenId( const TokenId& r ) : nId( r.nId ) {}
47 TokenId& operator =( const TokenId& r ) { nId = r.nId; return *this; }
48 TokenId& operator =( sal_uInt16 n ) { nId = n; return *this; }
49 operator const sal_uInt16&() const { return nId; }
50};
51
52class TokenStack;
53
55{
56 T_Id, // Id-Folge
57 T_Str, // String
58 T_D, // Double
59 T_Err, // Error code
60 T_RefC, // Cell Reference
61 T_RefA, // Area Reference
62 T_RN, // Range Name
63 T_Ext, // something unknown with function name
64 T_Nlf, // token for natural language formula
65 T_Matrix, // token for inline arrays
66 T_ExtName, // token for external names
69};
70
71template<typename T, int InitialCapacity>
73{
74 std::unique_ptr<T[]> ppP_Str;
75 sal_uInt16 m_capacity;
76 sal_uInt16 m_writemark;
77
79 ppP_Str( new T[InitialCapacity] ),
80 m_capacity(InitialCapacity),
82 {
83 }
84 bool Grow(sal_uInt16 nByMin = 1)
85 {
86 sal_uInt16 nP_StrNew = lcl_canGrow(m_capacity, nByMin);
87 if (!nP_StrNew)
88 return false;
89
90 T* ppP_StrNew = new T[ nP_StrNew ];
91
92 for( sal_uInt16 i = 0 ; i < m_capacity ; i++ )
93 ppP_StrNew[ i ] = std::move(ppP_Str[ i ]);
94
95 m_capacity = nP_StrNew;
96
97 ppP_Str.reset( ppP_StrNew );
98 return true;
99 }
101 static sal_uInt16 lcl_canGrow( sal_uInt16 nOld, sal_uInt16 nByMin )
102 {
103 if (!nOld)
104 return nByMin ? nByMin : 1;
105 if (nOld == SAL_MAX_UINT16)
106 return 0;
107 sal_uInt32 nNew = ::std::max( static_cast<sal_uInt32>(nOld) * 2,
108 static_cast<sal_uInt32>(nOld) + nByMin);
109 if (nNew > SAL_MAX_UINT16)
110 nNew = SAL_MAX_UINT16;
111 if (nNew - nByMin < nOld)
112 nNew = 0;
113 return static_cast<sal_uInt16>(nNew);
114 }
115 T* getIfInRange(sal_uInt16 n) const
116 {
117 return ( n < m_capacity ) ? &ppP_Str[ n ] : nullptr;
118 }
119 T const & operator[](sal_uInt16 n) const
120 {
121 return ppP_Str[ n ];
122 }
123 T & operator[](sal_uInt16 n)
124 {
125 return ppP_Str[ n ];
126 }
127};
128
130{
131 // !ATTENTION!: external Id-Basis is 1, internal 0!
132 // return Id = 0 -> Error
133private:
135
137 ppP_Str; // Pool for Strings
138
139 TokenPoolPool<double, 8> pP_Dbl; // Pool for Doubles
140
142 pP_Err; // Pool for error codes
143
145 ppP_RefTr; // Pool for References
146 std::unique_ptr<sal_uInt16[]> pP_Id; // Pool for Id-sets
147 sal_uInt16 nP_Id;
148 sal_uInt16 nP_IdCurrent;
149 sal_uInt16 nP_IdLast; // last set-start
150
151 struct EXTCONT
152 {
154 OUString aText;
155 EXTCONT( const DefTokenId e, OUString a ) :
156 eId( e ), aText(std::move( a )){}
157 };
160
163
164 std::unique_ptr<ScMatrix*[]> ppP_Matrix; // Pool for Matrices
165 sal_uInt16 nP_Matrix;
167
170 {
171 sal_uInt16 mnIndex;
172 sal_Int16 mnSheet;
173 };
174 ::std::vector<RangeName> maRangeNames;
175
177 struct ExtName
178 {
179 sal_uInt16 mnFileId;
180 OUString maName;
181 };
182 ::std::vector<ExtName> maExtNames;
183
186 {
187 OUString maTabName;
189 sal_uInt16 mnFileId;
190 };
191 ::std::vector<ExtCellRef> maExtCellRefs;
192
195 {
196 OUString maTabName;
198 sal_uInt16 mnFileId;
199 };
200 ::std::vector<ExtAreaRef> maExtAreaRefs;
201
202 std::unique_ptr<sal_uInt16[]> pElement; // Array with Indices for elements
203 std::unique_ptr<E_TYPE[]> pType; // ...with Type-Info
204 std::unique_ptr<sal_uInt16[]> pSize; // ...with size
205 sal_uInt16 nElement;
206 sal_uInt16 nElementCurrent;
207
208 static const sal_uInt16 nScTokenOff;// Offset for SC-Token
209#ifdef DBG_UTIL
210 sal_uInt16 m_nRek; // recursion counter
211#endif
212
213 bool GrowTripel( sal_uInt16 nByMin );
214 bool GrowId();
215 bool GrowElement();
216 bool GrowMatrix();
223 bool CheckElementOrGrow();
224 bool GetElement( const sal_uInt16 nId, ScTokenArray* pScToken );
225 bool GetElementRek( const sal_uInt16 nId, ScTokenArray* pScToken );
226 void ClearMatrix();
227public:
229 ~TokenPool();
230 inline TokenPool& operator <<( const TokenId& rId );
231 inline TokenPool& operator <<( const DefTokenId eId );
232 inline TokenPool& operator <<( TokenStack& rStack );
233 void operator >>( TokenId& rId );
234 inline void operator >>( TokenStack& rStack );
235 inline TokenId Store();
236 TokenId Store( const double& rDouble );
237
238 // only for Range-Names
239 TokenId Store( const sal_uInt16 nIndex );
240
241 TokenId Store( const OUString& rString );
242 TokenId Store( const ScSingleRefData& rTr );
243 TokenId Store( const ScComplexRefData& rTr );
244
245 TokenId Store( const DefTokenId eId, const OUString& rName );
246 // 4 externals (e.g. AddIns, Macros...)
247 TokenId StoreNlf( const ScSingleRefData& rTr );
249 TokenId StoreName( sal_uInt16 nIndex, sal_Int16 nSheet );
250 TokenId StoreExtName( sal_uInt16 nFileId, const OUString& rName );
251 TokenId StoreExtRef( sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef );
252 TokenId StoreExtRef( sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef );
253
254 std::unique_ptr<ScTokenArray> GetTokenArray( const ScDocument& rDoc, const TokenId& rId );
255 void Reset();
256 bool IsSingleOp( const TokenId& rId, const DefTokenId eId ) const;
257 const OUString* GetExternal( const TokenId& rId ) const;
258 ScMatrix* GetMatrix( unsigned int n ) const;
259};
260
262 // Stack for Token-Ids: reserve Id=0 for error; e.g. Get() returns 0 on error
263
264{
265 private:
266 std::unique_ptr<TokenId[]> pStack; // Stack as Array
267 sal_uInt16 nPos; // Write-mark
268 static const sal_uInt16 nSize = 1024; // first Index outside of stack
269 public:
270 TokenStack();
271 ~TokenStack();
272 inline TokenStack& operator <<( const TokenId& rNewId );
273 inline void operator >>( TokenId &rId );
274
275 inline void Reset();
276
277 bool HasMoreTokens() const { return nPos > 0; }
278 inline TokenId Get();
279};
280
282{
283 TokenId nRet;
284
285 if( nPos == 0 )
286 {
287 SAL_WARN("sc.filter", "*TokenStack::Get(): is empty, is empty, ...");
288 nRet = 0;
289 }
290 else
291 {
292 nPos--;
293 nRet = pStack[ nPos ];
294 }
295
296 return nRet;
297}
298
300{// Element on Stack
301 if( nPos < nSize )
302 {
303 pStack[ nPos ] = rNewId;
304 nPos++;
305 }
306 else
307 {
308 SAL_WARN("sc.filter", "*TokenStack::<<(): Stack overflow for " << static_cast<sal_uInt16>(rNewId));
309 }
310
311 return *this;
312}
313
315{// Element of Stack
316 if( nPos > 0 )
317 {
318 nPos--;
319 rId = pStack[ nPos ];
320 }
321 else
322 {
323 SAL_WARN("sc.filter", "*TokenStack::>>(): is empty, is empty, ...");
324 rId = 0;
325 }
326}
327
328inline void TokenStack::Reset()
329{
330 nPos = 0;
331}
332
334{
335 // POST: rId's are stored consecutively in Pool under a new Id;
336 // finalize with >> or Store()
337 // rId -> ( sal_uInt16 ) rId - 1;
338 sal_uInt16 nId = static_cast<sal_uInt16>(rId);
339 if (nId == 0)
340 {
341 // This would result in nId-1==0xffff, create error.
342 SAL_WARN("sc.filter", "-TokenPool::operator <<: TokenId 0");
343 nId = static_cast<sal_uInt16>(ocErrNull) + nScTokenOff + 1;
344 }
345 else if (nId >= nScTokenOff)
346 {
347 SAL_WARN("sc.filter", "-TokenPool::operator <<: TokenId in DefToken-Range! " << static_cast<sal_uInt16>(rId));
348
349 // Do not "invent" OpCode values by arbitrarily mapping into the Calc
350 // space. This badly smells like an overflow or binary garbage, so
351 // treat as error.
352 nId = static_cast<sal_uInt16>(ocErrNull) + nScTokenOff + 1;
353 }
354
355 if( nP_IdCurrent >= nP_Id && !GrowId())
356 return *this;
357
358 pP_Id[ nP_IdCurrent ] = nId - 1;
359 nP_IdCurrent++;
360
361 return *this;
362}
363
365{
366 if (static_cast<sal_uInt32>(eId) + nScTokenOff >= 0xFFFF)
367 {
368 SAL_WARN("sc.filter", "-TokenPool::operator<<: enum too large! " << static_cast<sal_uInt32>(eId));
369 }
370
371 if( nP_IdCurrent >= nP_Id && !GrowId())
372 return *this;
373
374 pP_Id[ nP_IdCurrent ] = static_cast<sal_uInt16>(eId) + nScTokenOff;
375 nP_IdCurrent++;
376
377 return *this;
378}
379
381{
382 if( nP_IdCurrent >= nP_Id && !GrowId())
383 return *this;
384
385 sal_uInt16 nId = static_cast<sal_uInt16>(rStack.Get());
386 if (nId == 0)
387 {
388 // Indicates error, so generate one. Empty stack, overflow, ...
389 nId = static_cast<sal_uInt16>(ocErrNull) + nScTokenOff + 1;
390 }
391 pP_Id[ nP_IdCurrent ] = nId - 1;
392 nP_IdCurrent++;
393
394 return *this;
395}
396
397inline void TokenPool::operator >>( TokenStack& rStack )
398{
399 TokenId nId;
400 *this >> nId;
401 rStack << nId;
402}
403
405{
406 TokenId nId;
407 *this >> nId;
408 return nId;
409}
410
411inline std::unique_ptr<ScTokenArray> TokenPool::GetTokenArray( const ScDocument& rDoc, const TokenId& rId )
412{
413 std::unique_ptr<ScTokenArray> pScToken( new ScTokenArray(rDoc) );
414
415 if( rId )
416 {//...only if rId > 0!
417#ifdef DBG_UTIL
418 m_nRek = 0;
419#endif
420 GetElement( static_cast<sal_uInt16>(rId) - 1, pScToken.get());
421 }
422
423 return pScToken;
424}
425
426
427/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:101
bool GrowElement()
Definition: tokstack.cxx:122
TokenId StoreName(sal_uInt16 nIndex, sal_Int16 nSheet)
Definition: tokstack.cxx:601
static const sal_uInt16 nScTokenOff
Definition: tokstack.hxx:208
sal_uInt16 nP_IdLast
Definition: tokstack.hxx:149
TokenId StoreExtName(sal_uInt16 nFileId, const OUString &rName)
Definition: tokstack.cxx:619
TokenId StoreNlf(const ScSingleRefData &rTr)
Definition: tokstack.cxx:554
bool IsSingleOp(const TokenId &rId, const DefTokenId eId) const
Definition: tokstack.cxx:687
::std::vector< ExtCellRef > maExtCellRefs
Definition: tokstack.hxx:191
void ClearMatrix()
Definition: tokstack.cxx:740
ScMatrix * GetMatrix(unsigned int n) const
Definition: tokstack.cxx:731
bool GrowId()
Definition: tokstack.cxx:88
sal_uInt16 nElement
Definition: tokstack.hxx:205
bool GetElement(const sal_uInt16 nId, ScTokenArray *pScToken)
Definition: tokstack.cxx:170
std::unique_ptr< sal_uInt16[]> pP_Id
Definition: tokstack.hxx:146
sal_uInt16 nP_IdCurrent
Definition: tokstack.hxx:148
svl::SharedStringPool & mrStringPool
Definition: tokstack.hxx:134
TokenId StoreMatrix()
Definition: tokstack.cxx:579
TokenPoolPool< sal_uInt16, 8 > pP_Err
Definition: tokstack.hxx:142
~TokenPool()
Definition: tokstack.cxx:67
std::unique_ptr< E_TYPE[]> pType
Definition: tokstack.hxx:203
sal_uInt16 nP_Matrix
Definition: tokstack.hxx:165
TokenPoolPool< std::unique_ptr< EXTCONT >, 32 > ppP_Ext
Definition: tokstack.hxx:159
::std::vector< ExtAreaRef > maExtAreaRefs
Definition: tokstack.hxx:200
sal_uInt16 m_nRek
Definition: tokstack.hxx:210
TokenPool & operator<<(const TokenId &rId)
Definition: tokstack.hxx:333
void Reset()
Definition: tokstack.cxx:675
TokenPoolPool< double, 8 > pP_Dbl
Definition: tokstack.hxx:139
::std::vector< ExtName > maExtNames
Definition: tokstack.hxx:182
sal_uInt16 nP_MatrixCurrent
Definition: tokstack.hxx:166
TokenPool(svl::SharedStringPool &rSPool)
Definition: tokstack.cxx:46
std::unique_ptr< ScMatrix *[]> ppP_Matrix
Definition: tokstack.hxx:164
::std::vector< RangeName > maRangeNames
Definition: tokstack.hxx:174
bool GetElementRek(const sal_uInt16 nId, ScTokenArray *pScToken)
Definition: tokstack.cxx:332
sal_uInt16 nP_Id
Definition: tokstack.hxx:147
TokenId StoreExtRef(sal_uInt16 nFileId, const OUString &rTabName, const ScSingleRefData &rRef)
Definition: tokstack.cxx:637
TokenPoolPool< std::unique_ptr< ScSingleRefData >, 16 > ppP_Nlf
Definition: tokstack.hxx:162
sal_uInt16 nElementCurrent
Definition: tokstack.hxx:206
bool GrowMatrix()
Definition: tokstack.cxx:151
bool GrowTripel(sal_uInt16 nByMin)
TokenPoolPool< std::unique_ptr< ScSingleRefData >, 32 > ppP_RefTr
Definition: tokstack.hxx:145
TokenId Store()
Definition: tokstack.hxx:404
std::unique_ptr< sal_uInt16[]> pSize
Definition: tokstack.hxx:204
TokenPoolPool< std::unique_ptr< OUString >, 4 > ppP_Str
Definition: tokstack.hxx:137
std::unique_ptr< sal_uInt16[]> pElement
Definition: tokstack.hxx:202
std::unique_ptr< ScTokenArray > GetTokenArray(const ScDocument &rDoc, const TokenId &rId)
Definition: tokstack.hxx:411
const OUString * GetExternal(const TokenId &rId) const
Definition: tokstack.cxx:713
void operator>>(TokenId &rId)
Definition: tokstack.cxx:403
bool CheckElementOrGrow()
Definition: tokstack.cxx:107
static const sal_uInt16 nSize
Definition: tokstack.hxx:268
std::unique_ptr< TokenId[]> pStack
Definition: tokstack.hxx:266
TokenStack & operator<<(const TokenId &rNewId)
Definition: tokstack.hxx:299
void operator>>(TokenId &rId)
Definition: tokstack.hxx:314
bool HasMoreTokens() const
Definition: tokstack.hxx:277
sal_uInt16 nPos
Definition: tokstack.hxx:267
void Reset()
Definition: tokstack.hxx:328
TokenId Get()
Definition: tokstack.hxx:281
sal_Int64 n
uno_Any a
#define SAL_WARN(area, stream)
int i
These need to be in global namespace just like their respective types are.
sal_Int16 nId
OpCode
ocErrNull
Complex reference (a range) into the sheet.
Definition: refdata.hxx:123
Single reference (one address) into the sheet.
Definition: refdata.hxx:30
sal_uInt16 nId
Definition: tokstack.hxx:42
TokenId(const TokenId &r)
Definition: tokstack.hxx:46
TokenId & operator=(const TokenId &r)
Definition: tokstack.hxx:47
TokenId()
Definition: tokstack.hxx:44
TokenId(sal_uInt16 n)
Definition: tokstack.hxx:45
bool Grow(sal_uInt16 nByMin=1)
Definition: tokstack.hxx:84
T * getIfInRange(sal_uInt16 n) const
Definition: tokstack.hxx:115
std::unique_ptr< T[]> ppP_Str
Definition: tokstack.hxx:74
sal_uInt16 m_writemark
Definition: tokstack.hxx:76
sal_uInt16 m_capacity
Definition: tokstack.hxx:75
T const & operator[](sal_uInt16 n) const
Definition: tokstack.hxx:119
T & operator[](sal_uInt16 n)
Definition: tokstack.hxx:123
static sal_uInt16 lcl_canGrow(sal_uInt16 nOld, sal_uInt16 nByMin)
Returns the new number of elements, or 0 if overflow.
Definition: tokstack.hxx:101
EXTCONT(const DefTokenId e, OUString a)
Definition: tokstack.hxx:155
DefTokenId eId
Definition: tokstack.hxx:153
for storage of external area references
Definition: tokstack.hxx:195
ScComplexRefData maRef
Definition: tokstack.hxx:197
for storage of external cell references
Definition: tokstack.hxx:186
ScSingleRefData maRef
Definition: tokstack.hxx:188
for storage of external names
Definition: tokstack.hxx:178
sal_uInt16 mnFileId
Definition: tokstack.hxx:179
for storage of named ranges
Definition: tokstack.hxx:170
sal_uInt16 mnIndex
Definition: tokstack.hxx:171
E_TYPE
Definition: tokstack.hxx:55
@ T_RefC
Definition: tokstack.hxx:60
@ T_Ext
Definition: tokstack.hxx:63
@ T_ExtName
Definition: tokstack.hxx:66
@ T_Matrix
Definition: tokstack.hxx:65
@ T_Nlf
Definition: tokstack.hxx:64
@ T_RN
Definition: tokstack.hxx:62
@ T_ExtRefA
Definition: tokstack.hxx:68
@ T_D
Definition: tokstack.hxx:58
@ T_Str
Definition: tokstack.hxx:57
@ T_Err
Definition: tokstack.hxx:59
@ T_Id
Definition: tokstack.hxx:56
@ T_ExtRefC
Definition: tokstack.hxx:67
@ T_RefA
Definition: tokstack.hxx:61
OpCode DefTokenId
Definition: tokstack.hxx:36
#define SAL_MAX_UINT16