[8733b5]: hdf5.pd Maximize Restore History

Download this file

hdf5.pd    1663 lines (1496 with data), 36.1 kB

use Config;





# Necessary includes for .xs file
pp_addhdr(<<'EOH');
#include <hdf5.h>
#define PDLchar pdl
#define PDLuchar pdl
#define PDLshort pdl
#define PDLint pdl
#define PDLlong pdl
#define PDLfloat pdl
#define PDLdouble pdl
#define uchar unsigned char
EOH

pp_bless ("PDL::HDF5");

$VERSION = '0.01';

                     
pp_addpm(<<'EOPM');

=head1 NAME

PDL::HDF5 - PDL Interface to the HDF5 Data Format.


=head1 DESCRIPTION

This package provides an object-oriented interface for L<PDL>s to
the HDF5 data-format. Information on the HDF5 Format can be found
at the NCSA's web site at http://hdf.ncsa.uiuc.edu/ .

Limitations: Currently this interface only provides a subset of the total HDF5 
capability. 

=head1 SYNOPSIS

	use PDL::HDF5;
	
	# Files
	my $newfile = new PDL::HDF5("newfile.hdf"); # create new hdf5 file
	my $attrValue = $existingFile->attrGet('AttrName'); # Get attribute value for file
	$existingFile->attSet('AttrName' => 'AttrValue');   # Set attribute value for file

	#Groups
	my $group = $newfile->group("/mygroup"); # create a new or open existing group
	my @groups = $existingFile->groups;  # get a list of all the groups

	my $attrValue = $group->attrGet('AttrName');  # Get attribute value for a group
	$group->attrSet('AttrName' => 'AttrValue');   # Set attribute value for a group
	$group->attrDel('AttrName1', 'AttrName2');    # Delete attribute(s) for a group
	@attrs = $group->attrs;                       # Get List of attributes for a group

	# Data Sets
	my $dataset = $group->dataset( 'datasetName'); # create a new or open existing dataset
	my @datasets =  $group->datasets;              # get a list of all datasets in a group
	$pdl = $dataset->get();                    # Get the array data in the dataset
	$dataset->set($pdl);                       # Set the array data in the dataset
	my $attrValue = $dataset->attrGet('AttrName'); # Get attribute value for a dataset
	$dataset->attSet('AttrName' => 'AttrValue');     # Set attribute value(s) for a dataset

=head1 MEMBER DATA

=over 1

=item fileID

ID number given to the file by the HDF5 library

=item filename

Name of the file.

=item accessMode

Access Mode?? ( read /write etc????)

=back

=head1 METHODS

=head2 new

=for ref

PDL::HDF5 constructor - creates PDL::HDF5 object for reading or 
writing data.

B<Usage:>

=for usage

   $a = new PDL::HDF5( $filename );
   
Arguments:  
1) The name of the file.

If this file exists and you want to write to it, 
prepend the name with the '>' character:  ">name.nc"

Returns undef on failure.

B<Example:>
     
=for example

	$hdf5obj = new PDL::HDF5( "file.hdf" );
        
=cut


sub new {
  my $type = shift;
  my $file = shift;

  my $self = {};
  my $rc;
  my $write;

  if (substr($file, 0, 1) eq '>') { # open for writing
    $file = substr ($file, 1);      # chop off >
    $write = 1;
  }
  
  my $fileID; # HDF file id
    
  if (-e $file) {    # Existing File

    if ($write) {

      $fileID = H5Fopen($file, H5F_ACC_RDWR(), H5P_DEFAULT());        
      if( $fileID < 0){  
	carp("Can't Open Existing HDF file '$file' for writing\n");
        return undef;
      }
 
      $self->{accessMode} = 'w';

    } else { # Open read-only
                      
      $fileID = H5Fopen($file, H5F_ACC_RDONLY(), H5P_DEFAULT());        
      
      if( $fileID < 0){  
	carp("Can't Open Existing HDF file '$file' for reading\n");
        return undef;
      }
      
      $self->{accessMode} = 'r';


    }
  }
  else{  # File doesn't exist, create it:
   
      $fileID = H5Fcreate($file, H5F_ACC_TRUNC(), H5P_DEFAULT(), H5P_DEFAULT());        
      if( $fileID < 0){  
	carp("Can't Open New HDF file '$file' for writing\n");
        return undef;
      }
      
            
      $self->{accessMode} = 'w';
  }
  
  # Record file name, ID
  $self->{filename} = $file;
  $self->{fileID} = $fileID;

  bless $self, $type;
}

=head2 DESTROY

=for ref

PDL::HDF5 Desctructor - Closes the HDF5 file

B<Usage:>

=for usage

   No Usage. Automatically called
   
    
=cut


sub DESTROY {
  my $self = shift;

  if( H5Fclose($self->{fileID}) < 0){
	warn("Error closing HDF5 file ".$self->{filename}."\n");
  }

}

EOPM




