//---------------------------------------------------------------------------

#ifdef _win32
#pragma hdrstop
#endif

#include <stdlib.h>
#include <stdio.h>

#include "nexusbox.h"
#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

NexusBoxClass	*hdf_file;

#define SET_BINARY 0
#define SET_ASCII 1
#define SET_VERBOSE 2
#define SET_ARRAYSPREFERRED 3
#define SET_COLUMNSPREFERRED 4
#define SET_WITHINDEX 5
#define SET_PIPE 6
#define N_OPTIONS 7

char *option[N_OPTIONS] = {
    "binary", "ascii", "verbose", 
    "arrayspreferred", "columnspreferred",
    "withindex", "pipe",
};
char *USAGE = "hdf2sdds <file path> <file name> [-pipe=output] [<output name>]\n[{-binary | -ascii}]\n[{-arraysPreferred | -columnsPreferred}]\n[-withIndex] [-verbose]\n\nProgram by Robert Soliday. ("__DATE__")";

void DisplayFileContents (char *output, long filemode, long verbose, 
			  long arraysPreferred, long withIndex);

int main(int argc, char **argv) {
  long i, i_arg, filemode=1, verbose=0, arraysPreferred=0, withIndex=0;
  SCANNED_ARG *s_arg;
  char *inputDir=NULL, *inputFile=NULL, *output=NULL;
  unsigned long pipeFlags=0;
  
  SDDS_RegisterProgramName(argv[0]);
  argc = scanargs(&s_arg, argc, argv);
  if (argc<4) 
    bomb(NULL, USAGE);

  for (i_arg=1; i_arg<argc; i_arg++) {
    if (s_arg[i_arg].arg_type==OPTION) {
      delete_chars(s_arg[i_arg].list[0], "_");
      switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
      case SET_BINARY:
	filemode = SDDS_BINARY;
	break;
      case SET_ASCII:
	filemode = SDDS_ASCII;
	break;
      case SET_VERBOSE:
	verbose = 1;
	break;
      case SET_ARRAYSPREFERRED:
	arraysPreferred = 1;
	break;
      case SET_COLUMNSPREFERRED:
	arraysPreferred = 0;
	break;
      case SET_WITHINDEX:
	withIndex = 1;
	break;
      case SET_PIPE:
	if (!processPipeOption(s_arg[i_arg].list+1, s_arg[i_arg].n_items-1, &pipeFlags))
	  SDDS_Bomb("invalid -pipe syntax");
	break;
      default:
	fprintf(stderr, "Error (%s): unknown switch: %s\n", argv[0], s_arg[i_arg].list[0]);
	exit(1);
	break;
      }
    } else {
      if (inputDir==NULL)
	inputDir = s_arg[i_arg].list[0];
      else if (inputFile==NULL)
	inputFile = s_arg[i_arg].list[0];
      else if (output==NULL)
	output = s_arg[i_arg].list[0];
      else
	SDDS_Bomb("too many filenames");
    }
  }

  if (output==NULL && !(pipeFlags&USE_STDOUT))
    SDDS_Bomb("no output specified");

  hdf_file = new NexusBoxClass();
  
  hdf_file->SetReadScheme (ENTIRE_CONTENTS);
  hdf_file->ReadAll (inputDir, inputFile);
  hdf_file->ChangeFile (inputDir, inputFile);
  
  DisplayFileContents(output, filemode, verbose, 
		      arraysPreferred, withIndex);
  
  delete (hdf_file);
  
  
  return 0;
}

