
#include "hdf5.h"

#include <stdlib.h> 


#define H5FILE_NAME ".h5"

void WriteReference()
 {
   hid_t fid;
   hid_t gid_a;
   hid_t did_b, sid_b/*, tid_b*/;
   hid_t did_r, tid_r, sid_r;
   herr_t status;


   //hobj_ref_t *wbuf; /* buffer to write to disk */
   hobj_ref_t *wbuf1; /* buffer to write to disk */
   hobj_ref_t *rbuf; /* buffer to read from disk */


   size_t totSize=0;
   hsize_t dim_r[1]/*,start[1] *//*,count[1] */;
   hsize_t dim_b[2];
   hsize_t dimExt[2]={2,2};


   hsize_t  offsetDim[2] ;   // offset given is absolute offset
   hsize_t  count[2] ;


   struct s1{
           unsigned int a;
           hobj_ref_t wbuf;
   };
   s1 st1;


  struct s2{
           float a1;
           hobj_ref_t wbuf;
   };
   s2 st2[2],temp;

   size_t offset_s1[2] = { HOFFSET( s1, a ),
                           HOFFSET( s1, wbuf )};

   size_t offset_s2[2] = { HOFFSET( s2, a1),
                           HOFFSET( s2, wbuf )};


   hsize_t   maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED};// to specify maximum dimension


   fprintf(stderr," \n In Write Reference function %d and type is %d\n",H5Tget_size(H5T_STD_REF_OBJ),sizeof(hobj_ref_t));


   tid_r = H5Tcopy(H5T_STD_REF_OBJ);
   totSize= H5Tget_size(H5T_NATIVE_FLOAT)+H5Tget_size(tid_r);

   totSize = sizeof ( s2 );
   hid_t DS1_type = H5Tcreate(H5T_COMPOUND,totSize);


   H5Tinsert(DS1_type, "value", offset_s2[0] , H5T_NATIVE_FLOAT);
   H5Tinsert(DS1_type, "ref", offset_s2[1] ,tid_r);


   size_t size_s1 = sizeof ( s1 );
   hid_t DS2_type = H5Tcreate(H5T_COMPOUND, size_s1 );
   

   H5Tinsert(DS2_type, "val", offset_s1[0] , H5T_NATIVE_UINT);
   H5Tinsert(DS2_type, "reference",offset_s1[1],tid_r);


   /*
   *  Create a file using default properties.
    */


   fid = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);


   /*
    *  Create  group "A" in the file.
    */
   gid_a = H5Gcreate(fid, "A", 0);



   //chunk parameters
    hid_t       cparms;
    hsize_t      chunk_dims[2] ={1,1};
    cparms = H5Pcreate (H5P_DATASET_CREATE);
    status = H5Pset_chunk ( cparms, 2, chunk_dims);


   /*
   *  Create dataset "B" in the file.
   */
   dim_b[0] = 1;
   dim_b[1] = 2;
   sid_b = H5Screate_simple(2, dim_b, maxdims);
   did_b = H5Dcreate(fid, "B", DS1_type, sid_b, cparms);



   /*
    *  Create dataset "R" to store references to the object  "B".
    */


   dim_r[0] = 1;
   sid_r = H5Screate_simple(1, dim_r, NULL);
   did_r = H5Dcreate(fid, "R", DS2_type, sid_r, H5P_DEFAULT );


   /*
    *  Allocate write and read buffers.
    */


   st1.a = 10;
   st2[0].a1 =6.2;
   st2[1].a1 =4.3;


   wbuf1 = (hobj_ref_t *)malloc(sizeof(hobj_ref_t)*2);
   rbuf = (hobj_ref_t *)malloc(sizeof(hobj_ref_t)*2);


   //Write Data Into the dataset
   H5Rcreate(&st1.wbuf, fid, "B", H5R_OBJECT, -1);
   H5Rcreate(&st2[0].wbuf, fid, "R", H5R_OBJECT, -1);
   H5Rcreate(&st2[1].wbuf, fid, "R", H5R_OBJECT, -1);


    hid_t fileSpace = H5Dget_space(did_r);
   //Write Data values
   status = H5Dwrite(did_r, DS2_type, H5S_ALL, fileSpace,H5P_DEFAULT,&st1);


    //Write Data values
   status = H5Dwrite(did_b, DS1_type, H5S_ALL, H5S_ALL,H5P_DEFAULT,&st2[0]);
   offsetDim[0]=0;
   offsetDim[1]=1;
   count[0]=1;
   count[1]=1;


   hid_t DSspace=H5Dget_space(did_b);
   H5Sselect_hyperslab( DSspace, H5S_SELECT_SET, offsetDim, NULL, /*slabDim*/ count, NULL);
   status = H5Dwrite(did_b, DS1_type, H5S_ALL, DSspace,H5P_DEFAULT,&st2[1]);


   fprintf(stderr," \n status of write %i",status);


   H5Dclose(did_r);
   H5Dclose(did_b);
   H5Fclose(fid);
   free(rbuf);
   free(wbuf1);



   // Reopen the file to read selections back.


    fid = H5Fopen(H5FILE_NAME, H5F_ACC_RDWR,  H5P_DEFAULT);



     // Reopen the dataset with object references and read references
     //to the buffer.


        did_r = H5Dopen (fid, "R");


        //hobj_ref_t  ref;
        status = H5Dread(did_r, DS2_type, sid_r, H5S_ALL,H5P_DEFAULT, &temp);
        fprintf(stderr,"status of read is %i \n ",status);
    fprintf(stderr," object id is  %d \n ",temp.wbuf);


        //Dereferencing
        hid_t dset_id = H5Rdereference(did_r,H5R_OBJECT,&temp.wbuf);


        fprintf(stderr," object id is  %d \n ",dset_id);

        H5Fclose(fid);



 }

int
main (int ac, char **av)
{


    WriteReference();

    return 0;

}

