netcdf-c/h5_test/tst_h_compounds.c
2018-12-04 16:51:40 -07:00

1199 lines
46 KiB
C

/* This is part of the netCDF package.
Copyright 2018 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 "h5_err_macros.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
#define STR_LEN 255
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))) ERR;
memcpy((void *)data2, (void *)dummy, sizeof(struct s2) * DIM1_LEN);
free(dummy);
if (!(dummy = calloc(sizeof(struct s1), DIM1_LEN))) ERR;
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, STR_LEN) < 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[STR_LEN + 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, STR_LEN+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, STR_LEN) < 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[STR_LEN * 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))) ERR;
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[STR_LEN + 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))) ERR;
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, STR_LEN + 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[STR_LEN + 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] = STR_LEN + 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[STR_LEN + 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, STR_LEN + 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[STR_LEN + 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] = {STR_LEN + 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[STR_LEN + 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] = {STR_LEN + 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))) ERR;
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[STR_LEN + 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] = {STR_LEN + 1};
int i, j;
/* Create some data. */
for (i = 0; i < DISC_DIM1_LEN; i++)
{
for (j = 0; j < STR_LEN + 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 < STR_LEN + 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))) ERR;
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))) ERR;
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;
}