
/* Sample code to read Global Attributes from and HDF5 file */

#include <math.h>
#include <ctype.h>
#include <string.h>
#include <HE5_HdfEosDef.h>

#define BUF_SIZE 4096
#define MAX_GD 256
#define MAX_ATT 256

static void HE5ParseName(char names_in[], char hdf_names[][256], long n_names)
{
  int i;
  char *tmp,*tmp2;
  
  tmp = names_in;
  for(i = 0; i < n_names; i++)
    {
      if((tmp2 = strchr(tmp,','))!= 0)
        {
	  *tmp2 = '\0';
        }
      strcpy(hdf_names[i], tmp);
      
      tmp2 = tmp;
      while(*tmp2 != '\0')
        {
	  if(!isalnum(*tmp2))
            {
	      *tmp2 = '_';
            }
	  tmp2++;
        }
      tmp = tmp2 + 1;
    }    
}

int main(int argc, char **argv)
{
  hid_t HE5_GDfid = 0;
  int i;
  long ngd;
  long ngrp_atts;
  long ns;
  long str_buf_size;
 
  int max_gd = MAX_GD;
  char gd_hdf_names[MAX_GD][256];
  
  int max_att = MAX_ATT;
  char att_hdf_names[MAX_ATT][256];
  
  hid_t att_type;
  hsize_t att_size;
  int cur_buf_size = BUF_SIZE;
  char *buffer;

  char *charstrs = NULL;
  char *orig_charstrs = NULL;
  unsigned char *rdbuffer = NULL;
  unsigned char *orig_rdbuffer;
  double *drdbuffer = NULL;
  float *frdbuffer = NULL;
  double *orig_drdbuffer = NULL;
  float *orig_frdbuffer = NULL;
  unsigned int * irdbuffer = NULL;
  unsigned int * orig_irdbuffer = NULL;
  
  int         n, k;
  int         statusr;
  herr_t      he5_status;
  hid_t       dtype;
  H5T_class_t classid;
  H5T_order_t order;
  size_t      size;
  hsize_t     size_count;
  int         count;
  
  char path[] = "/tools/pgs/ataaheri/DATA/OMI-Aura_L3-OMLER_2005m01-2009m12_v003-2010m0503t063707.he5";
  /* char path[] = "/tools/pgs/ataaheri/DATA/OMI-Aura_L3-OMSO2e_2004m1027_v003-2012m0409t095845.he5";*/
  
  ngd = HE5_GDinqgrid(path,NULL,&str_buf_size);
  
  while(ngd > max_gd)
    max_gd *= 2;
  
  if(str_buf_size >= cur_buf_size)
    {
      while(str_buf_size >= cur_buf_size)
	cur_buf_size *= 2;
    }
  
  buffer = malloc(cur_buf_size);
  ngd = HE5_GDinqgrid(path,buffer,&str_buf_size);
  HE5ParseName(buffer,gd_hdf_names,ngd);
  buffer[str_buf_size] = '\0';
  
  HE5_GDfid = HE5_GDopen(path,H5F_ACC_RDONLY);
  
  /*
   *global attributes from file
   */
  ngrp_atts = HE5_EHinqglbattrs(HE5_GDfid,NULL,&str_buf_size);
  
  if(1 > ngrp_atts)
    {
      fprintf(stderr, "\nfile: %s, line: %d\n", __FILE__, __LINE__);
      fprintf(stderr, "\tngrp_atts %ld is too small\n\n", ngrp_atts);
      return -1;
    }
  
  if (str_buf_size >= cur_buf_size)
    {
      while(str_buf_size >= cur_buf_size)
	cur_buf_size *= 2;
      buffer = realloc(buffer, cur_buf_size);
    }
       
       ngrp_atts = HE5_EHinqglbattrs(HE5_GDfid,buffer,&str_buf_size);
  if(max_att < ngrp_atts)
    {
      fprintf(stderr, "\nfile: %s, line: %d\n", __FILE__, __LINE__);
      fprintf(stderr, "\tngrp_atts %ld is bigger than MAX_ATT: %d\n\n",
	      ngrp_atts, MAX_ATT);
      return -2;
    }
  
  buffer[str_buf_size] = '\0';
  HE5ParseName(buffer, att_hdf_names, ngrp_atts);
  
  for(k = 0; k < ngrp_atts; ++k)
    {
      /* Note: att_size should be number of elements in attribute array */
      if(HE5_EHglbattrinfo(HE5_GDfid,att_hdf_names[k],&att_type,&att_size)==0)
	{
	  if(HE5T_CHARSTRING == att_type)
	    {
	      hsize_t      size_count;
	      int count;
	      
	      fprintf(stderr, "\nAtt No. %d, name: <%s>, array_size = %ld, type = %ld\n",
		      k, att_hdf_names[k], (long)att_size, (long)att_type);
	      
	      /* Note: size should be datatype size in bytes (max number of charcters for character string arrays */
	      he5_status = HE5_EHinqglbdatatype(HE5_GDfid, att_hdf_names[k], &dtype, &classid, &order, &size);
	      fprintf(stderr, "\the5_status = %ld, dtype = %ld, classid = %ld, order = %ld, array_element_Byte_size = %ld\n",
		      (long) he5_status, (long) dtype, (long) classid, (long) order, (long) size);
	      
	      
	      /* Note: size_count should be number of elements in attribute array */
	      he5_status = HE5_EHglbattrinfo(HE5_GDfid, att_hdf_names[k], &att_type,  &size_count);
	      
	      printf("=============== size_count=%d\n",(int)size_count);
	      
	      charstrs = (char *)calloc((size_count+1) * size, sizeof(char));
	      orig_charstrs = charstrs;
	      if(HE5_EHreadglbattr(HE5_GDfid,att_hdf_names[k],(void *)charstrs) == 0)
		{
		  for(count=0; count < size_count; count++)
		    { 
		      fprintf(stderr, "\tvalue: <%s>\n", charstrs);
		      charstrs=charstrs+size;
		    }
		}
	      if(charstrs != NULL)
		{
		  free(orig_charstrs);
		  orig_charstrs = NULL;
		  charstrs = orig_charstrs;
		}
	    }
	  else
	    {
	      fprintf(stderr, "\n+++++++++++++++++++++++++++++ None-String Attribute ++++++++++++++++++++++++\n");
	      fprintf(stderr, "Att No. %d, name: <%s>, array_size = %ld, type = %ld,\n",
		      k, att_hdf_names[k], (long)att_size, (long)att_type);
	      he5_status = HE5_EHinqglbdatatype(HE5_GDfid, att_hdf_names[k], &dtype, &classid, &order, &size);
	      fprintf(stderr, "\the5_status = %ld, dtype = %ld, classid = %ld, order = %ld, array_element_Byte_size = %ld\n",
		      (long) he5_status, (long) dtype, (long) classid, (long) order, (long) size);
	      
	      /* Note: size_count should be number of elements in attribute array */
	      he5_status = HE5_EHglbattrinfo(HE5_GDfid, att_hdf_names[k], &att_type,  &size_count);
	      printf("=============== size_count=%d\n",(int)size_count);
	      if(att_type == 11 )
		{
		  drdbuffer = calloc((size_count) * size, 1);
		  orig_drdbuffer = drdbuffer;
		  statusr=(int)HE5_EHreadglbattr(HE5_GDfid,att_hdf_names[k],(void *)drdbuffer);
		}
	      else if(att_type == 10)
		{
		  frdbuffer = calloc((size_count) * size, 1);
		  orig_frdbuffer = frdbuffer;
		  statusr=(int)HE5_EHreadglbattr(HE5_GDfid,att_hdf_names[k],(void *)frdbuffer);
		}
	      else if(att_type == 7 || att_type == 6 || att_type == 3 || 
		      att_type == 2 || att_type == 1 || att_type == 0 ) // uint/int types
		{
		  irdbuffer = calloc((size_count) * size, 1);
		  orig_irdbuffer = irdbuffer;
		  statusr=(int)HE5_EHreadglbattr(HE5_GDfid,att_hdf_names[k],(void *)irdbuffer);
		}
	      else // int8/uint8 types 
		{
		  rdbuffer = calloc((size_count) * size, 1);
		  orig_rdbuffer = rdbuffer;
		  statusr=(int)HE5_EHreadglbattr(HE5_GDfid,att_hdf_names[k],(void *)rdbuffer);
		}
	      
	      if(statusr == 0)
		
		{
		  for(count=0; count < size_count; count++)
		    { 
		      if(att_type == 11) // double
			{
			  fprintf(stderr, "\tvalue: <%lf>\n", (double)*drdbuffer);
			  drdbuffer=drdbuffer+size;
			}
		      if(att_type == 10) // float
			{
			  fprintf(stderr, "\tvalue: <%f>\n", (float)*frdbuffer);
			  frdbuffer=frdbuffer+size;
			}
		      else if(att_type == 5) // unsigned int8 
			{
			  fprintf(stderr, "\tvalue: <%d>\n", (uint)*rdbuffer);
			  rdbuffer=rdbuffer+size;
			}
		      else if(att_type == 13) // int8 
			{
			  fprintf(stderr, "\tvalue: <%d>\n", (int)*rdbuffer);
			  rdbuffer=rdbuffer+size;
			}
		      else if(att_type == 6) // long 
			{
			  fprintf(stderr, "\tvalue: <%d>\n", (int)*irdbuffer);
			  irdbuffer=irdbuffer+size;
			}
		      else if(att_type == 7) // unsigned long 
			{
			  fprintf(stderr, "\tvalue: <%d>\n", (uint)*irdbuffer);
			  irdbuffer=irdbuffer+size;
			}
		      else if(att_type == 3) // unsigned int 16
			{
			  fprintf(stderr, "\tvalue: <%d>\n", (uint)*irdbuffer);
			  irdbuffer=irdbuffer+size;
			}
		      else if(att_type == 2) // int 16
			{
			  fprintf(stderr, "\tvalue: <%d>\n", (int)*irdbuffer);
			  irdbuffer=irdbuffer+size;
			}
		      else if(att_type == 1) //  unsigned int
			{
			  fprintf(stderr, "\tvalue: <%d>\n", (uint)*irdbuffer);
			  irdbuffer=irdbuffer+size;
			}
		      else if(att_type == 0) // int
			{
			  fprintf(stderr, "\tvalue: <%d>\n", (int)*irdbuffer);
			  irdbuffer=irdbuffer+size;
			}
		    }
		}
	      if(rdbuffer != NULL)
		{
		  free(orig_rdbuffer);
		  orig_rdbuffer = NULL;
		  rdbuffer = orig_rdbuffer;
		}
	      if(drdbuffer != NULL)
		{
		  free(orig_drdbuffer);
		  orig_drdbuffer = NULL;
		  drdbuffer = orig_drdbuffer;
		}
	      if(frdbuffer != NULL)
		{
		  free(orig_frdbuffer);
		  orig_frdbuffer = NULL;
		  frdbuffer = orig_frdbuffer;
		}
	      if(irdbuffer != NULL)
		{
		  free(orig_irdbuffer);
		  orig_irdbuffer = NULL;
		  irdbuffer = orig_irdbuffer;
		}
	      fprintf(stderr, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
	    }
	}
    }
  fprintf(stderr, "\n======================================================================\n");
  fprintf(stderr, "======================================================================\n");
  fprintf(stderr, "\t Done writing all attributes Totla Number ngrp_atts=%d\n", ngrp_atts);
  fprintf(stderr, "======================================================================\n");
  fprintf(stderr, "======================================================================\n");
  HE5_GDclose(HE5_GDfid);
  
  free(buffer);
  
  return 0;
}


