Coverage Report

Created: 2026-07-16 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/netcdf-c/libnczarr/zarr.c
Line
Count
Source
1
/*********************************************************************
2
 *   Copyright 2018, UCAR/Unidata
3
 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4
 *********************************************************************/
5
6
#include "zincludes.h"
7
#include <stddef.h>
8
9
/**************************************************/
10
/* Forwards */
11
12
static int applycontrols(NCZ_FILE_INFO_T* zinfo);
13
14
/***************************************************/
15
/* API */
16
17
/**
18
@internal Create the topmost dataset object and setup up
19
          NCZ_FILE_INFO_T state.
20
@param zinfo - [in] the internal state
21
@return NC_NOERR
22
@author Dennis Heimbigner
23
*/
24
25
int
26
ncz_create_dataset(NC_FILE_INFO_T* file, NC_GRP_INFO_T* root, NClist* controls)
27
0
{
28
0
    int stat = NC_NOERR;
29
0
    NCZ_FILE_INFO_T* zinfo = NULL;
30
0
    NCZ_GRP_INFO_T* zgrp = NULL;
31
0
    NCURI* uri = NULL;
32
0
    NC* nc = NULL;
33
0
    NCjson* json = NULL;
34
0
    char* key = NULL;
35
36
0
    ZTRACE(3,"file=%s root=%s controls=%s",file->hdr.name,root->hdr.name,(controls?nczprint_envv(controls):"null"));
37
38
0
    nc = (NC*)file->controller;
39
40
    /* Add struct to hold NCZ-specific file metadata. */
41
0
    if (!(zinfo = calloc(1, sizeof(NCZ_FILE_INFO_T))))
42
0
        {stat = NC_ENOMEM; goto done;}
43
0
    file->format_file_info = zinfo;
44
0
    zinfo->common.file = file;
45
46
    /* Add struct to hold NCZ-specific group info. */
47
0
    if (!(zgrp = calloc(1, sizeof(NCZ_GRP_INFO_T))))
48
0
        {stat = NC_ENOMEM; goto done;}
49
0
    root->format_grp_info = zgrp;
50
0
    zgrp->common.file = file;
51
52
    /* Fill in NCZ_FILE_INFO_T */
53
0
    zinfo->creating = 1;
54
0
    zinfo->common.file = file;
55
0
    zinfo->native_endianness = (NC_isLittleEndian() ? NC_ENDIAN_LITTLE : NC_ENDIAN_BIG);
56
0
    if((zinfo->controllist=nclistclone(controls,1)) == NULL)
57
0
  {stat = NC_ENOMEM; goto done;}
58
59
    /* fill in some of the zinfo and zroot fields */
60
0
    zinfo->zarr.zarr_version = atoi(ZARRVERSION);
61
0
    sscanf(NCZARRVERSION,"%lu.%lu.%lu",
62
0
     &zinfo->zarr.nczarr_version.major,
63
0
     &zinfo->zarr.nczarr_version.minor,
64
0
     &zinfo->zarr.nczarr_version.release);
65
66
0
    zinfo->default_maxstrlen = NCZ_MAXSTR_DEFAULT;
67
68
    /* Apply client controls */
69
0
    if((stat = applycontrols(zinfo))) goto done;
70
71
    /* Load auth info from rc file */
72
0
    if((stat = ncuriparse(nc->path,&uri))) goto done;
73
0
    if(uri) {
74
0
  if((stat = NC_authsetup(&zinfo->auth, uri)))
75
0
      goto done;
76
0
    }
77
78
    /* initialize map handle*/
79
0
    if((stat = NCZ_get_map(file,uri,nc->mode,zinfo->controls.flags,NULL,&zinfo->map))){
80
0
        goto done;
81
0
    }
82
83
0
    if((stat = NCZMD_set_metadata_handler(zinfo))){
84
0
        goto done;
85
0
    }
86
87
0
done:
88
0
    ncurifree(uri);
89
0
    NCJreclaim(json);
90
0
    nullfree(key);
91
0
    return ZUNTRACE(stat);
92
0
}
93
94
/**
95
@internal Open the topmost dataset object.
96
@param file - [in] the file struct
97
@param controls - [in] the fragment list in envv form from uri
98
@return NC_NOERR
99
@author Dennis Heimbigner
100
*/
101
102
int
103
ncz_open_dataset(NC_FILE_INFO_T* file, NClist* controls)
104
0
{
105
0
    int stat = NC_NOERR;
106
0
    NC* nc = NULL;
107
0
    NC_GRP_INFO_T* root = NULL;
108
0
    NCURI* uri = NULL;
109
0
    void* content = NULL;
110
0
    NCjson* json = NULL;
111
0
    NCZ_FILE_INFO_T* zinfo = NULL;
112
0
    int mode;
113
0
    NClist* modeargs = NULL;
114
0
    char* nczarr_version = NULL;
115
0
    char* zarr_format = NULL;
116
117
0
    ZTRACE(3,"file=%s controls=%s",file->hdr.name,(controls?nczprint_envv(controls):"null"));
118
119
    /* Extract info reachable via file */
120
0
    nc = (NC*)file->controller;
121
0
    mode = nc->mode;
122
123
0
    root = file->root_grp;
124
0
    assert(root != NULL && root->hdr.sort == NCGRP);
125
126
    /* Add struct to hold NCZ-specific file metadata. */
127
0
    if (!(file->format_file_info = calloc(1, sizeof(NCZ_FILE_INFO_T))))
128
0
        {stat = NC_ENOMEM; goto done;}
129
0
    zinfo = file->format_file_info;
130
131
    /* Fill in NCZ_FILE_INFO_T */
132
0
    zinfo->creating = 0;
133
0
    zinfo->common.file = file;
134
0
    zinfo->native_endianness = (NC_isLittleEndian() ? NC_ENDIAN_LITTLE : NC_ENDIAN_BIG);
135
0
    if((zinfo->controllist=nclistclone(controls,1)) == NULL)
136
0
  {stat = NC_ENOMEM; goto done;}
137
0
    zinfo->default_maxstrlen = NCZ_MAXSTR_DEFAULT;
138
139
    /* Add struct to hold NCZ-specific group info. */
140
0
    if (!(root->format_grp_info = calloc(1, sizeof(NCZ_GRP_INFO_T))))
141
0
        {stat = NC_ENOMEM; goto done;}
142
0
    ((NCZ_GRP_INFO_T*)root->format_grp_info)->common.file = file;
143
144
    /* Apply client controls */
145
0
    if((stat = applycontrols(zinfo))) goto done;
146
147
    /* Load auth info from rc file */
148
0
    if((stat = ncuriparse(nc->path,&uri))) goto done;
149
0
    if(uri) {
150
0
  if((stat = NC_authsetup(&zinfo->auth, uri)))
151
0
      goto done;
152
0
    }
153
154
    /* initialize map handle*/
155
0
    if((stat = NCZ_get_map(file, uri, mode, zinfo->controls.flags,NULL,&zinfo->map))){
156
0
      goto done;
157
0
    }
158
159
    /* Determine zarr format of existing dataset */
160
0
    if((stat = NCZ_infer_zarr_format(file))) {
161
0
        goto done;
162
0
    }
163
164
0
    if((stat = NCZMD_set_metadata_handler(zinfo))) {
165
0
        goto done;
166
0
    }
167
168
0
    if((stat = NCZ_infer_nczarr_format(file))) {
169
0
        goto done;
170
0
    }
171
172
0
done:
173
0
    nullfree(zarr_format);
174
0
    nullfree(nczarr_version);
175
0
    ncurifree(uri);
176
0
    nclistfreeall(modeargs);
177
0
    if(json) NCJreclaim(json);
178
0
    nullfree(content);
179
0
    return ZUNTRACE(stat);
180
0
}
181
182
/**
183
 * @internal Determine whether file is netCDF-4.
184
 *
185
 * For libzarr, this is always true.
186
 *
187
 * @param h5 Pointer to HDF5 file info struct.
188
 *
189
 * @returns NC_NOERR No error.
190
 * @author Dennis Heimbigner.
191
 */
