NetCDF 4.9.3
Loading...
Searching...
No Matches
nc4grp.c
Go to the documentation of this file.
1/* Copyright 2005-2018, University Corporation for Atmospheric
2 * Research. See COPYRIGHT file for copying and redistribution
3 * conditions. */
14
15#include "nc4internal.h"
16#include "nc4dispatch.h"
31int
32NC4_inq_ncid(int ncid, const char *name, int *grp_ncid)
33{
34 NC_GRP_INFO_T *grp, *g;
35 NC_FILE_INFO_T *h5;
36 char norm_name[NC_MAX_NAME + 1];
37 int retval;
38
39 LOG((2, "nc_inq_ncid: ncid 0x%x name %s", ncid, name));
40
41 /* Find info for this file and group, and set pointer to each. */
42 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
43 return retval;
44 assert(h5);
45
46 /* Short circuit the case of name == NULL => return the root group */
47 if(name == NULL) {
48 if(grp_ncid) {
49 NC_FILE_INFO_T* file = grp->nc4_info;
50 *grp_ncid = file->controller->ext_ncid | file->root_grp->hdr.id;
51 }
52 return NC_NOERR;
53 }
54
55 /* Normalize name. */
56 if ((retval = nc4_check_name(name, norm_name)))
57 return retval;
58
59 g = (NC_GRP_INFO_T*)ncindexlookup(grp->children,norm_name);
60 if(g != NULL)
61 {
62 if (grp_ncid)
63 *grp_ncid = grp->nc4_info->controller->ext_ncid | g->hdr.id;
64 return NC_NOERR;
65 }
66
67 /* If we got here, we didn't find the named group. */
68 return NC_ENOGRP;
69}
70
83int
84NC4_inq_grps(int ncid, int *numgrps, int *ncids)
85{
86 NC_GRP_INFO_T *grp, *g;
87 NC_FILE_INFO_T *h5;
88 int num = 0;
89 int retval;
90
91 LOG((2, "nc_inq_grps: ncid 0x%x", ncid));
92
93 /* Find info for this file and group, and set pointer to each. */
94 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
95 return retval;
96 assert(h5);
97
98 /* Count the number of groups in this group. */
99 for(size_t i=0;i<ncindexsize(grp->children);i++)
100 {
101 g = (NC_GRP_INFO_T*)ncindexith(grp->children,i);
102 if(g == NULL) continue;
103 if (ncids)
104 {
105 /* Combine the nc_grpid in a bitwise or with the ext_ncid,
106 * which allows the returned ncid to carry both file and
107 * group information. */
108 *ncids = g->hdr.id | g->nc4_info->controller->ext_ncid;
109 ncids++;
110 }
111 num++;
112 }
113
114 if (numgrps)
115 *numgrps = num;
116
117 return NC_NOERR;
118}
119
131int
132NC4_inq_grpname(int ncid, char *name)
133{
134 NC_GRP_INFO_T *grp;
135 NC_FILE_INFO_T *h5;
136 int retval;
137
138 LOG((2, "nc_inq_grpname: ncid 0x%x", ncid));
139
140 /* Find info for this file and group, and set pointer to each. */
141 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
142 return retval;
143 assert(h5);
144
145 /* Copy the name. */
146 if (name)
147 strcpy(name, grp->hdr.name);
148
149 return NC_NOERR;
150}
151
167int
168NC4_inq_grpname_full(int ncid, size_t *lenp, char *full_name)
169{
170 char *name, grp_name[NC_MAX_NAME + 1];
171 int g, id = ncid, parent_id, *gid;
172 int i, ret = NC_NOERR;
173
174 /* How many generations? */
175 for (g = 0; !NC4_inq_grp_parent(id, &parent_id); g++, id = parent_id)
176 ;
177
178 /* Allocate storage. */
179 if (!(name = malloc((size_t)(g + 1) * (NC_MAX_NAME + 1) + 1)))
180 return NC_ENOMEM;
181 if (!(gid = malloc((size_t)(g + 1) * sizeof(int))))
182 {
183 free(name);
184 return NC_ENOMEM;
185 }
186 assert(name && gid);
187
188 /* Always start with a "/" for the root group. */
189 strcpy(name, NC_GROUP_NAME);
190
191 /* Get the ncids for all generations. */
192 gid[0] = ncid;
193 for (i = 1; i < g && !ret; i++)
194 ret = NC4_inq_grp_parent(gid[i - 1], &gid[i]);
195
196 /* Assemble the full name. */
197 for (i = g - 1; !ret && i >= 0 && !ret; i--)
198 {
199 if ((ret = NC4_inq_grpname(gid[i], grp_name)))
200 break;
201 strcat(name, grp_name);
202 if (i)
203 strcat(name, "/");
204 }
205
206 /* Give the user the length of the name, if he wants it. */
207 if (!ret && lenp)
208 *lenp = strlen(name);
209
210 /* Give the user the name, if he wants it. */
211 if (!ret && full_name)
212 strcpy(full_name, name);
213
214 free(gid);
215 free(name);
216
217 return ret;
218}
219
234int
235NC4_inq_grp_parent(int ncid, int *parent_ncid)
236{
237 NC_GRP_INFO_T *grp;
238 NC_FILE_INFO_T *h5;
239 int retval;
240
241 LOG((2, "nc_inq_grp_parent: ncid 0x%x", ncid));
242
243 /* Find info for this file and group. */
244 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
245 return retval;
246 assert(h5);
247
248 /* Set the parent ncid, if there is one. */
249 if (grp->parent)
250 {
251 if (parent_ncid)
252 *parent_ncid = grp->nc4_info->controller->ext_ncid | grp->parent->hdr.id;
253 }
254 else
255 return NC_ENOGRP;
256
257 return NC_NOERR;
258}
259
274int
275NC4_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid)
276{
277 NC_GRP_INFO_T *grp;
278 NC_FILE_INFO_T *h5;
279 int id1 = ncid, id2;
280 char *cp, *full_name_cpy;
281 int ret;
282
283 if (!full_name)
284 return NC_EINVAL;
285
286 /* Find info for this file and group, and set pointer to each. */
287 if ((ret = nc4_find_grp_h5(ncid, &grp, &h5)))
288 return ret;
289 assert(h5);
290
291 /* Copy full_name because strtok messes with the value it works
292 * with, and we don't want to mess up full_name. */
293 if (!(full_name_cpy = strdup(full_name)))
294 return NC_ENOMEM;
295
296 /* Get the first part of the name. */
297 if (!(cp = strtok(full_name_cpy, "/")))
298 {
299 /* If "/" is passed, and this is the root group, return the root
300 * group id. */
301 if (!grp->parent)
302 id2 = ncid;
303 else
304 {
305 free(full_name_cpy);
306 return NC_ENOGRP;
307 }
308 }
309 else
310 {
311 /* Keep parsing the string. */
312 for (; cp; id1 = id2)
313 {
314 if ((ret = NC4_inq_ncid(id1, cp, &id2)))
315 {
316 free(full_name_cpy);
317 return ret;
318 }
319 cp = strtok(NULL, "/");
320 }
321 }
322
323 /* Give the user the requested value. */
324 if (grp_ncid)
325 *grp_ncid = id2;
326
327 free(full_name_cpy);
328
329 return NC_NOERR;
330}
331
343int
344NC4_inq_varids(int ncid, int *nvars, int *varids)
345{
346 NC_GRP_INFO_T *grp;
347 NC_FILE_INFO_T *h5;
348 NC_VAR_INFO_T *var;
349 int num_vars = 0;
350 int retval;
351
352 LOG((2, "nc_inq_varids: ncid 0x%x", ncid));
353
354 /* Find info for this file and group, and set pointer to each. */
355 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
356 return retval;
357 assert(h5);
358
359 /* This is a netCDF-4 group. Round up them doggies and count
360 * 'em. The list is in correct (i.e. creation) order. */
361 for (size_t i=0; i < ncindexsize(grp->vars); i++)
362 {
363 var = (NC_VAR_INFO_T*)ncindexith(grp->vars,i);
364 if (!var) continue;
365 if (varids)
366 varids[num_vars] = var->hdr.id;
367 num_vars++;
368 }
369
370 /* If the user wants to know how many vars in the group, tell
371 * him. */
372 if (nvars)
373 *nvars = num_vars;
374
375 return NC_NOERR;
376}
377
389int int_cmp(const void *a, const void *b)
390{
391 const int *ia = (const int *)a;
392 const int *ib = (const int *)b;
393 return *ia - *ib;
394}
395
411int
412NC4_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents)
413{
414 NC_GRP_INFO_T *grp, *g;
415 NC_FILE_INFO_T *h5;
416 NC_DIM_INFO_T *dim;
417 int num = 0;
418 int retval;
419
420 LOG((2, "nc_inq_dimids: ncid 0x%x include_parents: %d", ncid,
421 include_parents));
422
423 /* Find info for this file and group, and set pointer to each. */
424 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
425 return retval;
426 assert(h5);
427
428 /* First count them. */
429 num = ncindexcount(grp->dim);
430 if (include_parents) {
431 for (g = grp->parent; g; g = g->parent)
432 num += ncindexcount(g->dim);
433 }
434
435 /* If the user wants the dimension ids, get them. */
436 if (dimids)
437 {
438 int n = 0;
439
440 /* Get dimension ids from this group. */
441 for(size_t i=0;i<ncindexsize(grp->dim);i++) {
442 dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,i);
443 if(dim == NULL) continue;
444 dimids[n++] = dim->hdr.id;
445 }
446
447 /* Get dimension ids from parent groups. */
448 if (include_parents)
449 for (g = grp->parent; g; g = g->parent) {
450 for(size_t i=0;i<ncindexsize(g->dim);i++) {
451 dim = (NC_DIM_INFO_T*)ncindexith(g->dim,i);
452 if(dim == NULL) continue;
453 dimids[n++] = dim->hdr.id;
454 }
455 }
456 qsort(dimids, (size_t)num, sizeof(int), int_cmp);
457 }
458
459 /* If the user wants the number of dims, give it. */
460 if (ndims)
461 *ndims = num;
462
463 return NC_NOERR;
464}
#define NC_ENOGRP
No group found.
Definition netcdf.h:515
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition netcdf.h:458
#define NC_EINVAL
Invalid Argument.
Definition netcdf.h:388
#define NC_MAX_NAME
Maximum for classic library.
Definition netcdf.h:291
#define NC_NOERR
No Error.
Definition netcdf.h:378