Coverage Report

Created: 2023-05-28 06:42

/src/netcdf-c/libnczarr/zclose.c
Line
Count
Source (jump to first uncovered line)
1
/*********************************************************************
2
 *   Copyright 1993, UCAR/Unidata
3
 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4
 *********************************************************************/
5
6
#include "zincludes.h"
7
#include "zfilter.h"
8
9
/* Forward */
10
static int zclose_group(NC_GRP_INFO_T*);
11
static int zclose_gatts(NC_GRP_INFO_T*);
12
static int zclose_vars(NC_GRP_INFO_T*);
13
static int zclose_dims(NC_GRP_INFO_T*);
14
static int zclose_types(NC_GRP_INFO_T*);
15
static int zclose_type(NC_TYPE_INFO_T* type);
16
static int zwrite_vars(NC_GRP_INFO_T *grp);
17
18
/**************************************************/
19
20
/**
21
 * @internal This function will recurse through an open ZARR file and
22
 * release resources. All ZARR annotations reclaimed
23
 *
24
 * @param file Pointer to ZARR file info struct.
25
 * @param abort True if this is an abort.
26
 *
27
 * @return ::NC_NOERR No error.
28
 * @return ::NC_ENCZARR could not close the file.
29
 * @author Dennis Heimbigner
30
 */
31
int
32
ncz_close_file(NC_FILE_INFO_T* file, int abort)
33
0
{
34
0
    int stat = NC_NOERR;
35
0
    NCZ_FILE_INFO_T* zinfo = NULL;
36
 
37
0
    ZTRACE(2,"file=%s abort=%d",file->hdr.name,abort);
38
39
0
    if(!abort) {
40
        /* Flush | create all chunks for all vars */
41
0
        if((stat=zwrite_vars(file->root_grp))) goto done;
42
0
    }
43
44
    /* Internal close to reclaim zarr annotations */
45
0
    if((stat = zclose_group(file->root_grp)))
46
0
  goto done;
47
48
0
    zinfo = file->format_file_info;
49
50
0
    if((stat = nczmap_close(zinfo->map,(abort && zinfo->created)?1:0)))
51
0
  goto done;
52
0
    NCZ_freestringvec(0,zinfo->envv_controls);
53
0
    NC_authfree(zinfo->auth);
54
0
    nullfree(zinfo);
55
56
0
done:
57
0
    return ZUNTRACE(stat);
58
0
}
59
60
/**************************************************/
61
/**
62
 * @internal Recursively free zarr annotations for a group (and everything
63
 * it contains).
64
 *
65
 * @param grp Pointer to group info struct.
66
 *
67
 * @return ::NC_NOERR No error.
68
 * @author Dennis Heimbigner
69
 */
70
static int
71
zclose_group(NC_GRP_INFO_T *grp)
72
0
{
73
0
    int stat = NC_NOERR;
74
0
    NCZ_GRP_INFO_T* zgrp;
75
0
    int i;
76
77
0
    assert(grp && grp->format_grp_info != NULL);
78
0
    LOG((3, "%s: grp->name %s", __func__, grp->hdr.name));
79
80
    /* Recursively call this function for each child, if any, stopping
81
     * if there is an error. */
82
0
    for(i=0; i<ncindexsize(grp->children); i++) {
83
0
        if ((stat = zclose_group((NC_GRP_INFO_T*)ncindexith(grp->children,i))))
84
0
            goto done;
85
0
    }
86
87
    /* Close resources associated with global attributes. */
88
0
    if ((stat = zclose_gatts(grp)))
89
0
        goto done;
90
91
    /* Close resources associated with vars. */
92
0
    if ((stat = zclose_vars(grp)))
93
0
        goto done;
94
95
    /* Close resources associated with dims. */
96
0
    if ((stat = zclose_dims(grp)))
97
0
        goto done;
98
99
    /* Close resources associated with types. */
100
0
    if ((stat = zclose_types(grp)))
101
0
        goto done;
102
103
    /* Close the zgroup. */
104
0
    zgrp = grp->format_grp_info;
105
0
    LOG((4, "%s: closing group %s", __func__, grp->hdr.name));
106
0
    nullfree(zgrp);
107
0
    grp->format_grp_info = NULL; /* avoid memory errors */
108
109
0
done:
110
0
    return stat;
111
0
}
112
113
/**
114
 * @internal Close resources for global atts in a group.
115
 *
116
 * @param grp Pointer to group info struct.
117
 *
118
 * @return ::NC_NOERR No error.
119
 * @author Dennis Heimbigner
120
 */
121
static int
122
zclose_gatts(NC_GRP_INFO_T* grp)
123
0
{
124
0
    int stat = NC_NOERR;
125
0
    NC_ATT_INFO_T *att;
126
0
    int a;
127
0
    for(a = 0; a < ncindexsize(grp->att); a++) {
128
0
        NCZ_ATT_INFO_T* zatt = NULL;
129
0
        att = (NC_ATT_INFO_T* )ncindexith(grp->att, a);
130
0
        assert(att && att->format_att_info != NULL);
131
0
        zatt = att->format_att_info;
132
0
  nullfree(zatt);
133
0
        att->format_att_info = NULL; /* avoid memory errors */
134
0
    }
135
0
    return stat;
136
0
}
137
138
/**
139
 * @internal Close resources for vars in a group.
140
 *
141
 * @param grp Pointer to group info struct.
142
 *
143
 * @return ::NC_NOERR No error.
144
 * @author Dennis Heimbigner
145
 */