192
int
193
NCZ_isnetcdf4(struct NC_FILE_INFO* h5)
194
0
{
195
0
    int isnc4 = 1;
196
0
    NC_UNUSED(h5);
197
0
    return isnc4;
198
0
}
199
200
/**
201
 * @internal Determine version info
202
 *
203
 * For libzarr, this is not well defined
204
 *
205
 * @param majorp Pointer to major version number
206
 * @param minorp Pointer to minor version number
207
 * @param releasep Pointer to release version number
208
 *
209
 * @returns NC_NOERR No error.
210
 * @author Dennis Heimbigner.
211
 */
212
int
213
NCZ_get_libversion(unsigned long* majorp, unsigned long* minorp,unsigned long* releasep)
214
1
{
215
1
    unsigned long m0,m1,m2;
216
1
    sscanf(NCZARRVERSION,"%lu.%lu.%lu",&m0,&m1,&m2);
217
1
    if(majorp) *majorp = m0;
218
1
    if(minorp) *minorp = m1;
219
1
    if(releasep) *releasep = m2;
220
1
    return NC_NOERR;
221
1
}
222
223
/**
224
 * @internal Determine "superblock" number.
225
 *
226
 * For libzarr, use the value of the major part of the nczarr version.
227
 *
228
 * @param superblocp Pointer to place to return superblock.
229
 * use the nczarr format version major as the superblock number.
230
 *
231
 * @returns NC_NOERR No error.
232
 * @author Dennis Heimbigner.
233
 */
