mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-27 07:30:33 +08:00
625 lines
26 KiB
C
625 lines
26 KiB
C
/* This is part of the netCDF package. Copyright 2005-2018 University
|
|
Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
|
|
conditions of use.
|
|
|
|
Test netcdf-4 file code.
|
|
Ed Hartnett
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <nc_tests.h>
|
|
#include "err_macros.h"
|
|
|
|
int test_redef(int format);
|
|
|
|
#define FILE_NAME "tst_files.nc"
|
|
#define ATT1_NAME "MoneyOwned"
|
|
#define ATT2_NAME "Number_of_Shoes"
|
|
#define ATT3_NAME "att3"
|
|
#define DIM1_NAME "Character_Growth"
|
|
#define DIM1_LEN 10
|
|
#define DIM2_NAME "TimeInMonths"
|
|
#define DIM2_LEN 15
|
|
#define VAR1_NAME "HuckFinn"
|
|
#define VAR2_NAME "TomSawyer"
|
|
#define VAR3_NAME "Jim"
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
printf("\n*** Testing netcdf-4 file functions.\n");
|
|
{
|
|
char str[NC_MAX_NAME+1];
|
|
|
|
/* Actually we never make any promises about the length of the
|
|
* version string, but it is always smaller than NC_MAX_NAME. */
|
|
if (strlen(nc_inq_libvers()) > NC_MAX_NAME) ERR;
|
|
strcpy(str, nc_inq_libvers());
|
|
printf("*** testing version %s...", str);
|
|
}
|
|
SUMMARIZE_ERR;
|
|
printf("*** testing with bad inputs...");
|
|
{
|
|
int ncid;
|
|
|
|
/* Create an empty file. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* These will all fail due to incorrect mode flag combinations. */
|
|
if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_NETCDF4, &ncid) != NC_EINVAL) ERR;
|
|
if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CDF5, &ncid) != NC_EINVAL) ERR;
|
|
if (nc_create(FILE_NAME, NC_NETCDF4|NC_CDF5, &ncid) != NC_EINVAL) ERR;
|
|
}
|
|
SUMMARIZE_ERR;
|
|
printf("*** testing simple opens and creates...");
|
|
{
|
|
int ncid, ncid2, ncid3, varid, dimids[2];
|
|
int ndims, nvars, natts, unlimdimid;
|
|
int dimids_var[1], var_type;
|
|
size_t dim_len;
|
|
char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
|
|
unsigned char uchar_out[DIM1_LEN] = {0, 128, 255};
|
|
|
|
/* Open and close empty file. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Recreate it again. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
|
|
if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
|
|
if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
|
|
if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Check the contents. Then define a new variable. Since it's
|
|
* netcdf-4, nc_enddef isn't required - it's called
|
|
* automatically. */
|
|
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 2 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
|
|
if (nc_redef(ncid)) ERR;
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_def_var(ncid, VAR3_NAME, NC_INT, 2, dimids, &varid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Open three copies of the same file. */
|
|
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
|
|
if (nc_open(FILE_NAME, NC_WRITE, &ncid2)) ERR;
|
|
if (nc_open(FILE_NAME, NC_WRITE, &ncid3)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
|
|
if (nc_inq(ncid2, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
|
|
if (nc_inq(ncid3, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
if (nc_close(ncid2)) ERR;
|
|
if (nc_close(ncid3)) ERR;
|
|
|
|
/* Open and close empty file. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Check the contents. */
|
|
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 0 || nvars != 0 || natts != 0 || unlimdimid != -1) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Create a file with one dimension and nothing else. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
|
|
if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Check the contents. */
|
|
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 1 || nvars != 0 || natts != 0 || unlimdimid != -1) ERR;
|
|
if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
|
|
if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Create a simple file, and write some data to it. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
|
|
if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
|
|
if (nc_def_var(ncid, VAR1_NAME, NC_BYTE, 1, dimids, &varid)) ERR;
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_put_var_uchar(ncid, varid, uchar_out) != NC_ERANGE) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Check the contents. */
|
|
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
|
|
if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
|
|
if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
|
|
if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
|
|
if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_BYTE ||
|
|
dimids_var[0] != dimids[0] || natts != 0) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Recreate the file. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
|
|
if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
|
|
if (nc_def_var(ncid, VAR1_NAME, NC_BYTE, 1, dimids, &varid)) ERR;
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_put_var_uchar(ncid, varid, uchar_out)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Recreate it, then make sure NOCLOBBER works. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
if (nc_create(FILE_NAME, NC_NETCDF4|NC_NOCLOBBER, &ncid) != NC_EEXIST) ERR;
|
|
|
|
/* Recreate it again. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
|
|
if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
|
|
if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
|
|
if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Check the contents. Then define a new variable. Since it's
|
|
* netcdf-4, nc_enddef isn't required - it's called
|
|
* automatically. */
|
|
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 2 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
|
|
if (nc_redef(ncid)) ERR;
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_def_var(ncid, VAR3_NAME, NC_INT, 2, dimids, &varid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Recreate it again with netcdf-3 rules turned on. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
|
|
if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
|
|
if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Check the contents. Check that netcdf-3 rules are in effect. */
|
|
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
|
|
if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid) != NC_ENOTINDEFINE) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Check some other stuff about it. Closing and reopening the
|
|
* file forces HDF5 to tell us if we forgot to free some HDF5
|
|
* resource associated with the file. */
|
|
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
|
|
if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
|
|
if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
|
|
if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
|
|
dimids_var[0] != dimids[0] || natts != 0) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
}
|
|
SUMMARIZE_ERR;
|
|
printf("*** testing more complex opens and creates...");
|
|
{
|
|
int ncid, varid, dimids[2];
|
|
int ndims, nvars, natts, unlimdimid;
|
|
int dimids_var[2], var_type;
|
|
size_t dim_len;
|
|
char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
|
|
float float_in, float_out = 99.99;
|
|
int int_in, int_out = -9999;
|
|
|
|
/* Create a file, this time with attributes. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
|
|
if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
|
|
if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
|
|
if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR;
|
|
if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
|
|
if (nc_put_att_float(ncid, NC_GLOBAL, ATT1_NAME, NC_FLOAT, 1, &float_out)) ERR;
|
|
if (nc_put_att_int(ncid, NC_GLOBAL, ATT2_NAME, NC_INT, 1, &int_out)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Reopen the file and check it. */
|
|
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != 2 || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Reopen it and check each dim, var, and att. */
|
|
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
|
|
if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
|
|
if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
|
|
if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR;
|
|
if (dim_len != DIM2_LEN || strcmp(dim_name, DIM2_NAME)) ERR;
|
|
if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
|
|
if (ndims != 2 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
|
|
dimids_var[0] != dimids[0] || natts != 0) ERR;
|
|
if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
|
|
if (ndims != 2 || strcmp(var_name, VAR2_NAME) || var_type != NC_UINT ||
|
|
dimids_var[1] != dimids[1] || natts != 0) ERR;
|
|
if (nc_get_att_float(ncid, NC_GLOBAL, ATT1_NAME, &float_in)) ERR;
|
|
if (float_in != float_out) ERR;
|
|
if (nc_get_att_int(ncid, NC_GLOBAL, ATT2_NAME, &int_in)) ERR;
|
|
if (int_in != int_out) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
}
|
|
SUMMARIZE_ERR;
|
|
|
|
printf("*** testing redef for netCDF classic...");
|
|
test_redef(NC_FORMAT_CLASSIC);
|
|
SUMMARIZE_ERR;
|
|
printf("*** testing redef for netCDF 64-bit offset...");
|
|
test_redef(NC_FORMAT_64BIT_OFFSET);
|
|
SUMMARIZE_ERR;
|
|
|
|
printf("*** testing redef for netCDF-4 ...");
|
|
test_redef(NC_FORMAT_NETCDF4);
|
|
SUMMARIZE_ERR;
|
|
printf("*** testing redef for netCDF-4, with strict netCDF-3 rules...");
|
|
test_redef(NC_FORMAT_NETCDF4_CLASSIC);
|
|
SUMMARIZE_ERR;
|
|
|
|
#ifdef ENABLE_CDF5
|
|
printf("*** testing redef for CDF5...");
|
|
test_redef(NC_FORMAT_CDF5);
|
|
SUMMARIZE_ERR;
|
|
#endif /* ENABLE_CDF5 */
|
|
|
|
printf("*** testing different formats...");
|
|
{
|
|
int ncid;
|
|
int format;
|
|
|
|
/* Create a netcdf-3 file. */
|
|
if (nc_create(FILE_NAME, NC_CLOBBER, &ncid)) ERR;
|
|
if (nc_inq_format(ncid, &format)) ERR;
|
|
if (format != NC_FORMAT_CLASSIC) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Create a netcdf-3 64-bit offset file. */
|
|
if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CLOBBER, &ncid)) ERR;
|
|
if (nc_inq_format(ncid, &format)) ERR;
|
|
if (format != NC_FORMAT_64BIT_OFFSET) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Create a netcdf-4 file. */
|
|
if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
|
|
if (nc_inq_format(ncid, &format)) ERR;
|
|
if (format != NC_FORMAT_NETCDF4) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
}
|
|
SUMMARIZE_ERR;
|
|
printf("*** testing CLASSIC_MODEL flag with classic formats...");
|
|
{
|
|
int ncid;
|
|
int format;
|
|
|
|
/* Create a netcdf-3 file. */
|
|
if (nc_create(FILE_NAME, NC_CLOBBER|NC_CLASSIC_MODEL, &ncid)) ERR;
|
|
if (nc_inq_format(ncid, &format)) ERR;
|
|
if (format != NC_FORMAT_CLASSIC) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Create a netcdf-3 64-bit offset file. */
|
|
if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CLOBBER|NC_CLASSIC_MODEL, &ncid)) ERR;
|
|
if (nc_inq_format(ncid, &format)) ERR;
|
|
if (format != NC_FORMAT_64BIT_OFFSET) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
}
|
|
SUMMARIZE_ERR;
|
|
printf("*** testing multiple open files...");
|
|
{
|
|
#define VAR_NAME "Captain_Kirk"
|
|
#define NDIMS 1
|
|
#define NUM_FILES 30
|
|
#define TEXT_LEN 15
|
|
#define D1_NAME "tl"
|
|
int ncid[NUM_FILES], varid;
|
|
int dimid;
|
|
size_t count[NDIMS], index[NDIMS] = {0};
|
|
const char ttext[TEXT_LEN + 1] = "20051224.150000";
|
|
char ttext_in[TEXT_LEN + 1];
|
|
char file_name[NC_MAX_NAME + 1];
|
|
size_t chunks[NDIMS] = {TEXT_LEN + 1};
|
|
int f;
|
|
|
|
/* Create a bunch of files. */
|
|
for (f = 0; f < NUM_FILES; f++)
|
|
{
|
|
sprintf(file_name, "tst_files2_%d.nc", f);
|
|
if (nc_create(file_name, NC_NETCDF4, &ncid[f])) ERR;
|
|
if (nc_def_dim(ncid[f], D1_NAME, TEXT_LEN + 1, &dimid)) ERR;
|
|
if (nc_def_var(ncid[f], VAR_NAME, NC_CHAR, NDIMS, &dimid, &varid)) ERR;
|
|
if (f % 2 == 0)
|
|
if (nc_def_var_chunking(ncid[f], varid, 0, chunks)) ERR;
|
|
|
|
/* Write one time to the coordinate variable. */
|
|
count[0] = TEXT_LEN + 1;
|
|
if (nc_put_vara_text(ncid[f], varid, index, count, ttext)) ERR;
|
|
}
|
|
|
|
/* Read something from each file. */
|
|
for (f = 0; f < NUM_FILES; f++)
|
|
{
|
|
if (nc_get_vara_text(ncid[f], varid, index, count, (char *)ttext_in)) ERR;
|
|
if (strcmp(ttext_in, ttext)) ERR;
|
|
}
|
|
|
|
/* Close all open files. */
|
|
for (f = 0; f < NUM_FILES; f++)
|
|
if (nc_close(ncid[f])) ERR;
|
|
}
|
|
SUMMARIZE_ERR;
|
|
FINAL_RESULTS;
|
|
}
|
|
|
|
#define REDEF_ATT1_NAME "CANTERBURY"
|
|
#define REDEF_ATT2_NAME "ELY"
|
|
#define REDEF_ATT3_NAME "KING_HENRY_V"
|
|
#define REDEF_DIM1_NAME "performance_length"
|
|
#define REDEF_DIM1_LEN 101
|
|
/* Change illegal name from '?' to '/'; the latter will
|
|
more likely be illegal even when the switch is made to
|
|
escaped characters in identifiers.
|
|
*/
|
|
#define REDEF_NAME_ILLEGAL "/"
|
|
#define REDEF_DIM2_NAME "ZZ_number_of_performers_or_perhaps_actors_or_maybe_I_should_say_players_or_one_could_call_them_artists_but_one_doesnt_like_to_get"
|
|
|
|
#define REDEF_DIM2_LEN 999
|
|
#define REDEF_VAR1_NAME "Royal_Shakespeare_Company_season_of_2004"
|
|
#define REDEF_VAR2_NAME "Ms_Beths_Kindergardern_class_of_2003"
|
|
#define REDEF_VAR3_NAME "Costumed_Mice_in_my_Garage_in_the_Winter_of_my_Discontent"
|
|
#define REDEF_NDIMS 2
|
|
|
|
#define NEW_CACHE_SIZE 32000000
|
|
#define NEW_CACHE_NELEMS 2000
|
|
#define NEW_CACHE_PREEMPTION .75
|
|
#define NEW_CACHE_SIZE_2 16000000
|
|
#define NEW_CACHE_NELEMS_2 1000
|
|
#define NEW_CACHE_PREEMPTION_2 .50
|
|
|
|
/* These prototypes are needed because these functions, used by the
|
|
* Fortran API, are not prototyped in netcdf.h. */
|
|
int nc_get_chunk_cache_ints(int *sizep, int *nelemsp, int *preemptionp);
|
|
int nc_set_chunk_cache_ints(int size, int nelems, int preemption);
|
|
|
|
int
|
|
test_redef(int format)
|
|
{
|
|
int ncid, varid, dimids[REDEF_NDIMS], dimids_in[REDEF_NDIMS];
|
|
int ndims, nvars, natts, unlimdimid;
|
|
int dimids_var[REDEF_NDIMS], var_type;
|
|
int cflags = 0;
|
|
size_t dim_len;
|
|
char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
|
|
float float_in;
|
|
double double_out = 99E99;
|
|
int int_in;
|
|
unsigned char uchar_in, uchar_out = 255;
|
|
short short_out = -999;
|
|
nc_type xtype_in;
|
|
size_t cache_size_in, cache_nelems_in;
|
|
int cache_size_int_in, cache_nelems_int_in;
|
|
int cache_preemption_int_in;
|
|
float cache_preemption_in;
|
|
int ret;
|
|
|
|
if (format == NC_FORMAT_64BIT_OFFSET)
|
|
cflags |= NC_64BIT_OFFSET;
|
|
else if (format == NC_FORMAT_CDF5)
|
|
cflags |= NC_CDF5;
|
|
else if (format == NC_FORMAT_NETCDF4_CLASSIC)
|
|
cflags |= (NC_NETCDF4|NC_CLASSIC_MODEL);
|
|
else if (format == NC_FORMAT_NETCDF4)
|
|
cflags |= NC_NETCDF4;
|
|
|
|
/* Change chunk cache. */
|
|
if (nc_set_chunk_cache(NEW_CACHE_SIZE, NEW_CACHE_NELEMS,
|
|
NEW_CACHE_PREEMPTION)) ERR;
|
|
|
|
/* Create a file with two dims, two vars, and two atts. */
|
|
if (nc_create(FILE_NAME, cflags|NC_CLOBBER, &ncid)) ERR;
|
|
|
|
/* Retrieve the chunk cache settings, just for fun. */
|
|
if (nc_get_chunk_cache(&cache_size_in, &cache_nelems_in,
|
|
&cache_preemption_in)) ERR;
|
|
if (cache_size_in != NEW_CACHE_SIZE || cache_nelems_in != NEW_CACHE_NELEMS ||
|
|
cache_preemption_in != NEW_CACHE_PREEMPTION) ERR;
|
|
cache_size_in = 0;
|
|
if (nc_get_chunk_cache(&cache_size_in, NULL, NULL)) ERR;
|
|
if (cache_size_in != NEW_CACHE_SIZE) ERR;
|
|
cache_nelems_in = 0;
|
|
if (nc_get_chunk_cache(NULL, &cache_nelems_in, NULL)) ERR;
|
|
if (cache_nelems_in != NEW_CACHE_NELEMS) ERR;
|
|
cache_preemption_in = 0;
|
|
if (nc_get_chunk_cache(NULL, NULL, &cache_preemption_in)) ERR;
|
|
if (cache_preemption_in != NEW_CACHE_PREEMPTION) ERR;
|
|
|
|
/* Retrieve the chunk cache settings as integers, like the fortran API. */
|
|
if (nc_get_chunk_cache_ints(&cache_size_int_in, &cache_nelems_int_in,
|
|
&cache_preemption_int_in)) ERR;
|
|
if (cache_size_int_in != NEW_CACHE_SIZE || cache_nelems_int_in != NEW_CACHE_NELEMS ||
|
|
cache_preemption_int_in != (int)(NEW_CACHE_PREEMPTION * 100)) ERR;
|
|
if (nc_get_chunk_cache_ints(NULL, NULL, NULL)) ERR;
|
|
cache_size_int_in = 0;
|
|
if (nc_get_chunk_cache_ints(&cache_size_int_in, NULL, NULL)) ERR;
|
|
if (cache_size_int_in != NEW_CACHE_SIZE) ERR;
|
|
cache_nelems_int_in = 0;
|
|
if (nc_get_chunk_cache_ints(NULL, &cache_nelems_int_in, NULL)) ERR;
|
|
if (cache_nelems_int_in != NEW_CACHE_NELEMS) ERR;
|
|
cache_preemption_int_in = 0;
|
|
if (nc_get_chunk_cache_ints(NULL, NULL, &cache_preemption_int_in)) ERR;
|
|
if (cache_preemption_int_in != (int)(NEW_CACHE_PREEMPTION * 100)) ERR;
|
|
|
|
/* These won't work. */
|
|
if (nc_set_chunk_cache_ints(-1, NEW_CACHE_NELEMS_2,
|
|
(int)(NEW_CACHE_PREEMPTION_2 * 100)) != NC_EINVAL) ERR;
|
|
if (nc_set_chunk_cache_ints(NEW_CACHE_SIZE_2, 0,
|
|
(int)(NEW_CACHE_PREEMPTION_2 * 100)) != NC_EINVAL) ERR;
|
|
if (nc_set_chunk_cache_ints(NEW_CACHE_SIZE_2, NEW_CACHE_NELEMS_2,
|
|
-1) != NC_EINVAL) ERR;
|
|
if (nc_set_chunk_cache_ints(NEW_CACHE_SIZE_2, NEW_CACHE_NELEMS_2,
|
|
101) != NC_EINVAL) ERR;
|
|
|
|
|
|
/* Change chunk cache again. */
|
|
if (nc_set_chunk_cache_ints(NEW_CACHE_SIZE_2, NEW_CACHE_NELEMS_2,
|
|
(int)(NEW_CACHE_PREEMPTION_2 * 100))) ERR;
|
|
if (nc_get_chunk_cache_ints(&cache_size_int_in, &cache_nelems_int_in,
|
|
&cache_preemption_int_in)) ERR;
|
|
if (cache_size_int_in != NEW_CACHE_SIZE_2 || cache_nelems_int_in != NEW_CACHE_NELEMS_2 ||
|
|
cache_preemption_int_in != (int)(NEW_CACHE_PREEMPTION_2 * 100)) ERR;
|
|
|
|
|
|
/* This will fail, except for netcdf-4/hdf5, which permits any
|
|
* name. */
|
|
if (format != NC_FORMAT_NETCDF4)
|
|
if (nc_def_dim(ncid, REDEF_NAME_ILLEGAL, REDEF_DIM2_LEN,
|
|
&dimids[1]) != NC_EBADNAME) ERR;
|
|
|
|
if (nc_def_dim(ncid, REDEF_DIM1_NAME, REDEF_DIM1_LEN, &dimids[0])) ERR;
|
|
if (nc_def_dim(ncid, REDEF_DIM2_NAME, REDEF_DIM2_LEN, &dimids[1])) ERR;
|
|
if (nc_def_var(ncid, REDEF_VAR1_NAME, NC_INT, REDEF_NDIMS, dimids, &varid)) ERR;
|
|
if (nc_def_var(ncid, REDEF_VAR2_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;
|
|
if (nc_put_att_double(ncid, NC_GLOBAL, REDEF_ATT1_NAME, NC_DOUBLE, 1, &double_out)) ERR;
|
|
if (nc_put_att_short(ncid, NC_GLOBAL, REDEF_ATT2_NAME, NC_SHORT, 1, &short_out)) ERR;
|
|
|
|
/* Check it out. */
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
|
|
if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
|
|
if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS ||
|
|
dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
|
|
if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
|
|
if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS ||
|
|
dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
|
|
|
|
/* Try enddef/redef. */
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_redef(ncid)) ERR;
|
|
|
|
/* NetCDF/HDF5 files ignore the repeated redef(). */
|
|
if (format != NC_FORMAT_NETCDF4)
|
|
{
|
|
if (nc_redef(ncid) != NC_EINDEFINE) ERR;
|
|
}
|
|
else
|
|
{
|
|
if (nc_redef(ncid)) ERR;
|
|
}
|
|
|
|
/* Close it up. */
|
|
if (format != NC_FORMAT_NETCDF4)
|
|
if (nc_enddef(ncid)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Reopen as read only - make sure it doesn't let us change file. */
|
|
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
|
|
if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
|
|
if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS ||
|
|
dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
|
|
if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
|
|
if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS ||
|
|
dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
|
|
|
|
/* This will fail. */
|
|
ret = nc_def_var(ncid, REDEF_VAR3_NAME, NC_UBYTE, REDEF_NDIMS,
|
|
dimids, &varid);
|
|
if(format == NC_FORMAT_NETCDF4) {
|
|
if(ret != NC_EPERM) {
|
|
ERR;
|
|
}
|
|
} else {
|
|
if(ret != NC_ENOTINDEFINE) {
|
|
ERR;
|
|
}
|
|
}
|
|
/* This will fail. */
|
|
if (!nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_CHAR, 1, &uchar_out)) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Make sure we can't redef a file opened for NOWRITE. */
|
|
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
|
|
if (nc_redef(ncid) != NC_EPERM) ERR;
|
|
|
|
/* Check it out again. */
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
|
|
if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
|
|
if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS ||
|
|
dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
|
|
if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
|
|
if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS ||
|
|
dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
|
|
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Reopen the file and check it, add a variable and attribute. */
|
|
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
|
|
|
|
/* Check it out. */
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
|
|
|
|
/* Add var. */
|
|
if ((format != NC_FORMAT_NETCDF4) && nc_redef(ncid)) ERR;
|
|
if (nc_def_var(ncid, REDEF_VAR3_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;
|
|
|
|
/* Add att. */
|
|
ret = nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_BYTE, 1, &uchar_out);
|
|
if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA)
|
|
{
|
|
if (ret != NC_ERANGE) ERR;
|
|
}
|
|
else if (ret) ERR;
|
|
|
|
/* Check it out. */
|
|
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
|
|
if (ndims != REDEF_NDIMS || nvars != 3 || natts != 3 || unlimdimid != -1) ERR;
|
|
if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
|
|
if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS ||
|
|
dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
|
|
if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
|
|
if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS ||
|
|
dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
|
|
if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
|
|
if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
|
|
natts != 0) ERR;
|
|
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/* Reopen it and check each dim, var, and att. */
|
|
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
|
|
if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
|
|
if (dim_len != REDEF_DIM1_LEN || strcmp(dim_name, REDEF_DIM1_NAME)) ERR;
|
|
if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR;
|
|
if (dim_len != REDEF_DIM2_LEN || strcmp(dim_name, REDEF_DIM2_NAME)) ERR;
|
|
if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
|
|
if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR1_NAME) || var_type != NC_INT ||
|
|
natts != 0) ERR;
|
|
if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
|
|
if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR2_NAME) || var_type != NC_BYTE ||
|
|
natts != 0) ERR;
|
|
if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
|
|
if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
|
|
natts != 0) ERR;
|
|
if (nc_get_att_float(ncid, NC_GLOBAL, REDEF_ATT1_NAME, &float_in) != NC_ERANGE) ERR;
|
|
if (nc_get_att_int(ncid, NC_GLOBAL, REDEF_ATT2_NAME, &int_in)) ERR;
|
|
if (int_in != short_out) ERR;
|
|
ret = nc_get_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, &uchar_in);
|
|
if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA)
|
|
{
|
|
if (ret != NC_ERANGE) ERR;
|
|
}
|
|
else if (ret) ERR;
|
|
|
|
if (uchar_in != uchar_out) ERR;
|
|
if (nc_close(ncid)) ERR;
|
|
return NC_NOERR;
|
|
}
|