diff options
Diffstat (limited to 'HDF5Examples/C/H5T/h5ex_t_cpxcmpdatt.c')
-rw-r--r-- | HDF5Examples/C/H5T/h5ex_t_cpxcmpdatt.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/HDF5Examples/C/H5T/h5ex_t_cpxcmpdatt.c b/HDF5Examples/C/H5T/h5ex_t_cpxcmpdatt.c new file mode 100644 index 0000000..c7efbce --- /dev/null +++ b/HDF5Examples/C/H5T/h5ex_t_cpxcmpdatt.c @@ -0,0 +1,331 @@ +/************************************************************ + + This example shows how to read and write a complex + compound datatype to an attribute. The program first + writes complex compound structures to an attribute with a + dataspace of DIM0, then closes the file. Next, it reopens + the file, reads back selected fields in the structure, and + outputs them to the screen. + + Unlike the other datatype examples, in this example we + save to the file using native datatypes to simplify the + type definitions here. To save using standard types you + must manually calculate the sizes and offsets of compound + types as shown in h5ex_t_cmpd.c, and convert enumerated + values as shown in h5ex_t_enum.c. + + The datatype defined here consists of a compound + containing a variable-length list of compound types, as + well as a variable-length string, enumeration, double + array, object reference and region reference. The nested + compound type contains an int, variable-length string and + two doubles. + + ************************************************************/ + +#include "hdf5.h" +#include <stdio.h> +#include <stdlib.h> + +#define FILE "h5ex_t_cpxcmpdatt.h5" +#define DATASET "DS1" +#define ATTRIBUTE "A1" +#define DIM0 2 + +typedef struct { + int serial_no; + char *location; + double temperature; + double pressure; +} sensor_t; /* Nested compound type */ + +typedef enum { RED, GREEN, BLUE } color_t; /* Enumerated type */ + +typedef struct { + hvl_t sensors; + char *name; + color_t color; + double location[3]; + hobj_ref_t group; + hdset_reg_ref_t surveyed_areas; +} vehicle_t; /* Main compound type */ + +typedef struct { + hvl_t sensors; + char *name; +} rvehicle_t; /* Read type */ + +int +main(void) +{ + hid_t file, vehicletype, colortype, sensortype, sensorstype, loctype, strtype, rvehicletype, rsensortype, + rsensorstype, space, dset, group, attr; + /* Handles */ + herr_t status; + hsize_t dims[1] = {DIM0}, adims[1] = {3}, adims2[2] = {32, 32}, start[2] = {8, 26}, count[2] = {4, 3}, + coords[3][2] = {{3, 2}, {3, 3}, {4, 4}}; + vehicle_t wdata[2]; /* Write buffer */ + rvehicle_t *rdata; /* Read buffer */ + color_t val; + sensor_t *ptr; + double wdata2[32][32]; + int ndims; + hsize_t i, j; + + /* + * Create a new file using the default properties. + */ + file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Create dataset to use for region references. + */ + for (i = 0; i < 32; i++) + for (j = 0; j < 32; j++) + wdata2[i][j] = 70. + 0.1 * (i - 16.) + 0.1 * (j - 16.); + space = H5Screate_simple(2, adims2, NULL); + dset = H5Dcreate(file, "Ambient_Temperature", H5T_NATIVE_DOUBLE, space, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT); + status = H5Dwrite(dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata2[0]); + status = H5Dclose(dset); + + /* + * Create groups to use for object references. + */ + group = H5Gcreate(file, "Land_Vehicles", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + status = H5Gclose(group); + group = H5Gcreate(file, "Air_Vehicles", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + status = H5Gclose(group); + + /* + * Initialize variable-length compound in the first data element. + */ + wdata[0].sensors.len = 4; + ptr = (sensor_t *)malloc(wdata[0].sensors.len * sizeof(sensor_t)); + ptr[0].serial_no = 1153; + ptr[0].location = "Exterior (static)"; + ptr[0].temperature = 53.23; + ptr[0].pressure = 24.57; + ptr[1].serial_no = 1184; + ptr[1].location = "Intake"; + ptr[1].temperature = 55.12; + ptr[1].pressure = 22.95; + ptr[2].serial_no = 1027; + ptr[2].location = "Intake manifold"; + ptr[2].temperature = 103.55; + ptr[2].pressure = 31.23; + ptr[3].serial_no = 1313; + ptr[3].location = "Exhaust manifold"; + ptr[3].temperature = 1252.89; + ptr[3].pressure = 84.11; + wdata[0].sensors.p = (void *)ptr; + + /* + * Initialize other fields in the first data element. + */ + wdata[0].name = "Airplane"; + wdata[0].color = GREEN; + wdata[0].location[0] = -103234.21; + wdata[0].location[1] = 422638.78; + wdata[0].location[2] = 5996.43; + status = H5Rcreate(&wdata[0].group, file, "Air_Vehicles", H5R_OBJECT, -1); + status = H5Sselect_elements(space, H5S_SELECT_SET, 3, coords[0]); + status = H5Rcreate(&wdata[0].surveyed_areas, file, "Ambient_Temperature", H5R_DATASET_REGION, space); + + /* + * Initialize variable-length compound in the second data element. + */ + wdata[1].sensors.len = 1; + ptr = (sensor_t *)malloc(wdata[1].sensors.len * sizeof(sensor_t)); + ptr[0].serial_no = 3244; + ptr[0].location = "Roof"; + ptr[0].temperature = 83.82; + ptr[0].pressure = 29.92; + wdata[1].sensors.p = (void *)ptr; + + /* + * Initialize other fields in the second data element. + */ + wdata[1].name = "Automobile"; + wdata[1].color = RED; + wdata[1].location[0] = 326734.36; + wdata[1].location[1] = 221568.23; + wdata[1].location[2] = 432.36; + status = H5Rcreate(&wdata[1].group, file, "Land_Vehicles", H5R_OBJECT, -1); + status = H5Sselect_hyperslab(space, H5S_SELECT_SET, start, NULL, count, NULL); + status = H5Rcreate(&wdata[1].surveyed_areas, file, "Ambient_Temperature", H5R_DATASET_REGION, space); + + status = H5Sclose(space); + + /* + * Create variable-length string datatype. + */ + strtype = H5Tcopy(H5T_C_S1); + status = H5Tset_size(strtype, H5T_VARIABLE); + + /* + * Create the nested compound datatype. + */ + sensortype = H5Tcreate(H5T_COMPOUND, sizeof(sensor_t)); + status = H5Tinsert(sensortype, "Serial number", HOFFSET(sensor_t, serial_no), H5T_NATIVE_INT); + status = H5Tinsert(sensortype, "Location", HOFFSET(sensor_t, location), strtype); + status = H5Tinsert(sensortype, "Temperature (F)", HOFFSET(sensor_t, temperature), H5T_NATIVE_DOUBLE); + status = H5Tinsert(sensortype, "Pressure (inHg)", HOFFSET(sensor_t, pressure), H5T_NATIVE_DOUBLE); + + /* + * Create the variable-length datatype. + */ + sensorstype = H5Tvlen_create(sensortype); + + /* + * Create the enumerated datatype. + */ + colortype = H5Tenum_create(H5T_NATIVE_INT); + val = (color_t)RED; + status = H5Tenum_insert(colortype, "Red", &val); + val = (color_t)GREEN; + status = H5Tenum_insert(colortype, "Green", &val); + val = (color_t)BLUE; + status = H5Tenum_insert(colortype, "Blue", &val); + + /* + * Create the array datatype. + */ + loctype = H5Tarray_create(H5T_NATIVE_DOUBLE, 1, adims); + + /* + * Create the main compound datatype. + */ + vehicletype = H5Tcreate(H5T_COMPOUND, sizeof(vehicle_t)); + status = H5Tinsert(vehicletype, "Sensors", HOFFSET(vehicle_t, sensors), sensorstype); + status = H5Tinsert(vehicletype, "Name", HOFFSET(vehicle_t, name), strtype); + status = H5Tinsert(vehicletype, "Color", HOFFSET(vehicle_t, color), colortype); + status = H5Tinsert(vehicletype, "Location", HOFFSET(vehicle_t, location), loctype); + status = H5Tinsert(vehicletype, "Group", HOFFSET(vehicle_t, group), H5T_STD_REF_OBJ); + status = + H5Tinsert(vehicletype, "Surveyed areas", HOFFSET(vehicle_t, surveyed_areas), H5T_STD_REF_DSETREG); + + /* + * Create dataset with a null dataspace. to serve as the parent for + * the attribute. + */ + space = H5Screate(H5S_NULL); + dset = H5Dcreate(file, DATASET, H5T_STD_I32LE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + status = H5Sclose(space); + + /* + * Create dataspace. Setting maximum size to NULL sets the maximum + * size to be the current size. + */ + space = H5Screate_simple(1, dims, NULL); + + /* + * Create the attribute and write the compound data to it. + */ + attr = H5Acreate(dset, ATTRIBUTE, vehicletype, space, H5P_DEFAULT, H5P_DEFAULT); + status = H5Awrite(attr, vehicletype, wdata); + + /* + * Close and release resources. Note that we cannot use + * H5Dvlen_reclaim as it would attempt to free() the string + * constants used to initialize the name fields in wdata. We must + * therefore manually free() only the data previously allocated + * through malloc(). + */ + for (i = 0; i < dims[0]; i++) + free(wdata[i].sensors.p); + status = H5Aclose(attr); + status = H5Dclose(dset); + status = H5Sclose(space); + status = H5Tclose(strtype); + status = H5Tclose(sensortype); + status = H5Tclose(sensorstype); + status = H5Tclose(colortype); + status = H5Tclose(loctype); + status = H5Tclose(vehicletype); + status = H5Fclose(file); + + /* + * Now we begin the read section of this example. Here we assume + * the attribute has the same name and rank, but can have any size. + * Therefore we must allocate a new array to read in data using + * malloc(). We will only read back the variable length strings. + */ + + /* + * Open file, dataset, and attribute. + */ + file = H5Fopen(FILE, H5F_ACC_RDONLY, H5P_DEFAULT); + dset = H5Dopen(file, DATASET, H5P_DEFAULT); + attr = H5Aopen(dset, ATTRIBUTE, H5P_DEFAULT); + + /* + * Create variable-length string datatype. + */ + strtype = H5Tcopy(H5T_C_S1); + status = H5Tset_size(strtype, H5T_VARIABLE); + + /* + * Create the nested compound datatype for reading. Even though it + * has only one field, it must still be defined as a compound type + * so the library can match the correct field in the file type. + * This matching is done by name. However, we do not need to + * define a structure for the read buffer as we can simply treat it + * as a char *. + */ + rsensortype = H5Tcreate(H5T_COMPOUND, sizeof(char *)); + status = H5Tinsert(rsensortype, "Location", 0, strtype); + + /* + * Create the variable-length datatype for reading. + */ + rsensorstype = H5Tvlen_create(rsensortype); + + /* + * Create the main compound datatype for reading. + */ + rvehicletype = H5Tcreate(H5T_COMPOUND, sizeof(rvehicle_t)); + status = H5Tinsert(rvehicletype, "Sensors", HOFFSET(rvehicle_t, sensors), rsensorstype); + status = H5Tinsert(rvehicletype, "Name", HOFFSET(rvehicle_t, name), strtype); + + /* + * Get dataspace and allocate memory for read buffer. + */ + space = H5Aget_space(attr); + ndims = H5Sget_simple_extent_dims(space, dims, NULL); + rdata = (rvehicle_t *)malloc(dims[0] * sizeof(rvehicle_t)); + + /* + * Read the data. + */ + status = H5Aread(attr, rvehicletype, rdata); + + /* + * Output the data to the screen. + */ + for (i = 0; i < dims[0]; i++) { + printf("%s[%llu]:\n", ATTRIBUTE, i); + printf(" Vehicle name :\n %s\n", rdata[i].name); + printf(" Sensor locations :\n"); + for (j = 0; j < rdata[i].sensors.len; j++) + printf(" %s\n", ((char **)rdata[i].sensors.p)[j]); + } + + /* + * Close and release resources. H5Dvlen_reclaim will automatically + * traverse the structure and free any vlen data (including + * strings). + */ + status = H5Dvlen_reclaim(rvehicletype, space, H5P_DEFAULT, rdata); + free(rdata); + status = H5Aclose(attr); + status = H5Dclose(dset); + status = H5Sclose(space); + status = H5Tclose(strtype); + status = H5Tclose(rsensortype); + status = H5Tclose(rsensorstype); + status = H5Tclose(rvehicletype); + status = H5Fclose(file); + + return 0; +} |