void AMExternalScanDataSourceAB::copyValues(int dataSourceIndex) { AMDataSource* ds = scan_->dataSourceAt(dataSourceIndex); const AMnDIndex size = ds->size(); switch(ds->rank()) { case 0: values_.clear(); values_ << ds->value(AMnDIndex()); break; case 1: { values_.resize(size.i()); for(int i=0; i<size.i(); i++) values_[i] = ds->value(i); break; } case 2: { values_.resize(size.i()*size.j()); for(int i=0; i<size.i(); i++) for(int j=0; j<size.j(); j++) values_[i*size.j() + j] = ds->value(AMnDIndex(i,j)); break; } case 3: { values_.resize(size.i()*size.j()*size.k()); for(int i=0; i<size.i(); i++) for(int j=0; j<size.j(); j++) for(int k=0; k<size.k(); k++) values_[i*size.j()*size.k() + j*size.k() + k] = ds->value(AMnDIndex(i,j,k)); break; } case 4: { values_.resize(size.i()*size.j()*size.k()*size.l()); for(int i=0; i<size.i(); i++) for(int j=0; j<size.j(); j++) for(int k=0; k<size.k(); k++) for(int l=0; l<size.l(); l++) values_[i*size.j()*size.k()*size.l() + j*size.k()*size.l() + k*size.l() + l] = ds->value(AMnDIndex(i,j,k,l)); break; } case 5: { values_.resize(size.i()*size.j()*size.k()*size.l()*size.m()); for(int i=0; i<size.i(); i++) for(int j=0; j<size.j(); j++) for(int k=0; k<size.k(); k++) for(int l=0; l<size.l(); l++) for(int m=0; m<size.m(); m++) values_[i*size.j()*size.k()*size.l()*size.m() + j*size.k()*size.l()*size.m() + k*size.l()*size.m() + l*size.m() + m] = ds->value(AMnDIndex(i,j,k,l,m)); /// \todo oh god, we really need a block copy or a multi-dimensional iterator for AMDataSource::value()... break; } } }
AMNumber AMExternalScanDataSourceAB::value(const AMnDIndex &indexes) const { if(!isValid()) return AMNumber::InvalidError; if(indexes.rank() != axes_.count()) return AMNumber::DimensionError; switch(axes_.count()) { case 0: return values_.at(0); case 1: #ifdef AM_ENABLE_BOUNDS_CHECKING if((unsigned)indexes.i() >= (unsigned)axes_.at(0).size) return AMNumber::OutOfBoundsError; #endif return values_.at(indexes.i()); case 2: #ifdef AM_ENABLE_BOUNDS_CHECKING if(((unsigned)indexes.i() >= (unsigned)axes_.at(0).size || (unsigned)indexes.j() >= (unsigned)axes_.at(1).size)) return AMNumber::OutOfBoundsError; #endif return values_.at(indexes.i()*axes_.at(1).size + indexes.j()); case 3: { #ifdef AM_ENABLE_BOUNDS_CHECKING if(((unsigned)indexes.i() >= (unsigned)axes_.at(0).size || (unsigned)indexes.j() >= (unsigned)axes_.at(1).size || (unsigned)indexes.k() >= (unsigned)axes_.at(2).size)) return AMNumber::OutOfBoundsError; #endif int flatIndex = indexes.k(); int stride = axes_.at(2).size; flatIndex += indexes.j()*stride; stride *= axes_.at(1).size; flatIndex += indexes.i()*stride; return values_.at(flatIndex); } case 4: { #ifdef AM_ENABLE_BOUNDS_CHECKING if(((unsigned)indexes.i() >= (unsigned)axes_.at(0).size || (unsigned)indexes.j() >= (unsigned)axes_.at(1).size || (unsigned)indexes.k() >= (unsigned)axes_.at(2).size || (unsigned)indexes.l() >= (unsigned)axes_.at(3).size)) return AMNumber::OutOfBoundsError; #endif int flatIndex = indexes.l(); int stride = axes_.at(3).size; flatIndex += indexes.k()*stride; stride *= axes_.at(2).size; flatIndex += indexes.j()*stride; stride *= axes_.at(1).size; flatIndex += indexes.i(); return values_.at(flatIndex); } case 5: { #ifdef AM_ENABLE_BOUNDS_CHECKING if(((unsigned)indexes.i() >= (unsigned)axes_.at(0).size || (unsigned)indexes.j() >= (unsigned)axes_.at(1).size || (unsigned)indexes.k() >= (unsigned)axes_.at(2).size || (unsigned)indexes.l() >= (unsigned)axes_.at(3).size || (unsigned)indexes.m() >= (unsigned)axes_.at(4).size)) return AMNumber::OutOfBoundsError; #endif int flatIndex = indexes.m(); int stride = axes_.at(4).size; flatIndex += indexes.l()*stride; stride *= axes_.at(3).size; flatIndex += indexes.k()*stride; stride *= axes_.at(2).size; flatIndex += indexes.j()*stride; stride *= axes_.at(1).size; flatIndex += indexes.i()*stride; return values_.at(flatIndex); } default: return AMNumber::InvalidError; } }