/********************************************************************* * 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;irank;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;irank;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;irank;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;irank;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;ideclsize; } 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;ilength/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;irank;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;irank;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;islices[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; }