NetCDF 4.8.0
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. */
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 /* Normalize name. */
47 if ((retval = nc4_check_name(name, norm_name)))
48 return retval;
49
50 g = (NC_GRP_INFO_T*)ncindexlookup(grp->children,norm_name);
51 if(g != NULL)
52 {
53 if (grp_ncid)
54 *grp_ncid = grp->nc4_info->controller->ext_ncid | g->hdr.id;
55 return NC_NOERR;
56 }
57
58 /* If we got here, we didn't find the named group. */
59 return NC_ENOGRP;
60}
61
74int
75NC4_inq_grps(int ncid, int *numgrps, int *ncids)
76{
77 NC_GRP_INFO_T *grp, *g;
78 NC_FILE_INFO_T *h5;
79 int num = 0;
80 int retval;
81 int i;
82
83 LOG((2, "nc_inq_grps: ncid 0x%x", ncid));
84
85 /* Find info for this file and group, and set pointer to each. */
86 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
87 return retval;
88 assert(h5);
89
90 /* Count the number of groups in this group. */
91 for(i=0;i<ncindexsize(grp->children);i++)
92 {
93 g = (NC_GRP_INFO_T*)ncindexith(grp->children,i);
94 if(g == NULL) continue;
95 if (ncids)
96 {
97 /* Combine the nc_grpid in a bitwise or with the ext_ncid,
98 * which allows the returned ncid to carry both file and
99 * group information. */
100 *ncids = g->hdr.id | g->nc4_info->controller->ext_ncid;
101 ncids++;
102 }
103 num++;
104 }
105
106 if (numgrps)
107 *numgrps = num;
108
109 return NC_NOERR;
110}
111
123int
124NC4_inq_grpname(int ncid, char *name)
125{
126 NC_GRP_INFO_T *grp;
127 NC_FILE_INFO_T *h5;
128 int retval;
129
130 LOG((2, "nc_inq_grpname: ncid 0x%x", ncid));
131
132 /* Find info for this file and group, and set pointer to each. */
133 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
134 return retval;
135 assert(h5);
136
137 /* Copy the name. */
138 if (name)
139 strcpy(name, grp->hdr.name);
140
141 return NC_NOERR;
142}
143
159int
160NC4_inq_grpname_full(int ncid, size_t *lenp, char *full_name)
161{
162 char *name, grp_name[NC_MAX_NAME + 1];
163 int g, id = ncid, parent_id, *gid;
164 int i, ret = NC_NOERR;
165
166 /* How many generations? */
167 for (g = 0; !NC4_inq_grp_parent(id, &parent_id); g++, id = parent_id)
168 ;
169
170 /* Allocate storage. */
171 if (!(name = malloc((g + 1) * (NC_MAX_NAME + 1) + 1)))
172 return NC_ENOMEM;
173 if (!(gid = malloc((g + 1) * sizeof(int))))
174 {
175 free(name);
176 return NC_ENOMEM;
177 }
178 assert(name && gid);
179
180 /* Always start with a "/" for the root group. */
181 strcpy(name, NC_GROUP_NAME);
182
183 /* Get the ncids for all generations. */
184 gid[0] = ncid;
185 for (i = 1; i < g && !ret; i++)
186 ret = NC4_inq_grp_parent(gid[i - 1], &gid[i]);
187
188 /* Assemble the full name. */
189 for (i = g - 1; !ret && i >= 0 && !ret; i--)
190 {
191 if ((ret = NC4_inq_grpname(gid[i], grp_name)))
192 break;
193 strcat(name, grp_name);
194 if (i)
195 strcat(name, "/");
196 }
197
198 /* Give the user the length of the name, if he wants it. */
199 if (!ret && lenp)
200 *lenp = strlen(name);
201
202 /* Give the user the name, if he wants it. */
203 if (!ret && full_name)
204 strcpy(full_name, name);
205
206 free(gid);
207 free(name);
208
209 return ret;
210}
211
226int
227NC4_inq_grp_parent(int ncid, int *parent_ncid)
228{
229 NC_GRP_INFO_T *grp;
230 NC_FILE_INFO_T *h5;
231 int retval;
232
233 LOG((2, "nc_inq_grp_parent: ncid 0x%x", ncid));
234
235 /* Find info for this file and group. */
236 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
237 return retval;
238 assert(h5);
239
240 /* Set the parent ncid, if there is one. */
241 if (grp->parent)
242 {
243 if (parent_ncid)
244 *parent_ncid = grp->nc4_info->controller->ext_ncid | grp->parent->hdr.id;
245 }
246 else
247 return NC_ENOGRP;
248
249 return NC_NOERR;
250}
251
266int
267NC4_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid)
268{
269 NC_GRP_INFO_T *grp;
270 NC_FILE_INFO_T *h5;
271 int id1 = ncid, id2;
272 char *cp, *full_name_cpy;
273 int ret;
274
275 if (!full_name)
276 return NC_EINVAL;
277
278 /* Find info for this file and group, and set pointer to each. */
279 if ((ret = nc4_find_grp_h5(ncid, &grp, &h5)))
280 return ret;
281 assert(h5);
282
283 /* Copy full_name because strtok messes with the value it works
284 * with, and we don't want to mess up full_name. */
285 if (!(full_name_cpy = strdup(full_name)))
286 return NC_ENOMEM;
287
288 /* Get the first part of the name. */
289 if (!(cp = strtok(full_name_cpy, "/")))
290 {
291 /* If "/" is passed, and this is the root group, return the root
292 * group id. */
293 if (!grp->parent)
294 id2 = ncid;
295 else
296 {
297 free(full_name_cpy);
298 return NC_ENOGRP;
299 }
300 }
301 else
302 {
303 /* Keep parsing the string. */
304 for (; cp; id1 = id2)
305 {
306 if ((ret = NC4_inq_ncid(id1, cp, &id2)))
307 {
308 free(full_name_cpy);
309 return ret;
310 }
311 cp = strtok(NULL, "/");
312 }
313 }
314
315 /* Give the user the requested value. */
316 if (grp_ncid)
317 *grp_ncid = id2;
318
319 free(full_name_cpy);
320
321 return NC_NOERR;
322}
323
335int
336NC4_inq_varids(int ncid, int *nvars, int *varids)
337{
338 NC_GRP_INFO_T *grp;
339 NC_FILE_INFO_T *h5;
340 NC_VAR_INFO_T *var;
341 int num_vars = 0;
342 int retval;
343 int i;
344
345 LOG((2, "nc_inq_varids: ncid 0x%x", ncid));
346
347 /* Find info for this file and group, and set pointer to each. */
348 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
349 return retval;
350 assert(h5);
351
352 /* This is a netCDF-4 group. Round up them doggies and count
353 * 'em. The list is in correct (i.e. creation) order. */
354 for (i=0; i < ncindexsize(grp->vars); i++)
355 {
356 var = (NC_VAR_INFO_T*)ncindexith(grp->vars,i);
357 if (!var) continue;
358 if (varids)
359 varids[num_vars] = var->hdr.id;
360 num_vars++;
361 }
362
363 /* If the user wants to know how many vars in the group, tell
364 * him. */
365 if (nvars)
366 *nvars = num_vars;
367
368 return NC_NOERR;
369}
370
382int int_cmp(const void *a, const void *b)
383{
384 const int *ia = (const int *)a;
385 const int *ib = (const int *)b;
386 return *ia - *ib;
387}
388
404int
405NC4_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents)
406{
407 NC_GRP_INFO_T *grp, *g;
408 NC_FILE_INFO_T *h5;
409 NC_DIM_INFO_T *dim;
410 int num = 0;
411 int retval;
412
413 LOG((2, "nc_inq_dimids: ncid 0x%x include_parents: %d", ncid,
414 include_parents));
415
416 /* Find info for this file and group, and set pointer to each. */
417 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
418 return retval;
419 assert(h5);
420
421 /* First count them. */
422 num = ncindexcount(grp->dim);
423 if (include_parents) {
424 for (g = grp->parent; g; g = g->parent)
425 num += ncindexcount(g->dim);
426 }
427
428 /* If the user wants the dimension ids, get them. */
429 if (dimids)
430 {
431 int n = 0;
432 int i;
433
434 /* Get dimension ids from this group. */
435 for(i=0;i<ncindexsize(grp->dim);i++) {
436 dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,i);
437 if(dim == NULL) continue;
438 dimids[n++] = dim->hdr.id;
439 }
440
441 /* Get dimension ids from parent groups. */
442 if (include_parents)
443 for (g = grp->parent; g; g = g->parent) {
444 for(i=0;i<ncindexsize(g->dim);i++) {
445 dim = (NC_DIM_INFO_T*)ncindexith(g->dim,i);
446 if(dim == NULL) continue;
447 dimids[n++] = dim->hdr.id;
448 }
449 }
450 qsort(dimids, num, sizeof(int), int_cmp);
451 }
452
453 /* If the user wants the number of dims, give it. */
454 if (ndims)
455 *ndims = num;
456
457 return NC_NOERR;
458}
int NC4_inq_grp_parent(int ncid, int *parent_ncid)
Definition nc4grp.c:227
int NC4_inq_ncid(int ncid, const char *name, int *grp_ncid)
Definition nc4grp.c:32
int int_cmp(const void *a, const void *b)
Definition nc4grp.c:382
int NC4_inq_grpname(int ncid, char *name)
Definition nc4grp.c:124
int NC4_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents)
Definition nc4grp.c:405
int NC4_inq_grpname_full(int ncid, size_t *lenp, char *full_name)
Definition nc4grp.c:160
int NC4_inq_grps(int ncid, int *numgrps, int *ncids)
Definition nc4grp.c:75
int NC4_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid)
Definition nc4grp.c:267
int NC4_inq_varids(int ncid, int *nvars, int *varids)
Definition nc4grp.c:336
int nc4_check_name(const char *name, char *norm_name)
Definition nc4internal.c:80
int nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5)
#define NC_ENOGRP
No group found.
Definition netcdf.h:467
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition netcdf.h:410
#define NC_EINVAL
Invalid Argument.
Definition netcdf.h:340
#define NC_MAX_NAME
Maximum for classic library.
Definition netcdf.h:276
#define NC_NOERR
No Error.
Definition netcdf.h:330