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_JUMPMATRIX_HXX 25 #define SC_JUMPMATRIX_HXX 26 27 #include "formula/token.hxx" 28 #include "formula/errorcodes.hxx" 29 #include <tools/solar.h> 30 #include <vector> 31 #include "scmatrix.hxx" 32 33 typedef ::std::vector< formula::FormulaToken*> ScTokenVec; 34 35 struct ScJumpMatrixEntry 36 { 37 double fBool; // 0:= false 1:= true also if no-path 38 // other values may contain error conditions like NAN and INF 39 short nStart; // start of path (actually start-1, see formula::FormulaTokenIterator) 40 short nNext; // next after path 41 // jump path exists if nStart != nNext, else no path 42 short nStop; // optional stop of path (nPC < nStop) 43 SetJumpScJumpMatrixEntry44 void SetJump( double fBoolP, short nStartP, short nNextP, short nStopP ) 45 { 46 fBool = fBoolP; 47 nStart = nStartP; 48 nNext = nNextP; 49 nStop = nStopP; 50 } GetJumpScJumpMatrixEntry51 void GetJump( double& rBool, short& rStart, short& rNext, short& rStop ) 52 { 53 rBool = fBool; 54 rStart = nStart; 55 rNext = nNext; 56 rStop = nStop; 57 } 58 }; 59 60 class ScJumpMatrix 61 { 62 ScJumpMatrixEntry* pJump; // the jumps 63 ScMatrixRef pMat; // the results 64 ScTokenVec* pParams; // parameter stack 65 SCSIZE nCols; 66 SCSIZE nRows; 67 SCSIZE nCurCol; 68 SCSIZE nCurRow; 69 SCSIZE nResMatCols; 70 SCSIZE nResMatRows; 71 bool bStarted; 72 73 // not implemented, prevent usage 74 ScJumpMatrix( const ScJumpMatrix& ); 75 ScJumpMatrix& operator=( const ScJumpMatrix& ); 76 77 public: ScJumpMatrix(SCSIZE nColsP,SCSIZE nRowsP)78 ScJumpMatrix( SCSIZE nColsP, SCSIZE nRowsP ) 79 : pJump( new ScJumpMatrixEntry[ nColsP * nRowsP ] ) 80 , pMat( new ScMatrix( nColsP, nRowsP) ) 81 , pParams( NULL ) 82 , nCols( nColsP ) 83 , nRows( nRowsP ) 84 , nCurCol( 0 ) 85 , nCurRow( 0 ) 86 , nResMatCols( nColsP ) 87 , nResMatRows( nRowsP ) 88 , bStarted( false ) 89 { 90 // Initialize result matrix in case of 91 // a premature end of the interpreter 92 // due to errors. 93 pMat->FillDouble( CreateDoubleError( 94 NOTAVAILABLE), 0, 0, nCols-1, 95 nRows-1); 96 /*! pJump not initialized */ 97 } ~ScJumpMatrix()98 ~ScJumpMatrix() 99 { 100 if ( pParams ) 101 { 102 for ( ScTokenVec::iterator i = 103 pParams->begin(); i != 104 pParams->end(); ++i ) 105 { 106 (*i)->DecRef(); 107 } 108 delete pParams; 109 } 110 delete [] pJump; 111 } GetDimensions(SCSIZE & rCols,SCSIZE & rRows) const112 void GetDimensions( SCSIZE& rCols, SCSIZE& rRows ) const 113 { 114 rCols = nCols; 115 rRows = nRows; 116 } SetJump(SCSIZE nCol,SCSIZE nRow,double fBool,short nStart,short nNext,short nStop=SHRT_MAX)117 void SetJump( SCSIZE nCol, SCSIZE nRow, double fBool, 118 short nStart, short nNext, 119 short nStop = SHRT_MAX ) 120 { 121 pJump[ (sal_uLong)nCol * nRows + nRow ]. 122 SetJump( fBool, nStart, nNext, nStop); 123 } GetJump(SCSIZE nCol,SCSIZE nRow,double & rBool,short & rStart,short & rNext,short & rStop) const124 void GetJump( SCSIZE nCol, SCSIZE nRow, double& rBool, 125 short& rStart, short& rNext, 126 short& rStop ) const 127 { 128 if (nCols == 1 && nRows == 1) 129 { 130 nCol = 0; 131 nRow = 0; 132 } 133 else if (nCols == 1 && nRow < nRows) 134 nCol = 0; 135 else if (nRows == 1 && nCol < nCols) 136 nRow = 0; 137 else if (nCols <= nCol || nRows <= nRow) 138 { 139 DBG_ERROR("ScJumpMatrix::GetJump: dimension error"); 140 nCol = 0; 141 nRow = 0; 142 } 143 pJump[ (sal_uLong)nCol * nRows + nRow ]. 144 GetJump( rBool, rStart, rNext, rStop); 145 } SetAllJumps(double fBool,short nStart,short nNext,short nStop=SHRT_MAX)146 void SetAllJumps( double fBool, 147 short nStart, short nNext, 148 short nStop = SHRT_MAX ) 149 { 150 sal_uLong n = (sal_uLong)nCols * nRows; 151 for ( sal_uLong j=0; j<n; ++j ) 152 { 153 pJump[ j ].SetJump( fBool, nStart, 154 nNext, nStop); 155 } 156 } SetJumpParameters(ScTokenVec * p)157 void SetJumpParameters( ScTokenVec* p ) 158 { pParams = p; } GetJumpParameters() const159 const ScTokenVec* GetJumpParameters() const { return pParams; } GetResultMatrix() const160 ScMatrix* GetResultMatrix() const { return pMat; } GetPos(SCSIZE & rCol,SCSIZE & rRow) const161 void GetPos( SCSIZE& rCol, SCSIZE& rRow ) const 162 { 163 rCol = nCurCol; 164 rRow = nCurRow; 165 } Next(SCSIZE & rCol,SCSIZE & rRow)166 bool Next( SCSIZE& rCol, SCSIZE& rRow ) 167 { 168 if ( !bStarted ) 169 { 170 bStarted = true; 171 nCurCol = nCurRow = 0; 172 } 173 else 174 { 175 if ( ++nCurRow >= nResMatRows ) 176 { 177 nCurRow = 0; 178 ++nCurCol; 179 } 180 } 181 GetPos( rCol, rRow ); 182 return nCurCol < nResMatCols; 183 } GetResMatDimensions(SCSIZE & rCols,SCSIZE & rRows)184 void GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows ) 185 { 186 rCols = nResMatCols; 187 rRows = nResMatRows; 188 } SetNewResMat(SCSIZE nNewCols,SCSIZE nNewRows)189 void SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows ) 190 { 191 if ( nNewCols > nResMatCols || nNewRows > nResMatRows ) 192 { 193 pMat = pMat->CloneAndExtend( nNewCols, nNewRows ); 194 if ( nResMatCols < nNewCols ) 195 { 196 pMat->FillDouble( CreateDoubleError( 197 NOTAVAILABLE), nResMatCols, 0, nNewCols-1, 198 nResMatRows-1); 199 } 200 if ( nResMatRows < nNewRows ) 201 { 202 pMat->FillDouble( CreateDoubleError( 203 NOTAVAILABLE), 0, nResMatRows, nNewCols-1, 204 nNewRows-1); 205 } 206 if ( nRows == 1 && nCurCol != 0 ) 207 { 208 nCurCol = 0; 209 nCurRow = nResMatRows - 1; 210 } 211 nResMatCols = nNewCols; 212 nResMatRows = nNewRows; 213 } 214 } 215 }; 216 217 #endif // SC_JUMPMATRIX_HXX 218 219