mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
more testing for late fill setting
This commit is contained in:
parent
d959512a2e
commit
91ec0109f3
@ -546,42 +546,57 @@ NC_getshape(int ncid, int varid, int ndims, size_t* shape)
|
||||
return status;
|
||||
}
|
||||
|
||||
/*! Set the fill value for a variable.
|
||||
|
||||
\ingroup variables
|
||||
|
||||
\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.)
|
||||
/**
|
||||
* @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_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.
|
||||
|
||||
\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
|
||||
* @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"
|
||||
@ -608,7 +623,8 @@ was turned on, the missing values would get the fill value.
|
||||
if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR;
|
||||
|
||||
if (nc_close(ncid)) ERR;
|
||||
\endcode
|
||||
@endcode
|
||||
* @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
|
||||
*/
|
||||
int
|
||||
nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
|
||||
@ -617,7 +633,7 @@ nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
|
||||
int stat = NC_check_id(ncid,&ncp);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
|
||||
/* Dennis Heimbigner: (Using NC_GLOBAL is ilegal, as this API) has no
|
||||
/* 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.
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define DIM_LEN 10
|
||||
#define VAR_NAME "Copernicus_var"
|
||||
#define DIM_NAME "Copernicus_dim"
|
||||
#define NUM_FILL_WRITE_TESTS 2
|
||||
|
||||
/* Determine how many formats are available, and what they are. */
|
||||
void
|
||||
@ -103,7 +104,7 @@ main(int argc, char **argv)
|
||||
printf("\n*** Testing netcdf format functions.\n");
|
||||
{
|
||||
int ncid;
|
||||
int f;
|
||||
int f, d;
|
||||
int format[MAX_NUM_FORMATS];
|
||||
int num_formats;
|
||||
|
||||
@ -160,20 +161,51 @@ main(int argc, char **argv)
|
||||
if (nc_close(ncid)) ERR;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
printf("*** testing NC_ELATEFILL errors with format %d...", format[f]);
|
||||
for (d = 0; d < NUM_FILL_WRITE_TESTS; d++)
|
||||
{
|
||||
printf("*** testing late fill handling with format %d writing %d...", format[f], d);
|
||||
char file_name[NC_MAX_NAME + 1];
|
||||
int dimid, varid;
|
||||
size_t index = {DIM_LEN - 1};
|
||||
int data = TEST_VAL_42;
|
||||
int data_in;
|
||||
int fill_value = TEST_VAL_42 * 2;
|
||||
|
||||
sprintf(file_name, "%s_%d_elatefill.nc", FILE_NAME_BASE, format[f]);
|
||||
/* Try to set fill mode after data have been written. */
|
||||
sprintf(file_name, "%s_%d_%d_elatefill.nc", FILE_NAME_BASE, format[f], d);
|
||||
if (nc_set_default_format(format[f], NULL)) ERR;
|
||||
if (nc_create(file_name, 0, &ncid)) ERR;
|
||||
if (nc_def_dim(ncid, DIM_NAME, DIM_LEN, &dimid)) ERR;
|
||||
if (nc_def_var(ncid, VAR_NAME, NC_INT, NDIM1, &dimid, &varid)) ERR;
|
||||
if (nc_enddef(ncid)) ERR;
|
||||
/* For netCDF-4, we don't actually have to write data to
|
||||
* prevent future setting of the fill value. Once the user
|
||||
* leaves calls enddef after defining a var, fill values
|
||||
* can no longer be set. */
|
||||
if (d)
|
||||
if (nc_put_var1_int(ncid, varid, &index, &data)) ERR;
|
||||
if (nc_redef(ncid)) ERR;
|
||||
/* Setting the fill value after data are written is
|
||||
* allowed in classic formats, but not netcdf-4. */
|
||||
if (format[f] == NC_FORMAT_CLASSIC || format[f] == NC_FORMAT_64BIT_OFFSET ||
|
||||
format[f] == NC_FORMAT_CDF5)
|
||||
{
|
||||
if (nc_def_var_fill(ncid, varid, NC_FILL, &fill_value)) ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nc_def_var_fill(ncid, varid, NC_FILL, &fill_value) != NC_ELATEDEF) ERR;
|
||||
}
|
||||
if (nc_enddef(ncid)) ERR;
|
||||
if (nc_close(ncid)) ERR;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
|
||||
/* Open the file and check data. */
|
||||
if (nc_open(file_name, NC_NOWRITE, &ncid)) ERR;
|
||||
if (nc_get_var1_int(ncid, varid, &index, &data_in)) ERR;
|
||||
if (data_in != (d ? data : NC_FILL_INT)) ERR;
|
||||
if (nc_close(ncid)) ERR;
|
||||
SUMMARIZE_ERR;
|
||||
} /* next fill val write test */
|
||||
} /* next format */
|
||||
}
|
||||
FINAL_RESULTS;
|
||||
|
Loading…
Reference in New Issue
Block a user