/* This is part of the netCDF package. Copyright 2018 University Corporation for Atmospheric Research/Unidata See COPYRIGHT file for conditions of use. Test netcdf-4 types. Ed Hartnett */ #include "config.h" #include "nc_tests.h" #include "err_macros.h" #define MAX_VARNAME 20 #define NUM_TYPES 6 #define NUM_DIMS 1 #define SIZE 5 #define STRIDE_SIZE 2 #define FILENAME "tst_types.nc" #define FILENAME2 "tst_types2.nc" #define FILENAME3 "tst_types3.nc" #define FILENAME4 "tst_types4.nc" #define A_NAME "some_name" #define CLEAN_INPUT_BUFFERS \ for (i = 0; i < SIZE; i++) { \ ubyte_data_out[i] = 0; \ ushort_data_out[i] = 0; \ uint_data_out[i] = 0; \ int64_data_out[i] = 0; \ uint64_data_out[i] = 0; \ } /* Create the test file for these tests. */ int create_test_file(char *filename, int *varid, int *ncid) { int dimid; int type; char varname[MAX_VARNAME]; /* Open a netcdf-4 file, and one dimension. */ if (nc_create(filename, NC_NETCDF4, ncid)) ERR; if (nc_def_dim(*ncid, "dim1", SIZE, &dimid)) ERR; /* Create vars of the new types. Take advantage of the fact that * new types are numbered from NC_UBYTE (7) through NC_STRING * (12). */ for (type = 0; type < NUM_TYPES; type++) { /* Create a var... */ sprintf(varname, "var_%d", type); if (nc_def_var(*ncid, varname, type + NC_UBYTE, 1, &dimid, &varid[type])) ERR; } return 0; } int main(int argc, char *argv[]) { /* IDs, names, and parameters for the var[asm1] functions. */ int ncid, varid[NUM_TYPES], dimid; char varname[MAX_VARNAME]; size_t index1[NUM_DIMS], start[NUM_DIMS]; size_t count[NUM_DIMS]; ptrdiff_t imap[NUM_DIMS]; ptrdiff_t stride[NUM_DIMS]; /* Phoney data we will write. */ unsigned char ubyte_data_out[] = {0,1,2,3,4}; unsigned short ushort_data_out[] = {0,11,22,33,44}; unsigned int uint_data_out[] = {0,111,222,333,3000000000u}; long long int int64_data_out[] = {0,-1111111111,222222222,-3333333333LL,444444444LL}; unsigned long long int uint64_data_out[] = {0,111111111,222222222,33333333,44444444}; /* We will read back in the phoney data with these. */ unsigned char ubyte_data_in[SIZE]; unsigned short ushort_data_in[SIZE]; unsigned int uint_data_in[SIZE]; long long int int64_data_in[SIZE]; unsigned long long int uint64_data_in[SIZE]; int i; int type; printf("\n*** Testing netCDF-4 types...\n"); printf("*** testing netCDF-4 new atomic types and equality..."); { int ncid1, ncid2; int equal; /* Open a netcdf-4 file, and one dimension. */ if (nc_create(FILENAME, NC_NETCDF4, &ncid1)) ERR; if (nc_def_dim(ncid1, "dim1", SIZE, &dimid)) ERR; /* Open another netcdf-4 file. */ if (nc_create(FILENAME2, NC_NETCDF4, &ncid2)) ERR; /* Create vars of the new types. Take advantage of the fact that * new types are numbered from NC_UBYTE (7) through NC_STRING * (12). */ for (type = 0; type < NUM_TYPES; type++) { /* Create a var... */ sprintf(varname, "var_%d", type); if (nc_def_var(ncid1, varname, type + NC_UBYTE, 1, &dimid, &varid[type])) ERR; if (nc_inq_type_equal(ncid1, type + NC_UBYTE, ncid2, type + NC_UBYTE, &equal)) ERR; if (!equal) ERR; } nc_close(ncid2); nc_close(ncid1); } SUMMARIZE_ERR; #define ENUM_TYPE_NAME "enum_type" #define ENUM_FIELD1_NAME "enum_field_1" #define ENUM_UNEQUAL_TYPE_NAME_3 "enum_type_3" #define ENUM_UNEQUAL_TYPE_NAME_4 "enum_type_4" #define NUM_CLASSIC_TYPES 6 #define NUM_ENHANCED_TYPES 12 printf("*** testing user-defined netCDF-4 enum types and equality..."); { int ncid1, ncid2, ncid3, ncid4; int typeid1, typeid2, typeid3; int enum_value = TEST_VAL_42; int equal; int classic_type[NUM_CLASSIC_TYPES] = {NC_BYTE, NC_CHAR, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE}; int enhanced_type[NUM_ENHANCED_TYPES] = {NC_BYTE, NC_CHAR, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE, NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64, NC_UINT64, NC_STRING}; int t; /* Create a netcdf-4 file. */ if (nc_create(FILENAME, NC_NETCDF4, &ncid1)) ERR; /* Create an enum type. */ if (nc_def_enum(ncid1, NC_INT, ENUM_TYPE_NAME, &typeid1)) ERR; if (nc_insert_enum(ncid1, typeid1, ENUM_FIELD1_NAME, &enum_value)) ERR; /* Create another netcdf-4 file. */ if (nc_create(FILENAME2, NC_NETCDF4, &ncid2)) ERR; /* Create a netcdf-3 classic file. */ if (nc_create(FILENAME3, 0, &ncid3)) ERR; /* Create a netcdf-4 classic model file. */ if (nc_create(FILENAME4, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid4)) ERR; /* Create an enum type that will be equal to typeid1. */ if (nc_def_enum(ncid2, NC_INT, ENUM_TYPE_NAME, &typeid2)) ERR; if (nc_insert_enum(ncid2, typeid2, ENUM_FIELD1_NAME, &enum_value)) ERR; /* These will fail. */ if (nc_def_enum(ncid2, NC_INT, ENUM_TYPE_NAME, &typeid3) != NC_ENAMEINUSE) ERR; if (nc_def_enum(ncid2 + TEST_VAL_42, NC_INT, ENUM_UNEQUAL_TYPE_NAME_3, &typeid3) != NC_EBADID) ERR; if (nc_def_enum(ncid2, NC_INT, NULL, &typeid3) != NC_EINVAL) ERR; if (nc_def_enum(ncid3, NC_SHORT, ENUM_UNEQUAL_TYPE_NAME_3, &typeid3) != NC_ENOTNC4) ERR; if (nc_def_enum(ncid4, NC_SHORT, ENUM_UNEQUAL_TYPE_NAME_3, &typeid3) != NC_ESTRICTNC3) ERR; if (nc_def_opaque(ncid4, TEST_VAL_42, A_NAME, &typeid3) != NC_ESTRICTNC3) ERR; if (nc_def_compound(ncid4, TEST_VAL_42, A_NAME, &typeid3) != NC_ESTRICTNC3) ERR; if (nc_def_vlen(ncid4, A_NAME, NC_INT, &typeid3) != NC_ESTRICTNC3) ERR; /* Create some enum types that will not be equal to typeid1. */ if (nc_def_enum(ncid2, NC_SHORT, ENUM_UNEQUAL_TYPE_NAME_3, &typeid3)) ERR; if (nc_insert_enum(ncid2, typeid3, ENUM_FIELD1_NAME, &enum_value)) ERR; /* This will fail because types are not yet committed. */ if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid2, &equal) != NC_EHDFERR) ERR; /* Commit the types to the file. */ if (nc_enddef(ncid1)) ERR; if (nc_enddef(ncid2)) ERR; /* This succeeds but does nothing. */ if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid2, NULL)) ERR; /* These will fail. */ if (nc_inq_type_equal(ncid1, 0, ncid2, typeid2, &equal) != NC_EINVAL) ERR; if (nc_inq_type_equal(ncid1, typeid1, ncid2, 0, &equal) != NC_EINVAL) ERR; if (nc_inq_type_equal(ncid1, -TEST_VAL_42, ncid2, typeid2, &equal) != NC_EINVAL) ERR; if (nc_inq_type_equal(ncid1, typeid1, ncid2, -TEST_VAL_42, &equal) != NC_EINVAL) ERR; if (nc_inq_type_equal(ncid1 + TEST_VAL_42, typeid1, ncid2, typeid2, &equal) != NC_EBADID) ERR; if (nc_inq_type_equal(ncid1, typeid1 + TEST_VAL_42, ncid2, typeid2, &equal) != NC_EBADTYPE) ERR; if (nc_inq_type_equal(ncid1, typeid1, ncid2 + TEST_VAL_42, typeid2, &equal) != NC_EBADID) ERR; if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid2 + TEST_VAL_42, &equal) != NC_EBADTYPE) ERR; /* Ensure the two equal types are equal. */ if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid2, &equal)) ERR; if (!equal) ERR; /* Ensure the two unequal types are not equal. */ if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid3, &equal)) ERR; if (equal) ERR; /* Atomic types are not equal to user-defined types, but are * equal to themselves. */ for (t = 0; t < NUM_CLASSIC_TYPES; t++) { if (nc_inq_type_equal(ncid1, typeid1, ncid3, classic_type[t], &equal)) ERR; if (equal) ERR; if (nc_inq_type_equal(ncid1, classic_type[t], ncid3, classic_type[t], &equal)) ERR; if (!equal) ERR; } for (t = 0; t < NUM_ENHANCED_TYPES; t++) { if (nc_inq_type_equal(ncid1, typeid1, ncid2, enhanced_type[t], &equal)) ERR; if (equal) ERR; if (nc_inq_type_equal(ncid1, enhanced_type[t], ncid2, enhanced_type[t], &equal)) ERR; if (!equal) ERR; } /* Close the files. */ nc_close(ncid1); nc_close(ncid2); nc_close(ncid3); nc_close(ncid4); } SUMMARIZE_ERR; /* Test the vara functions. */ printf("*** testing vara functions with new netCDF-4 atomic types..."); { CLEAN_INPUT_BUFFERS; start[0] = 0; count[0] = SIZE; /* Open a netcdf-4 file, and one dimension. */ if (create_test_file(FILENAME, varid, &ncid)) ERR; /* This will not work. */ if (nc_put_vara_uchar(ncid, varid[0], NULL, count, ubyte_data_out) != NC_EINVALCOORDS) ERR; /* This will work. */ if (nc_put_vara_uchar(ncid, varid[0], start, count, ubyte_data_out)) ERR; /* This will not work. */ if (nc_get_vara_uchar(ncid, varid[0], NULL, count, ubyte_data_in) != NC_EINVALCOORDS) ERR; /* This will work. */ if (nc_get_vara_uchar(ncid, varid[0], start, NULL, ubyte_data_in)) ERR; for (i = 0; i < SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; CLEAN_INPUT_BUFFERS; if (nc_get_vara_uchar(ncid, varid[0], start, count, ubyte_data_in)) ERR; for (i = 0; i < SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; /* NULL count will be interpreted as count of full extent. */ if (nc_put_vara_ushort(ncid, varid[1], start, NULL, ushort_data_out)) ERR; if (nc_get_vara_ushort(ncid, varid[1], start, count, ushort_data_in)) ERR; for (i = 0; i < SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; /* vars with NULL stride is the same as vara. */ if (nc_put_vars_uint(ncid, varid[2], start, NULL, NULL, uint_data_out)) ERR; if (nc_get_vara_uint(ncid, varid[2], start, count, uint_data_in)) ERR; for (i = 0; i < SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; if (nc_put_vara_longlong(ncid, varid[3], start, count, int64_data_out)) ERR; if (nc_get_vars_longlong(ncid, varid[3], start, NULL, NULL, int64_data_in)) ERR; for (i = 0; i < SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; if (nc_put_vara_ulonglong(ncid, varid[4], start, count, uint64_data_out)) ERR; if (nc_get_vara_ulonglong(ncid, varid[4], start, count, uint64_data_in)) ERR; for (i = 0; i < SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; /* Close the test file. */ nc_close(ncid); } SUMMARIZE_ERR; /* Test the vars functions. */ printf("*** testing vars functions with new netCDF-4 atomic types..."); { CLEAN_INPUT_BUFFERS; start[0] = 0; count[0] = 2; stride[0] = STRIDE_SIZE; /* Open a netcdf-4 file, and one dimension. */ if (create_test_file(FILENAME, varid, &ncid)) ERR; if (nc_put_vars_uchar(ncid, varid[0], start, count, stride, ubyte_data_out)) ERR; /* This will not work. */ if (nc_get_vars_uchar(ncid, varid[0], NULL, count, stride, ubyte_data_in) != NC_EINVALCOORDS) ERR; /* This will work. */ if (nc_get_vars_uchar(ncid, varid[0], start, count, stride, ubyte_data_in)) ERR; if (ubyte_data_in[0] != ubyte_data_out[0]) ERR; if (ubyte_data_in[1] != ubyte_data_out[STRIDE_SIZE]) ERR; /* This will not work. */ if (nc_put_vars_ushort(ncid, varid[1], NULL, count, stride, ushort_data_out) != NC_EINVALCOORDS) ERR; /* This will work. */ if (nc_put_vars_ushort(ncid, varid[1], start, count, stride, ushort_data_out)) ERR; if (nc_get_vars_ushort(ncid, varid[1], start, count, stride, ushort_data_in)) ERR; for (i = 0; i < 2; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; if (nc_put_vars_uint(ncid, varid[2], start, count, stride, uint_data_out)) ERR; if (nc_get_vars_uint(ncid, varid[2], start, count, stride, uint_data_in)) ERR; for (i = 0; i < 2; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; if (nc_put_vars_longlong(ncid, varid[3], start, count, stride, int64_data_out)) ERR; if (nc_get_vars_longlong(ncid, varid[3], start, count, stride, int64_data_in)) ERR; for (i = 0; i < 2; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; if (nc_put_vars_ulonglong(ncid, varid[4], start, count, stride, uint64_data_out)) ERR; if (nc_get_vars_ulonglong(ncid, varid[4], start, count, stride, uint64_data_in)) ERR; for (i = 0; i < 2; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; /* Close the test file. */ nc_close(ncid); } SUMMARIZE_ERR; /* Test the var1 functions. */ printf("*** testing var1 functions with new netCDF-4 atomic types..."); { CLEAN_INPUT_BUFFERS; index1[0] = 0; /* Open a netcdf-4 file, and one dimension. */ if (create_test_file(FILENAME, varid, &ncid)) ERR; /* This will not work. */ if (nc_put_var1_uchar(ncid, varid[0], NULL, ubyte_data_out) != NC_EINVALCOORDS) ERR; /* This will work. */ if (nc_put_var1_uchar(ncid, varid[0], index1, ubyte_data_out)) ERR; /* This will not work. */ if (nc_get_var1_uchar(ncid, varid[0], NULL, ubyte_data_in) != NC_EINVALCOORDS) ERR; /* This will work. */ if (nc_get_var1_uchar(ncid, varid[0], index1, ubyte_data_in)) ERR; if (ubyte_data_in[0] != ubyte_data_out[0]) ERR; if (nc_put_var1_ushort(ncid, varid[1], index1, ushort_data_out)) ERR; if (nc_get_var1_ushort(ncid, varid[1], index1, ushort_data_in)) ERR; if (ushort_data_in[0] != ushort_data_out[0]) ERR; if (nc_put_var1_uint(ncid, varid[2], index1, uint_data_out)) ERR; if (nc_get_var1_uint(ncid, varid[2], index1, uint_data_in)) ERR; if (uint_data_in[0] != uint_data_out[0]) ERR; if (nc_put_var1_longlong(ncid, varid[3], index1, int64_data_out)) ERR; if (nc_get_var1_longlong(ncid, varid[3], index1, int64_data_in)) ERR; if (int64_data_in[0] != int64_data_out[0]) ERR; if (nc_put_var1_ulonglong(ncid, varid[4], index1, uint64_data_out)) ERR; if (nc_get_var1_ulonglong(ncid, varid[4], index1, uint64_data_in)) ERR; if (uint64_data_in[0] != uint64_data_out[0]) ERR; /* Close the test file. */ nc_close(ncid); } SUMMARIZE_ERR; /* Test the varm functions. */ printf("*** testing varm functions with new netCDF-4 atomic types..."); { int ncid, varid[NUM_TYPES]; CLEAN_INPUT_BUFFERS; start[0] = 0; count[0] = 1; stride[0] = 1; imap[0] = 0; /* Open a netcdf-4 file, and one dimension. */ if (create_test_file(FILENAME, varid, &ncid)) ERR; /* This will not work. */ if (nc_put_varm_ubyte(ncid, varid[0], NULL, count, stride, imap, ubyte_data_out) != NC_EINVALCOORDS) ERR; /* This will work. */ if (nc_put_varm_ubyte(ncid, varid[0], start, count, stride, imap, ubyte_data_out)) ERR; /* This will not work. */ if (nc_get_varm_ubyte(ncid, varid[0], NULL, count, stride, imap, ubyte_data_in) != NC_EINVALCOORDS) ERR; /* This will work. */ if (nc_get_varm_ubyte(ncid, varid[0], start, count, stride, imap, ubyte_data_in)) ERR; for (i = 0; i < STRIDE_SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; if (nc_put_varm_ushort(ncid, varid[1], start, count, stride, imap, ushort_data_out)) ERR; if (nc_get_varm_ushort(ncid, varid[1], start, count, stride, imap, ushort_data_in)) ERR; for (i = 0; i < STRIDE_SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; if (nc_put_varm_uint(ncid, varid[2], start, count, stride, imap, uint_data_out)) ERR; if (nc_get_varm_uint(ncid, varid[2], start, count, stride, imap, uint_data_in)) ERR; for (i = 0; i < STRIDE_SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; if (nc_put_varm_longlong(ncid, varid[3], start, count, stride, imap, int64_data_out)) ERR; if (nc_get_varm_longlong(ncid, varid[3], start, count, stride, imap, int64_data_in)) ERR; for (i = 0; i < STRIDE_SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; if (nc_put_varm_ulonglong(ncid, varid[4], start, count, stride, imap, uint64_data_out)) ERR; if (nc_get_varm_ulonglong(ncid, varid[4], start, count, stride, imap, uint64_data_in)) ERR; for (i = 0; i < STRIDE_SIZE; i++) if (ubyte_data_in[i] != ubyte_data_out[i]) ERR; /* Close the test file. */ nc_close(ncid); } SUMMARIZE_ERR; FINAL_RESULTS; }