1/** \file
2Attribute functions
3
4These functions read and write attributes.
5
6Copyright 2010 University Corporation for Atmospheric
7Research/Unidata. See \ref copyright file for more info.  */
8
9#include "ncdispatch.h"
10
11/** \name Getting Attributes
12
13Functions to get the values of attributes.
14 */
15/*! \{ */
16
17/*!
18\ingroup attributes
19Get an attribute of any type.
20
21The nc_get_att() functions works for any type of attribute, and must
22be used to get attributes of user-defined type. We recommend that they
23type safe versions of this function be used where possible.
24
25\param ncid NetCDF or group ID, from a previous call to nc_open(),
26nc_create(), nc_def_grp(), or associated inquiry functions such as
27nc_inq_ncid().
28
29\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL
30for a global attribute.
31
32\param name Attribute \ref object_name.
33
34\param value Pointer to location for returned attribute value(s). All
35elements of the vector of attribute values are returned, so you must
36allocate enough space to hold them. Before using the value as a C
37string, make sure it is null-terminated. Call nc_inq_attlen() first to
38find out the length of the attribute.
39
40\note See documentation for nc_get_att_string() regarding a special case where memory must be explicitly released.
41
42*/
43int
44nc_get_att(int ncid, int varid, const char *name, void *value)
45{
46   NCncp;
47   int stat = NC_NOERR;
48   nc_type xtype;
49
50   if ((stat = NC_check_id(ncid, &ncp)))
51      return stat;
52
53   /* Need to get the type */
54   if ((stat = nc_inq_atttype(ncidvaridname, &xtype)))
55      return stat;
56
57   TRACE(nc_get_att);
58   return ncp->dispatch->get_att(ncidvaridnamevaluextype);
59}
60/*! \} */
61
62/*!
63\ingroup attributes
64Get an attribute.
65
66This function gets an attribute from the netCDF file. The nc_get_att()
67function works with any type of data, including user defined types.
68
69\note The netCDF library reads all attributes into memory when the
70file is opened with nc_open(). Getting an attribute copies the value
71from the in-memory store, and does not incure any file I/O penalties.
72
73\param ncid NetCDF or group ID, from a previous call to nc_open(),
74nc_create(), nc_def_grp(), or associated inquiry functions such as
75nc_inq_ncid().
76
77\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL
78for a global attribute.
79
80\param name Attribute \ref object_name.
81
82\param value Pointer to location for returned attribute value(s). All
83elements of the vector of attribute values are returned, so you must
84allocate enough space to hold them. If you don't know how much
85space to reserve, call nc_inq_attlen() first to find out the length of
86the attribute.
87
88<h1>Example</h1>
89
90Here is an example using nc_get_att_double() to determine the values
91of a variable attribute named valid_range for a netCDF variable named
92rh and using nc_get_att_text() to read a global attribute named title
93in an existing netCDF dataset named foo.nc.
94
95In this example, it is assumed that we don't know how many values will
96be returned, but that we do know the types of the attributes. Hence,
97to allocate enough space to store them, we must first inquire about
98the length of the attributes.
99
100\code
101     #include <netcdf.h>
102        ...
103     int  status;
104     int  ncid;
105     int  rh_id;
106     int  vr_len, t_len;
107     double *vr_val;
108     char *title;
109     extern char *malloc()
110
111        ...
112     status = nc_open("foo.nc", NC_NOWRITE, &ncid);
113     if (status != NC_NOERR) handle_error(status);
114        ...
115     status = nc_inq_varid (ncid, "rh", &rh_id);
116     if (status != NC_NOERR) handle_error(status);
117        ...
118     status = nc_inq_attlen (ncid, rh_id, "valid_range", &vr_len);
119     if (status != NC_NOERR) handle_error(status);
120     status = nc_inq_attlen (ncid, NC_GLOBAL, "title", &t_len);
121     if (status != NC_NOERR) handle_error(status);
122
123     vr_val = (double *) malloc(vr_len * sizeof(double));
124     title = (char *) malloc(t_len + 1);
125
126     status = nc_get_att_double(ncid, rh_id, "valid_range", vr_val);
127     if (status != NC_NOERR) handle_error(status);
128     status = nc_get_att_text(ncid, NC_GLOBAL, "title", title);
129     if (status != NC_NOERR) handle_error(status);
130     title[t_len] = '\0';
131        ...
132\endcode
133*/
134/*! \{ */
135
136int
137nc_get_att_text(int ncid, int varid, const char *name, char *value)
138{
139   NCncp;
140   int stat = NC_check_id(ncid, &ncp);
141   if(stat != NC_NOERR) return stat;
142   TRACE(nc_get_att_text);
143   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_CHAR);
144}
145
146int
147nc_get_att_schar(int ncid, int varid, const char *name, signed char *value)
148{
149   NCncp;
150   int stat = NC_check_id(ncid, &ncp);
151   if(stat != NC_NOERR) return stat;
152   TRACE(nc_get_att_schar);
153   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_BYTE);
154}
155
156int
157nc_get_att_uchar(int ncid, int varid, const char *name, unsigned char *value)
158{
159   NCncp;
160   int stat = NC_check_id(ncid, &ncp);
161   if(stat != NC_NOERR) return stat;
162   TRACE(nc_get_att_uchar);
163   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_UBYTE);
164}
165
166int
167nc_get_att_short(int ncid, int varid, const char *name, short *value)
168{
169   NCncp;
170   int stat = NC_check_id(ncid, &ncp);
171   if(stat != NC_NOERR) return stat;
172   TRACE(nc_get_att_short);
173   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_SHORT);
174}
175
176int
177nc_get_att_int(int ncid, int varid, const char *name, int *value)
178{
179   NCncp;
180   int stat = NC_check_id(ncid, &ncp);
181   if(stat != NC_NOERR) return stat;
182   TRACE(nc_get_att_int);
183   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_INT);
184}
185
186int
187nc_get_att_long(int ncid, int varid, const char *name, long *value)
188{
189   NCncp;
190   int stat = NC_check_id(ncid, &ncp);
191   if(stat != NC_NOERR) return stat;
192   TRACE(nc_get_att_long);
193   return ncp->dispatch->get_att(ncidvaridname, (void *)valuelongtype);
194}
195
196int
197nc_get_att_float(int ncid, int varid, const char *name, float *value)
198{
199   NCncp;
200   int stat = NC_check_id(ncid, &ncp);
201   if(stat != NC_NOERR) return stat;
202   TRACE(nc_get_att_float);
203   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_FLOAT);
204}
205
206int
207nc_get_att_double(int ncid, int varid, const char *name, double *value)
208{
209   NCncp;
210   int stat = NC_check_id(ncid, &ncp);
211   if(stat != NC_NOERR) return stat;
212   TRACE(nc_get_att_double);
213   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_DOUBLE);
214}
215
216int
217nc_get_att_ubyte(int ncid, int varid, const char *name, unsigned char *value)
218{
219   NCncp;
220   int stat = NC_check_id(ncid, &ncp);
221   if(stat != NC_NOERR) return stat;
222   TRACE(nc_get_att_ubyte);
223   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_UBYTE);
224}
225
226int
227nc_get_att_ushort(int ncid, int varid, const char *name, unsigned short *value)
228{
229   NCncp;
230   int stat = NC_check_id(ncid, &ncp);
231   if(stat != NC_NOERR) return stat;
232   TRACE(nc_get_att_ushort);
233   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_USHORT);
234}
235
236int
237nc_get_att_uint(int ncid, int varid, const char *name, unsigned int *value)
238{
239   NCncp;
240   int stat = NC_check_id(ncid, &ncp);
241   if(stat != NC_NOERR) return stat;
242   TRACE(nc_get_att_uint);
243   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_UINT);
244}
245
246int
247nc_get_att_longlong(int ncid, int varid, const char *name, long long *value)
248{
249   NCncp;
250   int stat = NC_check_id(ncid, &ncp);
251   if(stat != NC_NOERR) return stat;
252   TRACE(nc_get_att_longlong);
253   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_INT64);
254}
255
256int
257nc_get_att_ulonglong(int ncid, int varid, const char *name, unsigned long long *value)
258{
259   NC *ncp;
260   int stat = NC_check_id(ncid, &ncp);
261   if(stat != NC_NOERR) return stat;
262   TRACE(nc_get_att_ulonglong);
263   return ncp->dispatch->get_att(ncidvaridname, (void *)valueNC_UINT64);
264}
265/*! \} */
266
267/*!
268\ingroup attributes
269Get a variable-length string attribute.
270
271This function gets an attribute from netCDF file. Thhe nc_get_att() function works with any type of data including user defined types, but this function will retrieve attributes which are of type variable-length string.
272
273\note Note that unlike most other nc_get_att functions, nc_get_att_string() allocates a chunk of memory which is returned to the calling function.  This chunk of memory must be specifically deallocated with nc_free_string() to avoid any memory leaks.  Also note that you must still preallocate the memory needed for the array of pointers passed to nc_get_att_string().
274
275\param ncid NetCDF or group ID, from a previous call to nc_open(),
276nc_create(), nc_def_grp(), or associated inquiry functions such as
277nc_inq_ncid().
278
279\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL
280for a global attribute.
281
282\param name Attribute \ref object_name.
283
284\param value Pointer to location for returned attribute value(s). All
285elements of the vector of attribute values are returned, so you must
286allocate enough space to hold them. If you don't know how much
287space to reserve, call nc_inq_attlen() first to find out the length of
288the attribute.
289
290\section nc_get_att_string_example Example
291
292\code{.c}
293#include <stdlib.h>
294#include <stdio.h>
295#include <string.h>
296
297#include <netcdf.h>
298
299void check(int stat) {
300  if (stat != NC_NOERR) {
301    printf("NetCDF error: %s\n", nc_strerror(stat));
302    exit(1);
303  }
304}
305
306int main(int argc, char ** argv) {
307  int stat = 0;
308
309  int ncid = 0;
310  stat = nc_open("test.nc", NC_NOWRITE, &ncid); check(stat);
311
312  int varid = 0;
313  stat = nc_inq_varid(ncid, "variable", &varid); check(stat);
314
315  size_t attlen = 0;
316  stat = nc_inq_attlen(ncid, varid, "attribute", &attlen); check(stat);
317
318  char **string_attr = (char**)malloc(attlen * sizeof(char*));
319  memset(string_attr, 0, attlen * sizeof(char*));
320
321  stat = nc_get_att_string(ncid, varid, "attribute", string_attr); check(stat);
322
323  for (size_t k = 0; k < attlen; ++k) {
324    printf("variable:attribute[%d] = %s\n", k, string_attr[k]);
325  }
326
327  stat = nc_free_string(attlen, string_attr); check(stat);
328
329  free(string_attr);
330
331  stat = nc_close(ncid); check(stat);
332
333  return 0;
334}
335\endcode
336
337
338*/
339
340int
341nc_get_att_string(int ncid, int varid, const char *name, char **value)
342{
343    NC *ncp;
344    int stat = NC_check_id(ncid, &ncp);
345    if(stat != NC_NOERR) return stat;
346    TRACE(nc_get_att_string);
347    return ncp->dispatch->get_att(ncid,varid,name,(void*)valueNC_STRING);
348}
349/*! \} */


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed