Coverage Report

Created: 2026-08-11 08:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/netcdf-c-4.7.4/libdispatch/dattget.c
Line
Count
Source
1
/* Copyright 2018 University Corporation for Atmospheric
2
   Research/Unidata. See copyright file for more info.  */
3
/**
4
 * @file
5
 * Attribute functions
6
 *
7
 * These functions in this file read attributes.
8
 */
9
10
#include "ncdispatch.h"
11
12
/**
13
 * @anchor getting_attributes
14
 * @name Getting Attributes
15
 *
16
 * Functions to get the values of attributes.
17
 *
18
 * For classic format files, the netCDF library reads all attributes
19
 * into memory when the file is opened with nc_open().
20
 *
21
 * For netCDF-4/HDF5 files, since version 4.7.2, attributes are not
22
 * read on file open. Instead, when the first read of a variable
23
 * attribute is done, all attributes for that variable are
24
 * read. Subsequent access to other attributes of that variable will
25
 * not incur a disk read. Similarly, when the first NC_GLOBAL
26
 * attribute is read in a group, all NC_GLOBAL attributes for that
27
 * group will be read.
28
 *
29
 * @note All elements attribute data array are returned, so you must
30
 * allocate enough space to hold them. If you don't know how much
31
 * space to reserve, call nc_inq_attlen() first to find out the length
32
 * of the attribute.
33
 */
34
/**@{*/  /* Start doxygen member group. */
35
36
/**
37
 * @ingroup attributes
38
 * Get an attribute of any type.
39
 *
40
 * The nc_get_att() function works for any type of attribute, and must
41
 * be used to get attributes of user-defined type. We recommend that
42
 * the type safe versions of this function be used for atomic data
43
 * types.
44
 *
45
 * Also see @ref getting_attributes "Getting Attributes"
46
 *
47
 * @param ncid NetCDF file or group ID.
48
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
49
 * @param name Attribute name.
50
 * @param value Pointer that will get array of attribute value(s). Use
51
 * nc_inq_attlen() to learn length.
52
 *
53
 * @note See documentation for nc_get_att_string() regarding a special
54
 * case where memory must be explicitly released.
55
 *
56
 * <h1>Example</h1>
57
 *
58
 * Here is an example using nc_get_att() from nc_test4/tst_vl.c
59
 * creates a VLEN attribute, then uses nc_get_att() to read it.
60
 *
61
@code
62
#define FILE_NAME "tst_vl.nc"
63
#define VLEN_NAME "vlen_name"
64
#define ATT_NAME "att_name"
65
66
      int ncid, typeid;
67
      nc_vlen_t data[DIM_LEN], data_in[DIM_LEN];
68
      ...
69
70
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
71
      if (nc_def_vlen(ncid, VLEN_NAME, NC_INT, &typeid)) ERR;
72
      ...
73
      if (nc_put_att(ncid, NC_GLOBAL, ATT_NAME, typeid, DIM_LEN, data)) ERR;
74
      if (nc_close(ncid)) ERR;
75
76
      ...
77
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
78
      if (nc_get_att(ncid, NC_GLOBAL, ATT_NAME, data_in)) ERR;
79
      ...
80
      if (nc_close(ncid)) ERR;
81
@endcode
82
83
 * @return ::NC_NOERR for success.
84
 * @return ::NC_EBADID Bad ncid.
85
 * @return ::NC_ENOTVAR Bad varid.
86
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
87
 * @return ::NC_EINVAL Invalid parameters.
88
 * @return ::NC_ENOTATT Can't find attribute.
89
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
90
 * @return ::NC_ENOMEM Out of memory.
91
 * @return ::NC_ERANGE Data conversion went out of range.
92
 *
93
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
94
*/
95
int
96
nc_get_att(int ncid, int varid, const char *name, void *value)
97
14.0k
{
98
14.0k
   NC* ncp;
99
14.0k
   int stat = NC_NOERR;
100
14.0k
   nc_type xtype;
101
102
14.0k
   if ((stat = NC_check_id(ncid, &ncp)))
103
0
      return stat;
104
105
   /* Need to get the type */
106
14.0k
   if ((stat = nc_inq_atttype(ncid, varid, name, &xtype)))
107
0
      return stat;
108
109
14.0k
   TRACE(nc_get_att);
110
14.0k
   return ncp->dispatch->get_att(ncid, varid, name, value, xtype);
111
14.0k
}
112
113
/**
114
 * @ingroup attributes
115
 * Get a text attribute.
116
 *
117
 * This function gets a text attribute from the netCDF
118
 * file. Type conversions are not permitted.
119
 *
120
 * Also see @ref getting_attributes "Getting Attributes"
121
 *
122
 * @param ncid NetCDF file or group ID.
123
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
124
 * @param name Attribute name.
125
 * @param value Pointer that will get array of attribute value(s). Use
126
 * nc_inq_attlen() to learn length.
127
 *
128
 * @note The handling of NULL terminators is not specified by
129
 * netCDF. C programs can write attributes with or without NULL
130
 * terminators. It is up to the reader to know whether NULL
131
 * terminators have been used, and, if not, to add a NULL terminator
132
 * when reading text attributes.
133
 *
134
 * <h1>Example</h1>
135
 *
136
 * Here is an example using nc_get_att_text() to read a global
137
 * attribute named title in an existing netCDF dataset named foo.nc.
138
 *
139
 * In this example we learn the length of the attribute, so that an
140
 * array may be allocated, adding 1 in case a NULL terminator is
141
 * needed. We then take the precaution of setting the last element of
142
 * the array to 0, to NULL terminate the string. If a NULL terminator
143
 * was written with this attribute, strlen(title) will show the
144
 * correct length (the number of chars before the first NULL
145
 * terminator).
146
147
@code
148
     #include <netcdf.h>
149
        ...
150
     int  status;
151
     int  ncid;
152
     int  rh_id;
153
     int  t_len;
154
     char *title;
155
156
        ...
157
     status = nc_open("foo.nc", NC_NOWRITE, &ncid);
158
     if (status != NC_NOERR) handle_error(status);
159
        ...
160
     status = nc_inq_varid (ncid, "rh", &rh_id);
161
     if (status != NC_NOERR) handle_error(status);
162
        ...
163
     status = nc_inq_attlen (ncid, NC_GLOBAL, "title", &t_len);
164
     if (status != NC_NOERR) handle_error(status);
165
166
     title = (char *) malloc(t_len + 1);
167
     status = nc_get_att_text(ncid, NC_GLOBAL, "title", title);
168
     if (status != NC_NOERR) handle_error(status);
169
     title[t_len] = '\0';
170
        ...
171
@endcode
172
 *
173
 * @return ::NC_NOERR for success.
174
 * @return ::NC_EBADID Bad ncid.
175
 * @return ::NC_ENOTVAR Bad varid.
176
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
177
 * @return ::NC_EINVAL Invalid parameters.
178
 * @return ::NC_ENOTATT Can't find attribute.
179
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
180
 * @return ::NC_ENOMEM Out of memory.
181
 * @return ::NC_ERANGE Data conversion went out of range.
182
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
183
*/
184
int
185
nc_get_att_text(int ncid, int varid, const char *name, char *value)
186
79.7k
{
187
79.7k
   NC* ncp;
188
79.7k
   int stat = NC_check_id(ncid, &ncp);
189
79.7k
   if(stat != NC_NOERR) return stat;
190
79.7k
   TRACE(nc_get_att_text);
191
79.7k
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_CHAR);
192
79.7k
}
193
194
/**
195
 * @ingroup attributes
196
 * Get an attribute of an signed char type.
197
 *
198
 * Also see @ref getting_attributes "Getting Attributes"
199
 *
200
 * @param ncid NetCDF file or group ID.
201
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
202
 * @param name Attribute name.
203
 * @param value Pointer that will get array of attribute value(s). Use
204
 * nc_inq_attlen() to learn length.
205
 *
206
 * @return ::NC_NOERR for success.
207
 * @return ::NC_EBADID Bad ncid.
208
 * @return ::NC_ENOTVAR Bad varid.
209
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
210
 * @return ::NC_EINVAL Invalid parameters.
211
 * @return ::NC_ENOTATT Can't find attribute.
212
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
213
 * @return ::NC_ENOMEM Out of memory.
214
 * @return ::NC_ERANGE Data conversion went out of range.
215
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
216
 */
217
int
218
nc_get_att_schar(int ncid, int varid, const char *name, signed char *value)
219
14.4k
{
220
14.4k
   NC* ncp;
221
14.4k
   int stat = NC_check_id(ncid, &ncp);
222
14.4k
   if(stat != NC_NOERR) return stat;
223
14.4k
   TRACE(nc_get_att_schar);
224
14.4k
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_BYTE);
225
14.4k
}
226
227
/**
228
 * @ingroup attributes
229
 * Get an attribute of an atomic type.
230
 *
231
 * Also see @ref getting_attributes "Getting Attributes"
232
 *
233
 * This function gets an attribute of an atomic type from the netCDF
234
 * file.
235
 *
236
 * @param ncid NetCDF or group ID, from a previous call to nc_open(),
237
 * nc_create(), nc_def_grp(), or associated inquiry functions such as
238
 * nc_inq_ncid().
239
 * @param varid Variable ID of the attribute's variable, or
240
 * ::NC_GLOBAL for a global attribute.
241
 * @param name Attribute name.
242
 * @param value Pointer that will get array of attribute value(s). Use
243
 * nc_inq_attlen() to learn length.
244
 *
245
 * <h1>Example</h1>
246
 *
247
 * Here is an example using nc_get_att_double() to determine the
248
 * values of a variable attribute named valid_range for a netCDF
249
 * variable named rh from a netCDF dataset named foo.nc.
250
 *
251
 * In this example, it is assumed that we don't know how many values
252
 * will be returned, but that we do know the types of the
253
 * attributes. Hence, to allocate enough space to store them, we must
254
 * first inquire about the length of the attributes.
255
256
@code
257
     #include <netcdf.h>
258
        ...
259
     int  status;
260
     int  ncid;
261
     int  rh_id;
262
     int  vr_len;
263
     double *vr_val;
264
265
        ...
266
     status = nc_open("foo.nc", NC_NOWRITE, &ncid);
267
     if (status != NC_NOERR) handle_error(status);
268
        ...
269
     status = nc_inq_varid (ncid, "rh", &rh_id);
270
     if (status != NC_NOERR) handle_error(status);
271
        ...
272
     status = nc_inq_attlen (ncid, rh_id, "valid_range", &vr_len);
273
     if (status != NC_NOERR) handle_error(status);
274
275
     vr_val = (double *) malloc(vr_len * sizeof(double));
276
277
     status = nc_get_att_double(ncid, rh_id, "valid_range", vr_val);
278
     if (status != NC_NOERR) handle_error(status);
279
        ...
280
@endcode
281
282
 * @return ::NC_NOERR for success.
283
 * @return ::NC_EBADID Bad ncid.
284
 * @return ::NC_ENOTVAR Bad varid.
285
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
286
 * @return ::NC_EINVAL Invalid parameters.
287
 * @return ::NC_ENOTATT Can't find attribute.
288
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
289
 * @return ::NC_ENOMEM Out of memory.
290
 * @return ::NC_ERANGE Data conversion went out of range.
291
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
292
*/
293
294
/**
295
 * @ingroup attributes
296
 * Get an attribute of an signed char type.
297
 *
298
 * Also see @ref getting_attributes "Getting Attributes"
299
 *
300
 * @param ncid NetCDF file or group ID.
301
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
302
 * @param name Attribute name.
303
 * @param value Pointer that will get array of attribute value(s). Use
304
 * nc_inq_attlen() to learn length.
305
 *
306
 * @return ::NC_NOERR for success.
307
 * @return ::NC_EBADID Bad ncid.
308
 * @return ::NC_ENOTVAR Bad varid.
309
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
310
 * @return ::NC_EINVAL Invalid parameters.
311
 * @return ::NC_ENOTATT Can't find attribute.
312
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
313
 * @return ::NC_ENOMEM Out of memory.
314
 * @return ::NC_ERANGE Data conversion went out of range.
315
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
316
 */
