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