1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski #ifndef SC_JUMPMATRIX_HXX 25*b1cdbd2cSJim Jagielski #define SC_JUMPMATRIX_HXX 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include "formula/token.hxx" 28*b1cdbd2cSJim Jagielski #include "formula/errorcodes.hxx" 29*b1cdbd2cSJim Jagielski #include <tools/solar.h> 30*b1cdbd2cSJim Jagielski #include <vector> 31*b1cdbd2cSJim Jagielski #include "scmatrix.hxx" 32*b1cdbd2cSJim Jagielski 33*b1cdbd2cSJim Jagielski typedef ::std::vector< formula::FormulaToken*> ScTokenVec; 34*b1cdbd2cSJim Jagielski 35*b1cdbd2cSJim Jagielski struct ScJumpMatrixEntry 36*b1cdbd2cSJim Jagielski { 37*b1cdbd2cSJim Jagielski double fBool; // 0:= false 1:= true also if no-path 38*b1cdbd2cSJim Jagielski // other values may contain error conditions like NAN and INF 39*b1cdbd2cSJim Jagielski short nStart; // start of path (actually start-1, see formula::FormulaTokenIterator) 40*b1cdbd2cSJim Jagielski short nNext; // next after path 41*b1cdbd2cSJim Jagielski // jump path exists if nStart != nNext, else no path 42*b1cdbd2cSJim Jagielski short nStop; // optional stop of path (nPC < nStop) 43*b1cdbd2cSJim Jagielski SetJumpScJumpMatrixEntry44*b1cdbd2cSJim Jagielski void SetJump( double fBoolP, short nStartP, short nNextP, short nStopP ) 45*b1cdbd2cSJim Jagielski { 46*b1cdbd2cSJim Jagielski fBool = fBoolP; 47*b1cdbd2cSJim Jagielski nStart = nStartP; 48*b1cdbd2cSJim Jagielski nNext = nNextP; 49*b1cdbd2cSJim Jagielski nStop = nStopP; 50*b1cdbd2cSJim Jagielski } GetJumpScJumpMatrixEntry51*b1cdbd2cSJim Jagielski void GetJump( double& rBool, short& rStart, short& rNext, short& rStop ) 52*b1cdbd2cSJim Jagielski { 53*b1cdbd2cSJim Jagielski rBool = fBool; 54*b1cdbd2cSJim Jagielski rStart = nStart; 55*b1cdbd2cSJim Jagielski rNext = nNext; 56*b1cdbd2cSJim Jagielski rStop = nStop; 57*b1cdbd2cSJim Jagielski } 58*b1cdbd2cSJim Jagielski }; 59*b1cdbd2cSJim Jagielski 60*b1cdbd2cSJim Jagielski class ScJumpMatrix 61*b1cdbd2cSJim Jagielski { 62*b1cdbd2cSJim Jagielski ScJumpMatrixEntry* pJump; // the jumps 63*b1cdbd2cSJim Jagielski ScMatrixRef pMat; // the results 64*b1cdbd2cSJim Jagielski ScTokenVec* pParams; // parameter stack 65*b1cdbd2cSJim Jagielski SCSIZE nCols; 66*b1cdbd2cSJim Jagielski SCSIZE nRows; 67*b1cdbd2cSJim Jagielski SCSIZE nCurCol; 68*b1cdbd2cSJim Jagielski SCSIZE nCurRow; 69*b1cdbd2cSJim Jagielski SCSIZE nResMatCols; 70*b1cdbd2cSJim Jagielski SCSIZE nResMatRows; 71*b1cdbd2cSJim Jagielski bool bStarted; 72*b1cdbd2cSJim Jagielski 73*b1cdbd2cSJim Jagielski // not implemented, prevent usage 74*b1cdbd2cSJim Jagielski ScJumpMatrix( const ScJumpMatrix& ); 75*b1cdbd2cSJim Jagielski ScJumpMatrix& operator=( const ScJumpMatrix& ); 76*b1cdbd2cSJim Jagielski 77*b1cdbd2cSJim Jagielski public: ScJumpMatrix(SCSIZE nColsP,SCSIZE nRowsP)78*b1cdbd2cSJim Jagielski ScJumpMatrix( SCSIZE nColsP, SCSIZE nRowsP ) 79*b1cdbd2cSJim Jagielski : pJump( new ScJumpMatrixEntry[ nColsP * nRowsP ] ) 80*b1cdbd2cSJim Jagielski , pMat( new ScMatrix( nColsP, nRowsP) ) 81*b1cdbd2cSJim Jagielski , pParams( NULL ) 82*b1cdbd2cSJim Jagielski , nCols( nColsP ) 83*b1cdbd2cSJim Jagielski , nRows( nRowsP ) 84*b1cdbd2cSJim Jagielski , nCurCol( 0 ) 85*b1cdbd2cSJim Jagielski , nCurRow( 0 ) 86*b1cdbd2cSJim Jagielski , nResMatCols( nColsP ) 87*b1cdbd2cSJim Jagielski , nResMatRows( nRowsP ) 88*b1cdbd2cSJim Jagielski , bStarted( false ) 89*b1cdbd2cSJim Jagielski { 90*b1cdbd2cSJim Jagielski // Initialize result matrix in case of 91*b1cdbd2cSJim Jagielski // a premature end of the interpreter 92*b1cdbd2cSJim Jagielski // due to errors. 93*b1cdbd2cSJim Jagielski pMat->FillDouble( CreateDoubleError( 94*b1cdbd2cSJim Jagielski NOTAVAILABLE), 0, 0, nCols-1, 95*b1cdbd2cSJim Jagielski nRows-1); 96*b1cdbd2cSJim Jagielski /*! pJump not initialized */ 97*b1cdbd2cSJim Jagielski } ~ScJumpMatrix()98*b1cdbd2cSJim Jagielski ~ScJumpMatrix() 99*b1cdbd2cSJim Jagielski { 100*b1cdbd2cSJim Jagielski if ( pParams ) 101*b1cdbd2cSJim Jagielski { 102*b1cdbd2cSJim Jagielski for ( ScTokenVec::iterator i = 103*b1cdbd2cSJim Jagielski pParams->begin(); i != 104*b1cdbd2cSJim Jagielski pParams->end(); ++i ) 105*b1cdbd2cSJim Jagielski { 106*b1cdbd2cSJim Jagielski (*i)->DecRef(); 107*b1cdbd2cSJim Jagielski } 108*b1cdbd2cSJim Jagielski delete pParams; 109*b1cdbd2cSJim Jagielski } 110*b1cdbd2cSJim Jagielski delete [] pJump; 111*b1cdbd2cSJim Jagielski } GetDimensions(SCSIZE & rCols,SCSIZE & rRows) const112*b1cdbd2cSJim Jagielski void GetDimensions( SCSIZE& rCols, SCSIZE& rRows ) const 113*b1cdbd2cSJim Jagielski { 114*b1cdbd2cSJim Jagielski rCols = nCols; 115*b1cdbd2cSJim Jagielski rRows = nRows; 116*b1cdbd2cSJim Jagielski } SetJump(SCSIZE nCol,SCSIZE nRow,double fBool,short nStart,short nNext,short nStop=SHRT_MAX)117*b1cdbd2cSJim Jagielski void SetJump( SCSIZE nCol, SCSIZE nRow, double fBool, 118*b1cdbd2cSJim Jagielski short nStart, short nNext, 119*b1cdbd2cSJim Jagielski short nStop = SHRT_MAX ) 120*b1cdbd2cSJim Jagielski { 121*b1cdbd2cSJim Jagielski pJump[ (sal_uLong)nCol * nRows + nRow ]. 122*b1cdbd2cSJim Jagielski SetJump( fBool, nStart, nNext, nStop); 123*b1cdbd2cSJim Jagielski } GetJump(SCSIZE nCol,SCSIZE nRow,double & rBool,short & rStart,short & rNext,short & rStop) const124*b1cdbd2cSJim Jagielski void GetJump( SCSIZE nCol, SCSIZE nRow, double& rBool, 125*b1cdbd2cSJim Jagielski short& rStart, short& rNext, 126*b1cdbd2cSJim Jagielski short& rStop ) const 127*b1cdbd2cSJim Jagielski { 128*b1cdbd2cSJim Jagielski if (nCols == 1 && nRows == 1) 129*b1cdbd2cSJim Jagielski { 130*b1cdbd2cSJim Jagielski nCol = 0; 131*b1cdbd2cSJim Jagielski nRow = 0; 132*b1cdbd2cSJim Jagielski } 133*b1cdbd2cSJim Jagielski else if (nCols == 1 && nRow < nRows) 134*b1cdbd2cSJim Jagielski nCol = 0; 135*b1cdbd2cSJim Jagielski else if (nRows == 1 && nCol < nCols) 136*b1cdbd2cSJim Jagielski nRow = 0; 137*b1cdbd2cSJim Jagielski else if (nCols <= nCol || nRows <= nRow) 138*b1cdbd2cSJim Jagielski { 139*b1cdbd2cSJim Jagielski DBG_ERROR("ScJumpMatrix::GetJump: dimension error"); 140*b1cdbd2cSJim Jagielski nCol = 0; 141*b1cdbd2cSJim Jagielski nRow = 0; 142*b1cdbd2cSJim Jagielski } 143*b1cdbd2cSJim Jagielski pJump[ (sal_uLong)nCol * nRows + nRow ]. 144*b1cdbd2cSJim Jagielski GetJump( rBool, rStart, rNext, rStop); 145*b1cdbd2cSJim Jagielski } SetAllJumps(double fBool,short nStart,short nNext,short nStop=SHRT_MAX)146*b1cdbd2cSJim Jagielski void SetAllJumps( double fBool, 147*b1cdbd2cSJim Jagielski short nStart, short nNext, 148*b1cdbd2cSJim Jagielski short nStop = SHRT_MAX ) 149*b1cdbd2cSJim Jagielski { 150*b1cdbd2cSJim Jagielski sal_uLong n = (sal_uLong)nCols * nRows; 151*b1cdbd2cSJim Jagielski for ( sal_uLong j=0; j<n; ++j ) 152*b1cdbd2cSJim Jagielski { 153*b1cdbd2cSJim Jagielski pJump[ j ].SetJump( fBool, nStart, 154*b1cdbd2cSJim Jagielski nNext, nStop); 155*b1cdbd2cSJim Jagielski } 156*b1cdbd2cSJim Jagielski } SetJumpParameters(ScTokenVec * p)157*b1cdbd2cSJim Jagielski void SetJumpParameters( ScTokenVec* p ) 158*b1cdbd2cSJim Jagielski { pParams = p; } GetJumpParameters() const159*b1cdbd2cSJim Jagielski const ScTokenVec* GetJumpParameters() const { return pParams; } GetResultMatrix() const160*b1cdbd2cSJim Jagielski ScMatrix* GetResultMatrix() const { return pMat; } GetPos(SCSIZE & rCol,SCSIZE & rRow) const161*b1cdbd2cSJim Jagielski void GetPos( SCSIZE& rCol, SCSIZE& rRow ) const 162*b1cdbd2cSJim Jagielski { 163*b1cdbd2cSJim Jagielski rCol = nCurCol; 164*b1cdbd2cSJim Jagielski rRow = nCurRow; 165*b1cdbd2cSJim Jagielski } Next(SCSIZE & rCol,SCSIZE & rRow)166*b1cdbd2cSJim Jagielski bool Next( SCSIZE& rCol, SCSIZE& rRow ) 167*b1cdbd2cSJim Jagielski { 168*b1cdbd2cSJim Jagielski if ( !bStarted ) 169*b1cdbd2cSJim Jagielski { 170*b1cdbd2cSJim Jagielski bStarted = true; 171*b1cdbd2cSJim Jagielski nCurCol = nCurRow = 0; 172*b1cdbd2cSJim Jagielski } 173*b1cdbd2cSJim Jagielski else 174*b1cdbd2cSJim Jagielski { 175*b1cdbd2cSJim Jagielski if ( ++nCurRow >= nResMatRows ) 176*b1cdbd2cSJim Jagielski { 177*b1cdbd2cSJim Jagielski nCurRow = 0; 178*b1cdbd2cSJim Jagielski ++nCurCol; 179*b1cdbd2cSJim Jagielski } 180*b1cdbd2cSJim Jagielski } 181*b1cdbd2cSJim Jagielski GetPos( rCol, rRow ); 182*b1cdbd2cSJim Jagielski return nCurCol < nResMatCols; 183*b1cdbd2cSJim Jagielski } GetResMatDimensions(SCSIZE & rCols,SCSIZE & rRows)184*b1cdbd2cSJim Jagielski void GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows ) 185*b1cdbd2cSJim Jagielski { 186*b1cdbd2cSJim Jagielski rCols = nResMatCols; 187*b1cdbd2cSJim Jagielski rRows = nResMatRows; 188*b1cdbd2cSJim Jagielski } SetNewResMat(SCSIZE nNewCols,SCSIZE nNewRows)189*b1cdbd2cSJim Jagielski void SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows ) 190*b1cdbd2cSJim Jagielski { 191*b1cdbd2cSJim Jagielski if ( nNewCols > nResMatCols || nNewRows > nResMatRows ) 192*b1cdbd2cSJim Jagielski { 193*b1cdbd2cSJim Jagielski pMat = pMat->CloneAndExtend( nNewCols, nNewRows ); 194*b1cdbd2cSJim Jagielski if ( nResMatCols < nNewCols ) 195*b1cdbd2cSJim Jagielski { 196*b1cdbd2cSJim Jagielski pMat->FillDouble( CreateDoubleError( 197*b1cdbd2cSJim Jagielski NOTAVAILABLE), nResMatCols, 0, nNewCols-1, 198*b1cdbd2cSJim Jagielski nResMatRows-1); 199*b1cdbd2cSJim Jagielski } 200*b1cdbd2cSJim Jagielski if ( nResMatRows < nNewRows ) 201*b1cdbd2cSJim Jagielski { 202*b1cdbd2cSJim Jagielski pMat->FillDouble( CreateDoubleError( 203*b1cdbd2cSJim Jagielski NOTAVAILABLE), 0, nResMatRows, nNewCols-1, 204*b1cdbd2cSJim Jagielski nNewRows-1); 205*b1cdbd2cSJim Jagielski } 206*b1cdbd2cSJim Jagielski if ( nRows == 1 && nCurCol != 0 ) 207*b1cdbd2cSJim Jagielski { 208*b1cdbd2cSJim Jagielski nCurCol = 0; 209*b1cdbd2cSJim Jagielski nCurRow = nResMatRows - 1; 210*b1cdbd2cSJim Jagielski } 211*b1cdbd2cSJim Jagielski nResMatCols = nNewCols; 212*b1cdbd2cSJim Jagielski nResMatRows = nNewRows; 213*b1cdbd2cSJim Jagielski } 214*b1cdbd2cSJim Jagielski } 215*b1cdbd2cSJim Jagielski }; 216*b1cdbd2cSJim Jagielski 217*b1cdbd2cSJim Jagielski #endif // SC_JUMPMATRIX_HXX 218*b1cdbd2cSJim Jagielski 219