void DisplayFileContents (char *output, long filemode, long verbose, 
			  long arraysPreferred, long withIndex)
{
int32               num_indexes,
                    loop;
intn                rank,
                    dims[2],
                    type,
                    error_code;
char                *index;
char                *indexmod;
char                *ptr; 
int8                int8_val;
int16               int16_val;
int32               int32_val;
uint8               uint8_val;
uint16              uint16_val;
uint32              uint32_val;
float32             float32_val;
float64             float64_val;
char                char_val[256];
void		    *raw_data;
short		    *short_data;
long		    *long_data;
float		    *float_data;
double		    *double_data;
long                i, j,
                    rows=-1;
SDDS_DATASET        dataset;
int                 sddstype;
long                dimension[2];
char                stringIndex[100];

    hdf_file->GetIndexSize (&num_indexes);

    if (SDDS_InitializeOutput(&dataset,filemode,1,NULL,NULL,output) != 1) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }
    
    for (loop=0;loop<num_indexes;loop++) {
      index = hdf_file->GetIndex (loop);

      indexmod = (char*)malloc(sizeof(char*) * (strlen(index) + 1));
      sprintf(indexmod, "%s", index);
      ptr = strchr(indexmod, ';');
      while (ptr != NULL) {
        *ptr = ':';
        ptr = strchr(indexmod, ';');
      }

      error_code = hdf_file->GetDatumInfo (index, &rank, dims, &type);
      
      if (error_code == 0) {
	sddstype = -1;
	switch (type) {
	case NX_CHAR : {
	  sddstype = SDDS_STRING;
	  break;
	}
	case NX_INT8 : {
	  sddstype = SDDS_SHORT;
	  break;
	}
	case NX_UINT8 : {
	  sddstype = SDDS_SHORT;
	  break;
	}
	case NX_INT16 : {
	  sddstype = SDDS_LONG;
	  break;
	}
	case NX_UINT16 : {
	  sddstype = SDDS_LONG;
	  break;
	}
	case NX_INT32 : {
	  sddstype = SDDS_LONG;
	  break;
	}
	case NX_UINT32 : {
	  sddstype = SDDS_LONG;
	  break;
	}
	case NX_FLOAT32 : {
	  sddstype = SDDS_FLOAT;
	  break;
	}
	case NX_FLOAT64 : {
	  sddstype = SDDS_DOUBLE;
	  break;
	}
	default: {
	  break;
	}
	}
	if (sddstype != -1) {
	  if ((rank == 1) && 
	      ((dims[0] == 1) || (sddstype = SDDS_STRING))) {
	    if (SDDS_DefineParameter(&dataset, indexmod, NULL, NULL, \
				     NULL, NULL, sddstype, NULL) < 0) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if (rank == 1) {
	    if ((rows == -1) || (dims[0] == rows)) {
	      if (SDDS_DefineColumn(&dataset, indexmod, NULL, NULL, \
				    NULL, NULL, sddstype, 0) < 0) {
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		exit(1);
	      }
	      rows = dims[0];
	    } else {
	      fprintf(stderr, "warning: %s will not be added to the SDDS file.\nA different number of rows then a previous column were found\n");
	    }
	  } else if (rank < 3) {
	    if (sddstype == SDDS_STRING) {
	      if ((rows == -1) || (dims[1] == rows)) {
		if (SDDS_DefineColumn(&dataset, indexmod, NULL, NULL, \
				      NULL, NULL, sddstype, 0) < 0) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
		rows = dims[1];
	      } else {
		fprintf(stderr, "warning: %s will not be added to the SDDS file.\nA different number of rows then a previous column were found\n");
	      }
	    } else {
	      if (arraysPreferred) {
		if (SDDS_DefineArray(&dataset, indexmod, NULL, NULL, \
				     NULL, NULL, sddstype, 0, rank, NULL) < 0) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
	      } else {
		if ((rows == -1) || (dims[1] == rows)) {
		  for (i=1;i<=dims[0];i++) {
		    sprintf(stringIndex, "%s%ld", indexmod, i);
		    if (SDDS_DefineColumn(&dataset, stringIndex, NULL, NULL, \
					  NULL, NULL, sddstype, 0) < 0) {
		      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		      exit(1);
		    }    
		  }
		  rows = dims[1];
		} else {
		  fprintf(stderr, "warning: %s will not be added to the SDDS file.\nA different number of rows then a previous column were found\n");
		}
	      }
	    }
	  } else {
	    fprintf(stderr, "warning: %s will not be added to the SDDS file\n");
	  }
	}
      }
      free(indexmod);
    }

    if (withIndex) {
      if (SDDS_DefineColumn(&dataset, "Index", NULL, NULL, \
			    NULL, NULL, SDDS_LONG, 0) < 0) {
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	exit(1);
      }
    }

    if (SDDS_WriteLayout(&dataset) != 1) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }
    if (SDDS_StartPage(&dataset, 1000) != 1) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }
    if (verbose)
      printf("Converting\n");
    for (loop=0;loop<num_indexes;loop++) {
      
      index = hdf_file->GetIndex (loop);

      indexmod = (char*)malloc(sizeof(char*) * (strlen(index) + 1));
      sprintf(indexmod, "%s", index);
      ptr = strchr(indexmod, ';');
      while (ptr != NULL) {
        *ptr = ':';
        ptr = strchr(indexmod, ';');
      }

      error_code = hdf_file->GetDatumInfo (index, &rank, dims, &type);
      dimension[0] = dims[0];
      dimension[1] = dims[1];

      if (error_code == 0) {
	if (verbose)
	  printf ("%s\n", index);
	switch (type) {
	case NX_CHAR : {
	  if (rank == 1) {
	    hdf_file->GetDatum (index, (void *) char_val);
	    if (SDDS_SetParameters(&dataset, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,\
				   indexmod,char_val,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if ((rank < 3) && (rows == dims[1])) {
	    raw_data = malloc (dims[0]*dims[1]*sizeof(char));
	    if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,raw_data,\
			       dims[1],indexmod,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  }
	  break;
	}
	
	case NX_INT8 : {
	  if ((rank == 1) && (dims[0] == 1)) {
	    hdf_file->GetDatum (index, &int8_val);
	    if (SDDS_SetParameters(&dataset, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,\
				   indexmod,int8_val,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if ((rank == 1) && (rows == dims[0])) {
	    raw_data = malloc (dims[0]*sizeof(int8));
	    short_data = (short*)malloc (dims[0]*sizeof(short));
	    hdf_file->GetDatum (index, raw_data);
	    for (i=0; i < dims[0]; i++) {
	      short_data[i] = *(((int8*)raw_data)+i);
	    }
	    if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,short_data,\
			       dims[0],indexmod,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	    free(raw_data);
	    free(short_data);
	  } else if (rank < 3) {
	    raw_data = malloc (dims[0]*dims[1]*sizeof(int8));
	    hdf_file->GetDatum (index, raw_data);
	    if (arraysPreferred) {
	      short_data = (short*)malloc (dims[0]*dims[1]*sizeof(short));
	      for (i=0; i < dims[0]*dims[1]; i++) {
		short_data[i] = *(((int8*)raw_data)+i);
	      }
	      if (SDDS_SetArray(&dataset,indexmod,SDDS_CONTIGUOUS_DATA,short_data,dimension) != 1) {
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		exit(1);
	      }
	    } else if (dims[1] == rows) {
	      short_data = (short*)malloc (dims[1]*sizeof(short));
	      for (j=0; j < dims[0]; j++) {
		for (i=0; i < dims[1]; i++) {
		  short_data[i] = *(((int8*)raw_data)+(i+j*dims[1]));
		}
		sprintf(stringIndex, "%s%ld", indexmod, j+1);
		if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,short_data,dims[1],stringIndex,NULL) != 1) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
	      }
	    }
	    free(raw_data);
	    free(short_data);
	  }
	  break;
	}

	case NX_UINT8 : {
	  if ((rank == 1) && (dims[0] == 1)) {
	    hdf_file->GetDatum (index, &uint8_val);
	    if (SDDS_SetParameters(&dataset, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,\
				   indexmod,uint8_val,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if ((rank == 1) && (rows == dims[0])) {
	    raw_data = malloc (dims[0]*sizeof(uint8));
	    short_data = (short*)malloc (dims[0]*sizeof(short));
	    hdf_file->GetDatum (index, raw_data);
	    for (i=0; i < dims[0]; i++) {
	      short_data[i] = *(((uint8*)raw_data)+i);
	    }
	    if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,short_data,\
			       dims[0],indexmod,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	    free(raw_data);
	    free(short_data);
	  } else if (rank < 3) {
	    raw_data = malloc (dims[0]*dims[1]*sizeof(uint8));
	    hdf_file->GetDatum (index, raw_data);
	    if (arraysPreferred) {
	      short_data = (short*)malloc (dims[0]*dims[1]*sizeof(short));
	      for (i=0; i < dims[0]*dims[1]; i++) {
		short_data[i] = *(((uint8*)raw_data)+i);
	      }
	      if (SDDS_SetArray(&dataset,indexmod,SDDS_CONTIGUOUS_DATA,short_data,dimension) != 1) {
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		exit(1);
	      }
	    } else if (dims[1] == rows) {
	      short_data = (short*)malloc (dims[1]*sizeof(short));
	      for (j=0; j < dims[0]; j++) {
		for (i=0; i < dims[1]; i++) {
		  short_data[i] = *(((uint8*)raw_data)+(i+j*dims[1]));
		}
		sprintf(stringIndex, "%s%ld", indexmod, j+1);
		if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,short_data,dims[1],stringIndex,NULL) != 1) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
	      }
	    }
	    free(raw_data);
	    free(short_data);
	  }
	  break;
	}

	case NX_INT16 : {
	  if ((rank == 1) && (dims[0] == 1)) {
	    hdf_file->GetDatum (index, &int16_val);
	    if (SDDS_SetParameters(&dataset, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,\
				   indexmod,int16_val,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if ((rank == 1) && (rows == dims[0])) {
	    raw_data = malloc (dims[0]*sizeof(int16));
	    long_data = (long*)malloc (dims[0]*sizeof(long));
	    hdf_file->GetDatum (index, raw_data);
	    for (i=0; i < dims[0]; i++) {
	      long_data[i] = *(((int16*)raw_data)+i);
	    }
	    if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,long_data,\
			       dims[0],indexmod,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	    free(raw_data);
	    free(long_data);
	  } else if (rank < 3) {
	    raw_data = malloc (dims[0]*dims[1]*sizeof(int16));
	    hdf_file->GetDatum (index, raw_data);
	    if (arraysPreferred) {
	      long_data = (long*)malloc (dims[0]*dims[1]*sizeof(long));
	      for (i=0; i < dims[0]*dims[1]; i++) {
		long_data[i] = *(((int16*)raw_data)+i);
	      }
	      if (SDDS_SetArray(&dataset,indexmod,SDDS_CONTIGUOUS_DATA,long_data,dimension) != 1) {
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		exit(1);
	      }
	    } else if (dims[1] == rows) {
	      long_data = (long*)malloc (dims[1]*sizeof(long));
	      for (j=0; j < dims[0]; j++) {
		for (i=0; i < dims[1]; i++) {
		  long_data[i] = *(((int16*)raw_data)+(i+j*dims[1]));
		}
		sprintf(stringIndex, "%s%ld", indexmod, j+1);
		if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,long_data,dims[1],stringIndex,NULL) != 1) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
	      }
	    }
	    free(raw_data);
	    free(long_data);
	  }
	  break;
	}

	case NX_UINT16 : {
	  if ((rank == 1) && (dims[0] == 1)) {
	    hdf_file->GetDatum (index, &uint16_val);
	    if (SDDS_SetParameters(&dataset, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,\
				   indexmod,uint16_val,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if ((rank == 1) && (rows == dims[0])) {
	    raw_data = malloc (dims[0]*sizeof(uint16));
	    long_data = (long*)malloc (dims[0]*sizeof(long));
	    hdf_file->GetDatum (index, raw_data);
	    for (i=0; i < dims[0]; i++) {
	      long_data[i] = *(((uint16*)raw_data)+i);
	    }
	    if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,long_data,\
			       dims[0],indexmod,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	    free(raw_data);
	    free(long_data);
	  } else if (rank < 3) {
	    raw_data = malloc (dims[0]*dims[1]*sizeof(uint16));
	    hdf_file->GetDatum (index, raw_data);
	    if (arraysPreferred) {
	      long_data = (long*)malloc (dims[0]*dims[1]*sizeof(long));
	      for (i=0; i < dims[0]*dims[1]; i++) {
		long_data[i] = *(((uint16*)raw_data)+i);
	      }
	      if (SDDS_SetArray(&dataset,indexmod,SDDS_CONTIGUOUS_DATA,long_data,dimension) != 1) {
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		exit(1);
	      }
	    } else if (dims[1] == rows) {
	      long_data = (long*)malloc (dims[1]*sizeof(long));
	      for (j=0; j < dims[0]; j++) {
		for (i=0; i < dims[1]; i++) {
		  long_data[i] = *(((uint16*)raw_data)+(i+j*dims[1]));
		}
		sprintf(stringIndex, "%s%ld", indexmod, j+1);
		if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,long_data,dims[1],stringIndex,NULL) != 1) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
	      }
	    }
	    free(raw_data);
	    free(long_data);
	  }
	  break;
	}

	case NX_INT32 : {
	  if ((rank == 1) && (dims[0] == 1)) {
	    hdf_file->GetDatum (index, &int32_val);
	    if (SDDS_SetParameters(&dataset, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,\
				   indexmod,int32_val,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if ((rank == 1) && (rows == dims[0])) {
	    raw_data = malloc (dims[0]*sizeof(int32));
	    long_data = (long*)malloc (dims[0]*sizeof(long));
	    hdf_file->GetDatum (index, raw_data);
	    for (i=0; i < dims[0]; i++) {
	      long_data[i] = *(((int32*)raw_data)+i);
	    }
	    if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,long_data,\
			       dims[0],indexmod,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	    free(raw_data);
	    free(long_data);
	  } else if (rank < 3) {
	    raw_data = malloc (dims[0]*dims[1]*sizeof(int32));
	    hdf_file->GetDatum (index, raw_data);
	    if (arraysPreferred) {
	      long_data = (long*)malloc (dims[0]*dims[1]*sizeof(long));
	      for (i=0; i < dims[0]*dims[1]; i++) {
		long_data[i] = *(((int32*)raw_data)+i);
	      }
	      if (SDDS_SetArray(&dataset,indexmod,SDDS_CONTIGUOUS_DATA,long_data,dimension) != 1) {
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		exit(1);
	      }
	    } else if (dims[1] == rows) {
	      long_data = (long*)malloc (dims[1]*sizeof(long));
	      for (j=0; j < dims[0]; j++) {
		for (i=0; i < dims[1]; i++) {
		  long_data[i] = *(((int32*)raw_data)+(i+j*dims[1]));
		}
		sprintf(stringIndex, "%s%ld", indexmod, j+1);
		if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,long_data,dims[1],stringIndex,NULL) != 1) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
	      }
	    }
	    free(raw_data);
	    free(long_data);
	  }
	  break;
	}

	case NX_UINT32 : {
	  if ((rank == 1) && (dims[0] == 1)) {
	    hdf_file->GetDatum (index, &uint32_val);
	    if (SDDS_SetParameters(&dataset, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,\
				   indexmod,uint32_val,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if ((rank == 1) && (rows == dims[0])) {
	    raw_data = malloc (dims[0]*sizeof(uint32));
	    long_data = (long*)malloc (dims[0]*sizeof(long));
	    hdf_file->GetDatum (index, raw_data);
	    for (i=0; i < dims[0]; i++) {
	      long_data[i] = *(((uint32*)raw_data)+i);
	    }
	    if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,long_data,\
			       dims[0],indexmod,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	    free(raw_data);
	    free(long_data);
	  } else if (rank < 3) {
	    raw_data = malloc (dims[0]*dims[1]*sizeof(uint32));
	    hdf_file->GetDatum (index, raw_data);
	    if (arraysPreferred) {
	      long_data = (long*)malloc (dims[0]*dims[1]*sizeof(long));
	      for (i=0; i < dims[0]*dims[1]; i++) {
		long_data[i] = *(((uint32*)raw_data)+i);
	      }
	      if (SDDS_SetArray(&dataset,indexmod,SDDS_CONTIGUOUS_DATA,long_data,dimension) != 1) {
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		exit(1);
	      }
	    } else if (dims[1] == rows) {
	      long_data = (long*)malloc (dims[1]*sizeof(long));
	      for (j=0; j < dims[0]; j++) {
		for (i=0; i < dims[1]; i++) {
		  long_data[i] = *(((uint32*)raw_data)+(i+j*dims[1]));
		}
		sprintf(stringIndex, "%s%ld", indexmod, j+1);
		if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,long_data,dims[1],stringIndex,NULL) != 1) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
	      }
	    }
	    free(raw_data);
	    free(long_data);
	  }
	  break;
	}

	case NX_FLOAT32 : {
	  if ((rank == 1) && (dims[0] == 1)) {
	    hdf_file->GetDatum (index, &float32_val);
	    if (SDDS_SetParameters(&dataset, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,\
				   indexmod,float32_val,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if ((rank == 1) && (rows == dims[0])) {
	    raw_data = malloc (dims[0]*sizeof(float32));
	    float_data = (float*)malloc (dims[0]*sizeof(float));
	    hdf_file->GetDatum (index, raw_data);
	    for (i=0; i < dims[0]; i++) {
	      float_data[i] = *(((float32*)raw_data)+i);
	    }
	    if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,float_data,\
			       dims[0],indexmod,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	    free(raw_data);
	    free(float_data);
	  } else if (rank < 3) {
	    raw_data = malloc (dims[0]*dims[1]*sizeof(float32));
	    hdf_file->GetDatum (index, raw_data);
	    if (arraysPreferred) {
	      float_data = (float*)malloc (dims[0]*dims[1]*sizeof(float));
	      for (i=0; i < dims[0]*dims[1]; i++) {
		float_data[i] = *(((float32*)raw_data)+i);
	      }
	      if (SDDS_SetArray(&dataset,indexmod,SDDS_CONTIGUOUS_DATA,float_data,dimension) != 1) {
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		exit(1);
	      }
	    } else if (dims[1] == rows) {
	      float_data = (float*)malloc (dims[1]*sizeof(float));
	      for (j=0; j < dims[0]; j++) {
		for (i=0; i < dims[1]; i++) {
		  float_data[i] = *(((float32*)raw_data)+(i+j*dims[1]));
		}
		sprintf(stringIndex, "%s%ld", indexmod, j+1);
		if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,float_data,dims[1],stringIndex,NULL) != 1) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
	      }
	    }
	    free(raw_data);
	    free(float_data);
	  }
	  break;
	}
	
	case NX_FLOAT64 : {
	  if ((rank == 1) && (dims[0] == 1)) {
	    hdf_file->GetDatum (index, &float64_val);
	    if (SDDS_SetParameters(&dataset, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,\
				   indexmod,float64_val,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	  } else if ((rank == 1) && (rows == dims[0])) {
	    raw_data = malloc (dims[0]*sizeof(float64));
	    double_data = (double*)malloc (dims[0]*sizeof(double));
	    hdf_file->GetDatum (index, raw_data);
	    for (i=0; i < dims[0]; i++) {
	      double_data[i] = *(((float64*)raw_data)+i);
	    }
	    if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,double_data,\
			       dims[0],indexmod,NULL) != 1) {
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	      exit(1);
	    }
	    free(raw_data);
	    free(double_data);
	  } else if (rank < 3) {
	    raw_data = malloc (dims[0]*dims[1]*sizeof(float64));
	    hdf_file->GetDatum (index, raw_data);
	    if (arraysPreferred) {
	      double_data = (double*)malloc (dims[0]*dims[1]*sizeof(double));
	      for (i=0; i < dims[0]*dims[1]; i++) {
		double_data[i] = *(((float64*)raw_data)+i);
	      }
	      if (SDDS_SetArray(&dataset,indexmod,SDDS_CONTIGUOUS_DATA,double_data,dimension) != 1) {
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		exit(1);
	      }
	    } else if (dims[1] == rows) {
	      double_data = (double*)malloc (dims[1]*sizeof(double));
	      for (j=0; j < dims[0]; j++) {
		for (i=0; i < dims[1]; i++) {
		  double_data[i] = *(((float64*)raw_data)+(i+j*dims[1]));
		}
		sprintf(stringIndex, "%s%ld", indexmod, j+1);
		if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,double_data,dims[1],stringIndex,NULL) != 1) {
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
		  exit(1);
		}
	      }
	    }
	    free(raw_data);
	    free(double_data);
	  }
	  break;
	}
	default :
	  break;
	}
      }
      free(indexmod);
    }

    if ((withIndex) && (rows != -1)) {
      long_data = (long*)malloc (rows*sizeof(long));
      for (i=0; i < rows; i++) {
	long_data[i] = i;
      }
      if (SDDS_SetColumn(&dataset,SDDS_SET_BY_NAME,long_data,\
			 rows,"Index",NULL) != 1) {
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
	exit(1);
      }
      free(long_data);
    }

    if (SDDS_WritePage(&dataset) != 1) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }
    if (SDDS_Terminate(&dataset) != 1) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }


}

