1 /* Copyright 2003-2018, University Corporation for Atmospheric
2 * Research. See the COPYRIGHT file for copying and redistribution
3 * conditions. */
4 /**
5 * @file
6 * @internal This file is part of netcdf-4, a netCDF-like interface
7 * for HDF5, or a HDF5 backend for netCDF, depending on your point of
8 * view.
9 *
10 * This file handles the nc4 dimension functions.
11 *
12 * @author Ed Hartnett
13 */
14
15 #include "nc4internal.h"
16 #include "nc4dispatch.h"
17
18 /**
19 * @internal Netcdf-4 files might have more than one unlimited
20 * dimension, but return the first one anyway.
21 *
22 * @note that this code is inconsistent with nc_inq
23 *
24 * @param ncid File and group ID.
25 * @param unlimdimidp Pointer that gets ID of first unlimited
26 * dimension, or -1.
27 *
28 * @return ::NC_NOERR No error.
29 * @return ::NC_EBADID Bad ncid.
30 * @author Ed Hartnett
31 */
32 int
NC4_inq_unlimdim(int ncid,int * unlimdimidp)33 NC4_inq_unlimdim(int ncid, int *unlimdimidp)
34 {
35 NC *nc;
36 NC_GRP_INFO_T *grp, *g;
37 NC_FILE_INFO_T *h5;
38 NC_DIM_INFO_T *dim;
39 int found = 0;
40 int retval;
41 int i;
42
43 LOG((2, "%s: called", __func__));
44
45 if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
46 return retval;
47 assert(h5 && nc && grp);
48
49 if (unlimdimidp)
50 {
51 /* According to netcdf-3 manual, return -1 if there is no unlimited
52 dimension. */
53 *unlimdimidp = -1;
54 for (g = grp; g && !found; g = g->parent)
55 {
56 for(i=0;i<ncindexsize(grp->dim);i++)
57 {
58 dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,i);
59 if(dim == NULL) continue;
60 if (dim->unlimited)
61 {
62 *unlimdimidp = dim->hdr.id;
63 found++;
64 break;
65 }
66 }
67 }
68 }
69
70 return NC_NOERR;
71 }
72
73 /**
74 * @internal Given dim name, find its id.
75 *
76 * @param ncid File and group ID.
77 * @param name Name of the dimension to find.
78 * @param idp Pointer that gets dimension ID.
79 *
80 * @return ::NC_NOERR No error.
81 * @return ::NC_EBADID Bad ncid.
82 * @return ::NC_EBADDIM Dimension not found.
83 * @return ::NC_EINVAL Invalid input. Name must be provided.
84 * @author Ed Hartnett
85 */
86 int
NC4_inq_dimid(int ncid,const char * name,int * idp)87 NC4_inq_dimid(int ncid, const char *name, int *idp)
88 {
89 NC *nc;
90 NC_GRP_INFO_T *grp, *g;
91 NC_FILE_INFO_T *h5;
92 NC_DIM_INFO_T *dim;
93 char norm_name[NC_MAX_NAME + 1];
94 int retval;
95 int found;
96
97 LOG((2, "%s: ncid 0x%x name %s", __func__, ncid, name));
98
99 /* Check input. */
100 if (!name)
101 return NC_EINVAL;
102
103 /* Find metadata for this file. */
104 if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
105 return retval;
106 assert(h5 && nc && grp);
107
108 /* Normalize name. */
109 if ((retval = nc4_normalize_name(name, norm_name)))
110 return retval;
111
112 /* check for a name match in this group and its parents */
113 found = 0;
114 for (g = grp; g ; g = g->parent) {
115 dim = (NC_DIM_INFO_T*)ncindexlookup(g->dim,norm_name);
116 if(dim != NULL) {found = 1; break;}
117 }
118 if(!found)
119 return NC_EBADDIM;
120 assert(dim != NULL);
121 if (idp)
122 *idp = dim->hdr.id;
123 return NC_NOERR;
124 }
125
126 /**
127 * @internal Returns an array of unlimited dimension ids.The user can
128 * get the number of unlimited dimensions by first calling this with
129 * NULL for the second pointer.
130 *
131 * @param ncid File and group ID.
132 * @param nunlimdimsp Pointer that gets the number of unlimited
133 * dimensions. Ignored if NULL.
134 * @param unlimdimidsp Pointer that gets arrray of unlimited dimension
135 * ID. Ignored if NULL.
136 *
137 * @return ::NC_NOERR No error.
138 * @return ::NC_EBADID Bad ncid.
139 * @author Ed Hartnett, Dennis Heimbigner
140 */
141 int
NC4_inq_unlimdims(int ncid,int * nunlimdimsp,int * unlimdimidsp)142 NC4_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp)
143 {
144 NC_DIM_INFO_T *dim;
145 NC_GRP_INFO_T *grp;
146 NC *nc;
147 NC_FILE_INFO_T *h5;
148 int num_unlim = 0;
149 int retval;
150 int i;
151
152 LOG((2, "%s: ncid 0x%x", __func__, ncid));
153
154 /* Find info for this file and group, and set pointer to each. */
155 if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
156 return retval;
157 assert(h5 && nc && grp);
158
159 /* Get our dim info. */
160 assert(h5);
161 {
162 for(i=0;i<ncindexsize(grp->dim);i++)
163 {
164 dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,i);
165 if(dim == NULL) continue;
166 if (dim->unlimited)
167 {
168 if (unlimdimidsp)
169 unlimdimidsp[num_unlim] = dim->hdr.id;
170 num_unlim++;
171 }
172 }
173 }
174
175 /* Give the number if the user wants it. */
176 if (nunlimdimsp)
177 *nunlimdimsp = num_unlim;
178
179 return NC_NOERR;
180 }
181