234
int
235
NCZ_get_superblock(NC_FILE_INFO_T* file, int* superblockp)
236
0
{
237
0
    NCZ_FILE_INFO_T* zinfo = file->format_file_info;
238
0
    if(superblockp) *superblockp = zinfo->zarr.nczarr_version.major;
239
0
    return NC_NOERR;
240
0
}
241
242
/**************************************************/
243
/* Utilities */
244
245
static const char*
246
controllookup(NClist* controls, const char* key)
247
0
{
248
0
    size_t i;
249
0
    for(i=0;i<nclistlength(controls);i+=2) {
250
0
        const char* p = (char*)nclistget(controls,i);
251
0
  if(strcasecmp(key,p)==0) {
252
0
      return (const char*)nclistget(controls,i+1);
253
0
  }
254
0
    }
255
0
    return NULL;
256
0
}
257
258
259
static int
260
applycontrols(NCZ_FILE_INFO_T* zinfo)
261
0
{
262
0
    size_t i;
263
0
    int stat = NC_NOERR;
264
0
    const char* value = NULL;
265
0
    NClist* modelist = nclistnew();
266
0
    size64_t noflags = 0; /* track non-default negative flags */
267
268
0
    if((value = controllookup(zinfo->controllist,"mode")) != NULL) {
269
0
  if((stat = NCZ_comma_parse(value,modelist))) goto done;
270
0
    }
271
    /* Process the modelist first */
272
0
    zinfo->controls.mapimpl = NCZM_DEFAULT;
273
0
    zinfo->controls.flags |= FLAG_XARRAYDIMS; /* Always support XArray convention where possible */
274
0
    zinfo->controls.flags |= (NCZARR_CONSOLIDATED_DEFAULT ? FLAG_CONSOLIDATED : 0);
275
0
    for(i=0;i<nclistlength(modelist);i++) {
276
0
        const char* p = nclistget(modelist,i);
277
0
  if(strcasecmp(p,PUREZARRCONTROL)==0)
278
0
      zinfo->controls.flags |= (FLAG_PUREZARR);
279
0
  else if(strcasecmp(p,XARRAYCONTROL)==0)
280
0
      zinfo->controls.flags |= FLAG_PUREZARR;
281
0
  else if(strcasecmp(p,NOXARRAYCONTROL)==0)
282
0
      noflags |= FLAG_XARRAYDIMS;
283
0
  else if(strcasecmp(p,"zip")==0) zinfo->controls.mapimpl = NCZM_ZIP;
284
0
  else if(strcasecmp(p,"file")==0) zinfo->controls.mapimpl = NCZM_FILE;
285
0
  else if(strcasecmp(p,"s3")==0) zinfo->controls.mapimpl = NCZM_S3;
286
0
  else if(strcasecmp(p,"consolidated") == 0)
287
0
          zinfo->controls.flags |= FLAG_CONSOLIDATED;
288
0
    }
289
    /* Apply negative controls by turning off negative flags */
290
    /* This is necessary to avoid order dependence of mode flags when both positive and negative flags are defined */
291
0
    zinfo->controls.flags &= (~noflags);
292
293
    /* Process other controls */
294
0
    if((value = controllookup(zinfo->controllist,"log")) != NULL) {
295
0
  zinfo->controls.flags |= FLAG_LOGGING;
296
0
        ncsetloglevel(NCLOGNOTE);
297
0
    }
298
0
    if((value = controllookup(zinfo->controllist,"show")) != NULL) {
299
0
  if(strcasecmp(value,"fetch")==0)
300
0
      zinfo->controls.flags |= FLAG_SHOWFETCH;
301
0
    }
302
0
done:
303
0
    nclistfreeall(modelist);
304
0
    return stat;
305
0
}