From c7590ca38eb81dccfffa8e7132e0d1df0734cf44 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Fri, 4 Sep 2009 09:50:13 -0500 Subject: [svn-r17450] Bring h5dump single subsetting selection and region reference changes from NPOESS Tested: local linux smirom --- MANIFEST | 3 + tools/h5dump/h5dump.c | 203 ++- tools/h5dump/h5dumpgentest.c | 122 ++ tools/lib/h5tools.c | 3819 ++++++++++++++++++++++++++++----------- tools/lib/h5tools.h | 165 +- tools/lib/h5tools_str.c | 687 ++++--- tools/lib/h5tools_str.h | 13 +- tools/testfiles/tattrreg.ddl | 38 + tools/testfiles/tattrreg.h5 | Bin 0 -> 8288 bytes tools/testfiles/tattrregR.ddl | 66 + tools/testfiles/tdset-3s.ddl | 21 +- tools/testfiles/tnofilename.ddl | 19 +- 12 files changed, 3668 insertions(+), 1488 deletions(-) create mode 100644 tools/testfiles/tattrreg.ddl create mode 100644 tools/testfiles/tattrreg.h5 create mode 100644 tools/testfiles/tattrregR.ddl diff --git a/MANIFEST b/MANIFEST index 191bcab..4f8bb14 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1151,6 +1151,9 @@ ./tools/testfiles/tattr-2.ddl ./tools/testfiles/tattr-3.ddl ./tools/testfiles/tattr.h5 +./tools/testfiles/tattrreg.h5 +./tools/testfiles/tattrreg.ddl +./tools/testfiles/tattrregR.ddl ./tools/testfiles/tbitfields.h5 ./tools/testfiles/tchar.h5 ./tools/testfiles/tchar1.ddl diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c index beacdbb..c74c9f1 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,61 @@ 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; + + break; /** begin XML parameters **/ case 'x': diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c index c0d5801..77988f0 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 = H5Dcreate (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 = H5Acreate (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/lib/h5tools.c b/tools/lib/h5tools.c index 4955f95..05207de 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" @@ -39,11 +38,196 @@ 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); + +int 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); + +int 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_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_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 */ @@ -102,10 +286,12 @@ void h5tools_init(void) { if (!h5tools_init_g) { - if (!rawdatastream) - rawdatastream = stdout; + if (!rawdatastream) + rawdatastream = stdout; + + h5tools_dump_header_format = &h5tools_standardformat; - h5tools_init_g++; + h5tools_init_g++; } } @@ -131,9 +317,9 @@ 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 */ @@ -164,88 +350,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 +513,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 +537,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 +548,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'; } @@ -429,16 +624,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 +643,113 @@ 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; + } + + /* 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; + 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; + 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 +761,16 @@ 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; @@ -532,44 +818,40 @@ 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; - char *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; + int dimension_break = 1; + 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 - { + else { /* 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 @@ -579,552 +861,1018 @@ 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); - - if (i + 1 < nelmts || (flags & END_OF_DATA) == 0) - h5tools_str_append(&buffer, "%s", OPT(info->elmt_suf1, ",")); - - 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) { - /* - * ...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; - } - } - - /* - * 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 ((hsize_t)elmt_counter == ctx->size_last_dim) { - ctx->need_prefix = TRUE; - elmt_counter = 0; - } - } - - /* - * 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) + 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 { + H5Rget_name(region_id, H5R_DATASET_REGION, memref, (char*) ref_name, 1024); + + /* 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); + + /* Print block information */ + dimension_break = h5tools_dump_region_data_blocks( + region_space, region_id, stream, info, ctx, + &buffer, &curr_pos, ncols, i, elmt_counter); + /* Print point information */ + dimension_break = h5tools_dump_region_data_points( + region_space, region_id, stream, info, ctx, + &buffer, &curr_pos, ncols, i, elmt_counter); + /* Render the region element end */ + + } /* end else to if (h5tools_is_zero(... */ + H5Sclose(region_space); + } /* end if (region_space >= 0) */ + H5Dclose(region_id); + } /* if (region_id >= 0) */ 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); - /* - * 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; + if (i + 1 < nelmts || (flags & END_OF_DATA) == 0) + h5tools_str_append(&buffer, "%s", OPT(info->elmt_suf1, ",")); - /* - * 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. - */ - 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, " ")); - } + dimension_break = h5tools_render_element(stream, info, ctx, &buffer, + &curr_pos, ncols, i, elmt_counter); + /* Render the data element end*/ - /* Print the section */ - fputs(section, stream); - ctx->cur_column += strlen(section); } - - ctx->prev_multiline = multiline; - } + if(dimension_break==0) + elmt_counter = 0; + } /* end for (i = 0; i < nelmts... */ h5tools_str_close(&buffer); }/* else bin */ } - /*------------------------------------------------------------------------- * Audience: Public * Chapter: H5Tools Library - * Purpose: Dump out a subset of a dataset. + * Purpose: Render an element to output STREAM. * 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". - * + * 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: - * 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 - * + * 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 *------------------------------------------------------------------------- */ -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) +int +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) { - herr_t ret; /* the value to return */ - hid_t f_space; /* file data space */ - 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 */ - hid_t sm_space; /* stripmine data space */ - hsize_t count; /* hyperslab count */ - hsize_t outer_count; /* offset count */ - unsigned int row_dim; /* index of row_counter dimension */ - int current_outer_dim; /* dimension for start */ - hsize_t temp_start[H5S_MAX_RANK];/* temporary start inside offset count loop */ - hsize_t max_start[H5S_MAX_RANK]; /* maximum start inside offset count loop */ - hsize_t temp_count[H5S_MAX_RANK];/* temporary count inside offset count loop */ - 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 */ + int dimension_break = 1; + char *s; + char *section; /*a section of output */ + int secnum; /*section sequence number */ + int multiline; /*datum was multiline */ -#if defined (SANITY_CHECK) - hsize_t total_points = 1; /* to print */ - hsize_t printed_points = 0; /* printed */ -#endif + 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) { + /* + * ...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; + } + } - ret = FAIL; /* be pessimistic */ - f_space = H5Dget_space(dset); + /* + * 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 (f_space == FAIL) - goto done; + if (elmt_counter == ctx->size_last_dim) { + ctx->need_prefix = TRUE; + dimension_break = 0; + } + } /* - * 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. + * 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. */ - memset(&ctx, 0, sizeof(ctx)); - ctx.indent_level = indentlevel; - ctx.need_prefix = 1; - ctx.ndims = H5Sget_simple_extent_ndims(f_space); + 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 ((size_t)ctx.ndims > NELMTS(sm_size)) - goto done_close; + /* + * 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; - /* 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; + /* + * 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. + */ - H5Sget_simple_extent_dims(f_space, total_size, NULL); - ctx.size_last_dim = total_size[ctx.ndims - 1]; + /* + * 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; - if (ctx.ndims == 1) - row_dim = 0; - else - row_dim = ctx.ndims - 2; + /* + * Print the prefix or separate the beginning of this element + * from the previous element. + */ + if (ctx->need_prefix) { + if (secnum) + multiline++; - /* get the offset count */ - outer_count = 1; - 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 ]; + /* 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_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, " ")); } - 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 - + /* Print the section */ + fputs(section, stream); + ctx->cur_column += strlen(section); + } + ctx->prev_multiline = multiline; + return dimension_break; +} - /* 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; +/*------------------------------------------------------------------------- + * 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 + *------------------------------------------------------------------------- + */ +int +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) +{ + int dimension_break = 1; + char *s; + char *section; /*a section of output */ + int secnum; /*section sequence number */ + int multiline; /*datum was multiline */ - } - 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; + 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) { + /* + * ...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; } } + /* + * 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; - /* offset loop */ - for (n = 0; n < outer_count; n++) - { + if (elmt_counter == ctx->size_last_dim) { + ctx->need_prefix = TRUE; + dimension_break = 0; + } + } - hsize_t row_counter = 0; + /* + * 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; - /* number of read iterations in inner loop, read by rows, to match 2D display */ - if (ctx.ndims > 1) - { + /* + * 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; - /* 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 ]; + /* + * 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. + */ - /* 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; + /* + * 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; - /* advance 1 row_counter at a time */ - if (sset->block[ row_dim ] > 1 ) - temp_stride[ row_dim ] = 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); } - /* for the 1D case */ - else - { - count = 1; + 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); + } - size_row_block = sset->block[ row_dim ]; - - - /* display loop */ - for (; count > 0; - temp_start[ row_dim ] += temp_stride[ row_dim ], - count--) - { + ctx->prev_multiline = multiline; + return dimension_break; +} +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * 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 + *------------------------------------------------------------------------- + */ +int +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) { + int dimension_break = 1; + hssize_t nblocks; + hsize_t alloc_size; + hsize_t *ptdata; + hsize_t *dims1; + hsize_t *start; + hsize_t *count; + size_t numelem; + hsize_t region_total_size[H5S_MAX_RANK]; + h5tools_context_t region_ctx; /* print context */ + hsize_t region_elmtno; /* elemnt index */ + int region_dimension_break = 1; + unsigned int region_flags; /* buffer extent flags */ + hsize_t region_curr_pos; + int ndims; + int jndx; + int type_size; + hid_t mem_space; + hid_t dtype; + hid_t type_id; + void *region_buf; + herr_t status; + int i; + int blkndx; + hid_t sid1; - /* 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 ] - ) - { + /* + * This function fails if the region does not have blocks. + */ + H5E_BEGIN_TRY { + nblocks = H5Sget_select_hyper_nblocks(region_space); + } H5E_END_TRY; + + if (nblocks <= 0) + return dimension_break; + + /* Print block information */ + ndims = H5Sget_simple_extent_ndims(region_space); + + /* 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*/ + ptdata = (hsize_t*) malloc((size_t) alloc_size); + H5_CHECK_OVERFLOW(nblocks, hssize_t, hsize_t); + H5Sget_select_hyper_blocklist(region_space, (hsize_t) 0, (hsize_t) nblocks, ptdata); + + 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; + + dtype = H5Dget_type(region_id); + type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT); + + /* 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); - hsize_t increase_rows = sset->stride[ row_dim ] - - sset->block[ row_dim ]; + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the datatype element end */ - temp_start[ row_dim ] += increase_rows; + ctx->need_prefix = TRUE; - row_counter = 0; + /* Render the dataspace element begin */ + h5tools_str_reset(buffer); - } + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "%s ", h5tools_dump_header_format->dataspacebegin); - row_counter++; + h5tools_print_dataspace(buffer, info, ctx, 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); - /* 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); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the dataspace element end */ - if (sm_nelmts == 0) { - /* nothing to print */ - ret = SUCCEED; - goto done_close; - } + ctx->need_prefix = TRUE; - /* - * 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); + /* Render the databegin element begin */ + h5tools_str_reset(buffer); - 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); - } + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->databegin, + h5tools_dump_header_format->datablockbegin); - 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); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the databegin element end */ - H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, &zero, NULL, &sm_nelmts, NULL); + ctx->need_prefix = TRUE; - /* 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]; + /* Get the dataspace of the dataset */ + sid1 = H5Dget_space(region_id); - /* initialize the current stripmine position; this is necessary to print the array - indices */ - ctx.sm_pos = elmtno; + /* Allocate space for the dimension array */ + dims1 = (hsize_t *) malloc(sizeof(hsize_t) * ndims); - h5tools_dump_simple_data(stream, info, dset, &ctx, flags, sm_nelmts, - p_type, sm_buf); - free(sm_buf); + /* 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; + } - /* we need to jump to next line and update the index */ - ctx.need_prefix = 1; + /* Create dataspace for reading buffer */ + mem_space = H5Screate_simple(ndims, dims1, NULL); + + type_size = H5Tget_size(type_id); + region_buf = malloc(type_size * numelem); + + /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */ + /* 1 2 n 1 2 n */ + + start = (hsize_t *) malloc(sizeof(hsize_t) * ndims); + count = (hsize_t *) malloc(sizeof(hsize_t) * ndims); + region_curr_pos = 0; + for (blkndx = 0; blkndx < nblocks; blkndx++) { + /* initialize context structure for the region loop */ + memset(®ion_ctx, 0, sizeof(region_ctx)); + region_ctx.indent_level = ctx->indent_level; + region_ctx.ndims = ndims; + region_ctx.need_prefix = TRUE; + region_ctx.cur_column = ctx->cur_column; + region_ctx.cur_elmt = 0; + region_ctx.prev_multiline = ctx->prev_multiline; + region_ctx.prev_prefix_len = ctx->prev_prefix_len; + region_ctx.continuation = ctx->continuation; + region_ctx.default_indent_level = ctx->default_indent_level; + for (jndx = 0; jndx < ndims; jndx++) { + start[jndx] = ptdata[jndx + blkndx * ndims * 2]; + count[jndx] = dims1[jndx]; + } - ctx.continuation++; + status = H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL); + + status = H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf); + + region_ctx.indent_level++; + H5Sget_simple_extent_dims(mem_space, region_total_size, NULL); + + /* assume entire data space to be printed */ + for (jndx = 0; jndx < (size_t) region_ctx.ndims; jndx++) + region_ctx.p_min_idx[jndx] = start[jndx]; + init_acc_pos(®ion_ctx, region_total_size); + + /* print the data */ + region_flags = START_OF_DATA; + if (blkndx == nblocks - 1) + region_flags |= END_OF_DATA; + + for (jndx = 0; jndx < region_ctx.ndims; jndx++) + region_ctx.p_max_idx[jndx] = dims1[jndx]; + + region_curr_pos = 0; + region_ctx.sm_pos = blkndx*2*ndims; + region_ctx.size_last_dim = dims1[ndims-1]; + + h5tools_region_simple_prefix(stream, info, ®ion_ctx, region_curr_pos, ptdata, 0); + + region_elmtno = 0; + for (jndx = 0; jndx < numelem; jndx++, region_elmtno++, region_ctx.cur_elmt++) { + /* Render the region data element begin */ + h5tools_str_reset(buffer); + + h5tools_str_append(buffer, "%s", jndx ? OPTIONAL_LINE_BREAK "" : ""); + h5tools_str_sprint(buffer, info, region_id, type_id, + ((char*)region_buf + jndx * type_size), ®ion_ctx); + + if (jndx + 1 < numelem || (region_flags & END_OF_DATA) == 0) + h5tools_str_append(buffer, "%s", OPT(info->elmt_suf1, ",")); + + region_dimension_break = h5tools_render_region_element(stream, info, ®ion_ctx, buffer, ®ion_curr_pos, + ncols, ptdata, jndx, region_elmtno); + /* Render the region data element end */ + + if(region_dimension_break==0) + region_elmtno = 0; + } /* end for (jndx = 0; jndx < numelem; jndx++, region_elmtno++, region_ctx.cur_elmt++) */ + + region_ctx.indent_level--; + } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */ + + free(start); + free(count); + free(region_buf); + free(ptdata); + free(dims1); + status = H5Tclose(dtype); + status = H5Sclose(mem_space); + status = H5Sclose(sid1); + + 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 */ + + return dimension_break; +} +/*------------------------------------------------------------------------- + * 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 + *------------------------------------------------------------------------- + */ +int +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) { + int dimension_break = 1; + hssize_t npoints; + hsize_t alloc_size; + hsize_t *ptdata; + hsize_t *dims1; + h5tools_context_t region_ctx; /* print context */ + hsize_t region_elmtno; /* elemnt index */ + int region_dimension_break = 1; + unsigned int region_flags; /* buffer extent flags */ + hsize_t region_curr_pos; + int ndims; + int jndx; + int type_size; + hid_t mem_space; + hid_t dtype; + hid_t type_id; + void *region_buf; + herr_t status; -#if defined (SANITY_CHECK) - printed_points += sm_nelmts; -#endif + /* + * This function fails if the region does not have blocks. + */ + H5E_BEGIN_TRY { + npoints = H5Sget_select_elem_npoints(region_space); + } H5E_END_TRY; + + if (npoints > 0) { + int indx; + /* Render the region { element begin */ + h5tools_str_reset(buffer); - } /* count */ + 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 */ - if (ctx.ndims > 2) - { - /* dimension for start */ - current_outer_dim = (ctx.ndims - 2) -1; + /* Render the region datatype info and indices element begin */ + h5tools_str_reset(buffer); - /* 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 ]; - } + ctx->indent_level++; + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "REGION_TYPE POINT "); + /* Allocate space for the dimension array */ + ndims = H5Sget_simple_extent_ndims(region_space); + alloc_size = npoints * ndims * sizeof(ptdata[0]); + assert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ + ptdata = malloc((size_t) alloc_size); + H5_CHECK_OVERFLOW(npoints, hssize_t, hsize_t); + H5Sget_select_elem_pointlist(region_space, (hsize_t) 0, (hsize_t) npoints, ptdata); - /* increment start dimension */ - 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 ]; + for (indx = 0; indx < npoints; indx++) { + int loop_indx; - /* consider block */ - if ( sset->block[ current_outer_dim ] > 1 ) - temp_start[ current_outer_dim ]++; + h5tools_str_append(buffer, info->dset_ptformat_pre, + indx ? "," OPTIONAL_LINE_BREAK " " : "", (unsigned long) indx); - current_outer_dim--; - reset_dim = 1; - } - } - while (current_outer_dim >= 0 && reset_dim); + for (loop_indx = 0; loop_indx < ndims; loop_indx++) + h5tools_str_append(buffer, "%s%lu", loop_indx ? "," : "(", + (unsigned long) (ptdata[indx * ndims + loop_indx])); - } /* ctx.ndims > 1 */ + h5tools_str_append(buffer, ")"); + } /* end for (indx = 0; indx < npoints; indx++) */ - } /* outer_count */ + 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 */ -#if defined (SANITY_CHECK) - assert( printed_points == total_points ); -#endif + ctx->need_prefix = TRUE; + dtype = H5Dget_type(region_id); + type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT); - /* Terminate the output */ - if (ctx.cur_column) { - fputs(OPT(info->line_suf, ""), stream); - putc('\n', stream); - fputs(OPT(info->line_sep, ""), stream); - } + /* 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); - ret = SUCCEED; + h5tools_print_datatype(buffer, info, ctx, dtype); -done_close: - H5Sclose(f_space); -done: - return ret; + 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, info, ctx, 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; + + type_size = H5Tget_size(type_id); + + region_buf = malloc(type_size * npoints); + + /* Allocate space for the dimension array */ + dims1 = (hsize_t *) malloc(sizeof(hsize_t) * ndims); + + dims1[0] = npoints; + mem_space = H5Screate_simple(1, dims1, NULL); + + status = H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf); + + region_elmtno = 0; + region_curr_pos = 0; + for (jndx = 0; jndx < npoints; jndx++, region_elmtno++) { + /* initialize context structure for the region loop */ + memset(®ion_ctx, 0, sizeof(region_ctx)); + region_ctx.indent_level = ctx->indent_level; + region_ctx.ndims = ndims; + region_ctx.need_prefix = TRUE; + region_ctx.cur_column = ctx->cur_column; + region_ctx.cur_elmt = 0; /* points are always 0 */ + region_ctx.prev_multiline = ctx->prev_multiline; + region_ctx.prev_prefix_len = ctx->prev_prefix_len; + region_ctx.continuation = ctx->continuation; + region_ctx.default_indent_level = ctx->default_indent_level; + + /* Render the point element begin */ + h5tools_str_reset(buffer); + + region_ctx.indent_level++; + + /* assume entire data space to be printed */ + for (indx = 0; indx < (size_t) region_ctx.ndims; indx++) + region_ctx.p_min_idx[indx] = 0; + H5Sget_simple_extent_dims(region_space, region_ctx.p_max_idx, NULL); + + if (region_ctx.ndims > 0) { + region_ctx.size_last_dim = (int) (region_ctx.p_max_idx[region_ctx.ndims - 1]); + } + else + region_ctx.size_last_dim = 0; + + if (region_ctx.ndims > 0) + init_acc_pos(®ion_ctx, region_ctx.p_max_idx); + + /* print the data */ + region_flags = START_OF_DATA; + if (jndx == npoints - 1) + region_flags |= END_OF_DATA; + + region_curr_pos = 0; /* points requires constant 0 */ + region_ctx.sm_pos = jndx * ndims; + + h5tools_region_simple_prefix(stream, info, ®ion_ctx, region_curr_pos, ptdata, 0); + + h5tools_str_sprint(buffer, info, region_id, type_id, + ((char*)region_buf + jndx * type_size), ®ion_ctx); + + if (jndx + 1 < npoints || (region_flags & END_OF_DATA) == 0) + h5tools_str_append(buffer, "%s", OPT(info->elmt_suf1, ",")); + + region_dimension_break = + h5tools_render_region_element(stream, info, ®ion_ctx, buffer, ®ion_curr_pos, + ncols, ptdata, 0, region_elmtno); + /* Render the point element end */ + + region_ctx.indent_level--; + if(region_dimension_break == 0) + region_elmtno = 0; + } /* end for (jndx = 0; jndx < npoints; jndx++, region_elmtno++) */ + + free(region_buf); + free(ptdata); + free(dims1); + status = H5Tclose(dtype); + status = H5Sclose(mem_space); + + 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 */ + } /* end if (npoints > 0) */ + return dimension_break; } - - /*------------------------------------------------------------------------- * Audience: Public * Chapter: H5Tools Library - * Purpose: Print some values from a dataset with a simple data space. + * Purpose: Dump out a subset of a dataset. * Description: - * This is a special case of h5tools_dump_dset(). This function only - * intended for dumping datasets -- it does strip mining and some other - * things which are unnecessary for smaller objects such as attributes - * (to print small objects like attributes simply read the attribute and - * call h5tools_dump_simple_mem()). + * + * 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, the function returns SUCCEED. Otherwise, the function - * returns FAIL. - * Programmer: - * Robb Matzke, Thursday, July 23, 1998 - * Modifications: + * 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 int -h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, - hid_t p_type, int indentlevel) +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) { - hid_t f_space; /* file data space */ - hsize_t elmtno; /* counter */ - size_t i; /* counter */ - int carry; /* counter carry value */ - hsize_t zero[8]; /* vector of zeros */ - unsigned int flags; /* buffer extent flags */ - hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset*/ - - /* Print info */ - h5tools_context_t ctx; /* print context */ - size_t p_type_nbytes; /* size of memory type */ - hsize_t p_nelmts; /* total selected elmts */ - - /* Stripmine info */ - 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 */ - 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 */ + herr_t ret; /* the value to return */ + hid_t f_space; /* file data space */ + 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 */ + hid_t sm_space; /* stripmine data space */ + hsize_t count; /* hyperslab count */ + hsize_t outer_count; /* offset count */ + unsigned int row_dim; /* index of row_counter dimension */ + int current_outer_dim; /* dimension for start */ + hsize_t temp_start[H5S_MAX_RANK];/* temporary start inside offset count loop */ + hsize_t max_start[H5S_MAX_RANK]; /* maximum start inside offset count loop */ + hsize_t temp_count[H5S_MAX_RANK];/* temporary count inside offset count loop */ + 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 */ - /* VL data special information */ - unsigned int vl_data = 0; /* contains VL datatypes */ +#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) - return FAIL; + goto done; /* - * Check that everything looks okay. The dimensionality must not be too + * 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. */ @@ -1133,28 +1881,317 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, ctx.need_prefix = 1; ctx.ndims = H5Sget_simple_extent_ndims(f_space); - if ((size_t)ctx.ndims > NELMTS(sm_size)) { - H5Sclose(f_space); - return FAIL; - } + if ((size_t) ctx.ndims > NELMTS(sm_size)) + goto done_close; - /* Assume entire data space to be printed */ + /* assume entire data space to be printed */ if (ctx.ndims > 0) - for (i = 0; i < (size_t)ctx.ndims; i++) + 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]; - /* calculate the number of elements we're going to print */ - p_nelmts = 1; - - if (ctx.ndims > 0) { - for (i = 0; i < ctx.ndims; i++) - p_nelmts *= total_size[i]; - ctx.size_last_dim = (total_size[ctx.ndims - 1]); - } /* end if */ + if (ctx.ndims == 1) + row_dim = 0; else - ctx.size_last_dim = 0; + 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++) { + /* consider block size */ + outer_count = outer_count * sset->count[i] * sset->block[i]; + + } + + if (ctx.ndims > 0) + init_acc_pos(&ctx, total_size); + + /* calculate total number of points to print */ +#if defined (SANITY_CHECK) + for (i = 0; i < (size_t) ctx.ndims; i++) { + total_points *= sset->count[i] * sset->block[i];; + } +#endif + + /* initialize temporary start, count and maximum start */ + for (i = 0; i < (size_t) ctx.ndims; i++) { + 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; + + } + } + + /* offset loop */ + for (n = 0; n < outer_count; n++) { + + hsize_t row_counter = 0; + + /* number of read iterations in inner loop, read by rows, to match 2D display */ + if (ctx.ndims > 1) { + + /* 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; + + /* advance 1 row_counter at a time */ + if (sset->block[row_dim] > 1) + temp_stride[row_dim] = 1; + + } + /* for the 1D case */ + 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) { + /* dimension for start */ + 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]; + } + + /* increment start dimension */ + 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]; + + /* consider block */ + 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); + + } /* ctx.ndims > 1 */ + + } /* outer_count */ + +#if defined (SANITY_CHECK) + assert(printed_points == total_points); +#endif + + /* Terminate the output */ + if (ctx.cur_column) { + fputs(OPT(info->line_suf, ""), stream); + putc('\n', stream); + fputs(OPT(info->line_sep, ""), stream); + } + + ret = SUCCEED; + +done_close: + H5Sclose(f_space); +done: + return ret; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Print some values from a dataset with a simple data space. + * Description: + * This is a special case of h5tools_dump_dset(). This function only + * intended for dumping datasets -- it does strip mining and some other + * things which are unnecessary for smaller objects such as attributes + * (to print small objects like attributes simply read the attribute and + * call h5tools_dump_simple_mem()). + * Return: + * On success, the function returns SUCCEED. Otherwise, the function + * returns FAIL. + *------------------------------------------------------------------------- + */ +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 */ + int carry; /* counter carry value */ + hsize_t zero[8]; /* vector of zeros */ + unsigned int flags; /* buffer extent flags */ + hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset*/ + + /* Print info */ + h5tools_context_t ctx; /* print context */ + size_t p_type_nbytes; /* size of memory type */ + hsize_t p_nelmts; /* total selected elmts */ + + /* Stripmine info */ + 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 */ + 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 */ + + /* VL data special information */ + unsigned int vl_data = 0; /* contains VL datatypes */ + + f_space = H5Dget_space(dset); + + if (f_space == FAIL) + return FAIL; + + /* + * 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.ndims = H5Sget_simple_extent_ndims(f_space); + + if ((size_t)ctx.ndims > NELMTS(sm_size)) { + H5Sclose(f_space); + 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++) + ctx.p_min_idx[i] = 0; + + H5Sget_simple_extent_dims(f_space, total_size, NULL); + + /* calculate the number of elements we're going to print */ + p_nelmts = 1; + + if (ctx.ndims > 0) { + for (i = 0; i < ctx.ndims; i++) + p_nelmts *= total_size[i]; + ctx.size_last_dim = (total_size[ctx.ndims - 1]); + } /* end if */ + else + ctx.size_last_dim = 0; if (p_nelmts == 0) { /* nothing to print */ @@ -1189,8 +2226,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); @@ -1205,11 +2242,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; @@ -1228,14 +2264,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 */ @@ -1243,239 +2278,905 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, ctx.p_min_idx[i - 1] = ctx.p_max_idx[i - 1]; hs_offset[i - 1] += hs_size[i - 1]; - if (hs_offset[i - 1] == total_size[i - 1]) - hs_offset[i - 1] = 0; - else - carry = 0; - } + if (hs_offset[i - 1] == total_size[i - 1]) + hs_offset[i - 1] = 0; + else + carry = 0; + } + + ctx.continuation++; + } + + /* Terminate the output */ + if (ctx.cur_column) { + fputs(OPT(info->line_suf, ""), stream); + putc('\n', stream); + fputs(OPT(info->line_sep, ""), stream); + } + + H5Sclose(sm_space); + H5Sclose(f_space); + + free(sm_buf); + + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: h5tools_dump_simple_mem + * + * Purpose: Print some values from memory with a simple data space. + * This is a special case of h5tools_dump_mem(). + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +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 */ + + /* + * 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.ndims = H5Sget_simple_extent_ndims(space); + + if ((size_t) ctx.ndims > NELMTS(ctx.p_min_idx)) + return FAIL; + + ctx.indent_level = indentlevel; + ctx.need_prefix = 1; + + /* Assume entire data space to be printed */ + for (i = 0; i < ctx.ndims; i++) + ctx.p_min_idx[i] = 0; + + H5Sget_simple_extent_dims(space, ctx.p_max_idx, NULL); + + for (i = 0, nelmts = 1; ctx.ndims != 0 && i < ctx.ndims; i++) + nelmts *= ctx.p_max_idx[i] - ctx.p_min_idx[i]; + + 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]); + } /* end if */ + else + ctx.size_last_dim = 0; + + 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); + + /* Terminate the output */ + if (ctx.cur_column) { + fputs(OPT(info->line_suf, ""), stream); + putc('\n', stream); + fputs(OPT(info->line_sep, ""), stream); + } + + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: h5tools_dump_dset + * + * Purpose: Print some values from a dataset DSET to the file STREAM + * after converting all types to P_TYPE (which should be a + * native type). If P_TYPE is a negative value then it will be + * computed from the dataset type using only native types. + * + * Note: This function is intended only for datasets since it does + * some things like strip mining which are unnecessary for + * smaller objects such as attributes. The easiest way to print + * small objects is to read the object into memory and call + * h5tools_dump_mem(). + * + * Return: Success: SUCCEED + * 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. + * + * Bill Wendling, 2001-02-27 + * 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) +{ + 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; + + /* Use default values */ + if (!stream) + stream = stdout; + + if (!info) { + memset(&info_dflt, 0, sizeof info_dflt); + info = &info_dflt; + } + + if (p_type < 0) { + f_type = H5Dget_type(dset); + + if (info->raw || bin_form == 1) + p_type = H5Tcopy(f_type); + else if (bin_form == 2) + p_type = h5tools_get_little_endian_type(f_type); + else if (bin_form == 3) + p_type = h5tools_get_big_endian_type(f_type); + else + p_type = h5tools_get_native_type(f_type); + + H5Tclose(f_type); + + if (p_type < 0) + goto done; + } + + /* Check the data space */ + f_space = H5Dget_space(dset); + + space_type = H5Sget_simple_extent_type(f_space); + + /* 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 */ + status = SUCCEED; + + /* Close the dataspace */ + H5Sclose(f_space); + +done: + if (p_type != _p_type) + H5Tclose(p_type); + + return status; +} + +/*------------------------------------------------------------------------- + * Function: h5tools_dump_mem + * + * Purpose: Displays the data contained in MEM. MEM must have the + * specified data TYPE and SPACE. Currently only simple data + * spaces are allowed and only the `all' selection. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +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) +{ + h5tool_format_t info_dflt; + + /* Use default values */ + if (!stream) + stream = stdout; + + if (!info) { + memset(&info_dflt, 0, sizeof(info_dflt)); + info = &info_dflt; + } + + /* Check the data space */ + if (H5Sis_simple(space) <= 0) + return -1; + + return h5tools_dump_simple_mem(stream, info, obj_id, type, space, mem, indentlevel); +} + +/*------------------------------------------------------------------------- + * Function: print_datatype + * + * Purpose: print the datatype. + * + * Return: void + * + * In/Out: h5tools_str_t *buffer + * h5tools_context_t *ctx + * + *------------------------------------------------------------------------- + */ +void +h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, + h5tools_context_t *ctx, hid_t type) +{ + char *mname; + hid_t mtype, str_type; + unsigned nmembers; + unsigned ndims; + unsigned i; + size_t size = 0; + hsize_t dims[H5TOOLS_DUMP_MAX_RANK]; + H5T_str_t str_pad; + H5T_cset_t cset; + H5T_order_t order; + hid_t super; + hid_t tmp_type; + htri_t is_vlstr = FALSE; + const char *order_s = NULL; /* byte order string */ + H5T_sign_t sign; /* sign scheme value */ + const char *sign_s = NULL; /* sign scheme string */ + + switch (H5Tget_class(type)) { + 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. */ + H5Tclose(str_type); + 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: H5Tclose(str_type); + H5Tclose(tmp_type); + + 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: + nmembers = H5Tget_nmembers(type); + h5tools_str_append(buffer, "H5T_COMPOUND %s\n", h5tools_dump_header_format->structblockbegin); + + for (i = 0; i < nmembers; i++) { + mname = H5Tget_member_name(type, i); + mtype = H5Tget_member_type(type, i); + + if (H5Tget_class(mtype) == H5T_COMPOUND) + ctx->indent_level++; + + h5tools_print_datatype(buffer, info, ctx, mtype); + + if (H5Tget_class(mtype) == H5T_COMPOUND) + ctx->indent_level--; + + h5tools_str_append(buffer, " \"%s\";\n", mname); + 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: + h5tools_str_append(buffer, "H5T_ENUM %s\n", h5tools_dump_header_format->enumblockbegin); + ctx->indent_level++; + super = H5Tget_super(type); + h5tools_print_datatype(buffer, info, ctx, super); + h5tools_str_append(buffer, ";\n"); + h5tools_print_enum(buffer, info, ctx, type); + ctx->indent_level--; + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->enumblockend); + break; + + case H5T_VLEN: + h5tools_str_append(buffer, "H5T_VLEN %s ", h5tools_dump_header_format->vlenblockbegin); + super = H5Tget_super(type); + h5tools_print_datatype(buffer, info, ctx, super); + H5Tclose(super); + + /* Print closing */ + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->vlenblockend); + break; + + case H5T_ARRAY: + /* Get array base type */ + super = H5Tget_super(type); + + /* Print lead-in */ + h5tools_str_append(buffer, "H5T_ARRAY { "); + + /* Get array information */ + ndims = H5Tget_array_ndims(type); + H5Tget_array_dims2(type, dims); - ctx.continuation++; - } + /* Print array dimensions */ + for (i = 0; i < ndims; i++) + h5tools_str_append(buffer, "[%d]", (int) dims[i]); - /* Terminate the output */ - if (ctx.cur_column) { - fputs(OPT(info->line_suf, ""), stream); - putc('\n', stream); - fputs(OPT(info->line_sep, ""), stream); - } + h5tools_str_append(buffer, " "); - H5Sclose(sm_space); - H5Sclose(f_space); + /* Print base type */ + h5tools_print_datatype(buffer, info, ctx, super); - free(sm_buf); + /* Close array base type */ + H5Tclose(super); - return SUCCEED; + /* Print closing */ + h5tools_str_append(buffer, " }"); + + break; + + default: + h5tools_str_append(buffer, "unknown datatype"); + break; + } } /*------------------------------------------------------------------------- - * Function: h5tools_dump_simple_mem - * - * Purpose: Print some values from memory with a simple data space. - * This is a special case of h5tools_dump_mem(). + * Function: print_dataspace * - * Return: Success: SUCCEED - * - * Failure: FAIL + * Purpose: print the dataspace. * - * Programmer: Robb Matzke - * Thursday, July 23, 1998 + * Return: void * - * Modifications: + * In/Out: h5tools_str_t *buffer + * h5tools_context_t *ctx * *------------------------------------------------------------------------- */ -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) +void +h5tools_print_dataspace(h5tools_str_t *buffer, const h5tool_format_t *info, + h5tools_context_t *ctx, hid_t space) { - int i; /*counters */ - hsize_t nelmts; /*total selected elmts */ - h5tools_context_t ctx; /*printing context */ + hsize_t size[H5TOOLS_DUMP_MAX_RANK]; + hsize_t maxsize[H5TOOLS_DUMP_MAX_RANK]; + int ndims = H5Sget_simple_extent_dims(space, size, maxsize); + H5S_class_t space_type = H5Sget_simple_extent_type(space); + int i; - /* - * 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.ndims = H5Sget_simple_extent_ndims(space); - - if ((size_t)ctx.ndims > NELMTS(ctx.p_min_idx)) - return FAIL; - ctx.indent_level = indentlevel; - ctx.need_prefix = 1; + switch(space_type) { + case H5S_SCALAR: + /* scalar dataspace */ + h5tools_str_append(buffer, "%s %s", h5tools_dump_header_format->dataspacedescriptionbegin, S_SCALAR); + break; - /* Assume entire data space to be printed */ - for (i = 0; i < ctx.ndims; i++) - ctx.p_min_idx[i] = 0; + 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]); - H5Sget_simple_extent_dims(space, ctx.p_max_idx, NULL); + for(i = 1; i < ndims; i++) + h5tools_str_append(buffer, ", %" H5_PRINTF_LL_WIDTH "u", size[i]); - for (i = 0, nelmts = 1; ctx.ndims != 0 && i < ctx.ndims; i++) - nelmts *= ctx.p_max_idx[i] - ctx.p_min_idx[i]; + h5tools_str_append(buffer, " %s / ", h5tools_dump_header_format->dataspacedimend); - 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]); - } /* end if */ - else - ctx.size_last_dim = 0; + 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]); - if(ctx.ndims>0) - init_acc_pos(&ctx,ctx.p_max_idx); + 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]); - /* Print it */ - h5tools_dump_simple_data(stream, info, obj_id, &ctx, - START_OF_DATA | END_OF_DATA, nelmts, type, mem); + h5tools_str_append(buffer, " %s }", h5tools_dump_header_format->dataspacedimend); + break; - /* Terminate the output */ - if (ctx.cur_column) { - fputs(OPT(info->line_suf, ""), stream); - putc('\n', stream); - fputs(OPT(info->line_sep, ""), stream); - } + case H5S_NULL: + /* null dataspace */ + h5tools_str_append(buffer, "%s %s", h5tools_dump_header_format->dataspacedescriptionbegin, S_NULL); + break; - return SUCCEED; + case H5S_NO_CLASS: + default: + h5tools_str_append(buffer, "%s unknown dataspace %s\n", BEGIN, END); + break; + } /* end switch */ } + /*------------------------------------------------------------------------- - * Function: h5tools_dump_dset - * - * Purpose: Print some values from a dataset DSET to the file STREAM - * after converting all types to P_TYPE (which should be a - * native type). If P_TYPE is a negative value then it will be - * computed from the dataset type using only native types. - * - * Note: This function is intended only for datasets since it does - * some things like strip mining which are unnecessary for - * smaller objects such as attributes. The easiest way to print - * small objects is to read the object into memory and call - * h5tools_dump_mem(). - * - * Return: Success: SUCCEED - * - * Failure: FAIL + * Function: print_enum * - * Programmer: Robb Matzke - * Thursday, July 23, 1998 + * Purpose: prints the enum data * - * Modifications: - * Robb Matzke, 1999-06-07 - * If info->raw is set then the memory datatype will be the same - * as the file datatype. + * Return: void * - * Bill Wendling, 2001-02-27 - * Renamed to ``h5tools_dump_dset'' and added the subsetting - * parameter. + * In/Out: h5tools_str_t *buffer + * h5tools_context_t *ctx * - *------------------------------------------------------------------------- - */ -int -h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hid_t _p_type, - struct subset_t *sset, int indentlevel) + *-----------------------------------------------------------------------*/ +void +h5tools_print_enum(h5tools_str_t *buffer, const h5tool_format_t *info, + h5tools_context_t *ctx, hid_t type) { - 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; + char **name = NULL; /*member names */ + unsigned char *value = NULL; /*value array */ + unsigned char *copy = NULL; /*a pointer to value array */ + unsigned nmembs; /*number of members */ + int nchars; /*number of output characters */ + hid_t super; /*enum base integer type */ + hid_t native = -1; /*native integer datatype */ + size_t dst_size; /*destination value type size */ + unsigned i; + + nmembs = H5Tget_nmembers(type); + assert(nmembs > 0); + super = H5Tget_super(type); - /* Use default values */ - if (!stream) - stream = stdout; + /* + * 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 (H5Tget_size(type) <= sizeof(long long)) { + dst_size = sizeof(long long); - if (!info) { - memset(&info_dflt, 0, sizeof info_dflt); - info = &info_dflt; + if (H5T_SGN_NONE == H5Tget_sign(type)) { + native = H5T_NATIVE_ULLONG; + } + else { + native = H5T_NATIVE_LLONG; + } + } + else { + dst_size = H5Tget_size(type); } - if (p_type < 0) { - f_type = H5Dget_type(dset); + /* Get the names and raw values of all members */ + name = calloc(nmembs, sizeof(char *)); + value = calloc(nmembs, MAX(H5Tget_size(type), dst_size)); - if (info->raw || bin_form == 1 ) - p_type = H5Tcopy(f_type); - else if (bin_form == 2 ) - p_type = h5tools_get_little_endian_type(f_type); - else if (bin_form == 3 ) - p_type = h5tools_get_big_endian_type(f_type); - else - p_type = h5tools_get_native_type(f_type); + for (i = 0; i < nmembs; i++) { + name[i] = H5Tget_member_name(type, i); + H5Tget_member_value(type, i, value + i * H5Tget_size(type)); + } - H5Tclose(f_type); + /* Convert values to native datatype */ + if (native > 0) + H5Tconvert(super, native, nmembs, value, NULL, H5P_DEFAULT); - if (p_type < 0) - goto done; - } + /* + * Sort members by increasing value + * ***not implemented yet*** + */ - /* Check the data space */ - f_space = H5Dget_space(dset); + /* 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), ""); - space_type = H5Sget_simple_extent_type(f_space); + if (native < 0) { + size_t j; - /* 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 */ - status = SUCCEED; + h5tools_str_append(buffer, "0x"); - /* Close the dataspace */ - H5Sclose(f_space); + 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))); + } -done: - if (p_type != _p_type) - H5Tclose(p_type); + h5tools_str_append(buffer, ";\n"); + } - return status; + /* Release resources */ + for (i = 0; i < nmembs; i++) + free(name[i]); + + free(name); + free(value); + H5Tclose(super); + + if (0 == nmembs) + h5tools_str_append(buffer, "\n"); } /*------------------------------------------------------------------------- - * Function: h5tools_dump_mem - * - * Purpose: Displays the data contained in MEM. MEM must have the - * specified data TYPE and SPACE. Currently only simple data - * spaces are allowed and only the `all' selection. - * - * Return: Success: SUCCEED - * - * Failure: FAIL + * Function: dump_datatype * - * Programmer: Robb Matzke - * Wednesday, January 20, 1999 - * - * Modifications: + * Purpose: Dump the datatype. Datatype can be HDF5 predefined + * atomic datatype or committed/transient datatype. * + * Return: void + * + * In/Out: h5tools_context_t *ctx *------------------------------------------------------------------------- */ -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) +void +h5tools_dump_datatype(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx, hid_t type) { - h5tool_format_t info_dflt; + 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.*/ - /* Use default values */ - if (!stream) - stream = stdout; + /* setup */ + HDmemset(&buffer, 0, sizeof(h5tools_str_t)); - if (!info) { - memset(&info_dflt, 0, sizeof(info_dflt)); - info = &info_dflt; + 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; + + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + /* Render the element */ + h5tools_str_reset(&buffer); + + 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"); - /* Check the data space */ - if (H5Sis_simple(space) <= 0) - return -1; + curr_pos = h5tools_render_element(stream, info, ctx, &buffer, curr_pos, + ncols, &elmt_counter, 0); - return h5tools_dump_simple_mem(stream, info, obj_id, type, space, mem, - indentlevel); + ctx->need_prefix = TRUE; + ctx->indent_level--; } /*------------------------------------------------------------------------- @@ -1484,29 +3185,23 @@ h5tools_dump_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, hid_t * Purpose: initialize accumulator and matrix position * * Return: void - * - * Programmer: pvn - * - * Modifications: - * *------------------------------------------------------------------------- */ -void init_acc_pos(h5tools_context_t *ctx, hsize_t *dims) +void +init_acc_pos(h5tools_context_t *ctx, hsize_t *dims) { - int i; + int i; - assert(ctx->ndims); + 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; + 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 * @@ -1514,35 +3209,26 @@ 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; -} + 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; +} /*------------------------------------------------------------------------- * Function: render_bin_output @@ -1551,395 +3237,368 @@ 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; + 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); + size = H5Tget_size(tid); - 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)) + return FAIL; #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)) + return FAIL; #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)) + return FAIL; #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= 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) + 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) { #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)) + return FAIL; #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)) + return FAIL; #endif - } /*i*/ - }/*else 1 */ - } + } /*i*/ + }/*else 1 */ + } + + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * 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..bc29009 100644 --- a/tools/lib/h5tools.h +++ b/tools/lib/h5tools.h @@ -50,6 +50,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 +514,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 +553,19 @@ 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); +void h5tools_print_dataspace(h5tools_str_t *buffer/*in,out*/, + const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, + hid_t space); +void h5tools_print_datatype(h5tools_str_t *buffer/*in,out*/, + const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, + hid_t type); +void h5tools_print_enum(h5tools_str_t *buffer/*in,out*/, + const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, + hid_t type); #endif /* H5TOOLS_H__ */ diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 08ec5d7..200fa9e 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,128 @@ 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; + h5tools_str_append(str, "{"); + 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); - } + + h5tools_str_append(str, "}"); + } /* 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; + h5tools_str_append(str, "{"); + 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; + h5tools_str_append(str, "}"); + } /* end if (npoints > 0) */ } /*------------------------------------------------------------------------- @@ -454,11 +531,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 +541,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 +664,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 +672,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; ifmt_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 +894,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 +918,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 +961,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 +1007,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 +1047,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 +1059,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 +1085,62 @@ 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]; + + 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_dump_region_blocks(str, region, info, ctx); + h5tools_str_dump_region_points(str, region, info, ctx); + + H5Sclose(region); + } /* end if (region >= 0) */ + H5Dclose(obj); + } /* end if (obj >= 0) */ +} + /*------------------------------------------------------------------------- * Function: h5tools_escape * @@ -1047,70 +1169,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 +1247,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/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 new file mode 100644 index 0000000..193b3e1 Binary files /dev/null and b/tools/testfiles/tattrreg.h5 differ 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/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 -- cgit v0.12