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"
24 // Don't bother with buffer overhead for less than y rows.
25 const SCSIZE kBufferThreshhold
= 128;
28 ScJumpMatrix::ScJumpMatrix(SCSIZE nColsP
, SCSIZE nRowsP
)
29 : pJump(new ScJumpMatrixEntry
[nColsP
* nRowsP
])
30 , pMat(new ScMatrix(nColsP
, nRowsP
))
41 , mnBufferEmptyCount(0)
42 , mnBufferEmptyPathCount(0)
44 // Initialize result matrix in case of
45 // a premature end of the interpreter
47 pMat
->FillDouble(CreateDoubleError(NOTAVAILABLE
), 0, 0, nCols
- 1, nRows
- 1);
48 /*! pJump not initialized */
51 ScJumpMatrix::~ScJumpMatrix()
55 for (ScTokenVec::iterator i
=
56 pParams
->begin(); i
!=
66 void ScJumpMatrix::GetDimensions(SCSIZE
& rCols
, SCSIZE
& rRows
) const
72 void ScJumpMatrix::SetJump(SCSIZE nCol
, SCSIZE nRow
, double fBool
,
73 short nStart
, short nNext
, short nStop
)
75 pJump
[(sal_uLong
)nCol
* nRows
+ nRow
].SetJump(fBool
, nStart
, nNext
, nStop
);
78 void ScJumpMatrix::GetJump(
79 SCSIZE nCol
, SCSIZE nRow
, double& rBool
, short& rStart
, short& rNext
, short& rStop
) const
81 if (nCols
== 1 && nRows
== 1)
86 else if (nCols
== 1 && nRow
< nRows
) nCol
= 0;
87 else if (nRows
== 1 && nCol
< nCols
) nRow
= 0;
88 else if (nCols
<= nCol
|| nRows
<= nRow
)
90 OSL_FAIL("ScJumpMatrix::GetJump: dimension error");
94 pJump
[(sal_uLong
)nCol
* nRows
+ nRow
].
95 GetJump(rBool
, rStart
, rNext
, rStop
);
98 void ScJumpMatrix::SetAllJumps(double fBool
, short nStart
, short nNext
, short nStop
)
100 sal_uLong n
= (sal_uLong
)nCols
* nRows
;
101 for (sal_uLong j
= 0; j
< n
; ++j
)
103 pJump
[j
].SetJump(fBool
, nStart
,
108 void ScJumpMatrix::SetJumpParameters(ScTokenVec
* p
)
113 const ScTokenVec
* ScJumpMatrix::GetJumpParameters() const
118 void ScJumpMatrix::GetPos(SCSIZE
& rCol
, SCSIZE
& rRow
) const
124 bool ScJumpMatrix::Next(SCSIZE
& rCol
, SCSIZE
& rRow
)
129 nCurCol
= nCurRow
= 0;
133 if (++nCurRow
>= nResMatRows
)
140 return nCurCol
< nResMatCols
;
143 void ScJumpMatrix::GetResMatDimensions(SCSIZE
& rCols
, SCSIZE
& rRows
)
149 void ScJumpMatrix::SetNewResMat(SCSIZE nNewCols
, SCSIZE nNewRows
)
151 if (nNewCols
> nResMatCols
|| nNewRows
> nResMatRows
)
153 FlushBufferOtherThan( BUFFER_NONE
, 0, 0);
154 pMat
= pMat
->CloneAndExtend(nNewCols
, nNewRows
);
155 if (nResMatCols
< nNewCols
)
157 pMat
->FillDouble(CreateDoubleError(
158 NOTAVAILABLE
), nResMatCols
, 0, nNewCols
- 1,
161 if (nResMatRows
< nNewRows
)
163 pMat
->FillDouble(CreateDoubleError(
164 NOTAVAILABLE
), 0, nResMatRows
, nNewCols
- 1,
167 if (nRows
== 1 && nCurCol
!= 0)
170 nCurRow
= nResMatRows
- 1;
172 nResMatCols
= nNewCols
;
173 nResMatRows
= nNewRows
;
177 bool ScJumpMatrix::HasResultMatrix() const
179 // We now always have a matrix but caller logic may still want to check it.
180 return pMat
.get() != NULL
;
183 void ScJumpMatrix::FlushBufferOtherThan( ScJumpMatrix::BufferType eType
, SCSIZE nC
, SCSIZE nR
)
185 if (!mvBufferDoubles
.empty() &&
186 (eType
!= BUFFER_DOUBLE
|| nC
!= mnBufferCol
|| nR
!= mnBufferRowStart
+ mvBufferDoubles
.size()))
188 pMat
->PutDoubleVector( mvBufferDoubles
, mnBufferCol
, mnBufferRowStart
);
189 mvBufferDoubles
.clear();
191 if (!mvBufferStrings
.empty() &&
192 (eType
!= BUFFER_STRING
|| nC
!= mnBufferCol
|| nR
!= mnBufferRowStart
+ mvBufferStrings
.size()))
194 pMat
->PutStringVector( mvBufferStrings
, mnBufferCol
, mnBufferRowStart
);
195 mvBufferStrings
.clear();
197 if (mnBufferEmptyCount
&&
198 (eType
!= BUFFER_EMPTY
|| nC
!= mnBufferCol
|| nR
!= mnBufferRowStart
+ mnBufferEmptyCount
))
200 pMat
->PutEmptyVector( mnBufferEmptyCount
, mnBufferCol
, mnBufferRowStart
);
201 mnBufferEmptyCount
= 0;
203 if (mnBufferEmptyPathCount
&&
204 (eType
!= BUFFER_EMPTYPATH
|| nC
!= mnBufferCol
|| nR
!= mnBufferRowStart
+ mnBufferEmptyPathCount
))
206 pMat
->PutEmptyPathVector( mnBufferEmptyPathCount
, mnBufferCol
, mnBufferRowStart
);
207 mnBufferEmptyPathCount
= 0;
211 ScMatrix
* ScJumpMatrix::GetResultMatrix()
213 if (nResMatRows
>= kBufferThreshhold
)
214 FlushBufferOtherThan( BUFFER_NONE
, 0, 0);
218 void ScJumpMatrix::PutResultDouble( double fVal
, SCSIZE nC
, SCSIZE nR
)
220 if (nResMatRows
< kBufferThreshhold
)
221 pMat
->PutDouble( fVal
, nC
, nR
);
224 FlushBufferOtherThan( BUFFER_DOUBLE
, nC
, nR
);
225 if (mvBufferDoubles
.empty())
228 mnBufferRowStart
= nR
;
230 mvBufferDoubles
.push_back( fVal
);
234 void ScJumpMatrix::PutResultString( const svl::SharedString
& rStr
, SCSIZE nC
, SCSIZE nR
)
236 if (nResMatRows
< kBufferThreshhold
)
237 pMat
->PutString( rStr
, nC
, nR
);
240 FlushBufferOtherThan( BUFFER_STRING
, nC
, nR
);
241 if (mvBufferStrings
.empty())
244 mnBufferRowStart
= nR
;
246 mvBufferStrings
.push_back( rStr
);
250 void ScJumpMatrix::PutResultEmpty( SCSIZE nC
, SCSIZE nR
)
252 if (nResMatRows
< kBufferThreshhold
)
253 pMat
->PutEmpty( nC
, nR
);
256 FlushBufferOtherThan( BUFFER_EMPTY
, nC
, nR
);
257 if (!mnBufferEmptyCount
)
260 mnBufferRowStart
= nR
;
262 ++mnBufferEmptyCount
;
266 void ScJumpMatrix::PutResultEmptyPath( SCSIZE nC
, SCSIZE nR
)
268 if (nResMatRows
< kBufferThreshhold
)
269 pMat
->PutEmptyPath( nC
, nR
);
272 FlushBufferOtherThan( BUFFER_EMPTYPATH
, nC
, nR
);
273 if (!mnBufferEmptyPathCount
)
276 mnBufferRowStart
= nR
;
278 ++mnBufferEmptyPathCount
;
282 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */