xref: /AOO41X/main/sc/source/core/inc/jumpmatrix.hxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef SC_JUMPMATRIX_HXX
29 #define SC_JUMPMATRIX_HXX
30 
31 #include "formula/token.hxx"
32 #include "formula/errorcodes.hxx"
33 #include <tools/solar.h>
34 #include <vector>
35 #include "scmatrix.hxx"
36 
37 typedef ::std::vector< formula::FormulaToken*> ScTokenVec;
38 
39 struct ScJumpMatrixEntry
40 {
41     double  fBool;      // 0:= false  1:= true   also if no-path
42                         // other values may contain error conditions like NAN and INF
43     short   nStart;     // start of path (actually start-1, see formula::FormulaTokenIterator)
44     short   nNext;      // next after path
45                         // jump path exists if nStart != nNext, else no path
46     short   nStop;      // optional stop of path (nPC < nStop)
47 
48     void    SetJump( double fBoolP, short nStartP, short nNextP, short nStopP )
49                 {
50                     fBool = fBoolP;
51                     nStart = nStartP;
52                     nNext = nNextP;
53                     nStop = nStopP;
54                 }
55     void    GetJump( double& rBool, short& rStart, short& rNext, short& rStop )
56                 {
57                     rBool = fBool;
58                     rStart = nStart;
59                     rNext = nNext;
60                     rStop = nStop;
61                 }
62 };
63 
64 class ScJumpMatrix
65 {
66             ScJumpMatrixEntry*  pJump;      // the jumps
67             ScMatrixRef         pMat;       // the results
68             ScTokenVec*         pParams;    // parameter stack
69             SCSIZE              nCols;
70             SCSIZE              nRows;
71             SCSIZE              nCurCol;
72             SCSIZE              nCurRow;
73             SCSIZE              nResMatCols;
74             SCSIZE              nResMatRows;
75             bool                bStarted;
76 
77                                 // not implemented, prevent usage
78                                 ScJumpMatrix( const ScJumpMatrix& );
79             ScJumpMatrix&       operator=( const ScJumpMatrix& );
80 
81 public:
82                                 ScJumpMatrix( SCSIZE nColsP, SCSIZE nRowsP )
83                                         : pJump( new ScJumpMatrixEntry[ nColsP * nRowsP ] )
84                                         , pMat( new ScMatrix( nColsP, nRowsP) )
85                                         , pParams( NULL )
86                                         , nCols( nColsP )
87                                         , nRows( nRowsP )
88                                         , nCurCol( 0 )
89                                         , nCurRow( 0 )
90                                         , nResMatCols( nColsP )
91                                         , nResMatRows( nRowsP )
92                                         , bStarted( false )
93                                     {
94                                         // Initialize result matrix in case of
95                                         // a premature end of the interpreter
96                                         // due to errors.
97                                         pMat->FillDouble( CreateDoubleError(
98                                                 NOTAVAILABLE), 0, 0, nCols-1,
99                                                 nRows-1);
100                                         /*! pJump not initialized */
101                                     }
102                                 ~ScJumpMatrix()
103                                     {
104                                         if ( pParams )
105                                         {
106                                             for ( ScTokenVec::iterator i =
107                                                     pParams->begin(); i !=
108                                                     pParams->end(); ++i )
109                                             {
110                                                 (*i)->DecRef();
111                                             }
112                                             delete pParams;
113                                         }
114                                         delete [] pJump;
115                                     }
116             void                GetDimensions( SCSIZE& rCols, SCSIZE& rRows ) const
117                                     {
118                                         rCols = nCols;
119                                         rRows = nRows;
120                                     }
121             void                SetJump( SCSIZE nCol, SCSIZE nRow, double fBool,
122                                             short nStart, short nNext,
123                                             short nStop = SHRT_MAX )
124                                     {
125                                         pJump[ (sal_uLong)nCol * nRows + nRow ].
126                                             SetJump( fBool, nStart, nNext, nStop);
127                                     }
128             void                GetJump( SCSIZE nCol, SCSIZE nRow, double& rBool,
129                                             short& rStart, short& rNext,
130                                             short& rStop ) const
131                                     {
132                                         if (nCols == 1 && nRows == 1)
133                                         {
134                                             nCol = 0;
135                                             nRow = 0;
136                                         }
137                                         else if (nCols == 1 && nRow < nRows)
138                                             nCol = 0;
139                                         else if (nRows == 1 && nCol < nCols)
140                                             nRow = 0;
141                                         else if (nCols <= nCol || nRows <= nRow)
142                                         {
143                                             DBG_ERROR("ScJumpMatrix::GetJump: dimension error");
144                                             nCol = 0;
145                                             nRow = 0;
146                                         }
147                                         pJump[ (sal_uLong)nCol * nRows + nRow ].
148                                             GetJump( rBool, rStart, rNext, rStop);
149                                     }
150             void                SetAllJumps( double fBool,
151                                             short nStart, short nNext,
152                                             short nStop = SHRT_MAX )
153                                     {
154                                         sal_uLong n = (sal_uLong)nCols * nRows;
155                                         for ( sal_uLong j=0; j<n; ++j )
156                                         {
157                                             pJump[ j ].SetJump( fBool, nStart,
158                                                     nNext, nStop);
159                                         }
160                                     }
161             void                SetJumpParameters( ScTokenVec* p )
162                                     { pParams = p; }
163             const ScTokenVec*   GetJumpParameters() const { return pParams; }
164             ScMatrix*           GetResultMatrix() const { return pMat; }
165             void                GetPos( SCSIZE& rCol, SCSIZE& rRow ) const
166                                     {
167                                         rCol = nCurCol;
168                                         rRow = nCurRow;
169                                     }
170             bool                Next( SCSIZE& rCol, SCSIZE& rRow )
171                                     {
172                                         if ( !bStarted )
173                                         {
174                                             bStarted = true;
175                                             nCurCol = nCurRow = 0;
176                                         }
177                                         else
178                                         {
179                                             if ( ++nCurRow >= nResMatRows )
180                                             {
181                                                 nCurRow = 0;
182                                                 ++nCurCol;
183                                             }
184                                         }
185                                         GetPos( rCol, rRow );
186                                         return nCurCol < nResMatCols;
187                                     }
188             void                GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows )
189                                     {
190                                         rCols = nResMatCols;
191                                         rRows = nResMatRows;
192                                     }
193             void                SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows )
194                                     {
195                                         if ( nNewCols > nResMatCols || nNewRows > nResMatRows )
196                                         {
197                                             pMat = pMat->CloneAndExtend( nNewCols, nNewRows );
198                                             if ( nResMatCols < nNewCols )
199                                             {
200                                                 pMat->FillDouble( CreateDoubleError(
201                                                     NOTAVAILABLE), nResMatCols, 0, nNewCols-1,
202                                                     nResMatRows-1);
203                                             }
204                                             if ( nResMatRows < nNewRows )
205                                             {
206                                                 pMat->FillDouble( CreateDoubleError(
207                                                     NOTAVAILABLE), 0, nResMatRows, nNewCols-1,
208                                                     nNewRows-1);
209                                             }
210                                             if ( nRows == 1 && nCurCol != 0 )
211                                             {
212                                                 nCurCol = 0;
213                                                 nCurRow = nResMatRows - 1;
214                                             }
215                                             nResMatCols = nNewCols;
216                                             nResMatRows = nNewRows;
217                                         }
218                                     }
219 };
220 
221 #endif // SC_JUMPMATRIX_HXX
222 
223