# Read in a modified hdf.h file.  Define
# a low-level perl interface to hdf from these definitions.
sub create_low_level {

# This file must be modified to only include 
# hdf5 3 function definitions.
# Also, all C function declarations must be on one line.
  my $defn = shift;
  my @lines = split (/\n/, $defn);

  foreach (@lines) {

    next if (/^\#/);  # Skip commented out lines
    next if (/^\s*$/); # Skip blank lines

    my ($return_type, $func_name, $parms) = /^(\w+\**)\s+(\w+)\s*\((.*?)\)\;/;
    my @parms = split (/,/, $parms);

    my @vars  = ();
    my @types = ();
    my %output = ();
    foreach $parm (@parms) {

      my ($varname) = ($parm =~ /(\w+)$/);
      $parm =~ s/$varname$//; # parm now contains the full C type
      $output{$varname} = 1 if (($parm =~ /\*/) && ($parm !~ /const/));
      $parm =~ s/const //;  # get rid of 'const' in C type
      $parm =~ s/^\s+//;
      $parm =~ s/\s+$//;    # pare off the variable type from 'parm'
      
      push (@vars, $varname);
      push (@types, $parm);

    }

    my $xsout = '';
    $xsout .= "$return_type\n";
    $xsout .= "$func_name (" . join (", ", @vars) . ")\n";
    for (my $i=0;$i<@vars;$i++) {
      $xsout .= "\t$types[$i]\t$vars[$i]\n";
    }
    
    $xsout .= "CODE:\n";
    $xsout .= "\tRETVAL = $func_name (";
    for (my $i=0;$i<@vars;$i++) {
      if ($types[$i] =~ /PDL/) {
	($type = $types[$i]) =~ s/PDL//; # Get rid of PDL type when writine xs CODE section
	$xsout .= "($type)$vars[$i]"."->data,";
      } else {
	$xsout .= "$vars[$i],";
      }
    }
    chop ($xsout) if( $xsout =~ /\,$/s);  # remove last comma, if present
    $xsout .= ");\n";
    $xsout .= "OUTPUT:\n";
    $xsout .= "\tRETVAL\n";
    foreach $var (keys %output) {
      $xsout .= "\t$var\n";
    }
    $xsout .= "\n\n";

    pp_addxs ('', $xsout);

  }

}


#-------------------------------------------------------------------------
# Create low level interface from edited hdr5 header file.
#-------------------------------------------------------------------------

create_low_level (<<'EODEF');
# HDF5 Functions we create an interface to using the perl XS code
#
# Note: H5Gget_objinfo arg statbuf has been changed from a H5G_stat_t type to 
# a const void type to avoid compilation errors. This function only used
# to determine if a group exists, so the statbuf variable is not used as 
# I/O variable as stated in the HDF5 docs.

hid_t H5Fcreate (const char *name, unsigned flags, hid_t create_id, hid_t access_id); 
hid_t H5Fopen (const char *name, unsigned flags, hid_t access_id); 
herr_t H5Fclose (hid_t file_id); 
hid_t H5Screate_simple (int rank, const hsize_t * dims,  const hsize_t * maxdims);
herr_t H5Sclose(hid_t space_id); 
hid_t H5Dcreate (hid_t loc_id, const char *name, hid_t type_id,  hid_t space_id, hid_t create_plist_id); 
hid_t H5Dopen (hid_t loc_id, const char *name);
herr_t H5Dwrite (hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, const void * buf);
herr_t H5Dread (hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, void * buf);
hid_t H5Dclose (hid_t dataset_id);
hid_t H5Gcreate(hid_t loc_id, const char *name, size_t size_hint);
hid_t H5Gopen(hid_t loc_id, const char *name);
herr_t H5Gclose(hid_t group_id);
herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, const void *statbuf);
herr_t H5errorOn();
herr_t H5errorOff();
#
# Attribute Functions
hid_t H5Aopen_name(hid_t loc_id, const char *name);
hid_t H5Acreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t create_plist);
# Note: attrib write only supports char buffer right now
herr_t H5Awrite (hid_t attr_id, hid_t mem_type_id, char * buf);
herr_t H5Adelete(hid_t loc_id, const char * name);
herr_t H5Aclose(hid_t attr_id);
int H5Aget_num_attrs(hid_t loc_id);
hid_t H5Aopen_idx(hid_t loc_id, unsigned int idx);
ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf);

# Type Functions:
herr_t H5Tset_size(hid_t type_id, size_t size);
herr_t H5Tclose(hid_t type_id);
hid_t H5Tcopy(hid_t type_id);

EODEF


# Add Optional HDF Constants to export list.

