xref: /AOO41X/main/sc/source/filter/inc/tokstack.hxx (revision 3ee7c2db59af3948da1f0fe563f557d5b49b2c39)
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; }
operator const sal_uInt16&TokenId48     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