pyuno: call target only with internal python
[LibreOffice.git] / sc / source / core / tool / jumpmatrix.cxx
blob868d5da655f9c2c068083710c157f2b69b54e07f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <jumpmatrix.hxx>
21 #include <scmatrix.hxx>
22 #include <osl/diagnose.h>
24 namespace {
25 // Don't bother with buffer overhead for less than y rows.
26 const SCSIZE kBufferThreshold = 128;
29 ScJumpMatrix::ScJumpMatrix( OpCode eOp, SCSIZE nColsP, SCSIZE nRowsP )
30 : mvJump(nColsP * nRowsP)
31 // Initialize result matrix in case of
32 // a premature end of the interpreter
33 // due to errors.
34 , pMat(new ScMatrix(nColsP, nRowsP, CreateDoubleError(FormulaError::NotAvailable)))
35 , nCols(nColsP)
36 , nRows(nRowsP)
37 , nCurCol(0)
38 , nCurRow(0)
39 , nResMatCols(nColsP)
40 , nResMatRows(nRowsP)
41 , meOp(eOp)
42 , bStarted(false)
43 , mnBufferCol(0)
44 , mnBufferRowStart(0)
45 , mnBufferEmptyCount(0)
46 , mnBufferEmptyPathCount(0)
48 /*! pJump not initialized */
51 ScJumpMatrix::~ScJumpMatrix()
53 for (const auto & i : mvParams)
54 i->DecRef();
57 void ScJumpMatrix::GetDimensions(SCSIZE& rCols, SCSIZE& rRows) const
59 rCols = nCols;
60 rRows = nRows;
63 void ScJumpMatrix::SetJump(SCSIZE nCol, SCSIZE nRow, double fBool,
64 short nStart, short nNext)
66 mvJump[static_cast<sal_uInt64>(nCol) * nRows + nRow].SetJump(fBool, nStart, nNext, SHRT_MAX);
69 void ScJumpMatrix::GetJump(
70 SCSIZE nCol, SCSIZE nRow, double& rBool, short& rStart, short& rNext, short& rStop) const
72 if (nCols == 1 && nRows == 1)
74 nCol = 0;
75 nRow = 0;
77 else if (nCols == 1 && nRow < nRows) nCol = 0;
78 else if (nRows == 1 && nCol < nCols) nRow = 0;
79 else if (nCols <= nCol || nRows <= nRow)
81 OSL_FAIL("ScJumpMatrix::GetJump: dimension error");
82 nCol = 0;
83 nRow = 0;
85 mvJump[static_cast<sal_uInt64>(nCol) * nRows + nRow].
86 GetJump(rBool, rStart, rNext, rStop);
89 void ScJumpMatrix::SetAllJumps(double fBool, short nStart, short nNext, short nStop)
91 sal_uInt64 n = static_cast<sal_uInt64>(nCols) * nRows;
92 for (sal_uInt64 j = 0; j < n; ++j)
94 mvJump[j].SetJump(fBool, nStart,
95 nNext, nStop);
99 void ScJumpMatrix::SetJumpParameters(ScTokenVec&& p)
101 mvParams = std::move(p);
104 void ScJumpMatrix::GetPos(SCSIZE& rCol, SCSIZE& rRow) const
106 rCol = nCurCol;
107 rRow = nCurRow;
110 bool ScJumpMatrix::Next(SCSIZE& rCol, SCSIZE& rRow)
112 if (!bStarted)
114 bStarted = true;
115 nCurCol = nCurRow = 0;
117 else
119 if (++nCurRow >= nResMatRows)
121 nCurRow = 0;
122 ++nCurCol;
125 GetPos(rCol, rRow);
126 return nCurCol < nResMatCols;
129 void ScJumpMatrix::GetResMatDimensions(SCSIZE& rCols, SCSIZE& rRows)
131 rCols = nResMatCols;
132 rRows = nResMatRows;
135 void ScJumpMatrix::SetNewResMat(SCSIZE nNewCols, SCSIZE nNewRows)
137 if (nNewCols <= nResMatCols && nNewRows <= nResMatRows)
138 return;
140 FlushBufferOtherThan( BUFFER_NONE, 0, 0);
141 pMat = pMat->CloneAndExtend(nNewCols, nNewRows);
142 if (nResMatCols < nNewCols)
144 pMat->FillDouble(
145 CreateDoubleError(FormulaError::NotAvailable),
146 nResMatCols, 0, nNewCols - 1, nResMatRows - 1);
148 if (nResMatRows < nNewRows)
150 pMat->FillDouble(
151 CreateDoubleError(FormulaError::NotAvailable),
152 0, nResMatRows, nNewCols - 1, nNewRows - 1);
154 if (nRows == 1 && nCurCol != 0)
156 nCurCol = 0;
157 nCurRow = nResMatRows - 1;
159 nResMatCols = nNewCols;
160 nResMatRows = nNewRows;
163 bool ScJumpMatrix::HasResultMatrix() const
165 // We now always have a matrix but caller logic may still want to check it.
166 return bool(pMat);
169 ScRefList& ScJumpMatrix::GetRefList()
171 return mvRefList;
174 void ScJumpMatrix::FlushBufferOtherThan( ScJumpMatrix::BufferType eType, SCSIZE nC, SCSIZE nR )
176 if (!mvBufferDoubles.empty() &&
177 (eType != BUFFER_DOUBLE || nC != mnBufferCol || nR != mnBufferRowStart + mvBufferDoubles.size()))
179 pMat->PutDoubleVector( mvBufferDoubles, mnBufferCol, mnBufferRowStart);
180 mvBufferDoubles.clear();
182 if (!mvBufferStrings.empty() &&
183 (eType != BUFFER_STRING || nC != mnBufferCol || nR != mnBufferRowStart + mvBufferStrings.size()))
185 pMat->PutStringVector( mvBufferStrings, mnBufferCol, mnBufferRowStart);
186 mvBufferStrings.clear();
188 if (mnBufferEmptyCount &&
189 (eType != BUFFER_EMPTY || nC != mnBufferCol || nR != mnBufferRowStart + mnBufferEmptyCount))
191 pMat->PutEmptyVector( mnBufferEmptyCount, mnBufferCol, mnBufferRowStart);
192 mnBufferEmptyCount = 0;
194 if (mnBufferEmptyPathCount &&
195 (eType != BUFFER_EMPTYPATH || nC != mnBufferCol || nR != mnBufferRowStart + mnBufferEmptyPathCount))
197 pMat->PutEmptyPathVector( mnBufferEmptyPathCount, mnBufferCol, mnBufferRowStart);
198 mnBufferEmptyPathCount = 0;
202 ScMatrix* ScJumpMatrix::GetResultMatrix()
204 if (nResMatRows >= kBufferThreshold)
205 FlushBufferOtherThan( BUFFER_NONE, 0, 0);
206 return pMat.get();
209 void ScJumpMatrix::PutResultDouble( double fVal, SCSIZE nC, SCSIZE nR )
211 if (nResMatRows < kBufferThreshold)
212 pMat->PutDouble( fVal, nC, nR);
213 else
215 FlushBufferOtherThan( BUFFER_DOUBLE, nC, nR);
216 if (mvBufferDoubles.empty())
218 mnBufferCol = nC;
219 mnBufferRowStart = nR;
221 mvBufferDoubles.push_back( fVal);
225 void ScJumpMatrix::PutResultString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR )
227 if (nResMatRows < kBufferThreshold)
228 pMat->PutString( rStr, nC, nR);
229 else
231 FlushBufferOtherThan( BUFFER_STRING, nC, nR);
232 if (mvBufferStrings.empty())
234 mnBufferCol = nC;
235 mnBufferRowStart = nR;
237 mvBufferStrings.push_back( rStr);
241 void ScJumpMatrix::PutResultEmpty( SCSIZE nC, SCSIZE nR )
243 if (nResMatRows < kBufferThreshold)
244 pMat->PutEmpty( nC, nR);
245 else
247 FlushBufferOtherThan( BUFFER_EMPTY, nC, nR);
248 if (!mnBufferEmptyCount)
250 mnBufferCol = nC;
251 mnBufferRowStart = nR;
253 ++mnBufferEmptyCount;
257 void ScJumpMatrix::PutResultEmptyPath( SCSIZE nC, SCSIZE nR )
259 if (nResMatRows < kBufferThreshold)
260 pMat->PutEmptyPath( nC, nR);
261 else
263 FlushBufferOtherThan( BUFFER_EMPTYPATH, nC, nR);
264 if (!mnBufferEmptyPathCount)
266 mnBufferCol = nC;
267 mnBufferRowStart = nR;
269 ++mnBufferEmptyPathCount;
273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */