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