From 43db8230440604cac42af68264465c8a24605647 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Mon, 14 Sep 2009 14:52:42 -0500 Subject: [svn-r17475] Added error handling to h5dump and region reference handling functions in the tools lib. Bring back from NPOESS. Added missing tests to h5dump test script for region references. Tested: local linux --- MANIFEST | 4 +- tools/h5dump/testh5dump.sh.in | 3 + tools/lib/Makefile.am | 2 +- tools/lib/Makefile.in | 15 +- tools/lib/h5tools.c | 1369 +++++++++++++++++++++++++---------------- tools/lib/h5tools.h | 11 +- tools/lib/h5tools_error.h | 118 ++++ tools/lib/talign.c | 191 ------ tools/misc/Makefile.am | 2 +- tools/misc/Makefile.in | 19 +- tools/misc/talign.c | 191 ++++++ tools/testfiles/tdataregR.ddl | 60 ++ 12 files changed, 1232 insertions(+), 753 deletions(-) create mode 100644 tools/lib/h5tools_error.h delete mode 100644 tools/lib/talign.c create mode 100644 tools/misc/talign.c create mode 100644 tools/testfiles/tdataregR.ddl diff --git a/MANIFEST b/MANIFEST index 4f8bb14..f2d0777 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1072,7 +1072,7 @@ ./tools/lib/h5tools_ref.h ./tools/lib/h5tools_type.c ./tools/lib/ph5diff.h -./tools/lib/talign.c +./tools/lib/h5tools_error.h ./tools/misc/Makefile.am ./tools/misc/Makefile.in @@ -1085,6 +1085,7 @@ ./tools/misc/repart_test.c ./tools/misc/testh5mkgrp.sh ./tools/misc/testh5repart.sh.in +./tools/misc/talign.c ./tools/h5stat/Makefile.am ./tools/h5stat/Makefile.in @@ -1166,6 +1167,7 @@ ./tools/testfiles/tcompound_complex.h5 ./tools/testfiles/tdatareg.h5 ./tools/testfiles/tdatareg.ddl +./tools/testfiles/tdataregR.ddl ./tools/testfiles/tdset-1.ddl ./tools/testfiles/tdset-2.ddl ./tools/testfiles/tdset-3s.ddl diff --git a/tools/h5dump/testh5dump.sh.in b/tools/h5dump/testh5dump.sh.in index 5bf7f75..3ffff50 100644 --- a/tools/h5dump/testh5dump.sh.in +++ b/tools/h5dump/testh5dump.sh.in @@ -489,6 +489,9 @@ fi # test for dataset region references TOOLTEST tdatareg.ddl tdatareg.h5 +TOOLTEST tdataregR.ddl -R tdatareg.h5 +TOOLTEST tattrreg.ddl tattrreg.h5 +TOOLTEST tattrregR.ddl -R tattrreg.h5 # tests for group creation order # "1" tracked, "2" name, root tracked diff --git a/tools/lib/Makefile.am b/tools/lib/Makefile.am index c7e26e0..43ee863 100644 --- a/tools/lib/Makefile.am +++ b/tools/lib/Makefile.am @@ -31,7 +31,7 @@ libh5tools_la_SOURCES=h5tools.c h5tools_str.c h5tools_utils.c h5diff.c \ h5tools_filters.c h5tools_ref.c h5tools_type.c # Test program. Link using libhdf5 and libh5tools -TEST_PROG=talign +TEST_PROG= check_PROGRAMS=$(TEST_PROG) # Name libh5tools.la so that dependencies work out. Automake knows how diff --git a/tools/lib/Makefile.in b/tools/lib/Makefile.in index 0236c82..14d9a6d 100644 --- a/tools/lib/Makefile.in +++ b/tools/lib/Makefile.in @@ -72,11 +72,6 @@ am_libh5tools_la_OBJECTS = h5tools.lo h5tools_str.lo h5tools_utils.lo \ h5diff_util.lo h5trav.lo h5tools_filters.lo h5tools_ref.lo \ h5tools_type.lo libh5tools_la_OBJECTS = $(am_libh5tools_la_OBJECTS) -am__EXEEXT_1 = talign$(EXEEXT) -talign_SOURCES = talign.c -talign_OBJECTS = talign.$(OBJEXT) -talign_LDADD = $(LDADD) -talign_DEPENDENCIES = libh5tools.la $(LIBHDF5) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/bin/depcomp am__depfiles_maybe = depfiles @@ -90,8 +85,8 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(libh5tools_la_SOURCES) talign.c -DIST_SOURCES = $(libh5tools_la_SOURCES) talign.c +SOURCES = $(libh5tools_la_SOURCES) +DIST_SOURCES = $(libh5tools_la_SOURCES) ETAGS = etags CTAGS = ctags am__tty_colors = \ @@ -359,7 +354,7 @@ libh5tools_la_SOURCES = h5tools.c h5tools_str.c h5tools_utils.c h5diff.c \ # Test program. Link using libhdf5 and libh5tools -TEST_PROG = talign +TEST_PROG = # Name libh5tools.la so that dependencies work out. Automake knows how # to build 'libh5tools.la', but not '../../tools/lib/libh5tools.la'. @@ -434,9 +429,6 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -talign$(EXEEXT): $(talign_OBJECTS) $(talign_DEPENDENCIES) - @rm -f talign$(EXEEXT) - $(LINK) $(talign_OBJECTS) $(talign_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -456,7 +448,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5tools_type.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5tools_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5trav.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/talign.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index c1ad812..1df58c1 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -34,6 +34,9 @@ #define ALIGN(A,Z) ((((A) + (Z) - 1) / (Z)) * (Z)) /* global variables */ +hid_t H5tools_ERR_CLS_g = -1; +hid_t H5E_tools_g = -1; +hid_t H5E_tools_min_id_g = -1; int compound_data; FILE *rawdatastream; /* should initialize to stdout but gcc moans about it */ int bin_output; /* binary output */ @@ -213,6 +216,11 @@ hbool_t h5tools_render_region_element(FILE *stream, const h5tool_format_t *info, hsize_t local_elmt_counter/*element counter*/, hsize_t elmt_counter); +int h5tools_print_region_data_blocks(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, h5tools_context_t ctx, + h5tools_str_t *buffer/*string into which to render */, size_t ncols, + int ndims, hid_t type_id, hssize_t nblocks, hsize_t *ptdata); + hbool_t h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, @@ -221,6 +229,11 @@ hbool_t h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, size_t ncols, hsize_t region_elmt_counter/*element counter*/, hsize_t elmt_counter); +int h5tools_print_region_data_points(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, h5tools_context_t ctx, + h5tools_str_t *buffer, size_t ncols, + int ndims, hid_t type_id, hssize_t npoints, hsize_t *ptdata); + hbool_t h5tools_dump_region_data_blocks(hid_t region_space, hid_t region_id, FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, @@ -285,7 +298,14 @@ enum { void h5tools_init(void) { + char lib_str[256]; + if (!h5tools_init_g) { + /* register the error class */ + sprintf(lib_str, "%d.%d.%d",H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE); + + H5TOOLS_INIT_ERROR() + if (!rawdatastream) rawdatastream = stdout; @@ -325,6 +345,8 @@ h5tools_close(void) /* Clean up the reference path table, if it's been used */ term_ref_path_table(); + H5TOOLS_CLOSE_ERROR() + /* Shut down the library */ H5close(); @@ -875,7 +897,8 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai h5tools_str_append(&buffer, "NULL"); } else { - H5Rget_name(region_id, H5R_DATASET_REGION, memref, (char*) ref_name, 1024); + if(H5Rget_name(region_id, H5R_DATASET_REGION, memref, (char*) ref_name, 1024)<0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Rget_name failed"); /* Render the region element begin */ h5tools_str_reset(&buffer); @@ -883,7 +906,7 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai h5tools_str_append(&buffer, info->dset_format, ref_name); dimension_break = h5tools_render_element(stream, info, - ctx, &buffer, &curr_pos, ncols, i, elmt_counter); + ctx, &buffer, &curr_pos, ncols, i, elmt_counter); region_type = H5Sget_select_type(region_space); if(region_type==H5S_SEL_POINTS) @@ -891,18 +914,28 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai dimension_break = h5tools_dump_region_data_points( region_space, region_id, stream, info, ctx, &buffer, &curr_pos, ncols, i, elmt_counter); - else + else if(region_type==H5S_SEL_HYPERSLABS) /* Print block information */ dimension_break = h5tools_dump_region_data_blocks( region_space, region_id, stream, info, ctx, &buffer, &curr_pos, ncols, i, elmt_counter); + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "invalid region type"); /* Render the region element end */ } /* end else to if (h5tools_is_zero(... */ - H5Sclose(region_space); + if(H5Sclose(region_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); } /* end if (region_space >= 0) */ - H5Dclose(region_id); + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Rget_region failed"); + if(H5Dclose(region_id) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Dclose failed"); + } /* if (region_id >= 0) */ + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Rdereference failed"); + ctx->need_prefix = TRUE; } /* end if (region_output... */ else { @@ -1241,6 +1274,157 @@ h5tools_render_region_element(FILE *stream, const h5tool_format_t *info, /*------------------------------------------------------------------------- * Audience: Public * Chapter: H5Tools Library + * Purpose: Print the data values from a dataset referenced by region blocks. + * + * Description: + * This is a special case subfunction to print the data in a region reference of type blocks. + * + * Return: + * The function returns FAIL if there was an error, otherwise SUCEED + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * size_t ncols + * int ndims is the number of dimensions of the region element + * hssize_t nblocks is the number of blocks in the region + *------------------------------------------------------------------------- + */ +int +h5tools_print_region_data_blocks(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, h5tools_context_t ctx, + h5tools_str_t *buffer/*string into which to render */, size_t ncols, + int ndims, hid_t type_id, hssize_t nblocks, hsize_t *ptdata) { + HERR_INIT(int, FAIL) + hbool_t dimension_break = TRUE; + hsize_t *dims1 = NULL; + hsize_t *start = NULL; + hsize_t *count = NULL; + size_t numelem; + hsize_t total_size[H5S_MAX_RANK]; + hsize_t elmtno; /* elemnt index */ + unsigned int region_flags; /* buffer extent flags */ + hsize_t curr_pos; + int jndx; + int type_size; + hid_t mem_space; + void *region_buf = NULL; + int blkndx; + hid_t sid1; + + /* Get the dataspace of the dataset */ + if((sid1 = H5Dget_space(region_id)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_space failed"); + + /* Allocate space for the dimension array */ + if((dims1 = (hsize_t *) malloc(sizeof(hsize_t) * ndims)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for dims"); + + /* find the dimensions of each data space from the block coordinates */ + numelem = 1; + for (jndx = 0; jndx < ndims; jndx++) { + dims1[jndx] = ptdata[jndx + ndims] - ptdata[jndx] + 1; + numelem = dims1[jndx] * numelem; + } + + /* Create dataspace for reading buffer */ + if((mem_space = H5Screate_simple(ndims, dims1, NULL)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Screate_simple failed"); + + if((type_size = H5Tget_size(type_id)) == 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); + + if((region_buf = malloc(type_size * numelem)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate region buffer"); + + /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */ + /* 1 2 n 1 2 n */ + if((start = (hsize_t *) malloc(sizeof(hsize_t) * ndims)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for start"); + + if((count = (hsize_t *) malloc(sizeof(hsize_t) * ndims)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for count"); + + curr_pos = 0; + for (blkndx = 0; blkndx < nblocks; blkndx++) { + ctx.ndims = ndims; + ctx.need_prefix = TRUE; + ctx.cur_elmt = 0; + for (jndx = 0; jndx < ndims; jndx++) { + start[jndx] = ptdata[jndx + blkndx * ndims * 2]; + count[jndx] = dims1[jndx]; + } + + if(H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sselect_hyperslab failed"); + + if(H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Dread failed"); + + ctx.indent_level++; + if(H5Sget_simple_extent_dims(mem_space, total_size, NULL) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); + + /* assume entire data space to be printed */ + for (jndx = 0; jndx < (size_t) ctx.ndims; jndx++) + ctx.p_min_idx[jndx] = start[jndx]; + init_acc_pos(&ctx, total_size); + + /* print the data */ + region_flags = START_OF_DATA; + if (blkndx == nblocks - 1) + region_flags |= END_OF_DATA; + + for (jndx = 0; jndx < ctx.ndims; jndx++) + ctx.p_max_idx[jndx] = dims1[jndx]; + + curr_pos = 0; + ctx.sm_pos = blkndx*2*ndims; + ctx.size_last_dim = dims1[ndims-1]; + + h5tools_region_simple_prefix(stream, info, &ctx, curr_pos, ptdata, 0); + + elmtno = 0; + for (jndx = 0; jndx < numelem; jndx++, elmtno++, ctx.cur_elmt++) { + /* Render the region data element begin */ + h5tools_str_reset(buffer); + + h5tools_str_append(buffer, "%s", jndx ? OPTIONAL_LINE_BREAK "" : ""); + h5tools_str_sprint(buffer, info, region_id, type_id, + ((char*)region_buf + jndx * type_size), &ctx); + + if (jndx + 1 < numelem || (region_flags & END_OF_DATA) == 0) + h5tools_str_append(buffer, "%s", OPT(info->elmt_suf1, ",")); + + dimension_break = h5tools_render_region_element(stream, info, &ctx, buffer, &curr_pos, + ncols, ptdata, jndx, elmtno); + /* Render the region data element end */ + + if(FALSE == dimension_break) + elmtno = 0; + } /* end for (jndx = 0; jndx < numelem; jndx++, region_elmtno++, ctx.cur_elmt++) */ + + ctx.indent_level--; + } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */ + + done: + free(start); + free(count); + free(region_buf); + free(dims1); + + if(H5Sclose(mem_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + if(H5Sclose(sid1) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + + H5_LEAVE(SUCCEED) +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library * Purpose: Print some values from a dataset referenced by region blocks. * * Description: @@ -1269,39 +1453,22 @@ h5tools_dump_region_data_blocks(hid_t region_space, hid_t region_id, hsize_t *curr_pos/*total data element position*/, size_t ncols, hsize_t region_elmt_counter/*element counter*/, hsize_t elmt_counter) { - hbool_t dimension_break = TRUE; - hssize_t nblocks; - hsize_t alloc_size; - hsize_t *ptdata; - hsize_t *dims1; - hsize_t *start; - hsize_t *count; - size_t numelem; - hsize_t region_total_size[H5S_MAX_RANK]; - h5tools_context_t region_ctx; /* print context */ - hsize_t region_elmtno; /* elemnt index */ - hbool_t region_dimension_break = TRUE; - unsigned int region_flags; /* buffer extent flags */ - hsize_t region_curr_pos; - int ndims; - int jndx; - int type_size; - hid_t mem_space; - hid_t dtype; - hid_t type_id; - void *region_buf; - herr_t status; - int i; - int blkndx; - hid_t sid1; - - nblocks = H5Sget_select_hyper_nblocks(region_space); - - if (nblocks <= 0) - return dimension_break; + HERR_INIT(hbool_t, TRUE) + hbool_t dimension_break = TRUE; + hssize_t nblocks; + hsize_t alloc_size; + hsize_t *ptdata = NULL; + int ndims; + hid_t dtype; + hid_t type_id; + int i; + + if((nblocks = H5Sget_select_hyper_nblocks(region_space)) <= 0) + H5E_THROW(dimension_break, H5E_tools_min_id_g, "H5Sget_select_hyper_nblocks failed"); /* Print block information */ - ndims = H5Sget_simple_extent_ndims(region_space); + if((ndims = H5Sget_simple_extent_ndims(region_space)) < 0) + H5E_THROW(dimension_break, H5E_tools_min_id_g, "H5Sget_simple_extent_ndims failed"); /* Render the region { element begin */ h5tools_str_reset(buffer); @@ -1319,9 +1486,12 @@ h5tools_dump_region_data_blocks(hid_t region_space, hid_t region_id, alloc_size = nblocks * ndims * 2 * sizeof(ptdata[0]); assert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ - ptdata = (hsize_t*) malloc((size_t) alloc_size); + if((ptdata = (hsize_t*) malloc((size_t) alloc_size)) == NULL) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "Could not allocate buffer for ptdata"); + H5_CHECK_OVERFLOW(nblocks, hssize_t, hsize_t); - H5Sget_select_hyper_blocklist(region_space, (hsize_t) 0, (hsize_t) nblocks, ptdata); + if(H5Sget_select_hyper_blocklist(region_space, (hsize_t) 0, (hsize_t) nblocks, ptdata) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Rget_select_hyper_blocklist failed"); for (i = 0; i < nblocks; i++) { int j; @@ -1346,8 +1516,10 @@ h5tools_dump_region_data_blocks(hid_t region_space, hid_t region_id, ctx->need_prefix = TRUE; - dtype = H5Dget_type(region_id); - type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT); + if((dtype = H5Dget_type(region_id)) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Dget_type failed"); + if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Tget_native_type failed"); /* Render the datatype element begin */ h5tools_str_reset(buffer); @@ -1376,7 +1548,7 @@ h5tools_dump_region_data_blocks(hid_t region_space, hid_t region_id, ctx->need_prefix = TRUE; h5tools_str_append(buffer, "%s ", h5tools_dump_header_format->dataspacebegin); - h5tools_print_dataspace(buffer, info, ctx, region_space); + h5tools_print_dataspace(buffer, region_space); if (HDstrlen(h5tools_dump_header_format->dataspaceblockend)) { h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); @@ -1403,106 +1575,14 @@ h5tools_dump_region_data_blocks(hid_t region_space, hid_t region_id, ctx->need_prefix = TRUE; + h5tools_print_region_data_blocks(region_space, region_id, + stream, info, *ctx, buffer, ncols, ndims, type_id, nblocks, ptdata); - /* Get the dataspace of the dataset */ - sid1 = H5Dget_space(region_id); - - /* Allocate space for the dimension array */ - dims1 = (hsize_t *) malloc(sizeof(hsize_t) * ndims); - - /* find the dimensions of each data space from the block coordinates */ - numelem = 1; - for (jndx = 0; jndx < ndims; jndx++) { - dims1[jndx] = ptdata[jndx + ndims] - ptdata[jndx] + 1; - numelem = dims1[jndx] * numelem; - } - - /* Create dataspace for reading buffer */ - mem_space = H5Screate_simple(ndims, dims1, NULL); - - type_size = H5Tget_size(type_id); - region_buf = malloc(type_size * numelem); - - /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */ - /* 1 2 n 1 2 n */ - - start = (hsize_t *) malloc(sizeof(hsize_t) * ndims); - count = (hsize_t *) malloc(sizeof(hsize_t) * ndims); - region_curr_pos = 0; - for (blkndx = 0; blkndx < nblocks; blkndx++) { - /* initialize context structure for the region loop */ - memset(®ion_ctx, 0, sizeof(region_ctx)); - region_ctx.indent_level = ctx->indent_level; - region_ctx.ndims = ndims; - region_ctx.need_prefix = TRUE; - region_ctx.cur_column = ctx->cur_column; - region_ctx.cur_elmt = 0; - region_ctx.prev_multiline = ctx->prev_multiline; - region_ctx.prev_prefix_len = ctx->prev_prefix_len; - region_ctx.continuation = ctx->continuation; - region_ctx.default_indent_level = ctx->default_indent_level; - for (jndx = 0; jndx < ndims; jndx++) { - start[jndx] = ptdata[jndx + blkndx * ndims * 2]; - count[jndx] = dims1[jndx]; - } - - status = H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL); - - status = H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf); - - region_ctx.indent_level++; - H5Sget_simple_extent_dims(mem_space, region_total_size, NULL); - - /* assume entire data space to be printed */ - for (jndx = 0; jndx < (size_t) region_ctx.ndims; jndx++) - region_ctx.p_min_idx[jndx] = start[jndx]; - init_acc_pos(®ion_ctx, region_total_size); - - /* print the data */ - region_flags = START_OF_DATA; - if (blkndx == nblocks - 1) - region_flags |= END_OF_DATA; - - for (jndx = 0; jndx < region_ctx.ndims; jndx++) - region_ctx.p_max_idx[jndx] = dims1[jndx]; - - region_curr_pos = 0; - region_ctx.sm_pos = blkndx*2*ndims; - region_ctx.size_last_dim = dims1[ndims-1]; - - h5tools_region_simple_prefix(stream, info, ®ion_ctx, region_curr_pos, ptdata, 0); - - region_elmtno = 0; - for (jndx = 0; jndx < numelem; jndx++, region_elmtno++, region_ctx.cur_elmt++) { - /* Render the region data element begin */ - h5tools_str_reset(buffer); - - h5tools_str_append(buffer, "%s", jndx ? OPTIONAL_LINE_BREAK "" : ""); - h5tools_str_sprint(buffer, info, region_id, type_id, - ((char*)region_buf + jndx * type_size), ®ion_ctx); - - if (jndx + 1 < numelem || (region_flags & END_OF_DATA) == 0) - h5tools_str_append(buffer, "%s", OPT(info->elmt_suf1, ",")); - - region_dimension_break = h5tools_render_region_element(stream, info, ®ion_ctx, buffer, ®ion_curr_pos, - ncols, ptdata, jndx, region_elmtno); - /* Render the region data element end */ - - if(FALSE==region_dimension_break) - region_elmtno = 0; - } /* end for (jndx = 0; jndx < numelem; jndx++, region_elmtno++, region_ctx.cur_elmt++) */ - - region_ctx.indent_level--; - } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */ - - free(start); - free(count); - free(region_buf); + done: free(ptdata); - free(dims1); - status = H5Tclose(dtype); - status = H5Sclose(mem_space); - status = H5Sclose(sid1); + + if(H5Tclose(dtype) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); ctx->need_prefix = TRUE; @@ -1525,7 +1605,129 @@ h5tools_dump_region_data_blocks(hid_t region_space, hid_t region_id, ncols, region_elmt_counter, elmt_counter); /* Render the region } element end */ - return dimension_break; + H5_LEAVE(dimension_break) +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Print the data values from a dataset referenced by region points. + * + * Description: + * This is a special case subfunction to print the data in a region reference of type points. + * + * Return: + * The function returns FAIL on error, otherwise SUCCEED + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * size_t ncols + * int ndims is the number of dimensions of the region element + * hssize_t npoints is the number of points in the region + *------------------------------------------------------------------------- + */ +int +h5tools_print_region_data_points(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, h5tools_context_t ctx, + h5tools_str_t *buffer, size_t ncols, + int ndims, hid_t type_id, hssize_t npoints, hsize_t *ptdata) { + HERR_INIT(int, FAIL) + hbool_t dimension_break = TRUE; + hsize_t alloc_size; + hsize_t *dims1 = NULL; + h5tools_context_t region_ctx; /* print context */ + hsize_t elmtno; /* elemnt index */ + unsigned int region_flags; /* buffer extent flags */ + hsize_t curr_pos; + int indx; + int jndx; + int type_size; + hid_t mem_space; + hid_t dtype; + void *region_buf = NULL; + + if((type_size = H5Tget_size(type_id)) == 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); + + if((region_buf = malloc(type_size * npoints)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for region"); + + /* Allocate space for the dimension array */ + if((dims1 = (hsize_t *) malloc(sizeof(hsize_t) * ndims)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for dims"); + + dims1[0] = npoints; + if((mem_space = H5Screate_simple(1, dims1, NULL)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Screate_simple failed"); + + if(H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dread failed"); + + elmtno = 0; + curr_pos = 0; + for (jndx = 0; jndx < npoints; jndx++, elmtno++) { + ctx.ndims = ndims; + ctx.need_prefix = TRUE; + ctx.cur_elmt = 0; /* points are always 0 */ + + /* Render the point element begin */ + h5tools_str_reset(buffer); + + ctx.indent_level++; + + /* assume entire data space to be printed */ + for (indx = 0; indx < (size_t) ctx.ndims; indx++) + ctx.p_min_idx[indx] = 0; + if(H5Sget_simple_extent_dims(region_space, ctx.p_max_idx, NULL) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); + + if (ctx.ndims > 0) { + ctx.size_last_dim = (int) (ctx.p_max_idx[ctx.ndims - 1]); + } + else + ctx.size_last_dim = 0; + + if (ctx.ndims > 0) + init_acc_pos(&ctx, ctx.p_max_idx); + + /* print the data */ + region_flags = START_OF_DATA; + if (jndx == npoints - 1) + region_flags |= END_OF_DATA; + + curr_pos = 0; /* points requires constant 0 */ + ctx.sm_pos = jndx * ndims; + + h5tools_region_simple_prefix(stream, info, &ctx, curr_pos, ptdata, 0); + + h5tools_str_sprint(buffer, info, region_id, type_id, + ((char*)region_buf + jndx * type_size), &ctx); + + if (jndx + 1 < npoints || (region_flags & END_OF_DATA) == 0) + h5tools_str_append(buffer, "%s", OPT(info->elmt_suf1, ",")); + + dimension_break = + h5tools_render_region_element(stream, info, &ctx, buffer, &curr_pos, + ncols, ptdata, 0, elmtno); + /* Render the point element end */ + + ctx.indent_level--; + if(FALSE == dimension_break) + elmtno = 0; + } /* end for (jndx = 0; jndx < npoints; jndx++, region_elmtno++) */ + + done: + free(region_buf); + free(dims1); + + if(H5Sclose(mem_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + + H5_LEAVE(SUCCEED) +CATCH + return ret_value; } /*------------------------------------------------------------------------- @@ -1556,30 +1758,22 @@ h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx, h5tools_str_t *buffer, hsize_t *curr_pos, size_t ncols, hsize_t region_elmt_counter, hsize_t elmt_counter) { + HERR_INIT(hbool_t, TRUE) hbool_t dimension_break = TRUE; hssize_t npoints; hsize_t alloc_size; hsize_t *ptdata; - hsize_t *dims1; - h5tools_context_t region_ctx; /* print context */ - hsize_t region_elmtno; /* elemnt index */ - hbool_t region_dimension_break = TRUE; - unsigned int region_flags; /* buffer extent flags */ - hsize_t region_curr_pos; int ndims; int indx; - int jndx; - int type_size; - hid_t mem_space; hid_t dtype; hid_t type_id; - void *region_buf; - herr_t status; - npoints = H5Sget_select_elem_npoints(region_space); - - if (npoints <= 0) - return dimension_break; + if((npoints = H5Sget_select_elem_npoints(region_space)) <= 0) + H5E_THROW(dimension_break, H5E_tools_min_id_g, "H5Sget_select_elem_npoints failed"); + + /* Allocate space for the dimension array */ + if((ndims = H5Sget_simple_extent_ndims(region_space)) < 0) + H5E_THROW(dimension_break, H5E_tools_min_id_g, "H5Sget_simple_extent_ndims failed"); /* Render the region { element begin */ h5tools_str_reset(buffer); @@ -1595,13 +1789,14 @@ h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, ctx->need_prefix = TRUE; h5tools_str_append(buffer, "REGION_TYPE POINT "); - /* Allocate space for the dimension array */ - ndims = H5Sget_simple_extent_ndims(region_space); alloc_size = npoints * ndims * sizeof(ptdata[0]); assert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ - ptdata = malloc((size_t) alloc_size); + if((ptdata = malloc((size_t) alloc_size)) == NULL) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "Could not allocate buffer for ptdata"); + H5_CHECK_OVERFLOW(npoints, hssize_t, hsize_t); - H5Sget_select_elem_pointlist(region_space, (hsize_t) 0, (hsize_t) npoints, ptdata); + if(H5Sget_select_elem_pointlist(region_space, (hsize_t) 0, (hsize_t) npoints, ptdata) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Sget_select_elem_pointlist failed"); for (indx = 0; indx < npoints; indx++) { int loop_indx; @@ -1621,8 +1816,11 @@ h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, ctx->need_prefix = TRUE; - dtype = H5Dget_type(region_id); - type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT); + if((dtype = H5Dget_type(region_id)) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Dget_type failed"); + + if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Tget_native_type failed"); /* Render the datatype element begin */ h5tools_str_reset(buffer); @@ -1651,7 +1849,7 @@ h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, ctx->need_prefix = TRUE; h5tools_str_append(buffer, "%s ", h5tools_dump_header_format->dataspacebegin); - h5tools_print_dataspace(buffer, info, ctx, region_space); + h5tools_print_dataspace(buffer, region_space); if (HDstrlen(h5tools_dump_header_format->dataspaceblockend)) { h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); @@ -1678,83 +1876,14 @@ h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, ctx->need_prefix = TRUE; - type_size = H5Tget_size(type_id); - - region_buf = malloc(type_size * npoints); - - /* Allocate space for the dimension array */ - dims1 = (hsize_t *) malloc(sizeof(hsize_t) * ndims); - - dims1[0] = npoints; - mem_space = H5Screate_simple(1, dims1, NULL); - - status = H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf); - - region_elmtno = 0; - region_curr_pos = 0; - for (jndx = 0; jndx < npoints; jndx++, region_elmtno++) { - /* initialize context structure for the region loop */ - memset(®ion_ctx, 0, sizeof(region_ctx)); - region_ctx.indent_level = ctx->indent_level; - region_ctx.ndims = ndims; - region_ctx.need_prefix = TRUE; - region_ctx.cur_column = ctx->cur_column; - region_ctx.cur_elmt = 0; /* points are always 0 */ - region_ctx.prev_multiline = ctx->prev_multiline; - region_ctx.prev_prefix_len = ctx->prev_prefix_len; - region_ctx.continuation = ctx->continuation; - region_ctx.default_indent_level = ctx->default_indent_level; - - /* Render the point element begin */ - h5tools_str_reset(buffer); - - region_ctx.indent_level++; - - /* assume entire data space to be printed */ - for (indx = 0; indx < (size_t) region_ctx.ndims; indx++) - region_ctx.p_min_idx[indx] = 0; - H5Sget_simple_extent_dims(region_space, region_ctx.p_max_idx, NULL); - - if (region_ctx.ndims > 0) { - region_ctx.size_last_dim = (int) (region_ctx.p_max_idx[region_ctx.ndims - 1]); - } - else - region_ctx.size_last_dim = 0; - - if (region_ctx.ndims > 0) - init_acc_pos(®ion_ctx, region_ctx.p_max_idx); - - /* print the data */ - region_flags = START_OF_DATA; - if (jndx == npoints - 1) - region_flags |= END_OF_DATA; + h5tools_print_region_data_points(region_space, region_id, + stream, info, *ctx, buffer, ncols, ndims, type_id, npoints, ptdata); - region_curr_pos = 0; /* points requires constant 0 */ - region_ctx.sm_pos = jndx * ndims; - - h5tools_region_simple_prefix(stream, info, ®ion_ctx, region_curr_pos, ptdata, 0); - - h5tools_str_sprint(buffer, info, region_id, type_id, - ((char*)region_buf + jndx * type_size), ®ion_ctx); - - if (jndx + 1 < npoints || (region_flags & END_OF_DATA) == 0) - h5tools_str_append(buffer, "%s", OPT(info->elmt_suf1, ",")); - - region_dimension_break = - h5tools_render_region_element(stream, info, ®ion_ctx, buffer, ®ion_curr_pos, - ncols, ptdata, 0, region_elmtno); - /* Render the point element end */ - - region_ctx.indent_level--; - if(FALSE == region_dimension_break) - region_elmtno = 0; - } /* end for (jndx = 0; jndx < npoints; jndx++, region_elmtno++) */ - - free(region_buf); + done: free(ptdata); - free(dims1); - status = H5Tclose(dtype); - status = H5Sclose(mem_space); + + if(H5Tclose(dtype) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); ctx->need_prefix = TRUE; @@ -1777,13 +1906,15 @@ h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, ncols, region_elmt_counter, elmt_counter); /* Render the region } element end */ - return dimension_break; + H5_LEAVE(dimension_break) +CATCH + return ret_value; } /*------------------------------------------------------------------------- * Audience: Public * Chapter: H5Tools Library - * Purpose: Dump out a subset of a dataset. + * Purpose: print out the data for a subset of a dataset. * Description: * * Select a hyperslab from the dataset DSET using the parameters @@ -1795,22 +1926,13 @@ h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, * Return: * On success, return SUCCEED. Otherwise, the function returns FAIL. * - * Original programmer: - * Bill Wendling, Wednesday, March 07, 2001 - * - * Rewritten with modified algorithm by: - * Pedro Vicente, Wednesday, January 16, 2008, contributions from Quincey Koziol - * * Algorithm * - * In a inner loop, the parameters from SSET are translated into temporary + * The parameters from SSET are translated into temporary * variables so that 1 row is printed at a time (getting the coordinate indices * at each row). * We define the stride, count and block to be 1 in the row dimension to achieve * this and advance until all points are printed. - * An outer loop for cases where dimensionality is greater than 2D is made. - * In each iteration, the 2D block is displayed in the inner loop. The remaining - * slower dimensions above the first 2 are incremented one at a time in the outer loop * * The element position is obtained from the matrix according to: * Given an index I(z,y,x) its position from the beginning of an array @@ -1822,27 +1944,184 @@ h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, *------------------------------------------------------------------------- */ static herr_t -h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset, - hid_t p_type, struct subset_t *sset, int indentlevel) +h5tools_print_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx, + hid_t dset, hid_t p_type, struct subset_t *sset, + hid_t f_space, hsize_t hyperslab_count, + hsize_t *temp_start,/* start inside offset count loop */ + hsize_t *temp_count,/* count inside offset count loop */ + hsize_t *temp_block,/* block size used in loop */ + hsize_t *temp_stride,/* stride size used in loop */ + hsize_t *total_size,/* total size of dataset */ + unsigned int row_dim/* index of row_counter dimension */) { - herr_t ret; /* the value to return */ - hid_t f_space; /* file data space */ + HERR_INIT(herr_t, FAIL) size_t i; /* counters */ size_t j; /* counters */ - hsize_t n; /* counters */ hsize_t zero = 0; /* vector of zeros */ unsigned int flags; /* buffer extent flags */ - hsize_t total_size[H5S_MAX_RANK];/* total size of dataset*/ hsize_t elmtno; /* elemnt index */ hsize_t low[H5S_MAX_RANK]; /* low bound of hyperslab */ hsize_t high[H5S_MAX_RANK]; /* higher bound of hyperslab */ - h5tools_context_t ctx; /* print context */ size_t p_type_nbytes; /* size of memory type */ hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */ hsize_t sm_nbytes; /* bytes per stripmine */ hsize_t sm_nelmts; /* elements per stripmine*/ - unsigned char *sm_buf = NULL; /* buffer for raw data */ + unsigned char *sm_buf = NULL; /* buffer for raw data */ hid_t sm_space; /* stripmine data space */ + hsize_t size_row_block; /* size for blocks along rows */ + hsize_t row_counter = 0; + + if ((size_t) ctx->ndims > NELMTS(sm_size)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "ndims and sm_size comparision failed"); + + if (ctx->ndims > 0) + init_acc_pos(ctx, total_size); + + size_row_block = sset->block[row_dim]; + + /* display loop */ + for (; hyperslab_count > 0; temp_start[row_dim] += temp_stride[row_dim], hyperslab_count--) { + /* jump rows if size of block exceeded + cases where block > 1 only and stride > block */ + if (size_row_block > 1 + && row_counter == size_row_block + && sset->stride[row_dim] > sset->block[row_dim]) { + + hsize_t increase_rows = sset->stride[row_dim] - sset->block[row_dim]; + temp_start[row_dim] += increase_rows; + row_counter = 0; + } + + row_counter++; + + /* calculate the potential number of elements we're going to print */ + if(H5Sselect_hyperslab(f_space, H5S_SELECT_SET, temp_start, temp_stride, temp_count, temp_block) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sselect_hyperslab failed"); + + if((sm_nelmts = H5Sget_select_npoints(f_space)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_select_npoints failed"); + + if (sm_nelmts > 0) { + /* + * determine the strip mine size and allocate a buffer. the strip mine is + * a hyperslab whose size is manageable. + */ + if((sm_nbytes = p_type_nbytes = H5Tget_size(p_type)) == 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); + + if (ctx->ndims > 0) + for (i = ctx->ndims; i > 0; --i) { + hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes; + if (size == 0) /* datum size > H5TOOLS_BUFSIZE */ + size = 1; + sm_size[i - 1] = MIN(total_size[i - 1], size); + sm_nbytes *= sm_size[i - 1]; + assert(sm_nbytes > 0); + } + + assert(sm_nbytes == (hsize_t) ((size_t) sm_nbytes)); /*check for overflow*/ + if((sm_buf = malloc((size_t) sm_nelmts * p_type_nbytes)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for strip-mine"); + + if((sm_space = H5Screate_simple(1, &sm_nelmts, NULL)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Screate_simple failed"); + + if(H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, &zero, NULL, &sm_nelmts, NULL) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sselect_hyperslab failed"); + + /* read the data */ + if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) < 0) { + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dread failed"); + } + + /* print the data */ + flags = START_OF_DATA; + + if (hyperslab_count == 1) + flags |= END_OF_DATA; + + for (i = 0; i < ctx->ndims; i++) + ctx->p_max_idx[i] = ctx->p_min_idx[i] + MIN(total_size[i], sm_size[i]); + + /* print array indices. get the lower bound of the hyperslab and calulate + the element position at the start of hyperslab */ + if(H5Sget_select_bounds(f_space, low, high) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_select_bounds failed"); + + elmtno = 0; + for (i = 0; i < (size_t) ctx->ndims - 1; i++) { + hsize_t offset = 1; /* accumulation of the previous dimensions */ + for (j = i + 1; j < (size_t) ctx->ndims; j++) + offset *= total_size[j]; + elmtno += low[i] * offset; + } + elmtno += low[ctx->ndims - 1]; + + /* initialize the current stripmine position; this is necessary to print the array + indices */ + ctx->sm_pos = elmtno; + + h5tools_dump_simple_data(stream, info, dset, ctx, flags, sm_nelmts, p_type, sm_buf); +done: + if(H5Sclose(sm_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + free(sm_buf); + } + else + H5E_THROW(SUCCEED, H5E_tools_min_id_g, "nothing to print"); + /* we need to jump to next line and update the index */ + ctx->need_prefix = 1; + + ctx->continuation++; + + } /* hyperslab_count loop */ + + H5_LEAVE(SUCCEED) + +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: print out the data for a subset of a dataset. + * Description: + * + * Select a hyperslab from the dataset DSET using the parameters + * specified in SSET. Dump this out to STREAM. + * + * Hyperslabs select "count" blocks of size "block", spaced "stride" elements + * from each other, starting at coordinate "start". + * + * Return: + * On success, return SUCCEED. Otherwise, the function returns FAIL. + * + * Algorithm + * + * The parameters from SSET are translated into temporary + * variables so that 1 row is printed at a time (getting the coordinate indices + * at each row). + * We define the stride, count and block to be 1 in the row dimension to achieve + * this and advance until all points are printed. + * + * The element position is obtained from the matrix according to: + * Given an index I(z,y,x) its position from the beginning of an array + * of sizes A(size_z, size_y,size_x) is given by + * Position of I(z,y,x) = index_z * size_y * size_x + * + index_y * size_x + * + index_x + * + *------------------------------------------------------------------------- + */ +static herr_t +h5tools_display_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx, + hid_t dset, hid_t p_type, struct subset_t *sset, + hid_t f_space, hsize_t *total_size) +{ + HERR_INIT(herr_t, FAIL) + size_t i; /* counters */ + hsize_t n; /* counters */ hsize_t count; /* hyperslab count */ hsize_t outer_count; /* offset count */ unsigned int row_dim; /* index of row_counter dimension */ @@ -1853,75 +2132,32 @@ h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset hsize_t temp_block[H5S_MAX_RANK];/* temporary block size used in loop */ hsize_t temp_stride[H5S_MAX_RANK];/* temporary stride size used in loop */ int reset_dim; - hsize_t size_row_block; /* size for blocks along rows */ - -#if defined (SANITY_CHECK) - hsize_t total_points = 1; /* to print */ - hsize_t printed_points = 0; /* printed */ -#endif - - ret = FAIL; /* be pessimistic */ - f_space = H5Dget_space(dset); - - if (f_space == FAIL) - goto done; - - /* - * check that everything looks okay. the dimensionality must not be too - * great and the dimensionality of the items selected for printing must - * match the dimensionality of the dataset. - */ - memset(&ctx, 0, sizeof(ctx)); - ctx.indent_level = indentlevel; - ctx.need_prefix = 1; - ctx.ndims = H5Sget_simple_extent_ndims(f_space); - - if ((size_t) ctx.ndims > NELMTS(sm_size)) - goto done_close; - - /* assume entire data space to be printed */ - if (ctx.ndims > 0) - for (i = 0; i < (size_t) ctx.ndims; i++) - ctx.p_min_idx[i] = 0; - H5Sget_simple_extent_dims(f_space, total_size, NULL); - ctx.size_last_dim = total_size[ctx.ndims - 1]; - - if (ctx.ndims == 1) + if (ctx->ndims == 1) row_dim = 0; else - row_dim = ctx.ndims - 2; + row_dim = ctx->ndims - 2; /* get the offset count */ outer_count = 1; - if (ctx.ndims > 2) - for (i = 0; i < (size_t) ctx.ndims - 2; i++) { + if (ctx->ndims > 2) + for (i = 0; i < (size_t) ctx->ndims - 2; i++) { /* consider block size */ outer_count = outer_count * sset->count[i] * sset->block[i]; } - if (ctx.ndims > 0) - init_acc_pos(&ctx, total_size); - - /* calculate total number of points to print */ -#if defined (SANITY_CHECK) - for (i = 0; i < (size_t) ctx.ndims; i++) { - total_points *= sset->count[i] * sset->block[i];; - } -#endif - /* initialize temporary start, count and maximum start */ - for (i = 0; i < (size_t) ctx.ndims; i++) { + for (i = 0; i < (size_t) ctx->ndims; i++) { temp_start[i] = sset->start[i]; temp_count[i] = sset->count[i]; temp_block[i] = sset->block[i]; temp_stride[i] = sset->stride[i]; max_start[i] = 0; - } - if (ctx.ndims > 2) { - for (i = 0; i < (size_t) ctx.ndims - 2; i++) { + + if (ctx->ndims > 2) { + for (i = 0; i < (size_t) ctx->ndims - 2; i++) { max_start[i] = temp_start[i] + sset->count[i]; temp_count[i] = 1; @@ -1930,11 +2166,8 @@ h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset /* offset loop */ for (n = 0; n < outer_count; n++) { - - hsize_t row_counter = 0; - /* number of read iterations in inner loop, read by rows, to match 2D display */ - if (ctx.ndims > 1) { + if (ctx->ndims > 1) { /* count is the number of iterations to display all the rows, the block size count times */ @@ -1953,113 +2186,17 @@ h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset else { count = 1; } - - size_row_block = sset->block[row_dim]; - - /* display loop */ - for (; count > 0; temp_start[row_dim] += temp_stride[row_dim], count--) { - - /* jump rows if size of block exceeded - cases where block > 1 only and stride > block */ - if (size_row_block > 1 - && row_counter == size_row_block - && sset->stride[row_dim] > sset->block[row_dim]) { - - hsize_t increase_rows = sset->stride[row_dim] - sset->block[row_dim]; - - temp_start[row_dim] += increase_rows; - - row_counter = 0; - - } - - row_counter++; - - /* calculate the potential number of elements we're going to print */ - H5Sselect_hyperslab(f_space, H5S_SELECT_SET, temp_start, temp_stride, temp_count, temp_block); - sm_nelmts = H5Sget_select_npoints(f_space); - - if (sm_nelmts == 0) { - /* nothing to print */ - ret = SUCCEED; - goto done_close; - } - - /* - * determine the strip mine size and allocate a buffer. the strip mine is - * a hyperslab whose size is manageable. - */ - sm_nbytes = p_type_nbytes = H5Tget_size(p_type); - - if (ctx.ndims > 0) - for (i = ctx.ndims; i > 0; --i) { - hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes; - if ( size == 0) /* datum size > H5TOOLS_BUFSIZE */ - size = 1; - sm_size[i - 1] = MIN(total_size[i - 1], size); - sm_nbytes *= sm_size[i - 1]; - assert(sm_nbytes > 0); - } - - assert(sm_nbytes == (hsize_t) ((size_t) sm_nbytes)); /*check for overflow*/ - sm_buf = malloc((size_t) sm_nelmts * p_type_nbytes); - sm_space = H5Screate_simple(1, &sm_nelmts, NULL); - - H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, &zero, NULL, &sm_nelmts, NULL); - - /* read the data */ - if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) < 0) { - H5Sclose(f_space); - H5Sclose(sm_space); - free(sm_buf); - return FAIL; - } - - /* print the data */ - flags = START_OF_DATA; - - if (count == 1) - flags |= END_OF_DATA; - - for (i = 0; i < ctx.ndims; i++) - ctx.p_max_idx[i] = ctx.p_min_idx[i] + MIN(total_size[i], sm_size[i]); - - /* print array indices. get the lower bound of the hyperslab and calulate - the element position at the start of hyperslab */ - H5Sget_select_bounds(f_space, low, high); - elmtno = 0; - for (i = 0; i < (size_t) ctx.ndims - 1; i++) { - hsize_t offset = 1; /* accumulation of the previous dimensions */ - for (j = i + 1; j < (size_t) ctx.ndims; j++) - offset *= total_size[j]; - elmtno += low[i] * offset; - } - elmtno += low[ctx.ndims - 1]; - - /* initialize the current stripmine position; this is necessary to print the array - indices */ - ctx.sm_pos = elmtno; - - h5tools_dump_simple_data(stream, info, dset, &ctx, flags, sm_nelmts, p_type, sm_buf); - free(sm_buf); - - /* we need to jump to next line and update the index */ - ctx.need_prefix = 1; - - ctx.continuation++; - -#if defined (SANITY_CHECK) - printed_points += sm_nelmts; -#endif - - } /* count */ - - if (ctx.ndims > 2) { + + h5tools_print_simple_subset(stream, info, ctx, dset, p_type, sset, + f_space, count, temp_start, temp_count, + temp_block, temp_stride, total_size, row_dim); + + if (ctx->ndims > 2) { /* dimension for start */ - current_outer_dim = (ctx.ndims - 2) - 1; + current_outer_dim = (ctx->ndims - 2) - 1; /* set start to original from current_outer_dim up */ - for (i = current_outer_dim + 1; i < ctx.ndims; i++) { + for (i = current_outer_dim + 1; i < ctx->ndims; i++) { temp_start[i] = sset->start[i]; } @@ -2082,24 +2219,103 @@ h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset } /* ctx.ndims > 1 */ } /* outer_count */ + + H5_LEAVE(SUCCEED) -#if defined (SANITY_CHECK) - assert(printed_points == total_points); -#endif +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Dump out a subset of a dataset. + * Description: + * + * Select a hyperslab from the dataset DSET using the parameters + * specified in SSET. Dump this out to STREAM. + * + * Hyperslabs select "count" blocks of size "block", spaced "stride" elements + * from each other, starting at coordinate "start". + * + * Return: + * On success, return SUCCEED. Otherwise, the function returns FAIL. + * + * Original programmer: + * Bill Wendling, Wednesday, March 07, 2001 + * + * Rewritten with modified algorithm by: + * Pedro Vicente, Wednesday, January 16, 2008, contributions from Quincey Koziol + * + * Algorithm + * + * In a inner loop, the parameters from SSET are translated into temporary + * variables so that 1 row is printed at a time (getting the coordinate indices + * at each row). + * We define the stride, count and block to be 1 in the row dimension to achieve + * this and advance until all points are printed. + * An outer loop for cases where dimensionality is greater than 2D is made. + * In each iteration, the 2D block is displayed in the inner loop. The remaining + * slower dimensions above the first 2 are incremented one at a time in the outer loop + * + * The element position is obtained from the matrix according to: + * Given an index I(z,y,x) its position from the beginning of an array + * of sizes A(size_z, size_y,size_x) is given by + * Position of I(z,y,x) = index_z * size_y * size_x + * + index_y * size_x + * + index_x + * + *------------------------------------------------------------------------- + */ +static herr_t +h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset, + hid_t p_type, struct subset_t *sset, int indentlevel) +{ + HERR_INIT(herr_t, FAIL) + hid_t f_space; /* file data space */ + size_t i; /* counters */ + hsize_t total_size[H5S_MAX_RANK];/* total size of dataset*/ + h5tools_context_t ctx; /* print context */ + + if((f_space = H5Dget_space(dset)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Dget_space failed"); + + /* + * check that everything looks okay. the dimensionality must not be too + * great and the dimensionality of the items selected for printing must + * match the dimensionality of the dataset. + */ + memset(&ctx, 0, sizeof(ctx)); + ctx.indent_level = indentlevel; + ctx.need_prefix = 1; + if((ctx.ndims = H5Sget_simple_extent_ndims(f_space)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_ndims failed"); + + /* assume entire data space to be printed */ + if (ctx.ndims > 0) + for (i = 0; i < (size_t) ctx.ndims; i++) + ctx.p_min_idx[i] = 0; + + if(H5Sget_simple_extent_dims(f_space, total_size, NULL) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); + ctx.size_last_dim = total_size[ctx.ndims - 1]; + h5tools_display_simple_subset(stream, info, &ctx, dset, p_type, sset, f_space, total_size); /* Terminate the output */ if (ctx.cur_column) { fputs(OPT(info->line_suf, ""), stream); putc('\n', stream); fputs(OPT(info->line_sep, ""), stream); } + + H5_LEAVE(SUCCEED) - ret = SUCCEED; - -done_close: - H5Sclose(f_space); done: - return ret; + if(H5Sclose(f_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + +CATCH + return ret_value; } /*------------------------------------------------------------------------- @@ -2474,6 +2690,7 @@ int h5tools_dump_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, hid_t type, hid_t space, void *mem, int indentlevel) { + HERR_INIT(int, FAIL) h5tool_format_t info_dflt; /* Use default values */ @@ -2487,9 +2704,11 @@ h5tools_dump_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, hid_t /* Check the data space */ if (H5Sis_simple(space) <= 0) - return -1; + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Sis_simple failed") - return h5tools_dump_simple_mem(stream, info, obj_id, type, space, mem, indentlevel); + H5_LEAVE(h5tools_dump_simple_mem(stream, info, obj_id, type, space, mem, indentlevel)) +CATCH + return ret_value; } /*------------------------------------------------------------------------- @@ -2504,28 +2723,32 @@ h5tools_dump_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, hid_t * *------------------------------------------------------------------------- */ -void +int h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, h5tools_context_t *ctx, hid_t type) { - char *mname; - hid_t mtype, str_type; - unsigned nmembers; - unsigned ndims; - unsigned i; - size_t size = 0; - hsize_t dims[H5TOOLS_DUMP_MAX_RANK]; - H5T_str_t str_pad; - H5T_cset_t cset; - H5T_order_t order; - hid_t super; - hid_t tmp_type; - htri_t is_vlstr = FALSE; - const char *order_s = NULL; /* byte order string */ - H5T_sign_t sign; /* sign scheme value */ - const char *sign_s = NULL; /* sign scheme string */ - - switch (H5Tget_class(type)) { + HERR_INIT(int, FAIL) + char *mname; + hid_t mtype, str_type; + unsigned nmembers; + unsigned ndims; + unsigned i; + size_t size = 0; + hsize_t dims[H5TOOLS_DUMP_MAX_RANK]; + H5T_str_t str_pad; + H5T_cset_t cset; + H5T_order_t order; + H5T_class_t type_class; + hid_t super; + hid_t tmp_type; + htri_t is_vlstr = FALSE; + const char *order_s = NULL; /* byte order string */ + H5T_sign_t sign; /* sign scheme value */ + const char *sign_s = NULL; /* sign scheme string */ + + if((type_class = H5Tget_class(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_class failed"); + switch (type_class) { case H5T_INTEGER: if (H5Tequal(type, H5T_STD_I8BE) == TRUE) { h5tools_str_append(buffer, "H5T_STD_I8BE"); @@ -2776,8 +2999,10 @@ h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, } /* If not equal to C variable-length string, check Fortran type. */ - H5Tclose(str_type); + if(H5Tclose(str_type) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); str_type = H5Tcopy(H5T_FORTRAN_S1); + H5Tset_cset(str_type, cset); H5Tset_size(str_type, size); H5Tset_strpad(str_type, str_pad); @@ -2803,8 +3028,11 @@ h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, /* Type doesn't match any of above. */ h5tools_str_append(buffer, "unknown_one_character_type;\n "); - done: H5Tclose(str_type); - H5Tclose(tmp_type); + done: + if(H5Tclose(str_type) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + if(H5Tclose(tmp_type) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); ctx->indent_level--; h5tools_str_append(buffer, "%s", h5tools_dump_header_format->strblockend); @@ -2847,22 +3075,28 @@ h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, break; case H5T_COMPOUND: - nmembers = H5Tget_nmembers(type); + if((nmembers = H5Tget_nmembers(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed"); + h5tools_str_append(buffer, "H5T_COMPOUND %s\n", h5tools_dump_header_format->structblockbegin); for (i = 0; i < nmembers; i++) { mname = H5Tget_member_name(type, i); - mtype = H5Tget_member_type(type, i); - - if (H5Tget_class(mtype) == H5T_COMPOUND) - ctx->indent_level++; - - h5tools_print_datatype(buffer, info, ctx, mtype); - - if (H5Tget_class(mtype) == H5T_COMPOUND) - ctx->indent_level--; - - h5tools_str_append(buffer, " \"%s\";\n", mname); + if((mtype = H5Tget_member_type(type, i))>=0) { + if (H5Tget_class(mtype) == H5T_COMPOUND) + ctx->indent_level++; + + h5tools_print_datatype(buffer, info, ctx, mtype); + + if (H5Tget_class(mtype) == H5T_COMPOUND) + ctx->indent_level--; + + h5tools_str_append(buffer, " \"%s\";\n", mname); + if(H5Tclose(mtype) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + } + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tget_member_type failed"); free(mname); } @@ -2882,50 +3116,67 @@ h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, break; case H5T_ENUM: + if((super = H5Tget_super(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed"); + h5tools_str_append(buffer, "H5T_ENUM %s\n", h5tools_dump_header_format->enumblockbegin); ctx->indent_level++; - super = H5Tget_super(type); + h5tools_print_datatype(buffer, info, ctx, super); + if(H5Tclose(super) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + h5tools_str_append(buffer, ";\n"); - h5tools_print_enum(buffer, info, ctx, type); + h5tools_print_enum(buffer, type); + ctx->indent_level--; h5tools_str_append(buffer, "%s", h5tools_dump_header_format->enumblockend); + break; case H5T_VLEN: + if((super = H5Tget_super(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed"); + h5tools_str_append(buffer, "H5T_VLEN %s ", h5tools_dump_header_format->vlenblockbegin); - super = H5Tget_super(type); + h5tools_print_datatype(buffer, info, ctx, super); - H5Tclose(super); + if(H5Tclose(super) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); - /* Print closing */ h5tools_str_append(buffer, "%s", h5tools_dump_header_format->vlenblockend); + break; case H5T_ARRAY: - /* Get array base type */ - super = H5Tget_super(type); - - /* Print lead-in */ h5tools_str_append(buffer, "H5T_ARRAY { "); /* Get array information */ - ndims = H5Tget_array_ndims(type); - H5Tget_array_dims2(type, dims); - - /* Print array dimensions */ - for (i = 0; i < ndims; i++) - h5tools_str_append(buffer, "[%d]", (int) dims[i]); - - h5tools_str_append(buffer, " "); - - /* Print base type */ - h5tools_print_datatype(buffer, info, ctx, super); + if((ndims = H5Tget_array_ndims(type)) >= 0) { + if(H5Tget_array_dims2(type, dims) >= 0) { + /* Print array dimensions */ + for (i = 0; i < ndims; i++) + h5tools_str_append(buffer, "[%d]", (int) dims[i]); + + h5tools_str_append(buffer, " "); + } + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tget_array_dims2 failed"); + } + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tget_array_ndims failed"); - /* Close array base type */ - H5Tclose(super); + /* Get array base type */ + if((super = H5Tget_super(type)) >= 0) { + /* Print base type */ + h5tools_print_datatype(buffer, info, ctx, super); + /* Close array base type */ + if(H5Tclose(super) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + } + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tget_super failed"); - /* Print closing */ h5tools_str_append(buffer, " }"); break; @@ -2934,6 +3185,11 @@ h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, h5tools_str_append(buffer, "unknown datatype"); break; } + + H5_LEAVE(SUCCEED) + +CATCH + return ret_value; } /*------------------------------------------------------------------------- @@ -2948,16 +3204,21 @@ h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, * *------------------------------------------------------------------------- */ -void -h5tools_print_dataspace(h5tools_str_t *buffer, const h5tool_format_t *info, - h5tools_context_t *ctx, hid_t space) +int +h5tools_print_dataspace(h5tools_str_t *buffer, hid_t space) { + HERR_INIT(int, FAIL) hsize_t size[H5TOOLS_DUMP_MAX_RANK]; hsize_t maxsize[H5TOOLS_DUMP_MAX_RANK]; - int ndims = H5Sget_simple_extent_dims(space, size, maxsize); - H5S_class_t space_type = H5Sget_simple_extent_type(space); + int ndims = -1; + H5S_class_t space_type = -1; int i; + if((ndims = H5Sget_simple_extent_dims(space, size, maxsize)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); + + if((space_type = H5Sget_simple_extent_type(space)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_type failed"); switch(space_type) { case H5S_SCALAR: @@ -3002,6 +3263,11 @@ h5tools_print_dataspace(h5tools_str_t *buffer, const h5tool_format_t *info, h5tools_str_append(buffer, "%s unknown dataspace %s\n", BEGIN, END); break; } /* end switch */ + + H5_LEAVE(SUCCEED) + +CATCH + return ret_value; } @@ -3016,35 +3282,44 @@ h5tools_print_dataspace(h5tools_str_t *buffer, const h5tool_format_t *info, * h5tools_context_t *ctx * *-----------------------------------------------------------------------*/ -void -h5tools_print_enum(h5tools_str_t *buffer, const h5tool_format_t *info, - h5tools_context_t *ctx, hid_t type) +int +h5tools_print_enum(h5tools_str_t *buffer, hid_t type) { + HERR_INIT(int, FAIL) char **name = NULL; /*member names */ unsigned char *value = NULL; /*value array */ unsigned char *copy = NULL; /*a pointer to value array */ unsigned nmembs; /*number of members */ int nchars; /*number of output characters */ - hid_t super; /*enum base integer type */ + hid_t super = -1; /*enum base integer type */ hid_t native = -1; /*native integer datatype */ + H5T_sign_t sign_type; /*sign of value type */ + size_t type_size; /*value type size */ size_t dst_size; /*destination value type size */ unsigned i; - nmembs = H5Tget_nmembers(type); + if((nmembs = H5Tget_nmembers(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed"); assert(nmembs > 0); - super = H5Tget_super(type); - + + if((super = H5Tget_super(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_super failed"); + + if((type_size = H5Tget_size(type)) <= 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_size(type) failed"); /* * Determine what datatype to use for the native values. To simplify * things we entertain three possibilities: * 1. long long -- the largest native signed integer - * 2. unsigned long long -- the largest native unsigned integer - * 3. raw format + * 2. unsigned long long -- the largest native unsigned integer + * 3. raw format */ - if (H5Tget_size(type) <= sizeof(long long)) { + if (type_size <= sizeof(long long)) { dst_size = sizeof(long long); - if (H5T_SGN_NONE == H5Tget_sign(type)) { + if((sign_type = H5Tget_sign(type))<0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_sign failed"); + if (H5T_SGN_NONE == sign_type) { native = H5T_NATIVE_ULLONG; } else { @@ -3052,21 +3327,25 @@ h5tools_print_enum(h5tools_str_t *buffer, const h5tool_format_t *info, } } else { - dst_size = H5Tget_size(type); + dst_size = type_size; } /* Get the names and raw values of all members */ - name = calloc(nmembs, sizeof(char *)); - value = calloc(nmembs, MAX(H5Tget_size(type), dst_size)); + if((name = calloc(nmembs, sizeof(char *))) == NULL) + H5E_THROW(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for member name"); + if((value = calloc(nmembs, MAX(type_size, dst_size))) == NULL) + H5E_THROW(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for member value"); for (i = 0; i < nmembs; i++) { name[i] = H5Tget_member_name(type, i); - H5Tget_member_value(type, i, value + i * H5Tget_size(type)); + if(H5Tget_member_value(type, i, value + i * type_size) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_member_value failed"); } /* Convert values to native datatype */ if (native > 0) - H5Tconvert(super, native, nmembs, value, NULL, H5P_DEFAULT); + if(H5Tconvert(super, native, nmembs, value, NULL, H5P_DEFAULT) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tconvert failed"); /* * Sort members by increasing value @@ -3102,6 +3381,10 @@ h5tools_print_enum(h5tools_str_t *buffer, const h5tool_format_t *info, h5tools_str_append(buffer, ";\n"); } + + H5_LEAVE(SUCCEED) + +CATCH /* Release resources */ for (i = 0; i < nmembs; i++) @@ -3109,10 +3392,14 @@ h5tools_print_enum(h5tools_str_t *buffer, const h5tool_format_t *info, free(name); free(value); - H5Tclose(super); + + if(H5Tclose(super) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tclose failed"); if (0 == nmembs) h5tools_str_append(buffer, "\n"); + + return ret_value; } /*------------------------------------------------------------------------- @@ -3209,11 +3496,13 @@ init_acc_pos(h5tools_context_t *ctx, hsize_t *dims) static int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) { + HERR_INIT(int, FAIL) unsigned char *mem = (unsigned char*)_mem; size_t size; /* datum size */ hsize_t i; /* element counter */ - size = H5Tget_size(tid); + if((size = H5Tget_size(tid)) == 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); for (i = 0; i < nelmts; i++) { if (render_bin_output(stream, tid, mem + i * size) < 0) { @@ -3221,8 +3510,10 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) return FAIL; } } + H5_LEAVE(SUCCEED) - return SUCCEED; +CATCH + return ret_value; } /*------------------------------------------------------------------------- @@ -3237,6 +3528,7 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) static int render_bin_output(FILE *stream, hid_t tid, void *_mem) { + HERR_INIT(int, FAIL) unsigned char *mem = (unsigned char*)_mem; size_t size; /* datum size */ float tempfloat; @@ -3262,7 +3554,8 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) } #endif - size = H5Tget_size(tid); + if((size = H5Tget_size(tid)) == 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); if (H5Tequal(tid, H5T_NATIVE_FLOAT)) { memcpy(&tempfloat, mem, sizeof(float)); @@ -3270,7 +3563,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%g ", tempfloat); #else if (1 != fwrite(&tempfloat, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_DOUBLE)) { @@ -3279,7 +3572,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%g ", tempdouble); #else if (1 != fwrite(&tempdouble, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } #if H5_SIZEOF_LONG_DOUBLE !=0 @@ -3289,7 +3582,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%Lf ", templdouble); #else if (1 != fwrite(&templdouble, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } #endif @@ -3307,7 +3600,8 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) } else { s = (char *) mem; - size = H5Tget_size(tid); + if((size = H5Tget_size(tid)) == 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); } for (i = 0; i < size && (s[i] || pad != H5T_STR_NULLTERM); i++) { memcpy(&tempuchar, &s[i], sizeof(unsigned char)); @@ -3315,7 +3609,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%d", tempuchar); #else if (1 != fwrite(&tempuchar, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } /* i */ } @@ -3325,7 +3619,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%d ", tempint); #else if (1 != fwrite(&tempint, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_UINT)) { @@ -3334,7 +3628,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%u ", tempuint); #else if (1 != fwrite(&tempuint, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_SCHAR)) { @@ -3343,7 +3637,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%d ", tempschar); #else if (1 != fwrite(&tempschar, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_UCHAR)) { @@ -3352,7 +3646,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%u ", tempuchar); #else if (1 != fwrite(&tempuchar, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_SHORT)) { @@ -3361,7 +3655,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%d ", tempshort); #else if (1 != fwrite(&tempshort, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_USHORT)) { @@ -3370,7 +3664,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%u ", tempushort); #else if (1 != fwrite(&tempushort, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_LONG)) { @@ -3379,7 +3673,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%ld ", templong); #else if (1 != fwrite(&templong, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_ULONG)) { @@ -3388,7 +3682,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%lu ", tempulong); #else if (1 != fwrite(&tempulong, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_LLONG)) { @@ -3397,7 +3691,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, fmt_llong, templlong); #else if (1 != fwrite(&templlong, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_ULLONG)) { @@ -3406,7 +3700,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, fmt_ullong, tempullong); #else if (1 != fwrite(&tempullong, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (H5Tequal(tid, H5T_NATIVE_HSSIZE)) { @@ -3416,7 +3710,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%d ", tempint); #else if (1 != fwrite(&tempint, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (sizeof(hssize_t) == sizeof(long)) { @@ -3425,7 +3719,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%ld ", templong); #else if (1 != fwrite(&templong, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else { @@ -3434,7 +3728,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, fmt_llong, templlong); #else if (1 != fwrite(&templlong, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } } @@ -3445,7 +3739,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%u ", tempuint); #else if (1 != fwrite(&tempuint, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else if (sizeof(hsize_t) == sizeof(long)) { @@ -3454,7 +3748,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%lu ", tempulong); #else if (1 != fwrite(&tempulong, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else { @@ -3463,7 +3757,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, fmt_ullong, tempullong); #else if (1 != fwrite(&tempullong, size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } } @@ -3492,7 +3786,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "0x%02x", mem[0]); #else if (1 != fwrite(&mem[0], size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else { @@ -3501,7 +3795,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%s%02x", i?":":"", mem[i]); #else if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } /*i*/ }/*else 1 */ @@ -3528,7 +3822,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) /* dump the array element */ for (i = 0; i < nelmts; i++) { if (render_bin_output(stream, memb, mem + i * size) < 0) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "render_bin_output failed"); } H5Tclose(memb); @@ -3548,7 +3842,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) for (i = 0; i < nelmts; i++) { /* dump the array element */ if (render_bin_output(stream, memb, ((char *) (((hvl_t *) mem)->p)) + i * size) < 0) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "render_bin_output failed"); } H5Tclose(memb); } @@ -3559,7 +3853,7 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "0x%02x", mem[0]); #else if (1 != fwrite(&mem[0], size, 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } else { @@ -3568,13 +3862,16 @@ render_bin_output(FILE *stream, hid_t tid, void *_mem) fprintf(stream, "%s%02x", i?":":"", mem[i]); #else if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif } /*i*/ }/*else 1 */ } - return SUCCEED; + H5_LEAVE(SUCCEED) + +CATCH + return ret_value; } /*------------------------------------------------------------------------- diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h index bc29009..2b1e4bf 100644 --- a/tools/lib/h5tools.h +++ b/tools/lib/h5tools.h @@ -23,6 +23,7 @@ #define H5TOOLS_H__ #include "hdf5.h" +#include "h5tools_error.h" #define ESCAPE_HTML 1 #define OPT(X,S) ((X) ? (X) : (S)) @@ -558,14 +559,10 @@ void init_acc_pos(h5tools_context_t *ctx, hsize_t *dims); */ void h5tools_dump_datatype(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, hid_t type); -void h5tools_print_dataspace(h5tools_str_t *buffer/*in,out*/, - const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, - hid_t space); -void h5tools_print_datatype(h5tools_str_t *buffer/*in,out*/, +int h5tools_print_dataspace(h5tools_str_t *buffer/*in,out*/, hid_t space); +int h5tools_print_datatype(h5tools_str_t *buffer/*in,out*/, const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, hid_t type); -void h5tools_print_enum(h5tools_str_t *buffer/*in,out*/, - const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, - hid_t type); +int h5tools_print_enum(h5tools_str_t *buffer/*in,out*/, hid_t type); #endif /* H5TOOLS_H__ */ diff --git a/tools/lib/h5tools_error.h b/tools/lib/h5tools_error.h new file mode 100644 index 0000000..9efe223 --- /dev/null +++ b/tools/lib/h5tools_error.h @@ -0,0 +1,118 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Header file for error values, etc. + */ +#ifndef H5TOOLS_ERROR_H_ +#define H5TOOLS_ERROR_H_ + +#include "H5Epublic.h" + +/* tools-HDF5 Error variables */ +extern hid_t H5tools_ERR_CLS_g; +extern hid_t H5E_tools_g; +extern hid_t H5E_tools_min_id_g; + +/* Use FUNC to safely handle variations of C99 __func__ keyword handling */ +#ifdef H5_HAVE_C99_FUNC +#define FUNC __func__ +#elif defined(H5_HAVE_FUNCTION) +#define FUNC __FUNCTION__ +#else +#error "We need __func__ or __FUNCTION__ to test function names!" +#endif + +/* + * H5TOOLS_INIT_ERROR macro, used to initialize error reporting. + */ +#define H5TOOLS_INIT_ERROR() { \ + H5tools_ERR_CLS_g = H5Eregister_class("H5tools", "HDF5:tools", lib_str); \ + H5E_tools_g= H5Ecreate_msg(H5tools_ERR_CLS_g, H5E_MAJOR, "Failure in tools library"); \ + H5E_tools_min_id_g = H5Ecreate_msg(H5tools_ERR_CLS_g, H5E_MINOR, "error in function"); \ +} + +/* + * H5TOOLS_CLOSE_ERROR macro, used to initialize error reporting. + */ +#define H5TOOLS_CLOSE_ERROR() { \ + H5Eclose_msg(H5E_tools_min_id_g); \ + H5Eclose_msg(H5E_tools_g); \ + H5Eunregister_class(H5tools_ERR_CLS_g); \ +} + +/* + * HERR_INIT macro, used to facilitate error reporting. Declaration and assignments of error variables. + * Use at the beginning of a function using error handling macros. + */ +#define HERR_INIT(ret_typ, ret_init) \ + hbool_t past_catch = FALSE; \ + ret_typ ret_value = ret_init; + + +/* + * HERROR macro, used to facilitate error reporting . The arguments are the major + * error number, the minor error number, and a description of the error. + */ +#define HERROR(maj_id, min_id, str) H5Epush2(H5E_DEFAULT, __FILE__, FUNC, __LINE__, H5tools_ERR_CLS_g, maj_id, min_id, str) + +/* Macro for "catching" flow of control when an error occurs. Note that the + * H5_LEAVE macro won't jump back here once it's past this point. + */ +#define CATCH past_catch = TRUE; catch_except:; + +/* + * H5_LEAVE macro, used to facilitate control flow between a + * BEGIN_FUNC() and an END_FUNC() within a function body. The argument is + * the return value. + * The return value is assigned to a variable `ret_value' and control branches + * to the `catch_except' label, if we're not already past it. + */ +#define H5_LEAVE(v) { \ + ret_value = v; \ + if(!past_catch) \ + goto catch_except; \ +} + +/* + * H5E_THROW macro, used to facilitate error reporting within a function body. + * The arguments are the minor error number, and an error string. + * The return value is assigned to a variable `ret_value' and control branches + * to the `catch_except' label, if we're not already past it. + */ +#define H5E_THROW(fail_value, min_id, str) { \ + HERROR(H5E_tools_g, min_id, str); \ + H5_LEAVE(fail_value) \ +} + +/* + * HGOTO_ERROR macro, used to facilitate error reporting within a function body. The arguments are + * the major error number, the minor error number, the return value, and an + * error string. The return value is assigned to a variable `ret_value' and + * control branches to the `done' label. + */ +#define HGOTO_ERROR(fail_value, min_id, str) { \ + HERROR(H5E_tools_g, min_id, str); \ + HGOTO_DONE(fail_value) \ +} + +/* + * HGOTO_DONE macro, used to facilitate normal return within a function body. + * The argument is the return value which is assigned to the `ret_value' + * variable. Control branches to the `done' label. + */ +#define HGOTO_DONE(ret_val) {ret_value = ret_val; goto done;} + +#endif /* H5TOOLS_ERROR_H_ */ diff --git a/tools/lib/talign.c b/tools/lib/talign.c deleted file mode 100644 index 6c1bd81..0000000 --- a/tools/lib/talign.c +++ /dev/null @@ -1,191 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Small program to illustrate the "misalignment" of members within a compound - * datatype, in a datatype fixed by H5Tget_native_type(). - */ -#include -#include -/*#include *//* Required for unlink() */ - -#include "hdf5.h" -#include "H5private.h" -#include "h5tools.h" - -const char *fname = "talign.h5"; -const char *setname = "align"; - -/* - * This program assumes that there is no extra space between the members 'Ok' - * and 'Not Ok', (there shouldn't be because they are of the same atomic type - * H5T_NATIVE_FLOAT, and they are placed within the compound next to one - * another per construction) - */ - -int main(void) -{ - hid_t fil,spc,set; - hid_t cs6, cmp, fix; - hid_t cmp1, cmp2, cmp3; - hid_t plist; - hid_t array_dt; - - hsize_t dim[2]; - hsize_t cdim[4]; - - char string5[5]; - float fok[2] = {1234., 2341.}; - float fnok[2] = {5678., 6785.}; - float *fptr; - - char *data; - char *mname; - - int result = 0; - - printf("%-70s", "Testing alignment in compound datatypes"); - - strcpy(string5, "Hi!"); - HDunlink(fname); - fil = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - - if (fil < 0) { - puts("*FAILED*"); - return 1; - } - - H5E_BEGIN_TRY { - H5Ldelete(fil, setname, H5P_DEFAULT); - } H5E_END_TRY; - - cs6 = H5Tcopy(H5T_C_S1); - H5Tset_size(cs6, sizeof(string5)); - H5Tset_strpad(cs6, H5T_STR_NULLPAD); - - cmp = H5Tcreate(H5T_COMPOUND, sizeof(fok) + sizeof(string5) + sizeof(fnok)); - H5Tinsert(cmp, "Awkward length", 0, cs6); - - cdim[0] = sizeof(fok) / sizeof(float); - array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); - H5Tinsert(cmp, "Ok", sizeof(string5), array_dt); - H5Tclose(array_dt); - - cdim[0] = sizeof(fnok) / sizeof(float); - array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); - H5Tinsert(cmp, "Not Ok", sizeof(fok) + sizeof(string5), array_dt); - H5Tclose(array_dt); - - fix=h5tools_get_native_type(cmp); - - cmp1 = H5Tcreate(H5T_COMPOUND, sizeof(fok)); - - cdim[0] = sizeof(fok) / sizeof(float); - array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); - H5Tinsert(cmp1, "Ok", 0, array_dt); - H5Tclose(array_dt); - - cmp2 = H5Tcreate(H5T_COMPOUND, sizeof(string5)); - H5Tinsert(cmp2, "Awkward length", 0, cs6); - - cmp3 = H5Tcreate(H5T_COMPOUND, sizeof(fnok)); - - cdim[0] = sizeof(fnok) / sizeof(float); - array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); - H5Tinsert(cmp3, "Not Ok", 0, array_dt); - H5Tclose(array_dt); - - plist = H5Pcreate(H5P_DATASET_XFER); - H5Pset_preserve(plist, 1); - - /* - * Create a small dataset, and write data into it we write each field - * in turn so that we are avoid alignment issues at this point - */ - dim[0] = 1; - spc = H5Screate_simple(1, dim, NULL); - set = H5Dcreate2(fil, setname, cmp, spc, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - - H5Dwrite(set, cmp1, spc, H5S_ALL, plist, fok); - H5Dwrite(set, cmp2, spc, H5S_ALL, plist, string5); - H5Dwrite(set, cmp3, spc, H5S_ALL, plist, fnok); - - H5Dclose(set); - - /* Now open the set, and read it back in */ - data = malloc(H5Tget_size(fix)); - - if(!data) { - perror("malloc() failed"); - abort(); - } - - set = H5Dopen2(fil, setname, H5P_DEFAULT); - - H5Dread(set, fix, spc, H5S_ALL, H5P_DEFAULT, data); - fptr = (float *)(data + H5Tget_member_offset(fix, 1)); - - if(fok[0] != fptr[0] || fok[1] != fptr[1] - || fnok[0] != fptr[2] || fnok[1] != fptr[3]) { - result = 1; - printf("%14s (%2d) %6s = %s\n", - mname = H5Tget_member_name(fix, 0), (int)H5Tget_member_offset(fix,0), - string5, (char *)(data + H5Tget_member_offset(fix, 0))); - free(mname); - fptr = (float *)(data + H5Tget_member_offset(fix, 1)); - printf("Data comparison:\n" - "%14s (%2d) %6f = %f\n" - " %6f = %f\n", - mname = H5Tget_member_name(fix, 1), (int)H5Tget_member_offset(fix,1), - fok[0], fptr[0], - fok[1], fptr[1]); - free(mname); - fptr = (float *)(data + H5Tget_member_offset(fix, 2)); - printf("%14s (%2d) %6f = %f\n" - " %6f = %6f\n", - mname = H5Tget_member_name(fix, 2), (int)H5Tget_member_offset(fix,2), - fnok[0], fptr[0], - fnok[1], fptr[1]); - free(mname); - - fptr = (float *)(data + H5Tget_member_offset(fix, 1)); - printf("\n" - "Short circuit\n" - " %6f = %f\n" - " %6f = %f\n" - " %6f = %f\n" - " %6f = %f\n", - fok[0], fptr[0], - fok[1], fptr[1], - fnok[0], fptr[2], - fnok[1], fptr[3]); - puts("*FAILED*"); - } else { - puts(" PASSED"); - } - - free(data); - H5Sclose(spc); - H5Tclose(cmp); - H5Tclose(cmp1); - H5Tclose(cmp2); - H5Tclose(cmp3); - H5Pclose(plist); - H5Fclose(fil); - HDunlink(fname); - fflush(stdout); - return result; -} - diff --git a/tools/misc/Makefile.am b/tools/misc/Makefile.am index 7f78465..fe1acbd 100644 --- a/tools/misc/Makefile.am +++ b/tools/misc/Makefile.am @@ -24,7 +24,7 @@ include $(top_srcdir)/config/commence.am INCLUDES=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib #test script and program -TEST_PROG=h5repart_gentest +TEST_PROG=h5repart_gentest talign TEST_SCRIPT=testh5repart.sh $(srcdir)/testh5mkgrp.sh check_PROGRAMS=$(TEST_PROG) repart_test diff --git a/tools/misc/Makefile.in b/tools/misc/Makefile.in index dd8fce6..17502af 100644 --- a/tools/misc/Makefile.in +++ b/tools/misc/Makefile.in @@ -69,8 +69,15 @@ CONFIG_HEADER = $(top_builddir)/src/H5config.h CONFIG_CLEAN_FILES = h5cc testh5repart.sh CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" -am__EXEEXT_1 = h5repart_gentest$(EXEEXT) +am__EXEEXT_1 = h5repart_gentest$(EXEEXT) talign$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) +talign_SOURCES = talign.c +talign_OBJECTS = talign.$(OBJEXT) +talign_LDADD = $(LDADD) +talign_DEPENDENCIES = $(LIBH5TOOLS) $(LIBHDF5) +talign_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(talign_LDFLAGS) \ + $(LDFLAGS) -o $@ h5debug_SOURCES = h5debug.c h5debug_OBJECTS = h5debug.$(OBJEXT) h5debug_LDADD = $(LDADD) @@ -136,9 +143,9 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = h5debug.c h5mkgrp.c h5repart.c h5repart_gentest.c \ - repart_test.c + repart_test.c talign.c DIST_SOURCES = h5debug.c h5mkgrp.c h5repart.c h5repart_gentest.c \ - repart_test.c + repart_test.c talign.c ETAGS = etags CTAGS = ctags am__tty_colors = \ @@ -404,7 +411,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog *.h5 \ INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/tools/lib #test script and program -TEST_PROG = h5repart_gentest +TEST_PROG = h5repart_gentest talign.c TEST_SCRIPT = testh5repart.sh $(srcdir)/testh5mkgrp.sh check_SCRIPTS = $(TEST_SCRIPT) SCRIPT_DEPEND = h5repart$(EXEEXT) h5mkgrp$(EXEEXT) @@ -549,6 +556,9 @@ h5repart_gentest$(EXEEXT): $(h5repart_gentest_OBJECTS) $(h5repart_gentest_DEPEND repart_test$(EXEEXT): $(repart_test_OBJECTS) $(repart_test_DEPENDENCIES) @rm -f repart_test$(EXEEXT) $(LINK) $(repart_test_OBJECTS) $(repart_test_LDADD) $(LIBS) +talign$(EXEEXT): $(talign_OBJECTS) $(talign_DEPENDENCIES) + @rm -f talign$(EXEEXT) + $(LINK) $(talign_OBJECTS) $(talign_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @@ -595,6 +605,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5repart.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5repart_gentest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repart_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/talign.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/tools/misc/talign.c b/tools/misc/talign.c new file mode 100644 index 0000000..6c1bd81 --- /dev/null +++ b/tools/misc/talign.c @@ -0,0 +1,191 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Small program to illustrate the "misalignment" of members within a compound + * datatype, in a datatype fixed by H5Tget_native_type(). + */ +#include +#include +/*#include *//* Required for unlink() */ + +#include "hdf5.h" +#include "H5private.h" +#include "h5tools.h" + +const char *fname = "talign.h5"; +const char *setname = "align"; + +/* + * This program assumes that there is no extra space between the members 'Ok' + * and 'Not Ok', (there shouldn't be because they are of the same atomic type + * H5T_NATIVE_FLOAT, and they are placed within the compound next to one + * another per construction) + */ + +int main(void) +{ + hid_t fil,spc,set; + hid_t cs6, cmp, fix; + hid_t cmp1, cmp2, cmp3; + hid_t plist; + hid_t array_dt; + + hsize_t dim[2]; + hsize_t cdim[4]; + + char string5[5]; + float fok[2] = {1234., 2341.}; + float fnok[2] = {5678., 6785.}; + float *fptr; + + char *data; + char *mname; + + int result = 0; + + printf("%-70s", "Testing alignment in compound datatypes"); + + strcpy(string5, "Hi!"); + HDunlink(fname); + fil = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + if (fil < 0) { + puts("*FAILED*"); + return 1; + } + + H5E_BEGIN_TRY { + H5Ldelete(fil, setname, H5P_DEFAULT); + } H5E_END_TRY; + + cs6 = H5Tcopy(H5T_C_S1); + H5Tset_size(cs6, sizeof(string5)); + H5Tset_strpad(cs6, H5T_STR_NULLPAD); + + cmp = H5Tcreate(H5T_COMPOUND, sizeof(fok) + sizeof(string5) + sizeof(fnok)); + H5Tinsert(cmp, "Awkward length", 0, cs6); + + cdim[0] = sizeof(fok) / sizeof(float); + array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); + H5Tinsert(cmp, "Ok", sizeof(string5), array_dt); + H5Tclose(array_dt); + + cdim[0] = sizeof(fnok) / sizeof(float); + array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); + H5Tinsert(cmp, "Not Ok", sizeof(fok) + sizeof(string5), array_dt); + H5Tclose(array_dt); + + fix=h5tools_get_native_type(cmp); + + cmp1 = H5Tcreate(H5T_COMPOUND, sizeof(fok)); + + cdim[0] = sizeof(fok) / sizeof(float); + array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); + H5Tinsert(cmp1, "Ok", 0, array_dt); + H5Tclose(array_dt); + + cmp2 = H5Tcreate(H5T_COMPOUND, sizeof(string5)); + H5Tinsert(cmp2, "Awkward length", 0, cs6); + + cmp3 = H5Tcreate(H5T_COMPOUND, sizeof(fnok)); + + cdim[0] = sizeof(fnok) / sizeof(float); + array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); + H5Tinsert(cmp3, "Not Ok", 0, array_dt); + H5Tclose(array_dt); + + plist = H5Pcreate(H5P_DATASET_XFER); + H5Pset_preserve(plist, 1); + + /* + * Create a small dataset, and write data into it we write each field + * in turn so that we are avoid alignment issues at this point + */ + dim[0] = 1; + spc = H5Screate_simple(1, dim, NULL); + set = H5Dcreate2(fil, setname, cmp, spc, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + H5Dwrite(set, cmp1, spc, H5S_ALL, plist, fok); + H5Dwrite(set, cmp2, spc, H5S_ALL, plist, string5); + H5Dwrite(set, cmp3, spc, H5S_ALL, plist, fnok); + + H5Dclose(set); + + /* Now open the set, and read it back in */ + data = malloc(H5Tget_size(fix)); + + if(!data) { + perror("malloc() failed"); + abort(); + } + + set = H5Dopen2(fil, setname, H5P_DEFAULT); + + H5Dread(set, fix, spc, H5S_ALL, H5P_DEFAULT, data); + fptr = (float *)(data + H5Tget_member_offset(fix, 1)); + + if(fok[0] != fptr[0] || fok[1] != fptr[1] + || fnok[0] != fptr[2] || fnok[1] != fptr[3]) { + result = 1; + printf("%14s (%2d) %6s = %s\n", + mname = H5Tget_member_name(fix, 0), (int)H5Tget_member_offset(fix,0), + string5, (char *)(data + H5Tget_member_offset(fix, 0))); + free(mname); + fptr = (float *)(data + H5Tget_member_offset(fix, 1)); + printf("Data comparison:\n" + "%14s (%2d) %6f = %f\n" + " %6f = %f\n", + mname = H5Tget_member_name(fix, 1), (int)H5Tget_member_offset(fix,1), + fok[0], fptr[0], + fok[1], fptr[1]); + free(mname); + fptr = (float *)(data + H5Tget_member_offset(fix, 2)); + printf("%14s (%2d) %6f = %f\n" + " %6f = %6f\n", + mname = H5Tget_member_name(fix, 2), (int)H5Tget_member_offset(fix,2), + fnok[0], fptr[0], + fnok[1], fptr[1]); + free(mname); + + fptr = (float *)(data + H5Tget_member_offset(fix, 1)); + printf("\n" + "Short circuit\n" + " %6f = %f\n" + " %6f = %f\n" + " %6f = %f\n" + " %6f = %f\n", + fok[0], fptr[0], + fok[1], fptr[1], + fnok[0], fptr[2], + fnok[1], fptr[3]); + puts("*FAILED*"); + } else { + puts(" PASSED"); + } + + free(data); + H5Sclose(spc); + H5Tclose(cmp); + H5Tclose(cmp1); + H5Tclose(cmp2); + H5Tclose(cmp3); + H5Pclose(plist); + H5Fclose(fil); + HDunlink(fname); + fflush(stdout); + return result; +} + diff --git a/tools/testfiles/tdataregR.ddl b/tools/testfiles/tdataregR.ddl new file mode 100644 index 0000000..2d962ed --- /dev/null +++ b/tools/testfiles/tdataregR.ddl @@ -0,0 +1,60 @@ +############################# +Expected output for 'h5dump -R tdatareg.h5' +############################# +HDF5 "tdatareg.h5" { +GROUP "/" { + DATASET "Dataset1" { + DATATYPE H5T_REFERENCE { H5T_STD_REF_DSETREG } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } + DATA { + (0): DATASET /Dataset2 { + (0): REGION_TYPE BLOCK (2,2)-(7,7) + (0): DATATYPE H5T_STD_U8BE + (0): DATASPACE SIMPLE { ( 10, 10 ) / ( 10, 10 ) } + (0): DATA { + (2,2): 66, 69, 72, 75, 78, 81, + (3,2): 96, 99, 102, 105, 108, 111, + (4,2): 126, 129, 132, 135, 138, 141, + (5,2): 156, 159, 162, 165, 168, 171, + (6,2): 186, 189, 192, 195, 198, 201, + (7,2): 216, 219, 222, 225, 228, 231 + (0): } + (0): } + (1): DATASET /Dataset2 { + (1): REGION_TYPE POINT (6,9), (2,2), (8,4), (1,6), (2,8), (3,2), + (1): (0,4), (9,0), (7,1), (3,3) + (1): DATATYPE H5T_STD_U8BE + (1): DATASPACE SIMPLE { ( 10, 10 ) / ( 10, 10 ) } + (1): DATA { + (6,9): 207, + (2,2): 66, + (8,4): 252, + (1,6): 48, + (2,8): 84, + (3,2): 96, + (0,4): 12, + (9,0): 14, + (7,1): 213, + (3,3): 99 + (1): } + (1): } + } + } + DATASET "Dataset2" { + DATATYPE H5T_STD_U8BE + DATASPACE SIMPLE { ( 10, 10 ) / ( 10, 10 ) } + DATA { + (0,0): 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, + (1,0): 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, + (2,0): 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, + (3,0): 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, + (4,0): 120, 123, 126, 129, 132, 135, 138, 141, 144, 147, + (5,0): 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, + (6,0): 180, 183, 186, 189, 192, 195, 198, 201, 204, 207, + (7,0): 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, + (8,0): 240, 243, 246, 249, 252, 255, 2, 5, 8, 11, + (9,0): 14, 17, 20, 23, 26, 29, 32, 35, 38, 41 + } + } +} +} -- cgit v0.12