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 
11 static int applycontrols(NCZ_FILE_INFO_T* zinfo);
12 
13 /***************************************************/
14 /* API */
15 
24 int
25 ncz_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 
81 done:
82  ncurifree(uri);
83  NCJreclaim(json);
84  nullfree(key);
85  return ZUNTRACE(stat);
86 }
87 
96 int
97 ncz_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 
167 done:
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 
187 int
188 NCZ_isnetcdf4(struct NC_FILE_INFO* h5)
189 {
190  int isnc4 = 1;
191  NC_UNUSED(h5);
192  return isnc4;
193 }
194 
207 int
208 NCZ_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 
229 int
230 NCZ_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
248 static int
249 ncz_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 
286 done:
287  if(json) NCJreclaim(json);
288  nullfree(rootpath);
289  nullfree(content);
290  return ZUNTRACE(stat);
291 }
292 #endif
293 
294 
295 static const char*
296 controllookup(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 
308 static int
309 applycontrols(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  }
347 done:
348  nclistfreeall(modelist);
349  return stat;
350 }
351 
352 #if 0
362 int
363 ncz_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 
410 done:
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