317
int
318
nc_get_att_uchar(int ncid, int varid, const char *name, unsigned char *value)
319
0
{
320
0
   NC* ncp;
321
0
   int stat = NC_check_id(ncid, &ncp);
322
0
   if(stat != NC_NOERR) return stat;
323
0
   TRACE(nc_get_att_uchar);
324
0
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UBYTE);
325
0
}
326
327
/**
328
 * @ingroup attributes
329
 * Get an attribute array of type short.
330
 *
331
 * Also see @ref getting_attributes "Getting Attributes"
332
 *
333
 * @param ncid NetCDF file or group ID.
334
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
335
 * @param name Attribute name.
336
 * @param value Pointer that will get array of attribute value(s). Use
337
 * nc_inq_attlen() to learn length.
338
 *
339
 * @return ::NC_NOERR for success.
340
 * @return ::NC_EBADID Bad ncid.
341
 * @return ::NC_ENOTVAR Bad varid.
342
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
343
 * @return ::NC_EINVAL Invalid parameters.
344
 * @return ::NC_ENOTATT Can't find attribute.
345
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
346
 * @return ::NC_ENOMEM Out of memory.
347
 * @return ::NC_ERANGE Data conversion went out of range.
348
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
349
 */
350
int
351
nc_get_att_short(int ncid, int varid, const char *name, short *value)
352
19.5k
{
353
19.5k
   NC* ncp;
354
19.5k
   int stat = NC_check_id(ncid, &ncp);
355
19.5k
   if(stat != NC_NOERR) return stat;
356
19.5k
   TRACE(nc_get_att_short);
357
19.5k
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_SHORT);
358
19.5k
}
359
360
/**
361
 * @ingroup attributes
362
 * Get an attribute array of type int.
363
 *
364
 * Also see @ref getting_attributes "Getting Attributes"
365
 *
366
 * @param ncid NetCDF file or group ID.
367
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
368
 * @param name Attribute name.
369
 * @param value Pointer that will get array of attribute value(s). Use
370
 * nc_inq_attlen() to learn length.
371
 *
372
 * @return ::NC_NOERR for success.
373
 * @return ::NC_EBADID Bad ncid.
374
 * @return ::NC_ENOTVAR Bad varid.
375
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
376
 * @return ::NC_EINVAL Invalid parameters.
377
 * @return ::NC_ENOTATT Can't find attribute.
378
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
379
 * @return ::NC_ENOMEM Out of memory.
380
 * @return ::NC_ERANGE Data conversion went out of range.
381
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
382
 */
383
int
384
nc_get_att_int(int ncid, int varid, const char *name, int *value)
385
79.6k
{
386
79.6k
   NC* ncp;
387
79.6k
   int stat = NC_check_id(ncid, &ncp);
388
79.6k
   if(stat != NC_NOERR) return stat;
389
79.6k
   TRACE(nc_get_att_int);
390
79.6k
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_INT);
391
79.6k
}
392
393
/**
394
 * @ingroup attributes
395
 * Get an attribute array of type long.
396
 *
397
 * Also see @ref getting_attributes "Getting Attributes"
398
 *
399
 * @param ncid NetCDF file or group ID.
400
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
401
 * @param name Attribute name.
402
 * @param value Pointer that will get array of attribute value(s). Use
403
 * nc_inq_attlen() to learn length.
404
 *
405
 * @return ::NC_NOERR for success.
406
 * @return ::NC_EBADID Bad ncid.
407
 * @return ::NC_ENOTVAR Bad varid.
408
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
409
 * @return ::NC_EINVAL Invalid parameters.
410
 * @return ::NC_ENOTATT Can't find attribute.
411
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
412
 * @return ::NC_ENOMEM Out of memory.
413
 * @return ::NC_ERANGE Data conversion went out of range.
414
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
415
 */
