Coverage Report

Created: 2023-05-28 06:42

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