mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
253 lines
6.2 KiB
C
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;
|
|
}
|