mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
1205 lines
47 KiB
C
1205 lines
47 KiB
C
/* This is part of the netCDF package.
|
|
Copyright 2005 University Corporation for Atmospheric Research/Unidata
|
|
See COPYRIGHT file for conditions of use.
|
|
|
|
Test HDF5 file code. These are not intended to be exhaustive tests,
|
|
but they use HDF5 the same way that netCDF-4 does, so if these
|
|
tests don't work, than netCDF-4 won't work either.
|
|
|
|
This program deals with HDF5 compound types.
|
|
|
|
$Id: tst_h_compounds.c,v 1.25 2010/06/01 15:34:51 ed Exp $
|
|
*/
|
|
#include <nc_tests.h>
|
|
#include <hdf5.h>
|
|
|
|
#define FILE_NAME "tst_h_compounds.h5"
|
|
#define DIM1_LEN 3
|
|
#define OSMONDS "TheOsmonds"
|
|
#define WHO "TheWho"
|
|
#define BOOZE_VAR "Alcohol_Consumed"
|
|
#define BEER_OR_WINE "Beer_or_Wine"
|
|
#define LIQUOR "The_Hard_Stuff"
|
|
#define COMPOUND_NAME "Booze_Index"
|
|
#define ARRAY_LEN 5
|
|
|
|
int
|
|
main()
|
|
{
|
|
hid_t fileid, osmonds_grpid, who_grpid, spaceid, typeid;
|
|
hid_t datasetid, datasetid1, typeid1;
|
|
hsize_t dims[1];
|
|
struct s1 {
|
|
int i1, i2;
|
|
} data[DIM1_LEN];
|
|
struct s2 {
|
|
int i1[ARRAY_LEN], i2;
|
|
} data2[DIM1_LEN];
|
|
char *dummy;
|
|
int i, j;
|
|
|
|
/* REALLY initialize the data (even the gaps in the structs). This
|
|
* is only needed to pass valgrind. */
|
|
if (!(dummy = calloc(sizeof(struct s2), DIM1_LEN)))
|
|
return NC_ENOMEM;
|
|
memcpy((void *)data2, (void *)dummy, sizeof(struct s2) * DIM1_LEN);
|
|
free(dummy);
|
|
if (!(dummy = calloc(sizeof(struct s1), DIM1_LEN)))
|
|
return NC_ENOMEM;
|
|
memcpy((void *)data2, (void *)dummy, sizeof(struct s1) * DIM1_LEN);
|
|
free(dummy);
|
|
|
|
for (i=0; i<DIM1_LEN; i++)
|
|
{
|
|
data[i].i1 = 99;
|
|
data[i].i2 = -99;
|
|
data2[i].i2 = -99;
|
|
for (j=0; j<ARRAY_LEN; j++)
|
|
data2[i].i1[j] = 99;
|
|
}
|
|
|
|
printf("\n*** Checking HDF5 compound types.\n");
|
|
printf("*** Checking simple HDF5 compound types...");
|
|
{
|
|
|
|
/* Open file and create group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT,
|
|
H5P_DEFAULT)) < 0) ERR;
|
|
if ((osmonds_grpid = H5Gcreate(fileid, OSMONDS, 0)) < 0) ERR;
|
|
|
|
/* Create a simple compound type. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
|
|
if (H5Tinsert(typeid, BEER_OR_WINE, HOFFSET(struct s1, i1), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tinsert(typeid, LIQUOR, HOFFSET(struct s1, i2), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tcommit(osmonds_grpid, COMPOUND_NAME, typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM1_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create a dataset of this compound type. */
|
|
if ((datasetid = H5Dcreate(osmonds_grpid, BOOZE_VAR, typeid,
|
|
spaceid, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Dwrite(datasetid, typeid, H5S_ALL, H5S_ALL,
|
|
H5P_DEFAULT, data) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(osmonds_grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((osmonds_grpid = H5Gopen(fileid, OSMONDS)) < 0) ERR;
|
|
if ((datasetid = H5Dopen1(osmonds_grpid, BOOZE_VAR)) < 0) ERR;
|
|
if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Tget_nmembers(typeid) != 2) ERR;
|
|
/* This doesn't work because all I have is a reference to the type!
|
|
if (H5Iget_name(typeid, type_name, NC_MAX_NAME) < 0) ERR;
|
|
if (strcmp(type_name, COMPOUND_NAME)) ERR;*/
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(osmonds_grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking HDF5 compound types and groups...");
|
|
|
|
{
|
|
/* Open file and create two group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT,
|
|
H5P_DEFAULT)) < 0) ERR;
|
|
if ((osmonds_grpid = H5Gcreate(fileid, OSMONDS, 0)) < 0) ERR;
|
|
if ((who_grpid = H5Gcreate(fileid, WHO, 0)) < 0) ERR;
|
|
|
|
/* Create a simple compound type. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
|
|
if (H5Tinsert(typeid, BEER_OR_WINE, HOFFSET(struct s1, i1), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tinsert(typeid, LIQUOR, HOFFSET(struct s1, i2), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tcommit(osmonds_grpid, COMPOUND_NAME, typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM1_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create a dataset of this compound type in the same group. */
|
|
if ((datasetid = H5Dcreate(osmonds_grpid, BOOZE_VAR, typeid,
|
|
spaceid, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Dwrite(datasetid, typeid, H5S_ALL, H5S_ALL,
|
|
H5P_DEFAULT, data) < 0) ERR;
|
|
|
|
/* Create a dataset of this compound type in a different group. */
|
|
if ((datasetid1 = H5Dcreate(who_grpid, BOOZE_VAR, typeid,
|
|
spaceid, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Dwrite(datasetid1, typeid, H5S_ALL, H5S_ALL,
|
|
H5P_DEFAULT, data) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Dclose(datasetid1) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(osmonds_grpid) < 0 ||
|
|
H5Gclose(who_grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
{
|
|
hsize_t num_obj;
|
|
int i, obj_type;
|
|
char name[NC_MAX_NAME + 1];
|
|
htri_t equal;
|
|
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((osmonds_grpid = H5Gopen(fileid, OSMONDS)) < 0) ERR;
|
|
if (H5Gget_num_objs(osmonds_grpid, &num_obj) < 0) ERR;
|
|
for (i=0; i<num_obj; i++)
|
|
{
|
|
if (H5Gget_objname_by_idx(osmonds_grpid, i, name, NC_MAX_NAME+1) < 0) ERR;
|
|
if ((obj_type = H5Gget_objtype_by_idx(osmonds_grpid, i)) < 0) ERR;
|
|
switch(obj_type)
|
|
{
|
|
case H5G_DATASET:
|
|
if ((datasetid = H5Dopen1(osmonds_grpid, name)) < 0) ERR;
|
|
break;
|
|
case H5G_TYPE:
|
|
if ((typeid = H5Topen(osmonds_grpid, name)) < 0) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Tget_nmembers(typeid) != 2) ERR;
|
|
if (strcmp(name, COMPOUND_NAME)) ERR;
|
|
break;
|
|
default:
|
|
ERR;
|
|
}
|
|
}
|
|
|
|
/* Open the other dataset, and learn about its type. */
|
|
if ((who_grpid = H5Gopen(fileid, WHO)) < 0) ERR;
|
|
if ((datasetid1 = H5Dopen1(who_grpid, BOOZE_VAR)) < 0) ERR;
|
|
if ((typeid1 = H5Dget_type(datasetid1)) < 0) ERR;
|
|
if ((equal = H5Tequal(typeid, typeid1)) < 0) ERR;
|
|
if (!equal) ERR;
|
|
}
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Dclose(datasetid1) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Tclose(typeid1) < 0 ||
|
|
H5Gclose(osmonds_grpid) < 0 ||
|
|
H5Gclose(who_grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking HDF5 compound type which contains an array...");
|
|
|
|
{
|
|
hsize_t array_dims[] = {ARRAY_LEN};
|
|
hid_t array_typeid;
|
|
|
|
/* Open file and create group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT,
|
|
H5P_DEFAULT)) < 0) ERR;
|
|
if ((osmonds_grpid = H5Gcreate(fileid, OSMONDS, 0)) < 0) ERR;
|
|
|
|
/* Create an array type. */
|
|
if ((array_typeid = H5Tarray_create(H5T_NATIVE_INT, 1, array_dims, NULL)) < 0) ERR;
|
|
|
|
/* Create a compound type containing an array. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s2))) < 0) ERR;
|
|
if (H5Tinsert(typeid, BEER_OR_WINE, HOFFSET(struct s2, i1), array_typeid) < 0) ERR;
|
|
if (H5Tinsert(typeid, LIQUOR, HOFFSET(struct s2, i2), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tcommit(osmonds_grpid, COMPOUND_NAME, typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM1_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create a dataset of this compound type. */
|
|
if ((datasetid = H5Dcreate(osmonds_grpid, BOOZE_VAR, typeid,
|
|
spaceid, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Dwrite(datasetid, typeid, H5S_ALL, H5S_ALL,
|
|
H5P_DEFAULT, data2) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Tclose(array_typeid) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(osmonds_grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((osmonds_grpid = H5Gopen(fileid, OSMONDS)) < 0) ERR;
|
|
if ((datasetid = H5Dopen1(osmonds_grpid, BOOZE_VAR)) < 0) ERR;
|
|
if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Tget_nmembers(typeid) != 2) ERR;
|
|
/* This doesn't work because all I have is a reference to the type!
|
|
if (H5Iget_name(typeid, type_name, NC_MAX_NAME) < 0) ERR;
|
|
if (strcmp(type_name, COMPOUND_NAME)) ERR;*/
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(osmonds_grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking HDF5 compound type 6 different types...");
|
|
|
|
{
|
|
#define DAY "day"
|
|
#define ELEV "elev"
|
|
#define COUNT "count"
|
|
#define RELHUM "relhum"
|
|
#define TIME "time"
|
|
#define OBS_T "obs_t"
|
|
#define OBS_VAR "obs_var"
|
|
#define DIM6_LEN 3
|
|
|
|
hid_t fileid, grpid, spaceid, typeid, native_typeid;
|
|
hid_t datasetid, mem_type;
|
|
hsize_t dims[1];
|
|
typedef struct obs_t {
|
|
char day ;
|
|
short elev;
|
|
int count;
|
|
float relhum;
|
|
double time;
|
|
} obs_t ;
|
|
obs_t obsdata[DIM6_LEN];
|
|
obs_t obsdata_in[DIM6_LEN], obsdata2_in[DIM6_LEN];
|
|
char file_in[NC_MAX_NAME * 2];
|
|
char *dummy;
|
|
size_t size_in;
|
|
|
|
/* REALLY initialize the data (even the gaps in the structs). This
|
|
* is only needed to pass valgrind. */
|
|
if (!(dummy = calloc(sizeof(struct obs_t), DIM6_LEN)))
|
|
return NC_ENOMEM;
|
|
memcpy((void *)obsdata, (void *)dummy, sizeof(struct obs_t) * DIM6_LEN);
|
|
free(dummy);
|
|
|
|
/* Initialize data. */
|
|
for (i = 0; i < DIM6_LEN; i++)
|
|
{
|
|
obsdata[i].day = 15 * i + 1;
|
|
obsdata[i].elev = 2 * i + 1;
|
|
obsdata[i].count = 2 * i + 1;
|
|
obsdata[i].relhum = 2.0 * i + 1;
|
|
obsdata[i].time = 2.0 * i + 1;
|
|
}
|
|
|
|
/* Open file and create group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
|
|
/* Create a compound type containing some different types. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct obs_t))) < 0) ERR;
|
|
if (H5Tinsert(typeid, DAY, HOFFSET(struct obs_t, day), H5T_NATIVE_CHAR) < 0) ERR;
|
|
if (H5Tinsert(typeid, ELEV, HOFFSET(struct obs_t, elev), H5T_NATIVE_SHORT) < 0) ERR;
|
|
if (H5Tinsert(typeid, COUNT, HOFFSET(struct obs_t, count), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tinsert(typeid, RELHUM, HOFFSET(struct obs_t, relhum), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tinsert(typeid, TIME, HOFFSET(struct obs_t, time), H5T_NATIVE_DOUBLE) < 0) ERR;
|
|
if (H5Tcommit(grpid, OBS_T, typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM6_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create a dataset of this compound type. */
|
|
if ((datasetid = H5Dcreate(grpid, OBS_VAR, typeid, spaceid, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Dwrite(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, obsdata) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((datasetid = H5Dopen1(grpid, OBS_VAR)) < 0) ERR;
|
|
if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
|
|
if ((size_in = H5Tget_size(typeid)) == 0) ERR;
|
|
if (size_in != sizeof(struct obs_t)) ERR;
|
|
if ((native_typeid = H5Tget_native_type(typeid, H5T_DIR_DEFAULT)) < 0) ERR;
|
|
if ((size_in = H5Tget_size(native_typeid)) == 0) ERR;
|
|
if (size_in != sizeof(struct obs_t)) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Tget_nmembers(typeid) != 5) ERR;
|
|
|
|
/* Read all data. */
|
|
if (H5Dread(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, obsdata_in) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
for (i = 0; i < DIM6_LEN; i++)
|
|
{
|
|
if (obsdata[i].day != obsdata_in[i].day || obsdata[i].elev != obsdata_in[i].elev ||
|
|
obsdata[i].count != obsdata_in[i].count || obsdata[i].relhum != obsdata_in[i].relhum ||
|
|
obsdata[i].time != obsdata_in[i].time)
|
|
{
|
|
ERR;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the reference copy of this file and read it. */
|
|
#define REF_FILE_NAME "ref_tst_h_compounds.h5"
|
|
if (getenv("srcdir"))
|
|
{
|
|
strcpy(file_in, getenv("srcdir"));
|
|
strcat(file_in, "/");
|
|
strcat(file_in, REF_FILE_NAME);
|
|
}
|
|
else
|
|
strcpy(file_in, REF_FILE_NAME);
|
|
|
|
if ((fileid = H5Fopen(file_in, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((datasetid = H5Dopen1(grpid, OBS_VAR)) < 0) ERR;
|
|
if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
|
|
if ((mem_type = H5Tget_native_type(typeid, H5T_DIR_DEFAULT)) < 0) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Tget_nmembers(typeid) != 5) ERR;
|
|
|
|
/* Read all data. */
|
|
if (H5Dread(datasetid, mem_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, obsdata2_in) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
for (i = 0; i < DIM6_LEN; i++)
|
|
{
|
|
if (obsdata[i].day != obsdata2_in[i].day || obsdata[i].elev != obsdata2_in[i].elev ||
|
|
obsdata[i].count != obsdata2_in[i].count || obsdata[i].relhum != obsdata2_in[i].relhum ||
|
|
obsdata[i].time != obsdata2_in[i].time)
|
|
{
|
|
ERR;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking HDF5 compound variable which contains a compound type...");
|
|
{
|
|
#define DATASET_NAME "Enterprise"
|
|
/* This struct will be embeddeded in another. */
|
|
struct s1
|
|
{
|
|
int i1;
|
|
int i2;
|
|
};
|
|
/* StarFleet Human Resources Department has data records for all
|
|
* employees. */
|
|
struct hr_rec
|
|
{
|
|
int starfleet_id;
|
|
struct s1 svc_rec;
|
|
char name[NC_MAX_NAME + 1];
|
|
float max_temp, min_temp; /* temperature range */
|
|
double percent_transporter_errosion;
|
|
};
|
|
struct hr_rec hr_data_out[DIM1_LEN], hr_data_in[DIM1_LEN];
|
|
|
|
hid_t fileid, grpid, typeid_inner, typeid, spaceid, array1_tid, datasetid;
|
|
hsize_t dims[1];
|
|
char *dummy;
|
|
int i;
|
|
|
|
/* REALLY initialize the data (even the gaps in the structs). This
|
|
* is only needed to pass valgrind. */
|
|
if (!(dummy = calloc(sizeof(struct hr_rec), DIM1_LEN)))
|
|
return NC_ENOMEM;
|
|
memcpy((void *)hr_data_out, (void *)dummy, sizeof(struct hr_rec) * DIM1_LEN);
|
|
free(dummy);
|
|
|
|
/* Create some phony data. */
|
|
for (i = 0; i < DIM1_LEN; i++)
|
|
{
|
|
hr_data_out[i].starfleet_id = i;
|
|
hr_data_out[i].svc_rec.i1 = 95;
|
|
hr_data_out[i].svc_rec.i2 = 90;
|
|
if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
|
|
hr_data_out[i].max_temp = 99.99;
|
|
hr_data_out[i].min_temp = -9.99;
|
|
hr_data_out[i].percent_transporter_errosion = .1;
|
|
}
|
|
|
|
/* Open file and get root group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
|
|
/* Create a compound type. */
|
|
if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "i1", HOFFSET(struct s1, i1), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "i2", HOFFSET(struct s1, i2), H5T_NATIVE_INT) < 0) ERR;
|
|
|
|
/* Create a compound type containing a compound type. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
|
|
if (H5Tinsert(typeid, "starfleet_id", HOFFSET(struct hr_rec, starfleet_id), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tinsert(typeid, "svc_rec", HOFFSET(struct hr_rec, svc_rec), typeid_inner) < 0) ERR;
|
|
if ((array1_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
|
|
if (H5Tset_size(array1_tid, NC_MAX_NAME + 1) < 0) ERR;
|
|
if (H5Tinsert(typeid, "name", HOFFSET(struct hr_rec, name), array1_tid) < 0) ERR;
|
|
if (H5Tinsert(typeid, "max_temp", HOFFSET(struct hr_rec, max_temp), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tinsert(typeid, "min_temp", HOFFSET(struct hr_rec, min_temp), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tinsert(typeid, "percent_transporter_errosion", HOFFSET(struct hr_rec, percent_transporter_errosion),
|
|
H5T_NATIVE_DOUBLE) < 0) ERR;
|
|
if (H5Tcommit(grpid, "hr_rec", typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM1_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create a dataset of this compound type. */
|
|
if ((datasetid = H5Dcreate(grpid, DATASET_NAME, typeid, spaceid, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Dwrite(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, hr_data_out) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(array1_tid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Tclose(typeid_inner) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((datasetid = H5Dopen1(grpid, DATASET_NAME)) < 0) ERR;
|
|
if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Dread(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, hr_data_in) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
for (i = 0; i < DIM1_LEN; i++)
|
|
if (hr_data_out[i].starfleet_id != hr_data_in[i].starfleet_id ||
|
|
hr_data_out[i].svc_rec.i1 != hr_data_in[i].svc_rec.i1 ||
|
|
hr_data_out[i].svc_rec.i2 != hr_data_in[i].svc_rec.i2 ||
|
|
strcmp(hr_data_out[i].name, hr_data_in[i].name) ||
|
|
hr_data_out[i].max_temp != hr_data_in[i].max_temp ||
|
|
hr_data_out[i].min_temp != hr_data_in[i].min_temp ||
|
|
hr_data_out[i].percent_transporter_errosion != hr_data_in[i].percent_transporter_errosion)
|
|
ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking HDF5 variable which contains a compound type with different string handling...");
|
|
{
|
|
#define DATASET_NAME "Enterprise"
|
|
/* This struct will be embeddeded in another. */
|
|
struct s1
|
|
{
|
|
int i1;
|
|
int i2;
|
|
};
|
|
/* StarFleet Human Resources Department has data records for all
|
|
* employees. */
|
|
struct hr_rec
|
|
{
|
|
int starfleet_id;
|
|
struct s1 svc_rec;
|
|
char name[NC_MAX_NAME + 1];
|
|
float max_temp, min_temp; /* temperature range */
|
|
double percent_transporter_errosion;
|
|
};
|
|
struct hr_rec hr_data_out[DIM1_LEN], hr_data_in[DIM1_LEN];
|
|
|
|
hid_t fileid, grpid, typeid_inner, typeid, spaceid, array1_tid, datasetid, str_tid;
|
|
hsize_t dims[1];
|
|
int i;
|
|
|
|
/* Create some phony data. */
|
|
for (i = 0; i < DIM1_LEN; i++)
|
|
{
|
|
hr_data_out[i].starfleet_id = i;
|
|
hr_data_out[i].svc_rec.i1 = 95;
|
|
hr_data_out[i].svc_rec.i2 = 90;
|
|
if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
|
|
hr_data_out[i].max_temp = 99.99;
|
|
hr_data_out[i].min_temp = -9.99;
|
|
hr_data_out[i].percent_transporter_errosion = .1;
|
|
}
|
|
|
|
/* Open file and get root group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
|
|
/* Create a compound type. */
|
|
if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "i1", HOFFSET(struct s1, i1), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "i2", HOFFSET(struct s1, i2), H5T_NATIVE_INT) < 0) ERR;
|
|
|
|
/* Create a compound type containing a compound type. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
|
|
if (H5Tinsert(typeid, "starfleet_id", HOFFSET(struct hr_rec, starfleet_id), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tinsert(typeid, "svc_rec", HOFFSET(struct hr_rec, svc_rec), typeid_inner) < 0) ERR;
|
|
dims[0] = NC_MAX_NAME + 1;
|
|
if ((str_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
|
|
if (H5Tset_strpad(str_tid, H5T_STR_NULLTERM) < 0) ERR;
|
|
if ((array1_tid = H5Tarray_create2(str_tid, 1, dims)) < 0) ERR;
|
|
if (H5Tinsert(typeid, "name", HOFFSET(struct hr_rec, name), array1_tid) < 0) ERR;
|
|
if (H5Tinsert(typeid, "max_temp", HOFFSET(struct hr_rec, max_temp), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tinsert(typeid, "min_temp", HOFFSET(struct hr_rec, min_temp), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tinsert(typeid, "percent_transporter_errosion", HOFFSET(struct hr_rec, percent_transporter_errosion),
|
|
H5T_NATIVE_DOUBLE) < 0) ERR;
|
|
if (H5Tcommit(grpid, "hr_rec", typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM1_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create a dataset of this compound type. */
|
|
if ((datasetid = H5Dcreate(grpid, DATASET_NAME, typeid, spaceid, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Dwrite(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, hr_data_out) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(array1_tid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Tclose(typeid_inner) < 0 ||
|
|
H5Tclose(str_tid) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((datasetid = H5Dopen1(grpid, DATASET_NAME)) < 0) ERR;
|
|
if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Dread(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, hr_data_in) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
for (i = 0; i < DIM1_LEN; i++)
|
|
if (hr_data_out[i].starfleet_id != hr_data_in[i].starfleet_id ||
|
|
hr_data_out[i].svc_rec.i1 != hr_data_in[i].svc_rec.i1 ||
|
|
hr_data_out[i].svc_rec.i2 != hr_data_in[i].svc_rec.i2 ||
|
|
strcmp(hr_data_out[i].name, hr_data_in[i].name) ||
|
|
hr_data_out[i].max_temp != hr_data_in[i].max_temp ||
|
|
hr_data_out[i].min_temp != hr_data_in[i].min_temp ||
|
|
hr_data_out[i].percent_transporter_errosion != hr_data_in[i].percent_transporter_errosion)
|
|
ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking HDF5 compound attribute which contains a compound type...");
|
|
{
|
|
#define ATT_NAME1 "Space_Station_Regula_One"
|
|
/* This struct will be embeddeded in another. */
|
|
struct s1
|
|
{
|
|
int i1;
|
|
int i2;
|
|
};
|
|
/* StarFleet Human Resources Department has data records for all
|
|
* employees. */
|
|
struct hr_rec
|
|
{
|
|
int starfleet_id;
|
|
struct s1 svc_rec;
|
|
char name[NC_MAX_NAME + 1];
|
|
float max_temp, min_temp; /* temperature range */
|
|
double percent_transporter_errosion;
|
|
};
|
|
struct hr_rec hr_data_out[DIM1_LEN], hr_data_in[DIM1_LEN];
|
|
|
|
hid_t fileid, grpid, typeid_inner, typeid, spaceid, array1_tid, attid, native_typeid;
|
|
hsize_t dims[1];
|
|
int i;
|
|
|
|
/* Create some phony data. */
|
|
for (i = 0; i < DIM1_LEN; i++)
|
|
{
|
|
hr_data_out[i].starfleet_id = i;
|
|
hr_data_out[i].svc_rec.i1 = 95;
|
|
hr_data_out[i].svc_rec.i2 = 90;
|
|
if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
|
|
hr_data_out[i].max_temp = 99.99;
|
|
hr_data_out[i].min_temp = -9.99;
|
|
hr_data_out[i].percent_transporter_errosion = .1;
|
|
}
|
|
|
|
/* Open file and get root group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
|
|
/* Create a compound type. */
|
|
if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "i1", HOFFSET(struct s1, i1), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "i2", HOFFSET(struct s1, i2), H5T_NATIVE_INT) < 0) ERR;
|
|
|
|
/* Create a compound type containing a compound type. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
|
|
if (H5Tinsert(typeid, "starfleet_id", HOFFSET(struct hr_rec, starfleet_id), H5T_NATIVE_INT) < 0) ERR;
|
|
if (H5Tinsert(typeid, "svc_rec", HOFFSET(struct hr_rec, svc_rec), typeid_inner) < 0) ERR;
|
|
if ((array1_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
|
|
if (H5Tset_size(array1_tid, NC_MAX_NAME + 1) < 0) ERR;
|
|
if (H5Tinsert(typeid, "name", HOFFSET(struct hr_rec, name), array1_tid) < 0) ERR;
|
|
if (H5Tinsert(typeid, "max_temp", HOFFSET(struct hr_rec, max_temp), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tinsert(typeid, "min_temp", HOFFSET(struct hr_rec, min_temp), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tinsert(typeid, "percent_transporter_errosion", HOFFSET(struct hr_rec, percent_transporter_errosion),
|
|
H5T_NATIVE_DOUBLE) < 0) ERR;
|
|
if (H5Tcommit(grpid, "hr_rec", typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM1_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create an attribute of this compound type. */
|
|
if ((attid = H5Acreate2(grpid, ATT_NAME1, typeid, spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data to the attribute. */
|
|
if (H5Awrite(attid, typeid, hr_data_out) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Tclose(typeid_inner) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((attid = H5Aopen_by_name(grpid, ".", ATT_NAME1, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((typeid = H5Aget_type(attid)) < 0) ERR;
|
|
if ((native_typeid = H5Tget_native_type(typeid, H5T_DIR_DEFAULT)) < 0) ERR;
|
|
if (H5Aread(attid, native_typeid, hr_data_in) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
for (i = 0; i < DIM1_LEN; i++)
|
|
if (hr_data_out[i].starfleet_id != hr_data_in[i].starfleet_id ||
|
|
hr_data_out[i].svc_rec.i1 != hr_data_in[i].svc_rec.i1 ||
|
|
hr_data_out[i].svc_rec.i2 != hr_data_in[i].svc_rec.i2 ||
|
|
strcmp(hr_data_out[i].name, hr_data_in[i].name) ||
|
|
hr_data_out[i].max_temp != hr_data_in[i].max_temp ||
|
|
hr_data_out[i].min_temp != hr_data_in[i].min_temp ||
|
|
hr_data_out[i].percent_transporter_errosion != hr_data_in[i].percent_transporter_errosion)
|
|
ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking HDF5 variable of compound type which contains a string...");
|
|
{
|
|
#define DATASET_NAME "Enterprise"
|
|
struct hr_rec
|
|
{
|
|
char name[NC_MAX_NAME + 1];
|
|
float max_temp;
|
|
};
|
|
struct hr_rec hr_data_out[DIM1_LEN], hr_data_in[DIM1_LEN];
|
|
|
|
hid_t fileid, grpid, typeid, spaceid, array1_tid, datasetid, str_tid;
|
|
hsize_t dims[1] = {NC_MAX_NAME + 1};
|
|
int i;
|
|
|
|
/* Create some phony data. */
|
|
for (i = 0; i < DIM1_LEN; i++)
|
|
{
|
|
if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
|
|
hr_data_out[i].max_temp = 99.99;
|
|
}
|
|
|
|
/* Open file and get root group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
|
|
/* Create a compound type. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
|
|
/* printf("sizeof(struct hr_rec)=%d dims[0]=%d\n", sizeof(struct hr_rec), dims[0]);*/
|
|
if ((str_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
|
|
if (H5Tset_strpad(str_tid, H5T_STR_NULLTERM) < 0) ERR;
|
|
if ((array1_tid = H5Tarray_create2(str_tid, 1, dims)) < 0) ERR;
|
|
/* printf("sizeof(struct hr_rec)=%d HOFFSET(struct hr_rec, name) = %d HOFFSET(struct hr_rec, max_temp) = %d\n",
|
|
sizeof(struct hr_rec), HOFFSET(struct hr_rec, name), HOFFSET(struct hr_rec, max_temp));*/
|
|
if (H5Tinsert(typeid, "name", HOFFSET(struct hr_rec, name), array1_tid) < 0) ERR;
|
|
if (H5Tinsert(typeid, "max_temp", HOFFSET(struct hr_rec, max_temp), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tcommit(grpid, "hr_rec", typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM1_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create a dataset of this compound type. */
|
|
if ((datasetid = H5Dcreate(grpid, DATASET_NAME, typeid, spaceid, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Dwrite(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, hr_data_out) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(array1_tid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Tclose(str_tid) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((datasetid = H5Dopen1(grpid, DATASET_NAME)) < 0) ERR;
|
|
if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Dread(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, hr_data_in) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
for (i = 0; i < DIM1_LEN; i++)
|
|
if (strcmp(hr_data_out[i].name, hr_data_in[i].name) ||
|
|
hr_data_out[i].max_temp != hr_data_in[i].max_temp) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Dclose(datasetid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking HDF5 compound attribute which contains an array of char...");
|
|
{
|
|
#define DIM2_LEN 1
|
|
#define ATT_NAME "HR_Records"
|
|
struct hr_rec
|
|
{
|
|
char name[NC_MAX_NAME + 1];
|
|
float max_temp;
|
|
};
|
|
struct hr_rec hr_data_out[DIM2_LEN], hr_data_in[DIM2_LEN];
|
|
|
|
hid_t fileid, grpid, typeid, spaceid, array1_tid, attid, str_tid;
|
|
hsize_t dims[1] = {NC_MAX_NAME + 1};
|
|
char *dummy;
|
|
int i;
|
|
|
|
/* REALLY initialize the data (even the gaps in the structs). This
|
|
* is only needed to pass valgrind. */
|
|
if (!(dummy = calloc(sizeof(struct hr_rec), DIM2_LEN)))
|
|
return NC_ENOMEM;
|
|
memcpy((void *)hr_data_out, (void *)dummy, sizeof(struct hr_rec) * DIM2_LEN);
|
|
free(dummy);
|
|
|
|
/* Create some phony data. */
|
|
for (i = 0; i < DIM2_LEN; i++)
|
|
{
|
|
if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
|
|
hr_data_out[i].max_temp = 99.99;
|
|
}
|
|
|
|
/* Open file and get root group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
|
|
/* Create a compound type. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
|
|
if ((str_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
|
|
if (H5Tset_strpad(str_tid, H5T_STR_NULLTERM) < 0) ERR;
|
|
if ((array1_tid = H5Tarray_create2(str_tid, 1, dims)) < 0) ERR;
|
|
/* printf("sizeof(struct hr_rec)=%d HOFFSET(struct hr_rec, name) = %d HOFFSET(struct hr_rec, max_temp) = %d\n",
|
|
sizeof(struct hr_rec), HOFFSET(struct hr_rec, name), HOFFSET(struct hr_rec, max_temp));*/
|
|
if (H5Tinsert(typeid, "Name", HOFFSET(struct hr_rec, name), array1_tid) < 0) ERR;
|
|
if (H5Tinsert(typeid, "Max_Temp", HOFFSET(struct hr_rec, max_temp), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tcommit(grpid, "SF_HR_Record", typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM2_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create an attribute of this compound type. */
|
|
if ((attid = H5Acreate2(grpid, ATT_NAME, typeid, spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Awrite(attid, typeid, hr_data_out) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(array1_tid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Tclose(str_tid) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((attid = H5Aopen_by_name(grpid, ".", ATT_NAME, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((typeid = H5Aget_type(attid)) < 0) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Aread(attid, typeid, hr_data_in) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
for (i = 0; i < DIM2_LEN; i++)
|
|
if (strcmp(hr_data_out[i].name, hr_data_in[i].name) ||
|
|
hr_data_out[i].max_temp != hr_data_in[i].max_temp) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking HDF5 compound attribute which contains an array of unsigned byte...");
|
|
{
|
|
#define DISC_DIM1_LEN 2
|
|
#define DISC_ATT_NAME "Discovery"
|
|
struct s1
|
|
{
|
|
unsigned char x[NC_MAX_NAME + 1];
|
|
float y;
|
|
};
|
|
struct s1 data_out[DISC_DIM1_LEN], data_in[DISC_DIM1_LEN];
|
|
|
|
hid_t fileid, grpid, typeid, spaceid, array1_tid, attid;
|
|
hid_t fcpl_id, fapl_id;
|
|
hsize_t dims[1] = {NC_MAX_NAME + 1};
|
|
int i, j;
|
|
|
|
/* Create some data. */
|
|
for (i = 0; i < DISC_DIM1_LEN; i++)
|
|
{
|
|
for (j = 0; j < NC_MAX_NAME + 1; j++)
|
|
data_out[i].x[j] = 4;
|
|
data_out[i].y = 99.99;
|
|
}
|
|
|
|
/* Set latest_format in access propertly list and
|
|
* H5P_CRT_ORDER_TRACKED in the creation property list. This
|
|
* turns on HDF5 creation ordering. */
|
|
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
|
|
if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) ERR;
|
|
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) ERR;
|
|
if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
|
|
if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
|
|
/* Open file and get root group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
|
|
/* Create a compound type. */
|
|
if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
|
|
if ((array1_tid = H5Tarray_create2(H5T_NATIVE_UCHAR, 1, dims)) < 0) ERR;
|
|
if (H5Tinsert(typeid, "x", HOFFSET(struct s1, x), array1_tid) < 0) ERR;
|
|
if (H5Tinsert(typeid, "y", HOFFSET(struct s1, y), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tcommit(grpid, "c", typeid) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DISC_DIM1_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create an attribute of this compound type. */
|
|
if ((attid = H5Acreate2(grpid, DISC_ATT_NAME, typeid, spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data. */
|
|
if (H5Awrite(attid, typeid, data_out) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(array1_tid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and read it. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((attid = H5Aopen_by_name(grpid, ".", DISC_ATT_NAME, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((typeid = H5Aget_type(attid)) < 0) ERR;
|
|
if (H5Tget_class(typeid) != H5T_COMPOUND) ERR;
|
|
if (H5Aread(attid, typeid, data_in) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
for (i = 0; i < DISC_DIM1_LEN; i++)
|
|
{
|
|
for (j = 0; j < NC_MAX_NAME + 1; j++)
|
|
if (data_in[i].x[j] != data_out[i].x[j]) ERR_RET;
|
|
if (data_in[i].y != data_out[i].y) ERR;
|
|
}
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking simple read of HDF5 compound attribute which contains a simple compound type...");
|
|
{
|
|
#define DIM_CMP_LEN 1
|
|
#define ATT_CMP_NAME1 "The_Nutmeg_of_Consolation"
|
|
#define NUM_TYPES 2
|
|
#define INNER_TYPE_NAME "s1"
|
|
#define OUTER_TYPE_NAME "d"
|
|
|
|
/* This struct will be embeddeded in another. */
|
|
struct s1
|
|
{
|
|
float x;
|
|
double y;
|
|
};
|
|
struct s2
|
|
{
|
|
struct s1 s1;
|
|
};
|
|
struct s2 data_out[DIM_CMP_LEN], data_in[DIM_CMP_LEN];
|
|
hid_t fileid, grpid, typeid_inner, typeid_outer, spaceid, attid;
|
|
hid_t att_typeid, att_native_typeid;
|
|
hsize_t dims[1];
|
|
hid_t fapl_id, fcpl_id;
|
|
char *dummy;
|
|
int i;
|
|
|
|
/* REALLY initialize the data (even the gaps in the structs). This
|
|
* is only needed to pass valgrind. */
|
|
if (!(dummy = calloc(sizeof(struct s2), DIM_CMP_LEN)))
|
|
return NC_ENOMEM;
|
|
memcpy((void *)data_out, (void *)dummy, sizeof(struct s2) * DIM_CMP_LEN);
|
|
free(dummy);
|
|
|
|
/* Create some phony data. */
|
|
for (i = 0; i < DIM_CMP_LEN; i++)
|
|
{
|
|
data_out[i].s1.x = 1.0;
|
|
data_out[i].s1.y = -2.0;
|
|
}
|
|
|
|
/* Create file access and create property lists. */
|
|
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
|
|
if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
|
|
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) ERR;
|
|
if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
|
|
/* Create file and get root group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
|
|
/* Create the inner compound type. */
|
|
if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "x", HOFFSET(struct s1, x), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "y", HOFFSET(struct s1, y), H5T_NATIVE_DOUBLE) < 0) ERR;
|
|
if (H5Tcommit(grpid, INNER_TYPE_NAME, typeid_inner) < 0) ERR;
|
|
|
|
/* Create a compound type containing a compound type. */
|
|
if ((typeid_outer = H5Tcreate(H5T_COMPOUND, sizeof(struct s2))) < 0) ERR;
|
|
if (H5Tinsert(typeid_outer, INNER_TYPE_NAME, HOFFSET(struct s2, s1), typeid_inner) < 0) ERR;
|
|
if (H5Tcommit(grpid, OUTER_TYPE_NAME, typeid_outer) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM_CMP_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create an attribute of this compound type. */
|
|
if ((attid = H5Acreate2(grpid, ATT_CMP_NAME1, typeid_outer, spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data to the attribute. */
|
|
if (H5Awrite(attid, typeid_outer, data_out) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(typeid_outer) < 0 ||
|
|
H5Tclose(typeid_inner) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and get the type of the attribute. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((attid = H5Aopen_by_name(grpid, ".", ATT_CMP_NAME1, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((att_typeid = H5Aget_type(attid)) < 0) ERR;
|
|
if ((att_native_typeid = H5Tget_native_type(att_typeid, H5T_DIR_DEFAULT)) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
if (H5Aread(attid, att_native_typeid, data_in) < 0) ERR;
|
|
for (i = 0; i < DIM_CMP_LEN; i++)
|
|
if (data_out[i].s1.x != data_in[i].s1.x ||
|
|
data_out[i].s1.y != data_in[i].s1.y) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(att_typeid) < 0 ||
|
|
H5Tclose(att_native_typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
}
|
|
SUMMARIZE_ERR;
|
|
printf("*** Checking simple read of HDF5 compound attribute which contains a simple compound type...");
|
|
{
|
|
#define DIM_CMP_LEN 1
|
|
#define ATT_CMP_NAME1 "The_Nutmeg_of_Consolation"
|
|
#define NUM_TYPES 2
|
|
#define INNER_TYPE_NAME "s1"
|
|
#define OUTER_TYPE_NAME "d"
|
|
|
|
/* This struct will be embeddeded in another. */
|
|
struct s1
|
|
{
|
|
float x;
|
|
double y;
|
|
};
|
|
struct s2
|
|
{
|
|
struct s1 s1;
|
|
};
|
|
struct s2 data_out[DIM_CMP_LEN], data_in[DIM_CMP_LEN];
|
|
hid_t fileid, grpid, typeid_inner, typeid_outer, spaceid, attid;
|
|
hid_t att_typeid, att_native_typeid;
|
|
hsize_t dims[1];
|
|
hid_t fapl_id, fcpl_id;
|
|
int i;
|
|
|
|
/* REALLY initialize the data (even the gaps in the structs). This
|
|
* is only needed to pass valgrind. */
|
|
if (!(dummy = calloc(sizeof(struct s2), DIM_CMP_LEN)))
|
|
return NC_ENOMEM;
|
|
memcpy((void *)data_out, (void *)dummy, sizeof(struct s2) * DIM_CMP_LEN);
|
|
free(dummy);
|
|
|
|
/* Create some phony data. */
|
|
for (i = 0; i < DIM_CMP_LEN; i++)
|
|
{
|
|
data_out[i].s1.x = 1.0;
|
|
data_out[i].s1.y = -2.0;
|
|
}
|
|
|
|
/* Create file access and create property lists. */
|
|
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
|
|
if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
|
|
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) ERR;
|
|
if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
|
|
/* Create file and get root group. */
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
|
|
/* Create the inner compound type. */
|
|
if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "x", HOFFSET(struct s1, x), H5T_NATIVE_FLOAT) < 0) ERR;
|
|
if (H5Tinsert(typeid_inner, "y", HOFFSET(struct s1, y), H5T_NATIVE_DOUBLE) < 0) ERR;
|
|
if (H5Tcommit(grpid, INNER_TYPE_NAME, typeid_inner) < 0) ERR;
|
|
|
|
/* Create a compound type containing a compound type. */
|
|
if ((typeid_outer = H5Tcreate(H5T_COMPOUND, sizeof(struct s2))) < 0) ERR;
|
|
if (H5Tinsert(typeid_outer, INNER_TYPE_NAME, HOFFSET(struct s2, s1), typeid_inner) < 0) ERR;
|
|
if (H5Tcommit(grpid, OUTER_TYPE_NAME, typeid_outer) < 0) ERR;
|
|
|
|
/* Create a space. */
|
|
dims[0] = DIM_CMP_LEN;
|
|
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
|
|
|
|
/* Create an attribute of this compound type. */
|
|
if ((attid = H5Acreate2(grpid, ATT_CMP_NAME1, typeid_outer, spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
|
|
/* Write some data to the attribute. */
|
|
if (H5Awrite(attid, typeid_outer, data_out) < 0) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(typeid_outer) < 0 ||
|
|
H5Tclose(typeid_inner) < 0 ||
|
|
H5Sclose(spaceid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
/* Now open the file and get the type of the attribute. */
|
|
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR;
|
|
if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
|
|
if ((attid = H5Aopen_by_name(grpid, ".", ATT_CMP_NAME1, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
|
if ((att_typeid = H5Aget_type(attid)) < 0) ERR;
|
|
if ((att_native_typeid = H5Tget_native_type(att_typeid, H5T_DIR_DEFAULT)) < 0) ERR;
|
|
|
|
/* Check the data. */
|
|
if (H5Aread(attid, att_native_typeid, data_in) < 0) ERR;
|
|
for (i = 0; i < DIM_CMP_LEN; i++)
|
|
if (data_out[i].s1.x != data_in[i].s1.x ||
|
|
data_out[i].s1.y != data_in[i].s1.y) ERR;
|
|
|
|
/* Release all resources. */
|
|
if (H5Aclose(attid) < 0 ||
|
|
H5Tclose(att_typeid) < 0 ||
|
|
H5Tclose(att_native_typeid) < 0 ||
|
|
H5Gclose(grpid) < 0 ||
|
|
H5Fclose(fileid) < 0) ERR;
|
|
|
|
}
|
|
SUMMARIZE_ERR;
|
|
FINAL_RESULTS;
|
|
}
|