146
static int
147
zclose_vars(NC_GRP_INFO_T* grp)
148
0
{
149
0
    int stat = NC_NOERR;
150
0
    NC_VAR_INFO_T* var;
151
0
    NCZ_VAR_INFO_T* zvar;
152
0
    NC_ATT_INFO_T* att;
153
0
    int a, i;
154
155
0
    for(i = 0; i < ncindexsize(grp->vars); i++) {
156
0
        var = (NC_VAR_INFO_T*)ncindexith(grp->vars, i);
157
0
        assert(var && var->format_var_info);
158
0
        zvar = var->format_var_info;;
159
0
        for(a = 0; a < ncindexsize(var->att); a++) {
160
0
            NCZ_ATT_INFO_T* zatt;
161
0
            att = (NC_ATT_INFO_T*)ncindexith(var->att, a);
162
0
            assert(att && att->format_att_info);
163
0
            zatt = att->format_att_info;
164
0
      nullfree(zatt);
165
0
      att->format_att_info = NULL; /* avoid memory errors */
166
0
        }
167
0
#ifdef ENABLE_NCZARR_FILTERS
168
  /* Reclaim filters */
169
0
  if(var->filters != NULL) {
170
0
      (void)NCZ_filter_freelists(var);
171
0
  }
172
0
  var->filters = NULL;
173
0
#endif
174
  /* Reclaim the type */
175
0
  if(var->type_info) (void)zclose_type(var->type_info);
176
0
        if(zvar->cache) NCZ_free_chunk_cache(zvar->cache);
177
  /* reclaim xarray */
178
0
  if(zvar->xarray) nclistfreeall(zvar->xarray);
179
0
  nullfree(zvar);
180
0
  var->format_var_info = NULL; /* avoid memory errors */
181
0
    }
182
0
    return stat;
183
0
}
184
185
/**
186
 * @internal Close resources for dims in a group.
187
 *
188
 * @param grp Pointer to group info struct.
189
 *
190
 * @return ::NC_NOERR No error.
191
 * @author Dennis Heimbigner
192
 */
193
static int
194
zclose_dims(NC_GRP_INFO_T* grp)
195
0
{
196
0
    int stat = NC_NOERR;
197
0
    NC_DIM_INFO_T* dim;
198
0
    int i;
199
200
0
    for(i = 0; i < ncindexsize(grp->dim); i++) {
201
0
        NCZ_DIM_INFO_T* zdim;
202
0
        dim = (NC_DIM_INFO_T*)ncindexith(grp->dim, i);
203
0
        assert(dim && dim->format_dim_info);
204
0
        zdim = dim->format_dim_info;
205
0
  nullfree(zdim);
206
0
  dim->format_dim_info = NULL; /* avoid memory errors */
207
0
    }
208
209
0
    return stat;
210
0
}
211
212
/**
213
 * @internal Close resources for a single type.  Set values to
214
 * 0 after closing types. Because of type reference counters, these
215
 * closes can be called multiple times.
216
 *
217
 * @param type Pointer to type struct.
218
 *
219
 * @return ::NC_NOERR No error.
220
 * @author Dennis Heimbigner
221
 */
222
static int
223
zclose_type(NC_TYPE_INFO_T* type)
224
0
{
225
0
    int stat = NC_NOERR;
226
227
0
    assert(type && type->format_type_info != NULL);
228
0
    nullfree(type->format_type_info);
229
0
    return stat;
230
0
}
231
232
/**
233
 * @internal Close resources for types in a group.  Set values to
234
 * 0 after closing types. Because of type reference counters, these
235
 * closes can be called multiple times.
236
 * Warning: note that atomic types are not covered here; this
237
 * is only for user-defined types.
238
 *
239
 * @param grp Pointer to group info struct.
240
 *
241
 * @return ::NC_NOERR No error.
242
 * @author Dennis Heimbigner
243
 */
244
static int
245
zclose_types(NC_GRP_INFO_T* grp)
246
0
{
247
0
    int stat = NC_NOERR;
248
0
    int i;
249
0
    NC_TYPE_INFO_T* type;
250
251
0
    for(i = 0; i < ncindexsize(grp->type); i++)
252
0
    {
253
0
        type = (NC_TYPE_INFO_T*)ncindexith(grp->type, i);
254
0
  if((stat = zclose_type(type))) goto done;
255
0
    }
256
0
done:
257
0
    return stat;
258
0
}
259
260
/**
261
 * @internal Recursively flush/create all data for all vars.
262
 *
263
 * @param grp Pointer to group info struct whose vars need to be written
264
 *
265
 * @return ::NC_NOERR No error.
266
 * @author Dennis Heimbigner
267
 */
268
static int
269
zwrite_vars(NC_GRP_INFO_T *grp)
270
0
{
271
0
    int stat = NC_NOERR;
272
0
    int i;
273
274
0
    assert(grp && grp->format_grp_info != NULL);
275
0
    LOG((3, "%s: grp->name %s", __func__, grp->hdr.name));
276
277
    /* Write all vars for this group breadth first */
278
0
    for(i = 0; i < ncindexsize(grp->vars); i++) {
279
0
        NC_VAR_INFO_T* var = (NC_VAR_INFO_T*)ncindexith(grp->vars, i);
280
0
  if((stat = ncz_write_var(var))) goto done;
281
0
    }
282
283
    /* Recursively call this function for each child group, if any, stopping
284
     * if there is an error. */
285
0
    for(i=0; i<ncindexsize(grp->children); i++) {
286
0
        if ((stat = zwrite_vars((NC_GRP_INFO_T*)ncindexith(grp->children,i))))
287
0
            goto done;
288
0
    }
289
290
0
done:
291
0
    return stat;
292
0
}
293
294