NetCDF 4.8.0
Loading...
Searching...
No Matches
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->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
79done:
80 ncurifree(uri);
81 NCJreclaim(json);
82 nullfree(key);
83 return ZUNTRACE(stat);
84}
85
94int
95ncz_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
171done:
172 ncurifree(uri);
173 nclistfreeall(modeargs);
174 if(json) NCJreclaim(json);
175 nullfree(content);
176 return ZUNTRACE(stat);
177}
178
179
190int
191NCZ_isnetcdf4(struct NC_FILE_INFO* h5)
192{
193 int isnc4 = 1;
194 NC_UNUSED(h5);
195 return isnc4;
196}
197
210int
211NCZ_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
232int
233NCZ_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
251static int
252ncz_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
289done:
290 if(json) NCJreclaim(json);
291 nullfree(rootpath);
292 nullfree(content);
293 return ZUNTRACE(stat);
294}
295#endif
296
306int
307ncz_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
347done:
348 if(stat) {
349 NCJreclaim(jattrs);
350 NCJreclaim(jtypes);
351 }
352 nullfree(fullpath);
353 nullfree(akey);
354 nullfree(tkey);
355 return stat;
356}
357
358static const char*
359controllookup(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
371static int
372applycontrols(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 }
399done:
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