diff options
author | Allen Byrne <byrn@hdfgroup.org> | 2009-09-17 20:37:09 (GMT) |
---|---|---|
committer | Allen Byrne <byrn@hdfgroup.org> | 2009-09-17 20:37:09 (GMT) |
commit | c44c9feb358d5a843f3e92769780ef6e914b0b6f (patch) | |
tree | 0314a9747cc8abb5baf0463be91989b8febd08c8 /tools/lib/h5tools.c | |
parent | f4d69b78e505fa873f5fb29b903f5f7bcd07350b (diff) | |
download | hdf5-c44c9feb358d5a843f3e92769780ef6e914b0b6f.zip hdf5-c44c9feb358d5a843f3e92769780ef6e914b0b6f.tar.gz hdf5-c44c9feb358d5a843f3e92769780ef6e914b0b6f.tar.bz2 |
[svn-r17493] Bring changes from trunk to tools lib, h5dump and error handling.
Tested: h5committest, local linux
Diffstat (limited to 'tools/lib/h5tools.c')
-rw-r--r-- | tools/lib/h5tools.c | 3677 |
1 files changed, 2808 insertions, 869 deletions
diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index c238063..8380deb 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -26,7 +26,6 @@ #include "h5tools.h" #include "h5tools_ref.h" -#include "h5tools_str.h" #include "h5tools_utils.h" #include "H5private.h" @@ -35,15 +34,213 @@ #define ALIGN(A,Z) ((((A) + (Z) - 1) / (Z)) * (Z)) /* global variables */ +hid_t H5tools_ERR_CLS_g = -1; +hid_t H5E_tools_g = -1; +hid_t H5E_tools_min_id_g = -1; int compound_data; FILE *rawdatastream; /* should initialize to stdout but gcc moans about it */ int bin_output; /* binary output */ int bin_form; /* binary form */ +int region_output; /* region output */ + +static h5tool_format_t h5tools_dataformat = { +0, /*raw */ + +"", /*fmt_raw */ +"%d", /*fmt_int */ +"%u", /*fmt_uint */ +"%d", /*fmt_schar */ +"%u", /*fmt_uchar */ +"%d", /*fmt_short */ +"%u", /*fmt_ushort */ +"%ld", /*fmt_long */ +"%lu", /*fmt_ulong */ +NULL, /*fmt_llong */ +NULL, /*fmt_ullong */ +"%g", /*fmt_double */ +"%g", /*fmt_float */ + +0, /*ascii */ +0, /*str_locale */ +0, /*str_repeat */ + +"[ ", /*arr_pre */ +",", /*arr_sep */ +" ]", /*arr_suf */ +1, /*arr_linebreak */ + +"", /*cmpd_name */ +",\n", /*cmpd_sep */ +"{\n", /*cmpd_pre */ +"}", /*cmpd_suf */ +"\n", /*cmpd_end */ + +", ", /*vlen_sep */ +"(", /*vlen_pre */ +")", /*vlen_suf */ +"", /*vlen_end */ + +"%s", /*elmt_fmt */ +",", /*elmt_suf1 */ +" ", /*elmt_suf2 */ + +"", /*idx_n_fmt */ +"", /*idx_sep */ +"", /*idx_fmt */ + +80, /*line_ncols *//*standard default columns */ +0, /*line_per_line */ +"", /*line_pre */ +"%s", /*line_1st */ +"%s", /*line_cont */ +"", /*line_suf */ +"", /*line_sep */ +1, /*line_multi_new */ +" ", /*line_indent */ + +1, /*skip_first */ + +1, /*obj_hidefileno */ +" "H5_PRINTF_HADDR_FMT, /*obj_format */ + +1, /*dset_hidefileno */ +"DATASET %s ", /*dset_format */ +"%s", /*dset_blockformat_pre */ +"%s", /*dset_ptformat_pre */ +"%s", /*dset_ptformat */ +1, /*array indices */ +1 /*escape non printable characters */ +}; + +static const h5tools_dump_header_t h5tools_standardformat = { +"standardformat", /*name */ +"HDF5", /*fileebgin */ +"", /*fileend */ +SUPER_BLOCK, /*bootblockbegin */ +"", /*bootblockend */ +H5_TOOLS_GROUP, /*groupbegin */ +"", /*groupend */ +H5_TOOLS_DATASET, /*datasetbegin */ +"", /*datasetend */ +ATTRIBUTE, /*attributebegin */ +"", /*attributeend */ +H5_TOOLS_DATATYPE, /*datatypebegin */ +"", /*datatypeend */ +DATASPACE, /*dataspacebegin */ +"", /*dataspaceend */ +DATA, /*databegin */ +"", /*dataend */ +SOFTLINK, /*softlinkbegin */ +"", /*softlinkend */ +EXTLINK, /*extlinkbegin */ +"", /*extlinkend */ +UDLINK, /*udlinkbegin */ +"", /*udlinkend */ +SUBSET, /*subsettingbegin */ +"", /*subsettingend */ +START, /*startbegin */ +"", /*startend */ +STRIDE, /*stridebegin */ +"", /*strideend */ +COUNT, /*countbegin */ +"", /*countend */ +BLOCK, /*blockbegin */ +"", /*blockend */ + +"{", /*fileblockbegin */ +"}", /*fileblockend */ +"{", /*bootblockblockbegin */ +"}", /*bootblockblockend */ +"{", /*groupblockbegin */ +"}", /*groupblockend */ +"{", /*datasetblockbegin */ +"}", /*datasetblockend */ +"{", /*attributeblockbegin */ +"}", /*attributeblockend */ +"", /*datatypeblockbegin */ +"", /*datatypeblockend */ +"", /*dataspaceblockbegin */ +"", /*dataspaceblockend */ +"{", /*datablockbegin */ +"}", /*datablockend */ +"{", /*softlinkblockbegin */ +"}", /*softlinkblockend */ +"{", /*extlinkblockbegin */ +"}", /*extlinkblockend */ +"{", /*udlinkblockbegin */ +"}", /*udlinkblockend */ +"{", /*strblockbegin */ +"}", /*strblockend */ +"{", /*enumblockbegin */ +"}", /*enumblockend */ +"{", /*structblockbegin */ +"}", /*structblockend */ +"{", /*vlenblockbegin */ +"}", /*vlenblockend */ +"{", /*subsettingblockbegin */ +"}", /*subsettingblockend */ +"(", /*startblockbegin */ +");", /*startblockend */ +"(", /*strideblockbegin */ +");", /*strideblockend */ +"(", /*countblockbegin */ +");", /*countblockend */ +"(", /*blockblockbegin */ +");", /*blockblockend */ + +"", /*dataspacedescriptionbegin */ +"", /*dataspacedescriptionend */ +"(", /*dataspacedimbegin */ +")", /*dataspacedimend */ +}; +static const h5tools_dump_header_t * h5tools_dump_header_format; /* local prototypes */ static int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem); static int render_bin_output(FILE *stream, hid_t tid, void *_mem); +static hbool_t h5tools_is_zero(const void *_mem, size_t size); + +hbool_t h5tools_render_element(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols, hsize_t local_elmt_counter/*element counter*/, + hsize_t elmt_counter); + +hbool_t h5tools_render_region_element(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols, hsize_t *ptdata, + hsize_t local_elmt_counter/*element counter*/, + hsize_t elmt_counter); + +int h5tools_print_region_data_blocks(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, h5tools_context_t ctx, + h5tools_str_t *buffer/*string into which to render */, size_t ncols, + int ndims, hid_t type_id, hssize_t nblocks, hsize_t *ptdata); + +hbool_t h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols, hsize_t region_elmt_counter/*element counter*/, + hsize_t elmt_counter); + +int h5tools_print_region_data_points(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, h5tools_context_t ctx, + h5tools_str_t *buffer, size_t ncols, + int ndims, hid_t type_id, hssize_t npoints, hsize_t *ptdata); + +hbool_t h5tools_dump_region_data_blocks(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols, hsize_t region_elmt_counter/*element counter*/, + hsize_t elmt_counter); /* module-scoped variables */ static int h5tools_init_g; /* if h5tools lib has been initialized */ @@ -101,11 +298,20 @@ enum { void h5tools_init(void) { + char lib_str[256]; + if (!h5tools_init_g) { - if (!rawdatastream) - rawdatastream = stdout; + /* register the error class */ + sprintf(lib_str, "%d.%d.%d",H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE); + + H5TOOLS_INIT_ERROR() + + if (!rawdatastream) + rawdatastream = stdout; + + h5tools_dump_header_format = &h5tools_standardformat; - h5tools_init_g++; + h5tools_init_g++; } } @@ -131,14 +337,16 @@ h5tools_close(void) if (h5tools_init_g) { if (rawdatastream && rawdatastream != stdout) { if (fclose(rawdatastream)) - perror("closing rawdatastream"); + perror("closing rawdatastream"); else - rawdatastream = NULL; + rawdatastream = NULL; } /* Clean up the reference path table, if it's been used */ term_ref_path_table(); + H5TOOLS_CLOSE_ERROR() + /* Shut down the library */ H5close(); @@ -164,88 +372,95 @@ h5tools_close(void) static hid_t h5tools_get_fapl(hid_t fapl, const char *driver, unsigned *drivernum) { - hid_t new_fapl; /* Copy of file access property list passed in, or new property list */ + hid_t new_fapl; /* Copy of file access property list passed in, or new property list */ /* Make a copy of the FAPL, for the file open call to use, eventually */ - if(fapl == H5P_DEFAULT) { - if((new_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + if (fapl == H5P_DEFAULT) { + if ((new_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) goto error; } /* end if */ else { - if((new_fapl = H5Pcopy(fapl)) < 0) + if ((new_fapl = H5Pcopy(fapl)) < 0) goto error; } /* end else */ /* Determine which driver the user wants to open the file with. Try * that driver. If it can't open it, then fail. */ - if(!strcmp(driver, drivernames[SEC2_IDX])) { + if (!strcmp(driver, drivernames[SEC2_IDX])) { /* SEC2 driver */ - if(H5Pset_fapl_sec2(new_fapl) < 0) + if (H5Pset_fapl_sec2(new_fapl) < 0) goto error; - if(drivernum) + if (drivernum) *drivernum = SEC2_IDX; - } else if(!strcmp(driver, drivernames[FAMILY_IDX])) { + } + else if (!strcmp(driver, drivernames[FAMILY_IDX])) { /* FAMILY Driver */ /* Set member size to be 0 to indicate the current first member size * is the member size. */ - if(H5Pset_fapl_family(new_fapl, (hsize_t)0, H5P_DEFAULT) < 0) + if (H5Pset_fapl_family(new_fapl, (hsize_t) 0, H5P_DEFAULT) < 0) goto error; - if(drivernum) + if (drivernum) *drivernum = FAMILY_IDX; - } else if(!strcmp(driver, drivernames[SPLIT_IDX])) { + } + else if (!strcmp(driver, drivernames[SPLIT_IDX])) { /* SPLIT Driver */ - if(H5Pset_fapl_split(new_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) + if (H5Pset_fapl_split(new_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) goto error; - if(drivernum) + if (drivernum) *drivernum = SPLIT_IDX; - } else if(!strcmp(driver, drivernames[MULTI_IDX])) { + } + else if (!strcmp(driver, drivernames[MULTI_IDX])) { /* MULTI Driver */ - if(H5Pset_fapl_multi(new_fapl, NULL, NULL, NULL, NULL, TRUE) < 0) - goto error; + if (H5Pset_fapl_multi(new_fapl, NULL, NULL, NULL, NULL, TRUE) < 0) + goto error; if(drivernum) - *drivernum = MULTI_IDX; + *drivernum = MULTI_IDX; #ifdef H5_HAVE_STREAM - } else if(!strcmp(driver, drivernames[STREAM_IDX])) { - /* STREAM Driver */ - if(H5Pset_fapl_stream(new_fapl, NULL) < 0) - goto error; + } + else if(!strcmp(driver, drivernames[STREAM_IDX])) { + /* STREAM Driver */ + if(H5Pset_fapl_stream(new_fapl, NULL) < 0) + goto error; - if(drivernum) - *drivernum = STREAM_IDX; + if(drivernum) + *drivernum = STREAM_IDX; #endif /* H5_HAVE_STREAM */ #ifdef H5_HAVE_PARALLEL - } else if(!strcmp(driver, drivernames[MPIO_IDX])) { - /* MPI-I/O Driver */ - /* check if MPI has been initialized. */ - if(!h5tools_mpi_init_g) - MPI_Initialized(&h5tools_mpi_init_g); - if(h5tools_mpi_init_g) { - if(H5Pset_fapl_mpio(new_fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0) - goto error; + } + else if(!strcmp(driver, drivernames[MPIO_IDX])) { + /* MPI-I/O Driver */ + /* check if MPI has been initialized. */ + if(!h5tools_mpi_init_g) + MPI_Initialized(&h5tools_mpi_init_g); + if(h5tools_mpi_init_g) { + if(H5Pset_fapl_mpio(new_fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0) + goto error; if(drivernum) *drivernum = MPIO_IDX; } /* end if */ - } else if (!strcmp(driver, drivernames[MPIPOSIX_IDX])) { + } + else if (!strcmp(driver, drivernames[MPIPOSIX_IDX])) { /* MPI-I/O Driver */ - /* check if MPI has been initialized. */ - if(!h5tools_mpi_init_g) - MPI_Initialized(&h5tools_mpi_init_g); + /* check if MPI has been initialized. */ + if(!h5tools_mpi_init_g) + MPI_Initialized(&h5tools_mpi_init_g); if(h5tools_mpi_init_g) { if(H5Pset_fapl_mpiposix(new_fapl, MPI_COMM_WORLD, TRUE) < 0) - goto error; + goto error; if(drivernum) *drivernum = MPIPOSIX_IDX; } /* end if */ #endif /* H5_HAVE_PARALLEL */ - } else { + } + else { goto error; } @@ -320,21 +535,22 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver, hid_t fid = FAIL; hid_t my_fapl = H5P_DEFAULT; - if(driver && *driver) { + if (driver && *driver) { /* Get the correct FAPL for the given driver */ - if((my_fapl = h5tools_get_fapl(fapl, driver, &drivernum)) < 0) + if ((my_fapl = h5tools_get_fapl(fapl, driver, &drivernum)) < 0) goto done; H5E_BEGIN_TRY { fid = H5Fopen(fname, flags, my_fapl); } H5E_END_TRY; - if(fid == FAIL) + if (fid == FAIL) goto done; - } else { + } + else { /* Try to open the file using each of the drivers */ - for(drivernum = 0; drivernum < NUM_DRIVERS; drivernum++) { + for (drivernum = 0; drivernum < NUM_DRIVERS; drivernum++) { /* Get the correct FAPL for the given driver */ if((my_fapl = h5tools_get_fapl(fapl, drivernames[drivernum], NULL)) < 0) goto done; @@ -343,7 +559,7 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver, fid = H5Fopen(fname, flags, my_fapl); } H5E_END_TRY; - if(fid != FAIL) + if (fid != FAIL) break; else { /* Close the FAPL */ @@ -354,11 +570,12 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver, } /* Save the driver name */ - if(drivername && drivername_size) { - if(fid != FAIL) { + if (drivername && drivername_size) { + if (fid != FAIL) { strncpy(drivername, drivernames[drivernum], drivername_size); drivername[drivername_size - 1] = '\0'; - } else { + } + else { /*no file opened*/ drivername[0] = '\0'; } @@ -367,6 +584,7 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver, done: if(my_fapl != H5P_DEFAULT) H5Pclose(my_fapl); + return fid; } @@ -429,16 +647,16 @@ h5tools_simple_prefix(FILE *stream, const h5tool_format_t *info, int i, indentlevel = 0; if (!ctx->need_prefix) - return; + return; memset(&prefix, 0, sizeof(h5tools_str_t)); memset(&str, 0, sizeof(h5tools_str_t)); /* Terminate previous line, if any */ if (ctx->cur_column) { - fputs(OPT(info->line_suf, ""), stream); - putc('\n', stream); - fputs(OPT(info->line_sep, ""), stream); + fputs(OPT(info->line_suf, ""), stream); + putc('\n', stream); + fputs(OPT(info->line_sep, ""), stream); } /* Calculate new prefix */ @@ -448,22 +666,23 @@ h5tools_simple_prefix(FILE *stream, const h5tool_format_t *info, /* Write new prefix to output */ if (ctx->indent_level >= 0) { indentlevel = ctx->indent_level; - } else { + } + else { /* * This is because sometimes we don't print out all the header * info for the data (like the tattr-2.ddl example). If that happens * the ctx->indent_level is negative so we need to skip the above and * just print out the default indent levels. */ - indentlevel = ctx->default_indent_level; + indentlevel = ctx->default_indent_level; } /* when printing array indices, print the indentation before the prefix the prefix is printed one indentation level before */ if (info->pindex) { - for (i = 0; i < indentlevel-1; i++){ - fputs(h5tools_str_fmt(&str, 0, info->line_indent), stream); - } + for (i = 0; i < indentlevel - 1; i++) { + fputs(h5tools_str_fmt(&str, 0, info->line_indent), stream); + } } if (elmtno == 0 && secnum == 0 && info->line_1st) @@ -475,16 +694,106 @@ h5tools_simple_prefix(FILE *stream, const h5tool_format_t *info, templength = h5tools_str_len(&prefix); - for (i = 0; i < indentlevel; i++){ + for (i = 0; i < indentlevel; i++) { /*we already made the indent for the array indices case */ - if (!info->pindex) { - fputs(h5tools_str_fmt(&prefix, 0, info->line_indent), stream); - templength += h5tools_str_len(&prefix); - } - else { - /*we cannot count the prefix for the array indices case */ - templength += h5tools_str_len(&str); - } + if (!info->pindex) { + fputs(h5tools_str_fmt(&prefix, 0, info->line_indent), stream); + templength += h5tools_str_len(&prefix); + } + else { + /*we cannot count the prefix for the array indices case */ + templength += h5tools_str_len(&str); + } + } + + ctx->cur_column = ctx->prev_prefix_len = templength; + ctx->cur_elmt = 0; + ctx->need_prefix = 0; + + /* Free string */ + h5tools_str_close(&prefix); + h5tools_str_close(&str); +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Emit a simple prefix to STREAM. + * Description: + * If /ctx->need_prefix/ is set then terminate the current line (if + * applicable), calculate the prefix string, and display it at the start + * of a line. Calls region specific function. + * Return: + * None + *------------------------------------------------------------------------- + */ +static void +h5tools_region_simple_prefix(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx, hsize_t elmtno, hsize_t *ptdata, int secnum) +{ + h5tools_str_t prefix; + h5tools_str_t str; /*temporary for indentation */ + size_t templength = 0; + int i, indentlevel = 0; + + if (!ctx->need_prefix) + return; + + memset(&prefix, 0, sizeof(h5tools_str_t)); + memset(&str, 0, sizeof(h5tools_str_t)); + + /* Terminate previous line, if any */ + if (ctx->cur_column) { + fputs(OPT(info->line_suf, ""), stream); + putc('\n', stream); + fputs(OPT(info->line_sep, ""), stream); + } + + /* Calculate new prefix */ + h5tools_str_region_prefix(&prefix, info, elmtno, ptdata, ctx->ndims, ctx->p_min_idx, + ctx->p_max_idx, ctx); + + /* Write new prefix to output */ + if (ctx->indent_level >= 0) { + indentlevel = ctx->indent_level; + } + else { + /* + * This is because sometimes we don't print out all the header + * info for the data (like the tattr-2.ddl example). If that happens + * the ctx->indent_level is negative so we need to skip the above and + * just print out the default indent levels. + */ + indentlevel = ctx->default_indent_level; + } + + /* when printing array indices, print the indentation before the prefix + the prefix is printed one indentation level before */ + if (info->pindex) { + for (i = 0; i < indentlevel - 1; i++) { + fputs(h5tools_str_fmt(&str, 0, info->line_indent), stream); + } + } + + if (elmtno == 0 && secnum == 0 && info->line_1st) + fputs(h5tools_str_fmt(&prefix, 0, info->line_1st), stream); + else if (secnum && info->line_cont) + fputs(h5tools_str_fmt(&prefix, 0, info->line_cont), stream); + else + fputs(h5tools_str_fmt(&prefix, 0, info->line_pre), stream); + + templength = h5tools_str_len(&prefix); + + for (i = 0; i < indentlevel; i++) { + /*we already made the indent for the array indices case */ + if (!info->pindex) { + fputs(h5tools_str_fmt(&prefix, 0, info->line_indent), stream); + templength += h5tools_str_len(&prefix); + } + else { + /*we cannot count the prefix for the array indices case */ + templength += h5tools_str_len(&str); + } } ctx->cur_column = ctx->prev_prefix_len = templength; @@ -532,41 +841,41 @@ h5tools_simple_prefix(FILE *stream, const h5tool_format_t *info, * new field sm_pos in h5tools_context_t, the current stripmine element position *------------------------------------------------------------------------- */ -void +void h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t container, h5tools_context_t *ctx/*in,out*/, unsigned flags, hsize_t nelmts, hid_t type, void *_mem) { - unsigned char *mem = (unsigned char*)_mem; - hsize_t i; /*element counter */ - char *s, *section; /*a section of output */ - int secnum; /*section sequence number */ - size_t size; /*size of each datum */ - size_t ncols = 80; /*available output width */ - h5tools_str_t buffer; /*string into which to render */ - int multiline; /*datum was multiline */ - hsize_t curr_pos; /* total data element position */ - int elmt_counter = 0;/*counts the # elements printed. - *I (ptl?) needed something that - *isn't going to get reset when a new - *line is formed. I'm going to use - *this var to count elements and - *break after we see a number equal - *to the ctx->size_last_dim. */ - - /* binary dump */ - if(bin_output) { + unsigned char *mem = (unsigned char*) _mem; + hsize_t i; /*element counter */ + size_t size; /*size of each datum */ + hid_t region_space; + hid_t region_id; + hbool_t dimension_break = TRUE; + H5S_sel_type region_type; + size_t ncols = 80; /*available output width */ + h5tools_str_t buffer; /*string into which to render */ + hsize_t curr_pos; /* total data element position */ + hsize_t elmt_counter = 0;/*counts the # elements printed. + *I (ptl?) needed something that + *isn't going to get reset when a new + *line is formed. I'm going to use + *this var to count elements and + *break after we see a number equal + *to the ctx->size_last_dim. */ + + /* binary dump */ + if (bin_output) { do_bin_output(stream, nelmts, type, _mem); } /* end if */ else { - /* Setup */ + /* setup */ HDmemset(&buffer, 0, sizeof(h5tools_str_t)); size = H5Tget_size(type); - if(info->line_ncols > 0) + if (info->line_ncols > 0) ncols = info->line_ncols; - /* pass to the prefix in h5tools_simple_prefix the total position * instead of the current stripmine position i; this is necessary * to print the array indices @@ -576,135 +885,1035 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); for (i = 0; i < nelmts; i++, ctx->cur_elmt++, elmt_counter++) { - /* Render the element */ - h5tools_str_reset(&buffer); - h5tools_str_sprint(&buffer, info, container, type, mem + i * size, ctx); + void* memref = mem + i * size; + if (region_output && H5Tequal(type, H5T_STD_REF_DSETREG)) { + char ref_name[1024]; + + /* region data */ + region_id = H5Rdereference(container, H5R_DATASET_REGION, memref); + if (region_id >= 0) { + region_space = H5Rget_region(container, H5R_DATASET_REGION, memref); + if (region_space >= 0) { + if (h5tools_is_zero(memref, H5Tget_size(type))) { + h5tools_str_append(&buffer, "NULL"); + } + else { + if(H5Rget_name(region_id, H5R_DATASET_REGION, memref, (char*) ref_name, 1024)<0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Rget_name failed"); + + /* Render the region element begin */ + h5tools_str_reset(&buffer); + + h5tools_str_append(&buffer, info->dset_format, ref_name); + + dimension_break = h5tools_render_element(stream, info, + ctx, &buffer, &curr_pos, ncols, i, elmt_counter); + + region_type = H5Sget_select_type(region_space); + if(region_type==H5S_SEL_POINTS) + /* Print point information */ + dimension_break = h5tools_dump_region_data_points( + region_space, region_id, stream, info, ctx, + &buffer, &curr_pos, ncols, i, elmt_counter); + else if(region_type==H5S_SEL_HYPERSLABS) + /* Print block information */ + dimension_break = h5tools_dump_region_data_blocks( + region_space, region_id, stream, info, ctx, + &buffer, &curr_pos, ncols, i, elmt_counter); + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "invalid region type"); + /* Render the region element end */ + + } /* end else to if (h5tools_is_zero(... */ + if(H5Sclose(region_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + } /* end if (region_space >= 0) */ + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Rget_region failed"); + if(H5Dclose(region_id) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Dclose failed"); + + } /* if (region_id >= 0) */ + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Rdereference failed"); - if (i + 1 < nelmts || (flags & END_OF_DATA) == 0) - h5tools_str_append(&buffer, "%s", OPT(info->elmt_suf1, ",")); + ctx->need_prefix = TRUE; + } /* end if (region_output... */ + else { + /* Render the data element begin*/ + h5tools_str_reset(&buffer); + h5tools_str_sprint(&buffer, info, container, type, memref, ctx); - s = h5tools_str_fmt(&buffer, 0, "%s"); + if (i + 1 < nelmts || (flags & END_OF_DATA) == 0) + h5tools_str_append(&buffer, "%s", OPT(info->elmt_suf1, ",")); + + dimension_break = h5tools_render_element(stream, info, ctx, &buffer, + &curr_pos, ncols, i, elmt_counter); + /* Render the data element end*/ - /* - * If the element would split on multiple lines if printed at our - * current location... - */ - if (info->line_multi_new == 1 && - (ctx->cur_column + h5tools_ncols(s) + - strlen(OPT(info->elmt_suf2, " ")) + - strlen(OPT(info->line_suf, ""))) > ncols) { - if (ctx->prev_multiline) { - /* - * ... and the previous element also occupied more than one - * line, then start this element at the beginning of a line. - */ - ctx->need_prefix = TRUE; - } else if ((ctx->prev_prefix_len + h5tools_ncols(s) + - strlen(OPT(info->elmt_suf2, " ")) + - strlen(OPT(info->line_suf, ""))) <= ncols) { - /* - * ...but *could* fit on one line otherwise, then we - * should end the current line and start this element on its - * own line. - */ - ctx->need_prefix = TRUE; - } } + if(FALSE==dimension_break) + elmt_counter = 0; + } /* end for (i = 0; i < nelmts... */ + + h5tools_str_close(&buffer); + }/* else bin */ +} +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Render an element to output STREAM. + * Description: + * Prints the string buffer to the output STREAM. The string is + * printed according to the format described in INFO. The CTX struct + * contains context information shared between calls to this function. + * + * Return: + * False if a dimension end is reached, otherwise true + * + * In/Out: + * h5tools_context_t *ctx + * h5tools_str_t *buffer + * hsize_t *curr_pos + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * hsize_t curr_pos is the total data element position + * size_t ncols + * hsize_t local_elmt_counter is the local element loop counter + * hsize_t elmt_count is the data element loop counter + *------------------------------------------------------------------------- + */ +hbool_t +h5tools_render_element(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx, h5tools_str_t *buffer, hsize_t *curr_pos, + size_t ncols, hsize_t local_elmt_counter, hsize_t elmt_counter) +{ + hbool_t dimension_break = TRUE; + char *s; + char *section; /*a section of output */ + int secnum; /*section sequence number */ + int multiline; /*datum was multiline */ + + s = h5tools_str_fmt(buffer, 0, "%s"); + + /* + * If the element would split on multiple lines if printed at our + * current location... + */ + if (info->line_multi_new == 1 && + (ctx->cur_column + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) { + if (ctx->prev_multiline) { + /* + * ... and the previous element also occupied more than one + * line, then start this element at the beginning of a line. + */ + ctx->need_prefix = TRUE; + } + else if ((ctx->prev_prefix_len + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) <= ncols) { /* - * We need to break after each row_counter of a dimension---> we should - * break at the end of the each last dimension well that is the - * way the dumper did it before + * ...but *could* fit on one line otherwise, then we + * should end the current line and start this element on its + * own line. */ - if (info->arr_linebreak && ctx->cur_elmt) { - if (ctx->size_last_dim && (ctx->cur_elmt % ctx->size_last_dim) == 0) - ctx->need_prefix = TRUE; + ctx->need_prefix = TRUE; + } + } - if ((hsize_t)elmt_counter == ctx->size_last_dim) { - ctx->need_prefix = TRUE; - elmt_counter = 0; - } - } + /* + * We need to break after each row of a dimension---> we should + * break at the end of the each last dimension well that is the + * way the dumper did it before + */ + if (info->arr_linebreak && ctx->cur_elmt) { + if (ctx->size_last_dim && (ctx->cur_elmt % ctx->size_last_dim) == 0) + ctx->need_prefix = TRUE; - /* - * If the previous element occupied multiple lines and this element - * is too long to fit on a line then start this element at the - * beginning of the line. + if (elmt_counter == ctx->size_last_dim) { + ctx->need_prefix = TRUE; + dimension_break = FALSE; + } + } + + /* + * If the previous element occupied multiple lines and this element + * is too long to fit on a line then start this element at the + * beginning of the line. + */ + if (info->line_multi_new == 1 && + ctx->prev_multiline && + (ctx->cur_column + + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) + ctx->need_prefix = TRUE; + + /* + * If too many elements have already been printed then we need to + * start a new line. + */ + if (info->line_per_line > 0 && ctx->cur_elmt >= info->line_per_line) + ctx->need_prefix = TRUE; + + /* + * Each OPTIONAL_LINE_BREAK embedded in the rendered string can cause + * the data to split across multiple lines. We display the sections + * one-at a time. + */ + multiline = 0; + for (secnum = 0, multiline = 0; + (section = strtok(secnum ? NULL : s, OPTIONAL_LINE_BREAK)); + secnum++) { + /* + * If the current section plus possible suffix and end-of-line + * information would cause the output to wrap then we need to + * start a new line. + */ + + /* + * Added the info->skip_first because the dumper does not want + * this check to happen for the first line + */ + if ((!info->skip_first || local_elmt_counter) && + (ctx->cur_column + + strlen(section) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) + ctx->need_prefix = 1; + + /* + * Print the prefix or separate the beginning of this element + * from the previous element. + */ + if (ctx->need_prefix) { + if (secnum) + multiline++; + + /* pass to the prefix in h5tools_simple_prefix the total + * position instead of the current stripmine position i; + * this is necessary to print the array indices */ - if (info->line_multi_new == 1 && ctx->prev_multiline && - (ctx->cur_column + h5tools_ncols(s) + - strlen(OPT(info->elmt_suf2, " ")) + - strlen(OPT(info->line_suf, ""))) > ncols) - ctx->need_prefix = TRUE; + *curr_pos = ctx->sm_pos + local_elmt_counter; + + h5tools_simple_prefix(stream, info, ctx, *curr_pos, secnum); + } + else if ((local_elmt_counter || ctx->continuation) && secnum == 0) { + fputs(OPT(info->elmt_suf2, " "), stream); + ctx->cur_column += strlen(OPT(info->elmt_suf2, " ")); + } + + /* Print the section */ + fputs(section, stream); + ctx->cur_column += strlen(section); + } + ctx->prev_multiline = multiline; + return dimension_break; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Render a region element to output STREAM. + * Description: + * Prints the string buffer to the output STREAM. The string is + * printed according to the format described in INFO. The CTX struct + * contains context information shared between calls to this function. + * + * Return: + * False if a dimension end is reached, otherwise true + * + * In/Out: + * h5tools_context_t *ctx + * h5tools_str_t *buffer + * hsize_t *curr_pos + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * hsize_t curr_pos is the total data element position + * size_t ncols + * hsize_t *ptdata + * hsize_t local_elmt_counter is the local element loop counter + * hsize_t elmt_count is the data element loop counter + *------------------------------------------------------------------------- + */ +hbool_t +h5tools_render_region_element(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx, h5tools_str_t *buffer, hsize_t *curr_pos, + size_t ncols, hsize_t *ptdata, hsize_t local_elmt_counter, hsize_t elmt_counter) +{ + hbool_t dimension_break = TRUE; + char *s; + char *section; /*a section of output */ + int secnum; /*section sequence number */ + int multiline; /*datum was multiline */ + + s = h5tools_str_fmt(buffer, 0, "%s"); + + /* + * If the element would split on multiple lines if printed at our + * current location... + */ + if (info->line_multi_new == 1 && + (ctx->cur_column + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) { + if (ctx->prev_multiline) { /* - * If too many elements have already been printed then we need to - * start a new line. + * ... and the previous element also occupied more than one + * line, then start this element at the beginning of a line. */ - if (info->line_per_line > 0 && ctx->cur_elmt >= info->line_per_line) - ctx->need_prefix = TRUE; - + ctx->need_prefix = TRUE; + } + else if ((ctx->prev_prefix_len + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) <= ncols) { /* - * Each OPTIONAL_LINE_BREAK embedded in the rendered string can cause - * the data to split across multiple lines. We display the sections - * one-at a time. + * ...but *could* fit on one line otherwise, then we + * should end the current line and start this element on its + * own line. */ - for (secnum = 0, multiline = 0; - (section = strtok(secnum ? NULL : s, OPTIONAL_LINE_BREAK)); - secnum++) { - /* - * If the current section plus possible suffix and end-of-line - * information would cause the output to wrap then we need to - * start a new line. - */ - - /* - * Added the info->skip_first because the dumper does not want - * this check to happen for the first line - */ - if ((!info->skip_first || i) && - (ctx->cur_column + strlen(section) + - strlen(OPT(info->elmt_suf2, " ")) + - strlen(OPT(info->line_suf, ""))) > ncols) - ctx->need_prefix = 1; - - /* - * Print the prefix or separate the beginning of this element - * from the previous element. - */ - if (ctx->need_prefix) { - if (secnum) - multiline++; - - /* pass to the prefix in h5tools_simple_prefix the total - * position instead of the current stripmine position i; - * this is necessary to print the array indices - */ - curr_pos = ctx->sm_pos + i; - - h5tools_simple_prefix(stream, info, ctx, curr_pos, secnum); - } else if ((i || ctx->continuation) && secnum == 0) { - fputs(OPT(info->elmt_suf2, " "), stream); - ctx->cur_column += strlen(OPT(info->elmt_suf2, " ")); - } + ctx->need_prefix = TRUE; + } + } - /* Print the section */ - fputs(section, stream); - ctx->cur_column += strlen(section); - } + /* + * We need to break after each row of a dimension---> we should + * break at the end of the each last dimension well that is the + * way the dumper did it before + */ + if (info->arr_linebreak && ctx->cur_elmt) { + if (ctx->size_last_dim && (ctx->cur_elmt % ctx->size_last_dim) == 0) + ctx->need_prefix = TRUE; - ctx->prev_multiline = multiline; + if (elmt_counter == ctx->size_last_dim) { + ctx->need_prefix = TRUE; + dimension_break = FALSE; } + } - h5tools_str_close(&buffer); - }/* else bin */ + /* + * If the previous element occupied multiple lines and this element + * is too long to fit on a line then start this element at the + * beginning of the line. + */ + if (info->line_multi_new == 1 && + ctx->prev_multiline && + (ctx->cur_column + + h5tools_ncols(s) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) + ctx->need_prefix = TRUE; + + /* + * If too many elements have already been printed then we need to + * start a new line. + */ + if (info->line_per_line > 0 && ctx->cur_elmt >= info->line_per_line) + ctx->need_prefix = TRUE; + + /* + * Each OPTIONAL_LINE_BREAK embedded in the rendered string can cause + * the data to split across multiple lines. We display the sections + * one-at a time. + */ + multiline = 0; + for (secnum = 0, multiline = 0; (section = strtok(secnum ? NULL : s, + OPTIONAL_LINE_BREAK)); secnum++) { + /* + * If the current section plus possible suffix and end-of-line + * information would cause the output to wrap then we need to + * start a new line. + */ + + /* + * Added the info->skip_first because the dumper does not want + * this check to happen for the first line + */ + if ((!info->skip_first || local_elmt_counter) && + (ctx->cur_column + + strlen(section) + + strlen(OPT(info->elmt_suf2, " ")) + + strlen(OPT(info->line_suf, ""))) > ncols) + ctx->need_prefix = 1; + + /* + * Print the prefix or separate the beginning of this element + * from the previous element. + */ + if (ctx->need_prefix) { + if (secnum) + multiline++; + + /* pass to the prefix in h5tools_simple_prefix the total + * position instead of the current stripmine position i; + * this is necessary to print the array indices + */ + *curr_pos = ctx->sm_pos + local_elmt_counter; + + h5tools_region_simple_prefix(stream, info, ctx, local_elmt_counter, ptdata, secnum); + } + else if ((local_elmt_counter || ctx->continuation) && secnum == 0) { + fputs(OPT(info->elmt_suf2, " "), stream); + ctx->cur_column += strlen(OPT(info->elmt_suf2, " ")); + } + + /* Print the section */ + fputs(section, stream); + ctx->cur_column += strlen(section); + } + + ctx->prev_multiline = multiline; + return dimension_break; } +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Print the data values from a dataset referenced by region blocks. + * + * Description: + * This is a special case subfunction to print the data in a region reference of type blocks. + * + * Return: + * The function returns FAIL if there was an error, otherwise SUCEED + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * size_t ncols + * int ndims is the number of dimensions of the region element + * hssize_t nblocks is the number of blocks in the region + *------------------------------------------------------------------------- + */ +int +h5tools_print_region_data_blocks(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, h5tools_context_t ctx, + h5tools_str_t *buffer/*string into which to render */, size_t ncols, + int ndims, hid_t type_id, hssize_t nblocks, hsize_t *ptdata) { + HERR_INIT(int, SUCCEED) + hbool_t dimension_break = TRUE; + hsize_t *dims1 = NULL; + hsize_t *start = NULL; + hsize_t *count = NULL; + size_t numelem; + hsize_t total_size[H5S_MAX_RANK]; + hsize_t elmtno; /* elemnt index */ + unsigned int region_flags; /* buffer extent flags */ + hsize_t curr_pos; + int jndx; + int type_size; + hid_t mem_space; + void *region_buf = NULL; + int blkndx; + hid_t sid1; + + /* Get the dataspace of the dataset */ + if((sid1 = H5Dget_space(region_id)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_space failed"); + + /* Allocate space for the dimension array */ + if((dims1 = (hsize_t *) malloc(sizeof(hsize_t) * ndims)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for dims"); + + /* find the dimensions of each data space from the block coordinates */ + numelem = 1; + for (jndx = 0; jndx < ndims; jndx++) { + dims1[jndx] = ptdata[jndx + ndims] - ptdata[jndx] + 1; + numelem = dims1[jndx] * numelem; + } + + /* Create dataspace for reading buffer */ + if((mem_space = H5Screate_simple(ndims, dims1, NULL)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Screate_simple failed"); + + if((type_size = H5Tget_size(type_id)) == 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); + + if((region_buf = malloc(type_size * numelem)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate region buffer"); + + /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */ + /* 1 2 n 1 2 n */ + if((start = (hsize_t *) malloc(sizeof(hsize_t) * ndims)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for start"); + + if((count = (hsize_t *) malloc(sizeof(hsize_t) * ndims)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for count"); + + curr_pos = 0; + for (blkndx = 0; blkndx < nblocks; blkndx++) { + ctx.ndims = ndims; + ctx.need_prefix = TRUE; + ctx.cur_elmt = 0; + for (jndx = 0; jndx < ndims; jndx++) { + start[jndx] = ptdata[jndx + blkndx * ndims * 2]; + count[jndx] = dims1[jndx]; + } + + if(H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sselect_hyperslab failed"); + + if(H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Dread failed"); + + ctx.indent_level++; + if(H5Sget_simple_extent_dims(mem_space, total_size, NULL) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); + + /* assume entire data space to be printed */ + for (jndx = 0; jndx < (size_t) ctx.ndims; jndx++) + ctx.p_min_idx[jndx] = start[jndx]; + init_acc_pos(&ctx, total_size); + + /* print the data */ + region_flags = START_OF_DATA; + if (blkndx == nblocks - 1) + region_flags |= END_OF_DATA; + + for (jndx = 0; jndx < ctx.ndims; jndx++) + ctx.p_max_idx[jndx] = dims1[jndx]; + + curr_pos = 0; + ctx.sm_pos = blkndx*2*ndims; + ctx.size_last_dim = dims1[ndims-1]; + + h5tools_region_simple_prefix(stream, info, &ctx, curr_pos, ptdata, 0); + + elmtno = 0; + for (jndx = 0; jndx < numelem; jndx++, elmtno++, ctx.cur_elmt++) { + /* Render the region data element begin */ + h5tools_str_reset(buffer); + + h5tools_str_append(buffer, "%s", jndx ? OPTIONAL_LINE_BREAK "" : ""); + h5tools_str_sprint(buffer, info, region_id, type_id, + ((char*)region_buf + jndx * type_size), &ctx); + + if (jndx + 1 < numelem || (region_flags & END_OF_DATA) == 0) + h5tools_str_append(buffer, "%s", OPT(info->elmt_suf1, ",")); + + dimension_break = h5tools_render_region_element(stream, info, &ctx, buffer, &curr_pos, + ncols, ptdata, jndx, elmtno); + /* Render the region data element end */ + + if(FALSE == dimension_break) + elmtno = 0; + } /* end for (jndx = 0; jndx < numelem; jndx++, region_elmtno++, ctx.cur_elmt++) */ + + ctx.indent_level--; + } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */ + + done: + free(start); + free(count); + free(region_buf); + free(dims1); + + if(H5Sclose(mem_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + if(H5Sclose(sid1) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + +CATCH + return ret_value; +} /*------------------------------------------------------------------------- * Audience: Public * Chapter: H5Tools Library - * Purpose: Dump out a subset of a dataset. + * Purpose: Print some values from a dataset referenced by region blocks. + * + * Description: + * This is a special case subfunction to dump a region reference using blocks. + * + * Return: + * The function returns False if the last dimension has been reached, otherwise True + * + * In/Out: + * h5tools_context_t *ctx + * hsize_t *curr_pos + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * hsize_t curr_pos is the total data element position + * size_t ncols + * hsize_t region_elmt_counter is the region element loop counter + * hsize_t elmt_count is the data element loop counter + *------------------------------------------------------------------------- + */ +hbool_t +h5tools_dump_region_data_blocks(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols, hsize_t region_elmt_counter/*element counter*/, + hsize_t elmt_counter) { + HERR_INIT(hbool_t, TRUE) + hbool_t dimension_break = TRUE; + hssize_t nblocks; + hsize_t alloc_size; + hsize_t *ptdata = NULL; + int ndims; + hid_t dtype; + hid_t type_id; + int i; + + if((nblocks = H5Sget_select_hyper_nblocks(region_space)) <= 0) + H5E_THROW(dimension_break, H5E_tools_min_id_g, "H5Sget_select_hyper_nblocks failed"); + + /* Print block information */ + if((ndims = H5Sget_simple_extent_ndims(region_space)) < 0) + H5E_THROW(dimension_break, H5E_tools_min_id_g, "H5Sget_simple_extent_ndims failed"); + + /* Render the region { element begin */ + h5tools_str_reset(buffer); + + h5tools_str_append(buffer, "{"); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the region { element end */ + + /* Render the region datatype info and indices element begin */ + h5tools_str_reset(buffer); + + ctx->indent_level++; + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "REGION_TYPE BLOCK "); + + alloc_size = nblocks * ndims * 2 * sizeof(ptdata[0]); + assert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ + if((ptdata = (hsize_t*) malloc((size_t) alloc_size)) == NULL) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "Could not allocate buffer for ptdata"); + + H5_CHECK_OVERFLOW(nblocks, hssize_t, hsize_t); + if(H5Sget_select_hyper_blocklist(region_space, (hsize_t) 0, (hsize_t) nblocks, ptdata) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Rget_select_hyper_blocklist failed"); + + for (i = 0; i < nblocks; i++) { + int j; + + h5tools_str_append(buffer, info->dset_blockformat_pre, + i ? "," OPTIONAL_LINE_BREAK " " : "", (unsigned long) i); + + /* Start coordinates and opposite corner */ + for (j = 0; j < ndims; j++) + h5tools_str_append(buffer, "%s%lu", j ? "," : "(", + (unsigned long) ptdata[i * 2 * ndims + j]); + + for (j = 0; j < ndims; j++) + h5tools_str_append(buffer, "%s%lu", j ? "," : ")-(", + (unsigned long) ptdata[i * 2 * ndims + j + ndims]); + + h5tools_str_append(buffer, ")"); + } /* end for (i = 0; i < nblocks; i++) */ + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the region datatype info and indices element end */ + + ctx->need_prefix = TRUE; + + if((dtype = H5Dget_type(region_id)) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Dget_type failed"); + if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Tget_native_type failed"); + + /* Render the datatype element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->datatypebegin, + h5tools_dump_header_format->datatypeblockbegin); + + h5tools_print_datatype(buffer, info, ctx, dtype); + + if (HDstrlen(h5tools_dump_header_format->datatypeblockend)) { + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->datatypeblockend); + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->datatypeend); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the datatype element end */ + + ctx->need_prefix = TRUE; + + /* Render the dataspace element begin */ + h5tools_str_reset(buffer); + + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "%s ", h5tools_dump_header_format->dataspacebegin); + + h5tools_print_dataspace(buffer, region_space); + + if (HDstrlen(h5tools_dump_header_format->dataspaceblockend)) { + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); + if (HDstrlen(h5tools_dump_header_format->dataspaceend)) + h5tools_str_append(buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->dataspaceend)) + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the dataspace element end */ + + ctx->need_prefix = TRUE; + + /* Render the databegin element begin */ + h5tools_str_reset(buffer); + + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->databegin, + h5tools_dump_header_format->datablockbegin); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the databegin element end */ + + ctx->need_prefix = TRUE; + + h5tools_print_region_data_blocks(region_space, region_id, + stream, info, *ctx, buffer, ncols, ndims, type_id, nblocks, ptdata); + + done: + free(ptdata); + + if(H5Tclose(dtype) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + + ctx->need_prefix = TRUE; + + /* Render the dataend element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->dataend, + h5tools_dump_header_format->datablockend); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, + ncols, region_elmt_counter, elmt_counter); + /* Render the dataend element end */ + + ctx->indent_level--; + ctx->need_prefix = TRUE; + + /* Render the region } element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "}"); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, + ncols, region_elmt_counter, elmt_counter); + /* Render the region } element end */ + + H5_LEAVE(dimension_break) + + CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Print the data values from a dataset referenced by region points. + * + * Description: + * This is a special case subfunction to print the data in a region reference of type points. + * + * Return: + * The function returns FAIL on error, otherwise SUCCEED + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * size_t ncols + * int ndims is the number of dimensions of the region element + * hssize_t npoints is the number of points in the region + *------------------------------------------------------------------------- + */ +int +h5tools_print_region_data_points(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, h5tools_context_t ctx, + h5tools_str_t *buffer, size_t ncols, + int ndims, hid_t type_id, hssize_t npoints, hsize_t *ptdata) { + HERR_INIT(int, SUCCEED) + hbool_t dimension_break = TRUE; + hsize_t alloc_size; + hsize_t *dims1 = NULL; + h5tools_context_t region_ctx; /* print context */ + hsize_t elmtno; /* elemnt index */ + unsigned int region_flags; /* buffer extent flags */ + hsize_t curr_pos; + int indx; + int jndx; + int type_size; + hid_t mem_space; + hid_t dtype; + void *region_buf = NULL; + + if((type_size = H5Tget_size(type_id)) == 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); + + if((region_buf = malloc(type_size * npoints)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for region"); + + /* Allocate space for the dimension array */ + if((dims1 = (hsize_t *) malloc(sizeof(hsize_t) * ndims)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for dims"); + + dims1[0] = npoints; + if((mem_space = H5Screate_simple(1, dims1, NULL)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Screate_simple failed"); + + if(H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dread failed"); + + elmtno = 0; + curr_pos = 0; + for (jndx = 0; jndx < npoints; jndx++, elmtno++) { + ctx.ndims = ndims; + ctx.need_prefix = TRUE; + ctx.cur_elmt = 0; /* points are always 0 */ + + /* Render the point element begin */ + h5tools_str_reset(buffer); + + ctx.indent_level++; + + /* assume entire data space to be printed */ + for (indx = 0; indx < (size_t) ctx.ndims; indx++) + ctx.p_min_idx[indx] = 0; + if(H5Sget_simple_extent_dims(region_space, ctx.p_max_idx, NULL) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); + + if (ctx.ndims > 0) { + ctx.size_last_dim = (int) (ctx.p_max_idx[ctx.ndims - 1]); + } + else + ctx.size_last_dim = 0; + + if (ctx.ndims > 0) + init_acc_pos(&ctx, ctx.p_max_idx); + + /* print the data */ + region_flags = START_OF_DATA; + if (jndx == npoints - 1) + region_flags |= END_OF_DATA; + + curr_pos = 0; /* points requires constant 0 */ + ctx.sm_pos = jndx * ndims; + + h5tools_region_simple_prefix(stream, info, &ctx, curr_pos, ptdata, 0); + + h5tools_str_sprint(buffer, info, region_id, type_id, + ((char*)region_buf + jndx * type_size), &ctx); + + if (jndx + 1 < npoints || (region_flags & END_OF_DATA) == 0) + h5tools_str_append(buffer, "%s", OPT(info->elmt_suf1, ",")); + + dimension_break = + h5tools_render_region_element(stream, info, &ctx, buffer, &curr_pos, + ncols, ptdata, 0, elmtno); + /* Render the point element end */ + + ctx.indent_level--; + if(FALSE == dimension_break) + elmtno = 0; + } /* end for (jndx = 0; jndx < npoints; jndx++, region_elmtno++) */ + + done: + free(region_buf); + free(dims1); + + if(H5Sclose(mem_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Print some values from a dataset referenced by region points. + * + * Description: + * This is a special case subfunction to dump a region reference using points. + * + * Return: + * The function returns False if the last dimension has been reached, otherwise True + * + * In/Out: + * h5tools_context_t *ctx + * hsize_t *curr_pos + * + * Parameters Description: + * h5tools_str_t *buffer is the string into which to render + * hsize_t curr_pos is the total data element position + * size_t ncols + * hsize_t region_elmt_counter is the region element loop counter + * hsize_t elmt_count is the data element loop counter + *------------------------------------------------------------------------- + */ +hbool_t +h5tools_dump_region_data_points(hid_t region_space, hid_t region_id, + FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx, + h5tools_str_t *buffer, hsize_t *curr_pos, size_t ncols, hsize_t region_elmt_counter, + hsize_t elmt_counter) { + HERR_INIT(hbool_t, TRUE) + hbool_t dimension_break = TRUE; + hssize_t npoints; + hsize_t alloc_size; + hsize_t *ptdata; + int ndims; + int indx; + hid_t dtype; + hid_t type_id; + + if((npoints = H5Sget_select_elem_npoints(region_space)) <= 0) + H5E_THROW(dimension_break, H5E_tools_min_id_g, "H5Sget_select_elem_npoints failed"); + + /* Allocate space for the dimension array */ + if((ndims = H5Sget_simple_extent_ndims(region_space)) < 0) + H5E_THROW(dimension_break, H5E_tools_min_id_g, "H5Sget_simple_extent_ndims failed"); + + /* Render the region { element begin */ + h5tools_str_reset(buffer); + + h5tools_str_append(buffer, "{"); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the region { element end */ + + /* Render the region datatype info and indices element begin */ + h5tools_str_reset(buffer); + + ctx->indent_level++; + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "REGION_TYPE POINT "); + + alloc_size = npoints * ndims * sizeof(ptdata[0]); + assert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ + if((ptdata = malloc((size_t) alloc_size)) == NULL) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "Could not allocate buffer for ptdata"); + + H5_CHECK_OVERFLOW(npoints, hssize_t, hsize_t); + if(H5Sget_select_elem_pointlist(region_space, (hsize_t) 0, (hsize_t) npoints, ptdata) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Sget_select_elem_pointlist failed"); + + for (indx = 0; indx < npoints; indx++) { + int loop_indx; + + h5tools_str_append(buffer, info->dset_ptformat_pre, + indx ? "," OPTIONAL_LINE_BREAK " " : "", (unsigned long) indx); + + for (loop_indx = 0; loop_indx < ndims; loop_indx++) + h5tools_str_append(buffer, "%s%lu", loop_indx ? "," : "(", + (unsigned long) (ptdata[indx * ndims + loop_indx])); + + h5tools_str_append(buffer, ")"); + } /* end for (indx = 0; indx < npoints; indx++) */ + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the region datatype info and indices element end */ + + ctx->need_prefix = TRUE; + + if((dtype = H5Dget_type(region_id)) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Dget_type failed"); + + if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) + HGOTO_ERROR(dimension_break, H5E_tools_min_id_g, "H5Tget_native_type failed"); + + /* Render the datatype element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->datatypebegin, + h5tools_dump_header_format->datatypeblockbegin); + + h5tools_print_datatype(buffer, info, ctx, dtype); + + if (HDstrlen(h5tools_dump_header_format->datatypeblockend)) { + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->datatypeblockend); + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->datatypeend); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the datatype element end */ + + ctx->need_prefix = TRUE; + + /* Render the dataspace element begin */ + h5tools_str_reset(buffer); + + ctx->need_prefix = TRUE; + h5tools_str_append(buffer, "%s ", h5tools_dump_header_format->dataspacebegin); + + h5tools_print_dataspace(buffer, region_space); + + if (HDstrlen(h5tools_dump_header_format->dataspaceblockend)) { + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); + if (HDstrlen(h5tools_dump_header_format->dataspaceend)) + h5tools_str_append(buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->dataspaceend)) + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->dataspaceblockend); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the dataspace element end */ + + ctx->need_prefix = TRUE; + + /* Render the databegin element begin */ + h5tools_str_reset(buffer); + + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->databegin, + h5tools_dump_header_format->datablockbegin); + + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, ncols, region_elmt_counter, elmt_counter); + /* Render the databegin element end */ + + ctx->need_prefix = TRUE; + + h5tools_print_region_data_points(region_space, region_id, + stream, info, *ctx, buffer, ncols, ndims, type_id, npoints, ptdata); + + done: + free(ptdata); + + if(H5Tclose(dtype) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + + ctx->need_prefix = TRUE; + + /* Render the dataend element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s %s ", + h5tools_dump_header_format->dataend, + h5tools_dump_header_format->datablockend); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, + ncols, region_elmt_counter, elmt_counter); + /* Render the dataend element end*/ + + ctx->indent_level--; + ctx->need_prefix = TRUE; + + /* Render the region } element begin */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "}"); + dimension_break = h5tools_render_element(stream, info, ctx, buffer, curr_pos, + ncols, region_elmt_counter, elmt_counter); + /* Render the region } element end */ + + H5_LEAVE(dimension_break) +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: print out the data for a subset of a dataset. * Description: * * Select a hyperslab from the dataset DSET using the parameters @@ -716,22 +1925,13 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai * Return: * On success, return SUCCEED. Otherwise, the function returns FAIL. * - * Original programmer: - * Bill Wendling, Wednesday, March 07, 2001 - * - * Rewritten with modified algorithm by: - * Pedro Vicente, Wednesday, January 16, 2008, contributions from Quincey Koziol - * * Algorithm * - * In a inner loop, the parameters from SSET are translated into temporary + * The parameters from SSET are translated into temporary * variables so that 1 row is printed at a time (getting the coordinate indices * at each row). * We define the stride, count and block to be 1 in the row dimension to achieve * this and advance until all points are printed. - * An outer loop for cases where dimensionality is greater than 2D is made. - * In each iteration, the 2D block is displayed in the inner loop. The remaining - * slower dimensions above the first 2 are incremented one at a time in the outer loop * * The element position is obtained from the matrix according to: * Given an index I(z,y,x) its position from the beginning of an array @@ -743,28 +1943,182 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai *------------------------------------------------------------------------- */ static herr_t -h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset, - hid_t p_type, struct subset_t *sset, - int indentlevel) +h5tools_print_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx, + hid_t dset, hid_t p_type, struct subset_t *sset, + hid_t f_space, hsize_t hyperslab_count, + hsize_t *temp_start,/* start inside offset count loop */ + hsize_t *temp_count,/* count inside offset count loop */ + hsize_t *temp_block,/* block size used in loop */ + hsize_t *temp_stride,/* stride size used in loop */ + hsize_t *total_size,/* total size of dataset */ + unsigned int row_dim/* index of row_counter dimension */) { - herr_t ret; /* the value to return */ - hid_t f_space; /* file data space */ + HERR_INIT(herr_t, SUCCEED) size_t i; /* counters */ size_t j; /* counters */ - hsize_t n; /* counters */ hsize_t zero = 0; /* vector of zeros */ unsigned int flags; /* buffer extent flags */ - hsize_t total_size[H5S_MAX_RANK];/* total size of dataset*/ hsize_t elmtno; /* elemnt index */ hsize_t low[H5S_MAX_RANK]; /* low bound of hyperslab */ hsize_t high[H5S_MAX_RANK]; /* higher bound of hyperslab */ - h5tools_context_t ctx; /* print context */ size_t p_type_nbytes; /* size of memory type */ hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */ hsize_t sm_nbytes; /* bytes per stripmine */ hsize_t sm_nelmts; /* elements per stripmine*/ - unsigned char *sm_buf = NULL; /* buffer for raw data */ + unsigned char *sm_buf = NULL; /* buffer for raw data */ hid_t sm_space; /* stripmine data space */ + hsize_t size_row_block; /* size for blocks along rows */ + hsize_t row_counter = 0; + + if ((size_t) ctx->ndims > NELMTS(sm_size)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "ndims and sm_size comparision failed"); + + if (ctx->ndims > 0) + init_acc_pos(ctx, total_size); + + size_row_block = sset->block[row_dim]; + + /* display loop */ + for (; hyperslab_count > 0; temp_start[row_dim] += temp_stride[row_dim], hyperslab_count--) { + /* jump rows if size of block exceeded + cases where block > 1 only and stride > block */ + if (size_row_block > 1 + && row_counter == size_row_block + && sset->stride[row_dim] > sset->block[row_dim]) { + + hsize_t increase_rows = sset->stride[row_dim] - sset->block[row_dim]; + temp_start[row_dim] += increase_rows; + row_counter = 0; + } + + row_counter++; + + /* calculate the potential number of elements we're going to print */ + if(H5Sselect_hyperslab(f_space, H5S_SELECT_SET, temp_start, temp_stride, temp_count, temp_block) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sselect_hyperslab failed"); + + if((sm_nelmts = H5Sget_select_npoints(f_space)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_select_npoints failed"); + + if (sm_nelmts > 0) { + /* + * determine the strip mine size and allocate a buffer. the strip mine is + * a hyperslab whose size is manageable. + */ + if((sm_nbytes = p_type_nbytes = H5Tget_size(p_type)) == 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); + + if (ctx->ndims > 0) + for (i = ctx->ndims; i > 0; --i) { + hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes; + if (size == 0) /* datum size > H5TOOLS_BUFSIZE */ + size = 1; + sm_size[i - 1] = MIN(total_size[i - 1], size); + sm_nbytes *= sm_size[i - 1]; + assert(sm_nbytes > 0); + } + + assert(sm_nbytes == (hsize_t) ((size_t) sm_nbytes)); /*check for overflow*/ + if((sm_buf = malloc((size_t) sm_nelmts * p_type_nbytes)) == NULL) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for strip-mine"); + + if((sm_space = H5Screate_simple(1, &sm_nelmts, NULL)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Screate_simple failed"); + + if(H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, &zero, NULL, &sm_nelmts, NULL) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sselect_hyperslab failed"); + + /* read the data */ + if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) < 0) { + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dread failed"); + } + + /* print the data */ + flags = START_OF_DATA; + + if (hyperslab_count == 1) + flags |= END_OF_DATA; + + for (i = 0; i < ctx->ndims; i++) + ctx->p_max_idx[i] = ctx->p_min_idx[i] + MIN(total_size[i], sm_size[i]); + + /* print array indices. get the lower bound of the hyperslab and calulate + the element position at the start of hyperslab */ + if(H5Sget_select_bounds(f_space, low, high) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_select_bounds failed"); + + elmtno = 0; + for (i = 0; i < (size_t) ctx->ndims - 1; i++) { + hsize_t offset = 1; /* accumulation of the previous dimensions */ + for (j = i + 1; j < (size_t) ctx->ndims; j++) + offset *= total_size[j]; + elmtno += low[i] * offset; + } + elmtno += low[ctx->ndims - 1]; + + /* initialize the current stripmine position; this is necessary to print the array + indices */ + ctx->sm_pos = elmtno; + + h5tools_dump_simple_data(stream, info, dset, ctx, flags, sm_nelmts, p_type, sm_buf); +done: + if(H5Sclose(sm_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + free(sm_buf); + } + else + H5E_THROW(SUCCEED, H5E_tools_min_id_g, "nothing to print"); + /* we need to jump to next line and update the index */ + ctx->need_prefix = 1; + + ctx->continuation++; + + } /* hyperslab_count loop */ + +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: print out the data for a subset of a dataset. + * Description: + * + * Select a hyperslab from the dataset DSET using the parameters + * specified in SSET. Dump this out to STREAM. + * + * Hyperslabs select "count" blocks of size "block", spaced "stride" elements + * from each other, starting at coordinate "start". + * + * Return: + * On success, return SUCCEED. Otherwise, the function returns FAIL. + * + * Algorithm + * + * The parameters from SSET are translated into temporary + * variables so that 1 row is printed at a time (getting the coordinate indices + * at each row). + * We define the stride, count and block to be 1 in the row dimension to achieve + * this and advance until all points are printed. + * + * The element position is obtained from the matrix according to: + * Given an index I(z,y,x) its position from the beginning of an array + * of sizes A(size_z, size_y,size_x) is given by + * Position of I(z,y,x) = index_z * size_y * size_x + * + index_y * size_x + * + index_x + * + *------------------------------------------------------------------------- + */ +static herr_t +h5tools_display_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx, + hid_t dset, hid_t p_type, struct subset_t *sset, + hid_t f_space, hsize_t *total_size) +{ + HERR_INIT(herr_t, SUCCEED) + size_t i; /* counters */ + hsize_t n; /* counters */ hsize_t count; /* hyperslab count */ hsize_t outer_count; /* offset count */ unsigned int row_dim; /* index of row_counter dimension */ @@ -775,279 +2129,173 @@ h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset hsize_t temp_block[H5S_MAX_RANK];/* temporary block size used in loop */ hsize_t temp_stride[H5S_MAX_RANK];/* temporary stride size used in loop */ int reset_dim; - hsize_t size_row_block; /* size for blocks along rows */ - -#if defined (SANITY_CHECK) - hsize_t total_points = 1; /* to print */ - hsize_t printed_points = 0; /* printed */ -#endif - - - ret = FAIL; /* be pessimistic */ - f_space = H5Dget_space(dset); - - if (f_space == FAIL) - goto done; - - /* - * check that everything looks okay. the dimensionality must not be too - * great and the dimensionality of the items selected for printing must - * match the dimensionality of the dataset. - */ - memset(&ctx, 0, sizeof(ctx)); - ctx.indent_level = indentlevel; - ctx.need_prefix = 1; - ctx.ndims = H5Sget_simple_extent_ndims(f_space); - - if ((size_t)ctx.ndims > NELMTS(sm_size)) - goto done_close; - - /* assume entire data space to be printed */ - if (ctx.ndims > 0) - for (i = 0; i < (size_t)ctx.ndims; i++) - ctx.p_min_idx[i] = 0; - H5Sget_simple_extent_dims(f_space, total_size, NULL); - ctx.size_last_dim = total_size[ctx.ndims - 1]; - - if (ctx.ndims == 1) + if (ctx->ndims == 1) row_dim = 0; else - row_dim = ctx.ndims - 2; + row_dim = ctx->ndims - 2; /* get the offset count */ outer_count = 1; - if (ctx.ndims > 2) - for (i = 0; i < (size_t)ctx.ndims - 2; i++) - { + if (ctx->ndims > 2) + for (i = 0; i < (size_t) ctx->ndims - 2; i++) { /* consider block size */ - outer_count = outer_count * sset->count[ i ] * sset->block[ i ]; + outer_count = outer_count * sset->count[i] * sset->block[i]; } - if(ctx.ndims>0) - init_acc_pos(&ctx,total_size); - - /* calculate total number of points to print */ -#if defined (SANITY_CHECK) - for (i = 0; i < (size_t)ctx.ndims; i++) - { - total_points *= sset->count[ i ] * sset->block[ i ];; - } -#endif - - - /* initialize temporary start, count and maximum start */ - for (i = 0; i < (size_t)ctx.ndims; i++) - { - temp_start[ i ] = sset->start[ i ]; - temp_count[ i ] = sset->count[ i ]; - temp_block[ i ] = sset->block[ i ]; - temp_stride[ i ] = sset->stride[ i ]; - max_start[ i ] = 0; - + for (i = 0; i < (size_t) ctx->ndims; i++) { + temp_start[i] = sset->start[i]; + temp_count[i] = sset->count[i]; + temp_block[i] = sset->block[i]; + temp_stride[i] = sset->stride[i]; + max_start[i] = 0; } - if (ctx.ndims > 2) - { - for (i = 0; i < (size_t)ctx.ndims - 2; i++) - { - max_start[ i ] = temp_start[ i ] + sset->count[ i ]; - temp_count[ i ] = 1; + + if (ctx->ndims > 2) { + for (i = 0; i < (size_t) ctx->ndims - 2; i++) { + max_start[i] = temp_start[i] + sset->count[i]; + temp_count[i] = 1; } } - /* offset loop */ - for (n = 0; n < outer_count; n++) - { - - hsize_t row_counter = 0; - + for (n = 0; n < outer_count; n++) { /* number of read iterations in inner loop, read by rows, to match 2D display */ - if (ctx.ndims > 1) - { + if (ctx->ndims > 1) { - /* count is the number of iterations to display all the rows, - the block size count times */ - count = sset->count[ row_dim ] * sset->block[ row_dim ]; + /* count is the number of iterations to display all the rows, + the block size count times */ + count = sset->count[row_dim] * sset->block[row_dim]; /* always 1 row_counter at a time, that is a block of size 1, 1 time */ - temp_count[ row_dim ] = 1; - temp_block[ row_dim ] = 1; + temp_count[row_dim] = 1; + temp_block[row_dim] = 1; /* advance 1 row_counter at a time */ - if (sset->block[ row_dim ] > 1 ) - temp_stride[ row_dim ] = 1; - + if (sset->block[row_dim] > 1) + temp_stride[row_dim] = 1; } /* for the 1D case */ - else - { + else { count = 1; } - - - size_row_block = sset->block[ row_dim ]; - - - /* display loop */ - for (; count > 0; - temp_start[ row_dim ] += temp_stride[ row_dim ], - count--) - { - - - /* jump rows if size of block exceeded - cases where block > 1 only and stride > block */ - if ( size_row_block > 1 && - row_counter == size_row_block && - sset->stride[ row_dim ] > sset->block[ row_dim ] - ) - { - - hsize_t increase_rows = sset->stride[ row_dim ] - - sset->block[ row_dim ]; - - temp_start[ row_dim ] += increase_rows; - - row_counter = 0; - - } - - row_counter++; - - - /* calculate the potential number of elements we're going to print */ - H5Sselect_hyperslab(f_space, H5S_SELECT_SET, - temp_start, - temp_stride, - temp_count, - temp_block); - sm_nelmts = H5Sget_select_npoints(f_space); - - if (sm_nelmts == 0) { - /* nothing to print */ - ret = SUCCEED; - goto done_close; - } - - /* - * determine the strip mine size and allocate a buffer. the strip mine is - * a hyperslab whose size is manageable. - */ - sm_nbytes = p_type_nbytes = H5Tget_size(p_type); - - if (ctx.ndims > 0) - for (i = ctx.ndims; i > 0; --i) - { - hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes; - if ( size == 0) /* datum size > H5TOOLS_BUFSIZE */ - size = 1; - sm_size[i - 1] = MIN(total_size[i - 1], size); - sm_nbytes *= sm_size[i - 1]; - assert(sm_nbytes > 0); - } - - assert(sm_nbytes == (hsize_t)((size_t)sm_nbytes)); /*check for overflow*/ - sm_buf = malloc((size_t)sm_nelmts * p_type_nbytes); - sm_space = H5Screate_simple(1, &sm_nelmts, NULL); - - H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, &zero, NULL, &sm_nelmts, NULL); - - /* read the data */ - if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) < 0) { - H5Sclose(f_space); - H5Sclose(sm_space); - free(sm_buf); - return FAIL; - } - - /* print the data */ - flags = START_OF_DATA; - - if (count == 1) - flags |= END_OF_DATA; - - for (i = 0; i < ctx.ndims; i++) - ctx.p_max_idx[i] = ctx.p_min_idx[i] + MIN(total_size[i], sm_size[i]); - - /* print array indices. get the lower bound of the hyperslab and calulate - the element position at the start of hyperslab */ - H5Sget_select_bounds(f_space,low,high); - elmtno=0; - for (i = 0; i < (size_t)ctx.ndims-1; i++) - { - hsize_t offset = 1; /* accumulation of the previous dimensions */ - for (j = i+1; j < (size_t)ctx.ndims; j++) - offset *= total_size[j]; - elmtno+= low[i] * offset; - } - elmtno+= low[ctx.ndims - 1]; - - /* initialize the current stripmine position; this is necessary to print the array - indices */ - ctx.sm_pos = elmtno; - - h5tools_dump_simple_data(stream, info, dset, &ctx, flags, sm_nelmts, - p_type, sm_buf); - free(sm_buf); - - /* we need to jump to next line and update the index */ - ctx.need_prefix = 1; - - ctx.continuation++; - - -#if defined (SANITY_CHECK) - printed_points += sm_nelmts; -#endif - - - } /* count */ - - if (ctx.ndims > 2) - { + + h5tools_print_simple_subset(stream, info, ctx, dset, p_type, sset, + f_space, count, temp_start, temp_count, + temp_block, temp_stride, total_size, row_dim); + + if (ctx->ndims > 2) { /* dimension for start */ - current_outer_dim = (ctx.ndims - 2) -1; + current_outer_dim = (ctx->ndims - 2) - 1; /* set start to original from current_outer_dim up */ - for (i = current_outer_dim + 1; i < ctx.ndims; i++) - { - temp_start[ i ] = sset->start[ i ]; + for (i = current_outer_dim + 1; i < ctx->ndims; i++) { + temp_start[i] = sset->start[i]; } - /* increment start dimension */ - do - { + do { reset_dim = 0; - temp_start[ current_outer_dim ]++; - if (temp_start[ current_outer_dim ] >= max_start[ current_outer_dim ]) - { - temp_start[ current_outer_dim ] = sset->start[ current_outer_dim ]; + temp_start[current_outer_dim]++; + if (temp_start[current_outer_dim] >= max_start[current_outer_dim]) { + temp_start[current_outer_dim] = sset->start[current_outer_dim]; /* consider block */ - if ( sset->block[ current_outer_dim ] > 1 ) - temp_start[ current_outer_dim ]++; + if (sset->block[current_outer_dim] > 1) + temp_start[current_outer_dim]++; current_outer_dim--; reset_dim = 1; } - } - while (current_outer_dim >= 0 && reset_dim); + } while (current_outer_dim >= 0 && reset_dim); } /* ctx.ndims > 1 */ } /* outer_count */ -#if defined (SANITY_CHECK) - assert( printed_points == total_points ); -#endif +CATCH + return ret_value; +} +/*------------------------------------------------------------------------- + * Audience: Public + * Chapter: H5Tools Library + * Purpose: Dump out a subset of a dataset. + * Description: + * + * Select a hyperslab from the dataset DSET using the parameters + * specified in SSET. Dump this out to STREAM. + * + * Hyperslabs select "count" blocks of size "block", spaced "stride" elements + * from each other, starting at coordinate "start". + * + * Return: + * On success, return SUCCEED. Otherwise, the function returns FAIL. + * + * Original programmer: + * Bill Wendling, Wednesday, March 07, 2001 + * + * Rewritten with modified algorithm by: + * Pedro Vicente, Wednesday, January 16, 2008, contributions from Quincey Koziol + * + * Algorithm + * + * In a inner loop, the parameters from SSET are translated into temporary + * variables so that 1 row is printed at a time (getting the coordinate indices + * at each row). + * We define the stride, count and block to be 1 in the row dimension to achieve + * this and advance until all points are printed. + * An outer loop for cases where dimensionality is greater than 2D is made. + * In each iteration, the 2D block is displayed in the inner loop. The remaining + * slower dimensions above the first 2 are incremented one at a time in the outer loop + * + * The element position is obtained from the matrix according to: + * Given an index I(z,y,x) its position from the beginning of an array + * of sizes A(size_z, size_y,size_x) is given by + * Position of I(z,y,x) = index_z * size_y * size_x + * + index_y * size_x + * + index_x + * + *------------------------------------------------------------------------- + */ +static herr_t +h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset, + hid_t p_type, struct subset_t *sset, int indentlevel) +{ + HERR_INIT(herr_t, SUCCEED) + hid_t f_space; /* file data space */ + size_t i; /* counters */ + hsize_t total_size[H5S_MAX_RANK];/* total size of dataset*/ + h5tools_context_t ctx; /* print context */ + + if((f_space = H5Dget_space(dset)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Dget_space failed"); + + /* + * check that everything looks okay. the dimensionality must not be too + * great and the dimensionality of the items selected for printing must + * match the dimensionality of the dataset. + */ + memset(&ctx, 0, sizeof(ctx)); + ctx.indent_level = indentlevel; + ctx.need_prefix = 1; + if((ctx.ndims = H5Sget_simple_extent_ndims(f_space)) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_ndims failed"); + /* assume entire data space to be printed */ + if (ctx.ndims > 0) + for (i = 0; i < (size_t) ctx.ndims; i++) + ctx.p_min_idx[i] = 0; + + if(H5Sget_simple_extent_dims(f_space, total_size, NULL) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); + ctx.size_last_dim = total_size[ctx.ndims - 1]; + + h5tools_display_simple_subset(stream, info, &ctx, dset, p_type, sset, f_space, total_size); /* Terminate the output */ if (ctx.cur_column) { fputs(OPT(info->line_suf, ""), stream); @@ -1055,15 +2303,13 @@ h5tools_dump_simple_subset(FILE *stream, const h5tool_format_t *info, hid_t dset fputs(OPT(info->line_sep, ""), stream); } - ret = SUCCEED; - -done_close: - H5Sclose(f_space); done: - return ret; -} - + if(H5Sclose(f_space) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); +CATCH + return ret_value; +} /*------------------------------------------------------------------------- * Audience: Public @@ -1078,18 +2324,15 @@ done: * Return: * On success, the function returns SUCCEED. Otherwise, the function * returns FAIL. - * Programmer: - * Robb Matzke, Thursday, July 23, 1998 - * Modifications: *------------------------------------------------------------------------- */ -static int -h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, - hid_t p_type, int indentlevel) +static int +h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, + hid_t dset, hid_t p_type, int indentlevel) { hid_t f_space; /* file data space */ hsize_t elmtno; /* counter */ - size_t i; /* counter */ + size_t i; /* counter */ int carry; /* counter carry value */ hsize_t zero[8]; /* vector of zeros */ unsigned int flags; /* buffer extent flags */ @@ -1104,16 +2347,16 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */ hsize_t sm_nbytes; /* bytes per stripmine */ hsize_t sm_nelmts; /* elements per stripmine*/ - unsigned char *sm_buf = NULL; /* buffer for raw data */ + unsigned char *sm_buf = NULL; /* buffer for raw data */ hid_t sm_space; /* stripmine data space */ /* Hyperslab info */ - hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */ - hsize_t hs_size[H5S_MAX_RANK]; /* size this pass */ - hsize_t hs_nelmts; /* elements in request */ + hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */ + hsize_t hs_size[H5S_MAX_RANK]; /* size this pass */ + hsize_t hs_nelmts; /* elements in request */ /* VL data special information */ - unsigned int vl_data = 0; /* contains VL datatypes */ + unsigned int vl_data = 0; /* contains VL datatypes */ f_space = H5Dget_space(dset); @@ -1126,8 +2369,6 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, * match the dimensionality of the dataset. */ memset(&ctx, 0, sizeof(ctx)); - ctx.indent_level = indentlevel; - ctx.need_prefix = 1; ctx.ndims = H5Sget_simple_extent_ndims(f_space); if ((size_t)ctx.ndims > NELMTS(sm_size)) { @@ -1135,6 +2376,9 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, return FAIL; } + ctx.indent_level = indentlevel; + ctx.need_prefix = 1; + /* Assume entire data space to be printed */ if (ctx.ndims > 0) for (i = 0; i < (size_t)ctx.ndims; i++) @@ -1186,8 +2430,8 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, sm_nelmts = sm_nbytes / p_type_nbytes; sm_space = H5Screate_simple(1, &sm_nelmts, NULL); - if(ctx.ndims>0) - init_acc_pos(&ctx,total_size); + if (ctx.ndims > 0) + init_acc_pos(&ctx, total_size); /* The stripmine loop */ memset(hs_offset, 0, sizeof hs_offset); @@ -1202,11 +2446,10 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hs_nelmts *= hs_size[i]; } - H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, - hs_size, NULL); - H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, - &hs_nelmts, NULL); - } else { + H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL); + H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL); + } + else { H5Sselect_all(f_space); H5Sselect_all(sm_space); hs_nelmts = 1; @@ -1225,14 +2468,13 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, flags |= ((elmtno + hs_nelmts) >= p_nelmts) ? END_OF_DATA : 0; /* initialize the current stripmine position; this is necessary to print the array - indices */ + indices */ ctx.sm_pos = elmtno; - h5tools_dump_simple_data(stream, info, dset, &ctx, flags, hs_nelmts, - p_type, sm_buf); + h5tools_dump_simple_data(stream, info, dset, &ctx, flags, hs_nelmts, p_type, sm_buf); /* Reclaim any VL memory, if necessary */ - if(vl_data) + if (vl_data) H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); /* Calculate the next hyperslab offset */ @@ -1271,13 +2513,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, * This is a special case of h5tools_dump_mem(). * * Return: Success: SUCCEED - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Thursday, July 23, 1998 - * - * Modifications: + * Failure: FAIL * *------------------------------------------------------------------------- */ @@ -1285,9 +2521,9 @@ static int h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, hid_t type, hid_t space, void *mem, int indentlevel) { - int i; /*counters */ - hsize_t nelmts; /*total selected elmts */ - h5tools_context_t ctx; /*printing context */ + int i; /*counters */ + hsize_t nelmts; /*total selected elmts */ + h5tools_context_t ctx; /*printing context */ /* * Check that everything looks okay. The dimensionality must not be too @@ -1297,7 +2533,7 @@ h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, memset(&ctx, 0, sizeof(ctx)); ctx.ndims = H5Sget_simple_extent_ndims(space); - if ((size_t)ctx.ndims > NELMTS(ctx.p_min_idx)) + if ((size_t) ctx.ndims > NELMTS(ctx.p_min_idx)) return FAIL; ctx.indent_level = indentlevel; @@ -1314,19 +2550,18 @@ h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, if (nelmts == 0) return SUCCEED; /*nothing to print*/ - if(ctx.ndims>0) { - assert(ctx.p_max_idx[ctx.ndims - 1]==(hsize_t)((int)ctx.p_max_idx[ctx.ndims - 1])); - ctx.size_last_dim = (int)(ctx.p_max_idx[ctx.ndims - 1]); + if (ctx.ndims > 0) { + assert(ctx.p_max_idx[ctx.ndims - 1] == (hsize_t) ((int) ctx.p_max_idx[ctx.ndims - 1])); + ctx.size_last_dim = (int) (ctx.p_max_idx[ctx.ndims - 1]); } /* end if */ else ctx.size_last_dim = 0; - if(ctx.ndims>0) - init_acc_pos(&ctx,ctx.p_max_idx); + if (ctx.ndims > 0) + init_acc_pos(&ctx, ctx.p_max_idx); /* Print it */ - h5tools_dump_simple_data(stream, info, obj_id, &ctx, - START_OF_DATA | END_OF_DATA, nelmts, type, mem); + h5tools_dump_simple_data(stream, info, obj_id, &ctx, START_OF_DATA | END_OF_DATA, nelmts, type, mem); /* Terminate the output */ if (ctx.cur_column) { @@ -1353,33 +2588,29 @@ h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, * h5tools_dump_mem(). * * Return: Success: SUCCEED - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Thursday, July 23, 1998 + * Failure: FAIL * * Modifications: * Robb Matzke, 1999-06-07 - * If info->raw is set then the memory datatype will be the same - * as the file datatype. + * If info->raw is set then the memory datatype will be the same + * as the file datatype. * * Bill Wendling, 2001-02-27 - * Renamed to ``h5tools_dump_dset'' and added the subsetting - * parameter. + * Renamed to ``h5tools_dump_dset'' and added the subsetting + * parameter. * *------------------------------------------------------------------------- */ -int -h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hid_t _p_type, - struct subset_t *sset, int indentlevel) +int +h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, + hid_t _p_type, struct subset_t *sset, int indentlevel) { hid_t f_space; hid_t p_type = _p_type; hid_t f_type; H5S_class_t space_type; int status = FAIL; - h5tool_format_t info_dflt; + h5tool_format_t info_dflt; /* Use default values */ if (!stream) @@ -1393,11 +2624,11 @@ h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hid_t _ if (p_type < 0) { f_type = H5Dget_type(dset); - if (info->raw || bin_form == 1 ) + if (info->raw || bin_form == 1) p_type = H5Tcopy(f_type); - else if (bin_form == 2 ) + else if (bin_form == 2) p_type = h5tools_get_little_endian_type(f_type); - else if (bin_form == 3 ) + else if (bin_form == 3) p_type = h5tools_get_big_endian_type(f_type); else p_type = h5tools_get_native_type(f_type); @@ -1415,13 +2646,15 @@ h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset, hid_t _ /* Print the data */ if (space_type == H5S_SIMPLE || space_type == H5S_SCALAR) { - if (!sset) - status = h5tools_dump_simple_dset(rawdatastream, info, dset, p_type, - indentlevel); - else - status = h5tools_dump_simple_subset(rawdatastream, info, dset, p_type, - sset, indentlevel); - } else /* space is H5S_NULL */ + if (!sset) { + status = h5tools_dump_simple_dset(rawdatastream, info, dset, p_type, indentlevel); + } + else { + status = h5tools_dump_simple_subset(rawdatastream, info, dset, p_type, sset, indentlevel); + } + } + else + /* space is H5S_NULL */ status = SUCCEED; /* Close the dataspace */ @@ -1442,13 +2675,7 @@ done: * spaces are allowed and only the `all' selection. * * Return: Success: SUCCEED - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Wednesday, January 20, 1999 - * - * Modifications: + * Failure: FAIL * *------------------------------------------------------------------------- */ @@ -1456,53 +2683,794 @@ int h5tools_dump_mem(FILE *stream, const h5tool_format_t *info, hid_t obj_id, hid_t type, hid_t space, void *mem, int indentlevel) { + HERR_INIT(int, SUCCEED) h5tool_format_t info_dflt; /* Use default values */ if (!stream) - stream = stdout; + stream = stdout; if (!info) { - memset(&info_dflt, 0, sizeof(info_dflt)); - info = &info_dflt; + memset(&info_dflt, 0, sizeof(info_dflt)); + info = &info_dflt; } /* Check the data space */ if (H5Sis_simple(space) <= 0) - return -1; + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Sis_simple failed") + + H5_LEAVE(h5tools_dump_simple_mem(stream, info, obj_id, type, space, mem, indentlevel)) - return h5tools_dump_simple_mem(stream, info, obj_id, type, space, mem, - indentlevel); +CATCH + return ret_value; } /*------------------------------------------------------------------------- - * Function: init_acc_pos + * Function: print_datatype * - * Purpose: initialize accumulator and matrix position + * Purpose: print the datatype. * * Return: void * - * Programmer: pvn + * In/Out: h5tools_str_t *buffer + * h5tools_context_t *ctx * - * Modifications: + *------------------------------------------------------------------------- + */ +int +h5tools_print_datatype(h5tools_str_t *buffer, const h5tool_format_t *info, + h5tools_context_t *ctx, hid_t type) +{ + HERR_INIT(int, SUCCEED) + char *mname; + hid_t mtype, str_type; + unsigned nmembers; + unsigned ndims; + unsigned i; + size_t size = 0; + hsize_t dims[H5TOOLS_DUMP_MAX_RANK]; + H5T_str_t str_pad; + H5T_cset_t cset; + H5T_order_t order; + H5T_class_t type_class; + hid_t super; + hid_t tmp_type; + htri_t is_vlstr = FALSE; + const char *order_s = NULL; /* byte order string */ + H5T_sign_t sign; /* sign scheme value */ + const char *sign_s = NULL; /* sign scheme string */ + + if((type_class = H5Tget_class(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_class failed"); + switch (type_class) { + case H5T_INTEGER: + if (H5Tequal(type, H5T_STD_I8BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I8BE"); + } + else if (H5Tequal(type, H5T_STD_I8LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I8LE"); + } + else if (H5Tequal(type, H5T_STD_I16BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I16BE"); + } + else if (H5Tequal(type, H5T_STD_I16LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I16LE"); + } + else if (H5Tequal(type, H5T_STD_I32BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I32BE"); + } + else if (H5Tequal(type, H5T_STD_I32LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I32LE"); + } + else if (H5Tequal(type, H5T_STD_I64BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I64BE"); + } + else if (H5Tequal(type, H5T_STD_I64LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_I64LE"); + } + else if (H5Tequal(type, H5T_STD_U8BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U8BE"); + } + else if (H5Tequal(type, H5T_STD_U8LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U8LE"); + } + else if (H5Tequal(type, H5T_STD_U16BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U16BE"); + } + else if (H5Tequal(type, H5T_STD_U16LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U16LE"); + } + else if (H5Tequal(type, H5T_STD_U32BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U32BE"); + } + else if (H5Tequal(type, H5T_STD_U32LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U32LE"); + } + else if (H5Tequal(type, H5T_STD_U64BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U64BE"); + } + else if (H5Tequal(type, H5T_STD_U64LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_U64LE"); + } + else if (H5Tequal(type, H5T_NATIVE_SCHAR) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_SCHAR"); + } + else if (H5Tequal(type, H5T_NATIVE_UCHAR) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_UCHAR"); + } + else if (H5Tequal(type, H5T_NATIVE_SHORT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_SHORT"); + } + else if (H5Tequal(type, H5T_NATIVE_USHORT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_USHORT"); + } + else if (H5Tequal(type, H5T_NATIVE_INT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_INT"); + } + else if (H5Tequal(type, H5T_NATIVE_UINT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_UINT"); + } + else if (H5Tequal(type, H5T_NATIVE_LONG) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_LONG"); + } + else if (H5Tequal(type, H5T_NATIVE_ULONG) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_ULONG"); + } + else if (H5Tequal(type, H5T_NATIVE_LLONG) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_LLONG"); + } + else if (H5Tequal(type, H5T_NATIVE_ULLONG) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_ULLONG"); + } + else { + + /* byte order */ + if (H5Tget_size(type) > 1) { + order = H5Tget_order(type); + if (H5T_ORDER_LE == order) { + order_s = " little-endian"; + } + else if (H5T_ORDER_BE == order) { + order_s = " big-endian"; + } + else if (H5T_ORDER_VAX == order) { + order_s = " mixed-endian"; + } + else { + order_s = " unknown-byte-order"; + } + } + else { + order_s = ""; + } + + /* sign */ + if ((sign = H5Tget_sign(type)) >= 0) { + if (H5T_SGN_NONE == sign) { + sign_s = " unsigned"; + } + else if (H5T_SGN_2 == sign) { + sign_s = ""; + } + else { + sign_s = " unknown-sign"; + } + } + else { + sign_s = " unknown-sign"; + } + + /* print size, order, and sign */ + h5tools_str_append(buffer, "%lu-bit%s%s integer", + (unsigned long) (8 * H5Tget_size(type)), order_s, sign_s); + } + break; + + case H5T_FLOAT: + if (H5Tequal(type, H5T_IEEE_F32BE) == TRUE) { + h5tools_str_append(buffer, "H5T_IEEE_F32BE"); + } + else if (H5Tequal(type, H5T_IEEE_F32LE) == TRUE) { + h5tools_str_append(buffer, "H5T_IEEE_F32LE"); + } + else if (H5Tequal(type, H5T_IEEE_F64BE) == TRUE) { + h5tools_str_append(buffer, "H5T_IEEE_F64BE"); + } + else if (H5Tequal(type, H5T_IEEE_F64LE) == TRUE) { + h5tools_str_append(buffer, "H5T_IEEE_F64LE"); + } + else if (H5Tequal(type, H5T_VAX_F32) == TRUE) { + h5tools_str_append(buffer, "H5T_VAX_F32"); + } + else if (H5Tequal(type, H5T_VAX_F64) == TRUE) { + h5tools_str_append(buffer, "H5T_VAX_F64"); + } + else if (H5Tequal(type, H5T_NATIVE_FLOAT) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_FLOAT"); + } + else if (H5Tequal(type, H5T_NATIVE_DOUBLE) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_DOUBLE"); +#if H5_SIZEOF_LONG_DOUBLE !=0 + } + else if (H5Tequal(type, H5T_NATIVE_LDOUBLE) == TRUE) { + h5tools_str_append(buffer, "H5T_NATIVE_LDOUBLE"); +#endif + } + else { + + /* byte order */ + if (H5Tget_size(type) > 1) { + order = H5Tget_order(type); + if (H5T_ORDER_LE == order) { + order_s = " little-endian"; + } + else if (H5T_ORDER_BE == order) { + order_s = " big-endian"; + } + else if (H5T_ORDER_VAX == order) { + order_s = " mixed-endian"; + } + else { + order_s = " unknown-byte-order"; + } + } + else { + order_s = ""; + } + + /* print size and byte order */ + h5tools_str_append(buffer, "%lu-bit%s floating-point", + (unsigned long) (8 * H5Tget_size(type)), order_s); + + } + break; + + case H5T_TIME: + h5tools_str_append(buffer, "H5T_TIME: not yet implemented"); + break; + + case H5T_STRING: + /* Make a copy of type in memory in case when TYPE is on disk, the size + * will be bigger than in memory. This makes it easier to compare + * types in memory. */ + tmp_type = H5Tcopy(type); + size = H5Tget_size(tmp_type); + str_pad = H5Tget_strpad(tmp_type); + cset = H5Tget_cset(tmp_type); + is_vlstr = H5Tis_variable_str(tmp_type); + + h5tools_str_append(buffer, "H5T_STRING %s\n", h5tools_dump_header_format->strblockbegin); + ctx->indent_level++; + + if (is_vlstr) + h5tools_str_append(buffer, "%s H5T_VARIABLE;\n", STRSIZE); + else + h5tools_str_append(buffer, "%s %d;\n", STRSIZE, (int) size); + + h5tools_str_append(buffer, "%s ", STRPAD); + if (str_pad == H5T_STR_NULLTERM) + h5tools_str_append(buffer, "H5T_STR_NULLTERM;\n"); + else if (str_pad == H5T_STR_NULLPAD) + h5tools_str_append(buffer, "H5T_STR_NULLPAD;\n"); + else if (str_pad == H5T_STR_SPACEPAD) + h5tools_str_append(buffer, "H5T_STR_SPACEPAD;\n"); + else + h5tools_str_append(buffer, "H5T_STR_ERROR;\n"); + + h5tools_str_append(buffer, "%s ", CSET); + + if (cset == H5T_CSET_ASCII) + h5tools_str_append(buffer, "H5T_CSET_ASCII;\n"); + else + h5tools_str_append(buffer, "unknown_cset;\n"); + + str_type = H5Tcopy(H5T_C_S1); + if (is_vlstr) + H5Tset_size(str_type, H5T_VARIABLE); + else + H5Tset_size(str_type, size); + H5Tset_cset(str_type, cset); + H5Tset_strpad(str_type, str_pad); + + h5tools_str_append(buffer, "%s ", CTYPE); + + /* Check C variable-length string first. Are the two types equal? */ + if (H5Tequal(tmp_type, str_type)) { + h5tools_str_append(buffer, "H5T_C_S1;\n"); + goto done; + } + + /* Change the endianness and see if they're equal. */ + order = H5Tget_order(tmp_type); + if (order == H5T_ORDER_LE) + H5Tset_order(str_type, H5T_ORDER_LE); + else if (order == H5T_ORDER_BE) + H5Tset_order(str_type, H5T_ORDER_BE); + + if (H5Tequal(tmp_type, str_type)) { + h5tools_str_append(buffer, "H5T_C_S1;\n"); + goto done; + } + + /* If not equal to C variable-length string, check Fortran type. */ + if(H5Tclose(str_type) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + str_type = H5Tcopy(H5T_FORTRAN_S1); + + H5Tset_cset(str_type, cset); + H5Tset_size(str_type, size); + H5Tset_strpad(str_type, str_pad); + + /* Are the two types equal? */ + if (H5Tequal(tmp_type, str_type)) { + h5tools_str_append(buffer, "H5T_FORTRAN_S1;\n"); + goto done; + } + + /* Change the endianness and see if they're equal. */ + order = H5Tget_order(tmp_type); + if (order == H5T_ORDER_LE) + H5Tset_order(str_type, H5T_ORDER_LE); + else if (order == H5T_ORDER_BE) + H5Tset_order(str_type, H5T_ORDER_BE); + + if (H5Tequal(tmp_type, str_type)) { + h5tools_str_append(buffer, "H5T_FORTRAN_S1;\n"); + goto done; + } + + /* Type doesn't match any of above. */ + h5tools_str_append(buffer, "unknown_one_character_type;\n "); + + done: + if(H5Tclose(str_type) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + if(H5Tclose(tmp_type) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + + ctx->indent_level--; + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->strblockend); + break; + + case H5T_BITFIELD: + if (H5Tequal(type, H5T_STD_B8BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B8BE"); + } + else if (H5Tequal(type, H5T_STD_B8LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B8LE"); + } + else if (H5Tequal(type, H5T_STD_B16BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B16BE"); + } + else if (H5Tequal(type, H5T_STD_B16LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B16LE"); + } + else if (H5Tequal(type, H5T_STD_B32BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B32BE"); + } + else if (H5Tequal(type, H5T_STD_B32LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B32LE"); + } + else if (H5Tequal(type, H5T_STD_B64BE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B64BE"); + } + else if (H5Tequal(type, H5T_STD_B64LE) == TRUE) { + h5tools_str_append(buffer, "H5T_STD_B64LE"); + } + else { + h5tools_str_append(buffer, "undefined bitfield"); + } + break; + + case H5T_OPAQUE: + h5tools_str_append(buffer, "\n"); + h5tools_str_append(buffer, "H5T_OPAQUE;\n"); + h5tools_str_append(buffer, "OPAQUE_TAG \"%s\";\n", H5Tget_tag(type)); + break; + + case H5T_COMPOUND: + if((nmembers = H5Tget_nmembers(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed"); + + h5tools_str_append(buffer, "H5T_COMPOUND %s\n", h5tools_dump_header_format->structblockbegin); + + for (i = 0; i < nmembers; i++) { + mname = H5Tget_member_name(type, i); + if((mtype = H5Tget_member_type(type, i))>=0) { + if (H5Tget_class(mtype) == H5T_COMPOUND) + ctx->indent_level++; + + h5tools_print_datatype(buffer, info, ctx, mtype); + + if (H5Tget_class(mtype) == H5T_COMPOUND) + ctx->indent_level--; + + h5tools_str_append(buffer, " \"%s\";\n", mname); + if(H5Tclose(mtype) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + } + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tget_member_type failed"); + free(mname); + } + + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->structblockend); + break; + + case H5T_REFERENCE: + h5tools_str_append(buffer, "H5T_REFERENCE"); + if(region_output) { + if (H5Tequal(type, H5T_STD_REF_DSETREG) == TRUE) { + h5tools_str_append(buffer, " { H5T_STD_REF_DSETREG }"); + } + else { + h5tools_str_append(buffer, " { H5T_STD_REF_OBJECT }"); + } + } + break; + + case H5T_ENUM: + if((super = H5Tget_super(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed"); + + h5tools_str_append(buffer, "H5T_ENUM %s\n", h5tools_dump_header_format->enumblockbegin); + ctx->indent_level++; + + h5tools_print_datatype(buffer, info, ctx, super); + if(H5Tclose(super) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + + h5tools_str_append(buffer, ";\n"); + h5tools_print_enum(buffer, type); + + ctx->indent_level--; + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->enumblockend); + + break; + + case H5T_VLEN: + if((super = H5Tget_super(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed"); + + h5tools_str_append(buffer, "H5T_VLEN %s ", h5tools_dump_header_format->vlenblockbegin); + + h5tools_print_datatype(buffer, info, ctx, super); + if(H5Tclose(super) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->vlenblockend); + + break; + + case H5T_ARRAY: + h5tools_str_append(buffer, "H5T_ARRAY { "); + + /* Get array information */ + if((ndims = H5Tget_array_ndims(type)) >= 0) { + if(H5Tget_array_dims2(type, dims) >= 0) { + /* Print array dimensions */ + for (i = 0; i < ndims; i++) + h5tools_str_append(buffer, "[%d]", (int) dims[i]); + + h5tools_str_append(buffer, " "); + } + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tget_array_dims2 failed"); + } + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tget_array_ndims failed"); + + /* Get array base type */ + if((super = H5Tget_super(type)) >= 0) { + /* Print base type */ + h5tools_print_datatype(buffer, info, ctx, super); + /* Close array base type */ + if(H5Tclose(super) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tclose failed"); + } + else + HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Tget_super failed"); + + h5tools_str_append(buffer, " }"); + + break; + + default: + h5tools_str_append(buffer, "unknown datatype"); + break; + } + +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: print_dataspace + * + * Purpose: print the dataspace. + * + * Return: void + * + * In/Out: h5tools_str_t *buffer + * h5tools_context_t *ctx + * + *------------------------------------------------------------------------- + */ +int +h5tools_print_dataspace(h5tools_str_t *buffer, hid_t space) +{ + HERR_INIT(int, SUCCEED) + hsize_t size[H5TOOLS_DUMP_MAX_RANK]; + hsize_t maxsize[H5TOOLS_DUMP_MAX_RANK]; + int ndims = -1; + H5S_class_t space_type = -1; + int i; + + if((ndims = H5Sget_simple_extent_dims(space, size, maxsize)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); + + if((space_type = H5Sget_simple_extent_type(space)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_type failed"); + + switch(space_type) { + case H5S_SCALAR: + /* scalar dataspace */ + h5tools_str_append(buffer, "%s %s", h5tools_dump_header_format->dataspacedescriptionbegin, S_SCALAR); + break; + + case H5S_SIMPLE: + /* simple dataspace */ + h5tools_str_append(buffer, "%s %s { %s %" H5_PRINTF_LL_WIDTH "u", + h5tools_dump_header_format->dataspacedescriptionbegin, S_SIMPLE, + h5tools_dump_header_format->dataspacedimbegin, size[0]); + + for(i = 1; i < ndims; i++) + h5tools_str_append(buffer, ", %" H5_PRINTF_LL_WIDTH "u", size[i]); + + h5tools_str_append(buffer, " %s / ", h5tools_dump_header_format->dataspacedimend); + + if(maxsize[0] == H5S_UNLIMITED) + h5tools_str_append(buffer, "%s %s", + h5tools_dump_header_format->dataspacedimbegin, "H5S_UNLIMITED"); + else + h5tools_str_append(buffer, "%s %" H5_PRINTF_LL_WIDTH "u", + h5tools_dump_header_format->dataspacedimbegin, maxsize[0]); + + for(i = 1; i < ndims; i++) + if(maxsize[i] == H5S_UNLIMITED) + h5tools_str_append(buffer, ", %s", "H5S_UNLIMITED"); + else + h5tools_str_append(buffer, ", %" H5_PRINTF_LL_WIDTH "u", maxsize[i]); + + h5tools_str_append(buffer, " %s }", h5tools_dump_header_format->dataspacedimend); + break; + + case H5S_NULL: + /* null dataspace */ + h5tools_str_append(buffer, "%s %s", h5tools_dump_header_format->dataspacedescriptionbegin, S_NULL); + break; + + case H5S_NO_CLASS: + default: + h5tools_str_append(buffer, "%s unknown dataspace %s\n", BEGIN, END); + break; + } /* end switch */ + +CATCH + return ret_value; +} + + +/*------------------------------------------------------------------------- + * Function: print_enum + * + * Purpose: prints the enum data + * + * Return: void + * + * In/Out: h5tools_str_t *buffer + * h5tools_context_t *ctx + * + *-----------------------------------------------------------------------*/ +int +h5tools_print_enum(h5tools_str_t *buffer, hid_t type) +{ + HERR_INIT(int, SUCCEED) + char **name = NULL; /*member names */ + unsigned char *value = NULL; /*value array */ + unsigned char *copy = NULL; /*a pointer to value array */ + unsigned nmembs; /*number of members */ + int nchars; /*number of output characters */ + hid_t super = -1; /*enum base integer type */ + hid_t native = -1; /*native integer datatype */ + H5T_sign_t sign_type; /*sign of value type */ + size_t type_size; /*value type size */ + size_t dst_size; /*destination value type size */ + unsigned i; + + if((nmembs = H5Tget_nmembers(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed"); + assert(nmembs > 0); + + if((super = H5Tget_super(type)) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_super failed"); + + if((type_size = H5Tget_size(type)) <= 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_size(type) failed"); + /* + * Determine what datatype to use for the native values. To simplify + * things we entertain three possibilities: + * 1. long long -- the largest native signed integer + * 2. unsigned long long -- the largest native unsigned integer + * 3. raw format + */ + if (type_size <= sizeof(long long)) { + dst_size = sizeof(long long); + + if((sign_type = H5Tget_sign(type))<0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_sign failed"); + if (H5T_SGN_NONE == sign_type) { + native = H5T_NATIVE_ULLONG; + } + else { + native = H5T_NATIVE_LLONG; + } + } + else { + dst_size = type_size; + } + + /* Get the names and raw values of all members */ + if((name = calloc(nmembs, sizeof(char *))) == NULL) + H5E_THROW(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for member name"); + if((value = calloc(nmembs, MAX(type_size, dst_size))) == NULL) + H5E_THROW(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for member value"); + + for (i = 0; i < nmembs; i++) { + name[i] = H5Tget_member_name(type, i); + if(H5Tget_member_value(type, i, value + i * type_size) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_member_value failed"); + } + + /* Convert values to native datatype */ + if (native > 0) + if(H5Tconvert(super, native, nmembs, value, NULL, H5P_DEFAULT) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tconvert failed"); + + /* + * Sort members by increasing value + * ***not implemented yet*** + */ + + /* Print members */ + for (i = 0; i < nmembs; i++) { + h5tools_str_append(buffer, "\"%s\"", name[i]); + nchars = strlen(name[i]); + h5tools_str_append(buffer, "%*s ", MAX(0, 16 - nchars), ""); + + if (native < 0) { + size_t j; + + h5tools_str_append(buffer, "0x"); + + for (j = 0; j < dst_size; j++) + h5tools_str_append(buffer, "%02x", value[i * dst_size + j]); + } + else if (H5T_SGN_NONE == H5Tget_sign(native)) { + /*On SGI Altix(cobalt), wrong values were printed out with "value+i*dst_size" + *strangely, unless use another pointer "copy".*/ + copy = value + i * dst_size; + h5tools_str_append(buffer, "%" H5_PRINTF_LL_WIDTH "u", *((unsigned long long *) ((void *) copy))); + } + else { + /*On SGI Altix(cobalt), wrong values were printed out with "value+i*dst_size" + *strangely, unless use another pointer "copy".*/ + copy = value + i * dst_size; + h5tools_str_append(buffer, "%" H5_PRINTF_LL_WIDTH "d", *((long long *) ((void *) copy))); + } + + h5tools_str_append(buffer, ";\n"); + } + +CATCH + + /* Release resources */ + for (i = 0; i < nmembs; i++) + free(name[i]); + + free(name); + free(value); + + if(H5Tclose(super) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tclose failed"); + + if (0 == nmembs) + h5tools_str_append(buffer, "\n<empty>"); + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: dump_datatype + * + * Purpose: Dump the datatype. Datatype can be HDF5 predefined + * atomic datatype or committed/transient datatype. * + * Return: void + * + * In/Out: h5tools_context_t *ctx *------------------------------------------------------------------------- */ -void init_acc_pos(h5tools_context_t *ctx, hsize_t *dims) +void +h5tools_dump_datatype(FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx, hid_t type) { - int i; + size_t ncols = 80; /* available output width */ + h5tools_str_t buffer; /* string into which to render */ + hsize_t curr_pos; /* total data element position */ + hsize_t elmt_counter = 0;/* counts the # elements printed.*/ + + /* setup */ + HDmemset(&buffer, 0, sizeof(h5tools_str_t)); + + if (info->line_ncols > 0) + ncols = info->line_ncols; + + /* pass to the prefix in h5tools_simple_prefix the total position + * instead of the current stripmine position i; this is necessary + * to print the array indices + */ + curr_pos = ctx->sm_pos; - assert(ctx->ndims); + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + /* Render the element */ + h5tools_str_reset(&buffer); - ctx->acc[ctx->ndims-1]=1; - for(i=(ctx->ndims-2); i>=0; i--) - { - ctx->acc[i]=ctx->acc[i+1] * dims[i+1]; - } - for ( i = 0; i < ctx->ndims; i++) - ctx->pos[i]=0; + ctx->indent_level++; + h5tools_str_append(&buffer, "%s %s ", + h5tools_dump_header_format->datatypebegin, + h5tools_dump_header_format->datatypeblockbegin); + + h5tools_print_datatype(&buffer, info, ctx, type); + + if (HDstrlen(h5tools_dump_header_format->datatypeblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datatypeblockend); + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(&buffer, " "); + } + if (HDstrlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datatypeend); + h5tools_str_append(&buffer, "\n"); + + curr_pos = h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, + ncols, elmt_counter, 0); + + ctx->need_prefix = TRUE; + ctx->indent_level--; } +/*------------------------------------------------------------------------- + * Function: init_acc_pos + * + * Purpose: initialize accumulator and matrix position + * + * Return: void + *------------------------------------------------------------------------- + */ +void +init_acc_pos(h5tools_context_t *ctx, hsize_t *dims) +{ + int i; + + assert(ctx->ndims); + + ctx->acc[ctx->ndims - 1] = 1; + for (i = (ctx->ndims - 2); i >= 0; i--) { + ctx->acc[i] = ctx->acc[i + 1] * dims[i + 1]; + } + for (i = 0; i < ctx->ndims; i++) + ctx->pos[i] = 0; +} /*------------------------------------------------------------------------- * Function: do_bin_output @@ -1511,35 +3479,29 @@ void init_acc_pos(h5tools_context_t *ctx, hsize_t *dims) * * Return: Success: SUCCEED * Failure: FAIL - * - * Programmer: Pedro Vicente Nunes - * Friday, June 2, 2006 - * - * Modifications: - * *------------------------------------------------------------------------- */ static int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) { - unsigned char *mem = (unsigned char*)_mem; - size_t size; /* datum size */ - hsize_t i; /* element counter */ - - size = H5Tget_size(tid); - - for (i = 0; i < nelmts; i++) - { - if (render_bin_output(stream,tid,mem + i * size)<0) - { - printf("\nError in writing binary stream\n"); - return FAIL; - } - } - - return SUCCEED; -} + HERR_INIT(int, SUCCEED) + unsigned char *mem = (unsigned char*)_mem; + size_t size; /* datum size */ + hsize_t i; /* element counter */ + if((size = H5Tget_size(tid)) == 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); + + for (i = 0; i < nelmts; i++) { + if (render_bin_output(stream, tid, mem + i * size) < 0) { + printf("\nError in writing binary stream\n"); + return FAIL; + } + } + +CATCH + return ret_value; +} /*------------------------------------------------------------------------- * Function: render_bin_output @@ -1548,395 +3510,372 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) * * Return: Success: SUCCEED * Failure: FAIL - * - * Programmer: Pedro Vicente Nunes - * Friday, June 2, 2006 - * - * Modifications: - * *------------------------------------------------------------------------- */ -static -int render_bin_output(FILE *stream, hid_t tid, void *_mem) +static int +render_bin_output(FILE *stream, hid_t tid, void *_mem) { - unsigned char *mem = (unsigned char*)_mem; - size_t size; /* datum size */ - float tempfloat; - double tempdouble; - unsigned long long tempullong; - long long templlong; - unsigned long tempulong; - long templong; - unsigned int tempuint; - int tempint; - unsigned short tempushort; - short tempshort; - unsigned char tempuchar; - char tempschar; + HERR_INIT(int, SUCCEED) + unsigned char *mem = (unsigned char*)_mem; + size_t size; /* datum size */ + float tempfloat; + double tempdouble; + unsigned long long tempullong; + long long templlong; + unsigned long tempulong; + long templong; + unsigned int tempuint; + int tempint; + unsigned short tempushort; + short tempshort; + unsigned char tempuchar; + char tempschar; #if H5_SIZEOF_LONG_DOUBLE !=0 - long double templdouble; + long double templdouble; #endif #ifdef DEBUG_H5DUMP_BIN - static char fmt_llong[8], fmt_ullong[8]; - if (!fmt_llong[0]) { - sprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH); - sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); - } + static char fmt_llong[8], fmt_ullong[8]; + if (!fmt_llong[0]) { + sprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH); + sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); + } #endif - size = H5Tget_size(tid); + if((size = H5Tget_size(tid)) == 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); - if (H5Tequal(tid, H5T_NATIVE_FLOAT)) - { - memcpy(&tempfloat, mem, sizeof(float)); + if (H5Tequal(tid, H5T_NATIVE_FLOAT)) { + memcpy(&tempfloat, mem, sizeof(float)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%g ", tempfloat); + fprintf(stream, "%g ", tempfloat); #else - if (1 != fwrite(&tempfloat, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempfloat, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_DOUBLE)) - { - memcpy(&tempdouble, mem, sizeof(double)); + } + else if (H5Tequal(tid, H5T_NATIVE_DOUBLE)) { + memcpy(&tempdouble, mem, sizeof(double)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%g ", tempdouble); + fprintf(stream, "%g ", tempdouble); #else - if (1 != fwrite(&tempdouble, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempdouble, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } + } #if H5_SIZEOF_LONG_DOUBLE !=0 - else if (H5Tequal(tid, H5T_NATIVE_LDOUBLE)) - { - memcpy(&templdouble, mem, sizeof(long double)); + else if (H5Tequal(tid, H5T_NATIVE_LDOUBLE)) { + memcpy(&templdouble, mem, sizeof(long double)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%Lf ", templdouble); + fprintf(stream, "%Lf ", templdouble); #else - if (1 != fwrite(&templdouble, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templdouble, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } + } #endif - else if (H5T_STRING == H5Tget_class(tid)) - { - unsigned int i; - H5T_str_t pad; - char *s; - - pad = H5Tget_strpad(tid); - - if(H5Tis_variable_str(tid)) - { - s = *(char**)mem; - if(s!=NULL) - size = HDstrlen(s); - } - else - { - s = (char *)mem; - size = H5Tget_size(tid); - } - for (i=0; i<size && (s[i] || pad!=H5T_STR_NULLTERM); i++) - { - memcpy(&tempuchar, &s[i], sizeof(unsigned char)); + else if (H5T_STRING == H5Tget_class(tid)) { + unsigned int i; + H5T_str_t pad; + char *s; + + pad = H5Tget_strpad(tid); + + if (H5Tis_variable_str(tid)) { + s = *(char**) mem; + if (s != NULL) + size = HDstrlen(s); + } + else { + s = (char *) mem; + if((size = H5Tget_size(tid)) == 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); + } + for (i = 0; i < size && (s[i] || pad != H5T_STR_NULLTERM); i++) { + memcpy(&tempuchar, &s[i], sizeof(unsigned char)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d", tempuchar); + fprintf(stream, "%d", tempuchar); #else - if (1 != fwrite(&tempuchar, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempuchar, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } /* i */ - } - else if (H5Tequal(tid, H5T_NATIVE_INT)) - { - memcpy(&tempint, mem, sizeof(int)); + } /* i */ + } + else if (H5Tequal(tid, H5T_NATIVE_INT)) { + memcpy(&tempint, mem, sizeof(int)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d ", tempint); + fprintf(stream, "%d ", tempint); #else - if (1 != fwrite(&tempint, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempint, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_UINT)) - { - memcpy(&tempuint, mem, sizeof(unsigned int)); + } + else if (H5Tequal(tid, H5T_NATIVE_UINT)) { + memcpy(&tempuint, mem, sizeof(unsigned int)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%u ", tempuint); + fprintf(stream, "%u ", tempuint); #else - if (1 != fwrite(&tempuint, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempuint, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_SCHAR)) - { - memcpy(&tempschar, mem, sizeof(char)); + } + else if (H5Tequal(tid, H5T_NATIVE_SCHAR)) { + memcpy(&tempschar, mem, sizeof(char)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d ", tempschar); + fprintf(stream, "%d ", tempschar); #else - if (1 != fwrite(&tempschar, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempschar, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_UCHAR)) - { - memcpy(&tempuchar, mem, sizeof(unsigned char)); + } + else if (H5Tequal(tid, H5T_NATIVE_UCHAR)) { + memcpy(&tempuchar, mem, sizeof(unsigned char)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%u ", tempuchar); + fprintf(stream, "%u ", tempuchar); #else - if (1 != fwrite(&tempuchar, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempuchar, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_SHORT)) - { - memcpy(&tempshort, mem, sizeof(short)); + } + else if (H5Tequal(tid, H5T_NATIVE_SHORT)) { + memcpy(&tempshort, mem, sizeof(short)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d ", tempshort); + fprintf(stream, "%d ", tempshort); #else - if (1 != fwrite(&tempshort, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempshort, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_USHORT)) - { - memcpy(&tempushort, mem, sizeof(unsigned short)); + } + else if (H5Tequal(tid, H5T_NATIVE_USHORT)) { + memcpy(&tempushort, mem, sizeof(unsigned short)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%u ", tempushort); + fprintf(stream, "%u ", tempushort); #else - if (1 != fwrite(&tempushort, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempushort, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_LONG)) - { - memcpy(&templong, mem, sizeof(long)); + } + else if (H5Tequal(tid, H5T_NATIVE_LONG)) { + memcpy(&templong, mem, sizeof(long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%ld ", templong); + fprintf(stream, "%ld ", templong); #else - if (1 != fwrite(&templong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_ULONG)) - { - memcpy(&tempulong, mem, sizeof(unsigned long)); + } + else if (H5Tequal(tid, H5T_NATIVE_ULONG)) { + memcpy(&tempulong, mem, sizeof(unsigned long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%lu ", tempulong); + fprintf(stream, "%lu ", tempulong); #else - if (1 != fwrite(&tempulong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempulong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_LLONG)) - { - memcpy(&templlong, mem, sizeof(long long)); + } + else if (H5Tequal(tid, H5T_NATIVE_LLONG)) { + memcpy(&templlong, mem, sizeof(long long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, fmt_llong, templlong); + fprintf(stream, fmt_llong, templlong); #else - if (1 != fwrite(&templlong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templlong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_ULLONG)) - { - memcpy(&tempullong, mem, sizeof(unsigned long long)); + } + else if (H5Tequal(tid, H5T_NATIVE_ULLONG)) { + memcpy(&tempullong, mem, sizeof(unsigned long long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, fmt_ullong, tempullong); + fprintf(stream, fmt_ullong, tempullong); #else - if (1 != fwrite(&tempullong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempullong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (H5Tequal(tid, H5T_NATIVE_HSSIZE)) - { - if (sizeof(hssize_t) == sizeof(int)) - { - memcpy(&tempint, mem, sizeof(int)); + } + else if (H5Tequal(tid, H5T_NATIVE_HSSIZE)) { + if (sizeof(hssize_t) == sizeof(int)) { + memcpy(&tempint, mem, sizeof(int)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%d ", tempint); + fprintf(stream, "%d ", tempint); #else - if (1 != fwrite(&tempint, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempint, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (sizeof(hssize_t) == sizeof(long)) - { - memcpy(&templong, mem, sizeof(long)); + } + else if (sizeof(hssize_t) == sizeof(long)) { + memcpy(&templong, mem, sizeof(long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%ld ", templong); + fprintf(stream, "%ld ", templong); #else - if (1 != fwrite(&templong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else - { - memcpy(&templlong, mem, sizeof(long long)); + } + else { + memcpy(&templlong, mem, sizeof(long long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, fmt_llong, templlong); + fprintf(stream, fmt_llong, templlong); #else - if (1 != fwrite(&templlong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&templlong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - } - else if (H5Tequal(tid, H5T_NATIVE_HSIZE)) - { - if (sizeof(hsize_t) == sizeof(int)) - { - memcpy(&tempuint, mem, sizeof(unsigned int)); + } + } + else if (H5Tequal(tid, H5T_NATIVE_HSIZE)) { + if (sizeof(hsize_t) == sizeof(int)) { + memcpy(&tempuint, mem, sizeof(unsigned int)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%u ", tempuint); + fprintf(stream, "%u ", tempuint); #else - if (1 != fwrite(&tempuint, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempuint, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else if (sizeof(hsize_t) == sizeof(long)) - { - memcpy(&tempulong, mem, sizeof(unsigned long)); + } + else if (sizeof(hsize_t) == sizeof(long)) { + memcpy(&tempulong, mem, sizeof(unsigned long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%lu ", tempulong); + fprintf(stream, "%lu ", tempulong); #else - if (1 != fwrite(&tempulong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempulong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else - { - memcpy(&tempullong, mem, sizeof(unsigned long long)); + } + else { + memcpy(&tempullong, mem, sizeof(unsigned long long)); #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, fmt_ullong, tempullong); + fprintf(stream, fmt_ullong, tempullong); #else - if (1 != fwrite(&tempullong, size, 1, stream)) - return FAIL; + if (1 != fwrite(&tempullong, size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - } - else if (H5Tget_class(tid) == H5T_COMPOUND) - { - unsigned j; - hid_t memb; - unsigned nmembs; - size_t offset; - - nmembs = H5Tget_nmembers(tid); - - for (j = 0; j < nmembs; j++) - { - offset = H5Tget_member_offset(tid, j); - memb = H5Tget_member_type(tid, j); - - if (render_bin_output(stream,memb,mem + offset)<0) - return FAIL; - - H5Tclose(memb); - } - } - else if (H5Tget_class(tid) == H5T_ENUM) - { - unsigned int i; - if (1==size) - { + } + } + else if (H5Tget_class(tid) == H5T_COMPOUND) { + unsigned j; + hid_t memb; + unsigned nmembs; + size_t offset; + + nmembs = H5Tget_nmembers(tid); + + for (j = 0; j < nmembs; j++) { + offset = H5Tget_member_offset(tid, j); + memb = H5Tget_member_type(tid, j); + + if (render_bin_output(stream, memb, mem + offset) < 0) + return FAIL; + + H5Tclose(memb); + } + } + else if (H5Tget_class(tid) == H5T_ENUM) { + unsigned int i; + if (1 == size) { #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "0x%02x", mem[0]); + fprintf(stream, "0x%02x", mem[0]); #else - if (1 != fwrite(&mem[0], size, 1, stream)) - return FAIL; + if (1 != fwrite(&mem[0], size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else - { - for (i = 0; i < size; i++) - { + } + else { + for (i = 0; i < size; i++) { #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%s%02x", i?":":"", mem[i]); + fprintf(stream, "%s%02x", i?":":"", mem[i]); #else - if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) - return FAIL; + if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } /*i*/ - }/*else 1 */ - } - else if (H5Tget_class(tid) == H5T_ARRAY) - { - int k, ndims; - hsize_t i, dims[H5S_MAX_RANK], temp_nelmts, nelmts; - hid_t memb; - - /* get the array's base datatype for each element */ - memb = H5Tget_super(tid); - size = H5Tget_size(memb); - ndims = H5Tget_array_ndims(tid); - H5Tget_array_dims2(tid, dims); - assert(ndims >= 1 && ndims <= H5S_MAX_RANK); - - /* calculate the number of array elements */ - for (k = 0, nelmts = 1; k < ndims; k++) - { - temp_nelmts = nelmts; - temp_nelmts *= dims[k]; - nelmts = (size_t)temp_nelmts; - } - - /* dump the array element */ - for (i = 0; i < nelmts; i++) - { - if (render_bin_output(stream,memb,mem + i * size)<0) - return FAIL; - } - - H5Tclose(memb); - } - else if (H5Tget_class(tid) == H5T_VLEN) - { - unsigned int i; - hsize_t nelmts; - hid_t memb; - - /* get the VL sequences's base datatype for each element */ - memb = H5Tget_super(tid); - size = H5Tget_size(memb); - - /* Get the number of sequence elements */ - nelmts = ((hvl_t *)mem)->len; - - for (i = 0; i < nelmts; i++) - { - /* dump the array element */ - if (render_bin_output(stream,memb,((char *)(((hvl_t *)mem)->p)) + i * size)<0) - return FAIL; - } - H5Tclose(memb); - } - else - { - size_t i; - if (1==size) - { + } /*i*/ + }/*else 1 */ + } + else if (H5Tget_class(tid) == H5T_ARRAY) { + int k, ndims; + hsize_t i, dims[H5S_MAX_RANK], temp_nelmts, nelmts; + hid_t memb; + + /* get the array's base datatype for each element */ + memb = H5Tget_super(tid); + size = H5Tget_size(memb); + ndims = H5Tget_array_ndims(tid); + H5Tget_array_dims2(tid, dims); + assert(ndims >= 1 && ndims <= H5S_MAX_RANK); + + /* calculate the number of array elements */ + for (k = 0, nelmts = 1; k < ndims; k++) { + temp_nelmts = nelmts; + temp_nelmts *= dims[k]; + nelmts = (size_t) temp_nelmts; + } + + /* dump the array element */ + for (i = 0; i < nelmts; i++) { + if (render_bin_output(stream, memb, mem + i * size) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "render_bin_output failed"); + } + + H5Tclose(memb); + } + else if (H5Tget_class(tid) == H5T_VLEN) { + unsigned int i; + hsize_t nelmts; + hid_t memb; + + /* get the VL sequences's base datatype for each element */ + memb = H5Tget_super(tid); + size = H5Tget_size(memb); + + /* Get the number of sequence elements */ + nelmts = ((hvl_t *) mem)->len; + + for (i = 0; i < nelmts; i++) { + /* dump the array element */ + if (render_bin_output(stream, memb, ((char *) (((hvl_t *) mem)->p)) + i * size) < 0) + H5E_THROW(FAIL, H5E_tools_min_id_g, "render_bin_output failed"); + } + H5Tclose(memb); + } + else { + size_t i; + if (1 == size) { #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "0x%02x", mem[0]); + fprintf(stream, "0x%02x", mem[0]); #else - if (1 != fwrite(&mem[0], size, 1, stream)) - return FAIL; + if (1 != fwrite(&mem[0], size, 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } - else - { - for (i = 0; i < size; i++) - { + } + else { + for (i = 0; i < size; i++) { #ifdef DEBUG_H5DUMP_BIN - fprintf(stream, "%s%02x", i?":":"", mem[i]); + fprintf(stream, "%s%02x", i?":":"", mem[i]); #else - if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) - return FAIL; + if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) + H5E_THROW(FAIL, H5E_tools_min_id_g, "fwrite failed"); #endif - } /*i*/ - }/*else 1 */ - } + } /*i*/ + }/*else 1 */ + } + +CATCH + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: h5tools_is_zero + * + * Purpose: Determines if memory is initialized to all zero bytes. + * + * Return: TRUE if all bytes are zero; FALSE otherwise + *------------------------------------------------------------------------- + */ +static +hbool_t h5tools_is_zero(const void *_mem, size_t size) +{ + const unsigned char *mem = (const unsigned char *) _mem; + while (size-- > 0) + if (mem[size]) + return FALSE; - return SUCCEED; + return TRUE; } |