416
int
417
nc_get_att_long(int ncid, int varid, const char *name, long *value)
418
0
{
419
0
   NC* ncp;
420
0
   int stat = NC_check_id(ncid, &ncp);
421
0
   if(stat != NC_NOERR) return stat;
422
0
   TRACE(nc_get_att_long);
423
0
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, longtype);
424
0
}
425
426
/**
427
 * @ingroup attributes
428
 * Get an attribute array of type float.
429
 *
430
 * Also see @ref getting_attributes "Getting Attributes"
431
 *
432
 * @param ncid NetCDF file or group ID.
433
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
434
 * @param name Attribute name.
435
 * @param value Pointer that will get array of attribute value(s). Use
436
 * nc_inq_attlen() to learn length.
437
 *
438
 * @return ::NC_NOERR for success.
439
 * @return ::NC_EBADID Bad ncid.
440
 * @return ::NC_ENOTVAR Bad varid.
441
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
442
 * @return ::NC_EINVAL Invalid parameters.
443
 * @return ::NC_ENOTATT Can't find attribute.
444
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
445
 * @return ::NC_ENOMEM Out of memory.
446
 * @return ::NC_ERANGE Data conversion went out of range.
447
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
448
 */
449
int
450
nc_get_att_float(int ncid, int varid, const char *name, float *value)
451
0
{
452
0
   NC* ncp;
453
0
   int stat = NC_check_id(ncid, &ncp);
454
0
   if(stat != NC_NOERR) return stat;
455
0
   TRACE(nc_get_att_float);
456
0
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_FLOAT);
457
0
}
458
459
/**
460
 * @ingroup attributes
461
 * Get an attribute array of type double.
462
 *
463
 * Also see @ref getting_attributes "Getting Attributes"
464
 *
465
 * @param ncid NetCDF file or group ID.
466
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
467
 * @param name Attribute name.
468
 * @param value Pointer that will get array of attribute value(s). Use
469
 * nc_inq_attlen() to learn length.
470
 *
471
 * @return ::NC_NOERR for success.
472
 * @return ::NC_EBADID Bad ncid.
473
 * @return ::NC_ENOTVAR Bad varid.
474
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
475
 * @return ::NC_EINVAL Invalid parameters.
476
 * @return ::NC_ENOTATT Can't find attribute.
477
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
478
 * @return ::NC_ENOMEM Out of memory.
479
 * @return ::NC_ERANGE Data conversion went out of range.
480
 * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
481
 */
482
int
483
nc_get_att_double(int ncid, int varid, const char *name, double *value)
484
11.7k
{
485
11.7k
   NC* ncp;
486
11.7k
   int stat = NC_check_id(ncid, &ncp);
487
11.7k
   if(stat != NC_NOERR) return stat;
488
11.7k
   TRACE(nc_get_att_double);
489
11.7k
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_DOUBLE);
490
11.7k
}
491
492
/**
493
 * @ingroup attributes
494
 * Get an attribute array of type unsigned char.
495
 *
496
 * Also see @ref getting_attributes "Getting Attributes"
497
 *
498
 * @param ncid NetCDF file or group ID.
499
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
500
 * @param name Attribute name.
501
 * @param value Pointer that will get array of attribute value(s). Use
502
 * nc_inq_attlen() to learn length.
503
 *
504
 * @return ::NC_NOERR for success.
505
 * @return ::NC_EBADID Bad ncid.
506
 * @return ::NC_ENOTVAR Bad varid.
507
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
508
 * @return ::NC_EINVAL Invalid parameters.
509
 * @return ::NC_ENOTATT Can't find attribute.
510
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
511
 * @return ::NC_ENOMEM Out of memory.
512
 * @return ::NC_ERANGE Data conversion went out of range.
513
 * @author Ed Hartnett, Dennis Heimbigner
514
 */
515
int
516
nc_get_att_ubyte(int ncid, int varid, const char *name, unsigned char *value)
517
0
{
518
0
   NC* ncp;
519
0
   int stat = NC_check_id(ncid, &ncp);
520
0
   if(stat != NC_NOERR) return stat;
521
0
   TRACE(nc_get_att_ubyte);
522
0
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UBYTE);
523
0
}
524
525
/**
526
 * @ingroup attributes
527
 * Get an attribute array of type unsigned short.
528
 *
529
 * Also see @ref getting_attributes "Getting Attributes"
530
 *
531
 * @param ncid NetCDF file or group ID.
532
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
533
 * @param name Attribute name.
534
 * @param value Pointer that will get array of attribute value(s). Use
535
 * nc_inq_attlen() to learn length.
536
 *
537
 * @return ::NC_NOERR for success.
538
 * @return ::NC_EBADID Bad ncid.
539
 * @return ::NC_ENOTVAR Bad varid.
540
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
541
 * @return ::NC_EINVAL Invalid parameters.
542
 * @return ::NC_ENOTATT Can't find attribute.
543
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
544
 * @return ::NC_ENOMEM Out of memory.
545
 * @return ::NC_ERANGE Data conversion went out of range.
546
 * @author Ed Hartnett, Dennis Heimbigner
547
 */
548
int
549
nc_get_att_ushort(int ncid, int varid, const char *name, unsigned short *value)
550
0
{
551
0
   NC* ncp;
552
0
   int stat = NC_check_id(ncid, &ncp);
553
0
   if(stat != NC_NOERR) return stat;
554
0
   TRACE(nc_get_att_ushort);
555
0
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_USHORT);
556
0
}
557
558
/**
559
 * @ingroup attributes
560
 * Get an attribute array of type unsigned int.
561
 *
562
 * Also see @ref getting_attributes "Getting Attributes"
563
 *
564
 * @param ncid NetCDF file or group ID.
565
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
566
 * @param name Attribute name.
567
 * @param value Pointer that will get array of attribute value(s). Use
568
 * nc_inq_attlen() to learn length.
569
 *
570
 * @return ::NC_NOERR for success.
571
 * @return ::NC_EBADID Bad ncid.
572
 * @return ::NC_ENOTVAR Bad varid.
573
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
574
 * @return ::NC_EINVAL Invalid parameters.
575
 * @return ::NC_ENOTATT Can't find attribute.
576
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
577
 * @return ::NC_ENOMEM Out of memory.
578
 * @return ::NC_ERANGE Data conversion went out of range.
579
 * @author Ed Hartnett, Dennis Heimbigner
580
 */
581
int
582
nc_get_att_uint(int ncid, int varid, const char *name, unsigned int *value)
583
0
{
584
0
   NC* ncp;
585
0
   int stat = NC_check_id(ncid, &ncp);
586
0
   if(stat != NC_NOERR) return stat;
587
0
   TRACE(nc_get_att_uint);
588
0
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UINT);
589
0
}
590
591
/**
592
 * @ingroup attributes
593
 * Get an attribute array of type long long.
594
 *
595
 * Also see @ref getting_attributes "Getting Attributes"
596
 *
597
 * @param ncid NetCDF file or group ID.
598
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
599
 * @param name Attribute name.
600
 * @param value Pointer that will get array of attribute value(s). Use
601
 * nc_inq_attlen() to learn length.
602
 *
603
 * @return ::NC_NOERR for success.
604
 * @return ::NC_EBADID Bad ncid.
605
 * @return ::NC_ENOTVAR Bad varid.
606
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
607
 * @return ::NC_EINVAL Invalid parameters.
608
 * @return ::NC_ENOTATT Can't find attribute.
609
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
610
 * @return ::NC_ENOMEM Out of memory.
611
 * @return ::NC_ERANGE Data conversion went out of range.
612
 * @author Ed Hartnett, Dennis Heimbigner
613
 */
614
int
615
nc_get_att_longlong(int ncid, int varid, const char *name, long long *value)
616
0
{
617
0
   NC* ncp;
618
0
   int stat = NC_check_id(ncid, &ncp);
619
0
   if(stat != NC_NOERR) return stat;
620
0
   TRACE(nc_get_att_longlong);
621
0
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_INT64);
622
0
}
623
624
/**
625
 * @ingroup attributes
626
 * Get an attribute array of type unsigned long long.
627
 *
628
 * Also see @ref getting_attributes "Getting Attributes"
629
 *
630
 * @param ncid NetCDF file or group ID.
631
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
632
 * @param name Attribute name.
633
 * @param value Pointer that will get array of attribute value(s). Use
634
 * nc_inq_attlen() to learn length.
635
 *
636
 * @return ::NC_NOERR for success.
637
 * @return ::NC_EBADID Bad ncid.
638
 * @return ::NC_ENOTVAR Bad varid.
639
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
640
 * @return ::NC_EINVAL Invalid parameters.
641
 * @return ::NC_ENOTATT Can't find attribute.
642
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
643
 * @return ::NC_ENOMEM Out of memory.
644
 * @return ::NC_ERANGE Data conversion went out of range.
645
 * @author Ed Hartnett, Dennis Heimbigner
646
 */
