/*
 * This example shows how to create an unlimited dataset with a 
 * compound data type and write slabs to it.
*/

#include "hdf5.h"

#define FILE          "cmploop.h5"
#define DATASETNAME   "Array"
#define LENGTH        8 
#define RANK          1 

int
main(void)
{

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

    hssize_t offset[1]={0};
    hsize_t count[1]={LENGTH};
    size_t size;

    int        i,j;
    hid_t      file, dataset, memspace, space, atype, ctype;
    herr_t     status;
    hsize_t    dim[1] = {LENGTH};   /* Dataspace dimensions */
    hsize_t    maxdim[1] = {H5S_UNLIMITED};   /* Dataspace dimensions */
    hid_t      cparms;
    hsize_t    chkdim[1]={3};
    hsize_t    newsize[1]={LENGTH};
    char       nm_suf[2], arrname[5];
    char       *base="St";


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

    /* Create the file  */
    file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    printf ("H5Fcreate: %i\n", file);

    cparms = H5Pcreate (H5P_DATASET_CREATE);
    printf ("H5Pcreate: %i\n", cparms);
    status = H5Pset_chunk ( cparms, RANK, chkdim);
    printf ("H5Pset_chunk: %i\n", status);

    atype = H5Tcopy (H5T_C_S1);
    size = 5;
    status = H5Tset_size (atype, size);

    ctype = H5Tcopy (H5T_C_S1);
    size = 5;
    status = H5Tset_size (ctype, size);

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

    /* Create the dataset  */
    dataset = H5Dcreate(file, DATASETNAME, s1_tid, space, cparms);
    printf ("H5Dcreate: %i\n", dataset);

    /* Create memory space for slab writes */
    memspace = H5Dget_space (dataset);
    printf ("H5Dget_space: %i\n", memspace);

    for (i = 0; i< LENGTH; i++) {
       strcpy (arrname, base);
       sprintf (nm_suf, "%i",i); 
       strcat (arrname, nm_suf);
       strcpy (s1[i].a, arrname);
       strcpy (s1[i].c, arrname);
       s1[i].a[5]='\0';
       s1[i].b=i;
       s1[i].c[5]='\0';
    }
    status = H5Dwrite(dataset, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s1);
    printf ("H5Dwrite: %i\n", status);

    /* Loop through, extending dataset by 5 and writing values to just
       the extended portion of dataset */
    for (j=0;j<5;j++)
    {
       for (i = 0; i< LENGTH; i++) {
          strcpy (arrname, base);
          sprintf (nm_suf, "%i",i); 
          strcat (arrname, nm_suf);
          strcpy (s1[i].a, arrname);
          strcpy (s1[i].c, arrname);
          s1[i].a[5]='\0';
          s1[i].c[5]='\0';
          s1[i].b=5+i;
       }
     
       offset[0] = newsize[0]; 
       newsize[0]=newsize[0]+LENGTH;
       
       status = H5Dextend (dataset, newsize);
       printf ("H5Dextend: %i\n", status);

       space = H5Dget_space (dataset);
       printf ("H5Dget_space: %i\n", space);

       status = H5Sselect_hyperslab (space, H5S_SELECT_SET, offset, NULL,
                count, NULL);
       printf ("H5Sselect_hyperslab: %i\n", status);

       /* Write data to the dataset */
       status = H5Dwrite(dataset, s1_tid, memspace, space, H5P_DEFAULT, s1);
       printf ("H5Dwrite: %i\n", status);

       /* Be sure to close dataspace IN the loop to avoid using up lots of memory */
       status=H5Sclose(space);
       printf ("H5Sclose: %i\n", status);
    }

    /* Release resources */
    status= H5Pclose (cparms);
    printf ("H5Pclose: %i\n", status);
    status= H5Tclose(s1_tid);
    printf ("H5Tclose: %i\n", status);
    status=H5Sclose(memspace);
    printf ("H5Sclose: %i\n", status);
    status=H5Dclose(dataset);
    printf ("H5Dclose: %i\n", status);
    status=H5Fclose(file);
    printf ("H5Fclose: %i\n", status);
}