pp_add_exported('', <<'EOPM');
	H5F_ACC_DEBUG
	H5F_ACC_EXCL
	H5F_ACC_RDONLY
	H5F_ACC_RDWR
	H5F_ACC_TRUNC
	H5P_DEFAULT
	H5S_ALL
	H5S_UNLIMITED
	H5T_ALPHA_B16
	H5T_ALPHA_B32
	H5T_ALPHA_B64
	H5T_ALPHA_B8
	H5T_ALPHA_F32
	H5T_ALPHA_F64
	H5T_ALPHA_I16
	H5T_ALPHA_I32
	H5T_ALPHA_I64
	H5T_ALPHA_I8
	H5T_ALPHA_U16
	H5T_ALPHA_U32
	H5T_ALPHA_U64
	H5T_ALPHA_U8
	H5T_C_S1
	H5T_FORTRAN_S1
	H5T_IEEE_F32BE
	H5T_IEEE_F32LE
	H5T_IEEE_F64BE
	H5T_IEEE_F64LE
	H5T_INTEL_B16
	H5T_INTEL_B32
	H5T_INTEL_B64
	H5T_INTEL_B8
	H5T_INTEL_F32
	H5T_INTEL_F64
	H5T_INTEL_I16
	H5T_INTEL_I32
	H5T_INTEL_I64
	H5T_INTEL_I8
	H5T_INTEL_U16
	H5T_INTEL_U32
	H5T_INTEL_U64
	H5T_INTEL_U8
	H5T_MIPS_B16
	H5T_MIPS_B32
	H5T_MIPS_B64
	H5T_MIPS_B8
	H5T_MIPS_F32
	H5T_MIPS_F64
	H5T_MIPS_I16
	H5T_MIPS_I32
	H5T_MIPS_I64
	H5T_MIPS_I8
	H5T_MIPS_U16
	H5T_MIPS_U32
	H5T_MIPS_U64
	H5T_MIPS_U8
	H5T_NATIVE_B16
	H5T_NATIVE_B32
	H5T_NATIVE_B64
	H5T_NATIVE_B8
	H5T_NATIVE_CHAR
	H5T_NATIVE_DOUBLE
	H5T_NATIVE_FLOAT
	H5T_NATIVE_HBOOL
	H5T_NATIVE_HERR
	H5T_NATIVE_HSIZE
	H5T_NATIVE_HSSIZE
	H5T_NATIVE_INT
	H5T_NATIVE_INT16
	H5T_NATIVE_INT32
	H5T_NATIVE_INT64
	H5T_NATIVE_INT8
	H5T_NATIVE_INT_FAST16
	H5T_NATIVE_INT_FAST32
	H5T_NATIVE_INT_FAST64
	H5T_NATIVE_INT_FAST8
	H5T_NATIVE_INT_LEAST16
	H5T_NATIVE_INT_LEAST32
	H5T_NATIVE_INT_LEAST64
	H5T_NATIVE_INT_LEAST8
	H5T_NATIVE_LDOUBLE
	H5T_NATIVE_LLONG
	H5T_NATIVE_LONG
	H5T_NATIVE_OPAQUE
	H5T_NATIVE_SCHAR
	H5T_NATIVE_SHORT
	H5T_NATIVE_UCHAR
	H5T_NATIVE_UINT
	H5T_NATIVE_UINT16
	H5T_NATIVE_UINT32
	H5T_NATIVE_UINT64
	H5T_NATIVE_UINT8
	H5T_NATIVE_UINT_FAST16
	H5T_NATIVE_UINT_FAST32
	H5T_NATIVE_UINT_FAST64
	H5T_NATIVE_UINT_FAST8
	H5T_NATIVE_UINT_LEAST16
	H5T_NATIVE_UINT_LEAST32
	H5T_NATIVE_UINT_LEAST64
	H5T_NATIVE_UINT_LEAST8
	H5T_NATIVE_ULLONG
	H5T_NATIVE_ULONG
	H5T_NATIVE_USHORT
	H5T_STD_B16BE
	H5T_STD_B16LE
	H5T_STD_B32BE
	H5T_STD_B32LE
	H5T_STD_B64BE
	H5T_STD_B64LE
	H5T_STD_B8BE
	H5T_STD_B8LE
	H5T_STD_I16BE
	H5T_STD_I16LE
	H5T_STD_I32BE
	H5T_STD_I32LE
	H5T_STD_I64BE
	H5T_STD_I64LE
	H5T_STD_I8BE
	H5T_STD_I8LE
	H5T_STD_REF_DSETREG
	H5T_STD_REF_OBJ
	H5T_STD_U16BE
	H5T_STD_U16LE
	H5T_STD_U32BE
	H5T_STD_U32LE
	H5T_STD_U64BE
	H5T_STD_U64LE
	H5T_STD_U8BE
	H5T_STD_U8LE
	H5T_UNIX_D32BE
	H5T_UNIX_D32LE
	H5T_UNIX_D64BE
	H5T_UNIX_D64LE
EOPM

###############################################################
# XS Code that implements self-contained turn-on/off for
#  the h5 library error reporting. We can turn error reporting
#  selectively on and off to keep the library from complaining
#  when we are doing things like checking to see if a particular
#  group name exists.

pp_addhdr(<<'EOXS');

/* ############################################################### 
#
#  H5 Library error reporting turn-on/off functions
#
#
*/ 
herr_t
H5errorOff()
{
	return H5Eset_auto(NULL, NULL );
}

