Skip to content

Commit

Permalink
Addressed github issue #171
Browse files Browse the repository at this point in the history
  • Loading branch information
WardF committed Dec 8, 2015
1 parent 9c4777c commit 9909221
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 15 deletions.
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ This file contains a high-level description of this package's evolution. Release

## 4.4.0 Released TBD

* Updated documentation for `nc_get_att_string()` to reflect the fact that it returns allocated memory which must be explicitly free'd using `nc_free_string()`. Reported by Constantine Khroulev, see [GitHub Issue 171](https://github.com/Unidata/netcdf-c/issues/171) for more information.

* Modified ncgen to properly handle the L and UL suffixes for integer constants
to keep backward compatibility. Now it is the case the single L suffix
(e.g. 111L) is treated as a 32 bit integer. This makes it consistent with
Expand Down
105 changes: 90 additions & 15 deletions libdispatch/dattget.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ be used to get attributes of user-defined type. We recommend that they
type safe versions of this function be used where possible.
\param ncid NetCDF or group ID, from a previous call to nc_open(),
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL
Expand All @@ -36,6 +36,9 @@ elements of the vector of attribute values are returned, so you must
allocate enough space to hold them. Before using the value as a C
string, make sure it is null-terminated. Call nc_inq_attlen() first to
find out the length of the attribute.
\note See documentation for nc_get_att_string() regarding a special case where memory must be explicitly released.
*/
int
nc_get_att(int ncid, int varid, const char *name, void *value)
Expand All @@ -53,7 +56,7 @@ nc_get_att(int ncid, int varid, const char *name, void *value)

return ncp->dispatch->get_att(ncid, varid, name, value, xtype);
}
/*! \} */
/*! \} */

/*!
\ingroup attributes
Expand All @@ -67,7 +70,7 @@ file is opened with nc_open(). Getting an attribute copies the value
from the in-memory store, and does not incure any file I/O penalties.
\param ncid NetCDF or group ID, from a previous call to nc_open(),
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL
Expand Down Expand Up @@ -96,14 +99,14 @@ the length of the attributes.
\code
#include <netcdf.h>
...
int status;
int ncid;
int rh_id;
int vr_len, t_len;
double *vr_val;
char *title;
int status;
int ncid;
int rh_id;
int vr_len, t_len;
double *vr_val;
char *title;
extern char *malloc()
...
status = nc_open("foo.nc", NC_NOWRITE, &ncid);
if (status != NC_NOERR) handle_error(status);
Expand All @@ -115,15 +118,15 @@ the length of the attributes.
if (status != NC_NOERR) handle_error(status);
status = nc_inq_attlen (ncid, NC_GLOBAL, "title", &t_len);
if (status != NC_NOERR) handle_error(status);
vr_val = (double *) malloc(vr_len * sizeof(double));
title = (char *) malloc(t_len + 1);
title = (char *) malloc(t_len + 1);
status = nc_get_att_double(ncid, rh_id, "valid_range", vr_val);
if (status != NC_NOERR) handle_error(status);
status = nc_get_att_text(ncid, NC_GLOBAL, "title", title);
if (status != NC_NOERR) handle_error(status);
title[t_len] = '\0';
title[t_len] = '\0';
...
\endcode
*/
Expand Down Expand Up @@ -244,7 +247,80 @@ nc_get_att_ulonglong(int ncid, int varid, const char *name, unsigned long long *
if(stat != NC_NOERR) return stat;
return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UINT64);
}
/*! \} */

/*!
\ingroup attributes
Get a variable-length string attribute.
This 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.
\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().
\param ncid NetCDF or group ID, from a previous call to nc_open(),
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL
for a global attribute.
\param name Attribute \ref object_name.
\param value Pointer to location for returned attribute value(s). All
elements of the vector of attribute values are returned, so you must
allocate enough space to hold them. If you don't know how much
space to reserve, call nc_inq_attlen() first to find out the length of
the attribute.
\section nc_get_att_string_example Example
\code{.c}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netcdf.h>
void check(int stat) {
if (stat != NC_NOERR) {
printf("NetCDF error: %s\n", nc_strerror(stat));
exit(1);
}
}
int main(int argc, char ** argv) {
int stat = 0;
int ncid = 0;
stat = nc_open("test.nc", NC_NOWRITE, &ncid); check(stat);
int varid = 0;
stat = nc_inq_varid(ncid, "variable", &varid); check(stat);
size_t attlen = 0;
stat = nc_inq_attlen(ncid, varid, "attribute", &attlen); check(stat);
char **string_attr = (char**)malloc(attlen * sizeof(char*));
memset(string_attr, 0, attlen * sizeof(char*));
stat = nc_get_att_string(ncid, varid, "attribute", string_attr); check(stat);
for (size_t k = 0; k < attlen; ++k) {
printf("variable:attribute[%d] = %s\n", k, string_attr[k]);
}
stat = nc_free_string(attlen, string_attr); check(stat);
free(string_attr);
stat = nc_close(ncid); check(stat);
return 0;
}
\endcode
*/
int
nc_get_att_string(int ncid, int varid, const char *name, char **value)
{
Expand All @@ -253,4 +329,3 @@ nc_get_att_string(int ncid, int varid, const char *name, char **value)
if(stat != NC_NOERR) return stat;
return ncp->dispatch->get_att(ncid,varid,name,(void*)value, NC_STRING);
}
/*! \} */

0 comments on commit 9909221

Please sign in to comment.