NetCDF  4.8.0
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->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 = 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  /* Apply client controls */
66  if((stat = applycontrols(zinfo))) goto done;
67 
68  /* Load auth info from rc file */
69  if((stat = ncuriparse(nc->path,&uri))) goto done;
70  if(uri) {
71  if((stat = NC_authsetup(&zinfo->auth, uri)))
72  goto done;
73  }
74 
75  /* initialize map handle*/
76  if((stat = nczmap_create(zinfo->features.mapimpl,nc->path,nc->mode,zinfo->features.flags,NULL,&zinfo->map)))
77  goto done;
78 
79 done:
80  ncurifree(uri);
81  NCJreclaim(json);
82  nullfree(key);
83  return ZUNTRACE(stat);
84 }
85 
94 int
95 ncz_open_dataset(NC_FILE_INFO_T* file, const char** controls)
96 {
97  int i,stat = NC_NOERR;
98  NC* nc = NULL;
99  NC_GRP_INFO_T* root = NULL;
100  NCURI* uri = NULL;
101  void* content = NULL;
102  NCjson* json = NULL;
103  NCZ_FILE_INFO_T* zinfo = NULL;
104  int mode;
105  NClist* modeargs = NULL;
106 
107  ZTRACE(3,"file=%s controls=%s",file->hdr.name,(controls?nczprint_envv(controls):"null"));
108 
109  /* Extract info reachable via file */
110  nc = (NC*)file->controller;
111  mode = nc->mode;
112 
113  root = file->root_grp;
114  assert(root != NULL && root->hdr.sort == NCGRP);
115 
116  /* Add struct to hold NCZ-specific file metadata. */
117  if (!(file->format_file_info = calloc(1, sizeof(NCZ_FILE_INFO_T))))
118  {stat = NC_ENOMEM; goto done;}
119  zinfo = file->format_file_info;
120 
121  /* Fill in NCZ_FILE_INFO_T */
122  zinfo->created = 0;
123  zinfo->common.file = file;
124  zinfo->native_endianness = (NCZ_isLittleEndian() ? NC_ENDIAN_LITTLE : NC_ENDIAN_BIG);
125  if((zinfo->controls = NCZ_clonestringvec(0,controls))==NULL) /*0=>envv style*/
126  {stat = NC_ENOMEM; goto done;}
127 
128  /* Add struct to hold NCZ-specific group info. */
129  if (!(root->format_grp_info = calloc(1, sizeof(NCZ_GRP_INFO_T))))
130  {stat = NC_ENOMEM; goto done;}
131  ((NCZ_GRP_INFO_T*)root->format_grp_info)->common.file = file;
132 
133  /* Apply client controls */
134  if((stat = applycontrols(zinfo))) goto done;
135 
136  /* initialize map handle*/
137  if((stat = nczmap_open(zinfo->features.mapimpl,nc->path,mode,zinfo->features.flags,NULL,&zinfo->map)))
138  goto done;
139 
140  if(!(zinfo->features.flags & FLAG_PUREZARR)
141  && (stat = NCZ_downloadjson(zinfo->map, NCZMETAROOT, &json)) == NC_NOERR) {
142  /* Extract the information from it */
143  for(i=0;i<nclistlength(json->contents);i+=2) {
144  const NCjson* key = nclistget(json->contents,i);
145  const NCjson* value = nclistget(json->contents,i+1);
146  if(strcmp(key->value,"zarr_format")==0) {
147  if(sscanf(value->value,"%d",&zinfo->zarr.zarr_version)!=1)
148  {stat = NC_ENOTNC; goto done;}
149  } else if(strcmp(key->value,"nczarr_version")==0) {
150  sscanf(value->value,"%lu.%lu.%lu",
151  &zinfo->zarr.nczarr_version.major,
152  &zinfo->zarr.nczarr_version.minor,
153  &zinfo->zarr.nczarr_version.release);
154  }
155  }
156  } else { /* zinfo->features.purezarr || no object */
157  zinfo->zarr.zarr_version = ZARRVERSION;
158  sscanf(NCZARRVERSION,"%lu.%lu.%lu",
159  &zinfo->zarr.nczarr_version.major,
160  &zinfo->zarr.nczarr_version.minor,
161  &zinfo->zarr.nczarr_version.release);
162  }
163 
164  /* Load auth info from rc file */
165  if((stat = ncuriparse(nc->path,&uri))) goto done;
166  if(uri) {
167  if((stat = NC_authsetup(&zinfo->auth, uri)))
168  goto done;
169  }
170 
171 done:
172  ncurifree(uri);
173  nclistfreeall(modeargs);
174  if(json) NCJreclaim(json);
175  nullfree(content);
176  return ZUNTRACE(stat);
177 }
178 
179 
190 int
191 NCZ_isnetcdf4(struct NC_FILE_INFO* h5)
192 {
193  int isnc4 = 1;
194  NC_UNUSED(h5);
195  return isnc4;
196 }
197 
210 int
211 NCZ_get_libversion(unsigned long* majorp, unsigned long* minorp,unsigned long* releasep)
212 {
213  unsigned long m0,m1,m2;
214  sscanf(NCZARRVERSION,"%lu.%lu.%lu",&m0,&m1,&m2);
215  if(majorp) *majorp = m0;
216  if(minorp) *minorp = m1;
217  if(releasep) *releasep = m2;
218  return NC_NOERR;
219 }
220 
232 int
233 NCZ_get_superblock(NC_FILE_INFO_T* file, int* superblockp)
234 {
235  NCZ_FILE_INFO_T* zinfo = file->format_file_info;
236  if(superblockp) *superblockp = zinfo->zarr.nczarr_version.major;
237  return NC_NOERR;
238 }
239 
240 /**************************************************/
241 /* Utilities */
242 
243 #if 0
251 static int
252 ncz_open_rootgroup(NC_FILE_INFO_T* dataset)
253 {
254  int stat = NC_NOERR;
255  int i;
256  NCZ_FILE_INFO_T* zfile = NULL;
257  NC_GRP_INFO_T* root = NULL;
258  void* content = NULL;
259  char* rootpath = NULL;
260  NCjson* json = NULL;
261 
262  ZTRACE(3,"dataset=",dataset->hdr.name);
263 
264  zfile = dataset->format_file_info;
265 
266  /* Root should already be defined */
267  root = dataset->root_grp;
268 
269  assert(root != NULL);
270 
271  if((stat=nczm_concat(NULL,ZGROUP,&rootpath)))
272  goto done;
273  if((stat = NCZ_downloadjson(zfile->map, rootpath, &json)))
274  goto done;
275  /* Process the json */
276  for(i=0;i<nclistlength(json->contents);i+=2) {
277  const NCjson* key = nclistget(json->contents,i);
278  const NCjson* value = nclistget(json->contents,i+1);
279  if(strcmp(key->value,"zarr_format")==0) {
280  int zversion;
281  if(sscanf(value->value,"%d",&zversion)!=1)
282  {stat = NC_ENOTNC; goto done;}
283  /* Verify against the dataset */
284  if(zversion != zfile->zarr.zarr_version)
285  {stat = NC_ENOTNC; goto done;}
286  }
287  }
288 
289 done:
290  if(json) NCJreclaim(json);
291  nullfree(rootpath);
292  nullfree(content);
293  return ZUNTRACE(stat);
294 }
295 #endif
296 
306 int
307 ncz_unload_jatts(NCZ_FILE_INFO_T* zinfo, NC_OBJ* container, NCjson* jattrs, NCjson* jtypes)
308 {
309  int stat = NC_NOERR;
310  char* fullpath = NULL;
311  char* akey = NULL;
312  char* tkey = NULL;
313  NCZMAP* map = zinfo->map;
314 
315  assert((jattrs->sort = NCJ_DICT));
316  assert((jtypes->sort = NCJ_DICT));
317 
318  if(container->sort == NCGRP) {
319  NC_GRP_INFO_T* grp = (NC_GRP_INFO_T*)container;
320  /* Get grp's fullpath name */
321  if((stat = NCZ_grpkey(grp,&fullpath)))
322  goto done;
323  } else {
324  NC_VAR_INFO_T* var = (NC_VAR_INFO_T*)container;
325  /* Get var's fullpath name */
326  if((stat = NCZ_varkey(var,&fullpath)))
327  goto done;
328  }
329 
330  /* Construct the path to the .zattrs object */
331  if((stat = nczm_concat(fullpath,ZATTRS,&akey)))
332  goto done;
333 
334  /* Upload the .zattrs object */
335  if((stat=NCZ_uploadjson(map,tkey,jattrs)))
336  goto done;
337 
338  if(!(zinfo->features.flags & FLAG_PUREZARR)) {
339  /* Construct the path to the .nczattr object */
340  if((stat = nczm_concat(fullpath,NCZATTR,&tkey)))
341  goto done;
342  /* Upload the .nczattr object */
343  if((stat=NCZ_uploadjson(map,tkey,jtypes)))
344  goto done;
345  }
346 
347 done:
348  if(stat) {
349  NCJreclaim(jattrs);
350  NCJreclaim(jtypes);
351  }
352  nullfree(fullpath);
353  nullfree(akey);
354  nullfree(tkey);
355  return stat;
356 }
357 
358 static const char*
359 controllookup(const char** controls, const char* key)
360 {
361  const char** p;
362  for(p=controls;*p;p++) {
363  if(strcasecmp(key,*p)==0) {
364  return p[1];
365  }
366  }
367  return NULL;
368 }
369 
370 
371 static int
372 applycontrols(NCZ_FILE_INFO_T* zinfo)
373 {
374  int i,stat = NC_NOERR;
375  const char* value = NULL;
376  NClist* modelist = nclistnew();
377 
378  if((value = controllookup((const char**)zinfo->controls,"mode")) != NULL) {
379  if((stat = NCZ_comma_parse(value,modelist))) goto done;
380  }
381  /* Process the modelist first */
382  zinfo->features.mapimpl = NCZM_DEFAULT;
383  for(i=0;i<nclistlength(modelist);i++) {
384  const char* p = nclistget(modelist,i);
385  if(strcasecmp(p,PUREZARR)==0) zinfo->features.flags |= FLAG_PUREZARR;
386  else if(strcasecmp(p,"zip")==0) zinfo->features.mapimpl = NCZM_ZIP;
387  else if(strcasecmp(p,"file")==0) zinfo->features.mapimpl = NCZM_FILE;
388  else if(strcasecmp(p,"s3")==0) zinfo->features.mapimpl = NCZM_S3;
389  }
390  /* Process other controls */
391  if((value = controllookup((const char**)zinfo->controls,"log")) != NULL) {
392  zinfo->features.flags |= FLAG_LOGGING;
393  ncsetlogging(1);
394  }
395  if((value = controllookup((const char**)zinfo->controls,"show")) != NULL) {
396  if(strcasecmp(value,"fetch")==0)
397  zinfo->features.flags |= FLAG_SHOWFETCH;
398  }
399 done:
400  nclistfreeall(modelist);
401  return stat;
402 }
403 
#define NC_ENDIAN_BIG
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
Definition: netcdf.h:291
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:386
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition: netcdf.h:410
#define NC_ENDIAN_LITTLE
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
Definition: netcdf.h:290
#define NC_NOERR
No Error.
Definition: netcdf.h:330