diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/h5dump/h5dump.c | 201 | ||||
-rw-r--r-- | tools/h5dump/h5dumpgentest.c | 122 | ||||
-rw-r--r-- | tools/h5dump/testh5dump.sh.in | 3 | ||||
-rw-r--r-- | tools/lib/Makefile.am | 2 | ||||
-rw-r--r-- | tools/lib/Makefile.in | 15 | ||||
-rw-r--r-- | tools/lib/h5tools.c | 3677 | ||||
-rw-r--r-- | tools/lib/h5tools.h | 162 | ||||
-rw-r--r-- | tools/lib/h5tools_error.h | 118 | ||||
-rw-r--r-- | tools/lib/h5tools_str.c | 690 | ||||
-rw-r--r-- | tools/lib/h5tools_str.h | 13 | ||||
-rw-r--r-- | tools/misc/Makefile.am | 2 | ||||
-rw-r--r-- | tools/misc/Makefile.in | 19 | ||||
-rw-r--r-- | tools/misc/talign.c (renamed from tools/lib/talign.c) | 33 | ||||
-rw-r--r-- | tools/testfiles/tattrreg.ddl | 38 | ||||
-rw-r--r-- | tools/testfiles/tattrreg.h5 | bin | 0 -> 8288 bytes | |||
-rw-r--r-- | tools/testfiles/tattrregR.ddl | 66 | ||||
-rw-r--r-- | tools/testfiles/tdataregR.ddl | 60 | ||||
-rw-r--r-- | tools/testfiles/tdset-3s.ddl | 21 | ||||
-rw-r--r-- | tools/testfiles/tnofilename.ddl | 19 |
19 files changed, 3964 insertions, 1297 deletions
diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c index beacdbb..43b2813 100644 --- a/tools/h5dump/h5dump.c +++ b/tools/h5dump/h5dump.c @@ -81,7 +81,6 @@ static const char *fp_format = NULL; const char *outfname=NULL; - /* things to display or which are set via command line parameters */ static int display_all = TRUE; static int display_oid = FALSE; @@ -94,6 +93,7 @@ static int display_dcpl = FALSE; /*dcpl */ static int display_fi = FALSE; /*file index */ static int display_ai = TRUE; /*array index */ static int display_escape = FALSE; /*escape non printable characters */ +static int display_region = FALSE; /*print region reference data */ /* sort parameters */ static H5_index_t sort_by = H5_INDEX_NAME; /*sort_by [creation_order | name] */ @@ -388,7 +388,7 @@ struct handler_t { * parameters. The long-named ones can be partially spelled. When * adding more, make sure that they don't clash with each other. */ -static const char *s_opts = "hnpeyBHirVa:c:d:f:g:k:l:t:w:xD:uX:o:b*F:s:S:Aq:z:m:"; +static const char *s_opts = "hnpeyBHirVa:c:d:f:g:k:l:t:w:xD:uX:o:b*F:s:S:Aq:z:m:R"; static struct long_options l_opts[] = { { "help", no_arg, 'h' }, { "hel", no_arg, 'h' }, @@ -500,6 +500,7 @@ static struct long_options l_opts[] = { { "sort_by", require_arg, 'q' }, { "sort_order", require_arg, 'z' }, { "format", require_arg, 'm' }, + { "region", no_arg, 'R' }, { NULL, 0, '\0' } }; @@ -655,6 +656,7 @@ usage(const char *prog) fprintf(stdout, " -m T, --format=T Set the floating point output format\n"); fprintf(stdout, " -q Q, --sort_by=Q Sort groups and attributes by index Q\n"); fprintf(stdout, " -z Z, --sort_order=Z Sort groups and attributes by order Z\n"); + fprintf(stdout, " -R, --region Print dataset pointed by region references\n"); fprintf(stdout, " -x, --xml Output in XML using Schema\n"); fprintf(stdout, " -u, --use-dtd Output in XML using DTD\n"); fprintf(stdout, " -D U, --xml-dtd=U Use the DTD or schema at U\n"); @@ -665,14 +667,16 @@ usage(const char *prog) fprintf(stdout, " Subsetting is available by using the following options with a dataset\n"); fprintf(stdout, " attribute. Subsetting is done by selecting a hyperslab from the data.\n"); fprintf(stdout, " Thus, the options mirror those for performing a hyperslab selection.\n"); - fprintf(stdout, " The START and COUNT parameters are mandatory if you do subsetting.\n"); - fprintf(stdout, " The STRIDE and BLOCK parameters are optional and will default to 1 in\n"); - fprintf(stdout, " each dimension.\n"); + fprintf(stdout, " One of the START, COUNT, STRIDE, or BLOCK parameters are mandatory if you do subsetting.\n"); + fprintf(stdout, " The STRIDE, COUNT, and BLOCK parameters are optional and will default to 1 in\n"); + fprintf(stdout, " each dimension. START is optional and will default to 0 in each dimension.\n"); fprintf(stdout, "\n"); - fprintf(stdout, " -s L, --start=L Offset of start of subsetting selection\n"); - fprintf(stdout, " -S L, --stride=L Hyperslab stride\n"); - fprintf(stdout, " -c L, --count=L Number of blocks to include in selection\n"); - fprintf(stdout, " -k L, --block=L Size of block in hyperslab\n"); + fprintf(stdout, " -s START, --start=START Offset of start of subsetting selection\n"); + fprintf(stdout, " -S STRIDE, --stride=STRIDE Hyperslab stride\n"); + fprintf(stdout, " -c COUNT, --count=COUNT Number of blocks to include in selection\n"); + fprintf(stdout, " -k BLOCK, --block=BLOCK Size of block in hyperslab\n"); + fprintf(stdout, " START, COUNT, STRIDE, and BLOCK - is a list of integers the number of which are equal to the\n"); + fprintf(stdout, " number of dimensions in the dataspace being queried\n"); fprintf(stdout, "\n"); fprintf(stdout, " D - is the file driver to use in opening the file. Acceptable values\n"); fprintf(stdout, " are \"sec2\", \"family\", \"split\", \"multi\", \"direct\", and \"stream\". Without\n"); @@ -683,8 +687,6 @@ usage(const char *prog) fprintf(stdout, " P - is the full path from the root group to the object.\n"); fprintf(stdout, " N - is an integer greater than 1.\n"); fprintf(stdout, " T - is a string containing the floating point format, e.g '%%.3f'\n"); - fprintf(stdout, " L - is a list of integers the number of which are equal to the\n"); - fprintf(stdout, " number of dimensions in the dataspace being queried\n"); fprintf(stdout, " U - is a URI reference (as defined in [IETF RFC 2396],\n"); fprintf(stdout, " updated by [IETF RFC 2732])\n"); fprintf(stdout, " B - is the form of binary output: NATIVE for a memory type, FILE for the\n"); @@ -1189,6 +1191,18 @@ print_datatype(hid_t type,unsigned in_group) case H5T_REFERENCE: printf("H5T_REFERENCE"); + /* The BNF document states that the type of reference should be + * displayed after "H5T_REFERENCE". Therefore add the missing + * reference type if the region command line option is used. This + * reference type will not be displayed if the region option is not used. */ + if(display_region) { + if (H5Tequal(type, H5T_STD_REF_DSETREG)==TRUE) { + printf(" { H5T_STD_REF_DSETREG }"); + } + else { + printf(" { H5T_STD_REF_OBJECT }"); + } + } break; case H5T_ENUM: @@ -2391,13 +2405,29 @@ dump_data(hid_t obj_id, int obj_data, struct subset_t *sset, int display_index) outputformat->pindex=display_index; /* do not print indices for regions */ - if(obj_data == DATASET_DATA) - { + if(obj_data == DATASET_DATA) { hid_t f_type = H5Dget_type(obj_id); - if (H5Tequal(f_type, H5T_STD_REF_DSETREG)) - { - outputformat->pindex = 0; + if (H5Tequal(f_type, H5T_STD_REF_DSETREG)) { + /* For the region option, correct the display of indices */ + if (display_region) { + if (display_index) { + outputformat->pindex = 1; + outputformat->idx_fmt = "(%s): "; + outputformat->idx_n_fmt = HSIZE_T_FORMAT; + outputformat->idx_sep = ","; + outputformat->line_pre = "%s"; + } + else { + outputformat->pindex = 0; + outputformat->idx_fmt = ""; + outputformat->idx_n_fmt = ""; + outputformat->idx_sep = ""; + outputformat->line_pre = ""; + } + } + else + outputformat->pindex = 0; } H5Tclose(f_type); } @@ -2470,13 +2500,15 @@ dump_data(hid_t obj_id, int obj_data, struct subset_t *sset, int display_index) status = h5tools_dump_dset(stdout, outputformat, obj_id, -1, sset, depth); H5Tclose(f_type); - } else { + } + else { /* need to call h5tools_dump_mem for the attribute data */ space = H5Aget_space(obj_id); space_type = H5Sget_simple_extent_type(space); if(space_type == H5S_NULL || space_type == H5S_NO_CLASS) { status = SUCCEED; - } else { + } + else { char string_prefix[64]; h5tool_format_t string_dataformat; @@ -3516,21 +3548,13 @@ handle_datasets(hid_t fid, const char *dset, void *data, int pe, const char *dis } if (!sset->count) { - hsize_t dims[H5S_MAX_RANK]; - herr_t status = H5Sget_simple_extent_dims(sid, dims, NULL); unsigned int i; - if (status == FAIL) { - error_msg(progname, "unable to get dataset dimensions\n"); - d_status = EXIT_FAILURE; - H5Sclose(sid); - return; - } sset->count = calloc(ndims, sizeof(hsize_t)); for (i = 0; i < ndims; i++) - sset->count[i] = dims[i] - sset->start[i]; + sset->count[i] = 1; } if (!sset->block) { @@ -3872,6 +3896,10 @@ parse_command_line(int argc, const char *argv[]) while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) { parse_start: switch ((char)opt) { + case 'R': + display_region = TRUE; + region_output = TRUE; + break; case 'B': display_bb = TRUE; last_was_dset = FALSE; @@ -3981,74 +4009,59 @@ parse_start: break; case 'o': + if ( bin_output ) { + if (set_output_file(opt_arg, 1) < 0) { + usage(progname); + leave(EXIT_FAILURE); + } + } + else { + if (set_output_file(opt_arg, 0) < 0) { + usage(progname); + leave(EXIT_FAILURE); + } + } + + usingdasho = TRUE; + last_was_dset = FALSE; + outfname = opt_arg; + break; + + case 'b': + if ( opt_arg != NULL) { + if ( ( bin_form = set_binary_form(opt_arg)) < 0) { + /* failed to set binary form */ + usage(progname); + leave(EXIT_FAILURE); + } + } + bin_output = TRUE; + if (outfname!=NULL) { + if (set_output_file(outfname, 1) < 0) { + /* failed to set output file */ + usage(progname); + leave(EXIT_FAILURE); + } + + last_was_dset = FALSE; + } + break; - if ( bin_output ) - { - if (set_output_file(opt_arg, 1) < 0){ - usage(progname); - leave(EXIT_FAILURE); - } - } - else - { - if (set_output_file(opt_arg, 0) < 0){ - usage(progname); - leave(EXIT_FAILURE); - } - } - - usingdasho = TRUE; - last_was_dset = FALSE; - outfname = opt_arg; - break; - - case 'b': - - if ( opt_arg != NULL) - { - if ( ( bin_form = set_binary_form(opt_arg)) < 0) - { - /* failed to set binary form */ - usage(progname); - leave(EXIT_FAILURE); - } - } - bin_output = TRUE; - if (outfname!=NULL) - { - if (set_output_file(outfname, 1) < 0) - { - /* failed to set output file */ - usage(progname); - leave(EXIT_FAILURE); - } - - last_was_dset = FALSE; - } - - break; - - case 'q': - - if ( ( sort_by = set_sort_by(opt_arg)) < 0) - { - /* failed to set "sort by" form */ - usage(progname); - leave(EXIT_FAILURE); - } - - break; - - case 'z': - - if ( ( sort_order = set_sort_order(opt_arg)) < 0) - { - /* failed to set "sort order" form */ - usage(progname); - leave(EXIT_FAILURE); - } - - break; + case 'q': + if ( ( sort_by = set_sort_by(opt_arg)) < 0) { + /* failed to set "sort by" form */ + usage(progname); + leave(EXIT_FAILURE); + } + break; + + case 'z': + if ( ( sort_order = set_sort_order(opt_arg)) < 0) { + /* failed to set "sort order" form */ + usage(progname); + leave(EXIT_FAILURE); + } + break; /** begin XML parameters **/ case 'x': diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c index c0d5801..b8ed41d 100644 --- a/tools/h5dump/h5dumpgentest.c +++ b/tools/h5dump/h5dumpgentest.c @@ -92,6 +92,7 @@ #define FILE62 "textlinktar.h5" #define FILE63 "textlinkfar.h5" #define FILE64 "tarray8.h5" +#define FILE65 "tattrreg.h5" @@ -1852,6 +1853,126 @@ static void gent_datareg(void) free(drbuf); } +static void gent_attrreg(void) +{ + /*some code is taken from enum.c in the test dir */ + + hid_t fid1; /* HDF5 File IDs */ + hid_t dset1; /* Dataset ID */ + hid_t dset2; /* Dereferenced dataset ID */ + hid_t sid1; /* Dataspace ID #1 */ + hid_t sid2; /* Dataspace ID #2 */ + hid_t sid3; /* Dataspace ID #3 */ + hid_t attr1; /* Attribute ID */ + hsize_t dims1[] = {SPACE1_DIM1}; + hsize_t dims2[] = {SPACE2_DIM1, SPACE2_DIM2}; + hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE2_RANK]; /* Stride of hyperslab */ + hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ + hdset_reg_ref_t *wbuf; /* buffer to write to disk */ + hdset_reg_ref_t *rbuf; /* buffer read from disk */ + uint8_t *dwbuf; /* Buffer for writing numeric data to disk */ + uint8_t *drbuf; /* Buffer for reading numeric data from disk */ + uint8_t *tu8; /* Temporary pointer to uint8 data */ + int i; /* counting variables */ + + /* Allocate write & read buffers */ + wbuf=calloc(sizeof(hdset_reg_ref_t), SPACE1_DIM1); + rbuf=malloc(sizeof(hdset_reg_ref_t)*SPACE1_DIM1); + dwbuf=malloc(sizeof(uint8_t)*SPACE2_DIM1*SPACE2_DIM2); + drbuf=calloc(sizeof(uint8_t),SPACE2_DIM1*SPACE2_DIM2); + + /* Create file */ + fid1 = H5Fcreate(FILE65, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create dataspace for datasets */ + sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); + + /* Create a dataset */ + dset2 = H5Dcreate2(fid1, "Dataset2", H5T_STD_U8BE, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + for(tu8 = dwbuf, i = 0; i < SPACE2_DIM1 * SPACE2_DIM2; i++) + *tu8++=i*3; + + /* Write selection to disk */ + H5Dwrite(dset2, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, dwbuf); + + /* Close Dataset */ + H5Dclose(dset2); + + /* + * Create dataset with a null dataspace to serve as the parent for + * the attribute. + */ + sid1 = H5Screate (H5S_NULL); + dset1 = H5Dcreate2 (fid1, "Dataset1", H5T_STD_I32LE, sid1, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + H5Sclose (sid1); + + /* Create references */ + + /* Select 6x6 hyperslab for first reference */ + start[0] = 2; start[1] = 2; + stride[0] = 1; stride[1] = 1; + count[0] = 6; count[1] = 6; + block[0] = 1; block[1] = 1; + H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); + + H5Sget_select_npoints(sid2); + + /* Store first dataset region */ + H5Rcreate(&wbuf[0], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + + /* Select sequence of ten points for second reference */ + coord1[0][0]=6; coord1[0][1]=9; + coord1[1][0]=2; coord1[1][1]=2; + coord1[2][0]=8; coord1[2][1]=4; + coord1[3][0]=1; coord1[3][1]=6; + coord1[4][0]=2; coord1[4][1]=8; + coord1[5][0]=3; coord1[5][1]=2; + coord1[6][0]=0; coord1[6][1]=4; + coord1[7][0]=9; coord1[7][1]=0; + coord1[8][0]=7; coord1[8][1]=1; + coord1[9][0]=3; coord1[9][1]=3; + H5Sselect_elements(sid2,H5S_SELECT_SET,POINT1_NPOINTS,(hsize_t *)coord1); + + H5Sget_select_npoints(sid2); + + /* Store second dataset region */ + H5Rcreate(&wbuf[1],fid1,"/Dataset2",H5R_DATASET_REGION,sid2); + + /* Create dataspace for the attribute */ + sid3 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + + /* Create the attribute and write the region references to it. */ + attr1 = H5Acreate2 (dset1, "Attribute1", H5T_STD_REF_DSETREG, sid3, H5P_DEFAULT, + H5P_DEFAULT); + H5Awrite (attr1, H5T_STD_REF_DSETREG, wbuf); + + /* Close attribute dataspace */ + H5Sclose(sid3); + + /* Close attribute */ + H5Aclose (attr1); + + /* Close Dataset */ + H5Dclose(dset1); + + /* Close uint8 dataset dataspace */ + H5Sclose(sid2); + + /* Close file */ + H5Fclose(fid1); + + /* Free memory buffers */ + free(wbuf); + free(rbuf); + free(dwbuf); + free(drbuf); +} + /*taken from Elena's compound test file*/ static void gent_nestcomp(void) { @@ -6351,6 +6472,7 @@ int main(void) gent_enum(); gent_objref(); gent_datareg(); + gent_attrreg(); gent_nestcomp(); gent_opaque(); gent_bitfields(); 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 c238063..8380deb 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -26,7 +26,6 @@ #include "h5tools.h" #include "h5tools_ref.h" -#include "h5tools_str.h" #include "h5tools_utils.h" #include "H5private.h" @@ -35,15 +34,213 @@ #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 */ int bin_form; /* binary form */ +int region_output; /* region output */ + +static h5tool_format_t h5tools_dataformat = { +0, /*raw */ + +"", /*fmt_raw */ +"%d", /*fmt_int */ +"%u", /*fmt_uint */ +"%d", /*fmt_schar */ +"%u", /*fmt_uchar */ +"%d", /*fmt_short */ +"%u", /*fmt_ushort */ +"%ld", /*fmt_long */ +"%lu", /*fmt_ulong */ +NULL, /*fmt_llong */ +NULL, /*fmt_ullong */ +"%g", /*fmt_double */ +"%g", /*fmt_float */ + +0, /*ascii */ +0, /*str_locale */ +0, /*str_repeat */ + +"[ ", /*arr_pre */ +",", /*arr_sep */ +" ]", /*arr_suf */ +1, /*arr_linebreak */ + +"", /*cmpd_name */ +",\n", /*cmpd_sep */ +"{\n", /*cmpd_pre */ +"}", /*cmpd_suf */ +"\n", /*cmpd_end */ + +", ", /*vlen_sep */ +"(", /*vlen_pre */ +")", /*vlen_suf */ +"", /*vlen_end */ + +"%s", /*elmt_fmt */ +",", /*elmt_suf1 */ +" ", /*elmt_suf2 */ + +"", /*idx_n_fmt */ +"", /*idx_sep */ +"", /*idx_fmt */ + +80, /*line_ncols *//*standard default columns */ +0, /*line_per_line */ +"", /*line_pre */ +"%s", /*line_1st */ +"%s", /*line_cont */ +"", /*line_suf */ +"", /*line_sep */ +1, /*line_multi_new */ +" ", /*line_indent */ + +1, /*skip_first */ + +1, /*obj_hidefileno */ +" "H5_PRINTF_HADDR_FMT, /*obj_format */ + +1, /*dset_hidefileno */ +"DATASET %s ", /*dset_format */ +"%s", /*dset_blockformat_pre */ +"%s", /*dset_ptformat_pre */ +"%s", /*dset_ptformat */ +1, /*array indices */ +1 /*escape non printable characters */ +}; + +static const h5tools_dump_header_t h5tools_standardformat = { +"standardformat", /*name */ +"HDF5", /*fileebgin */ +"", /*fileend */ +SUPER_BLOCK, /*bootblockbegin */ +"", /*bootblockend */ +H5_TOOLS_GROUP, /*groupbegin */ +"", /*groupend */ +H5_TOOLS_DATASET, /*datasetbegin */ +"", /*datasetend */ +ATTRIBUTE, /*attributebegin */ +"", /*attributeend */ +H5_TOOLS_DATATYPE, /*datatypebegin */ +"", /*datatypeend */ +DATASPACE, /*dataspacebegin */ +"", /*dataspaceend */ +DATA, /*databegin */ +"", /*dataend */ +SOFTLINK, /*softlinkbegin */ +"", /*softlinkend */ +EXTLINK, /*extlinkbegin */ +"", /*extlinkend */ +UDLINK, /*udlinkbegin */ +"", /*udlinkend */ +SUBSET, /*subsettingbegin */ +"", /*subsettingend */ +START, /*startbegin */ +"", /*startend */ +STRIDE, /*stridebegin */ +"", /*strideend */ +COUNT, /*countbegin */ +"", /*countend */ +BLOCK, /*blockbegin */ +"", /*blockend */ + +"{", /*fileblockbegin */ +"}", /*fileblockend */ +"{", /*bootblockblockbegin */ +"}", /*bootblockblockend */ +"{", /*groupblockbegin */ +"}", /*groupblockend */ +"{", /*datasetblockbegin */ +"}", /*datasetblockend */ +"{", /*attributeblockbegin */ +"}", /*attributeblockend */ +"", /*datatypeblockbegin */ +"", /*datatypeblockend */ +"", /*dataspaceblockbegin */ +"", /*dataspaceblockend */ +"{", /*datablockbegin */ +"}", /*datablockend */ +"{", /*softlinkblockbegin */ +"}", /*softlinkblockend */ +"{", /*extlinkblockbegin */ +"}", /*extlinkblockend */ +"{", /*udlinkblockbegin */ +"}", /*udlinkblockend */ +"{", /*strblockbegin */ +"}", /*strblockend */ +"{", /*enumblockbegin */ +"}", /*enumblockend */ +"{", /*structblockbegin */ +"}", /*structblockend */ +"{", /*vlenblockbegin */ +"}", /*vlenblockend */ +"{", /*subsettingblockbegin */ +"}", /*subsettingblockend */ +"(", /*startblockbegin */ +");", /*startblockend */ +"(", /*strideblockbegin */ +");", /*strideblockend */ +"(", /*countblockbegin */ +");", /*countblockend */ +"(", /*blockblockbegin */ +");", /*blockblockend */ + +"", /*dataspacedescriptionbegin */ +"", /*dataspacedescriptionend */ +"(", /*dataspacedimbegin */ +")", /*dataspacedimend */ +}; +static const h5tools_dump_header_t * h5tools_dump_header_format; /* local prototypes */ static 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); +static hbool_t h5tools_is_zero(const void *_mem, size_t size); + +hbool_t h5tools_render_element(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols, hsize_t local_elmt_counter/*element counter*/, + hsize_t elmt_counter); + +hbool_t h5tools_render_region_element(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols, hsize_t *ptdata, + 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*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + 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*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols, hsize_t region_elmt_counter/*element counter*/, + hsize_t elmt_counter); /* module-scoped variables */ static int h5tools_init_g; /* if h5tools lib has been initialized */ @@ -101,11 +298,20 @@ enum { void h5tools_init(void) { + char lib_str[256]; + if (!h5tools_init_g) { - if (!rawdatastream) - rawdatastream = stdout; + /* 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; + + h5tools_dump_header_format = &h5tools_standardformat; - h5tools_init_g++; + h5tools_init_g++; } } @@ -131,14 +337,16 @@ h5tools_close(void) if (h5tools_init_g) { if (rawdatastream && rawdatastream != stdout) { if (fclose(rawdatastream)) - perror("closing rawdatastream"); + perror("closing rawdatastream"); else - rawdatastream = NULL; + rawdatastream = NULL; } /* Clean up the reference path table, if it's been used */ term_ref_path_table(); + H5TOOLS_CLOSE_ERROR() + /* Shut down the library */ H5close(); @@ -164,88 +372,95 @@ h5tools_close(void) static hid_t h5tools_get_fapl(hid_t fapl, const char *driver, unsigned *drivernum) { - hid_t new_fapl; /* Copy of file access property list passed in, or new property list */ + hid_t new_fapl; /* Copy of file access property list passed in, or new property list */ /* Make a copy of the FAPL, for the file open call to use, eventually */ - if(fapl == H5P_DEFAULT) { - if((new_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + if (fapl == H5P_DEFAULT) { + if ((new_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) goto error; } /* end if */ else { - if((new_fapl = H5Pcopy(fapl)) < 0) + if ((new_fapl = H5Pcopy(fapl)) < 0) goto error; } /* end else */ /* Determine which driver the user wants to open the file with. Try * that driver. If it can't open it, then fail. */ - if(!strcmp(driver, drivernames[SEC2_IDX])) { + if (!strcmp(driver, drivernames[SEC2_IDX])) { /* SEC2 driver */ - if(H5Pset_fapl_sec2(new_fapl) < 0) + if (H5Pset_fapl_sec2(new_fapl) < 0) goto error; - if(drivernum) + if (drivernum) *drivernum = SEC2_IDX; - } else if(!strcmp(driver, drivernames[FAMILY_IDX])) { + } + else if (!strcmp(driver, drivernames[FAMILY_IDX])) { /* FAMILY Driver */ /* Set member size to be 0 to indicate the current first member size * is the member size. */ - if(H5Pset_fapl_family(new_fapl, (hsize_t)0, H5P_DEFAULT) < 0) + if (H5Pset_fapl_family(new_fapl, (hsize_t) 0, H5P_DEFAULT) < 0) goto error; - if(drivernum) + if (drivernum) *drivernum = FAMILY_IDX; - } else if(!strcmp(driver, drivernames[SPLIT_IDX])) { + } + else if (!strcmp(driver, drivernames[SPLIT_IDX])) { /* SPLIT Driver */ - if(H5Pset_fapl_split(new_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) + if (H5Pset_fapl_split(new_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) goto error; - if(drivernum) + if (drivernum) *drivernum = SPLIT_IDX; - } else if(!strcmp(driver, drivernames[MULTI_IDX])) { + } + else if (!strcmp(driver, drivernames[MULTI_IDX])) { /* MULTI Driver */ - if(H5Pset_fapl_multi(new_fapl, NULL, NULL, NULL, NULL, TRUE) < 0) - goto error; + if (H5Pset_fapl_multi(new_fapl, NULL, NULL, NULL, NULL, TRUE) < 0) + goto error; if(drivernum) - *drivernum = MULTI_IDX; + *drivernum = MULTI_IDX; #ifdef H5_HAVE_STREAM - } else if(!strcmp(driver, drivernames[STREAM_IDX])) { - /* STREAM Driver */ - if(H5Pset_fapl_stream(new_fapl, NULL) < 0) - goto error; + } + else if(!strcmp(driver, drivernames[STREAM_IDX])) { + /* STREAM Driver */ + if(H5Pset_fapl_stream(new_fapl, NULL) < 0) + goto error; - if(drivernum) - *drivernum = STREAM_IDX; + if(drivernum) + *drivernum = STREAM_IDX; #endif /* H5_HAVE_STREAM */ #ifdef H5_HAVE_PARALLEL - } else if(!strcmp(driver, drivernames[MPIO_IDX])) { - /* MPI-I/O Driver */ - /* check if MPI has been initialized. */ - if(!h5tools_mpi_init_g) - MPI_Initialized(&h5tools_mpi_init_g); - if(h5tools_mpi_init_g) { - if(H5Pset_fapl_mpio(new_fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0) - goto error; + } + else if(!strcmp(driver, drivernames[MPIO_IDX])) { + /* MPI-I/O Driver */ + /* check if MPI has been initialized. */ + if(!h5tools_mpi_init_g) + MPI_Initialized(&h5tools_mpi_init_g); + if(h5tools_mpi_init_g) { + if(H5Pset_fapl_mpio(new_fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0) + goto error; if(drivernum) *drivernum = MPIO_IDX; } /* end if */ - } else if (!strcmp(driver, drivernames[MPIPOSIX_IDX])) { + } + else if (!strcmp(driver, drivernames[MPIPOSIX_IDX])) { /* MPI-I/O Driver */ - /* check if MPI has been initialized. */ - if(!h5tools_mpi_init_g) - MPI_Initialized(&h5tools_mpi_init_g); + /* check if MPI has been initialized. */ + if(!h5tools_mpi_init_g) + MPI_Initialized(&h5tools_mpi_init_g); if(h5tools_mpi_init_g) { if(H5Pset_fapl_mpiposix(new_fapl, MPI_COMM_WORLD, TRUE) < 0) - goto error; + goto error; if(drivernum) *drivernum = MPIPOSIX_IDX; } /* end if */ #endif /* H5_HAVE_PARALLEL */ - } else { + } + else { goto error; } @@ -320,21 +535,22 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver, hid_t fid = FAIL; hid_t my_fapl = H5P_DEFAULT; - if(driver && *driver) { + if (driver && *driver) { /* Get the correct FAPL for the given driver */ - if((my_fapl = h5tools_get_fapl(fapl, driver, &drivernum)) < 0) + if ((my_fapl = h5tools_get_fapl(fapl, driver, &drivernum)) < 0) goto done; H5E_BEGIN_TRY { fid = H5Fopen(fname, flags, my_fapl); } H5E_END_TRY; - if(fid == FAIL) + if (fid == FAIL) goto done; - } else { + } + else { /* Try to open the file using each of the drivers */ - for(drivernum = 0; drivernum < NUM_DRIVERS; drivernum++) { + for (drivernum = 0; drivernum < NUM_DRIVERS; drivernum++) { /* Get the correct FAPL for the given driver */ if((my_fapl = h5tools_get_fapl(fapl, drivernames[drivernum], NULL)) < 0) goto done; @@ -343,7 +559,7 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver, fid = H5Fopen(fname, flags, my_fapl); } H5E_END_TRY; - if(fid != FAIL) + if (fid != FAIL) break; else { /* Close the FAPL */ @@ -354,11 +570,12 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver, } /* Save the driver name */ - if(drivername && drivername_size) { - if(fid != FAIL) { + if (drivername && drivername_size) { + if (fid != FAIL) { strncpy(drivername, drivernames[drivernum], drivername_size); drivername[drivername_size - 1] = '\0'; - } else { + } + else { /*no file opened*/ drivername[0] = '\0'; } @@ -367,6 +584,7 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver, done: if(my_fapl != H5P_DEFAULT) H5Pclose(my_fapl); + return fid; } @@ -429,16 +647,16 @@ h5tools_simple_prefix(FILE *stream, const h5tool_format_t *info, int i, indentlevel = 0; if (!ctx->need_prefix) - return; + return; memset(&prefix, 0, sizeof(h5tools_str_t)); memset(&str, 0, sizeof(h5tools_str_t)); /* Terminate previous line, if any */ if (ctx->cur_column) { - fputs(OPT(info->line_suf, ""), stream); - putc('\n', stream); - fputs(OPT(info->line_sep, ""), stream); + fputs(OPT(info->line_suf, ""), stream); + putc('\n', stream); + fputs(OPT(info->line_sep, ""), stream); } /* Calculate new prefix */ @@ -448,22 +666,23 @@ h5tools_simple_prefix(FILE *stream, const h5tool_format_t *info, /* Write new prefix to output */ if (ctx->indent_level >= 0) { indentlevel = ctx->indent_level; - } else { + } + else { /* * This is because sometimes we don't print out all the header * info for the data (like the tattr-2.ddl example). If that happens * the ctx->indent_level is negative so we need to skip the above and * just print out the default indent levels. */ - indentlevel = ctx->default_indent_level; + indentlevel = ctx->default_indent_level; } /* when printing array indices, print the indentation before the prefix the prefix is printed one indentation level before */ if (info->pindex) { - for (i = 0; i < indentlevel-1; i++){ - fputs(h5tools_str_fmt(&str, 0, info->line_indent), stream); - } + for (i = 0; i < indentlevel - 1; i++) { + fputs(h5tools_str_fmt(&str, 0, info->line_indent), stream); + } } if (elmtno == 0 && secnum == 0 && info->line_1st) @@ -475,16 +694,106 @@ h5tools_simple_prefix(FILE *stream, const h5tool_format_t *info, templength = h5tools_str_len(&prefix); - for (i = 0; i < indentlevel; i++){ + for (i = 0; i < indentlevel; i++) { /*we already made the indent for the array indices case */ - if (!info->pindex) { - fputs(h5tools_str_fmt(&prefix, 0, info->line_indent), stream); - templength += h5tools_str_len(&prefix); - } - else { - /*we cannot count the prefix for the array indices case */ - templength += h5tools_str_len(&str); - } + if (!info->pindex) { + fputs(h5tools_str_fmt(&prefix, 0, info->line_indent), stream); + templength += h5tools_str_len(&prefix); + } + else { + /*we cannot count the prefix for the array indices case */ + templength += h5tools_str_len(&str); + } + } + + ctx->cur_column = ctx->prev_prefix_len = templength; + ctx->cur_elmt = 0; + ctx->need_prefix = 0; + + /* Free string */ + h5tools_str_close(&prefix); + h5tools_str_close(&str); +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Emit a simple prefix to STREAM. + * Description: + * If /ctx->need_prefix/ is set then terminate the current line (if + * applicable), calculate the prefix string, and display it at the start + * of a line. Calls region specific function. + * Return: + * None + *------------------------------------------------------------------------- + */ +static void +h5tools_region_simple_prefix(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx, hsize_t elmtno, hsize_t *ptdata, int secnum) +{ + h5tools_str_t prefix; + h5tools_str_t str; /*temporary for indentation */ + size_t templength = 0; + int i, indentlevel = 0; + + if (!ctx->need_prefix) + return; + + memset(&prefix, 0, sizeof(h5tools_str_t)); + memset(&str, 0, sizeof(h5tools_str_t)); + + /* Terminate previous line, if any */ + if (ctx->cur_column) { + fputs(OPT(info->line_suf, ""), stream); + putc('\n', stream); + fputs(OPT(info->line_sep, ""), stream); + } + + /* Calculate new prefix */ + h5tools_str_region_prefix(&prefix, info, elmtno, ptdata, ctx->ndims, ctx->p_min_idx, + ctx->p_max_idx, ctx); + + /* Write new prefix to output */ + if (ctx->indent_level >= 0) { + indentlevel = ctx->indent_level; + } + else { + /* + * This is because sometimes we don't print out all the header + * info for the data (like the tattr-2.ddl example). If that happens + * the ctx->indent_level is negative so we need to skip the above and + * just print out the default indent levels. + */ + indentlevel = ctx->default_indent_level; + } + + /* when printing array indices, print the indentation before the prefix + the prefix is printed one indentation level before */ + if (info->pindex) { + for (i = 0; i < indentlevel - 1; i++) { + fputs(h5tools_str_fmt(&str, 0, info->line_indent), stream); + } + } + + if (elmtno == 0 && secnum == 0 && info->line_1st) + fputs(h5tools_str_fmt(&prefix, 0, info->line_1st), stream); + else if (secnum && info->line_cont) + fputs(h5tools_str_fmt(&prefix, 0, info->line_cont), stream); + else + fputs(h5tools_str_fmt(&prefix, 0, info->line_pre), stream); + + templength = h5tools_str_len(&prefix); + + for (i = 0; i < indentlevel; i++) { + /*we already made the indent for the array indices case */ + if (!info->pindex) { + fputs(h5tools_str_fmt(&prefix, 0, info->line_indent), stream); + templength += h5tools_str_len(&prefix); + } + else { + /*we cannot count the prefix for the array indices case */ + templength += h5tools_str_len(&str); + } } ctx->cur_column = ctx->prev_prefix_len = templength; @@ -532,41 +841,41 @@ h5tools_simple_prefix(FILE *stream, const h5tool_format_t *info, * new field sm_pos in h5tools_context_t, the current stripmine element position *------------------------------------------------------------------------- */ -void +void h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t container, h5tools_context_t *ctx/*in,out*/, unsigned flags, hsize_t nelmts, hid_t type, void *_mem) { - unsigned char *mem = (unsigned char*)_mem; - hsize_t i; /*element counter */ - char *s, *section; /*a section of output */ - int secnum; /*section sequence number */ - size_t size; /*size of each datum */ - size_t ncols = 80; /*available output width */ - h5tools_str_t buffer; /*string into which to render */ - int multiline; /*datum was multiline */ - hsize_t curr_pos; /* total data element position */ - int elmt_counter = 0;/*counts the # elements printed. - *I (ptl?) needed something that - *isn't going to get reset when a new - *line is formed. I'm going to use - *this var to count elements and - *break after we see a number equal - *to the ctx->size_last_dim. */ - - /* binary dump */ - if(bin_output) { + unsigned char *mem = (unsigned char*) _mem; + hsize_t i; /*element counter */ + size_t size; /*size of each datum */ + hid_t region_space; + hid_t region_id; + hbool_t dimension_break = TRUE; + H5S_sel_type region_type; + size_t ncols = 80; /*available output width */ + h5tools_str_t buffer; /*string into which to render */ + hsize_t curr_pos; /* total data element position */ + hsize_t elmt_counter = 0;/*counts the # elements printed. + *I (ptl?) needed something that + *isn't going to get reset when a new + *line is formed. I'm going to use + *this var to count elements and + *break after we see a number equal + *to the ctx->size_last_dim. */ + + /* binary dump */ + if (bin_output) { do_bin_output(stream, nelmts, type, _mem); } /* end if */ else { - /* Setup */ + /* setup */ HDmemset(&buffer, 0, sizeof(h5tools_str_t)); size = H5Tget_size(type); - if(info->line_ncols > 0) + if (info->line_ncols > 0) ncols = info->line_ncols; - /* pass to the prefix in h5tools_simple_prefix the total position * instead of the current stripmine position i; this is necessary * to print the array indices @@ -576,135 +885,1035 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); for (i = 0; i < nelmts; i++, ctx->cur_elmt++, elmt_counter++) { - /* Render the element */ - h5tools_str_reset(&buffer); - h5tools_str_sprint(&buffer, info, container, type, mem + i * size, ctx); + void* memref = mem + i * size; + if (region_output && H5Tequal(type, H5T_STD_REF_DSETREG)) { + char ref_name[1024]; + + /* region data */ + region_id = H5Rdereference(container, H5R_DATASET_REGION, memref); + if (region_id >= 0) { + region_space = H5Rget_region(container, H5R_DATASET_REGION, memref); + if (region_space >= 0) { + if (h5tools_is_zero(memref, H5Tget_size(type))) { + h5tools_str_append(&buffer, "NULL"); + } + else { + 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); + + h5tools_str_append(&buffer, info->dset_format, ref_name); + + dimension_break = h5tools_render_element(stream, info, + ctx, &buffer, &curr_pos, ncols, i, elmt_counter); + + region_type = H5Sget_select_type(region_space); + if(region_type==H5S_SEL_POINTS) + /* Print point information */ + dimension_break = h5tools_dump_region_data_points( + region_space, region_id, stream, info, ctx, + &buffer, &curr_pos, ncols, i, elmt_counter); + 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(... */ + if(H5Sclose(region_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + } /* end if (region_space >= 0) */ + 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"); - if (i + 1 < nelmts || (flags & END_OF_DATA) == 0) - h5tools_str_append(&buffer, "%s", OPT(info->elmt_suf1, ",")); + ctx->need_prefix = TRUE; + } /* end if (region_output... */ + else { + /* Render the data element begin*/ + h5tools_str_reset(&buffer); + h5tools_str_sprint(&buffer, info, container, type, memref, ctx); - s = h5tools_str_fmt(&buffer, 0, "%s"); + if (i + 1 < nelmts || (flags & END_OF_DATA) == 0) + h5tools_str_append(&buffer, "%s", OPT(info->elmt_suf1, ",")); + + dimension_break = h5tools_render_element(stream, info, ctx, &buffer, + &curr_pos, ncols, i, elmt_counter); + /* Render the data element end*/ - /* - * If the element would split on multiple lines if printed at our - * current location... - */ - if (info->line_multi_new == 1 && - (ctx->cur_column + h5tools_ncols(s) + - strlen(OPT(info->elmt_suf2, " ")) + - strlen(OPT(info->line_suf, ""))) > ncols) { - if (ctx->prev_multiline) { - /* - * ... and the previous element also occupied more than one - * line, then start this element at the beginning of a line. - */ - ctx->need_prefix = TRUE; - } else if ((ctx->prev_prefix_len + h5tools_ncols(s) + - strlen(OPT(info->elmt_suf2, " ")) + - strlen(OPT(info->line_suf, ""))) <= ncols) { - /* - * ...but *could* fit on one line otherwise, then we - * should end the current line and start this element on its - * own line. - */ - ctx->need_prefix = TRUE; - } } + if(FALSE==dimension_break) + elmt_counter = 0; + } /* end for (i = 0; i < nelmts... */ + + h5tools_str_close(&buffer); + }/* else bin */ +} +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Render an element to output STREAM. + * Description: + * Prints the string buffer to the output STREAM. The string is + * printed according to the format described in INFO. The CTX struct + * contains context information shared between calls to this function. + * + * Return: + * False if a dimension end is reached, otherwise true + * + * In/Out: + * h5tools_context_t *ctx + * h5tools_str_t *buffer + * hsize_t *curr_pos + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * hsize_t curr_pos is the total data element position + * size_t ncols + * hsize_t local_elmt_counter is the local element loop counter + * hsize_t elmt_count is the data element loop counter + *------------------------------------------------------------------------- + */ +hbool_t +h5tools_render_element(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx, h5tools_str_t *buffer, hsize_t *curr_pos, + size_t ncols, hsize_t local_elmt_counter, hsize_t elmt_counter) +{ + hbool_t dimension_break = TRUE; + char *s; + char *section; /*a section of output */ + int secnum; /*section sequence number */ + int multiline; /*datum was multiline */ + + s = h5tools_str_fmt(buffer, 0, "%s"); + + /* + * If the element would split on multiple lines if printed at our + * current location... + */ + if (info->line_multi_new == 1 && + (ctx->cur_column + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) { + if (ctx->prev_multiline) { + /* + * ... and the previous element also occupied more than one + * line, then start this element at the beginning of a line. + */ + ctx->need_prefix = TRUE; + } + else if ((ctx->prev_prefix_len + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) <= ncols) { /* - * We need to break after each row_counter of a dimension---> we should - * break at the end of the each last dimension well that is the - * way the dumper did it before + * ...but *could* fit on one line otherwise, then we + * should end the current line and start this element on its + * own line. */ - if (info->arr_linebreak && ctx->cur_elmt) { - if (ctx->size_last_dim && (ctx->cur_elmt % ctx->size_last_dim) == 0) - ctx->need_prefix = TRUE; + ctx->need_prefix = TRUE; + } + } - if ((hsize_t)elmt_counter == ctx->size_last_dim) { - ctx->need_prefix = TRUE; - elmt_counter = 0; - } - } + /* + * We need to break after each row of a dimension---> we should + * break at the end of the each last dimension well that is the + * way the dumper did it before + */ + if (info->arr_linebreak && ctx->cur_elmt) { + if (ctx->size_last_dim && (ctx->cur_elmt % ctx->size_last_dim) == 0) + ctx->need_prefix = TRUE; - /* - * If the previous element occupied multiple lines and this element - * is too long to fit on a line then start this element at the - * beginning of the line. + if (elmt_counter == ctx->size_last_dim) { + ctx->need_prefix = TRUE; + dimension_break = FALSE; + } + } + + /* + * If the previous element occupied multiple lines and this element + * is too long to fit on a line then start this element at the + * beginning of the line. + */ + if (info->line_multi_new == 1 && + ctx->prev_multiline && + (ctx->cur_column + + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) + ctx->need_prefix = TRUE; + + /* + * If too many elements have already been printed then we need to + * start a new line. + */ + if (info->line_per_line > 0 && ctx->cur_elmt >= info->line_per_line) + ctx->need_prefix = TRUE; + + /* + * Each OPTIONAL_LINE_BREAK embedded in the rendered string can cause + * the data to split across multiple lines. We display the sections + * one-at a time. + */ + multiline = 0; + for (secnum = 0, multiline = 0; + (section = strtok(secnum ? NULL : s, OPTIONAL_LINE_BREAK)); + secnum++) { + /* + * If the current section plus possible suffix and end-of-line + * information would cause the output to wrap then we need to + * start a new line. + */ + + /* + * Added the info->skip_first because the dumper does not want + * this check to happen for the first line + */ + if ((!info->skip_first || local_elmt_counter) && + (ctx->cur_column + + strlen(section) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) + ctx->need_prefix = 1; + + /* + * Print the prefix or separate the beginning of this element + * from the previous element. + */ + if (ctx->need_prefix) { + if (secnum) + multiline++; + + /* pass to the prefix in h5tools_simple_prefix the total + * position instead of the current stripmine position i; + * this is necessary to print the array indices */ - if (info->line_multi_new == 1 && ctx->prev_multiline && - (ctx->cur_column + h5tools_ncols(s) + - strlen(OPT(info->elmt_suf2, " ")) + - strlen(OPT(info->line_suf, ""))) > ncols) - ctx->need_prefix = TRUE; + *curr_pos = ctx->sm_pos + local_elmt_counter; + + h5tools_simple_prefix(stream, info, ctx, *curr_pos, secnum); + } + else if ((local_elmt_counter || ctx->continuation) && secnum == 0) { + fputs(OPT(info->elmt_suf2, " "), stream); + ctx->cur_column += strlen(OPT(info->elmt_suf2, " ")); + } + + /* Print the section */ + fputs(section, stream); + ctx->cur_column += strlen(section); + } + ctx->prev_multiline = multiline; + return dimension_break; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Render a region element to output STREAM. + * Description: + * Prints the string buffer to the output STREAM. The string is + * printed according to the format described in INFO. The CTX struct + * contains context information shared between calls to this function. + * + * Return: + * False if a dimension end is reached, otherwise true + * + * In/Out: + * h5tools_context_t *ctx + * h5tools_str_t *buffer + * hsize_t *curr_pos + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * hsize_t curr_pos is the total data element position + * size_t ncols + * hsize_t *ptdata + * hsize_t local_elmt_counter is the local element loop counter + * hsize_t elmt_count is the data element loop counter + *------------------------------------------------------------------------- + */ +hbool_t +h5tools_render_region_element(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx, h5tools_str_t *buffer, hsize_t *curr_pos, + size_t ncols, hsize_t *ptdata, hsize_t local_elmt_counter, hsize_t elmt_counter) +{ + hbool_t dimension_break = TRUE; + char *s; + char *section; /*a section of output */ + int secnum; /*section sequence number */ + int multiline; /*datum was multiline */ + + s = h5tools_str_fmt(buffer, 0, "%s"); + + /* + * If the element would split on multiple lines if printed at our + * current location... + */ + if (info->line_multi_new == 1 && + (ctx->cur_column + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) { + if (ctx->prev_multiline) { /* - * If too many elements have already been printed then we need to - * start a new line. + * ... and the previous element also occupied more than one + * line, then start this element at the beginning of a line. */ - if (info->line_per_line > 0 && ctx->cur_elmt >= info->line_per_line) - ctx->need_prefix = TRUE; - + ctx->need_prefix = TRUE; + } + else if ((ctx->prev_prefix_len + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) <= ncols) { /* - * Each OPTIONAL_LINE_BREAK embedded in the rendered string can cause - * the data to split across multiple lines. We display the sections - * one-at a time. + * ...but *could* fit on one line otherwise, then we + * should end the current line and start this element on its + * own line. */ - for (secnum = 0, multiline = 0; - (section = strtok(secnum ? NULL : s, OPTIONAL_LINE_BREAK)); - secnum++) { - /* - * If the current section plus possible suffix and end-of-line - * information would cause the output to wrap then we need to - * start a new line. - */ - - /* - * Added the info->skip_first because the dumper does not want - * this check to happen for the first line - */ - if ((!info->skip_first || i) && - (ctx->cur_column + strlen(section) + - strlen(OPT(info->elmt_suf2, " ")) + - strlen(OPT(info->line_suf, ""))) > ncols) - ctx->need_prefix = 1; - - /* - * Print the prefix or separate the beginning of this element - * from the previous element. - */ - if (ctx->need_prefix) { - if (secnum) - multiline++; - - /* pass to the prefix in h5tools_simple_prefix the total - * position instead of the current stripmine position i; - * this is necessary to print the array indices - */ - curr_pos = ctx->sm_pos + i; - - h5tools_simple_prefix(stream, info, ctx, curr_pos, secnum); - } else if ((i || ctx->continuation) && secnum == 0) { - fputs(OPT(info->elmt_suf2, " "), stream); - ctx->cur_column += strlen(OPT(info->elmt_suf2, " ")); - } + ctx->need_prefix = TRUE; + } + } - /* Print the section */ - fputs(section, stream); - ctx->cur_column += strlen(section); - } + /* + * We need to break after each row of a dimension---> we should + * break at the end of the each last dimension well that is the + * way the dumper did it before + */ + if (info->arr_linebreak && ctx->cur_elmt) { + if (ctx->size_last_dim && (ctx->cur_elmt % ctx->size_last_dim) == 0) + ctx->need_prefix = TRUE; - ctx->prev_multiline = multiline; + if (elmt_counter == ctx->size_last_dim) { + ctx->need_prefix = TRUE; + dimension_break = FALSE; } + } - h5tools_str_close(&buffer); - }/* else bin */ + /* + * If the previous element occupied multiple lines and this element + * is too long to fit on a line then start this element at the + * beginning of the line. + */ + if (info->line_multi_new == 1 && + ctx->prev_multiline && + (ctx->cur_column + + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) + ctx->need_prefix = TRUE; + + /* + * If too many elements have already been printed then we need to + * start a new line. + */ + if (info->line_per_line > 0 && ctx->cur_elmt >= info->line_per_line) + ctx->need_prefix = TRUE; + + /* + * Each OPTIONAL_LINE_BREAK embedded in the rendered string can cause + * the data to split across multiple lines. We display the sections + * one-at a time. + */ + multiline = 0; + for (secnum = 0, multiline = 0; (section = strtok(secnum ? NULL : s, + OPTIONAL_LINE_BREAK)); secnum++) { + /* + * If the current section plus possible suffix and end-of-line + * information would cause the output to wrap then we need to + * start a new line. + */ + + /* + * Added the info->skip_first because the dumper does not want + * this check to happen for the first line + */ + if ((!info->skip_first || local_elmt_counter) && + (ctx->cur_column + + strlen(section) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) + ctx->need_prefix = 1; + + /* + * Print the prefix or separate the beginning of this element + * from the previous element. + */ + if (ctx->need_prefix) { + if (secnum) + multiline++; + + /* pass to the prefix in h5tools_simple_prefix the total + * position instead of the current stripmine position i; + * this is necessary to print the array indices + */ + *curr_pos = ctx->sm_pos + local_elmt_counter; + + h5tools_region_simple_prefix(stream, info, ctx, local_elmt_counter, ptdata, secnum); + } + else if ((local_elmt_counter || ctx->continuation) && secnum == 0) { + fputs(OPT(info->elmt_suf2, " "), stream); + ctx->cur_column += strlen(OPT(info->elmt_suf2, " ")); + } + + /* Print the section */ + fputs(section, stream); + ctx->cur_column += strlen(section); + } + + ctx->prev_multiline = multiline; + return dimension_break; } +/*------------------------------------------------------------------------- + * 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, SUCCEED) + 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"); + +CATCH + return ret_value; +} /*------------------------------------------------------------------------- * Audience: Public * Chapter: H5Tools Library - * Purpose: Dump out a subset of a dataset. + * Purpose: Print some values from a dataset referenced by region blocks. + * + * Description: + * This is a special case subfunction to dump a region reference using blocks. + * + * Return: + * The function returns False if the last dimension has been reached, otherwise True + * + * In/Out: + * h5tools_context_t *ctx + * hsize_t *curr_pos + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * hsize_t curr_pos is the total data element position + * size_t ncols + * hsize_t region_elmt_counter is the region element loop counter + * hsize_t elmt_count is the data element loop counter + *------------------------------------------------------------------------- + */ +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*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols, hsize_t region_elmt_counter/*element counter*/, + hsize_t elmt_counter) { + 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 */ + 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); + + h5tools_str_append(buffer, "{"); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the region { element end */ + + /* Render the region datatype info and indices element begin */ + h5tools_str_reset(buffer); + + ctx->indent_level++; + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "REGION_TYPE BLOCK "); + + alloc_size = nblocks * ndims * 2 * sizeof(ptdata[0]); + assert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ + 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); + 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; + + h5tools_str_append(buffer, info->dset_blockformat_pre, + i ? "," OPTIONAL_LINE_BREAK " " : "", (unsigned long) i); + + /* Start coordinates and opposite corner */ + for (j = 0; j < ndims; j++) + h5tools_str_append(buffer, "%s%lu", j ? "," : "(", + (unsigned long) ptdata[i * 2 * ndims + j]); + + for (j = 0; j < ndims; j++) + h5tools_str_append(buffer, "%s%lu", j ? "," : ")-(", + (unsigned long) ptdata[i * 2 * ndims + j + ndims]); + + h5tools_str_append(buffer, ")"); + } /* end for (i = 0; i < nblocks; i++) */ + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the region datatype info and indices element end */ + + ctx->need_prefix = TRUE; + + 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); + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->datatypebegin, + h5tools_dump_header_format->datatypeblockbegin); + + h5tools_print_datatype(buffer, info, ctx, dtype); + + if (HDstrlen(h5tools_dump_header_format->datatypeblockend)) { + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->datatypeblockend); + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->datatypeend); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the datatype element end */ + + ctx->need_prefix = TRUE; + + /* Render the dataspace element begin */ + h5tools_str_reset(buffer); + + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "%s ", h5tools_dump_header_format->dataspacebegin); + + h5tools_print_dataspace(buffer, region_space); + + if (HDstrlen(h5tools_dump_header_format->dataspaceblockend)) { + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); + if (HDstrlen(h5tools_dump_header_format->dataspaceend)) + h5tools_str_append(buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->dataspaceend)) + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the dataspace element end */ + + ctx->need_prefix = TRUE; + + /* Render the databegin element begin */ + h5tools_str_reset(buffer); + + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->databegin, + h5tools_dump_header_format->datablockbegin); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the databegin element end */ + + ctx->need_prefix = TRUE; + + h5tools_print_region_data_blocks(region_space, region_id, + stream, info, *ctx, buffer, ncols, ndims, type_id, nblocks, ptdata); + + done: + free(ptdata); + + if(H5Tclose(dtype) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + + ctx->need_prefix = TRUE; + + /* Render the dataend element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->dataend, + h5tools_dump_header_format->datablockend); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, + ncols, region_elmt_counter, elmt_counter); + /* Render the dataend element end */ + + ctx->indent_level--; + ctx->need_prefix = TRUE; + + /* Render the region } element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "}"); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, + ncols, region_elmt_counter, elmt_counter); + /* Render the region } element end */ + + 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, SUCCEED) + 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"); +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Print some values from a dataset referenced by region points. + * + * Description: + * This is a special case subfunction to dump a region reference using points. + * + * Return: + * The function returns False if the last dimension has been reached, otherwise True + * + * In/Out: + * h5tools_context_t *ctx + * hsize_t *curr_pos + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * hsize_t curr_pos is the total data element position + * size_t ncols + * hsize_t region_elmt_counter is the region element loop counter + * hsize_t elmt_count is the data element loop counter + *------------------------------------------------------------------------- + */ +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, + 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; + int ndims; + int indx; + hid_t dtype; + hid_t type_id; + + 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); + + h5tools_str_append(buffer, "{"); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the region { element end */ + + /* Render the region datatype info and indices element begin */ + h5tools_str_reset(buffer); + + ctx->indent_level++; + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "REGION_TYPE POINT "); + + alloc_size = npoints * ndims * sizeof(ptdata[0]); + assert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ + 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); + 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; + + h5tools_str_append(buffer, info->dset_ptformat_pre, + indx ? "," OPTIONAL_LINE_BREAK " " : "", (unsigned long) indx); + + for (loop_indx = 0; loop_indx < ndims; loop_indx++) + h5tools_str_append(buffer, "%s%lu", loop_indx ? "," : "(", + (unsigned long) (ptdata[indx * ndims + loop_indx])); + + h5tools_str_append(buffer, ")"); + } /* end for (indx = 0; indx < npoints; indx++) */ + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the region datatype info and indices element end */ + + ctx->need_prefix = TRUE; + + 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); + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->datatypebegin, + h5tools_dump_header_format->datatypeblockbegin); + + h5tools_print_datatype(buffer, info, ctx, dtype); + + if (HDstrlen(h5tools_dump_header_format->datatypeblockend)) { + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->datatypeblockend); + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->datatypeend); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the datatype element end */ + + ctx->need_prefix = TRUE; + + /* Render the dataspace element begin */ + h5tools_str_reset(buffer); + + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "%s ", h5tools_dump_header_format->dataspacebegin); + + h5tools_print_dataspace(buffer, region_space); + + if (HDstrlen(h5tools_dump_header_format->dataspaceblockend)) { + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); + if (HDstrlen(h5tools_dump_header_format->dataspaceend)) + h5tools_str_append(buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->dataspaceend)) + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the dataspace element end */ + + ctx->need_prefix = TRUE; + + /* Render the databegin element begin */ + h5tools_str_reset(buffer); + + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->databegin, + h5tools_dump_header_format->datablockbegin); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the databegin element end */ + + ctx->need_prefix = TRUE; + + h5tools_print_region_data_points(region_space, region_id, + stream, info, *ctx, buffer, ncols, ndims, type_id, npoints, ptdata); + + done: + free(ptdata); + + if(H5Tclose(dtype) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + + ctx->need_prefix = TRUE; + + /* Render the dataend element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->dataend, + h5tools_dump_header_format->datablockend); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, + ncols, region_elmt_counter, elmt_counter); + /* Render the dataend element end*/ + + ctx->indent_level--; + ctx->need_prefix = TRUE; + + /* Render the region } element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "}"); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, + ncols, region_elmt_counter, elmt_counter); + /* Render the region } element end */ + + H5_LEAVE(dimension_break) +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 @@ -716,22 +1925,13 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai * 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 @@ -743,28 +1943,182 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai *------------------------------------------------------------------------- */ 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, SUCCEED) 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 */ + +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, SUCCEED) + 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 */ @@ -775,279 +2129,173 @@ 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 ]; + 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++) - { - 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; - + 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++) - { - max_start[ i ] = temp_start[ i ] + sset->count[ i ]; - temp_count[ i ] = 1; + + 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; } } - /* offset loop */ - for (n = 0; n < outer_count; n++) - { - - hsize_t row_counter = 0; - + for (n = 0; n < outer_count; n++) { /* 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 */ - count = sset->count[ row_dim ] * sset->block[ row_dim ]; + /* count is the number of iterations to display all the rows, + the block size count times */ + count = sset->count[row_dim] * sset->block[row_dim]; /* always 1 row_counter at a time, that is a block of size 1, 1 time */ - temp_count[ row_dim ] = 1; - temp_block[ row_dim ] = 1; + temp_count[row_dim] = 1; + temp_block[row_dim] = 1; /* advance 1 row_counter at a time */ - if (sset->block[ row_dim ] > 1 ) - temp_stride[ row_dim ] = 1; - + if (sset->block[row_dim] > 1) + temp_stride[row_dim] = 1; } /* for the 1D case */ - else - { + 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++) - { - temp_start[ i ] = sset->start[ i ]; + for (i = current_outer_dim + 1; i < ctx->ndims; i++) { + temp_start[i] = sset->start[i]; } - /* increment start dimension */ - do - { + do { reset_dim = 0; - temp_start[ current_outer_dim ]++; - if (temp_start[ current_outer_dim ] >= max_start[ current_outer_dim ]) - { - temp_start[ current_outer_dim ] = sset->start[ current_outer_dim ]; + temp_start[current_outer_dim]++; + if (temp_start[current_outer_dim] >= max_start[current_outer_dim]) { + temp_start[current_outer_dim] = sset->start[current_outer_dim]; /* consider block */ - if ( sset->block[ current_outer_dim ] > 1 ) - temp_start[ current_outer_dim ]++; + if (sset->block[current_outer_dim] > 1) + temp_start[current_outer_dim]++; current_outer_dim--; reset_dim = 1; } - } - while (current_outer_dim >= 0 && reset_dim); + } while (current_outer_dim >= 0 && reset_dim); } /* ctx.ndims > 1 */ } /* outer_count */ -#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, SUCCEED) + 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); @@ -1055,15 +2303,13 @@ h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset fputs(OPT(info->line_sep, ""), stream); } - 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; +} /*------------------------------------------------------------------------- * Audience: Public @@ -1078,18 +2324,15 @@ done: * Return: * On success, the function returns SUCCEED. Otherwise, the function * returns FAIL. - * Programmer: - * Robb Matzke, Thursday, July 23, 1998 - * Modifications: *------------------------------------------------------------------------- */ -static int -h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, - hid_t p_type, int indentlevel) +static int +h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, + hid_t dset, hid_t p_type, int indentlevel) { hid_t f_space; /* file data space */ hsize_t elmtno; /* counter */ - size_t i; /* counter */ + size_t i; /* counter */ int carry; /* counter carry value */ hsize_t zero[8]; /* vector of zeros */ unsigned int flags; /* buffer extent flags */ @@ -1104,16 +2347,16 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, 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 */ /* Hyperslab info */ - hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */ - hsize_t hs_size[H5S_MAX_RANK]; /* size this pass */ - hsize_t hs_nelmts; /* elements in request */ + hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */ + hsize_t hs_size[H5S_MAX_RANK]; /* size this pass */ + hsize_t hs_nelmts; /* elements in request */ /* VL data special information */ - unsigned int vl_data = 0; /* contains VL datatypes */ + unsigned int vl_data = 0; /* contains VL datatypes */ f_space = H5Dget_space(dset); @@ -1126,8 +2369,6 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, * 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)) { @@ -1135,6 +2376,9 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, return FAIL; } + ctx.indent_level = indentlevel; + ctx.need_prefix = 1; + /* Assume entire data space to be printed */ if (ctx.ndims > 0) for (i = 0; i < (size_t)ctx.ndims; i++) @@ -1186,8 +2430,8 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, sm_nelmts = sm_nbytes / p_type_nbytes; sm_space = H5Screate_simple(1, &sm_nelmts, NULL); - if(ctx.ndims>0) - init_acc_pos(&ctx,total_size); + if (ctx.ndims > 0) + init_acc_pos(&ctx, total_size); /* The stripmine loop */ memset(hs_offset, 0, sizeof hs_offset); @@ -1202,11 +2446,10 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hs_nelmts *= hs_size[i]; } - H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, - hs_size, NULL); - H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, - &hs_nelmts, NULL); - } else { + H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL); + H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL); + } + else { H5Sselect_all(f_space); H5Sselect_all(sm_space); hs_nelmts = 1; @@ -1225,14 +2468,13 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, flags |= ((elmtno + hs_nelmts) >= p_nelmts) ? END_OF_DATA : 0; /* initialize the current stripmine position; this is necessary to print the array - indices */ + indices */ ctx.sm_pos = elmtno; - h5tools_dump_simple_data(stream, info, dset, &ctx, flags, hs_nelmts, - p_type, sm_buf); + h5tools_dump_simple_data(stream, info, dset, &ctx, flags, hs_nelmts, p_type, sm_buf); /* Reclaim any VL memory, if necessary */ - if(vl_data) + if (vl_data) H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); /* Calculate the next hyperslab offset */ @@ -1271,13 +2513,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, * This is a special case of h5tools_dump_mem(). * * Return: Success: SUCCEED - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Thursday, July 23, 1998 - * - * Modifications: + * Failure: FAIL * *------------------------------------------------------------------------- */ @@ -1285,9 +2521,9 @@ static int h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, hid_t type, hid_t space, void *mem, int indentlevel) { - int i; /*counters */ - hsize_t nelmts; /*total selected elmts */ - h5tools_context_t ctx; /*printing context */ + int i; /*counters */ + hsize_t nelmts; /*total selected elmts */ + h5tools_context_t ctx; /*printing context */ /* * Check that everything looks okay. The dimensionality must not be too @@ -1297,7 +2533,7 @@ h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, memset(&ctx, 0, sizeof(ctx)); ctx.ndims = H5Sget_simple_extent_ndims(space); - if ((size_t)ctx.ndims > NELMTS(ctx.p_min_idx)) + if ((size_t) ctx.ndims > NELMTS(ctx.p_min_idx)) return FAIL; ctx.indent_level = indentlevel; @@ -1314,19 +2550,18 @@ h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, if (nelmts == 0) return SUCCEED; /*nothing to print*/ - if(ctx.ndims>0) { - assert(ctx.p_max_idx[ctx.ndims - 1]==(hsize_t)((int)ctx.p_max_idx[ctx.ndims - 1])); - ctx.size_last_dim = (int)(ctx.p_max_idx[ctx.ndims - 1]); + if (ctx.ndims > 0) { + assert(ctx.p_max_idx[ctx.ndims - 1] == (hsize_t) ((int) ctx.p_max_idx[ctx.ndims - 1])); + ctx.size_last_dim = (int) (ctx.p_max_idx[ctx.ndims - 1]); } /* end if */ else ctx.size_last_dim = 0; - if(ctx.ndims>0) - init_acc_pos(&ctx,ctx.p_max_idx); + if (ctx.ndims > 0) + init_acc_pos(&ctx, ctx.p_max_idx); /* Print it */ - h5tools_dump_simple_data(stream, info, obj_id, &ctx, - START_OF_DATA | END_OF_DATA, nelmts, type, mem); + h5tools_dump_simple_data(stream, info, obj_id, &ctx, START_OF_DATA | END_OF_DATA, nelmts, type, mem); /* Terminate the output */ if (ctx.cur_column) { @@ -1353,33 +2588,29 @@ h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, * h5tools_dump_mem(). * * Return: Success: SUCCEED - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Thursday, July 23, 1998 + * Failure: FAIL * * Modifications: * Robb Matzke, 1999-06-07 - * If info->raw is set then the memory datatype will be the same - * as the file datatype. + * If info->raw is set then the memory datatype will be the same + * as the file datatype. * * Bill Wendling, 2001-02-27 - * Renamed to ``h5tools_dump_dset'' and added the subsetting - * parameter. + * Renamed to ``h5tools_dump_dset'' and added the subsetting + * parameter. * *------------------------------------------------------------------------- */ -int -h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hid_t _p_type, - struct subset_t *sset, int indentlevel) +int +h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, + hid_t _p_type, struct subset_t *sset, int indentlevel) { hid_t f_space; hid_t p_type = _p_type; hid_t f_type; H5S_class_t space_type; int status = FAIL; - h5tool_format_t info_dflt; + h5tool_format_t info_dflt; /* Use default values */ if (!stream) @@ -1393,11 +2624,11 @@ h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hid_t _ if (p_type < 0) { f_type = H5Dget_type(dset); - if (info->raw || bin_form == 1 ) + if (info->raw || bin_form == 1) p_type = H5Tcopy(f_type); - else if (bin_form == 2 ) + else if (bin_form == 2) p_type = h5tools_get_little_endian_type(f_type); - else if (bin_form == 3 ) + else if (bin_form == 3) p_type = h5tools_get_big_endian_type(f_type); else p_type = h5tools_get_native_type(f_type); @@ -1415,13 +2646,15 @@ h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hid_t _ /* Print the data */ if (space_type == H5S_SIMPLE || space_type == H5S_SCALAR) { - if (!sset) - status = h5tools_dump_simple_dset(rawdatastream, info, dset, p_type, - indentlevel); - else - status = h5tools_dump_simple_subset(rawdatastream, info, dset, p_type, - sset, indentlevel); - } else /* space is H5S_NULL */ + if (!sset) { + status = h5tools_dump_simple_dset(rawdatastream, info, dset, p_type, indentlevel); + } + else { + status = h5tools_dump_simple_subset(rawdatastream, info, dset, p_type, sset, indentlevel); + } + } + else + /* space is H5S_NULL */ status = SUCCEED; /* Close the dataspace */ @@ -1442,13 +2675,7 @@ done: * spaces are allowed and only the `all' selection. * * Return: Success: SUCCEED - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Wednesday, January 20, 1999 - * - * Modifications: + * Failure: FAIL * *------------------------------------------------------------------------- */ @@ -1456,53 +2683,794 @@ 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, SUCCEED) h5tool_format_t info_dflt; /* Use default values */ if (!stream) - stream = stdout; + stream = stdout; if (!info) { - memset(&info_dflt, 0, sizeof(info_dflt)); - info = &info_dflt; + memset(&info_dflt, 0, sizeof(info_dflt)); + info = &info_dflt; } /* Check the data space */ if (H5Sis_simple(space) <= 0) - return -1; + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Sis_simple failed") + + H5_LEAVE(h5tools_dump_simple_mem(stream, info, obj_id, type, space, mem, indentlevel)) - return h5tools_dump_simple_mem(stream, info, obj_id, type, space, mem, - indentlevel); +CATCH + return ret_value; } /*------------------------------------------------------------------------- - * Function: init_acc_pos + * Function: print_datatype * - * Purpose: initialize accumulator and matrix position + * Purpose: print the datatype. * * Return: void * - * Programmer: pvn + * In/Out: h5tools_str_t *buffer + * h5tools_context_t *ctx * - * Modifications: + *------------------------------------------------------------------------- + */ +int +h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, + h5tools_context_t *ctx, hid_t type) +{ + HERR_INIT(int, SUCCEED) + 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"); + } + else if (H5Tequal(type, H5T_STD_I8LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I8LE"); + } + else if (H5Tequal(type, H5T_STD_I16BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I16BE"); + } + else if (H5Tequal(type, H5T_STD_I16LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I16LE"); + } + else if (H5Tequal(type, H5T_STD_I32BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I32BE"); + } + else if (H5Tequal(type, H5T_STD_I32LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I32LE"); + } + else if (H5Tequal(type, H5T_STD_I64BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I64BE"); + } + else if (H5Tequal(type, H5T_STD_I64LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I64LE"); + } + else if (H5Tequal(type, H5T_STD_U8BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U8BE"); + } + else if (H5Tequal(type, H5T_STD_U8LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U8LE"); + } + else if (H5Tequal(type, H5T_STD_U16BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U16BE"); + } + else if (H5Tequal(type, H5T_STD_U16LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U16LE"); + } + else if (H5Tequal(type, H5T_STD_U32BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U32BE"); + } + else if (H5Tequal(type, H5T_STD_U32LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U32LE"); + } + else if (H5Tequal(type, H5T_STD_U64BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U64BE"); + } + else if (H5Tequal(type, H5T_STD_U64LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U64LE"); + } + else if (H5Tequal(type, H5T_NATIVE_SCHAR) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_SCHAR"); + } + else if (H5Tequal(type, H5T_NATIVE_UCHAR) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_UCHAR"); + } + else if (H5Tequal(type, H5T_NATIVE_SHORT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_SHORT"); + } + else if (H5Tequal(type, H5T_NATIVE_USHORT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_USHORT"); + } + else if (H5Tequal(type, H5T_NATIVE_INT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_INT"); + } + else if (H5Tequal(type, H5T_NATIVE_UINT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_UINT"); + } + else if (H5Tequal(type, H5T_NATIVE_LONG) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_LONG"); + } + else if (H5Tequal(type, H5T_NATIVE_ULONG) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_ULONG"); + } + else if (H5Tequal(type, H5T_NATIVE_LLONG) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_LLONG"); + } + else if (H5Tequal(type, H5T_NATIVE_ULLONG) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_ULLONG"); + } + else { + + /* byte order */ + if (H5Tget_size(type) > 1) { + order = H5Tget_order(type); + if (H5T_ORDER_LE == order) { + order_s = " little-endian"; + } + else if (H5T_ORDER_BE == order) { + order_s = " big-endian"; + } + else if (H5T_ORDER_VAX == order) { + order_s = " mixed-endian"; + } + else { + order_s = " unknown-byte-order"; + } + } + else { + order_s = ""; + } + + /* sign */ + if ((sign = H5Tget_sign(type)) >= 0) { + if (H5T_SGN_NONE == sign) { + sign_s = " unsigned"; + } + else if (H5T_SGN_2 == sign) { + sign_s = ""; + } + else { + sign_s = " unknown-sign"; + } + } + else { + sign_s = " unknown-sign"; + } + + /* print size, order, and sign */ + h5tools_str_append(buffer, "%lu-bit%s%s integer", + (unsigned long) (8 * H5Tget_size(type)), order_s, sign_s); + } + break; + + case H5T_FLOAT: + if (H5Tequal(type, H5T_IEEE_F32BE) == TRUE) { + h5tools_str_append(buffer, "H5T_IEEE_F32BE"); + } + else if (H5Tequal(type, H5T_IEEE_F32LE) == TRUE) { + h5tools_str_append(buffer, "H5T_IEEE_F32LE"); + } + else if (H5Tequal(type, H5T_IEEE_F64BE) == TRUE) { + h5tools_str_append(buffer, "H5T_IEEE_F64BE"); + } + else if (H5Tequal(type, H5T_IEEE_F64LE) == TRUE) { + h5tools_str_append(buffer, "H5T_IEEE_F64LE"); + } + else if (H5Tequal(type, H5T_VAX_F32) == TRUE) { + h5tools_str_append(buffer, "H5T_VAX_F32"); + } + else if (H5Tequal(type, H5T_VAX_F64) == TRUE) { + h5tools_str_append(buffer, "H5T_VAX_F64"); + } + else if (H5Tequal(type, H5T_NATIVE_FLOAT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_FLOAT"); + } + else if (H5Tequal(type, H5T_NATIVE_DOUBLE) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_DOUBLE"); +#if H5_SIZEOF_LONG_DOUBLE !=0 + } + else if (H5Tequal(type, H5T_NATIVE_LDOUBLE) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_LDOUBLE"); +#endif + } + else { + + /* byte order */ + if (H5Tget_size(type) > 1) { + order = H5Tget_order(type); + if (H5T_ORDER_LE == order) { + order_s = " little-endian"; + } + else if (H5T_ORDER_BE == order) { + order_s = " big-endian"; + } + else if (H5T_ORDER_VAX == order) { + order_s = " mixed-endian"; + } + else { + order_s = " unknown-byte-order"; + } + } + else { + order_s = ""; + } + + /* print size and byte order */ + h5tools_str_append(buffer, "%lu-bit%s floating-point", + (unsigned long) (8 * H5Tget_size(type)), order_s); + + } + break; + + case H5T_TIME: + h5tools_str_append(buffer, "H5T_TIME: not yet implemented"); + break; + + case H5T_STRING: + /* Make a copy of type in memory in case when TYPE is on disk, the size + * will be bigger than in memory. This makes it easier to compare + * types in memory. */ + tmp_type = H5Tcopy(type); + size = H5Tget_size(tmp_type); + str_pad = H5Tget_strpad(tmp_type); + cset = H5Tget_cset(tmp_type); + is_vlstr = H5Tis_variable_str(tmp_type); + + h5tools_str_append(buffer, "H5T_STRING %s\n", h5tools_dump_header_format->strblockbegin); + ctx->indent_level++; + + if (is_vlstr) + h5tools_str_append(buffer, "%s H5T_VARIABLE;\n", STRSIZE); + else + h5tools_str_append(buffer, "%s %d;\n", STRSIZE, (int) size); + + h5tools_str_append(buffer, "%s ", STRPAD); + if (str_pad == H5T_STR_NULLTERM) + h5tools_str_append(buffer, "H5T_STR_NULLTERM;\n"); + else if (str_pad == H5T_STR_NULLPAD) + h5tools_str_append(buffer, "H5T_STR_NULLPAD;\n"); + else if (str_pad == H5T_STR_SPACEPAD) + h5tools_str_append(buffer, "H5T_STR_SPACEPAD;\n"); + else + h5tools_str_append(buffer, "H5T_STR_ERROR;\n"); + + h5tools_str_append(buffer, "%s ", CSET); + + if (cset == H5T_CSET_ASCII) + h5tools_str_append(buffer, "H5T_CSET_ASCII;\n"); + else + h5tools_str_append(buffer, "unknown_cset;\n"); + + str_type = H5Tcopy(H5T_C_S1); + if (is_vlstr) + H5Tset_size(str_type, H5T_VARIABLE); + else + H5Tset_size(str_type, size); + H5Tset_cset(str_type, cset); + H5Tset_strpad(str_type, str_pad); + + h5tools_str_append(buffer, "%s ", CTYPE); + + /* Check C variable-length string first. Are the two types equal? */ + if (H5Tequal(tmp_type, str_type)) { + h5tools_str_append(buffer, "H5T_C_S1;\n"); + goto done; + } + + /* Change the endianness and see if they're equal. */ + order = H5Tget_order(tmp_type); + if (order == H5T_ORDER_LE) + H5Tset_order(str_type, H5T_ORDER_LE); + else if (order == H5T_ORDER_BE) + H5Tset_order(str_type, H5T_ORDER_BE); + + if (H5Tequal(tmp_type, str_type)) { + h5tools_str_append(buffer, "H5T_C_S1;\n"); + goto done; + } + + /* If not equal to C variable-length string, check Fortran 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); + + /* Are the two types equal? */ + if (H5Tequal(tmp_type, str_type)) { + h5tools_str_append(buffer, "H5T_FORTRAN_S1;\n"); + goto done; + } + + /* Change the endianness and see if they're equal. */ + order = H5Tget_order(tmp_type); + if (order == H5T_ORDER_LE) + H5Tset_order(str_type, H5T_ORDER_LE); + else if (order == H5T_ORDER_BE) + H5Tset_order(str_type, H5T_ORDER_BE); + + if (H5Tequal(tmp_type, str_type)) { + h5tools_str_append(buffer, "H5T_FORTRAN_S1;\n"); + goto done; + } + + /* Type doesn't match any of above. */ + h5tools_str_append(buffer, "unknown_one_character_type;\n "); + + 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); + break; + + case H5T_BITFIELD: + if (H5Tequal(type, H5T_STD_B8BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B8BE"); + } + else if (H5Tequal(type, H5T_STD_B8LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B8LE"); + } + else if (H5Tequal(type, H5T_STD_B16BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B16BE"); + } + else if (H5Tequal(type, H5T_STD_B16LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B16LE"); + } + else if (H5Tequal(type, H5T_STD_B32BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B32BE"); + } + else if (H5Tequal(type, H5T_STD_B32LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B32LE"); + } + else if (H5Tequal(type, H5T_STD_B64BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B64BE"); + } + else if (H5Tequal(type, H5T_STD_B64LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B64LE"); + } + else { + h5tools_str_append(buffer, "undefined bitfield"); + } + break; + + case H5T_OPAQUE: + h5tools_str_append(buffer, "\n"); + h5tools_str_append(buffer, "H5T_OPAQUE;\n"); + h5tools_str_append(buffer, "OPAQUE_TAG \"%s\";\n", H5Tget_tag(type)); + break; + + case H5T_COMPOUND: + 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); + 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); + } + + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->structblockend); + break; + + case H5T_REFERENCE: + h5tools_str_append(buffer, "H5T_REFERENCE"); + if(region_output) { + if (H5Tequal(type, H5T_STD_REF_DSETREG) == TRUE) { + h5tools_str_append(buffer, " { H5T_STD_REF_DSETREG }"); + } + else { + h5tools_str_append(buffer, " { H5T_STD_REF_OBJECT }"); + } + } + 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++; + + 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, 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); + + 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, "%s", h5tools_dump_header_format->vlenblockend); + + break; + + case H5T_ARRAY: + h5tools_str_append(buffer, "H5T_ARRAY { "); + + /* Get array information */ + 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"); + + /* 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"); + + h5tools_str_append(buffer, " }"); + + break; + + default: + h5tools_str_append(buffer, "unknown datatype"); + break; + } + +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: print_dataspace + * + * Purpose: print the dataspace. + * + * Return: void + * + * In/Out: h5tools_str_t *buffer + * h5tools_context_t *ctx + * + *------------------------------------------------------------------------- + */ +int +h5tools_print_dataspace(h5tools_str_t *buffer, hid_t space) +{ + HERR_INIT(int, SUCCEED) + hsize_t size[H5TOOLS_DUMP_MAX_RANK]; + hsize_t maxsize[H5TOOLS_DUMP_MAX_RANK]; + 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: + /* scalar dataspace */ + h5tools_str_append(buffer, "%s %s", h5tools_dump_header_format->dataspacedescriptionbegin, S_SCALAR); + break; + + case H5S_SIMPLE: + /* simple dataspace */ + h5tools_str_append(buffer, "%s %s { %s %" H5_PRINTF_LL_WIDTH "u", + h5tools_dump_header_format->dataspacedescriptionbegin, S_SIMPLE, + h5tools_dump_header_format->dataspacedimbegin, size[0]); + + for(i = 1; i < ndims; i++) + h5tools_str_append(buffer, ", %" H5_PRINTF_LL_WIDTH "u", size[i]); + + h5tools_str_append(buffer, " %s / ", h5tools_dump_header_format->dataspacedimend); + + if(maxsize[0] == H5S_UNLIMITED) + h5tools_str_append(buffer, "%s %s", + h5tools_dump_header_format->dataspacedimbegin, "H5S_UNLIMITED"); + else + h5tools_str_append(buffer, "%s %" H5_PRINTF_LL_WIDTH "u", + h5tools_dump_header_format->dataspacedimbegin, maxsize[0]); + + for(i = 1; i < ndims; i++) + if(maxsize[i] == H5S_UNLIMITED) + h5tools_str_append(buffer, ", %s", "H5S_UNLIMITED"); + else + h5tools_str_append(buffer, ", %" H5_PRINTF_LL_WIDTH "u", maxsize[i]); + + h5tools_str_append(buffer, " %s }", h5tools_dump_header_format->dataspacedimend); + break; + + case H5S_NULL: + /* null dataspace */ + h5tools_str_append(buffer, "%s %s", h5tools_dump_header_format->dataspacedescriptionbegin, S_NULL); + break; + + case H5S_NO_CLASS: + default: + h5tools_str_append(buffer, "%s unknown dataspace %s\n", BEGIN, END); + break; + } /* end switch */ + +CATCH + return ret_value; +} + + +/*------------------------------------------------------------------------- + * Function: print_enum + * + * Purpose: prints the enum data + * + * Return: void + * + * In/Out: h5tools_str_t *buffer + * h5tools_context_t *ctx + * + *-----------------------------------------------------------------------*/ +int +h5tools_print_enum(h5tools_str_t *buffer, hid_t type) +{ + HERR_INIT(int, SUCCEED) + 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 = -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; + + if((nmembs = H5Tget_nmembers(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed"); + assert(nmembs > 0); + + 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 + */ + if (type_size <= sizeof(long long)) { + dst_size = sizeof(long long); + + 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 { + native = H5T_NATIVE_LLONG; + } + } + else { + dst_size = type_size; + } + + /* Get the names and raw values of all members */ + 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); + 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) + 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 + * ***not implemented yet*** + */ + + /* Print members */ + for (i = 0; i < nmembs; i++) { + h5tools_str_append(buffer, "\"%s\"", name[i]); + nchars = strlen(name[i]); + h5tools_str_append(buffer, "%*s ", MAX(0, 16 - nchars), ""); + + if (native < 0) { + size_t j; + + h5tools_str_append(buffer, "0x"); + + for (j = 0; j < dst_size; j++) + h5tools_str_append(buffer, "%02x", value[i * dst_size + j]); + } + else if (H5T_SGN_NONE == H5Tget_sign(native)) { + /*On SGI Altix(cobalt), wrong values were printed out with "value+i*dst_size" + *strangely, unless use another pointer "copy".*/ + copy = value + i * dst_size; + h5tools_str_append(buffer, "%" H5_PRINTF_LL_WIDTH "u", *((unsigned long long *) ((void *) copy))); + } + else { + /*On SGI Altix(cobalt), wrong values were printed out with "value+i*dst_size" + *strangely, unless use another pointer "copy".*/ + copy = value + i * dst_size; + h5tools_str_append(buffer, "%" H5_PRINTF_LL_WIDTH "d", *((long long *) ((void *) copy))); + } + + h5tools_str_append(buffer, ";\n"); + } + +CATCH + + /* Release resources */ + for (i = 0; i < nmembs; i++) + free(name[i]); + + free(name); + free(value); + + if(H5Tclose(super) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tclose failed"); + + if (0 == nmembs) + h5tools_str_append(buffer, "\n<empty>"); + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: dump_datatype + * + * Purpose: Dump the datatype. Datatype can be HDF5 predefined + * atomic datatype or committed/transient datatype. * + * Return: void + * + * In/Out: h5tools_context_t *ctx *------------------------------------------------------------------------- */ -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, hid_t type) { - int i; + size_t ncols = 80; /* available output width */ + h5tools_str_t buffer; /* string into which to render */ + hsize_t curr_pos; /* total data element position */ + hsize_t elmt_counter = 0;/* counts the # elements printed.*/ + + /* setup */ + HDmemset(&buffer, 0, sizeof(h5tools_str_t)); + + if (info->line_ncols > 0) + ncols = info->line_ncols; + + /* pass to the prefix in h5tools_simple_prefix the total position + * instead of the current stripmine position i; this is necessary + * to print the array indices + */ + curr_pos = ctx->sm_pos; - assert(ctx->ndims); + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + /* Render the element */ + h5tools_str_reset(&buffer); - ctx->acc[ctx->ndims-1]=1; - for(i=(ctx->ndims-2); i>=0; i--) - { - ctx->acc[i]=ctx->acc[i+1] * dims[i+1]; - } - for ( i = 0; i < ctx->ndims; i++) - ctx->pos[i]=0; + ctx->indent_level++; + h5tools_str_append(&buffer, "%s %s ", + h5tools_dump_header_format->datatypebegin, + h5tools_dump_header_format->datatypeblockbegin); + + h5tools_print_datatype(&buffer, info, ctx, type); + + if (HDstrlen(h5tools_dump_header_format->datatypeblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datatypeblockend); + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(&buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datatypeend); + h5tools_str_append(&buffer, "\n"); + + curr_pos = h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, + ncols, elmt_counter, 0); + + ctx->need_prefix = TRUE; + ctx->indent_level--; } +/*------------------------------------------------------------------------- + * Function: init_acc_pos + * + * Purpose: initialize accumulator and matrix position + * + * Return: void + *------------------------------------------------------------------------- + */ +void +init_acc_pos(h5tools_context_t *ctx, hsize_t *dims) +{ + int i; + + assert(ctx->ndims); + + ctx->acc[ctx->ndims - 1] = 1; + for (i = (ctx->ndims - 2); i >= 0; i--) { + ctx->acc[i] = ctx->acc[i + 1] * dims[i + 1]; + } + for (i = 0; i < ctx->ndims; i++) + ctx->pos[i] = 0; +} /*------------------------------------------------------------------------- * Function: do_bin_output @@ -1511,35 +3479,29 @@ void init_acc_pos(h5tools_context_t *ctx, hsize_t *dims) * * Return: Success: SUCCEED * Failure: FAIL - * - * Programmer: Pedro Vicente Nunes - * Friday, June 2, 2006 - * - * Modifications: - * *------------------------------------------------------------------------- */ static int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) { - unsigned char *mem = (unsigned char*)_mem; - size_t size; /* datum size */ - hsize_t i; /* element counter */ - - size = H5Tget_size(tid); - - for (i = 0; i < nelmts; i++) - { - if (render_bin_output(stream,tid,mem + i * size)<0) - { - printf("\nError in writing binary stream\n"); - return FAIL; - } - } - - return SUCCEED; -} + HERR_INIT(int, SUCCEED) + unsigned char *mem = (unsigned char*)_mem; + size_t size; /* datum size */ + hsize_t i; /* element counter */ + 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) { + printf("\nError in writing binary stream\n"); + return FAIL; + } + } + +CATCH + return ret_value; +} /*------------------------------------------------------------------------- * Function: render_bin_output @@ -1548,395 +3510,372 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) * * Return: Success: SUCCEED * Failure: FAIL - * - * Programmer: Pedro Vicente Nunes - * Friday, June 2, 2006 - * - * Modifications: - * *------------------------------------------------------------------------- */ -static -int render_bin_output(FILE *stream, hid_t tid, void *_mem) +static int +render_bin_output(FILE *stream, hid_t tid, void *_mem) { - unsigned char *mem = (unsigned char*)_mem; - size_t size; /* datum size */ - float tempfloat; - double tempdouble; - unsigned long long tempullong; - long long templlong; - unsigned long tempulong; - long templong; - unsigned int tempuint; - int tempint; - unsigned short tempushort; - short tempshort; - unsigned char tempuchar; - char tempschar; + HERR_INIT(int, SUCCEED) + unsigned char *mem = (unsigned char*)_mem; + size_t size; /* datum size */ + float tempfloat; + double tempdouble; + unsigned long long tempullong; + long long templlong; + unsigned long tempulong; + long templong; + unsigned int tempuint; + int tempint; + unsigned short tempushort; + short tempshort; + unsigned char tempuchar; + char tempschar; #if H5_SIZEOF_LONG_DOUBLE !=0 - long double templdouble; + long double templdouble; #endif #ifdef DEBUG_H5DUMP_BIN - static char fmt_llong[8], fmt_ullong[8]; - if (!fmt_llong[0]) { - sprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH); - sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); - } + static char fmt_llong[8], fmt_ullong[8]; + if (!fmt_llong[0]) { + sprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH); + sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); + } #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)); + if (H5Tequal(tid, H5T_NATIVE_FLOAT)) { + memcpy(&tempfloat, mem, sizeof(float)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%g ", tempfloat); + fprintf(stream, "%g ", tempfloat); #else - if (1 != fwrite(&tempfloat, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempfloat, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_DOUBLE)) - { - memcpy(&tempdouble, mem, sizeof(double)); + } + else if (H5Tequal(tid, H5T_NATIVE_DOUBLE)) { + memcpy(&tempdouble, mem, sizeof(double)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%g ", tempdouble); + fprintf(stream, "%g ", tempdouble); #else - if (1 != fwrite(&tempdouble, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempdouble, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } + } #if H5_SIZEOF_LONG_DOUBLE !=0 - else if (H5Tequal(tid, H5T_NATIVE_LDOUBLE)) - { - memcpy(&templdouble, mem, sizeof(long double)); + else if (H5Tequal(tid, H5T_NATIVE_LDOUBLE)) { + memcpy(&templdouble, mem, sizeof(long double)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%Lf ", templdouble); + fprintf(stream, "%Lf ", templdouble); #else - if (1 != fwrite(&templdouble, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templdouble, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } + } #endif - else if (H5T_STRING == H5Tget_class(tid)) - { - unsigned int i; - H5T_str_t pad; - char *s; - - pad = H5Tget_strpad(tid); - - if(H5Tis_variable_str(tid)) - { - s = *(char**)mem; - if(s!=NULL) - size = HDstrlen(s); - } - else - { - s = (char *)mem; - size = H5Tget_size(tid); - } - for (i=0; i<size && (s[i] || pad!=H5T_STR_NULLTERM); i++) - { - memcpy(&tempuchar, &s[i], sizeof(unsigned char)); + else if (H5T_STRING == H5Tget_class(tid)) { + unsigned int i; + H5T_str_t pad; + char *s; + + pad = H5Tget_strpad(tid); + + if (H5Tis_variable_str(tid)) { + s = *(char**) mem; + if (s != NULL) + size = HDstrlen(s); + } + else { + s = (char *) mem; + 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)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d", tempuchar); + fprintf(stream, "%d", tempuchar); #else - if (1 != fwrite(&tempuchar, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempuchar, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } /* i */ - } - else if (H5Tequal(tid, H5T_NATIVE_INT)) - { - memcpy(&tempint, mem, sizeof(int)); + } /* i */ + } + else if (H5Tequal(tid, H5T_NATIVE_INT)) { + memcpy(&tempint, mem, sizeof(int)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d ", tempint); + fprintf(stream, "%d ", tempint); #else - if (1 != fwrite(&tempint, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempint, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_UINT)) - { - memcpy(&tempuint, mem, sizeof(unsigned int)); + } + else if (H5Tequal(tid, H5T_NATIVE_UINT)) { + memcpy(&tempuint, mem, sizeof(unsigned int)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%u ", tempuint); + fprintf(stream, "%u ", tempuint); #else - if (1 != fwrite(&tempuint, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempuint, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_SCHAR)) - { - memcpy(&tempschar, mem, sizeof(char)); + } + else if (H5Tequal(tid, H5T_NATIVE_SCHAR)) { + memcpy(&tempschar, mem, sizeof(char)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d ", tempschar); + fprintf(stream, "%d ", tempschar); #else - if (1 != fwrite(&tempschar, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempschar, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_UCHAR)) - { - memcpy(&tempuchar, mem, sizeof(unsigned char)); + } + else if (H5Tequal(tid, H5T_NATIVE_UCHAR)) { + memcpy(&tempuchar, mem, sizeof(unsigned char)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%u ", tempuchar); + fprintf(stream, "%u ", tempuchar); #else - if (1 != fwrite(&tempuchar, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempuchar, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_SHORT)) - { - memcpy(&tempshort, mem, sizeof(short)); + } + else if (H5Tequal(tid, H5T_NATIVE_SHORT)) { + memcpy(&tempshort, mem, sizeof(short)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d ", tempshort); + fprintf(stream, "%d ", tempshort); #else - if (1 != fwrite(&tempshort, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempshort, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_USHORT)) - { - memcpy(&tempushort, mem, sizeof(unsigned short)); + } + else if (H5Tequal(tid, H5T_NATIVE_USHORT)) { + memcpy(&tempushort, mem, sizeof(unsigned short)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%u ", tempushort); + fprintf(stream, "%u ", tempushort); #else - if (1 != fwrite(&tempushort, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempushort, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_LONG)) - { - memcpy(&templong, mem, sizeof(long)); + } + else if (H5Tequal(tid, H5T_NATIVE_LONG)) { + memcpy(&templong, mem, sizeof(long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%ld ", templong); + fprintf(stream, "%ld ", templong); #else - if (1 != fwrite(&templong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_ULONG)) - { - memcpy(&tempulong, mem, sizeof(unsigned long)); + } + else if (H5Tequal(tid, H5T_NATIVE_ULONG)) { + memcpy(&tempulong, mem, sizeof(unsigned long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%lu ", tempulong); + fprintf(stream, "%lu ", tempulong); #else - if (1 != fwrite(&tempulong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempulong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_LLONG)) - { - memcpy(&templlong, mem, sizeof(long long)); + } + else if (H5Tequal(tid, H5T_NATIVE_LLONG)) { + memcpy(&templlong, mem, sizeof(long long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, fmt_llong, templlong); + fprintf(stream, fmt_llong, templlong); #else - if (1 != fwrite(&templlong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templlong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_ULLONG)) - { - memcpy(&tempullong, mem, sizeof(unsigned long long)); + } + else if (H5Tequal(tid, H5T_NATIVE_ULLONG)) { + memcpy(&tempullong, mem, sizeof(unsigned long long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, fmt_ullong, tempullong); + fprintf(stream, fmt_ullong, tempullong); #else - if (1 != fwrite(&tempullong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempullong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_HSSIZE)) - { - if (sizeof(hssize_t) == sizeof(int)) - { - memcpy(&tempint, mem, sizeof(int)); + } + else if (H5Tequal(tid, H5T_NATIVE_HSSIZE)) { + if (sizeof(hssize_t) == sizeof(int)) { + memcpy(&tempint, mem, sizeof(int)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d ", tempint); + fprintf(stream, "%d ", tempint); #else - if (1 != fwrite(&tempint, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempint, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (sizeof(hssize_t) == sizeof(long)) - { - memcpy(&templong, mem, sizeof(long)); + } + else if (sizeof(hssize_t) == sizeof(long)) { + memcpy(&templong, mem, sizeof(long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%ld ", templong); + fprintf(stream, "%ld ", templong); #else - if (1 != fwrite(&templong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else - { - memcpy(&templlong, mem, sizeof(long long)); + } + else { + memcpy(&templlong, mem, sizeof(long long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, fmt_llong, templlong); + fprintf(stream, fmt_llong, templlong); #else - if (1 != fwrite(&templlong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templlong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - } - else if (H5Tequal(tid, H5T_NATIVE_HSIZE)) - { - if (sizeof(hsize_t) == sizeof(int)) - { - memcpy(&tempuint, mem, sizeof(unsigned int)); + } + } + else if (H5Tequal(tid, H5T_NATIVE_HSIZE)) { + if (sizeof(hsize_t) == sizeof(int)) { + memcpy(&tempuint, mem, sizeof(unsigned int)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%u ", tempuint); + fprintf(stream, "%u ", tempuint); #else - if (1 != fwrite(&tempuint, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempuint, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (sizeof(hsize_t) == sizeof(long)) - { - memcpy(&tempulong, mem, sizeof(unsigned long)); + } + else if (sizeof(hsize_t) == sizeof(long)) { + memcpy(&tempulong, mem, sizeof(unsigned long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%lu ", tempulong); + fprintf(stream, "%lu ", tempulong); #else - if (1 != fwrite(&tempulong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempulong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else - { - memcpy(&tempullong, mem, sizeof(unsigned long long)); + } + else { + memcpy(&tempullong, mem, sizeof(unsigned long long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, fmt_ullong, tempullong); + fprintf(stream, fmt_ullong, tempullong); #else - if (1 != fwrite(&tempullong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempullong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - } - else if (H5Tget_class(tid) == H5T_COMPOUND) - { - unsigned j; - hid_t memb; - unsigned nmembs; - size_t offset; - - nmembs = H5Tget_nmembers(tid); - - for (j = 0; j < nmembs; j++) - { - offset = H5Tget_member_offset(tid, j); - memb = H5Tget_member_type(tid, j); - - if (render_bin_output(stream,memb,mem + offset)<0) - return FAIL; - - H5Tclose(memb); - } - } - else if (H5Tget_class(tid) == H5T_ENUM) - { - unsigned int i; - if (1==size) - { + } + } + else if (H5Tget_class(tid) == H5T_COMPOUND) { + unsigned j; + hid_t memb; + unsigned nmembs; + size_t offset; + + nmembs = H5Tget_nmembers(tid); + + for (j = 0; j < nmembs; j++) { + offset = H5Tget_member_offset(tid, j); + memb = H5Tget_member_type(tid, j); + + if (render_bin_output(stream, memb, mem + offset) < 0) + return FAIL; + + H5Tclose(memb); + } + } + else if (H5Tget_class(tid) == H5T_ENUM) { + unsigned int i; + if (1 == size) { #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "0x%02x", mem[0]); + fprintf(stream, "0x%02x", mem[0]); #else - if (1 != fwrite(&mem[0], size, 1, stream)) - return FAIL; + if (1 != fwrite(&mem[0], size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else - { - for (i = 0; i < size; i++) - { + } + else { + for (i = 0; i < size; i++) { #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%s%02x", i?":":"", mem[i]); + fprintf(stream, "%s%02x", i?":":"", mem[i]); #else - if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) - return FAIL; + if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } /*i*/ - }/*else 1 */ - } - else if (H5Tget_class(tid) == H5T_ARRAY) - { - int k, ndims; - hsize_t i, dims[H5S_MAX_RANK], temp_nelmts, nelmts; - hid_t memb; - - /* get the array's base datatype for each element */ - memb = H5Tget_super(tid); - size = H5Tget_size(memb); - ndims = H5Tget_array_ndims(tid); - H5Tget_array_dims2(tid, dims); - assert(ndims >= 1 && ndims <= H5S_MAX_RANK); - - /* calculate the number of array elements */ - for (k = 0, nelmts = 1; k < ndims; k++) - { - temp_nelmts = nelmts; - temp_nelmts *= dims[k]; - nelmts = (size_t)temp_nelmts; - } - - /* dump the array element */ - for (i = 0; i < nelmts; i++) - { - if (render_bin_output(stream,memb,mem + i * size)<0) - return FAIL; - } - - H5Tclose(memb); - } - else if (H5Tget_class(tid) == H5T_VLEN) - { - unsigned int i; - hsize_t nelmts; - hid_t memb; - - /* get the VL sequences's base datatype for each element */ - memb = H5Tget_super(tid); - size = H5Tget_size(memb); - - /* Get the number of sequence elements */ - nelmts = ((hvl_t *)mem)->len; - - 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; - } - H5Tclose(memb); - } - else - { - size_t i; - if (1==size) - { + } /*i*/ + }/*else 1 */ + } + else if (H5Tget_class(tid) == H5T_ARRAY) { + int k, ndims; + hsize_t i, dims[H5S_MAX_RANK], temp_nelmts, nelmts; + hid_t memb; + + /* get the array's base datatype for each element */ + memb = H5Tget_super(tid); + size = H5Tget_size(memb); + ndims = H5Tget_array_ndims(tid); + H5Tget_array_dims2(tid, dims); + assert(ndims >= 1 && ndims <= H5S_MAX_RANK); + + /* calculate the number of array elements */ + for (k = 0, nelmts = 1; k < ndims; k++) { + temp_nelmts = nelmts; + temp_nelmts *= dims[k]; + nelmts = (size_t) temp_nelmts; + } + + /* dump the array element */ + for (i = 0; i < nelmts; i++) { + if (render_bin_output(stream, memb, mem + i * size) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "render_bin_output failed"); + } + + H5Tclose(memb); + } + else if (H5Tget_class(tid) == H5T_VLEN) { + unsigned int i; + hsize_t nelmts; + hid_t memb; + + /* get the VL sequences's base datatype for each element */ + memb = H5Tget_super(tid); + size = H5Tget_size(memb); + + /* Get the number of sequence elements */ + nelmts = ((hvl_t *) mem)->len; + + for (i = 0; i < nelmts; i++) { + /* dump the array element */ + if (render_bin_output(stream, memb, ((char *) (((hvl_t *) mem)->p)) + i * size) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "render_bin_output failed"); + } + H5Tclose(memb); + } + else { + size_t i; + if (1 == size) { #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "0x%02x", mem[0]); + fprintf(stream, "0x%02x", mem[0]); #else - if (1 != fwrite(&mem[0], size, 1, stream)) - return FAIL; + if (1 != fwrite(&mem[0], size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else - { - for (i = 0; i < size; i++) - { + } + else { + for (i = 0; i < size; i++) { #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%s%02x", i?":":"", mem[i]); + fprintf(stream, "%s%02x", i?":":"", mem[i]); #else - if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) - return FAIL; + if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } /*i*/ - }/*else 1 */ - } + } /*i*/ + }/*else 1 */ + } + +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: h5tools_is_zero + * + * Purpose: Determines if memory is initialized to all zero bytes. + * + * Return: TRUE if all bytes are zero; FALSE otherwise + *------------------------------------------------------------------------- + */ +static +hbool_t h5tools_is_zero(const void *_mem, size_t size) +{ + const unsigned char *mem = (const unsigned char *) _mem; + while (size-- > 0) + if (mem[size]) + return FALSE; - return SUCCEED; + return TRUE; } diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h index fb24f76..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)) @@ -50,6 +51,147 @@ /* format for hsize_t */ #define HSIZE_T_FORMAT "%"H5_PRINTF_LL_WIDTH"u" +#define H5TOOLS_DUMP_MAX_RANK H5S_MAX_RANK + +/* + * Strings for output - these were duplicated from the h5dump.h + * file in order to support region reference data display + */ +#define ATTRIBUTE "ATTRIBUTE" +#define BLOCK "BLOCK" +#define SUPER_BLOCK "SUPER_BLOCK" +#define COMPRESSION "COMPRESSION" +#define CONCATENATOR "//" +#define COMPLEX "COMPLEX" +#define COUNT "COUNT" +#define CSET "CSET" +#define CTYPE "CTYPE" +#define DATA "DATA" +#define DATASPACE "DATASPACE" +#define EXTERNAL "EXTERNAL" +#define FILENO "FILENO" +#define HARDLINK "HARDLINK" +#define NLINK "NLINK" +#define OBJID "OBJECTID" +#define OBJNO "OBJNO" +#define S_SCALAR "SCALAR" +#define S_SIMPLE "SIMPLE" +#define S_NULL "NULL" +#define SOFTLINK "SOFTLINK" +#define EXTLINK "EXTERNAL_LINK" +#define UDLINK "USERDEFINED_LINK" +#define START "START" +#define STRIDE "STRIDE" +#define STRSIZE "STRSIZE" +#define STRPAD "STRPAD" +#define SUBSET "SUBSET" +#define FILTERS "FILTERS" +#define DEFLATE "COMPRESSION DEFLATE" +#define DEFLATE_LEVEL "LEVEL" +#define SHUFFLE "PREPROCESSING SHUFFLE" +#define FLETCHER32 "CHECKSUM FLETCHER32" +#define SZIP "COMPRESSION SZIP" +#define NBIT "COMPRESSION NBIT" +#define SCALEOFFSET "COMPRESSION SCALEOFFSET" +#define SCALEOFFSET_MINBIT "MIN BITS" +#define STORAGE_LAYOUT "STORAGE_LAYOUT" +#define CONTIGUOUS "CONTIGUOUS" +#define COMPACT "COMPACT" +#define CHUNKED "CHUNKED" +#define EXTERNAL_FILE "EXTERNAL_FILE" +#define FILLVALUE "FILLVALUE" +#define FILE_CONTENTS "FILE_CONTENTS" + +#define BEGIN "{" +#define END "}" + +/* + * dump structure for output - this was duplicated from the h5dump.h + * file in order to support region reference data display + */ +typedef struct h5tools_dump_header_t { + const char *name; + const char *filebegin; + const char *fileend; + const char *bootblockbegin; + const char *bootblockend; + const char *groupbegin; + const char *groupend; + const char *datasetbegin; + const char *datasetend; + const char *attributebegin; + const char *attributeend; + const char *datatypebegin; + const char *datatypeend; + const char *dataspacebegin; + const char *dataspaceend; + const char *databegin; + const char *dataend; + const char *softlinkbegin; + const char *softlinkend; + const char *extlinkbegin; + const char *extlinkend; + const char *udlinkbegin; + const char *udlinkend; + const char *subsettingbegin; + const char *subsettingend; + const char *startbegin; + const char *startend; + const char *stridebegin; + const char *strideend; + const char *countbegin; + const char *countend; + const char *blockbegin; + const char *blockend; + + const char *fileblockbegin; + const char *fileblockend; + const char *bootblockblockbegin; + const char *bootblockblockend; + const char *groupblockbegin; + const char *groupblockend; + const char *datasetblockbegin; + const char *datasetblockend; + const char *attributeblockbegin; + const char *attributeblockend; + const char *datatypeblockbegin; + const char *datatypeblockend; + const char *dataspaceblockbegin; + const char *dataspaceblockend; + const char *datablockbegin; + const char *datablockend; + const char *softlinkblockbegin; + const char *softlinkblockend; + const char *extlinkblockbegin; + const char *extlinkblockend; + const char *udlinkblockbegin; + const char *udlinkblockend; + const char *strblockbegin; + const char *strblockend; + const char *enumblockbegin; + const char *enumblockend; + const char *structblockbegin; + const char *structblockend; + const char *vlenblockbegin; + const char *vlenblockend; + const char *subsettingblockbegin; + const char *subsettingblockend; + const char *startblockbegin; + const char *startblockend; + const char *strideblockbegin; + const char *strideblockend; + const char *countblockbegin; + const char *countblockend; + const char *blockblockbegin; + const char *blockblockend; + + const char *dataspacedescriptionbegin; + const char *dataspacedescriptionend; + const char *dataspacedimbegin; + const char *dataspacedimend; + +} h5tools_dump_header_t; + /* * Information about how to format output. */ @@ -373,11 +515,16 @@ struct subset_t { hsize_t *block; }; +/* The following include, h5tools_str.h, must be after the + * above stucts are defined. There is a dependency in the following + * include that hasn't been identified yet. */ + +#include "h5tools_str.h" + extern FILE *rawdatastream; /* output stream for raw data */ extern int bin_output; /* binary output */ extern int bin_form; /* binary form */ - - +extern int region_output; /* region output */ /* Strings for output */ #define H5_TOOLS_GROUP "GROUP" @@ -407,6 +554,15 @@ extern int h5tools_canreadf(const char* name, extern int h5tools_can_encode(H5Z_filter_t filtn); void init_acc_pos(h5tools_context_t *ctx, hsize_t *dims); - +/* + * new functions needed to display region reference data + */ +void h5tools_dump_datatype(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, hid_t type); +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); +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/h5tools_str.c b/tools/lib/h5tools_str.c index 08ec5d7..3567975 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -29,7 +29,6 @@ #include "h5tools_ref.h" #include "h5tools_str.h" /*function prototypes */ - /* * If REPEAT_VERBOSE is defined then character strings will be printed so * that repeated character sequences like "AAAAAAAAAA" are displayed as @@ -47,7 +46,7 @@ #define STR_INIT_LEN 4096 /*initial length */ static char *h5tools_escape(char *s, size_t size); -static hbool_t h5tools_is_zero(const void *_mem, size_t size); +static hbool_t h5tools_str_is_zero(const void *_mem, size_t size); static void h5tools_print_char(h5tools_str_t *str, const h5tool_format_t *info, char ch); /*------------------------------------------------------------------------- @@ -161,7 +160,7 @@ h5tools_str_append(h5tools_str_t *str/*in,out*/, const char *fmt, ...) * something other than "%s" * Alocate at least twice as much space and try again. */ - size_t newsize = MAX(str->len+nchars+1, 2*str->nalloc); + size_t newsize = MAX(str->len + nchars + 1, 2 * str->nalloc); assert(newsize > str->nalloc); /*overflow*/ str->s = realloc(str->s, newsize); assert(str->s); @@ -198,9 +197,9 @@ char * h5tools_str_reset(h5tools_str_t *str/*in,out*/) { if (!str->s || str->nalloc <= 0) { - str->nalloc = STR_INIT_LEN; - str->s = malloc(str->nalloc); - assert(str->s); + str->nalloc = STR_INIT_LEN; + str->s = malloc(str->nalloc); + assert(str->s); } str->s[0] = '\0'; @@ -228,8 +227,8 @@ char * h5tools_str_trunc(h5tools_str_t *str/*in,out*/, size_t size) { if (size < str->len) { - str->len = size; - str->s[size] = '\0'; + str->len = size; + str->s[size] = '\0'; } return str->s; @@ -270,7 +269,7 @@ h5tools_str_fmt(h5tools_str_t *str/*in,out*/, size_t start, const char *fmt) */ if (strchr(fmt, '%')) { if (str->len - start + 1 > sizeof(_temp)) { - temp = malloc(str->len-start + 1); + temp = malloc(str->len - start + 1); assert(temp); } @@ -309,6 +308,59 @@ h5tools_str_prefix(h5tools_str_t *str/*in,out*/, const h5tool_format_t *info, hsize_t elmtno, unsigned ndims, hsize_t min_idx[], hsize_t max_idx[], h5tools_context_t *ctx) { + size_t i = 0; + hsize_t curr_pos = elmtno; + + h5tools_str_reset(str); + + if (ndims > 0) { + /* + * Calculate the number of elements represented by a unit change in a + * certain index position. + */ + for (i = 0; i < (size_t) ndims; i++) { + ctx->pos[i] = curr_pos / ctx->acc[i]; + curr_pos -= ctx->acc[i] * ctx->pos[i]; + } + assert(curr_pos == 0); + + /* Print the index values */ + for (i = 0; i < (size_t) ndims; i++) { + if (i) + h5tools_str_append(str, "%s", OPT(info->idx_sep, ",")); + + h5tools_str_append(str, OPT(info->idx_n_fmt, HSIZE_T_FORMAT), + (hsize_t) ctx->pos[i]); + + } + } + else { + /* Scalar */ + h5tools_str_append(str, OPT(info->idx_n_fmt, HSIZE_T_FORMAT), (hsize_t) 0); + } + + /* Add prefix and suffix to the index */ + return h5tools_str_fmt(str, 0, OPT(info->idx_fmt, "%s: ")); +} + +/*------------------------------------------------------------------------- + * Function: h5tools_str_region_prefix + * + * Purpose: Renders the line prefix value into string STR. Region reference specific. + * + * Return: Success: Pointer to the prefix. + * Failure: NULL + * + * In/Out: + * h5tools_context_t *ctx + * h5tools_str_t *str + *------------------------------------------------------------------------- + */ +char * +h5tools_str_region_prefix(h5tools_str_t *str, const h5tool_format_t *info, + hsize_t elmtno, hsize_t *ptdata, unsigned ndims, hsize_t min_idx[], hsize_t max_idx[], + h5tools_context_t *ctx) +{ hsize_t p_prod[H5S_MAX_RANK]; size_t i = 0; hsize_t curr_pos = elmtno; @@ -321,26 +373,26 @@ h5tools_str_prefix(h5tools_str_t *str/*in,out*/, const h5tool_format_t *info, * certain index position. */ for (i = ndims - 1, p_prod[ndims - 1] = 1; i > 0; --i) - p_prod[i - 1] = (max_idx[i] - min_idx[i]) * p_prod[i]; + p_prod[i - 1] = (max_idx[i]) * p_prod[i]; - for ( i = 0; i < (size_t)ndims; i++) { - ctx->pos[i] = curr_pos/ctx->acc[i]; - curr_pos -= ctx->acc[i]*ctx->pos[i]; + for (i = 0; i < (size_t) ndims; i++) { + ctx->pos[i] = curr_pos / p_prod[i]; + curr_pos -= p_prod[i] * ctx->pos[i]; + ctx->pos[i] += (unsigned long) ptdata[ctx->sm_pos+i]; } - assert( curr_pos == 0 ); /* Print the index values */ - for (i = 0; i < (size_t)ndims; i++) { + for (i = 0; i < (size_t) ndims; i++) { if (i) h5tools_str_append(str, "%s", OPT(info->idx_sep, ",")); - h5tools_str_append(str, OPT(info->idx_n_fmt, HSIZE_T_FORMAT), - (hsize_t)ctx->pos[i]); + h5tools_str_append(str, OPT(info->idx_n_fmt, HSIZE_T_FORMAT), (hsize_t) ctx->pos[i]); } - } else { + } /* if (ndims > 0) */ + else { /* Scalar */ - h5tools_str_append(str, OPT(info->idx_n_fmt, HSIZE_T_FORMAT), (hsize_t)0); + h5tools_str_append(str, OPT(info->idx_n_fmt, HSIZE_T_FORMAT), (hsize_t) 0); } /* Add prefix and suffix to the index */ @@ -348,103 +400,120 @@ h5tools_str_prefix(h5tools_str_t *str/*in,out*/, const h5tool_format_t *info, } /*------------------------------------------------------------------------- - * Function: h5tools_str_dump_region + * Function: h5tools_str_dump_region_blocks * * Purpose: Prints information about a dataspace region by appending - * the information to the specified string. - * - * Return: Success: 0 - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Monday, June 7, 1999 - * - * Modifications: + * the information to the specified string. * + * Return: none + * + * In/Out: + * h5tools_context_t *ctx + * h5tools_str_t *str *------------------------------------------------------------------------- */ -int -h5tools_str_dump_region(h5tools_str_t *str, hid_t region, const h5tool_format_t *info) +void +h5tools_str_dump_region_blocks(h5tools_str_t *str, hid_t region, + const h5tool_format_t *info, h5tools_context_t *ctx) { - hssize_t nblocks, npoints; - hsize_t alloc_size; - hsize_t *ptdata; - int ndims = H5Sget_simple_extent_ndims(region); + hssize_t nblocks; + hsize_t alloc_size; + hsize_t *ptdata; + int ndims = H5Sget_simple_extent_ndims(region); /* - * These two functions fail if the region does not have blocks or points, - * respectively. They do not currently know how to translate from one to - * the other. + * This function fails if the region does not have blocks. */ H5E_BEGIN_TRY { nblocks = H5Sget_select_hyper_nblocks(region); - npoints = H5Sget_select_elem_npoints(region); } H5E_END_TRY; - h5tools_str_append(str, "{"); - /* Print block information */ if (nblocks > 0) { int i; alloc_size = nblocks * ndims * 2 * sizeof(ptdata[0]); - assert(alloc_size == (hsize_t)((size_t)alloc_size)); /*check for overflow*/ - ptdata = malloc((size_t)alloc_size); + assert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ + ptdata = malloc((size_t) alloc_size); H5_CHECK_OVERFLOW(nblocks, hssize_t, hsize_t); H5Sget_select_hyper_blocklist(region, (hsize_t)0, (hsize_t)nblocks, ptdata); for (i = 0; i < nblocks; i++) { int j; - h5tools_str_append(str, info->dset_blockformat_pre, - i ? "," OPTIONAL_LINE_BREAK " " : "", + h5tools_str_append(str, info->dset_blockformat_pre, i ? "," OPTIONAL_LINE_BREAK " " : "", (unsigned long)i); /* Start coordinates and opposite corner */ for (j = 0; j < ndims; j++) h5tools_str_append(str, "%s%lu", j ? "," : "(", - (unsigned long)ptdata[i * 2 * ndims + j]); + (unsigned long) ptdata[i * 2 * ndims + j]); for (j = 0; j < ndims; j++) h5tools_str_append(str, "%s%lu", j ? "," : ")-(", - (unsigned long)ptdata[i * 2 * ndims + j + ndims]); + (unsigned long) ptdata[i * 2 * ndims + j + ndims]); h5tools_str_append(str, ")"); } free(ptdata); - } + } /* end if (nblocks > 0) */ +} + +/*------------------------------------------------------------------------- + * Function: h5tools_str_dump_region_points + * + * Purpose: Prints information about a dataspace region by appending + * the information to the specified string. + * + * Return: none + * + * In/Out: + * h5tools_context_t *ctx + * h5tools_str_t *str + *------------------------------------------------------------------------- + */ +void +h5tools_str_dump_region_points(h5tools_str_t *str, hid_t region, + const h5tool_format_t *info, h5tools_context_t *ctx) +{ + hssize_t npoints; + hsize_t alloc_size; + hsize_t *ptdata; + int ndims = H5Sget_simple_extent_ndims(region); + + /* + * This function fails if the region does not have points. + */ + H5E_BEGIN_TRY { + npoints = H5Sget_select_elem_npoints(region); + } H5E_END_TRY; /* Print point information */ if (npoints > 0) { int i; 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); - H5_CHECK_OVERFLOW(npoints,hssize_t,hsize_t); + assert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ + ptdata = malloc((size_t) alloc_size); + H5_CHECK_OVERFLOW(npoints, hssize_t, hsize_t); H5Sget_select_elem_pointlist(region, (hsize_t)0, (hsize_t)npoints, ptdata); for (i = 0; i < npoints; i++) { int j; - h5tools_str_append(str, info->dset_ptformat_pre , - i ? "," OPTIONAL_LINE_BREAK " " : "", + h5tools_str_append(str, info->dset_ptformat_pre, i ? "," OPTIONAL_LINE_BREAK " " : "", (unsigned long)i); for (j = 0; j < ndims; j++) h5tools_str_append(str, "%s%lu", j ? "," : "(", - (unsigned long)(ptdata[i * ndims + j])); + (unsigned long) (ptdata[i * ndims + j])); h5tools_str_append(str, ")"); } free(ptdata); - } - - h5tools_str_append(str, "}"); - return 0; + } /* end if (npoints > 0) */ } /*------------------------------------------------------------------------- @@ -454,11 +523,6 @@ h5tools_str_dump_region(h5tools_str_t *str, hid_t region, const h5tool_format_t * * Return: Nothing * - * Programmer: Bill Wendling - * Tuesday, 20. February 2001 - * - * Modifications: - * *------------------------------------------------------------------------- */ static void @@ -469,66 +533,66 @@ h5tools_print_char(h5tools_str_t *str, const h5tool_format_t *info, char ch) h5tools_str_append(str, "%%%02x", ch); else h5tools_str_append(str, "%c", ch); - } else { + } + else { switch (ch) { - case '"': - if (!info->do_escape) + case '"': + if (!info->do_escape) h5tools_str_append(str, "\""); - else + else h5tools_str_append(str, "\\\""); - break; - case '\\': - if (!info->do_escape) + break; + case '\\': + if (!info->do_escape) h5tools_str_append(str, "\\"); - else + else h5tools_str_append(str, "\\\\"); - break; - case '\b': - if (!info->do_escape) + break; + case '\b': + if (!info->do_escape) h5tools_str_append(str, "\b"); - else + else h5tools_str_append(str, "\\b"); - break; - case '\f': - if (!info->do_escape) - h5tools_str_append(str, "\f"); - else - h5tools_str_append(str, "\\f"); - break; - case '\n': - if (!info->do_escape) { - h5tools_str_append(str, "\n"); - h5tools_str_append(str, " "); - } - else + break; + case '\f': + if (!info->do_escape) + h5tools_str_append(str, "\f"); + else + h5tools_str_append(str, "\\f"); + break; + case '\n': + if (!info->do_escape) { + h5tools_str_append(str, "\n"); + h5tools_str_append(str, " "); + } + else h5tools_str_append(str, "\\n"); - break; - case '\r': - if (!info->do_escape) { - h5tools_str_append(str, "\r"); - h5tools_str_append(str, " "); - } - else + break; + case '\r': + if (!info->do_escape) { + h5tools_str_append(str, "\r"); + h5tools_str_append(str, " "); + } + else h5tools_str_append(str, "\\r"); - break; - case '\t': - if (!info->do_escape) - h5tools_str_append(str, "\t"); - else - h5tools_str_append(str, "\\t"); - break; - default: - if (isprint(ch)) - h5tools_str_append(str, "%c", ch); - else - h5tools_str_append(str, "\\%03o", ch); + break; + case '\t': + if (!info->do_escape) + h5tools_str_append(str, "\t"); + else + h5tools_str_append(str, "\\t"); + break; + default: + if (isprint(ch)) + h5tools_str_append(str, "%c", ch); + else + h5tools_str_append(str, "\\%03o", ch); - break; + break; } } } - /*------------------------------------------------------------------------- * Function: h5tools_str_sprint * @@ -592,7 +656,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai int tempint; /* Build default formats for long long types */ - if(!fmt_llong[0]) { + if (!fmt_llong[0]) { sprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH); sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); } @@ -600,63 +664,70 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai /* Append value depending on data type */ start = h5tools_str_len(str); - if(info->raw) { + if (info->raw) { size_t i; n = H5Tget_size(type); - if (1==n) { + if (1 == n) { h5tools_str_append(str, OPT(info->fmt_raw, "0x%02x"), ucp_vp[0]); - } else { - for(i = 0; i < n; i++) { - if(i) + } + else { + for (i = 0; i < n; i++) { + if (i) h5tools_str_append(str, ":"); h5tools_str_append(str, OPT(info->fmt_raw, "%02x"), ucp_vp[i]); } } - } else if (H5Tequal(type, H5T_NATIVE_FLOAT)) { - float tempfloat; + } + else if (H5Tequal(type, H5T_NATIVE_FLOAT)) { + float tempfloat; HDmemcpy(&tempfloat, vp, sizeof(float)); h5tools_str_append(str, OPT(info->fmt_float, "%g"), tempfloat); - } else if (H5Tequal(type, H5T_NATIVE_DOUBLE)) { - double tempdouble; + } + else if (H5Tequal(type, H5T_NATIVE_DOUBLE)) { + double tempdouble; HDmemcpy(&tempdouble, vp, sizeof(double)); h5tools_str_append(str, OPT(info->fmt_double, "%g"), tempdouble); #if H5_SIZEOF_LONG_DOUBLE !=0 - } else if (H5Tequal(type, H5T_NATIVE_LDOUBLE)) { - long double templdouble; + } + else if (H5Tequal(type, H5T_NATIVE_LDOUBLE)) { + long double templdouble; HDmemcpy(&templdouble, vp, sizeof(long double)); h5tools_str_append(str, "%Lf", templdouble); #endif - } else if (info->ascii && (H5Tequal(type, H5T_NATIVE_SCHAR) || - H5Tequal(type, H5T_NATIVE_UCHAR))) { - h5tools_print_char(str, info, (char)(*ucp_vp)); - } else if (H5T_STRING == H5Tget_class(type)) { + } + else if (info->ascii && (H5Tequal(type, H5T_NATIVE_SCHAR) || + H5Tequal(type, H5T_NATIVE_UCHAR))) { + h5tools_print_char(str, info, (char) (*ucp_vp)); + } + else if (H5T_STRING == H5Tget_class(type)) { unsigned int i; char quote = '\0'; char *s; quote = '\0'; - if(H5Tis_variable_str(type)) { + if (H5Tis_variable_str(type)) { /* cp_vp is the pointer into the struct where a `char*' is stored. So we have * to dereference the pointer to get the `char*' to pass to HDstrlen(). */ - s = *(char**)cp_vp; - if(s!=NULL) + s = *(char**) cp_vp; + if (s != NULL) size = HDstrlen(s); - } else { + } + else { s = cp_vp; size = H5Tget_size(type); } pad = H5Tget_strpad(type); /* Check for NULL pointer for string */ - if(s==NULL) { + if (s == NULL) { h5tools_str_append(str, "NULL"); } else { - for (i=0; i<size && (s[i] || pad!=H5T_STR_NULLTERM); i++) { + for (i = 0; i < size && (s[i] || pad != H5T_STR_NULLTERM); i++) { int j = 1; /* @@ -680,7 +751,8 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai quote = '\''; h5tools_str_append(str, "%s%c", i ? " " : "", quote); - } else if (!quote) { + } + else if (!quote) { quote = '"'; h5tools_str_append(str, "%s%c", i ? " " : "", quote); } @@ -708,61 +780,78 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai /*empty string*/ h5tools_str_append(str, "\"\""); } /* end else */ - } else if (H5Tequal(type, H5T_NATIVE_INT)) { + } + else if (H5Tequal(type, H5T_NATIVE_INT)) { HDmemcpy(&tempint, vp, sizeof(int)); h5tools_str_append(str, OPT(info->fmt_int, "%d"), tempint); - } else if (H5Tequal(type, H5T_NATIVE_UINT)) { + } + else if (H5Tequal(type, H5T_NATIVE_UINT)) { HDmemcpy(&tempuint, vp, sizeof(unsigned int)); h5tools_str_append(str, OPT(info->fmt_uint, "%u"), tempuint); - } else if (H5Tequal(type, H5T_NATIVE_SCHAR)) { + } + else if (H5Tequal(type, H5T_NATIVE_SCHAR)) { h5tools_str_append(str, OPT(info->fmt_schar, "%d"), *cp_vp); - } else if (H5Tequal(type, H5T_NATIVE_UCHAR)) { + } + else if (H5Tequal(type, H5T_NATIVE_UCHAR)) { h5tools_str_append(str, OPT(info->fmt_uchar, "%u"), *ucp_vp); - } else if (H5Tequal(type, H5T_NATIVE_SHORT)) { - short tempshort; + } + else if (H5Tequal(type, H5T_NATIVE_SHORT)) { + short tempshort; HDmemcpy(&tempshort, vp, sizeof(short)); h5tools_str_append(str, OPT(info->fmt_short, "%d"), tempshort); - } else if (H5Tequal(type, H5T_NATIVE_USHORT)) { - unsigned short tempushort; + } + else if (H5Tequal(type, H5T_NATIVE_USHORT)) { + unsigned short tempushort; HDmemcpy(&tempushort, vp, sizeof(unsigned short)); h5tools_str_append(str, OPT(info->fmt_ushort, "%u"), tempushort); - } else if (H5Tequal(type, H5T_NATIVE_LONG)) { + } + else if (H5Tequal(type, H5T_NATIVE_LONG)) { HDmemcpy(&templong, vp, sizeof(long)); h5tools_str_append(str, OPT(info->fmt_long, "%ld"), templong); - } else if (H5Tequal(type, H5T_NATIVE_ULONG)) { + } + else if (H5Tequal(type, H5T_NATIVE_ULONG)) { HDmemcpy(&tempulong, vp, sizeof(unsigned long)); h5tools_str_append(str, OPT(info->fmt_ulong, "%lu"), tempulong); - } else if (H5Tequal(type, H5T_NATIVE_LLONG)) { + } + else if (H5Tequal(type, H5T_NATIVE_LLONG)) { HDmemcpy(&templlong, vp, sizeof(long long)); h5tools_str_append(str, OPT(info->fmt_llong, fmt_llong), templlong); - } else if (H5Tequal(type, H5T_NATIVE_ULLONG)) { + } + else if (H5Tequal(type, H5T_NATIVE_ULLONG)) { HDmemcpy(&tempullong, vp, sizeof(unsigned long long)); h5tools_str_append(str, OPT(info->fmt_ullong, fmt_ullong), tempullong); - } else if (H5Tequal(type, H5T_NATIVE_HSSIZE)) { + } + else if (H5Tequal(type, H5T_NATIVE_HSSIZE)) { if (sizeof(hssize_t) == sizeof(int)) { memcpy(&tempint, vp, sizeof(int)); h5tools_str_append(str, OPT(info->fmt_int, "%d"), tempint); - } else if (sizeof(hssize_t) == sizeof(long)) { + } + else if (sizeof(hssize_t) == sizeof(long)) { memcpy(&templong, vp, sizeof(long)); h5tools_str_append(str, OPT(info->fmt_long, "%ld"), templong); - } else { + } + else { memcpy(&templlong, vp, sizeof(long long)); h5tools_str_append(str, OPT(info->fmt_llong, fmt_llong), templlong); } - } else if (H5Tequal(type, H5T_NATIVE_HSIZE)) { + } + else if (H5Tequal(type, H5T_NATIVE_HSIZE)) { if (sizeof(hsize_t) == sizeof(int)) { memcpy(&tempuint, vp, sizeof(unsigned int)); h5tools_str_append(str, OPT(info->fmt_uint, "%u"), tempuint); - } else if (sizeof(hsize_t) == sizeof(long)) { + } + else if (sizeof(hsize_t) == sizeof(long)) { memcpy(&tempulong, vp, sizeof(long)); h5tools_str_append(str, OPT(info->fmt_ulong, "%lu"), tempulong); - } else { + } + else { memcpy(&tempullong, vp, sizeof(unsigned long long)); h5tools_str_append(str, OPT(info->fmt_ullong, fmt_ullong), tempullong); } - } else if (H5Tget_class(type) == H5T_COMPOUND) { + } + else if (H5Tget_class(type) == H5T_COMPOUND) { unsigned j; nmembs = H5Tget_nmembers(type); @@ -797,7 +886,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai memb = H5Tget_member_type(type, j); ctx->indent_level++; - h5tools_str_sprint(str, info, container, memb, cp_vp + offset , ctx); + h5tools_str_sprint(str, info, container, memb, cp_vp + offset, ctx); ctx->indent_level--; H5Tclose(memb); @@ -821,51 +910,42 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai } h5tools_str_append(str, "%s", OPT(info->cmpd_suf, "}")); - } else if (H5Tget_class(type) == H5T_ENUM) { + } + else if (H5Tget_class(type) == H5T_ENUM) { char enum_name[1024]; if (H5Tenum_nameof(type, vp, enum_name, sizeof enum_name) >= 0) { h5tools_str_append(str, h5tools_escape(enum_name, sizeof(enum_name))); - } else { + } + else { size_t i; n = H5Tget_size(type); - if (1==n) { + if (1 == n) { h5tools_str_append(str, "0x%02x", ucp_vp[0]); - } else { - for (i = 0; i < n; i++) - h5tools_str_append(str, "%s%02x", i?":":"", ucp_vp[i]); + } + else { + for (i = 0; i < n; i++) + h5tools_str_append(str, "%s%02x", i ? ":" : "", ucp_vp[i]); } } - } else if (H5Tequal(type, H5T_STD_REF_DSETREG)) { - /* - * Dataset region reference -- show the type and OID of the referenced - * object, but we are unable to show the region yet because there - * isn't enough support in the data space layer. - rpm 19990604 - */ - if (h5tools_is_zero(vp, H5Tget_size(type))) { + } + else if (H5Tequal(type, H5T_STD_REF_DSETREG)) { + if (h5tools_str_is_zero(vp, H5Tget_size(type))) { h5tools_str_append(str, "NULL"); - } else { - char ref_name[1024]; - - obj = H5Rdereference(container, H5R_DATASET_REGION, vp); - region = H5Rget_region(container, H5R_DATASET_REGION, vp); - - /* get name of the dataset the region reference points to using H5Rget_name */ - H5Rget_name(obj, H5R_DATASET_REGION, vp, (char*)ref_name, 1024); - h5tools_str_append(str, info->dset_format, ref_name); - - h5tools_str_dump_region(str, region, info); - H5Sclose(region); - H5Dclose(obj); } - } else if (H5Tequal(type, H5T_STD_REF_OBJ)) { + else { + h5tools_str_sprint_region(str, info, container, vp, ctx); + } + } + else if (H5Tequal(type, H5T_STD_REF_OBJ)) { /* * Object references -- show the type and OID of the referenced * object. */ - if (h5tools_is_zero(vp, H5Tget_size(type))) { + if (h5tools_str_is_zero(vp, H5Tget_size(type))) { h5tools_str_append(str, "NULL"); - } else { + } + else { H5O_info_t oi; const char *path; @@ -873,42 +953,43 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai H5Oget_info(obj, &oi); /* Print object type and close object */ - switch(oi.type) { - case H5O_TYPE_GROUP: - h5tools_str_append(str, H5_TOOLS_GROUP); - break; - - case H5O_TYPE_DATASET: - h5tools_str_append(str, H5_TOOLS_DATASET); - break; - - case H5O_TYPE_NAMED_DATATYPE: - h5tools_str_append(str, H5_TOOLS_DATATYPE); - break; - - default: - h5tools_str_append(str, "%u-", (unsigned)oi.type); - break; + switch (oi.type) { + case H5O_TYPE_GROUP: + h5tools_str_append(str, H5_TOOLS_GROUP); + break; + + case H5O_TYPE_DATASET: + h5tools_str_append(str, H5_TOOLS_DATASET); + break; + + case H5O_TYPE_NAMED_DATATYPE: + h5tools_str_append(str, H5_TOOLS_DATATYPE); + break; + + default: + h5tools_str_append(str, "%u-", (unsigned) oi.type); + break; } /* end switch */ H5Oclose(obj); /* Print OID */ - if(info->obj_hidefileno) + if (info->obj_hidefileno) h5tools_str_append(str, info->obj_format, oi.addr); else h5tools_str_append(str, info->obj_format, oi.fileno, oi.addr); - /* Print name */ - path = lookup_ref_path(*(haddr_t *)vp); + /* Print name */ + path = lookup_ref_path(*(haddr_t *) vp); if (path) { h5tools_str_append(str, " "); h5tools_str_append(str, path); h5tools_str_append(str, " "); } /* end if */ } /* end else */ - } else if (H5Tget_class(type) == H5T_ARRAY) { + } + else if (H5Tget_class(type) == H5T_ARRAY) { int k, ndims; - hsize_t i, dims[H5S_MAX_RANK],temp_nelmts; + hsize_t i, dims[H5S_MAX_RANK], temp_nelmts; /* Get the array's base datatype for each element */ memb = H5Tget_super(type); @@ -918,34 +999,33 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai assert(ndims >= 1 && ndims <= H5S_MAX_RANK); /* Calculate the number of array elements */ - for (k = 0, nelmts = 1; k < ndims; k++){ + for (k = 0, nelmts = 1; k < ndims; k++) { temp_nelmts = nelmts; temp_nelmts *= dims[k]; - assert(temp_nelmts==(hsize_t)((size_t)temp_nelmts)); - nelmts = (size_t)temp_nelmts; + assert(temp_nelmts == (hsize_t) ((size_t) temp_nelmts)); + nelmts = (size_t) temp_nelmts; } /* Print the opening bracket */ h5tools_str_append(str, "%s", OPT(info->arr_pre, "[")); - for(i = 0; i < nelmts; i++) { - if(i) - h5tools_str_append(str, "%s", - OPT(info->arr_sep, "," OPTIONAL_LINE_BREAK)); + for (i = 0; i < nelmts; i++) { + if (i) + h5tools_str_append(str, "%s", OPT(info->arr_sep, "," OPTIONAL_LINE_BREAK)); - if(info->arr_linebreak && i && i % dims[ndims - 1] == 0) { + if (info->arr_linebreak && i && i % dims[ndims - 1] == 0) { int x; h5tools_str_append(str, "%s", "\n"); /* need to indent some more here*/ - if(ctx->indent_level >= 0) - if(!info->pindex) + if (ctx->indent_level >= 0) + if (!info->pindex) h5tools_str_append(str, "%s", OPT(info->line_pre, "")); - for(x = 0; x < ctx->indent_level + 1; x++) + for (x = 0; x < ctx->indent_level + 1; x++) h5tools_str_append(str, "%s", OPT(info->line_indent, "")); } /* end if */ - else if(i && info->arr_sep) + else if (i && info->arr_sep) h5tools_str_append(str, " "); ctx->indent_level++; @@ -959,7 +1039,8 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai /* Print the closing bracket */ h5tools_str_append(str, "%s", OPT(info->arr_suf, "]")); H5Tclose(memb); - } else if (H5Tget_class(type) == H5T_VLEN) { + } + else if (H5Tget_class(type) == H5T_VLEN) { unsigned int i; /* Get the VL sequences's base datatype for each element */ @@ -970,15 +1051,14 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai h5tools_str_append(str, "%s", OPT(info->vlen_pre, "(")); /* Get the number of sequence elements */ - nelmts = ((hvl_t *)cp_vp)->len; + nelmts = ((hvl_t *) cp_vp)->len; for (i = 0; i < nelmts; i++) { if (i) - h5tools_str_append(str, "%s", - OPT(info->vlen_sep, "," OPTIONAL_LINE_BREAK)); + h5tools_str_append(str, "%s", OPT(info->vlen_sep, "," OPTIONAL_LINE_BREAK)); #ifdef LATER -/* Need to fix so VL data breaks at correct location on end of line -QAK */ + /* Need to fix so VL data breaks at correct location on end of line -QAK */ if (info->arr_linebreak && h5tools_str_len(str)>=info->line_ncols) { int x; @@ -997,28 +1077,71 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai /* Dump the array element */ h5tools_str_sprint(str, info, container, memb, - ((char *)(((hvl_t *)cp_vp)->p)) + i * size, ctx); + ((char *) (((hvl_t *) cp_vp)->p)) + i * size, ctx); ctx->indent_level--; } /* end for */ h5tools_str_append(str, "%s", OPT(info->vlen_suf, ")")); H5Tclose(memb); - } else { + } + else { /* All other types get printed as hexadecimal */ size_t i; n = H5Tget_size(type); - if (1==n) { + if (1 == n) { h5tools_str_append(str, "0x%02x", ucp_vp[0]); - } else { + } + else { for (i = 0; i < n; i++) - h5tools_str_append(str, "%s%02x", i?":":"", ucp_vp[i]); + h5tools_str_append(str, "%s%02x", i ? ":" : "", ucp_vp[i]); } } return h5tools_str_fmt(str, start, OPT(info->elmt_fmt, "%s")); } + +/*------------------------------------------------------------------------- + * Function: h5tools_str_sprint_region + * + * Purpose: Dataset region reference -- show the type and data of the referenced object. + * + * Return: Nothing + *------------------------------------------------------------------------- + */ +void +h5tools_str_sprint_region(h5tools_str_t *str, const h5tool_format_t *info, + hid_t container, void *vp, h5tools_context_t *ctx) +{ + hid_t obj, region; + char ref_name[1024]; + H5S_sel_type region_type; + + obj = H5Rdereference(container, H5R_DATASET_REGION, vp); + if (obj >= 0) { + region = H5Rget_region(container, H5R_DATASET_REGION, vp); + if (region >= 0) { + H5Rget_name(obj, H5R_DATASET_REGION, vp, (char*) ref_name, 1024); + + h5tools_str_append(str, info->dset_format, ref_name); + + h5tools_str_append(str, "{"); + + region_type = H5Sget_select_type(region); + if(region_type==H5S_SEL_POINTS) + h5tools_str_dump_region_points(str, region, info, ctx); + else + h5tools_str_dump_region_blocks(str, region, info, ctx); + + h5tools_str_append(str, "}"); + + H5Sclose(region); + } /* end if (region >= 0) */ + H5Dclose(obj); + } /* end if (obj >= 0) */ +} + /*------------------------------------------------------------------------- * Function: h5tools_escape * @@ -1047,70 +1170,71 @@ h5tools_escape(char *s/*in,out*/, size_t size) char octal[8]; for (i = 0; i < n; i++) { - switch (s[i]) { - case '\'': - escape = "\\\'"; - break; - case '\"': - escape = "\\\""; - break; - case '\\': - escape = "\\\\"; - break; - case '\?': - escape = "\\\?"; - break; - case '\a': - escape = "\\a"; - break; - case '\b': - escape = "\\b"; - break; - case '\f': - escape = "\\f"; - break; - case '\n': - escape = "\\n"; - break; - case '\r': - escape = "\\r"; - break; - case '\t': - escape = "\\t"; - break; - case '\v': - escape = "\\v"; - break; - default: - if (!isprint(s[i])) { - sprintf(octal, "\\%03o", (unsigned char)s[i]); - escape = octal; - } else { - escape = NULL; - } + switch (s[i]) { + case '\'': + escape = "\\\'"; + break; + case '\"': + escape = "\\\""; + break; + case '\\': + escape = "\\\\"; + break; + case '\?': + escape = "\\\?"; + break; + case '\a': + escape = "\\a"; + break; + case '\b': + escape = "\\b"; + break; + case '\f': + escape = "\\f"; + break; + case '\n': + escape = "\\n"; + break; + case '\r': + escape = "\\r"; + break; + case '\t': + escape = "\\t"; + break; + case '\v': + escape = "\\v"; + break; + default: + if (!isprint(s[i])) { + sprintf(octal, "\\%03o", (unsigned char) s[i]); + escape = octal; + } + else { + escape = NULL; + } - break; - } + break; + } - if (escape) { - size_t esc_size = strlen(escape); + if (escape) { + size_t esc_size = strlen(escape); - if (n + esc_size + 1 > size) - /*would overflow*/ - return NULL; + if (n + esc_size + 1 > size) + /*would overflow*/ + return NULL; - memmove(s + i + esc_size, s + i + 1, n - i); /*make room*/ - memcpy(s + i, escape, esc_size); /*insert*/ - n += esc_size - 1; /* adjust total string size */ - i += esc_size; /* adjust string position */ - } + memmove(s + i + esc_size, s + i + 1, n - i); /*make room*/ + memcpy(s + i, escape, esc_size); /*insert*/ + n += esc_size - 1; /* adjust total string size */ + i += esc_size; /* adjust string position */ + } } return s; } /*------------------------------------------------------------------------- - * Function: h5tools_is_zero + * Function: h5tools_str_is_zero * * Purpose: Determines if memory is initialized to all zero bytes. * @@ -1124,13 +1248,13 @@ h5tools_escape(char *s/*in,out*/, size_t size) *------------------------------------------------------------------------- */ static hbool_t -h5tools_is_zero(const void *_mem, size_t size) +h5tools_str_is_zero(const void *_mem, size_t size) { - const unsigned char *mem = (const unsigned char *)_mem; + const unsigned char *mem = (const unsigned char *) _mem; while (size-- > 0) - if (mem[size]) - return FALSE; + if (mem[size]) + return FALSE; return TRUE; } diff --git a/tools/lib/h5tools_str.h b/tools/lib/h5tools_str.h index 607d412..61b7905 100644 --- a/tools/lib/h5tools_str.h +++ b/tools/lib/h5tools_str.h @@ -35,7 +35,18 @@ extern char *h5tools_str_fmt(h5tools_str_t *str, size_t start, const char *fm extern char *h5tools_str_prefix(h5tools_str_t *str, const h5tool_format_t *info, hsize_t elmtno, unsigned ndims, hsize_t min_idx[], hsize_t max_idx[], h5tools_context_t *ctx); -extern int h5tools_str_dump_region(h5tools_str_t *, hid_t, const h5tool_format_t *); +/* + * new functions needed to display region reference data + */ +extern char *h5tools_str_region_prefix(h5tools_str_t *str, const h5tool_format_t *info, + hsize_t elmtno, hsize_t *ptdata, unsigned ndims, hsize_t min_idx[], + hsize_t max_idx[], h5tools_context_t *ctx); +extern void h5tools_str_dump_region_blocks(h5tools_str_t *, hid_t, const h5tool_format_t *, + h5tools_context_t *ctx); +extern void h5tools_str_dump_region_points(h5tools_str_t *, hid_t, const h5tool_format_t *, + h5tools_context_t *ctx); +extern void h5tools_str_sprint_region(h5tools_str_t *str, const h5tool_format_t *info, hid_t container, + void *vp, h5tools_context_t *ctx); extern char *h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t container, hid_t type, void *vp, h5tools_context_t *ctx); 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..5f5d640 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 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/lib/talign.c b/tools/misc/talign.c index 6c1bd81..24420bf 100644 --- a/tools/lib/talign.c +++ b/tools/misc/talign.c @@ -23,7 +23,6 @@ #include "hdf5.h" #include "H5private.h" -#include "h5tools.h" const char *fname = "talign.h5"; const char *setname = "align"; @@ -189,3 +188,35 @@ int main(void) return result; } +/*------------------------------------------------------------------------- + * Function: h5tools_get_native_type + * + * Purpose: Wrapper around H5Tget_native_type() to work around + * Problems with bitfields. + * + * Return: Success: datatype ID + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Tuesday, October 5, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +h5tools_get_native_type(hid_t type) +{ + hid_t p_type; + H5T_class_t type_class; + + type_class = H5Tget_class(type); + if(type_class==H5T_BITFIELD) + p_type=H5Tcopy(type); + else + p_type = H5Tget_native_type(type,H5T_DIR_DEFAULT); + + return(p_type); +} + diff --git a/tools/testfiles/tattrreg.ddl b/tools/testfiles/tattrreg.ddl new file mode 100644 index 0000000..5b64b18 --- /dev/null +++ b/tools/testfiles/tattrreg.ddl @@ -0,0 +1,38 @@ +############################# +Expected output for 'h5dump tattrreg.h5' +############################# +HDF5 "tattrreg.h5" { +GROUP "/" { + DATASET "Dataset1" { + DATATYPE H5T_STD_I32LE + DATASPACE NULL + DATA { + } + ATTRIBUTE "Attribute1" { + DATATYPE H5T_REFERENCE + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } + DATA { + (0): DATASET /Dataset2 {(2,2)-(7,7)}, DATASET /Dataset2 {(6,9), + (1): (2,2), (8,4), (1,6), (2,8), (3,2), (0,4), (9,0), (7,1), + (1): (3,3)}, NULL, NULL + } + } + } + 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 + } + } +} +} diff --git a/tools/testfiles/tattrreg.h5 b/tools/testfiles/tattrreg.h5 Binary files differnew file mode 100644 index 0000000..193b3e1 --- /dev/null +++ b/tools/testfiles/tattrreg.h5 diff --git a/tools/testfiles/tattrregR.ddl b/tools/testfiles/tattrregR.ddl new file mode 100644 index 0000000..6e399c0 --- /dev/null +++ b/tools/testfiles/tattrregR.ddl @@ -0,0 +1,66 @@ +############################# +Expected output for 'h5dump -R tattrreg.h5' +############################# +HDF5 "tattrreg.h5" { +GROUP "/" { + DATASET "Dataset1" { + DATATYPE H5T_STD_I32LE + DATASPACE NULL + DATA { + } + ATTRIBUTE "Attribute1" { + 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), + (1): (3,2), (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 + } + } +} +} 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 + } + } +} +} diff --git a/tools/testfiles/tdset-3s.ddl b/tools/testfiles/tdset-3s.ddl index d8deced..5963e90 100644 --- a/tools/testfiles/tdset-3s.ddl +++ b/tools/testfiles/tdset-3s.ddl @@ -8,27 +8,10 @@ DATASET "/dset1" { SUBSET { START ( 1, 1 ); STRIDE ( 1, 1 ); - COUNT ( 9, 19 ); + COUNT ( 1, 1 ); BLOCK ( 1, 1 ); DATA { - (1,1): 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - (1,19): 20, - (2,1): 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - (2,18): 20, 21, - (3,1): 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - (3,18): 21, 22, - (4,1): 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - (4,18): 22, 23, - (5,1): 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - (5,18): 23, 24, - (6,1): 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - (6,17): 23, 24, 25, - (7,1): 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - (7,17): 24, 25, 26, - (8,1): 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - (8,17): 25, 26, 27, - (9,1): 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - (9,17): 26, 27, 28 + (1,1): 2 } } } diff --git a/tools/testfiles/tnofilename.ddl b/tools/testfiles/tnofilename.ddl index 594b0c0..5b9299b 100644 --- a/tools/testfiles/tnofilename.ddl +++ b/tools/testfiles/tnofilename.ddl @@ -28,6 +28,7 @@ usage: h5dump [OPTIONS] file -m T, --format=T Set the floating point output format -q Q, --sort_by=Q Sort groups and attributes by index Q -z Z, --sort_order=Z Sort groups and attributes by order Z + -R, --region Print dataset pointed by region references -x, --xml Output in XML using Schema -u, --use-dtd Output in XML using DTD -D U, --xml-dtd=U Use the DTD or schema at U @@ -38,14 +39,16 @@ usage: h5dump [OPTIONS] file Subsetting is available by using the following options with a dataset attribute. Subsetting is done by selecting a hyperslab from the data. Thus, the options mirror those for performing a hyperslab selection. - The START and COUNT parameters are mandatory if you do subsetting. - The STRIDE and BLOCK parameters are optional and will default to 1 in - each dimension. + One of the START, COUNT, STRIDE, or BLOCK parameters are mandatory if you do subsetting. + The STRIDE, COUNT, and BLOCK parameters are optional and will default to 1 in + each dimension. START is optional and will default to 0 in each dimension. - -s L, --start=L Offset of start of subsetting selection - -S L, --stride=L Hyperslab stride - -c L, --count=L Number of blocks to include in selection - -k L, --block=L Size of block in hyperslab + -s START, --start=START Offset of start of subsetting selection + -S STRIDE, --stride=STRIDE Hyperslab stride + -c COUNT, --count=COUNT Number of blocks to include in selection + -k BLOCK, --block=BLOCK Size of block in hyperslab + START, COUNT, STRIDE, and BLOCK - is a list of integers the number of which are equal to the + number of dimensions in the dataspace being queried D - is the file driver to use in opening the file. Acceptable values are "sec2", "family", "split", "multi", "direct", and "stream". Without @@ -56,8 +59,6 @@ usage: h5dump [OPTIONS] file P - is the full path from the root group to the object. N - is an integer greater than 1. T - is a string containing the floating point format, e.g '%.3f' - L - is a list of integers the number of which are equal to the - number of dimensions in the dataspace being queried U - is a URI reference (as defined in [IETF RFC 2396], updated by [IETF RFC 2732]) B - is the form of binary output: NATIVE for a memory type, FILE for the |