/* 
 *   Writing/reading external datasets
 */


#include     "hdf5.h"

#define      FILENAME "extdat.h5"
#define      EXTFILE1 "ext1.dat"
#define      EXTFILE2 "ext2.dat"
#define      EXTFILE3 "ext3.dat"
#define      DIM1    10
#define      DIM2    20
#define      DIM3    30
#define      DIMTOT  60
#define      FAIL    (-1)

int main() {
  FILE         *in_1, *in_2, *in_3;
  hid_t        file_id, data_id, space_id, plist_id;
  hsize_t      dims[1]    = {DIMTOT};
  hsize_t      size       = 0;
  hsize_t      size_out   = 0;
  herr_t       status     = FAIL;
  off_t        offset     = 0;   
  off_t        offset_out = 0;
  int          i;
  int          data[DIMTOT];
  int          data_out[DIMTOT];
  int          nsegmts = 0;
  int          idx;
  char         name[128];


     /* Initialize the data buffers */
     /* --------------------------- */
       for (i = 0; i < DIMTOT; i++)
          data[i] = 1000 + i + 1;  

     /* Create the "external" data files */
     /* ------------------------------ */
       in_1 = fopen (EXTFILE1, "w");
       in_2 = fopen (EXTFILE2, "w");
       in_3 = fopen (EXTFILE3, "w");  
       fclose(in_1);
       fclose(in_2);
       fclose(in_3);

     /* Create HDF5 file and dataset using external file property list */
     /* -------------------------------------------------------------- */

       file_id  = H5Fcreate (FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
		  
       space_id = H5Screate_simple (1, dims, NULL);
  
       plist_id = H5Pcreate (H5P_DATASET_CREATE);

       offset = 0;
       size   = DIM1 * sizeof(int);
       status = H5Pset_external (plist_id, EXTFILE1, offset, size);

       offset = 40;
       size   = DIM2 * sizeof(int);
       status = H5Pset_external (plist_id, EXTFILE2, offset, size);

       offset = 80;
       size   = DIM3 * sizeof(int);
       status = H5Pset_external (plist_id, EXTFILE3, offset, size);

       data_id  = H5Dcreate (file_id, "External Data", H5T_NATIVE_INT, 
                             space_id, plist_id);

       status   = H5Dwrite (data_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, 
                            H5P_DEFAULT, data);

     /* Read the data from external file */
     /* -------------------------------- */
       status   = H5Dread (data_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, 
                           H5P_DEFAULT, data_out); 
 
     /* Display the data */
     /* ---------------- */
       if (status != FAIL)
       {
          printf ("Data: \n  ");
          for (i = 0; i < DIMTOT; i++) 
             printf ("%d ", data_out[i]);
          printf ("\n\n");
       }
		
     /* Inquire external property list */
     /* ------------------------------ */
       nsegmts = H5Pget_external_count (plist_id);
       printf ("Number of segments in an external file list: %d \n", nsegmts);

     /* Loop through all segments */
     /* ------------------------- */
       for (idx = 0; idx < nsegmts; idx++)
       {
         /* Get information about external file */
         /* ----------------------------------- */
           status = H5Pget_external (plist_id, idx, sizeof (name), name, 
                                    &offset_out, &size_out);

           printf ("Segment: %d Name: %s Offset: %d  Size: %d \n", idx, name,  
                   (int)offset_out, (int)size_out);
       }
     /* Release the IDs */
     /* --------------- */
       status = H5Sclose (space_id);
       status = H5Pclose (plist_id);
       status = H5Dclose (data_id);
       status = H5Fclose (file_id);
}
