diff --git a/.travis.yml b/.travis.yml
index 240cb48193..3dc594ff66 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,4 +37,4 @@ before_install:
script:
- - docker run --rm -it -h "$CURHOST" -e USEDASH=FALSE -e RUNF=OFF -e RUNCXX=OFF -e RUNP=OFF -e RUNNCO=OFF -e USECMAKE=$USECMAKE -e USEAC=$USEAC -e DISTCHECK=$DISTCHECK -e COPTS="$COPTS" -e AC_OPTS="$AC_OPTS" -e CTEST_OUTPUT_ON_FAILURE=1 -v $(pwd):/netcdf-c -e USE_LOCAL_CP=$USECP -e TESTPROC=100 -e ENABLE_FILTER_TESTING=$TESTFILTER $DOCKIMG
+ - docker run --privileged --rm -it -h "$CURHOST" -e USEDASH=FALSE -e RUNF=OFF -e RUNCXX=OFF -e RUNP=OFF -e RUNNCO=OFF -e USECMAKE=$USECMAKE -e USEAC=$USEAC -e DISTCHECK=$DISTCHECK -e COPTS="$COPTS" -e AC_OPTS="$AC_OPTS" -e CTEST_OUTPUT_ON_FAILURE=1 -v $(pwd):/netcdf-c -e USE_LOCAL_CP=$USECP -e TESTPROC=100 -e ENABLE_FILTER_TESTING=$TESTFILTER -e ENABLE_C_MEMCHECK=OFF $DOCKIMG
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c998aa54f7..4d79f4fd68 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,13 +26,13 @@ set(PACKAGE "netCDF" CACHE STRING "")
SET(NC_VERSION_MAJOR 4)
SET(NC_VERSION_MINOR 6)
-SET(NC_VERSION_PATCH 3)
+SET(NC_VERSION_PATCH 4)
SET(NC_VERSION_NOTE "-development")
SET(netCDF_VERSION ${NC_VERSION_MAJOR}.${NC_VERSION_MINOR}.${NC_VERSION_PATCH}${NC_VERSION_NOTE})
SET(VERSION ${netCDF_VERSION})
SET(NC_VERSION ${netCDF_VERSION})
-SET(netCDF_LIB_VERSION 13)
-SET(netCDF_SO_VERSION 13)
+SET(netCDF_LIB_VERSION 15)
+SET(netCDF_SO_VERSION 15)
SET(PACKAGE_VERSION ${VERSION})
# Get system configuration, Use it to determine osname, os release, cpu. These
@@ -737,6 +737,8 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5Pset_libver_bounds "" HDF5_HAS_LIBVER_BOUNDS)
CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5free_memory "" HDF5_HAS_H5FREE)
+ CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5allocate_memory "" HDF5_HAS_ALLOCATE_MEMORY)
+ CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5resize_memory "" HDF5_HAS_RESIZE_MEMORY)
IF(HDF5_PARALLEL)
SET(HDF5_CC h5pcc)
@@ -1845,7 +1847,7 @@ FOREACH(_LIB ${ALL_TLL_LIBS})
LIST(APPEND LINKFLAGS "-L${_LIB_DIR}")
ENDFOREACH()
-SET(NC_LIBS "-lnetcdf ${NC_LIBS}")
+#SET(NC_LIBS "-lnetcdf ${NC_LIBS}")
STRING(REPLACE ";" " " NC_LIBS "${NC_LIBS}")
STRING(REPLACE "-lhdf5::hdf5-shared" "-lhdf5" NC_LIBS ${NC_LIBS})
@@ -1859,6 +1861,9 @@ STRING(REPLACE ";" " " LINKFLAGS "${LINKFLAGS}")
LIST(REMOVE_DUPLICATES NC_LIBS)
LIST(REMOVE_DUPLICATES LINKFLAGS)
+SET(LIBS ${NC_LIBS})
+SET(NC_LIBS "-lnetcdf")
+
configure_file(
${netCDF_SOURCE_DIR}/netcdf.pc.in
${netCDF_BINARY_DIR}/netcdf.pc @ONLY)
@@ -1919,10 +1924,6 @@ SET(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_${CMAKE_BU
is_disabled(BUILD_SHARED_LIBS enable_static)
is_enabled(BUILD_SHARED_LIBS enable_shared)
-# Remove libnetcdf from NC_LIBS.
-STRING(REPLACE "-lnetcdf " "" TMP_NC_LIBS "${NC_LIBS}")
-SET(LIBS "${TMP_NC_LIBS}")
-
is_enabled(ENABLE_V2_API HAS_NC2)
is_enabled(ENABLE_NETCDF_4 HAS_NC4)
is_enabled(ENABLE_HDF4 HAS_HDF4)
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 8a7310609a..4151186d37 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -5,15 +5,16 @@ Release Notes {#RELEASE_NOTES}
This file contains a high-level description of this package's evolution. Releases are in reverse chronological order (most recent first). Note that, as of netcdf 4.2, the `netcdf-c++` and `netcdf-fortran` libraries have been separated into their own libraries.
-## 4.6.3 - TBD
-
-## 4.6.2.1 - February 15, 2019
-
-### Maintenance Release
+## 4.6.3 - February 28, 2019
+* [Bug Fix] Correctly generated `netcdf.pc` generated either by `configure` or `cmake`. If linking against a static netcdf, you would need to pass the `--static` argument to `pkg-config` in order to list all of the downstream dependencies. See [Github #1324](https://github.com/Unidata/netcdf-c/issues/1324) for more information.
+* Now always write hidden coordinates attribute, which allows faster file opens when present. See [Github #1262](https://github.com/Unidata/netcdf-c/issues/1262) for more information.
+* Some fixes for rename, including fix for renumbering of varids after a rename (#1307), renaming var to dim without coordinate var. See [Github #1297](https://github.com/Unidata/netcdf-c/issues/1297).
+* Fix of NULL parameter causing segfaults in put_vars functions. See [Github #1265](https://github.com/Unidata/netcdf-c/issues/1265) for more information.
+* Fix of --enable-benchmark benchmark tests [Github #1211](https://github.com/Unidata/netcdf-c/issues/1211)
* Update the license from the home-brewed NetCDF license to the standard 3-Clause BSD License. This change does not result in any new restrictions; it is merely the adoption of a standard, well-known and well-understood license in place of the historic NetCDF license written at Unidata. This is part of a broader push by Unidata to adopt modern, standardized licensing.
* [BugFix] Corrected DAP-releated issues on big-endian machines. See [Github #1321](https://github.com/Unidata/netcdf-c/issues/1321), [Github #1302](https://github.com/Unidata/netcdf-c/issues/1302) for more information.
-* [BugFix][Enhancement] Various and sundry bugfixes and performance enhancements, thanks to @edhartnett, @gsjaardema, @t-b, @wkliao, and all of our other contributors.
+* [BugFix][Enhancement] Various and sundry bugfixes and performance enhancements, thanks to \@edhartnett, \@gsjaardema, \@t-b, \@wkliao, and all of our other contributors.
* [Enhancement] Extended `nccopy -F` syntax to support multiple variables with a single invocation. See [Github #1311](https://github.com/Unidata/netcdf-c/issues/1311) for more information.
* [BugFix] Corrected an issue where DAP2 was incorrectly converting signed bytes, resulting in an erroneous error message under some circumstances. See [GitHub #1317](https://github.com/Unidata/netcdf-c/issues/1317) for more information. See [Github #1319](https://github.com/Unidata/netcdf-c/issues/1319) for related information.
* [BugFix][Enhancement] Modified `nccopy` so that `_NCProperties` is not copied over verbatim but is instead generated based on the version of `libnetcdf` used when copying the file. Additionally, `_NCProperties` are displayed if/when associated with a netcdf3 file, now. See [GitHub #803](https://github.com/Unidata/netcdf-c/issues/803) for more information.
diff --git a/config.h.cmake.in b/config.h.cmake.in
index 9c145fb135..7fbbc26a68 100644
--- a/config.h.cmake.in
+++ b/config.h.cmake.in
@@ -367,6 +367,12 @@ are set when opening a binary file on Windows. */
nc4file. */
#cmakedefine HDF5_HAS_H5FREE 1
+/* if true, H5allocate_memory() will be used. */
+#cmakedefine HDF5_HAS_ALLOCATE_MEMORY 1
+
+/* if true, H5resize_memory() will be used. */
+#cmakedefine HDF5_HAS_RESIZE_MEMORY 1
+
/* if true, hdf5 has parallelism enabled */
#cmakedefine HDF5_PARALLEL 1
diff --git a/configure.ac b/configure.ac
index 828d5501fd..b5543fbf61 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,7 +13,7 @@
AC_PREREQ([2.59])
# Initialize with name, version, and support email address.
-AC_INIT([netCDF], [4.6.3-development], [support-netcdf@unidata.ucar.edu], [netcdf-c])
+AC_INIT([netCDF], [4.6.4-development], [support-netcdf@unidata.ucar.edu], [netcdf-c])
##
# Prefer an empty CFLAGS variable instead of the default -g -O2.
@@ -24,7 +24,7 @@ AC_INIT([netCDF], [4.6.3-development], [support-netcdf@unidata.ucar.edu], [netcd
AC_SUBST([NC_VERSION_MAJOR]) NC_VERSION_MAJOR=4
AC_SUBST([NC_VERSION_MINOR]) NC_VERSION_MINOR=6
-AC_SUBST([NC_VERSION_PATCH]) NC_VERSION_PATCH=3
+AC_SUBST([NC_VERSION_PATCH]) NC_VERSION_PATCH=4
AC_SUBST([NC_VERSION_NOTE]) NC_VERSION_NOTE="-development"
#####
@@ -1028,7 +1028,7 @@ if test "x$enable_hdf5" = xyes; then
# H5Pset_fapl_mpiposix and H5Pget_fapl_mpiposix have been removed since HDF5 1.8.12.
# Use H5Pset_fapl_mpio and H5Pget_fapl_mpio, instead.
- AC_CHECK_FUNCS([H5Pget_fapl_mpio H5Pset_deflate H5Z_SZIP H5free_memory H5Pset_libver_bounds H5Pset_all_coll_metadata_ops])
+ AC_CHECK_FUNCS([H5Pget_fapl_mpio H5Pset_deflate H5Z_SZIP H5free_memory H5resize_memory H5allocate_memory H5Pset_libver_bounds H5Pset_all_coll_metadata_ops])
# Check to see if HDF5 library has collective metadata APIs, (HDF5 >= 1.10.0)
if test "x$ac_cv_func_H5Pset_all_coll_metadata_ops" = xyes; then
@@ -1062,6 +1062,14 @@ if test "x$enable_hdf5" = xyes; then
AC_DEFINE([HDF5_HAS_H5FREE], [1], [if true, H5free_memory() will be used to free hdf5-allocated memory in nc4file.])
fi
+ if test "x$ac_cv_func_H5allocate_memory" = xyes; then
+ AC_DEFINE([HDF5_HAS_ALLOCATE_MEMORY], [1], [if true, H5allocate_memory() will be used.])
+ fi
+
+ if test "x$ac_cv_func_H5resize_memory" = xyes; then
+ AC_DEFINE([HDF5_HAS_resize_MEMORY], [1], [if true, H5resize_memory() will be used.])
+ fi
+
if test "x$ac_cv_func_H5Pset_libver_bounds" = xyes; then
AC_DEFINE([HDF5_HAS_LIBVER_BOUNDS], [1], [if true, netcdf4 file properties will be set using H5Pset_libver_bounds])
fi
diff --git a/docs/Doxyfile.developer b/docs/Doxyfile.developer
index 84ef2c1106..c5ced7e021 100644
--- a/docs/Doxyfile.developer
+++ b/docs/Doxyfile.developer
@@ -38,7 +38,7 @@ PROJECT_NAME = netCDF-C
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 4.6.3-development
+PROJECT_NUMBER = 4.6.4-development
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/docs/guide.dox b/docs/guide.dox
index a581454f99..18ae59d96c 100644
--- a/docs/guide.dox
+++ b/docs/guide.dox
@@ -8,7 +8,6 @@
- \subpage netcdf_data_set_components
- \subpage netcdf_perf_chunking
- \subpage netcdf_utilities_guide
-- \subpage compress
- \subpage BestPractices
- \subpage user_defined_formats
- \subpage users_guide_appendices
@@ -48,7 +47,10 @@ web site (http://www.unidata.ucar.edu/netcdf), and with the netCDF
distribution.
The latest version of this document, and the language specific guides,
-can be found at the netCDF web site (http://www.unidata.ucar.edu/netcdf/docs) along with extensive additional information about netCDF, including pointers to other software that works with netCDF data.
+can be found at the netCDF web site
+(http://www.unidata.ucar.edu/netcdf/docs) along with extensive
+additional information about netCDF, including pointers to other
+software that works with netCDF data.
Separate documentation of the Java netCDF library can be found at
http://www.unidata.ucar.edu/software/netcdf-java/.
@@ -88,8 +90,10 @@ were written.
Unidata supports the netCDF interfaces for C (see NetCDF-C User's
-Guide), Fortran (see NetCDF-Fortran User's Guide)
-and C++ (see ), Fortran (see NetCDF-Fortran User's Guide) and C++ (see NetCDF C++ Interface Guide).
The netCDF library is supported for various UNIX operating systems. A
diff --git a/libdispatch/ddim.c b/libdispatch/ddim.c
index 4abcc4e382..58b6fcda06 100644
--- a/libdispatch/ddim.c
+++ b/libdispatch/ddim.c
@@ -1,125 +1,122 @@
-/** \file
-Dimension functions
+/* Copyright 2018 University Corporation for Atmospheric
+ Research/Unidata. See COPYRIGHT file for more info. */
+/**
+ @file
-These functions define and inquire about dimensions.
-
-Copyright 2018 University Corporation for Atmospheric
-Research/Unidata. See COPYRIGHT file for more info.
+ The functions in this file define, inquire about, and rename
+ dimensions.
*/
#include "ncdispatch.h"
-/*! \defgroup dimensions Dimensions
-
-Dimensions are used to define the shape of data in netCDF.
-
-Dimensions for a netCDF dataset are defined when it is created, while
-the netCDF dataset is in define mode. Additional dimensions may be
-added later by reentering define mode. A netCDF dimension has a name
-and a length. In a netCDF classic or 64-bit offset file, at most one
-dimension can have the unlimited length, which means variables using
-this dimension can grow along this dimension. In a netCDF-4 file
-multiple unlimited dimensions are supported.
-
-There is a suggested limit (1024) to the number of dimensions that can
-be defined in a single netCDF dataset. The limit is the value of the
-predefined macro NC_MAX_DIMS. The purpose of the limit is to make
-writing generic applications simpler. They need only provide an array
-of NC_MAX_DIMS dimensions to handle any netCDF dataset. The
-implementation of the netCDF library does not enforce this advisory
-maximum, so it is possible to use more dimensions, if necessary, but
-netCDF utilities that assume the advisory maximums may not be able to
-handle the resulting netCDF datasets.
-
-NC_MAX_VAR_DIMS, which must not exceed NC_MAX_DIMS, is the maximum
-number of dimensions that can be used to specify the shape of a single
-variable. It is also intended to simplify writing generic
-applications.
-
-Ordinarily, the name and length of a dimension are fixed when the
-dimension is first defined. The name may be changed later, but the
-length of a dimension (other than the unlimited dimension) cannot be
-changed without copying all the data to a new netCDF dataset with a
-redefined dimension length.
-
-Dimension lengths in the C interface are type size_t rather than type
-int to make it possible to access all the data in a netCDF dataset on
-a platform that only supports a 16-bit int data type, for example
-MSDOS. If dimension lengths were type int instead, it would not be
-possible to access data from variables with a dimension length greater
-than a 16-bit int can accommodate.
-
-A netCDF dimension in an open netCDF dataset is referred to by a small
-integer called a dimension ID. In the C interface, dimension IDs are
-0, 1, 2, ..., in the order in which the dimensions were defined.
-
-Operations supported on dimensions are:
-- Create a dimension, given its name and length.
-- Get a dimension ID from its name.
-- Get a dimension's name and length from its ID.
-- Rename a dimension.
-
+/**
+ @defgroup dimensions Dimensions
+
+ Dimensions are used to define the shape of data in netCDF.
+
+ Dimensions for a netCDF dataset are defined when it is created,
+ while the netCDF dataset is in define mode. Additional dimensions
+ may be added later by reentering define mode. A netCDF dimension
+ has a name and a length. In a netCDF classic or 64-bit offset file,
+ at most one dimension can have the unlimited length, which means
+ variables using this dimension can grow along this dimension. In a
+ netCDF-4 file multiple unlimited dimensions are supported.
+
+ There is a suggested limit (1024) to the number of dimensions that
+ can be defined in a single netCDF dataset. The limit is the value
+ of the predefined macro ::NC_MAX_DIMS. The purpose of the limit is
+ to make writing generic applications simpler. They need only
+ provide an array of ::NC_MAX_DIMS dimensions to handle any netCDF
+ dataset. The implementation of the netCDF library does not enforce
+ this advisory maximum, so it is possible to use more dimensions, if
+ necessary, but netCDF utilities that assume the advisory maximums
+ may not be able to handle the resulting netCDF datasets.
+
+ ::NC_MAX_VAR_DIMS, which must not exceed ::NC_MAX_DIMS, is the
+ maximum number of dimensions that can be used to specify the shape
+ of a single variable. It is also intended to simplify writing
+ generic applications.
+
+ Ordinarily, the name and length of a dimension are fixed when the
+ dimension is first defined. The name may be changed later, but the
+ length of a dimension (other than the unlimited dimension) cannot
+ be changed without copying all the data to a new netCDF dataset
+ with a redefined dimension length.
+
+ Dimension lengths in the C interface are type size_t rather than
+ type int to make it possible to access all the data in a netCDF
+ dataset on a platform that only supports a 16-bit int data type,
+ for example MSDOS. If dimension lengths were type int instead, it
+ would not be possible to access data from variables with a
+ dimension length greater than a 16-bit int can accommodate.
+
+ A netCDF dimension in an open netCDF dataset is referred to by a
+ small integer called a dimension ID. In the C interface, dimension
+ IDs are 0, 1, 2, ..., in the order in which the dimensions were
+ defined.
+
+ Operations supported on dimensions are:
+ - Create a dimension, given its name and length.
+ - Get a dimension ID from its name.
+ - Get a dimension's name and length from its ID.
+ - Rename a dimension.
*/
-/*! \{*/ /* All these functions are part of the above defgroup... */
-
-/** \name Deleting and Renaming Dimensions
-
-Functions to delete or rename an dimension. */
-/*! \{ */ /* All these functions are part of this named group... */
-
-/*!
-
-Define a new dimension. The function nc_def_dim adds a new
-dimension to an open netCDF dataset in define mode. It returns (as an
-argument) a dimension ID, given the netCDF ID, the dimension name, and
-the dimension length. At most one unlimited length dimension, called
-the record dimension, may be defined for each classic or 64-bit offset
-netCDF dataset. NetCDF-4 datasets may have multiple unlimited
-dimensions.
-
-\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 name Name of the dimension to be created.
-
-\param len Length of the dimension to be created. Use NC_UNLIMITED for
-unlimited dimensions.
-
-\param idp Pointer where dimension ID will be stored.
-
-\retval ::NC_NOERR No error.
-\returns ::NC_EBADID Not a valid ID.
-\returns ::NC_ENOTINDEFINE Not in define mode.
-\returns ::NC_EDIMSIZE Invalid dimension size.
-\returns ::NC_EUNLIMIT NC_UNLIMITED size already in use
-\returns ::NC_EMAXDIMS NC_MAX_DIMS exceeded [not enforced after 4.5.0]
-\returns ::NC_ENAMEINUSE String match to name in use
-\returns ::NC_ENOMEM Memory allocation (malloc) failure
-\returns ::NC_EPERM Write to read only
-
-\section nc_def_dim_example Example
-
-Here is an example using nc_def_dim() to create a dimension named lat of
-length 18 and a unlimited dimension named rec in a new netCDF dataset
-named foo.nc:
-
-\code
- #include
- ...
- int status, ncid, latid, recid;
- ...
- status = nc_create("foo.nc", NC_NOCLOBBER, &ncid);
- if (status != NC_NOERR) handle_error(status);
- ...
- status = nc_def_dim(ncid, "lat", 18L, &latid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_def_dim(ncid, "rec", NC_UNLIMITED, &recid);
- if (status != NC_NOERR) handle_error(status);
-\endcode
-
- */
+/** @{ */
+
+/**
+ Define a new dimension. The function nc_def_dim() adds a new
+ dimension to an open netCDF dataset in define mode. It returns (as an
+ argument) a dimension ID, given the netCDF ID, the dimension name, and
+ the dimension length. At most one unlimited length dimension, called
+ the record dimension, may be defined for each classic or 64-bit offset
+ netCDF dataset. NetCDF-4 datasets may have multiple unlimited
+ dimensions.
+
+ @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 name Name of the dimension to be created.
+ @param len Length of the dimension to be created. Use NC_UNLIMITED for
+ unlimited dimensions.
+ @param idp Pointer where dimension ID will be stored.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Not a valid ID.
+ @return ::NC_EMAXNAME Name is too long.
+ @return ::NC_EBADNAME Name breaks netCDF name rules.
+ @return ::NC_EINVAL Invalid input.
+ @return ::NC_ENOTINDEFINE Not in define mode.
+ @return ::NC_EDIMSIZE Invalid dimension size.
+ @return ::NC_EUNLIMIT NC_UNLIMITED size already in use
+ @return ::NC_EMAXDIMS NC_MAX_DIMS exceeded [not enforced after 4.5.0]
+ @return ::NC_ENAMEINUSE String match to name in use
+ @return ::NC_ENOMEM Memory allocation (malloc) failure
+ @return ::NC_EPERM Write to read only
+
+ @section nc_def_dim_example Example
+
+ Here is an example using nc_def_dim() to create a dimension named lat of
+ length 18 and a unlimited dimension named rec in a new netCDF dataset
+ named foo.nc:
+
+ @code
+ #include
+ ...
+ int status, ncid, latid, recid;
+ ...
+ status = nc_create("foo.nc", NC_NOCLOBBER, &ncid);
+ if (status != NC_NOERR) handle_error(status);
+ ...
+ status = nc_def_dim(ncid, "lat", 18L, &latid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_def_dim(ncid, "rec", NC_UNLIMITED, &recid);
+ if (status != NC_NOERR) handle_error(status);
+ @endcode
+
+ @author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward
+ Fisher
+*/
int
nc_def_dim(int ncid, const char *name, size_t len, int *idp)
{
@@ -130,26 +127,27 @@ nc_def_dim(int ncid, const char *name, size_t len, int *idp)
return ncp->dispatch->def_dim(ncid, name, len, idp);
}
-/*!
-Find the ID of a dimension from the name.
-
-The function nc_inq_dimid returns (as an argument) the ID of a netCDF
-dimension, given the name of the dimension. If ndims is the number of
-dimensions defined for a netCDF dataset, each dimension has an ID
-between 0 and ndims-1.
+/**
+ Find the ID of a dimension from the name.
-\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().
+ The function nc_inq_dimid returns (as an argument) the ID of a
+ netCDF dimension, given the name of the dimension. If ndims is the
+ number of dimensions defined for a netCDF dataset, each dimension
+ has an ID between 0 and ndims-1.
-\param name Name of the dimension.
+ @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 name Name of the dimension.
+ @param idp Pointer where dimension ID will be stored.
-\param idp Pointer where dimension ID will be stored.
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Not a valid ID.
+ @return ::NC_EBADDIM Invalid dimension ID.
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Not a valid ID.
-\returns ::NC_EBADDIM Invalid dimension ID or name.
- */
+ @author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward
+ Fisher
+*/
int
nc_inq_dimid(int ncid, const char *name, int *idp)
{
@@ -160,60 +158,60 @@ nc_inq_dimid(int ncid, const char *name, int *idp)
return ncp->dispatch->inq_dimid(ncid,name,idp);
}
-/*!
-Find the name and length of a dimension.
-
-The length for the unlimited dimension, if any, is the number of
-records written so far.
-
-\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 dimid Dimension ID, from a previous call to nc_inq_dimid() or
-nc_def_dim().
-
-\param name Returned dimension name. The caller must allocate space
-for the returned name. The maximum possible length, in characters, of
-a dimension name is given by the predefined constant
-NC_MAX_NAME. (This doesn't include the null terminator, so declare
-your array to be size NC_MAX_NAME+1). The returned character array
-will be null-terminated.
-
-\param lenp Pointer to location for returned length of dimension. For
-the unlimited dimension, this is the number of records written so far.
-
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Not a valid ID.
-\returns ::NC_EBADDIM Invalid dimension ID or name.
-
-\section nc_inq_dim_example Example
-
-Here is an example using nc_inq_dim() to determine the length of a
-dimension named lat, and the name and current maximum length of the
-unlimited dimension for an existing netCDF dataset named foo.nc:
-
-\code
- #include
- ...
- int status, ncid, latid, recid;
- size_t latlength, recs;
- char recname[NC_MAX_NAME+1];
- ...
- status = nc_open("foo.nc", NC_NOWRITE, &ncid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_inq_unlimdim(ncid, &recid);
- if (status != NC_NOERR) handle_error(status);
- ...
- status = nc_inq_dimid(ncid, "lat", &latid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_inq_dimlen(ncid, latid, &latlength);
- if (status != NC_NOERR) handle_error(status);
-
- status = nc_inq_dim(ncid, recid, recname, &recs);
- if (status != NC_NOERR) handle_error(status);
-\endcode
- */
+/**
+ Find the name and length of a dimension.
+
+ The length for the unlimited dimension, if any, is the number of
+ records written so far.
+
+ @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 dimid Dimension ID, from a previous call to nc_inq_dimid() or
+ nc_def_dim().
+ @param name Returned dimension name. The caller must allocate space
+ for the returned name. The maximum possible length, in characters, of
+ a dimension name is given by the predefined constant
+ ::NC_MAX_NAME. (This doesn't include the null terminator, so declare
+ your array to be size NC_MAX_NAME+1). The returned character array
+ will be null-terminated.
+ @param lenp Pointer to location for returned length of dimension. For
+ the unlimited dimension, this is the number of records written so far.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Not a valid ID.
+ @return ::NC_EBADDIM Invalid dimension ID or name.
+
+ @section nc_inq_dim_example Example
+
+ Here is an example using nc_inq_dim() to determine the length of a
+ dimension named lat, and the name and current maximum length of the
+ unlimited dimension for an existing netCDF dataset named foo.nc:
+
+ @code
+ #include
+ ...
+ int status, ncid, latid, recid;
+ size_t latlength, recs;
+ char recname[NC_MAX_NAME+1];
+ ...
+ status = nc_open("foo.nc", NC_NOWRITE, &ncid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_inq_unlimdim(ncid, &recid);
+ if (status != NC_NOERR) handle_error(status);
+ ...
+ status = nc_inq_dimid(ncid, "lat", &latid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_inq_dimlen(ncid, latid, &latlength);
+ if (status != NC_NOERR) handle_error(status);
+
+ status = nc_inq_dim(ncid, recid, recname, &recs);
+ if (status != NC_NOERR) handle_error(status);
+ @endcode
+
+ @author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward
+ Fisher
+*/
int
nc_inq_dim(int ncid, int dimid, char *name, size_t *lenp)
{
@@ -224,59 +222,65 @@ nc_inq_dim(int ncid, int dimid, char *name, size_t *lenp)
return ncp->dispatch->inq_dim(ncid,dimid,name,lenp);
}
-/*!
-Rename a dimension.
-
-This function renames an existing dimension in a netCDF dataset open
-for writing. You cannot rename a dimension to have the same name as
-another dimension.
-
-For netCDF classic and 64-bit offset files, if the new name is longer
-than the old name, the netCDF dataset must be in define mode.
-
-For netCDF-4 files the dataset is switched to define mode for the
-rename, regardless of the name length.
-
-\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 dimid Dimension ID, from a previous call to nc_inq_dimid() or
-nc_def_dim().
-
-\param name New name for dimension. Must be a null-terminated string
-with length less than NC_MAX_NAME.
-
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Not a valid ID.
-\returns ::NC_EBADDIM Invalid dimension ID or name.
-\returns ::NC_ENAMEINUSE String match to name in use
-\returns ::NC_ENOMEM Memory allocation (malloc) failure
-\returns ::NC_EPERM Write to read only
-\returns ::NC_ENOTINDEFINE Not in define mode and new name is longer than old.
-\section nc_rename_dim_example Example
-
-Here is an example using nc_rename_dim to rename the dimension lat to
-latitude in an existing netCDF dataset named foo.nc:
-
-\code
- #include
- ...
- int status, ncid, latid;
- ...
- status = nc_open("foo.nc", NC_WRITE, &ncid);
- if (status != NC_NOERR) handle_error(status);
- ...
- status = nc_redef(ncid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_inq_dimid(ncid, "lat", &latid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_rename_dim(ncid, latid, "latitude");
- if (status != NC_NOERR) handle_error(status);
- status = nc_enddef(ncid);
- if (status != NC_NOERR) handle_error(status);
-\endcode
- */
+/**
+ Rename a dimension.
+
+ This function renames an existing dimension in a netCDF dataset
+ open for writing. You cannot rename a dimension to have the same
+ name as another dimension.
+
+ For netCDF classic and 64-bit offset files, if the new name is
+ longer than the old name, which has been flushed to disk, the
+ netCDF dataset must be in define mode.
+
+ For netCDF-4 files the length of the name is not checked against
+ the length of the old name, even for classic model files. This is
+ due to the difficulty of exactly reproducing classic library
+ behavior in this case.
+
+ @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 dimid Dimension ID, from a previous call to nc_inq_dimid()
+ or nc_def_dim().
+ @param name New name for dimension. Must be a null-terminated
+ string with length less than ::NC_MAX_NAME.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Not a valid ID.
+ @return ::NC_EBADDIM Invalid dimension ID or name.
+ @return ::NC_ENAMEINUSE String match to name in use
+ @return ::NC_ENOMEM Memory allocation (malloc) failure
+ @return ::NC_EPERM Write to read only
+ @return ::NC_ENOTINDEFINE Not in define mode and new name is longer
+ than old.
+
+ @section nc_rename_dim_example Example
+
+ Here is an example using nc_rename_dim to rename the dimension lat
+ to latitude in an existing netCDF dataset named foo.nc:
+
+ @code
+ #include
+ ...
+ int status, ncid, latid;
+ ...
+ status = nc_open("foo.nc", NC_WRITE, &ncid);
+ if (status != NC_NOERR) handle_error(status);
+ ...
+ status = nc_redef(ncid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_inq_dimid(ncid, "lat", &latid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_rename_dim(ncid, latid, "latitude");
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_enddef(ncid);
+ if (status != NC_NOERR) handle_error(status);
+ @endcode
+
+ @author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward
+ Fisher
+*/
int
nc_rename_dim(int ncid, int dimid, const char *name)
{
@@ -287,27 +291,28 @@ nc_rename_dim(int ncid, int dimid, const char *name)
return ncp->dispatch->rename_dim(ncid,dimid,name);
}
-/*!
-Find the number of dimensions.
+/**
+ Find the number of dimensions.
-In a classic model netCDF file, this function returns the number of
-defined dimensions. In a netCDF-4/HDF5 file, this function returns the
-number of dimensions available in the group specified by ncid, which
-may be less than the total number of dimensions in a file. In a
-netCDF-4/HDF5 file, dimensions are in all sub-groups, sub-sub-groups,
-etc.
+ In a classic model netCDF file, this function returns the number of
+ defined dimensions. In a netCDF-4/HDF5 file, this function returns
+ the number of dimensions available in the group specified by ncid,
+ which may be less than the total number of dimensions in a file. In
+ a netCDF-4/HDF5 file, dimensions are in all sub-groups,
+ sub-sub-groups, etc.
-\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 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 ndimsp Pointer where number of dimensions will be
+ written. Ignored if NULL.
-\param ndimsp Pointer where number of dimensions will be
-written. Ignored if NULL.
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Not a valid ID.
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Not a valid ID.
-
- */
+ @author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward
+ Fisher
+*/
int
nc_inq_ndims(int ncid, int *ndimsp)
{
@@ -319,26 +324,28 @@ nc_inq_ndims(int ncid, int *ndimsp)
return ncp->dispatch->inq(ncid,ndimsp,NULL,NULL,NULL);
}
-/*!
-Find the ID of the unlimited dimension.
+/**
+ Find the ID of the unlimited dimension.
-This function finds the ID of the unlimited dimension. For
-netCDF-4/HDF5 files (which may have more than one unlimited
-dimension), the ID of the first unlimited dimesnion is returned. For
-these files, nc_inq_unlimdims() will return all the unlimited dimension IDs.
+ This function finds the ID of the unlimited dimension. For
+ netCDF-4/HDF5 files (which may have more than one unlimited
+ dimension), the ID of the first unlimited dimesnion is
+ returned. For these files, nc_inq_unlimdims() will return all the
+ unlimited dimension IDs.
-\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 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 unlimdimidp Pointer where unlimited dimension ID will be
+ stored. If there is no unlimited dimension, -1 will be stored
+ here. Ignored if NULL.
-\param unlimdimidp Pointer where unlimited dimension ID will be
-stored. If there is no unlimited dimension, -1 will be stored
-here. Ignored if NULL.
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Not a valid ID.
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Not a valid ID.
-
- */
+ @author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward
+ Fisher
+*/
int
nc_inq_unlimdim(int ncid, int *unlimdimidp)
{
@@ -349,55 +356,55 @@ nc_inq_unlimdim(int ncid, int *unlimdimidp)
return ncp->dispatch->inq_unlimdim(ncid,unlimdimidp);
}
-/*!
-Find out the name of a dimension.
-
-\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 dimid Dimension ID, from a previous call to nc_inq_dimid() or
-nc_def_dim().
-
-\param name Returned dimension name. The caller must allocate space
-for the returned name. The maximum possible length, in characters, of
-a dimension name is given by the predefined constant
-NC_MAX_NAME. (This doesn't include the null terminator, so declare
-your array to be size NC_MAX_NAME+1). The returned character array
-will be null-terminated. Ignored if NULL.
-
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Not a valid ID.
-\returns ::NC_EBADDIM Invalid dimension ID or name.
-
-\section nc_inq_dim_example2 Example
-
-Here is an example using nc_inq_dim() to determine the length of a
-dimension named lat, and the name and current maximum length of the
-unlimited dimension for an existing netCDF dataset named foo.nc:
-
-\code
- #include
- ...
- int status, ncid, latid, recid;
- size_t latlength, recs;
- char recname[NC_MAX_NAME+1];
- ...
- status = nc_open("foo.nc", NC_NOWRITE, &ncid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_inq_unlimdim(ncid, &recid);
- if (status != NC_NOERR) handle_error(status);
- ...
- status = nc_inq_dimid(ncid, "lat", &latid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_inq_dimlen(ncid, latid, &latlength);
- if (status != NC_NOERR) handle_error(status);
-
- status = nc_inq_dim(ncid, recid, recname, &recs);
- if (status != NC_NOERR) handle_error(status);
-\endcode
-
- */
+/**
+ Find out the name of a dimension.
+
+ @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 dimid Dimension ID, from a previous call to nc_inq_dimid()
+ or nc_def_dim().
+ @param name Returned dimension name. The caller must allocate space
+ for the returned name. The maximum possible length, in characters,
+ of a dimension name is given by the predefined constant
+ ::NC_MAX_NAME. (This doesn't include the null terminator, so
+ declare your array to be size NC_MAX_NAME+1). The returned
+ character array will be null-terminated. Ignored if NULL.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Not a valid ID.
+ @return ::NC_EBADDIM Invalid dimension ID or name.
+
+ @section nc_inq_dim_example2 Example
+
+ Here is an example using nc_inq_dim() to determine the length of a
+ dimension named lat, and the name and current maximum length of the
+ unlimited dimension for an existing netCDF dataset named foo.nc:
+
+ @code
+ #include
+ ...
+ int status, ncid, latid, recid;
+ size_t latlength, recs;
+ char recname[NC_MAX_NAME+1];
+ ...
+ status = nc_open("foo.nc", NC_NOWRITE, &ncid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_inq_unlimdim(ncid, &recid);
+ if (status != NC_NOERR) handle_error(status);
+ ...
+ status = nc_inq_dimid(ncid, "lat", &latid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_inq_dimlen(ncid, latid, &latlength);
+ if (status != NC_NOERR) handle_error(status);
+
+ status = nc_inq_dim(ncid, recid, recname, &recs);
+ if (status != NC_NOERR) handle_error(status);
+ @endcode
+
+ @author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward
+ Fisher
+*/
int
nc_inq_dimname(int ncid, int dimid, char *name)
{
@@ -409,52 +416,53 @@ nc_inq_dimname(int ncid, int dimid, char *name)
return ncp->dispatch->inq_dim(ncid,dimid,name,NULL);
}
-/*!
-Find the length of a dimension.
-
-The length for the unlimited dimension, if any, is the number of
-records written so far.
-
-\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 dimid Dimension ID, from a previous call to nc_inq_dimid() or
-nc_def_dim().
-
-\param lenp Pointer where the length will be stored.
-
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Not a valid ID.
-\returns ::NC_EBADDIM Invalid dimension ID or name.
-
-\section nc_inq_dim_example3 Example
-
-Here is an example using nc_inq_dim() to determine the length of a
-dimension named lat, and the name and current maximum length of the
-unlimited dimension for an existing netCDF dataset named foo.nc:
-
-\code
- #include
- ...
- int status, ncid, latid, recid;
- size_t latlength, recs;
- char recname[NC_MAX_NAME+1];
- ...
- status = nc_open("foo.nc", NC_NOWRITE, &ncid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_inq_unlimdim(ncid, &recid);
- if (status != NC_NOERR) handle_error(status);
- ...
- status = nc_inq_dimid(ncid, "lat", &latid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_inq_dimlen(ncid, latid, &latlength);
- if (status != NC_NOERR) handle_error(status);
-
- status = nc_inq_dim(ncid, recid, recname, &recs);
- if (status != NC_NOERR) handle_error(status);
-\endcode
- */
+/**
+ Find the length of a dimension.
+
+ The length for the unlimited dimension, if any, is the number of
+ records written so far.
+
+ @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 dimid Dimension ID, from a previous call to nc_inq_dimid()
+ or nc_def_dim().
+ @param lenp Pointer where the length will be stored.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Not a valid ID.
+ @return ::NC_EBADDIM Invalid dimension ID or name.
+
+ @section nc_inq_dim_example3 Example
+
+ Here is an example using nc_inq_dim() to determine the length of a
+ dimension named lat, and the name and current maximum length of the
+ unlimited dimension for an existing netCDF dataset named foo.nc:
+
+ @code
+ #include
+ ...
+ int status, ncid, latid, recid;
+ size_t latlength, recs;
+ char recname[NC_MAX_NAME+1];
+ ...
+ status = nc_open("foo.nc", NC_NOWRITE, &ncid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_inq_unlimdim(ncid, &recid);
+ if (status != NC_NOERR) handle_error(status);
+ ...
+ status = nc_inq_dimid(ncid, "lat", &latid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_inq_dimlen(ncid, latid, &latlength);
+ if (status != NC_NOERR) handle_error(status);
+
+ status = nc_inq_dim(ncid, recid, recname, &recs);
+ if (status != NC_NOERR) handle_error(status);
+ @endcode
+
+ @author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward
+ Fisher
+*/
int
nc_inq_dimlen(int ncid, int dimid, size_t *lenp)
{
@@ -466,6 +474,4 @@ nc_inq_dimlen(int ncid, int dimid, size_t *lenp)
return ncp->dispatch->inq_dim(ncid,dimid,NULL,lenp);
}
-/*! \} */ /* End of named group ...*/
-
-/*! \} */ /* End of defgroup. */
+/** @} */
diff --git a/libdispatch/dvar.c b/libdispatch/dvar.c
index f91e5df315..07b0a62b8b 100644
--- a/libdispatch/dvar.c
+++ b/libdispatch/dvar.c
@@ -2,1190 +2,1211 @@
Research/Unidata. See COPYRIGHT file for more info. */
/**
* @file
- * Functions for defining and inquiring about variables.
-*/
+ * Functions for defining and inquiring about variables. @note The
+ * order of functions in this file affects the doxygen documentation.
+ */
#include "ncdispatch.h"
#include "netcdf_f.h"
/**
-\defgroup variables Variables
-
-Variables hold multi-dimensional arrays of data.
-
-Variables for a netCDF dataset are defined when the dataset is
-created, while the netCDF dataset is in define mode. Other variables
-may be added later by reentering define mode. A netCDF variable has a
-name, a type, and a shape, which are specified when it is defined. A
-variable may also have values, which are established later in data
-mode.
-
-Ordinarily, the name, type, and shape are fixed when the variable is
-first defined. The name may be changed, but the type and shape of a
-variable cannot be changed. However, a variable defined in terms of
-the unlimited dimension can grow without bound in that dimension.
-
-A netCDF variable in an open netCDF dataset is referred to by a small
-integer called a variable ID.
-
-Variable IDs reflect the order in which variables were defined within
-a netCDF dataset. Variable IDs are 0, 1, 2,..., in the order in which
-the variables were defined. A function is available for getting the
-variable ID from the variable name and vice-versa.
-
-Attributes (see Attributes) may be associated with a variable to
-specify such properties as units.
-
-Operations supported on variables are:
-- Create a variable, given its name, data type, and shape.
-- Get a variable ID from its name.
-- Get a variable's name, data type, shape, and number of attributes
- from its ID.
-- Put a data value into a variable, given variable ID, indices, and value.
-- Put an array of values into a variable, given variable ID, corner
- indices, edge lengths, and a block of values.
-- Put a subsampled or mapped array-section of values into a variable,
- given variable ID, corner indices, edge lengths, stride vector,
- index mapping vector, and a block of values.
-- Get a data value from a variable, given variable ID and indices.
-- Get an array of values from a variable, given variable ID, corner
- indices, and edge lengths.
-- Get a subsampled or mapped array-section of values from a variable,
- given variable ID, corner indices, edge lengths, stride vector, and
- index mapping vector.
-- Rename a variable.
-
-\section language_types Language Types Corresponding to netCDF
-External Data Types
-
-NetCDF supported six atomic data types through version 3.6.0 (char,
-byte, short, int, float, and double). Starting with version 4.0, many
-new atomic and user defined data types are supported (unsigned int
-types, strings, compound types, variable length arrays, enums,
-opaque).
-
-The additional data types are only supported in netCDF-4/HDF5
-files. To create netCDF-4/HDF5 files, use the HDF5 flag in
-nc_create. (see nc_create).
-
-\section classic_types NetCDF-3 Classic and 64-Bit Offset Data Types
-
-NetCDF-3 classic and 64-bit offset files support 6 atomic data types,
-and none of the user defined datatype introduced in NetCDF-4.
-
-The following table gives the netCDF-3 external data types and the
-corresponding type constants for defining variables in the C
-interface:
-
-
-Type | C define | Bits |
-byte | NC_BYTE | 8 |
-char | NC_CHAR | 8 |
-short | NC_SHORT | 16 |
-int | NC_INT | 32 |
-float | NC_FLOAT | 32 |
-double | NC_DOUBLE | 64 |
-
-
-The first column gives the netCDF external data type, which is the
-same as the CDL data type. The next column gives the corresponding C
-pre-processor macro for use in netCDF functions (the pre-processor
-macros are defined in the netCDF C header-file netcdf.h). The last
-column gives the number of bits used in the external representation of
-values of the corresponding type.
-
-\section netcdf_4_atomic NetCDF-4 Atomic Types
-
-NetCDF-4 files support all of the atomic data types from netCDF-3,
-plus additional unsigned integer types, 64-bit integer types, and a
-string type.
-
-
-Type | C define | Bits
-
- |
byte | NC_BYTE | 8 |
-unsigned byte | NC_UBYTE^ | 8 |
-char | NC_CHAR | 8 |
-short | NC_SHORT | 16 |
-unsigned short | NC_USHORT^ | 16 |
-int | NC_INT | 32 |
-unsigned int | NC_UINT^ | 32 |
-unsigned long long | NC_UINT64^ | 64 |
-long long | NC_INT64^ | 64 |
-float | NC_FLOAT | 32 |
-double | NC_DOUBLE | 64 |
-char ** | NC_STRING^ | string length + 1 |
-
-
-^This type was introduced in netCDF-4, and is not supported in netCDF
-classic or 64-bit offset format files, or in netCDF-4 files if they
-are created with the NC_CLASSIC_MODEL flags.
- */
+ @defgroup variables Variables
+
+ Variables hold multi-dimensional arrays of data.
+
+ Variables for a netCDF dataset are defined when the dataset is
+ created, while the netCDF dataset is in define mode. Other
+ variables may be added later by reentering define mode. A netCDF
+ variable has a name, a type, and a shape, which are specified when
+ it is defined. A variable may also have values, which are
+ established later in data mode.
+
+ Ordinarily, the name, type, and shape are fixed when the variable
+ is first defined. The name may be changed, but the type and shape
+ of a variable cannot be changed. However, a variable defined in
+ terms of the unlimited dimension can grow without bound in that
+ dimension.
+
+ A netCDF variable in an open netCDF dataset is referred to by a
+ small integer called a variable ID.
+
+ Variable IDs reflect the order in which variables were defined
+ within a netCDF dataset. Variable IDs are 0, 1, 2,..., in the order
+ in which the variables were defined. A function is available for
+ getting the variable ID from the variable name and vice-versa.
+
+ @ref attributes may be associated with a variable to specify such
+ properties as units.
+
+ Operations supported on variables are:
+ - Create a variable, given its name, data type, and shape.
+ - Get a variable ID from its name.
+ - Get a variable's name, data type, shape, and number of attributes
+ from its ID.
+ - Put a data value into a variable, given variable ID, indices, and value.
+ - Put an array of values into a variable, given variable ID, corner
+ indices, edge lengths, and a block of values.
+ - Put a subsampled or mapped array-section of values into a variable,
+ given variable ID, corner indices, edge lengths, stride vector,
+ index mapping vector, and a block of values.
+ - Get a data value from a variable, given variable ID and indices.
+ - Get an array of values from a variable, given variable ID, corner
+ indices, and edge lengths.
+ - Get a subsampled or mapped array-section of values from a variable,
+ given variable ID, corner indices, edge lengths, stride vector, and
+ index mapping vector.
+ - Rename a variable.
+
+ @section language_types Data Types
+
+ NetCDF supported six atomic data types through version 3.6.0 (char,
+ byte, short, int, float, and double). Starting with version 4.0, many
+ new atomic and user defined data types are supported (unsigned int
+ types, strings, compound types, variable length arrays, enums,
+ opaque).
+
+ The additional data types are only supported in netCDF-4/HDF5
+ files. To create netCDF-4/HDF5 files, use the ::NC_NETCDF4 flag in
+ nc_create().
+
+ @section classic_types NetCDF-3 Classic and 64-Bit Offset Data Types
+
+ NetCDF-3 classic and 64-bit offset files support 6 atomic data types,
+ and none of the user defined datatype introduced in NetCDF-4.
+
+ The following table gives the netCDF-3 external data types and the
+ corresponding type constants for defining variables in the C
+ interface:
+
+
+ Type | C define | Bits |
+ byte | ::NC_BYTE | 8 |
+ char | ::NC_CHAR | 8 |
+ short | ::NC_SHORT | 16 |
+ int | ::NC_INT | 32 |
+ float | ::NC_FLOAT | 32 |
+ double | ::NC_DOUBLE | 64 |
+
+
+ The first column gives the netCDF external data type, which is the
+ same as the CDL data type. The next column gives the corresponding C
+ pre-processor macro for use in netCDF functions (the pre-processor
+ macros are defined in the netCDF C header-file netcdf.h). The last
+ column gives the number of bits used in the external representation of
+ values of the corresponding type.
+
+ @section netcdf_4_atomic NetCDF-4 Atomic Data Types
+
+ NetCDF-4 files support all of the atomic data types from netCDF-3,
+ plus additional unsigned integer types, 64-bit integer types, and a
+ string type.
+
+
+ Type | C define | Bits
+
+ |
byte | ::NC_BYTE | 8 |
+ unsigned byte | ::NC_UBYTE^ | 8 |
+ char | ::NC_CHAR | 8 |
+ short | ::NC_SHORT | 16 |
+ unsigned short | ::NC_USHORT^ | 16 |
+ int | ::NC_INT | 32 |
+ unsigned int | ::NC_UINT^ | 32 |
+ unsigned long long | ::NC_UINT64^ | 64 |
+ long long | ::NC_INT64^ | 64 |
+ float | ::NC_FLOAT | 32 |
+ double | ::NC_DOUBLE | 64 |
+ char ** | ::NC_STRING^ | string length + 1 |
+
+
+ ^This type was introduced in netCDF-4, and is not supported in netCDF
+ classic or 64-bit offset format files, or in netCDF-4 files if they
+ are created with the ::NC_CLASSIC_MODEL flags.
+*/
+/** @{ */
/**
-@name Defining Variables
+ @name Defining Variables
-Use these functions to define variables.
- */
-/*! \{ */
+ Use these functions to define variables.
+*/
+/*! @{ */
/**
-@ingroup variables
-Define a new variable.
-
-This function adds a new variable to an open netCDF dataset or group.
-It returns (as an argument) a variable ID, given the netCDF ID,
-the variable name, the variable type, the number of dimensions, and a
-list of the dimension IDs.
-
-@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 name Variable \ref object_name.
-
-@param xtype \ref data_type of the variable.
-
-@param ndims Number of dimensions for the variable. For example, 2
-specifies a matrix, 1 specifies a vector, and 0 means the variable is
-a scalar with no dimensions. Must not be negative or greater than the
-predefined constant ::NC_MAX_VAR_DIMS. In netCDF-4/HDF5 files, may not
-exceed the HDF5 maximum number of dimensions (32).
-
-@param dimidsp Vector of ndims dimension IDs corresponding to the
-variable dimensions. For classic model netCDF files, if the ID of the
-unlimited dimension is included, it must be first. This argument is
-ignored if ndims is 0. For expanded model netCDF4/HDF5 files, there
-may be any number of unlimited dimensions, and they may be used in any
-element of the dimids array.
-
-@param varidp Pointer to location for the returned variable ID.
-
-@returns ::NC_NOERR No error.
-@returns ::NC_EBADID Bad ncid.
-@returns ::NC_ENOTINDEFINE Not in define mode.
-@returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
-@returns ::NC_EMAXVARS NC_MAX_VARS exceeded [Not enforced after 4.5.0]
-@returns ::NC_EBADTYPE Bad type.
-@returns ::NC_EINVAL Invalid input.
-@returns ::NC_ENAMEINUSE Name already in use.
-@returns ::NC_EPERM Attempt to create object in read-only file.
-
-@section nc_def_var_example Example
-
-Here is an example using nc_def_var to create a variable named rh of
-type double with three dimensions, time, lat, and lon in a new netCDF
-dataset named foo.nc:
-
-@code
- #include
- ...
- int status;
- int ncid;
- int lat_dim, lon_dim, time_dim;
- int rh_id;
- int rh_dimids[3];
- ...
- status = nc_create("foo.nc", NC_NOCLOBBER, &ncid);
- if (status != NC_NOERR) handle_error(status);
- ...
-
- status = nc_def_dim(ncid, "lat", 5L, &lat_dim);
- if (status != NC_NOERR) handle_error(status);
- status = nc_def_dim(ncid, "lon", 10L, &lon_dim);
- if (status != NC_NOERR) handle_error(status);
- status = nc_def_dim(ncid, "time", NC_UNLIMITED, &time_dim);
- if (status != NC_NOERR) handle_error(status);
- ...
-
- rh_dimids[0] = time_dim;
- rh_dimids[1] = lat_dim;
- rh_dimids[2] = lon_dim;
- status = nc_def_var (ncid, "rh", NC_DOUBLE, 3, rh_dimids, &rh_id);
- if (status != NC_NOERR) handle_error(status);
-@endcode
-@author Glenn Davis, Ed Hartnett, Dennis Heimbigner
- */
-int
-nc_def_var(int ncid, const char *name, nc_type xtype,
- int ndims, const int *dimidsp, int *varidp)
-{
- NC* ncp;
- int stat = NC_NOERR;
-
- if ((stat = NC_check_id(ncid, &ncp)))
- return stat;
- TRACE(nc_def_var);
- return ncp->dispatch->def_var(ncid, name, xtype, ndims,
- dimidsp, varidp);
-}
-/*! \} */
+ Define a new variable.
+
+ This function adds a new variable to an open netCDF dataset or group.
+ It returns (as an argument) a variable ID, given the netCDF ID,
+ the variable name, the variable type, the number of dimensions, and a
+ list of the dimension IDs.
+
+ @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 name Variable @ref object_name.
+ @param xtype @ref data_type of the variable.
+ @param ndims Number of dimensions for the variable. For example, 2
+ specifies a matrix, 1 specifies a vector, and 0 means the variable is
+ a scalar with no dimensions. Must not be negative or greater than the
+ predefined constant ::NC_MAX_VAR_DIMS. In netCDF-4/HDF5 files, may not
+ exceed the HDF5 maximum number of dimensions (32).
+ @param dimidsp Vector of ndims dimension IDs corresponding to the
+ variable dimensions. For classic model netCDF files, if the ID of the
+ unlimited dimension is included, it must be first. This argument is
+ ignored if ndims is 0. For expanded model netCDF4/HDF5 files, there
+ may be any number of unlimited dimensions, and they may be used in any
+ element of the dimids array.
+ @param varidp Pointer to location for the returned variable ID.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ncid.
+ @return ::NC_ENOTINDEFINE Not in define mode.
+ @return ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
+ @return ::NC_EMAXVARS NC_MAX_VARS exceeded [Not enforced after 4.5.0]
+ @return ::NC_EBADTYPE Bad type.
+ @return ::NC_EINVAL Invalid input.
+ @return ::NC_ENAMEINUSE Name already in use.
+ @return ::NC_EPERM Attempt to create object in read-only file.
+
+ @section nc_def_var_example Example
+
+ Here is an example using nc_def_var to create a variable named rh of
+ type double with three dimensions, time, lat, and lon in a new netCDF
+ dataset named foo.nc:
+
+ @code
+ #include
+ ...
+ int status;
+ int ncid;
+ int lat_dim, lon_dim, time_dim;
+ int rh_id;
+ int rh_dimids[3];
+ ...
+ status = nc_create("foo.nc", NC_NOCLOBBER, &ncid);
+ if (status != NC_NOERR) handle_error(status);
+ ...
-/**
-@name Rename a Variable
+ status = nc_def_dim(ncid, "lat", 5L, &lat_dim);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_def_dim(ncid, "lon", 10L, &lon_dim);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_def_dim(ncid, "time", NC_UNLIMITED, &time_dim);
+ if (status != NC_NOERR) handle_error(status);
+ ...
-Rename a variable.
- */
-/*! \{ */
+ rh_dimids[0] = time_dim;
+ rh_dimids[1] = lat_dim;
+ rh_dimids[2] = lon_dim;
+ status = nc_def_var (ncid, "rh", NC_DOUBLE, 3, rh_dimids, &rh_id);
+ if (status != NC_NOERR) handle_error(status);
+ @endcode
-/**
-Rename a variable.
-@ingroup variables
-
-This function changes the name of a netCDF variable in an open netCDF
-file or group. You cannot rename a variable to have the name of any existing
-variable.
-
-For classic format, 64-bit offset format, and netCDF-4/HDF5 with
-classic mode, if the new name is longer than the old name, the netCDF
-dataset must be in define mode.
-
-For netCDF-4/HDF5 files, renaming the variable changes the order of
-the variables in the file. The renamed variable becomes the last
-variable in the file.
-
-@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
-
-@param name New name of the variable.
-
-@returns ::NC_NOERR No error.
-@returns ::NC_EBADID Bad ncid.
-@returns ::NC_ENOTVAR Invalid variable ID.
-@returns ::NC_EBADNAME Bad name.
-@returns ::NC_EMAXNAME Name is too long.
-@returns ::NC_ENAMEINUSE Name in use.
-@returns ::NC_ENOMEM Out of memory.
-
-@section nc_rename_var_example Example
-
-Here is an example using nc_rename_var to rename the variable rh to
-rel_hum in an existing netCDF dataset named foo.nc:
-
-@code
- #include
- ...
- int status;
- int ncid;
- int rh_id;
- ...
- status = nc_open("foo.nc", NC_WRITE, &ncid);
- if (status != NC_NOERR) handle_error(status);
- ...
- status = nc_redef(ncid);
- if (status != NC_NOERR) handle_error(status);
- status = nc_inq_varid (ncid, "rh", &rh_id);
- if (status != NC_NOERR) handle_error(status);
- status = nc_rename_var (ncid, rh_id, "rel_hum");
- if (status != NC_NOERR) handle_error(status);
- status = nc_enddef(ncid);
- if (status != NC_NOERR) handle_error(status);
-@endcode
-@author Glenn Davis, Ed Hartnett, Dennis Heimbigner
+ @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
*/
int
-nc_rename_var(int ncid, int varid, const char *name)
+nc_def_var(int ncid, const char *name, nc_type xtype,
+ int ndims, const int *dimidsp, int *varidp)
{
- NC* ncp;
- int stat = NC_check_id(ncid, &ncp);
- if(stat != NC_NOERR) return stat;
- TRACE(nc_rename_var);
- return ncp->dispatch->rename_var(ncid, varid, name);
+ NC* ncp;
+ int stat = NC_NOERR;
+
+ if ((stat = NC_check_id(ncid, &ncp)))
+ return stat;
+ TRACE(nc_def_var);
+ return ncp->dispatch->def_var(ncid, name, xtype, ndims,
+ dimidsp, varidp);
}
-/*! \} */
/**
-@ingroup variables
-@internal Does a variable have a record dimension?
+ Set the fill value for a variable.
+
+ @note For netCDF classic, 64-bit offset, and CDF5 formats, it is
+ allowed (but not good practice) to set the fill value after data
+ have been written to the variable. In this case, unless the
+ variable has been completely specified (without gaps in the data),
+ any existing filled values will not be recognized as fill values by
+ applications reading the data. Best practice is to set the fill
+ value after the variable has been defined, but before any data have
+ been written to that varibale. In NetCDF-4 files, this is enforced
+ by the HDF5 library. For netCDF-4 files, an error is returned if
+ the user attempts to set the fill value after writing data to the
+ variable.
+
+ @param ncid NetCDF ID, from a previous call to nc_open() or
+ nc_create().
+ @param varid Variable ID.
+ @param no_fill Set to ::NC_NOFILL to turn off fill mode for this
+ variable. Set to ::NC_FILL (the default) to turn on fill mode for
+ the variable.
+ @param fill_value the fill value to be used for this variable. Must
+ be the same type as the variable. This must point to enough free
+ memory to hold one element of the data type of the variable. (For
+ example, an ::NC_INT will require 4 bytes for it's fill value,
+ which is also an ::NC_INT.)
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ID.
+ @return ::NC_ENOTINDEFINE Not in define mode. This is returned for
+ netCDF classic, 64-bit offset, or 64-bit data files, or for
+ netCDF-4 files, when they were created with ::NC_CLASSIC_MODEL flag by
+ nc_creae().
+ @return ::NC_EPERM Attempt to create object in read-only file.
+ @return ::NC_ELATEDEF (NetCDF-4 only). Returned when user attempts
+ to set fill value after data are written.
+ @return ::NC_EGLOBAL Attempt to set fill value on NC_GLOBAL.
+
+ @section nc_def_var_fill_example Example
+
+ In this example from libsrc4/tst_vars.c, a variable is defined, and
+ the fill mode turned off. Then nc_inq_fill() is used to check that
+ the setting is correct. Then some data are written to the
+ variable. Since the data that are written do not cover the full
+ extent of the variable, the missing values will just be random. If
+ fill value mode was turned on, the missing values would get the
+ fill value.
+
+ @code
+ #define DIM7_LEN 2
+ #define DIM7_NAME "dim_7_from_Indiana"
+ #define VAR7_NAME "var_7_from_Idaho"
+ #define NDIMS 1
+ int dimids[NDIMS];
+ size_t index[NDIMS];
+ int varid;
+ int no_fill;
+ unsigned short ushort_data = 42, ushort_data_in, fill_value_in;
-@param ncid File ID.
-@param varid Variable ID.
-@param nrecs Pointer that gets number of records.
+ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+ if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
+ if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
+ &varid)) ERR;
+ if (nc_def_var_fill(ncid, varid, 1, NULL)) ERR;
-@returns 0 if not a record var, 1 if it is.
- */
-int
-NC_is_recvar(int ncid, int varid, size_t* nrecs)
-{
- int status = NC_NOERR;
- int unlimid;
- int ndims;
- int dimset[NC_MAX_VAR_DIMS];
-
- status = nc_inq_unlimdim(ncid,&unlimid);
- if(status != NC_NOERR) return 0; /* no unlimited defined */
- status = nc_inq_varndims(ncid,varid,&ndims);
- if(status != NC_NOERR) return 0; /* no unlimited defined */
- if(ndims == 0) return 0; /* scalar */
- status = nc_inq_vardimid(ncid,varid,dimset);
- if(status != NC_NOERR) return 0; /* no unlimited defined */
- status = nc_inq_dim(ncid,dimset[0],NULL,nrecs);
- if(status != NC_NOERR) return 0;
- return (dimset[0] == unlimid ? 1: 0);
-}
+ if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
+ if (!no_fill) ERR;
-/**
-@ingroup variables
-@internal Get the number of record dimensions for a variable and an
-array that identifies which of a variable's dimensions are record
-dimensions. Intended to be used instead of NC_is_recvar(), which
-doesn't work for netCDF-4 variables which have multiple unlimited
-dimensions or an unlimited dimension that is not the first of a
-variable's dimensions.
-
-@param ncid File ID.
-@param varid Variable ID.
-@param nrecdimsp Pointer that gets number of record dims.
-@param is_recdim Pointer that gets 1 if there is one or more record
-dimensions, 0 if not.
-
-@returns 0 if not a record var, 1 if it is.
-
-Example use:
-@code
-int nrecdims;
-int is_recdim[NC_MAX_VAR_DIMS];
- ...
-status = NC_inq_recvar(ncid,varid,&nrecdims,is_recdim);
-isrecvar = (nrecdims > 0);
-@endcode
- */
-int
-NC_inq_recvar(int ncid, int varid, int* nrecdimsp, int *is_recdim)
-{
- int status = NC_NOERR;
- int unlimid;
- int nvardims;
- int dimset[NC_MAX_VAR_DIMS];
- int dim;
- int nrecdims = 0;
-
- status = nc_inq_varndims(ncid,varid,&nvardims);
- if(status != NC_NOERR) return status;
- if(nvardims == 0) return NC_NOERR; /* scalars have no dims */
- for(dim = 0; dim < nvardims; dim++)
- is_recdim[dim] = 0;
- status = nc_inq_unlimdim(ncid, &unlimid);
- if(status != NC_NOERR) return status;
- if(unlimid == -1) return status; /* no unlimited dims for any variables */
-#ifdef USE_NETCDF4
- {
- int nunlimdims;
- int *unlimids;
- int recdim;
- status = nc_inq_unlimdims(ncid, &nunlimdims, NULL); /* for group or file, not variable */
- if(status != NC_NOERR) return status;
- if(nunlimdims == 0) return status;
-
- if (!(unlimids = malloc(nunlimdims * sizeof(int))))
- return NC_ENOMEM;
- status = nc_inq_unlimdims(ncid, &nunlimdims, unlimids); /* for group or file, not variable */
- if(status != NC_NOERR) {
- free(unlimids);
- return status;
- }
- status = nc_inq_vardimid(ncid, varid, dimset);
- if(status != NC_NOERR) {
- free(unlimids);
- return status;
- }
- for (dim = 0; dim < nvardims; dim++) { /* netCDF-4 rec dims need not be first dim for a rec var */
- for(recdim = 0; recdim < nunlimdims; recdim++) {
- if(dimset[dim] == unlimids[recdim]) {
- is_recdim[dim] = 1;
- nrecdims++;
- }
- }
- }
- free(unlimids);
- }
-#else
- status = nc_inq_vardimid(ncid, varid, dimset);
- if(status != NC_NOERR) return status;
- if(dimset[0] == unlimid) {
- is_recdim[0] = 1;
- nrecdims++;
- }
-#endif /* USE_NETCDF4 */
- if(nrecdimsp) *nrecdimsp = nrecdims;
- return status;
-}
+ index[0] = 1;
+ if (nc_put_var1_ushort(ncid, varid, index, &ushort_data)) ERR;
-/* Ok to use NC pointers because
- all IOSP's will use that structure,
- but not ok to use e.g. NC_Var pointers
- because they may be different structure
- entirely.
-*/
+ index[0] = 0;
+ if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR;
-/**
- * @internal
- * @ingroup variables
- * Find the length of a type. This is how much space is required by
- * the in memory to hold one element of this type.
- *
- * @param type A netCDF atomic type.
- *
- * @return Length of the type in bytes, or -1 if type not found.
- * @author Ed Hartnett
- */
+ if (nc_close(ncid)) ERR;
+ @endcode
+ @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
+*/
int
-nctypelen(nc_type type)
+nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
{
- switch(type){
- case NC_CHAR :
- return ((int)sizeof(char));
- case NC_BYTE :
- return ((int)sizeof(signed char));
- case NC_SHORT :
- return ((int)sizeof(short));
- case NC_INT :
- return ((int)sizeof(int));
- case NC_FLOAT :
- return ((int)sizeof(float));
- case NC_DOUBLE :
- return ((int)sizeof(double));
-
- /* These can occur in netcdf-3 code */
- case NC_UBYTE :
- return ((int)sizeof(unsigned char));
- case NC_USHORT :
- return ((int)(sizeof(unsigned short)));
- case NC_UINT :
- return ((int)sizeof(unsigned int));
- case NC_INT64 :
- return ((int)sizeof(signed long long));
- case NC_UINT64 :
- return ((int)sizeof(unsigned long long));
-#ifdef USE_NETCDF4
- case NC_STRING :
- return ((int)sizeof(char*));
-#endif /*USE_NETCDF4*/
+ NC* ncp;
+ int stat = NC_check_id(ncid,&ncp);
+ if(stat != NC_NOERR) return stat;
- default:
- return -1;
- }
-}
+ /* Using NC_GLOBAL is illegal, as this API has no provision for
+ * specifying the type of the fillvalue, it must of necessity be
+ * using the type of the variable to interpret the bytes of the
+ * fill_value argument. */
+ if (varid == NC_GLOBAL) return NC_EGLOBAL;
-/** \internal
-\ingroup variables
-Find the length of a type. Redundant over nctypelen() above. */
-size_t
-NC_atomictypelen(nc_type xtype)
-{
- size_t sz = 0;
- switch(xtype) {
- case NC_NAT: sz = 0; break;
- case NC_BYTE: sz = sizeof(signed char); break;
- case NC_CHAR: sz = sizeof(char); break;
- case NC_SHORT: sz = sizeof(short); break;
- case NC_INT: sz = sizeof(int); break;
- case NC_FLOAT: sz = sizeof(float); break;
- case NC_DOUBLE: sz = sizeof(double); break;
- case NC_INT64: sz = sizeof(signed long long); break;
- case NC_UBYTE: sz = sizeof(unsigned char); break;
- case NC_USHORT: sz = sizeof(unsigned short); break;
- case NC_UINT: sz = sizeof(unsigned int); break;
- case NC_UINT64: sz = sizeof(unsigned long long); break;
-#ifdef USE_NETCDF4
- case NC_STRING: sz = sizeof(char*); break;
-#endif
- default: break;
- }
- return sz;
+ return ncp->dispatch->def_var_fill(ncid,varid,no_fill,fill_value);
}
-/** \internal
-\ingroup variables
- Get the type name. */
-char *
-NC_atomictypename(nc_type xtype)
-{
- char* nm = NULL;
- switch(xtype) {
- case NC_NAT: nm = "undefined"; break;
- case NC_BYTE: nm = "byte"; break;
- case NC_CHAR: nm = "char"; break;
- case NC_SHORT: nm = "short"; break;
- case NC_INT: nm = "int"; break;
- case NC_FLOAT: nm = "float"; break;
- case NC_DOUBLE: nm = "double"; break;
- case NC_INT64: nm = "int64"; break;
- case NC_UBYTE: nm = "ubyte"; break;
- case NC_USHORT: nm = "ushort"; break;
- case NC_UINT: nm = "uint"; break;
- case NC_UINT64: nm = "uint64"; break;
#ifdef USE_NETCDF4
- case NC_STRING: nm = "string"; break;
-#endif
- default: break;
- }
- return nm;
-}
+/**
+ Set the compression settings for a netCDF-4/HDF5 variable.
+
+ This function must be called after nc_def_var and before nc_enddef
+ or any functions which writes data to the file.
+
+ Deflation and shuffline require chunked data. If this function is
+ called on a variable with contiguous data, then the data is changed
+ to chunked data, with default chunksizes. Use nc_def_var_chunking()
+ to tune performance with user-defined chunksizes.
+
+ If this function is called on a scalar variable, it is ignored.
+
+ @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
+ @param shuffle True to turn on the shuffle filter. The shuffle
+ filter can assist with the compression of integer data by changing
+ the byte order in the data stream. It makes no sense to use the
+ shuffle filter without setting a deflate level, or to use shuffle
+ on non-integer data.
+ @param deflate True to turn on deflation for this variable.
+ @param deflate_level A number between 0 (no compression) and 9
+ (maximum compression).
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ncid.
+ @return ::NC_ENOTVAR Invalid variable ID.
+ @return ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ not netCDF-4/HDF5.
+ @return ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+ netcdf-4 file.
+ @return ::NC_ELATEDEF Too late to change settings for this variable.
+ @return ::NC_ENOTINDEFINE Not in define mode.
+ @return ::NC_EPERM File is read only.
+ @return ::NC_EMAXDIMS Classic model file exceeds ::NC_MAX_VAR_DIMS.
+ @return ::NC_ESTRICTNC3 Attempting to create netCDF-4 type var in
+ classic model file
+ @return ::NC_EBADTYPE Bad type.
+ @return ::NC_ENOMEM Out of memory.
+ @return ::NC_EHDFERR Error returned by HDF5 layer.
+ @return ::NC_EINVAL Invalid input. Deflate can't be set unless
+ variable storage is NC_CHUNK.
+
+ @section nc_def_var_deflate_example Example
+
+ Here is an example from /examples/C/simple_xy_nc4_wr.c using
+ nc_def_var_deflate to create a variable and then turn on the shuffle
+ filter and compression.
+
+ @code
+ #include
+ #define NDIMS 2
+ #define NX 6
+ #define NY 12
-/** \internal
-\ingroup variables
-Get the shape of a variable.
- */
-int
-NC_getshape(int ncid, int varid, int ndims, size_t* shape)
-{
- int dimids[NC_MAX_VAR_DIMS];
- int i;
- int status = NC_NOERR;
+ int ncid, x_dimid, y_dimid, varid;
+ int dimids[NDIMS];
+ int shuffle, deflate, deflate_level;
+ int data_out[NX][NY];
+ int x, y, retval;
- if ((status = nc_inq_vardimid(ncid, varid, dimids)))
- return status;
- for(i = 0; i < ndims; i++)
- if ((status = nc_inq_dimlen(ncid, dimids[i], &shape[i])))
- break;
+ shuffle = NC_SHUFFLE;
+ deflate = 1;
+ deflate_level = 1;
+ ...
+ if ((retval = nc_create(FILE_NAME, NC_NETCDF4, &ncid)))
+ ERR(retval);
- return status;
-}
+ if ((retval = nc_def_dim(ncid, "x", NX, &x_dimid)))
+ ERR(retval);
+ if ((retval = nc_def_dim(ncid, "y", NY, &y_dimid)))
+ ERR(retval);
-/**
- * @ingroup variables
- *
- * Set the fill value for a variable.
- *
- * @note For netCDF classic, 64-bit offset, and CDF5 formats, it is
- * allowed (but not good practice) to set the fill value after data
- * have been written to the variable. In this case, unless the
- * variable has been completely specified (without gaps in the data),
- * any existing filled values will not be recognized as fill values by
- * applications reading the data. Best practice is to set the fill
- * value after the variable has been defined, but before any data have
- * been written to that varibale. In NetCDF-4 files, this is enforced
- * by the HDF5 library. For netCDF-4 files, an error is returned if
- * the user attempts to set the fill value after writing data to the
- * variable.
-
- * @param ncid NetCDF ID, from a previous call to nc_open or
- * nc_create.
- * @param varid Variable ID.
- * @param no_fill Set to NC_NOFILL to turn off fill mode for this
- * variable. Set to NC_FILL (the default) to turn on fill mode for the
- * variable.
- * @param fill_value the fill value to be used for this variable. Must
- * be the same type as the variable. This must point to enough free
- * memory to hold one element of the data type of the variable. (For
- * example, an NC_INT will require 4 bytes for it's fill value, which
- * is also an NC_INT.)
- *
- * @returns ::NC_NOERR No error.
- * @returns ::NC_EBADID Bad ID.
- * @returns ::NC_ENOTINDEFINE Not in define mode. This is returned
- * for netCDF classic, 64-bit offset, or 64-bit data files, or for
- * netCDF-4 files, when they were created with NC_STRICT_NC3 flag. See
- * @ref nc_create.
- * @returns ::NC_EPERM Attempt to create object in read-only file.
- * @returns ::NC_ELATEDEF (NetCDF-4 only). Returned when user attempts
- * to set fill value after data are written.
- * @returns ::NC_EGLOBAL Attempt to set fill value on NC_GLOBAL.
- *
- * @section nc_def_var_fill_example Example
- *
- * In this example from libsrc4/tst_vars.c, a variable is defined, and
- * the fill mode turned off. Then nc_inq_fill() is used to check that
- * the setting is correct. Then some data are written to the
- * variable. Since the data that are written do not cover the full
- * extent of the variable, the missing values will just be random. If
- * fill value mode was turned on, the missing values would get the
- * fill value.
- *
- @code
-#define DIM7_LEN 2
-#define DIM7_NAME "dim_7_from_Indiana"
-#define VAR7_NAME "var_7_from_Idaho"
-#define NDIMS 1
- int dimids[NDIMS];
- size_t index[NDIMS];
- int varid;
- int no_fill;
- unsigned short ushort_data = 42, ushort_data_in, fill_value_in;
-
- if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
- if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
- if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
- &varid)) ERR;
- if (nc_def_var_fill(ncid, varid, 1, NULL)) ERR;
-
- if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
- if (!no_fill) ERR;
-
- index[0] = 1;
- if (nc_put_var1_ushort(ncid, varid, index, &ushort_data)) ERR;
-
- index[0] = 0;
- if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR;
-
- if (nc_close(ncid)) ERR;
- @endcode
- * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
+ dimids[0] = x_dimid;
+ dimids[1] = y_dimid;
+
+ if ((retval = nc_def_var(ncid, "data", NC_INT, NDIMS,
+ dimids, &varid)))
+ ERR(retval);
+
+ ...
+
+ if ((retval = nc_def_var_deflate(ncid, varid, shuffle, deflate,
+ deflate_level)))
+ ERR(retval);
+ ...
+ @endcode
+ @author Ed Hartnett, Dennis Heimbigner
*/
int
-nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
+nc_def_var_deflate(int ncid, int varid, int shuffle, int deflate, int deflate_level)
{
NC* ncp;
int stat = NC_check_id(ncid,&ncp);
if(stat != NC_NOERR) return stat;
-
- /* Dennis Heimbigner: Using NC_GLOBAL is illegal, as this API has no
- * provision for specifying the type of the fillvalue, it must of necessity
- * be using the type of the variable to interpret the bytes of the
- * fill_value argument.
- */
- if (varid == NC_GLOBAL) return NC_EGLOBAL;
-
- return ncp->dispatch->def_var_fill(ncid,varid,no_fill,fill_value);
+ return ncp->dispatch->def_var_deflate(ncid,varid,shuffle,deflate,deflate_level);
}
/**
- * @internal Check the start, count, and stride parameters for gets
- * and puts, and handle NULLs.
- *
- * @param ncid The file ID.
- * @param varid The variable ID.
- * @param start Pointer to start array. If NULL NC_EINVALCOORDS will
- * be returned for non-scalar variable.
- * @param count Pointer to pointer to count array. If *count is NULL,
- * an array of the correct size will be allocated, and filled with
- * counts that represent the full extent of the variable. In this
- * case, the memory must be freed by the caller.
- * @param stride Pointer to pointer to stride array. If NULL, stide is
- * ignored. If *stride is NULL an array of the correct size will be
- * allocated, and filled with ones. In this case, the memory must be
- * freed by the caller.
- *
- * @return ::NC_NOERR No error.
- * @return ::NC_EBADID Bad ncid.
- * @return ::NC_ENOTVAR Variable not found.
- * @return ::NC_ENOMEM Out of memory.
- * @return ::NC_EINVALCOORDS Missing start array.
- * @author Ed Hartnett
- */
+ Set checksum for a var.
+
+ This function must be called after nc_def_var and before nc_enddef
+ or any functions which writes data to the file.
+
+ Checksums require chunked data. If this function is called on a
+ variable with contiguous data, then the data is changed to chunked
+ data, with default chunksizes. Use nc_def_var_chunking() to tune
+ performance with user-defined chunksizes.
+
+ @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
+ @param fletcher32 True to turn on Fletcher32 checksums for this
+ variable.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ncid.
+ @return ::NC_ENOTVAR Invalid variable ID.
+ @return ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ not netCDF-4/HDF5.
+ @return ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+ netcdf-4 file.
+ @return ::NC_ELATEDEF Too late to change settings for this variable.
+ @return ::NC_EINVAL Invalid input
+ @author Ed Hartnett, Dennis Heimbigner
+*/
int
-NC_check_nulls(int ncid, int varid, const size_t *start, size_t **count,
- ptrdiff_t **stride)
+nc_def_var_fletcher32(int ncid, int varid, int fletcher32)
{
- int varndims;
- int stat;
-
- if ((stat = nc_inq_varndims(ncid, varid, &varndims)))
- return stat;
-
- /* For non-scalar vars, start is required. */
- if (!start && varndims)
- return NC_EINVALCOORDS;
+ NC* ncp;
+ int stat = NC_check_id(ncid,&ncp);
+ if(stat != NC_NOERR) return stat;
+ return ncp->dispatch->def_var_fletcher32(ncid,varid,fletcher32);
+}
- /* If count is NULL, assume full extent of var. */
- if (!*count)
+/**
+ Define chunking parameters for a variable
+
+ The function nc_def_var_chunking sets the chunking parameters for a
+ variable in a netCDF-4 file. It can set the chunk sizes to get chunked
+ storage, or it can set the contiguous flag to get contiguous storage.
+
+ The total size of a chunk must be less than 4 GiB. That is, the
+ product of all chunksizes and the size of the data (or the size of
+ nc_vlen_t for VLEN types) must be less than 4 GiB.
+
+ This function may only be called after the variable is defined, but
+ before nc_enddef is called. Once the chunking parameters are set for a
+ variable, they cannot be changed.
+
+ Note that this does not work for scalar variables. Only non-scalar
+ variables can have chunking.
+
+ @param[in] ncid NetCDF ID, from a previous call to nc_open or
+ nc_create.
+
+ @param[in] varid Variable ID.
+
+ @param[in] storage If ::NC_CONTIGUOUS, then contiguous storage is used
+ for this variable. Variables with one or more unlimited dimensions
+ cannot use contiguous storage. If contiguous storage is turned on, the
+ chunksizes parameter is ignored. If ::NC_CHUNKED, then chunked storage
+ is used for this variable. Chunk sizes may be specified with the
+ chunksizes parameter or default sizes will be used if that parameter
+ is NULL.
+
+ @param[in] chunksizesp A pointer to an array list of chunk sizes. The
+ array must have one chunksize for each dimension of the variable. If
+ ::NC_CONTIGUOUS storage is set, then the chunksizes parameter is
+ ignored.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ID.
+ @return ::NC_ENOTNC4 Not a netCDF-4 file.
+ @return ::NC_ELATEDEF This variable has already been the subject of a
+ nc_enddef call. In netCDF-4 files nc_enddef will be called
+ automatically for any data read or write. Once nc_enddef has been
+ called after the nc_def_var call for a variable, it is impossible to
+ set the chunking for that variable.
+ @return ::NC_ENOTINDEFINE Not in define mode. This is returned for
+ netCDF classic or 64-bit offset files, or for netCDF-4 files, when
+ they wwere created with ::NC_CLASSIC_MODEL flag by nc_create().
+ @return ::NC_EPERM Attempt to create object in read-only file.
+ @return ::NC_EBADCHUNK Retunrs if the chunk size specified for a
+ variable is larger than the length of the dimensions associated with
+ variable.
+
+ @section nc_def_var_chunking_example Example
+
+ In this example from libsrc4/tst_vars2.c, chunksizes are set with
+ nc_var_def_chunking, and checked with nc_var_inq_chunking.
+
+ @code
+ printf("**** testing chunking...");
{
- if (!(*count = malloc(varndims * sizeof(size_t))))
- return NC_ENOMEM;
- if ((stat = NC_getshape(ncid, varid, varndims, *count)))
- {
- free(*count);
- *count = NULL;
- return stat;
- }
- }
+ #define NDIMS5 1
+ #define DIM5_NAME "D5"
+ #define VAR_NAME5 "V5"
+ #define DIM5_LEN 1000
+
+ int dimids[NDIMS5], dimids_in[NDIMS5];
+ int varid;
+ int ndims, nvars, natts, unlimdimid;
+ nc_type xtype_in;
+ char name_in[NC_MAX_NAME + 1];
+ int data[DIM5_LEN], data_in[DIM5_LEN];
+ size_t chunksize[NDIMS5] = {5};
+ size_t chunksize_in[NDIMS5];
+ int storage_in;
+ int i, d;
+
+ for (i = 0; i < DIM5_LEN; i++)
+ data[i] = i;
+
+ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+ if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimids[0])) ERR;
+ if (nc_def_var(ncid, VAR_NAME5, NC_INT, NDIMS5, dimids, &varid)) ERR;
+ if (nc_def_var_chunking(ncid, varid, NC_CHUNKED, chunksize)) ERR;
+ if (nc_put_var_int(ncid, varid, data)) ERR;
+
+ if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksize_in)) ERR;
+ for (d = 0; d < NDIMS5; d++)
+ if (chunksize[d] != chunksize_in[d]) ERR;
+ if (storage_in != NC_CHUNKED) ERR;
+ @endcode
+*/
+int
+nc_def_var_chunking(int ncid, int varid, int storage,
+ const size_t *chunksizesp)
+{
+ NC* ncp;
+ int stat = NC_check_id(ncid, &ncp);
+ if(stat != NC_NOERR) return stat;
+ return ncp->dispatch->def_var_chunking(ncid, varid, storage,
+ chunksizesp);
+}
- /* If stride is NULL, do nothing, if *stride is NULL use all 1s. */
- if (stride && !*stride)
+/**
+ Define endianness of a variable.
+
+ With this function the endianness (i.e. order of bits in integers) can
+ be changed on a per-variable basis. By default, the endianness is the
+ same as the default endianness of the platform. But with
+ nc_def_var_endianness the endianness can be explicitly set for a
+ variable.
+
+ Warning: this function is only defined if the type of the variable
+ is an atomic integer or float type.
+
+ This function may only be called after the variable is defined, but
+ before nc_enddef is called.
+
+ @param ncid NetCDF ID, from a previous call to nc_open() or
+ nc_create().
+
+ @param varid Variable ID.
+
+ @param endian ::NC_ENDIAN_NATIVE to select the native endianness of
+ the platform (the default), ::NC_ENDIAN_LITTLE to use
+ little-endian, ::NC_ENDIAN_BIG to use big-endian.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ID.
+ @return ::NC_ENOTNC4 Not a netCDF-4 file.
+ @return ::NC_ELATEDEF This variable has already been the subject of a
+ nc_enddef call. In netCDF-4 files nc_enddef will be called
+ automatically for any data read or write. Once nc_enddef has been
+ called after the nc_def_var call for a variable, it is impossible to
+ set the chunking for that variable.
+ @return ::NC_ENOTINDEFINE Not in define mode. This is returned for
+ netCDF classic or 64-bit offset files, or for netCDF-4 files, when
+ they wwere created with ::NC_CLASSIC_MODEL flag by nc_create().
+ @return ::NC_EPERM Attempt to create object in read-only file.
+
+ @section nc_def_var_endian_example Example
+
+ In this example from libsrc4/tst_vars2.c, a variable is created, and
+ the endianness set to ::NC_ENDIAN_BIG.
+
+ @code
+ #define NDIMS4 1
+ #define DIM4_NAME "Joe"
+ #define VAR_NAME4 "Ed"
+ #define DIM4_LEN 10
{
- int i;
+ int dimids[NDIMS4], dimids_in[NDIMS4];
+ int varid;
+ int ndims, nvars, natts, unlimdimid;
+ nc_type xtype_in;
+ char name_in[NC_MAX_NAME + 1];
+ int data[DIM4_LEN], data_in[DIM4_LEN];
+ int endian_in;
+ int i;
- if (!(*stride = malloc(varndims * sizeof(ptrdiff_t))))
- return NC_ENOMEM;
- for (i = 0; i < varndims; i++)
- (*stride)[i] = 1;
- }
+ for (i = 0; i < DIM4_LEN; i++)
+ data[i] = i;
- return NC_NOERR;
+ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+ if (nc_def_dim(ncid, DIM4_NAME, DIM4_LEN, &dimids[0])) ERR;
+ if (dimids[0] != 0) ERR;
+ if (nc_def_var(ncid, VAR_NAME4, NC_INT, NDIMS4, dimids, &varid)) ERR;
+ if (nc_def_var_endian(ncid, varid, NC_ENDIAN_BIG)) ERR;
+ @endcode
+ @author Ed Hartnett
+*/
+int
+nc_def_var_endian(int ncid, int varid, int endian)
+{
+ NC* ncp;
+ int stat = NC_check_id(ncid,&ncp);
+ if(stat != NC_NOERR) return stat;
+ return ncp->dispatch->def_var_endian(ncid,varid,endian);
}
-/** \ingroup variables
-Free string space allocated by the library.
-
-When you read string type the library will allocate the storage space
-for the data. This storage space must be freed, so pass the pointer
-back to this function, when you're done with the data, and it will
-free the string memory.
+/**
+ Define a new variable filter.
-\param len The number of character arrays in the array.
-\param data The pointer to the data array.
+ @param ncid File and group ID.
+ @param varid Variable ID.
+ @param id
+ @param nparams Number of filter parameters.
+ @param parms Filter parameters.
-\returns ::NC_NOERR No error.
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ID.
+ @author Dennis Heimbigner
*/
int
-nc_free_string(size_t len, char **data)
+nc_def_var_filter(int ncid, int varid, unsigned int id,
+ size_t nparams, const unsigned int* parms)
{
- int i;
- for (i = 0; i < len; i++)
- free(data[i]);
- return NC_NOERR;
+ NC* ncp;
+ int stat = NC_check_id(ncid,&ncp);
+ if(stat != NC_NOERR) return stat;
+ return ncp->dispatch->def_var_filter(ncid,varid,id,nparams,parms);
}
+#endif /* USE_NETCDF4 */
-#ifdef USE_NETCDF4
-/** \ingroup variables
+/** @} */
-Change the cache settings for a chunked variable. This function allows
-users to control the amount of memory used in the per-variable chunk
-cache at the HDF5 level. Changing the chunk cache only has effect
-until the file is closed. Once re-opened, the variable chunk cache
-returns to its default value.
+/**
+ @name Rename a Variable
-\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().
+ Rename a variable.
+*/
+/** @{ */
-\param varid Variable ID
+/**
+ Rename a variable.
-\param size The total size of the raw data chunk cache, in bytes.
+ This function changes the name of a netCDF variable in an open netCDF
+ file or group. You cannot rename a variable to have the name of any existing
+ variable.
-\param nelems The number of chunk slots in the raw data chunk cache.
+ For classic format, 64-bit offset format, and netCDF-4/HDF5 with
+ classic mode, if the new name is longer than the old name, the netCDF
+ dataset must be in define mode.
-\param preemption The preemption, a value between 0 and 1 inclusive
-that indicates how much chunks that have been fully read are favored
-for preemption. A value of zero means fully read chunks are treated no
-differently than other chunks (the preemption is strictly LRU) while a
-value of one means fully read chunks are always preempted before other
-chunks.
+ For netCDF-4/HDF5 files, renaming the variable changes the order of
+ the variables in the file. The renamed variable becomes the last
+ variable in the file.
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Bad ncid.
-\returns ::NC_ENOTVAR Invalid variable ID.
-\returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
-\returns ::NC_EINVAL Invalid input
+ @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().
-\section nc_def_var_chunk_cache_example Example
+ @param varid Variable ID
-In this example from nc_test4/tst_coords.c, a variable is defined, and
-the chunk cache settings are changed for that variable.
+ @param name New name of the variable.
-\code
- printf("**** testing setting cache values for coordinate variables...");
- {
-#define RANK_1 1
-#define DIM0_NAME "d0"
-#define CACHE_SIZE 1000000
-#define CACHE_NELEMS 1009
-#define CACHE_PREEMPTION .90
-
- int ncid, dimid, varid;
- char name_in[NC_MAX_NAME + 1];
-
- if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_NETCDF4, &ncid)) ERR;
- if (nc_def_dim(ncid, DIM0_NAME, NC_UNLIMITED, &dimid)) ERR;
- if (nc_def_var(ncid, DIM0_NAME, NC_DOUBLE, 1, &dimid, &varid)) ERR;
- if (nc_set_var_chunk_cache(ncid, varid, CACHE_SIZE, CACHE_NELEMS, CACHE_PREEMPTION)) ERR;
- if (nc_close(ncid)) ERR;
-
- ...
- }
- SUMMARIZE_ERR;
-\endcode
- */
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ncid.
+ @return ::NC_ENOTVAR Invalid variable ID.
+ @return ::NC_EBADNAME Bad name.
+ @return ::NC_EMAXNAME Name is too long.
+ @return ::NC_ENAMEINUSE Name in use.
+ @return ::NC_ENOMEM Out of memory.
+
+ @section nc_rename_var_example Example
+
+ Here is an example using nc_rename_var to rename the variable rh to
+ rel_hum in an existing netCDF dataset named foo.nc:
+
+ @code
+ #include
+ ...
+ int status;
+ int ncid;
+ int rh_id;
+ ...
+ status = nc_open("foo.nc", NC_WRITE, &ncid);
+ if (status != NC_NOERR) handle_error(status);
+ ...
+ status = nc_redef(ncid);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_inq_varid (ncid, "rh", &rh_id);
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_rename_var (ncid, rh_id, "rel_hum");
+ if (status != NC_NOERR) handle_error(status);
+ status = nc_enddef(ncid);
+ if (status != NC_NOERR) handle_error(status);
+ @endcode
+ @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
+*/
int
-nc_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
- float preemption)
+nc_rename_var(int ncid, int varid, const char *name)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
- return ncp->dispatch->set_var_chunk_cache(ncid, varid, size,
- nelems, preemption);
+ TRACE(nc_rename_var);
+ return ncp->dispatch->rename_var(ncid, varid, name);
}
+/** @} */
-/** \ingroup variables
+/**
+ @internal Does a variable have a record dimension?
-Get the per-variable chunk cache settings from the HDF5 layer.
+ @param ncid File ID.
+ @param varid Variable ID.
+ @param nrecs Pointer that gets number of records.
-\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().
+ @return 0 if not a record var, 1 if it is.
+*/
+int
+NC_is_recvar(int ncid, int varid, size_t* nrecs)
+{
+ int status = NC_NOERR;
+ int unlimid;
+ int ndims;
+ int dimset[NC_MAX_VAR_DIMS];
+
+ status = nc_inq_unlimdim(ncid,&unlimid);
+ if(status != NC_NOERR) return 0; /* no unlimited defined */
+ status = nc_inq_varndims(ncid,varid,&ndims);
+ if(status != NC_NOERR) return 0; /* no unlimited defined */
+ if(ndims == 0) return 0; /* scalar */
+ status = nc_inq_vardimid(ncid,varid,dimset);
+ if(status != NC_NOERR) return 0; /* no unlimited defined */
+ status = nc_inq_dim(ncid,dimset[0],NULL,nrecs);
+ if(status != NC_NOERR) return 0;
+ return (dimset[0] == unlimid ? 1: 0);
+}
-\param varid Variable ID
+/**
+ @internal Get the number of record dimensions for a variable and an
+ array that identifies which of a variable's dimensions are record
+ dimensions. Intended to be used instead of NC_is_recvar(), which
+ doesn't work for netCDF-4 variables which have multiple unlimited
+ dimensions or an unlimited dimension that is not the first of a
+ variable's dimensions.
+
+ @param ncid File ID.
+ @param varid Variable ID.
+ @param nrecdimsp Pointer that gets number of record dims.
+ @param is_recdim Pointer that gets 1 if there is one or more record
+ dimensions, 0 if not.
+
+ @return 0 if not a record var, 1 if it is.
+
+ Example use:
+ @code
+ int nrecdims;
+ int is_recdim[NC_MAX_VAR_DIMS];
+ ...
+ status = NC_inq_recvar(ncid,varid,&nrecdims,is_recdim);
+ isrecvar = (nrecdims > 0);
+ @endcode
+*/
+int
+NC_inq_recvar(int ncid, int varid, int* nrecdimsp, int *is_recdim)
+{
+ int status = NC_NOERR;
+ int unlimid;
+ int nvardims;
+ int dimset[NC_MAX_VAR_DIMS];
+ int dim;
+ int nrecdims = 0;
+
+ status = nc_inq_varndims(ncid,varid,&nvardims);
+ if(status != NC_NOERR) return status;
+ if(nvardims == 0) return NC_NOERR; /* scalars have no dims */
+ for(dim = 0; dim < nvardims; dim++)
+ is_recdim[dim] = 0;
+ status = nc_inq_unlimdim(ncid, &unlimid);
+ if(status != NC_NOERR) return status;
+ if(unlimid == -1) return status; /* no unlimited dims for any variables */
+#ifdef USE_NETCDF4
+ {
+ int nunlimdims;
+ int *unlimids;
+ int recdim;
+ status = nc_inq_unlimdims(ncid, &nunlimdims, NULL); /* for group or file, not variable */
+ if(status != NC_NOERR) return status;
+ if(nunlimdims == 0) return status;
+
+ if (!(unlimids = malloc(nunlimdims * sizeof(int))))
+ return NC_ENOMEM;
+ status = nc_inq_unlimdims(ncid, &nunlimdims, unlimids); /* for group or file, not variable */
+ if(status != NC_NOERR) {
+ free(unlimids);
+ return status;
+ }
+ status = nc_inq_vardimid(ncid, varid, dimset);
+ if(status != NC_NOERR) {
+ free(unlimids);
+ return status;
+ }
+ for (dim = 0; dim < nvardims; dim++) { /* netCDF-4 rec dims need not be first dim for a rec var */
+ for(recdim = 0; recdim < nunlimdims; recdim++) {
+ if(dimset[dim] == unlimids[recdim]) {
+ is_recdim[dim] = 1;
+ nrecdims++;
+ }
+ }
+ }
+ free(unlimids);
+ }
+#else
+ status = nc_inq_vardimid(ncid, varid, dimset);
+ if(status != NC_NOERR) return status;
+ if(dimset[0] == unlimid) {
+ is_recdim[0] = 1;
+ nrecdims++;
+ }
+#endif /* USE_NETCDF4 */
+ if(nrecdimsp) *nrecdimsp = nrecdims;
+ return status;
+}
-\param sizep The total size of the raw data chunk cache, in bytes,
-will be put here. \ref ignored_if_null.
+/* Ok to use NC pointers because
+ all IOSP's will use that structure,
+ but not ok to use e.g. NC_Var pointers
+ because they may be different structure
+ entirely.
+*/
-\param nelemsp The number of chunk slots in the raw data chunk cache
-hash table will be put here. \ref ignored_if_null.
+/**
+ @internal
+ Find the length of a type. This is how much space is required by
+ the in memory to hold one element of this type.
-\param preemptionp The preemption will be put here. The preemtion
-value is between 0 and 1 inclusive and indicates how much chunks that
-have been fully read are favored for preemption. A value of zero means
-fully read chunks are treated no differently than other chunks (the
-preemption is strictly LRU) while a value of one means fully read
-chunks are always preempted before other chunks. \ref ignored_if_null.
+ @param type A netCDF atomic type.
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Bad ncid.
-\returns ::NC_ENOTVAR Invalid variable ID.
-\returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
-netcdf-4 file.
-\returns ::NC_EINVAL Invalid input
+ @return Length of the type in bytes, or -1 if type not found.
+ @author Ed Hartnett
*/
int
-nc_get_var_chunk_cache(int ncid, int varid, size_t *sizep, size_t *nelemsp,
- float *preemptionp)
+nctypelen(nc_type type)
{
- NC* ncp;
- int stat = NC_check_id(ncid, &ncp);
- if(stat != NC_NOERR) return stat;
- return ncp->dispatch->get_var_chunk_cache(ncid, varid, sizep,
- nelemsp, preemptionp);
+ switch(type){
+ case NC_CHAR :
+ return ((int)sizeof(char));
+ case NC_BYTE :
+ return ((int)sizeof(signed char));
+ case NC_SHORT :
+ return ((int)sizeof(short));
+ case NC_INT :
+ return ((int)sizeof(int));
+ case NC_FLOAT :
+ return ((int)sizeof(float));
+ case NC_DOUBLE :
+ return ((int)sizeof(double));
+
+ /* These can occur in netcdf-3 code */
+ case NC_UBYTE :
+ return ((int)sizeof(unsigned char));
+ case NC_USHORT :
+ return ((int)(sizeof(unsigned short)));
+ case NC_UINT :
+ return ((int)sizeof(unsigned int));
+ case NC_INT64 :
+ return ((int)sizeof(signed long long));
+ case NC_UINT64 :
+ return ((int)sizeof(unsigned long long));
+#ifdef USE_NETCDF4
+ case NC_STRING :
+ return ((int)sizeof(char*));
+#endif /*USE_NETCDF4*/
+
+ default:
+ return -1;
+ }
}
/**
- * @ingroup variables
- *
- * Set the compression settings for a netCDF-4/HDF5 variable.
- *
- * This function must be called after nc_def_var and before nc_enddef
- * or any functions which writes data to the file.
- *
- * Deflation and shuffline require chunked data. If this function is
- * called on a variable with contiguous data, then the data is changed
- * to chunked data, with default chunksizes. Use nc_def_var_chunking()
- * to tune performance with user-defined chunksizes.
- *
- * If this function is called on a scalar variable, it is ignored.
- *
- * @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
- * @param shuffle True to turn on the shuffle filter. The shuffle
- * filter can assist with the compression of integer data by changing
- * the byte order in the data stream. It makes no sense to use the
- * shuffle filter without setting a deflate level, or to use shuffle
- * on non-integer data.
- * @param deflate True to turn on deflation for this variable.
- * @param deflate_level A number between 0 (no compression) and 9
- * (maximum compression).
- *
- * @returns ::NC_NOERR No error.
- * @returns ::NC_EBADID Bad ncid.
- * @returns ::NC_ENOTVAR Invalid variable ID.
- * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
- * not netCDF-4/HDF5.
- * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
- * netcdf-4 file.
- * @returns ::NC_ELATEDEF Too late to change settings for this variable.
- * @returns ::NC_ENOTINDEFINE Not in define mode.
- * @returns ::NC_EPERM File is read only.
- * @returns ::NC_EMAXDIMS Classic model file exceeds ::NC_MAX_VAR_DIMS.
- * @returns ::NC_ESTRICTNC3 Attempting to create netCDF-4 type var in
-classic model file
- * @returns ::NC_EBADTYPE Bad type.
- * @returns ::NC_ENOMEM Out of memory.
- * @returns ::NC_EHDFERR Error returned by HDF5 layer.
- * @returns ::NC_EINVAL Invalid input. Deflate can't be set unless
-variable storage is NC_CHUNK.
-
-@section nc_def_var_deflate_example Example
-
-Here is an example from /examples/C/simple_xy_nc4_wr.c using
-nc_def_var_deflate to create a variable and then turn on the shuffle
-filter and compression.
-
-@code
-#include
-#define NDIMS 2
-#define NX 6
-#define NY 12
+ @internal
+ Find the length of a type. Redundant over nctypelen() above.
- int ncid, x_dimid, y_dimid, varid;
- int dimids[NDIMS];
- int shuffle, deflate, deflate_level;
- int data_out[NX][NY];
- int x, y, retval;
+ @param xtype an nc_type.
- shuffle = NC_SHUFFLE;
- deflate = 1;
- deflate_level = 1;
- ...
- if ((retval = nc_create(FILE_NAME, NC_NETCDF4, &ncid)))
- ERR(retval);
+ @author Dennis Heimbigner
+*/
+size_t
+NC_atomictypelen(nc_type xtype)
+{
+ size_t sz = 0;
+ switch(xtype) {
+ case NC_NAT: sz = 0; break;
+ case NC_BYTE: sz = sizeof(signed char); break;
+ case NC_CHAR: sz = sizeof(char); break;
+ case NC_SHORT: sz = sizeof(short); break;
+ case NC_INT: sz = sizeof(int); break;
+ case NC_FLOAT: sz = sizeof(float); break;
+ case NC_DOUBLE: sz = sizeof(double); break;
+ case NC_INT64: sz = sizeof(signed long long); break;
+ case NC_UBYTE: sz = sizeof(unsigned char); break;
+ case NC_USHORT: sz = sizeof(unsigned short); break;
+ case NC_UINT: sz = sizeof(unsigned int); break;
+ case NC_UINT64: sz = sizeof(unsigned long long); break;
+#ifdef USE_NETCDF4
+ case NC_STRING: sz = sizeof(char*); break;
+#endif
+ default: break;
+ }
+ return sz;
+}
- if ((retval = nc_def_dim(ncid, "x", NX, &x_dimid)))
- ERR(retval);
- if ((retval = nc_def_dim(ncid, "y", NY, &y_dimid)))
- ERR(retval);
+/**
+ @internal
+ Get the type name.
- dimids[0] = x_dimid;
- dimids[1] = y_dimid;
+ @param xtype an nc_type.
- if ((retval = nc_def_var(ncid, "data", NC_INT, NDIMS,
- dimids, &varid)))
- ERR(retval);
+ @author Dennis Heimbigner
+*/
+char *
+NC_atomictypename(nc_type xtype)
+{
+ char* nm = NULL;
+ switch(xtype) {
+ case NC_NAT: nm = "undefined"; break;
+ case NC_BYTE: nm = "byte"; break;
+ case NC_CHAR: nm = "char"; break;
+ case NC_SHORT: nm = "short"; break;
+ case NC_INT: nm = "int"; break;
+ case NC_FLOAT: nm = "float"; break;
+ case NC_DOUBLE: nm = "double"; break;
+ case NC_INT64: nm = "int64"; break;
+ case NC_UBYTE: nm = "ubyte"; break;
+ case NC_USHORT: nm = "ushort"; break;
+ case NC_UINT: nm = "uint"; break;
+ case NC_UINT64: nm = "uint64"; break;
+#ifdef USE_NETCDF4
+ case NC_STRING: nm = "string"; break;
+#endif
+ default: break;
+ }
+ return nm;
+}
- ...
+/**
+ @internal
+ Get the shape of a variable.
- if ((retval = nc_def_var_deflate(ncid, varid, shuffle, deflate,
- deflate_level)))
- ERR(retval);
- ...
-@endcode
-* @author Ed Hartnett, Dennis Heimbigner
+ @param ncid NetCDF ID, from a previous call to nc_open() or
+ nc_create().
+ @param varid Variable ID.
+ @param ndims Number of dimensions for this var.
+ @param shape Pointer to pre-allocated array that gets the size of
+ each dimension.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ncid.
+ @return ::NC_ENOTVAR Bad varid.
+
+ @author Dennis Heimbigner
*/
int
-nc_def_var_deflate(int ncid, int varid, int shuffle, int deflate, int deflate_level)
+NC_getshape(int ncid, int varid, int ndims, size_t* shape)
{
- NC* ncp;
- int stat = NC_check_id(ncid,&ncp);
- if(stat != NC_NOERR) return stat;
- return ncp->dispatch->def_var_deflate(ncid,varid,shuffle,deflate,deflate_level);
+ int dimids[NC_MAX_VAR_DIMS];
+ int i;
+ int status = NC_NOERR;
+
+ if ((status = nc_inq_vardimid(ncid, varid, dimids)))
+ return status;
+ for(i = 0; i < ndims; i++)
+ if ((status = nc_inq_dimlen(ncid, dimids[i], &shape[i])))
+ break;
+
+ return status;
}
/**
- * @ingroup variables
- *
- * Set checksum for a var.
- *
- * This function must be called after nc_def_var and before nc_enddef
- * or any functions which writes data to the file.
- *
- * Checksums require chunked data. If this function is called on a
- * variable with contiguous data, then the data is changed to chunked
- * data, with default chunksizes. Use nc_def_var_chunking() to tune
- * performance with user-defined chunksizes.
- *
- * @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
- * @param fletcher32 True to turn on Fletcher32 checksums for this
- * variable.
- *
- * @returns ::NC_NOERR No error.
- * @returns ::NC_EBADID Bad ncid.
- * @returns ::NC_ENOTVAR Invalid variable ID.
- * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
-not netCDF-4/HDF5.
- * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
-netcdf-4 file.
- * @returns ::NC_ELATEDEF Too late to change settings for this variable.
- * @returns ::NC_EINVAL Invalid input
- * @author Ed Hartnett, Dennis Heimbigner
+ @internal Check the start, count, and stride parameters for gets
+ and puts, and handle NULLs.
+
+ @param ncid The file ID.
+ @param varid The variable ID.
+ @param start Pointer to start array. If NULL ::NC_EINVALCOORDS will
+ be returned for non-scalar variable.
+ @param count Pointer to pointer to count array. If *count is NULL,
+ an array of the correct size will be allocated, and filled with
+ counts that represent the full extent of the variable. In this
+ case, the memory must be freed by the caller.
+ @param stride Pointer to pointer to stride array. If NULL, stide is
+ ignored. If *stride is NULL an array of the correct size will be
+ allocated, and filled with ones. In this case, the memory must be
+ freed by the caller.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ncid.
+ @return ::NC_ENOTVAR Variable not found.
+ @return ::NC_ENOMEM Out of memory.
+ @return ::NC_EINVALCOORDS Missing start array.
+ @author Ed Hartnett
*/
int
-nc_def_var_fletcher32(int ncid, int varid, int fletcher32)
+NC_check_nulls(int ncid, int varid, const size_t *start, size_t **count,
+ ptrdiff_t **stride)
{
- NC* ncp;
- int stat = NC_check_id(ncid,&ncp);
- if(stat != NC_NOERR) return stat;
- return ncp->dispatch->def_var_fletcher32(ncid,varid,fletcher32);
+ int varndims;
+ int stat;
+
+ if ((stat = nc_inq_varndims(ncid, varid, &varndims)))
+ return stat;
+
+ /* For non-scalar vars, start is required. */
+ if (!start && varndims)
+ return NC_EINVALCOORDS;
+
+ /* If count is NULL, assume full extent of var. */
+ if (!*count)
+ {
+ if (!(*count = malloc(varndims * sizeof(size_t))))
+ return NC_ENOMEM;
+ if ((stat = NC_getshape(ncid, varid, varndims, *count)))
+ {
+ free(*count);
+ *count = NULL;
+ return stat;
+ }
+ }
+
+ /* If stride is NULL, do nothing, if *stride is NULL use all
+ * 1s. */
+ if (stride && !*stride)
+ {
+ int i;
+
+ if (!(*stride = malloc(varndims * sizeof(ptrdiff_t))))
+ return NC_ENOMEM;
+ for (i = 0; i < varndims; i++)
+ (*stride)[i] = 1;
+ }
+
+ return NC_NOERR;
}
-/*! Define chunking parameters for a variable
-
-\ingroup variables
-
-The function nc_def_var_chunking sets the chunking parameters for a
-variable in a netCDF-4 file. It can set the chunk sizes to get chunked
-storage, or it can set the contiguous flag to get contiguous storage.
-
-The total size of a chunk must be less than 4 GiB. That is, the
-product of all chunksizes and the size of the data (or the size of
-nc_vlen_t for VLEN types) must be less than 4 GiB.
-
-This function may only be called after the variable is defined, but
-before nc_enddef is called. Once the chunking parameters are set for a
-variable, they cannot be changed.
-
-Note that this does not work for scalar variables. Only non-scalar
-variables can have chunking.
-
-\param[in] ncid NetCDF ID, from a previous call to nc_open or
-nc_create.
-
-\param[in] varid Variable ID.
-
-\param[in] storage If ::NC_CONTIGUOUS, then contiguous storage is used
-for this variable. Variables with one or more unlimited dimensions
-cannot use contiguous storage. If contiguous storage is turned on, the
-chunksizes parameter is ignored. If ::NC_CHUNKED, then chunked storage
-is used for this variable. Chunk sizes may be specified with the
-chunksizes parameter or default sizes will be used if that parameter
-is NULL.
-
-\param[in] chunksizesp A pointer to an array list of chunk sizes. The
-array must have one chunksize for each dimension of the variable. If
-::NC_CONTIGUOUS storage is set, then the chunksizes parameter is
-ignored.
-
- * @returns ::NC_NOERR No error.
- * @returns ::NC_EBADID Bad ID.
- * @returns ::NC_ENOTNC4 Not a netCDF-4 file.
- * @returns ::NC_ELATEDEF This variable has already been the subject of a
-nc_enddef call. In netCDF-4 files nc_enddef will be called
-automatically for any data read or write. Once nc_enddef has been
-called after the nc_def_var call for a variable, it is impossible to
-set the chunking for that variable.
- * @returns ::NC_ENOTINDEFINE Not in define mode. This is returned for
-netCDF classic or 64-bit offset files, or for netCDF-4 files, when
-they wwere created with NC_STRICT_NC3 flag. See \ref nc_create.
- * @returns ::NC_EPERM Attempt to create object in read-only file.
- * @returns ::NC_EBADCHUNK Retunrs if the chunk size specified for a
-variable is larger than the length of the dimensions associated with
-variable.
-
-\section nc_def_var_chunking_example Example
-
-In this example from libsrc4/tst_vars2.c, chunksizes are set with
-nc_var_def_chunking, and checked with nc_var_inq_chunking.
-
-\code
- printf("**** testing chunking...");
- {
- #define NDIMS5 1
- #define DIM5_NAME "D5"
- #define VAR_NAME5 "V5"
- #define DIM5_LEN 1000
-
- int dimids[NDIMS5], dimids_in[NDIMS5];
- int varid;
- int ndims, nvars, natts, unlimdimid;
- nc_type xtype_in;
- char name_in[NC_MAX_NAME + 1];
- int data[DIM5_LEN], data_in[DIM5_LEN];
- size_t chunksize[NDIMS5] = {5};
- size_t chunksize_in[NDIMS5];
- int storage_in;
- int i, d;
-
- for (i = 0; i < DIM5_LEN; i++)
- data[i] = i;
-
- if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
- if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimids[0])) ERR;
- if (nc_def_var(ncid, VAR_NAME5, NC_INT, NDIMS5, dimids, &varid)) ERR;
- if (nc_def_var_chunking(ncid, varid, NC_CHUNKED, chunksize)) ERR;
- if (nc_put_var_int(ncid, varid, data)) ERR;
-
- if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksize_in)) ERR;
- for (d = 0; d < NDIMS5; d++)
- if (chunksize[d] != chunksize_in[d]) ERR;
- if (storage_in != NC_CHUNKED) ERR;
-\endcode
+/**
+ @name Free String Resources
+
+ Use this functions to free resources associated with ::NC_STRING
+ data.
+*/
+/*! @{ */
+/**
+ Free string space allocated by the library.
+
+ When you read string type the library will allocate the storage
+ space for the data. This storage space must be freed, so pass the
+ pointer back to this function, when you're done with the data, and
+ it will free the string memory.
+
+ @param len The number of character arrays in the array.
+ @param data The pointer to the data array.
+
+ @return ::NC_NOERR No error.
+ @author Ed Hartnett
*/
int
-nc_def_var_chunking(int ncid, int varid, int storage,
- const size_t *chunksizesp)
+nc_free_string(size_t len, char **data)
{
- NC* ncp;
- int stat = NC_check_id(ncid, &ncp);
- if(stat != NC_NOERR) return stat;
- return ncp->dispatch->def_var_chunking(ncid, varid, storage,
- chunksizesp);
+ int i;
+ for (i = 0; i < len; i++)
+ free(data[i]);
+ return NC_NOERR;
}
+/** @} */
+#ifdef USE_NETCDF4
/**
-@ingroup variables
-
-Define endianness of a variable.
-
-With this function the endianness (i.e. order of bits in integers) can
-be changed on a per-variable basis. By default, the endianness is the
-same as the default endianness of the platform. But with
-nc_def_var_endianness the endianness can be explicitly set for a
-variable.
-
-Warning: this function is only defined if the type of the variable
-is an atomic integer or float type.
-
-This function may only be called after the variable is defined, but
-before nc_enddef is called.
-
-@param[in] ncid NetCDF ID, from a previous call to nc_open or
-nc_create.
-
-@param[in] varid Variable ID.
-
-@param[in] endian NC_ENDIAN_NATIVE to select the native endianness of
-the platform (the default), NC_ENDIAN_LITTLE to use little-endian,
-NC_ENDIAN_BIG to use big-endian.
-
-@returns ::NC_NOERR No error.
-@returns ::NC_EBADID Bad ID.
-@returns ::NC_ENOTNC4 Not a netCDF-4 file.
-@returns ::NC_ELATEDEF This variable has already been the subject of a
-nc_enddef call. In netCDF-4 files nc_enddef will be called
-automatically for any data read or write. Once nc_enddef has been
-called after the nc_def_var call for a variable, it is impossible to
-set the chunking for that variable.
-@returns ::NC_ENOTINDEFINE Not in define mode. This is returned for
-netCDF classic or 64-bit offset files, or for netCDF-4 files, when
-they wwere created with NC_STRICT_NC3 flag. See \ref nc_create.
-@returns ::NC_EPERM Attempt to create object in read-only file.
-
-@section nc_def_var_endian_example Example
-
-In this example from libsrc4/tst_vars2.c, a variable is created, and
-the endianness set to NC_ENDIAN_BIG.
-
-@code
-#define NDIMS4 1
-#define DIM4_NAME "Joe"
-#define VAR_NAME4 "Ed"
-#define DIM4_LEN 10
+ @name Variables Chunk Caches
+
+ Use these functions to change the variable chunk cache settings.
+*/
+/*! @{ */
+/**
+ Change the cache settings for a chunked variable. This function allows
+ users to control the amount of memory used in the per-variable chunk
+ cache at the HDF5 level. Changing the chunk cache only has effect
+ until the file is closed. Once re-opened, the variable chunk cache
+ returns to its default value.
+
+ @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
+ @param size The total size of the raw data chunk cache, in bytes.
+ @param nelems The number of chunk slots in the raw data chunk cache.
+ @param preemption The preemption, a value between 0 and 1 inclusive
+ that indicates how much chunks that have been fully read are favored
+ for preemption. A value of zero means fully read chunks are treated no
+ differently than other chunks (the preemption is strictly LRU) while a
+ value of one means fully read chunks are always preempted before other
+ chunks.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ncid.
+ @return ::NC_ENOTVAR Invalid variable ID.
+ @return ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+ netcdf-4 file.
+ @return ::NC_EINVAL Invalid input
+
+ @section nc_def_var_chunk_cache_example Example
+
+ In this example from nc_test4/tst_coords.c, a variable is defined, and
+ the chunk cache settings are changed for that variable.
+
+ @code
+ printf("**** testing setting cache values for coordinate variables...");
{
- int dimids[NDIMS4], dimids_in[NDIMS4];
- int varid;
- int ndims, nvars, natts, unlimdimid;
- nc_type xtype_in;
- char name_in[NC_MAX_NAME + 1];
- int data[DIM4_LEN], data_in[DIM4_LEN];
- int endian_in;
- int i;
-
- for (i = 0; i < DIM4_LEN; i++)
- data[i] = i;
-
- if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
- if (nc_def_dim(ncid, DIM4_NAME, DIM4_LEN, &dimids[0])) ERR;
- if (dimids[0] != 0) ERR;
- if (nc_def_var(ncid, VAR_NAME4, NC_INT, NDIMS4, dimids, &varid)) ERR;
- if (nc_def_var_endian(ncid, varid, NC_ENDIAN_BIG)) ERR;
-@endcode
-@author Ed Hartnett
+ #define RANK_1 1
+ #define DIM0_NAME "d0"
+ #define CACHE_SIZE 1000000
+ #define CACHE_NELEMS 1009
+ #define CACHE_PREEMPTION .90
+
+ int ncid, dimid, varid;
+ char name_in[NC_MAX_NAME + 1];
+
+ if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_NETCDF4, &ncid)) ERR;
+ if (nc_def_dim(ncid, DIM0_NAME, NC_UNLIMITED, &dimid)) ERR;
+ if (nc_def_var(ncid, DIM0_NAME, NC_DOUBLE, 1, &dimid, &varid)) ERR;
+ if (nc_set_var_chunk_cache(ncid, varid, CACHE_SIZE, CACHE_NELEMS, CACHE_PREEMPTION)) ERR;
+ if (nc_close(ncid)) ERR;
+
+ ...
+ }
+ SUMMARIZE_ERR;
+ @endcode
+ @author Ed Hartnett
*/
int
-nc_def_var_endian(int ncid, int varid, int endian)
+nc_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
+ float preemption)
{
NC* ncp;
- int stat = NC_check_id(ncid,&ncp);
+ int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
- return ncp->dispatch->def_var_endian(ncid,varid,endian);
+ return ncp->dispatch->set_var_chunk_cache(ncid, varid, size,
+ nelems, preemption);
}
/**
- * Define a new variable filter.
- *
- * @param ncid File and group ID.
- * @param varid Variable ID.
- * @param id
- * @param nparams Number of filter parameters.
- * @param parms Filter parameters.
- *
- * @return ::NC_NOERR No error.
- * @return ::NC_EBADID Bad ID.
- * @author Dennis Heimbigner
- */
+ Get the per-variable chunk cache settings from the HDF5 layer.
+
+ @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
+ @param sizep The total size of the raw data chunk cache, in bytes,
+ will be put here. @ref ignored_if_null.
+ @param nelemsp The number of chunk slots in the raw data chunk
+ cache hash table will be put here. @ref ignored_if_null.
+ @param preemptionp The preemption will be put here. The preemtion
+ value is between 0 and 1 inclusive and indicates how much chunks
+ that have been fully read are favored for preemption. A value of
+ zero means fully read chunks are treated no differently than other
+ chunks (the preemption is strictly LRU) while a value of one means
+ fully read chunks are always preempted before other chunks. @ref
+ ignored_if_null.
+
+ @return ::NC_NOERR No error.
+ @return ::NC_EBADID Bad ncid.
+ @return ::NC_ENOTVAR Invalid variable ID.
+ @return ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+ netcdf-4 file.
+ @return ::NC_EINVAL Invalid input
+ @author Ed Hartnett
+*/
int
-nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms)
+nc_get_var_chunk_cache(int ncid, int varid, size_t *sizep, size_t *nelemsp,
+ float *preemptionp)
{
NC* ncp;
- int stat = NC_check_id(ncid,&ncp);
+ int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
- return ncp->dispatch->def_var_filter(ncid,varid,id,nparams,parms);
+ return ncp->dispatch->get_var_chunk_cache(ncid, varid, sizep,
+ nelemsp, preemptionp);
}
-
+/** @} */
#endif /* USE_NETCDF4 */
+/** @} */
diff --git a/libdispatch/dvarget.c b/libdispatch/dvarget.c
index 0a18108092..9b541800a8 100644
--- a/libdispatch/dvarget.c
+++ b/libdispatch/dvarget.c
@@ -107,6 +107,7 @@ NC_get_vara(int ncid, int varid,
}
/**
+\internal
Get data for a variable.
\param ncid NetCDF or group ID.
@@ -129,7 +130,6 @@ they are read.
\returns ::NC_EBADID Bad ncid.
\ingroup variables
-\internal
\author Dennis Heimbigner
*/
static int
@@ -547,6 +547,7 @@ NCDEFAULT_get_varm(int ncid, int varid, const size_t *start,
}
/**
+\internal
Called by externally visible nc_get_vars_xxx routines.
\param ncid NetCDF or group ID.
@@ -575,7 +576,6 @@ they are read.
\returns ::NC_EBADID Bad ncid.
\ingroup variables
-\internal
\author Dennis Heimbigner, Ed Hartnett
*/
static int
@@ -605,6 +605,7 @@ NC_get_vars(int ncid, int varid, const size_t *start,
}
/**
+\internal
Called by externally visible nc_get_varm_xxx routines. Note that the
varm routines are deprecated. Use the vars routines instead for new
code.
@@ -637,7 +638,6 @@ they are read.
\returns ::NC_EBADID Bad ncid.
\ingroup variables
-\internal
\author Dennis Heimbigner, Ed Hartnett
*/
static int
diff --git a/libhdf5/hdf5dim.c b/libhdf5/hdf5dim.c
index 8a146d9014..a184f99251 100644
--- a/libhdf5/hdf5dim.c
+++ b/libhdf5/hdf5dim.c
@@ -187,6 +187,11 @@ NC4_inq_dim(int ncid, int dimid, char *name, size_t *lenp)
/**
* @internal Rename a dimension, for those who like to prevaricate.
*
+ * @note If we're not in define mode, new name must be of equal or
+ * less size, if strict nc3 rules are in effect for this file. But we
+ * don't check this because reproducing the exact classic behavior
+ * would be too difficult. See github issue #1340.
+ *
* @param ncid File and group ID.
* @param dimid Dimension ID.
* @param name New dimension name.
diff --git a/liblib/Makefile.am b/liblib/Makefile.am
index 0a0bab73d7..6c81bec0a3 100644
--- a/liblib/Makefile.am
+++ b/liblib/Makefile.am
@@ -18,7 +18,7 @@ lib_LTLIBRARIES = libnetcdf.la
# for information regarding incrementing `-version-info`.
##
-libnetcdf_la_LDFLAGS = -version-info 14:1:1
+libnetcdf_la_LDFLAGS = -version-info 15:0:0
libnetcdf_la_CPPFLAGS = ${AM_CPPFLAGS}
libnetcdf_la_LIBADD =
diff --git a/nc-config.in b/nc-config.in
index 41887de6f2..5138462257 100644
--- a/nc-config.in
+++ b/nc-config.in
@@ -90,7 +90,7 @@ Available values for OPTION include:
--has-parallel4 whether has parallel IO support via HDF5
--has-parallel whether has parallel IO support via HDF5 or PnetCDF
--libs library linking information for netcdf
- --prefix Install prefixx
+ --prefix Install prefix
--includedir Include directory
--libdir Library directory
--version Library version
diff --git a/nc_test4/tst_filterparser.c b/nc_test4/tst_filterparser.c
index 833e981ada..2176c480cf 100644
--- a/nc_test4/tst_filterparser.c
+++ b/nc_test4/tst_filterparser.c
@@ -172,11 +172,11 @@ buildbaseline(void)
insert(7,&val4,sizeof(val4)); /* signed int */
val4 = 4294967295U; /*0xffffffff*/
insert(8,&val4,sizeof(val4)); /* unsigned int */
- float4 = 789.0f;
+ float4 = (float)FLTVAL;
insert(9,&float4,sizeof(float4)); /*float */
- val8 = -9223372036854775807L;
+ val8 = LONGLONGVAL;
insert(10,&val8,sizeof(val8)); /* signed long long */
- val8 = 18446744073709551615UL;
+ val8 = ULONGLONGVAL;
insert(12,&val8,sizeof(val8)); /* unsigned long long */
float8 = DBLVAL;
insert(14,&float8,sizeof(float8)); /* double */
@@ -190,6 +190,11 @@ main(int argc, char **argv)
unsigned int id = 0;
size_t i,nparams = 0;
unsigned int* params = NULL;
+ /* Provide for 8-byte values */
+ long long basell;
+ unsigned long long baseull;
+ float basef;
+ double based;
printf("\nTesting filter parser.\n");
@@ -211,28 +216,32 @@ main(int argc, char **argv)
/* float */
uf.ui = params[9];
- if(uf.f != (float)FLTVAL)
+ memcpy(&basef,&baseline[9],4);
+ if(uf.f != basef)
mismatch(9,params,"uf.f");
/* signed long long */
ul.ui[0] = params[10];
ul.ui[1] = params[11];
NC_filterfix8((unsigned char*)&ul.ll,1);
- if(ul.ll != LONGLONGVAL)
+ memcpy(&basell,&baseline[10],8);
+ if(ul.ll != basell)
mismatch2(10,params,"ul.ll");
/* unsigned long long */
ul.ui[0] = params[12];
ul.ui[1] = params[13];
NC_filterfix8((unsigned char*)&ul.ull,1);
- if(ul.ull != ULONGLONGVAL)
+ memcpy(&baseull,&baseline[12],8);
+ if(ul.ull != baseull)
mismatch2(12,params,"ul.ull");
/* double */
ud.ui[0] = params[14];
ud.ui[1] = params[15];
NC_filterfix8((unsigned char*)&ud.d,1);
- if(ud.d != (double)DBLVAL)
+ memcpy(&based,&baseline[14],8);
+ if(ud.d != based)
mismatch2(14,params,"ud.d");
if (!nerrs)
diff --git a/netcdf.pc.in b/netcdf.pc.in
index 089ceec9ed..22b5594b2b 100644
--- a/netcdf.pc.in
+++ b/netcdf.pc.in
@@ -9,5 +9,5 @@ Description: NetCDF Client Library for C
URL: http://www.unidata.ucar.edu/netcdf
Version: @PACKAGE_VERSION@
Libs: -L${libdir} @NC_LIBS@
+Libs.private: @LIBS@
Cflags: -I${includedir}
-
diff --git a/plugins/H5Zbzip2.c b/plugins/H5Zbzip2.c
index 993455b438..b840cd5ff7 100644
--- a/plugins/H5Zbzip2.c
+++ b/plugins/H5Zbzip2.c
@@ -1,3 +1,4 @@
+#include "config.h"
#include
#include
#include
@@ -7,6 +8,8 @@
/* Older versions of the hdf library may define H5PL_type_t here */
#include
+
+
#ifndef DLL_EXPORT
#define DLL_EXPORT
#endif
@@ -90,7 +93,11 @@ size_t H5Z_filter_bzip2(unsigned int flags, size_t cd_nelmts,
/* Prepare the output buffer. */
outbuflen = nbytes * 3 + 1; /* average bzip2 compression ratio is 3:1 */
+#ifdef HDF5_HAS_ALLOCATE_MEMORY
outbuf = H5allocate_memory(outbuflen,0);
+#else
+ outbuf = (char*)malloc(outbuflen * sizeof(char));
+#endif
if (outbuf == NULL) {
fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
goto cleanupAndFail;
@@ -123,7 +130,11 @@ size_t H5Z_filter_bzip2(unsigned int flags, size_t cd_nelmts,
if (ret != BZ_STREAM_END && stream.avail_out == 0) {
/* Grow the output buffer. */
newbuflen = outbuflen * 2;
+#ifdef HDF5_HAS_RESIZE_MEMORY
newbuf = H5resize_memory(outbuf, newbuflen);
+#else
+ newbuf = realloc(outbuf,newbuflen);
+#endif
if (newbuf == NULL) {
fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
goto cleanupAndFail;
@@ -167,7 +178,12 @@ size_t H5Z_filter_bzip2(unsigned int flags, size_t cd_nelmts,
/* Prepare the output buffer. */
outbuflen = nbytes + nbytes / 100 + 600; /* worst case (bzip2 docs) */
+#ifdef HDF5_HAS_ALLOCATE_MEMORY
outbuf = H5allocate_memory(outbuflen,0);
+#else
+ outbuf = (char*)malloc(outbuflen * sizeof(char));
+#endif
+
if (outbuf == NULL) {
fprintf(stderr, "memory allocation failed for bzip2 compression\n");
goto cleanupAndFail;
@@ -185,13 +201,23 @@ size_t H5Z_filter_bzip2(unsigned int flags, size_t cd_nelmts,
}
/* Always replace the input buffer with the output buffer. */
+#ifdef HDF5_HAS_H5FREE
H5free_memory(*buf);
+#else
+ free(*buf);
+#endif
+
*buf = outbuf;
*buf_size = outbuflen;
return outdatalen;
cleanupAndFail:
if (outbuf)
+#ifdef HDF5_HAS_H5FREE
H5free_memory(outbuf);
+#else
+ free(outbuf);
+#endif
+
return 0;
}
diff --git a/plugins/H5Zmisc.c b/plugins/H5Zmisc.c
index a4b3352622..7a04f1003d 100644
--- a/plugins/H5Zmisc.c
+++ b/plugins/H5Zmisc.c
@@ -1,3 +1,4 @@
+#include "config.h"
#include
#include
#include
@@ -109,21 +110,37 @@ H5Z_filter_test(unsigned int flags, size_t cd_nelmts,
if (flags & H5Z_FLAG_REVERSE) {
/* Replace buffer */
+#ifdef HDF5_HAS_ALLOCATE_MEMORY
newbuf = H5allocate_memory(*buf_size,0);
+#else
+ newbuf = malloc(*buf_size * sizeof(void));
+#endif
if(newbuf == NULL) abort();
memcpy(newbuf,*buf,*buf_size);
- /* reclaim old buffer */
- H5free_memory(*buf);
+ /* reclaim old buffer */
+#ifdef HDF5_HAS_H5FREE
+ H5free_memory(*buf);
+#else
+ free(*buf);
+#endif
*buf = newbuf;
} else {
/* Replace buffer */
- newbuf = H5allocate_memory(*buf_size,0);
- if(newbuf == NULL) abort();
+#ifdef HDF5_HAS_ALLOCATE_MEMORY
+ newbuf = H5allocate_memory(*buf_size,0);
+#else
+ newbuf = malloc(*buf_size * sizeof(void));
+#endif
+ if(newbuf == NULL) abort();
memcpy(newbuf,*buf,*buf_size);
/* reclaim old buffer */
- H5free_memory(*buf);
+#ifdef HDF5_HAS_H5FREE
+ H5free_memory(*buf);
+#else
+ free(*buf);
+#endif
*buf = newbuf;
}
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 4c8380eb7e..d439900209 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1,6 +1,9 @@
# Copyright 2018, UCAR/Unidata
# See netcdf/COPYRIGHT file for copying and redistribution conditions.
+# Put Together AM_CPPFLAGS and AM_LDFLAGS
+include $(top_srcdir)/lib_flags.am
+
BZIP2HDRS=bzlib.h bzlib_private.h
BZIP2SRC= blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c