NetCDF 4.9.3
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. */
18
19#include "nc.h"
20#include "nc4internal.h"
21#include "nc4dispatch.h"
22#include "ncdispatch.h"
23
46int
47nc4_get_att_ptrs(NC_FILE_INFO_T *h5, NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var,
48 const char *name, nc_type *xtype, nc_type mem_type,
49 size_t *lenp, int *attnum, void *data)
50{
51 NC_ATT_INFO_T *att = NULL;
52 int my_attnum = -1;
53 int need_to_convert = 0;
54 int range_error = NC_NOERR;
55 void *bufr = NULL;
56 size_t type_size;
57 int varid;
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 NC_NOQUANTIZE, 0)))
121 BAIL(retval);
122
123 /* For strict netcdf-3 rules, ignore erange errors between UBYTE
124 * and BYTE types. */
125 if ((h5->cmode & NC_CLASSIC_MODEL) &&
126 (att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE) &&
127 (mem_type == NC_UBYTE || mem_type == NC_BYTE) &&
128 range_error)
129 range_error = 0;
130 }
131 else
132 {
133 bufr = att->data;
134 }
135
136 /* If the caller wants data, copy it for him. If he hasn't
137 allocated enough memory for it, he will burn in segmentation
138 fault hell, writhing with the agony of undiscovered memory
139 bugs! */
140 if (data)
141 {
142 {
143 if((retval = NC_copy_data(h5->controller,mem_type,bufr,att->len,data)))
144 BAIL(retval);
145 }
146 }
147
148exit:
149 if (need_to_convert)
150 free(bufr);
151 if (range_error)
152 retval = NC_ERANGE;
153 return retval;
154}
155
177int
178nc4_get_att(int ncid, int varid, const char *name, nc_type *xtype,
179 nc_type mem_type, size_t *lenp, int *attnum, void *data)
180{
181 NC_FILE_INFO_T *h5;
182 NC_GRP_INFO_T *grp;
183 NC_VAR_INFO_T *var = NULL;
184 char norm_name[NC_MAX_NAME + 1];
185 int retval;
186
187 LOG((3, "%s: ncid 0x%x varid %d mem_type %d", __func__, ncid,
188 varid, mem_type));
189
190 /* Find info for this file, group, and h5 info. */
191 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
192 return retval;
193 assert(h5 && grp);
194
195 /* Check varid */
196 if (varid != NC_GLOBAL)
197 {
198 if (!(var = (NC_VAR_INFO_T*)ncindexith(grp->vars,(size_t)varid)))
199 return NC_ENOTVAR;
200 assert(var->hdr.id == varid);
201 }
202
203 /* Name is required. */
204 if (!name)
205 return NC_EBADNAME;
206
207 /* Normalize name. */
208 if ((retval = nc4_normalize_name(name, norm_name)))
209 return retval;
210
211 return nc4_get_att_ptrs(h5, grp, var, norm_name, xtype, mem_type, lenp,
212 attnum, data);
213}
214
229int
230NC4_inq_att(int ncid, int varid, const char *name, nc_type *xtypep,
231 size_t *lenp)
232{
233 LOG((2, "%s: ncid 0x%x varid %d name %s", __func__, ncid, varid, name));
234 return nc4_get_att(ncid, varid, name, xtypep, NC_NAT, lenp, NULL, NULL);
235}
236
248int
249NC4_inq_attid(int ncid, int varid, const char *name, int *attnump)
250{
251 LOG((2, "%s: ncid 0x%x varid %d name %s", __func__, ncid, varid, name));
252 return nc4_get_att(ncid, varid, name, NULL, NC_NAT, NULL, attnump, NULL);
253}
254
267int
268NC4_inq_attname(int ncid, int varid, int attnum, char *name)
269{
270 NC_ATT_INFO_T *att;
271 int retval;
272
273 LOG((2, "nc_inq_attname: ncid 0x%x varid %d attnum %d", ncid, varid,
274 attnum));
275
276 /* Find the attribute metadata. */
277 if ((retval = nc4_find_nc_att(ncid, varid, NULL, attnum, &att)))
278 return retval;
279
280 /* Get the name. */
281 if (name)
282 strcpy(name, att->hdr.name);
283
284 return NC_NOERR;
285}
286
300int
301NC4_get_att(int ncid, int varid, const char *name, void *value, nc_type memtype)
302{
303 return nc4_get_att(ncid, varid, name, NULL, memtype, NULL, NULL, value);
304}
#define NC_ECHAR
Attempt to convert between text & numbers.
Definition netcdf.h:439
#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:458
#define NC_GLOBAL
Attribute id to put/get a global attribute.
Definition netcdf.h:264
#define NC_ENOTVAR
Variable not found.
Definition netcdf.h:432
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
Definition netcdf.h:149
#define NC_MAX_NAME
Maximum for classic library.
Definition netcdf.h:291
#define NC_NOERR
No Error.
Definition netcdf.h:378
#define NC_NOQUANTIZE
No quantization in use.
Definition netcdf.h:345
#define NC_EBADNAME
Attribute or variable name contains illegal characters.
Definition netcdf.h:450
#define NC_CHAR
ISO/ASCII character.
Definition netcdf.h:36
#define NC_ERANGE
Math result not representable.
Definition netcdf.h:457
int nc_type
The nc_type type is just an int.
Definition netcdf.h:25