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

#include "hdf5.h"

#define FILE          "cmp5loop.h5"
#define DATASETNAME   "Array"
#define LENGTH        5 
#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,d;
    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       nm_sufd[2],dsetname[20];
    char       *base="St";


    /* 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);


    /* Loop through creating 5 datasets  */
    for (d=0; d<5; d++) 
    {
       strcpy (dsetname, DATASETNAME);
       sprintf (nm_sufd, "%i",d); 
       strcat (dsetname, nm_sufd);

       space = H5Screate_simple (RANK, dim, maxdim);

       /* 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);


       dataset = H5Dcreate(file, dsetname, s1_tid, space, cparms);
       printf ("H5Dcreate: %i\n", dataset);

       status=H5Sclose(space);
       printf ("H5Sclose: %i\n", status);

       /* 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=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 a loop to avoid using up lots of memory */
          status=H5Sclose(space);
          printf ("H5Sclose: %i\n", status);
       }
   

       /* Release resources */
       status=H5Sclose(memspace);
       printf ("H5Sclose: %i\n", status);

       status= H5Tclose(s1_tid);
       printf ("H5Tclose: %i\n", status);
       status=H5Dclose(dataset);
       printf ("H5Dclose: %i\n", status);
       newsize[0]=LENGTH;

    }
  
    status= H5Tclose(atype);
    printf ("H5Tclose: %i\n", status);
    status= H5Tclose(ctype);
    printf ("H5Tclose: %i\n", status);
    status= H5Pclose (cparms);
    printf ("H5Pclose: %i\n", status);

    status=H5Fclose(file);
    printf ("H5Fclose: %i\n", status);

}