herr_t
H5errorOn()
{
	return H5Eset_auto((herr_t(*)(void*))H5Eprint, stderr );
}

/* ############################################################### 
#
#  Operator Interation Functions (Supplied to and called by 'H5Giterate') 
#  used to get the number of datasets in a group, 
#   and the names of the dataset in the group.

#
#
*/
/*
 * Operator function to get number of datasets
 */
herr_t incIfDset(hid_t loc_id, const char *name, void *opdata)
{
    H5G_stat_t statbuf;
    unsigned int * dsetCount;

    dsetCount = (unsigned int *) opdata; 
    /*
     * Get type of the object and increment *dsetCount
     *  if it is a dataset
     * The name of the object is passed to this function by 
     * the Library. Some magic :-)
     */
    H5Gget_objinfo(loc_id, name, FALSE, &statbuf);
    if( statbuf.type == H5G_DATASET){
          (*dsetCount)++;
    }       
    return 0;
 }

/*
 * Operator function to fill up char array of dataset names
 *
 *  opdata is a pointer to an Array of strings (i.e. 2D char array)
 */
herr_t getName_if_Dset(hid_t loc_id, const char *name, void *opdata)
{
    H5G_stat_t statbuf;
    char ** datasetName;
  
    char *** tempptr;
    tempptr = (char ***) opdata;

    datasetName =  *tempptr; 
    /*
     * Get type of the object.
     *  If it is a dataset, get allocate space for it at *datasetName
     *  Increment *tempptr so we will be looking at the next name space when
     *  this function is called again.
     *
     *  Note: The calling function must take care of freeing memory allocateed
     *        
     */
    H5Gget_objinfo(loc_id, name, FALSE, &statbuf);
    if( statbuf.type == H5G_DATASET){
          
         *datasetName = (char *) malloc( (strlen(name)+1) * sizeof(char));
         if( *datasetName == NULL){
            printf("PDL::HDF5; Out of Memory in getName_if_Dset\n");
            exit(1);
         }

         strcpy(*datasetName,name);
         (*tempptr)++;
     }
    return 0;
 } 
 

/*
 * Operator function to get number of groups in a particular location
 */
herr_t incIfGroup(hid_t loc_id, const char *name, void *opdata)
{
    H5G_stat_t statbuf;
    unsigned int * groupCount;

    groupCount = (unsigned int *) opdata; 
    /*
     * Get type of the object and increment *groupCount
     *  if it is a group
     * The name of the object is passed to this function by 
     * the Library. Some magic :-)
     */
    H5Gget_objinfo(loc_id, name, FALSE, &statbuf);
    if( statbuf.type == H5G_GROUP){
          (*groupCount)++;
    }       
    return 0;
 }

/*
 * Operator function to fill up char array of group names
 *
 *  opdata is a pointer to an Array of strings (i.e. 2D char array)
 */
herr_t getName_if_Group(hid_t loc_id, const char *name, void *opdata)
{
    H5G_stat_t statbuf;
    char ** groupName;
  
    char *** tempptr;
    tempptr = (char ***) opdata;

    groupName =  *tempptr; 
    /*
     * Get type of the object.
     *  If it is a group, get allocate space for it at *groupName
     *  Increment *tempptr so we will be looking at the next name space when
     *  this function is called again.
     *
     *  Note: The calling function must take care of freeing memory allocateed
     *        
     */
    H5Gget_objinfo(loc_id, name, FALSE, &statbuf);
    if( statbuf.type == H5G_GROUP){
          
         *groupName = (char *) malloc( (strlen(name)+1) * sizeof(char));
         if( *groupName == NULL){
            printf("PDL::HDF5; Out of Memory in getName_if_Group\n");
            exit(1);
         }

         strcpy(*groupName,name);
         (*tempptr)++;
     }
    return 0;
 } 
EOXS
###############################################################
# XS Code that implements the HDF constants 
#  Using the AUTOLOAD routine, any calls to hdf5 constants, like 
#  H5F_ACC_RDONLY will call the 'constant' routine here and return
#   the value of the #defined'ed H5F_ACC_RDONLY

pp_addhdr(<<'EOXS');

/* ############################################################### 
#
#  Functions to handle interfacing HDF5 constants with perl
#
#   This originally generated using h2xs and manually editing
#
*/ 
static int
not_here(s)
char *s;
{
    croak("%s not implemented on this architecture", s);
    return -1;
}