647
int
648
nc_get_att_ulonglong(int ncid, int varid, const char *name, unsigned long long *value)
649
0
{
650
0
   NC *ncp;
651
0
   int stat = NC_check_id(ncid, &ncp);
652
0
   if(stat != NC_NOERR) return stat;
653
0
   TRACE(nc_get_att_ulonglong);
654
0
   return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UINT64);
655
0
}
656
657
/**
658
 * @ingroup attributes
659
 * Get an attribute array of type string.
660
 *
661
 * This function gets an attribute from netCDF file. The nc_get_att()
662
 * function works with any type of data including user defined types,
663
 * but this function will retrieve attributes which are of type
664
 * variable-length string.
665
 *
666
 * Also see @ref getting_attributes "Getting Attributes"
667
 *
668
 * @note Note that unlike most other nc_get_att functions,
669
 * nc_get_att_string() allocates a chunk of memory which is returned
670
 * to the calling function.  This chunk of memory must be specifically
671
 * deallocated with nc_free_string() to avoid any memory leaks.  Also
672
 * note that you must still preallocate the memory needed for the
673
 * array of pointers passed to nc_get_att_string().
674
 *
675
 * @param ncid NetCDF file or group ID.
676
 * @param varid Variable ID, or ::NC_GLOBAL for a global attribute.
677
 * @param name Attribute name.
678
 * @param value Pointer that will get array of attribute value(s). Use
679
 * nc_inq_attlen() to learn length.
680
 *
681
 * @section nc_get_att_string_example Example
682
 *
683
@code{.c}
684
#include <stdlib.h>
685
#include <stdio.h>
686
#include <string.h>
687
688
#include <netcdf.h>
689
690
void check(int stat) {
691
  if (stat != NC_NOERR) {
692
    printf("NetCDF error: %s\n", nc_strerror(stat));
693
    exit(1);
694
  }
695
}
696
697
int main(int argc, char ** argv) {
698
  int stat = 0;
699
700
  int ncid = 0;
701
  stat = nc_open("test.nc", NC_NOWRITE, &ncid); check(stat);
702
703
  int varid = 0;
704
  stat = nc_inq_varid(ncid, "variable", &varid); check(stat);
705
706
  size_t attlen = 0;
707
  stat = nc_inq_attlen(ncid, varid, "attribute", &attlen); check(stat);
708
709
  char **string_attr = (char**)malloc(attlen * sizeof(char*));
710
  memset(string_attr, 0, attlen * sizeof(char*));
711
712
  stat = nc_get_att_string(ncid, varid, "attribute", string_attr); check(stat);
713
714
  for (size_t k = 0; k < attlen; ++k) {
715
    printf("variable:attribute[%d] = %s\n", k, string_attr[k]);
716
  }
717
718
  stat = nc_free_string(attlen, string_attr); check(stat);
719
720
  free(string_attr);
721
722
  stat = nc_close(ncid); check(stat);
723
724
  return 0;
725
}
726
@endcode
727
728
 * @return ::NC_NOERR for success.
729
 * @return ::NC_EBADID Bad ncid.
730
 * @return ::NC_ENOTVAR Bad varid.
731
 * @return ::NC_EBADNAME Bad name. See \ref object_name.
732
 * @return ::NC_EINVAL Invalid parameters.
733
 * @return ::NC_ENOTATT Can't find attribute.
734
 * @return ::NC_ECHAR Can't convert to or from NC_CHAR.
735
 * @return ::NC_ENOMEM Out of memory.
736
 * @return ::NC_ERANGE Data conversion went out of range.
737
 *
738
 * @author Ed Hartnett, Dennis Heimbigner
739
 */
740
int
741
nc_get_att_string(int ncid, int varid, const char *name, char **value)
742
0
{
743
0
    NC *ncp;
744
0
    int stat = NC_check_id(ncid, &ncp);
745
0
    if(stat != NC_NOERR) return stat;
746
0
    TRACE(nc_get_att_string);
747
0
    return ncp->dispatch->get_att(ncid,varid,name,(void*)value, NC_STRING);
748
0
}
749
/**@}*/  /* End doxygen member group. */