NetCDF  4.6.3
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
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"
31 int
32 NC4_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 
74 int
75 NC4_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 
123 int
124 NC4_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 
159 int
160 NC4_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 
226 int
227 NC4_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 
266 int
267 NC4_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 
335 int
336 NC4_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 
382 int 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 
404 int
405 NC4_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 }
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition: netcdf.h:403
#define NC_ENOGRP
No group found.
Definition: netcdf.h:460
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:333
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:273
#define NC_NOERR
No Error.
Definition: netcdf.h:323

Return to the Main Unidata NetCDF page.
Generated on Sat Apr 6 2019 08:19:00 for NetCDF. NetCDF is a Unidata library.