/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community. If not, see .
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see
* or contact Peter Baumann via .
/
/**
* SOURCE: miter.cc
*
* MODULE: raslib
* CLASS: r_Miter
*
*/
#include "raslib/miter.hh"
#include "raslib/minterval.hh"
#include "raslib/rmdebug.hh"
inline
r_Miter::r_Miter( const r_Minterval* newAreaIter,
const r_Minterval* newAreaTile,
r_Bytes newCellSize, const char* newFirstCell )
: areaIter(newAreaIter), areaTile(newAreaTile), cellSize(newCellSize),
firstCell(newFirstCell), done(false)
{
RMDBGENTER(1, RMDebug::module_raslib, "r_Miter", "r_Miter()");
// the following initializes incArrIter and calculates the first offset
int tIncIter = 1; // total increment for current dimension
int prevTIncIter = 1; // total increment for previous dimension
r_Bytes incIter = cellSize; // current increment
r_Dimension i;
int firstOff = 0;
RMDBGMIDDLE(2, RMDebug::module_raslib, "r_Miter", "area for iteration: " << *newAreaIter);
RMDBGMIDDLE(2, RMDebug::module_raslib, "r_Miter", "whole area: " << *newAreaTile);
// dimensionality of both areaIter and areaTile
r_Dimension dim = areaIter->dimension();
// stores the increments
incArrIter = new incArrElem[dim];
for( i=0; idimension(); i++ ) {
incArrIter[i].curr = 0;
}
}
inline char*
r_Miter::nextCell()
{
// return the current cell
char* retVal = currCell;
r_Dimension i = 0;
if(done)
return retVal;
// increment adresses
currCell += incArrIter[0].inc;
lowCount++;
if(lowCount == incArrIter[0].repeat) {
lowCount = 0;
// increment other dimensions
for(i=1; i < areaIter->dimension(); i++) {
incArrIter[i].curr++;
currCell += incArrIter[i].inc;
if(incArrIter[i].curr < incArrIter[i].repeat) {
// no overflow in this dimension
break;
} else {
// overflow in this dimension
incArrIter[i].curr = 0;
}
}
if( i == areaIter->dimension() ) {
// overflow in last dimension
done = true;
currCell = retVal;
}
}
return retVal;
}
bool
r_Miter::isDone()
{
return done;
}