1/*********************************************************************
2 *   Copyright 1993, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *********************************************************************/
5
6#include "ncdap.h"
7#include "dapodom.h"
8
9/**********************************************/
10/* Define methods for a dimension dapodometer*/
11
12/* Build an odometer covering slices startslice upto, but not including, stopslice */
13Dapodometer*
14dapodom_fromsegment(DCEsegmentsegment, size_t startindex, size_t stopindex)
15{
16    int i;
17    Dapodometerodom;
18
19    assert(stopindex > startindex);
20    assert((stopindex - startindex) <= NC_MAX_VAR_DIMS);
21    odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
22    MEMCHECK(odom,NULL);
23    odom->rank = (stopindex - startindex);
24    for(i=0;i<odom->rank;i++) {
25 odom->start[i] = segment->slices[i+startindex].first;
26 odom->stride[i] = segment->slices[i+startindex].stride;
27 odom->stop[i] = (segment->slices[i+startindex].last + 1);
28 /* should the above line be instead?
29  odom->stop[i] = odom->start[i] + (odom->count[i]*odom->stride[i]);
30 */
31#if 0
32 odom->count[i] = segment->slices[i+startindex].count;
33#endif
34 odom->declsize[i] = segment->slices[i+startindex].declsize;
35 odom->index[i] = odom->start[i];
36    }
37    return odom;
38}
39
40Dapodometer*
41dapodom_new(size_t rank,
42     const size_t* start, const size_t* count,
43     const ptrdiff_tstride, const size_t* size)
44{
45    int i;
46    Dapodometerodom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
47    MEMCHECK(odom,NULL);
48    odom->rank = rank;
49    assert(odom->rank <= NC_MAX_VAR_DIMS);
50    for(i=0;i<odom->rank;i++) {
51 size_t istart,icount,istop,ideclsize;
52 ptrdiff_t istride;
53 istart = (start != NULL ? start[i] : 0);
54 icount = (count != NULL ? count[i] : (size != NULL ? size[i] : 1));
55 istride = (size_t)(stride != NULL ? stride[i] : 1);
56 istop = istart + icount*istride;
57 ideclsize = (size != NULL ? size[i]: (istop - istart));
58 odom->start[i] = istart;
59 odom->stop[i] = istop;
60 odom->stride[i] = istride;
61 odom->declsize[i] = ideclsize;
62 odom->index[i] = odom->start[i];
63    }
64    return odom;
65}
66
67void
68dapodom_free(Dapodometerodom)
69{
70    if(odom) free(odom);
71}
72
73#if 0
74char*
75dapodom_print(Dapodometerodom)
76{
77    int i;
78    static char line[1024];
79    char tmp[64];
80    line[0] = '\0';
81    if(odom->rank == 0) {
82 strcat(line,"[]");
83    } else for(i=0;i<odom->rank;i++) {
84 sprintf(tmp,"[%lu/%lu:%lu:%lu]",
85 (size_t)odom->index[i],
86 (size_t)odom->start[i],
87 (size_t)odom->stride[i],
88 (size_t)odom->length[i]);
89 strcat(line,tmp);
90    }
91    return line;
92}
93#endif
94
95int
96dapodom_more(Dapodometerodom)
97{
98    return (odom->index[0] < odom->stop[0]);
99}
100
101/* Convert current dapodometer settings to a single integer count*/
102off_t
103dapodom_count(Dapodometerodom)
104{
105    int i;
106    off_t offset = 0;
107    for(i=0;i<odom->rank;i++) {
108 offset *= odom->declsize[i];
109 offset += odom->index[i];
110    }
111    return offset;
112}
113
114int
115dapodom_next(Dapodometerodom)
116{
117    int i; /* do not make unsigned */
118    if(odom->rank == 0) return 0;
119    for(i=odom->rank-1;i>=0;i--) {
120        odom->index[i] += odom->stride[i];
121        if(odom->index[i] < odom->stop[i]) break;
122 if(i == 0) return 0; /* leave the 0th entry if it overflows*/
123 odom->index[i] = odom->start[i]; /* reset this position*/
124    }
125    return 1;
126}
127
128/**************************************************/
129size_t
130dapodom_varmcount(Dapodometerodom, const ptrdiff_tsteps, const size_t* declsizes)
131{
132    int i;
133    size_t offset = 0;
134    for(i=0;i<odom->rank;i++) {
135 size_t tmp;
136 tmp = odom->index[i];
137 tmp = tmp - odom->start[i];
138 tmp = tmp / odom->stride[i];
139 tmp = tmp * steps[i];
140 offset += tmp;
141    }
142    return offset;
143}
144
145/*
146Given a dapodometer, compute the total
147number of elements in its space.
148*/
149
150#if 0
151off_t
152dapodom_space(Dapodometerodom)
153{
154    size_t i;
155    off_t count = 1;
156    for(i=0;i<odom->rank;i++) {
157 count *= odom->size[i];
158    }
159    return count;
160}
161#endif


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