1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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
34 , pMat(new ScMatrix(nColsP
, nRowsP
, CreateDoubleError(FormulaError::NotAvailable
)))
45 , mnBufferEmptyCount(0)
46 , mnBufferEmptyPathCount(0)
48 /*! pJump not initialized */
51 ScJumpMatrix::~ScJumpMatrix()
53 for (const auto & i
: mvParams
)
57 void ScJumpMatrix::GetDimensions(SCSIZE
& rCols
, SCSIZE
& rRows
) const
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)
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");
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
,
99 void ScJumpMatrix::SetJumpParameters(ScTokenVec
&& p
)
101 mvParams
= std::move(p
);
104 void ScJumpMatrix::GetPos(SCSIZE
& rCol
, SCSIZE
& rRow
) const
110 bool ScJumpMatrix::Next(SCSIZE
& rCol
, SCSIZE
& rRow
)
115 nCurCol
= nCurRow
= 0;
119 if (++nCurRow
>= nResMatRows
)
126 return nCurCol
< nResMatCols
;
129 void ScJumpMatrix::GetResMatDimensions(SCSIZE
& rCols
, SCSIZE
& rRows
)
135 void ScJumpMatrix::SetNewResMat(SCSIZE nNewCols
, SCSIZE nNewRows
)
137 if (nNewCols
<= nResMatCols
&& nNewRows
<= nResMatRows
)
140 FlushBufferOtherThan( BUFFER_NONE
, 0, 0);
141 pMat
= pMat
->CloneAndExtend(nNewCols
, nNewRows
);
142 if (nResMatCols
< nNewCols
)
145 CreateDoubleError(FormulaError::NotAvailable
),
146 nResMatCols
, 0, nNewCols
- 1, nResMatRows
- 1);
148 if (nResMatRows
< nNewRows
)
151 CreateDoubleError(FormulaError::NotAvailable
),
152 0, nResMatRows
, nNewCols
- 1, nNewRows
- 1);
154 if (nRows
== 1 && 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.
169 ScRefList
& ScJumpMatrix::GetRefList()
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);
209 void ScJumpMatrix::PutResultDouble( double fVal
, SCSIZE nC
, SCSIZE nR
)
211 if (nResMatRows
< kBufferThreshold
)
212 pMat
->PutDouble( fVal
, nC
, nR
);
215 FlushBufferOtherThan( BUFFER_DOUBLE
, nC
, nR
);
216 if (mvBufferDoubles
.empty())
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
);
231 FlushBufferOtherThan( BUFFER_STRING
, nC
, nR
);
232 if (mvBufferStrings
.empty())
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
);
247 FlushBufferOtherThan( BUFFER_EMPTY
, nC
, nR
);
248 if (!mnBufferEmptyCount
)
251 mnBufferRowStart
= nR
;
253 ++mnBufferEmptyCount
;
257 void ScJumpMatrix::PutResultEmptyPath( SCSIZE nC
, SCSIZE nR
)
259 if (nResMatRows
< kBufferThreshold
)
260 pMat
->PutEmptyPath( nC
, nR
);
263 FlushBufferOtherThan( BUFFER_EMPTYPATH
, nC
, nR
);
264 if (!mnBufferEmptyPathCount
)
267 mnBufferRowStart
= nR
;
269 ++mnBufferEmptyPathCount
;
273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */