/*
 * This example shows how to create a compound data type,
 * and write to one field in every element of a dataset.
 */

#include "hdf5.h"

#define FILE          "bfld.h5"
#define DATASETNAME   "ArrayOfStructures"
#define LENGTH        10
#define RANK          1

int
main(void)
{

    /* First structure  and dataset*/
    typedef struct s1_t {
	int    a;
	float  b;
	double c; 
    } s1_t;
    s1_t       s1[LENGTH];
    hid_t      s1_tid;     /* File datatype identifier */

    /* Second structure (subset of s1_t)  and dataset*/
    typedef struct s2_t {
	double c;
	int    a;
    } s2_t;
    s2_t       s2[LENGTH];
    hid_t      s2_tid;    /* Memory datatype handle */

    /* Third "structure" ( will be used to read float field of s1) */
    hid_t      s3_tid;   /* Memory datatype handle */
    float      s3[LENGTH];

    int        i;
    hid_t      file, dataset, space; /* Handles */
    herr_t     status;
    hsize_t    dim[] = {LENGTH};   /* Dataspace dimensions */


    /*
     * Initialize the data
     */
    for (i = 0; i< LENGTH; i++) {
        s1[i].a = i;
        s1[i].b = i*i;
        s1[i].c = 1./(i+1);
    }

    /*
     * Create the data space.
     */
    space = H5Screate_simple(RANK, dim, NULL);

    /*
     * Create the file.
     */
    file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

    /*
     * Create the memory data type. 
     */
    s1_tid = H5Tcreate (H5T_COMPOUND, sizeof(s1_t));
    H5Tinsert(s1_tid, "a_name", HOFFSET(s1_t, a), H5T_NATIVE_INT);
    H5Tinsert(s1_tid, "c_name", HOFFSET(s1_t, c), H5T_NATIVE_DOUBLE);
    H5Tinsert(s1_tid, "b_name", HOFFSET(s1_t, b), H5T_NATIVE_FLOAT);

    /* 
     * Create the dataset.
     */
    dataset = H5Dcreate(file, DATASETNAME, s1_tid, space, H5P_DEFAULT);

    /*
     * Wtite data to the dataset; 
     */
    status = H5Dwrite(dataset, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s1);

    /*
     * Release resources
     */
    H5Tclose(s1_tid);
    H5Sclose(space);
    H5Dclose(dataset);
    H5Fclose(file);
 
    /**************************************/ 
    /* Re-open the file and the dataset.  */
    /**************************************/ 

    file = H5Fopen(FILE, H5F_ACC_RDWR, H5P_DEFAULT);
    dataset = H5Dopen(file, DATASETNAME);

    /* Create a data type for s3.  */

    s3_tid = H5Tcreate(H5T_COMPOUND, sizeof(float));
    status = H5Tinsert(s3_tid, "b_name", 0, H5T_NATIVE_FLOAT);

    /* Read field b from s1 dataset. Field in the file is found by its name. */

    status = H5Dread(dataset, s3_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s3);

    /* Display the field */

    printf("\n");
    printf("Field b : \n");
    for( i = 0; i < LENGTH; i++) printf("%.4f ", s3[i]);
    printf("\n");
    
    /*********************************************/
    /* Overwrite the third field with 3.99.      */
    /* Compare the resulting file first with the */
    /* following two lines uncommented, then with*/
    /* them commented out.                       */
    /*********************************************/
    
    for( i = 0; i < LENGTH; i++) s3[i]=3.99;
    status = H5Dwrite(dataset, s3_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s3);
   
    /*********************************************/
    /* End overwrite section                     */
    /*********************************************/

    /* Release resources */

    H5Tclose(s3_tid);
    H5Dclose(dataset);
    H5Fclose(file);

    return 0;
}
