mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-27 07:30:33 +08:00
Regarding [NCF-331], the issues appears to have been in nc4file.c:get_type_info2(). The call to H5Tget_order() was only happening for H5T_Float. According to the documentation, this works for all datatypes as of hdf5 1.8.6. This tentatively fixes the bug reported, but additional testing (and cleanup from debugging) is needed.
This commit is contained in:
parent
de29c4d0a8
commit
99ef1624bc
@ -1375,6 +1375,7 @@ IF(ENABLE_TESTS)
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(nc_test)
|
||||
IF(USE_NETCDF4)
|
||||
INCLUDE_DIRECTORIES(h5_test)
|
||||
ADD_SUBDIRECTORY(nc_test4)
|
||||
ADD_SUBDIRECTORY(h5_test)
|
||||
ENDIF()
|
||||
|
@ -895,31 +895,51 @@ get_type_info2(NC_HDF5_FILE_INFO_T *h5, hid_t datasetid,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Find out about endianness. */
|
||||
if (class == H5T_INTEGER)
|
||||
{
|
||||
if ((order = H5Tget_order(hdf_typeid)) < 0)
|
||||
return NC_EHDFERR;
|
||||
/* Find out about endianness.
|
||||
* As of HDF 1.8.6, this works with all data types
|
||||
* Not just H5T_INTEGER.
|
||||
*
|
||||
* See https://www.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-GetOrder
|
||||
*/
|
||||
if((order = H5Tget_order(hdf_typeid)) < 0)
|
||||
return NC_EHDFERR;
|
||||
|
||||
if(order == H5T_ORDER_LE)
|
||||
(*type_info)->endianness = NC_ENDIAN_LITTLE;
|
||||
else if(order == H5T_ORDER_BE)
|
||||
(*type_info)->endianness = NC_ENDIAN_BIG;
|
||||
else
|
||||
return NC_EBADTYPE;
|
||||
|
||||
if(class == H5T_INTEGER)
|
||||
(*type_info)->nc_type_class = NC_INT;
|
||||
else
|
||||
(*type_info)->nc_type_class = NC_FLOAT;
|
||||
|
||||
|
||||
// if (class == H5T_INTEGER)
|
||||
// {
|
||||
// if ((order = H5Tget_order(hdf_typeid)) < 0)
|
||||
// return NC_EHDFERR;
|
||||
|
||||
/* Copy this into the type_info struct. */
|
||||
if (order == H5T_ORDER_LE)
|
||||
(*type_info)->endianness = NC_ENDIAN_LITTLE;
|
||||
else if (order == H5T_ORDER_BE)
|
||||
(*type_info)->endianness = NC_ENDIAN_BIG;
|
||||
else /* don't support H5T_ORDER_VAX, H5T_ORDER_MIXED, H5T_ORDER_NONE */
|
||||
return NC_EBADTYPE;
|
||||
// if (order == H5T_ORDER_LE)
|
||||
// (*type_info)->endianness = NC_ENDIAN_LITTLE;
|
||||
// else if (order == H5T_ORDER_BE)
|
||||
// (*type_info)->endianness = NC_ENDIAN_BIG;
|
||||
// else /* don't support H5T_ORDER_VAX, H5T_ORDER_MIXED, H5T_ORDER_NONE */
|
||||
// return NC_EBADTYPE;
|
||||
|
||||
/* Set a class for the type */
|
||||
/* (Note use of 'NC_INT' for all integer types) */
|
||||
(*type_info)->nc_type_class = NC_INT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// /* Set a class for the type */
|
||||
// /* (Note use of 'NC_INT' for all integer types) */
|
||||
// (*type_info)->nc_type_class = NC_INT;
|
||||
// } else
|
||||
// {
|
||||
/* Set a class for the type */
|
||||
/* (Note use of 'NC_FLOAT' for all floating-point types) */
|
||||
(*type_info)->nc_type_class = NC_FLOAT;
|
||||
}
|
||||
}
|
||||
// (*type_info)->nc_type_class = NC_FLOAT;
|
||||
// }
|
||||
}
|
||||
(*type_info)->nc_typeid = nc_type_constant_g[t];
|
||||
(*type_info)->size = nc_type_size_g[t];
|
||||
if (!((*type_info)->name = strdup(nc_type_name_g[t])))
|
||||
|
@ -11,90 +11,178 @@
|
||||
#include <netcdf.h>
|
||||
#include <stdio.h>
|
||||
#include "nc_logging.h"
|
||||
#include <hdf5.h>
|
||||
#include <nc_tests.h>
|
||||
|
||||
#define FILE_NAME_NC "tst_endian_float.nc"
|
||||
#define FILE_NAME_H5 "tst_endian_float.h5"
|
||||
|
||||
|
||||
#define FILE_NAME "tst_endian_float.nc"
|
||||
#define NDIM 10
|
||||
#define NLON 20
|
||||
#define DIM_NAME "x"
|
||||
#define DIM_LEN 3
|
||||
#define GRP_NAME "grp"
|
||||
#define VAR_NAME2 "fv"
|
||||
#define VAR_NAME3 "iv"
|
||||
#define VAR_NAME "jv"
|
||||
int main() {
|
||||
|
||||
/*
|
||||
* 1. Create a file with endianness as desired.
|
||||
*/
|
||||
|
||||
int ncid, dimid, varid, varid2, varid3, retval;
|
||||
int ed, ed2, ed3;
|
||||
int failures = 0;
|
||||
int oldfill = 0;
|
||||
int ed, ed2, ed3;
|
||||
int failures = 0;
|
||||
int oldfill = 0;
|
||||
|
||||
#ifdef LOGGING
|
||||
printf("Setting log level 10\n");
|
||||
nc_set_log_level(10);
|
||||
LOG((2,"setting Log_level, logging with level 2."));
|
||||
#ifdef LOGGING1
|
||||
printf("Setting log level 10\n");
|
||||
nc_set_log_level(10);
|
||||
LOG((2,"setting Log_level, logging with level 2."));
|
||||
#endif
|
||||
printf("* Checking that endianness is properly read from file.\n");
|
||||
printf("** Generating test files.\n");
|
||||
/*
|
||||
* 1. Create a netcdf file with endianness as desired.
|
||||
*/
|
||||
{
|
||||
|
||||
retval = nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid);
|
||||
printf("*** Creating a file via netcdf API: %s.\n",FILE_NAME_NC);
|
||||
retval = nc_create(FILE_NAME_NC, NC_NETCDF4 | NC_CLOBBER, &ncid);
|
||||
|
||||
retval = nc_def_dim(ncid, DIM_NAME, NDIM, &dimid);
|
||||
retval = nc_def_dim(ncid, DIM_NAME, NDIM, &dimid);
|
||||
|
||||
/* First, Float */
|
||||
retval = nc_def_var(ncid, VAR_NAME, NC_FLOAT, 1, &dimid, &varid);
|
||||
/* First, Float */
|
||||
retval = nc_def_var(ncid, VAR_NAME, NC_FLOAT, 1, &dimid, &varid);
|
||||
retval = nc_def_var_endian(ncid, varid, NC_ENDIAN_BIG);
|
||||
|
||||
/* Second, Double */
|
||||
//retval = nc_def_var(ncid, VAR_NAME2, NC_DOUBLE, 1, &dimid, &varid2);
|
||||
//retval = nc_def_var_endian(ncid, varid2, NC_ENDIAN_BIG);
|
||||
/* Second, Double */
|
||||
retval = nc_def_var(ncid, VAR_NAME2, NC_DOUBLE, 1, &dimid, &varid2);
|
||||
retval = nc_def_var_endian(ncid, varid2, NC_ENDIAN_BIG);
|
||||
|
||||
/* Third, Int */
|
||||
retval = nc_def_var(ncid, VAR_NAME3, NC_INT, 1, &dimid, &varid3);
|
||||
retval = nc_def_var_endian(ncid, varid3, NC_ENDIAN_BIG);
|
||||
/* Third, Int */
|
||||
retval = nc_def_var(ncid, VAR_NAME3, NC_INT, 1, &dimid, &varid3);
|
||||
retval = nc_def_var_endian(ncid, varid3, NC_ENDIAN_BIG);
|
||||
|
||||
retval = nc_close(ncid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a file with the hdf5 api
|
||||
*/
|
||||
{
|
||||
hid_t fileid, grpid, spaceid;
|
||||
hid_t native_did, le_did, be_did;
|
||||
hsize_t dims[1];
|
||||
printf("*** Creating a file via hdf5 API: %s\n",FILE_NAME_H5);
|
||||
|
||||
if ((fileid = H5Fcreate(FILE_NAME_H5, H5F_ACC_TRUNC, H5P_DEFAULT,
|
||||
H5P_DEFAULT)) < 0) ERR;
|
||||
if ((grpid = H5Gcreate1(fileid, GRP_NAME, 0)) < 0) ERR;
|
||||
|
||||
/* Create a dataset of native endian. */
|
||||
dims[0] = DIM_LEN;
|
||||
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
||||
if ((native_did = H5Dcreate1(grpid, VAR_NAME3, H5T_STD_I32BE,
|
||||
spaceid, H5P_DEFAULT)) < 0) ERR;
|
||||
if ((le_did = H5Dcreate1(grpid, VAR_NAME, H5T_IEEE_F32BE,
|
||||
spaceid, H5P_DEFAULT)) < 0) ERR;
|
||||
if ((be_did = H5Dcreate1(grpid, VAR_NAME2, H5T_IEEE_F32BE,
|
||||
spaceid, H5P_DEFAULT)) < 0) ERR;
|
||||
|
||||
if (H5Dclose(native_did) < 0 ||
|
||||
H5Dclose(le_did) < 0 ||
|
||||
H5Dclose(be_did) < 0 ||
|
||||
H5Sclose(spaceid) < 0 ||
|
||||
H5Gclose(grpid) < 0 ||
|
||||
H5Fclose(fileid) < 0)
|
||||
{
|
||||
printf("Error closing hdf5 file.\n");
|
||||
failures++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 3. Reopen netcdf-generated file, check to see if the endianness attribute
|
||||
* exists.
|
||||
*/
|
||||
printf("** Checking test files.\n");
|
||||
{
|
||||
ncid = 0;
|
||||
printf("*** %s\n",FILE_NAME_NC);
|
||||
retval = nc_open(FILE_NAME_NC, NC_NETCDF4 | NC_NOWRITE, &ncid);
|
||||
retval = nc_set_fill(ncid, NC_NOFILL, &oldfill);
|
||||
retval = nc_inq_varid(ncid,VAR_NAME,&varid);
|
||||
retval = nc_inq_varid(ncid,VAR_NAME2,&varid2);
|
||||
retval = nc_inq_varid(ncid,VAR_NAME3,&varid3);
|
||||
|
||||
retval = nc_inq_var_endian(ncid,varid,&ed);
|
||||
if(ed != NC_ENDIAN_BIG) {
|
||||
printf("\tTest 1: Error for float variable endianness: [%d] not NC_ENDIAN_BIG\n",ed);
|
||||
failures++;
|
||||
} else {
|
||||
printf("\tTest 1: [%d] is NC_ENDIAN_BIG, Success.\n",ed);
|
||||
}
|
||||
|
||||
retval = nc_inq_var_endian(ncid,varid2,&ed2);
|
||||
if(ed2 != NC_ENDIAN_BIG) {
|
||||
printf("\tTest 2: Error for double variable endianness: [%d] not NC_ENDIAN_BIG\n",ed);
|
||||
failures++;
|
||||
} else {
|
||||
printf("\tTest 2: [%d] is NC_ENDIAN_BIG, Success.\n",ed2);
|
||||
}
|
||||
|
||||
retval = nc_inq_var_endian(ncid,varid3,&ed3);
|
||||
if(ed3 != NC_ENDIAN_BIG) {
|
||||
printf("\tTest 3: Error for integer variable endianness: [%d] not NC_ENDIAN_BIG\n",ed2);
|
||||
failures++;
|
||||
} else {
|
||||
printf("\tTest 3: [%d] is NC_ENDIAN_BIG, Success.\n",ed3);
|
||||
}
|
||||
|
||||
retval = nc_close(ncid);
|
||||
return retval;
|
||||
/*
|
||||
* 2. Reopen file, check to see if the endianness attribute
|
||||
* exists.
|
||||
*/
|
||||
ncid = 0;
|
||||
retval = nc_open(FILE_NAME, NC_NETCDF4 | NC_NOWRITE, &ncid);
|
||||
retval = nc_set_fill(ncid, NC_NOFILL, &oldfill);
|
||||
retval = nc_inq_varid(ncid,VAR_NAME,&varid);
|
||||
retval = nc_inq_varid(ncid,VAR_NAME2,&varid2);
|
||||
retval = nc_inq_varid(ncid,VAR_NAME3,&varid3);
|
||||
|
||||
retval = nc_inq_var_endian(ncid,varid,&ed);
|
||||
if(ed != NC_ENDIAN_BIG) {
|
||||
printf("Test 1: Error for float variable endianness: [%d] not NC_ENDIAN_BIG\n",ed);
|
||||
failures++;
|
||||
} else {
|
||||
printf("Test 1: [%d] is NC_ENDIAN_BIG, Success.\n",ed);
|
||||
}
|
||||
|
||||
retval = nc_inq_var_endian(ncid,varid2,&ed2);
|
||||
if(ed2 != NC_ENDIAN_BIG) {
|
||||
printf("Test 2: Error for double variable endianness: [%d] not NC_ENDIAN_BIG\n",ed);
|
||||
failures++;
|
||||
} else {
|
||||
printf("Test 2: [%d] is NC_ENDIAN_BIG, Success.\n",ed2);
|
||||
}
|
||||
|
||||
retval = nc_inq_var_endian(ncid,varid3,&ed3);
|
||||
if(ed3 != NC_ENDIAN_LITTLE) {
|
||||
printf("Test 3: Error for integer variable endianness: [%d] not NC_ENDIAN_BIG\n",ed2);
|
||||
failures++;
|
||||
} else {
|
||||
printf("Test 3: [%d] is NC_ENDIAN_BIG, Success.\n",ed3);
|
||||
}
|
||||
/*
|
||||
* 4. Reopen hdf5-generated file, check to see if the endianness attribute
|
||||
* exists.
|
||||
*/
|
||||
{
|
||||
ncid = 0;
|
||||
printf("*** %s\n",FILE_NAME_H5);
|
||||
retval = nc_open(FILE_NAME_H5, NC_NETCDF4 | NC_NOWRITE, &ncid);
|
||||
retval = nc_inq_varid(ncid,VAR_NAME,&varid);
|
||||
retval = nc_inq_varid(ncid,VAR_NAME2,&varid2);
|
||||
retval = nc_inq_varid(ncid,VAR_NAME3,&varid3);
|
||||
|
||||
retval = nc_inq_var_endian(ncid,varid,&ed);
|
||||
if(ed != NC_ENDIAN_BIG) {
|
||||
printf("\tTest 1: Error for float variable endianness: [%d] not NC_ENDIAN_BIG\n",ed);
|
||||
failures++;
|
||||
} else {
|
||||
printf("\tTest 1: [%d] is NC_ENDIAN_BIG, Success.\n",ed);
|
||||
}
|
||||
|
||||
retval = nc_inq_var_endian(ncid,varid2,&ed2);
|
||||
if(ed2 != NC_ENDIAN_BIG) {
|
||||
printf("\tTest 2: Error for double variable endianness: [%d] not NC_ENDIAN_BIG\n",ed);
|
||||
failures++;
|
||||
} else {
|
||||
printf("\tTest 2: [%d] is NC_ENDIAN_BIG, Success.\n",ed2);
|
||||
}
|
||||
|
||||
retval = nc_inq_var_endian(ncid,varid3,&ed3);
|
||||
if(ed3 != NC_ENDIAN_BIG) {
|
||||
printf("\tTest 3: Error for integer variable endianness: [%d] not NC_ENDIAN_BIG\n",ed2);
|
||||
failures++;
|
||||
} else {
|
||||
printf("\tTest 3: [%d] is NC_ENDIAN_BIG, Success.\n",ed3);
|
||||
}
|
||||
|
||||
retval = nc_close(ncid);
|
||||
|
||||
|
||||
/* Force a failure for now, until I can automate the check
|
||||
programatically that the endianess attribute is properly
|
||||
stored. */
|
||||
|
||||
}
|
||||
printf("** Failures Returned: [%d]\n",failures);
|
||||
return failures;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user