NetCDF 4.9.2
zarr.c
1/*********************************************************************
2 * Copyright 2018, UCAR/Unidata
3 * See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *********************************************************************/
5
6#include "zincludes.h"
7
8/**************************************************/
9/* Forwards */
10
11static int applycontrols(NCZ_FILE_INFO_T* zinfo);
12
13/***************************************************/
14/* API */
15
24int
25ncz_create_dataset(NC_FILE_INFO_T* file, NC_GRP_INFO_T* root, const char** controls)
26{
27 int stat = NC_NOERR;
28 NCZ_FILE_INFO_T* zinfo = NULL;
29 NCZ_GRP_INFO_T* zgrp = NULL;
30 NCURI* uri = NULL;
31 NC* nc = NULL;
32 NCjson* json = NULL;
33 char* key = NULL;
34
35 ZTRACE(3,"file=%s root=%s controls=%s",file->hdr.name,root->hdr.name,(controls?nczprint_envv(controls):"null"));
36
37 nc = (NC*)file->controller;
38
39 /* Add struct to hold NCZ-specific file metadata. */
40 if (!(zinfo = calloc(1, sizeof(NCZ_FILE_INFO_T))))
41 {stat = NC_ENOMEM; goto done;}
42 file->format_file_info = zinfo;
43 zinfo->common.file = file;
44
45 /* Add struct to hold NCZ-specific group info. */
46 if (!(zgrp = calloc(1, sizeof(NCZ_GRP_INFO_T))))
47 {stat = NC_ENOMEM; goto done;}
48 root->format_grp_info = zgrp;
49 zgrp->common.file = file;
50
51 /* Fill in NCZ_FILE_INFO_T */
52 zinfo->created = 1;
53 zinfo->common.file = file;
54 zinfo->native_endianness = (NCZ_isLittleEndian() ? NC_ENDIAN_LITTLE : NC_ENDIAN_BIG);
55 if((zinfo->envv_controls=NCZ_clonestringvec(0,controls)) == NULL)
56 {stat = NC_ENOMEM; goto done;}
57
58 /* fill in some of the zinfo and zroot fields */
59 zinfo->zarr.zarr_version = atoi(ZARRVERSION);
60 sscanf(NCZARRVERSION,"%lu.%lu.%lu",
61 &zinfo->zarr.nczarr_version.major,
62 &zinfo->zarr.nczarr_version.minor,
63 &zinfo->zarr.nczarr_version.release);
64
65 zinfo->default_maxstrlen = NCZ_MAXSTR_DEFAULT;
66
67 /* Apply client controls */
68 if((stat = applycontrols(zinfo))) goto done;
69
70 /* Load auth info from rc file */
71 if((stat = ncuriparse(nc->path,&uri))) goto done;
72 if(uri) {
73 if((stat = NC_authsetup(&zinfo->auth, uri)))
74 goto done;
75 }
76
77 /* initialize map handle*/
78 if((stat = nczmap_create(zinfo->controls.mapimpl,nc->path,nc->mode,zinfo->controls.flags,NULL,&zinfo->map)))
79 goto done;
80
81done:
82 ncurifree(uri);
83 NCJreclaim(json);
84 nullfree(key);
85 return ZUNTRACE(stat);
86}
87
96int
97ncz_open_dataset(NC_FILE_INFO_T* file, const char** controls)
98{
99 int stat = NC_NOERR;
100 NC* nc = NULL;
101 NC_GRP_INFO_T* root = NULL;
102 NCURI* uri = NULL;
103 void* content = NULL;
104 NCjson* json = NULL;
105 NCZ_FILE_INFO_T* zinfo = NULL;
106 int mode;
107 NClist* modeargs = NULL;
108 char* nczarr_version = NULL;
109 char* zarr_format = NULL;
110
111 ZTRACE(3,"file=%s controls=%s",file->hdr.name,(controls?nczprint_envv(controls):"null"));
112
113 /* Extract info reachable via file */
114 nc = (NC*)file->controller;
115 mode = nc->mode;
116
117 root = file->root_grp;
118 assert(root != NULL && root->hdr.sort == NCGRP);
119
120 /* Add struct to hold NCZ-specific file metadata. */
121 if (!(file->format_file_info = calloc(1, sizeof(NCZ_FILE_INFO_T))))
122 {stat = NC_ENOMEM; goto done;}
123 zinfo = file->format_file_info;
124
125 /* Fill in NCZ_FILE_INFO_T */
126 zinfo->created = 0;
127 zinfo->common.file = file;
128 zinfo->native_endianness = (NCZ_isLittleEndian() ? NC_ENDIAN_LITTLE : NC_ENDIAN_BIG);
129 if((zinfo->envv_controls = NCZ_clonestringvec(0,controls))==NULL) /*0=>envv style*/
130 {stat = NC_ENOMEM; goto done;}
131 zinfo->default_maxstrlen = NCZ_MAXSTR_DEFAULT;
132
133 /* Add struct to hold NCZ-specific group info. */
134 if (!(root->format_grp_info = calloc(1, sizeof(NCZ_GRP_INFO_T))))
135 {stat = NC_ENOMEM; goto done;}
136 ((NCZ_GRP_INFO_T*)root->format_grp_info)->common.file = file;
137
138 /* Apply client controls */
139 if((stat = applycontrols(zinfo))) goto done;
140
141 /* initialize map handle*/
142 if((stat = nczmap_open(zinfo->controls.mapimpl,nc->path,mode,zinfo->controls.flags,NULL,&zinfo->map)))
143 goto done;
144
145 if((stat = ncz_read_superblock(file,&nczarr_version,&zarr_format))) goto done;
146
147 if(nczarr_version == NULL) /* default */
148 nczarr_version = strdup(NCZARRVERSION);
149 if(zarr_format == NULL) /* default */
150 zarr_format = strdup(ZARRVERSION);
151 /* Extract the information from it */
152 if(sscanf(zarr_format,"%d",&zinfo->zarr.zarr_version)!=1)
153 {stat = NC_ENCZARR; goto done;}
154 if(sscanf(nczarr_version,"%lu.%lu.%lu",
155 &zinfo->zarr.nczarr_version.major,
156 &zinfo->zarr.nczarr_version.minor,
157 &zinfo->zarr.nczarr_version.release) == 0)
158 {stat = NC_ENCZARR; goto done;}
159
160 /* Load auth info from rc file */
161 if((stat = ncuriparse(nc->path,&uri))) goto done;
162 if(uri) {
163 if((stat = NC_authsetup(&zinfo->auth, uri)))
164 goto done;
165 }
166
167done:
168 nullfree(zarr_format);
169 nullfree(nczarr_version);
170 ncurifree(uri);
171 nclistfreeall(modeargs);
172 if(json) NCJreclaim(json);
173 nullfree(content);
174 return ZUNTRACE(stat);
175}
176
187int
188NCZ_isnetcdf4(struct NC_FILE_INFO* h5)
189{
190 int isnc4 = 1;
191 NC_UNUSED(h5);
192 return isnc4;
193}
194
207int
208NCZ_get_libversion(unsigned long* majorp, unsigned long* minorp,unsigned long* releasep)
209{
210 unsigned long m0,m1,m2;
211 sscanf(NCZARRVERSION,"%lu.%lu.%lu",&m0,&m1,&m2);
212 if(majorp) *majorp = m0;
213 if(minorp) *minorp = m1;
214 if(releasep) *releasep = m2;
215 return NC_NOERR;
216}
217
229int
230NCZ_get_superblock(NC_FILE_INFO_T* file, int* superblockp)
231{
232 NCZ_FILE_INFO_T* zinfo = file->format_file_info;
233 if(superblockp) *superblockp = zinfo->zarr.nczarr_version.major;
234 return NC_NOERR;
235}
236
237/**************************************************/
238/* Utilities */
239
240#if 0
248static int
249ncz_open_rootgroup(NC_FILE_INFO_T* dataset)
250{
251 int stat = NC_NOERR;
252 int i;
253 NCZ_FILE_INFO_T* zfile = NULL;
254 NC_GRP_INFO_T* root = NULL;
255 void* content = NULL;
256 char* rootpath = NULL;
257 NCjson* json = NULL;
258
259 ZTRACE(3,"dataset=",dataset->hdr.name);
260
261 zfile = dataset->format_file_info;
262
263 /* Root should already be defined */
264 root = dataset->root_grp;
265
266 assert(root != NULL);
267
268 if((stat=nczm_concat(NULL,ZGROUP,&rootpath)))
269 goto done;
270 if((stat = NCZ_downloadjson(zfile->map, rootpath, &json)))
271 goto done;
272 /* Process the json */
273 for(i=0;i<nclistlength(json->contents);i+=2) {
274 const NCjson* key = nclistget(json->contents,i);
275 const NCjson* value = nclistget(json->contents,i+1);
276 if(strcmp(NCJstring(key),"zarr_format")==0) {
277 int zversion;
278 if(sscanf(NCJstring(value),"%d",&zversion)!=1)
279 {stat = NC_ENOTNC; goto done;}
280 /* Verify against the dataset */
281 if(zversion != zfile->zarr.zarr_version)
282 {stat = NC_ENOTNC; goto done;}
283 }
284 }
285
286done:
287 if(json) NCJreclaim(json);
288 nullfree(rootpath);
289 nullfree(content);
290 return ZUNTRACE(stat);
291}
292#endif
293
294
295static const char*
296controllookup(const char** envv_controls, const char* key)
297{
298 const char** p;
299 for(p=envv_controls;*p;p+=2) {
300 if(strcasecmp(key,*p)==0) {
301 return p[1];
302 }
303 }
304 return NULL;
305}
306
307
308static int
309applycontrols(NCZ_FILE_INFO_T* zinfo)
310{
311 int i,stat = NC_NOERR;
312 const char* value = NULL;
313 NClist* modelist = nclistnew();
314 int noflags = 0; /* track non-default negative flags */
315
316 if((value = controllookup((const char**)zinfo->envv_controls,"mode")) != NULL) {
317 if((stat = NCZ_comma_parse(value,modelist))) goto done;
318 }
319 /* Process the modelist first */
320 zinfo->controls.mapimpl = NCZM_DEFAULT;
321 zinfo->controls.flags |= FLAG_XARRAYDIMS; /* Always support XArray convention where possible */
322 for(i=0;i<nclistlength(modelist);i++) {
323 const char* p = nclistget(modelist,i);
324 if(strcasecmp(p,PUREZARRCONTROL)==0)
325 zinfo->controls.flags |= (FLAG_PUREZARR);
326 else if(strcasecmp(p,XARRAYCONTROL)==0)
327 zinfo->controls.flags |= FLAG_PUREZARR;
328 else if(strcasecmp(p,NOXARRAYCONTROL)==0)
329 noflags |= FLAG_XARRAYDIMS;
330 else if(strcasecmp(p,"zip")==0) zinfo->controls.mapimpl = NCZM_ZIP;
331 else if(strcasecmp(p,"file")==0) zinfo->controls.mapimpl = NCZM_FILE;
332 else if(strcasecmp(p,"s3")==0) zinfo->controls.mapimpl = NCZM_S3;
333 }
334 /* Apply negative controls by turning off negative flags */
335 /* This is necessary to avoid order dependence of mode flags when both positive and negative flags are defined */
336 zinfo->controls.flags &= (~noflags);
337
338 /* Process other controls */
339 if((value = controllookup((const char**)zinfo->envv_controls,"log")) != NULL) {
340 zinfo->controls.flags |= FLAG_LOGGING;
341 ncsetlogging(1);
342 }
343 if((value = controllookup((const char**)zinfo->envv_controls,"show")) != NULL) {
344 if(strcasecmp(value,"fetch")==0)
345 zinfo->controls.flags |= FLAG_SHOWFETCH;
346 }
347done:
348 nclistfreeall(modelist);
349 return stat;
350}
351
352#if 0
362int
363ncz_unload_jatts(NCZ_FILE_INFO_T* zinfo, NC_OBJ* container, NCjson* jattrs, NCjson* jtypes)
364{
365 int stat = NC_NOERR;
366 char* fullpath = NULL;
367 char* akey = NULL;
368 char* tkey = NULL;
369 NCZMAP* map = zinfo->map;
370
371 assert((NCJsort(jattrs) == NCJ_DICT));
372 assert((NCJsort(jtypes) == NCJ_DICT));
373
374 if(container->sort == NCGRP) {
375 NC_GRP_INFO_T* grp = (NC_GRP_INFO_T*)container;
376 /* Get grp's fullpath name */
377 if((stat = NCZ_grpkey(grp,&fullpath)))
378 goto done;
379 } else {
380 NC_VAR_INFO_T* var = (NC_VAR_INFO_T*)container;
381 /* Get var's fullpath name */
382 if((stat = NCZ_varkey(var,&fullpath)))
383 goto done;
384 }
385
386 /* Construct the path to the .zattrs object */
387 if((stat = nczm_concat(fullpath,ZATTRS,&akey)))
388 goto done;
389
390 /* Always write as V2 */
391
392 {
393 NCjson* k = NULL;
394 NCjson* v = NULL;
395 /* remove any previous version */
396 if(!NCJremove(jattrs,NCZ_V2_ATTRS,1,&k,&v)) {
397 NCJreclaim(k); NCJreclaim(v);
398 }
399 }
400
401 if(!(zinfo->controls.flags & FLAG_PUREZARR)) {
402 /* Insert the jtypes into the set of attributes */
403 if((stat = NCJinsert(jattrs,NCZ_V2_ATTRS,jtypes))) goto done;
404 }
405
406 /* Upload the .zattrs object */
407 if((stat=NCZ_uploadjson(map,tkey,jattrs)))
408 goto done;
409
410done:
411 if(stat) {
412 NCJreclaim(jattrs);
413 NCJreclaim(jtypes);
414 }
415 nullfree(fullpath);
416 nullfree(akey);
417 nullfree(tkey);
418 return stat;
419}
420#endif
421
422
423
#define NC_ENDIAN_BIG
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
Definition: netcdf.h:296
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:424
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition: netcdf.h:448
#define NC_ENCZARR
Error at NCZarr layer.
Definition: netcdf.h:518
#define NC_ENDIAN_LITTLE
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
Definition: netcdf.h:295
#define NC_NOERR
No Error.
Definition: netcdf.h:368