NetCDF 4.8.0
Loading...
Searching...
No Matches
nc4attr.c
Go to the documentation of this file.
1/* Copyright 2003-2018, University Corporation for Atmospheric
2 * Research. See COPYRIGHT file for copying and redistribution
3 * conditions. */
19#include "nc.h"
20#include "nc4internal.h"
21#include "nc4dispatch.h"
22#include "ncdispatch.h"
23
45int
46nc4_get_att_ptrs(NC_FILE_INFO_T *h5, NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var,
47 const char *name, nc_type *xtype, nc_type mem_type,
48 size_t *lenp, int *attnum, void *data)
49{
50 NC_ATT_INFO_T *att = NULL;
51 int my_attnum = -1;
52 int need_to_convert = 0;
53 int range_error = NC_NOERR;
54 void *bufr = NULL;
55 size_t type_size;
56 int varid;
57 int i;
58 int retval;
59
60 LOG((3, "%s: mem_type %d", __func__, mem_type));
61
62 /* Get the varid, or NC_GLOBAL. */
63 varid = var ? var->hdr.id : NC_GLOBAL;
64
65 if (attnum)
66 my_attnum = *attnum;
67
68 if (name == NULL)
69 BAIL(NC_EBADNAME);
70
71 /* Find the attribute, if it exists. */
72 if ((retval = nc4_find_grp_att(grp, varid, name, my_attnum, &att)))
73 return retval;
74
75 /* If mem_type is NC_NAT, it means we want to use the attribute's
76 * file type as the mem type as well. */
77 if (mem_type == NC_NAT)
78 mem_type = att->nc_typeid;
79
80 /* If the attribute is NC_CHAR, and the mem_type isn't, or vice
81 * versa, that's a freakish attempt to convert text to
82 * numbers. Some pervert out there is trying to pull a fast one!
83 * Send him an NC_ECHAR error. */
84 if (data && att->len)
85 if ((att->nc_typeid == NC_CHAR && mem_type != NC_CHAR) ||
86 (att->nc_typeid != NC_CHAR && mem_type == NC_CHAR))
87 BAIL(NC_ECHAR); /* take that, you freak! */
88
89 /* Copy the info. */
90 if (lenp)
91 *lenp = att->len;
92 if (xtype)
93 *xtype = att->nc_typeid;
94 if (attnum) {
95 *attnum = att->hdr.id;
96 }
97
98 /* Zero len attributes are easy to read! */
99 if (!att->len)
100 BAIL(NC_NOERR);
101
102 /* Later on, we will need to know the size of this type. */
103 if ((retval = nc4_get_typelen_mem(h5, mem_type, &type_size)))
104 BAIL(retval);
105
106 /* We may have to convert data. Treat NC_CHAR the same as
107 * NC_UBYTE. If the mem_type is NAT, don't try any conversion - use
108 * the attribute's type. */
109 if (data && att->len && mem_type != att->nc_typeid &&
110 mem_type != NC_NAT &&
111 !(mem_type == NC_CHAR &&
112 (att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE)))
113 {
114 if (!(bufr = malloc((size_t)(att->len * type_size))))
115 BAIL(NC_ENOMEM);
116 need_to_convert++;
117 if ((retval = nc4_convert_type(att->data, bufr, att->nc_typeid,
118 mem_type, (size_t)att->len, &range_error,
119 NULL, (h5->cmode & NC_CLASSIC_MODEL))))
120 BAIL(retval);
121
122 /* For strict netcdf-3 rules, ignore erange errors between UBYTE
123 * and BYTE types. */
124 if ((h5->cmode & NC_CLASSIC_MODEL) &&
125 (att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE) &&
126 (mem_type == NC_UBYTE || mem_type == NC_BYTE) &&
127 range_error)
128 range_error = 0;
129 }
130 else
131 {
132 bufr = att->data;
133 }
134
135 /* If the caller wants data, copy it for him. If he hasn't
136 allocated enough memory for it, he will burn in segmentation
137 fault hell, writhing with the agony of undiscovered memory
138 bugs! */
139 if (data)
140 {
141 if (att->vldata)
142 {
143 size_t base_typelen;
144 nc_hvl_t *vldest = data;
145 NC_TYPE_INFO_T *type;
146
147 /* Get the type object for the attribute's type */
148 if ((retval = nc4_find_type(h5, att->nc_typeid, &type)))
149 BAIL(retval);
150
151 /* Retrieve the size of the base type */
152 if ((retval = nc4_get_typelen_mem(h5, type->u.v.base_nc_typeid, &base_typelen)))
153 BAIL(retval);
154
155 for (i = 0; i < att->len; i++)
156 {
157 vldest[i].len = att->vldata[i].len;
158 if (!(vldest[i].p = malloc(vldest[i].len * base_typelen)))
159 BAIL(NC_ENOMEM);
160 memcpy(vldest[i].p, att->vldata[i].p, vldest[i].len * base_typelen);
161 }
162 }
163 else if (att->stdata)
164 {
165 for (i = 0; i < att->len; i++)
166 {
167 /* Check for NULL pointer for string (valid in HDF5) */
168 if(att->stdata[i])
169 {
170 if (!(((char **)data)[i] = strdup(att->stdata[i])))
171 BAIL(NC_ENOMEM);
172 }
173 else
174 ((char **)data)[i] = att->stdata[i];
175 }
176 }
177 else
178 {
179 memcpy(data, bufr, (size_t)(att->len * type_size));
180 }
181 }
182
183exit:
184 if (need_to_convert)
185 free(bufr);
186 if (range_error)
187 retval = NC_ERANGE;
188 return retval;
189}
190
212int
213nc4_get_att(int ncid, int varid, const char *name, nc_type *xtype,
214 nc_type mem_type, size_t *lenp, int *attnum, void *data)
215{
216 NC_FILE_INFO_T *h5;
217 NC_GRP_INFO_T *grp;
218 NC_VAR_INFO_T *var = NULL;
219 char norm_name[NC_MAX_NAME + 1];
220 int retval;
221
222 LOG((3, "%s: ncid 0x%x varid %d mem_type %d", __func__, ncid,
223 varid, mem_type));
224
225 /* Find info for this file, group, and h5 info. */
226 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
227 return retval;
228 assert(h5 && grp);
229
230 /* Check varid */
231 if (varid != NC_GLOBAL)
232 {
233 if (!(var = (NC_VAR_INFO_T*)ncindexith(grp->vars,varid)))
234 return NC_ENOTVAR;
235 assert(var->hdr.id == varid);
236 }
237
238 /* Name is required. */
239 if (!name)
240 return NC_EBADNAME;
241
242 /* Normalize name. */
243 if ((retval = nc4_normalize_name(name, norm_name)))
244 return retval;
245
246 return nc4_get_att_ptrs(h5, grp, var, norm_name, xtype, mem_type, lenp,
247 attnum, data);
248}
249
264int
265NC4_inq_att(int ncid, int varid, const char *name, nc_type *xtypep,
266 size_t *lenp)
267{
268 LOG((2, "%s: ncid 0x%x varid %d name %s", __func__, ncid, varid, name));
269 return nc4_get_att(ncid, varid, name, xtypep, NC_NAT, lenp, NULL, NULL);
270}
271
283int
284NC4_inq_attid(int ncid, int varid, const char *name, int *attnump)
285{
286 LOG((2, "%s: ncid 0x%x varid %d name %s", __func__, ncid, varid, name));
287 return nc4_get_att(ncid, varid, name, NULL, NC_NAT, NULL, attnump, NULL);
288}
289
302int
303NC4_inq_attname(int ncid, int varid, int attnum, char *name)
304{
305 NC_ATT_INFO_T *att;
306 int retval;
307
308 LOG((2, "nc_inq_attname: ncid 0x%x varid %d attnum %d", ncid, varid,
309 attnum));
310
311 /* Find the attribute metadata. */
312 if ((retval = nc4_find_nc_att(ncid, varid, NULL, attnum, &att)))
313 return retval;
314
315 /* Get the name. */
316 if (name)
317 strcpy(name, att->hdr.name);
318
319 return NC_NOERR;
320}
321
335int
336NC4_get_att(int ncid, int varid, const char *name, void *value, nc_type memtype)
337{
338 return nc4_get_att(ncid, varid, name, NULL, memtype, NULL, NULL, value);
339}
int NC4_inq_att(int ncid, int varid, const char *name, nc_type *xtypep, size_t *lenp)
Definition nc4attr.c:265
int NC4_inq_attid(int ncid, int varid, const char *name, int *attnump)
Definition nc4attr.c:284
int NC4_inq_attname(int ncid, int varid, int attnum, char *name)
Definition nc4attr.c:303
int nc4_get_att(int ncid, int varid, const char *name, nc_type *xtype, nc_type mem_type, size_t *lenp, int *attnum, void *data)
Definition nc4attr.c:213
int nc4_get_att_ptrs(NC_FILE_INFO_T *h5, NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, const char *name, nc_type *xtype, nc_type mem_type, size_t *lenp, int *attnum, void *data)
Definition nc4attr.c:46
int NC4_get_att(int ncid, int varid, const char *name, void *value, nc_type memtype)
Definition nc4attr.c:336
int nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum, NC_ATT_INFO_T **att)
int nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5)
int nc4_find_nc_att(int ncid, int varid, const char *name, int attnum, NC_ATT_INFO_T **att)
int nc4_normalize_name(const char *name, char *norm_name)
int nc4_find_type(const NC_FILE_INFO_T *h5, nc_type typeid, NC_TYPE_INFO_T **type)
int nc4_convert_type(const void *src, void *dest, const nc_type src_type, const nc_type dest_type, const size_t len, int *range_error, const void *fill_value, int strict_nc3)
Definition nc4var.c:465
int nc4_get_typelen_mem(NC_FILE_INFO_T *h5, nc_type xtype, size_t *len)
Definition nc4var.c:1417
#define NC_ECHAR
Attempt to convert between text & numbers.
Definition netcdf.h:391
#define NC_BYTE
signed 1 byte integer
Definition netcdf.h:35
#define NC_NAT
Not A Type.
Definition netcdf.h:34
#define NC_UBYTE
unsigned 1 byte int
Definition netcdf.h:42
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition netcdf.h:410
#define NC_GLOBAL
Attribute id to put/get a global attribute.
Definition netcdf.h:249
#define NC_ENOTVAR
Variable not found.
Definition netcdf.h:384
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
Definition netcdf.h:139
#define NC_MAX_NAME
Maximum for classic library.
Definition netcdf.h:276
#define NC_NOERR
No Error.
Definition netcdf.h:330
#define NC_EBADNAME
Attribute or variable name contains illegal characters.
Definition netcdf.h:402
#define NC_CHAR
ISO/ASCII character.
Definition netcdf.h:36
#define NC_ERANGE
Math result not representable.
Definition netcdf.h:409
int nc_type
The nc_type type is just an int.
Definition netcdf.h:25