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