Files
loongoffice/sc/source/core/data/columniterator.cxx
Noel Grandin 697e9f3cc9 pass sc::ColumnIterator by value
no need to allocate on heap

Change-Id: Ie0f3fa39092083b9c30f3e769bb65fa975150021
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119312
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2021-07-21 21:48:25 +02:00

210 lines
5.4 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <columniterator.hxx>
#include <column.hxx>
#include <document.hxx>
#include <table.hxx>
#include <osl/diagnose.h>
ScColumnTextWidthIterator::ScColumnTextWidthIterator(const ScDocument& rDoc, ScColumn& rCol, SCROW nStartRow, SCROW nEndRow) :
mnEnd(static_cast<size_t>(nEndRow)),
mnCurPos(0)
{
miBlockCur = rCol.maCellTextAttrs.begin();
miBlockEnd = rCol.maCellTextAttrs.end();
init(rDoc, nStartRow, nEndRow);
}
ScColumnTextWidthIterator::ScColumnTextWidthIterator(const ScDocument& rDoc, const ScAddress& rStartPos, SCROW nEndRow) :
mnEnd(static_cast<size_t>(nEndRow)),
mnCurPos(0)
{
auto & rCellTextAttrs = rDoc.maTabs[rStartPos.Tab()]->aCol[rStartPos.Col()].maCellTextAttrs;
miBlockCur = rCellTextAttrs.begin();
miBlockEnd = rCellTextAttrs.end();
init(rDoc, rStartPos.Row(), nEndRow);
}
void ScColumnTextWidthIterator::next()
{
++miDataCur;
++mnCurPos;
if (miDataCur != miDataEnd)
{
// Still in the same block. We're good.
checkEndRow();
return;
}
// Move to the next block.
for (++miBlockCur; miBlockCur != miBlockEnd; ++miBlockCur)
{
if (miBlockCur->type != sc::element_type_celltextattr)
{
// We don't iterator over this block.
mnCurPos += miBlockCur->size;
continue;
}
getDataIterators(0);
checkEndRow();
return;
}
// Reached the end.
assert(miBlockCur == miBlockEnd);
}
bool ScColumnTextWidthIterator::hasCell() const
{
return miBlockCur != miBlockEnd;
}
SCROW ScColumnTextWidthIterator::getPos() const
{
assert(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
return static_cast<SCROW>(mnCurPos);
}
sal_uInt16 ScColumnTextWidthIterator::getValue() const
{
assert(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
return miDataCur->mnTextWidth;
}
void ScColumnTextWidthIterator::setValue(sal_uInt16 nVal)
{
assert(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
miDataCur->mnTextWidth = nVal;
}
void ScColumnTextWidthIterator::init(const ScDocument& rDoc, SCROW nStartRow, SCROW nEndRow)
{
if (!rDoc.ValidRow(nStartRow) || !rDoc.ValidRow(nEndRow))
miBlockCur = miBlockEnd;
size_t nStart = static_cast<size_t>(nStartRow);
// Locate the start row position.
size_t nBlockStart = 0, nBlockEnd = 0;
for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
{
nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
if (nBlockStart <= nStart && nStart < nBlockEnd)
{
// Initial block is found!
break;
}
}
if (miBlockCur == miBlockEnd)
// Initial block not found for whatever reason... Bail out.
return;
// Locate the initial row position within this block.
if (miBlockCur->type == sc::element_type_celltextattr)
{
// This block stores text widths for non-empty cells.
size_t nOffsetInBlock = nStart - nBlockStart;
mnCurPos = nStart;
getDataIterators(nOffsetInBlock);
checkEndRow();
return;
}
// Current block is not of ushort type. Skip to the next block.
nBlockStart = nBlockEnd;
++miBlockCur;
// Look for the first ushort block.
for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
{
nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
if (miBlockCur->type != sc::element_type_celltextattr)
continue;
// Found!
mnCurPos = nBlockStart;
getDataIterators(0);
checkEndRow();
return;
}
// Not found.
assert(miBlockCur == miBlockEnd);
}
void ScColumnTextWidthIterator::getDataIterators(size_t nOffsetInBlock)
{
OSL_ENSURE(miBlockCur != miBlockEnd, "block is at end position");
#if 0
// Does not compile
OSL_ENSURE(miBlockCur->type == sc::celltextattr_block,
"wrong block type - unsigned short block expected.");
#endif
miDataCur = sc::celltextattr_block::begin(*miBlockCur->data);
miDataEnd = sc::celltextattr_block::end(*miBlockCur->data);
std::advance(miDataCur, nOffsetInBlock);
}
void ScColumnTextWidthIterator::checkEndRow()
{
if (mnCurPos <= mnEnd)
// We're still good.
return;
// We're below the end position. End the iteration.
miBlockCur = miBlockEnd;
}
namespace sc {
ColumnIterator::ColumnIterator( const CellStoreType& rCells, SCROW nRow1, SCROW nRow2 ) :
maPos(rCells.position(nRow1)),
maPosEnd(rCells.position(maPos.first, nRow2)),
mbComplete(false)
{
}
void ColumnIterator::next()
{
if ( maPos == maPosEnd)
mbComplete = true;
else
maPos = CellStoreType::next_position(maPos);
}
SCROW ColumnIterator::getRow() const
{
return CellStoreType::logical_position(maPos);
}
bool ColumnIterator::hasCell() const
{
return !mbComplete;
}
mdds::mtv::element_t ColumnIterator::getType() const
{
return maPos.first->type;
}
ScRefCellValue ColumnIterator::getCell() const
{
return toRefCell(maPos.first, maPos.second);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */