netcdf-c/libdap2/dapodom.c
2012-04-01 20:15:06 +00:00

253 lines
6.2 KiB
C

/*********************************************************************
* Copyright 1993, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
* $Header: /upc/share/CVS/netcdf-3/libncdap3/dapodom.c,v 1.12 2010/05/27 21:34:08 dmh Exp $
*********************************************************************/
#include "ncdap3.h"
#include "dapodom.h"
/**********************************************/
/* Define methods for a dimension dapodometer*/
Dapodometer*
newdapodometer(DCEslice* slices, unsigned int first, unsigned int rank)
{
int i;
Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
MEMCHECK(odom,NULL);
if(rank == 0) {
return newdapodometer1(1);
}
odom->rank = rank;
ASSERT(odom->rank <= NC_MAX_VAR_DIMS);
for(i=0;i<odom->rank;i++) {
DCEslice* slice = slices+(first+i);
odom->slices[i] = *slice;
odom->index[i] = odom->slices[i].first;
}
return odom;
}
Dapodometer*
newsimpledapodometer(DCEsegment* segment, unsigned int rank)
{
int i;
Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
MEMCHECK(odom,NULL);
if(rank == 0) {
return newdapodometer1(1);
}
odom->rank = rank;
assert(odom->rank <= NC_MAX_VAR_DIMS);
assert(segment->slicesdefined && segment->slicesdeclized);
for(i=0;i<odom->rank;i++) {
DCEslice* odslice = &odom->slices[i];
DCEslice* segslice = &segment->slices[i];
odslice->first = 0;
odslice->stride = 1;
odslice->declsize = segslice->count;
odslice->length = odslice->declsize;
odslice->stop = odslice->declsize;
odslice->count = odslice->declsize;
odom->index[i] = 0;
}
return odom;
}
Dapodometer*
newdapodometer1(unsigned int count)
{
Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
MEMCHECK(odom,NULL);
odom->rank = 1;
odom->slices[0].first = 0;
odom->slices[0].length = count;
odom->slices[0].stride = 1;
odom->slices[0].stop = count;
odom->slices[0].declsize = count;
odom->slices[0].count = count;
odom->index[0] = 0;
return odom;
}
void
freedapodometer(Dapodometer* odom)
{
if(odom) free(odom);
}
char*
dapodometerprint(Dapodometer* odom)
{
int i;
static char line[1024];
char tmp[64];
line[0] = '\0';
if(odom->rank == 0) {
strcat(line,"[]");
} else for(i=0;i<odom->rank;i++) {
sprintf(tmp,"[%lu/%lu:%lu:%lu]",
(unsigned long)odom->index[i],
(unsigned long)odom->slices[i].first,
(unsigned long)odom->slices[i].stride,
(unsigned long)odom->slices[i].length);
strcat(line,tmp);
}
return line;
}
int
dapodometermore(Dapodometer* odom)
{
return (odom->index[0] < odom->slices[0].stop);
}
void
dapodometerreset(Dapodometer* odom)
{
int rank = odom->rank;
while(rank-- > 0) {odom->index[rank] = odom->slices[rank].first;}
}
/* Convert current dapodometer settings to a single integer count*/
size_t
dapodometercount(Dapodometer* odom)
{
int i;
size_t offset = 0;
for(i=0;i<odom->rank;i++) {
offset *= odom->slices[i].declsize;
offset += odom->index[i];
}
return offset;
}
/*
Given a dapodometer, compute the total
number of elements in its space
as determined by declsize; start at
offset wheel
*/
size_t
dapodometerspace(Dapodometer* odom, unsigned int wheel)
{
unsigned int i,rank = odom->rank;
size_t count = 1;
DCEslice* slice;
ASSERT((wheel < rank));
slice = odom->slices+wheel;
for(i=wheel;i<rank;i++,slice++) {
count *= slice->declsize;
}
return count;
}
/*
Compute the number of elements
that will be returned as the odometer
is incremented to its stop point.
*/
size_t
dapodometerpoints(Dapodometer* odom)
{
unsigned int i,rank = odom->rank;
size_t count = 1;
DCEslice* slice = odom->slices;
for(i=0;i<rank;i++,slice++) {
size_t slicecount = (slice->length/slice->stride);
count *= slicecount;
}
return count;
}
int
dapodometerincr(Dapodometer* odom)
{
return dapodometerincrith(odom,-1);
}
int
dapodometerincrith(Dapodometer* odom, int wheel)
{
int i; /* do not make unsigned */
DCEslice* slice;
if(odom->rank == 0) return 0;
if(wheel < 0) wheel = (odom->rank - 1);
for(slice=odom->slices+(wheel),i=wheel;i>=0;i--,slice--) {
odom->index[i] += slice->stride;
if(odom->index[i] < slice->stop) break;
if(i == 0) return 0; /* leave the 0th entry if it overflows*/
odom->index[i] = slice->first; /* reset this position*/
}
return 1;
}
/**************************************************/
int
dapodometervarmcount(Dapodometer* odom, const ptrdiff_t* steps, const size_t* declsizes)
{
int i;
size_t offset = 0;
for(i=0;i<odom->rank;i++) {
size_t tmp;
tmp = odom->index[i];
tmp = tmp - odom->slices[i].first;
tmp = tmp / odom->slices[i].stride;
tmp = tmp * steps[i];
offset += tmp;
}
return offset;
}
/* Return the current set of indices */
size_t*
dapodometerindices(Dapodometer* odom)
{
if(odom == NULL) return NULL;
return odom->index;
}
Dapodometer*
newdapodometer2(const size_t* start, const size_t* count, const ptrdiff_t* stride,
unsigned int first, unsigned int rank)
{
int i;
Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
MEMCHECK(odom,NULL);
odom->rank = rank;
assert(odom->rank <= NC_MAX_VAR_DIMS);
for(i=0;i<odom->rank;i++) {
odom->slices[i].first = start[first+i];
odom->slices[i].stride = (size_t)stride[first+i];
odom->slices[i].length = count[first+i] * stride[first+i];
odom->slices[i].stop = (odom->slices[i].first+odom->slices[i].length);
odom->slices[i].declsize = odom->slices[i].stop;
odom->slices[i].count = (odom->slices[i].length /odom->slices[i].stride);
odom->index[i] = odom->slices[i].first;
}
return odom;
}
Dapodometer*
newdapodometer3(int rank, size_t* dimsizes)
{
int i;
Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
MEMCHECK(odom,NULL);
odom->rank = rank;
for(i=0;i<rank;i++) {
odom->slices[i].first = 0;
odom->slices[i].length = dimsizes[i];
odom->slices[i].stride = 1;
odom->slices[i].stop = dimsizes[i];
odom->slices[i].declsize = dimsizes[i];
odom->slices[i].count = (odom->slices[i].length / odom->slices[i].stride);
odom->index[i] = 0;
}
return odom;
}