Line data Source code
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_SC_SOURCE_FILTER_INC_TOKSTACK_HXX
21 : #define INCLUDED_SC_SOURCE_FILTER_INC_TOKSTACK_HXX
22 :
23 : #include <string.h>
24 : #include "compiler.hxx"
25 : #include "tokenarray.hxx"
26 : #include <osl/diagnose.h>
27 :
28 : #include <vector>
29 :
30 : namespace svl {
31 :
32 : class SharedStringPool;
33 :
34 : }
35 :
36 : typedef OpCode DefTokenId;
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;
40 : struct TokenId
41 : {
42 : sal_uInt16 nId;
43 :
44 1239827 : TokenId() : nId( 0 ) {}
45 22225 : TokenId( sal_uInt16 n ) : nId( n ) {}
46 177 : TokenId( const TokenId& r ) : nId( r.nId ) {}
47 53632 : inline TokenId& operator =( const TokenId& r ) { nId = r.nId; return *this; }
48 0 : inline TokenId& operator =( sal_uInt16 n ) { nId = n; return *this; }
49 : inline operator sal_uInt16&() { return nId; }
50 25077 : inline operator const sal_uInt16&() const { return nId; }
51 : inline bool operator <( sal_uInt16 n ) const { return nId < n; }
52 : inline bool operator >( sal_uInt16 n ) const { return nId > n; }
53 : inline bool operator <=( sal_uInt16 n ) const { return nId <= n; }
54 : inline bool operator >=( sal_uInt16 n ) const { return nId >= n; }
55 : inline bool operator ==( sal_uInt16 n ) const { return nId == n; }
56 : inline bool operator !=( sal_uInt16 n ) const { return nId != n; }
57 : };
58 :
59 : struct ScComplexRefData;
60 : class TokenStack;
61 :
62 : enum E_TYPE
63 : {
64 : T_Id, // Id-Folge
65 : T_Str, // String
66 : T_D, // Double
67 : T_Err, // Error code
68 : T_RefC, // Cell Reference
69 : T_RefA, // Area Reference
70 : T_RN, // Range Name
71 : T_Ext, // something unknown with function name
72 : T_Nlf, // token for natural language formula
73 : T_Matrix, // token for inline arrays
74 : T_ExtName, // token for external names
75 : T_ExtRefC,
76 : T_ExtRefA,
77 : T_Error // for check in case of error
78 : };
79 :
80 : class TokenPool
81 : {
82 : // !ATTENTION!: external Id-Basis is 1, internal 0!
83 : // return Id = 0 -> Error
84 : private:
85 : svl::SharedStringPool& mrStringPool;
86 :
87 : OUString** ppP_Str; // Pool for Strings
88 : sal_uInt16 nP_Str; // ...with size
89 : sal_uInt16 nP_StrAkt; // ...and Write-Mark
90 :
91 : double* pP_Dbl; // Pool for Doubles
92 : sal_uInt16 nP_Dbl;
93 : sal_uInt16 nP_DblAkt;
94 :
95 : sal_uInt16* pP_Err; // Pool for error codes
96 : sal_uInt16 nP_Err;
97 : sal_uInt16 nP_ErrAkt;
98 :
99 : ScSingleRefData** ppP_RefTr; // Pool for References
100 : sal_uInt16 nP_RefTr;
101 : sal_uInt16 nP_RefTrAkt;
102 :
103 : sal_uInt16* pP_Id; // Pool for Id-sets
104 : sal_uInt16 nP_Id;
105 : sal_uInt16 nP_IdAkt;
106 : sal_uInt16 nP_IdLast; // last set-start
107 :
108 2 : struct EXTCONT
109 : {
110 : DefTokenId eId;
111 : OUString aText;
112 2 : EXTCONT( const DefTokenId e, const OUString& r ) :
113 2 : eId( e ), aText( r ){}
114 : };
115 : EXTCONT** ppP_Ext;
116 : sal_uInt16 nP_Ext;
117 : sal_uInt16 nP_ExtAkt;
118 :
119 : struct NLFCONT
120 : {
121 : ScSingleRefData aRef;
122 0 : NLFCONT( const ScSingleRefData& r ) : aRef( r ) {}
123 : };
124 : NLFCONT** ppP_Nlf;
125 : sal_uInt16 nP_Nlf;
126 : sal_uInt16 nP_NlfAkt;
127 :
128 : ScMatrix** ppP_Matrix; // Pool for Matrices
129 : sal_uInt16 nP_Matrix;
130 : sal_uInt16 nP_MatrixAkt;
131 :
132 : /** for storage of named ranges */
133 : struct RangeName
134 : {
135 : sal_uInt16 mnIndex;
136 : bool mbGlobal;
137 : };
138 : ::std::vector<RangeName> maRangeNames;
139 :
140 : /** for storage of external names */
141 0 : struct ExtName
142 : {
143 : sal_uInt16 mnFileId;
144 : OUString maName;
145 : };
146 : ::std::vector<ExtName> maExtNames;
147 :
148 : /** for storage of external cell references */
149 8 : struct ExtCellRef
150 : {
151 : sal_uInt16 mnFileId;
152 : OUString maTabName;
153 : ScSingleRefData maRef;
154 : };
155 : ::std::vector<ExtCellRef> maExtCellRefs;
156 :
157 : /** for storage of external area references */
158 0 : struct ExtAreaRef
159 : {
160 : sal_uInt16 mnFileId;
161 : OUString maTabName;
162 : ScComplexRefData maRef;
163 : };
164 : ::std::vector<ExtAreaRef> maExtAreaRefs;
165 :
166 : sal_uInt16* pElement; // Array with Indices for elements
167 : E_TYPE* pType; // ...with Type-Info
168 : sal_uInt16* pSize; // ...with size (Anz. sal_uInt16)
169 : sal_uInt16 nElement;
170 : sal_uInt16 nElementAkt;
171 :
172 : static const sal_uInt16 nScTokenOff;// Offset for SC-Token
173 : #ifdef DBG_UTIL
174 : sal_uInt16 m_nRek; // recursion counter
175 : #endif
176 : ScTokenArray* pScToken; // Token array
177 :
178 : bool GrowString();
179 : bool GrowDouble();
180 : /* TODO: in case we had FormulaTokenArray::AddError() */
181 : #if 0
182 : bool GrowError();
183 : #endif
184 : bool GrowTripel( sal_uInt16 nByMin = 1 );
185 : bool GrowId();
186 : bool GrowElement();
187 : bool GrowExt();
188 : bool GrowNlf();
189 : bool GrowMatrix();
190 : bool GetElement( const sal_uInt16 nId );
191 : bool GetElementRek( const sal_uInt16 nId );
192 : public:
193 : TokenPool( svl::SharedStringPool& rSPool );
194 : ~TokenPool();
195 : inline TokenPool& operator <<( const TokenId& rId );
196 : inline TokenPool& operator <<( const DefTokenId eId );
197 : inline TokenPool& operator <<( TokenStack& rStack );
198 : void operator >>( TokenId& rId );
199 : inline void operator >>( TokenStack& rStack );
200 : inline const TokenId Store();
201 : const TokenId Store( const double& rDouble );
202 :
203 : // only for Range-Names
204 : const TokenId Store( const sal_uInt16 nIndex );
205 : inline const TokenId Store( const sal_Int16 nWert );
206 : const TokenId Store( const OUString& rString );
207 : const TokenId Store( const ScSingleRefData& rTr );
208 : const TokenId Store( const ScComplexRefData& rTr );
209 :
210 : const TokenId Store( const DefTokenId eId, const OUString& rName );
211 : // 4 externals (e.g. AddIns, Macros...)
212 : const TokenId StoreNlf( const ScSingleRefData& rTr );
213 : const TokenId StoreMatrix();
214 : const TokenId StoreName( sal_uInt16 nIndex, bool bGlobal );
215 : const TokenId StoreExtName( sal_uInt16 nFileId, const OUString& rName );
216 : const TokenId StoreExtRef( sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef );
217 : const TokenId StoreExtRef( sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef );
218 :
219 : inline const TokenId LastId() const;
220 : inline const ScTokenArray* operator []( const TokenId& rId );
221 : void Reset();
222 : inline E_TYPE GetType( const TokenId& rId ) const;
223 : bool IsSingleOp( const TokenId& rId, const DefTokenId eId ) const;
224 : const OUString* GetExternal( const TokenId& rId ) const;
225 : ScMatrix* GetMatrix( unsigned int n ) const;
226 : };
227 :
228 : class TokenStack
229 : // Stack for Token-Ids: reserve Id=0 for error; e.g. Get() returns 0 on error
230 :
231 : {
232 : private:
233 : TokenId* pStack; // Stack as Array
234 : sal_uInt16 nPos; // Write-mark
235 : sal_uInt16 nSize; // first Index outside of stack
236 : public:
237 : TokenStack( sal_uInt16 nNewSize = 1024 );
238 : ~TokenStack();
239 : inline TokenStack& operator <<( const TokenId& rNewId );
240 : inline void operator >>( TokenId &rId );
241 :
242 : inline void Reset();
243 :
244 10281 : inline bool HasMoreTokens() const { return nPos > 0; }
245 : inline const TokenId Get();
246 : };
247 :
248 9385 : inline const TokenId TokenStack::Get()
249 : {
250 : OSL_ENSURE( nPos > 0,
251 : "*TokenStack::Get(): is empty, is empty, ..." );
252 :
253 9385 : TokenId nRet;
254 :
255 9385 : if( nPos == 0 )
256 0 : nRet = 0;
257 : else
258 : {
259 9385 : nPos--;
260 9385 : nRet = pStack[ nPos ];
261 : }
262 :
263 9385 : return nRet;
264 : }
265 :
266 21561 : inline TokenStack &TokenStack::operator <<( const TokenId& rNewId )
267 : {// Element on Stack
268 : OSL_ENSURE( nPos < nSize, "*TokenStack::<<(): Stack overflow" );
269 21561 : if( nPos < nSize )
270 : {
271 21561 : pStack[ nPos ] = rNewId;
272 21561 : nPos++;
273 : }
274 :
275 21561 : return *this;
276 : }
277 :
278 12174 : inline void TokenStack::operator >>( TokenId& rId )
279 : {// Element of Stack
280 : OSL_ENSURE( nPos > 0,
281 : "*TokenStack::>>(): is empty, is empty, ..." );
282 12174 : if( nPos > 0 )
283 : {
284 12174 : nPos--;
285 12174 : rId = pStack[ nPos ];
286 : }
287 12174 : }
288 :
289 4669 : inline void TokenStack::Reset()
290 : {
291 4669 : nPos = 0;
292 4669 : }
293 :
294 12330 : inline TokenPool& TokenPool::operator <<( const TokenId& rId )
295 : {
296 : // POST: rId's are stored consecutively in Pool under a new Id;
297 : // finalize with >> or Store()
298 : // rId -> ( sal_uInt16 ) rId - 1;
299 : OSL_ENSURE( ( sal_uInt16 ) rId < nScTokenOff,
300 : "-TokenPool::operator <<: TokenId in DefToken-Range!" );
301 :
302 12330 : if( nP_IdAkt >= nP_Id )
303 0 : if (!GrowId())
304 0 : return *this;
305 :
306 12330 : pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) rId ) - 1;
307 12330 : nP_IdAkt++;
308 :
309 12330 : return *this;
310 : }
311 :
312 21402 : inline TokenPool& TokenPool::operator <<( const DefTokenId eId )
313 : {
314 : OSL_ENSURE( ( sal_uInt32 ) eId + nScTokenOff < 0xFFFF,
315 : "-TokenPool::operator<<: enmum too large!" );
316 :
317 21402 : if( nP_IdAkt >= nP_Id )
318 0 : if (!GrowId())
319 0 : return *this;
320 :
321 21402 : pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) eId ) + nScTokenOff;
322 21402 : nP_IdAkt++;
323 :
324 21402 : return *this;
325 : }
326 :
327 6210 : inline TokenPool& TokenPool::operator <<( TokenStack& rStack )
328 : {
329 6210 : if( nP_IdAkt >= nP_Id )
330 0 : if (!GrowId())
331 0 : return *this;
332 :
333 6210 : pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) rStack.Get() ) - 1;
334 6210 : nP_IdAkt++;
335 :
336 6210 : return *this;
337 : }
338 :
339 9677 : inline void TokenPool::operator >>( TokenStack& rStack )
340 : {
341 9677 : TokenId nId;
342 9677 : *this >> nId;
343 9677 : rStack << nId;
344 9677 : }
345 :
346 332 : inline const TokenId TokenPool::Store()
347 : {
348 332 : TokenId nId;
349 332 : *this >> nId;
350 332 : return nId;
351 : }
352 :
353 : inline const TokenId TokenPool::Store( const sal_Int16 nWert )
354 : {
355 : return Store( ( double ) nWert );
356 : }
357 :
358 : inline const TokenId TokenPool::LastId() const
359 : {
360 : return static_cast<TokenId>(nElementAkt); // correct, as Ausgabe with Offset 1!
361 : }
362 :
363 3175 : const inline ScTokenArray* TokenPool::operator []( const TokenId& rId )
364 : {
365 3175 : pScToken->ClearScTokenArray();
366 :
367 3175 : if( rId )
368 : {//...only if rId > 0!
369 : #ifdef DBG_UTIL
370 : m_nRek = 0;
371 : #endif
372 3175 : GetElement( ( sal_uInt16 ) rId - 1 );
373 : }
374 :
375 3175 : return pScToken;
376 : }
377 :
378 : inline E_TYPE TokenPool::GetType( const TokenId& rId ) const
379 : {
380 : E_TYPE nRet;
381 :
382 : sal_uInt16 nId = (sal_uInt16) rId - 1;
383 :
384 : if( nId < nElementAkt )
385 : nRet = pType[ nId ] ;
386 : else
387 : nRet = T_Error;
388 :
389 : return nRet;
390 : }
391 :
392 : #endif
393 :
394 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|