double 
constant(name, arg)
char *name;
int arg;
{
    errno = 0;
    switch (*name) {
    case 'A':
	break;
    case 'B':
	break;
    case 'C':
	break;
    case 'D':
	break;
    case 'E':
	break;
    case 'F':
	break;
    case 'G':
	break;
    case 'H':
	if (strEQ(name, "H5F_ACC_DEBUG"))
#ifdef H5F_ACC_DEBUG
	    return H5F_ACC_DEBUG;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5F_ACC_EXCL"))
#ifdef H5F_ACC_EXCL
	    return H5F_ACC_EXCL;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5F_ACC_RDONLY"))
#ifdef H5F_ACC_RDONLY
	    return H5F_ACC_RDONLY;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5F_ACC_RDWR"))
#ifdef H5F_ACC_RDWR
	    return H5F_ACC_RDWR;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5F_ACC_TRUNC"))
#ifdef H5F_ACC_TRUNC
	    return H5F_ACC_TRUNC;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5P_DEFAULT"))
#ifdef H5P_DEFAULT
	    return H5P_DEFAULT;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5S_ALL"))
#ifdef H5S_ALL
	    return H5S_ALL;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5S_UNLIMITED"))
#ifdef H5S_UNLIMITED
	    return H5S_UNLIMITED;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_B16"))
#ifdef H5T_ALPHA_B16
	    return H5T_ALPHA_B16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_B32"))
#ifdef H5T_ALPHA_B32
	    return H5T_ALPHA_B32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_B64"))
#ifdef H5T_ALPHA_B64
	    return H5T_ALPHA_B64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_B8"))
#ifdef H5T_ALPHA_B8
	    return H5T_ALPHA_B8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_F32"))
#ifdef H5T_ALPHA_F32
	    return H5T_ALPHA_F32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_F64"))
#ifdef H5T_ALPHA_F64
	    return H5T_ALPHA_F64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_I16"))
#ifdef H5T_ALPHA_I16
	    return H5T_ALPHA_I16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_I32"))
#ifdef H5T_ALPHA_I32
	    return H5T_ALPHA_I32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_I64"))
#ifdef H5T_ALPHA_I64
	    return H5T_ALPHA_I64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_I8"))
#ifdef H5T_ALPHA_I8
	    return H5T_ALPHA_I8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_U16"))
#ifdef H5T_ALPHA_U16
	    return H5T_ALPHA_U16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_U32"))
#ifdef H5T_ALPHA_U32
	    return H5T_ALPHA_U32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_U64"))
#ifdef H5T_ALPHA_U64
	    return H5T_ALPHA_U64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_ALPHA_U8"))
#ifdef H5T_ALPHA_U8
	    return H5T_ALPHA_U8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_C_S1"))
#ifdef H5T_C_S1
	    return H5T_C_S1;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_FORTRAN_S1"))
#ifdef H5T_FORTRAN_S1
	    return H5T_FORTRAN_S1;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_IEEE_F32BE"))
#ifdef H5T_IEEE_F32BE
	    return H5T_IEEE_F32BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_IEEE_F32LE"))
#ifdef H5T_IEEE_F32LE
	    return H5T_IEEE_F32LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_IEEE_F64BE"))
#ifdef H5T_IEEE_F64BE
	    return H5T_IEEE_F64BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_IEEE_F64LE"))
#ifdef H5T_IEEE_F64LE
	    return H5T_IEEE_F64LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_B16"))
#ifdef H5T_INTEL_B16
	    return H5T_INTEL_B16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_B32"))
#ifdef H5T_INTEL_B32
	    return H5T_INTEL_B32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_B64"))
#ifdef H5T_INTEL_B64
	    return H5T_INTEL_B64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_B8"))
#ifdef H5T_INTEL_B8
	    return H5T_INTEL_B8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_F32"))
#ifdef H5T_INTEL_F32
	    return H5T_INTEL_F32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_F64"))
#ifdef H5T_INTEL_F64
	    return H5T_INTEL_F64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_I16"))
#ifdef H5T_INTEL_I16
	    return H5T_INTEL_I16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_I32"))
#ifdef H5T_INTEL_I32
	    return H5T_INTEL_I32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_I64"))
#ifdef H5T_INTEL_I64
	    return H5T_INTEL_I64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_I8"))
#ifdef H5T_INTEL_I8
	    return H5T_INTEL_I8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_U16"))
#ifdef H5T_INTEL_U16
	    return H5T_INTEL_U16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_U32"))
#ifdef H5T_INTEL_U32
	    return H5T_INTEL_U32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_U64"))
#ifdef H5T_INTEL_U64
	    return H5T_INTEL_U64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_INTEL_U8"))
#ifdef H5T_INTEL_U8
	    return H5T_INTEL_U8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_B16"))
#ifdef H5T_MIPS_B16
	    return H5T_MIPS_B16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_B32"))
#ifdef H5T_MIPS_B32
	    return H5T_MIPS_B32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_B64"))
#ifdef H5T_MIPS_B64
	    return H5T_MIPS_B64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_B8"))
#ifdef H5T_MIPS_B8
	    return H5T_MIPS_B8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_F32"))
#ifdef H5T_MIPS_F32
	    return H5T_MIPS_F32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_F64"))
#ifdef H5T_MIPS_F64
	    return H5T_MIPS_F64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_I16"))
#ifdef H5T_MIPS_I16
	    return H5T_MIPS_I16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_I32"))
#ifdef H5T_MIPS_I32
	    return H5T_MIPS_I32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_I64"))
#ifdef H5T_MIPS_I64
	    return H5T_MIPS_I64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_I8"))
#ifdef H5T_MIPS_I8
	    return H5T_MIPS_I8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_U16"))
#ifdef H5T_MIPS_U16
	    return H5T_MIPS_U16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_U32"))
#ifdef H5T_MIPS_U32
	    return H5T_MIPS_U32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_U64"))
#ifdef H5T_MIPS_U64
	    return H5T_MIPS_U64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_MIPS_U8"))
#ifdef H5T_MIPS_U8
	    return H5T_MIPS_U8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_B16"))
#ifdef H5T_NATIVE_B16
	    return H5T_NATIVE_B16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_B32"))
#ifdef H5T_NATIVE_B32
	    return H5T_NATIVE_B32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_B64"))
#ifdef H5T_NATIVE_B64
	    return H5T_NATIVE_B64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_B8"))
#ifdef H5T_NATIVE_B8
	    return H5T_NATIVE_B8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_CHAR"))
#ifdef H5T_NATIVE_CHAR
	    return H5T_NATIVE_CHAR;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_DOUBLE"))
#ifdef H5T_NATIVE_DOUBLE
	    return H5T_NATIVE_DOUBLE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_FLOAT"))
#ifdef H5T_NATIVE_FLOAT
	    return H5T_NATIVE_FLOAT;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_HBOOL"))
#ifdef H5T_NATIVE_HBOOL
	    return H5T_NATIVE_HBOOL;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_HERR"))
#ifdef H5T_NATIVE_HERR
	    return H5T_NATIVE_HERR;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_HSIZE"))
#ifdef H5T_NATIVE_HSIZE
	    return H5T_NATIVE_HSIZE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_HSSIZE"))
#ifdef H5T_NATIVE_HSSIZE
	    return H5T_NATIVE_HSSIZE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT"))
#ifdef H5T_NATIVE_INT
	    return H5T_NATIVE_INT;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT16"))
#ifdef H5T_NATIVE_INT16
	    return H5T_NATIVE_INT16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT32"))
#ifdef H5T_NATIVE_INT32
	    return H5T_NATIVE_INT32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT64"))
#ifdef H5T_NATIVE_INT64
	    return H5T_NATIVE_INT64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT8"))
#ifdef H5T_NATIVE_INT8
	    return H5T_NATIVE_INT8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT_FAST16"))
#ifdef H5T_NATIVE_INT_FAST16
	    return H5T_NATIVE_INT_FAST16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT_FAST32"))
#ifdef H5T_NATIVE_INT_FAST32
	    return H5T_NATIVE_INT_FAST32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT_FAST64"))
#ifdef H5T_NATIVE_INT_FAST64
	    return H5T_NATIVE_INT_FAST64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT_FAST8"))
#ifdef H5T_NATIVE_INT_FAST8
	    return H5T_NATIVE_INT_FAST8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT_LEAST16"))
#ifdef H5T_NATIVE_INT_LEAST16
	    return H5T_NATIVE_INT_LEAST16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT_LEAST32"))
#ifdef H5T_NATIVE_INT_LEAST32
	    return H5T_NATIVE_INT_LEAST32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT_LEAST64"))
#ifdef H5T_NATIVE_INT_LEAST64
	    return H5T_NATIVE_INT_LEAST64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_INT_LEAST8"))
#ifdef H5T_NATIVE_INT_LEAST8
	    return H5T_NATIVE_INT_LEAST8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_LDOUBLE"))
#ifdef H5T_NATIVE_LDOUBLE
	    return H5T_NATIVE_LDOUBLE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_LLONG"))
#ifdef H5T_NATIVE_LLONG
	    return H5T_NATIVE_LLONG;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_LONG"))
#ifdef H5T_NATIVE_LONG
	    return H5T_NATIVE_LONG;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_OPAQUE"))
#ifdef H5T_NATIVE_OPAQUE
	    return H5T_NATIVE_OPAQUE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_SCHAR"))
#ifdef H5T_NATIVE_SCHAR
	    return H5T_NATIVE_SCHAR;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_SHORT"))
#ifdef H5T_NATIVE_SHORT
	    return H5T_NATIVE_SHORT;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UCHAR"))
#ifdef H5T_NATIVE_UCHAR
	    return H5T_NATIVE_UCHAR;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT"))
#ifdef H5T_NATIVE_UINT
	    return H5T_NATIVE_UINT;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT16"))
#ifdef H5T_NATIVE_UINT16
	    return H5T_NATIVE_UINT16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT32"))
#ifdef H5T_NATIVE_UINT32
	    return H5T_NATIVE_UINT32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT64"))
#ifdef H5T_NATIVE_UINT64
	    return H5T_NATIVE_UINT64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT8"))
#ifdef H5T_NATIVE_UINT8
	    return H5T_NATIVE_UINT8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT_FAST16"))
#ifdef H5T_NATIVE_UINT_FAST16
	    return H5T_NATIVE_UINT_FAST16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT_FAST32"))
#ifdef H5T_NATIVE_UINT_FAST32
	    return H5T_NATIVE_UINT_FAST32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT_FAST64"))
#ifdef H5T_NATIVE_UINT_FAST64
	    return H5T_NATIVE_UINT_FAST64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT_FAST8"))
#ifdef H5T_NATIVE_UINT_FAST8
	    return H5T_NATIVE_UINT_FAST8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT_LEAST16"))
#ifdef H5T_NATIVE_UINT_LEAST16
	    return H5T_NATIVE_UINT_LEAST16;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT_LEAST32"))
#ifdef H5T_NATIVE_UINT_LEAST32
	    return H5T_NATIVE_UINT_LEAST32;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT_LEAST64"))
#ifdef H5T_NATIVE_UINT_LEAST64
	    return H5T_NATIVE_UINT_LEAST64;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_UINT_LEAST8"))
#ifdef H5T_NATIVE_UINT_LEAST8
	    return H5T_NATIVE_UINT_LEAST8;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_ULLONG"))
#ifdef H5T_NATIVE_ULLONG
	    return H5T_NATIVE_ULLONG;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_ULONG"))
#ifdef H5T_NATIVE_ULONG
	    return H5T_NATIVE_ULONG;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_NATIVE_USHORT"))
#ifdef H5T_NATIVE_USHORT
	    return H5T_NATIVE_USHORT;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_B16BE"))
#ifdef H5T_STD_B16BE
	    return H5T_STD_B16BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_B16LE"))
#ifdef H5T_STD_B16LE
	    return H5T_STD_B16LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_B32BE"))
#ifdef H5T_STD_B32BE
	    return H5T_STD_B32BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_B32LE"))
#ifdef H5T_STD_B32LE
	    return H5T_STD_B32LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_B64BE"))
#ifdef H5T_STD_B64BE
	    return H5T_STD_B64BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_B64LE"))
#ifdef H5T_STD_B64LE
	    return H5T_STD_B64LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_B8BE"))
#ifdef H5T_STD_B8BE
	    return H5T_STD_B8BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_B8LE"))
#ifdef H5T_STD_B8LE
	    return H5T_STD_B8LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_I16BE"))
#ifdef H5T_STD_I16BE
	    return H5T_STD_I16BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_I16LE"))
#ifdef H5T_STD_I16LE
	    return H5T_STD_I16LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_I32BE"))
#ifdef H5T_STD_I32BE
	    return H5T_STD_I32BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_I32LE"))
#ifdef H5T_STD_I32LE
	    return H5T_STD_I32LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_I64BE"))
#ifdef H5T_STD_I64BE
	    return H5T_STD_I64BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_I64LE"))
#ifdef H5T_STD_I64LE
	    return H5T_STD_I64LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_I8BE"))
#ifdef H5T_STD_I8BE
	    return H5T_STD_I8BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_I8LE"))
#ifdef H5T_STD_I8LE
	    return H5T_STD_I8LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_REF_DSETREG"))
#ifdef H5T_STD_REF_DSETREG
	    return H5T_STD_REF_DSETREG;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_REF_OBJ"))
#ifdef H5T_STD_REF_OBJ
	    return H5T_STD_REF_OBJ;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_U16BE"))
#ifdef H5T_STD_U16BE
	    return H5T_STD_U16BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_U16LE"))
#ifdef H5T_STD_U16LE
	    return H5T_STD_U16LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_U32BE"))
#ifdef H5T_STD_U32BE
	    return H5T_STD_U32BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_U32LE"))
#ifdef H5T_STD_U32LE
	    return H5T_STD_U32LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_U64BE"))
#ifdef H5T_STD_U64BE
	    return H5T_STD_U64BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_U64LE"))
#ifdef H5T_STD_U64LE
	    return H5T_STD_U64LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_U8BE"))
#ifdef H5T_STD_U8BE
	    return H5T_STD_U8BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_STD_U8LE"))
#ifdef H5T_STD_U8LE
	    return H5T_STD_U8LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_UNIX_D32BE"))
#ifdef H5T_UNIX_D32BE
	    return H5T_UNIX_D32BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_UNIX_D32LE"))
#ifdef H5T_UNIX_D32LE
	    return H5T_UNIX_D32LE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_UNIX_D64BE"))
#ifdef H5T_UNIX_D64BE
	    return H5T_UNIX_D64BE;
#else
	    goto not_there;
#endif
	if (strEQ(name, "H5T_UNIX_D64LE"))
#ifdef H5T_UNIX_D64LE
	    return H5T_UNIX_D64LE;
#else
	    goto not_there;
#endif
	break;
    case 'I':
	break;
    case 'J':
	break;
    case 'K':
	break;
    case 'L':
	break;
    case 'M':
	break;
    case 'N':
	break;
    case 'O':
	break;
    case 'P':
	break;
    case 'Q':
	break;
    case 'R':
	break;
    case 'S':
	break;
    case 'T':
	break;
    case 'U':
	break;
    case 'V':
	break;
    case 'W':
	break;
    case 'X':
	break;
    case 'Y':
	break;
    case 'Z':
	break;
    }
    errno = EINVAL;
    return 0;

not_there:
    errno = ENOENT;
    return 0;
}

