xref: /aoo4110/main/sc/source/filter/inc/tokstack.hxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef SC_TOKSTACK_HXX
25 #define SC_TOKSTACK_HXX
26 
27 #include <string.h>
28 #include <tools/debug.hxx>
29 #include "compiler.hxx"
30 #include "tokenarray.hxx"
31 
32 #include <vector>
33 
34 typedef OpCode DefTokenId;
35 // in PRODUCT version: ambiguity between OpCode (being sal_uInt16) and UINT16
36 // Unfortunately a typedef is just a dumb alias and not a real type ...
37 //typedef sal_uInt16 TokenId;
38 struct TokenId
39 {
40 		sal_uInt16			nId;
41 
TokenIdTokenId42 						TokenId() : nId( 0 ) {}
TokenIdTokenId43 						TokenId( sal_uInt16 n ) : nId( n ) {}
TokenIdTokenId44 						TokenId( const TokenId& r ) : nId( r.nId ) {}
operator =TokenId45 	inline	TokenId&	operator =( const TokenId& r ) { nId = r.nId; return *this; }
operator =TokenId46 	inline	TokenId&	operator =( sal_uInt16 n ) { nId = n; return *this; }
operator sal_uInt16&TokenId47 	inline				operator sal_uInt16&() { return nId; }
48 	inline				operator const sal_uInt16&() const { return nId; }
operator <TokenId49 	inline	sal_Bool		operator <( sal_uInt16 n ) const { return nId < n; }
operator >TokenId50 	inline	sal_Bool		operator >( sal_uInt16 n ) const { return nId > n; }
operator <=TokenId51 	inline	sal_Bool		operator <=( sal_uInt16 n ) const { return nId <= n; }
operator >=TokenId52 	inline	sal_Bool		operator >=( sal_uInt16 n ) const { return nId >= n; }
operator ==TokenId53 	inline	sal_Bool		operator ==( sal_uInt16 n ) const { return nId == n; }
operator !=TokenId54 	inline	sal_Bool		operator !=( sal_uInt16 n ) const { return nId != n; }
55 };
56 
57 
58 //------------------------------------------------------------------------
59 struct ScComplexRefData;
60 class TokenStack;
61 class ScToken;
62 
63 
64 enum E_TYPE
65 {
66 	T_Id,		// Id-Folge
67 	T_Str,		// String
68 	T_D,		// Double
69     T_Err,      // Error code
70 	T_RefC,		// Cell Reference
71 	T_RefA,		// Area Reference
72 	T_RN,		// Range Name
73 	T_Ext,		// irgendwas Unbekanntes mit Funktionsnamen
74 	T_Nlf,		// token for natural language formula
75 	T_Matrix,	// token for inline arrays
76     T_ExtName,  // token for external names
77     T_ExtRefC,
78     T_ExtRefA,
79 	T_Error		// fuer Abfrage im Fehlerfall
80 };
81 
82 
83 
84 
85 class TokenPool
86 {
87 	// !ACHTUNG!: externe Id-Basis ist 1, interne 0!
88 	// Ausgabe Id = 0 -> Fehlerfall
89 	private:
90 		String**					ppP_Str;	// Pool fuer Strings
91 		sal_uInt16						nP_Str;		// ...mit Groesse
92 		sal_uInt16						nP_StrAkt;	// ...und Schreibmarke
93 
94 		double*						pP_Dbl;		// Pool fuer Doubles
95 		sal_uInt16						nP_Dbl;
96 		sal_uInt16						nP_DblAkt;
97 
98         sal_uInt16*                     pP_Err;     // Pool for error codes
99         sal_uInt16                      nP_Err;
100         sal_uInt16                      nP_ErrAkt;
101 
102 		ScSingleRefData**				ppP_RefTr;	// Pool fuer Referenzen
103 		sal_uInt16						nP_RefTr;
104 		sal_uInt16						nP_RefTrAkt;
105 
106 		sal_uInt16*						pP_Id;		// Pool fuer Id-Folgen
107 		sal_uInt16						nP_Id;
108 		sal_uInt16						nP_IdAkt;
109 		sal_uInt16						nP_IdLast;	// letzter Folgen-Beginn
110 
111 		struct	EXTCONT
112 		{
113 			DefTokenId				eId;
114 			String					aText;
EXTCONTTokenPool::EXTCONT115 									EXTCONT( const DefTokenId e, const String& r ) :
116 										eId( e ), aText( r ){}
117 		};
118 		EXTCONT**					ppP_Ext;
119 		sal_uInt16						nP_Ext;
120 		sal_uInt16						nP_ExtAkt;
121 
122 		struct	NLFCONT
123 		{
124 			ScSingleRefData			aRef;
NLFCONTTokenPool::NLFCONT125 									NLFCONT( const ScSingleRefData& r ) : aRef( r )	{}
126 		};
127 		NLFCONT**					ppP_Nlf;
128 		sal_uInt16						nP_Nlf;
129 		sal_uInt16						nP_NlfAkt;
130 
131 		ScMatrix**					ppP_Matrix;		// Pool fuer Matricies
132 		sal_uInt16						nP_Matrix;
133 		sal_uInt16						nP_MatrixAkt;
134 
135         /** for storage of external names */
136         struct ExtName
137         {
138             sal_uInt16  mnFileId;
139             String      maName;
140         };
141         ::std::vector<ExtName>      maExtNames;
142 
143         /** for storage of external cell references */
144         struct ExtCellRef
145         {
146             sal_uInt16      mnFileId;
147 			String			maTabName;
148             ScSingleRefData   maRef;
149         };
150         ::std::vector<ExtCellRef>   maExtCellRefs;
151 
152         /** for storage of external area references */
153         struct ExtAreaRef
154         {
155             sal_uInt16      mnFileId;
156 			String			maTabName;
157             ScComplexRefData    maRef;
158         };
159         ::std::vector<ExtAreaRef>   maExtAreaRefs;
160 
161 		sal_uInt16*						pElement;	// Array mit Indizes fuer Elemente
162 		E_TYPE*						pType;		// ...mit Typ-Info
163 		sal_uInt16*						pSize;		// ...mit Laengenangabe (Anz. sal_uInt16)
164 		sal_uInt16						nElement;
165 		sal_uInt16						nElementAkt;
166 
167 		static const sal_uInt16			nScTokenOff;// Offset fuer SC-Token
168 #ifdef DBG_UTIL
169 		sal_uInt16						nRek;		// Rekursionszaehler
170 #endif
171 		ScTokenArray*				pScToken;	// Tokenbastler
172 
173 		bool						GrowString( void );
174 		bool						GrowDouble( void );
175 /* TODO: in case we had FormulaTokenArray::AddError() */
176 #if 0
177         bool                        GrowError( void );
178 #endif
179 		bool						GrowTripel( sal_uInt16 nByMin = 1 );
180 		bool						GrowId( void );
181 		bool						GrowElement( void );
182 		bool						GrowExt( void );
183 		bool						GrowNlf( void );
184 		bool						GrowMatrix( void );
185 		bool						GetElement( const sal_uInt16 nId );
186 		bool						GetElementRek( const sal_uInt16 nId );
187 	public:
188 									TokenPool( void );
189 									~TokenPool();
190 		inline TokenPool&			operator <<( const TokenId nId );
191 		inline TokenPool&			operator <<( const DefTokenId eId );
192 		inline TokenPool&			operator <<( TokenStack& rStack );
193 		void						operator >>( TokenId& rId );
194 		inline void					operator >>( TokenStack& rStack );
195 		inline const TokenId		Store( void );
196 		const TokenId				Store( const double& rDouble );
197 //UNUSED2008-05  const TokenId               StoreError( sal_uInt16 nError );
198 
199 									// nur fuer Range-Names
200 		const TokenId				Store( const sal_uInt16 nIndex );
201 		inline const TokenId		Store( const sal_Int16 nWert );
202 		const TokenId				Store( const String& rString );
203 		const TokenId				Store( const ScSingleRefData& rTr );
204 		const TokenId				Store( const ScComplexRefData& rTr );
205 
206 		const TokenId				Store( const DefTokenId eId, const String& rName );
207 										// 4 externals (e.g. AddIns, Makros...)
208 		const TokenId				StoreNlf( const ScSingleRefData& rTr );
209         const TokenId               StoreMatrix();
210         const TokenId               StoreExtName( sal_uInt16 nFileId, const String& rName );
211         const TokenId               StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
212         const TokenId               StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef );
213 
214 		inline const TokenId		LastId( void ) const;
215 		inline const ScTokenArray*	operator []( const TokenId nId );
216 		void						Reset( void );
217 		inline E_TYPE				GetType( const TokenId& nId ) const;
218 		sal_Bool						IsSingleOp( const TokenId& nId, const DefTokenId eId ) const;
219         const String*               GetExternal( const TokenId& nId ) const;
220 		ScMatrix*					GetMatrix( unsigned int n ) const;
221 };
222 
223 
224 
225 
226 class TokenStack
227 	// Stack fuer Token-Ids: Id 0 sollte reserviert bleiben als
228 	//	fehlerhafte Id,	da z.B. Get() im Fehlerfall 0 liefert
229 {
230 	private:
231 		TokenId*					pStack;		// Stack als Array
232 		sal_uInt16						nPos;		// Schreibmarke
233 		sal_uInt16						nSize;		// Erster Index ausserhalb des Stacks
234 	public:
235 									TokenStack( sal_uInt16 nNewSize = 1024 );
236 									~TokenStack();
237 		inline TokenStack&			operator <<( const TokenId nNewId );
238 		inline void					operator >>( TokenId &rId );
239 
240 		inline void					Reset( void );
241 
HasMoreTokens() const242         inline bool                 HasMoreTokens() const { return nPos > 0; }
243 		inline const TokenId		Get( void );
244 };
245 
246 
247 
248 
Get(void)249 inline const TokenId TokenStack::Get( void )
250 {
251 	DBG_ASSERT( nPos > 0,
252 		"*TokenStack::Get(): Leer ist leer, ist leer, ist leer, ist..." );
253 
254     TokenId nRet;
255 
256 	if( nPos == 0 )
257 		nRet = 0;
258 	else
259 	{
260 		nPos--;
261 		nRet = pStack[ nPos ];
262 	}
263 
264 	return nRet;
265 }
266 
267 
operator <<(const TokenId nNewId)268 inline TokenStack &TokenStack::operator <<( const TokenId nNewId )
269 {// Element auf Stack
270 	DBG_ASSERT( nPos < nSize, "*TokenStack::<<(): Stackueberlauf" );
271 	if( nPos < nSize )
272 	{
273 		pStack[ nPos ] = nNewId;
274 		nPos++;
275 	}
276 
277 	return *this;
278 }
279 
280 
operator >>(TokenId & rId)281 inline void TokenStack::operator >>( TokenId& rId )
282 {// Element von Stack
283 	DBG_ASSERT( nPos > 0,
284 		"*TokenStack::>>(): Leer ist leer, ist leer, ist leer, ..." );
285 	if( nPos > 0 )
286 	{
287 		nPos--;
288 		rId = pStack[ nPos ];
289 	}
290 }
291 
292 
Reset(void)293 inline void TokenStack::Reset( void )
294 {
295 	nPos = 0;
296 }
297 
298 
299 
300 
operator <<(const TokenId nId)301 inline TokenPool& TokenPool::operator <<( const TokenId nId )
302 {
303 	// POST: nId's werden hintereinander im Pool unter einer neuen Id
304 	//		 abgelegt. Vorgang wird mit >> oder Store() abgeschlossen
305 	// nId -> ( sal_uInt16 ) nId - 1;
306 	DBG_ASSERT( ( sal_uInt16 ) nId < nScTokenOff,
307 		"-TokenPool::operator <<: TokenId im DefToken-Bereich!" );
308 
309 	if( nP_IdAkt >= nP_Id )
310 		if (!GrowId())
311             return *this;
312 
313 	pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) nId ) - 1;
314 	nP_IdAkt++;
315 
316 	return *this;
317 }
318 
319 
operator <<(const DefTokenId eId)320 inline TokenPool& TokenPool::operator <<( const DefTokenId eId )
321 {
322 	DBG_ASSERT( ( sal_uInt32 ) eId + nScTokenOff < 0xFFFF,
323 		"-TokenPool::operator<<: enmum zu gross!" );
324 
325 	if( nP_IdAkt >= nP_Id )
326 		if (!GrowId())
327             return *this;
328 
329 	pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) eId ) + nScTokenOff;
330 	nP_IdAkt++;
331 
332 	return *this;
333 }
334 
335 
operator <<(TokenStack & rStack)336 inline TokenPool& TokenPool::operator <<( TokenStack& rStack )
337 {
338 	if( nP_IdAkt >= nP_Id )
339 		if (!GrowId())
340             return *this;
341 
342 	pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) rStack.Get() ) - 1;
343 	nP_IdAkt++;
344 
345 	return *this;
346 }
347 
348 
operator >>(TokenStack & rStack)349 inline void TokenPool::operator >>( TokenStack& rStack )
350 {
351     TokenId nId;
352 	*this >> nId;
353 	rStack << nId;
354 }
355 
356 
Store(void)357 inline const TokenId TokenPool::Store( void )
358 {
359     TokenId nId;
360 	*this >> nId;
361 	return nId;
362 }
363 
364 
Store(const sal_Int16 nWert)365 inline const TokenId TokenPool::Store( const sal_Int16 nWert )
366 {
367 	return Store( ( double ) nWert );
368 }
369 
370 
LastId(void) const371 inline const TokenId TokenPool::LastId( void ) const
372 {
373 	return ( TokenId ) nElementAkt; // stimmt, da Ausgabe mit Offset 1!
374 }
375 
376 
operator [](const TokenId nId)377 const inline ScTokenArray* TokenPool::operator []( const TokenId nId )
378 {
379 	pScToken->Clear();
380 
381 	if( nId )
382 	{//...nur wenn nId > 0!
383 #ifdef DBG_UTIL
384 		nRek = 0;
385 #endif
386 		GetElement( ( sal_uInt16 ) nId - 1 );
387 	}
388 
389 	return pScToken;
390 }
391 
392 
GetType(const TokenId & rId) const393 inline E_TYPE TokenPool::GetType( const TokenId& rId ) const
394 {
395     E_TYPE nRet;
396 
397 	sal_uInt16 nId = (sal_uInt16) rId - 1;
398 
399 	if( nId < nElementAkt )
400 		nRet = pType[ nId ] ;
401 	else
402 		nRet = T_Error;
403 
404 	return nRet;
405 }
406 
407 
408 #endif
409 
410