Coverage Report

Created: 2023-05-28 06:42

/src/netcdf-c/libnczarr/zodom.c
Line
Count
Source (jump to first uncovered line)
1
/*********************************************************************
2
 *   Copyright 2018, UCAR/Unidata
3
 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4
 *********************************************************************/
5
#include "zincludes.h"
6
7
/*Forward*/
8
static int buildodom(int rank, NCZOdometer** odomp);
9
10
void
11
nczodom_reset(NCZOdometer* odom)
12
0
{
13
0
    int r;
14
0
    for(r=0;r<odom->rank;r++)
15
0
        odom->index[r] = odom->start[r];
16
0
}
17
18
NCZOdometer*
19
nczodom_new(int rank, const size64_t* start, const size64_t* stop, const size64_t* stride, const size64_t* len)
20
0
{
21
0
    int i;
22
0
    NCZOdometer* odom = NULL;
23
0
    if(buildodom(rank,&odom)) return NULL;
24
0
    odom->properties.stride1 = 1; /* assume */
25
0
    odom->properties.start0 = 1; /* assume */
26
0
    for(i=0;i<rank;i++) { 
27
0
  odom->start[i] = (size64_t)start[i];
28
0
  odom->stop[i] = (size64_t)stop[i];
29
0
  odom->stride[i] = (size64_t)stride[i];
30
0
  odom->len[i] = (size64_t)len[i];
31
0
  if(odom->start[i] != 0) odom->properties.start0 = 0;
32
0
  if(odom->stride[i] != 1) odom->properties.stride1 = 0;
33
0
    }
34
0
    nczodom_reset(odom);
35
0
    for(i=0;i<rank;i++)
36
0
        assert(stop[i] >= start[i] && stride[i] > 0 && (len[i]+1) >= stop[i]);
37
0
    return odom;
38
0
}
39
40
NCZOdometer*
41
nczodom_fromslices(int rank, const NCZSlice* slices)
42
0
{
43
0
    size_t i;
44
0
    NCZOdometer* odom = NULL;
45
46
0
    if(buildodom(rank,&odom)) return NULL;
47
0
    odom->properties.stride1 = 1; /* assume */
48
0
    odom->properties.start0 = 1; /* assume */
49
0
    for(i=0;i<rank;i++) {    
50
0
  odom->start[i] = slices[i].start;
51
0
  odom->stop[i] = slices[i].stop;
52
0
  odom->stride[i] = slices[i].stride;
53
0
  odom->len[i] = slices[i].len;
54
0
  if(odom->start[i] != 0) odom->properties.start0 = 0;
55
0
  if(odom->stride[i] != 1) odom->properties.stride1 = 0;
56
0
    }
57
0
    nczodom_reset(odom);
58
0
    for(i=0;i<rank;i++) {
59
0
        assert(slices[i].stop >= slices[i].start && slices[i].stride > 0);
60
0
        assert((slices[i].stop - slices[i].start) <= slices[i].len);
61
0
    }
62
0
    return odom;
63
0
}
64
  
65
void
66
nczodom_free(NCZOdometer* odom)
67
0
{
68
0
    if(odom == NULL) return;
69
0
    nullfree(odom->start);
70
0
    nullfree(odom->stop);
71
0
    nullfree(odom->stride);
72
0
    nullfree(odom->len);
73
0
    nullfree(odom->index);
74
0
    nullfree(odom);
75
0
}
76
77
int
78
nczodom_more(const NCZOdometer* odom)
79
0
{
80
0
    return (odom->index[0] < odom->stop[0]);
81
0
}
82
83
void
84
nczodom_next(NCZOdometer* odom)
85
0
{
86
0
    int i;
87
0
    int rank;
88
0
    rank = odom->rank;
89
0
    for(i=rank-1;i>=0;i--) {
90
0
  odom->index[i] += odom->stride[i];
91
0
        if(odom->index[i] < odom->stop[i]) break;
92
0
        if(i == 0) goto done; /* leave the 0th entry if it overflows */
93
0
        odom->index[i] = odom->start[i]; /* reset this position */
94
0
    }
95
0
done:
96
0
    return;
97
0
}
98
  
99
/* Get the value of the odometer */
100
size64_t*
101
nczodom_indices(const NCZOdometer* odom)
102
0
{
103
0
    return odom->index;
104
0
}
105
106
size64_t
107
nczodom_offset(const NCZOdometer* odom)
108
0
{
109
0
    int i;
110
0
    size64_t offset;
111
0
    int rank = odom->rank;
112
113
0
    offset = 0;
114
0
    for(i=0;i<rank;i++) {
115
0
#if 1
116
0
        offset *= odom->len[i];
117
#else
118
        offset *= odom->stop[i];
119
#endif
120
0
        offset += odom->index[i];
121
0
    } 
122
0
    return offset;
123
0
}
124
125
static int
126
buildodom(int rank, NCZOdometer** odomp)
127
0
{
128
0
    int stat = NC_NOERR;
129
0
    NCZOdometer* odom = NULL;
130
0
    if(odomp) {
131
0
        if((odom = calloc(1,sizeof(NCZOdometer))) == NULL)
132
0
      goto done;   
133
0
        odom->rank = rank;
134
0
        if((odom->start=malloc(sizeof(size64_t)*rank))==NULL) goto nomem;
135
0
        if((odom->stop=malloc(sizeof(size64_t)*rank))==NULL) goto nomem;
136
0
        if((odom->stride=malloc(sizeof(size64_t)*rank))==NULL) goto nomem;
137
0
        if((odom->len=malloc(sizeof(size64_t)*rank))==NULL) goto nomem;
138
0
        if((odom->index=malloc(sizeof(size64_t)*rank))==NULL) goto nomem;
139
0
        *odomp = odom; odom = NULL;
140
0
    }
141
0
done:
142
0
    nczodom_free(odom);
143
0
    return stat;
144
0
nomem:
145
0
    stat = NC_ENOMEM;
146
0
    goto done;
147
0
}
148
149
/* Compute the total avail in last position */
150
size64_t
151
nczodom_avail(const NCZOdometer* odom)
152
0
{
153
0
    size64_t avail;
154
    /* The best we can do is compute the count for the rightmost index */
155
0
    avail = (odom->stop[odom->rank-1] - odom->start[odom->rank-1]);
156
0
    return avail;
157
0
}
158
159
/*
160
Incr the odometer by nczodom_avail() values.
161
Calling nczodom_next at that point should properly increment
162
rest of the odometer.
163
*/
164
void
165
nczodom_skipavail(NCZOdometer* odom)
166
0
{
167
0
    if(odom->rank > 0)
168
0
        odom->index[odom->rank-1] = odom->stop[odom->rank-1];
169
0
}
170
171
#if 0
172
size64_t
173
nczodom_laststride(const NCZOdometer* odom)
174
{
175
    assert(odom != NULL && odom->rank > 0);
176
    return odom->stride[odom->rank-1];
177
}
178
179
size64_t
180
nczodom_lastlen(const NCZOdometer* odom)
181
{
182
    assert(odom != NULL && odom->rank > 0);
183
    return odom->len[odom->rank-1];
184
}
185
#endif