/* ############################################################# */
EOXS

pp_addxs('',<<'EOXS');

double
constant(name,arg)
	char *		name
	int		arg


EOXS
############### Add Autoload Routine for the hdf5 constants ##########

pp_addpm( {At => Top}, <<'EOPM');



use Carp;

sub AUTOLOAD {
    # This AUTOLOAD is used to 'autoload' constants from the constant()
    # XS function.  If a constant is not found then control is passed
    # to the AUTOLOAD in AutoLoader.

    my $constname;
    ($constname = $AUTOLOAD) =~ s/.*:://;
    croak "& not defined" if $constname eq 'constant';
    my $val = constant($constname, @_ ? $_[0] : 0);
    if ($! != 0) {
	if ($! =~ /Invalid/) {
	    $AutoLoader::AUTOLOAD = $AUTOLOAD;
	    goto &AutoLoader::AUTOLOAD;
	}
	else {
		croak "Your vendor has not defined hdf5 macro $constname";
	}
    }
    *$AUTOLOAD = sub { $val };
    goto &$AUTOLOAD;
}
EOPM

# Code that implements the dataset count and dataset name functions
pp_addxs('',<<'EOXS');

# Code to get the number of datasets in a group

int
H5GgetDatasetCount( groupID, groupName )
	hid_t	groupID
	char * 	groupName
CODE:
	int	dsetCount = 0;
        H5Giterate(groupID, groupName, NULL, incIfDset, &dsetCount);
	RETVAL = dsetCount;
OUTPUT:
	RETVAL


# Code to get the names of the datasets in a group

void
H5GgetDatasetNames( groupID, groupName )
	hid_t	groupID
	char * 	groupName
PREINIT:
	int	dsetCount = 0;
	char ** datasetNames;  /* Array of dataset names */
	char ** datasetPtr;    /* temp pointer to datasetNames */
	int i; 	               /* Index variable */
PPCODE:
	/* Get the number of datasets */
        H5Giterate(groupID, groupName, NULL, incIfDset, &dsetCount);
	
	if( dsetCount > 0){ /* Datasets found */
		
		/* Allocate Space  for array of strings */
		datasetNames = (char **) malloc( dsetCount * sizeof(char *));
		if( datasetNames == NULL){
			printf("PDL::HDF5; out of Memory in H5GgetDatasetNames\n");
			exit(1);
		}
 
		datasetPtr = datasetNames;

		H5Giterate(groupID, groupName, NULL, getName_if_Dset, &datasetPtr);

		EXTEND(SP, dsetCount); /* Make room for results on the return stack */
		for( i = 0; i< dsetCount; i++){ /* Push Names onto return stack */
		       /*  printf("Name found = '%s'\n",datasetNames[i]); */
		       PUSHs(sv_2mortal(newSVpv(datasetNames[i],0)));
		       free(datasetNames[i]); /* Release Memory */
		}

		free(datasetNames);
	}


# Code to get the number of groups in a group/file

int
H5GgetGroupCount( groupID, groupName )
	hid_t	groupID
	char * 	groupName
CODE:
	int	groupCount = 0;
        H5Giterate(groupID, groupName, NULL, incIfGroup, &groupCount);
	RETVAL = groupCount;
OUTPUT:
	RETVAL


# Code to get the names of the groups in a group/file

void
H5GgetGroupNames( groupID, groupName )
	hid_t	groupID
	char * 	groupName
PREINIT:
	int	groupCount = 0;
	char ** groupNames;     /* Array of group names */
	char ** groupPtr;    /* temp pointer to groupnames */
	int i; 	               /* Index variable */
PPCODE:
	/* Get the number of datasets */
        H5Giterate(groupID, groupName, NULL, incIfGroup, &groupCount);
	
	if( groupCount > 0){ /* Groups found */
		
		/* Allocate Space  for array of strings */
		groupNames = (char **) malloc( groupCount * sizeof(char *));
		if( groupNames == NULL){
			printf("PDL::HDF5; out of Memory in H5GgetGroupNames\n");
			exit(1);
		}
 
		groupPtr = groupNames;

		H5Giterate(groupID, groupName, NULL, getName_if_Group, &groupPtr);

		EXTEND(SP, groupCount); /* Make room for results on the return stack */
		for( i = 0; i< groupCount; i++){ /* Push Names onto return stack */
		       /*  printf("Name found = '%s'\n",datasetNames[i]); */
		       PUSHs(sv_2mortal(newSVpv(groupNames[i],0)));
		       free(groupNames[i]); /* Release Memory */
		}

		free(groupNames);
	}


EOXS


pp_done();