1/*********************************************************************
2 *   Copyright 2009, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *********************************************************************/
5/* $Id: odom.c,v 1.5 2010/05/27 21:34:18 dmh Exp $ */
6/* $Header: /upc/share/CVS/netcdf-3/ncgen/odom.c,v 1.5 2010/05/27 21:34:18 dmh Exp $ */
7
8#include "includes.h"
9#include "odom.h"
10
11/**************************************************/
12/* Define methods for a dimension odometer*/
13
14Odometer*
15newodometer(Dimsetdimset, size_t* startp, size_t* countp)
16{
17    int i;
18    Odometerodom;
19    ASSERT(dimset != NULL);
20    ASSERT(dimset->ndims > 0);
21    odom = (Odometer*)emalloc(sizeof(Odometer));
22    if(odom == NULL) return NULL;
23    odom->origin = odom;
24    odom->offset = 0;
25    odom->rank = dimset->ndims;
26    ASSERT(odom->rank <= NC_MAX_VAR_DIMS);
27    for(i=0;i<odom->rank;i++) {
28 odom->declsize[i] = dimset->dimsyms[i]->dim.declsize;
29 odom->start[i] = (startp == NULL ? 0
30                                         : startp[i]);
31 odom->count[i] = (countp == NULL ? odom->declsize[i]
32                                         : countp[i]);
33 odom->index[i] = odom->start[i];
34 /* verify */
35 ASSERT(odom->start[i] + odom->count[i] <= odom->declsize[i]);
36    }
37    return odom;
38}
39
40Odometer*
41newsubodometer(OdometeroriginDimsetdimset, int start, int stop)
42{
43    Odometerodom;
44    ASSERT(dimset != NULL);
45    ASSERT(dimset->ndims > 0 && dimset->ndims >= stop);
46    ASSERT(stop > start);
47    odom = (Odometer*)emalloc(sizeof(Odometer));
48    if(odom == NULL) return NULL;
49    odom->origin = origin;
50    odom->offset = start;
51    odom->rank = (stop - start);
52    ASSERT(odom->rank <= NC_MAX_VAR_DIMS);
53    return odom;
54}
55
56void
57odometerfree(Odometerodom)
58{
59    if(odomefree(odom);
60}
61
62char*
63odometerprint(Odometerodom)
64{
65    int i;
66    static char line[1024];
67    char tmp[64];
68    line[0] = '\0';
69    if(odom->origin->rank == 0) {
70 strcat(line,"[]");
71    } else for(i=0;i<odom->rank;i++) {
72 int ioffset = i + odom->offset;
73 sprintf(tmp,"[%lu/%lu..%lu:%lu]",
74 (unsigned long)odom->origin->index[ioffset],
75 (unsigned long)odom->origin->start[ioffset],
76 (unsigned long)odom->origin->declsize[ioffset],
77 (unsigned long)odom->origin->count[ioffset]
78        );
79 strcat(line,tmp);
80    }
81    return line;
82}
83
84int
85odometermore(Odometerodom)
86{
87    size_t index,start,count;
88    int offset = odom->offset;
89    ASSERT(odom->rank > 0);
90    index = odom->origin->index[offset];
91    start = odom->origin->start[offset];
92    count = odom->origin->count[offset];
93    if(index < start + count) return 1;
94    /* reset the zero'th wheel before returning */
95    odom->origin->index[offset] = odom->origin->start[offset];
96    return 0;
97}
98
99int
100odometerincr(Odometerodom)
101{
102    int i;
103    int last = odom->rank-1;
104    ASSERT(odom->rank > 0);
105    for(i=last;i>=0;i--) {
106 int ioffset = i+odom->offset;
107        odom->origin->index[ioffset]++;
108 if(odom->origin->index[ioffset]
109           < (odom->origin->start[ioffset]
110              +odom->origin->count[ioffset]))
111     break;
112 if(i==0) break; /* leave 0'th for next more() check */
113 odom->origin->index[ioffset] = odom->origin->start[ioffset];
114    }
115    return i; /* return rightmost incremented */
116}
117
118
119/*
120Suppose we have the declaration int F[2][5][3];
121There are obviously a total of 2 X 5 X 3 = 30 integers in F.
122Thus, these three dimensions will be reduced to a single
123dimension of size 30 (0..29).
124A particular point in the three dimensions, say [x][y][z], is reduced to
125a number in the range 0..29 by computing ((x*5)+y)*3+z
126So, given an odometer in some state, it computes the offset
127for that odometer's state.
128*/
129
130size_t
131odometeroffset(Odometerodom)
132{
133    int i;
134    size_t count = 0;
135    for(i=0;i<odom->rank;i++) {
136 int ioffset = i+odom->offset;
137 if(i > 0) count *= odom->origin->declsize[ioffset];
138 count += odom->origin->index[ioffset];
139    }
140    return count;
141}
142
143/*
144Get the start vector
145from the odometer
146*/
147size_t*
148odometerstartvector(Odometerodom)
149{
150    return odom->start;
151}
152
153/*
154Get the count vector
155from the odometer
156*/
157size_t*
158odometercountvector(Odometerodom)
159{
160    return odom->count;
161}
162


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed