From 0a27d163bcfee73f32d52e673fb4b2fe038bddfe Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Sat, 27 Nov 2004 11:07:44 -0500 Subject: [svn-r9581] This commit was manufactured by cvs2svn to create branch 'hdf5_1_6'. --- hl/Makefile.in | 100 ++ hl/src/Dependencies | 14 + hl/src/H5IM.c | 1264 +++++++++++++++ hl/src/H5IM.h | 91 ++ hl/src/H5LT.c | 2716 +++++++++++++++++++++++++++++++ hl/src/H5LT.h | 374 +++++ hl/src/H5TA.c | 3689 ++++++++++++++++++++++++++++++++++++++++++ hl/src/H5TA.h | 246 +++ hl/src/Makefile.in | 34 + hl/test/Dependencies | 69 + hl/test/test_image.c | 197 +++ hl/test/test_lite.c | 1071 ++++++++++++ hl/test/test_table.c | 1597 ++++++++++++++++++ hl/test/test_table_be.hdf5 | Bin 0 -> 55912 bytes hl/test/test_table_cray.hdf5 | Bin 0 -> 55912 bytes hl/test/test_table_le.hdf5 | Bin 0 -> 53880 bytes src/H5SL.c | 715 ++++++++ src/H5SLprivate.h | 66 + test/tskiplist.c | 497 ++++++ 19 files changed, 12740 insertions(+) create mode 100755 hl/Makefile.in create mode 100644 hl/src/Dependencies create mode 100644 hl/src/H5IM.c create mode 100644 hl/src/H5IM.h create mode 100644 hl/src/H5LT.c create mode 100644 hl/src/H5LT.h create mode 100644 hl/src/H5TA.c create mode 100644 hl/src/H5TA.h create mode 100644 hl/src/Makefile.in create mode 100644 hl/test/Dependencies create mode 100644 hl/test/test_image.c create mode 100644 hl/test/test_lite.c create mode 100644 hl/test/test_table.c create mode 100644 hl/test/test_table_be.hdf5 create mode 100644 hl/test/test_table_cray.hdf5 create mode 100644 hl/test/test_table_le.hdf5 create mode 100644 src/H5SL.c create mode 100644 src/H5SLprivate.h create mode 100644 test/tskiplist.c diff --git a/hl/Makefile.in b/hl/Makefile.in new file mode 100755 index 0000000..5314fd8 --- /dev/null +++ b/hl/Makefile.in @@ -0,0 +1,100 @@ +## Top-level HDF5 Makefile(.in) +## +## Copyright (C) 2001 National Center for Supercomputing Applications. +## All rights reserved. +## +## +## This makefile mostly just reinvokes make in the various subdirectories +## but does so in the correct order. You can alternatively invoke make from +## each subdirectory manually. +## +top_srcdir=@top_srcdir@ +top_builddir=.. +srcdir=@srcdir@ + + +# Subdirectories in build-order +SUBDIRS=src test + +############################################################################## +## T A R G E T S +## +## all: Build libraries, header files, tests, and programs in the +## various subdirectories but does not run tests or install the +## library, header files, or programs. The components can be +## built individually with the targets lib, progs, and tests. +## check: Test the uninstalled library to make sure it works. You may +## also say `test' or `_test' (`test' doesn't work from the top +## level directory for some versions of make because `test' is +## also a directory). +## install: Installs libraries, header files, programs, and documentation +## in the various directories under the prefix directory (lib, +## include, bin, man, info). Use the `--prefix=PATH' option +## to `configure' (or `config.status') or say `--help' for +## other alternatives. The default prefix is `/usr/local'. +## uninstall: Delete all the installed files that the `install' target +## created (but not the noninstalled files such as `make all' +## created). +## clean: Removes temporary files except those that record the +## configuration and those that are part of the distribution. +## mostlyclean: Like `clean' except it doesn't delete a few files like +## libraries, programs, and/or generated header files because +## regenerating them is rarely necessary and takes a lot of time. +## distclean: Deletes all files that are created by configuring or building +## HDF5. If you have unpacked the source and built HDF5 without +## creating any other files, then `make distclean' will leave +## only the files that were in the distrubution. +## maintainer-clean: +## Like `distclean' except it deletes more files. It deletes +## all generated files. This target is not intended for normal +## users; it deletes files that may require special tools to +## rebuild. +## TAGS: Updates the tags table for this program. +## dep depend: Builds dependencies in all subdirectories. These targets +## might not be available on certain combinations of make +## programs and C compilers. At the other extreme, the GNU +## make used in combination with gcc will maintain dependency +## information automatically. +lib progs check test _test uninstall: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done + +tests TAGS dep depend: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done + +install: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done + +install-doc: + (cd doc && $(MAKE) $@) || exit 1; + +uninstall-doc: + (cd doc && $(MAKE) $@) || exit 1; + +.PHONY: all lib progs test _test install uninstall dep depend clean \ + mostlyclean distclean maintainer-clean + +clean mostlyclean: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@); \ + done + +distclean: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@); \ + done + -$(RM) Makefile + +maintainer-clean: + @echo "This target is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@); \ + done + + diff --git a/hl/src/Dependencies b/hl/src/Dependencies new file mode 100644 index 0000000..2218168 --- /dev/null +++ b/hl/src/Dependencies @@ -0,0 +1,14 @@ +## This file is machine generated on GNU systems. +## Only temporary changes may be made here. + +H5IM.lo: \ + $(srcdir)/H5IM.c \ + $(srcdir)/H5IM.h \ + $(srcdir)/H5LT.h +H5LT.lo: \ + $(srcdir)/H5LT.c \ + $(srcdir)/H5LT.h +H5TB.lo: \ + $(srcdir)/H5TB.c \ + $(srcdir)/H5TB.h \ + $(srcdir)/H5LT.h diff --git a/hl/src/H5IM.c b/hl/src/H5IM.c new file mode 100644 index 0000000..a2b8172 --- /dev/null +++ b/hl/src/H5IM.c @@ -0,0 +1,1264 @@ +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + +#include "H5IM.h" + +#include +#include + + +/*------------------------------------------------------------------------- + * Function: H5IMmake_image_8bit + * + * Purpose: Creates and writes an image an 8 bit image + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: June 13, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMmake_image_8bit( hid_t loc_id, + const char *dset_name, + hsize_t width, + hsize_t height, + const unsigned char *buffer ) +{ + int rank = 3; + hsize_t dims[3]; + + /* Initialize the image dimensions */ + dims[0] = height; + dims[1] = width; + dims[2] = 1; + + /* Make the dataset */ + if ( H5LTmake_dataset( loc_id, dset_name, rank, dims, H5T_NATIVE_UCHAR, buffer ) < 0 ) + return -1; + + /* Attach the CLASS attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "CLASS", "IMAGE" ) < 0 ) + return -1; + + /* Attach the VERSION attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "IMAGE_VERSION", "1.2" ) < 0 ) + return -1; + + /* Attach the IMAGE_SUBCLASS attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "IMAGE_SUBCLASS", "IMAGE_INDEXED" ) < 0 ) + return -1; + + return 0; +} + + + +/*------------------------------------------------------------------------- + * Function: H5IMmake_image_24bit + * + * Purpose: + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: June 13, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Interlace Mode Dimensions in the Dataspace + * INTERLACE_PIXEL [height][width][pixel components] + * INTERLACE_PLANE [pixel components][height][width] + * + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMmake_image_24bit( hid_t loc_id, + const char *dset_name, + hsize_t width, + hsize_t height, + const char *interlace, + const unsigned char *buffer ) +{ + int rank = 3; + hsize_t dims[3]; + + /* Initialize the image dimensions */ + + if ( strcmp( interlace, "INTERLACE_PIXEL" ) == 0 ) + { + /* Number of color planes is defined as the third dimension */ + dims[0] = height; + dims[1] = width; + dims[2] = 3; + } + else + if ( strcmp( interlace, "INTERLACE_PLANE" ) == 0 ) + { + /* Number of color planes is defined as the first dimension */ + dims[0] = 3; + dims[1] = height; + dims[2] = width; + } + else return -1; + + /* Make the dataset */ + if ( H5LTmake_dataset( loc_id, dset_name, rank, dims, H5T_NATIVE_UCHAR, buffer ) < 0 ) + return -1; + + /* Attach the CLASS attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "CLASS", "IMAGE" ) < 0 ) + return -1; + + /* Attach the VERSION attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "IMAGE_VERSION", "1.2" ) < 0 ) + return -1; + + /* Attach the IMAGE_SUBCLASS attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "IMAGE_SUBCLASS", "IMAGE_TRUECOLOR" ) < 0 ) + return -1; + + /* Attach the INTERLACE_MODE attribute. This attributes is only for true color images */ + if ( H5LTset_attribute_string( loc_id, dset_name, "INTERLACE_MODE", interlace ) < 0 ) + return -1; + + return 0; + +} + + + +/*------------------------------------------------------------------------- + * Function: find_palette + * + * Purpose: operator function used by H5LT_find_palette + * + * Return: + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: May 28, 2001 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static herr_t find_palette( hid_t loc_id, const char *name, void *op_data ) +{ + + /* Define a default zero value for return. This will cause the iterator to continue if + * the palette attribute is not found yet. + */ + + int ret = 0; + + /* Shut compiler */ + loc_id=loc_id; + op_data=op_data; + + /* Define a positive value for return value if the attribute was found. This will + * cause the iterator to immediately return that positive value, + * indicating short-circuit success + */ + + if( strcmp( name, "PALETTE" ) == 0 ) + ret = 1; + + + return ret; +} + + +/*------------------------------------------------------------------------- + * Function: H5IM_find_palette + * + * Purpose: Private function. Find the attribute "PALETTE" in the image dataset + * + * Return: Success: 1, Failure: 0 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: May 11, 2001 + * + * Comments: + * The function uses H5Aiterate with the operator function find_palette + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static herr_t H5IM_find_palette( hid_t loc_id ) +{ + + unsigned int attr_num; /* Starting attribute to look up */ + herr_t ret; + + attr_num = 0; + ret = H5Aiterate( loc_id, &attr_num, find_palette, 0 ); + + return ret; +} + + +/*------------------------------------------------------------------------- + * Function: H5IMget_image_info + * + * Purpose: Gets information about an image dataset (dimensions, interlace mode + * and number of associated palettes). + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: July 25, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMget_image_info( hid_t loc_id, + const char *dset_name, + hsize_t *width, + hsize_t *height, + hsize_t *planes, + char *interlace, + hssize_t *npals ) +{ + hid_t did, sid; + hsize_t dims[3]; + hid_t attr_id; + hid_t attr_type; + int has_attr; + hid_t attr_space_id; + hid_t attr_class; + int has_pal; + + /*assume initially we have no palettes attached*/ + *npals = 0; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Try to find the attribute "INTERLACE_MODE" on the >>image<< dataset */ + has_attr = H5LT_find_attribute( did, "INTERLACE_MODE" ); + + /* It exists, get it */ + if ( has_attr == 1 ) + { + + if ( (attr_id = H5Aopen_name( did, "INTERLACE_MODE" )) < 0 ) + goto out; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( H5Aread( attr_id, attr_type, interlace ) < 0 ) + goto out; + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + goto out; + } + + /* Get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* Get dimensions */ + if ( H5Sget_simple_extent_dims( sid, dims, NULL) < 0 ) + goto out; + + /* Initialize the image dimensions */ + + if ( has_attr == 1 ) + /* This is a 24 bit image */ + { + + if ( strcmp( interlace, "INTERLACE_PIXEL" ) == 0 ) + { + /* Number of color planes is defined as the third dimension */ + *height = dims[0]; + *width = dims[1]; + *planes = dims[2]; + } + else + if ( strcmp( interlace, "INTERLACE_PLANE" ) == 0 ) + { + /* Number of color planes is defined as the first dimension */ + *planes = dims[0]; + *height = dims[1]; + *width = dims[2]; + } + else return -1; + } + else + /* This is a 8 bit image */ + { + *height = dims[0]; + *width = dims[1]; + *planes = dims[2]; + } + + /* Close */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + + /* Get number of palettes */ + + + /* Try to find the attribute "PALETTE" on the >>image<< dataset */ + has_pal = H5IM_find_palette( did ); + + if ( has_pal == 1 ) + { + + if ( (attr_id = H5Aopen_name( did, "PALETTE" )) < 0 ) + goto out; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( (attr_class = H5Tget_class( attr_type )) < 0 ) + goto out; + + /* Check if it is really a reference */ + + if ( attr_class == H5T_REFERENCE ) + { + + /* Get the reference(s) */ + + if ( (attr_space_id = H5Aget_space( attr_id )) < 0 ) + goto out; + + *npals = H5Sget_simple_extent_npoints( attr_space_id ); + + if ( H5Sclose( attr_space_id ) < 0 ) + goto out; + + } /* H5T_REFERENCE */ + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + /* Close the attribute. */ + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + } + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) < 0 ) + goto out; + + return 0; + +out: + H5Dclose( did ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5IMread_image + * + * Purpose: Reads image data from disk. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: June 13, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMread_image( hid_t loc_id, + const char *dset_name, + unsigned char *buffer ) +{ + hid_t did; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Read */ + if ( H5Dread( did, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer ) < 0 ) + goto out; + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5IMmake_palette + * + * Purpose: Creates and writes a palette. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: May 01, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMmake_palette( hid_t loc_id, + const char *pal_name, + const hsize_t *pal_dims, + const unsigned char *pal_data ) + +{ + + int has_pal; + + /* Check if the dataset already exists */ + has_pal = H5LTfind_dataset( loc_id, pal_name ); + + /* It exists. Return */ + if ( has_pal == 1 ) + return 0; + + /* Make the palette dataset. */ + if ( H5LTmake_dataset( loc_id, pal_name, 2, pal_dims, H5T_NATIVE_UCHAR, pal_data ) < 0 ) + return -1; + + /* Attach the attribute "CLASS" to the >>palette<< dataset*/ + if ( H5LTset_attribute_string( loc_id, pal_name, "CLASS", "PALETTE" ) < 0 ) + return -1; + + /* Attach the attribute "PAL_VERSION" to the >>palette<< dataset*/ + if ( H5LTset_attribute_string( loc_id, pal_name, "PAL_VERSION", "1.2" ) < 0 ) + return -1; + + return 0; + +} + + +/*------------------------------------------------------------------------- + * Function: H5IMlink_palette + * + * Purpose: This function attaches a palette to an existing image dataset + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: May 01, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * An image (dataset) within an HDF5 file may optionally specify an array of + * palettes to be viewed with. The dataset will have an attribute + * which contains an array of object reference pointers which refer to palettes in the file. + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMlink_palette( hid_t loc_id, + const char *image_name, + const char *pal_name ) + +{ + + hid_t image_id; + hid_t attr_type; + hid_t attr_id; + hid_t attr_space_id; + hid_t attr_class; + hobj_ref_t ref; /* write a new reference */ + hobj_ref_t *refbuf; /* buffer to read references */ + hssize_t n_refs; + hsize_t dim_ref; + int ok_pal, has_pal; + + /* Try to find the palette dataset */ + has_pal = H5LTfind_dataset( loc_id, pal_name ); + + /* The image dataset may or not have the attribute "PALETTE" + * First we try to open to see if it is already there; if not, it is created. + * If it exists, the array of references is extended to hold the reference + * to the new palette + */ + + /* First we get the image id */ + if ( (image_id = H5Dopen( loc_id, image_name )) < 0 ) + return -1; + + /* Try to find the attribute "PALETTE" on the >>image<< dataset */ + ok_pal = H5LT_find_attribute( image_id, "PALETTE" ); + + /* It does not exist. We create the attribute and one reference */ + if ( ok_pal == 0 ) + { + + if ( (attr_space_id = H5Screate( H5S_SCALAR )) < 0 ) + goto out; + + /* Create the attribute type for the reference */ + if ( (attr_type = H5Tcopy( H5T_STD_REF_OBJ )) < 0 ) + goto out; + + /* Create the attribute "PALETTE" to be attached to the image*/ + if ( (attr_id = H5Acreate( image_id, "PALETTE", attr_type, attr_space_id, H5P_DEFAULT )) < 0 ) + goto out; + + /* Create a reference. The reference is created on the local id. */ + if ( H5Rcreate( &ref, loc_id, pal_name, H5R_OBJECT, -1 ) < 0 ) + goto out; + + /* Write the attribute with the reference */ + if ( H5Awrite( attr_id, attr_type, &ref ) < 0 ) + goto out; + + if ( H5Sclose( attr_space_id ) < 0 ) + goto out; + + } + + /* The attribute already exists, open it */ + + else if ( ok_pal == 1 ) + + { + + if ( (attr_id = H5Aopen_name( image_id, "PALETTE" )) < 0 ) + goto out; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( (attr_class = H5Tget_class( attr_type )) < 0 ) + goto out; + + /* Check if it is really a reference */ + + if ( attr_class == H5T_REFERENCE ) + { + + /* Get and save the old reference(s) */ + + if ( (attr_space_id = H5Aget_space( attr_id )) < 0 ) + goto out; + + n_refs = H5Sget_simple_extent_npoints( attr_space_id ); + + dim_ref = n_refs + 1; + + refbuf = malloc( sizeof(hobj_ref_t) * (int)dim_ref ); + + if ( H5Aread( attr_id, attr_type, refbuf ) < 0 ) + goto out; + + if ( H5Sclose( attr_space_id ) < 0 ) + goto out; + + /* The attribute must be deleted, in order to the new one can reflect the changes*/ + if ( H5Adelete( image_id, "PALETTE" ) < 0 ) + goto out; + + /* Create a new reference for this palette. */ + if ( H5Rcreate( &ref, loc_id, pal_name, H5R_OBJECT, -1 ) < 0 ) + goto out; + + refbuf[n_refs] = ref; + + /* Create the data space for the new references */ + if ( (attr_space_id = H5Screate_simple( 1, &dim_ref, NULL )) < 0 ) + goto out; + + /* Create the attribute again with the changes of space */ + if ( (attr_id = H5Acreate( image_id, "PALETTE", attr_type, attr_space_id, H5P_DEFAULT )) < 0 ) + goto out; + + /* Write the attribute with the new references */ + if ( H5Awrite( attr_id, attr_type, refbuf ) < 0 ) + goto out; + + if ( H5Sclose( attr_space_id ) < 0 ) + goto out; + + free( refbuf ); + + } /* H5T_REFERENCE */ + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + /* Close the attribute. */ + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + } + + /* Close the image dataset. */ + if ( H5Dclose( image_id ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( image_id ); + return -1; +} + + + +/*------------------------------------------------------------------------- + * Function: H5IMunlink_palette + * + * Purpose: This function dettaches a palette from an existing image dataset + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 10, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMunlink_palette( hid_t loc_id, + const char *image_name, + const char *pal_name ) +{ + hid_t image_id; + hid_t attr_type; + hid_t attr_id; + hid_t attr_class; + int ok_pal, has_pal; + + /* Try to find the palette dataset */ + has_pal = H5LTfind_dataset( loc_id, pal_name ); + + /* It does not exist. Return */ + if ( has_pal == 0 ) + return -1; + + /* The image dataset may or not have the attribute "PALETTE" + * First we try to open to see if it is already there; if not, it is created. + * If it exists, the array of references is extended to hold the reference + * to the new palette + */ + + /* First we get the image id */ + if ( (image_id = H5Dopen( loc_id, image_name )) < 0 ) + return -1; + + /* Try to find the attribute "PALETTE" on the >>image<< dataset */ + ok_pal = H5LT_find_attribute( image_id, "PALETTE" ); + + /* It does not exist. Nothing to do */ + if ( ok_pal == 0 ) + return -1; + + /* The attribute exists, open it */ + else if ( ok_pal == 1 ) + { + if ( (attr_id = H5Aopen_name( image_id, "PALETTE" )) < 0 ) + goto out; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( (attr_class = H5Tget_class( attr_type )) < 0 ) + goto out; + + /* Check if it is really a reference */ + if ( attr_class == H5T_REFERENCE ) + { + + /* Deelete the attribute */ + if ( H5Adelete( image_id, "PALETTE" ) < 0 ) + goto out; + + } /* H5T_REFERENCE */ + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + /* Close the attribute. */ + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + } /* ok_pal */ + + /* Close the image dataset. */ + if ( H5Dclose( image_id ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( image_id ); + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: H5IMget_npalettes + * + * Purpose: Gets the number of palettes associated to an image + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: July 22, 2001 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMget_npalettes( hid_t loc_id, + const char *image_name, + hssize_t *npals ) +{ + hid_t image_id; + hid_t attr_type; + hid_t attr_id; + hid_t attr_space_id; + hid_t attr_class; + int has_pal; + + /*assume initially we have no palettes attached*/ + *npals = 0; + + /* Open the dataset. */ + if ( (image_id = H5Dopen( loc_id, image_name )) < 0 ) + return -1; + + /* Try to find the attribute "PALETTE" on the >>image<< dataset */ + has_pal = H5IM_find_palette( image_id ); + + if ( has_pal == 1 ) + { + + if ( (attr_id = H5Aopen_name( image_id, "PALETTE" )) < 0 ) + goto out; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( (attr_class = H5Tget_class( attr_type )) < 0 ) + goto out; + + /* Check if it is really a reference */ + + if ( attr_class == H5T_REFERENCE ) + { + if ( (attr_space_id = H5Aget_space( attr_id )) < 0 ) + goto out; + + *npals = H5Sget_simple_extent_npoints( attr_space_id ); + + if ( H5Sclose( attr_space_id ) < 0 ) + goto out; + + } /* H5T_REFERENCE */ + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + /* Close the attribute. */ + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + } + + /* Close the image dataset. */ + if ( H5Dclose( image_id ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( image_id ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5IMget_palette_info + * + * Purpose: Get palette information + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: July 22, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMget_palette_info( hid_t loc_id, + const char *image_name, + int pal_number, + hsize_t *pal_dims ) +{ + hid_t image_id; + int has_pal; + hid_t attr_type; + hid_t attr_id; + hid_t attr_space_id; + hid_t attr_class; + hssize_t n_refs; + hsize_t dim_ref; + hobj_ref_t *refbuf; /* buffer to read references */ + hid_t pal_id; + int rank; + hid_t pal_space_id; + hsize_t pal_maxdims[2]; + + /* Open the dataset. */ + if ( (image_id = H5Dopen( loc_id, image_name )) < 0 ) + return -1; + + /* Try to find the attribute "PALETTE" on the >>image<< dataset */ + has_pal = H5IM_find_palette( image_id ); + + if ( has_pal == 1 ) + { + + if ( (attr_id = H5Aopen_name( image_id, "PALETTE" )) < 0 ) + goto out; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( (attr_class = H5Tget_class( attr_type )) < 0 ) + goto out; + + /* Check if it is really a reference */ + + if ( attr_class == H5T_REFERENCE ) + { + + /* Get the reference(s) */ + + if ( (attr_space_id = H5Aget_space( attr_id )) < 0 ) + goto out; + + n_refs = H5Sget_simple_extent_npoints( attr_space_id ); + + dim_ref = n_refs; + + refbuf = malloc( sizeof(hobj_ref_t) * (int)dim_ref ); + + if ( H5Aread( attr_id, attr_type, refbuf ) < 0 ) + goto out; + + /* Get the actual palette */ + + if ( (pal_id = H5Rdereference( image_id, H5R_OBJECT, &refbuf[pal_number] )) < 0 ) + goto out; + + if ( (pal_space_id = H5Dget_space( pal_id )) < 0 ) + goto out; + + if ( (rank = H5Sget_simple_extent_ndims( pal_space_id )) < 0 ) + goto out; + + if ( H5Sget_simple_extent_dims( pal_space_id, pal_dims, pal_maxdims ) < 0 ) + goto out; + + if ( H5Sclose( pal_space_id ) < 0 ) + goto out; + + if ( H5Sclose( attr_space_id ) < 0 ) + goto out; + + free( refbuf ); + + } /* H5T_REFERENCE */ + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + /* Close the attribute. */ + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + } + + /* Close the image dataset. */ + if ( H5Dclose( image_id ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( image_id ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5IMget_palette + * + * Purpose: Read palette + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: August 30, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMget_palette( hid_t loc_id, + const char *image_name, + int pal_number, + unsigned char *pal_data ) +{ + hid_t image_id; + int has_pal; + hid_t attr_type; + hid_t attr_id; + hid_t attr_space_id; + hid_t attr_class; + hssize_t n_refs; + hsize_t dim_ref; + hobj_ref_t *refbuf; /* buffer to read references */ + hid_t pal_id; + + /* Open the dataset. */ + if ( (image_id = H5Dopen( loc_id, image_name )) < 0 ) + return -1; + + /* Try to find the attribute "PALETTE" on the >>image<< dataset */ + has_pal = H5IM_find_palette( image_id ); + + if ( has_pal == 1 ) + { + + if ( (attr_id = H5Aopen_name( image_id, "PALETTE" )) < 0 ) + goto out; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( (attr_class = H5Tget_class( attr_type )) < 0 ) + goto out; + + /* Check if it is really a reference */ + + if ( attr_class == H5T_REFERENCE ) + { + + /* Get the reference(s) */ + + if ( (attr_space_id = H5Aget_space( attr_id )) < 0 ) + goto out; + + n_refs = H5Sget_simple_extent_npoints( attr_space_id ); + + dim_ref = n_refs; + + refbuf = malloc( sizeof(hobj_ref_t) * (int)dim_ref ); + + if ( H5Aread( attr_id, attr_type, refbuf ) < 0 ) + goto out; + + /* Get the palette id */ + if ( (pal_id = H5Rdereference( image_id, H5R_OBJECT, &refbuf[pal_number] )) < 0 ) + goto out; + + /* Read the palette dataset */ + if ( H5Dread( pal_id, H5Dget_type(pal_id), H5S_ALL, H5S_ALL, H5P_DEFAULT, pal_data ) < 0 ) + goto out; + + if ( H5Sclose( attr_space_id ) < 0 ) + goto out; + + free( refbuf ); + + } /* H5T_REFERENCE */ + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + /* Close the attribute. */ + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + } + + + /* Close the image dataset. */ + if ( H5Dclose( image_id ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( image_id ); + return -1; + +} + +/*------------------------------------------------------------------------- + * Function: H5IMis_image + * + * Purpose: + * + * Return: true, false, fail + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: August 30, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMis_image( hid_t loc_id, + const char *dset_name ) +{ + hid_t did; + int has_class; + hid_t attr_type; + hid_t attr_id; + hid_t attr_class; + char attr_data[20]; + herr_t ret; + + /* Assume initially fail condition */ + ret = -1; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Try to find the attribute "CLASS" on the dataset */ + has_class = H5LT_find_attribute( did, "CLASS" ); + + if ( has_class == 0 ) + { + H5Dclose( did ); + return 0; + } + + else if ( has_class == 1 ) + { + + if ( (attr_id = H5Aopen_name( did, "CLASS" )) < 0 ) + goto out; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( (attr_class = H5Tget_class( attr_type )) < 0 ) + goto out; + + if ( H5Aread( attr_id, attr_type, attr_data ) < 0 ) + goto out; + + if( strcmp( attr_data, "IMAGE" ) == 0 ) + ret = 1; + else + ret = 0; + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + } + + /* Close the dataset. */ + if ( H5Dclose( did ) < 0 ) + return -1; + + return ret; + +out: + H5Dclose( did ); + return -1; + +} + + + +/*------------------------------------------------------------------------- + * Function: H5IMis_palette + * + * Purpose: + * + * Return: true, false, fail + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: August 30, 2001 + * + * Comments: + * based on HDF5 Image and Palette Specification + * http://hdf.ncsa.uiuc.edu/HDF5/H5Image/ImageSpec.html + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5IMis_palette( hid_t loc_id, + const char *dset_name ) +{ + hid_t did; + int has_class; + hid_t attr_type; + hid_t attr_id; + hid_t attr_class; + char attr_data[20]; + herr_t ret; + + /* Assume initially fail condition */ + ret = -1; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Try to find the attribute "CLASS" on the dataset */ + has_class = H5LT_find_attribute( did, "CLASS" ); + + if ( has_class == 0 ) + { + H5Dclose( did ); + return 0; + } + + else if ( has_class == 1 ) + { + + if ( (attr_id = H5Aopen_name( did, "CLASS" )) < 0 ) + goto out; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( (attr_class = H5Tget_class( attr_type )) < 0 ) + goto out; + + if ( H5Aread( attr_id, attr_type, attr_data ) < 0 ) + goto out; + + if( strcmp( attr_data, "PALETTE" ) == 0 ) + ret = 1; + else + ret = 0; + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + } + + /* Close the dataset. */ + if ( H5Dclose( did ) < 0 ) + return -1; + + return ret; + +out: + H5Dclose( did ); + return -1; + +} diff --git a/hl/src/H5IM.h b/hl/src/H5IM.h new file mode 100644 index 0000000..db79222 --- /dev/null +++ b/hl/src/H5IM.h @@ -0,0 +1,91 @@ + +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + + +#ifndef _H5IM_H +#define _H5IM_H + +#include "H5LT.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +herr_t H5IMmake_image_8bit( hid_t loc_id, + const char *dset_name, + hsize_t width, + hsize_t height, + const unsigned char *buffer ); + +herr_t H5IMmake_image_24bit( hid_t loc_id, + const char *dset_name, + hsize_t width, + hsize_t height, + const char *interlace, + const unsigned char *buffer ); + +herr_t H5IMget_image_info( hid_t loc_id, + const char *dset_name, + hsize_t *width, + hsize_t *height, + hsize_t *planes, + char *interlace, + hssize_t *npals ); + +herr_t H5IMread_image( hid_t loc_id, + const char *dset_name, + unsigned char *buffer ); + + + +herr_t H5IMmake_palette( hid_t loc_id, + const char *pal_name, + const hsize_t *pal_dims, + const unsigned char *pal_data ); + +herr_t H5IMlink_palette( hid_t loc_id, + const char *image_name, + const char *pal_name ); + +herr_t H5IMunlink_palette( hid_t loc_id, + const char *image_name, + const char *pal_name ); + +herr_t H5IMget_npalettes( hid_t loc_id, + const char *image_name, + hssize_t *npals ); + +herr_t H5IMget_palette_info( hid_t loc_id, + const char *image_name, + int pal_number, + hsize_t *pal_dims ); + + +herr_t H5IMget_palette( hid_t loc_id, + const char *image_name, + int pal_number, + unsigned char *pal_data ); + +herr_t H5IMis_image( hid_t loc_id, + const char *dset_name ); + +herr_t H5IMis_palette( hid_t loc_id, + const char *dset_name ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hl/src/H5LT.c b/hl/src/H5LT.c new file mode 100644 index 0000000..c8ac099 --- /dev/null +++ b/hl/src/H5LT.c @@ -0,0 +1,2716 @@ +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + +#include "H5LT.h" +#include +#include + +/*------------------------------------------------------------------------- + * + * Private functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5LT_open_id( hid_t loc_id, + const char *obj_name, + int obj_type ); + +herr_t H5LT_close_id( hid_t obj_id, + int obj_type ); + +/*------------------------------------------------------------------------- + * + * Public functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5LTmake_dataset + * + * Purpose: Creates and writes a dataset of a type tid + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 19, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTmake_dataset( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + hid_t tid, + const void *data ) +{ + + hid_t did, sid; + + /* Create the data space for the dataset. */ + if ( (sid = H5Screate_simple( rank, dims, NULL )) < 0 ) + return -1; + + /* Create the dataset. */ + if ( (did = H5Dcreate( loc_id, dset_name, tid, sid, H5P_DEFAULT )) < 0 ) + goto out; + + /* Write the dataset only if there is data to write */ + + if ( data ) + { + if ( H5Dwrite( did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + } + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) < 0 ) + return -1; + + /* Terminate access to the data space. */ + if ( H5Sclose( sid ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( did ); + H5Sclose( sid ); + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5LTmake_dataset_char + * + * Purpose: Creates and writes a dataset of H5T_NATIVE_CHAR type + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 14, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTmake_dataset_char( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const char *data ) +{ + + hid_t did, sid; + + /* Create the data space for the dataset. */ + if ( (sid = H5Screate_simple( rank, dims, NULL )) < 0 ) + return -1; + + /* Create the dataset. */ + if ( (did = H5Dcreate( loc_id, dset_name, H5T_NATIVE_CHAR, sid, H5P_DEFAULT )) < 0 ) + goto out; + + /* Write the dataset only if there is data to write */ + + if ( data ) + { + if ( H5Dwrite( did, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + } + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) < 0 ) + return -1; + + /* Terminate access to the data space. */ + if ( H5Sclose( sid ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( did ); + H5Sclose( sid ); + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: H5LTmake_dataset_short + * + * Purpose: Creates and writes a dataset of H5T_NATIVE_SHORT type + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 14, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTmake_dataset_short( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const short *data ) +{ + + hid_t did, sid; + + /* Create the data space for the dataset. */ + if ( (sid = H5Screate_simple( rank, dims, NULL )) < 0 ) + return -1; + + /* Create the dataset. */ + if ( (did = H5Dcreate( loc_id, dset_name, H5T_NATIVE_SHORT, sid, H5P_DEFAULT )) < 0 ) + goto out; + + /* Write the dataset only if there is data to write */ + + if ( data ) + { + if ( H5Dwrite( did, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + } + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) < 0 ) + return -1; + + /* Terminate access to the data space. */ + if ( H5Sclose( sid ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( did ); + H5Sclose( sid ); + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5LTmake_dataset_int + * + * Purpose: Creates and writes a dataset of H5T_NATIVE_INT type + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 14, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTmake_dataset_int( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const int *data ) +{ + + hid_t did, sid; + + /* Create the data space for the dataset. */ + if ( (sid = H5Screate_simple( rank, dims, NULL )) < 0 ) + return -1; + + /* Create the dataset. */ + if ( (did = H5Dcreate( loc_id, dset_name, H5T_NATIVE_INT, sid, H5P_DEFAULT )) < 0 ) + goto out; + + /* Write the dataset only if there is data to write */ + + if ( data ) + { + if ( H5Dwrite( did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + } + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) < 0 ) + return -1; + + /* Terminate access to the data space. */ + if ( H5Sclose( sid ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( did ); + H5Sclose( sid ); + return -1; +} + + + +/*------------------------------------------------------------------------- + * Function: H5LTmake_dataset_long + * + * Purpose: Creates and writes a dataset of H5T_NATIVE_LONG type + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 14, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTmake_dataset_long( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const long *data ) +{ + + hid_t did, sid; + + /* Create the data space for the dataset. */ + if ( (sid = H5Screate_simple( rank, dims, NULL )) < 0 ) + return -1; + + /* Create the dataset. */ + if ( (did = H5Dcreate( loc_id, dset_name, H5T_NATIVE_LONG, sid, H5P_DEFAULT )) < 0 ) + goto out; + + /* Write the dataset only if there is data to write */ + + if ( data ) + { + if ( H5Dwrite( did, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + } + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) < 0 ) + return -1; + + /* Terminate access to the data space. */ + if ( H5Sclose( sid ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( did ); + H5Sclose( sid ); + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5LTmake_dataset_float + * + * Purpose: Creates and writes a dataset of H5T_NATIVE_FLOAT type + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 14, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTmake_dataset_float( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const float *data ) +{ + + hid_t did, sid; + + /* Create the data space for the dataset. */ + if ( (sid = H5Screate_simple( rank, dims, NULL )) < 0 ) + return -1; + + /* Create the dataset. */ + if ( (did = H5Dcreate( loc_id, dset_name, H5T_NATIVE_FLOAT, sid, H5P_DEFAULT )) < 0 ) + goto out; + + /* Write the dataset only if there is data to write */ + + if ( data ) + { + if ( H5Dwrite( did, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + } + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) < 0 ) + return -1; + + /* Terminate access to the data space. */ + if ( H5Sclose( sid ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( did ); + H5Sclose( sid ); + return -1; +} + + + +/*------------------------------------------------------------------------- + * Function: H5LTmake_dataset_double + * + * Purpose: Creates and writes a dataset of H5T_NATIVE_DOUBLE type + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 14, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTmake_dataset_double( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const double *data ) +{ + + hid_t did, sid; + + /* Create the data space for the dataset. */ + if ( (sid = H5Screate_simple( rank, dims, NULL )) < 0 ) + return -1; + + /* Create the dataset. */ + if ( (did = H5Dcreate( loc_id, dset_name, H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT )) < 0 ) + goto out; + + /* Write the dataset only if there is data to write */ + + if ( data ) + { + if ( H5Dwrite( did, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + } + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) < 0 ) + return -1; + + /* Terminate access to the data space. */ + if ( H5Sclose( sid ) < 0 ) + return -1; + + return 0; + +out: + H5Dclose( did ); + H5Sclose( sid ); + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: H5LTmake_dataset_string + * + * Purpose: Creates and writes a dataset of H5T_C_S1 type + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: October 05, 2004 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTmake_dataset_string(hid_t loc_id, + const char *dset_name, + const char *buf ) +{ + + hid_t did=-1; + hid_t sid=-1; + hid_t tid; + size_t size; + + /* create a string data type */ + if ( (tid = H5Tcopy( H5T_C_S1 )) < 0 ) + goto out; + + size = strlen(buf) + 1; /* extra null term */ + + if ( H5Tset_size(tid,size) < 0 ) + goto out; + + if ( H5Tset_strpad(tid,H5T_STR_NULLTERM ) < 0 ) + goto out; + + /* Create the data space for the dataset. */ + if ( (sid = H5Screate( H5S_SCALAR )) < 0 ) + goto out; + + /* Create the dataset. */ + if ( (did = H5Dcreate(loc_id,dset_name,tid,sid,H5P_DEFAULT)) < 0 ) + goto out; + + /* Write the dataset only if there is data to write */ + + if (buf) + { + if ( H5Dwrite(did,tid,H5S_ALL,H5S_ALL,H5P_DEFAULT,buf) < 0 ) + goto out; + } + + /* close*/ + if ( H5Dclose(did) < 0 ) + return -1; + if ( H5Sclose(sid) < 0 ) + return -1; + if ( H5Tclose(tid) < 0 ) + goto out; + + return 0; + +out: + H5Dclose(did); + H5Tclose(tid); + H5Sclose(sid); + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: H5LTread_dataset + * + * Purpose: Reads a dataset from disk. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: June 13, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTread_dataset( hid_t loc_id, + const char *dset_name, + hid_t tid, + void *data ) +{ + hid_t did; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Read */ + if ( H5Dread( did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTread_dataset_char + * + * Purpose: Reads a dataset from disk. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 5, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTread_dataset_char( hid_t loc_id, + const char *dset_name, + char *data ) +{ + hid_t did; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Read */ + if ( H5Dread( did, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + return -1; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTread_dataset_short + * + * Purpose: Reads a dataset from disk. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 5, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTread_dataset_short( hid_t loc_id, + const char *dset_name, + short *data ) +{ + hid_t did; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Read */ + if ( H5Dread( did, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + return -1; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTread_dataset_int + * + * Purpose: Reads a dataset from disk. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 5, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTread_dataset_int( hid_t loc_id, + const char *dset_name, + int *data ) +{ + hid_t did; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Read */ + if ( H5Dread( did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + return -1; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTread_dataset_long + * + * Purpose: Reads a dataset from disk. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 5, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTread_dataset_long( hid_t loc_id, + const char *dset_name, + long *data ) +{ + hid_t did; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Read */ + if ( H5Dread( did, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + return -1; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTread_dataset_float + * + * Purpose: Reads a dataset from disk. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 5, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTread_dataset_float( hid_t loc_id, + const char *dset_name, + float *data ) +{ + hid_t did; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Read */ + if ( H5Dread( did, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTread_dataset_double + * + * Purpose: Reads a dataset from disk. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 5, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTread_dataset_double( hid_t loc_id, + const char *dset_name, + double *data ) +{ + hid_t did; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Read */ + if ( H5Dread( did, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* End access to the dataset and release resources used by it. */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTread_dataset_string + * + * Purpose: Reads a dataset + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: October 05, 2004 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTread_dataset_string( hid_t loc_id, + const char *dset_name, + char *buf ) +{ + hid_t did; + hid_t tid; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + if ( (tid = H5Dget_type(did)) < 0 ) + goto out; + + /* Read */ + if ( H5Dread(did,tid,H5S_ALL,H5S_ALL,H5P_DEFAULT,buf) < 0 ) + goto out; + + /* close */ + if ( H5Dclose(did) ) + goto out; + if ( H5Tclose(tid) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + H5Tclose( tid ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTget_dataset_ndims + * + * Purpose: Gets the dimensionality of a dataset. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 4, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTget_dataset_ndims( hid_t loc_id, + const char *dset_name, + int *rank ) +{ + hid_t did; + hid_t sid; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* Get rank */ + if ( (*rank = H5Sget_simple_extent_ndims( sid )) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Dclose( did ); + H5Sclose( sid ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTget_dataset_info + * + * Purpose: Gets information about a dataset. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 4, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTget_dataset_info( hid_t loc_id, + const char *dset_name, + hsize_t *dims, + H5T_class_t *type_class, + size_t *type_size ) +{ + hid_t did; + hid_t tid; + hid_t sid; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Get an identifier for the datatype. */ + tid = H5Dget_type( did ); + + /* Get the class. */ + *type_class = H5Tget_class( tid ); + + /* Get the size. */ + *type_size = H5Tget_size( tid ); + + /* Get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* Get dimensions */ + if ( H5Sget_simple_extent_dims( sid, dims, NULL) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( tid ) ) + return -1; + + /* End access to the dataset */ + if ( H5Dclose( did ) ) + return -1; + + return 0; + +out: + H5Tclose( tid ); + H5Dclose( did ); + return -1; + +} + +/*------------------------------------------------------------------------- + * Function: find_dataset + * + * Purpose: operator function used by H5LTfind_dataset + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: June 21, 2001 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static herr_t find_dataset( hid_t loc_id, const char *name, void *op_data) +{ + + /* Define a default zero value for return. This will cause the iterator to continue if + * the dataset is not found yet. + */ + + int ret = 0; + + char *dset_name = (char*)op_data; + + /* Shut the compiler up */ + loc_id=loc_id; + + /* Define a positive value for return value if the dataset was found. This will + * cause the iterator to immediately return that positive value, + * indicating short-circuit success + */ + + if( strcmp( name, dset_name ) == 0 ) + ret = 1; + + + return ret; +} + + + +/*------------------------------------------------------------------------- + * Function: H5LTfind_dataset + * + * Purpose: Inquires if a dataset named dset_name exists attached + * to the object loc_id. + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: July 15, 2001 + * + * Return: + * Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTfind_dataset( hid_t loc_id, const char *dset_name ) +{ + + herr_t ret; + + ret = H5Giterate( loc_id, ".", 0, find_dataset, (void *)dset_name ); + + return ret; +} + + +/*------------------------------------------------------------------------- + * + * Set attribute functions + * + *------------------------------------------------------------------------- + */ + + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_string + * + * Purpose: Creates and writes a string attribute named attr_name and attaches + * it to the object specified by the name obj_name. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: July 23, 2001 + * + * Comments: If the attribute already exists, it is overwritten + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_string( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const char *attr_data ) +{ + hid_t attr_type; + hid_t attr_space_id; + hid_t attr_id; + hid_t obj_id; + int has_attr; + H5G_stat_t statbuf; + size_t attr_size; + + + /* Get the type of object */ + if (H5Gget_objinfo( loc_id, obj_name, 1, &statbuf )<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Create the attribute */ + if ( (attr_type = H5Tcopy( H5T_C_S1 )) < 0 ) + goto out; + + attr_size = strlen( attr_data ) + 1; /* extra null term */ + + if ( H5Tset_size( attr_type, (size_t)attr_size) < 0 ) + goto out; + + if ( H5Tset_strpad( attr_type, H5T_STR_NULLTERM ) < 0 ) + goto out; + + if ( (attr_space_id = H5Screate( H5S_SCALAR )) < 0 ) + goto out; + + /* Verify if the attribute already exists */ + has_attr = H5LT_find_attribute( obj_id, attr_name ); + + /* The attribute already exists, delete it */ + if ( has_attr == 1 ) + { + if ( H5Adelete( obj_id, attr_name ) < 0 ) + goto out; + } + + /* Create and write the attribute */ + + if ( (attr_id = H5Acreate( obj_id, attr_name, attr_type, attr_space_id, H5P_DEFAULT )) < 0 ) + goto out; + + if ( H5Awrite( attr_id, attr_type, attr_data ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + if ( H5Sclose( attr_space_id ) < 0 ) + goto out; + + if ( H5Tclose(attr_type) < 0 ) + goto out; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +out: + + H5LT_close_id( obj_id, statbuf.type ); + return -1; +} + + + + + +/*------------------------------------------------------------------------- + * Function: H5LT_set_attribute_numerical + * + * Purpose: Private function used by H5LTset_attribute_int and H5LTset_attribute_float + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: July 25, 2001 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LT_set_attribute_numerical( hid_t loc_id, + const char *obj_name, + const char *attr_name, + size_t size, + hid_t tid, + const void *data ) +{ + + hid_t obj_id, sid, attr_id; + hsize_t dim_size=size; + int has_attr; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Create the data space for the attribute. */ + if ( (sid = H5Screate_simple( 1, &dim_size, NULL )) < 0 ) + goto out; + + /* Verify if the attribute already exists */ + has_attr = H5LT_find_attribute( obj_id, attr_name ); + + /* The attribute already exists, delete it */ + if ( has_attr == 1 ) + { + if ( H5Adelete( obj_id, attr_name ) < 0 ) + goto out; + } + + /* Create the attribute. */ + if ( (attr_id = H5Acreate( obj_id, attr_name, tid, sid, H5P_DEFAULT )) < 0 ) + goto out; + + /* Write the attribute data. */ + if ( H5Awrite( attr_id, tid, data ) < 0 ) + goto out; + + /* Close the attribute. */ + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + /* Close the dataspace. */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +out: + H5LT_close_id( obj_id, statbuf.type ); + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5LT_open_id + * + * Purpose: Private function used by H5LT_set_attribute_* + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LT_open_id( hid_t loc_id, + const char *obj_name, + int obj_type /*basic object type*/ ) +{ + + hid_t obj_id = -1; + + switch ( obj_type ) + { + case H5G_DATASET: + + /* Open the dataset. */ + if ( (obj_id = H5Dopen( loc_id, obj_name )) < 0 ) + return -1; + break; + + case H5G_GROUP: + + /* Open the group. */ + if ( (obj_id = H5Gopen( loc_id, obj_name )) < 0 ) + return -1; + break; + + default: + return -1; + } + + return obj_id; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LT_close_id + * + * Purpose: Private function used by H5LT_set_attribute_* + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LT_close_id( hid_t obj_id, + int obj_type /*basic object type*/ ) +{ + switch ( obj_type ) + { + case H5G_DATASET: + /* Close the dataset. */ + if ( H5Dclose( obj_id ) < 0 ) + return -1; + break; + + case H5G_GROUP: + /* Close the group. */ + if ( H5Gclose( obj_id ) < 0 ) + return -1; + break; + + default: + return -1; + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_char + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 7, 2001 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_char( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const char *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_CHAR, data ) < 0 ) + return -1; + + return 0; +} + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_uchar + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_uchar( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const unsigned char *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_UCHAR, data ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_short + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 7, 2001 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_short( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const short *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_SHORT, data ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_ushort + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_ushort( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const unsigned short *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_USHORT, data ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_int + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 7, 2001 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_int( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const int *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_INT, data ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_uint + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_uint( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const unsigned int *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_UINT, data ) < 0 ) + return -1; + + return 0; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_long + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 7, 2001 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_long( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const long *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_LONG, data ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_ulong + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_ulong( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const unsigned long *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_ULONG, data ) < 0 ) + return -1; + + return 0; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_float + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: July 25, 2001 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTset_attribute_float( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const float *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_FLOAT, data ) < 0 ) + return -1; + + return 0; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTset_attribute_double + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 7, 2001 + * + * Comments: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTset_attribute_double( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const double *data, + size_t size ) +{ + + if ( H5LT_set_attribute_numerical( loc_id, obj_name, attr_name, size, + H5T_NATIVE_DOUBLE, data ) < 0 ) + return -1; + + return 0; + +} + + + +/*------------------------------------------------------------------------- + * Function: find_attr + * + * Purpose: operator function used by H5LT_find_attribute + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: June 21, 2001 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static herr_t find_attr( hid_t loc_id, const char *name, void *op_data) +{ + + /* Define a default zero value for return. This will cause the iterator to continue if + * the palette attribute is not found yet. + */ + + int ret = 0; + + char *attr_name = (char*)op_data; + + /* Shut the compiler up */ + loc_id=loc_id; + + /* Define a positive value for return value if the attribute was found. This will + * cause the iterator to immediately return that positive value, + * indicating short-circuit success + */ + + if( strcmp( name, attr_name ) == 0 ) + ret = 1; + + + return ret; +} + + +/*------------------------------------------------------------------------- + * Function: H5LT_find_attribute + * + * Purpose: Inquires if an attribute named attr_name exists attached to the object loc_id. + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: June 21, 2001 + * + * Comments: + * The function uses H5Aiterate with the operator function find_attr + * + * Return: + * Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + *------------------------------------------------------------------------- + */ + +herr_t H5LT_find_attribute( hid_t loc_id, const char* attr_name ) +{ + + unsigned int attr_num; + herr_t ret; + + attr_num = 0; + ret = H5Aiterate( loc_id, &attr_num, find_attr, (void *)attr_name ); + + return ret; +} + + + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_ndims + * + * Purpose: Gets the dimensionality of an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 4, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTget_attribute_ndims( hid_t loc_id, + const char *obj_name, + const char *attr_name, + int *rank ) +{ + hid_t attr_id; + hid_t sid; + H5G_stat_t statbuf; + hid_t obj_id; + + /* Get the type of object */ + if (H5Gget_objinfo( loc_id, obj_name, 1, &statbuf )<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Open the attribute. */ + if ( ( attr_id = H5Aopen_name( obj_id, attr_name ) ) < 0 ) + { + H5LT_close_id( obj_id, statbuf.type ); + return -1; + } + + /* Get the dataspace handle */ + if ( (sid = H5Aget_space( attr_id )) < 0 ) + goto out; + + /* Get rank */ + if ( (*rank = H5Sget_simple_extent_ndims( sid )) < 0 ) + goto out; + + /* Terminate access to the attribute */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* End access to the attribute */ + if ( H5Aclose( attr_id ) ) + goto out;; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +out: + H5Aclose( attr_id ); + H5LT_close_id( obj_id, statbuf.type ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_info + * + * Purpose: Gets information about an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 4, 2001 + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTget_attribute_info( hid_t loc_id, + const char *obj_name, + const char *attr_name, + hsize_t *dims, + H5T_class_t *type_class, + size_t *type_size ) +{ + hid_t attr_id; + hid_t tid; + hid_t sid; + H5G_stat_t statbuf; + hid_t obj_id; + + /* Get the type of object */ + if (H5Gget_objinfo( loc_id, obj_name, 1, &statbuf )<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Open the attribute. */ + if ( ( attr_id = H5Aopen_name( obj_id, attr_name ) ) < 0 ) + { + H5LT_close_id( obj_id, statbuf.type ); + return -1; + } + + /* Get an identifier for the datatype. */ + tid = H5Aget_type( attr_id ); + + /* Get the class. */ + *type_class = H5Tget_class( tid ); + + /* Get the size. */ + *type_size = H5Tget_size( tid ); + + /* Get the dataspace handle */ + if ( (sid = H5Aget_space( attr_id )) < 0 ) + goto out; + + /* Get dimensions */ + if ( H5Sget_simple_extent_dims( sid, dims, NULL) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( tid ) ) + goto out; + + /* End access to the attribute */ + if ( H5Aclose( attr_id ) ) + goto out; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +out: + H5Tclose( tid ); + H5Aclose( attr_id ); + H5LT_close_id( obj_id, statbuf.type ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * + * General functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5LTcreate_compound_type + * + * Purpose: + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 18, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + +hid_t H5LTcreate_compound_type( hsize_t nfields, size_t size, const char *field_names[], + const size_t *field_offset, const hid_t *field_types ) +{ + + hid_t tid; + hsize_t i; + + /* Create the memory data type. */ + if ((tid = H5Tcreate (H5T_COMPOUND, size )) < 0 ) + goto out; + + /* Insert fields. */ + for ( i = 0; i < nfields; i++) + { + if ( H5Tinsert(tid, field_names[i], field_offset[i], field_types[i] ) < 0 ) + goto out; + } + + return tid; + +out: + return -1; +} + + + + + +/*------------------------------------------------------------------------- + * Function: H5LTrepack + * + * Purpose: Packs/Unpacks data from buffers. This function transfers data from a packed + * data, src_buf, to a "natural byte aligned" (an n-byte item at an n-byte boundary) + * data, dst_buf, and vice-versa. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: January 17, 2002 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTrepack( hsize_t nfields, + hsize_t nrecords, + size_t src_size, + const size_t *src_offset, + const size_t *src_sizes, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + unsigned char *src_buf, + unsigned char *dst_buf ) +{ + hsize_t i, j; + /* size of each field of destination data counting with padding */ + size_t *size_pad = (size_t *)malloc((size_t)nfields * sizeof(size_t)); + + /* Shut compiler */ + src_size=src_size; + src_offset=src_offset; + + if ( size_pad == NULL ) + goto out; + + for ( i= 0; i < nfields; i++) + { + + size_pad[i] = ( i == nfields-1 ? dst_size-dst_offset[i] : dst_offset[i+1]-dst_offset[i] ); + + } + + /* Iterate tru the records */ + for ( i = 0; i < nrecords; i++) + { + /* Iterate tru the members */ + for ( j = 0; j < nfields; j++) + { + + memcpy( dst_buf, src_buf, dst_sizes[j] ); + dst_buf += size_pad[j]; + src_buf += src_sizes[j]; + + } + + } + + if ( size_pad != NULL ) + free( size_pad ); + +return 0; + +out: + return -1; + +} + + +/*------------------------------------------------------------------------- + * + * Get attribute functions + * + *------------------------------------------------------------------------- + */ + + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_string + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTget_attribute_string( hid_t loc_id, + const char *obj_name, + const char *attr_name, + char *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_disk( obj_id, attr_name, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_char + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5LTget_attribute_char( hid_t loc_id, + const char *obj_name, + const char *attr_name, + char *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_CHAR, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_uchar + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5LTget_attribute_uchar( hid_t loc_id, + const char *obj_name, + const char *attr_name, + unsigned char *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_UCHAR, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + + + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_short + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5LTget_attribute_short( hid_t loc_id, + const char *obj_name, + const char *attr_name, + short *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_SHORT, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_ushort + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5LTget_attribute_ushort( hid_t loc_id, + const char *obj_name, + const char *attr_name, + unsigned short *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_USHORT, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + + + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_int + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5LTget_attribute_int( hid_t loc_id, + const char *obj_name, + const char *attr_name, + int *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_INT, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_uint + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5LTget_attribute_uint( hid_t loc_id, + const char *obj_name, + const char *attr_name, + unsigned int *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_UINT, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + + + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_long + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5LTget_attribute_long( hid_t loc_id, + const char *obj_name, + const char *attr_name, + long *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_LONG, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_ulong + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5LTget_attribute_ulong( hid_t loc_id, + const char *obj_name, + const char *attr_name, + unsigned long *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_ULONG, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_float + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTget_attribute_float( hid_t loc_id, + const char *obj_name, + const char *attr_name, + float *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_FLOAT, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute_double + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTget_attribute_double( hid_t loc_id, + const char *obj_name, + const char *attr_name, + double *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, H5T_NATIVE_DOUBLE, data ) < 0 ) + return -1; + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; + +} + + +/*------------------------------------------------------------------------- + * Function: H5LTget_attribute + * + * Purpose: Reads an attribute named attr_name with the memory type mem_type_id + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: Private function + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTget_attribute( hid_t loc_id, + const char *obj_name, + const char *attr_name, + hid_t mem_type_id, + void *data ) +{ + + /* identifiers */ + hid_t obj_id; + H5G_stat_t statbuf; + + /* Get the type of object */ + if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0) + return -1; + + /* Open the object */ + if ((obj_id = H5LT_open_id( loc_id, obj_name, statbuf.type )) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_mem( obj_id, attr_name, mem_type_id, data ) < 0 ) + { + H5LT_close_id( obj_id, statbuf.type ); + return -1; + } + + /* Close the object */ + if ( H5LT_close_id( obj_id, statbuf.type ) < 0 ) + return -1; + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5LT_get_attribute_mem + * + * Purpose: Reads an attribute named attr_name with the memory type mem_type_id + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: Private function + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LT_get_attribute_mem( hid_t obj_id, + const char *attr_name, + hid_t mem_type_id, + void *data ) +{ + + /* identifiers */ + hid_t attr_id; + + if ( ( attr_id = H5Aopen_name( obj_id, attr_name ) ) < 0 ) + return -1; + + if ( H5Aread( attr_id, mem_type_id, data ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + return -1; + + return 0; + +out: + H5Aclose( attr_id ); + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5LT_get_attribute_disk + * + * Purpose: Reads an attribute named attr_name with the datatype stored on disk + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: September 19, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5LT_get_attribute_disk( hid_t loc_id, + const char *attr_name, + void *attr_out ) +{ + /* identifiers */ + hid_t attr_id; + hid_t attr_type; + + if ( ( attr_id = H5Aopen_name( loc_id, attr_name ) ) < 0 ) + return -1; + + if ( (attr_type = H5Aget_type( attr_id )) < 0 ) + goto out; + + if ( H5Aread( attr_id, attr_type, attr_out ) < 0 ) + goto out; + + if ( H5Tclose( attr_type ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + return -1;; + + return 0; + +out: + H5Tclose( attr_type ); + H5Aclose( attr_id ); + return -1; +} + + + + diff --git a/hl/src/H5LT.h b/hl/src/H5LT.h new file mode 100644 index 0000000..aa4b1b1 --- /dev/null +++ b/hl/src/H5LT.h @@ -0,0 +1,374 @@ + +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + + +#ifndef _H5LT_H +#define _H5LT_H + +#include + +#define TESTING(WHAT) {printf("%-70s", "Testing " WHAT); fflush(stdout);} +#define PASSED() {puts(" PASSED");fflush(stdout);} +#define H5_FAILED() {puts("*FAILED*");fflush(stdout);} +#define SKIPPED() {puts(" -SKIP-");fflush(stdout);} +#define EXAMPLE(WHAT) {printf("%-70s", "Example " WHAT); fflush(stdout);} + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*------------------------------------------------------------------------- + * + * Make dataset functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTmake_dataset( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + hid_t type_id, + const void *buffer ); + +herr_t H5LTmake_dataset_char( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const char *buffer ); + +herr_t H5LTmake_dataset_short( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const short *buffer ); + +herr_t H5LTmake_dataset_int( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const int *buffer ); + +herr_t H5LTmake_dataset_long( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const long *buffer ); + +herr_t H5LTmake_dataset_float( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const float *buffer ); + +herr_t H5LTmake_dataset_double( hid_t loc_id, + const char *dset_name, + int rank, + const hsize_t *dims, + const double *buffer ); + +herr_t H5LTmake_dataset_string(hid_t loc_id, + const char *dset_name, + const char *buf ); + + +/*------------------------------------------------------------------------- + * + * Read dataset functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTread_dataset( hid_t loc_id, + const char *dset_name, + hid_t type_id, + void *buffer ); + +herr_t H5LTread_dataset_char( hid_t loc_id, + const char *dset_name, + char *buffer ); + +herr_t H5LTread_dataset_short( hid_t loc_id, + const char *dset_name, + short *buffer ); + +herr_t H5LTread_dataset_int( hid_t loc_id, + const char *dset_name, + int *buffer ); + +herr_t H5LTread_dataset_long( hid_t loc_id, + const char *dset_name, + long *buffer ); + +herr_t H5LTread_dataset_float( hid_t loc_id, + const char *dset_name, + float *buffer ); + +herr_t H5LTread_dataset_double( hid_t loc_id, + const char *dset_name, + double *buffer ); + +herr_t H5LTread_dataset_string( hid_t loc_id, + const char *dset_name, + char *buf ); + +/*------------------------------------------------------------------------- + * + * Query dataset functions + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTget_dataset_ndims( hid_t loc_id, + const char *dset_name, + int *rank ); + +herr_t H5LTget_dataset_info( hid_t loc_id, + const char *dset_name, + hsize_t *dims, + H5T_class_t *type_class, + size_t *type_size ); + +herr_t H5LTfind_dataset( hid_t loc_id, const char *name ); + + + +/*------------------------------------------------------------------------- + * + * Set attribute functions + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTset_attribute_string( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const char *attr_data ); + +herr_t H5LTset_attribute_char( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const char *buffer, + size_t size ); + +herr_t H5LTset_attribute_uchar( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const unsigned char *buffer, + size_t size ); + +herr_t H5LTset_attribute_short( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const short *buffer, + size_t size ); + +herr_t H5LTset_attribute_ushort( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const unsigned short *buffer, + size_t size ); + +herr_t H5LTset_attribute_int( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const int *buffer, + size_t size ); + +herr_t H5LTset_attribute_uint( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const unsigned int *buffer, + size_t size ); + +herr_t H5LTset_attribute_long( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const long *buffer, + size_t size ); + +herr_t H5LTset_attribute_ulong( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const unsigned long *buffer, + size_t size ); + +herr_t H5LTset_attribute_float( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const float *buffer, + size_t size ); + +herr_t H5LTset_attribute_double( hid_t loc_id, + const char *obj_name, + const char *attr_name, + const double *buffer, + size_t size ); + +/*------------------------------------------------------------------------- + * + * Get attribute functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5LTget_attribute( hid_t loc_id, + const char *obj_name, + const char *attr_name, + hid_t mem_type_id, + void *data ); + +herr_t H5LTget_attribute_string( hid_t loc_id, + const char *obj_name, + const char *attr_name, + char *data ); + +herr_t H5LTget_attribute_char( hid_t loc_id, + const char *obj_name, + const char *attr_name, + char *data ); + +herr_t H5LTget_attribute_uchar( hid_t loc_id, + const char *obj_name, + const char *attr_name, + unsigned char *data ); + +herr_t H5LTget_attribute_short( hid_t loc_id, + const char *obj_name, + const char *attr_name, + short *data ); + +herr_t H5LTget_attribute_ushort( hid_t loc_id, + const char *obj_name, + const char *attr_name, + unsigned short *data ); + +herr_t H5LTget_attribute_int( hid_t loc_id, + const char *obj_name, + const char *attr_name, + int *data ); + +herr_t H5LTget_attribute_uint( hid_t loc_id, + const char *obj_name, + const char *attr_name, + unsigned int *data ); + +herr_t H5LTget_attribute_long( hid_t loc_id, + const char *obj_name, + const char *attr_name, + long *data ); + +herr_t H5LTget_attribute_ulong( hid_t loc_id, + const char *obj_name, + const char *attr_name, + unsigned long *data ); + +herr_t H5LTget_attribute_float( hid_t loc_id, + const char *obj_name, + const char *attr_name, + float *data ); + +herr_t H5LTget_attribute_double( hid_t loc_id, + const char *obj_name, + const char *attr_name, + double *data ); + + +/*------------------------------------------------------------------------- + * + * Query attribute functions + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LTget_attribute_ndims( hid_t loc_id, + const char *obj_name, + const char *attr_name, + int *rank ); + +herr_t H5LTget_attribute_info( hid_t loc_id, + const char *obj_name, + const char *attr_name, + hsize_t *dims, + H5T_class_t *type_class, + size_t *type_size ); + + + + + +/*------------------------------------------------------------------------- + * + * General functions + * + *------------------------------------------------------------------------- + */ + + +hid_t H5LTcreate_compound_type( hsize_t nfields, size_t size, const char *field_names[], + const size_t *field_offset, const hid_t *field_types ); + + +herr_t H5LTrepack( hsize_t nfields, + hsize_t nrecords, + size_t src_size, + const size_t *src_offset, + const size_t *src_sizes, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + unsigned char *src_buf, + unsigned char *dst_buf ); + + + +/*------------------------------------------------------------------------- + * + * Private functions + * + *------------------------------------------------------------------------- + */ + + +herr_t H5LT_get_attribute_mem( hid_t obj_id, + const char *attr_name, + hid_t mem_type_id, + void *data ); + +herr_t H5LT_get_attribute_disk( hid_t obj_id, + const char *attr_name, + void *data ); + +herr_t H5LT_find_attribute( hid_t loc_id, const char *name ); + + +herr_t H5LT_set_attribute_numerical( hid_t loc_id, + const char *obj_name, + const char *attr_name, + size_t size, + hid_t type_id, + const void *data ); + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hl/src/H5TA.c b/hl/src/H5TA.c new file mode 100644 index 0000000..79a845b --- /dev/null +++ b/hl/src/H5TA.c @@ -0,0 +1,3689 @@ +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + +#include "H5TA.h" +#include +#include + +#if 0 +#define SHRINK +#endif + + +/*------------------------------------------------------------------------- + * + * Private functions + * + *------------------------------------------------------------------------- + */ + +int H5TB_find_field(const char *field, + const char *field_list); + +herr_t H5TB_attach_attributes(const char *table_title, + hid_t loc_id, + const char *dset_name, + hsize_t nfields, + hid_t tid ); + +hid_t H5TB_create_type(hid_t loc_id, + const char *dset_name, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + hid_t ftype_id); + +/*------------------------------------------------------------------------- + * + * Create functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5TBmake_table + * + * Purpose: Make a table + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * Quincey Koziol + * + * Date: January 17, 2001 + * + * Comments: The data is packed + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBmake_table( const char *table_title, + hid_t loc_id, + const char *dset_name, + hsize_t nfields, + hsize_t nrecords, + size_t type_size, + const char *field_names[], + const size_t *field_offset, + const hid_t *field_types, + hsize_t chunk_size, + void *fill_data, + int compress, + const void *data ) +{ + + hid_t did; + hid_t sid; + hid_t mem_type_id; + hid_t plist_id; + hsize_t dims[1]; + hsize_t dims_chunk[1]; + hsize_t maxdims[1] = { H5S_UNLIMITED }; + char attr_name[255]; + char *member_name; + hid_t attr_id; + char aux[255]; + hsize_t i; + unsigned char *tmp_buf; + + dims[0] = nrecords; + dims_chunk[0] = chunk_size; + + /* Create the memory data type. */ + if ((mem_type_id = H5Tcreate (H5T_COMPOUND, type_size )) < 0 ) + return -1; + + /* Insert fields. */ + for ( i = 0; i < nfields; i++) + { + if ( H5Tinsert(mem_type_id, field_names[i], field_offset[i], field_types[i] ) < 0 ) + return -1; + } + + /* Create a simple data space with unlimited size */ + if ( (sid = H5Screate_simple( 1, dims, maxdims )) < 0 ) + return -1; + + /* Modify dataset creation properties, i.e. enable chunking */ + plist_id = H5Pcreate (H5P_DATASET_CREATE); + if ( H5Pset_chunk ( plist_id, 1, dims_chunk ) < 0 ) + return -1; + + /* Set the fill value using a struct as the data type. */ + if ( fill_data ) + { + if ( H5Pset_fill_value( plist_id, mem_type_id, fill_data ) < 0 ) + return -1; + } + + /* + Dataset creation property list is modified to use + GZIP compression with the compression effort set to 6. + Note that compression can be used only when dataset is chunked. + */ + if ( compress ) + { + if ( H5Pset_deflate( plist_id, 6) < 0 ) + return -1; + } + + /* Create the dataset. */ + if ( (did = H5Dcreate( loc_id, dset_name, mem_type_id, sid, plist_id )) < 0 ) + goto out; + + /* Only write if there is something to write */ + if ( data ) + { + /* Write data to the dataset. */ + if ( H5Dwrite( did, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 ) + goto out; + } + + /* Terminate access to the data space. */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( did ) < 0 ) + goto out; + + /* End access to the property list */ + if ( H5Pclose( plist_id ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Set the conforming table attributes + *------------------------------------------------------------------------- + */ + + /* Attach the CLASS attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "CLASS", "TABLE" ) < 0 ) + goto out; + + /* Attach the VERSION attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "VERSION", "2.0" ) < 0 ) + goto out; + + /* Attach the TITLE attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "TITLE", table_title ) < 0 ) + goto out; + + /* Attach the FIELD_ name attribute */ + for ( i = 0; i < nfields; i++) + { + + /* Get the member name */ + member_name = H5Tget_member_name( mem_type_id,(unsigned) i ); + + strcpy( attr_name, "FIELD_" ); + sprintf( aux, "%d", (int)i ); + strcat( attr_name, aux ); + sprintf( aux, "%s", "_NAME" ); + strcat( attr_name, aux ); + + /* Attach the attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, attr_name, member_name ) < 0 ) + goto out; + + free( member_name ); + + } + + /* Attach the FIELD_ fill value attribute */ + if ( fill_data ) + { + + tmp_buf = fill_data; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + if (( sid = H5Screate(H5S_SCALAR)) < 0 ) + goto out; + + for ( i = 0; i < nfields; i++) + { + + /* Get the member name */ + member_name = H5Tget_member_name( mem_type_id, (unsigned) i ); + + strcpy( attr_name, "FIELD_" ); + sprintf( aux, "%d", (int)i ); + strcat( attr_name, aux ); + sprintf( aux, "%s", "_FILL" ); + strcat( attr_name, aux ); + + if ( (attr_id = H5Acreate( did, attr_name, field_types[i], sid, H5P_DEFAULT )) < 0 ) + goto out; + + if ( H5Awrite( attr_id, field_types[i], tmp_buf+field_offset[i] ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + free( member_name ); + } + + /* Close the dataset. */ + H5Dclose( did ); + + /* Close data space. */ + H5Sclose( sid ); + } + + /* Release the datatype. */ + if ( H5Tclose( mem_type_id ) < 0 ) + return -1; + + +return 0; + +/* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Sclose(sid); + H5Pclose(plist_id); + H5Tclose(mem_type_id); + } H5E_END_TRY; + return -1; + +} + +/*------------------------------------------------------------------------- + * + * Write functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5TBappend_records + * + * Purpose: Appends records to a table + * + * Return: Success: 0, Failure: -1 + * + * Programmers: + * Pedro Vicente, pvn@ncsa.uiuc.edu + * Quincey Koziol + * + * Date: November 19, 2001 + * + * Comments: Uses memory offsets + * + * Modifications: April 1, 2004 + * the DST_SIZES parameter is used to define the memory type ID + * returned by H5TB_create_type + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBappend_records( hid_t loc_id, + const char *dset_name, + hsize_t nrecords, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + const void *data ) +{ + hid_t did; + hid_t tid=-1; + hid_t mem_type_id=-1; + hsize_t count[1]; + hssize_t offset[1]; + hid_t sid=-1; + hid_t mem_space_id=-1; + int rank; + hsize_t dims[1]; + hsize_t mem_dims[1]; + hsize_t nrecords_orig; + hsize_t nfields; + + /* Get the original number of records and fields */ + if ( H5TBget_table_info ( loc_id, dset_name, &nfields, &nrecords_orig ) < 0 ) + return -1; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + goto out; + + /* Get the datatypes */ + if ( (tid = H5Dget_type( did )) < 0 ) + goto out; + + if ((mem_type_id=H5TB_create_type(loc_id,dset_name,dst_size,dst_offset,dst_sizes,tid))<0) + goto out; + + /* Extend the dataset */ + dims[0] = nrecords_orig; + dims[0] += nrecords; + + if ( H5Dextend ( did, dims ) < 0 ) + goto out; + + /* Create a simple memory data space */ + mem_dims[0]=nrecords; + if ( (mem_space_id = H5Screate_simple( 1, mem_dims, NULL )) < 0 ) + return -1; + + /* Get the file data space */ + if ( (sid = H5Dget_space( did )) < 0 ) + return -1; + + /* Get the dimensions */ + if ( (rank = H5Sget_simple_extent_dims( sid, dims, NULL )) != 1 ) + goto out; + + /* Define a hyperslab in the dataset */ + offset[0] = nrecords_orig; + count[0] = nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + if ( H5Dwrite( did, mem_type_id, mem_space_id, sid, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( tid ) < 0 ) + return -1; + + /* Release the datatype. */ + if ( H5Tclose( mem_type_id ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( did ) < 0 ) + goto out; + + +return 0; + +/* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Tclose(mem_type_id); + H5Tclose(tid); + H5Sclose(mem_space_id); + H5Sclose(sid); + } H5E_END_TRY; + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5TBwrite_records + * + * Purpose: Writes records + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 19, 2001 + * + * Comments: Uses memory offsets + * + * Modifications: April 1, 2004 + * the DST_SIZES parameter is used to define the memory type ID + * returned by H5TB_create_type + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBwrite_records( hid_t loc_id, + const char *dset_name, + hsize_t start, + hsize_t nrecords, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + const void *data ) +{ + + hid_t did; + hid_t tid; + hsize_t count[1]; + hssize_t offset[1]; + hid_t sid=-1; + hid_t mem_space_id=-1; + hsize_t mem_size[1]; + hsize_t dims[1]; + hid_t mem_type_id=-1; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Get the datatype */ + if ( (tid = H5Dget_type( did )) < 0 ) + goto out; + + if ((mem_type_id=H5TB_create_type(loc_id,dset_name,dst_size,dst_offset,dst_sizes,tid))<0) + goto out; + + /* Get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* Get records */ + if ( H5Sget_simple_extent_dims( sid, dims, NULL) < 0 ) + goto out; + + if ( start + nrecords > dims[0] ) + goto out; + + /* Define a hyperslab in the dataset of the size of the records */ + offset[0] = start; + count[0] = nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Create a memory dataspace handle */ + mem_size[0] = count[0]; + if ( (mem_space_id = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + if ( H5Dwrite( did, mem_type_id, mem_space_id, sid, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* Terminate access to the memory dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( tid ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( mem_type_id ) < 0 ) + return -1; + + /* End access to the dataset */ + if ( H5Dclose( did ) < 0 ) + return -1; + + +return 0; + +/* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Tclose(mem_type_id); + H5Tclose(tid); + H5Sclose(mem_space_id); + H5Sclose(sid); + } H5E_END_TRY; + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5TBwrite_fields_name + * + * Purpose: Writes fields + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 21, 2001 + * + * Comments: + * + * Modifications: April 1, 2004 + * the DST_SIZES parameter is used to define the memory type ID + * returned by H5TB_create_type + * + *------------------------------------------------------------------------- + */ +herr_t H5TBwrite_fields_name( hid_t loc_id, + const char *dset_name, + const char *field_names, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + const void *data ) +{ + + hid_t did; + hid_t tid=-1; + hid_t write_type_id=-1; + hid_t member_type_id; + hid_t nmtype_id; + hsize_t count[1]; + hssize_t offset[1]; + hid_t sid=-1; + char *member_name; + hssize_t nfields; + hssize_t i, j; + hid_t PRESERVE; + size_t size_native; + + /* Create xfer properties to preserve initialized data */ + if ((PRESERVE = H5Pcreate (H5P_DATASET_XFER))<0) + return -1; + if (H5Pset_preserve (PRESERVE, 1)<0) + return -1; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + goto out; + + /* Get the datatype */ + if ( (tid = H5Dget_type( did )) < 0 ) + goto out; + + /* Get the number of fields */ + if ( ( nfields = H5Tget_nmembers( tid )) < 0 ) + goto out; + + /* Create a write id */ + if ( ( write_type_id = H5Tcreate( H5T_COMPOUND, type_size )) < 0 ) + goto out; + + j = 0; + + /* Iterate tru the members */ + for ( i = 0; i < nfields; i++) + { + /* Get the member name */ + member_name = H5Tget_member_name( tid, (unsigned)i ); + + if ( H5TB_find_field( member_name, field_names ) > 0 ) + { + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( tid,(unsigned) i )) < 0 ) + goto out; + + /* Convert to native type */ + if ((nmtype_id=H5Tget_native_type(member_type_id,H5T_DIR_DEFAULT))<0) + goto out; + + size_native=H5Tget_size(nmtype_id); + + /* Adjust, if necessary */ + if (dst_sizes[j]!=size_native) + { + if (H5Tset_size(nmtype_id, dst_sizes[j])<0) + goto out; + } + + /* The field in the file is found by its name */ + if ( field_offset ) + { + if ( H5Tinsert( write_type_id, member_name, field_offset[j], nmtype_id ) < 0 ) + goto out; + } + /* Only one field */ + else + { + if ( H5Tinsert( write_type_id, member_name, 0, nmtype_id ) < 0 ) + goto out; + } + + j++; + + /* Close */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + if ( H5Tclose( nmtype_id ) < 0 ) + goto out; + } + + free( member_name ); + + } + + /* Get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* Define a hyperslab in the dataset */ + offset[0] = start; + count[0] = nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Write */ + if ( H5Dwrite( did, write_type_id, H5S_ALL, sid, PRESERVE, data ) < 0 ) + goto out; + + /* End access to the write id */ + if ( H5Tclose( write_type_id ) ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( tid ) < 0 ) + return -1; + + /* End access to the dataset */ + if ( H5Dclose( did ) < 0 ) + return -1; + + /* End access to the property list */ + if ( H5Pclose( PRESERVE ) < 0 ) + return -1; + +return 0; + + /* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Pclose(PRESERVE); + H5Dclose(did); + H5Sclose(sid); + H5Tclose(write_type_id); + H5Tclose(tid); + } H5E_END_TRY; + return -1; + +} + + + +/*------------------------------------------------------------------------- + * Function: H5TBwrite_fields_index + * + * Purpose: Writes fields + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 21, 2001 + * + * Comments: Uses memory offsets + * + * Modifications: April 1, 2004 + * the DST_SIZES parameter is used to define the memory type ID + * returned by H5TB_create_type + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBwrite_fields_index( hid_t loc_id, + const char *dset_name, + hsize_t nfields, + const int *field_index, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + const void *data ) +{ + + hid_t did; + hid_t tid=-1; + hid_t write_type_id=-1; + hid_t member_type_id; + hid_t nmtype_id; + hsize_t count[1]; + hssize_t offset[1]; + hid_t sid=-1; + char *member_name; + int nmenbers; + hsize_t i, j; + hid_t PRESERVE; + size_t size_native; + + /* Create xfer properties to preserve initialized data */ + if ((PRESERVE = H5Pcreate (H5P_DATASET_XFER))<0) + return -1; + if (H5Pset_preserve (PRESERVE, 1)<0) + return -1; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + goto out; + + /* Get the datatype */ + if ( (tid = H5Dget_type( did )) < 0 ) + goto out; + + /* Get the number of fields */ + if ( ( nmenbers = H5Tget_nmembers( tid )) < 0 ) + goto out; + + /* Create a write id */ + if ( ( write_type_id = H5Tcreate( H5T_COMPOUND, type_size )) < 0 ) + goto out; + + + /* Iterate tru the members */ + for ( i = 0; i < nfields; i++) + { + + j = field_index[i]; + + /* Get the member name */ + member_name = H5Tget_member_name( tid, (unsigned) j ); + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( tid, (unsigned) j )) < 0 ) + goto out; + + /* Convert to native type */ + if ((nmtype_id=H5Tget_native_type(member_type_id,H5T_DIR_DEFAULT))<0) + goto out; + + size_native=H5Tget_size(nmtype_id); + + if (dst_sizes[i]!=size_native) + { + if (H5Tset_size(nmtype_id, dst_sizes[i])<0) + goto out; + } + + /* The field in the file is found by its name */ + if ( field_offset ) + { + if ( H5Tinsert( write_type_id, member_name, field_offset[ i ], nmtype_id ) < 0 ) + goto out; + } + /* Only one field */ + else + { + if ( H5Tinsert( write_type_id, member_name, 0, nmtype_id ) < 0 ) + goto out; + } + /* Close */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + if ( H5Tclose( nmtype_id ) < 0 ) + goto out; + + free( member_name ); + + } + + /* Get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* Define a hyperslab in the dataset */ + offset[0] = start; + count[0] = nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Write */ + if ( H5Dwrite( did, write_type_id, H5S_ALL, sid, PRESERVE, data ) < 0 ) + goto out; + + /* End access to the write id */ + if ( H5Tclose( write_type_id ) ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( tid ) < 0 ) + return -1; + + /* End access to the dataset */ + if ( H5Dclose( did ) < 0 ) + return -1; + + /* End access to the property list */ + if ( H5Pclose( PRESERVE ) < 0 ) + return -1; + +return 0; + + /* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Pclose(PRESERVE); + H5Dclose(did); + H5Sclose(sid); + H5Tclose(write_type_id); + H5Tclose(tid); + } H5E_END_TRY; + return -1; +} + + +/*------------------------------------------------------------------------- + * + * Read functions + * + *------------------------------------------------------------------------- + */ + + +/*------------------------------------------------------------------------- + * Function: H5TBread_table + * + * Purpose: Reads a table + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 20, 2001 + * + * Comments: + * + * Modifications: April 1, 2004 + * used a memory type ID returned by H5TB_create_type + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBread_table( hid_t loc_id, + const char *dset_name, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + void *dst_buf ) +{ + hid_t did; + hid_t ftype_id=-1; + hid_t mem_type_id=-1; + hid_t sid; + hsize_t dims[1]; + + /* open the dataset. */ + if ((did=H5Dopen(loc_id,dset_name))<0) + return -1; + + /* get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* get dimensions */ + if ( H5Sget_simple_extent_dims( sid, dims, NULL) < 0 ) + goto out; + + /* get the datatypes */ + if ((ftype_id=H5Dget_type (did))<0) + goto out; + + if ((mem_type_id=H5TB_create_type(loc_id,dset_name,dst_size,dst_offset,dst_sizes,ftype_id))<0) + goto out; + + /* read */ + if ( H5Dread( did, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, dst_buf) < 0 ) + goto out; + + /* close */ + if ( H5Tclose( ftype_id ) < 0 ) + goto out; + if ( H5Tclose( mem_type_id ) < 0 ) + goto out; + if ( H5Sclose( sid ) < 0 ) + goto out; + if ( H5Dclose( did ) < 0 ) + return -1; + + return 0; + + /* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Tclose(mem_type_id); + H5Tclose(ftype_id); + H5Sclose(sid); + } H5E_END_TRY; + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5TBread_records + * + * Purpose: Reads records + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 19, 2001 + * + * Comments: + * + * Modifications: April 1, 2004 + * the DST_SIZES parameter is used to define the memory type ID + * returned by H5TB_create_type + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBread_records( hid_t loc_id, + const char *dset_name, + hsize_t start, + hsize_t nrecords, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + void *data ) +{ + + hid_t did; + hid_t ftype_id; + hid_t mem_type_id=-1; + hsize_t count[1]; + hssize_t offset[1]; + hid_t sid=-1; + hsize_t dims[1]; + hid_t mem_space_id=-1; + hsize_t mem_size[1]; + hsize_t nrecords_orig; + hsize_t nfields; + + /* get the number of records and fields */ + if ( H5TBget_table_info ( loc_id, dset_name, &nfields, &nrecords_orig ) < 0 ) + return -1; + + /* open the dataset */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* get the datatypes */ + if ( (ftype_id = H5Dget_type( did )) < 0 ) + goto out; + + if ((mem_type_id=H5TB_create_type(loc_id,dset_name,dst_size,dst_offset,dst_sizes,ftype_id))<0) + goto out; + + /* get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* get records */ + if ( H5Sget_simple_extent_dims( sid, dims, NULL) < 0 ) + goto out; + + if ( start + nrecords > dims[0] ) + goto out; + + /* define a hyperslab in the dataset of the size of the records */ + offset[0] = start; + count[0] = nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* create a memory dataspace handle */ + mem_size[0] = count[0]; + if ( (mem_space_id = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + /* read */ + if ( H5Dread( did, mem_type_id, mem_space_id, sid, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* close */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + if ( H5Sclose( sid ) < 0 ) + goto out; + if ( H5Tclose( ftype_id ) < 0 ) + return -1; + if ( H5Tclose( mem_type_id ) < 0 ) + return -1; + if ( H5Dclose( did ) < 0 ) + return -1; + + return 0; + + /* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Tclose(mem_type_id); + H5Tclose(ftype_id); + H5Sclose(mem_space_id); + H5Sclose(sid); + } H5E_END_TRY; + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5TBread_fields_name + * + * Purpose: Reads fields + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 19, 2001 + * + * Comments: + * + * Modifications: April 1, 2004 + * the DST_SIZES parameter is used to define the memory type ID + * returned by H5TB_create_type + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBread_fields_name( hid_t loc_id, + const char *dset_name, + const char *field_names, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + void *data ) +{ + + hid_t did; + hid_t ftype_id=-1; + hid_t mem_type_id=-1; + hid_t mtype_id; + hid_t nmtype_id; + char *member_name; + hssize_t nfields; + hsize_t count[1]; + hssize_t offset[1]; + hid_t sid=-1; + hid_t mem_space_id=-1; + hsize_t mem_size[1]; + size_t size_native; + hssize_t i, j; + + /* open the dataset */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + goto out; + + /* get the datatype */ + if ( (ftype_id = H5Dget_type( did )) < 0 ) + goto out; + + /* get the number of fields */ + if ( ( nfields = H5Tget_nmembers( ftype_id )) < 0 ) + goto out; + + /* create a memory read id */ + if ( ( mem_type_id = H5Tcreate( H5T_COMPOUND, type_size )) < 0 ) + goto out; + + /* iterate tru the members */ + for ( i=0,j=0; i 0 ) + { + /* get the member type */ + if ( ( mtype_id = H5Tget_member_type( ftype_id, (unsigned) i )) < 0 ) + goto out; + + /* convert to native type */ + if ((nmtype_id=H5Tget_native_type(mtype_id,H5T_DIR_DEFAULT))<0) + goto out; + + size_native=H5Tget_size(nmtype_id); + + if (dst_sizes[j]!=size_native) + { + if (H5Tset_size(nmtype_id, dst_sizes[j])<0) + goto out; + } + /* the field in the file is found by its name */ + if ( field_offset ) + { + if ( H5Tinsert( mem_type_id, member_name, field_offset[j], nmtype_id ) < 0 ) + goto out; + } + else + { + if ( H5Tinsert( mem_type_id, member_name, 0, nmtype_id ) < 0 ) + goto out; + } + + /* close */ + if ( H5Tclose( mtype_id ) < 0 ) + goto out; + if ( H5Tclose( nmtype_id ) < 0 ) + goto out; + j++; + } + free( member_name ); + } + + /* get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* define a hyperslab in the dataset */ + offset[0] = start; + count[0] = nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* create a memory dataspace handle */ + mem_size[0] = count[0]; + if ( (mem_space_id = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + /* read */ + if ( H5Dread( did, mem_type_id, mem_space_id, sid, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* close */ + if ( H5Tclose( mem_type_id ) ) + goto out; + if ( H5Tclose( ftype_id ) < 0 ) + return -1; + if ( H5Sclose( sid ) < 0 ) + goto out; + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + if ( H5Dclose( did ) < 0 ) + return -1; + + return 0; + +/* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Tclose(mem_type_id); + H5Tclose(ftype_id); + H5Sclose(mem_space_id); + H5Sclose(sid); + } H5E_END_TRY; + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5TBread_fields_index + * + * Purpose: Reads fields + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 19, 2001 + * + * Comments: + * + * Modifications: April 1, 2004 + * the DST_SIZES parameter is used to define the memory type ID + * returned by H5TB_create_type + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBread_fields_index( hid_t loc_id, + const char *dset_name, + hsize_t nfields, + const int *field_index, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + void *data ) +{ + + hid_t did; + hid_t tid=-1; + hid_t read_type_id=-1; + hid_t member_type_id; + hid_t nmtype_id; + hssize_t member_size; + char *member_name; + hsize_t count[1]; + hssize_t offset[1]; + hid_t sid=-1; + hid_t mem_space_id=-1; + hsize_t mem_size[1]; + size_t size_native; + hsize_t i, j; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + goto out; + + /* Get the datatype */ + if ( (tid = H5Dget_type( did )) < 0 ) + goto out; + + /* Create a read id */ + if ( ( read_type_id = H5Tcreate( H5T_COMPOUND, type_size )) < 0 ) + goto out; + + /* Iterate tru the members */ + for ( i = 0; i < nfields; i++) + { + j = field_index[i]; + + /* Get the member name */ + member_name = H5Tget_member_name( tid, (unsigned) j ); + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( tid, (unsigned) j )) < 0 ) + goto out; + + /* Get the member size */ + if ( ( member_size = H5Tget_size( member_type_id )) < 0 ) + goto out; + + /* Convert to native type */ + if ((nmtype_id=H5Tget_native_type(member_type_id,H5T_DIR_DEFAULT))<0) + goto out; + + size_native=H5Tget_size(nmtype_id); + + if (dst_sizes[i]!=size_native) + { + if (H5Tset_size(nmtype_id, dst_sizes[i])<0) + goto out; + } + + /* The field in the file is found by its name */ + if ( field_offset ) + { + if ( H5Tinsert( read_type_id, member_name, field_offset[i], nmtype_id ) < 0 ) + goto out; + } + else + { + if ( H5Tinsert( read_type_id, member_name, 0, nmtype_id ) < 0 ) + goto out; + } + + /* Close the member type */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + if ( H5Tclose( nmtype_id ) < 0 ) + goto out; + + free( member_name ); + } + + /* Get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* Define a hyperslab in the dataset */ + offset[0] = start; + count[0] = nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Create a memory dataspace handle */ + mem_size[0] = count[0]; + if ( (mem_space_id = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + /* Read */ + if ( H5Dread( did, read_type_id, mem_space_id, sid, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* Terminate access to the memory dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + + /* End access to the read id */ + if ( H5Tclose( read_type_id ) ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( tid ) < 0 ) + return -1; + + /* End access to the dataset */ + if ( H5Dclose( did ) < 0 ) + return -1; + +return 0; + +/* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Tclose(read_type_id); + H5Tclose(tid); + H5Sclose(mem_space_id); + H5Sclose(sid); + } H5E_END_TRY; + return -1; + +} + + +/*------------------------------------------------------------------------- + * + * Manipulation functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5TBdelete_record + * + * Purpose: Delete records from middle of table ("pulling up" all the records after it) + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 26, 2001 + * + * Modifications: April 29, 2003 + * + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBdelete_record( hid_t loc_id, + const char *dset_name, + hsize_t start, + hsize_t nrecords ) +{ + + hsize_t nfields; + hsize_t ntotal_records; + hsize_t read_start; + hsize_t read_nrecords; + hid_t did; + hid_t tid; + hsize_t count[1]; + hssize_t offset[1]; + hid_t sid; + hid_t mem_space_id; + hsize_t mem_size[1]; + unsigned char *tmp_buf; + size_t src_size; + size_t *src_offset; + size_t *src_sizes; + hsize_t nrows; +#if defined (SHRINK) + hsize_t dims[1]; +#endif + + +/*------------------------------------------------------------------------- + * First we get information about type size and offsets on disk + *------------------------------------------------------------------------- + */ + + /* Get the number of records and fields */ + if ( H5TBget_table_info ( loc_id, dset_name, &nfields, &ntotal_records ) < 0 ) + return -1; + + src_offset = (size_t *)malloc((size_t)nfields * sizeof(size_t)); + src_sizes = (size_t *)malloc((size_t)nfields * sizeof(size_t)); + + if ( src_offset == NULL ) + return -1; + + /* Get field info */ + if ( H5TBget_field_info( loc_id, dset_name, NULL, src_sizes, src_offset, &src_size ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Read the records after the deleted one(s) + *------------------------------------------------------------------------- + */ + + read_start = start + nrecords; + read_nrecords = ntotal_records - read_start; + tmp_buf = (unsigned char *)calloc((size_t) read_nrecords, src_size ); + + if ( tmp_buf == NULL ) + return -1; + + /* Read the records after the deleted one(s) */ + if ( H5TBread_records( loc_id, dset_name, read_start, read_nrecords, src_size, + src_offset, src_sizes, tmp_buf ) < 0 ) + return -1; + + +/*------------------------------------------------------------------------- + * Write the records in another position + *------------------------------------------------------------------------- + */ + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Get the datatype */ + if ( (tid = H5Dget_type( did )) < 0 ) + goto out; + + /* Get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* Define a hyperslab in the dataset of the size of the records */ + offset[0] = start; + count[0] = read_nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Create a memory dataspace handle */ + mem_size[0] = count[0]; + if ( (mem_space_id = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + if ( H5Dwrite( did, tid, mem_space_id, sid, H5P_DEFAULT, tmp_buf ) < 0 ) + goto out; + + /* Terminate access to the memory dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( tid ) < 0 ) + goto out; + + +/*------------------------------------------------------------------------- + * Change the table dimension + *------------------------------------------------------------------------- + */ +#if defined (SHRINK) + dims[0] = ntotal_records - nrecords; + if ( H5Dset_extent( did, dims ) < 0 ) + goto out; +#endif + + /* End access to the dataset */ + if ( H5Dclose( did ) < 0 ) + return -1; + + free( tmp_buf ); + free( src_offset ); + free( src_sizes ); + + +/*------------------------------------------------------------------------- + * Store the new dimension as an attribute + *------------------------------------------------------------------------- + */ + + nrows = ntotal_records - nrecords; + /* Set the attribute */ + if (H5LT_set_attribute_numerical(loc_id,dset_name,"NROWS",1, + H5T_NATIVE_LLONG,&nrows)<0) + return -1; + + + return 0; + +out: + H5Dclose( did ); + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5TBinsert_record + * + * Purpose: Inserts records into middle of table ("pushing down" all the records after it) + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 26, 2001 + * + * Comments: Uses memory offsets + * + * Modifications: April 1, 2004 + * the DST_SIZES parameter is used to define the memory type ID + * returned by H5TB_create_type + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBinsert_record( hid_t loc_id, + const char *dset_name, + hsize_t start, + hsize_t nrecords, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + void *data ) +{ + + hsize_t nfields; + hsize_t ntotal_records; + hsize_t read_nrecords; + hid_t did; + hid_t tid=-1; + hid_t mem_type_id=-1; + hsize_t count[1]; + hssize_t offset[1]; + hid_t sid=-1; + hid_t mem_space_id=-1; + hsize_t dims[1]; + hsize_t mem_dims[1]; + unsigned char *tmp_buf; + +/*------------------------------------------------------------------------- + * Read the records after the inserted one(s) + *------------------------------------------------------------------------- + */ + + /* Get the dimensions */ + if ( H5TBget_table_info ( loc_id, dset_name, &nfields, &ntotal_records ) < 0 ) + return -1; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + goto out; + + /* Get the datatype */ + if ( (tid = H5Dget_type( did )) < 0 ) + goto out; + + /* Create the memory data type. */ + if ((mem_type_id=H5TB_create_type(loc_id,dset_name,dst_size,dst_offset,dst_sizes,tid))<0) + goto out; + + read_nrecords = ntotal_records - start; + tmp_buf = (unsigned char *)calloc((size_t) read_nrecords, dst_size ); + + /* Read the records after the inserted one(s) */ + if ( H5TBread_records( loc_id, dset_name, start, read_nrecords, dst_size, dst_offset, + dst_sizes, tmp_buf ) < 0 ) + return -1; + + /* Extend the dataset */ + dims[0] = ntotal_records + nrecords; + + if ( H5Dextend ( did, dims ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Write the inserted records + *------------------------------------------------------------------------- + */ + + /* Create a simple memory data space */ + mem_dims[0]=nrecords; + if ( (mem_space_id = H5Screate_simple( 1, mem_dims, NULL )) < 0 ) + return -1; + + /* Get the file data space */ + if ( (sid = H5Dget_space( did )) < 0 ) + return -1; + + /* Define a hyperslab in the dataset to write the new data */ + offset[0] = start; + count[0] = nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + if ( H5Dwrite( did, mem_type_id, mem_space_id, sid, H5P_DEFAULT, data ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + if ( H5Sclose( sid ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Write the "pushed down" records + *------------------------------------------------------------------------- + */ + + /* Create a simple memory data space */ + mem_dims[0]=read_nrecords; + if ( (mem_space_id = H5Screate_simple( 1, mem_dims, NULL )) < 0 ) + return -1; + + /* Get the file data space */ + if ( (sid = H5Dget_space( did )) < 0 ) + return -1; + + /* Define a hyperslab in the dataset to write the new data */ + offset[0] = start + nrecords; + count[0] = read_nrecords; + if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + if ( H5Dwrite( did, mem_type_id, mem_space_id, sid, H5P_DEFAULT, tmp_buf ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + + if ( H5Sclose( sid ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( tid ) < 0 ) + return -1; + + /* Release the datatype. */ + if ( H5Tclose( mem_type_id ) < 0 ) + return -1; + + /* End access to the dataset */ + if ( H5Dclose( did ) < 0 ) + return -1; + + free( tmp_buf ); + + return 0; + + /* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Sclose(sid); + H5Sclose(mem_space_id); + H5Tclose(mem_type_id); + H5Tclose(tid); + } H5E_END_TRY; + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5TBadd_records_from + * + * Purpose: Add records from first table to second table + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: December 5, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBadd_records_from( hid_t loc_id, + const char *dset_name1, + hsize_t start1, + hsize_t nrecords, + const char *dset_name2, + hsize_t start2 ) +{ + + /* Identifiers for the 1st dataset. */ + hid_t dataset_id1; + hid_t type_id1; + hid_t space_id1=-1; + hid_t mem_space_id1=-1; + hssize_t type_size1; + + hsize_t count[1]; + hssize_t offset[1]; + hsize_t mem_size[1]; + hsize_t nfields; + hsize_t ntotal_records; + unsigned char *tmp_buf; + size_t src_size; + size_t *src_offset; + size_t *src_sizes; + +/*------------------------------------------------------------------------- + * First we get information about type size and offsets on disk + *------------------------------------------------------------------------- + */ + + /* Get the number of records and fields */ + if ( H5TBget_table_info ( loc_id, dset_name1, &nfields, &ntotal_records ) < 0 ) + return -1; + + src_offset = (size_t *)malloc((size_t)nfields * sizeof(size_t)); + src_sizes = (size_t *)malloc((size_t)nfields * sizeof(size_t)); + + if ( src_offset == NULL ) + return -1; + + /* Get field info */ + if ( H5TBget_field_info( loc_id, dset_name1, NULL, src_sizes, src_offset, &src_size ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Get information about the first table and read it + *------------------------------------------------------------------------- + */ + + /* Open the 1st dataset. */ + if ( (dataset_id1 = H5Dopen( loc_id, dset_name1 )) < 0 ) + return -1; + + /* Get the datatype */ + if ( (type_id1 = H5Dget_type( dataset_id1 )) < 0 ) + goto out; + + /* Get the dataspace handle */ + if ( (space_id1 = H5Dget_space( dataset_id1 )) < 0 ) + goto out; + + /* Get the size of the datatype */ + if ( ( type_size1 = H5Tget_size( type_id1 )) < 0 ) + goto out; + + tmp_buf = (unsigned char *)calloc((size_t)nrecords, (size_t)type_size1 ); + + /* Define a hyperslab in the dataset of the size of the records */ + offset[0] = start1; + count[0] = nrecords; + if ( H5Sselect_hyperslab( space_id1, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Create a memory dataspace handle */ + mem_size[0] = count[0]; + if ( (mem_space_id1 = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + if ( H5Dread( dataset_id1, type_id1, mem_space_id1, space_id1, H5P_DEFAULT, tmp_buf ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Add to the second table + *------------------------------------------------------------------------- + */ + if ( H5TBinsert_record(loc_id,dset_name2,start2,nrecords,src_size,src_offset,src_sizes,tmp_buf ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Close resources for table 1 + *------------------------------------------------------------------------- + */ + + /* Terminate access to the memory dataspace */ + if ( H5Sclose( mem_space_id1 ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( space_id1 ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( type_id1 ) < 0 ) + return -1; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id1 ) < 0 ) + return -1; + + free( tmp_buf ); + free( src_offset ); + free( src_sizes ); + +return 0; + + /* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(dataset_id1); + H5Sclose(space_id1); + H5Sclose(mem_space_id1); + H5Tclose(type_id1); + } H5E_END_TRY; + return -1; + +} + +/*------------------------------------------------------------------------- + * Function: H5TBcombine_tables + * + * Purpose: Combine records from two tables into a third + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: December 10, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t H5TBcombine_tables( hid_t loc_id1, + const char *dset_name1, + hid_t loc_id2, + const char *dset_name2, + const char *dset_name3 ) +{ + + /* Identifiers for the 1st dataset. */ + hid_t dataset_id1; + hid_t type_id1; + hid_t space_id1; + hid_t plist_id1; + + /* Identifiers for the 2nd dataset. */ + hid_t dataset_id2; + hid_t type_id2; + hid_t space_id2; + hid_t plist_id2; + + /* Identifiers for the 3rd dataset. */ + hid_t dataset_id3; + hid_t type_id3; + hid_t space_id3; + hid_t plist_id3; + + hsize_t count[1]; + hssize_t offset[1]; + hid_t mem_space_id; + hsize_t mem_size[1]; + hsize_t nfields; + hsize_t nrecords; + hsize_t dims[1]; + hsize_t maxdims[1] = { H5S_UNLIMITED }; + + + size_t type_size; + hid_t sid; + hid_t member_type_id; + hssize_t member_offset; + char attr_name[255]; + hid_t attr_id; + char aux[255]; + unsigned char *tmp_buf; + unsigned char *tmp_fill_buf; + hsize_t i; + size_t src_size; + size_t *src_offset; + size_t *src_sizes; + int has_fill=0; + +/*------------------------------------------------------------------------- + * First we get information about type size and offsets on disk + *------------------------------------------------------------------------- + */ + + /* Get the number of records and fields */ + if ( H5TBget_table_info ( loc_id1, dset_name1, &nfields, &nrecords ) < 0 ) + return -1; + + src_offset = (size_t *)malloc((size_t)nfields * sizeof(size_t)); + src_sizes = (size_t *)malloc((size_t)nfields * sizeof(size_t)); + + + if ( src_offset == NULL ) + return -1; + + /* Get field info */ + if ( H5TBget_field_info( loc_id1, dset_name1, NULL, src_sizes, src_offset, &src_size ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Get information about the first table + *------------------------------------------------------------------------- + */ + + /* Open the 1st dataset. */ + if ( (dataset_id1 = H5Dopen( loc_id1, dset_name1 )) < 0 ) + goto out; + + /* Get the datatype */ + if ( (type_id1 = H5Dget_type( dataset_id1 )) < 0 ) + goto out; + + /* Get the dataspace handle */ + if ( (space_id1 = H5Dget_space( dataset_id1 )) < 0 ) + goto out; + + /* Get creation properties list */ + if ( (plist_id1 = H5Dget_create_plist( dataset_id1 )) < 0 ) + goto out; + + /* Get the dimensions */ + if ( H5TBget_table_info ( loc_id1, dset_name1, &nfields, &nrecords ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Make the merged table with no data originally + *------------------------------------------------------------------------- + */ + + /* Clone the property list */ + if ( ( plist_id3 = H5Pcopy( plist_id1 )) < 0 ) + goto out; + + /* Clone the type id */ + if ( ( type_id3 = H5Tcopy( type_id1 )) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Here we do not clone the file space from the 1st dataset, because we want to create + * an empty table. Instead we create a new dataspace with zero records and expandable. + *------------------------------------------------------------------------- + */ + dims[0] = 0; + +/* Create a simple data space with unlimited size */ + if ( (space_id3 = H5Screate_simple( 1, dims, maxdims )) < 0 ) + return -1; + + /* Create the dataset */ + if ( (dataset_id3 = H5Dcreate( loc_id1, dset_name3, type_id3, space_id3, plist_id3 )) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Attach the conforming table attributes + *------------------------------------------------------------------------- + */ + if ( H5TB_attach_attributes( "Merge table", loc_id1, dset_name3, nfields, type_id3 ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Get attributes + *------------------------------------------------------------------------- + */ + + type_size = H5Tget_size( type_id3 ); + + /* alloc fill value attribute buffer */ + tmp_fill_buf = (unsigned char *)malloc((size_t) type_size ); + + /* Get the fill value attributes */ + has_fill=H5TBAget_fill( loc_id1, dset_name1, dataset_id1, tmp_fill_buf ); + +/*------------------------------------------------------------------------- + * Attach the fill attributes from previous table + *------------------------------------------------------------------------- + */ + if ( has_fill == 1 ) + { + + if (( sid = H5Screate(H5S_SCALAR)) < 0 ) + goto out; + + for ( i = 0; i < nfields; i++) + { + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( type_id3, (unsigned) i )) < 0 ) + goto out; + + /* Get the member offset */ + if ( ( member_offset = H5Tget_member_offset( type_id3, (unsigned) i )) < 0 ) + goto out; + + strcpy( attr_name, "FIELD_" ); + sprintf( aux, "%d", (int) i ); + strcat( attr_name, aux ); + sprintf( aux, "%s", "_FILL" ); + strcat( attr_name, aux ); + + if ( (attr_id = H5Acreate( dataset_id3, attr_name, member_type_id, sid, H5P_DEFAULT )) < 0 ) + goto out; + + if ( H5Awrite( attr_id, member_type_id, tmp_fill_buf+member_offset ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + } + + /* Close data space. */ + if ( H5Sclose( sid ) < 0 ) + goto out; + } + +/*------------------------------------------------------------------------- + * Read data from 1st table + *------------------------------------------------------------------------- + */ + + tmp_buf = (unsigned char *)calloc((size_t) nrecords, type_size ); + + /* Define a hyperslab in the dataset of the size of the records */ + offset[0] = 0; + count[0] = nrecords; + if ( H5Sselect_hyperslab( space_id1, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Create a memory dataspace handle */ + mem_size[0] = count[0]; + if ( (mem_space_id = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + if ( H5Dread( dataset_id1, type_id1, mem_space_id, space_id1, H5P_DEFAULT, tmp_buf ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Save data from 1st table into new table + *------------------------------------------------------------------------- + */ + + /* Append the records to the new table */ + if ( H5TBappend_records( loc_id1, dset_name3, nrecords, src_size, src_offset, src_sizes, tmp_buf ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Release resources from 1st table + *------------------------------------------------------------------------- + */ + + /* Terminate access to the memory dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( space_id1 ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( type_id1 ) < 0 ) + goto out; + + /* Terminate access to a property list */ + if ( H5Pclose( plist_id1 ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id1 ) < 0 ) + goto out; + + /* Release resources. */ + free( tmp_buf ); + +/*------------------------------------------------------------------------- + * Get information about the 2nd table + *------------------------------------------------------------------------- + */ + + /* Open the dataset. */ + if ( (dataset_id2 = H5Dopen( loc_id2, dset_name2 )) < 0 ) + goto out; + + /* Get the datatype */ + if ( (type_id2 = H5Dget_type( dataset_id2 )) < 0 ) + goto out; + + /* Get the dataspace handle */ + if ( (space_id2 = H5Dget_space( dataset_id2 )) < 0 ) + goto out; + + /* Get the property list handle */ + if ( (plist_id2 = H5Dget_create_plist( dataset_id2 )) < 0 ) + goto out; + + /* Get the dimensions */ + if ( H5TBget_table_info ( loc_id2, dset_name2, &nfields, &nrecords ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Read data from 2nd table + *------------------------------------------------------------------------- + */ + + tmp_buf = (unsigned char *)calloc((size_t) nrecords, type_size ); + + /* Define a hyperslab in the dataset of the size of the records */ + offset[0] = 0; + count[0] = nrecords; + if ( H5Sselect_hyperslab( space_id2, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Create a memory dataspace handle */ + mem_size[0] = count[0]; + if ( (mem_space_id = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + if ( H5Dread( dataset_id2, type_id2, mem_space_id, space_id2, H5P_DEFAULT, tmp_buf ) < 0 ) + goto out; + + +/*------------------------------------------------------------------------- + * Save data from 2nd table into new table + *------------------------------------------------------------------------- + */ + + /* append the records to the new table */ + if ( H5TBappend_records( loc_id1, dset_name3, nrecords, src_size, src_offset, src_sizes, tmp_buf ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Release resources from 2nd table + *------------------------------------------------------------------------- + */ + + /* Terminate access to the memory dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( space_id2 ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( type_id2 ) < 0 ) + return -1; + + /* Terminate access to a property list */ + if ( H5Pclose( plist_id2 ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id2 ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Release resources from 3rd table + *------------------------------------------------------------------------- + */ + + /* Terminate access to the dataspace */ + if ( H5Sclose( space_id3 ) < 0 ) + return -1; + + /* Release the datatype. */ + if ( H5Tclose( type_id3 ) < 0 ) + return -1; + + /* Terminate access to a property list */ + if ( H5Pclose( plist_id3 ) < 0 ) + return -1; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id3 ) < 0 ) + return -1; + + /* Release resources. */ + free( tmp_buf ); + free( tmp_fill_buf ); + free( src_offset ); + free( src_sizes ); + +return 0; + +out: + H5Dclose( dataset_id1 ); + return -1; + +} + + + +/*------------------------------------------------------------------------- + * Function: H5TBinsert_field + * + * Purpose: Inserts a field + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: January 30, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBinsert_field( hid_t loc_id, + const char *dset_name, + const char *field_name, + hid_t field_type, + hsize_t position, + const void *fill_data, + const void *data ) +{ + + /* Identifiers for the 1st, original dataset */ + hid_t dataset_id1; + hid_t type_id1; + hid_t space_id1; + hid_t plist_id1; + hid_t mem_space_id1; + + /* Identifiers for the 2nd, new dataset */ + hid_t dataset_id2; + hid_t type_id2; + hid_t space_id2; + hid_t plist_id2; + hid_t mem_space_id2; + + hid_t member_type_id; + size_t member_size; + size_t new_member_size = 0; + char *member_name; + hssize_t total_size; + hsize_t nfields; + hsize_t nrecords; + int rank_chunk; + hsize_t dims_chunk[1]; + hsize_t dims[1]; + hsize_t maxdims[1] = { H5S_UNLIMITED }; + hsize_t count[1]; + hssize_t offset[1]; + hsize_t mem_size[1]; + hid_t write_type_id; + hid_t PRESERVE; + size_t curr_offset; + int inserted; + hsize_t idx; + char table_title[255]; + hssize_t member_offset; + char attr_name[255]; + hid_t attr_id; + char aux[255]; + unsigned char *tmp_buf; + unsigned char *tmp_fill_buf; + hsize_t i; + + /* Get the number of records and fields */ + if ( H5TBget_table_info ( loc_id, dset_name, &nfields, &nrecords ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Get information about the old data type + *------------------------------------------------------------------------- + */ + + /* Open the dataset. */ + if ( (dataset_id1 = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Get creation properties list */ + if ( (plist_id1 = H5Dget_create_plist( dataset_id1 )) < 0 ) + goto out; + + /* Get the datatype */ + if ( (type_id1 = H5Dget_type( dataset_id1 )) < 0 ) + goto out; + + /* Get the size of the datatype */ + if ( ( total_size = H5Tget_size( type_id1 )) < 0 ) + goto out; + + /* Get the dataspace handle */ + if ( (space_id1 = H5Dget_space( dataset_id1 )) < 0 ) + goto out; + + /* Get dimension */ + if ( H5Sget_simple_extent_dims( space_id1, dims, NULL) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Get attributes + *------------------------------------------------------------------------- + */ + + /* Get the table title */ + if ( (H5TBAget_title( dataset_id1, table_title )) < 0 ) + goto out; + + /* alloc fill value attribute buffer */ + tmp_fill_buf = (unsigned char *)malloc((size_t) total_size ); + + /* Get the fill value attributes */ + if ( (H5TBAget_fill( loc_id, dset_name, dataset_id1, tmp_fill_buf )) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Create a new data type + *------------------------------------------------------------------------- + */ + + /* Get the new member size */ + member_size = H5Tget_size( field_type ); + + /* Create the data type. */ + if (( type_id2 = H5Tcreate (H5T_COMPOUND,(size_t)(total_size + member_size) )) < 0 ) + goto out; + + curr_offset = 0; + inserted = 0; + + /* Insert the old fields, counting with the new one */ + for ( i = 0; i < nfields + 1; i++) + { + + idx = i; + if ( inserted ) + idx = i - 1; + + if ( i == position ) + { + + /* Get the new member size */ + new_member_size = H5Tget_size( field_type ); + + /* Insert the new field type */ + if ( H5Tinsert( type_id2, field_name, curr_offset, field_type ) < 0 ) + goto out; + + curr_offset += new_member_size; + + inserted = 1; + + continue; + + } + + /* Get the member name */ + member_name = H5Tget_member_name( type_id1, (unsigned)idx ); + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( type_id1,(unsigned)idx )) < 0 ) + goto out; + + /* Get the member size */ + member_size = H5Tget_size( member_type_id ); + + /* Insert it into the new type */ + if ( H5Tinsert( type_id2, member_name, curr_offset, member_type_id ) < 0 ) + goto out; + + curr_offset += member_size; + + free( member_name ); + + /* Close the member type */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + + + } /* i */ + +/*------------------------------------------------------------------------- + * Create a new temporary dataset + *------------------------------------------------------------------------- + */ + + /* Retrieve the size of chunk */ + if ( ( rank_chunk = H5Pget_chunk( plist_id1, 1, dims_chunk )) < 0 ) + goto out; + + /* Create a new simple data space with unlimited size, using the dimension */ + if ( ( space_id2 = H5Screate_simple( 1, dims, maxdims )) < 0 ) + return -1; + + /* Modify dataset creation properties, i.e. enable chunking */ + plist_id2 = H5Pcreate (H5P_DATASET_CREATE); + if ( H5Pset_chunk ( plist_id2, 1, dims_chunk ) < 0 ) + return -1; + + /* Create the dataset. */ + if ( ( dataset_id2 = H5Dcreate( loc_id, "new", type_id2, space_id2, plist_id2 )) < 0 ) + goto out; + + +/*------------------------------------------------------------------------- + * Read data from 1st table + *------------------------------------------------------------------------- + */ + + tmp_buf = (unsigned char *)calloc((size_t) nrecords, (size_t)total_size ); + + /* Define a hyperslab in the dataset of the size of the records */ + offset[0] = 0; + count[0] = nrecords; + if ( H5Sselect_hyperslab( space_id1, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Create a memory dataspace handle */ + mem_size[0] = count[0]; + if ( (mem_space_id1 = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + if ( H5Dread( dataset_id1, type_id1, mem_space_id1, H5S_ALL, H5P_DEFAULT, tmp_buf ) < 0 ) + goto out; + + +/*------------------------------------------------------------------------- + * Save data from 1st table into new table, using the 1st type id + *------------------------------------------------------------------------- + */ + + /* Write */ + if ( H5Dwrite( dataset_id2, type_id1, mem_space_id1, H5S_ALL, H5P_DEFAULT, tmp_buf ) < 0 ) + goto out; + + +/*------------------------------------------------------------------------- + * Save the function supplied data of the new field + *------------------------------------------------------------------------- + */ + + + /* Create a write id */ + if ( ( write_type_id = H5Tcreate( H5T_COMPOUND, (size_t)new_member_size )) < 0 ) + goto out; + + /* The field in the file is found by its name */ + if ( H5Tinsert( write_type_id, field_name, 0, field_type ) < 0 ) + goto out; + + /* Create xfer properties to preserve initialized data */ + if ((PRESERVE = H5Pcreate (H5P_DATASET_XFER))<0) + goto out; + if (H5Pset_preserve (PRESERVE, 1)<0) + goto out; + + /* Only write if there is something to write */ + if ( data ) + { + + /* Create a memory dataspace handle */ + if ( (mem_space_id2 = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + + /* Write */ + if ( H5Dwrite( dataset_id2, write_type_id, mem_space_id2, space_id2, PRESERVE, data ) < 0 ) + goto out; + + /* Terminate access to the memory dataspace */ + if ( H5Sclose( mem_space_id2 ) < 0 ) + goto out; + } + + /* End access to the property list */ + if ( H5Pclose( PRESERVE ) < 0 ) + goto out; + + + +/*------------------------------------------------------------------------- + * Release resources from 1st table + *------------------------------------------------------------------------- + */ + + /* Terminate access to the memory dataspace */ + if ( H5Sclose( mem_space_id1 ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( type_id1 ) < 0 ) + goto out; + + /* Terminate access to a property list */ + if ( H5Pclose( plist_id1 ) < 0 ) + goto out; + + /* Terminate access to the data space */ + if ( H5Sclose( space_id1 ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id1 ) < 0 ) + goto out; + + +/*------------------------------------------------------------------------- + * Release resources from 2nd table + *------------------------------------------------------------------------- + */ + + /* Terminate access to the dataspace */ + if ( H5Sclose( space_id2 ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( type_id2 ) < 0 ) + return -1; + + /* Terminate access to a property list */ + if ( H5Pclose( plist_id2 ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id2 ) < 0 ) + return -1; +/*------------------------------------------------------------------------- + * Delete 1st table + *------------------------------------------------------------------------- + */ + if ( H5Gunlink( loc_id, dset_name ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Rename 2nd table + *------------------------------------------------------------------------- + */ + + if ( H5Gmove( loc_id, "new", dset_name ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Attach the conforming table attributes + *------------------------------------------------------------------------- + */ + + /* Get the number of records and fields */ + if ( H5TBget_table_info ( loc_id, dset_name, &nfields, &nrecords ) < 0 ) + return -1; + + /* Open the dataset. */ + if ( (dataset_id1 = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Get the datatype */ + if ( (type_id1 = H5Dget_type( dataset_id1 )) < 0 ) + goto out; + + /* Set the attributes */ + if ( H5TB_attach_attributes( table_title, loc_id, dset_name,(hsize_t) nfields, type_id1 ) < 0 ) + return -1; +/*------------------------------------------------------------------------- + * Attach the fill attributes from previous table + *------------------------------------------------------------------------- + */ + + if (( space_id1 = H5Screate(H5S_SCALAR)) < 0 ) + goto out; + + for ( i = 0; i < nfields-1; i++) + { + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( type_id1, (unsigned) i )) < 0 ) + goto out; + + /* Get the member offset */ + if ( ( member_offset = H5Tget_member_offset( type_id1, (unsigned) i )) < 0 ) + goto out; + + strcpy( attr_name, "FIELD_" ); + sprintf( aux, "%d", (int)i ); + strcat( attr_name, aux ); + sprintf( aux, "%s", "_FILL" ); + strcat( attr_name, aux ); + + if ( (attr_id = H5Acreate( dataset_id1, attr_name, member_type_id, space_id1, H5P_DEFAULT )) < 0 ) + goto out; + + if ( H5Awrite( attr_id, member_type_id, tmp_fill_buf+member_offset ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + /* Close the member type */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + } + +/*------------------------------------------------------------------------- + * Attach the fill attribute from the new field, if present + *------------------------------------------------------------------------- + */ + if ( fill_data ) + { + + strcpy( attr_name, "FIELD_" ); + sprintf( aux, "%d",(int)( nfields-1) ); + strcat( attr_name, aux ); + sprintf( aux, "%s", "_FILL" ); + strcat( attr_name, aux ); + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( type_id1, (unsigned)nfields-1 )) < 0 ) + goto out; + + if ( (attr_id = H5Acreate( dataset_id1, attr_name, member_type_id, space_id1, H5P_DEFAULT )) < 0 ) + goto out; + + if ( H5Awrite( attr_id, member_type_id, fill_data ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + + } + + /* Close data space. */ + if ( H5Sclose( space_id1 ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( type_id1 ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id1 ) < 0 ) + goto out; + + /* Release resources. */ + free ( tmp_buf ); + free ( tmp_fill_buf ); + + +return 0; + +out: + H5Dclose( dataset_id1 ); + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5TBdelete_field + * + * Purpose: Deletes a field + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: January 30, 2002 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBdelete_field( hid_t loc_id, + const char *dset_name, + const char *field_name ) +{ + + /* Identifiers for the 1st original dataset */ + hid_t dataset_id1; + hid_t type_id1; + hid_t space_id1; + hid_t plist_id1; + + /* Identifiers for the 2nd new dataset */ + hid_t dataset_id2; + hid_t type_id2; + hid_t space_id2; + hid_t plist_id2; + + hid_t member_type_id; + size_t member_size; + char *member_name; + size_t type_size1; + size_t type_size2; + hsize_t nfields; + hsize_t nrecords; + int rank_chunk; + hsize_t dims_chunk[1]; + hsize_t dims[1]; + hsize_t maxdims[1] = { H5S_UNLIMITED }; + hid_t PRESERVE; + size_t curr_offset; + size_t delete_member_size = 0; + hid_t read_type_id; + hid_t write_type_id; + unsigned char *tmp_buf; + unsigned char *tmp_fill_buf; + char attr_name[255]; + char aux[255]; + char table_title[255]; + size_t member_offset; + hid_t attr_id; + hsize_t i; + int has_fill=0; + + /* Get the number of records and fields */ + if ( H5TBget_table_info ( loc_id, dset_name, &nfields, &nrecords ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Get information about the old data type + *------------------------------------------------------------------------- + */ + + /* Open the dataset. */ + if ( (dataset_id1 = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Get creation properties list */ + if ( (plist_id1 = H5Dget_create_plist( dataset_id1 )) < 0 ) + goto out; + + /* Get the datatype */ + if ( (type_id1 = H5Dget_type( dataset_id1 )) < 0 ) + goto out; + + /* Get the size of the datatype */ + type_size1 = H5Tget_size( type_id1 ); + + /* Get the dataspace handle */ + if ( (space_id1 = H5Dget_space( dataset_id1 )) < 0 ) + goto out; + + /* Get dimension */ + if ( H5Sget_simple_extent_dims( space_id1, dims, NULL) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Create a new data type; first we find the size of the datatype to delete + *------------------------------------------------------------------------- + */ + + /* Check out the field */ + for ( i = 0; i < nfields; i++) + { + + /* Get the member name */ + member_name = H5Tget_member_name( type_id1,(unsigned) i ); + + /* We want to find the field to delete */ + if ( H5TB_find_field( member_name, field_name ) > 0 ) + { + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( type_id1,(unsigned) i )) < 0 ) + goto out; + + /* Get the member size */ + delete_member_size = H5Tget_size( member_type_id ); + + /* Close the member type */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + + free( member_name ); + + break; + + } + + free( member_name ); + + } /* i */ + + /* No field to delete was found */ + if ( delete_member_size == 0 ) + goto out; + +/*------------------------------------------------------------------------- + * Create a new data type; we now insert all the fields into the new type + *------------------------------------------------------------------------- + */ + + type_size2 = type_size1 - delete_member_size; + + /* Create the data type. */ + if (( type_id2 = H5Tcreate (H5T_COMPOUND, type_size2 )) < 0 ) + goto out; + + curr_offset = 0; + + /* alloc fill value attribute buffer */ + tmp_fill_buf = (unsigned char *)malloc((size_t) type_size2 ); + +/*------------------------------------------------------------------------- + * Get attributes from previous table in the process + *------------------------------------------------------------------------- + */ + + /* Get the table title */ + if ( (H5TBAget_title( dataset_id1, table_title )) < 0 ) + goto out; + + /* Insert the old fields except the one to delete */ + for ( i = 0; i < nfields; i++) + { + + /* Get the member name */ + member_name = H5Tget_member_name( type_id1, (unsigned) i ); + + /* We want to skip the field to delete */ + if ( H5TB_find_field( member_name, field_name ) > 0 ) + { + free( member_name ); + continue; + } + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( type_id1, (unsigned)i )) < 0 ) + goto out; + + /* Get the member size */ + member_size = H5Tget_size( member_type_id ); + + /* Insert it into the new type */ + if ( H5Tinsert( type_id2, member_name, curr_offset, member_type_id ) < 0 ) + goto out; + + /*------------------------------------------------------------------------- + * Get the fill value information + *------------------------------------------------------------------------- + */ + + strcpy( attr_name, "FIELD_" ); + sprintf( aux, "%d", (int)i ); + strcat( attr_name, aux ); + sprintf( aux, "%s", "_FILL" ); + strcat( attr_name, aux ); + + /* Check if we have the _FILL attribute */ + has_fill = H5LT_find_attribute( dataset_id1, attr_name ); + + /* Get it */ + if ( has_fill == 1 ) + { + if ( H5LT_get_attribute_disk( dataset_id1, attr_name, tmp_fill_buf+curr_offset ) < 0 ) + goto out; + } + + curr_offset += member_size; + + free( member_name ); + + /* Close the member type */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + + } /* i */ + +/*------------------------------------------------------------------------- + * Create a new temporary dataset + *------------------------------------------------------------------------- + */ + + /* Retrieve the size of chunk */ + if ( ( rank_chunk = H5Pget_chunk( plist_id1, 1, dims_chunk )) < 0 ) + goto out; + + /* Create a new simple data space with unlimited size, using the dimension */ + if ( ( space_id2 = H5Screate_simple( 1, dims, maxdims )) < 0 ) + return -1; + + /* Modify dataset creation properties, i.e. enable chunking */ + plist_id2 = H5Pcreate (H5P_DATASET_CREATE); + if ( H5Pset_chunk ( plist_id2, 1, dims_chunk ) < 0 ) + return -1; + + /* Create the dataset. */ + if ( ( dataset_id2 = H5Dcreate( loc_id, "new", type_id2, space_id2, plist_id2 )) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * We have to read field by field of the old dataset and save it into the new one + *------------------------------------------------------------------------- + */ + for ( i = 0; i < nfields; i++) + { + + /* Get the member name */ + member_name = H5Tget_member_name( type_id1,(unsigned) i ); + + /* Skip the field to delete */ + if ( H5TB_find_field( member_name, field_name ) > 0 ) + { + free( member_name ); + continue; + } + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( type_id1, (unsigned)i )) < 0 ) + goto out; + + /* Get the member size */ + member_size = H5Tget_size( member_type_id ); + + /* Create a read id */ + if ( ( read_type_id = H5Tcreate( H5T_COMPOUND, member_size )) < 0 ) + goto out; + + /* Insert it into the new type */ + if ( H5Tinsert( read_type_id, member_name, 0, member_type_id ) < 0 ) + goto out; + + tmp_buf = (unsigned char *)calloc((size_t) nrecords, member_size ); + + /* Read */ + if ( H5Dread( dataset_id1, read_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, tmp_buf ) < 0 ) + goto out; + + /* Create a write id */ + if ( ( write_type_id = H5Tcreate( H5T_COMPOUND, member_size )) < 0 ) + goto out; + + /* The field in the file is found by its name */ + if ( H5Tinsert( write_type_id, member_name, 0, member_type_id ) < 0 ) + goto out; + + /* Create xfer properties to preserve initialized data */ + if ((PRESERVE = H5Pcreate (H5P_DATASET_XFER))<0) + goto out; + if (H5Pset_preserve (PRESERVE, 1)<0) + goto out; + + /* Write */ + if ( H5Dwrite( dataset_id2, write_type_id, H5S_ALL, H5S_ALL, PRESERVE, tmp_buf ) < 0 ) + goto out; + + /* End access to the property list */ + if ( H5Pclose( PRESERVE ) < 0 ) + goto out; + + /* Close the member type */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + + /* Close the read type */ + if ( H5Tclose( read_type_id ) < 0 ) + goto out; + + /* Close the write type */ + if ( H5Tclose( write_type_id ) < 0 ) + goto out; + + /* Release resources. */ + free( member_name ); + free ( tmp_buf ); + + } /* i */ + +/*------------------------------------------------------------------------- + * Release resources from 1st table + *------------------------------------------------------------------------- + */ + + /* Release the datatype. */ + if ( H5Tclose( type_id1 ) < 0 ) + goto out; + + /* Terminate access to a property list */ + if ( H5Pclose( plist_id1 ) < 0 ) + goto out; + + /* Terminate access to the data space */ + if ( H5Sclose( space_id1 ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id1 ) < 0 ) + goto out; + + +/*------------------------------------------------------------------------- + * Release resources from 2nd table + *------------------------------------------------------------------------- + */ + + /* Terminate access to the dataspace */ + if ( H5Sclose( space_id2 ) < 0 ) + goto out; + + /* Release the datatype. */ + if ( H5Tclose( type_id2 ) < 0 ) + return -1; + + /* Terminate access to a property list */ + if ( H5Pclose( plist_id2 ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id2 ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Delete 1st table + *------------------------------------------------------------------------- + */ + + if ( H5Gunlink( loc_id, dset_name ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Rename 2nd table + *------------------------------------------------------------------------- + */ + + if ( H5Gmove( loc_id, "new", dset_name ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Attach the conforming table attributes + *------------------------------------------------------------------------- + */ + + /* Get the number of records and fields */ + if ( H5TBget_table_info ( loc_id, dset_name, &nfields, &nrecords ) < 0 ) + return -1; + + /* Open the dataset. */ + if ( (dataset_id1 = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Get the datatype */ + if ( (type_id1 = H5Dget_type( dataset_id1 )) < 0 ) + goto out; + + /* Set the attributes */ + if ( H5TB_attach_attributes( table_title, loc_id, dset_name, nfields, type_id1 ) < 0 ) + return -1; + +/*------------------------------------------------------------------------- + * Attach the fill attributes from previous table + *------------------------------------------------------------------------- + */ + + if ( has_fill == 1 ) + { + + if (( space_id1 = H5Screate(H5S_SCALAR)) < 0 ) + goto out; + + for ( i = 0; i < nfields; i++) + { + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( type_id1, (unsigned)i )) < 0 ) + goto out; + + /* Get the member offset */ + member_offset = H5Tget_member_offset( type_id1, (unsigned)i ); + + strcpy( attr_name, "FIELD_" ); + sprintf( aux, "%d", (int)i ); + strcat( attr_name, aux ); + sprintf( aux, "%s", "_FILL" ); + strcat( attr_name, aux ); + + if ( (attr_id = H5Acreate( dataset_id1, attr_name, member_type_id, space_id1, H5P_DEFAULT )) < 0 ) + goto out; + + if ( H5Awrite( attr_id, member_type_id, tmp_fill_buf+member_offset ) < 0 ) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + goto out; + + /* Close the member type */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + + } + + /* Close data space. */ + if ( H5Sclose( space_id1 ) < 0 ) + goto out; + + } /*has_fill*/ + + /* Release the datatype. */ + if ( H5Tclose( type_id1 ) < 0 ) + goto out; + + /* End access to the dataset */ + if ( H5Dclose( dataset_id1 ) < 0 ) + goto out; + + /* Release resources. */ + free ( tmp_fill_buf ); + +return 0; + +out: + H5Dclose( dataset_id1 ); + return -1; +} + +/*------------------------------------------------------------------------- + * + * Table attribute functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5TBAget_title + * + * Purpose: Read the table title + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: January 30, 2001 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBAget_title( hid_t loc_id, + char *table_title ) +{ + + /* Get the TITLE attribute */ + if ( H5LT_get_attribute_disk( loc_id, "TITLE", table_title ) < 0 ) + return -1; + + + return 0; + +} + +/*------------------------------------------------------------------------- + * Function: H5TBAget_fill + * + * Purpose: Read the table attribute fill values + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: January 30, 2002 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBAget_fill( hid_t loc_id, + const char *dset_name, + hid_t dset_id, + unsigned char *dst_buf ) +{ + + hsize_t nfields; + hsize_t nrecords; + char attr_name[255]; + char aux[255]; + hsize_t i; + size_t *src_offset; + int has_fill=0; + + /* Get the number of records and fields */ + if ( H5TBget_table_info ( loc_id, dset_name, &nfields, &nrecords ) < 0 ) + return -1; + + src_offset = (size_t *)malloc((size_t)nfields * sizeof(size_t)); + + if (src_offset == NULL ) + return -1; + + /* Get field info */ + if ( H5TBget_field_info( loc_id, dset_name, NULL, NULL, src_offset, NULL ) < 0 ) + goto out; + + for ( i = 0; i < nfields; i++) + { + strcpy( attr_name, "FIELD_" ); + sprintf( aux, "%d", (int)i ); + strcat( attr_name, aux ); + sprintf( aux, "%s", "_FILL" ); + strcat( attr_name, aux ); + + /* Check if we have the _FILL attribute */ + has_fill = H5LT_find_attribute( dset_id, attr_name ); + + /* Get it */ + if ( has_fill == 1 ) + { + if ( H5LT_get_attribute_disk( dset_id, attr_name, dst_buf+src_offset[i] ) < 0 ) + goto out; + } + + } + + free( src_offset ); + + return has_fill; + +out: + free( src_offset ); + return -1; + +} + + +/*------------------------------------------------------------------------- + * + * Inquiry functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5TBget_table_info + * + * Purpose: Gets the number of records and fields of a table + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 19, 2001 + * + * Comments: + * + * Modifications: May 08, 2003 + * In version 2.0 of Table, the number of records is stored as an + * attribute "NROWS" + * + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBget_table_info ( hid_t loc_id, + const char *dset_name, + hsize_t *nfields, + hsize_t *nrecords ) +{ + hid_t tid; + hid_t sid=-1; + hid_t did; + int num_members; + hsize_t dims[1]; + int has_attr; + hsize_t n[1]; + + /* Open the dataset. */ + if ( (did = H5Dopen( loc_id, dset_name )) < 0 ) + return -1; + + /* Get the datatype */ + if ( (tid = H5Dget_type( did )) < 0 ) + goto out; + + /* Get the number of members */ + if ( (num_members = H5Tget_nmembers( tid )) < 0 ) + goto out; + + if (nfields) + *nfields = num_members; + + +/*------------------------------------------------------------------------- + * Get number of records + *------------------------------------------------------------------------- + */ + + if (nrecords) + { + /* Try to find the attribute "NROWS" */ + has_attr = H5LT_find_attribute( did, "NROWS" ); + + /* It exists, get it */ + if ( has_attr == 1 ) + { + /* Get the attribute */ + if ( H5LTget_attribute(loc_id,dset_name,"NROWS",H5T_NATIVE_LLONG,n)<0) + return -1; + + *nrecords = *n; + } + else + { + /* Get the dataspace handle */ + if ( (sid = H5Dget_space( did )) < 0 ) + goto out; + + /* Get records */ + if ( H5Sget_simple_extent_dims( sid, dims, NULL) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( sid ) < 0 ) + goto out; + + *nrecords = dims[0]; + } + }/*nrecords*/ + + /* close */ + if ( H5Tclose( tid ) < 0 ) + goto out; + if ( H5Dclose( did ) < 0 ) + return -1; + +return 0; + +/* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Sclose(sid); + H5Tclose(tid); + } H5E_END_TRY; + return -1; + +} + +/*------------------------------------------------------------------------- + * Function: H5TBget_field_info + * + * Purpose: Get information about fields + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 19, 2001 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t H5TBget_field_info( hid_t loc_id, + const char *dset_name, + char *field_names[], + size_t *field_sizes, + size_t *field_offsets, + size_t *type_size ) +{ + hid_t did; + hid_t ftype_id; + hid_t native_type_id; + hssize_t nfields; + char *member_name; + hid_t member_type_id; + hid_t nativem_type_id; + size_t member_size; + size_t member_offset; + size_t size; + hssize_t i; + + /* Open the dataset. */ + if ( ( did = H5Dopen( loc_id, dset_name )) < 0 ) + goto out; + + /* Get the datatype */ + if ( ( ftype_id = H5Dget_type( did )) < 0 ) + goto out; + + if ((native_type_id = H5Tget_native_type(ftype_id,H5T_DIR_DEFAULT))<0) + goto out; + + /* Get the type size */ + size = H5Tget_size( native_type_id ); + + if ( type_size ) + *type_size = size; + + /* Get the number of members */ + if ( ( nfields = H5Tget_nmembers( ftype_id )) < 0 ) + goto out; + + /* Iterate tru the members */ + for ( i = 0; i < nfields; i++) + { + /* Get the member name */ + member_name = H5Tget_member_name( ftype_id, (unsigned)i ); + + if ( field_names ) + strcpy( field_names[i], member_name ); + + /* Get the member type */ + if ( ( member_type_id = H5Tget_member_type( ftype_id,(unsigned) i )) < 0 ) + goto out; + if ((nativem_type_id = H5Tget_native_type(member_type_id,H5T_DIR_DEFAULT))<0) + goto out; + + /* Get the member size */ + member_size = H5Tget_size( nativem_type_id ); + + if ( field_sizes ) + field_sizes[i] = member_size; + + /* Get the member offset */ + member_offset = H5Tget_member_offset( native_type_id,(unsigned) i ); + + if ( field_offsets ) + field_offsets[i] = member_offset; + + /* Close the member type */ + if ( H5Tclose( member_type_id ) < 0 ) + goto out; + if ( H5Tclose( nativem_type_id ) < 0 ) + goto out; + + free( member_name ); + + } /* i */ + + /* Release the datatype. */ + if ( H5Tclose( ftype_id ) < 0 ) + return -1; + if ( H5Tclose( native_type_id ) < 0 ) + return -1; + + /* End access to the dataset */ + if ( H5Dclose( did ) < 0 ) + return -1; + +return 0; + +out: + H5Dclose( did ); + return -1; + +} + +/*------------------------------------------------------------------------- + * + * Private functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5TB_find_field + * + * Purpose: Find a string field + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: November 19, 2001 + * + *------------------------------------------------------------------------- + */ + + +int H5TB_find_field( const char *field, const char *field_list ) +{ + const char *start = field_list; + const char *end; + + while ( (end = strstr( start, "," )) != 0 ) { + if ( strncmp(start,field,(size_t)(end-start)) == 0 ) return 1; + start = end + 1; + } + + if ( strcmp( start, field ) == 0 ) return 1; + + return -1; + +} + + +/*------------------------------------------------------------------------- + * Function: H5TB_attach_attributes + * + * Purpose: Private function that creates the conforming table attributes; + * Used by H5TBcombine_tables; not used by H5TBmake_table, which does not read + * the fill value attributes from an existing table + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: December 6, 2001 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TB_attach_attributes( const char *table_title, + hid_t loc_id, + const char *dset_name, + hsize_t nfields, + hid_t tid ) +{ + + char attr_name[255]; + char *member_name; + char aux[255]; + hsize_t i; + + /* Attach the CLASS attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "CLASS", "TABLE" ) < 0 ) + goto out; + + /* Attach the VERSION attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "VERSION", "2.0" ) < 0 ) + goto out; + + /* Attach the TITLE attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, "TITLE", table_title ) < 0 ) + goto out; + + /* Attach the FIELD_ name attribute */ + for ( i = 0; i < nfields; i++) + { + + /* Get the member name */ + member_name = H5Tget_member_name( tid, (unsigned)i ); + + strcpy( attr_name, "FIELD_" ); + sprintf( aux, "%d", (int)i ); + strcat( attr_name, aux ); + sprintf( aux, "%s", "_NAME" ); + strcat( attr_name, aux ); + + /* Attach the attribute */ + if ( H5LTset_attribute_string( loc_id, dset_name, attr_name, member_name ) < 0 ) + goto out; + + free( member_name ); + + } + + return 0; + +out: + return -1; + +} + +/*------------------------------------------------------------------------- + * Function: H5TB_create_type + * + * Purpose: Private function that creates a memory type ID + * + * Return: Success: the memory type ID, Failure: -1 + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: March 31, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +hid_t H5TB_create_type(hid_t loc_id, + const char *dset_name, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + hid_t ftype_id) +{ + hid_t mem_type_id; + hid_t mtype_id=-1; + hid_t nmtype_id=-1; + size_t size_native; + hsize_t nfields; + char **fnames; + unsigned i; + + /* get the number of fields */ + if (H5TBget_table_info(loc_id,dset_name,&nfields,NULL)<0) + return -1; + + if ((fnames=malloc(sizeof(char*)*(size_t)nfields))==NULL) + return -1; + + for ( i=0; i(Y)?(X):(Y)) +#endif + + + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*------------------------------------------------------------------------- + * + * Create functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBmake_table( const char *table_title, + hid_t loc_id, + const char *dset_name, + hsize_t nfields, + hsize_t nrecords, + size_t type_size, + const char *field_names[], + const size_t *field_offset, + const hid_t *field_types, + hsize_t chunk_size, + void *fill_data, + int compress, + const void *data ); + + +/*------------------------------------------------------------------------- + * + * Write functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBappend_records( hid_t loc_id, + const char *dset_name, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + const void *data ); + +herr_t H5TBwrite_records( hid_t loc_id, + const char *dset_name, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + const void *data ); + + +herr_t H5TBwrite_fields_name( hid_t loc_id, + const char *dset_name, + const char *field_names, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + const void *data ); + +herr_t H5TBwrite_fields_index( hid_t loc_id, + const char *dset_name, + hsize_t nfields, + const int *field_index, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + const void *data ); + + +/*------------------------------------------------------------------------- + * + * Read functions + * + *------------------------------------------------------------------------- + */ + + + +herr_t H5TBread_table( hid_t loc_id, + const char *dset_name, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + void *dst_buf ); + + +herr_t H5TBread_fields_name( hid_t loc_id, + const char *dset_name, + const char *field_names, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + void *data ); + +herr_t H5TBread_fields_index( hid_t loc_id, + const char *dset_name, + hsize_t nfields, + const int *field_index, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *field_offset, + const size_t *dst_sizes, + void *data ); + + +herr_t H5TBread_records( hid_t loc_id, + const char *dset_name, + hsize_t start, + hsize_t nrecords, + size_t type_size, + const size_t *dst_offset, + const size_t *dst_sizes, + void *data ); + +/*------------------------------------------------------------------------- + * + * Inquiry functions + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBget_table_info ( hid_t loc_id, + const char *dset_name, + hsize_t *nfields, + hsize_t *nrecords ); + +herr_t H5TBget_field_info( hid_t loc_id, + const char *dset_name, + char *field_names[], + size_t *field_sizes, + size_t *field_offsets, + size_t *type_size ); + + +/*------------------------------------------------------------------------- + * + * Manipulation functions + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBdelete_record( hid_t loc_id, + const char *dset_name, + hsize_t start, + hsize_t nrecords ); + + +herr_t H5TBinsert_record( hid_t loc_id, + const char *dset_name, + hsize_t start, + hsize_t nrecords, + size_t dst_size, + const size_t *dst_offset, + const size_t *dst_sizes, + void *data ); + +herr_t H5TBadd_records_from( hid_t loc_id, + const char *dset_name1, + hsize_t start1, + hsize_t nrecords, + const char *dset_name2, + hsize_t start2 ); + +herr_t H5TBcombine_tables( hid_t loc_id1, + const char *dset_name1, + hid_t loc_id2, + const char *dset_name2, + const char *dset_name3 ); + +herr_t H5TBinsert_field( hid_t loc_id, + const char *dset_name, + const char *field_name, + hid_t field_type, + hsize_t position, + const void *fill_data, + const void *data ); + +herr_t H5TBdelete_field( hid_t loc_id, + const char *dset_name, + const char *field_name ); + + +/*------------------------------------------------------------------------- + * + * Table attribute functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBAget_title( hid_t loc_id, + char *table_title ); + +herr_t H5TBAget_fill( hid_t loc_id, + const char *dset_name, + hid_t dset_id, + unsigned char *dst_buf ); + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/hl/src/Makefile.in b/hl/src/Makefile.in new file mode 100644 index 0000000..07b8020 --- /dev/null +++ b/hl/src/Makefile.in @@ -0,0 +1,34 @@ +## HDF5 Library Makefile(.in) +## +## Copyright (C) 2001 National Center for Supercomputing Applications. +## All rights reserved. +## +## +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +@COMMENCE@ + +## Add `-I.' to the C preprocessor flags. +CPPFLAGS=-I. -I$(srcdir) -I$(top_builddir)/src -I$(top_srcdir)/src -I$(top_srcdir)/tools/lib @CPPFLAGS@ + +## This is our main target, but also remove the settings file when cleaning. +LIB=libhdf5_hl.la +LIBHDF5=$(top_builddir)/src/libhdf5.la +CLEAN= + +## Source and object files for the library (lexicographically)... +LIB_SRC=H5LT.c H5TA.c H5IM.c + +LIB_OBJ=$(LIB_SRC:.c=.lo) + +## Temporary files +MOSTLYCLEAN= + +## Public header files (to be installed)... +PUB_HDR=H5IM.h H5LT.h H5TA.h + +## Other header files (not to be installed)... +PRIVATE_HDR= + +@CONCLUDE@ diff --git a/hl/test/Dependencies b/hl/test/Dependencies new file mode 100644 index 0000000..256da53 --- /dev/null +++ b/hl/test/Dependencies @@ -0,0 +1,69 @@ +## This file is machine generated on GNU systems. +## Only temporary changes may be made here. + +lite_dset_test.lo: \ + $(srcdir)/lite_dset_test.c \ + $(top_srcdir)/src/H5LT.h +lite_attr_test.lo: \ + $(srcdir)/lite_attr_test.c \ + $(top_srcdir)/src/H5LT.h +image_test.lo: \ + $(srcdir)/image_test.c \ + $(top_srcdir)/src/H5IM.h \ + $(top_srcdir)/src/H5LT.h +image_demo.lo: \ + $(srcdir)/image_demo.c \ + $(top_srcdir)/src/H5IM.h \ + $(top_srcdir)/src/H5LT.h \ + $(srcdir)/pal_rgb.h +image_make.lo: \ + $(srcdir)/image_make.c \ + $(top_srcdir)/src/H5IM.h \ + $(top_srcdir)/src/H5LT.h \ + $(srcdir)/pal_rgb.h +make_table.lo: \ + $(srcdir)/make_table.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +append_record.lo: \ + $(srcdir)/append_record.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +write_record_fill.lo: \ + $(srcdir)/write_record_fill.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +field_names.lo: \ + $(srcdir)/field_names.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +field_index.lo: \ + $(srcdir)/field_index.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +query_table.lo: \ + $(srcdir)/query_table.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +insert_record.lo: \ + $(srcdir)/insert_record.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +delete_record.lo: \ + $(srcdir)/delete_record.c +add_record_from.lo: \ + $(srcdir)/add_record_from.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +combine_tables.lo: \ + $(srcdir)/combine_tables.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +insert_field.lo: \ + $(srcdir)/insert_field.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h +delete_field.lo: \ + $(srcdir)/delete_field.c \ + $(top_srcdir)/src/H5TB.h \ + $(top_srcdir)/src/H5LT.h diff --git a/hl/test/test_image.c b/hl/test/test_image.c new file mode 100644 index 0000000..d47cab1 --- /dev/null +++ b/hl/test/test_image.c @@ -0,0 +1,197 @@ + +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING f. * + * * + ****************************************************************************/ + + + +#include "H5IM.h" + +#define FILE_NAME "test_image.h5" +#define WIDTH (hsize_t)500 +#define HEIGHT (hsize_t)200 +unsigned char image_in1 [ WIDTH*HEIGHT ]; +unsigned char image_out1[ WIDTH*HEIGHT ]; +unsigned char image_in2 [ WIDTH*HEIGHT*3 ]; +unsigned char image_out2[ WIDTH*HEIGHT*3 ]; + + +/*------------------------------------------------------------------------- + * the main program + *------------------------------------------------------------------------- + */ +int main( void ) +{ + hid_t file_id; + herr_t status; + hsize_t width, height, planes; + hsize_t pal_dims[] = {9,3}; + hsize_t pal_dims_out[2]; + hsize_t i; + char interlace[20]; + hssize_t npals; + herr_t is_image; + herr_t is_palette; + + unsigned char pal_data_out[9*3]; + /* create a 9 entry grey palette */ + unsigned char pal_data_in[9*3] = {0,0,0, + 25,25,25, + 50,50,50, + 75,75,75, + 100,100,100, + 125,125,125, + 150,150,150, + 175,175,175, + 200,200,200}; + + for (i = 0; i < WIDTH*HEIGHT; i++ ) + image_in1[i] = (unsigned char)i; + for (i = 0; i < WIDTH*HEIGHT*3; i++) + image_in2[i] = (unsigned char)i; + + /* Create a new HDF5 file using default properties. */ + file_id = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT ); + +/*------------------------------------------------------------------------- + * Indexed image test + *------------------------------------------------------------------------- + */ + + TESTING("indexed image"); + + /* Write image */ + if ( H5IMmake_image_8bit( file_id, "Image1", WIDTH, HEIGHT, image_in1 ) < 0 ) + goto out; + + /* Make a palette */ + if ( H5IMmake_palette( file_id, "Pallete", pal_dims, pal_data_in ) < 0 ) + goto out; + + /* Attach a palette to the image dataset */ + if ( H5IMlink_palette( file_id, "Image1", "Pallete" ) < 0 ) + goto out; + + /* Read image */ + if ( H5IMget_image_info( file_id, "Image1", &width, &height, &planes, interlace, &npals ) < 0 ) + goto out; + + if ( H5IMread_image( file_id, "Image1", image_out1 ) < 0 ) + goto out; + + for (i = 0; i < height*width*planes; i++) { + if ( image_in1[i] != image_out1[i] ) { + goto out; + + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * True color image test + *------------------------------------------------------------------------- + */ + + TESTING("true color image"); + + /* Write image */ + if ( H5IMmake_image_24bit( file_id, "Image2", WIDTH, HEIGHT, "INTERLACE_PIXEL", image_in2 ) ) + goto out; + + /* Read image */ + if ( H5IMget_image_info( file_id, "Image2", &width, &height, &planes, interlace, &npals ) < 0 ) + goto out; + + if ( H5IMread_image( file_id, "Image2", image_out2 ) < 0 ) + goto out; + + for (i = 0; i < height*width*planes; i++) { + if ( image_in2[i] != image_out2[i] ) { + goto out; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * H5IMget_npalettes test + *------------------------------------------------------------------------- + */ + + TESTING("pallete functions"); + + if ( H5IMget_npalettes( file_id, "Image1", &npals ) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * H5IMget_palette_info test + *------------------------------------------------------------------------- + */ + + if ( H5IMget_palette_info( file_id, "Image1", 0, pal_dims_out ) < 0 ) + goto out; + + for (i = 0; i < 2; i++) { + if ( pal_dims[i] != pal_dims_out[i] ) { + goto out; + } + } + +/*------------------------------------------------------------------------- + * H5IMget_palette test + *------------------------------------------------------------------------- + */ + + if ( H5IMget_palette( file_id, "Image1", 0, pal_data_out ) < 0 ) + goto out; + + for (i = 0; i < 9*3; i++) { + if ( pal_data_in[i] != pal_data_out[i] ) { + goto out; + } + } + +/*------------------------------------------------------------------------- + * H5IMis_image test + *------------------------------------------------------------------------- + */ + + if ( (is_image = H5IMis_image( file_id, "Image1" )) < 0 ) + goto out; + + if ( (is_image = H5IMis_image( file_id, "Image2" )) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * H5IMis_palette test + *------------------------------------------------------------------------- + */ + + if ( (is_palette = H5IMis_palette( file_id, "Pallete" )) < 0 ) + goto out; + +/*------------------------------------------------------------------------- + * end tests + *------------------------------------------------------------------------- + */ + + /* Close the file. */ + status = H5Fclose( file_id ); + + PASSED(); + return 0; + +out: + H5_FAILED(); + return 1; + +} diff --git a/hl/test/test_lite.c b/hl/test/test_lite.c new file mode 100644 index 0000000..bc5fb72 --- /dev/null +++ b/hl/test/test_lite.c @@ -0,0 +1,1071 @@ + +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING f. * + * * + ****************************************************************************/ + +#include + + +#include "H5LT.h" + + +#define FILE_NAME "test_lite1.h5" +#define FILE_NAME2 "test_lite2.h5" + +#define DSET0_NAME "2D int array" +#define DSET1_NAME "dataset char" +#define DSET2_NAME "dataset short" +#define DSET3_NAME "dataset int" +#define DSET4_NAME "dataset long" +#define DSET5_NAME "dataset float" +#define DSET6_NAME "dataset double" +#define DSET7_NAME "dataset string" + +#define DIM 6 + +#define ATTR1_NAME "attr string" +#define ATTR2_NAME "attr char" +#define ATTR3_NAME "attr short" +#define ATTR4_NAME "attr int" +#define ATTR5_NAME "attr long" +#define ATTR6_NAME "attr uchar" +#define ATTR7_NAME "attr ushort" +#define ATTR8_NAME "attr uint" +#define ATTR9_NAME "attr ulong" +#define ATTR10_NAME "attr float" +#define ATTR11_NAME "attr double" + +static herr_t make_attributes( hid_t loc_id, const char* obj_name ); + + + +/*------------------------------------------------------------------------- + * test dataset functions + *------------------------------------------------------------------------- + */ + +static int test_dsets( void ) +{ + int rank = 2; + hsize_t dims[2] = {2,3}; + hid_t file_id; + hid_t dataset_id; + char data_char_in[DIM] = {1,2,3,4,5,6}; + char data_char_out[DIM]; + short data_short_in[DIM] = {1,2,3,4,5,6}; + short data_short_out[DIM]; + int data_int_in[DIM] = {1,2,3,4,5,6}; + int data_int_out[DIM]; + long data_long_in[DIM] = {1,2,3,4,5,6}; + long data_long_out[DIM]; + float data_float_in[DIM] = {1,2,3,4,5,6}; + float data_float_out[DIM]; + double data_double_in[DIM] = {1,2,3,4,5,6}; + double data_double_out[DIM]; + char *data_string_in = "This is a string"; + char data_string_out[20]; + int i; + + + /* Create a new file using default properties. */ + file_id = H5Fcreate( FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT ); + +/*------------------------------------------------------------------------- + * H5LTmake_dataset test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTmake_dataset"); + + /* Make dataset */ + if ( H5LTmake_dataset( file_id, DSET0_NAME, rank, dims, H5T_NATIVE_INT, data_int_in ) < 0 ) + goto out; + + /* Read dataset using the basic HDF5 API */ + + if ( ( dataset_id = H5Dopen ( file_id, DSET0_NAME) ) < 0 ) + goto out; + + if ( H5Dread ( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data_int_out ) < 0 ) + goto out; + + if ( H5Dclose( dataset_id ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_int_in[i] != data_int_out[i] ) { + goto out; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * read using the LT function H5LTread_dataset + *------------------------------------------------------------------------- + */ + + TESTING("H5LTread_dataset"); + + if ( H5LTread_dataset( file_id, DSET0_NAME, H5T_NATIVE_INT, data_int_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_int_in[i] != data_int_out[i] ) { + goto out; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * test the H5LTmake_dataset_ functions + *------------------------------------------------------------------------- + */ + + +/*------------------------------------------------------------------------- + * H5LTmake_dataset_char + *------------------------------------------------------------------------- + */ + + TESTING("H5LTmake_dataset_char"); + + /* Make dataset char */ + if ( H5LTmake_dataset_char( file_id, DSET1_NAME, rank, dims, data_char_in ) < 0 ) + goto out; + + /* Read dataset */ + if ( H5LTread_dataset( file_id, DSET1_NAME, H5T_NATIVE_CHAR, data_char_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_char_in[i] != data_char_out[i] ) { + goto out; + } + } + + /* Read dataset */ + if ( H5LTread_dataset_char( file_id, DSET1_NAME, data_char_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_char_in[i] != data_char_out[i] ) { + goto out; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTmake_dataset_short + *------------------------------------------------------------------------- + */ + + TESTING("H5LTmake_dataset_short"); + + /* Make dataset short */ + if ( H5LTmake_dataset_short( file_id, DSET2_NAME, rank, dims, data_short_in ) < 0 ) + goto out; + + /* Read dataset */ + if ( H5LTread_dataset( file_id, DSET2_NAME, H5T_NATIVE_SHORT, data_short_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_short_in[i] != data_short_out[i] ) { + goto out; + } + } + + /* Read dataset */ + if ( H5LTread_dataset_short( file_id, DSET2_NAME, data_short_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_short_in[i] != data_short_out[i] ) { + goto out; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTmake_dataset_int + *------------------------------------------------------------------------- + */ + + TESTING("H5LTmake_dataset_int"); + + /* Make dataset int */ + if ( H5LTmake_dataset_int( file_id, DSET3_NAME, rank, dims, data_int_in ) < 0 ) + goto out; + + /* Read dataset */ + if ( H5LTread_dataset( file_id, DSET3_NAME, H5T_NATIVE_INT, data_int_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_int_in[i] != data_int_out[i] ) { + goto out; + } + } + + /* Read dataset */ + if ( H5LTread_dataset_int( file_id, DSET3_NAME, data_int_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_int_in[i] != data_int_out[i] ) { + goto out; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTmake_dataset_long + *------------------------------------------------------------------------- + */ + + TESTING("H5LTmake_dataset_long"); + + /* Make dataset long */ + if ( H5LTmake_dataset_long( file_id, DSET4_NAME, rank, dims, data_long_in ) < 0 ) + goto out; + + /* Read dataset */ + if ( H5LTread_dataset( file_id, DSET4_NAME, H5T_NATIVE_LONG, data_long_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_long_in[i] != data_long_out[i] ) { + goto out; + } + } + + /* Read dataset */ + if ( H5LTread_dataset_long( file_id, DSET4_NAME, data_long_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_long_in[i] != data_long_out[i] ) { + goto out; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTmake_dataset_float + *------------------------------------------------------------------------- + */ + + TESTING("H5LTmake_dataset_float"); + + /* Make dataset float */ + if ( H5LTmake_dataset_float( file_id, DSET5_NAME, rank, dims, data_float_in ) < 0 ) + goto out; + + /* Read dataset */ + if ( H5LTread_dataset( file_id, DSET5_NAME, H5T_NATIVE_FLOAT, data_float_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_float_in[i] != data_float_out[i] ) { + goto out; + } + } + + /* Read dataset */ + if ( H5LTread_dataset_float( file_id, DSET5_NAME, data_float_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_float_in[i] != data_float_out[i] ) { + goto out; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTmake_dataset_double + *------------------------------------------------------------------------- + */ + + TESTING("H5LTmake_dataset_double"); + + /* Make dataset double */ + if ( H5LTmake_dataset_double( file_id, DSET6_NAME, rank, dims, data_double_in ) < 0 ) + goto out; + + /* Read dataset */ + if ( H5LTread_dataset( file_id, DSET6_NAME, H5T_NATIVE_DOUBLE, data_double_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_double_in[i] != data_double_out[i] ) { + goto out; + } + } + + /* Read dataset */ + if ( H5LTread_dataset_double( file_id, DSET6_NAME, data_double_out ) < 0 ) + goto out; + + for (i = 0; i < DIM; i++) + { + if ( data_double_in[i] != data_double_out[i] ) { + goto out; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTmake_dataset_string + *------------------------------------------------------------------------- + */ + + TESTING("H5LTmake_dataset_string"); + + /* Make dataset string */ + if ( H5LTmake_dataset_string(file_id,DSET7_NAME,data_string_in) < 0 ) + goto out; + + /* Read dataset */ + if ( H5LTread_dataset_string(file_id,DSET7_NAME,data_string_out) < 0 ) + goto out; + + if ( strcmp(data_string_in,data_string_out) != 0 ) + goto out; + + + +/*------------------------------------------------------------------------- + * end tests + *------------------------------------------------------------------------- + */ + + /* Close the file. */ + H5Fclose( file_id ); + + PASSED(); + + + return 0; + +out: + /* Close the file. */ + H5_FAILED(); + return -1; +} + +/*------------------------------------------------------------------------- + * test attribute functions + *------------------------------------------------------------------------- + */ + +static int test_attr( void ) +{ + + hid_t file_id; + hid_t dataset_id; + hid_t group_id; + hid_t space_id; + hsize_t dims[1] = { 5 }; + + /* Create a new file using default properties. */ + file_id = H5Fcreate( FILE_NAME2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT ); + +/*------------------------------------------------------------------------- + * Create a dataset named "dset" on the root group + *------------------------------------------------------------------------- + */ + + /* Create the data space */ + if ((space_id = H5Screate_simple( 1, dims, NULL ))<0) goto out; + + /* Create the dataset */ + if ((dataset_id = H5Dcreate( file_id , "dset", H5T_NATIVE_INT, space_id, + H5P_DEFAULT ))<0) goto out; + + /* Close */ + H5Dclose( dataset_id ); + +/*------------------------------------------------------------------------- + * Create a group named "grp" on the root group + *------------------------------------------------------------------------- + */ + + /* Create a group. */ + if ((group_id = H5Gcreate( file_id, "grp", 0 ))<0) + goto out; + + /* Close */ + H5Gclose( group_id ); + +/*------------------------------------------------------------------------- + * + * Create attributes in the root group + * Note that we are calling the H5LTset_attribute functions with the name "." + * + *------------------------------------------------------------------------- + */ + if (make_attributes( file_id, "." )<0) + goto out; + +/*------------------------------------------------------------------------- + * + * Create attributes in the dataset "dset" + * + *------------------------------------------------------------------------- + */ + if (make_attributes( file_id, "dset" )<0) + goto out; + +/*------------------------------------------------------------------------- + * + * Create attributes in the group "grp" + * + *------------------------------------------------------------------------- + */ + if (make_attributes( file_id, "grp" )<0) + goto out; + +/*------------------------------------------------------------------------- + * end + *------------------------------------------------------------------------- + */ + /* Close the file. */ + H5Fclose( file_id ); + + return 0; + +out: + /* Close the file. */ + H5Fclose( file_id ); + H5_FAILED(); + return -1; +} + +/*------------------------------------------------------------------------- + * make_attributes + *------------------------------------------------------------------------- + */ + +static herr_t make_attributes( hid_t loc_id, const char* obj_name ) +{ + + int rank_out; + hsize_t *dims_out = 0; + H5T_class_t type_class; + size_t type_size; + int i; + + char attr_str_in[] = {"My attribute"}; + char attr_str_out[20]; + char attr_char_in[5] = {1,2,3,4,5}; + char attr_char_out[5]; + short attr_short_in[5] = {1,2,3,4,5}; + short attr_short_out[5]; + int attr_int_in[5] = {1,2,3,4,5}; + int attr_int_out[5]; + long attr_long_in[5] = {1,2,3,4,5}; + long attr_long_out[5]; + float attr_float_in[5] = {1,2,3,4,5}; + float attr_float_out[5]; + double attr_double_in[5] = {1,2,3,4,5}; + double attr_double_out[5]; + unsigned char attr_uchar_in[5] = {1,2,3,4,5}; + unsigned char attr_uchar_out[5]; + unsigned short attr_ushort_in[5] = {1,2,3,4,5}; + unsigned short attr_ushort_out[5]; + unsigned int attr_uint_in[5] = {1,2,3,4,5}; + unsigned int attr_uint_out[5]; + unsigned long attr_ulong_in[5] = {1,2,3,4,5}; + unsigned long attr_ulong_out[5]; + +/*------------------------------------------------------------------------- + * H5LTset_attribute_string test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_string"); + + /* Set the attribute */ + if ( H5LTset_attribute_string( loc_id, obj_name, ATTR1_NAME, attr_str_in ) < 0 ) + return -1; + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTset_attribute_string test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_string"); + + + /* Get the attribute */ + if ( H5LTget_attribute_string( loc_id, obj_name, ATTR1_NAME, attr_str_out ) < 0 ) + return -1; + + if ( strcmp( attr_str_in, attr_str_out ) != 0 ) + { + return -1; + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTset_attribute_char test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_char"); + + /* Set the attribute */ + if ( H5LTset_attribute_char( loc_id, obj_name, ATTR2_NAME, attr_char_in, 5 ) < 0 ) + return -1; + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTget_attribute_char test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_char"); + + /* Get the attribute */ + if ( H5LTget_attribute_char( loc_id, obj_name, ATTR2_NAME, attr_char_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_char_in[i] != attr_char_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR2_NAME, H5T_NATIVE_CHAR, attr_char_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_char_in[i] != attr_char_out[i] ) { + return -1; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTset_attribute_short test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_short"); + + /* Set the attribute */ + if ( H5LTset_attribute_short( loc_id, obj_name, ATTR3_NAME, attr_short_in, 5 ) < 0 ) + return -1; + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTget_attribute_short test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_short"); + + /* Get the attribute */ + if ( H5LTget_attribute_short( loc_id, obj_name, ATTR3_NAME, attr_short_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_short_in[i] != attr_short_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR3_NAME, H5T_NATIVE_SHORT, attr_short_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_short_in[i] != attr_short_out[i] ) { + return -1; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTset_attribute_int test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_int"); + + /* Set the attribute */ + if ( H5LTset_attribute_int( loc_id, obj_name, ATTR4_NAME, attr_int_in, 5 ) < 0 ) + return -1; + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTget_attribute_int test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_int"); + + /* Get the attribute */ + if ( H5LTget_attribute_int( loc_id, obj_name, ATTR4_NAME, attr_int_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_int_in[i] != attr_int_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR4_NAME, H5T_NATIVE_INT, attr_int_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_int_in[i] != attr_int_out[i] ) { + return -1; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTset_attribute_long test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_long"); + + /* Set the attribute */ + if ( H5LTset_attribute_long( loc_id, obj_name, ATTR5_NAME, attr_long_in, 5 ) < 0 ) + return -1; + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTget_attribute_long test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_long"); + + /* Get the attribute */ + if ( H5LTget_attribute_long( loc_id, obj_name, ATTR5_NAME, attr_long_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_long_in[i] != attr_long_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR5_NAME, H5T_NATIVE_LONG, attr_long_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_long_in[i] != attr_long_out[i] ) { + return -1; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTset_attribute_uchar test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_uchar"); + + /* Set the attribute */ + if ( H5LTset_attribute_uchar( loc_id, obj_name, ATTR6_NAME, attr_uchar_in, 5 ) < 0 ) + return -1; + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTget_attribute_uchar test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_uchar"); + + /* Get the attribute */ + if ( H5LTget_attribute_uchar( loc_id, obj_name, ATTR6_NAME, attr_uchar_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_uchar_in[i] != attr_uchar_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR6_NAME, H5T_NATIVE_UCHAR, attr_uchar_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_uchar_in[i] != attr_uchar_out[i] ) { + return -1; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTset_attribute_ushort test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_ushort"); + + /* Set the attribute */ + if ( H5LTset_attribute_ushort( loc_id, obj_name, ATTR7_NAME, attr_ushort_in, 5 ) < 0 ) + return -1; + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTget_attribute_ushort test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_ushort"); + + /* Get the attribute */ + if ( H5LTget_attribute_ushort( loc_id, obj_name, ATTR7_NAME, attr_ushort_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_ushort_in[i] != attr_ushort_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR7_NAME, H5T_NATIVE_USHORT, attr_ushort_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_ushort_in[i] != attr_ushort_out[i] ) { + return -1; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTset_attribute_int test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_uint"); + + /* Set the attribute */ + if ( H5LTset_attribute_uint( loc_id, obj_name, ATTR8_NAME, attr_uint_in, 5 ) < 0 ) + return -1; + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTget_attribute_int test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_uint"); + + /* Get the attribute */ + if ( H5LTget_attribute_uint( loc_id, obj_name, ATTR8_NAME, attr_uint_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_uint_in[i] != attr_uint_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR8_NAME, H5T_NATIVE_UINT, attr_uint_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_uint_in[i] != attr_uint_out[i] ) { + return -1; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTset_attribute_ulong test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_ulong"); + + /* Set the attribute */ + if ( H5LTset_attribute_ulong( loc_id, obj_name, ATTR9_NAME, attr_ulong_in, 5 ) < 0 ) + return -1; + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTget_attribute_long test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_ulong"); + + /* Get the attribute */ + if ( H5LTget_attribute_ulong( loc_id, obj_name, ATTR9_NAME, attr_ulong_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_ulong_in[i] != attr_ulong_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR9_NAME, H5T_NATIVE_ULONG, attr_ulong_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_ulong_in[i] != attr_ulong_out[i] ) { + return -1; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTset_attribute_float test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_float"); + + /* Set the attribute */ + if ( H5LTset_attribute_float( loc_id, obj_name, ATTR10_NAME, attr_float_in, 5 ) < 0 ) + return -1; + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTget_attribute_float test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_float"); + + + /* Get the attribute */ + if ( H5LTget_attribute_float( loc_id, obj_name, ATTR10_NAME, attr_float_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_float_in[i] != attr_float_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR10_NAME, H5T_NATIVE_FLOAT, attr_float_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_float_in[i] != attr_float_out[i] ) { + return -1; + } + } + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTset_attribute_double test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTset_attribute_double"); + + /* Set the attribute */ + if ( H5LTset_attribute_double( loc_id, obj_name, ATTR11_NAME, attr_double_in, 5 ) < 0 ) + return -1; + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTget_attribute_double test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_double"); + + /* Get the attribute */ + if ( H5LTget_attribute_double( loc_id, obj_name, ATTR11_NAME, attr_double_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_double_in[i] != attr_double_out[i] ) { + return -1; + } + } + + /* Get the attribute */ + if ( H5LTget_attribute( loc_id, obj_name, ATTR11_NAME, H5T_NATIVE_DOUBLE, attr_double_out ) < 0 ) + return -1; + + for (i = 0; i < 5; i++) + { + if ( attr_double_in[i] != attr_double_out[i] ) { + return -1; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * H5LTget_attribute_ndims test + *------------------------------------------------------------------------- + */ + + + TESTING("H5LTget_attribute_ndims"); + + if ( H5LTget_attribute_ndims( loc_id, obj_name, ATTR2_NAME, &rank_out ) < 0 ) + return -1; + + if ( rank_out != 1 ) { + return -1; + } + + PASSED(); + +/*------------------------------------------------------------------------- + * H5LTget_attribute_info test + *------------------------------------------------------------------------- + */ + + TESTING("H5LTget_attribute_info"); + + dims_out = malloc( sizeof(hsize_t) * rank_out ); + + if ( H5LTget_attribute_info( loc_id, obj_name, ATTR2_NAME, dims_out, &type_class, + &type_size) < 0 ) + return -1; + + for (i = 0; i < rank_out; i++) + { + if ( dims_out[i] != 5 ) { + return -1; + } + } + + if ( type_class != H5T_INTEGER ) { + return -1; + } + + if ( dims_out ) + free( dims_out ); + + PASSED(); + + return 0; +} + +/*------------------------------------------------------------------------- + * the main program + *------------------------------------------------------------------------- + */ + +int main( void ) +{ + int nerrors=0; + + /* test dataset functions */ + nerrors += test_dsets(); + + /* test attribute functions */ + nerrors += test_attr(); + + /* check for errors */ + if (nerrors) + goto error; + + return 0; + +error: + return 1; + + +} + diff --git a/hl/test/test_table.c b/hl/test/test_table.c new file mode 100644 index 0000000..b791fe1 --- /dev/null +++ b/hl/test/test_table.c @@ -0,0 +1,1597 @@ + +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING f. * + * * + ****************************************************************************/ + + + +#include "H5TA.h" + +#include +#include + +#define TEST_FILE_BE "test_table_be.hdf5" +#define TEST_FILE_LE "test_table_le.hdf5" +#define TEST_FILE_CRAY "test_table_cray.hdf5" + + +/*------------------------------------------------------------------------- + * Table API test + * + * Functions tested: + * + * H5TBmake_table + * H5TBread_table + * H5TBwrite_records + * H5TBread_records + * H5TBappend_records + * H5TBinsert_record + * H5TBdelete_record + * H5TBcombine_tables + * H5TBwrite_fields_name + * H5TBread_fields_name + * H5TBwrite_fields_index + * H5TBinsert_field + * H5TBdelete_field + * H5TBget_table_info + * H5TBget_field_info + * + *------------------------------------------------------------------------- + */ + +#define TITLE "Title" +#define NFIELDS (hsize_t)5 +#define NRECORDS (hsize_t)8 +#define TESTING2(WHAT) {printf("%-70s", "Testing " WHAT); fflush(stdout);} + +/*------------------------------------------------------------------------- + * structure used for all tests, a particle with properties + *------------------------------------------------------------------------- + */ +typedef struct particle_t +{ + char name[16]; + long longi; + float pressure; + double temperature; + int lati; +} particle_t; + +/*------------------------------------------------------------------------- + * local auxiliary functions + *------------------------------------------------------------------------- + */ + +static hid_t h5file_open(const char *fname, unsigned flags); +static int cmp_par(hsize_t i, hsize_t j, particle_t *rbuf, particle_t *wbuf ); +static int compare_deleted(hsize_t rrecords, hsize_t dstart, hsize_t drecords, + particle_t *rbuf, particle_t *wbuf); + +/*------------------------------------------------------------------------- + * a subset of particle_t, with latitude and longitude fields + *------------------------------------------------------------------------- + */ + typedef struct position_t + { + long longi; + int lati; + } position_t; + +/*------------------------------------------------------------------------- + * a subset of particle_t, with name and pressure fields + *------------------------------------------------------------------------- + */ + typedef struct namepressure_t + { + char name[16]; + float pressure; + } namepressure_t; + +/*------------------------------------------------------------------------- + * an extended particle, used in the insert field test + *------------------------------------------------------------------------- + */ + typedef struct particle2_t + { + char name[16]; + long longi; + float pressure; + double temperature; + int lati; + int new_field; + } particle2_t; + +/*------------------------------------------------------------------------- + * a particle with one field less, used in the delete field test + *------------------------------------------------------------------------- + */ + typedef struct particle3_t + { + char name[16]; + long longi; + double temperature; + int lati; + } particle3_t; + + +/*------------------------------------------------------------------------- + * the test program + *------------------------------------------------------------------------- + */ + +int test_table(hid_t fid, int write) +{ + /* identifiers */ + hid_t fid1; + hid_t fid2; + hsize_t chunk_size=10; + int compress=0; + int *fill=NULL; + particle_t fill1[1] = { {"no data",-1, -99.0f, -99.0, -1} }; + int fill1_new[1] = { -100 }; + hsize_t position; + char tname[20]; + + /* write, read, append, delete, insert some records and fields */ + hsize_t start; + hsize_t wstart; + hsize_t rstart; + hsize_t istart; + hsize_t dstart; + hsize_t nrecords; + hsize_t rrecords; + hsize_t wrecords; + hsize_t arecords; + hsize_t irecords; + hsize_t drecords; + hsize_t nfields; + hsize_t rfields; + hsize_t i, j; + hsize_t start1; /* record to start reading from 1st table */ + hsize_t start2; /* record to start writing in 2nd table */ + +/*------------------------------------------------------------------------- + * read, write, insert, append buffers + *------------------------------------------------------------------------- + */ + particle_t rbuf[NRECORDS+4]; + particle2_t rbuf2[NRECORDS]; + particle3_t rbuf3[NRECORDS]; + particle_t rbufc[NRECORDS*2]; + particle_t abuf[2]={{"eight",80,8.0f,80.0,80},{"nine",90,9.0f,90.0,90}}; + particle_t ibuf[2]={{"zero", 0, 0.0f, 0.0, 0},{"zero", 0, 0.0f, 0.0, 0}}; + particle_t wbufd[NRECORDS]; + particle_t wbuf[NRECORDS] = { + {"zero", 0, 0.0f, 0.0, 0,}, + {"one", 10, 1.0f, 10.0, 10}, + {"two", 20, 2.0f, 20.0, 20}, + {"three",30, 3.0f, 30.0, 30}, + {"four", 40, 4.0f, 40.0, 40}, + {"five", 50, 5.0f, 50.0, 50}, + {"six", 60, 6.0f, 60.0, 60}, + {"seven",70, 7.0f, 70.0, 70} + }; + /* buffers for the field "Pressure" and "New_field" */ + float pressure_in [NRECORDS] = { 0.0f,1.0f,2.0f,3.0f,4.0f,5.0f,6.0f,7.0f }; + float pressure_out [NRECORDS]; + int buf_new[NRECORDS] = { 0,1,2,3,4,5,6,7 }; + /* buffers for the fields "Latitude,Longitude" */ + position_t position_out[NRECORDS]; + position_t position_in[NRECORDS] = { {0,0}, + {10,10}, + {20,20}, + {30,30}, + {40,40}, + {50,50}, + {60,60}, + {70,70} }; + /* buffers for the fields "Name,Pressure" */ + namepressure_t namepre_out[NRECORDS]; + namepressure_t namepre_in[NRECORDS] = + { {"zero",0.0f}, + {"one", 1.0f}, + {"two", 2.0f}, + {"three", 3.0f}, + {"four", 4.0f}, + {"five", 5.0f}, + {"six", 6.0f}, + {"seven", 7.0f}, + }; + + +/*------------------------------------------------------------------------- + * initialize table parameters + * field offsets and sizes used in the fields functions + *------------------------------------------------------------------------- + */ + + size_t field_offset_pos[2]= + { + HOFFSET( position_t, longi ), + HOFFSET( position_t, lati ) + }; + size_t field_offset_namepre[2]= + { + HOFFSET( namepressure_t, name ), + HOFFSET( namepressure_t, pressure ) + }; + size_t field_sizes_pos[2]= + { + sizeof(position_in[0].longi), + sizeof(position_in[0].lati) + }; + size_t field_sizes_namepre[2]= + { + sizeof(namepre_in[0].name), + sizeof(namepre_in[0].pressure) + }; + size_t field_sizes_pre[1]= + { + sizeof(namepre_in[0].pressure) + }; + +/*------------------------------------------------------------------------- + * query table test + *------------------------------------------------------------------------- + */ + char **names_out; + size_t sizes_out[NFIELDS]; + size_t offset_out[NFIELDS]; + size_t size_out; + +/*------------------------------------------------------------------------- + * initialize table parameters + * field indexes (zero based) used in the fields functions + * "Name 0","Longitude 1","Pressure 2","Temperature 3","Latitude 4" + *------------------------------------------------------------------------- + */ + int field_index_pre[1] = { 2 }; + int field_index_pos[2] = { 1,4 }; + int field_index_namepre[2] = { 0,2 }; + int field_index[NFIELDS] = { 0,1,2,3,4 }; + +/*------------------------------------------------------------------------- + * initialize table parameters + * size and the offsets of struct members in memory + * define the inserted field HDF5 type and buffers + * these are used for the insert field test + *------------------------------------------------------------------------- + */ + hid_t field_type_new = H5T_NATIVE_INT; + size_t dst_size2 = sizeof( particle2_t ); + size_t dst_offset2[NFIELDS+1] = { HOFFSET( particle2_t, name ), + HOFFSET( particle2_t, longi ), + HOFFSET( particle2_t, pressure ), + HOFFSET( particle2_t, temperature ), + HOFFSET( particle2_t, lati ), + HOFFSET( particle2_t, new_field )}; + size_t dst_sizes2[NFIELDS+1] = { sizeof( rbuf2[0].name), + sizeof( rbuf2[0].longi), + sizeof( rbuf2[0].pressure), + sizeof( rbuf2[0].temperature), + sizeof( rbuf2[0].lati), + sizeof( rbuf2[0].new_field)}; +/*------------------------------------------------------------------------- + * initialize table parameters + * size and the offsets of struct members in memory + * these are used for the delete field test + *------------------------------------------------------------------------- + */ + size_t dst_size3 = sizeof( particle3_t ); + size_t dst_offset3[NFIELDS-1] = { HOFFSET( particle3_t, name ), + HOFFSET( particle3_t, longi ), + HOFFSET( particle3_t, temperature ), + HOFFSET( particle3_t, lati )}; + + size_t dst_sizes3[NFIELDS-1] = { sizeof( rbuf3[0].name), + sizeof( rbuf3[0].longi), + sizeof( rbuf3[0].temperature), + sizeof( rbuf3[0].lati)}; + + +/*------------------------------------------------------------------------- + * initialize table parameters + * 1) size and the offsets of struct members in memory + * 2) field names + * 3) define a HDF5 type for the fields + *------------------------------------------------------------------------- + */ + + size_t type_size_mem = sizeof( particle_t ); + size_t field_offset[NFIELDS]= + { + HOFFSET( particle_t, name ), + HOFFSET( particle_t, longi ), + HOFFSET( particle_t, pressure ), + HOFFSET( particle_t, temperature ), + HOFFSET( particle_t, lati ) + }; + size_t field_size[NFIELDS] = + { + sizeof( rbuf[0].name), + sizeof( rbuf[0].longi), + sizeof( rbuf[0].pressure), + sizeof( rbuf[0].temperature), + sizeof( rbuf[0].lati) + }; + const char *field_names[NFIELDS] = + { "Name","Longitude","Pressure","Temperature","Latitude" }; + hid_t field_type[NFIELDS]; + hid_t string_type = H5Tcopy( H5T_C_S1 ); + H5Tset_size( string_type, 16 ); + field_type[0] = string_type; + field_type[1] = H5T_NATIVE_LONG; + field_type[2] = H5T_NATIVE_FLOAT; + field_type[3] = H5T_NATIVE_DOUBLE; + field_type[4] = H5T_NATIVE_INT; + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBmake_table + * H5TBread_table + * + *------------------------------------------------------------------------- + */ + if (write) + { + TESTING2("making table"); + + if (H5TBmake_table(TITLE,fid,"table1",NFIELDS,NRECORDS,type_size_mem, + field_names,field_offset,field_type, + chunk_size,fill,compress,wbuf)<0) + goto out; + PASSED(); + } + + + TESTING2("reading table"); + +/*------------------------------------------------------------------------- + * read the table + *------------------------------------------------------------------------- + */ + + if (H5TBread_table(fid,"table1",type_size_mem,field_offset,field_size,rbuf)<0) + goto out; + + /* compare the extracted table with the original array */ + for( i = 0; i < NRECORDS; i++ ) + { + if (cmp_par(i,i,rbuf,wbuf)<0) + goto out; + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBwrite_records + * + *------------------------------------------------------------------------- + */ + if (write) + { + TESTING2("writing records"); + + /* create an empty table */ + if (H5TBmake_table(TITLE,fid,"table2",NFIELDS,NRECORDS,type_size_mem, + field_names,field_offset,field_type, + chunk_size,fill,compress,0)<0) + goto out; + +/*------------------------------------------------------------------------- + * write records, start at 0, write 8 + * pos = 0 1 2 3 4 5 6 7 + * data= 0 1 2 3 4 5 6 7 + *------------------------------------------------------------------------- + */ + wstart=0; wrecords=8; + if (H5TBwrite_records(fid,"table2",wstart,wrecords,type_size_mem,field_offset, + field_size,wbuf)<0) + goto out; + + /* read it back */ + if (H5TBread_table(fid,"table2",type_size_mem,field_offset,field_size,rbuf)<0) + goto out; + + /* compare */ + for( i = 0; i < NRECORDS; i++ ) + { + if (cmp_par(i,i,rbuf,wbuf)<0) + goto out; + } + + PASSED(); + } + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBread_records + * + *------------------------------------------------------------------------- + */ + + TESTING2("reading records"); + +/*------------------------------------------------------------------------- + * read records, start at 0, read 8 + * pos = 0 1 2 3 4 5 6 7 + * data= 0 1 2 3 4 5 6 7 + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * for the read test we cannot use "table2" because it has been appended + * we use the original "table1" instead + *------------------------------------------------------------------------- + */ + if(write) + strcpy(tname,"table2"); + else + strcpy(tname,"table1"); + + rstart=0; rrecords=8; + if (H5TBread_records(fid,tname,rstart,rrecords,type_size_mem,field_offset, + field_size,rbuf)<0) + goto out; + + /* compare */ + for( i=rstart; i=istart && i=istart+irecords && i<10) + { + j=i-irecords; + if (cmp_par(i,j,rbuf,wbuf)<0) + goto out; + } + else + { + j=i-10; + if (cmp_par(i,j,rbuf,abuf)<0) + goto out; + } + } + PASSED(); + } + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBdelete_record + * H5TBread_records + * + *------------------------------------------------------------------------- + */ + if (write) + { + TESTING2("deleting records"); + +/*------------------------------------------------------------------------- + * Create a table + * pos = 0 1 2 3 4 5 6 7 + * data= 0 1 2 3 4 5 6 7 + *------------------------------------------------------------------------- + */ + for( i=0; i= 2 && i <= 4 ) + { + if ( rbuf[i].lati != position_in[i].lati || + rbuf[i].longi != position_in[i].longi || + rbuf[i].pressure != pressure_in[i] ) + { + fprintf(stderr,"%d %f %d\n", + rbuf[i].longi,rbuf[i].pressure,rbuf[i].lati); + fprintf(stderr,"%d %f %d\n", + position_in[i].longi,pressure_in[i],position_in[i].lati); + goto out; + } + } + } + + PASSED(); + } /*write*/ + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBread_fields_name + * + *------------------------------------------------------------------------- + */ + TESTING2("reading fields by name"); + +/*------------------------------------------------------------------------- + * write and read the "Pressure" field + *------------------------------------------------------------------------- + */ + if (write) + { + if (H5TBmake_table(TITLE,fid,"table10",NFIELDS,NRECORDS,type_size_mem, + field_names,field_offset,field_type, + chunk_size,fill1,compress,0)<0) + goto out; + + /* write the pressure field to all the records */ + start = 0; + nrecords = NRECORDS; + if ( H5TBwrite_fields_name(fid,"table10","Pressure",start,nrecords, + sizeof( float ),0,field_sizes_pre,pressure_in)<0) + goto out; + } + + /* read the "Pressure" field */ + start = 0; + nrecords = NRECORDS; + if ( H5TBread_fields_name(fid,"table10","Pressure",start,nrecords, + sizeof(float),0,field_sizes_pre,pressure_out)<0) + goto out; + + /* Compare the extracted table with the initial values */ + for( i = 0; i < NRECORDS; i++ ) + { + if ( pressure_out[i] != pressure_in[i] ) { + goto out; + } + } + +/*------------------------------------------------------------------------- + * Write and read the "Latitude,Longitude" fields + *------------------------------------------------------------------------- + */ + if (write) + { + /* Write the new longitude and latitude information to all the records */ + start = 0; + nrecords = NRECORDS; + if ( H5TBwrite_fields_name(fid,"table10", "Latitude,Longitude", start, nrecords, + sizeof( position_t ), field_offset_pos, field_sizes_pos, position_in ) < 0 ) + goto out; + }/*write*/ + + /* Read the "Latitude,Longitude" fields */ + start = 0; + nrecords = NRECORDS; + if ( H5TBread_fields_name( fid, "table10", "Latitude,Longitude", + start, nrecords, sizeof(position_t), field_offset_pos, field_sizes_pos, position_out ) < 0 ) + goto out; + + /* Compare the extracted table with the initial values */ + for( i = 0; i < NRECORDS; i++ ) + { + if ( position_out[i].lati != position_in[i].lati || + position_out[i].longi != position_in[i].longi ) + goto out; + } + + +/*------------------------------------------------------------------------- + * Write and read the "Name,Pressure" fields + *------------------------------------------------------------------------- + */ + if (write) + { + /* Write the new name and pressure information to all the records */ + start = 0; + nrecords = NRECORDS; + if ( H5TBwrite_fields_name( fid, "table10", "Name,Pressure", start, nrecords, + sizeof( namepressure_t ), field_offset_namepre, field_sizes_namepre, namepre_in ) < 0 ) + goto out; + }/*write*/ + + /* Read the "Name,Pressure" fields */ + start = 0; + nrecords = NRECORDS; + if ( H5TBread_fields_name( fid, "table10", "Name,Pressure", + start, nrecords, sizeof(namepressure_t), field_offset_namepre, field_sizes_namepre, + namepre_out ) < 0 ) + goto out; + + /* Compare the extracted table with the initial values */ + for( i = 0; i < NRECORDS; i++ ) + { + if ( ( strcmp( namepre_out[i].name, namepre_in[i].name ) != 0 ) || + namepre_out[i].pressure != namepre_in[i].pressure ) { + goto out; + } + } + /* reset buffer */ + for( i = 0; i < NRECORDS; i++ ) + { + strcpy( namepre_out[i].name, "\0" ); + namepre_out[i].pressure = -1; + } + +/*------------------------------------------------------------------------- + * read only 3 records of the "Name,Pressure" fields, starting at record 2 + *------------------------------------------------------------------------- + */ + start = 2; + nrecords = 3; + if ( H5TBread_fields_name( fid, "table10", "Name,Pressure", + start, nrecords, sizeof(namepressure_t), field_offset_namepre, + field_sizes_namepre, namepre_out ) < 0 ) + goto out; + + /* Compare the extracted table with the initial values */ + for( i = 0; i < 3; i++ ) + { + if ( ( strcmp( namepre_out[i].name, namepre_in[start+i].name ) != 0 ) || + namepre_out[i].pressure != namepre_in[start+i].pressure ) { + goto out; + } + } + PASSED(); + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBwrite_fields_index + * + *------------------------------------------------------------------------- + */ + if (write) + { + TESTING2("writing fields by index"); + + /* make an empty table */ + if (H5TBmake_table(TITLE,fid,"table11",NFIELDS,NRECORDS,type_size_mem, + field_names,field_offset,field_type, + chunk_size,fill,compress,NULL)<0) + goto out; + + /* write the pressure field starting at record 2 */ + nfields = 1; + start = 2; + nrecords = 3; + if ( H5TBwrite_fields_index(fid, "table11", nfields, field_index_pre, start, nrecords, + sizeof( float ), 0, field_sizes_pre, pressure_in ) < 0 ) + goto out; + + + /* write the new longitude and latitude information starting at record 2 */ + nfields = 2; + start = 2; + nrecords = 3; + if ( H5TBwrite_fields_index(fid, "table11", nfields, field_index_pos, start, nrecords, + sizeof( position_t ), field_offset_pos, field_sizes_pos, position_in ) < 0 ) + goto out; + + /* read back the all table */ + nfields = 5; + start = 0; + nrecords = NRECORDS; + if ( H5TBread_fields_index(fid, "table11", nfields, field_index, + start, nrecords, type_size_mem, field_offset, field_size, rbuf ) < 0 ) + goto out; + + /* Compare the extracted table with the initial values */ + for( i = 0; i < NRECORDS; i++ ) + { + if ( i >= 2 && i <= 4 ) + { + if ( rbuf[i].lati != position_in[i].lati || + rbuf[i].longi != position_in[i].longi || + rbuf[i].pressure != pressure_in[i] ) + goto out; + } + } + + PASSED(); + } + + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBread_fields_index + * + *------------------------------------------------------------------------- + */ + + TESTING2("reading fields by index"); + + if (write) + { + /* make an empty table */ + if (H5TBmake_table(TITLE,fid,"table12",NFIELDS,NRECORDS,type_size_mem, + field_names,field_offset,field_type, + chunk_size,fill,compress,NULL)<0) + goto out; + +/*------------------------------------------------------------------------- + * write and read the "Pressure" field + *------------------------------------------------------------------------- + */ + + /* write the pressure field to all the records */ + nfields = 1; + start = 0; + nrecords = NRECORDS; + if ( H5TBwrite_fields_index(fid, "table12", nfields, field_index_pre, start, nrecords, + sizeof( float ), 0, field_sizes_pre, pressure_in ) < 0 ) + goto out; + } + + /* read the "Pressure" field */ + nfields = 1; + start = 0; + nrecords = NRECORDS; + if ( H5TBread_fields_index(fid, "table12", nfields, field_index_pre, + start, nrecords, sizeof(float), 0, field_sizes_pre, pressure_out ) < 0 ) + goto out; + + /* compare the extracted table with the initial values */ + for( i = 0; i < NRECORDS; i++ ) + { + if ( pressure_out[i] != pressure_in[i] ) { + goto out; + } + } + +/*------------------------------------------------------------------------- + * write and read the "Latitude,Longitude" fields + *------------------------------------------------------------------------- + */ + if (write) + { + /* write the new longitude and latitude information to all the records */ + nfields = 2; + start = 0; + nrecords = NRECORDS; + if ( H5TBwrite_fields_index(fid, "table12", nfields, field_index_pos, start, nrecords, + sizeof( position_t ), field_offset_pos, field_sizes_pos, position_in ) < 0 ) + goto out; + } /*write*/ + + /* read the "Latitude,Longitude" fields */ + nfields = 2; + start = 0; + nrecords = NRECORDS; + if ( H5TBread_fields_index(fid, "table12", nfields, field_index_pos, + start, nrecords, sizeof(position_t), field_offset_pos, field_sizes_pos, position_out ) < 0 ) + goto out; + + /* compare the extracted table with the initial values */ + for( i = 0; i < NRECORDS; i++ ) + { + if ( position_out[i].lati != position_in[i].lati || + position_out[i].longi != position_in[i].longi ) { + goto out; + } + } + +/*------------------------------------------------------------------------- + * write and read the "Name,Pressure" fields + *------------------------------------------------------------------------- + */ + + if (write) + { + /* write the new name and pressure information to all the records */ + nfields = 2; + start = 0; + nrecords = NRECORDS; + if ( H5TBwrite_fields_index(fid, "table12", nfields, field_index_namepre, start, nrecords, + sizeof( namepressure_t ), field_offset_namepre, field_sizes_namepre, namepre_in ) < 0 ) + goto out; + } + + /* read the "Name,Pressure" fields */ + nfields = 2; + start = 0; + nrecords = NRECORDS; + if ( H5TBread_fields_index(fid, "table12", nfields, field_index_namepre, + start, nrecords, sizeof(namepressure_t), field_offset_namepre, + field_sizes_namepre, namepre_out ) < 0 ) + goto out; + + /* compare the extracted table with the initial values */ + for( i = 0; i < NRECORDS; i++ ) + { + if ( ( strcmp( namepre_out[i].name, namepre_in[i].name ) != 0 ) || + namepre_out[i].pressure != namepre_in[i].pressure ) { + goto out; + } + } + + /* reset buffer */ + for( i = 0; i < NRECORDS; i++ ) + { + strcpy( namepre_out[i].name, "\0" ); + namepre_out[i].pressure = -1; + } + +/*------------------------------------------------------------------------- + * read only 3 records of the "Name,Pressure" fields, starting at record 2 + *------------------------------------------------------------------------- + */ + + /* write the new name and pressure information to all the records */ + nfields = 2; + start = 2; + nrecords = 3; + if ( H5TBread_fields_index(fid, "table12", nfields, field_index_namepre, + start, nrecords, sizeof(namepressure_t), field_offset_namepre, + field_sizes_namepre, namepre_out ) < 0 ) + goto out; + + /* compare the extracted table with the initial values */ + for( i = 0; i < 3; i++ ) + { + if ( ( strcmp( namepre_out[i].name, wbuf[start+i].name ) != 0 ) || + namepre_out[i].pressure != wbuf[start+i].pressure ) { + goto out; + } + } + + PASSED(); + + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBinsert_field + * + *------------------------------------------------------------------------- + */ + + if (write) + { + TESTING2("inserting fields"); + + /* make a table */ + if (H5TBmake_table(TITLE,fid,"table13",NFIELDS,NRECORDS,type_size_mem, + field_names,field_offset,field_type, + chunk_size,fill1,compress,wbuf)<0) + goto out; + + /* insert the new field at the end of the field list */ + position = NFIELDS; + if ( H5TBinsert_field( fid, "table13", "New Field", field_type_new, position, + fill1_new, buf_new ) < 0 ) + goto out; + + /* read the table */ + if ( H5TBread_table( fid, "table13", dst_size2, dst_offset2, dst_sizes2, rbuf2 ) < 0 ) + goto out; + + /* compare the extracted table with the original array */ + for( i = 0; i < NRECORDS; i++ ) + { + if ( ( strcmp( rbuf2[i].name, wbuf[i].name ) != 0 ) || + rbuf2[i].lati != wbuf[i].lati || + rbuf2[i].longi != wbuf[i].longi || + rbuf2[i].pressure != wbuf[i].pressure || + rbuf2[i].temperature != wbuf[i].temperature || + rbuf2[i].new_field != buf_new[i] ) { + goto out; + } + } + PASSED(); + } + + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBdelete_field + * + *------------------------------------------------------------------------- + */ + if (write) + { + TESTING2("deleting fields"); + + /* make a table */ + if (H5TBmake_table(TITLE,fid,"table14",NFIELDS,NRECORDS,type_size_mem, + field_names,field_offset,field_type, + chunk_size,fill,compress,wbuf)<0) + goto out; + + + /* delete the field */ + if ( H5TBdelete_field(fid, "table14", "Pressure" ) < 0 ) + goto out; + + /* read the table */ + if ( H5TBread_table(fid, "table14", dst_size3, dst_offset3, dst_sizes3, rbuf3 ) < 0 ) + goto out; + + /* compare the extracted table with the original array */ + for( i = 0; i < NRECORDS; i++ ) + { + if ( ( strcmp( rbuf3[i].name, wbuf[i].name ) != 0 ) || + rbuf3[i].lati != wbuf[i].lati || + rbuf3[i].longi != wbuf[i].longi || + rbuf3[i].temperature != wbuf[i].temperature ) { + goto out; + } + } + + PASSED(); + } + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBget_table_info + * H5TBget_field_info + * + *------------------------------------------------------------------------- + */ + + TESTING2("getting table info"); + + /* get table info */ + if ( H5TBget_table_info (fid, "table1", &rfields, &rrecords ) < 0 ) + goto out; + + if ( NFIELDS != rfields || rrecords != NRECORDS ) { + goto out; + } + + PASSED(); + +/*------------------------------------------------------------------------- + * + * Functions tested: + * + * H5TBget_field_info + * + *------------------------------------------------------------------------- + */ + + TESTING2("getting field info"); + + /* alocate */ + names_out = malloc( sizeof(char*) * (size_t)NFIELDS ); + for ( i = 0; i < NFIELDS; i++) + { + names_out[i] = malloc( sizeof(char) * 255 ); + } + + /* Get field info */ + if ( H5TBget_field_info(fid, "table1", names_out, sizes_out, offset_out, &size_out ) < 0 ) + goto out; + + for ( i = 0; i < NFIELDS; i++) + { + if ( (strcmp( field_names[i], names_out[i] ) != 0)) { + goto out; + } + } + + /* release */ + for ( i = 0; i < NFIELDS; i++) + { + free ( names_out[i] ); + } + free ( names_out ); + + PASSED(); + +/*------------------------------------------------------------------------- + * end + *------------------------------------------------------------------------- + */ + return 0; +out: + H5_FAILED(); + return -1; +} + + +/*------------------------------------------------------------------------- + * the main program + *------------------------------------------------------------------------- + */ + +int main(void) +{ + hid_t fid; /* identifier for the file */ + unsigned flags=H5F_ACC_RDONLY; + +/*------------------------------------------------------------------------- + * test1: create a file for the write/read test + *------------------------------------------------------------------------- + */ + + /* create a file using default properties */ + fid=H5Fcreate("test_table.h5",H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT); + + puts("Testing table with file creation mode (read/write in native architecture):"); + + /* test, do write */ + if (test_table(fid,1)<0) + goto out; + + /* close */ + H5Fclose(fid); + +/*------------------------------------------------------------------------- + * test2: open a file written in test1 on a big-endian machine + *------------------------------------------------------------------------- + */ + puts("Testing table with file open mode (read big-endian data):"); + + fid=h5file_open(TEST_FILE_BE,flags); + + /* test, do not write */ + if (test_table(fid,0)<0) + goto out; + + /* close */ + H5Fclose(fid); + +/*------------------------------------------------------------------------- + * test3: open a file written in test1 on a little-endian machine + *------------------------------------------------------------------------- + */ + puts("Testing table with file open mode (read little-endian data):"); + + fid=h5file_open(TEST_FILE_LE,flags); + + /* test, do not write */ + if (test_table(fid,0)<0) + goto out; + + /* close */ + H5Fclose(fid); + +/*------------------------------------------------------------------------- + * test4: open a file written in test1 on the Cray T3 machine + *------------------------------------------------------------------------- + */ + puts("Testing table with file open mode (read Cray data):"); + + fid=h5file_open(TEST_FILE_CRAY,flags); + + /* test, do not write */ + if (test_table(fid,0)<0) + goto out; + + /* close */ + H5Fclose(fid); + + return 0; +out: + H5Fclose(fid); + return 1; +} + + +/*------------------------------------------------------------------------- + * function to open an HDF5 file and return its file identifier + *------------------------------------------------------------------------- + */ +static hid_t h5file_open(const char *fname, unsigned flags) +{ + + hid_t fid; /* identifier for the file */ + char *srcdir = getenv("srcdir"); /* the source directory */ + char data_file[512]=""; /* buffer to hold name of existing file */ + + /* compose the name of the file to open, using the srcdir, if appropriate */ + if (srcdir){ + strcpy(data_file,srcdir); + strcat(data_file,"/"); + } + strcat(data_file,fname); + + /* open */ + if((fid=H5Fopen(data_file,flags,H5P_DEFAULT))<0) { + fprintf(stderr,"Error: Cannot open file <%s>\n",data_file ); + exit(1); + } + + return fid; +} + +/*------------------------------------------------------------------------- + * function that compares one particle + *------------------------------------------------------------------------- + */ +static int cmp_par(hsize_t i, hsize_t j, particle_t *rbuf, particle_t *wbuf ) +{ + if ( ( strcmp( rbuf[i].name, wbuf[j].name ) != 0 ) || + rbuf[i].lati != wbuf[j].lati || + rbuf[i].longi != wbuf[j].longi || + rbuf[i].pressure != wbuf[j].pressure || + rbuf[i].temperature != wbuf[j].temperature ) { + fprintf(stderr,"read and write buffers have differences\n"); + fprintf(stderr,"%s %d %f %f %d\n", + rbuf[i].name,rbuf[i].longi,rbuf[i].pressure,rbuf[i].temperature,rbuf[i].lati); + fprintf(stderr,"%s %d %f %f %d\n", + wbuf[j].name,wbuf[j].longi,wbuf[j].pressure,wbuf[j].temperature,wbuf[j].lati); + return -1; + } + return 0; +} + +/*------------------------------------------------------------------------- + * function to compare deleted records + *------------------------------------------------------------------------- + */ +static int compare_deleted(hsize_t rrecords, hsize_t dstart, hsize_t drecords, + particle_t *rbuf, particle_t *wbuf) +{ + hsize_t i,j; + for( i=0; iitem=ITEM; \ + HGOTO_DONE(SUCCEED); + +/* Define the code template for removals for the "OP" in the H5SL_FIND macro */ +#define H5SL_FIND_REMOVE_FOUND(SLIST,X,UPDATE,I,ITEM) \ + void *tmp; \ + \ + for(I=0; I<=(int)SLIST->curr_level; I++) { \ + if(*UPDATE[I]!=X) \ + break; \ + *UPDATE[I]=X->forward[I]; \ + } /* end for */ \ + tmp=X->item; \ + H5MM_xfree(X); \ + while(SLIST->curr_level>0 && SLIST->header->forward[SLIST->curr_level]==NULL) \ + SLIST->curr_level--; \ + SLIST->nobjs--; \ + HGOTO_DONE(tmp); + +/* Define the code template for searches for the "OP" in the H5SL_FIND macro */ +#define H5SL_FIND_SEARCH_FOUND(SLIST,X,UPDATE,I,ITEM) \ + HGOTO_DONE(X->item); + +/* Define a code template for updating the "update" vector for the "DOUPDATE" in the H5SL_FIND macro */ +#define H5SL_FIND_YES_UPDATE(X,UPDATE,I) \ + UPDATE[I]=&X->forward[I]; + +/* Define a code template for _NOT_ updating the "update" vector for the "DOUPDATE" in the H5SL_FIND macro */ +#define H5SL_FIND_NO_UPDATE(X,UPDATE,I) + +/* Macro used to find node for operation */ +#define H5SL_FIND(OP,DOUPDATE,SLIST,X,UPDATE,I,TYPE,ITEM,KEY,CHECKED) \ + CHECKED=NULL; \ + for(I=(int)SLIST->curr_level; I>=0; I--) { \ + if(X->forward[I]!=CHECKED) { \ + while(X->forward[I] && *(TYPE *)X->forward[I]->key<*(TYPE *)KEY) \ + X=X->forward[I]; \ + CHECKED=X->forward[I]; \ + } /* end if */ \ + H5_GLUE3(H5SL_FIND_,DOUPDATE,_UPDATE)(X,UPDATE,I) \ + } /* end for */ \ + X=X->forward[0]; \ + if(X!=NULL && *(TYPE *)X->key==*(TYPE *)key) { \ + /* What to do when a node is found */ \ + H5_GLUE3(H5SL_FIND_,OP,_FOUND)(SLIST,X,UPDATE,I,ITEM) \ + } /* end if */ + +/* Macro used to insert node */ +#define H5SL_INSERT(SLIST,X,UPDATE,I,TYPE,ITEM,KEY,CHECKED) \ + H5SL_FIND(INSERT,YES,SLIST,X,UPDATE,I,TYPE,ITEM,KEY,CHECKED) + +/* Macro used to remove node */ +#define H5SL_REMOVE(SLIST,X,UPDATE,I,TYPE,ITEM,KEY,CHECKED) \ + H5SL_FIND(REMOVE,YES,SLIST,X,UPDATE,I,TYPE,ITEM,KEY,CHECKED) + +/* Macro used to search for node */ +#define H5SL_SEARCH(SLIST,X,UPDATE,I,TYPE,ITEM,KEY,CHECKED) \ + H5SL_FIND(SEARCH,NO,SLIST,X,UPDATE,I,TYPE,ITEM,KEY,CHECKED) + + +/* Private typedefs & structs */ + +/* Skip list node data structure */ +struct H5SL_node_t { + void *key; /* Pointer to node's key */ + void *item; /* Pointer to node's item */ + size_t level; /* The level of this node */ + struct H5SL_node_t *forward[1]; /* Array of forward pointers from this node */ +}; + +/* Main skip list data structure */ +struct H5SL_t { + /* Static values for each list */ + H5SL_type_t type; /* Type of skip list */ + double p; /* Probability of using a higher level [0..1) */ + size_t max_level; /* Maximum number of levels */ + + /* Dynamic values for each list */ + int curr_level; /* Current top level used in list */ + size_t nobjs; /* Number of active objects in skip list */ + H5SL_node_t *header; /* Header for nodes in skip list */ +}; + +/* Static functions */ +static size_t H5SL_random_level(double p, size_t max_level); +static H5SL_node_t * H5SL_new_node(size_t lvl, void *item, void *key); + +/* Declare a free list to manage the H5SL_t struct */ +H5FL_DEFINE_STATIC(H5SL_t); + + +/*-------------------------------------------------------------------------- + NAME + H5SL_init_interface + PURPOSE + Initialize interface-specific information + USAGE + herr_t H5SL_init_interface() + + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Initializes any interface-specific data or routines. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5SL_init_interface(void) +{ + time_t curr_time; /* Current time, for seeding random number generator */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_init_interface) + + /* Create randomized set of numbers */ + curr_time=HDtime(NULL); + HDsrandom((unsigned long)curr_time); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SL_init_interface() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_random_level + PURPOSE + Generate a random level + USAGE + size_t H5SL_random_level(p,max_level) + double p; IN: probability distribution + size_t max_level; IN: Maximum level for node height + + RETURNS + Returns non-negative level value + DESCRIPTION + Count elements in a skip list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Do we really need a 'random' value, or is a series of nodes with the + correct heights "good enough". We could track the state of the nodes + allocated for this list and issue node heights appropriately (i.e. 1,2, + 1,4,1,2,1,8,...) (or would that be 1,1,2,1,1,2,4,... ?) + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static size_t +H5SL_random_level(double p, size_t max_level) +{ + size_t lvl; /* Level generated */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_random_level); + + lvl=0; + while((((double)HDrandom())/((double)LONG_MAX))

key=key; + ret_value->item=item; + ret_value->level=lvl; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5SL_new_node() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_create + PURPOSE + Create a skip list + USAGE + H5SL_t *H5SL_create(void) + + RETURNS + Returns a pointer to a skip list on success, NULL on failure. + DESCRIPTION + Create a skip list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5SL_t * +H5SL_create(H5SL_type_t type, double p, size_t max_level) +{ + H5SL_t *new_slist=NULL; /* Pointer to new skip list object created */ + H5SL_node_t *header; /* Pointer to skip list header node */ + size_t u; /* Local index variable */ + H5SL_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5SL_create,NULL); + + /* Check args */ + HDassert(p>0.0 && p<1.0); + HDassert(max_level>0 && max_level<=H5SL_LEVEL_MAX); + HDassert(type>=H5SL_TYPE_INT && type<=H5SL_TYPE_HADDR); + + /* Allocate skip list structure */ + if((new_slist=H5FL_MALLOC(H5SL_t))==NULL) + HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"memory allocation failed"); + + /* Set the static internal fields */ + new_slist->type=type; + new_slist->p=p; + new_slist->max_level=max_level; + + /* Set the dynamic internal fields */ + new_slist->curr_level=-1; + new_slist->nobjs=0; + + /* Allocate the header node */ + if((header=H5SL_new_node(max_level-1,NULL,NULL))==NULL) + HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"memory allocation failed"); + + /* Initialize header node's forward pointers */ + for(u=0; uforward[u]=NULL; + + /* Attach the header */ + new_slist->header=header; + + /* Set the return value */ + ret_value=new_slist; + +done: + /* Error cleanup */ + if(ret_value==NULL) { + if(new_slist!=NULL) { + H5FL_FREE(H5SL_t,new_slist); + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5SL_create() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_count + PURPOSE + Count the number of objects in a skip list + USAGE + ssize_t H5SL_count(slist) + H5SL_t *slist; IN: Pointer to skip list to count + + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Count elements in a skip list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +ssize_t +H5SL_count(H5SL_t *slist) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_count); + + /* Check args */ + assert(slist); + + /* Check internal consistency */ + /* (Pre-condition) */ + + FUNC_LEAVE_NOAPI(slist->nobjs); +} /* end H5SL_count() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_insert + PURPOSE + Insert an objects into a skip list + USAGE + herr_t H5SL_insert(slist,item,key) + H5SL_t *slist; IN/OUT: Pointer to skip list + void *item; IN: Item to insert + void *key; IN: Key for item to insert + + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Insert element into a skip list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Inserting an item with the same key as an existing object replaces + the existing object's item pointer with the new item pointer. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5SL_insert(H5SL_t *slist, void *item, void *key) +{ + H5SL_node_t **update[H5SL_LEVEL_MAX]; /* 'update' vector */ + H5SL_node_t *checked; /* Pointer to last node checked */ + H5SL_node_t *x; /* Current node to examine */ + size_t lvl; /* Level of new node */ + int i; /* Local index value */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5SL_insert); + + /* Check args */ + assert(slist); + assert(key); + + /* Check internal consistency */ + /* (Pre-condition) */ + + /* Insert item into skip list */ + + /* Work through the forward pointers for a node, finding the node at each + * level that is before the location to insert + */ + x=slist->header; + switch(slist->type) { + case H5SL_TYPE_INT: + H5SL_INSERT(slist,x,update,i,int,item,key,checked) + break; + + case H5SL_TYPE_HADDR: + H5SL_INSERT(slist,x,update,i,haddr_t,item,key,checked) + break; + } /* end switch */ + + /* 'key' must not have been found in existing list, if we get here */ + + /* Generate level for new node */ + lvl=H5SL_random_level(slist->p,slist->max_level); + if((int)lvl>slist->curr_level) { + /* Cap the increase in the current level to just one greater */ + lvl=slist->curr_level+1; + + /* Set the update pointer correctly */ + update[lvl]=&slist->header->forward[lvl]; + + /* Increase the maximum level of the list */ + slist->curr_level=lvl; + } /* end if */ + + /* Create new node of proper level */ + if((x=H5SL_new_node(lvl,item,key))==NULL) + HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"can't create new skip list node"); + + /* Link the new node into the existing list */ + for(i=0; i<=(int)lvl; i++) { + x->forward[i]=*update[i]; + *update[i]=x; + } /* end for */ + + /* Increment the number of nodes in the skip list */ + slist->nobjs++; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5SL_insert() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_search + PURPOSE + Search for objects into a skip list + USAGE + void *H5SL_search(slist,key) + H5SL_t *slist; IN/OUT: Pointer to skip list + void *key; IN: Key for item to search for + + RETURNS + Returns pointer to item on success, NULL on failure + DESCRIPTION + Search for an object in a skip list, according to it's key + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +void * +H5SL_search(H5SL_t *slist, void *key) +{ + H5SL_node_t *checked; /* Pointer to last node checked */ + H5SL_node_t *x; /* Current node to examine */ + int i; /* Local index value */ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_search); + + /* Check args */ + assert(slist); + assert(key); + + /* Check internal consistency */ + /* (Pre-condition) */ + + /* Insert item into skip list */ + + /* Work through the forward pointers for a node, finding the node at each + * level that is before the location to insert + */ + x=slist->header; + switch(slist->type) { + case H5SL_TYPE_INT: + H5SL_SEARCH(slist,x,-,i,int,-,key,checked) + break; + + case H5SL_TYPE_HADDR: + H5SL_SEARCH(slist,x,-,i,haddr_t,-,key,checked) + break; + } /* end switch */ + + /* 'key' must not have been found in existing list, if we get here */ + ret_value=NULL; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5SL_search() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_remove + PURPOSE + Removes an object from a skip list + USAGE + void *H5SL_remove(slist,key) + H5SL_t *slist; IN/OUT: Pointer to skip list + void *key; IN: Key for item to remove + + RETURNS + Returns pointer to item removed on success, NULL on failure. + DESCRIPTION + Remove element from a skip list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +void * +H5SL_remove(H5SL_t *slist, void *key) +{ + H5SL_node_t **update[H5SL_LEVEL_MAX]; /* 'update' vector */ + H5SL_node_t *checked; /* Pointer to last node checked */ + H5SL_node_t *x; /* Current node to examine */ + int i; /* Local index value */ + void *ret_value=NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_remove); + + /* Check args */ + assert(slist); + assert(key); + + /* Check internal consistency */ + /* (Pre-condition) */ + + /* Remove item from skip list */ + + /* Work through the forward pointers for a node, finding the node at each + * level that is before the location to remove + */ + x=slist->header; + switch(slist->type) { + case H5SL_TYPE_INT: + H5SL_REMOVE(slist,x,update,i,int,-,key,checked) + break; + + case H5SL_TYPE_HADDR: + H5SL_REMOVE(slist,x,update,i,haddr_t,-,key,checked) + break; + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5SL_remove() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_first + PURPOSE + Gets a pointer to the first node in a skip list + USAGE + H5SL_node_t *H5SL_first(slist) + H5SL_t *slist; IN: Pointer to skip list + + RETURNS + Returns pointer to first node in skip list on success, NULL on failure. + DESCRIPTION + Retrieves a pointer to the first node in a skip list, for iterating over + the list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5SL_node_t * +H5SL_first(H5SL_t *slist) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_first); + + /* Check args */ + assert(slist); + + /* Check internal consistency */ + /* (Pre-condition) */ + + FUNC_LEAVE_NOAPI(slist->header->forward[0]); +} /* end H5SL_first() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_next + PURPOSE + Gets a pointer to the next node in a skip list + USAGE + H5SL_node_t *H5SL_next(slist_node) + H5SL_node_t *slist_node; IN: Pointer to skip list node + + RETURNS + Returns pointer to node after slist_node in skip list on success, NULL on failure. + DESCRIPTION + Retrieves a pointer to the next node in a skip list, for iterating over + the list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5SL_node_t * +H5SL_next(H5SL_node_t *slist_node) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_next); + + /* Check args */ + assert(slist_node); + + /* Check internal consistency */ + /* (Pre-condition) */ + + FUNC_LEAVE_NOAPI(slist_node->forward[0]); +} /* end H5SL_next() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_item + PURPOSE + Gets pointer to the 'item' for a skip list node + USAGE + void *H5SL_item(slist_node) + H5SL_node_t *slist_node; IN: Pointer to skip list node + + RETURNS + Returns pointer to node 'item' on success, NULL on failure. + DESCRIPTION + Retrieves a node's 'item' + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +void * +H5SL_item(H5SL_node_t *slist_node) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_item); + + /* Check args */ + assert(slist_node); + + /* Check internal consistency */ + /* (Pre-condition) */ + + FUNC_LEAVE_NOAPI(slist_node->item); +} /* end H5SL_item() */ + + +/*-------------------------------------------------------------------------- + NAME + H5SL_close + PURPOSE + Close a skip list, deallocating it. + USAGE + herr_t H5SL_close(slist) + H5SL_t *slist; IN/OUT: Pointer to skip list to close + + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Close a skip list, freeing all internal information. Any objects left in + the skip list are not deallocated. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5SL_close(H5SL_t *slist) +{ + H5SL_node_t *node, *next_node; /* Pointers to skip list nodes */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_close); + + /* Check args */ + assert(slist); + + /* Check internal consistency */ + /* (Pre-condition) */ + + /* Free skip list nodes */ + node=slist->header; + while(node!=NULL) { + next_node=node->forward[0]; + H5MM_xfree(node); + node=next_node; + } /* end while */ + + /* Free skip list object */ + H5FL_FREE(H5SL_t,slist); + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* end H5SL_close() */ + diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h new file mode 100644 index 0000000..94e2b4d --- /dev/null +++ b/src/H5SLprivate.h @@ -0,0 +1,66 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains private information about the H5SL module + */ +#ifndef _H5SLprivate_H +#define _H5SLprivate_H + +/**************************************/ +/* Public headers needed by this file */ +/**************************************/ +#ifdef LATER +#include "H5SLpublic.h" +#endif /* LATER */ + +/***************************************/ +/* Private headers needed by this file */ +/***************************************/ +#include "H5private.h" + +/************/ +/* Typedefs */ +/************/ + +/* Typedefs for skip list struct (defined in H5SL.c) */ +typedef struct H5SL_t H5SL_t; +typedef struct H5SL_node_t H5SL_node_t; + +/* Typedef for kinds of skip lists supported */ +typedef enum { + H5SL_TYPE_INT, /* Skip list keys are 'int's */ + H5SL_TYPE_HADDR /* Skip list keys are 'haddr_t's */ +} H5SL_type_t; + +/**********/ +/* Macros */ +/**********/ +#define H5SL_LEVEL_MAX 32 /* (for now) */ + +/********************/ +/* Private routines */ +/********************/ +H5_DLL H5SL_t *H5SL_create(H5SL_type_t type, double p, size_t max_level); +H5_DLL ssize_t H5SL_count(H5SL_t *slist); +H5_DLL herr_t H5SL_insert(H5SL_t *slist, void *item, void *key); +H5_DLL void *H5SL_remove(H5SL_t *slist, void *key); +H5_DLL void *H5SL_search(H5SL_t *slist, void *key); +H5_DLL H5SL_node_t *H5SL_first(H5SL_t *slist); +H5_DLL H5SL_node_t *H5SL_next(H5SL_node_t *slist_node); +H5_DLL void *H5SL_item(H5SL_node_t *slist_node); +H5_DLL herr_t H5SL_close(H5SL_t *slist); + +#endif /* _H5HPprivate_H */ + diff --git a/test/tskiplist.c b/test/tskiplist.c new file mode 100644 index 0000000..20bde76 --- /dev/null +++ b/test/tskiplist.c @@ -0,0 +1,497 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + Test HDF Skip List routines. + + REMARKS + + DESIGN + + BUGS/LIMITATIONS + + EXPORTED ROUTINES + + AUTHOR + Quincey Koziol + + MODIFICATION HISTORY + 11/15/04 - Started coding + */ + +#include +#include + +#include "testhdf5.h" +#include "H5SLprivate.h" + +/* The number of elements in testing arrays */ +#define NUM_ELEMS 1000 + +/* Random numbers */ +static int rand_num[NUM_ELEMS]; +static int sort_rand_num[NUM_ELEMS]; +static int rev_sort_rand_num[NUM_ELEMS]; + +static int tst_sort(const void *i1, const void *i2) +{ + return(*(const int *)i1-*(const int *)i2); +} + +static int tst_rev_sort(const void *i1, const void *i2) +{ + return(*(const int *)i2-*(const int *)i1); +} + +/**************************************************************** +** +** test_skiplist_init(): Test H5SL (skiplist) code. +** Initialize data for skip list testing +** +****************************************************************/ +static void +test_skiplist_init(void) +{ + time_t curr_time; /* Current time, for seeding random number generator */ + int new_val; /* New value to insert */ + unsigned found; /* Flag to indicate value was inserted already */ + size_t u,v; /* Local index variables */ + + /* Initialize random number seed */ + curr_time=time(NULL); + HDsrandom((unsigned long)curr_time); + + /* Create randomized set of numbers */ + for(u=0; u