summaryrefslogtreecommitdiffstats
path: root/tools/src
diff options
context:
space:
mode:
authorAllen Byrne <byrn@hdfgroup.org>2016-10-27 15:06:00 (GMT)
committerAllen Byrne <byrn@hdfgroup.org>2016-10-27 15:06:00 (GMT)
commit2c6dbbf2129c4997606be4b130346d42fe12eae3 (patch)
treedb8430aa5757b32f3bd46928798cc2b686a72bfb /tools/src
parent5b562d9ce9b2945d0378b9c03e01f42923da80f4 (diff)
downloadhdf5-2c6dbbf2129c4997606be4b130346d42fe12eae3.zip
hdf5-2c6dbbf2129c4997606be4b130346d42fe12eae3.tar.gz
hdf5-2c6dbbf2129c4997606be4b130346d42fe12eae3.tar.bz2
Split tools into src and test - add folders
Diffstat (limited to 'tools/src')
-rw-r--r--tools/src/CMakeLists.txt37
-rw-r--r--tools/src/Makefile.am29
-rw-r--r--tools/src/h5copy/CMakeLists.txt39
-rw-r--r--tools/src/h5copy/Makefile.am40
-rw-r--r--tools/src/h5copy/h5copy.c534
-rw-r--r--tools/src/h5diff/CMakeLists.txt67
-rw-r--r--tools/src/h5diff/Makefile.am46
-rw-r--r--tools/src/h5diff/h5diff_common.c607
-rw-r--r--tools/src/h5diff/h5diff_common.h36
-rw-r--r--tools/src/h5diff/h5diff_main.c145
-rw-r--r--tools/src/h5diff/ph5diff_main.c329
-rw-r--r--tools/src/h5dump/CMakeLists.txt43
-rw-r--r--tools/src/h5dump/Makefile.am38
-rw-r--r--tools/src/h5dump/h5dump.c1802
-rw-r--r--tools/src/h5dump/h5dump.h115
-rw-r--r--tools/src/h5dump/h5dump_ddl.c2178
-rw-r--r--tools/src/h5dump/h5dump_ddl.h52
-rw-r--r--tools/src/h5dump/h5dump_defines.h56
-rw-r--r--tools/src/h5dump/h5dump_extern.h114
-rw-r--r--tools/src/h5dump/h5dump_xml.c4567
-rw-r--r--tools/src/h5dump/h5dump_xml.h39
-rw-r--r--tools/src/h5format_convert/CMakeLists.txt39
-rw-r--r--tools/src/h5format_convert/Makefile.am35
-rw-r--r--tools/src/h5format_convert/h5format_convert.c474
-rw-r--r--tools/src/h5import/CMakeLists.txt40
-rw-r--r--tools/src/h5import/Makefile.am35
-rw-r--r--tools/src/h5import/h5import.c4393
-rw-r--r--tools/src/h5import/h5import.h198
-rw-r--r--tools/src/h5jam/CMakeLists.txt49
-rw-r--r--tools/src/h5jam/Makefile.am35
-rw-r--r--tools/src/h5jam/h5jam.c571
-rw-r--r--tools/src/h5jam/h5unjam.c411
-rw-r--r--tools/src/h5ls/CMakeLists.txt41
-rw-r--r--tools/src/h5ls/Makefile.am35
-rw-r--r--tools/src/h5ls/h5ls.c2939
-rw-r--r--tools/src/h5repack/CMakeLists.txt50
-rw-r--r--tools/src/h5repack/Makefile.am42
-rw-r--r--tools/src/h5repack/h5repack.c942
-rw-r--r--tools/src/h5repack/h5repack.h243
-rw-r--r--tools/src/h5repack/h5repack_copy.c1581
-rw-r--r--tools/src/h5repack/h5repack_filters.c493
-rw-r--r--tools/src/h5repack/h5repack_main.c664
-rw-r--r--tools/src/h5repack/h5repack_opttable.c367
-rw-r--r--tools/src/h5repack/h5repack_parse.c616
-rw-r--r--tools/src/h5repack/h5repack_refs.c877
-rw-r--r--tools/src/h5repack/h5repack_verify.c675
-rw-r--r--tools/src/h5stat/CMakeLists.txt39
-rw-r--r--tools/src/h5stat/Makefile.am39
-rw-r--r--tools/src/h5stat/h5stat.c1815
-rw-r--r--tools/src/h5stat/testh5stat.sh.in318
-rw-r--r--tools/src/misc/CMakeLists.txt67
-rw-r--r--tools/src/misc/Makefile.am61
-rw-r--r--tools/src/misc/h5cc.in401
-rw-r--r--tools/src/misc/h5debug.c723
-rw-r--r--tools/src/misc/h5mkgrp.c336
-rw-r--r--tools/src/misc/h5redeploy.in218
-rw-r--r--tools/src/misc/h5repart.c510
57 files changed, 31285 insertions, 0 deletions
diff --git a/tools/src/CMakeLists.txt b/tools/src/CMakeLists.txt
new file mode 100644
index 0000000..5001b26
--- /dev/null
+++ b/tools/src/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC)
+
+#-----------------------------------------------------------------------------
+# Apply Definitions to compiler in this directory and below
+#-----------------------------------------------------------------------------
+add_definitions (${HDF_EXTRA_C_FLAGS})
+
+#-- Add the h5diff and test executables
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/h5diff)
+
+#-- Add the h5ls executable
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/h5ls)
+
+#-- Misc Executables
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/misc)
+
+#-- Add the h5import and test executables
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/h5import)
+
+#-- h5Repack executables
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/h5repack)
+
+#-- Add the h5dump and test executables
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/h5jam)
+
+#-- Add the h5copy and test executables
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/h5copy)
+
+#-- Add the h5stat and test executables
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/h5stat)
+
+#-- Add the h5dump and test executables
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/h5dump)
+
+#-- Add the h5format_convert and test executables
+add_subdirectory (${HDF5_TOOLS_SRC_SOURCE_DIR}/h5format_convert)
diff --git a/tools/src/Makefile.am b/tools/src/Makefile.am
new file mode 100644
index 0000000..0cea969
--- /dev/null
+++ b/tools/src/Makefile.am
@@ -0,0 +1,29 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+##
+#
+# Tools HDF5 Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+CONFIG=ordered
+
+# All subdirectories
+SUBDIRS=h5diff h5ls h5dump misc h5import h5repack h5jam h5copy h5stat
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/h5copy/CMakeLists.txt b/tools/src/h5copy/CMakeLists.txt
new file mode 100644
index 0000000..2a33c9e
--- /dev/null
+++ b/tools/src/h5copy/CMakeLists.txt
@@ -0,0 +1,39 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_H5COPY)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+
+# --------------------------------------------------------------------
+# Add the h5copy and test executables
+# --------------------------------------------------------------------
+add_executable (h5copy ${HDF5_TOOLS_SRC_H5COPY_SOURCE_DIR}/h5copy.c)
+TARGET_NAMING (h5copy STATIC)
+TARGET_C_PROPERTIES (h5copy STATIC " " " ")
+target_link_libraries (h5copy ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5copy PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5copy")
+
+set (H5_DEP_EXECUTABLES h5copy)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5copy ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5copy
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
diff --git a/tools/src/h5copy/Makefile.am b/tools/src/h5copy/Makefile.am
new file mode 100644
index 0000000..b2cdf92
--- /dev/null
+++ b/tools/src/h5copy/Makefile.am
@@ -0,0 +1,40 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src and tools/lib directories
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+# This is our main target, the h5copy tool
+bin_PROGRAMS=h5copy
+check_PROGRAMS=$(TEST_PROG)
+
+# Add h5copy specific linker flags here
+h5copy_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# All programs depend on the hdf5 and h5tools libraries
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+# Temporary files. *.h5 are generated by h5dumpgentest. They should
+# copied to the testfiles/ directory if update is required.
+CHECK_CLEANFILES+=*.h5
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/h5copy/h5copy.c b/tools/src/h5copy/h5copy.c
new file mode 100644
index 0000000..5371a21
--- /dev/null
+++ b/tools/src/h5copy/h5copy.c
@@ -0,0 +1,534 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+#include <string.h>
+#include <stdlib.h>
+
+/* Name of tool */
+#define PROGRAMNAME "h5copy"
+
+/* command-line options: short and long-named parameters */
+static const char *s_opts = "d:f:hi:o:ps:vVE";
+static struct long_options l_opts[] = {
+ { "destination", require_arg, 'd' },
+ { "flag", require_arg, 'f' },
+ { "help", no_arg, 'h' },
+ { "input", require_arg, 'i' },
+ { "output", require_arg, 'o' },
+ { "parents", no_arg, 'p' },
+ { "source", require_arg, 's' },
+ { "verbose", no_arg, 'v' },
+ { "version", no_arg, 'V' },
+ { "enable-error-stack", no_arg, 'E' },
+ { NULL, 0, '\0' }
+};
+char *fname_src = NULL;
+char *fname_dst = NULL;
+char *oname_src = NULL;
+char *oname_dst = NULL;
+char *str_flag = NULL;
+
+/*-------------------------------------------------------------------------
+ * Function: leave
+ *
+ * Purpose: Shutdown MPI & HDF5 and call exit()
+ *
+ * Return: Does not return
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, 31. January 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+leave(int ret)
+{
+ if (fname_src)
+ HDfree(fname_src);
+ if (fname_dst)
+ HDfree(fname_dst);
+ if (oname_dst)
+ HDfree(oname_dst);
+ if (oname_src)
+ HDfree(oname_src);
+ if (str_flag)
+ HDfree(str_flag);
+
+ h5tools_close();
+ HDexit(ret);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Prints a usage message on stderr and then returns.
+ *
+ * Return: void
+ *
+ * Programmer: Pedro Vicente Nunes, 7/8/2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage (void)
+{
+ FLUSHSTREAM(rawoutstream);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "usage: h5copy [OPTIONS] [OBJECTS...]\n");
+ PRINTVALSTREAM(rawoutstream, " OBJECTS\n");
+ PRINTVALSTREAM(rawoutstream, " -i, --input input file name\n");
+ PRINTVALSTREAM(rawoutstream, " -o, --output output file name\n");
+ PRINTVALSTREAM(rawoutstream, " -s, --source source object name\n");
+ PRINTVALSTREAM(rawoutstream, " -d, --destination destination object name\n");
+ PRINTVALSTREAM(rawoutstream, " OPTIONS\n");
+ PRINTVALSTREAM(rawoutstream, " -h, --help Print a usage message and exit\n");
+ PRINTVALSTREAM(rawoutstream, " -p, --parents No error if existing, make parent groups as needed\n");
+ PRINTVALSTREAM(rawoutstream, " -v, --verbose Print information about OBJECTS and OPTIONS\n");
+ PRINTVALSTREAM(rawoutstream, " -V, --version Print version number and exit\n");
+ PRINTVALSTREAM(rawoutstream, " -f, --flag Flag type\n\n");
+ PRINTVALSTREAM(rawoutstream, " Flag type is one of the following strings:\n\n");
+ PRINTVALSTREAM(rawoutstream, " shallow Copy only immediate members for groups\n\n");
+ PRINTVALSTREAM(rawoutstream, " soft Expand soft links into new objects\n\n");
+ PRINTVALSTREAM(rawoutstream, " ext Expand external links into new objects\n\n");
+ PRINTVALSTREAM(rawoutstream, " ref Copy references and any referenced objects, i.e., objects\n");
+ PRINTVALSTREAM(rawoutstream, " that the references point to.\n");
+ PRINTVALSTREAM(rawoutstream, " Referenced objects are copied in addition to the objects\n");
+ PRINTVALSTREAM(rawoutstream, " specified on the command line and reference datasets are\n");
+ PRINTVALSTREAM(rawoutstream, " populated with correct reference values. Copies of referenced\n");
+ PRINTVALSTREAM(rawoutstream, " datasets outside the copy range specified on the command line\n");
+ PRINTVALSTREAM(rawoutstream, " will normally have a different name from the original.\n");
+ PRINTVALSTREAM(rawoutstream, " (Default:Without this option, reference value(s) in any\n");
+ PRINTVALSTREAM(rawoutstream, " reference datasets are set to NULL and referenced objects are\n");
+ PRINTVALSTREAM(rawoutstream, " not copied unless they are otherwise within the copy range\n");
+ PRINTVALSTREAM(rawoutstream, " specified on the command line.)\n\n");
+ PRINTVALSTREAM(rawoutstream, " noattr Copy object without copying attributes\n\n");
+ PRINTVALSTREAM(rawoutstream, " allflags Switches all flags from the default to the non-default setting\n\n");
+ PRINTVALSTREAM(rawoutstream, " These flag types correspond to the following API symbols\n\n");
+ PRINTVALSTREAM(rawoutstream, " H5O_COPY_SHALLOW_HIERARCHY_FLAG\n");
+ PRINTVALSTREAM(rawoutstream, " H5O_COPY_EXPAND_SOFT_LINK_FLAG\n");
+ PRINTVALSTREAM(rawoutstream, " H5O_COPY_EXPAND_EXT_LINK_FLAG\n");
+ PRINTVALSTREAM(rawoutstream, " H5O_COPY_EXPAND_REFERENCE_FLAG\n");
+ PRINTVALSTREAM(rawoutstream, " H5O_COPY_WITHOUT_ATTR_FLAG\n");
+ PRINTVALSTREAM(rawoutstream, " H5O_COPY_ALL\n");
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: parse_flag
+ *
+ * Purpose: read the flag -f STRING
+ *
+ * STRING is one of the following (API symbol and description)
+ *
+ * shallow H5O_COPY_SHALLOW_HIERARCHY_FLAG: Copy only immediate members for groups
+ * soft H5O_COPY_EXPAND_SOFT_LINK_FLAG: Expand soft links into new objects
+ * ext H5O_COPY_EXPAND_EXT_LINK_FLAG: Expand external links into new objects
+ * ref H5O_COPY_EXPAND_OBJ_REFERENCE_FLAG: Copy objects that are pointed by references
+ * noattr H5O_COPY_WITHOUT_ATTR_FLAG Copy object without copying attributes
+ * allflags Switches all flags from the default to the non-default setting
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Pedro Vicente Nunes, 7/8/2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+
+static int parse_flag(const char* s_flag, unsigned *flag)
+{
+ unsigned fla=0;
+
+ if (HDstrcmp(s_flag,"shallow")==0)
+ {
+ fla = H5O_COPY_SHALLOW_HIERARCHY_FLAG;
+ }
+ else if (HDstrcmp(s_flag,"soft")==0)
+ {
+ fla = H5O_COPY_EXPAND_SOFT_LINK_FLAG;
+ }
+ else if (HDstrcmp(s_flag,"ext")==0)
+ {
+ fla = H5O_COPY_EXPAND_EXT_LINK_FLAG;
+ }
+ else if (HDstrcmp(s_flag,"ref")==0)
+ {
+ fla = H5O_COPY_EXPAND_REFERENCE_FLAG;
+ }
+ else if (HDstrcmp(s_flag,"noattr")==0)
+ {
+ fla = H5O_COPY_WITHOUT_ATTR_FLAG;
+ }
+ else if (HDstrcmp(s_flag,"allflags")==0)
+ {
+ fla = H5O_COPY_ALL;
+ }
+ else if (HDstrcmp(s_flag,"nullmsg")==0)
+ {
+ fla = H5O_COPY_PRESERVE_NULL_FLAG;
+ }
+ else
+ {
+ error_msg("Error in input flag\n");
+ return -1;
+ }
+
+ *flag = (*flag) | fla;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: main program
+ *
+ * Programmer: Pedro Vicente Nunes
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int
+main (int argc, const char *argv[])
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ H5E_auto2_t func;
+ H5E_auto2_t tools_func;
+ void *edata;
+ void *tools_edata;
+ hid_t fid_src = -1;
+ hid_t fid_dst = -1;
+ unsigned flag = 0;
+ unsigned verbose = 0;
+ unsigned parents = 0;
+ hid_t ocpl_id = (-1); /* Object copy property list */
+ hid_t lcpl_id = (-1); /* Link creation property list */
+ int opt;
+ int li_ret;
+ h5tool_link_info_t linkinfo;
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Disable error reporting */
+ H5Eget_auto2(H5E_DEFAULT, &func, &edata);
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /* Disable tools error reporting */
+ H5Eget_auto2(H5tools_ERR_STACK_g, &tools_func, &tools_edata);
+ H5Eset_auto2(H5tools_ERR_STACK_g, NULL, NULL);
+
+ /* init linkinfo struct */
+ HDmemset(&linkinfo, 0, sizeof(h5tool_link_info_t));
+
+ /* Check for no command line parameters */
+ if(argc == 1)
+ {
+ usage();
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* parse command line options */
+ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF)
+ {
+ switch ((char)opt)
+ {
+ case 'd':
+ oname_dst = HDstrdup(opt_arg);
+ break;
+
+ case 'f':
+ /* validate flag */
+ if (parse_flag(opt_arg,&flag)<0)
+ {
+ usage();
+ leave(EXIT_FAILURE);
+ }
+ str_flag = HDstrdup(opt_arg);
+ break;
+
+ case 'h':
+ usage();
+ leave(EXIT_SUCCESS);
+ break;
+
+ case 'i':
+ fname_src = HDstrdup(opt_arg);
+ break;
+
+ case 'o':
+ fname_dst = HDstrdup(opt_arg);
+ break;
+
+ case 'p':
+ parents = 1;
+ break;
+
+ case 's':
+ oname_src = HDstrdup(opt_arg);
+ break;
+
+ case 'V':
+ print_version(h5tools_getprogname());
+ leave(EXIT_SUCCESS);
+ break;
+
+ case 'v':
+ verbose = 1;
+ break;
+
+ case 'E':
+ enable_error_stack = TRUE;
+ break;
+
+ default:
+ usage();
+ leave(EXIT_FAILURE);
+ }
+ } /* end of while */
+
+/*-------------------------------------------------------------------------
+ * check for missing file/object names
+ *-------------------------------------------------------------------------*/
+
+ if (fname_src==NULL)
+ {
+ error_msg("Input file name missing\n");
+ usage();
+ leave(EXIT_FAILURE);
+ }
+
+ if (fname_dst==NULL)
+ {
+ error_msg("Output file name missing\n");
+ usage();
+ leave(EXIT_FAILURE);
+ }
+
+ if (oname_src==NULL)
+ {
+ error_msg("Source object name missing\n");
+ usage();
+ leave(EXIT_FAILURE);
+ }
+
+ if (oname_dst==NULL)
+ {
+ error_msg("Destination object name missing\n");
+ usage();
+ leave(EXIT_FAILURE);
+ }
+
+ if (enable_error_stack) {
+ H5Eset_auto2(H5E_DEFAULT, func, edata);
+ H5Eset_auto2(H5tools_ERR_STACK_g, tools_func, tools_edata);
+ }
+
+ /*-------------------------------------------------------------------------
+ * open output file
+ *-------------------------------------------------------------------------*/
+
+ /* Attempt to open an existing HDF5 file first. Need to open the dst file
+ before the src file just in case that the dst and src are the same file
+ */
+ fid_dst = h5tools_fopen(fname_dst, H5F_ACC_RDWR, H5P_DEFAULT, NULL, NULL, 0);
+
+ /*-------------------------------------------------------------------------
+ * open input file
+ *-------------------------------------------------------------------------*/
+
+ fid_src = h5tools_fopen(fname_src, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, 0);
+
+ /*-------------------------------------------------------------------------
+ * test for error in opening input file
+ *-------------------------------------------------------------------------*/
+ if (fid_src==-1)
+ {
+ error_msg("Could not open input file <%s>...Exiting\n", fname_src);
+ leave(EXIT_FAILURE);
+ }
+
+
+ /*-------------------------------------------------------------------------
+ * create an output file when failed to open it
+ *-------------------------------------------------------------------------*/
+
+ /* If we couldn't open an existing file, try creating file */
+ /* (use "EXCL" instead of "TRUNC", so we don't blow away existing non-HDF5 file) */
+ if(fid_dst < 0)
+ fid_dst = H5Fcreate(fname_dst, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
+
+ /*-------------------------------------------------------------------------
+ * test for error in opening output file
+ *-------------------------------------------------------------------------*/
+ if (fid_dst==-1)
+ {
+ error_msg("Could not open output file <%s>...Exiting\n", fname_dst);
+ leave(EXIT_FAILURE);
+ }
+
+ /*-------------------------------------------------------------------------
+ * print some info
+ *-------------------------------------------------------------------------*/
+
+ if (verbose)
+ {
+ printf("Copying file <%s> and object <%s> to file <%s> and object <%s>\n",
+ fname_src, oname_src, fname_dst, oname_dst);
+ if (flag) {
+ HDassert(str_flag);
+ printf("Using %s flag\n", str_flag);
+ }
+ }
+
+
+ /*-------------------------------------------------------------------------
+ * create property lists for copy
+ *-------------------------------------------------------------------------*/
+
+ /* create property to pass copy options */
+ if ( (ocpl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0)
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Pcreate failed");
+
+ /* set options for object copy */
+ if (flag)
+ {
+ if ( H5Pset_copy_object(ocpl_id, flag) < 0)
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Pset_copy_object failed");
+ }
+
+ /* Create link creation property list */
+ if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) {
+ error_msg("Could not create link creation property list\n");
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Pcreate failed");
+ } /* end if */
+
+ /* Check for creating intermediate groups */
+ if(parents) {
+ /* Set the intermediate group creation property */
+ if(H5Pset_create_intermediate_group(lcpl_id, 1) < 0) {
+ error_msg("Could not set property for creating parent groups\n");
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Pset_create_intermediate_group failed");
+ } /* end if */
+
+ /* Display some output if requested */
+ if(verbose)
+ printf("%s: Creating parent groups\n", h5tools_getprogname());
+ } /* end if */
+ else /* error, if parent groups doesn't already exist in destination file */
+ {
+ size_t i, len;
+
+ len = HDstrlen(oname_dst);
+
+ /* check if all the parents groups exist. skip root group */
+ for (i = 1; i < len; i++)
+ {
+ if ('/'==oname_dst[i])
+ {
+ char *str_ptr;
+
+ str_ptr = (char *)HDcalloc(i + 1, sizeof(char));
+ HDstrncpy(str_ptr, oname_dst, i);
+ str_ptr[i]='\0';
+ if (H5Lexists(fid_dst, str_ptr, H5P_DEFAULT) <= 0)
+ {
+ error_msg("group <%s> doesn't exist. Use -p to create parent groups.\n", str_ptr);
+ HDfree(str_ptr);
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Lexists failed");
+ }
+ HDfree(str_ptr);
+ }
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * do the copy
+ *-------------------------------------------------------------------------*/
+
+ if(verbose)
+ linkinfo.opt.msg_mode = 1;
+
+ li_ret = H5tools_get_symlink_info(fid_src, oname_src, &linkinfo, 1);
+ if (li_ret == 0) /* dangling link */
+ {
+ if(H5Lcopy(fid_src, oname_src,
+ fid_dst, oname_dst,
+ H5P_DEFAULT, H5P_DEFAULT) < 0)
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Lcopy failed");
+ }
+ else /* valid link */
+ {
+ if (H5Ocopy(fid_src, /* Source file or group identifier */
+ oname_src, /* Name of the source object to be copied */
+ fid_dst, /* Destination file or group identifier */
+ oname_dst, /* Name of the destination object */
+ ocpl_id, /* Object copy property list */
+ lcpl_id)<0) /* Link creation property list */
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Ocopy failed");
+ }
+
+ /* free link info path */
+ if (linkinfo.trg_path)
+ HDfree(linkinfo.trg_path);
+
+ /* close propertis */
+ if(H5Pclose(ocpl_id)<0)
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Pclose failed");
+ if(H5Pclose(lcpl_id)<0)
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Pclose failed");
+
+ /* close files */
+ if (H5Fclose(fid_src)<0)
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Fclose failed");
+ if (H5Fclose(fid_dst)<0)
+ HGOTO_ERROR(EXIT_FAILURE, H5E_tools_min_id_g, "H5Fclose failed");
+
+ leave(EXIT_SUCCESS);
+
+done:
+ printf("Error in copy...Exiting\n");
+
+ /* free link info path */
+ if (linkinfo.trg_path)
+ HDfree(linkinfo.trg_path);
+
+ H5E_BEGIN_TRY {
+ H5Pclose(ocpl_id);
+ H5Pclose(lcpl_id);
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ } H5E_END_TRY;
+
+ leave(ret_value);
+}
+
diff --git a/tools/src/h5diff/CMakeLists.txt b/tools/src/h5diff/CMakeLists.txt
new file mode 100644
index 0000000..85a24ef
--- /dev/null
+++ b/tools/src/h5diff/CMakeLists.txt
@@ -0,0 +1,67 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_H5DIFF)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+
+# --------------------------------------------------------------------
+# Add the h5diff executables
+# --------------------------------------------------------------------
+add_executable (h5diff
+ ${HDF5_TOOLS_SRC_H5DIFF_SOURCE_DIR}/h5diff_common.c
+ ${HDF5_TOOLS_SRC_H5DIFF_SOURCE_DIR}/h5diff_main.c
+)
+TARGET_NAMING (h5diff STATIC)
+TARGET_C_PROPERTIES (h5diff STATIC " " " ")
+target_link_libraries (h5diff ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5diff PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5diff")
+
+set (H5_DEP_EXECUTABLES h5diff)
+
+if (H5_HAVE_PARALLEL)
+ add_executable (ph5diff
+ ${HDF5_TOOLS_SRC_H5DIFF_SOURCE_DIR}/h5diff_common.c
+ ${HDF5_TOOLS_SRC_H5DIFF_SOURCE_DIR}/ph5diff_main.c
+ )
+ TARGET_NAMING (ph5diff STATIC)
+ TARGET_C_PROPERTIES (ph5diff STATIC " " " ")
+ target_link_libraries (ph5diff ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+ set_target_properties (ph5diff PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};ph5diff")
+endif (H5_HAVE_PARALLEL)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5diff ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5diff
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
+
+if (H5_HAVE_PARALLEL)
+
+ #INSTALL_PROGRAM_PDB (ph5diff ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+ install (
+ TARGETS
+ ph5diff
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+ )
+endif (H5_HAVE_PARALLEL)
diff --git a/tools/src/h5diff/Makefile.am b/tools/src/h5diff/Makefile.am
new file mode 100644
index 0000000..a5af3f2
--- /dev/null
+++ b/tools/src/h5diff/Makefile.am
@@ -0,0 +1,46 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src and tools/lib directories
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+# Always build and test h5diff but build and test ph5diff only if parallel
+# is enabled.
+if BUILD_PARALLEL_CONDITIONAL
+ H5PDIFF=ph5diff
+endif
+
+# Our main target, h5diff
+bin_PROGRAMS=h5diff $(H5PDIFF)
+
+# Add h5diff specific linker flags here
+h5diff_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# Source files for the program
+h5diff_SOURCES=h5diff_main.c h5diff_common.c
+ph5diff_SOURCES=ph5diff_main.c h5diff_common.c
+
+# Programs depend on the main HDF5 library and tools library
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+include $(top_srcdir)/config/conclude.am
+
diff --git a/tools/src/h5diff/h5diff_common.c b/tools/src/h5diff/h5diff_common.c
new file mode 100644
index 0000000..2453ffc
--- /dev/null
+++ b/tools/src/h5diff/h5diff_common.c
@@ -0,0 +1,607 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <string.h>
+#include "H5private.h"
+#include "h5diff.h"
+#include "h5diff_common.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+static int check_n_input( const char* );
+static int check_p_input( const char* );
+static int check_d_input( const char* );
+
+/*
+ * Command-line options: The user can specify short or long-named
+ * parameters.
+ */
+static const char *s_opts = "hVrv:qn:d:p:Nc";
+static struct long_options l_opts[] = {
+ { "help", no_arg, 'h' },
+ { "version", no_arg, 'V' },
+ { "report", no_arg, 'r' },
+ { "verbose", optional_arg, 'v' },
+ { "quiet", no_arg, 'q' },
+ { "count", require_arg, 'n' },
+ { "delta", require_arg, 'd' },
+ { "relative", require_arg, 'p' },
+ { "nan", no_arg, 'N' },
+ { "compare", no_arg, 'c' },
+ { "use-system-epsilon", no_arg, 'e' },
+ { "follow-symlinks", no_arg, 'l' },
+ { "no-dangling-links", no_arg, 'x' },
+ { "exclude-path", require_arg, 'E' },
+ { NULL, 0, '\0' }
+};
+
+/*-------------------------------------------------------------------------
+ * Function: check_options
+ *
+ * Purpose: parse command line input
+ *
+ *-------------------------------------------------------------------------
+ */
+static void check_options(diff_opt_t* options)
+{
+ /*--------------------------------------------------------------
+ * check for mutually exclusive options
+ *--------------------------------------------------------------*/
+
+ /* check between -d , -p, --use-system-epsilon.
+ * These options are mutually exclusive.
+ */
+ if ((options->d + options->p + options->use_system_epsilon) > 1)
+ {
+ printf("%s error: -d, -p and --use-system-epsilon options are mutually-exclusive;\n", PROGRAMNAME);
+ printf("use no more than one.\n");
+ printf("Try '-h' or '--help' option for more information or see the %s entry in the 'HDF5 Reference Manual'.\n", PROGRAMNAME);
+ h5diff_exit(EXIT_FAILURE);
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: parse command line input
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void parse_command_line(int argc,
+ const char* argv[],
+ const char** fname1,
+ const char** fname2,
+ const char** objname1,
+ const char** objname2,
+ diff_opt_t* options)
+{
+ int i;
+ int opt;
+ struct exclude_path_list *exclude_head, *exclude_prev, *exclude_node;
+
+ /* process the command-line */
+ memset(options, 0, sizeof (diff_opt_t));
+
+ /* assume equal contents initially */
+ options->contents = 1;
+
+ /* NaNs are handled by default */
+ options->do_nans = 1;
+
+ /* not Listing objects that are not comparable */
+ options->m_list_not_cmp = 0;
+
+ /* initially no not-comparable. */
+ /**this is bad in mixing option with results**/
+ options->not_cmp=0;
+
+ /* init for exclude-path option */
+ exclude_head = NULL;
+
+ /* parse command line options */
+ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF)
+ {
+ switch ((char)opt)
+ {
+ default:
+ usage();
+ h5diff_exit(EXIT_FAILURE);
+ case 'h':
+ usage();
+ h5diff_exit(EXIT_SUCCESS);
+ case 'V':
+ print_version(h5tools_getprogname());
+ h5diff_exit(EXIT_SUCCESS);
+ case 'v':
+ options->m_verbose = 1;
+ /* This for loop is for handling style like
+ * -v, -v1, --verbose, --verbose=1.
+ */
+ for (i = 1; i < argc; i++)
+ {
+ /*
+ * short opt
+ */
+ if (!strcmp (argv[i], "-v")) /* no arg */
+ {
+ opt_ind--;
+ options->m_verbose_level = 0;
+ break;
+ }
+ else if (!strncmp (argv[i], "-v", (size_t)2))
+ {
+ options->m_verbose_level = atoi(&argv[i][2]);
+ break;
+ }
+
+ /*
+ * long opt
+ */
+ if (!strcmp (argv[i], "--verbose")) /* no arg */
+ {
+ options->m_verbose_level = 0;
+ break;
+ }
+ else if ( !strncmp (argv[i], "--verbose", (size_t)9) && argv[i][9]=='=')
+ {
+ options->m_verbose_level = atoi(&argv[i][10]);
+ break;
+ }
+ }
+ break;
+ case 'q':
+ /* use quiet mode; supress the message "0 differences found" */
+ options->m_quiet = 1;
+ break;
+ case 'r':
+ options->m_report = 1;
+ break;
+ case 'l':
+ options->follow_links = TRUE;
+ break;
+ case 'x':
+ options->no_dangle_links = 1;
+ break;
+ case 'E':
+ options->exclude_path = 1;
+
+ /* create linked list of excluding objects */
+ if( (exclude_node = (struct exclude_path_list*) HDmalloc(sizeof(struct exclude_path_list))) == NULL)
+ {
+ printf("Error: lack of memory!\n");
+ h5diff_exit(EXIT_FAILURE);
+ }
+
+ /* init */
+ exclude_node->obj_path = (char*)opt_arg;
+ exclude_node->obj_type = H5TRAV_TYPE_UNKNOWN;
+ exclude_prev = exclude_head;
+
+ if (NULL == exclude_head)
+ {
+ exclude_head = exclude_node;
+ exclude_head->next = NULL;
+ }
+ else
+ {
+ while(NULL != exclude_prev->next)
+ exclude_prev=exclude_prev->next;
+
+ exclude_node->next = NULL;
+ exclude_prev->next = exclude_node;
+ }
+ break;
+ case 'd':
+ options->d=1;
+
+ if ( check_d_input( opt_arg )==-1)
+ {
+ printf("<-d %s> is not a valid option\n", opt_arg );
+ usage();
+ h5diff_exit(EXIT_FAILURE);
+ }
+ options->delta = atof( opt_arg );
+
+ /* -d 0 is the same as default */
+ if (H5_DBL_ABS_EQUAL(options->delta, (double)0.0F))
+ options->d=0;
+
+ break;
+
+ case 'p':
+
+ options->p=1;
+ if ( check_p_input( opt_arg )==-1)
+ {
+ printf("<-p %s> is not a valid option\n", opt_arg );
+ usage();
+ h5diff_exit(EXIT_FAILURE);
+ }
+ options->percent = atof( opt_arg );
+
+ /* -p 0 is the same as default */
+ if (H5_DBL_ABS_EQUAL(options->percent, (double)0.0F))
+ options->p = 0;
+
+ break;
+
+ case 'n':
+
+ options->n=1;
+ if ( check_n_input( opt_arg )==-1)
+ {
+ printf("<-n %s> is not a valid option\n", opt_arg );
+ usage();
+ h5diff_exit(EXIT_FAILURE);
+ }
+ options->count = HDstrtoull(opt_arg, NULL, 0);
+ break;
+
+ case 'N':
+ options->do_nans = 0;
+ break;
+
+ case 'c':
+ options->m_list_not_cmp = 1;
+ break;
+
+ case 'e':
+ options->use_system_epsilon = 1;
+ break;
+ }
+ }
+
+ /* check options */
+ check_options(options);
+
+ /* if exclude-path option is used, keep the exclude path list */
+ if (options->exclude_path)
+ options->exclude = exclude_head;
+
+ /* check for file names to be processed */
+ if (argc <= opt_ind || argv[ opt_ind + 1 ] == NULL)
+ {
+ error_msg("missing file names\n");
+ usage();
+ h5diff_exit(EXIT_FAILURE);
+ }
+
+ *fname1 = argv[ opt_ind ];
+ *fname2 = argv[ opt_ind + 1 ];
+ *objname1 = argv[ opt_ind + 2 ];
+
+ if ( *objname1 == NULL )
+ {
+ *objname2 = NULL;
+ return;
+ }
+
+ if ( argv[ opt_ind + 3 ] != NULL)
+ {
+ *objname2 = argv[ opt_ind + 3 ];
+ }
+ else
+ {
+ *objname2 = *objname1;
+ }
+
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_info
+ *
+ * Purpose: print several information messages after h5diff call
+ *
+ *-------------------------------------------------------------------------
+ */
+
+ void print_info(diff_opt_t* options)
+ {
+ if (options->m_quiet || options->err_stat )
+ return;
+
+ if (options->cmn_objs==0)
+ {
+ printf("No common objects found. Files are not comparable.\n");
+ if (!options->m_verbose)
+ printf("Use -v for a list of objects.\n");
+ }
+
+ if (options->not_cmp==1)
+ {
+ if ( options->m_list_not_cmp == 0 )
+ {
+ printf("--------------------------------\n");
+ printf("Some objects are not comparable\n");
+ printf("--------------------------------\n");
+ if (options->m_verbose)
+ printf("Use -c for a list of objects without details of differences.\n");
+ else
+ printf("Use -c for a list of objects.\n");
+ }
+
+
+ }
+
+ }
+
+/*-------------------------------------------------------------------------
+ * Function: check_n_input
+ *
+ * Purpose: check for valid input
+ *
+ * Return: 1 for ok, -1 for fail
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: May 9, 2003
+ *
+ * Comments:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_ATTR_PURE static int
+check_n_input( const char *str )
+{
+ unsigned i;
+ char c;
+
+ for ( i = 0; i < strlen(str); i++)
+ {
+ c = str[i];
+ if ( i==0 )
+ {
+ if ( c < 49 || c > 57 ) /* ascii values between 1 and 9 */
+ return -1;
+ }
+ else
+ if ( c < 48 || c > 57 ) /* 0 also */
+ return -1;
+ }
+ return 1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: check_p_input
+ *
+ * Purpose: check for a valid p option input
+ *
+ * Return: 1 for ok, -1 for fail
+ *
+ * Date: May 9, 2003
+ *
+ * Comments:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+check_p_input( const char *str )
+{
+ double x;
+
+ /*
+ the atof return value on a hexadecimal input is different
+ on some systems; we do a character check for this
+ */
+ if (strlen(str)>2 && str[0]=='0' && str[1]=='x')
+ return -1;
+
+ x=atof(str);
+ if (x<0)
+ return -1;
+
+ return 1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: check_d_input
+ *
+ * Purpose: check for a valid d option input
+ *
+ * Return: 1 for ok, -1 for fail
+ *
+ * Date: November 11, 2007
+ *
+ * Comments:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+check_d_input( const char *str )
+{
+ double x;
+
+ /*
+ the atof return value on a hexadecimal input is different
+ on some systems; we do a character check for this
+ */
+ if (strlen(str)>2 && str[0]=='0' && str[1]=='x')
+ return -1;
+
+ x=atof(str);
+ if (x <0)
+ return -1;
+
+ return 1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: print a usage message
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void usage(void)
+{
+ printf("usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] \n");
+ printf(" file1 File name of the first HDF5 file\n");
+ printf(" file2 File name of the second HDF5 file\n");
+ printf(" [obj1] Name of an HDF5 object, in absolute path\n");
+ printf(" [obj2] Name of an HDF5 object, in absolute path\n");
+ printf("\n");
+ printf(" OPTIONS\n");
+ printf(" -h, --help\n");
+ printf(" Print a usage message and exit.\n");
+ printf(" -V, --version\n");
+ printf(" Print version number and exit.\n");
+ printf(" -r, --report\n");
+ printf(" Report mode. Print differences.\n");
+ printf(" -v --verbose\n");
+ printf(" Verbose mode. Print differences information and list of objects.\n");
+ printf(" -vN --verbose=N\n");
+ printf(" Verbose mode with level. Print differences and list of objects.\n");
+ printf(" Level of detail depends on value of N:\n");
+ printf(" 0 : Identical to '-v' or '--verbose'.\n");
+ printf(" 1 : All level 0 information plus one-line attribute\n");
+ printf(" status summary.\n");
+ printf(" 2 : All level 1 information plus extended attribute\n");
+ printf(" status report.\n");
+ printf(" -q, --quiet\n");
+ printf(" Quiet mode. Do not produce output.\n");
+ printf(" --follow-symlinks\n");
+ printf(" Follow symbolic links (soft links and external links and compare the)\n");
+ printf(" links' target objects.\n");
+ printf(" If symbolic link(s) with the same name exist in the files being\n");
+ printf(" compared, then determine whether the target of each link is an existing\n");
+ printf(" object (dataset, group, or named datatype) or the link is a dangling\n");
+ printf(" link (a soft or external link pointing to a target object that does\n");
+ printf(" not yet exist).\n");
+ printf(" - If both symbolic links are dangling links, they are treated as being\n");
+ printf(" the same; by default, h5diff returns an exit code of 0.\n");
+ printf(" If, however, --no-dangling-links is used with --follow-symlinks,\n");
+ printf(" this situation is treated as an error and h5diff returns an\n");
+ printf(" exit code of 2.\n");
+ printf(" - If only one of the two links is a dangling link,they are treated as\n");
+ printf(" being different and h5diff returns an exit code of 1.\n");
+ printf(" If, however, --no-dangling-links is used with --follow-symlinks,\n");
+ printf(" this situation is treated as an error and h5diff returns an\n");
+ printf(" exit code of 2.\n");
+ printf(" - If both symbolic links point to existing objects, h5diff compares the\n");
+ printf(" two objects.\n");
+ printf(" If any symbolic link specified in the call to h5diff does not exist,\n");
+ printf(" h5diff treats it as an error and returns an exit code of 2.\n");
+ printf(" --no-dangling-links\n");
+ printf(" Must be used with --follow-symlinks option; otherwise, h5diff shows\n");
+ printf(" error message and returns an exit code of 2.\n");
+ printf(" Check for any symbolic links (soft links or external links) that do not\n");
+ printf(" resolve to an existing object (dataset, group, or named datatype).\n");
+ printf(" If any dangling link is found, this situation is treated as an error\n");
+ printf(" and h5diff returns an exit code of 2.\n");
+ printf(" -c, --compare\n");
+ printf(" List objects that are not comparable\n");
+ printf(" -N, --nan\n");
+ printf(" Avoid NaNs detection\n");
+ printf(" -n C, --count=C\n");
+ printf(" Print differences up to C. C must be a positive integer.\n");
+ printf(" -d D, --delta=D\n");
+ printf(" Print difference if (|a-b| > D). D must be a positive number.\n");
+ printf(" Can not use with '-p' or '--use-system-epsilon'.\n");
+ printf(" -p R, --relative=R\n");
+ printf(" Print difference if (|(a-b)/b| > R). R must be a positive number.\n");
+ printf(" Can not use with '-d' or '--use-system-epsilon'.\n");
+ printf(" --use-system-epsilon\n");
+ printf(" Print difference if (|a-b| > EPSILON), EPSILON is system defined value.\n");
+ printf(" If the system epsilon is not defined,one of the following predefined\n");
+ printf(" values will be used:\n");
+ printf(" FLT_EPSILON = 1.19209E-07 for floating-point type\n");
+ printf(" DBL_EPSILON = 2.22045E-16 for double precision type\n");
+ printf(" Can not use with '-p' or '-d'.\n");
+ printf(" --exclude-path \"path\" \n");
+ printf(" Exclude the specified path to an object when comparing files or groups.\n");
+ printf(" If a group is excluded, all member objects will also be excluded.\n");
+ printf(" The specified path is excluded wherever it occurs.\n");
+ printf(" This flexibility enables the same option to exclude either objects that\n");
+ printf(" exist only in one file or common objects that are known to differ.\n");
+ printf("\n");
+ printf(" When comparing files, \"path\" is the absolute path to the excluded;\n");
+ printf(" object; when comparing groups, \"path\" is similar to the relative\n");
+ printf(" path from the group to the excluded object. This \"path\" can be\n");
+ printf(" taken from the first section of the output of the --verbose option.\n");
+ printf(" For example, if you are comparing the group /groupA in two files and\n");
+ printf(" you want to exclude /groupA/groupB/groupC in both files, the exclude\n");
+ printf(" option would read as follows:\n");
+ printf(" --exclude-path \"/groupB/groupC\"\n");
+ printf("\n");
+ printf(" If there are multiple paths to an object, only the specified path(s)\n");
+ printf(" will be excluded; the comparison will include any path not explicitly\n");
+ printf(" excluded.\n");
+ printf(" This option can be used repeatedly to exclude multiple paths.\n");
+ printf("\n");
+
+ printf(" Modes of output:\n");
+ printf(" Default mode: print the number of differences found and where they occured\n");
+ printf(" -r Report mode: print the above plus the differences\n");
+ printf(" -v Verbose mode: print the above plus a list of objects and warnings\n");
+ printf(" -q Quiet mode: do not print output\n");
+
+ printf("\n");
+
+ printf(" File comparison:\n");
+ printf(" If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as\n");
+ printf(" a comparison of the two files' root groups. That is, h5diff first compares\n");
+ printf(" the names of root group members, generates a report of root group objects\n");
+ printf(" that appear in only one file or in both files, and recursively compares\n");
+ printf(" common objects.\n");
+ printf("\n");
+
+ printf(" Object comparison:\n");
+ printf(" 1) Groups \n");
+ printf(" First compares the names of member objects (relative path, from the\n");
+ printf(" specified group) and generates a report of objects that appear in only\n");
+ printf(" one group or in both groups. Common objects are then compared recursively.\n");
+ printf(" 2) Datasets \n");
+ printf(" Array rank and dimensions, datatypes, and data values are compared.\n");
+ printf(" 3) Datatypes \n");
+ printf(" The comparison is based on the return value of H5Tequal.\n");
+ printf(" 4) Symbolic links \n");
+ printf(" The paths to the target objects are compared.\n");
+ printf(" (The option --follow-symlinks overrides the default behavior when\n");
+ printf(" symbolic links are compared.).\n");
+ printf("\n");
+
+ printf(" Exit code:\n");
+ printf(" 0 if no differences, 1 if differences found, 2 if error\n");
+ printf("\n");
+ printf(" Examples of use:\n");
+ printf(" 1) h5diff file1 file2 /g1/dset1 /g1/dset2\n");
+ printf(" Compares object '/g1/dset1' in file1 with '/g1/dset2' in file2\n");
+ printf("\n");
+ printf(" 2) h5diff file1 file2 /g1/dset1\n");
+ printf(" Compares object '/g1/dset1' in both files\n");
+ printf("\n");
+ printf(" 3) h5diff file1 file2\n");
+ printf(" Compares all objects in both files\n");
+ printf("\n");
+ printf(" Notes:\n");
+ printf(" file1 and file2 can be the same file.\n");
+ printf(" Use h5diff file1 file1 /g1/dset1 /g1/dset2 to compare\n");
+ printf(" '/g1/dset1' and '/g1/dset2' in the same file\n");
+ printf("\n");
+}
diff --git a/tools/src/h5diff/h5diff_common.h b/tools/src/h5diff/h5diff_common.h
new file mode 100644
index 0000000..5b1317f
--- /dev/null
+++ b/tools/src/h5diff/h5diff_common.h
@@ -0,0 +1,36 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef H5DIFFCOMMON_H__
+#define H5DIFFCOMMON_H__
+
+#include "h5tools.h"
+/* Name of tool */
+#define PROGRAMNAME "h5diff"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void usage(void);
+void parse_command_line(int argc, const char* argv[], const char** fname1, const char** fname2, const char** objname1, const char** objname2, diff_opt_t* options);
+void h5diff_exit(int status);
+void print_info(diff_opt_t* options);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H5DIFFCOMMON_H__ */
diff --git a/tools/src/h5diff/h5diff_main.c b/tools/src/h5diff/h5diff_main.c
new file mode 100644
index 0000000..cdaca29
--- /dev/null
+++ b/tools/src/h5diff/h5diff_main.c
@@ -0,0 +1,145 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <memory.h>
+#include "H5private.h"
+#include "h5diff.h"
+#include "h5diff_common.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: h5diff main program
+ *
+ * Return: An exit status of 0 means no differences were found, 1 means some
+ * differences were found.
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: May 9, 2003
+ *
+ * Comments:
+ *
+ * Modifications: July 2004
+ * Introduced the four modes:
+ * Normal mode: print the number of differences found and where they occured
+ * Report mode: print the above plus the differences
+ * Verbose mode: print the above plus a list of objects and warnings
+ * Quiet mode: do not print output
+ *
+ * November 2004: Leon Arber (larber@uiuc.edu)
+ * Additions that allow h5diff to be run in parallel
+ *
+ * February 2005: Leon Arber (larber@uiuc.edu)
+ * h5diff and ph5diff split into two files, one that is used
+ * to build a serial h5diff and one used to build a parallel h5diff
+ * Common functions have been moved to h5diff_common.c
+ *
+ * October 2005
+ * Introduced a new field 'not_cmp' to 'diff_opt_t' that detects
+ * if some objects are not comparable and prints the message
+ * "Some objects are not comparable"
+ *
+ * February 2007
+ * Added comparison for dataset regions.
+ * Added support for reading and comparing by hyperslabs for large files.
+ * Inclusion of a relative error formula to compare floating
+ * point numbers in order to deal with floating point uncertainty.
+ * Printing of dataset dimensions along with dataset name
+ *
+ * November 19, 2007
+ * adopted the syntax h5diff [OPTIONS] file1 file2 [obj1[obj2]]
+ *
+ *-------------------------------------------------------------------------
+ */
+
+
+int main(int argc, const char *argv[])
+{
+ int ret;
+ const char *fname1 = NULL;
+ const char *fname2 = NULL;
+ const char *objname1 = NULL;
+ const char *objname2 = NULL;
+ hsize_t nfound=0;
+ diff_opt_t options;
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /*-------------------------------------------------------------------------
+ * process the command-line
+ *-------------------------------------------------------------------------
+ */
+ parse_command_line(argc, argv, &fname1, &fname2, &objname1, &objname2, &options);
+
+ /*-------------------------------------------------------------------------
+ * do the diff
+ *-------------------------------------------------------------------------
+ */
+
+ nfound = h5diff(fname1,fname2,objname1,objname2,&options);
+
+ print_info(&options);
+
+ /*-------------------------------------------------------------------------
+ * exit code
+ * 1 if differences, 0 if no differences, 2 if error
+ *-------------------------------------------------------------------------
+ */
+
+ ret = (nfound == 0 ? 0 : 1 );
+
+ /* if graph difference return 1 for differences */
+ if ( options.contents == 0 )
+ ret = 1;
+
+ /* and return 2 for error */
+ if (options.err_stat)
+ ret = 2;
+
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: h5diff_exit
+ *
+ * Purpose: dismiss phdiff worker processes and exit
+ *
+ * Return: none
+ *
+ * Programmer: Albert Cheng
+ * Date: Feb 6, 2005
+ *
+ * Comments:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_ATTR_NORETURN void
+h5diff_exit(int status)
+{
+ HDexit(status);
+}
+
diff --git a/tools/src/h5diff/ph5diff_main.c b/tools/src/h5diff/ph5diff_main.c
new file mode 100644
index 0000000..a26b6e9
--- /dev/null
+++ b/tools/src/h5diff/ph5diff_main.c
@@ -0,0 +1,329 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "H5private.h"
+#include "h5diff.h"
+#include "ph5diff.h"
+#include "h5diff_common.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5diff"
+
+static void ph5diff_worker(int );
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: ph5diff main program
+ *
+ * Return: An exit status of 0 means no differences were found, 1 means some
+ * differences were found.
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: May 9, 2003
+ *
+ * Comments:
+ *
+ * This function drives the diff process and will do a serial or parallel diff depending
+ * on the value of the global variable g_Parallel (default is 0), set to 1 when the program
+ * is run as "ph5diff"
+ *-------------------------------------------------------------------------
+ */
+
+int main(int argc, const char *argv[])
+{
+ int nID = 0;
+ const char *fname1 = NULL;
+ const char *fname2 = NULL;
+ const char *objname1 = NULL;
+ const char *objname2 = NULL;
+ diff_opt_t options;
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ outBuffOffset = 0;
+ g_Parallel = 1;
+
+ MPI_Init(&argc, (char***) &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &nID);
+ MPI_Comm_size(MPI_COMM_WORLD, &g_nTasks);
+
+ if(g_nTasks == 1)
+ {
+ printf("Only 1 task available...doing serial diff\n");
+
+ g_Parallel = 0;
+
+ parse_command_line(argc, argv, &fname1, &fname2, &objname1, &objname2, &options);
+
+ h5diff(fname1, fname2, objname1, objname2, &options);
+
+ print_info(&options);
+ }
+ /* Parallel h5diff */
+ else {
+
+ /* Have the manager process the command-line */
+ if(nID == 0)
+ {
+ parse_command_line(argc, argv, &fname1, &fname2, &objname1, &objname2, &options);
+
+ h5diff(fname1, fname2, objname1, objname2, &options);
+
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ print_info(&options);
+ print_manager_output();
+ }
+ /* All other tasks become workers and wait for assignments. */
+ else {
+ ph5diff_worker(nID);
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ } /* end else */
+
+ } /* end else */
+
+ MPI_Finalize();
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: ph5diff_worker
+ *
+ * Purpose: worker process of ph5diff
+ *
+ * Return: none
+ *
+ * Programmer: Leon Arber
+ * Date: January 2005
+ *
+ * Comments:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+ph5diff_worker(int nID)
+{
+ hid_t file1_id = -1, file2_id = -1;
+
+ while(1)
+ {
+ MPI_Status Status;
+
+ MPI_Probe(0, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
+
+ /* Check for filenames */
+ if(Status.MPI_TAG == MPI_TAG_PARALLEL)
+ {
+ char filenames[2][MAX_FILENAME];
+
+ /* Retrieve filenames */
+ MPI_Recv(filenames, MAX_FILENAME*2, MPI_CHAR, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
+
+ /* disable error reporting */
+ H5E_BEGIN_TRY
+ {
+ /* Open the files */
+ if ((file1_id = H5Fopen (filenames[0], H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
+ {
+ printf ("h5diff Task [%d]: <%s>: unable to open file\n", nID, filenames[0]);
+ MPI_Abort(MPI_COMM_WORLD, 0);
+ }
+ if ((file2_id = H5Fopen (filenames[1], H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
+ {
+ printf ("h5diff Task [%d]: <%s>: unable to open file\n", nID, filenames[1]);
+ MPI_Abort(MPI_COMM_WORLD, 0);
+ }
+ /* enable error reporting */
+ }
+ H5E_END_TRY;
+ }
+ /* Check for work */
+ else if(Status.MPI_TAG == MPI_TAG_ARGS)
+ {
+ struct diff_mpi_args args;
+ struct diffs_found diffs;
+ int i;
+
+ /* Make certain we've received the filenames and opened the files already */
+ if(file1_id < 0 || file2_id < 0)
+ {
+ printf("ph5diff_worker: ERROR: work received before/without filenames\n");
+ break;
+ }
+
+ /* Recv parameters for diff from manager task */
+ MPI_Recv(&args, sizeof(args), MPI_BYTE, 0, MPI_TAG_ARGS, MPI_COMM_WORLD, &Status);
+
+ /* Do the diff */
+ diffs.nfound = diff(file1_id, args.name1, file2_id, args.name2, &(args.options), &(args.argdata));
+ diffs.not_cmp = args.options.not_cmp;
+
+ /* If print buffer has something in it, request print token.*/
+ if(outBuffOffset>0)
+ {
+ MPI_Send(NULL, 0, MPI_BYTE, 0, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD);
+
+ /* Wait for print token. */
+ MPI_Recv(NULL, 0, MPI_BYTE, 0, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD, &Status);
+
+ /* When get token, send all of our output to the manager task and then return the token */
+ for(i=0; i<outBuffOffset; i+=PRINT_DATA_MAX_SIZE)
+ MPI_Send(outBuff+i, PRINT_DATA_MAX_SIZE, MPI_BYTE, 0, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD);
+
+ /* An overflow file exists, so we send it's output to the manager too and then delete it */
+ if(overflow_file)
+ {
+ char out_data[PRINT_DATA_MAX_SIZE];
+ int tmp;
+
+ memset(out_data, 0, PRINT_DATA_MAX_SIZE);
+ i=0;
+
+ rewind(overflow_file);
+ while((tmp = getc(overflow_file)) >= 0)
+ {
+ *(out_data + i++) = (char)tmp;
+ if(i==PRINT_DATA_MAX_SIZE)
+ {
+ MPI_Send(out_data, PRINT_DATA_MAX_SIZE, MPI_BYTE, 0, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD);
+ i=0;
+ memset(out_data, 0, PRINT_DATA_MAX_SIZE);
+ }
+ }
+
+ if(i>0)
+ MPI_Send(out_data, PRINT_DATA_MAX_SIZE, MPI_BYTE, 0, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD);
+
+ fclose(overflow_file);
+ overflow_file = NULL;
+ }
+
+ fflush(stdout);
+ memset(outBuff, 0, OUTBUFF_SIZE);
+ outBuffOffset = 0;
+
+ MPI_Send(&diffs, sizeof(diffs), MPI_BYTE, 0, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD);
+ }
+ else
+ MPI_Send(&diffs, sizeof(diffs), MPI_BYTE, 0, MPI_TAG_DONE, MPI_COMM_WORLD);
+ }
+ /* Check for leaving */
+ else if(Status.MPI_TAG == MPI_TAG_END)
+ {
+ MPI_Recv(NULL, 0, MPI_BYTE, 0, MPI_TAG_END, MPI_COMM_WORLD, &Status);
+ break;
+ }
+ else
+ {
+ printf("ph5diff_worker: ERROR: invalid tag (%d) received\n", Status.MPI_TAG);
+ break;
+ }
+
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: print_manager_output
+ *
+ * Purpose: special function that prints any output accumulated by the
+ * manager task.
+ *
+ * Return: none
+ *
+ * Programmer: Leon Arber
+ *
+ * Date: Feb 7, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+void print_manager_output(void)
+{
+ /* If there was something we buffered, let's print it now */
+ if( (outBuffOffset>0) && g_Parallel)
+ {
+ printf("%s", outBuff);
+
+ if(overflow_file)
+ {
+ int tmp;
+ rewind(overflow_file);
+ while((tmp = getc(overflow_file)) >= 0)
+ putchar(tmp);
+ fclose(overflow_file);
+ overflow_file = NULL;
+ }
+
+ HDfflush(stdout);
+ HDmemset(outBuff, 0, OUTBUFF_SIZE);
+ outBuffOffset = 0;
+ }
+ else if( (outBuffOffset>0) && !g_Parallel)
+ {
+ HDfprintf(stderr, "h5diff error: outBuffOffset>0, but we're not in parallel!\n");
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: h5diff_exit
+ *
+ * Purpose: dismiss phdiff worker processes and exit
+ *
+ * Return: none
+ *
+ * Programmer: Albert Cheng
+ * Date: Feb 6, 2005
+ *
+ * Comments:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void h5diff_exit(int status)
+{
+ /* if in parallel mode, dismiss workers, close down MPI, then exit */
+ if(g_Parallel) {
+ if(g_nTasks > 1) {
+ phdiff_dismiss_workers();
+ MPI_Barrier(MPI_COMM_WORLD);
+ }
+ MPI_Finalize();
+ status = EXIT_SUCCESS; /* Reset exit status, since some mpiexec commands generate output on failure status */
+ }
+
+ /* Always exit(0), since MPI implementations do weird stuff when they
+ * receive a non-zero exit value. - QAK
+ */
+ exit(0);
+}
+
diff --git a/tools/src/h5dump/CMakeLists.txt b/tools/src/h5dump/CMakeLists.txt
new file mode 100644
index 0000000..ab310db
--- /dev/null
+++ b/tools/src/h5dump/CMakeLists.txt
@@ -0,0 +1,43 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_H5DUMP)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+
+# --------------------------------------------------------------------
+# Add the h5dump executables
+# --------------------------------------------------------------------
+add_executable (h5dump
+ ${HDF5_TOOLS_SRC_H5DUMP_SOURCE_DIR}/h5dump.c
+ ${HDF5_TOOLS_SRC_H5DUMP_SOURCE_DIR}/h5dump_ddl.c
+ ${HDF5_TOOLS_SRC_H5DUMP_SOURCE_DIR}/h5dump_xml.c
+)
+TARGET_NAMING (h5dump STATIC)
+TARGET_C_PROPERTIES (h5dump STATIC " " " ")
+target_link_libraries (h5dump ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5dump PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5dump")
+
+set (H5_DEP_EXECUTABLES h5dump)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5dump ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5dump
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
diff --git a/tools/src/h5dump/Makefile.am b/tools/src/h5dump/Makefile.am
new file mode 100644
index 0000000..dc43065
--- /dev/null
+++ b/tools/src/h5dump/Makefile.am
@@ -0,0 +1,38 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include files in /src directory and /tools/lib directory
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+# Our main target, the h5dump tool.
+bin_PROGRAMS=h5dump
+
+# Add h5dump specific linker flags here
+h5dump_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# All the programs depend on the hdf5 and h5tools libraries
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+# Source files for the program
+h5dump_SOURCES=h5dump.c h5dump_ddl.c h5dump_xml.c
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c
new file mode 100644
index 0000000..562cfd5
--- /dev/null
+++ b/tools/src/h5dump/h5dump.c
@@ -0,0 +1,1802 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "h5dump.h"
+#include "h5dump_ddl.h"
+#include "h5dump_xml.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5dump"
+
+static const char *driver = NULL; /* The driver to open the file with. */
+const char *outfname=NULL;
+static int doxml = 0;
+static int useschema = 1;
+static const char *xml_dtd_uri = NULL;
+
+/* module-scoped variables for XML option */
+#define DEFAULT_XSD "http://www.hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd"
+#define DEFAULT_DTD "http://www.hdfgroup.org/HDF5/XML/DTD/HDF5-File.dtd"
+
+/* Standard DDL output */
+static const dump_functions ddl_function_table = {
+ dump_group,
+ dump_named_datatype,
+ dump_dataset,
+ dump_dataspace,
+ dump_datatype,
+ dump_attr_cb,
+ dump_data
+};
+
+/* XML output */
+static const dump_functions xml_function_table = {
+ xml_dump_group,
+ xml_dump_named_datatype,
+ xml_dump_dataset,
+ xml_dump_dataspace,
+ xml_dump_datatype,
+ xml_dump_attr,
+ xml_dump_data
+};
+
+/* internal functions */
+static void init_prefix(char **prfx, size_t prfx_len);
+
+/* a structure for handling the order command-line parameters come in */
+struct handler_t {
+ void (*func)(hid_t, const char *, void *, int, const char *);
+ char *obj;
+ struct subset_t *subset_info;
+};
+
+/*
+ * Command-line options: The user can specify short or long-named
+ * parameters. The long-named ones can be partially spelled. When
+ * adding more, make sure that they don't clash with each other.
+ */
+/* The following initialization makes use of C language cancatenating */
+/* "xxx" "yyy" into "xxxyyy". */
+static const char *s_opts = "hn*peyBHirVa:c:d:f:g:k:l:t:w:xD:uX:o*b*F:s:S:A*q:z:m:RECM:O*N:vG:";
+static struct long_options l_opts[] = {
+ { "help", no_arg, 'h' },
+ { "hel", no_arg, 'h' },
+ { "contents", optional_arg, 'n' },
+ { "properties", no_arg, 'p' },
+ { "superblock", no_arg, 'B' },
+ { "boot-block", no_arg, 'B' },
+ { "boot-bloc", no_arg, 'B' },
+ { "boot-blo", no_arg, 'B' },
+ { "boot-bl", no_arg, 'B' },
+ { "boot-b", no_arg, 'B' },
+ { "boot", no_arg, 'B' },
+ { "boo", no_arg, 'B' },
+ { "bo", no_arg, 'B' },
+ { "header", no_arg, 'H' },
+ { "heade", no_arg, 'H' },
+ { "head", no_arg, 'H' },
+ { "hea", no_arg, 'H' },
+ { "object-ids", no_arg, 'i' },
+ { "object-id", no_arg, 'i' },
+ { "object-i", no_arg, 'i' },
+ { "object", no_arg, 'i' },
+ { "objec", no_arg, 'i' },
+ { "obje", no_arg, 'i' },
+ { "obj", no_arg, 'i' },
+ { "ob", no_arg, 'i' },
+ { "version", no_arg, 'V' },
+ { "versio", no_arg, 'V' },
+ { "versi", no_arg, 'V' },
+ { "vers", no_arg, 'V' },
+ { "ver", no_arg, 'V' },
+ { "ve", no_arg, 'V' },
+ { "attribute", require_arg, 'a' },
+ { "attribut", require_arg, 'a' },
+ { "attribu", require_arg, 'a' },
+ { "attrib", require_arg, 'a' },
+ { "attri", require_arg, 'a' },
+ { "attr", require_arg, 'a' },
+ { "att", require_arg, 'a' },
+ { "at", require_arg, 'a' },
+ { "block", require_arg, 'k' },
+ { "bloc", require_arg, 'k' },
+ { "blo", require_arg, 'k' },
+ { "bl", require_arg, 'k' },
+ { "count", require_arg, 'c' },
+ { "coun", require_arg, 'c' },
+ { "cou", require_arg, 'c' },
+ { "co", require_arg, 'c' },
+ { "dataset", require_arg, 'd' },
+ { "datase", require_arg, 'd' },
+ { "datas", require_arg, 'd' },
+ { "datatype", require_arg, 't' },
+ { "datatyp", require_arg, 't' },
+ { "dataty", require_arg, 't' },
+ { "datat", require_arg, 't' },
+ { "filedriver", require_arg, 'f' },
+ { "filedrive", require_arg, 'f' },
+ { "filedriv", require_arg, 'f' },
+ { "filedri", require_arg, 'f' },
+ { "filedr", require_arg, 'f' },
+ { "filed", require_arg, 'f' },
+ { "file", require_arg, 'f' },
+ { "fil", require_arg, 'f' },
+ { "fi", require_arg, 'f' },
+ { "group", require_arg, 'g' },
+ { "grou", require_arg, 'g' },
+ { "gro", require_arg, 'g' },
+ { "gr", require_arg, 'g' },
+ { "output", optional_arg, 'o' },
+ { "outpu", optional_arg, 'o' },
+ { "outp", optional_arg, 'o' },
+ { "out", optional_arg, 'o' },
+ { "ou", optional_arg, 'o' },
+ { "soft-link", require_arg, 'l' },
+ { "soft-lin", require_arg, 'l' },
+ { "soft-li", require_arg, 'l' },
+ { "soft-l", require_arg, 'l' },
+ { "soft", require_arg, 'l' },
+ { "sof", require_arg, 'l' },
+ { "start", require_arg, 's' },
+ { "star", require_arg, 's' },
+ { "sta", require_arg, 's' },
+ { "stride", require_arg, 'S' },
+ { "strid", require_arg, 'S' },
+ { "string", no_arg, 'r' },
+ { "strin", no_arg, 'r' },
+ { "use-dtd", no_arg, 'u' },
+ { "use-dt", no_arg, 'u' },
+ { "use-d", no_arg, 'u' },
+ { "use-", no_arg, 'u' },
+ { "use", no_arg, 'u' },
+ { "us", no_arg, 'u' },
+ { "u", no_arg, 'u' },
+ { "width", require_arg, 'w' },
+ { "widt", require_arg, 'w' },
+ { "wid", require_arg, 'w' },
+ { "wi", require_arg, 'w' },
+ { "xml-dtd", require_arg, 'D' },
+ { "xml-dt", require_arg, 'D' },
+ { "xml-d", require_arg, 'D' },
+ { "xml-ns", require_arg, 'X' },
+ { "xml-n", require_arg, 'X' },
+ { "xml", no_arg, 'x' },
+ { "xm", no_arg, 'x' },
+ { "onlyattr", optional_arg, 'A' },
+ { "escape", no_arg, 'e' },
+ { "noindex", no_arg, 'y' },
+ { "binary", optional_arg, 'b' },
+ { "form", require_arg, 'F' },
+ { "sort_by", require_arg, 'q' },
+ { "sort_order", require_arg, 'z' },
+ { "format", require_arg, 'm' },
+ { "region", no_arg, 'R' },
+ { "enable-error-stack", no_arg, 'E' },
+ { "packed-bits", require_arg, 'M' },
+ { "no-compact-subset", no_arg, 'C' },
+ { "ddl", optional_arg, 'O' },
+ { "any_path", require_arg, 'N' },
+ { "vds-view-first-missing", no_arg, 'v' },
+ { "vds-gap-size", require_arg, 'G' },
+ { NULL, 0, '\0' }
+};
+
+
+/*-------------------------------------------------------------------------
+ * Function: leave
+ *
+ * Purpose: Shutdown MPI & HDF5 and call exit()
+ *
+ * Return: Does not return
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, 31. January 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+leave(int ret)
+{
+ h5tools_close();
+
+ HDexit(ret);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Print the usage message about dumper
+ *
+ * Return: void
+ *-------------------------------------------------------------------------
+ */
+static void
+usage(const char *prog)
+{
+ FLUSHSTREAM(rawoutstream);
+ PRINTSTREAM(rawoutstream, "usage: %s [OPTIONS] files\n", prog);
+ PRINTVALSTREAM(rawoutstream, " OPTIONS\n");
+ PRINTVALSTREAM(rawoutstream, " -h, --help Print a usage message and exit\n");
+ PRINTVALSTREAM(rawoutstream, " -V, --version Print version number and exit\n");
+ PRINTVALSTREAM(rawoutstream, "--------------- File Options ---------------\n");
+ PRINTVALSTREAM(rawoutstream, " -n, --contents Print a list of the file contents and exit\n");
+ PRINTVALSTREAM(rawoutstream, " Optional value 1 also prints attributes.\n");
+ PRINTVALSTREAM(rawoutstream, " -B, --superblock Print the content of the super block\n");
+ PRINTVALSTREAM(rawoutstream, " -H, --header Print the header only; no data is displayed\n");
+ PRINTVALSTREAM(rawoutstream, " -f D, --filedriver=D Specify which driver to open the file with\n");
+ PRINTVALSTREAM(rawoutstream, " -o F, --output=F Output raw data into file F\n");
+ PRINTVALSTREAM(rawoutstream, " -b B, --binary=B Binary file output, of form B\n");
+ PRINTVALSTREAM(rawoutstream, " -O F, --ddl=F Output ddl text into file F\n");
+ PRINTVALSTREAM(rawoutstream, " Use blank(empty) filename F to suppress ddl display\n");
+ PRINTVALSTREAM(rawoutstream, "--------------- Object Options ---------------\n");
+ PRINTVALSTREAM(rawoutstream, " -a P, --attribute=P Print the specified attribute\n");
+ PRINTVALSTREAM(rawoutstream, " If an attribute name contains a slash (/), escape the\n");
+ PRINTVALSTREAM(rawoutstream, " slash with a preceding backslash (\\).\n");
+ PRINTVALSTREAM(rawoutstream, " (See example section below.)\n");
+ PRINTVALSTREAM(rawoutstream, " -d P, --dataset=P Print the specified dataset\n");
+ PRINTVALSTREAM(rawoutstream, " -g P, --group=P Print the specified group and all members\n");
+ PRINTVALSTREAM(rawoutstream, " -l P, --soft-link=P Print the value(s) of the specified soft link\n");
+ PRINTVALSTREAM(rawoutstream, " -t P, --datatype=P Print the specified named datatype\n");
+ PRINTVALSTREAM(rawoutstream, " -N P, --any_path=P Print any attribute, dataset, group, datatype, or link that matches P\n");
+ PRINTVALSTREAM(rawoutstream, " P can be the absolute path or just a relative path.\n");
+ PRINTVALSTREAM(rawoutstream, " -A, --onlyattr Print the header and value of attributes\n");
+ PRINTVALSTREAM(rawoutstream, " Optional value 0 suppresses printing attributes.\n");
+ PRINTVALSTREAM(rawoutstream, " --vds-view-first-missing Set the VDS bounds to first missing mapped elements.\n");
+ PRINTVALSTREAM(rawoutstream, " --vds-gap-size=N Set the missing file gap size, N=non-negative integers\n");
+ PRINTVALSTREAM(rawoutstream, "--------------- Object Property Options ---------------\n");
+ PRINTVALSTREAM(rawoutstream, " -i, --object-ids Print the object ids\n");
+ PRINTVALSTREAM(rawoutstream, " -p, --properties Print dataset filters, storage layout and fill value\n");
+ PRINTVALSTREAM(rawoutstream, " -M L, --packedbits=L Print packed bits as unsigned integers, using mask\n");
+ PRINTVALSTREAM(rawoutstream, " format L for an integer dataset specified with\n");
+ PRINTVALSTREAM(rawoutstream, " option -d. L is a list of offset,length values,\n");
+ PRINTVALSTREAM(rawoutstream, " separated by commas. Offset is the beginning bit in\n");
+ PRINTVALSTREAM(rawoutstream, " the data value and length is the number of bits of\n");
+ PRINTVALSTREAM(rawoutstream, " the mask.\n");
+ PRINTVALSTREAM(rawoutstream, " -R, --region Print dataset pointed by region references\n");
+ PRINTVALSTREAM(rawoutstream, "--------------- Formatting Options ---------------\n");
+ PRINTVALSTREAM(rawoutstream, " -e, --escape Escape non printing characters\n");
+ PRINTVALSTREAM(rawoutstream, " -r, --string Print 1-byte integer datasets as ASCII\n");
+ PRINTVALSTREAM(rawoutstream, " -y, --noindex Do not print array indices with the data\n");
+ PRINTVALSTREAM(rawoutstream, " -m T, --format=T Set the floating point output format\n");
+ PRINTVALSTREAM(rawoutstream, " -q Q, --sort_by=Q Sort groups and attributes by index Q\n");
+ PRINTVALSTREAM(rawoutstream, " -z Z, --sort_order=Z Sort groups and attributes by order Z\n");
+ PRINTVALSTREAM(rawoutstream, " --enable-error-stack Prints messages from the HDF5 error stack as they\n");
+ PRINTVALSTREAM(rawoutstream, " occur.\n");
+ PRINTVALSTREAM(rawoutstream, " --no-compact-subset Disable compact form of subsetting and allow the use\n");
+ PRINTVALSTREAM(rawoutstream, " of \"[\" in dataset names.\n");
+ PRINTVALSTREAM(rawoutstream, " -w N, --width=N Set the number of columns of output. A value of 0 (zero)\n");
+ PRINTVALSTREAM(rawoutstream, " sets the number of columns to the maximum (65535).\n");
+ PRINTVALSTREAM(rawoutstream, " Default width is 80 columns.\n");
+ PRINTVALSTREAM(rawoutstream, "--------------- XML Options ---------------\n");
+ PRINTVALSTREAM(rawoutstream, " -x, --xml Output in XML using Schema\n");
+ PRINTVALSTREAM(rawoutstream, " -u, --use-dtd Output in XML using DTD\n");
+ PRINTVALSTREAM(rawoutstream, " -D U, --xml-dtd=U Use the DTD or schema at U\n");
+ PRINTVALSTREAM(rawoutstream, " -X S, --xml-ns=S (XML Schema) Use qualified names n the XML\n");
+ PRINTVALSTREAM(rawoutstream, " \":\": no namespace, default: \"hdf5:\"\n");
+ PRINTVALSTREAM(rawoutstream, " E.g., to dump a file called `-f', use h5dump -- -f\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "--------------- Subsetting Options ---------------\n");
+ PRINTVALSTREAM(rawoutstream, " Subsetting is available by using the following options with a dataset\n");
+ PRINTVALSTREAM(rawoutstream, " option. Subsetting is done by selecting a hyperslab from the data.\n");
+ PRINTVALSTREAM(rawoutstream, " Thus, the options mirror those for performing a hyperslab selection.\n");
+ PRINTVALSTREAM(rawoutstream, " One of the START, COUNT, STRIDE, or BLOCK parameters are mandatory if you do subsetting.\n");
+ PRINTVALSTREAM(rawoutstream, " The STRIDE, COUNT, and BLOCK parameters are optional and will default to 1 in\n");
+ PRINTVALSTREAM(rawoutstream, " each dimension. START is optional and will default to 0 in each dimension.\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " -s START, --start=START Offset of start of subsetting selection\n");
+ PRINTVALSTREAM(rawoutstream, " -S STRIDE, --stride=STRIDE Hyperslab stride\n");
+ PRINTVALSTREAM(rawoutstream, " -c COUNT, --count=COUNT Number of blocks to include in selection\n");
+ PRINTVALSTREAM(rawoutstream, " -k BLOCK, --block=BLOCK Size of block in hyperslab\n");
+ PRINTVALSTREAM(rawoutstream, " START, COUNT, STRIDE, and BLOCK - is a list of integers the number of which are equal to the\n");
+ PRINTVALSTREAM(rawoutstream, " number of dimensions in the dataspace being queried\n");
+ PRINTVALSTREAM(rawoutstream, " (Alternate compact form of subsetting is described in the Reference Manual)\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "--------------- Option Argument Conventions ---------------\n");
+ PRINTVALSTREAM(rawoutstream, " D - is the file driver to use in opening the file. Acceptable values\n");
+ PRINTVALSTREAM(rawoutstream, " are \"sec2\", \"family\", \"split\", \"multi\", \"direct\", and \"stream\". Without\n");
+ PRINTVALSTREAM(rawoutstream, " the file driver flag, the file will be opened with each driver in\n");
+ PRINTVALSTREAM(rawoutstream, " turn and in the order specified above until one driver succeeds\n");
+ PRINTVALSTREAM(rawoutstream, " in opening the file.\n");
+ PRINTVALSTREAM(rawoutstream, " See examples below for family, split, and multi driver special file name usage.\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " F - is a filename.\n");
+ PRINTVALSTREAM(rawoutstream, " P - is the full path from the root group to the object.\n");
+ PRINTVALSTREAM(rawoutstream, " N - is an integer greater than 1.\n");
+ PRINTVALSTREAM(rawoutstream, " T - is a string containing the floating point format, e.g '%%.3f'\n");
+ PRINTVALSTREAM(rawoutstream, " U - is a URI reference (as defined in [IETF RFC 2396],\n");
+ PRINTVALSTREAM(rawoutstream, " updated by [IETF RFC 2732])\n");
+ PRINTVALSTREAM(rawoutstream, " B - is the form of binary output: NATIVE for a memory type, FILE for the\n");
+ PRINTVALSTREAM(rawoutstream, " file type, LE or BE for pre-existing little or big endian types.\n");
+ PRINTVALSTREAM(rawoutstream, " Must be used with -o (output file) and it is recommended that\n");
+ PRINTVALSTREAM(rawoutstream, " -d (dataset) is used. B is an optional argument, defaults to NATIVE\n");
+ PRINTVALSTREAM(rawoutstream, " Q - is the sort index type. It can be \"creation_order\" or \"name\" (default)\n");
+ PRINTVALSTREAM(rawoutstream, " Z - is the sort order type. It can be \"descending\" or \"ascending\" (default)\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "--------------- Examples ---------------\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " 1) Attribute foo of the group /bar_none in file quux.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " h5dump -a /bar_none/foo quux.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " Attribute \"high/low\" of the group /bar_none in the file quux.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " h5dump -a \"/bar_none/high\\/low\" quux.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " 2) Selecting a subset from dataset /foo in file quux.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " h5dump -d /foo -s \"0,1\" -S \"1,1\" -c \"2,3\" -k \"2,2\" quux.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " 3) Saving dataset 'dset' in file quux.h5 to binary file 'out.bin'\n");
+ PRINTVALSTREAM(rawoutstream, " using a little-endian type\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " h5dump -d /dset -b LE -o out.bin quux.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " 4) Display two packed bits (bits 0-1 and bits 4-6) in the dataset /dset\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " h5dump -d /dset -M 0,1,4,3 quux.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " 5) Dataset foo in files file1.h5 file2.h5 file3.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " h5dump -d /foo file1.h5 file2.h5 file3.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " 6) Dataset foo in split files splitfile-m.h5 splitfile-r.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " h5dump -d /foo -f split splitfile\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " 7) Dataset foo in multi files mf-s.h5, mf-b.h5, mf-r.h5, mf-g.h5, mf-l.h5 and mf-o.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " h5dump -d /foo -f multi mf\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " 8) Dataset foo in family files fam00000.h5 fam00001.h5 and fam00002.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " h5dump -d /foo -f family fam%%05d.h5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: table_list_add
+ *
+ * Purpose: Add a new set of tables
+ *
+ * Return: index of added table on success, -1 on failure
+ *
+ * Programmer: Neil Fortner, nfortne2@hdfgroup.org
+ * Adapted from trav_addr_add in h5trav.c by Quincey Koziol
+ *
+ * Date: October 13, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+table_list_add(hid_t oid, unsigned long file_no)
+{
+ size_t idx; /* Index of table to use */
+ find_objs_t info;
+
+ /* Allocate space if necessary */
+ if(table_list.nused == table_list.nalloc) {
+ h5dump_table_items_t *tmp_ptr;
+
+ table_list.nalloc = MAX(1, table_list.nalloc * 2);
+ if(NULL == (tmp_ptr = (h5dump_table_items_t *)HDrealloc(table_list.tables, table_list.nalloc * sizeof(table_list.tables[0]))))
+ return -1;
+ table_list.tables = tmp_ptr;
+ } /* end if */
+
+ /* Append it */
+ idx = table_list.nused++;
+ table_list.tables[idx].fileno = file_no;
+ table_list.tables[idx].oid = oid;
+ if(H5Iinc_ref(oid) < 0) {
+ table_list.nused--;
+ return -1;
+ }
+ if(init_objs(oid, &info, &table_list.tables[idx].group_table,
+ &table_list.tables[idx].dset_table, &table_list.tables[idx].type_table) < 0) {
+ H5Idec_ref(oid);
+ table_list.nused--;
+ return -1;
+ }
+
+#ifdef H5DUMP_DEBUG
+ dump_tables(&info);
+#endif /* H5DUMP_DEBUG */
+
+ return((ssize_t) idx);
+} /* end table_list_add() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: table_list_visited
+ *
+ * Purpose: Check if a table already exists for the specified fileno
+ *
+ * Return: The index of the matching table, or -1 if no matches found
+ *
+ * Programmer: Neil Fortner, nfortne2@hdfgroup.org
+ * Adapted from trav_addr_visited in h5trav.c by Quincey Koziol
+ *
+ * Date: October 13, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_ATTR_PURE ssize_t
+table_list_visited(unsigned long file_no)
+{
+ size_t u; /* Local index variable */
+
+ /* Look for table */
+ for(u = 0; u < table_list.nused; u++)
+ /* Check for fileno value already in array */
+ if(table_list.tables[u].fileno == file_no)
+ return((ssize_t) u);
+
+ /* Didn't find table */
+ return(-1);
+} /* end table_list_visited() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: table_list_free
+ *
+ * Purpose: Frees the table list
+ *
+ * Return: void
+ *
+ * Programmer: Neil Fortner, nfortne2@hdfgroup.org
+ *
+ * Date: October 13, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+table_list_free(void)
+{
+ size_t u; /* Local index variable */
+
+ /* Iterate over tables */
+ for(u = 0; u < table_list.nused; u++) {
+ /* Release object id */
+ if(H5Idec_ref(table_list.tables[u].oid) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+
+ /* Free each table */
+ free_table(table_list.tables[u].group_table);
+ HDfree(table_list.tables[u].group_table);
+ free_table(table_list.tables[u].dset_table);
+ HDfree(table_list.tables[u].dset_table);
+ free_table(table_list.tables[u].type_table);
+ HDfree(table_list.tables[u].type_table);
+ }
+
+ /* Free the table list */
+ HDfree(table_list.tables);
+ table_list.tables = NULL;
+ table_list.nalloc = table_list.nused = 0;
+} /* end table_list_free() */
+
+/*-------------------------------------------------------------------------
+ * Function: set_binary_form
+ *
+ * Purpose: set the binary form of output by translating from a string input
+ * parameter to a integer return value
+ *
+ * Return: integer form of binary output or -1 if none found
+ *
+ * Programmer: Pedro Vicente Nunes
+ * June 28, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+set_binary_form(const char *form)
+{
+ int bform = -1;
+
+ if (HDstrcmp(form,"NATIVE") == 0 || HDstrcmp(form,"MEMORY") == 0) {
+ /* native form */
+ bform = 0;
+ }
+ else if (HDstrcmp(form,"FILE") == 0) /* file type form */
+ bform = 1;
+ else if (HDstrcmp(form,"LE") == 0) /* convert to little endian */
+ bform = 2;
+ else if (HDstrcmp(form,"BE") == 0) /* convert to big endian */
+ bform = 3;
+
+ return bform;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: set_sort_by
+ *
+ * Purpose: set the "by" form of sorting by translating from a string input
+ * parameter to a H5_index_t return value
+ * current sort values are [creation_order | name]
+ *
+ * Return: H5_index_t form of sort or H5_INDEX_UNKNOWN if none found
+ *
+ * Programmer: Pedro Vicente Nunes
+ * October 1, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5_index_t
+set_sort_by(const char *form)
+{
+ H5_index_t idx_type = H5_INDEX_UNKNOWN;
+
+ if (HDstrcmp(form,"name")==0) /* H5_INDEX_NAME */
+ idx_type = H5_INDEX_NAME;
+ else if (HDstrcmp(form,"creation_order")==0) /* H5_INDEX_CRT_ORDER */
+ idx_type = H5_INDEX_CRT_ORDER;
+
+ return idx_type;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: set_sort_order
+ *
+ * Purpose: set the order of sorting by translating from a string input
+ * parameter to a H5_iter_order_t return value
+ * current order values are [ascending | descending ]
+ *
+ * Return: H5_iter_order_t form of order or H5_ITER_UNKNOWN if none found
+ *
+ * Programmer: Pedro Vicente Nunes
+ * October 1, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5_iter_order_t
+set_sort_order(const char *form)
+{
+ H5_iter_order_t iter_order = H5_ITER_UNKNOWN;
+
+ if (HDstrcmp(form,"ascending")==0) /* H5_ITER_INC */
+ iter_order = H5_ITER_INC;
+ else if (HDstrcmp(form,"descending")==0) /* H5_ITER_DEC */
+ iter_order = H5_ITER_DEC;
+
+ return iter_order;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_hsize_list
+ *
+ * Purpose: Parse a list of comma or space separated integers and return
+ * them in a list. The string being passed into this function
+ * should be at the start of the list you want to parse. You are
+ * responsible for freeing the array returned from here.
+ *
+ * Lists in the so-called "terse" syntax are separated by
+ * semicolons (;). The lists themselves can be separated by
+ * either commas (,) or white spaces.
+ *
+ * Return: <none>
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 6. February 2001
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+parse_hsize_list(const char *h_list, subset_d *d)
+{
+ hsize_t *p_list;
+ const char *ptr;
+ unsigned int size_count = 0;
+ unsigned int i = 0;
+ unsigned int last_digit = 0;
+
+ if (!h_list || !*h_list || *h_list == ';')
+ return;
+
+ /* count how many integers do we have */
+ for (ptr = h_list; ptr && *ptr && *ptr != ';' && *ptr != ']'; ptr++)
+ if (HDisdigit(*ptr)) {
+ if (!last_digit)
+ /* the last read character wasn't a digit */
+ size_count++;
+
+ last_digit = 1;
+ }
+ else
+ last_digit = 0;
+
+ if (size_count == 0)
+ /* there aren't any integers to read */
+ return;
+
+ /* allocate an array for the integers in the list */
+ p_list = (hsize_t *)HDcalloc(size_count, sizeof(hsize_t));
+
+ for (ptr = h_list; i < size_count && ptr && *ptr && *ptr != ';' && *ptr != ']'; ptr++)
+ if(HDisdigit(*ptr)) {
+ /* we should have an integer now */
+ p_list[i++] = (hsize_t)HDstrtoull(ptr, NULL, 0);
+
+ while (HDisdigit(*ptr))
+ /* scroll to end of integer */
+ ptr++;
+ }
+ d->data = p_list;
+ d->len = size_count;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_subset_params
+ *
+ * Purpose: Parse the so-called "terse" syntax for specifying subsetting
+ * parameters.
+ *
+ * Return: Success: struct subset_t object
+ * Failure: NULL
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 6. February 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static struct subset_t *
+parse_subset_params(char *dset)
+{
+ struct subset_t *s = NULL;
+ char *brace;
+
+ if (!disable_compact_subset && ((brace = HDstrrchr(dset, '[')) != NULL)) {
+ *brace++ = '\0';
+
+ s = (struct subset_t *)HDcalloc(1, sizeof(struct subset_t));
+ parse_hsize_list(brace, &s->start);
+
+ while (*brace && *brace != ';')
+ brace++;
+
+ if (*brace) brace++;
+
+ parse_hsize_list(brace, &s->stride);
+
+ while (*brace && *brace != ';')
+ brace++;
+
+ if (*brace) brace++;
+
+ parse_hsize_list(brace, &s->count);
+
+ while (*brace && *brace != ';')
+ brace++;
+
+ if (*brace) brace++;
+
+ parse_hsize_list(brace, &s->block);
+ }
+
+ return s;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_mask_list
+ *
+ * Purpose: Parse a list of comma or space separated integers and fill
+ * the packed_bits list and counter. The string being passed into this function
+ * should be at the start of the list you want to parse.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+parse_mask_list(const char *h_list)
+{
+ int soffset_value;
+ unsigned offset_value;
+ int slength_value;
+ unsigned length_value;
+ unsigned long long temp_mask;
+ const char *ptr = NULL;
+
+ /* sanity check */
+ HDassert(h_list);
+
+ HDmemset(packed_mask,0,sizeof(packed_mask));
+
+ packed_bits_num = 0;
+ /* scan in pair of offset,length separated by commas. */
+ ptr = h_list;
+ while (*ptr) {
+ /* scan for an offset which is an unsigned int */
+ if (!HDisdigit(*ptr)) {
+ error_msg("Bad mask list(%s)\n", h_list);
+ return FAIL;
+ }
+ soffset_value = HDatoi(ptr);
+ offset_value = (unsigned)soffset_value;
+ if (soffset_value < 0 || offset_value >= PACKED_BITS_SIZE_MAX) {
+ error_msg("Packed Bit offset value(%d) must be between 0 and %u\n",
+ soffset_value, (unsigned)(PACKED_BITS_SIZE_MAX - 1));
+ return FAIL;
+ }
+
+ /* skip to end of integer */
+ while (HDisdigit(*++ptr))
+ ;
+ /* Look for the common separator */
+ if (*ptr++ != ',') {
+ error_msg("Bad mask list(%s), missing expected comma separator.\n", h_list);
+ return FAIL;
+ }
+
+ /* scan for a length which is a positive int */
+ if (!HDisdigit(*ptr)) {
+ error_msg("Bad mask list(%s)\n", h_list);
+ return FAIL;
+ }
+ slength_value = HDatoi(ptr);
+ if (slength_value <= 0) {
+ error_msg("Packed Bit length value(%d) must be positive.\n", slength_value);
+ return FAIL;
+ }
+ length_value = (unsigned)slength_value;
+ if ((offset_value + length_value) > PACKED_BITS_SIZE_MAX) {
+ error_msg("Packed Bit offset+length value(%u) too large. Max is %u\n",
+ offset_value+length_value, (unsigned)PACKED_BITS_SIZE_MAX);
+ return FAIL;
+ }
+
+ /* skip to end of int */
+ while (HDisdigit(*++ptr))
+ ;
+
+ /* store the offset,length pair */
+ if (packed_bits_num >= PACKED_BITS_MAX) {
+ /* too many requests */
+ error_msg("Too many masks requested (max. %d). Mask list(%s)\n", PACKED_BITS_MAX, h_list);
+ return FAIL;
+ }
+ packed_offset[packed_bits_num] = offset_value;
+ packed_length[packed_bits_num] = length_value;
+ /* create the bit mask by left shift 1's by length, then negate it. */
+ /* After packed_mask is calculated, packed_length is not needed but */
+ /* keep it for debug purpose. */
+ temp_mask = ~0ULL;
+ if(length_value < (int)(8 *sizeof(unsigned long long))) {
+ temp_mask = temp_mask << length_value;
+ packed_mask[packed_bits_num] = ~temp_mask;
+ }
+ else
+ packed_mask[packed_bits_num] = temp_mask;
+ packed_bits_num++;
+
+ /* skip a possible comma separator */
+ if (*ptr == ',') {
+ if (!(*++ptr)) {
+ /* unexpected end of string */
+ error_msg("Bad mask list(%s), unexpected end of string.\n", h_list);
+ return FAIL;
+ }
+ }
+ }
+ HDassert(packed_bits_num <= PACKED_BITS_MAX);
+ if (packed_bits_num == 0) {
+ /* got no masks! */
+ error_msg("Bad mask list(%s)\n", h_list);
+ return FAIL;
+ }
+ return SUCCEED;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: free_handler
+ *
+ * Purpose: Convenience function to free the handler_t structures. Needs a
+ * length variable (LEN) to know how many in the array it needs
+ * to free
+ *
+ * Return: Nothing
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 20. February 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+free_handler(struct handler_t *hand, int len)
+{
+ int i;
+
+ if(hand) {
+ for (i = 0; i < len; i++) {
+ if(hand[i].obj) {
+ HDfree(hand[i].obj);
+ hand[i].obj=NULL;
+ }
+
+ if (hand[i].subset_info) {
+ if(hand[i].subset_info->start.data)
+ HDfree(hand[i].subset_info->start.data);
+ if(hand[i].subset_info->stride.data)
+ HDfree(hand[i].subset_info->stride.data);
+ if(hand[i].subset_info->count.data)
+ HDfree(hand[i].subset_info->count.data);
+ if(hand[i].subset_info->block.data)
+ HDfree(hand[i].subset_info->block.data);
+
+ HDfree(hand[i].subset_info);
+ hand[i].subset_info=NULL;
+ }
+ }
+
+ HDfree(hand);
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parse the command line for the h5dumper.
+ *
+ * Return: Success: A pointer to an array of handler_t structures.
+ * These contain all the information needed to dump
+ * the necessary object.
+ *
+ * Failure: Exits program with EXIT_FAILURE value.
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 20. February 2001
+ *
+ * Modifications:
+ * pvn June, 1, 2006. Add a switch for binary output
+ *
+ *-------------------------------------------------------------------------
+ */
+static struct handler_t *
+parse_command_line(int argc, const char *argv[])
+{
+ struct handler_t *hand = NULL;
+ struct handler_t *last_dset = NULL;
+ int i;
+ int opt;
+ int last_was_dset = FALSE;
+
+ /* no arguments */
+ if (argc == 1) {
+ usage(h5tools_getprogname());
+ goto error;
+ }
+
+ /* this will be plenty big enough to hold the info */
+ if((hand = (struct handler_t *)HDcalloc((size_t)argc, sizeof(struct handler_t)))==NULL) {
+ goto error;
+ }
+
+ /* parse command line options */
+ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
+parse_start:
+ switch ((char)opt) {
+ case 'R':
+ display_region = TRUE;
+ region_output = TRUE;
+ break;
+ case 'B':
+ display_bb = TRUE;
+ last_was_dset = FALSE;
+ break;
+ case 'n':
+ display_fi = TRUE;
+ last_was_dset = FALSE;
+ if ( opt_arg != NULL) {
+ h5trav_set_verbose(HDatoi(opt_arg));
+ }
+ break;
+ case 'p':
+ display_dcpl = TRUE;
+ break;
+ case 'y':
+ display_ai = FALSE;
+ break;
+ case 'e':
+ display_escape = TRUE;
+ break;
+ case 'H':
+ display_data = FALSE;
+ display_attr_data = FALSE;
+ last_was_dset = FALSE;
+ break;
+ case 'A':
+ if ( opt_arg != NULL) {
+ if(0 == HDatoi(opt_arg)) include_attrs = FALSE;
+ }
+ else {
+ display_data = FALSE;
+ display_attr_data = TRUE;
+ last_was_dset = FALSE;
+ }
+ break;
+ case 'i':
+ display_oid = TRUE;
+ last_was_dset = FALSE;
+ break;
+ case 'r':
+ display_char = TRUE;
+ break;
+ case 'V':
+ print_version(h5tools_getprogname());
+ free_handler(hand, argc);
+ hand = NULL;
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+ break;
+ case 'w':
+ {
+ int sh5tools_nCols = HDatoi(opt_arg);
+
+ if (sh5tools_nCols <= 0)
+ h5tools_nCols = 65535;
+ else
+ h5tools_nCols = (unsigned)sh5tools_nCols;
+ last_was_dset = FALSE;
+ }
+ break;
+ case 'N':
+ display_all = 0;
+
+ for (i = 0; i < argc; i++)
+ if (!hand[i].func) {
+ hand[i].func = handle_paths;
+ hand[i].obj = HDstrdup(opt_arg);
+ break;
+ }
+
+ last_was_dset = FALSE;
+ break;
+ case 'a':
+ display_all = 0;
+
+ for (i = 0; i < argc; i++)
+ if (!hand[i].func) {
+ hand[i].func = handle_attributes;
+ hand[i].obj = HDstrdup(opt_arg);
+ break;
+ }
+
+ last_was_dset = FALSE;
+ break;
+ case 'd':
+ display_all = 0;
+
+ for (i = 0; i < argc; i++)
+ if (!hand[i].func) {
+ hand[i].func = handle_datasets;
+ hand[i].obj = HDstrdup(opt_arg);
+ hand[i].subset_info = parse_subset_params(hand[i].obj);
+ last_dset = &hand[i];
+ break;
+ }
+
+ last_was_dset = TRUE;
+ break;
+ case 'f':
+ driver = opt_arg;
+ break;
+ case 'g':
+ display_all = 0;
+
+ for (i = 0; i < argc; i++)
+ if (!hand[i].func) {
+ hand[i].func = handle_groups;
+ hand[i].obj = HDstrdup(opt_arg);
+ break;
+ }
+
+ last_was_dset = FALSE;
+ break;
+ case 'l':
+ display_all = 0;
+
+ for (i = 0; i < argc; i++)
+ if (!hand[i].func) {
+ hand[i].func = handle_links;
+ hand[i].obj = HDstrdup(opt_arg);
+ break;
+ }
+
+ last_was_dset = FALSE;
+ break;
+ case 't':
+ display_all = 0;
+
+ for (i = 0; i < argc; i++)
+ if (!hand[i].func) {
+ hand[i].func = handle_datatypes;
+ hand[i].obj = HDstrdup(opt_arg);
+ break;
+ }
+
+ last_was_dset = FALSE;
+ break;
+
+ case 'O':
+ if (h5tools_set_output_file(opt_arg, 0) < 0) {
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ break;
+
+ case 'o':
+ if ( bin_output ) {
+ if (h5tools_set_data_output_file(opt_arg, 1) < 0) {
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ }
+ else {
+ if(display_attr_data && !display_data) {
+ if (h5tools_set_attr_output_file(opt_arg, 0) < 0) {
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ }
+ if(display_data || display_all) {
+ if (h5tools_set_data_output_file(opt_arg, 0) < 0) {
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ }
+ }
+
+ usingdasho = TRUE;
+ last_was_dset = FALSE;
+ outfname = opt_arg;
+ break;
+
+ case 'b':
+ if ( opt_arg != NULL) {
+ if ( ( bin_form = set_binary_form(opt_arg)) < 0) {
+ /* failed to set binary form */
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ }
+ bin_output = TRUE;
+ if (outfname!=NULL) {
+ if (h5tools_set_data_output_file(outfname, 1) < 0) {
+ /* failed to set output file */
+ usage(h5tools_getprogname());
+ goto error;
+ }
+
+ last_was_dset = FALSE;
+ }
+ break;
+
+ case 'q':
+ if ( ( sort_by = set_sort_by(opt_arg)) < 0) {
+ /* failed to set "sort by" form */
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ break;
+
+ case 'z':
+ if ( ( sort_order = set_sort_order(opt_arg)) < 0) {
+ /* failed to set "sort order" form */
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ break;
+
+ case 'M':
+ if (!last_was_dset) {
+ error_msg("option `-%c' can only be used after --dataset option\n", opt);
+ goto error;
+ }
+ if (parse_mask_list(opt_arg) != SUCCEED){
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ display_packed_bits = TRUE;
+ break;
+ case 'v':
+ display_vds_first = TRUE;
+ break;
+ case 'G':
+ vds_gap_size = HDatoi(opt_arg);
+ if (vds_gap_size < 0) {
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ break;
+
+ /** begin XML parameters **/
+ case 'x':
+ /* select XML output */
+ doxml = TRUE;
+ useschema = TRUE;
+ h5tools_dump_header_format = NULL;
+ dump_function_table = &xml_function_table;
+ h5tools_nCols = 0;
+ break;
+ case 'u':
+ doxml = TRUE;
+ useschema = FALSE;
+ xmlnsprefix = "";
+ h5tools_dump_header_format = NULL;
+ dump_function_table = &xml_function_table;
+ h5tools_nCols = 0;
+ break;
+ case 'D':
+ /* specify alternative XML DTD or schema */
+ /* To Do: check format of this value? */
+ xml_dtd_uri = opt_arg;
+ h5tools_nCols = 0;
+ break;
+
+ case 'm':
+ /* specify alternative floating point printing format */
+ fp_format = opt_arg;
+ h5tools_nCols = 0;
+ break;
+
+ case 'X':
+ /* specify XML namespace (default="hdf5:"), or none */
+ /* To Do: check format of this value? */
+ if (!useschema) {
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ if (HDstrcmp(opt_arg,":") == 0)
+ xmlnsprefix = "";
+ else
+ xmlnsprefix = opt_arg;
+ h5tools_nCols = 0;
+ break;
+ /** end XML parameters **/
+
+ /** begin subsetting parameters **/
+ case 's':
+ case 'S':
+ case 'c':
+ case 'k': {
+ struct subset_t *s;
+
+ if (!last_was_dset) {
+ error_msg("option `-%c' can only be used after --dataset option\n", opt);
+ goto error;
+ }
+
+ if (last_dset->subset_info) {
+ /*
+ * This overrides the "terse" syntax if they actually mixed
+ * the two.
+ */
+ s = last_dset->subset_info;
+ }
+ else {
+ last_dset->subset_info = s = (struct subset_t *)HDcalloc(1, sizeof(struct subset_t));
+ }
+
+ /*
+ * slightly convoluted, but...we are only interested in options
+ * for subsetting: "--start", "--stride", "--count", and "--block"
+ * which can come in any order. If we run out of parameters (EOF)
+ * or run into one which isn't a subsetting parameter (NOT s, S,
+ * c, or K), then we exit the do-while look, set the subset_info
+ * to the structure we've been filling. If we've reached the end
+ * of the options, we exit the parsing (goto parse_end) otherwise,
+ * since we've "read" the next option, we need to parse it. So we
+ * jump to the beginning of the switch statement (goto parse_start).
+ */
+ do {
+ switch ((char)opt) {
+ case 's':
+ if (s->start.data) {
+ HDfree(s->start.data);
+ s->start.data = NULL;
+ }
+ parse_hsize_list(opt_arg, &s->start);
+ break;
+ case 'S':
+ if (s->stride.data) {
+ HDfree(s->stride.data);
+ s->stride.data = NULL;
+ }
+ parse_hsize_list(opt_arg, &s->stride);
+ break;
+ case 'c':
+ if (s->count.data) {
+ HDfree(s->count.data);
+ s->count.data = NULL;
+ }
+ parse_hsize_list(opt_arg, &s->count);
+ break;
+ case 'k':
+ if (s->block.data) {
+ HDfree(s->block.data);
+ s->block.data = NULL;
+ }
+ parse_hsize_list(opt_arg, &s->block);
+ break;
+ default:
+ goto end_collect;
+ }
+ } while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF);
+
+end_collect:
+ last_was_dset = FALSE;
+
+ if (opt != EOF)
+ goto parse_start;
+ else
+ goto parse_end;
+ }
+ /** end subsetting parameters **/
+
+ case 'E':
+ enable_error_stack = TRUE;
+ break;
+ case 'C':
+ disable_compact_subset = TRUE;
+ break;
+ case 'h':
+ usage(h5tools_getprogname());
+ free_handler(hand, argc);
+ hand = NULL;
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+ case '?':
+ default:
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ }
+
+parse_end:
+ /* check for file name to be processed */
+ if (argc <= opt_ind) {
+ error_msg("missing file name\n");
+ usage(h5tools_getprogname());
+ goto error;
+ }
+done:
+ return hand;
+
+error:
+ if (hand) {
+ free_handler(hand, argc);
+ hand = NULL;
+ }
+ h5tools_setstatus(EXIT_FAILURE);
+
+ return hand;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: HDF5 dumper
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ * Albert Cheng
+ * 30. September 2000
+ * Add the -o option--output file for datasets raw data
+ *
+ * REMcG
+ * November 2000
+ * Changes to support XML.
+ *
+ * Bill Wendling
+ * Wednesday, 10. January 2001
+ * Modified the way command line parameters are interpreted. They go
+ * through one function call now (get_option).
+ *
+ * Bill Wendling
+ * Tuesday, 20. February 2001
+ * Moved command line parsing to separate function. Made various
+ * "display_*" flags global.
+ *
+ * REMcG
+ * August 2003
+ * Major upgrade to XML support.
+ *
+ * Pedro Vicente
+ * September 2007
+ * list objects in requested order (creation order or alphabetically)
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, const char *argv[])
+{
+ hid_t fid = -1;
+ hid_t gid = -1;
+ H5E_auto2_t func;
+ H5E_auto2_t tools_func;
+ H5O_info_t oi;
+ struct handler_t *hand = NULL;
+ int i;
+ unsigned u;
+ void *edata;
+ void *tools_edata;
+ char *fname = NULL;
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+ h5tools_dump_header_format = &h5tools_standardformat;
+ dump_function_table = &ddl_function_table;
+ dump_indent = 0;
+
+ /* Disable error reporting */
+ H5Eget_auto2(H5E_DEFAULT, &func, &edata);
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /* Disable tools error reporting */
+ H5Eget_auto2(H5tools_ERR_STACK_g, &tools_func, &tools_edata);
+ H5Eset_auto2(H5tools_ERR_STACK_g, NULL, NULL);
+
+ if((hand = parse_command_line(argc, argv))==NULL) {
+ goto done;
+ }
+
+ if (bin_output && outfname == NULL) {
+ error_msg("binary output requires a file name, use -o <filename>\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ if (enable_error_stack) {
+ H5Eset_auto2(H5E_DEFAULT, func, edata);
+ H5Eset_auto2(H5tools_ERR_STACK_g, tools_func, tools_edata);
+ }
+
+ /* Check for conflicting options */
+ if (doxml) {
+ if (!display_all) {
+ error_msg("option \"%s\" not available for XML\n",
+ "to display selected objects");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ else if (display_bb) {
+ error_msg("option \"%s\" not available for XML\n", "--boot-block");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ else if (display_oid == 1) {
+ error_msg("option \"%s\" not available for XML\n", "--object-ids");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ else if (display_char == TRUE) {
+ error_msg("option \"%s\" not available for XML\n", "--string");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ else if (usingdasho) {
+ error_msg("option \"%s\" not available for XML\n", "--output");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ }
+ else {
+ if (xml_dtd_uri) {
+ warn_msg("option \"%s\" only applies with XML: %s\n", "--xml-dtd", xml_dtd_uri);
+ }
+ }
+
+ if (argc <= opt_ind) {
+ error_msg("missing file name\n");
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ /* Initialize indexing options */
+ h5trav_set_index(sort_by, sort_order);
+
+ while(opt_ind < argc) {
+ fname = HDstrdup(argv[opt_ind++]);
+
+ fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, driver, NULL, 0);
+
+ if (fid < 0) {
+ error_msg("unable to open file \"%s\"\n", fname);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ /* allocate and initialize internal data structure */
+ init_prefix(&prefix, prefix_len);
+
+ /* Prepare to find objects that might be targets of a reference */
+ fill_ref_path_table(fid);
+
+ if(doxml) {
+ /* initialize XML */
+ /* reset prefix! */
+ HDstrcpy(prefix, "");
+
+ /* make sure the URI is initialized to something */
+ if (xml_dtd_uri == NULL) {
+ if (useschema) {
+ xml_dtd_uri = DEFAULT_XSD;
+ }
+ else {
+ xml_dtd_uri = DEFAULT_DTD;
+ xmlnsprefix = "";
+ }
+ }
+ else {
+ if (useschema && HDstrcmp(xmlnsprefix,"")) {
+ error_msg("Cannot set Schema URL for a qualified namespace--use -X or -U option with -D \n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ }
+ }
+
+ /* Get object info for root group */
+ if(H5Oget_info_by_name(fid, "/", &oi, H5P_DEFAULT) < 0) {
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ /* Initialize object tables */
+ if(table_list_add(fid, oi.fileno) < 0) {
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ group_table = table_list.tables[0].group_table;
+ dset_table = table_list.tables[0].dset_table;
+ type_table = table_list.tables[0].type_table;
+
+ /* does there exist unamed committed datatype */
+ for (u = 0; u < type_table->nobjs; u++)
+ if (!type_table->objs[u].recorded) {
+ unamedtype = 1;
+ break;
+ } /* end if */
+
+ /* start to dump - display file header information */
+ if (!doxml) {
+ begin_obj(h5tools_dump_header_format->filebegin, fname, h5tools_dump_header_format->fileblockbegin);
+ }
+ else {
+ PRINTVALSTREAM(rawoutstream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+
+ /* alternative first element, depending on schema or DTD. */
+ if (useschema) {
+ if (HDstrcmp(xmlnsprefix,"") == 0) {
+ PRINTSTREAM(rawoutstream, "<HDF5-File xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"%s\">\n",
+ xml_dtd_uri);
+ }
+ else {
+ /* TO DO: make -url option work in this case (may need new option) */
+ char *ns;
+ char *indx;
+
+ ns = HDstrdup(xmlnsprefix);
+ indx = HDstrrchr(ns,(int)':');
+ if (indx) *indx = '\0';
+
+ PRINTSTREAM(rawoutstream, "<%sHDF5-File xmlns:%s=\"http://hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd\" "
+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
+ "xsi:schemaLocation=\"http://hdfgroup.org/HDF5/XML/schema/HDF5-File "
+ "http://www.hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd\">\n",xmlnsprefix,ns);
+ HDfree(ns);
+ }
+ }
+ else {
+ PRINTSTREAM(rawoutstream, "<!DOCTYPE HDF5-File PUBLIC \"HDF5-File.dtd\" \"%s\">\n", xml_dtd_uri);
+ PRINTVALSTREAM(rawoutstream, "<HDF5-File>\n");
+ }
+ }
+
+ if (!doxml) {
+ if (display_fi) {
+ PRINTVALSTREAM(rawoutstream, "\n");
+ dump_fcontents(fid);
+ end_obj(h5tools_dump_header_format->fileend,h5tools_dump_header_format->fileblockend);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ goto done;
+ }
+
+ if (display_bb)
+ dump_fcpl(fid);
+ }
+
+ if(display_all) {
+ if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) {
+ error_msg("unable to open root group\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ if (!doxml)
+ dump_indent += COL;
+ dump_function_table->dump_group_function(gid, "/" );
+ if (!doxml)
+ dump_indent -= COL;
+ PRINTVALSTREAM(rawoutstream, "\n");
+ }
+
+ if(H5Gclose(gid) < 0) {
+ error_msg("unable to close root group\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ }
+ else {
+ /* Note: this option is not supported for XML */
+ if(doxml) {
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ } /* end if */
+
+ for(i = 0; i < argc; i++) {
+ if(hand[i].func) {
+ hand[i].func(fid, hand[i].obj, hand[i].subset_info, 1, NULL);
+ }
+ }
+ PRINTVALSTREAM(rawoutstream, "\n");
+ }
+
+ if (!doxml) {
+ end_obj(h5tools_dump_header_format->fileend, h5tools_dump_header_format->fileblockend);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ }
+ else {
+ PRINTSTREAM(rawoutstream, "</%sHDF5-File>\n", xmlnsprefix);
+ }
+ /* Free tables for objects */
+ table_list_free();
+
+ if(fid >=0)
+ if (H5Fclose(fid) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+
+ if(prefix) {
+ HDfree(prefix);
+ prefix = NULL;
+ }
+ if(fname) {
+ HDfree(fname);
+ fname = NULL;
+ }
+ } /* end while */
+
+ if(hand)
+ free_handler(hand, argc);
+
+ /* To Do: clean up XML table */
+
+ leave(h5tools_getstatus());
+
+done:
+ /* Free tables for objects */
+ table_list_free();
+
+ if(fid >=0)
+ if (H5Fclose(fid) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+
+ if(prefix) {
+ HDfree(prefix);
+ prefix = NULL;
+ }
+ if(fname) {
+ HDfree(fname);
+ fname = NULL;
+ }
+
+ if(hand)
+ free_handler(hand, argc);
+
+ /* To Do: clean up XML table */
+
+ H5Eset_auto2(H5E_DEFAULT, func, edata);
+
+ leave(h5tools_getstatus());
+}
+
+/*-------------------------------------------------------------------------
+ * Function: h5_fileaccess
+ *
+ * Purpose: Returns a file access template which is the default template
+ * but with a file driver set according to the constant or
+ * environment variable HDF5_DRIVER
+ *
+ * Return: Success: A file access property list
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 19, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+h5_fileaccess(void)
+{
+ static const char *multi_letters = "msbrglo";
+ const char *val = NULL;
+ const char *name;
+ char s[1024];
+ hid_t fapl = -1;
+
+ /* First use the environment variable, then the constant */
+ val = HDgetenv("HDF5_DRIVER");
+#ifdef HDF5_DRIVER
+ if (!val) val = HDF5_DRIVER;
+#endif
+
+ if ((fapl=H5Pcreate(H5P_FILE_ACCESS))<0) return -1;
+ if (!val || !*val) return fapl; /*use default*/
+
+ HDstrncpy(s, val, sizeof s);
+ s[sizeof(s)-1] = '\0';
+ if (NULL==(name=HDstrtok(s, " \t\n\r"))) return fapl;
+
+ if (!HDstrcmp(name, "sec2")) {
+ /* Unix read() and write() system calls */
+ if (H5Pset_fapl_sec2(fapl)<0) return -1;
+ }
+ else if (!HDstrcmp(name, "stdio")) {
+ /* Standard C fread() and fwrite() system calls */
+ if (H5Pset_fapl_stdio(fapl)<0) return -1;
+ }
+ else if (!HDstrcmp(name, "core")) {
+ /* In-core temporary file with 1MB increment */
+ if (H5Pset_fapl_core(fapl, 1024*1024, FALSE)<0) return -1;
+ }
+ else if (!HDstrcmp(name, "split")) {
+ /* Split meta data and raw data each using default driver */
+ if (H5Pset_fapl_split(fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0)
+ return -1;
+ }
+ else if (!HDstrcmp(name, "multi")) {
+ /* Multi-file driver, general case of the split driver */
+ H5FD_mem_t memb_map[H5FD_MEM_NTYPES];
+ hid_t memb_fapl[H5FD_MEM_NTYPES];
+ const char *memb_name[H5FD_MEM_NTYPES];
+ char sv[H5FD_MEM_NTYPES][1024];
+ haddr_t memb_addr[H5FD_MEM_NTYPES];
+ H5FD_mem_t mt;
+
+ HDmemset(memb_map, 0, sizeof memb_map);
+ HDmemset(memb_fapl, 0, sizeof memb_fapl);
+ HDmemset(memb_name, 0, sizeof memb_name);
+ HDmemset(memb_addr, 0, sizeof memb_addr);
+
+ HDassert(HDstrlen(multi_letters)==H5FD_MEM_NTYPES);
+ for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,mt)) {
+ memb_fapl[mt] = H5P_DEFAULT;
+ memb_map[mt] = mt;
+ sprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]);
+ memb_name[mt] = sv[mt];
+ memb_addr[mt] = (haddr_t)MAX(mt - 1, 0) * (HADDR_MAX / 10);
+ }
+
+ if (H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr, FALSE) < 0)
+ return -1;
+ }
+ else if (!HDstrcmp(name, "family")) {
+ hsize_t fam_size = 100*1024*1024; /*100 MB*/
+
+ /* Family of files, each 1MB and using the default driver */
+ if ((val=HDstrtok(NULL, " \t\n\r")))
+ fam_size = (hsize_t)(HDstrtod(val, NULL) * 1024*1024);
+ if (H5Pset_fapl_family(fapl, fam_size, H5P_DEFAULT)<0)
+ return -1;
+ }
+ else if (!HDstrcmp(name, "log")) {
+ long log_flags = H5FD_LOG_LOC_IO;
+
+ /* Log file access */
+ if ((val = HDstrtok(NULL, " \t\n\r")))
+ log_flags = HDstrtol(val, NULL, 0);
+
+ if (H5Pset_fapl_log(fapl, NULL, (unsigned)log_flags, 0) < 0)
+ return -1;
+ }
+ else if (!HDstrcmp(name, "direct")) {
+ /* Substitute Direct I/O driver with sec2 driver temporarily because
+ * some output has sec2 driver as the standard. */
+ if (H5Pset_fapl_sec2(fapl)<0) return -1;
+ }
+ else {
+ /* Unknown driver */
+ return -1;
+ }
+
+ return fapl;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: init_prefix
+ *
+ * Purpose: allocate and initialize prefix
+ *
+ * Return: void
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+init_prefix(char **prfx, size_t prfx_len)
+{
+ HDassert(prfx_len > 0);
+ *prfx = (char *)HDcalloc(prfx_len, 1);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: add_prefix
+ *
+ * Purpose: Add object to prefix
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+add_prefix(char **prfx, size_t *prfx_len, const char *name)
+{
+ size_t new_len = HDstrlen(*prfx) + HDstrlen(name) + 2;
+
+ /* Check if we need more space */
+ if(*prfx_len <= new_len) {
+ *prfx_len = new_len + 1;
+ *prfx = (char *)HDrealloc(*prfx, *prfx_len);
+ }
+
+ /* Append object name to prefix */
+ HDstrcat(HDstrcat(*prfx, "/"), name);
+} /* end add_prefix */
+
diff --git a/tools/src/h5dump/h5dump.h b/tools/src/h5dump/h5dump.h
new file mode 100644
index 0000000..8224c02
--- /dev/null
+++ b/tools/src/h5dump/h5dump.h
@@ -0,0 +1,115 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#ifndef H5DUMP_H__
+#define H5DUMP_H__
+
+#include "hdf5.h"
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+#include "h5tools_ref.h"
+#include "h5trav.h"
+#include "h5dump_defines.h"
+
+/**
+ ** This is the global dispatch table for the dump functions.
+ **/
+/* the table of dump functions */
+typedef struct dump_functions_t {
+ void (*dump_group_function) (hid_t, const char *);
+ void (*dump_named_datatype_function) (hid_t, const char *);
+ void (*dump_dataset_function) (hid_t, const char *, struct subset_t *);
+ void (*dump_dataspace_function) (hid_t);
+ void (*dump_datatype_function) (hid_t);
+ herr_t (*dump_attribute_function) (hid_t, const char *, const H5A_info_t *, void *);
+ void (*dump_data_function) (hid_t, int, struct subset_t *, int);
+} dump_functions;
+
+/* List of table structures. There is one table structure for each file */
+typedef struct h5dump_table_items_t {
+ unsigned long fileno; /* File number that these tables refer to */
+ hid_t oid; /* ID of an object in this file, held open so fileno is consistent */
+ table_t *group_table; /* Table of groups */
+ table_t *dset_table; /* Table of datasets */
+ table_t *type_table; /* Table of datatypes */
+} h5dump_table_items_t;
+typedef struct h5dump_table_list_t {
+ size_t nalloc;
+ size_t nused;
+ h5dump_table_items_t *tables;
+} h5dump_table_list_t;
+
+h5dump_table_list_t table_list = {0, 0, NULL};
+table_t *group_table = NULL, *dset_table = NULL, *type_table = NULL;
+unsigned dump_indent = 0; /*how far in to indent the line */
+
+int unamedtype = 0; /* shared datatype with no name */
+hbool_t hit_elink = FALSE; /* whether we have traversed an external link */
+size_t prefix_len = 1024;
+char *prefix = NULL;
+const char *fp_format = NULL;
+
+/* things to display or which are set via command line parameters */
+int display_all = TRUE;
+int display_oid = FALSE;
+int display_data = TRUE;
+int display_attr_data = TRUE;
+int display_char = FALSE; /*print 1-byte numbers as ASCII */
+int usingdasho = FALSE;
+int display_bb = FALSE; /*superblock */
+int display_dcpl = FALSE; /*dcpl */
+int display_fi = FALSE; /*file index */
+int display_ai = TRUE; /*array index */
+int display_escape = FALSE; /*escape non printable characters */
+int display_region = FALSE; /*print region reference data */
+int disable_compact_subset= FALSE; /* disable compact form of subset notation */
+int display_packed_bits = FALSE; /*print 1-8 byte numbers as packed bits*/
+int include_attrs = TRUE; /* Display attributes */
+int display_vds_first = FALSE; /* vds display to all by default*/
+int vds_gap_size = 0; /* vds skip missing files default is none */
+
+/* sort parameters */
+H5_index_t sort_by = H5_INDEX_NAME; /*sort_by [creation_order | name] */
+H5_iter_order_t sort_order = H5_ITER_INC; /*sort_order [ascending | descending] */
+
+#define PACKED_BITS_MAX 8 /* Maximum number of packed-bits to display */
+#define PACKED_BITS_SIZE_MAX (8*sizeof(long long)) /* Maximum bits size of integer types of packed-bits */
+/* mask list for packed bits */
+unsigned long long packed_mask[PACKED_BITS_MAX]; /* packed bits are restricted to 8*sizeof(llong) bytes */
+
+/* packed bits display parameters */
+unsigned packed_offset[PACKED_BITS_MAX];
+unsigned packed_length[PACKED_BITS_MAX];
+
+/*
+ * The global table is set to either ddl_function_table or
+ * xml_function_table in the initialization.
+ */
+const dump_functions *dump_function_table;
+
+#ifdef __cplusplus
+"C" {
+#endif
+
+void add_prefix(char **prfx, size_t *prfx_len, const char *name);
+hid_t h5_fileaccess(void);
+ssize_t table_list_add(hid_t oid, unsigned long file_no);
+ssize_t table_list_visited(unsigned long file_no);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !H5DUMP_H__ */
diff --git a/tools/src/h5dump/h5dump_ddl.c b/tools/src/h5dump/h5dump_ddl.c
new file mode 100644
index 0000000..182d570
--- /dev/null
+++ b/tools/src/h5dump/h5dump_ddl.c
@@ -0,0 +1,2178 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_dump.h"
+#include "h5tools_utils.h"
+#include "h5tools_ref.h"
+#include "h5trav.h"
+#include "h5dump_extern.h"
+#include "h5dump_ddl.h"
+
+typedef struct {
+ hid_t fid; /* File ID being traversed */
+ const char *op_name; /* Object name wanted */
+} trav_handle_udata_t;
+
+typedef struct {
+ const char *path; /* Path of object being searched */
+ const char *op_name; /* Object name wanted */
+} trav_attr_udata_t;
+
+/* callback function used by H5Literate() */
+static herr_t dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void *op_data);
+static int dump_extlink(hid_t group, const char *linkname, const char *objname);
+
+/*-------------------------------------------------------------------------
+ * Function: dump_datatype
+ *
+ * Purpose: Dump the datatype. Datatype can be HDF5 predefined
+ * atomic datatype or committed/transient datatype.
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_datatype(hid_t type)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ h5dump_type_table = type_table;
+ h5tools_dump_datatype(rawoutstream, outputformat, &ctx, type);
+ h5dump_type_table = NULL;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_dataspace
+ *
+ * Purpose: Dump the dataspace. Dataspace can be named dataspace,
+ * array, or others.
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_dataspace(hid_t space)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ h5tools_dump_dataspace(rawoutstream, outputformat, &ctx, space);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_attr_cb
+ *
+ * Purpose: attribute function callback called by H5Aiterate2, displays the attribute
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications: Pedro Vicente, October 4, 2007
+ * Added H5A_info_t parameter to conform with H5Aiterate2
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+dump_attr_cb(hid_t oid, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *info, void H5_ATTR_UNUSED *_op_data)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+
+ hid_t attr_id;
+ herr_t ret = SUCCEED;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ attr_id = H5Aopen(oid, attr_name, H5P_DEFAULT);
+ oid_output = display_oid;
+ data_output = display_data;
+ attr_data_output = display_attr_data;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ h5dump_type_table = type_table;
+ h5tools_dump_attribute(rawoutstream, outputformat, &ctx, attr_name, attr_id, display_ai, display_char);
+ h5dump_type_table = NULL;
+
+ if(attr_id < 0) {
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+
+ return ret;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_all_cb
+ *
+ * Purpose: function callback called by H5Literate,
+ * displays everything in the specified object
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ * RMcG, November 2000
+ * Added XML support. Also, optionally checks the op_data argument
+ *
+ * PVN, May 2008
+ * Dump external links
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ATTR_UNUSED *op_data)
+{
+ hid_t obj;
+ hid_t dapl_id = H5P_DEFAULT; /* dataset access property list ID */
+ herr_t ret = SUCCEED;
+ char *obj_path = NULL; /* Full path of object */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ /* Build the object's path name */
+ obj_path = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2);
+ if(!obj_path) {
+ ret = FAIL;
+ goto done;
+ }
+
+ HDstrcpy(obj_path, prefix);
+ HDstrcat(obj_path, "/");
+ HDstrcat(obj_path, name);
+
+ if(linfo->type == H5L_TYPE_HARD) {
+ H5O_info_t oinfo;
+
+ /* Stat the object */
+ if(H5Oget_info_by_name(group, name, &oinfo, H5P_DEFAULT) < 0) {
+ error_msg("unable to get object information for \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ goto done;
+ } /* end if */
+
+ switch(oinfo.type) {
+ case H5O_TYPE_GROUP:
+ if((obj = H5Gopen2(group, name, H5P_DEFAULT)) < 0) {
+ error_msg("unable to dump group \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ char *old_prefix; /* Pointer to previous prefix */
+
+ /* Keep copy of prefix before iterating into group */
+ old_prefix = HDstrdup(prefix);
+ HDassert(old_prefix);
+
+ /* Append group name to prefix */
+ add_prefix(&prefix, &prefix_len, name);
+
+ /* Iterate into group */
+ dump_function_table->dump_group_function(obj, name);
+
+ /* Restore old prefix name */
+ HDstrcpy(prefix, old_prefix);
+ HDfree(old_prefix);
+
+ /* Close group */
+ H5Gclose(obj);
+ }
+ break;
+
+ case H5O_TYPE_DATASET:
+ if(display_data) {
+ if ((dapl_id = H5Pcreate(H5P_DATASET_ACCESS)) < 0) {
+ error_msg("error in creating default access property list ID\n");
+ }
+ if (display_vds_first) {
+ if(H5Pset_virtual_view(dapl_id, H5D_VDS_FIRST_MISSING) < 0)
+ error_msg("error in setting access property list ID, virtual_view\n");
+ }
+ if (vds_gap_size > 0) {
+ if(H5Pset_virtual_printf_gap(dapl_id, (hsize_t)vds_gap_size) < 0)
+ error_msg("error in setting access property list ID, virtual_printf_gap\n");
+ }
+ }
+ if((obj = H5Dopen2(group, name, dapl_id)) >= 0) {
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(dset_table, oinfo.addr);
+
+ if(found_obj == NULL) {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->datasetbegin, name,
+ h5tools_dump_header_format->datasetblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->datasetblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend);
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ H5Dclose(obj);
+ goto done;
+ }
+ else if(found_obj->displayed) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->datasetbegin, name,
+ h5tools_dump_header_format->datasetblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\"", HARDLINK, found_obj->objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->datasetblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend);
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ H5Dclose(obj);
+ goto done;
+ }
+ else {
+ found_obj->displayed = TRUE;
+ }
+ } /* end if */
+
+ dump_function_table->dump_dataset_function(obj, name, NULL);
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ H5Dclose(obj);
+ }
+ else {
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ error_msg("unable to dump dataset \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ if((obj = H5Topen2(group, name, H5P_DEFAULT)) < 0) {
+ error_msg("unable to dump datatype \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ dump_function_table->dump_named_datatype_function(obj, name);
+ H5Tclose(obj);
+ }
+ break;
+
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ error_msg("unknown object \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ } /* end if */
+ else {
+ char *targbuf;
+
+ switch(linfo->type) {
+ case H5L_TYPE_SOFT:
+ targbuf = (char *)HDmalloc(linfo->u.val_size);
+ HDassert(targbuf);
+
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->softlinkbegin, name,
+ h5tools_dump_header_format->softlinkblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+
+ if(H5Lget_val(group, name, targbuf, linfo->u.val_size, H5P_DEFAULT) < 0) {
+ error_msg("unable to get link value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ /* print the value of a soft link */
+ /* Standard DDL: no modification */
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "LINKTARGET \"%s\"", targbuf);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->softlinkblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->softlinkblockend);
+ if(HDstrlen(h5tools_dump_header_format->softlinkend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->softlinkend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->softlinkend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(targbuf);
+ break;
+
+ case H5L_TYPE_EXTERNAL:
+ targbuf = (char *)HDmalloc(linfo->u.val_size);
+ HDassert(targbuf);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->extlinkbegin, name,
+ h5tools_dump_header_format->extlinkblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ if(H5Lget_val(group, name, targbuf, linfo->u.val_size, H5P_DEFAULT) < 0) {
+ indentation(dump_indent);
+ error_msg("unable to get external link value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ } /* end if */
+ else {
+ const char *filename;
+ const char *targname;
+
+ if(H5Lunpack_elink_val(targbuf, linfo->u.val_size, NULL, &filename, &targname) < 0) {
+ indentation(dump_indent);
+ error_msg("unable to unpack external link value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ } /* end if */
+ else {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "TARGETFILE \"%s\"", filename);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "TARGETPATH \"%s\"", targname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* dump the external link */
+ dump_extlink(group, name, targname);
+ ctx.indent_level--;
+ } /* end else */
+ } /* end else */
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->extlinkblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->extlinkblockend);
+ if(HDstrlen(h5tools_dump_header_format->extlinkend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->extlinkend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->extlinkend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(targbuf);
+ break;
+
+ case H5L_TYPE_ERROR:
+ case H5L_TYPE_MAX:
+ HDassert(0);
+ /* fall through */
+ case H5L_TYPE_HARD:
+ default:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->udlinkbegin, name,
+ h5tools_dump_header_format->udlinkblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "LINKCLASS %d", linfo->type);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->udlinkblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->udlinkblockend);
+ if(HDstrlen(h5tools_dump_header_format->udlinkend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->udlinkend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->udlinkend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ break;
+ } /* end switch */
+ } /* end else */
+
+done:
+
+ h5tools_str_close(&buffer);
+
+ if(obj_path)
+ HDfree(obj_path);
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: attr_iteration
+ *
+ * Purpose: Iterate and display attributes within the specified group
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+attr_iteration(hid_t gid, unsigned attr_crt_order_flags)
+{
+ /* attribute iteration: if there is a request to do H5_INDEX_CRT_ORDER and tracking order is set
+ in the group for attributes, then, sort by creation order, otherwise by name */
+ if(include_attrs) {
+ if((sort_by == H5_INDEX_CRT_ORDER) && (attr_crt_order_flags & H5P_CRT_ORDER_TRACKED)) {
+ if(H5Aiterate2(gid, sort_by, sort_order, NULL, dump_attr_cb, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end if */
+ else {
+ if(H5Aiterate2(gid, H5_INDEX_NAME, sort_order, NULL, dump_attr_cb, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end else */
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: link_iteration
+ *
+ * Purpose: Iterate and display links within the specified group
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+link_iteration(hid_t gid, unsigned crt_order_flags)
+{
+
+ /* if there is a request to do H5_INDEX_CRT_ORDER and tracking order is set
+ in the group, then, sort by creation order, otherwise by name */
+ if((sort_by == H5_INDEX_CRT_ORDER) && (crt_order_flags & H5P_CRT_ORDER_TRACKED))
+ H5Literate(gid, sort_by, sort_order, NULL, dump_all_cb, NULL);
+ else
+ H5Literate(gid, H5_INDEX_NAME, sort_order, NULL, dump_all_cb, NULL);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_named_datatype
+ *
+ * Purpose: Dump named datatype
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ * Pedro Vicente, March 27, 2006
+ * added display of attributes
+ * Pedro Vicente, October 4, 2007, added parameters to H5Aiterate2() to allow for
+ * other iteration orders
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_named_datatype(hid_t tid, const char *name)
+{
+ H5O_info_t oinfo;
+ unsigned attr_crt_order_flags;
+ hid_t tcpl_id = -1; /* datatype creation property list ID */
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ if ((tcpl_id = H5Tget_create_plist(tid)) < 0) {
+ error_msg("error in getting creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the creation properties for attributes */
+ if (H5Pget_attr_creation_order(tcpl_id, &attr_crt_order_flags) < 0) {
+ error_msg("error in getting creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ if(H5Pclose(tcpl_id) < 0) {
+ error_msg("error in closing creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->datatypebegin, name,
+ h5tools_dump_header_format->datatypeblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ H5Oget_info(tid, &oinfo);
+
+ /* Must check for uniqueness of all objects if we've traversed an elink,
+ * otherwise only check if the reference count > 1.
+ */
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(type_table, oinfo.addr);
+
+ if (found_obj == NULL) {
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ else if (found_obj->displayed) {
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\"", HARDLINK, found_obj->objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ goto done;
+ }
+ else
+ found_obj->displayed = TRUE;
+ } /* end if */
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_print_datatype(rawoutstream, &buffer, outputformat, &ctx, tid, FALSE);
+
+ if(H5Tget_class(tid) != H5T_COMPOUND) {
+ h5tools_str_append(&buffer, ";");
+ }
+
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* print attributes */
+ dump_indent += COL;
+
+ attr_iteration(tid, attr_crt_order_flags);
+
+ dump_indent -= COL;
+
+done:
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ 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_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_group
+ *
+ * Purpose: Dump everything within the specified group
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ * Call to dump_all_cb -- add parameter to select everything.
+ *
+ * Pedro Vicente, October 1, 2007
+ * handle several iteration orders for attributes and groups
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_group(hid_t gid, const char *name)
+{
+ H5O_info_t oinfo;
+ hid_t dset;
+ hid_t type;
+ hid_t gcpl_id;
+ unsigned crt_order_flags;
+ unsigned attr_crt_order_flags;
+ char type_name[1024];
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ if ((gcpl_id = H5Gget_create_plist(gid)) < 0) {
+ error_msg("error in getting group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties for attributes */
+ if (H5Pget_attr_creation_order(gcpl_id, &attr_crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties */
+ if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ if(H5Pclose(gcpl_id) < 0) {
+ error_msg("error in closing group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->groupbegin, name,
+ h5tools_dump_header_format->groupblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ if(!HDstrcmp(name, "/") && unamedtype) {
+ unsigned u; /* Local index variable */
+
+ /* dump unamed type in root group */
+ for(u = 0; u < type_table->nobjs; u++)
+ if(!type_table->objs[u].recorded) {
+ dset = H5Dopen2(gid, type_table->objs[u].objname, H5P_DEFAULT);
+ type = H5Dget_type(dset);
+ sprintf(type_name, "#"H5_PRINTF_HADDR_FMT, type_table->objs[u].objno);
+ dump_function_table->dump_named_datatype_function(type, type_name);
+ H5Tclose(type);
+ H5Dclose(dset);
+ }
+ } /* end if */
+
+ if(display_oid)
+ h5tools_dump_oid(rawoutstream, outputformat, &ctx, gid);
+
+ h5tools_dump_comment(rawoutstream, outputformat, &ctx, gid);
+
+ H5Oget_info(gid, &oinfo);
+
+ /* Must check for uniqueness of all objects if we've traversed an elink,
+ * otherwise only check if the reference count > 1.
+ */
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(group_table, oinfo.addr);
+
+ if (found_obj == NULL) {
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else if (found_obj->displayed) {
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\"", HARDLINK, found_obj->objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ found_obj->displayed = TRUE;
+ attr_iteration(gid, attr_crt_order_flags);
+ link_iteration(gid, crt_order_flags);
+ }
+ }
+ else {
+ attr_iteration(gid, attr_crt_order_flags);
+ link_iteration(gid, crt_order_flags);
+ }
+
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->groupblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->groupblockend);
+ if(HDstrlen(h5tools_dump_header_format->groupend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->groupend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->groupend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_dataset
+ *
+ * Purpose: Dump the specified data set
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ * Pedro Vicente, 2004, added dataset creation property list display
+ * Pedro Vicente, October 4, 2007, added parameters to H5Aiterate2() to allow for
+ * other iteration orders
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_dataset(hid_t did, const char *name, struct subset_t *sset)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ hid_t type, space;
+ unsigned attr_crt_order_flags;
+ hid_t dcpl_id; /* dataset creation property list ID */
+ h5tools_str_t buffer; /* string into which to render */
+ hsize_t curr_pos = 0; /* total data element position */
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ if ((dcpl_id = H5Dget_create_plist(did)) < 0) {
+ error_msg("error in getting creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the creation properties for attributes */
+ if (H5Pget_attr_creation_order(dcpl_id, &attr_crt_order_flags) < 0) {
+ error_msg("error in getting creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->datasetbegin, name,
+ h5tools_dump_header_format->datasetblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_dump_comment(rawoutstream, outputformat, &ctx, did);
+
+ dump_indent += COL;
+ ctx.indent_level++;
+
+ type = H5Dget_type(did);
+ h5dump_type_table = type_table;
+ h5tools_dump_datatype(rawoutstream, outputformat, &ctx, type);
+ h5dump_type_table = NULL;
+
+ space = H5Dget_space(did);
+ h5tools_dump_dataspace(rawoutstream, outputformat, &ctx, space);
+ H5Sclose(space);
+
+ if(display_oid) {
+ h5tools_dump_oid(rawoutstream, outputformat, &ctx, did);
+ }
+
+ if(display_dcpl) {
+ h5dump_type_table = type_table;
+ h5tools_dump_dcpl(rawoutstream, outputformat, &ctx, dcpl_id, type, did);
+ h5dump_type_table = NULL;
+ }
+ H5Pclose(dcpl_id);
+
+ if(display_data) {
+ unsigned data_loop = 1;
+ unsigned u;
+
+ if(display_packed_bits)
+ data_loop = packed_bits_num;
+ for(u = 0; u < data_loop; u++) {
+ if(display_packed_bits) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ packed_data_mask = packed_mask[u];
+ packed_data_offset = packed_offset[u];
+ packed_data_length = packed_length[u];
+ h5tools_print_packed_bits(&buffer, type);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ switch(H5Tget_class(type)) {
+ case H5T_TIME:
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "DATA{ not yet implemented.}");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+ break;
+
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_COMPOUND:
+ case H5T_REFERENCE:
+ case H5T_ENUM:
+ case H5T_VLEN:
+ case H5T_ARRAY:
+ {
+ h5tools_dump_data(rawoutstream, outputformat, &ctx, did, TRUE, sset, display_ai, display_char);
+ }
+ break;
+
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES:
+ default:
+ HDassert(0);
+ break;
+ } /* end switch */
+ } /* for(u=0; u<data_loop; u++) */
+ }
+ H5Tclose(type);
+
+ if (!bin_output) {
+ attr_iteration(did, attr_crt_order_flags);
+ }
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->datasetblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend);
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_data
+ *
+ * Purpose: Dump attribute or dataset data
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications: pvn, print the matrix indices
+ * Albert Cheng, 2004/11/18
+ * Add --string printing for attributes too.
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_data(hid_t obj_id, int obj_data, struct subset_t *sset, int display_index)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ int print_dataset = FALSE;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ if(obj_data == DATASET_DATA)
+ print_dataset = TRUE;
+ h5tools_dump_data(rawoutstream, outputformat, &ctx, obj_id, print_dataset, sset, display_index, display_char);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_fcpl
+ *
+ * Purpose: prints file creation property list information
+ *
+ * Return: void
+ *
+ * Programmer: pvn
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_fcpl(hid_t fid)
+{
+ hid_t fcpl; /* file creation property list ID */
+ hsize_t userblock; /* userblock size retrieved from FCPL */
+ size_t off_size; /* size of offsets in the file */
+ size_t len_size; /* size of lengths in the file */
+ H5F_file_space_type_t fs_strategy; /* file space strategy */
+ hsize_t fs_threshold; /* free-space section threshold */
+ H5F_info2_t finfo; /* file information */
+#ifdef SHOW_FILE_DRIVER
+ hid_t fapl; /* file access property list ID */
+ hid_t fdriver; /* file driver */
+ char dname[32]; /* buffer to store driver name */
+#endif
+ unsigned sym_lk; /* symbol table B-tree leaf 'K' value */
+ unsigned sym_ik; /* symbol table B-tree internal 'K' value */
+ unsigned istore_ik; /* indexed storage B-tree internal 'K' value */
+
+ fcpl=H5Fget_create_plist(fid);
+ H5Fget_info2(fid, &finfo);
+ H5Pget_userblock(fcpl,&userblock);
+ H5Pget_sizes(fcpl,&off_size,&len_size);
+ H5Pget_sym_k(fcpl,&sym_ik,&sym_lk);
+ H5Pget_istore_k(fcpl,&istore_ik);
+ H5Pget_file_space(fcpl, &fs_strategy, &fs_threshold);
+ H5Pclose(fcpl);
+#ifdef SHOW_FILE_DRIVER
+ fapl=h5_fileaccess();
+ fdriver=H5Pget_driver(fapl);
+ H5Pclose(fapl);
+#endif
+
+ /*-------------------------------------------------------------------------
+ * SUPER_BLOCK
+ *-------------------------------------------------------------------------
+ */
+ PRINTSTREAM(rawoutstream, "\n%s %s\n",SUPER_BLOCK, BEGIN);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","SUPERBLOCK_VERSION", finfo.super.version);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","FREELIST_VERSION", finfo.free.version);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","SYMBOLTABLE_VERSION", 0); /* Retain this for backward compatibility, for now (QAK) */
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","OBJECTHEADER_VERSION", finfo.sohm.version);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream,"%s %zu\n","OFFSET_SIZE", off_size);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream,"%s %zu\n","LENGTH_SIZE", len_size);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","BTREE_RANK", sym_ik);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %d\n","BTREE_LEAF", sym_lk);
+
+#ifdef SHOW_FILE_DRIVER
+ if(H5FD_CORE==fdriver)
+ HDstrcpy(dname,"H5FD_CORE");
+#ifdef H5_HAVE_DIRECT
+ else if(H5FD_DIRECT==fdriver)
+ HDstrcpy(dname,"H5FD_DIRECT");
+#endif
+ else if(H5FD_FAMILY==fdriver)
+ HDstrcpy(dname,"H5FD_FAMILY");
+ else if(H5FD_LOG==fdriver)
+ HDstrcpy(dname,"H5FD_LOG");
+ else if(H5FD_MPIO==fdriver)
+ HDstrcpy(dname,"H5FD_MPIO");
+ else if(H5FD_MULTI==fdriver)
+ HDstrcpy(dname,"H5FD_MULTI");
+ else if(H5FD_SEC2==fdriver)
+ HDstrcpy(dname,"H5FD_SEC2");
+ else if(H5FD_STDIO==fdriver)
+ HDstrcpy(dname,"H5FD_STDIO");
+ else
+ HDstrcpy(dname,"Unknown driver");
+
+ /* Take out this because the driver used can be different from the
+ * standard output. */
+ /*indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %s\n","FILE_DRIVER", dname);*/
+#endif
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","ISTORE_K", istore_ik);
+
+ indentation(dump_indent + COL);
+ if(fs_strategy == H5F_FILE_SPACE_ALL_PERSIST) {
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_ALL_PERSIST");
+ } else if(fs_strategy == H5F_FILE_SPACE_ALL) {
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_ALL");
+ } else if(fs_strategy == H5F_FILE_SPACE_AGGR_VFD) {
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_AGGR_VFD");
+ } else if(fs_strategy == H5F_FILE_SPACE_VFD) {
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_VFD");
+ } else
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "Unknown strategy");
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %Hu\n","FREE_SPACE_THRESHOLD", fs_threshold);
+
+ /*-------------------------------------------------------------------------
+ * USER_BLOCK
+ *-------------------------------------------------------------------------
+ */
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "USER_BLOCK %s\n",BEGIN);
+ indentation(dump_indent + COL + COL);
+ PRINTSTREAM(rawoutstream,"%s %Hu\n","USERBLOCK_SIZE", userblock);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s\n",END);
+
+ PRINTSTREAM(rawoutstream, "%s",END);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_fcontents
+ *
+ * Purpose: prints all objects
+ *
+ * Return: void
+ *
+ * Programmer: pvn
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_fcontents(hid_t fid)
+{
+ PRINTSTREAM(rawoutstream, "%s %s\n",FILE_CONTENTS, BEGIN);
+
+ /* special case of unamed types in root group */
+ if (unamedtype) {
+ unsigned u;
+
+ for (u = 0; u < type_table->nobjs; u++) {
+ if (!type_table->objs[u].recorded)
+ PRINTSTREAM(rawoutstream, " %-10s /#"H5_PRINTF_HADDR_FMT"\n", "datatype", type_table->objs[u].objno);
+ }
+ }
+
+ /* print objects in the files */
+ h5trav_print(fid);
+
+ PRINTSTREAM(rawoutstream, " %s\n",END);
+}
+
+static herr_t
+attr_search(hid_t oid, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *ainfo, void *_op_data)
+{
+ herr_t ret = SUCCEED;
+ int j;
+ char *obj_op_name;
+ char *obj_name;
+ trav_attr_udata_t *attr_data = (trav_attr_udata_t*)_op_data;
+ const char *buf = attr_data->path;
+ const char *op_name = attr_data->op_name;
+
+ j = (int)HDstrlen(op_name) - 1;
+ /* find the last / */
+ while(j >= 0) {
+ if(op_name[j] == '/' && (j == 0 || (j > 0 && op_name[j - 1] != '\\')))
+ break;
+ j--;
+ }
+
+ obj_op_name = h5tools_str_replace(op_name + j + 1, "\\/", "/");
+
+ if(obj_op_name == NULL) {
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ if(HDstrcmp(attr_name, obj_op_name)==0) {
+ size_t u, v, w;
+
+ /* object name */
+ u = HDstrlen(buf);
+ v = HDstrlen(op_name);
+ w = u + 1 + v + 1 + 2;
+ obj_name = (char *)HDmalloc(w);
+ if(obj_name == NULL) {
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ HDmemset(obj_name, '\0', w);
+ if(op_name[0] != '/') {
+ HDstrncat(obj_name, buf, u + 1);
+ if(buf[u - 1] != '/')
+ HDstrncat(obj_name, "/", (size_t)2);
+ }
+ HDstrncat(obj_name, op_name, v + 1);
+
+ handle_attributes(oid, obj_name, NULL, 0, NULL);
+ HDfree(obj_name);
+ }
+ }
+ HDfree(obj_op_name);
+ }
+ return ret;
+} /* end attr_search() */
+
+static herr_t
+obj_search(const char *path, const H5O_info_t *oi, const char H5_ATTR_UNUSED *already_visited, void *_op_data)
+{
+ trav_handle_udata_t *handle_data = (trav_handle_udata_t*)_op_data;
+ const char *op_name = handle_data->op_name;
+ trav_attr_udata_t attr_data;
+
+ attr_data.path = path;
+ attr_data.op_name = op_name;
+ H5Aiterate_by_name(handle_data->fid, path, H5_INDEX_NAME, H5_ITER_INC, NULL, attr_search, (void*)&attr_data, H5P_DEFAULT);
+
+ if(HDstrcmp(path, op_name) == 0) {
+ switch(oi->type) {
+ case H5O_TYPE_GROUP:
+ handle_groups(handle_data->fid, path, NULL, 0, NULL);
+ break;
+
+ case H5O_TYPE_DATASET:
+ handle_datasets(handle_data->fid, path, NULL, 0, NULL);
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ handle_datatypes(handle_data->fid, path, NULL, 0, NULL);
+ break;
+
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ error_msg("unknown object type value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end switch */
+ }
+
+ return 0;
+} /* end obj_search() */
+
+static herr_t
+lnk_search(const char *path, const H5L_info_t *li, void *_op_data)
+{
+ size_t search_len;
+ size_t k;
+ char *search_name;
+ trav_handle_udata_t *handle_data = (trav_handle_udata_t*)_op_data;
+ const char *op_name = handle_data->op_name;
+
+ search_len = HDstrlen(op_name);
+ if(search_len > 0 && op_name[0] != '/')
+ k = 2;
+ else
+ k = 1;
+ search_name = (char *)HDmalloc(search_len + k);
+ if(search_name == NULL) {
+ error_msg("creating temporary link\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ if (k == 2) {
+ HDstrcpy(search_name, "/");
+ HDstrncat(search_name, op_name, search_len + 1);
+ }
+ else
+ HDstrncpy(search_name, op_name, search_len + 1);
+ search_name[search_len + k - 1] = '\0';
+
+ if(HDstrcmp(path, search_name) == 0) {
+ switch(li->type) {
+ case H5L_TYPE_SOFT:
+ case H5L_TYPE_EXTERNAL:
+ handle_links(handle_data->fid, op_name, NULL, 0, NULL);
+ break;
+
+ case H5L_TYPE_HARD:
+ case H5L_TYPE_MAX:
+ case H5L_TYPE_ERROR:
+ default:
+ error_msg("unknown link type value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ break;
+ } /* end switch() */
+ }
+ HDfree(search_name);
+ }
+ return 0;
+} /* end lnk_search() */
+
+/*-------------------------------------------------------------------------
+ * Function: handle_paths
+ *
+ * Purpose: Handle objects from the command.
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_paths(hid_t fid, const char *path_name, void H5_ATTR_UNUSED * data, int H5_ATTR_UNUSED pe, const char H5_ATTR_UNUSED *display_name)
+{
+ hid_t gid = -1;
+
+ if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) {
+ error_msg("unable to open root group\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ hid_t gcpl_id;
+ unsigned crt_order_flags;
+ unsigned attr_crt_order_flags;
+ trav_handle_udata_t handle_udata; /* User data for traversal */
+
+ if ((gcpl_id = H5Gget_create_plist(gid)) < 0) {
+ error_msg("error in getting group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties for attributes */
+ if (H5Pget_attr_creation_order(gcpl_id, &attr_crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties */
+ if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ if(H5Pclose(gcpl_id) < 0) {
+ error_msg("error in closing group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ handle_udata.fid = fid;
+ handle_udata.op_name = path_name;
+ if(h5trav_visit(fid, "/", TRUE, TRUE, obj_search, lnk_search, &handle_udata) < 0) {
+ error_msg("error traversing information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: handle_attributes
+ *
+ * Purpose: Handle the attributes from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications:
+ *
+ * PVN, May 2008
+ * add an extra parameter PE, to allow printing/not printing of error messages
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_attributes(hid_t fid, const char *attr, void H5_ATTR_UNUSED * data, int H5_ATTR_UNUSED pe, const char H5_ATTR_UNUSED *display_name)
+{
+ hid_t oid = -1;
+ hid_t attr_id = -1;
+ char *obj_name = NULL;
+ char *attr_name = NULL;
+ int j;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ j = (int)HDstrlen(attr) - 1;
+ obj_name = (char *)HDmalloc((size_t)j + 2);
+ if(obj_name == NULL)
+ goto error;
+
+ /* find the last / */
+ while(j >= 0) {
+ if (attr[j] == '/' && (j==0 || (j>0 && attr[j-1]!='\\')))
+ break;
+ j--;
+ }
+
+ /* object name */
+ if(j == -1)
+ HDstrcpy(obj_name, "/");
+ else {
+ HDstrncpy(obj_name, attr, (size_t)j + 1);
+ obj_name[j + 1] = '\0';
+ } /* end else */
+
+ dump_indent += COL;
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ attr_name = h5tools_str_replace(attr + j + 1, "\\/", "/");
+
+ /* handle error case: cannot open the object with the attribute */
+ if((oid = H5Oopen(fid, obj_name, H5P_DEFAULT)) < 0) {
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->attributebegin, attr,
+ h5tools_dump_header_format->attributeblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ error_msg("unable to open object \"%s\"\n", obj_name);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->attributeblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->attributeblockend);
+ if(HDstrlen(h5tools_dump_header_format->attributeend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->attributeend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->attributeend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+
+ goto error;
+ } /* end if */
+
+ attr_id = H5Aopen(oid, attr_name, H5P_DEFAULT);
+ oid_output = display_oid;
+ data_output = display_data;
+ attr_data_output = display_attr_data;
+
+ h5dump_type_table = type_table;
+ h5tools_dump_attribute(rawoutstream, outputformat, &ctx, attr_name, attr_id, display_ai, display_char);
+ h5dump_type_table = NULL;
+
+ if(attr_id < 0) {
+ goto error;
+ }
+
+ /* Close object */
+ if(H5Oclose(oid) < 0) {
+ goto error;
+ } /* end if */
+
+ HDfree(obj_name);
+ HDfree(attr_name);
+ dump_indent -= COL;
+ return;
+
+error:
+ h5tools_setstatus(EXIT_FAILURE);
+ if(obj_name)
+ HDfree(obj_name);
+
+ if (attr_name)
+ HDfree(attr_name);
+
+ H5E_BEGIN_TRY {
+ H5Oclose(oid);
+ H5Aclose(attr_id);
+ } H5E_END_TRY;
+ dump_indent -= COL;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: handle_datasets
+ *
+ * Purpose: Handle the datasets from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications:
+ * Pedro Vicente, Tuesday, January 15, 2008
+ * check for block overlap\
+ *
+ * Pedro Vicente, May 8, 2008
+ * added a flag PE that prints/not prints error messages
+ * added for cases of external links not found, to avoid printing of
+ * objects not found, since external links are dumped on a trial error basis
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_datasets(hid_t fid, const char *dset, void *data, int pe, const char *display_name)
+{
+ H5O_info_t oinfo;
+ hid_t dsetid;
+ hid_t dapl_id = H5P_DEFAULT; /* dataset access property list ID */
+ struct subset_t *sset = (struct subset_t *)data;
+ const char *real_name = display_name ? display_name : dset;
+
+ if(display_data) {
+ if ((dapl_id = H5Pcreate(H5P_DATASET_ACCESS)) < 0) {
+ error_msg("error in creating default access property list ID\n");
+ }
+ if (display_vds_first) {
+ if(H5Pset_virtual_view(dapl_id, H5D_VDS_FIRST_MISSING) < 0)
+ error_msg("error in setting access property list ID, virtual_view\n");
+ }
+ if (vds_gap_size > 0) {
+ if(H5Pset_virtual_printf_gap(dapl_id, (hsize_t)vds_gap_size) < 0)
+ error_msg("error in setting access property list ID, virtual_printf_gap\n");
+ }
+ }
+ if((dsetid = H5Dopen2(fid, dset, dapl_id)) < 0) {
+ if (pe)
+ handle_links(fid, dset, data, pe, display_name);
+ return;
+ } /* end if */
+
+ if(sset) {
+ unsigned int i;
+ unsigned int ndims;
+ hid_t sid = H5Dget_space(dsetid);
+ int ndims_res = H5Sget_simple_extent_ndims(sid);
+
+ H5Sclose(sid);
+ if(ndims_res < 0) {
+ error_msg("H5Sget_simple_extent_ndims failed\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+ ndims = (unsigned)ndims_res;
+
+ if(!sset->start.data || !sset->stride.data || !sset->count.data || !sset->block.data) {
+ /* they didn't specify a ``stride'' or ``block''. default to 1 in all
+ * dimensions */
+ if(!sset->start.data) {
+ /* default to (0, 0, ...) for the start coord */
+ sset->start.data = (hsize_t *)HDcalloc((size_t)ndims, sizeof(hsize_t));
+ sset->start.len = ndims;
+ }
+
+ if(!sset->stride.data) {
+ sset->stride.data = (hsize_t *)HDcalloc((size_t)ndims, sizeof(hsize_t));
+ sset->stride.len = ndims;
+ for (i = 0; i < ndims; i++)
+ sset->stride.data[i] = 1;
+ }
+
+ if(!sset->count.data) {
+ sset->count.data = (hsize_t *)HDcalloc((size_t)ndims, sizeof(hsize_t));
+ sset->count.len = ndims;
+ for (i = 0; i < ndims; i++)
+ sset->count.data[i] = 1;
+ }
+
+ if(!sset->block.data) {
+ sset->block.data = (hsize_t *)HDcalloc((size_t)ndims, sizeof(hsize_t));
+ sset->block.len = ndims;
+ for (i = 0; i < ndims; i++)
+ sset->block.data[i] = 1;
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * check for dimension overflow
+ *-------------------------------------------------------------------------
+ */
+ if(sset->start.len > ndims) {
+ error_msg("number of start dims (%u) exceed dataset dims (%u)\n", sset->start.len, ndims);
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+ if(sset->stride.len > ndims) {
+ error_msg("number of stride dims (%u) exceed dataset dims (%u)\n", sset->stride.len, ndims);
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+ if(sset->count.len > ndims) {
+ error_msg("number of count dims (%u) exceed dataset dims (%u)\n", sset->count.len, ndims);
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+ if(sset->block.len > ndims) {
+ error_msg("number of block dims (%u) exceed dataset dims (%u)\n", sset->block.len, ndims);
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+
+ /*-------------------------------------------------------------------------
+ * check for block overlap
+ *-------------------------------------------------------------------------
+ */
+ for(i = 0; i < ndims; i++) {
+ if(sset->count.data[i] > 1) {
+ if(sset->stride.data[i] < sset->block.data[i]) {
+ error_msg("wrong subset selection; blocks overlap\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ } /* end if */
+ } /* end if */
+ } /* end for */
+ } /* end if */
+
+
+ H5Oget_info(dsetid, &oinfo);
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(dset_table, oinfo.addr);
+
+ if(found_obj) {
+ if (found_obj->displayed) {
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(dump_indent);
+ begin_obj(h5tools_dump_header_format->datasetbegin, real_name, h5tools_dump_header_format->datasetblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s \"%s\"\n", HARDLINK, found_obj->objname);
+ indentation(dump_indent);
+ end_obj(h5tools_dump_header_format->datasetend, h5tools_dump_header_format->datasetblockend);
+ }
+ else {
+ found_obj->displayed = TRUE;
+ dump_indent += COL;
+ dump_dataset(dsetid, real_name, sset);
+ dump_indent -= COL;
+ }
+ }
+ else
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ dump_indent += COL;
+ dump_dataset(dsetid, real_name, sset);
+ dump_indent -= COL;
+ }
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ if(H5Dclose(dsetid) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: handle_groups
+ *
+ * Purpose: Handle the groups from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications: Pedro Vicente, September 26, 2007
+ * handle creation order
+ *
+ * Pedro Vicente, May 8, 2008
+ * added a flag PE that prints/not prints error messages
+ * added for cases of external links not found, to avoid printing of
+ * objects not found, since external links are dumped on a trial error basis
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_groups(hid_t fid, const char *group, void H5_ATTR_UNUSED *data, int pe, const char *display_name)
+{
+ hid_t gid;
+ const char *real_name = display_name ? display_name : group;
+
+ if((gid = H5Gopen2(fid, group, H5P_DEFAULT)) < 0) {
+ if (pe) {
+ PRINTVALSTREAM(rawoutstream, "\n");
+ begin_obj(h5tools_dump_header_format->groupbegin, real_name, h5tools_dump_header_format->groupblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ error_msg("unable to open group \"%s\"\n", real_name);
+ end_obj(h5tools_dump_header_format->groupend, h5tools_dump_header_format->groupblockend);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ }
+ else {
+ size_t new_len = HDstrlen(group) + 1;
+
+ if(prefix_len <= new_len) {
+ prefix_len = new_len;
+ prefix = (char *)HDrealloc(prefix, prefix_len);
+ } /* end if */
+
+ HDstrcpy(prefix, group);
+
+ dump_indent += COL;
+ dump_group(gid, real_name);
+ dump_indent -= COL;
+
+ if(H5Gclose(gid) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end else */
+} /* end handle_groups() */
+
+/*-------------------------------------------------------------------------
+ * Function: handle_links
+ *
+ * Purpose: Handle soft or UD links from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_links(hid_t fid, const char *links, void H5_ATTR_UNUSED * data, int H5_ATTR_UNUSED pe, const char H5_ATTR_UNUSED *display_name)
+{
+ H5L_info_t linfo;
+
+ if(H5Lget_info(fid, links, &linfo, H5P_DEFAULT) < 0) {
+ error_msg("unable to get link info from \"%s\"\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else if(linfo.type == H5L_TYPE_HARD) {
+ error_msg("\"%s\" is a hard link\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ char *buf = (char *)HDmalloc(linfo.u.val_size);
+ PRINTVALSTREAM(rawoutstream, "\n");
+
+ switch(linfo.type) {
+ case H5L_TYPE_SOFT: /* Soft link */
+ begin_obj(h5tools_dump_header_format->softlinkbegin, links, h5tools_dump_header_format->softlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ if(H5Lget_val(fid, links, buf, linfo.u.val_size, H5P_DEFAULT) >= 0) {
+ PRINTSTREAM(rawoutstream, "LINKTARGET \"%s\"\n", buf);
+ }
+ else {
+ error_msg("h5dump error: unable to get link value for \"%s\"\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ end_obj(h5tools_dump_header_format->softlinkend, h5tools_dump_header_format->softlinkblockend);
+ break;
+
+ case H5L_TYPE_EXTERNAL:
+ begin_obj(h5tools_dump_header_format->udlinkbegin, links, h5tools_dump_header_format->udlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ begin_obj(h5tools_dump_header_format->extlinkbegin, links, h5tools_dump_header_format->extlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ if(H5Lget_val(fid, links, buf, linfo.u.val_size, H5P_DEFAULT) >= 0) {
+ const char *elink_file;
+ const char *elink_path;
+
+ if(H5Lunpack_elink_val(buf, linfo.u.val_size, NULL, &elink_file, &elink_path)>=0) {
+ indentation(COL);
+ PRINTSTREAM(rawoutstream, "LINKCLASS %d\n", linfo.type);
+ indentation(COL);
+ PRINTSTREAM(rawoutstream, "TARGETFILE \"%s\"\n", elink_file);
+ indentation(COL);
+ PRINTSTREAM(rawoutstream, "TARGETPATH \"%s\"\n", elink_path);
+ }
+ else {
+ error_msg("h5dump error: unable to unpack external link value for \"%s\"\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ }
+ else {
+ error_msg("h5dump error: unable to get external link value for \"%s\"\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ end_obj(h5tools_dump_header_format->extlinkend, h5tools_dump_header_format->extlinkblockend);
+ break;
+
+ case H5L_TYPE_ERROR:
+ case H5L_TYPE_MAX:
+ HDassert(0);
+ /* fall through */
+ case H5L_TYPE_HARD:
+ default:
+ begin_obj(h5tools_dump_header_format->udlinkbegin, links, h5tools_dump_header_format->udlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ begin_obj(h5tools_dump_header_format->udlinkbegin, links, h5tools_dump_header_format->udlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ PRINTSTREAM(rawoutstream, "LINKCLASS %d\n", linfo.type);
+ end_obj(h5tools_dump_header_format->udlinkend, h5tools_dump_header_format->udlinkblockend);
+ break;
+ } /* end switch */
+ HDfree(buf);
+ } /* end else */
+}
+
+/*-------------------------------------------------------------------------
+ * Function: handle_datatypes
+ *
+ * Purpose: Handle the datatypes from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications:
+ *
+ * Pedro Vicente, May 8, 2008
+ * added a flag PE that prints/not prints error messages
+ * added for cases of external links not found, to avoid printing of
+ * objects not found, since external links are dumped on a trial error basis
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_datatypes(hid_t fid, const char *type, void H5_ATTR_UNUSED * data, int pe, const char *display_name)
+{
+ hid_t type_id;
+ const char *real_name = display_name ? display_name : type;
+
+ if((type_id = H5Topen2(fid, type, H5P_DEFAULT)) < 0) {
+ /* check if type is unamed datatype */
+ unsigned idx = 0;
+
+ while(idx < type_table->nobjs ) {
+ char name[128];
+
+ if(!type_table->objs[idx].recorded) {
+ /* unamed datatype */
+ sprintf(name, "/#"H5_PRINTF_HADDR_FMT, type_table->objs[idx].objno);
+
+ if(!HDstrcmp(name, real_name))
+ break;
+ } /* end if */
+
+ idx++;
+ } /* end while */
+
+ if(idx == type_table->nobjs) {
+ if (pe) {
+ /* unknown type */
+ PRINTVALSTREAM(rawoutstream, "\n");
+ begin_obj(h5tools_dump_header_format->datatypebegin, real_name, h5tools_dump_header_format->datatypeblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ error_msg("unable to open datatype \"%s\"\n", real_name);
+ end_obj(h5tools_dump_header_format->datatypeend, h5tools_dump_header_format->datatypeblockend);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ }
+ else {
+ hid_t dsetid = H5Dopen2(fid, type_table->objs[idx].objname, H5P_DEFAULT);
+ type_id = H5Dget_type(dsetid);
+
+ dump_indent += COL;
+ dump_named_datatype(type_id, real_name);
+ dump_indent -= COL;
+
+ H5Tclose(type_id);
+ H5Dclose(dsetid);
+ }
+ }
+ else {
+ dump_indent += COL;
+ dump_named_datatype(type_id, real_name);
+ dump_indent -= COL;
+
+ if(H5Tclose(type_id) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_extlink
+ *
+ * made by: PVN
+ *
+ * Purpose: Dump an external link
+ * Since external links are soft links, they are dumped on a trial error
+ * basis, attempting to dump as a dataset, as a group and as a named datatype
+ * Error messages are supressed
+ *
+ * Modifications:
+ * Neil Fortner
+ * 13 October 2008
+ * Function basically rewritten. No longer directly opens the target file,
+ * now initializes a new set of tables for the external file. No longer
+ * dumps on a trial and error basis, but errors are still suppressed.
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+dump_extlink(hid_t group, const char *linkname, const char *objname)
+{
+ hid_t oid;
+ H5O_info_t oi;
+ table_t *old_group_table = group_table;
+ table_t *old_dset_table = dset_table;
+ table_t *old_type_table = type_table;
+ hbool_t old_hit_elink;
+ ssize_t idx;
+
+ /* Open target object */
+ if ((oid = H5Oopen(group, linkname, H5P_DEFAULT)) < 0)
+ goto fail;
+
+ /* Get object info */
+ if (H5Oget_info(oid, &oi) < 0) {
+ H5Oclose(oid);
+ goto fail;
+ }
+
+ /* Check if we have visited this file already */
+ if ((idx = table_list_visited(oi.fileno)) < 0) {
+ /* We have not visited this file, build object tables */
+ if ((idx = table_list_add(oid, oi.fileno)) < 0) {
+ H5Oclose(oid);
+ goto fail;
+ }
+ }
+
+ /* Do not recurse through an external link into the original file (idx=0) */
+ if (idx) {
+ /* Update table pointers */
+ group_table = table_list.tables[idx].group_table;
+ dset_table = table_list.tables[idx].dset_table;
+ type_table = table_list.tables[idx].type_table;
+
+ /* We will now traverse the external link, set this global to indicate this */
+ old_hit_elink = hit_elink;
+ hit_elink = TRUE;
+
+ /* add some indentation to distinguish that these objects are external */
+ dump_indent += COL;
+
+ /* Recurse into the external file */
+ switch (oi.type) {
+ case H5O_TYPE_GROUP:
+ handle_groups(group, linkname, NULL, 0, objname);
+ break;
+
+ case H5O_TYPE_DATASET:
+ handle_datasets(group, linkname, NULL, 0, objname);
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ handle_datatypes(group, linkname, NULL, 0, objname);
+ break;
+
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ dump_indent -= COL;
+
+ /* Reset table pointers */
+ group_table = old_group_table;
+ dset_table = old_dset_table;
+ type_table = old_type_table;
+
+ /* Reset hit_elink */
+ hit_elink = old_hit_elink;
+ } /* end if */
+
+ if (H5Idec_ref(oid) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+
+ return SUCCEED;
+
+fail:
+ return FAIL;
+}
+
diff --git a/tools/src/h5dump/h5dump_ddl.h b/tools/src/h5dump/h5dump_ddl.h
new file mode 100644
index 0000000..2b3f61e
--- /dev/null
+++ b/tools/src/h5dump/h5dump_ddl.h
@@ -0,0 +1,52 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef H5DUMP_DDL_H__
+#define H5DUMP_DDL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The dump functions of the dump_function_table */
+/* standard format: no change */
+void dump_group(hid_t, const char *);
+void dump_named_datatype(hid_t, const char *);
+void dump_dataset(hid_t, const char *, struct subset_t *);
+void dump_dataspace(hid_t space);
+void dump_datatype(hid_t type);
+void dump_data(hid_t, int, struct subset_t *, int);
+void dump_fcpl(hid_t fid);
+void dump_fcontents(hid_t fid);
+
+/* callback function used by H5Aiterate2() */
+herr_t dump_attr_cb(hid_t loc_id, const char *attr_name, const H5A_info_t *info, void *_op_data);
+
+/* other iteration functions */
+void link_iteration(hid_t gid, unsigned crt_order_flags);
+void attr_iteration(hid_t gid, unsigned attr_crt_order_flags);
+
+void handle_paths(hid_t fid, const char *path_name, void *data, int pe, const char *display_name);
+void handle_datasets(hid_t fid, const char *dset, void *data, int pe, const char *display_name);
+void handle_attributes(hid_t fid, const char *attr, void H5_ATTR_UNUSED * data, int H5_ATTR_UNUSED pe, const char H5_ATTR_UNUSED *display_name);
+void handle_groups(hid_t fid, const char *group, void H5_ATTR_UNUSED *data, int pe, const char *display_name);
+void handle_links(hid_t fid, const char *links, void H5_ATTR_UNUSED * data, int H5_ATTR_UNUSED pe, const char H5_ATTR_UNUSED *display_name);
+void handle_datatypes(hid_t fid, const char *type, void H5_ATTR_UNUSED * data, int pe, const char *display_name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !H5DUMP_DDL_H__ */
diff --git a/tools/src/h5dump/h5dump_defines.h b/tools/src/h5dump/h5dump_defines.h
new file mode 100644
index 0000000..2be2dcc
--- /dev/null
+++ b/tools/src/h5dump/h5dump_defines.h
@@ -0,0 +1,56 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#ifndef H5DUMP_DEFINES_H__
+#define H5DUMP_DEFINES_H__
+
+#define H5DUMP_MAX_RANK H5S_MAX_RANK
+
+#define ATTRIBUTE_DATA 0
+#define DATASET_DATA 1
+#define ENUM_DATA 2
+#define COL 3
+
+/* Macros for displaying objects */
+#define begin_obj(obj,name,begin) \
+ do { \
+ if ((name)) { \
+ PRINTSTREAM(rawoutstream, "%s \"%s\" %s", (obj), (name), (begin)); \
+ } \
+ else { \
+ PRINTSTREAM(rawoutstream, "%s %s", (obj), (begin)); \
+ } \
+ } while(0);
+
+#define end_obj(obj,end) \
+ do { \
+ if(HDstrlen(end)) { \
+ PRINTSTREAM(rawoutstream, "%s", end); \
+ if(HDstrlen(obj)) \
+ PRINTVALSTREAM(rawoutstream, " "); \
+ } \
+ if(HDstrlen(obj)) \
+ PRINTSTREAM(rawoutstream, "%s", obj); \
+ } while(0);
+
+
+/* 3 private values: can't be set, but can be read.
+ Note: these are defined in H5Zprivate, they are
+ duplicated here.
+ */
+#define H5_SZIP_LSB_OPTION_MASK 8
+#define H5_SZIP_MSB_OPTION_MASK 16
+#define H5_SZIP_RAW_OPTION_MASK 128
+
+#endif /* !H5DUMP_DEFINES_H__ */
diff --git a/tools/src/h5dump/h5dump_extern.h b/tools/src/h5dump/h5dump_extern.h
new file mode 100644
index 0000000..8fef1b9
--- /dev/null
+++ b/tools/src/h5dump/h5dump_extern.h
@@ -0,0 +1,114 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#ifndef H5DUMP_EXTERN_H__
+#define H5DUMP_EXTERN_H__
+
+#include "hdf5.h"
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+#include "h5tools_ref.h"
+#include "h5trav.h"
+#include "h5dump_defines.h"
+
+/**
+ ** This is the global dispatch table for the dump functions.
+ **/
+/* the table of dump functions */
+typedef struct dump_functions_t {
+ void (*dump_group_function) (hid_t, const char *);
+ void (*dump_named_datatype_function) (hid_t, const char *);
+ void (*dump_dataset_function) (hid_t, const char *, struct subset_t *);
+ void (*dump_dataspace_function) (hid_t);
+ void (*dump_datatype_function) (hid_t);
+ herr_t (*dump_attribute_function) (hid_t, const char *, const H5A_info_t *, void *);
+ void (*dump_data_function) (hid_t, int, struct subset_t *, int);
+} dump_functions;
+
+/* List of table structures. There is one table structure for each file */
+typedef struct h5dump_table_list_t {
+ size_t nalloc;
+ size_t nused;
+ struct {
+ unsigned long fileno; /* File number that these tables refer to */
+ hid_t oid; /* ID of an object in this file, held open so fileno is consistent */
+ table_t *group_table; /* Table of groups */
+ table_t *dset_table; /* Table of datasets */
+ table_t *type_table; /* Table of datatypes */
+ } *tables;
+} h5dump_table_list_t;
+
+extern h5dump_table_list_t table_list;
+extern table_t *group_table, *dset_table, *type_table;
+extern unsigned dump_indent; /*how far in to indent the line */
+
+extern int unamedtype; /* shared datatype with no name */
+extern hbool_t hit_elink; /* whether we have traversed an external link */
+extern size_t prefix_len;
+extern char *prefix;
+extern const char *fp_format;
+
+/* things to display or which are set via command line parameters */
+extern int display_all;
+extern int display_oid;
+extern int display_data;
+extern int display_attr_data;
+extern int display_char; /*print 1-byte numbers as ASCII */
+extern int usingdasho;
+extern int display_bb; /*superblock */
+extern int display_dcpl; /*dcpl */
+extern int display_fi; /*file index */
+extern int display_ai; /*array index */
+extern int display_escape; /*escape non printable characters */
+extern int display_region; /*print region reference data */
+extern int disable_compact_subset; /* disable compact form of subset notation */
+extern int display_packed_bits; /*print 1-8 byte numbers as packed bits*/
+extern int include_attrs; /* Display attributes */
+extern int display_vds_first; /* vds display to first missing */
+extern int vds_gap_size; /* vds skip missing files */
+
+/* sort parameters */
+extern H5_index_t sort_by; /*sort_by [creation_order | name] */
+extern H5_iter_order_t sort_order; /*sort_order [ascending | descending] */
+
+#define PACKED_BITS_MAX 8 /* Maximum number of packed-bits to display */
+#define PACKED_BITS_SIZE_MAX 8*sizeof(long long) /* Maximum bits size of integer types of packed-bits */
+/* mask list for packed bits */
+extern unsigned long long packed_mask[PACKED_BITS_MAX]; /* packed bits are restricted to 8*sizeof(llong) bytes */
+
+/* packed bits display parameters */
+extern unsigned packed_offset[PACKED_BITS_MAX];
+extern unsigned packed_length[PACKED_BITS_MAX];
+
+/*
+ * The global table is set to either ddl_function_table or
+ * xml_function_table in the initialization.
+ */
+extern const dump_functions *dump_function_table;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void add_prefix(char **prfx, size_t *prfx_len, const char *name);
+hid_t h5_fileaccess(void);
+ssize_t table_list_add(hid_t oid, unsigned long file_no);
+ssize_t table_list_visited(unsigned long file_no);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !H5DUMP_EXTERN_H__ */
diff --git a/tools/src/h5dump/h5dump_xml.c b/tools/src/h5dump/h5dump_xml.c
new file mode 100644
index 0000000..41f3914
--- /dev/null
+++ b/tools/src/h5dump/h5dump_xml.c
@@ -0,0 +1,4567 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_dump.h"
+#include "h5tools_utils.h"
+#include "h5tools_ref.h"
+#include "h5trav.h"
+#include "h5dump_extern.h"
+#include "h5dump_xml.h"
+
+const char *xmlnsprefix="hdf5:";
+
+/*
+ * Alternative formating for data dumped to XML
+ * In general, the numbers are the same, but separators
+ * except spaces are not used.
+ *
+ * Some of these are not used, as some kinds of data are
+ * dumped in completely new subroutines.
+ *
+ * Some of this formatting may yet need to change.
+ *
+ * This table only affects XML output.
+ */
+static h5tool_format_t xml_dataformat = {
+ 0, /*raw */
+
+ "", /*fmt_raw */
+ "%d", /*fmt_int */
+ "%u", /*fmt_uint */
+ "%hhd", /*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 */
+ "", /*cmpd_sep */
+ "", /*cmpd_pre */
+ "", /*cmpd_suf */
+ "", /*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 */
+ 0, /*array indices */
+ 0 /*escape non printable characters */
+};
+
+
+/* internal functions */
+static int xml_name_to_XID(const char *, char *, int , int );
+
+/* internal functions used by XML option */
+static void xml_print_datatype(hid_t, unsigned);
+static void xml_print_enum(hid_t);
+static int xml_print_refs(hid_t, int);
+static int xml_print_strs(hid_t, int);
+static char *xml_escape_the_string(const char *, int);
+static char *xml_escape_the_name(const char *);
+
+/*-------------------------------------------------------------------------
+ * Function: xml_dump_all_cb
+ *
+ * Purpose: function callback called by H5Literate,
+ * displays everything in the specified object
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ * RMcG, November 2000
+ * Added XML support. Also, optionally checks the op_data argument
+ *
+ * PVN, May 2008
+ * Dump external links
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+xml_dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ATTR_UNUSED *op_data)
+{
+ hid_t obj;
+ herr_t ret = SUCCEED;
+ char *obj_path = NULL; /* Full path of object */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols==0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ /* Build the object's path name */
+ obj_path = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2);
+ if(!obj_path) {
+ ret = FAIL;
+ goto done;
+ }
+
+ HDstrcpy(obj_path, prefix);
+ HDstrcat(obj_path, "/");
+ HDstrcat(obj_path, name);
+
+ if(linfo->type == H5L_TYPE_HARD) {
+ H5O_info_t oinfo;
+
+ /* Stat the object */
+ if(H5Oget_info_by_name(group, name, &oinfo, H5P_DEFAULT) < 0) {
+ error_msg("unable to get object information for \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ goto done;
+ } /* end if */
+
+ switch(oinfo.type) {
+ case H5O_TYPE_GROUP:
+ if((obj = H5Gopen2(group, name, H5P_DEFAULT)) < 0) {
+ error_msg("unable to dump group \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ char *old_prefix; /* Pointer to previous prefix */
+
+ /* Keep copy of prefix before iterating into group */
+ old_prefix = HDstrdup(prefix);
+ HDassert(old_prefix);
+
+ /* Append group name to prefix */
+ add_prefix(&prefix, &prefix_len, name);
+
+ /* Iterate into group */
+ dump_function_table->dump_group_function(obj, name);
+
+ /* Restore old prefix name */
+ HDstrcpy(prefix, old_prefix);
+ HDfree(old_prefix);
+
+ /* Close group */
+ H5Gclose(obj);
+ }
+ break;
+
+ case H5O_TYPE_DATASET:
+ if((obj = H5Dopen2(group, name, H5P_DEFAULT)) >= 0) {
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(dset_table, oinfo.addr);
+
+ if(found_obj == NULL) {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->datasetbegin, name,
+ h5tools_dump_header_format->datasetblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->datasetblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend);
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ H5Dclose(obj);
+ goto done;
+ }
+ else if(found_obj->displayed) {
+ /* the XML version */
+ char *t_obj_path = xml_escape_the_name(obj_path);
+ char *t_prefix = xml_escape_the_name(HDstrcmp(prefix,"") ? prefix : "/");
+ char *t_name = xml_escape_the_name(name);
+ char *t_objname = xml_escape_the_name(found_obj->objname);
+ char dsetxid[100];
+ char parentxid[100];
+ char pointerxid[100];
+
+ /* Create OBJ-XIDs for the parent and object */
+ xml_name_to_XID(obj_path, dsetxid, (int)sizeof(dsetxid), 1);
+ xml_name_to_XID(prefix, parentxid, (int)sizeof(parentxid), 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataset Name=\"%s\" OBJ-XID=\"%s-%d\" "
+ "H5Path=\"%s\" Parents=\"%s\" "
+ "H5ParentPaths=\"%s\">",
+ xmlnsprefix,
+ t_name, /* Dataset Name */
+ dsetxid, get_next_xid(), /* OBJ-XID */
+ t_obj_path, /* H5Path */
+ parentxid, /* Parents */
+ t_prefix); /* H5ParentPaths */
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ xml_name_to_XID(found_obj->objname, pointerxid, (int)sizeof(pointerxid), 1);
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDatasetPtr OBJ-XID=\"%s\" H5Path=\"%s\"/>",
+ xmlnsprefix,
+ pointerxid,t_objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataset>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(t_name);
+ HDfree(t_obj_path);
+ HDfree(t_prefix);
+ HDfree(t_objname);
+
+ H5Dclose(obj);
+ goto done;
+ }
+ else
+ found_obj->displayed = TRUE;
+ } /* end if */
+
+ dump_function_table->dump_dataset_function(obj, name, NULL);
+ H5Dclose(obj);
+ }
+ else {
+ error_msg("unable to dump dataset \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ if((obj = H5Topen2(group, name, H5P_DEFAULT)) < 0) {
+ error_msg("unable to dump datatype \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ dump_function_table->dump_named_datatype_function(obj, name);
+ H5Tclose(obj);
+ }
+ break;
+
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ error_msg("unknown object \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ } /* end if */
+ else {
+ char *targbuf;
+
+ switch(linfo->type) {
+ case H5L_TYPE_SOFT:
+ targbuf = (char *)HDmalloc(linfo->u.val_size);
+ HDassert(targbuf);
+
+ if(H5Lget_val(group, name, targbuf, linfo->u.val_size, H5P_DEFAULT) < 0) {
+ error_msg("unable to get link value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ /* print the value of a soft link */
+ /* XML */
+ char linkxid[100];
+ char parentxid[100];
+ char targetxid[100];
+ char *t_prefix = xml_escape_the_name(HDstrcmp(prefix,"") ? prefix : "/");
+ char *t_name = xml_escape_the_name(name);
+ char *t_targbuf = xml_escape_the_name(targbuf);
+ char *t_obj_path = xml_escape_the_name(obj_path);
+ char *t_link_path;
+ int res;
+
+ t_link_path = (char *)HDmalloc(HDstrlen(prefix) + linfo->u.val_size + 1);
+ if(targbuf[0] == '/')
+ HDstrcpy(t_link_path, targbuf);
+ else {
+ HDstrcpy(t_link_path, prefix);
+ HDstrcat(HDstrcat(t_link_path, "/"), targbuf);
+ } /* end else */
+
+ /* Create OBJ-XIDs for the parent and object */
+ xml_name_to_XID(t_obj_path, linkxid, (int)sizeof(linkxid), 1);
+ xml_name_to_XID(prefix, parentxid, (int)sizeof(parentxid), 1);
+
+ /* Try to create an OBJ-XID for the object pointed to */
+ res = xml_name_to_XID(t_link_path, targetxid, (int)sizeof(targetxid), 0);
+ if (res == 0) {
+ /* target obj found */
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sSoftLink LinkName=\"%s\" "
+ "OBJ-XID=\"%s\" "
+ "H5SourcePath=\"%s\" "
+ "TargetPath=\"%s\" TargetObj=\"%s\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\" />",
+ xmlnsprefix,
+ t_name, /* LinkName */
+ linkxid, /* OBJ-XID */
+ t_obj_path, /* H5SourcePath */
+ t_targbuf, /* TargetPath */
+ targetxid, /* TargetObj */
+ parentxid, /* Parents */
+ t_prefix); /* H5ParentPaths */
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ /* dangling link -- omit from xml attributes */
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sSoftLink LinkName=\"%s\" "
+ "OBJ-XID=\"%s\" "
+ "H5SourcePath=\"%s\" "
+ "TargetPath=\"%s\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\" />",
+ xmlnsprefix,
+ t_name, /* LinkName */
+ linkxid, /* OBJ-XID */
+ t_obj_path, /* H5SourcePath */
+ t_targbuf, /* TargetPath */
+ parentxid, /* Parents */
+ t_prefix); /* H5ParentPaths */
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ HDfree(t_prefix);
+ HDfree(t_name);
+ HDfree(t_targbuf);
+ HDfree(t_obj_path);
+ HDfree(t_link_path);
+ }
+
+ HDfree(targbuf);
+ break;
+
+ case H5L_TYPE_EXTERNAL:
+ targbuf = (char *)HDmalloc(linfo->u.val_size);
+ HDassert(targbuf);
+
+ if(H5Lget_val(group, name, targbuf, linfo->u.val_size, H5P_DEFAULT) < 0) {
+ error_msg("unable to get external link value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ } /* end if */
+ else {
+ const char *filename;
+ const char *targname;
+
+ if(H5Lunpack_elink_val(targbuf, linfo->u.val_size, NULL, &filename, &targname) < 0) {
+ error_msg("unable to unpack external link value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ } /* end if */
+ else {
+ char linkxid[100];
+ char parentxid[100];
+ char *t_name = xml_escape_the_name(name);
+ char *t_prefix = xml_escape_the_name(HDstrcmp(prefix,"") ? prefix : "/");
+ char *t_obj_path = xml_escape_the_name(obj_path);
+ char *t_filename = xml_escape_the_name(filename);
+ char *t_targname = xml_escape_the_name(targname);
+
+ /* Create OBJ-XIDs for the parent and object */
+ xml_name_to_XID(t_obj_path, linkxid, (int)sizeof(linkxid), 1);
+ xml_name_to_XID(prefix, parentxid, (int)sizeof(parentxid), 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sExternalLink LinkName=\"%s\" "
+ "OBJ-XID=\"%s\" "
+ "H5SourcePath=\"%s\" "
+ "TargetFilename=\"%s\" "
+ "TargetPath=\"%s\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\" />",
+ xmlnsprefix,
+ t_name, /* LinkName */
+ linkxid, /* OBJ-XID */
+ t_obj_path, /* H5SourcePath */
+ filename, /* TargetFilename */
+ targname, /* TargetPath*/
+ parentxid, /* Parents */
+ t_prefix); /* H5ParentPaths */
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(t_prefix);
+ HDfree(t_name);
+ HDfree(t_filename);
+ HDfree(t_targname);
+ HDfree(t_obj_path);
+ } /* end else */
+ } /* end else */
+ HDfree(targbuf);
+ break;
+
+ case H5L_TYPE_ERROR:
+ case H5L_TYPE_MAX:
+ HDassert(0);
+ /* fall through */
+ case H5L_TYPE_HARD:
+ default:
+ {
+ char linkxid[100];
+ char parentxid[100];
+ char *t_name = xml_escape_the_name(name);
+ char *t_prefix = xml_escape_the_name(HDstrcmp(prefix,"") ? prefix : "/");
+ char *t_obj_path = xml_escape_the_name(obj_path);
+
+ /* Create OBJ-XIDs for the parent and object */
+ xml_name_to_XID(t_obj_path, linkxid, (int)sizeof(linkxid), 1);
+ xml_name_to_XID(prefix, parentxid, (int)sizeof(parentxid), 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sUserDefined LinkName=\"%s\" "
+ "OBJ-XID=\"%s\" "
+ "H5SourcePath=\"%s\" "
+ "LinkClass=\"%d\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\" />",
+ xmlnsprefix,
+ t_name, /* LinkName */
+ linkxid, /* OBJ-XID */
+ t_obj_path, /* H5SourcePath */
+ linfo->type, /* LinkClass */
+ parentxid, /* Parents */
+ t_prefix); /* H5ParentPaths */
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(t_prefix);
+ HDfree(t_name);
+ HDfree(t_obj_path);
+ }
+ break;
+
+ } /* end switch */
+ } /* end else */
+
+done:
+
+ h5tools_str_close(&buffer);
+
+ if(obj_path)
+ HDfree(obj_path);
+ return ret;
+}
+
+/*
+ * create a string suitable for and XML NCNAME. Uses the
+ * object reference to create the string.
+ *
+ * 'gen'; 0 - return null if not found
+ * 1 - generate a fake entry and return fake id.
+ */
+int
+xml_name_to_XID(const char *str , char *outstr, int outlen, int gen)
+{
+ haddr_t objno; /* Object ID for object at path */
+
+ if (outlen < 22) return 1;
+
+ objno = ref_path_table_lookup(str);
+ if (objno == HADDR_UNDEF) {
+ if (HDstrlen(str) == 0) {
+ objno = ref_path_table_lookup("/");
+ if (objno == HADDR_UNDEF) {
+ if (gen) {
+ objno = ref_path_table_gen_fake(str);
+ sprintf(outstr, "xid_"H5_PRINTF_HADDR_FMT, objno);
+ return 0;
+ }
+ else {
+ return 1;
+ }
+ }
+ }
+ else {
+ if (gen) {
+ objno = ref_path_table_gen_fake(str);
+ sprintf(outstr, "xid_"H5_PRINTF_HADDR_FMT, objno);
+ return 0;
+ }
+ else {
+ return 1;
+ }
+ }
+ }
+
+ sprintf(outstr, "xid_"H5_PRINTF_HADDR_FMT, objno);
+
+ return(0);
+}
+
+static const char *quote = "&quot;";
+static const char *amp = "&amp;";
+static const char *lt = "&lt;";
+static const char *gt = "&gt;";
+static const char *apos = "&apos;";
+
+/*-------------------------------------------------------------------------
+ * Function: xml_escape_the_name
+ *
+ * Purpose: Escape XML reserved chars in a name, so HDF5 strings
+ * and paths can be correctly read back in XML element.
+ *
+ * Return: The revised string.
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static char *
+xml_escape_the_name(const char *str)
+{
+ size_t extra;
+ size_t len;
+ size_t i;
+ const char *cp;
+ char *ncp;
+ char *rcp;
+ size_t ncp_len;
+
+ if (!str)
+ return NULL;
+
+ cp = str;
+ len = HDstrlen(str);
+ extra = 0;
+
+ for (i = 0; i < len; i++) {
+ if (*cp == '\"')
+ extra += (HDstrlen(quote) - 1);
+ else if (*cp == '\'')
+ extra += (HDstrlen(apos) - 1);
+ else if (*cp == '<')
+ extra += (HDstrlen(lt) - 1);
+ else if (*cp == '>')
+ extra += (HDstrlen(gt) - 1);
+ else if (*cp == '&')
+ extra += (HDstrlen(amp) - 1);
+
+ cp++;
+ }
+
+ if (extra == 0)
+ return HDstrdup(str);
+
+ cp = str;
+ ncp_len = len + extra + 1;
+ rcp = ncp = (char *)HDmalloc(ncp_len);
+
+ if (!ncp)
+ return NULL; /* ?? */
+
+ for (i = 0; i < len; i++) {
+ size_t esc_len;
+
+ HDassert(ncp_len);
+ if (*cp == '\'') {
+ HDstrncpy(ncp, apos, ncp_len);
+ esc_len = HDstrlen(apos);
+ }
+ else if (*cp == '<') {
+ HDstrncpy(ncp, lt, ncp_len);
+ esc_len = HDstrlen(lt);
+ }
+ else if (*cp == '>') {
+ HDstrncpy(ncp, gt, ncp_len);
+ esc_len = HDstrlen(gt);
+ }
+ else if (*cp == '\"') {
+ HDstrncpy(ncp, quote, ncp_len);
+ esc_len = HDstrlen(quote);
+ }
+ else if (*cp == '&') {
+ HDstrncpy(ncp, amp, ncp_len);
+ esc_len = HDstrlen(amp);
+ }
+ else {
+ *ncp = *cp;
+ esc_len = 1;
+ }
+ ncp += esc_len;
+ ncp_len -= esc_len;
+ cp++;
+ }
+
+ *ncp = '\0';
+ return rcp;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_escape_the_string
+ *
+ * Purpose: Escape XML reserved chars in a string, so HDF5 strings
+ * and paths can be correctly read back in XML CDATA.
+ *
+ * Return: The revised string.
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static char *
+xml_escape_the_string(const char *str, int slen)
+{
+ size_t extra;
+ size_t len;
+ size_t i;
+ const char *cp;
+ char *ncp;
+ char *rcp;
+ size_t ncp_len;
+
+ if (!str)
+ return NULL;
+
+ cp = str;
+
+ if (slen < 0)
+ len = HDstrlen(str);
+ else
+ len = (size_t)slen;
+
+ extra = 0;
+
+ for (i = 0; i < len; i++) {
+ if (*cp == '\\')
+ extra++;
+ else if (*cp == '\"')
+ extra++;
+ else if (*cp == '\'')
+ extra += (HDstrlen(apos) - 1);
+ else if (*cp == '<')
+ extra += (HDstrlen(lt) - 1);
+ else if (*cp == '>')
+ extra += (HDstrlen(gt) - 1);
+ else if (*cp == '&')
+ extra += (HDstrlen(amp) - 1);
+ cp++;
+ }
+
+ cp = str;
+ ncp_len = len + extra + 1;
+ rcp = ncp = (char *) HDcalloc(ncp_len, sizeof(char));
+
+ if (ncp == NULL)
+ return NULL; /* ?? */
+
+ for (i = 0; i < len; i++) {
+ size_t esc_len;
+
+ HDassert(ncp_len);
+ if (*cp == '\\') {
+ *ncp++ = '\\';
+ *ncp = *cp;
+ esc_len = 1;
+ }
+ else if (*cp == '\"') {
+ *ncp++ = '\\';
+ *ncp = *cp;
+ esc_len = 1;
+ }
+ else if (*cp == '\'') {
+ HDstrncpy(ncp, apos, ncp_len);
+ esc_len = HDstrlen(apos);
+ }
+ else if (*cp == '<') {
+ HDstrncpy(ncp, lt, ncp_len);
+ esc_len = HDstrlen(lt);
+ }
+ else if (*cp == '>') {
+ HDstrncpy(ncp, gt, ncp_len);
+ esc_len = HDstrlen(gt);
+ }
+ else if (*cp == '&') {
+ HDstrncpy(ncp, amp, ncp_len);
+ esc_len = HDstrlen(amp);
+ }
+ else {
+ *ncp = *cp;
+ esc_len = 1;
+ }
+ ncp += esc_len;
+ ncp_len -= esc_len;
+ cp++;
+ }
+
+ *ncp = '\0';
+ return rcp;
+}
+
+/**
+ ** XML print functions--these replace some functions in the
+ ** h5tools.c suite.
+ **/
+
+/*-------------------------------------------------------------------------
+ * Function: xml_print_datatype
+ *
+ * Purpose: Print description of a datatype in XML.
+ * Note: this is called inside a <DataType> element.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+xml_print_datatype(hid_t type, unsigned in_group)
+{
+ char *mname;
+ hid_t mtype;
+ unsigned nmembers;
+ unsigned ndims;
+ unsigned i;
+ size_t size;
+ hsize_t dims[H5DUMP_MAX_RANK];
+ H5T_str_t str_pad;
+ H5T_cset_t cset;
+ hid_t super;
+ H5T_order_t ord;
+ H5T_sign_t sgn;
+ size_t sz;
+ size_t spos;
+ size_t epos;
+ size_t esize;
+ size_t mpos;
+ size_t msize;
+ int nmembs;
+ htri_t is_vlstr=FALSE;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols==0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ if(!in_group && H5Tcommitted(type) > 0) {
+ H5O_info_t oinfo;
+ obj_t *found_obj; /* Found object */
+
+ /* detect a shared datatype, output only once */
+ H5Oget_info(type, &oinfo);
+ found_obj = search_obj(type_table, oinfo.addr);
+
+ if(found_obj) {
+ /* This should be defined somewhere else */
+ /* These 2 cases are handled the same right now, but
+ probably will have something different eventually */
+ char * dtxid = (char *)HDmalloc((size_t)100);
+
+ xml_name_to_XID(found_obj->objname, dtxid, 100, 1);
+ if (!found_obj->recorded) {
+ /* 'anonymous' NDT. Use it's object num.
+ as it's name. */
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNamedDataTypePtr OBJ-XID=\"/%s\"/>",
+ xmlnsprefix, dtxid);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ /* point to the NDT by name */
+ char *t_objname = xml_escape_the_name(found_obj->objname);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNamedDataTypePtr OBJ-XID=\"%s\" H5Path=\"%s\"/>",
+ xmlnsprefix, dtxid, t_objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ HDfree(t_objname);
+ }
+ HDfree(dtxid);
+ }
+ else {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- h5dump error: unknown committed type. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ }
+ else {
+ switch (H5Tget_class(type)) {
+ case H5T_INTEGER:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+
+ /* <hdf5:IntegerType ByteOrder="bo" Sign="torf" Size="bytes"/> */
+ ord = H5Tget_order(type);
+ sgn = H5Tget_sign(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sIntegerType ByteOrder=\"",xmlnsprefix);
+ switch (ord) {
+ case H5T_ORDER_LE:
+ h5tools_str_append(&buffer, "LE");
+ break;
+ case H5T_ORDER_BE:
+ h5tools_str_append(&buffer, "BE");
+ break;
+ case H5T_ORDER_VAX:
+ case H5T_ORDER_MIXED:
+ case H5T_ORDER_NONE:
+ case H5T_ORDER_ERROR:
+ default:
+ h5tools_str_append(&buffer, "ERROR_UNKNOWN");
+ break;
+ } /* end switch */
+
+ h5tools_str_append(&buffer, "\" Sign=\"");
+
+ switch (sgn) {
+ case H5T_SGN_NONE:
+ h5tools_str_append(&buffer, "false");
+ break;
+ case H5T_SGN_2:
+ h5tools_str_append(&buffer, "true");
+ break;
+ case H5T_SGN_ERROR:
+ case H5T_NSGN:
+ default:
+ h5tools_str_append(&buffer, "ERROR_UNKNOWN");
+ break;
+ } /* end switch */
+
+ h5tools_str_append(&buffer, "\" Size=\"");
+ sz = H5Tget_size(type);
+ h5tools_str_append(&buffer, "%lu", (unsigned long)sz);
+ h5tools_str_append(&buffer, "\" />");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_FLOAT:
+ /* <hdf5:FloatType ByteOrder="bo" Size="bytes"
+ SignBitLocation="bytes"
+ ExponentBits="eb" ExponentLocation="el"
+ MantissaBits="mb" MantissaLocation="ml" /> */
+ ord = H5Tget_order(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sFloatType ByteOrder=\"",xmlnsprefix);
+
+ switch (ord) {
+ case H5T_ORDER_LE:
+ h5tools_str_append(&buffer, "LE");
+ break;
+ case H5T_ORDER_BE:
+ h5tools_str_append(&buffer, "BE");
+ break;
+ case H5T_ORDER_VAX:
+ h5tools_str_append(&buffer, "VAX");
+ break;
+ case H5T_ORDER_MIXED:
+ case H5T_ORDER_NONE:
+ case H5T_ORDER_ERROR:
+ default:
+ h5tools_str_append(&buffer, "ERROR_UNKNOWN");
+ } /* end switch */
+
+ h5tools_str_append(&buffer, "\" Size=\"");
+ sz = H5Tget_size(type);
+ h5tools_str_append(&buffer, "%lu", (unsigned long)sz);
+ H5Tget_fields(type, &spos, &epos, &esize, &mpos, &msize);
+ h5tools_str_append(&buffer, "\" SignBitLocation=\"%lu\" ", (unsigned long)spos);
+ h5tools_str_append(&buffer, "ExponentBits=\"%lu\" ExponentLocation=\"%lu\" ", (unsigned long)esize, (unsigned long)epos);
+ h5tools_str_append(&buffer, "MantissaBits=\"%lu\" MantissaLocation=\"%lu\" />", (unsigned long)msize, (unsigned long)mpos);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_TIME:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sTimeType />",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ h5tools_str_append(&buffer, "<!-- H5T_TIME: not yet implemented -->");
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_STRING:
+ /* <hdf5:StringType Cset="cs" StrSize="chars" StrPad="pad" /> */
+ size = H5Tget_size(type);
+ str_pad = H5Tget_strpad(type);
+ cset = H5Tget_cset(type);
+ is_vlstr = H5Tis_variable_str(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sStringType Cset=\"",xmlnsprefix);
+
+ if (cset == H5T_CSET_ASCII)
+ h5tools_str_append(&buffer, "H5T_CSET_ASCII\" ");
+ else
+ h5tools_str_append(&buffer, "unknown_cset\" ");
+
+ if(is_vlstr)
+ h5tools_str_append(&buffer, "StrSize=\"H5T_VARIABLE\" StrPad=\"");
+ else
+ h5tools_str_append(&buffer, "StrSize=\"%d\" StrPad=\"", (int) size);
+
+ if (str_pad == H5T_STR_NULLTERM)
+ h5tools_str_append(&buffer, "H5T_STR_NULLTERM\"/>");
+ else if (str_pad == H5T_STR_NULLPAD)
+ h5tools_str_append(&buffer, "H5T_STR_NULLPAD\"/>");
+ else if (str_pad == H5T_STR_SPACEPAD)
+ h5tools_str_append(&buffer, "H5T_STR_SPACEPAD\"/>");
+ else
+ h5tools_str_append(&buffer, "H5T_STR_ERROR\"/>");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_BITFIELD:
+ /* <hdf5:BitfieldType ByteOrder="bo" Size="bytes"/> */
+ ord = H5Tget_order(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sBitfieldType ByteOrder=\"",xmlnsprefix);
+
+ switch (ord) {
+ case H5T_ORDER_LE:
+ h5tools_str_append(&buffer, "LE");
+ break;
+ case H5T_ORDER_BE:
+ h5tools_str_append(&buffer, "BE");
+ break;
+ case H5T_ORDER_VAX:
+ case H5T_ORDER_MIXED:
+ case H5T_ORDER_NONE:
+ case H5T_ORDER_ERROR:
+ default:
+ h5tools_str_append(&buffer, "ERROR_UNKNOWN");
+ } /* end switch */
+
+ size = H5Tget_size(type);
+ h5tools_str_append(&buffer, "\" Size=\"%lu\"/>", (unsigned long)size);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_OPAQUE:
+ /* <hdf5:OpaqueType Tag="tag" Size="bytes" /> */
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+ mname = H5Tget_tag(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sOpaqueType Tag=\"%s\" ",xmlnsprefix, mname);
+ H5free_memory(mname);
+ size = H5Tget_size(type);
+ h5tools_str_append(&buffer, "Size=\"%lu\"/>", (unsigned long)size);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_COMPOUND:
+ /* recursively describe the components of a compound datatype */
+
+ /* type of a dataset */
+ nmembers = (unsigned)H5Tget_nmembers(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sCompoundType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* List each member Field of the type */
+ /* <hdf5:Field FieldName="name" > */
+ /* <hdf5:DataType > */
+ ctx.indent_level++;
+ dump_indent += COL;
+ for (i = 0; i < nmembers; i++) {
+ char *t_fname;
+
+ mname = H5Tget_member_name(type, i);
+ mtype = H5Tget_member_type(type, i);
+ t_fname = xml_escape_the_name(mname);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sField FieldName=\"%s\">",xmlnsprefix, t_fname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ H5free_memory(mname);
+ HDfree(t_fname);
+ dump_indent += COL;
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+ dump_indent += COL;
+ xml_print_datatype(mtype,0);
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sField>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sCompoundType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_REFERENCE:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+ /* Only Object references supported at this time */
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sReferenceType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sObjectReferenceType />",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sReferenceType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_ENUM:
+ /* <hdf5:EnumType Nelems="ne" > list Name, values of enum */
+ nmembs = H5Tget_nmembers(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ dump_indent += COL;
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sEnumType Nelems=\"%d\">",xmlnsprefix, nmembs);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ xml_print_enum(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sEnumType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAtomicType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_VLEN:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sVLType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ super = H5Tget_super(type);
+ dump_indent += COL;
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ dump_indent += COL;
+ ctx.indent_level++;
+ xml_print_datatype(super,0);
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sVLType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ H5Tclose(super);
+
+ break;
+
+ case H5T_ARRAY:
+ /* Get array base type */
+ super = H5Tget_super(type);
+
+ /* Print lead-in */
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sArrayType Ndims=\"",xmlnsprefix);
+ ndims = (unsigned)H5Tget_array_ndims(type);
+ h5tools_str_append(&buffer, "%u\">", ndims);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* Get array information */
+ H5Tget_array_dims2(type, dims);
+
+ /* list of dimensions */
+ ctx.indent_level++;
+ for (i = 0; i < ndims; i++) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sArrayDimension DimSize=\"%u\"/>", xmlnsprefix, (int) dims[i]);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ ctx.indent_level--;
+
+ dump_indent += COL;
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ dump_indent += COL;
+ ctx.indent_level++;
+ xml_print_datatype(super,0);
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sArrayType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ /* Close array base type */
+ H5Tclose(super);
+ break;
+
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES:
+ HDassert(0);
+ /* fall through */
+ default:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- unknown datatype -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ h5tools_setstatus(EXIT_FAILURE);
+ break;
+ }
+ } /* end else */
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_dump_datatype
+ *
+ * Purpose: Dump description of a datatype in XML.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+xml_dump_datatype(hid_t type)
+{
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ if(H5Tcommitted(type) > 0) {
+ H5O_info_t oinfo;
+ obj_t *found_obj; /* Found object */
+
+ /* Datatype is a shared or named datatype */
+ H5Oget_info(type, &oinfo);
+ found_obj = search_obj(type_table, oinfo.addr);
+
+ if(found_obj) {
+ /* Shared datatype, must be entered as an object */
+ /* These 2 cases are the same now, but may change */
+ char *dtxid = (char *)HDmalloc((size_t)100);
+
+ xml_name_to_XID(found_obj->objname, dtxid, 100, 1);
+ if (!found_obj->recorded) {
+ /* anonymous stored datatype:
+ following the dumper's current
+ practice:
+ use it's object ref as its name
+ */
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNamedDataTypePtr OBJ-XID=\"%s\"/>",
+ xmlnsprefix, dtxid);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ /* pointer to a named datatype already in XML */
+ char *t_objname = xml_escape_the_name(found_obj->objname);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNamedDataTypePtr OBJ-XID=\"%s\" H5Path=\"%s\" />",
+ xmlnsprefix, dtxid, t_objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ HDfree(t_objname);
+ }
+ HDfree(dtxid);
+ }
+ else {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- h5dump error: unknown committed type. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ }
+ else {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataType>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+ dump_indent += COL;
+ xml_print_datatype(type, 0);
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataType>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_dump_dataspace
+ *
+ * Purpose: Dump description of a dataspace in XML.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+xml_dump_dataspace(hid_t space)
+{
+ hsize_t size[H5DUMP_MAX_RANK];
+ hsize_t maxsize[H5DUMP_MAX_RANK];
+ int i;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ int ndims = H5Sget_simple_extent_dims(space, size, maxsize);
+ H5S_class_t space_type = H5Sget_simple_extent_type(space);
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataspace>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+
+ switch (space_type) {
+ case H5S_SCALAR:
+ /* scalar dataspace (just a tag, no XML attrs. defined */
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sScalarDataspace />",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5S_SIMPLE:
+ /* simple dataspace */
+ /* <hdf5:SimpleDataspace Ndims="nd"> */
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sSimpleDataspace Ndims=\"%d\">",xmlnsprefix, ndims);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* print the <hdf5:Dimension> elements */
+ ctx.indent_level++;
+ for (i = 0; i < ndims; i++) {
+ if (maxsize[i] == H5S_UNLIMITED) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDimension DimSize=\"%" H5_PRINTF_LL_WIDTH "u\" MaxDimSize=\"UNLIMITED\"/>",
+ xmlnsprefix,size[i]);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else if (maxsize[i] == (hsize_t) 0) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDimension DimSize=\"%" H5_PRINTF_LL_WIDTH "u\" MaxDimSize=\"%" H5_PRINTF_LL_WIDTH "u\"/>",
+ xmlnsprefix,size[i], size[i]);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDimension DimSize=\"%" H5_PRINTF_LL_WIDTH "u\" MaxDimSize=\"%" H5_PRINTF_LL_WIDTH "u\"/>",
+ xmlnsprefix, size[i], maxsize[i]);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ }
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sSimpleDataspace>", xmlnsprefix );
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+#ifdef TMP
+ /* Commented out: wait until the schema is updated first */
+ case H5S_NULL:
+ /* null dataspace (just a tag, no XML attrs. defined */
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNullDataspace />",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+#endif /* TMP */
+
+ case H5S_NULL:
+ case H5S_NO_CLASS:
+ default:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- unknown dataspace -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataspace>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_dump_data
+ *
+ * Purpose: Dump description of data in XML.
+ * Note that this calls the h5dump_xxx calls in
+ * the h5tools library.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+xml_dump_data(hid_t obj_id, int obj_data, struct subset_t H5_ATTR_UNUSED * sset, int H5_ATTR_UNUSED pindex)
+{
+ hid_t space = -1;
+ hid_t type = -1;
+ hid_t p_type = -1;
+ hsize_t size[64];
+ hsize_t nelmts = 1;
+ int ndims;
+ int i;
+ int status = -1;
+ void *buf = NULL;
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ /* Print all the values. */
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+ string_dataformat.cmpd_sep = " ";
+ string_dataformat.cmpd_pre = "";
+ string_dataformat.cmpd_suf = "";
+ string_dataformat.cmpd_end = "";
+ string_dataformat.arr_linebreak = 0;
+ string_dataformat.arr_pre = "";
+ outputformat = &string_dataformat;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ dump_indent += COL;
+ ctx.indent_level++;
+
+ if (obj_data == DATASET_DATA) {
+ type = H5Dget_type(obj_id);
+ if (H5Tget_class(type) == H5T_REFERENCE)
+ status = xml_print_refs(obj_id, DATASET_DATA);
+ else if (H5Tget_class(type) == H5T_STRING)
+ status = xml_print_strs(obj_id, DATASET_DATA);
+ else {
+ h5tools_context_t datactx;
+ HDmemset(&datactx, 0, sizeof(datactx));
+ datactx.need_prefix = TRUE;
+ datactx.indent_level = ctx.indent_level;
+ datactx.cur_column = ctx.cur_column;
+ status = h5tools_dump_dset(rawoutstream, outputformat, &datactx, obj_id, NULL);
+ }
+ }
+ else {
+ /* Attribute data */
+ type = H5Aget_type(obj_id);
+
+ if (H5Tget_class(type) == H5T_REFERENCE) {
+ /* references are done differently than
+ the standard output:
+ XML dumps a path to the object
+ referenced.
+ */
+ status = xml_print_refs(obj_id, ATTRIBUTE_DATA);
+ H5Tclose(type);
+ }
+ else if (H5Tget_class(type) == H5T_STRING) {
+ status = xml_print_strs(obj_id, ATTRIBUTE_DATA);
+ }
+ else { /* all other data */
+ /* VL data special information */
+ unsigned int vl_data = 0; /* contains VL datatypes */
+
+ p_type = h5tools_get_native_type(type);
+
+ /* Check if we have VL data in the dataset's datatype */
+ if (h5tools_detect_vlen(p_type) == TRUE)
+ vl_data = TRUE;
+
+ H5Tclose(type);
+
+ space = H5Aget_space(obj_id);
+
+ ndims = H5Sget_simple_extent_dims(space, size, NULL);
+
+ for (i = 0; i < ndims; i++)
+ nelmts *= size[i];
+
+ buf = HDmalloc((size_t)(nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type))));
+ HDassert(buf);
+
+ if (H5Aread(obj_id, p_type, buf) >= 0) {
+ h5tools_context_t datactx;
+ HDmemset(&datactx, 0, sizeof(datactx));
+ datactx.need_prefix = TRUE;
+ datactx.indent_level = ctx.indent_level;
+ datactx.cur_column = ctx.cur_column;
+ status = h5tools_dump_mem(rawoutstream, outputformat, &datactx, obj_id, p_type, space, buf);
+ }
+ /* Reclaim any VL memory, if necessary */
+ if (vl_data)
+ H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf);
+
+ HDfree(buf);
+ H5Tclose(p_type);
+ H5Sclose(space);
+ H5Tclose(type);
+ }
+ }
+
+ if (status == FAIL) {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "Unable to print data.");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ status = 1;
+ }
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataFromFile>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_dump_attr
+ *
+ * Purpose: Dump a description of an HDF5 attribute in XML.
+ *
+ * Return: herr_t
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+xml_dump_attr(hid_t attr, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *info,
+ void H5_ATTR_UNUSED * op_data)
+{
+ hid_t attr_id = -1;
+ hid_t type = -1;
+ hid_t space = -1;
+ H5S_class_t space_type;
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+
+ char *t_aname = xml_escape_the_name(attr_name);
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sAttribute Name=\"%s\">", xmlnsprefix, t_aname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ HDfree(t_aname);
+
+ if ((attr_id = H5Aopen(attr, attr_name, H5P_DEFAULT)) >= 0) {
+ type = H5Aget_type(attr_id);
+ space = H5Aget_space(attr_id);
+ space_type = H5Sget_simple_extent_type(space);
+
+ dump_function_table->dump_dataspace_function(space);
+ dump_function_table->dump_datatype_function(type);
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ if (display_attr_data && space_type != H5S_NULL) {
+ switch (H5Tget_class(type)) {
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_ENUM:
+ case H5T_ARRAY:
+ dump_function_table->dump_data_function(attr_id, ATTRIBUTE_DATA, NULL, 0);
+ break;
+
+ case H5T_TIME:
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Time data not yet implemented. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData/>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<hdf5:Data>");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+ dump_indent -= COL;
+ break;
+
+ case H5T_COMPOUND:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Note: format of compound data not specified -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ dump_function_table->dump_data_function(attr_id, ATTRIBUTE_DATA, NULL, 0);
+ break;
+
+ case H5T_REFERENCE:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ if (!H5Tequal(type, H5T_STD_REF_OBJ)) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Note: Region references not supported -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ xml_print_refs(attr_id, ATTRIBUTE_DATA);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_VLEN:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Note: format of VL data not specified -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ dump_function_table->dump_data_function(attr_id, ATTRIBUTE_DATA, NULL, 0);
+ break;
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES:
+ HDassert(0);
+ /* fall through */
+ default:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Unknown datatype: %d -->", H5Tget_class(type));
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData/>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ }
+ }
+ else {
+ /* The case of an attribute never yet written ??
+ * Or dataspace is H5S_NULL. */
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData/>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ H5Tclose(type);
+ H5Sclose(space);
+ H5Aclose(attr_id);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAttribute>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+ return SUCCEED;
+ }
+ else {
+ /* ?? failed */
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- h5dump error: unable to open attribute. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sAttribute>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+
+ h5tools_setstatus(EXIT_FAILURE);
+ return FAIL;
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_dump_named_datatype
+ *
+ * Purpose: Dump a description of an HDF5 NDT in XML.
+ *
+ * Return: herr_t
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+xml_dump_named_datatype(hid_t type, const char *name)
+{
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ char *tmp;
+ char *dtxid;
+ char *parentxid;
+ char *t_tmp;
+ char *t_prefix;
+ char *t_name;
+
+ tmp = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2);
+ HDstrcpy(tmp, prefix);
+ HDstrcat(tmp, "/");
+ HDstrcat(tmp, name);
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ dtxid = (char *)HDmalloc((size_t)100);
+ parentxid = (char *)HDmalloc((size_t)100);
+ t_tmp = xml_escape_the_name(tmp);
+ t_prefix = xml_escape_the_name(prefix);
+ t_name = xml_escape_the_name(name);
+
+ xml_name_to_XID(tmp, dtxid, 100, 1);
+ xml_name_to_XID(prefix, parentxid, 100, 1);
+ if(HDstrncmp(name, "#", (size_t)1) == 0) {
+ /* Special: this is an 'anonymous' NDT, deleted but
+ still in use.
+ We follow the dumper's undocumented practice, and
+ use its object id as its name.
+ Exactly the same as normal, but a separate case
+ in the event we want to do something else in
+ the future.
+ */
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNamedDataType Name=\"%s\" OBJ-XID=\"%s\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\">",
+ xmlnsprefix,
+ name, dtxid,
+ parentxid, HDstrcmp(prefix,"") ? t_prefix : "/");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ H5O_info_t oinfo; /* Object info */
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNamedDataType Name=\"%s\" OBJ-XID=\"%s\" "
+ "H5Path=\"%s\" Parents=\"%s\" H5ParentPaths=\"%s\">",
+ xmlnsprefix,
+ t_name, dtxid,
+ t_tmp, parentxid, (HDstrcmp(prefix, "") ? t_prefix : "/"));
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* Check uniqueness of named datatype */
+ H5Oget_info(type, &oinfo);
+ if(oinfo.rc > 1) {
+ obj_t *found_obj; /* Found object */
+
+ /* Group with more than one link to it... */
+ found_obj = search_obj(type_table, oinfo.addr);
+
+ if (found_obj == NULL) {
+ indentation(dump_indent);
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ else if(found_obj->displayed) {
+ /* We have already printed this named datatype, print it as a
+ * NamedDatatypePtr
+ */
+ char pointerxid[100];
+ char *t_objname = xml_escape_the_name(found_obj->objname);
+
+ ctx.indent_level++;
+
+ xml_name_to_XID(found_obj->objname, pointerxid, (int)sizeof(pointerxid), 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNamedDatatypePtr OBJ-XID=\"%s\" H5Path=\"%s\"/>", xmlnsprefix, pointerxid, t_objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sNamedDataType>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ HDfree(t_objname);
+ goto done;
+ }
+ else
+ found_obj->displayed = TRUE;
+ }
+ }
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+ dump_indent += COL;
+ xml_print_datatype(type,1);
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sNamedDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+done:
+
+ h5tools_str_close(&buffer);
+
+ HDfree(dtxid);
+ HDfree(parentxid);
+ HDfree(t_tmp);
+ HDfree(t_prefix);
+ HDfree(t_name);
+ HDfree(tmp);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_dump_group
+ *
+ * Purpose: Dump a description of an HDF5 Group (and its members) in XML.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ * Pedro Vicente, October 9, 2007
+ * added parameters to H5A(L)iterate to allow for other iteration orders
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+xml_dump_group(hid_t gid, const char *name)
+{
+ H5O_info_t oinfo;
+ hid_t gcpl_id;
+ hid_t dset, type;
+ unsigned crt_order_flags;
+ unsigned attr_crt_order_flags;
+ int isRoot = 0;
+ char type_name[1024];
+ char *t_objname = NULL;
+ char *par_name = NULL;
+ char *cp = NULL;
+ char *tmp = NULL;
+ char *par = NULL;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ if ((gcpl_id = H5Gget_create_plist(gid)) < 0) {
+ error_msg("error in getting group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties for attributes */
+ if (H5Pget_attr_creation_order(gcpl_id, &attr_crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties */
+ if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ if(H5Pclose(gcpl_id) < 0) {
+ error_msg("error in closing group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ if(HDstrcmp(name, "/") == 0) {
+ isRoot = 1;
+ tmp = HDstrdup("/");
+ }
+ else {
+ tmp = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2);
+ HDstrcpy(tmp, prefix);
+ par = HDstrdup(tmp);
+ cp = HDstrrchr(par, '/');
+ if(cp) {
+ if((cp == par) && HDstrlen(par) > 1)
+ *(cp + 1) = '\0';
+ else
+ *cp = '\0';
+ }
+ }
+
+ H5Oget_info(gid, &oinfo);
+
+ if(oinfo.rc > 1) {
+ obj_t *found_obj; /* Found object */
+
+ /* Group with more than one link to it... */
+ found_obj = search_obj(group_table, oinfo.addr);
+
+ if (found_obj == NULL) {
+ indentation(dump_indent);
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ char *t_name = xml_escape_the_name(name);
+ char *grpxid = (char *)HDmalloc((size_t)100);
+ char *parentxid = (char *)HDmalloc((size_t)100);
+
+ if(found_obj->displayed) {
+ char *ptrstr = (char *)HDmalloc((size_t)100);
+
+ /* already seen: enter a groupptr */
+ if(isRoot) {
+ /* probably can't happen! */
+ xml_name_to_XID("/", grpxid, 100, 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sRootGroup OBJ-XID=\"%s\" H5Path=\"%s\">",
+ xmlnsprefix, grpxid, "/");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ t_objname = xml_escape_the_name(found_obj->objname);
+ par_name = xml_escape_the_name(par);
+ xml_name_to_XID(tmp, grpxid, 100, 1);
+ xml_name_to_XID(par, parentxid, 100, 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sGroup Name=\"%s\" OBJ-XID=\"%s-%d\" H5Path=\"%s\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\">",
+ xmlnsprefix,t_name, grpxid, get_next_xid(),
+ t_objname, parentxid, par_name);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ HDfree(t_objname);
+ HDfree(par_name);
+
+ ctx.indent_level++;
+
+ t_objname = xml_escape_the_name(found_obj->objname);/* point to the NDT by name */
+ par_name = xml_escape_the_name(par);
+ xml_name_to_XID(found_obj->objname, ptrstr, 100, 1);
+ xml_name_to_XID(par, parentxid, 100, 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sGroupPtr OBJ-XID=\"%s\" H5Path=\"%s\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\" />",
+ xmlnsprefix,
+ ptrstr, t_objname, parentxid, par_name);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ HDfree(t_objname);
+ HDfree(par_name);
+ }
+ HDfree(ptrstr);
+ }
+ else {
+
+ /* first time this group has been seen -- describe it */
+ if(isRoot) {
+ xml_name_to_XID("/", grpxid, 100, 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sRootGroup OBJ-XID=\"%s\" H5Path=\"%s\">",
+ xmlnsprefix, grpxid, "/");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ char *t_tmp = xml_escape_the_name(tmp);
+
+ par_name = xml_escape_the_name(par);
+ xml_name_to_XID(tmp, grpxid, 100, 1);
+ xml_name_to_XID(par, parentxid, 100, 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sGroup Name=\"%s\" OBJ-XID=\"%s\" H5Path=\"%s\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\" >",
+ xmlnsprefix,t_name, grpxid, t_tmp, parentxid, par_name);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(t_tmp);
+ HDfree(par_name);
+ }
+ found_obj->displayed = TRUE;
+
+ /* 1. do all the attributes of the group */
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ if((sort_by == H5_INDEX_CRT_ORDER) && (attr_crt_order_flags & H5P_CRT_ORDER_TRACKED)) {
+ if(H5Aiterate2(gid, sort_by, sort_order, NULL, dump_function_table->dump_attribute_function, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end if */
+ else {
+ if(H5Aiterate2(gid, H5_INDEX_NAME, sort_order, NULL, dump_function_table->dump_attribute_function, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end else */
+
+ if(isRoot && unamedtype) {
+ unsigned u;
+
+ /* Very special case: dump unamed type in root group */
+ for(u = 0; u < type_table->nobjs; u++) {
+ if(!type_table->objs[u].recorded) {
+ dset = H5Dopen2(gid, type_table->objs[u].objname, H5P_DEFAULT);
+ type = H5Dget_type(dset);
+ sprintf(type_name, "#"H5_PRINTF_HADDR_FMT, type_table->objs[u].objno);
+ dump_function_table->dump_named_datatype_function(type, type_name);
+ H5Tclose(type);
+ H5Dclose(dset);
+ }
+ }
+ }
+
+ /* iterate through all the links */
+
+ if((sort_by == H5_INDEX_CRT_ORDER) && (crt_order_flags & H5P_CRT_ORDER_TRACKED))
+ H5Literate(gid, sort_by, sort_order, NULL, xml_dump_all_cb, NULL);
+ else
+ H5Literate(gid, H5_INDEX_NAME, sort_order, NULL, xml_dump_all_cb, NULL);
+
+ dump_indent -= COL;
+ ctx.indent_level--;
+ }
+ HDfree(t_name);
+ HDfree(grpxid);
+ HDfree(parentxid);
+ }
+ }
+ else {
+ /* only link -- must be first time! */
+ char *t_name = xml_escape_the_name(name);
+ char *grpxid = (char *)HDmalloc((size_t)100);
+ char *parentxid = (char *)HDmalloc((size_t)100);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+
+ if(isRoot) {
+ xml_name_to_XID("/", grpxid, 100, 1);
+ h5tools_str_append(&buffer, "<%sRootGroup OBJ-XID=\"%s\" H5Path=\"%s\">", xmlnsprefix, grpxid, "/");
+ }
+ else {
+ char *t_tmp = xml_escape_the_name(tmp);
+
+ par_name = xml_escape_the_name(par);
+ xml_name_to_XID(tmp, grpxid, 100, 1);
+ xml_name_to_XID(par, parentxid, 100, 1);
+ h5tools_str_append(&buffer, "<%sGroup Name=\"%s\" OBJ-XID=\"%s\" H5Path=\"%s\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\" >",
+ xmlnsprefix, t_name, grpxid, t_tmp, parentxid, par_name);
+ HDfree(t_tmp);
+ HDfree(par_name);
+ }
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(t_name);
+ HDfree(grpxid);
+ HDfree(parentxid);
+
+ /* 1. do all the attributes of the group */
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ if((sort_by == H5_INDEX_CRT_ORDER) && (attr_crt_order_flags & H5P_CRT_ORDER_TRACKED)) {
+ if(H5Aiterate2(gid, sort_by, sort_order, NULL, dump_function_table->dump_attribute_function, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end if */
+ else {
+ if(H5Aiterate2(gid, H5_INDEX_NAME, sort_order, NULL, dump_function_table->dump_attribute_function, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end else */
+
+ if(isRoot && unamedtype) {
+ unsigned u;
+
+ /* Very special case: dump unamed type in root group */
+ for(u = 0; u < type_table->nobjs; u++) {
+ if(!type_table->objs[u].recorded) {
+ dset = H5Dopen2(gid, type_table->objs[u].objname, H5P_DEFAULT);
+ type = H5Dget_type(dset);
+ sprintf(type_name, "#"H5_PRINTF_HADDR_FMT, type_table->objs[u].objno);
+ dump_function_table->dump_named_datatype_function(type, type_name);
+ H5Tclose(type);
+ H5Dclose(dset);
+ }
+ }
+ }
+
+ /* iterate through all the links */
+
+ if((sort_by == H5_INDEX_CRT_ORDER) && (crt_order_flags & H5P_CRT_ORDER_TRACKED))
+ H5Literate(gid, sort_by, sort_order, NULL, xml_dump_all_cb, NULL);
+ else
+ H5Literate(gid, H5_INDEX_NAME, sort_order, NULL, xml_dump_all_cb, NULL);
+
+ dump_indent -= COL;
+ ctx.indent_level--;
+ }
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(isRoot)
+ h5tools_str_append(&buffer, "</%sRootGroup>", xmlnsprefix);
+ else
+ h5tools_str_append(&buffer, "</%sGroup>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+
+ if(par)
+ HDfree(par);
+ if(tmp)
+ HDfree(tmp);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_print_refs
+ *
+ * Purpose: Print a path to the objects referenced by HDF5 Referneces.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+xml_print_refs(hid_t did, int source)
+{
+ herr_t e;
+ hid_t type = -1;
+ hid_t space = -1;
+ hssize_t ssiz = -1;
+ hsize_t i;
+ size_t tsiz;
+ hobj_ref_t *refbuf = NULL;
+ char *buf = NULL;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ if (source == DATASET_DATA) {
+ type = H5Dget_type(did);
+ }
+ else if (source == ATTRIBUTE_DATA) {
+ type = H5Aget_type(did);
+ }
+ else {
+ /* return an error */
+ return FAIL;
+ }
+ if (H5Tget_class(type) != H5T_REFERENCE) {
+ /* return an error */
+ goto error;
+ }
+ if (!H5Tequal(type, H5T_STD_REF_OBJ)) {
+ /* region ref not supported yet... */
+ /* return an error */
+ goto error;
+ }
+ if (source == DATASET_DATA) {
+ space = H5Dget_space(did);
+ if ((ssiz = H5Sget_simple_extent_npoints(space)) < 0)
+ goto error;
+ if ((tsiz = H5Tget_size(type)) == 0)
+ goto error;
+
+ buf = (char *) HDcalloc((size_t)ssiz, tsiz);
+ if (buf == NULL)
+ goto error;
+ e = H5Dread(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
+ /* need to check result here */
+ if (e < 0)
+ goto error;
+ }
+ else if (source == ATTRIBUTE_DATA) {
+ space = H5Aget_space(did);
+ if ((ssiz = H5Sget_simple_extent_npoints(space)) < 0)
+ goto error;
+ if ((tsiz = H5Tget_size(type)) == 0)
+ goto error;
+
+ buf = (char *) HDcalloc((size_t)ssiz, tsiz);
+ if (buf == NULL)
+ goto error;
+ e = H5Aread(did, H5T_STD_REF_OBJ, buf);
+ /* need to check the result here */
+ if (e < 0)
+ goto error;
+ }
+
+ refbuf = (hobj_ref_t *) buf;
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ for (i = 0; i < (hsize_t)ssiz; i++) {
+ const char *path = lookup_ref_path(*refbuf);
+ ctx.indent_level++;
+
+ if (!path) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\"%s\"", "NULL");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ char *t_path = xml_escape_the_string(path, -1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\"%s\"", t_path);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ HDfree(t_path);
+ }
+ ctx.indent_level--;
+
+ refbuf++;
+ }
+
+ h5tools_str_close(&buffer);
+
+ HDfree(buf);
+ H5Tclose(type);
+ H5Sclose(space);
+ return SUCCEED;
+
+error:
+ if(buf)
+ HDfree(buf);
+
+ H5E_BEGIN_TRY {
+ H5Tclose(type);
+ H5Sclose(space);
+ } H5E_END_TRY;
+ return FAIL;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_print_strs
+ *
+ * Purpose: Print strings.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+xml_print_strs(hid_t did, int source)
+{
+ herr_t e;
+ hid_t type = -1;
+ hid_t space = -1;
+ hssize_t ssiz = -1;
+ htri_t is_vlstr = FALSE;
+ size_t tsiz = 0;
+ hsize_t i;
+ size_t str_size = 0;
+ char *bp = NULL;
+ char *onestring = NULL;
+ void *buf = NULL;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ if (source == DATASET_DATA)
+ type = H5Dget_type(did);
+ else if (source == ATTRIBUTE_DATA)
+ type = H5Aget_type(did);
+ else
+ /* return an error */
+ return FAIL;
+ if (H5Tget_class(type) != H5T_STRING)
+ /* return an error */
+ goto error;
+ /* Check if we have VL data in the dataset's datatype */
+ is_vlstr = H5Tis_variable_str(type);
+
+ if (source == DATASET_DATA) {
+ space = H5Dget_space(did);
+ if((ssiz = H5Sget_simple_extent_npoints(space)) < 0)
+ goto error;
+ if((tsiz = H5Tget_size(type)) == 0)
+ goto error;
+
+ buf = HDmalloc((size_t)ssiz * tsiz);
+ if (buf == NULL)
+ goto error;
+
+ e = H5Dread(did, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
+ if (e < 0)
+ goto error;
+ }
+ else if (source == ATTRIBUTE_DATA) {
+ space = H5Aget_space(did);
+ if((ssiz = H5Sget_simple_extent_npoints(space)) < 0)
+ goto error;
+ if((tsiz = H5Tget_size(type)) == 0)
+ goto error;
+
+ buf = HDmalloc((size_t)ssiz * tsiz);
+ if (buf == NULL)
+ goto error;
+
+ e = H5Aread(did, type, buf);
+ if (e < 0)
+ goto error;
+ }
+
+ bp = (char*) buf;
+ if (!is_vlstr)
+ onestring = (char *) HDcalloc(tsiz, sizeof(char));
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ for (i = 0; i < (hsize_t)ssiz; i++) {
+ if (is_vlstr) {
+ onestring = *(char **) bp;
+ if (onestring)
+ str_size = HDstrlen(onestring);
+ }
+ else {
+ HDstrncpy(onestring, bp, tsiz);
+ str_size = tsiz;
+ }
+
+ if (!onestring) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "NULL");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ char *t_onestring = xml_escape_the_string(onestring, (int)str_size);
+ if (t_onestring) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\"%s\"", t_onestring);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ HDfree(t_onestring);
+ }
+ }
+ bp += tsiz;
+ }
+
+ h5tools_str_close(&buffer);
+
+ /* Reclaim any VL memory, if necessary */
+ if (!is_vlstr)
+ if (onestring)
+ HDfree(onestring);
+ if (buf) {
+ if (is_vlstr)
+ H5Dvlen_reclaim(type, space, H5P_DEFAULT, buf);
+ HDfree(buf);
+ }
+ H5Tclose(type);
+ H5Sclose(space);
+ return SUCCEED;
+
+error:
+ if(buf)
+ HDfree(buf);
+
+ H5E_BEGIN_TRY {
+ H5Tclose(type);
+ H5Sclose(space);
+ } H5E_END_TRY;
+ return FAIL;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: check_filters
+ *
+ * Purpose: private function to check for the filters and
+ * put tags in the XML.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+check_filters(hid_t dcpl)
+{
+ int nfilt;
+ int i;
+ H5Z_filter_t filter;
+ char namebuf[120];
+ size_t cd_nelmts = 20;
+ unsigned int cd_values[20];
+ unsigned int flags;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ nfilt = H5Pget_nfilters(dcpl);
+ if (nfilt <= 0)
+ return;
+ for (i = 0; i < nfilt; i++) {
+ filter = H5Pget_filter2(dcpl, (unsigned) i, &flags, (size_t *) &cd_nelmts, cd_values, (size_t)120, namebuf, NULL);
+ if (filter == H5Z_FILTER_DEFLATE) {
+ ctx.indent_level++;
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDeflate Level=\"", xmlnsprefix);
+ if (cd_nelmts < 1) {
+ /* not sure what this means? */
+ h5tools_str_append(&buffer, "6");
+ }
+ else {
+ h5tools_str_append(&buffer, "%d", cd_values[0]);
+ }
+ h5tools_str_append(&buffer, "\"/>");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ }
+ else if (filter == H5Z_FILTER_FLETCHER32) {
+ ctx.indent_level++;
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sFletcher32 />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ }
+ else if (filter == H5Z_FILTER_SHUFFLE) {
+ ctx.indent_level++;
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sShuffle />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ }
+ else if (filter == H5Z_FILTER_SZIP) {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sSZIP ", xmlnsprefix);
+ if (cd_nelmts < 2) {
+ /* no pixels ? */
+ h5tools_str_append(&buffer, "Pixels_per_block=\"-1\" ");
+ }
+ else {
+ h5tools_str_append(&buffer, "Pixels_per_block=\"%d\" ", cd_values[1]);
+ }
+ /* analyse the options mask */
+ if (cd_values[0] & H5_SZIP_CHIP_OPTION_MASK) {
+ h5tools_str_append(&buffer, "Mode =\"Hardware\" ");
+ }
+ else if (cd_values[0] & H5_SZIP_ALLOW_K13_OPTION_MASK) {
+ h5tools_str_append(&buffer, "Mode =\"K13\" ");
+ }
+ h5tools_str_append(&buffer, "Coding=\"");
+ if (cd_values[0] & H5_SZIP_EC_OPTION_MASK) {
+ h5tools_str_append(&buffer, "Entropy");
+ }
+ else if (cd_values[0] & H5_SZIP_NN_OPTION_MASK) {
+ h5tools_str_append(&buffer, "NN");
+ }
+ h5tools_str_append(&buffer, "\" ");
+
+ h5tools_str_append(&buffer, "ByteOrder=\"");
+ if (cd_values[0] & H5_SZIP_LSB_OPTION_MASK) {
+ h5tools_str_append(&buffer, "LSB");
+ }
+ else if (cd_values[0] & H5_SZIP_MSB_OPTION_MASK) {
+ h5tools_str_append(&buffer, "MSB");
+ }
+ h5tools_str_append(&buffer, "\" ");
+
+ if (cd_values[0] & H5_SZIP_RAW_OPTION_MASK) {
+ h5tools_str_append(&buffer, "Header=\"Raw\"");
+ }
+ h5tools_str_append(&buffer, "/>");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ }
+ else {
+ /* unknown option */
+ }
+ }
+
+ h5tools_str_close(&buffer);
+}
+
+static void
+xml_dump_fill_value(hid_t dcpl, hid_t type)
+{
+ size_t sz;
+ size_t i;
+ hsize_t space;
+ void *buf;
+ char *name;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ space = H5Tget_size(type);
+ buf = HDmalloc((size_t) space);
+
+ H5Pget_fill_value(dcpl, type, buf);
+
+ if (H5Tget_class(type) == H5T_REFERENCE) {
+ const char * path = lookup_ref_path(*(hobj_ref_t *) buf);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ if (!path) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\"%s\"", "NULL");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ char *t_path = xml_escape_the_string(path, -1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\"%s\"", t_path);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ HDfree(t_path);
+ }
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else if (H5Tget_class(type) == H5T_STRING) {
+ /* ????? */
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- String fill values not yet implemented. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ /* all other data */
+ switch (H5Tget_class(type)) {
+ case H5T_INTEGER:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\"%d\"", *(int *) buf);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ case H5T_FLOAT:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\"%f\"", (double)*(float *)buf);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ sz = H5Tget_size(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\"");
+ for (i = 0; i < sz; i++) {
+ h5tools_str_append(&buffer, "%x ", *(unsigned int *) buf);
+ buf = (char *) buf + sizeof(unsigned int);
+ }
+ h5tools_str_append(&buffer, "\"");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ case H5T_ENUM:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ name = H5Tget_member_name(type, *(unsigned *) buf);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\"%s\"", name);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ if(name)
+ H5free_memory(name);
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ case H5T_ARRAY:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Array fill values not yet implemented. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ case H5T_TIME:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Time fill not yet implemented. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ case H5T_COMPOUND:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Compound fill not yet implemented. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ case H5T_VLEN:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- VL fill not yet implemented. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES:
+ HDassert(0);
+ /* fall through */
+ case H5T_STRING:
+ case H5T_REFERENCE:
+ default:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Unknown fill datatype: %d -->", H5Tget_class(type));
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData/>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ }
+ }
+ HDfree(buf);
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_dump_dataset
+ *
+ * Purpose: Dump a description of an HDF5 dataset in XML.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ * Pedro Vicente, October 9, 2007
+ * added parameters to H5Aiterate2 to allow for other iteration orders
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+xml_dump_dataset(hid_t did, const char *name, struct subset_t H5_ATTR_UNUSED * sset)
+{
+ hid_t type;
+ hid_t space;
+ hid_t dcpl;
+ H5D_fill_value_t fvstatus;
+ int maxdims;
+ hsize_t *chsize;
+ int ndims;
+ int i;
+ H5D_alloc_time_t at;
+ H5D_fill_time_t ft;
+ hsize_t tempi;
+ char *tmp;
+ char *t_name;
+ char *t_tmp;
+ char *t_prefix;
+ unsigned attr_crt_order_flags;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ char *rstr = (char*) HDmalloc((size_t)100);
+ char *pstr = (char*) HDmalloc((size_t)100);
+
+ tmp = (char*) HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2);
+ HDstrcpy(tmp, prefix);
+ HDstrcat(tmp, "/");
+ HDstrcat(tmp, name);
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ t_name = xml_escape_the_name(name);
+ t_tmp = xml_escape_the_name(tmp);
+ t_prefix = xml_escape_the_name(prefix);
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ xml_name_to_XID(tmp, rstr, 100, 1);
+ xml_name_to_XID(prefix, pstr, 100, 1);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataset Name=\"%s\" OBJ-XID=\"%s\" H5Path= \"%s\" Parents=\"%s\" H5ParentPaths=\"%s\">",
+ xmlnsprefix, t_name, rstr, t_tmp, pstr,
+ strcmp(prefix, "") ? t_prefix : "/");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(t_name);
+ HDfree(t_tmp);
+ HDfree(t_prefix);
+ HDfree(rstr);
+ HDfree(pstr);
+ HDfree(tmp);
+
+ dcpl = H5Dget_create_plist(did);
+ type = H5Dget_type(did);
+ space = H5Dget_space(did);
+
+ /* query the creation properties for attributes */
+ H5Pget_attr_creation_order(dcpl, &attr_crt_order_flags);
+
+ /* Print information about storage layout */
+ if (H5D_CHUNKED == H5Pget_layout(dcpl)) {
+ maxdims = H5Sget_simple_extent_ndims(space);
+ HDassert(maxdims >= 0);
+ chsize = (hsize_t *)HDmalloc((size_t)maxdims * sizeof(hsize_t));
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sStorageLayout>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sChunkedLayout ", xmlnsprefix);
+ ndims = H5Pget_chunk(dcpl, maxdims, chsize);
+ h5tools_str_append(&buffer, "Ndims=\"%d\">", ndims);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ for (i = 0; i < ndims; i++) {
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sChunkDimension DimSize=\"%" H5_PRINTF_LL_WIDTH "u\" />", xmlnsprefix, chsize[i]);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sRequiredFilter>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+ dump_indent += COL;
+ check_filters(dcpl);
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sRequiredFilter>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sChunkedLayout>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sStorageLayout>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ dump_indent -= COL;
+ HDfree(chsize);
+ }
+ else if (H5D_CONTIGUOUS == H5Pget_layout(dcpl)) {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sStorageLayout>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sContiguousLayout/>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sStorageLayout>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ }
+ else if (H5D_COMPACT == H5Pget_layout(dcpl)) {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sStorageLayout>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sCompactLayout/>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sStorageLayout>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ }
+ /* and check for external.... ?? */
+
+ /* fill value */
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sFillValueInfo ", xmlnsprefix);
+ H5Pget_fill_time(dcpl, &ft);
+ h5tools_str_append(&buffer, "FillTime=\"");
+ switch (ft) {
+ case H5D_FILL_TIME_ALLOC:
+ h5tools_str_append(&buffer, "FillOnAlloc");
+ break;
+ case H5D_FILL_TIME_NEVER:
+ h5tools_str_append(&buffer, "FillNever");
+ break;
+ case H5D_FILL_TIME_IFSET:
+ h5tools_str_append(&buffer, "FillIfSet");
+ break;
+ case H5D_FILL_TIME_ERROR:
+ HDassert(0);
+ /* fall through */
+ default:
+ h5tools_str_append(&buffer, "?");
+ break;
+ } /* end switch */
+ h5tools_str_append(&buffer, "\" ");
+ H5Pget_alloc_time(dcpl, &at);
+ h5tools_str_append(&buffer, "AllocationTime=\"");
+ switch (at) {
+ case H5D_ALLOC_TIME_EARLY:
+ h5tools_str_append(&buffer, "Early");
+ break;
+ case H5D_ALLOC_TIME_INCR:
+ h5tools_str_append(&buffer, "Incremental");
+ break;
+ case H5D_ALLOC_TIME_LATE:
+ h5tools_str_append(&buffer, "Late");
+ break;
+ case H5D_ALLOC_TIME_DEFAULT:
+ case H5D_ALLOC_TIME_ERROR:
+ HDassert(0);
+ /* fall through */
+ default:
+ h5tools_str_append(&buffer, "?");
+ break;
+ } /* end switch */
+ h5tools_str_append(&buffer, "\"");
+ h5tools_str_append(&buffer, ">");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sFillValue>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ H5Pfill_value_defined(dcpl, &fvstatus);
+ if (fvstatus == H5D_FILL_VALUE_UNDEFINED || (fvstatus == H5D_FILL_VALUE_DEFAULT && ft == H5D_FILL_TIME_IFSET)) {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoFill/>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ }
+ else {
+ xml_dump_fill_value(dcpl, type);
+ }
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sFillValue>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sFillValueInfo>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ dump_function_table->dump_dataspace_function(space);
+ dump_function_table->dump_datatype_function(type);
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ if ((sort_by == H5_INDEX_CRT_ORDER) && (attr_crt_order_flags & H5P_CRT_ORDER_TRACKED)) {
+ if (H5Aiterate2(did, sort_by, sort_order, NULL, dump_function_table->dump_attribute_function, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end if */
+ else {
+ if (H5Aiterate2(did, H5_INDEX_NAME, sort_order, NULL, dump_function_table->dump_attribute_function, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end else */
+
+ ctx.indent_level--;
+ dump_indent -= COL;
+ tempi = H5Dget_storage_size(did);
+
+ if (display_data && (tempi > 0)) {
+ switch (H5Tget_class(type)) {
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_ENUM:
+ case H5T_ARRAY:
+ ctx.indent_level++;
+ dump_indent += COL;
+ dump_function_table->dump_data_function(did, DATASET_DATA, NULL, 0);
+ ctx.indent_level--;
+ dump_indent -= COL;
+ break;
+
+ case H5T_TIME:
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Time data not yet implemented. -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+ break;
+
+ case H5T_COMPOUND:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Note: format of compound data not specified -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+ dump_indent += COL;
+ dump_function_table->dump_data_function(did, DATASET_DATA, NULL, 0);
+ ctx.indent_level--;
+ dump_indent -= COL;
+ break;
+
+ case H5T_REFERENCE:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ if (!H5Tequal(type, H5T_STD_REF_OBJ)) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Note: Region references not supported -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData />", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ xml_print_refs(did, DATASET_DATA);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataFromFile>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5T_VLEN:
+ ctx.indent_level--;
+ dump_indent -= COL;
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Note: format of VL data not specified -->");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ ctx.indent_level++;
+ dump_indent += COL;
+ dump_function_table->dump_data_function(did, DATASET_DATA, NULL, 0);
+ ctx.indent_level--;
+ dump_indent -= COL;
+ break;
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES:
+ HDassert(0);
+ /* fall through */
+
+ default:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<!-- Unknown datatype: %d -->", H5Tget_class(type));
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData/>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ }
+ }
+ else {
+ /* no data written */
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sNoData/>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sData>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+ }
+
+ H5Tclose(type);
+ H5Sclose(space);
+ H5Pclose(dcpl);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataset>", xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: xml_print_enum
+ *
+ * Purpose: Print the values of an HDF5 ENUM in XML.
+ * Very similar to regular DDL output.
+ *
+ * Return: void
+ *
+ * Programmer: REMcG
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+xml_print_enum(hid_t type)
+{
+ char **name = NULL; /*member names */
+ unsigned char *value = NULL; /*value array */
+ unsigned nmembs; /*number of members */
+ hid_t super; /*enum base integer type */
+ hid_t native = -1; /*native integer datatype */
+ size_t dst_size; /*destination value type size */
+ unsigned i; /*miscellaneous counters */
+ size_t j;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &xml_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ nmembs = (unsigned)H5Tget_nmembers(type);
+ super = H5Tget_super(type);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ xml_print_datatype(super,0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sDataType>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /*
+ * Determine what datatype to use for the native values. To simplify
+ * things we entertain three possibilities:
+ * 1. long long -- the largest native signed integer
+ * 2. unsigned long long -- the largest native unsigned integer
+ * 3. raw format
+ */
+ if (H5Tget_size(type) <= sizeof(long long)) {
+ dst_size = sizeof(long long);
+
+ if (H5T_SGN_NONE == H5Tget_sign(type)) {
+ native = H5T_NATIVE_ULLONG;
+ }
+ else {
+ native = H5T_NATIVE_LLONG;
+ }
+ }
+ else {
+ dst_size = H5Tget_size(type);
+ }
+
+ /* Get the names and raw values of all members */
+ name = (char **)HDcalloc((size_t)nmembs, sizeof(char *));
+ value = (unsigned char *)HDcalloc((size_t)nmembs, MAX(H5Tget_size(type), dst_size));
+
+ for (i = 0; i < nmembs; i++) {
+ name[i] = H5Tget_member_name(type, i);
+ H5Tget_member_value(type, i, value + i * H5Tget_size(type));
+ }
+
+ /* Convert values to native datatype */
+ if (native > 0)
+ H5Tconvert(super, native, (size_t)nmembs, value, NULL, H5P_DEFAULT);
+
+ /* Sort members by increasing value */
+ /*not implemented yet */
+
+ /* Print members */
+ ctx.indent_level++;
+ dump_indent += COL;
+ for (i = 0; i < nmembs; i++) {
+ char *t_name = xml_escape_the_name(name[i]);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sEnumElement>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s", t_name);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ HDfree(t_name);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sEnumElement>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "<%sEnumValue>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level++;
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if (native < 0) {
+ 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)) {
+ h5tools_str_append(&buffer,"%" H5_PRINTF_LL_WIDTH "u", *((unsigned long long *)
+ ((void *) (value + i * dst_size))));
+ }
+ else {
+ h5tools_str_append(&buffer,"%" H5_PRINTF_LL_WIDTH "d",
+ *((long long *) ((void *) (value + i * dst_size))));
+ }
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "</%sEnumValue>",xmlnsprefix);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ h5tools_str_close(&buffer);
+
+ /* Release resources */
+ for (i = 0; i < nmembs; i++)
+ H5free_memory(name[i]);
+
+ HDfree(name);
+ HDfree(value);
+ H5Tclose(super);
+}
+
diff --git a/tools/src/h5dump/h5dump_xml.h b/tools/src/h5dump/h5dump_xml.h
new file mode 100644
index 0000000..c1d6c62
--- /dev/null
+++ b/tools/src/h5dump/h5dump_xml.h
@@ -0,0 +1,39 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#ifndef H5DUMP_XML_H__
+#define H5DUMP_XML_H__
+
+extern const char *xmlnsprefix;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The dump functions of the dump_function_table */
+/* XML format: same interface, alternative output */
+
+void xml_dump_group(hid_t, const char *);
+void xml_dump_named_datatype(hid_t, const char *);
+void xml_dump_dataset(hid_t, const char *, struct subset_t *);
+void xml_dump_dataspace(hid_t space);
+void xml_dump_datatype(hid_t type);
+herr_t xml_dump_attr(hid_t, const char *, const H5A_info_t *, void *);
+void xml_dump_data(hid_t, int, struct subset_t *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !H5DUMP_XML_H__ */
diff --git a/tools/src/h5format_convert/CMakeLists.txt b/tools/src/h5format_convert/CMakeLists.txt
new file mode 100644
index 0000000..957055d
--- /dev/null
+++ b/tools/src/h5format_convert/CMakeLists.txt
@@ -0,0 +1,39 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_H5FC)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+
+# --------------------------------------------------------------------
+# Add the h5format_convert executables
+# --------------------------------------------------------------------
+add_executable (h5format_convert ${HDF5_TOOLS_SRC_H5FC_SOURCE_DIR}/h5format_convert.c)
+TARGET_NAMING (h5format_convert STATIC)
+TARGET_C_PROPERTIES (h5format_convert STATIC " " " ")
+target_link_libraries (h5format_convert ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5format_convert PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5format_convert")
+
+set (H5_DEP_EXECUTABLES h5format_convert)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5format_convert ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5format_convert
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
diff --git a/tools/src/h5format_convert/Makefile.am b/tools/src/h5format_convert/Makefile.am
new file mode 100644
index 0000000..e2d1acf
--- /dev/null
+++ b/tools/src/h5format_convert/Makefile.am
@@ -0,0 +1,35 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src directory
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+# These are our main targets, the tools
+bin_PROGRAMS=h5format_convert
+
+# Add h5format_convert specific linker flags here
+h5format_convert_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# All programs rely on hdf5 library and h5tools library
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/h5format_convert/h5format_convert.c b/tools/src/h5format_convert/h5format_convert.c
new file mode 100644
index 0000000..8ce28dd
--- /dev/null
+++ b/tools/src/h5format_convert/h5format_convert.c
@@ -0,0 +1,474 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Vailin Choi; Feb 2015
+ */
+
+
+/*
+ * We include the private header file so we can get to the uniform
+ * programming environment it declares.
+ * HDF5 API functions (except for H5G_basename())
+ */
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+#include "h5trav.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5format_convert"
+
+static char *fname_g = NULL;
+static char *dname_g = NULL;
+static int dset_g = FALSE;
+static int noop_g = FALSE;
+static int verbose_g = 0;
+
+/*
+ * Command-line options: The user can specify short or long-named
+ * parameters.
+ */
+static const char *s_opts = "hVvd:n";
+static struct long_options l_opts[] = {
+ { "help", no_arg, 'h' },
+ { "hel", no_arg, 'h'},
+ { "he", no_arg, 'h'},
+ { "version", no_arg, 'V' },
+ { "version", no_arg, 'V' },
+ { "versio", no_arg, 'V' },
+ { "versi", no_arg, 'V' },
+ { "vers", no_arg, 'V' },
+ { "verbose", no_arg, 'v' },
+ { "verbos", no_arg, 'v' },
+ { "verbo", no_arg, 'v' },
+ { "verb", no_arg, 'v' },
+ { "dname", require_arg, 'd' },
+ { "dnam", require_arg, 'd' },
+ { "dna", require_arg, 'd' },
+ { "dn", require_arg, 'd' },
+ { "noop", no_arg, 'n' },
+ { "noo", no_arg, 'n' },
+ { "no", no_arg, 'n' },
+ { NULL, 0, '\0' }
+};
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: print usage
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+static void usage(const char *prog)
+{
+ HDfprintf(stdout, "usage: %s [OPTIONS] file_name\n", prog);
+ HDfprintf(stdout, " OPTIONS\n");
+ HDfprintf(stdout, " -h, --help Print a usage message and exit\n");
+ HDfprintf(stdout, " -V, --version Print version number and exit\n");
+ HDfprintf(stdout, " -v, --verbose Turn on verbose mode\n");
+ HDfprintf(stdout, " -d dname, --dname=dataset_name Pathname for the dataset\n");
+ HDfprintf(stdout, " -n, --noop Perform all the steps except the actual conversion\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, "Examples of use:\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, "h5format_convert -d /group/dataset file_name\n");
+ HDfprintf(stdout, " Convert the dataset </group/dataset> in the HDF5 file <file_name>:\n");
+ HDfprintf(stdout, " a. chunked dataset: convert the chunk indexing type to version 1 B-tree\n");
+ HDfprintf(stdout, " b. compact/contiguous dataset: downgrade the layout version to 3\n");
+ HDfprintf(stdout, " c. virtual dataset: no action\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, "h5format_convert file_name\n");
+ HDfprintf(stdout, " Convert all datasets in the HDF5 file <file_name>:\n");
+ HDfprintf(stdout, " a. chunked dataset: convert the chunk indexing type to version 1 B-tree\n");
+ HDfprintf(stdout, " b. compact/contiguous dataset: downgrade the layout version to 3\n");
+ HDfprintf(stdout, " c. virtual dataset: no action\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, "h5format_convert -n -d /group/dataset file_name\n");
+ HDfprintf(stdout, " Go through all the steps except the actual conversion when \n");
+ HDfprintf(stdout, " converting the dataset </group/dataset> in the HDF5 file <file_name>.\n");
+} /* usage() */
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: parse command line input
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+parse_command_line(int argc, const char **argv)
+{
+ int opt;
+
+ /* no arguments */
+ if (argc == 1) {
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ }
+
+ /* parse command line options */
+ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
+ switch((char) opt) {
+ case 'h':
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto error;
+
+ case 'V':
+ print_version(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto error;
+
+ case 'v':
+ verbose_g = TRUE;
+ break;
+
+ case 'd': /* -d dname */
+ if(opt_arg != NULL && *opt_arg)
+ dname_g = HDstrdup(opt_arg);
+ if(dname_g == NULL) {
+ h5tools_setstatus(EXIT_FAILURE);
+ error_msg("No dataset name\n", opt_arg);
+ usage(h5tools_getprogname());
+ goto error;
+ }
+ dset_g = TRUE;
+ break;
+
+ case 'n': /* -n */
+ noop_g = TRUE;
+ break;
+
+ default:
+ h5tools_setstatus(EXIT_FAILURE);
+ usage(h5tools_getprogname());
+ goto error;
+ break;
+ } /* switch */
+ } /* while */
+
+ if (argc <= opt_ind) {
+ error_msg("missing file name\n");
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ }
+
+ fname_g = HDstrdup(argv[opt_ind]);
+
+ return(0);
+
+error:
+ return(-1); ;
+} /* parse_command_line() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: leave
+ *
+ * Purpose: Close HDF5
+ *
+ * Return: Does not return
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+leave(int ret)
+{
+ h5tools_close();
+
+ HDexit(ret);
+} /* leave() */
+
+/*-------------------------------------------------------------------------
+ * Function: convert()
+ *
+ * Purpose: To downgrade a dataset's indexing type or layout version:
+ * For chunked:
+ * Downgrade the chunk indexing type to version 1 B-tree
+ * If type is already version 1 B-tree, no further action
+ * For compact/contiguous:
+ * Downgrade the layout version from 4 to 3
+ * If version is already <= 3, no further action
+ * For virtual:
+ * No further action
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+convert(hid_t fid, const char *dname)
+{
+ hid_t dcpl = -1;
+ hid_t did = -1;
+ H5D_layout_t layout_type;
+ H5D_chunk_index_t idx_type;
+
+ /* Open the dataset */
+ if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) {
+ error_msg("unable to open dataset \"%s\"\n", dname);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+
+ } else if(verbose_g)
+ HDfprintf(stdout, "Open the dataset\n");
+
+ /* Get the dataset's creation property list */
+ if((dcpl = H5Dget_create_plist(did)) < 0) {
+ error_msg("unable to get the dataset creation property list\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ }
+
+ /* Get the dataset's layout */
+ if((layout_type = H5Pget_layout(dcpl)) < 0) {
+ error_msg("unable to get the dataset layout type\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+
+ } else if(verbose_g)
+ HDfprintf(stdout, "Retrieve the dataset's layout\n");
+
+ switch(layout_type) {
+ case H5D_CHUNKED:
+ if(verbose_g)
+ HDfprintf(stdout, "Dataset is a chunked dataset\n");
+
+ /* Get the dataset's chunk indexing type */
+ if(H5Dget_chunk_index_type(did, &idx_type) < 0) {
+ error_msg("unable to get the chunk indexing type for \"%s\"\n", dname);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ } else if(verbose_g)
+ HDfprintf(stdout, "Retrieve the dataset's chunk indexing type\n");
+
+ if(idx_type == H5D_CHUNK_IDX_BTREE) {
+ if(verbose_g)
+ HDfprintf(stdout, "Dataset's chunk indexing type is already version 1 B-tree: no further action\n");
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+ } else if (verbose_g)
+ HDfprintf(stdout, "Dataset's chunk indexing type is not version 1 B-tree\n");
+ break;
+
+ case H5D_CONTIGUOUS:
+ if(verbose_g)
+ HDfprintf(stdout, "Dataset is a contiguous dataset: downgrade layout version as needed\n");
+ break;
+
+ case H5D_COMPACT:
+ if(verbose_g)
+ HDfprintf(stdout, "Dataset is a compact dataset: downgrade layout version as needed\n");
+ break;
+
+ case H5D_VIRTUAL:
+ if(verbose_g)
+ HDfprintf(stdout, "No further action for virtual dataset\n");
+ goto done;
+
+ case H5D_NLAYOUTS:
+ case H5D_LAYOUT_ERROR:
+ default:
+ error_msg("unknown layout type for \"%s\"\n", dname);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+
+ } /* end switch */
+
+ /* No further action if it is a noop */
+ if(noop_g) {
+ if(verbose_g)
+ HDfprintf(stdout, "Not converting the dataset\n");
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+ }
+
+ if(verbose_g)
+ HDfprintf(stdout, "Converting the dataset...\n");
+
+ /* Downgrade the dataset */
+ if(H5Dformat_convert(did) < 0) {
+ error_msg("unable to downgrade dataset \"%s\"\n", dname);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ } else if(verbose_g)
+ HDfprintf(stdout, "Done\n");
+
+done:
+ /* Close the dataset */
+ if(H5Dclose(did) < 0) {
+ error_msg("unable to close dataset \"%s\"\n", dname);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ } else if(verbose_g)
+ HDfprintf(stdout, "Close the dataset\n");
+
+ /* Close the dataset creation property list */
+ if(H5Pclose(dcpl) < 0) {
+ error_msg("unable to close dataset creation property list\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ } else if(verbose_g)
+ printf("Close the dataset creation property list\n");
+
+ return(0);
+
+error:
+ if(verbose_g)
+ HDfprintf(stdout, "Error encountered\n");
+
+ H5E_BEGIN_TRY {
+ H5Pclose(dcpl);
+ H5Dclose(did);
+ } H5E_END_TRY;
+
+ return(-1);
+} /* convert() */
+
+/*-------------------------------------------------------------------------
+ * Function: convert_dsets_cb()
+ *
+ * Purpose: The callback routine from the traversal to convert the
+ * chunk indexing type of the dataset object.
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *-------------------------------------------------------------------------
+ */
+static int
+convert_dsets_cb(const char *path, const H5O_info_t *oi, const char *already_visited, void *_fid)
+{
+ hid_t fid = *(hid_t *)_fid;
+
+ /* If the object has already been seen then just return */
+ if(NULL == already_visited) {
+ if(oi->type == H5O_TYPE_DATASET) {
+ if(verbose_g)
+ HDfprintf(stdout, "Going to process dataset:%s...\n", path);
+ if(convert(fid, path) < 0)
+ goto error;
+ } /* end if */
+ } /* end if */
+
+ return 0;
+
+error:
+ return -1;
+} /* end convert_dsets_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: To convert the chunk indexing type of a dataset in a file to
+ * version 1 B-tree.
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, const char *argv[])
+{
+ H5E_auto2_t func;
+ void *edata;
+ hid_t fid = -1;
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Disable error reporting */
+ H5Eget_auto2(H5E_DEFAULT, &func, &edata);
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /* Parse command line options */
+ if(parse_command_line(argc, argv) < 0)
+ goto done;
+ else if(verbose_g)
+ HDfprintf(stdout, "Process command line options\n");
+
+ if(noop_g && verbose_g)
+ HDfprintf(stdout, "It is noop...\n");
+
+ /* Open the HDF5 file */
+ if((fid = h5tools_fopen(fname_g, H5F_ACC_RDWR, H5P_DEFAULT, NULL, NULL, 0)) < 0) {
+ error_msg("unable to open file \"%s\"\n", fname_g);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ } else if(verbose_g)
+ HDfprintf(stdout, "Open the file %s\n", fname_g);
+
+ if(dset_g) { /* Convert a specified dataset in the file */
+ if(verbose_g)
+ HDfprintf(stdout, "Going to process dataset: %s...\n", dname_g);
+ if(convert(fid, dname_g) < 0)
+ goto done;
+ } else { /* Convert all datasets in the file */
+ if(verbose_g)
+ HDfprintf(stdout, "Processing all datasets in the file...\n");
+ if(h5trav_visit(fid, "/", TRUE, TRUE, convert_dsets_cb, NULL, &fid) < 0)
+ goto done;
+ } /* end else */
+
+ if(verbose_g) {
+ if(noop_g) {
+ HDfprintf(stdout, "Not processing the file's superblock...\n");
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+ } /* end if */
+ HDfprintf(stdout, "Processing the file's superblock...\n");
+ } /* end if */
+
+ /* Process superblock */
+ if(H5Fformat_convert(fid) < 0) {
+ error_msg("unable to convert file's superblock\"%s\"\n", fname_g);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ } /* end if */
+
+done:
+ /* Close the file */
+ if(fid >= 0) {
+ if(H5Fclose(fid) < 0) {
+ error_msg("unable to close file \"%s\"\n", fname_g);
+ h5tools_setstatus(EXIT_FAILURE);
+ } else if(verbose_g)
+ HDfprintf(stdout, "Close the file\n");
+ } /* end if */
+
+ if(fname_g)
+ HDfree(fname_g);
+ if(dname_g)
+ HDfree(dname_g);
+
+ H5Eset_auto2(H5E_DEFAULT, func, edata);
+ leave(h5tools_getstatus());
+
+} /* end main() */
+
diff --git a/tools/src/h5import/CMakeLists.txt b/tools/src/h5import/CMakeLists.txt
new file mode 100644
index 0000000..97ab4ec
--- /dev/null
+++ b/tools/src/h5import/CMakeLists.txt
@@ -0,0 +1,40 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_H5IMPORT)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+
+# --------------------------------------------------------------------
+# Add the h5import executables
+# --------------------------------------------------------------------
+add_executable (h5import ${HDF5_TOOLS_SRC_H5IMPORT_SOURCE_DIR}/h5import.c)
+TARGET_NAMING (h5import STATIC)
+TARGET_C_PROPERTIES (h5import STATIC " " " ")
+target_link_libraries (h5import ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+#set_target_properties (h5import PROPERTIES COMPILE_DEFINITIONS H5DEBUGIMPORT)
+set_target_properties (h5import PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5import")
+
+set (H5_DEP_EXECUTABLES h5import)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5import ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5import
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
diff --git a/tools/src/h5import/Makefile.am b/tools/src/h5import/Makefile.am
new file mode 100644
index 0000000..2eae9ec
--- /dev/null
+++ b/tools/src/h5import/Makefile.am
@@ -0,0 +1,35 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src and tools/lib directories
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+# Our main targets
+bin_PROGRAMS=h5import
+
+# Add h5import specific linker flags here
+h5import_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# All programs depend on the main hdf5 library and the tools library
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/h5import/h5import.c b/tools/src/h5import/h5import.c
new file mode 100644
index 0000000..d1aab0c
--- /dev/null
+++ b/tools/src/h5import/h5import.c
@@ -0,0 +1,4393 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "hdf5.h"
+#include "H5private.h"
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <ctype.h>
+#include "h5import.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5import"
+
+#ifdef H5_HAVE_WIN32_API
+#define READ_OPEN_FLAGS "rb"
+#else
+#define READ_OPEN_FLAGS "r"
+#endif
+
+/* Local function declarations */
+static int gtoken(char *s);
+static int process(struct Options *opt);
+static int processConfigurationFile(char *infile, struct Input *in);
+static int mapKeywordToIndex(char *key);
+static int parsePathInfo(struct path_info *path, char *strm);
+static int parseDimensions(struct Input *in, char *strm);
+static int getInputSize(struct Input *in, int ival);
+static int getInputClass(struct Input *in, char * strm);
+static int getInputClassType(struct Input *in, char * strm);
+static int InputClassStrToInt(char *temp);
+static int getRank(struct Input *in, FILE *strm);
+static int getDimensionSizes(struct Input *in, FILE *strm);
+static int getOutputSize(struct Input *in, FILE *strm);
+static int getOutputClass(struct Input *in, FILE *strm);
+static int OutputClassStrToInt(char *temp);
+static int getOutputArchitecture(struct Input *in, FILE *strm);
+static int OutputArchStrToInt(const char *temp);
+static int getOutputByteOrder(struct Input *in, FILE *strm);
+static int OutputByteOrderStrToInt(const char *temp);
+static int getChunkedDimensionSizes(struct Input *in, FILE *strm);
+static int getCompressionType(struct Input *in, FILE *strm);
+static int CompressionTypeStrToInt(char *temp);
+static int getCompressionParameter(struct Input *in, FILE *strm);
+static int getExternalFilename(struct Input *in, FILE *strm);
+static int getMaximumDimensionSizes(struct Input *in, FILE *strm);
+static int processDataFile(char *infile, struct Input *in, hid_t file_id);
+static int readIntegerData(FILE *strm, struct Input *in);
+static int readFloatData(FILE *strm, struct Input *in);
+static int allocateIntegerStorage(struct Input *in);
+static int allocateFloatStorage(struct Input *in);
+static int readUIntegerData(FILE *strm, struct Input *in);
+static int allocateUIntegerStorage(struct Input *in);
+static int validateConfigurationParameters(struct Input *in);
+static int processStrData(FILE *strm, struct Input *in, hid_t file_id);
+static int processStrHDFData(FILE *strm, struct Input *in, hid_t file_id);
+
+int main(int argc, char *argv[])
+{
+ struct Options opt;
+ int outfile_named = FALSE;
+ int token;
+ int i;
+ int state = 0;
+ struct Input *in = NULL;
+
+ const char *err1 = "Invalid number of arguments: %d.\n";
+ const char *err2 = "Error in state table.\n";
+ const char *err3 = "No output file given.\n";
+ const char *err4 = "Program aborted.\n";
+ const char *err5 = "Invalid path %s.\n";
+ const char *err6 = "Invalid dimensions - %s.\n";
+ const char *err7 = "Invalid type of data - %s.\n";
+ const char *err8 = "Invalid size of data - %s.\n";
+ const char *err9 = "Cannot specify more than 30 input files in one call to h5import.\n";
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ (void) HDsetvbuf(stderr, (char *) NULL, _IOLBF, 0);
+ (void) HDsetvbuf(stdout, (char *) NULL, _IOLBF, 0);
+
+ if (argv[1] && (HDstrcmp("-V", argv[1]) == 0)) {
+ print_version(PROGRAMNAME);
+ HDexit(EXIT_SUCCESS);
+ }
+
+ /*
+ * validate the number of command line arguments
+ */
+ if (argc < 2) {
+ (void) HDfprintf(stderr, err1, argc);
+ usage(argv[0]);
+ goto err;
+ }
+
+ /* Initialize the file structure to 0 */
+ HDmemset(&opt, 0, sizeof(struct Options));
+
+ /*
+ * parse the command line
+ */
+ for (i = 1; i < argc; i++) {
+ if ((token = gtoken(argv[i])) == ERR) {
+ usage(argv[0]);
+ goto err;
+ }
+
+ state = state_table[state][token];
+
+ switch (state) {
+
+ case 1: /* counting input files */
+ if (opt.fcount < 29) {
+ (void) HDstrcpy(opt.infiles[opt.fcount].datafile, argv[i]);
+ in = &(opt.infiles[opt.fcount].in);
+ opt.infiles[opt.fcount].config = 0;
+ setDefaultValues(in, opt.fcount);
+ opt.fcount++;
+ }
+ else {
+ (void) HDfprintf(stderr, err9, argv[i]);
+ goto err;
+ }
+
+ break;
+
+ case 2: /* -c found; look for configfile */
+ break;
+
+ case 3: /* get configfile name */
+ (void) HDstrcpy(opt.infiles[opt.fcount-1].configfile, argv[i]);
+ opt.infiles[opt.fcount - 1].config = 1;
+ break;
+
+ case 4: /* -o found; look for outfile */
+ break;
+
+ case 5: /* get outfile found */
+ (void) HDstrcpy(opt.outfile, argv[i]);
+ outfile_named = TRUE;
+ break;
+
+ case 6: /* -h found; help, then exit */
+ help(argv[0]);
+ HDexit(EXIT_SUCCESS);
+ break;
+
+ case 7: /* -d found; look for dimensions */
+ break;
+
+ case 8: /* read dimensions */
+ if (parseDimensions(in, argv[i]) == -1) {
+ (void) HDfprintf(stderr, err6, argv[i]);
+ goto err;
+ }
+ break;
+
+ case 9: /* -p found; look for path name */
+ break;
+
+ case 10: /* read path name */
+ if (parsePathInfo(&in->path, argv[i]) == -1) {
+ (void) HDfprintf(stderr, err5, argv[i]);
+ goto err;
+ }
+ break;
+
+ case 11: /* -t found; look for data type */
+ break;
+
+ case 12: /* read data type */
+ if (getInputClass(in, argv[i]) == -1) {
+ (void) HDfprintf(stderr, err7, argv[i]);
+ goto err;
+ }
+
+ if (in->inputClass == 0 || in->inputClass == 4)
+ in->outputClass = 0;
+ if (in->inputClass == 1 || in->inputClass == 2 || in->inputClass == 3)
+ in->outputClass = 1;
+ if (in->inputClass == 6 || in->inputClass == 7)
+ in->outputClass = 2;
+ break;
+
+ case 13: /* -s found; look for data size */
+ break;
+
+ case 14: /* read data size */
+ if (getInputSize(in, (int) HDstrtol(argv[i], NULL, BASE_10)) == -1) {
+ (void) HDfprintf(stderr, err8, argv[i]);
+ goto err;
+ }
+ /*set default value for output-size */
+ in->outputSize = in->inputSize;
+ break;
+
+ case ERR: /* command syntax error */
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ usage(argv[0]);
+ goto err;
+ }
+ }
+
+ if (FALSE == outfile_named) {
+ (void) HDfprintf(stderr, "%s", err3);
+ usage(argv[0]);
+ goto err;
+ }
+
+ if (process(&opt) == -1)
+ goto err;
+
+ for (i = 0; i < opt.fcount; i++) {
+ in = &(opt.infiles[i].in);
+ if (in->sizeOfDimension)
+ HDfree(in->sizeOfDimension);
+ if (in->sizeOfChunk)
+ HDfree(in->sizeOfChunk);
+ if (in->maxsizeOfDimension)
+ HDfree(in->maxsizeOfDimension);
+ if (in->externFilename)
+ HDfree(in->externFilename);
+ if (in->data)
+ HDfree(in->data);
+ }
+
+ return (EXIT_SUCCESS);
+err:
+ (void) HDfprintf(stderr, "%s", err4);
+ for (i = 0; i < opt.fcount; i++) {
+ in = &(opt.infiles[i].in);
+ if (in->sizeOfDimension)
+ HDfree(in->sizeOfDimension);
+ if (in->sizeOfChunk)
+ HDfree(in->sizeOfChunk);
+ if (in->maxsizeOfDimension)
+ HDfree(in->maxsizeOfDimension);
+ if (in->externFilename)
+ HDfree(in->externFilename);
+ if (in->data)
+ HDfree(in->data);
+ }
+ return (EXIT_FAILURE);
+}
+
+static int gtoken(char *s)
+{
+ size_t len;
+ int token = ERR;
+
+ const char *err1 = "Illegal argument: %s.\n";
+
+ /*
+ * identify the token type
+ */
+ if (s[0] == '-') { /* option name (or negative number) */
+ len = HDstrlen(&s[1]);
+ switch (s[1]) {
+ case 'o':
+ if (!HDstrncmp("outfile", &s[1], len))
+ token = OPT_o;
+ break;
+
+ case 'c':
+ if (!HDstrncmp("config", &s[1], len))
+ token = OPT_c;
+ break;
+
+ case 'h':
+ if (!HDstrncmp("help", &s[1], len))
+ token = OPT_h;
+ break;
+
+ case 'd':
+ if (!HDstrncmp("dims", &s[1], len))
+ token = OPT_d;
+ break;
+
+ case 'p':
+ if (!HDstrncmp("path", &s[1], len))
+ token = OPT_p;
+ break;
+
+ case 't':
+ if (!HDstrncmp("type", &s[1], len))
+ token = OPT_t;
+ break;
+
+ case 's':
+ if (!HDstrncmp("size", &s[1], len))
+ token = OPT_s;
+ break;
+ default:
+ token = ERR; /* not a supported option tag */
+ break;
+ }
+
+ if (token == ERR)
+ (void) HDfprintf(stderr, err1, s);
+ }
+ else { /* filename */
+ token = FILNAME;
+ }
+ return (token);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: processDataFile
+ *
+ * Purpose: allocate memory and read data file
+ *
+ * Return: 0, success, -1, error
+ *
+ * Programmer: pkmat
+ *
+ * Modifications: pvn
+ * 7/23/2007. Added support for STR type, extra parameter FILE_ID
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int processDataFile(char *infile, struct Input *in, hid_t file_id)
+{
+ FILE *strm = NULL;
+ const char *err1 = "Unable to open the input file %s for reading.\n";
+ const char *err2 = "Error in allocating integer data storage.\n";
+ const char *err3 = "Error in allocating floating-point data storage.\n";
+ const char *err4 = "Error in reading integer data.\n";
+ const char *err5 = "Error in reading floating-point data.\n";
+ const char *err6 = "Error in allocating unsigned integer data storage.\n";
+ const char *err7 = "Error in reading unsigned integer data.\n";
+ const char *err10 = "Unrecognized input class type.\n";
+ const char *err11 = "Error in reading string data.\n";
+ int retval = -1;
+
+ /*-------------------------------------------------------------------------
+ * special case for opening binary classes in H5_HAVE_WIN32_API
+ * "FP" denotes a floating point binary file,
+ * "IN" denotes a signed integer binary file,
+ * "UIN" denotes an unsigned integer binary file,
+ *-------------------------------------------------------------------------
+ */
+ if (in->inputClass == 4 /* "IN" */|| in->inputClass == 3 /* "FP" */|| in->inputClass == 7 /* "UIN" */) {
+
+ if ((strm = HDfopen(infile, READ_OPEN_FLAGS)) == NULL) {
+ (void) HDfprintf(stderr, err1, infile);
+ goto error;
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * if the input class is not binary, just use "r"
+ *-------------------------------------------------------------------------
+ */
+ else {
+ if ((strm = HDfopen(infile, "r")) == NULL) {
+ (void) HDfprintf(stderr, err1, infile);
+ goto error;
+ }
+ }
+
+ switch (in->inputClass) {
+ case 0: /* TEXTIN */
+ case 4: /* IN */
+ if (allocateIntegerStorage(in) == -1) {
+ (void) HDfprintf(stderr, err2, infile);
+ goto error;
+ }
+
+ if (readIntegerData(strm, in) == -1) {
+ (void) HDfprintf(stderr, err4, infile);
+ goto error;
+ }
+ break;
+
+ case 1: /* TEXTFP */
+ case 2: /* TEXTFPE */
+ case 3: /* FP */
+ if (allocateFloatStorage(in) == -1) {
+ (void) HDfprintf(stderr, err3, infile);
+ goto error;
+
+ }
+
+ if (readFloatData(strm, in) == -1) {
+ (void) HDfprintf(stderr, err5, infile);
+ goto error;
+ }
+ break;
+
+ case 5: /* STR */
+ if (in->h5dumpInput) {
+ if (processStrHDFData(strm, in, file_id) == -1) {
+ (void) HDfprintf(stderr, err11, infile);
+ goto error;
+ }
+ }
+ else {
+ if (processStrData(strm, in, file_id) == -1) {
+ (void) HDfprintf(stderr, err11, infile);
+ goto error;
+ }
+ }
+
+ break;
+
+ case 6: /* TEXTUIN */
+ case 7: /* UIN */
+ if (allocateUIntegerStorage(in) == -1) {
+ (void) HDfprintf(stderr, err6, infile);
+ goto error;
+ }
+ if (readUIntegerData(strm, in) == -1) {
+ (void) HDfprintf(stderr, err7, infile);
+ goto error;
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err10);
+ goto error;
+ }
+
+ /* Set success return value */
+ retval = 0;
+
+error:
+ if(strm)
+ HDfclose(strm);
+ return(retval);
+}
+
+static int readIntegerData(FILE *strm, struct Input *in)
+{
+ H5DT_INT8 *in08;
+ H5DT_INT16 *in16;
+ H5DT_INT16 temp;
+ H5DT_INT32 *in32;
+#ifdef H5_SIZEOF_LONG_LONG
+ H5DT_INT64 *in64;
+ char buffer[256];
+#endif
+ hsize_t len = 1;
+ hsize_t i;
+ int j;
+
+ const char *err1 = "Unable to get integer value from file.\n";
+ const char *err2 = "Unrecognized input class type.\n";
+ const char *err3 = "Invalid input size.\n";
+
+ for (j = 0; j < in->rank; j++)
+ len *= in->sizeOfDimension[j];
+
+ switch (in->inputSize) {
+ case 8:
+ switch (in->inputClass) {
+ case 0: /* TEXTIN */
+ in08 = (H5DT_INT8 *) in->data;
+ for (i = 0; i < len; i++, in08++) {
+ if (fscanf(strm, "%hd", &temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ (*in08) = (H5DT_INT8) temp;
+ }
+ break;
+
+ case 4: /* IN */
+ in08 = (H5DT_INT8 *) in->data;
+ for (i = 0; i < len; i++, in08++) {
+ if (HDfread((char *) in08, sizeof(H5DT_INT8), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ case 16:
+ in16 = (H5DT_INT16 *) in->data;
+ switch (in->inputClass) {
+ case 0: /* TEXTIN */
+ for (i = 0; i < len; i++, in16++) {
+ if (fscanf(strm, "%hd", in16) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ in16 = (H5DT_INT16 *) in->data;
+ break;
+
+ case 4: /* IN */
+ for (i = 0; i < len; i++, in16++) {
+ if (HDfread((char *) in16, sizeof(H5DT_INT16), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ case 32:
+ in32 = (H5DT_INT32 *) in->data;
+ switch (in->inputClass) {
+ case 0: /* TEXTIN */
+ for (i = 0; i < len; i++, in32++) {
+ if (fscanf(strm, "%d", in32) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ case 4: /* IN */
+ for (i = 0; i < len; i++, in32++) {
+ if (HDfread((char *) in32, sizeof(H5DT_INT32), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+#ifdef H5_SIZEOF_LONG_LONG
+ case 64:
+ in64 = (H5DT_INT64 *) in->data;
+ switch (in->inputClass) {
+ case 0: /* TEXTIN */
+ for (i = 0; i < len; i++, in64++) {
+ if (fscanf(strm, "%s", buffer) < 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ *in64 = (H5DT_INT64) HDstrtoll(buffer, NULL, 10);
+ }
+ break;
+
+ case 4: /* IN */
+ for (i = 0; i < len; i++, in64++) {
+ if (HDfread((char *) in64, sizeof(H5DT_INT64), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+#endif /* ifdef H5_SIZEOF_LONG_LONG */
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ break;
+ }
+ return (0);
+}
+
+static int readUIntegerData(FILE *strm, struct Input *in)
+{
+ H5DT_UINT8 *in08;
+ H5DT_UINT16 *in16;
+ H5DT_UINT16 temp;
+ H5DT_UINT32 *in32;
+#ifdef H5_SIZEOF_LONG_LONG
+ H5DT_UINT64 *in64;
+ char buffer[256];
+#endif
+ hsize_t len = 1;
+ hsize_t i;
+ int j;
+ const char *err1 = "Unable to get unsigned integer value from file.\n";
+ const char *err2 = "Unrecognized input class type.\n";
+ const char *err3 = "Invalid input size.\n";
+
+ for (j = 0; j < in->rank; j++)
+ len *= in->sizeOfDimension[j];
+
+ switch (in->inputSize) {
+ case 8:
+ switch (in->inputClass) {
+ case 6: /* TEXTUIN */
+ in08 = (H5DT_UINT8 *) in->data;
+ for (i = 0; i < len; i++, in08++) {
+ if (fscanf(strm, "%hu", &temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ (*in08) = (H5DT_UINT8) temp;
+ }
+ break;
+
+ case 7: /* UIN */
+ in08 = (H5DT_UINT8 *) in->data;
+ for (i = 0; i < len; i++, in08++) {
+ if (HDfread((char *) in08, sizeof(H5DT_UINT8), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ case 16:
+ in16 = (H5DT_UINT16 *) in->data;
+ switch (in->inputClass) {
+ case 6: /* TEXTUIN */
+ for (i = 0; i < len; i++, in16++) {
+ if (fscanf(strm, "%hu", in16) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ case 7: /* UIN */
+ for (i = 0; i < len; i++, in16++) {
+ if (HDfread((char *) in16, sizeof(H5DT_UINT16), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ case 32:
+ in32 = (H5DT_UINT32 *) in->data;
+ switch (in->inputClass) {
+ case 6: /* TEXTUIN */
+ for (i = 0; i < len; i++, in32++) {
+ if (fscanf(strm, "%u", in32) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ case 7: /* UIN */
+ for (i = 0; i < len; i++, in32++) {
+ if (HDfread((char *) in32, sizeof(H5DT_UINT32), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+#ifdef H5_SIZEOF_LONG_LONG
+ case 64:
+ in64 = (H5DT_UINT64 *) in->data;
+ switch (in->inputClass) {
+ case 6: /* TEXTUIN */
+ for (i = 0; i < len; i++, in64++) {
+ if (fscanf(strm, "%s", buffer) < 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ *in64 = (H5DT_UINT64) HDstrtoll(buffer, NULL, 10);
+ }
+ break;
+
+ case 7: /* UIN */
+ for (i = 0; i < len; i++, in64++) {
+ if (HDfread((char *) in64, sizeof(H5DT_UINT64), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+#endif /* ifdef H5_SIZEOF_LONG_LONG */
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ break;
+ }
+ return (0);
+}
+
+static int readFloatData(FILE *strm, struct Input *in)
+{
+ H5DT_FLOAT32 *fp32;
+ H5DT_FLOAT64 *fp64;
+
+ hsize_t len = 1;
+ hsize_t i;
+ int j;
+ const char *err1 = "Unable to get integer value from file.\n";
+ const char *err2 = "Unrecognized input class type.\n";
+ const char *err3 = "Invalid input size type.\n";
+
+ for (j = 0; j < in->rank; j++)
+ len *= in->sizeOfDimension[j];
+
+ switch (in->inputSize) {
+ case 32:
+ fp32 = (H5DT_FLOAT32 *) in->data;
+ switch (in->inputClass) {
+ case 1: /* TEXTFP */
+ for (i = 0; i < len; i++, fp32++) {
+ if (fscanf(strm, "%f", fp32) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+
+ fp32 = (H5DT_FLOAT32 *) in->data;
+ break;
+
+ /* same as TEXTFP */
+ case 2: /*TEXTFPE */
+
+ for (i = 0; i < len; i++, fp32++) {
+ if (fscanf(strm, "%f", fp32) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+
+ fp32 = (H5DT_FLOAT32 *) in->data;
+ break;
+
+ case 3: /* FP */
+ for (i = 0; i < len; i++, fp32++) {
+ if (HDfread((char *) fp32, sizeof(H5DT_FLOAT32), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ case 64:
+ fp64 = (H5DT_FLOAT64 *) in->data;
+ switch (in->inputClass) {
+ case 1: /* TEXTFP */
+ for (i = 0; i < len; i++, fp64++) {
+ if (fscanf(strm, "%lf", fp64) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+
+ fp64 = (H5DT_FLOAT64 *) in->data;
+ break;
+
+ /* same as TEXTFP */
+ case 2: /*TEXTFPE */
+
+ for (i = 0; i < len; i++, fp64++) {
+ if (fscanf(strm, "%lf", fp64) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+
+ fp64 = (H5DT_FLOAT64 *) in->data;
+ break;
+
+ case 3: /* FP */
+ for (i = 0; i < len; i++, fp64++) {
+ if (HDfread((char *) fp64, sizeof(H5DT_FLOAT64), 1, strm) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ break;
+ }
+ return (0);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: processStrData
+ *
+ * Purpose: read an ASCII file with string data and generate an HDF5 dataset
+ * with a variable length type
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Pedro Vicente, pvn@hdfgroup.org
+ *
+ * Date: July, 26, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int processStrData(FILE *strm, struct Input *in, hid_t file_id)
+{
+ hid_t group_id;
+ hid_t dset_id;
+ hid_t space_id;
+ hid_t mspace_id;
+ hid_t type_id;
+ hid_t handle;
+ hsize_t dims[1];
+ char str[1024];
+ int c;
+ int i = 0;
+ int j;
+ hsize_t nlines = 0;
+ hsize_t line;
+
+ /*-------------------------------------------------------------------------
+ * get number of lines in the input file
+ *-------------------------------------------------------------------------
+ */
+
+ while(EOF != (c = HDfgetc(strm)))
+ if (c == 10) /* eol */
+ nlines++;
+
+ if (!nlines)
+ return 0;
+
+ /* number of records */
+ dims[0] = nlines;
+
+ /* rewind */
+ HDfseek(strm, 0L, 0);
+
+ /*-------------------------------------------------------------------------
+ * read file again and generate an HDF5 dataset
+ *-------------------------------------------------------------------------
+ */
+
+ if ((type_id = H5Tcopy(H5T_C_S1)) < 0)
+ goto out;
+
+ if (H5Tset_size(type_id, H5T_VARIABLE) < 0)
+ goto out;
+
+ /* disable error reporting */
+ H5E_BEGIN_TRY
+ {
+ /* create parent groups */
+ if (in->path.count > 1) {
+ j = 0;
+ handle = file_id;
+ while (j < in->path.count - 1) {
+ if ((group_id = H5Gopen2(handle, in->path.group[j], H5P_DEFAULT)) < 0) {
+ group_id = H5Gcreate2(handle, in->path.group[j++], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ for (; j < in->path.count - 1; j++)
+ group_id = H5Gcreate2(group_id, in->path.group[j], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ handle = group_id;
+ break;
+ }
+ handle = group_id;
+ j++;
+ }
+ }
+ else {
+ handle = file_id;
+ j = 0;
+ }
+
+ /*enable error reporting */
+ }
+ H5E_END_TRY;
+
+ if ((space_id = H5Screate_simple(1, dims, NULL)) < 0)
+ goto out;
+
+ if ((mspace_id = H5Screate(H5S_SCALAR)) < 0)
+ goto out;
+
+ if ((dset_id = H5Dcreate2(handle, in->path.group[j], type_id, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ goto out;
+
+ line = 0;
+
+ while(EOF != (c = HDfgetc(strm))) {
+ str[i] = (char)c;
+
+ i++;
+
+ if (c == 10) { /* eol */
+ char *str2 = str;
+ hid_t fspace_id;
+ hsize_t start[1];
+ hsize_t count[1] = { 1 };
+
+ str[i - 1] = '\0'; /* terminate string */
+
+ if ((fspace_id = H5Dget_space(dset_id)) < 0)
+ goto out;
+
+ start[0] = line++;
+
+ if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, NULL, count, NULL) < 0)
+ goto out;
+
+ if (H5Dwrite(dset_id, type_id, mspace_id, fspace_id, H5P_DEFAULT, &str2) < 0)
+ goto out;
+
+ if (H5Sclose(fspace_id) < 0)
+ goto out;
+
+ i = 0;
+ str[0] = '\0';
+
+ }
+ }
+
+ /* close */
+ H5Dclose(dset_id);
+ H5Sclose(space_id);
+ H5Sclose(mspace_id);
+ H5Tclose(type_id);
+
+ return (0);
+
+out:
+
+ return (-1);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: processStrData
+ *
+ * Purpose: read an ASCII file with string data and generate an HDF5 dataset
+ * with a variable length type
+ *
+ * Return: 0, ok, -1 no
+ *
+ *-------------------------------------------------------------------------
+ */
+static int processStrHDFData(FILE *strm, struct Input *in, hid_t file_id)
+{
+ hid_t group_id = -1;
+ hid_t dset_id = -1;
+ hid_t space_id = -1;
+ hid_t mspace_id = -1;
+ hid_t type_id = -1;
+ hid_t handle = -1;
+ char *str1 = NULL;
+ char *str2 = NULL;
+ char *str3 = NULL;
+ char str[1024] = "";
+ int j;
+ hsize_t line;
+
+ /*-------------------------------------------------------------------------
+ * read file and generate an HDF5 dataset
+ *-------------------------------------------------------------------------
+ */
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING\n");
+#endif
+
+ if ((type_id = H5Tcopy(H5T_C_S1)) < 0)
+ goto out;
+
+ if (H5Tset_size(type_id, H5T_VARIABLE) < 0)
+ goto out;
+
+ /* disable error reporting */
+ H5E_BEGIN_TRY
+ {
+ /* create parent groups */
+ if (in->path.count > 1) {
+ j = 0;
+ handle = file_id;
+ while (j < in->path.count - 1) {
+ if ((group_id = H5Gopen2(handle, in->path.group[j], H5P_DEFAULT)) < 0) {
+ group_id = H5Gcreate2(handle, in->path.group[j++], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ for (; j < in->path.count - 1; j++)
+ group_id = H5Gcreate2(group_id, in->path.group[j], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ handle = group_id;
+ break;
+ }
+ handle = group_id;
+ j++;
+ }
+ }
+ else {
+ handle = file_id;
+ j = 0;
+ }
+
+ /*enable error reporting */
+ }
+ H5E_END_TRY;
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING groups created\n");
+#endif
+
+ if ((space_id = H5Screate_simple(in->rank, in->sizeOfDimension, NULL)) < 0)
+ goto out;
+
+ if ((mspace_id = H5Screate(H5S_SCALAR)) < 0)
+ goto out;
+
+ if ((dset_id = H5Dcreate2(handle, in->path.group[j], type_id, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ goto out;
+
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING ready to process strings\n");
+#endif
+ line = 0;
+ j = 0;
+
+ while (HDfgets(str,sizeof(str),strm)) {
+ str1 = str;
+ str2 = NULL;
+ str3 = NULL;
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING[%llu]={%s}\n", (unsigned long long)line, str1);
+#endif
+ /* process string to remove the first and last quote char */
+ str2 = strchr(str1, '"');
+ if (str2 != NULL) {
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING len:%d for {%s}\n", strlen(str2), str2);
+#endif
+ str2++;
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING len:%d for {%s}\n", strlen(str2), str2);
+#endif
+ str3 = strrchr(str2, '"');
+ if (str3 != NULL) {
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING len:%d for {%s}\n", strlen(str3), str3);
+#endif
+ *str3 = '\0';
+
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING len:%d for {%s}\n", strlen(str2), str2);
+#endif
+
+ if(strlen(str2) > 0) {
+ hid_t fspace_id;
+ hsize_t start[1];
+ hsize_t count[1] = { 1 };
+
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING[%llu] store %s\n", (unsigned long long)line, str2);
+#endif
+ if ((fspace_id = H5Dget_space(dset_id)) < 0)
+ goto out;
+
+ start[0] = line++;
+
+ if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, NULL, count, NULL) < 0)
+ goto out;
+
+ if (H5Dwrite(dset_id, type_id, mspace_id, fspace_id, H5P_DEFAULT, &str2) < 0)
+ goto out;
+
+ if (H5Sclose(fspace_id) < 0)
+ goto out;
+ }
+ }
+ }
+ str[0] = '\0';
+ j++;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING eof reached\n");
+#endif
+
+ /* close */
+ H5Dclose(dset_id);
+ H5Sclose(space_id);
+ H5Sclose(mspace_id);
+ H5Tclose(type_id);
+
+ return (0);
+
+out:
+#ifdef H5DEBUGIMPORT
+ printf("processStrHDFData DATATYPE STRING error exit\n");
+#endif
+/* disable error reporting */
+H5E_BEGIN_TRY
+{
+ /* close */
+ H5Dclose(dset_id);
+ H5Sclose(space_id);
+ H5Sclose(mspace_id);
+ H5Tclose(type_id);
+}
+H5E_END_TRY;
+
+ return (-1);
+}
+
+static int allocateIntegerStorage(struct Input *in)
+{
+ hsize_t len = 1;
+ int j;
+ const char *err1 = "Unable to allocate dynamic memory.\n";
+ const char *err2 = "Invalid storage size for integer input data.\n";
+
+ for (j = 0; j < in->rank; j++)
+ len *= in->sizeOfDimension[j];
+
+ switch (in->inputSize) {
+ case 8:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_INT8))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ case 16:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_INT16))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ case 32:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_INT32))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ case 64:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_INT64))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ break;
+ }
+ return (0);
+}
+
+static int allocateUIntegerStorage(struct Input *in)
+{
+ hsize_t len = 1;
+ const char *err1 = "Unable to allocate dynamic memory.\n";
+ const char *err2 = "Invalid storage size for unsigned integer input data.\n";
+ int j;
+
+ for (j = 0; j < in->rank; j++)
+ len *= in->sizeOfDimension[j];
+
+ switch (in->inputSize) {
+ case 8:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_UINT8))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ case 16:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_UINT16))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ case 32:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_UINT32))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ case 64:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_UINT64))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ break;
+ }
+ return (0);
+}
+
+static int allocateFloatStorage(struct Input *in)
+{
+ hsize_t len = 1;
+ int j;
+ const char *err1 = "Unable to allocate dynamic memory.\n";
+ const char *err2 = "Invalid storage size for float input data.\n";
+
+ for (j = 0; j < in->rank; j++)
+ len *= in->sizeOfDimension[j];
+
+ switch (in->inputSize) {
+ case 32:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_FLOAT32))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ case 64:
+ if ((in->data = (VOIDP) HDmalloc((size_t) len * sizeof(H5DT_FLOAT64))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ break;
+ }
+ return (0);
+}
+
+static int processConfigurationFile(char *infile, struct Input *in)
+{
+ FILE *strm = NULL;
+ char key[255];
+ int kindex;
+ char temp[255];
+ int ival;
+ int scanret;
+ int retval = -1;
+
+ const char *err1 = "Unable to open the configuration file: %s for reading.\n";
+ const char *err2 = "Unknown keyword in configuration file: %s\n";
+ const char *err3a = "PATH keyword appears twice in %s.\n";
+ const char *err3b = "Error in parsing the path information from %s.\n";
+ const char *err4a = "INPUT-CLASS keyword appears twice in %s.\n";
+ const char *err4b = "Error in retrieving the input class from %s.\n";
+ const char *err5a = "INPUT-SIZE keyword appears twice in %s.\n";
+ const char *err5b = "Error in retrieving the input size from %s.\n";
+ const char *err6a = "RANK keyword appears twice in %s.\n";
+ const char *err6b = "Error in retrieving the rank from %s.\n";
+ const char *err7a = "DIMENSION-SIZES keyword appears twice in %s.\n";
+ const char *err7b = "DIMENSION-SIZES cannot appear before RANK is provided.\n";
+ const char *err7c = "Error in retrieving the dimension sizes from %s.\n";
+ const char *err8a = "OUTPUT-CLASS keyword appears twice in %s.\n";
+ const char *err8b = "Error in retrieving the output class from %s.\n";
+ const char *err9a = "OUTPUT-SIZE keyword appears twice in %s.\n";
+ const char *err9b = "Error in retrieving the output size from %s.\n";
+ const char *err10a = "OUTPUT-ARCHITECTURE keyword appears twice in %s.\n";
+ const char *err10b = "Error in retrieving the output architecture from %s.\n";
+ const char *err11a = "OUTPUT-BYTE-ORDER keyword appears twice in %s.\n";
+ const char *err11b = "Error in retrieving the output byte order from %s.\n";
+ const char *err12a = "CHUNKED-DIMENSION-SIZES keyword appears twice in %s.\n";
+ const char *err12b = "CHUNKED-DIMENSION-SIZES cannot appear before DIMENSION-SIZES are provided.\n";
+ const char *err12c = "Error in retrieving the chunked dimension sizes from %s.\n";
+ const char *err13a = "COMPRESSION-TYPE keyword appears twice in %s.\n";
+ const char *err13b = "Error in retrieving the compression type from %s.\n";
+ const char *err14a = "COMPRESSION-PARAM keyword appears twice in %s.\n";
+ const char *err14b = "Error in retrieving the compression parameter from %s.\n";
+ const char *err15a = "EXTERNAL-STORAGE keyword appears twice in %s.\n";
+ const char *err15b = "Error in retrieving the external storage paramters from %s.\n";
+ const char *err16a = "MAXIMUM-DIMENSIONS keyword appears twice in %s.\n";
+ const char *err16b = "MAXIMUM-DIMENSIONS cannot appear before DIMENSION-SIZES are provided.\n";
+ const char *err16c = "Error in retrieving the maximum dimension sizes from %s.\n";
+ const char *err17 = "Configuration parameters are invalid in %s.\n";
+ const char *err18 = "Unable to get string value.\n";
+ const char *err19 = "Unable to get integer value.\n";
+
+ /* create vector to map which keywords have been found
+ check vector after each keyword to check for violation
+ at the end check vector to see if required fields have been provided
+ process the output file according to the options
+ */
+
+ if ((strm = HDfopen(infile, "r")) == NULL) {
+ (void) HDfprintf(stderr, err1, infile);
+ goto error;
+ }
+
+ scanret = fscanf(strm, "%s", key);
+ if((scanret == 1) && !HDstrcmp("HDF5", key)) {
+#ifdef H5DEBUGIMPORT
+ int pndx;
+ printf("\nh5dump file\n");
+#endif
+ in->h5dumpInput = 1;
+ scanret = fscanf(strm, "%s", temp); /* filename */
+ scanret = fscanf(strm, "%s", temp); /* start bracket */
+ scanret = fscanf(strm, "%s", key); /* DATASET */
+ while (scanret == 1) {
+ if(!HDstrcmp("DATASET", key)) { /* PATH */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASET key\n");
+#endif
+ if (in->configOptionVector[PATH] == 1) {
+ (void) HDfprintf(stderr, err3a, infile);
+ goto error;
+ }
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASET %s found\n", temp);
+#endif
+ if (parsePathInfo(&in->path, temp) == -1) {
+ (void) HDfprintf(stderr, err3b, infile);
+ goto error;
+ }
+ in->configOptionVector[PATH] = 1;
+ scanret = fscanf(strm, "%s", temp); /* start bracket */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASET %s found\n", temp);
+#endif
+ } /* if(!HDstrcmp("DATASET", key)) PATH */
+ else if(!HDstrcmp("DATATYPE", key)) { /* INPUT-CLASS */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE key\n");
+#endif
+ if (in->configOptionVector[INPUT_CLASS] == 1) {
+ (void) HDfprintf(stderr, err4a, infile);
+ goto error;
+ }
+
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE %s found\n", temp);
+#endif
+ if ((kindex = getInputClassType(in, temp)) == -1) {
+ (void) HDfprintf(stderr, err4b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE type %d inputClass\n", in->inputClass);
+#endif
+
+ in->configOptionVector[INPUT_CLASS] = 1;
+
+ /*set default value for output-class */
+ if (in->configOptionVector[OUTPUT_CLASS] == 0) {
+ if (in->inputClass == 0 || in->inputClass == 4)
+ in->outputClass = 0;
+ if (in->inputClass == 1 || in->inputClass == 2
+ || in->inputClass == 3)
+ in->outputClass = 1;
+ if (in->inputClass == 6 || in->inputClass == 7)
+ in->outputClass = 2;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE type %d outputClass\n", in->outputClass);
+#endif
+
+ if(in->inputClass == 5) { /* STRING */
+ int get_next_prop = 1;
+ in->outputClass = -1;
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE STRING found\n");
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* start bracket */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE STRING %s found\n", temp);
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* string properties */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+ while (get_next_prop) {
+ if(!HDstrcmp("STRSIZE", temp)) { /* STRSIZE */
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err19);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE STRING STRSIZE %s found\n", temp);
+#endif
+ if (HDstrcmp("H5T_VARIABLE;", temp)) {
+ char *more = temp;
+ ival = (int)HDstrtol(more, &more, 10);
+ if (getInputSize(in, ival) == -1) {
+ (void) HDfprintf(stderr, err5b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE STRING %d InputSize\n", in->inputSize);
+#endif
+ }
+ }
+ else if(!HDstrcmp("STRPAD", temp)) { /* STRPAD */
+ if (fscanf(strm, "%s", temp) != 1) { /* STRPAD type */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE STRING STRPAD %s found\n", temp);
+#endif
+ }
+ else if(!HDstrcmp("CSET", key)) { /* CSET */
+ if (fscanf(strm, "%s", temp) != 1) { /* CSET type */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE STRING CSET %s found\n", temp);
+#endif
+
+ }
+ else if(!HDstrcmp("CTYPE", temp)) { /* CTYPE */
+ if (fscanf(strm, "%s", temp) != 1) { /* CTYPE type */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE STRING CTYPE %s found\n", temp);
+#endif
+ } /* if(!HDstrcmp("CSET", key)) */
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE STRING %s found\n", temp);
+#endif
+ if(!HDstrcmp("}", temp)) { /* end bracket */
+ get_next_prop = 0;
+ }
+ } /* while (get_next_prop) */
+ } /* if(kindex == 5) STRING */
+ } /* else if(!HDstrcmp("DATATYPE", key)) INPUT-CLASS */
+ else if(!HDstrcmp("DATASPACE", key)) { /* RANK and DIMENSIONS */
+ hsize_t temp_dims[MAX_NUM_DIMENSION];
+
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE key\n");
+#endif
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+ if(!HDstrcmp("SCALAR", temp)) { /* SCALAR */
+ in->rank = 0;
+ } /* if(!HDstrcmp("SCALAR", key)) */
+ else if(!HDstrcmp("NULL", temp)) { /* NULL */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ } /* else if(!HDstrcmp("NULL", key)) */
+ else if(!HDstrcmp("SIMPLE", temp)) { /* SIMPLE */
+ int icount = 0;
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE found\n");
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* start bracket */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %s found\n", temp);
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* start paren */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %s found\n", temp);
+#endif
+ if(!HDstrcmp("(", temp)) { /* start paren */
+ int get_next_dim = 1;
+ int i = 0;
+
+ if (fscanf(strm, "%s", temp) != 1) { /* Dimension with optional comma */
+ (void) HDfprintf(stderr, err16c, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %s found\n", temp);
+#endif
+ while (get_next_dim) {
+ char *more = temp;
+ temp_dims[icount] = HDstrtoull(more, &more, 10);
+ if (fscanf(strm, "%s", temp) != 1) { /* Dimension or end paren */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %s found\n", temp);
+#endif
+ if(!HDstrcmp(")", temp)) { /* end paren */
+ in->rank = ++icount;
+ in->configOptionVector[RANK] = 1;
+ get_next_dim = 0;
+ }
+ else { /* Dimension */
+ icount++;
+ if (icount > MAX_NUM_DIMENSION) {
+ (void) HDfprintf(stderr, "Invalid value for rank.\n");
+ goto error;
+ }
+ }
+ } /* while (get_next_dim) */
+
+ if ((in->sizeOfDimension = (hsize_t *) HDmalloc ((size_t) in->rank * sizeof(hsize_t))) == NULL) {
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %d rank\n", in->rank);
+#endif
+ for (i = 0; i < in->rank; i++) {
+ in->sizeOfDimension[i] = temp_dims[i];
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE dims:", in->rank);
+ for (pndx = 0; pndx < in->rank; pndx++) {
+ printf(" %d", in->sizeOfDimension[pndx]);
+ }
+ printf("\n");
+#endif
+ in->configOptionVector[DIM] = 1;
+ } /* if(!HDstrcmp("(", key)) start paren */
+ else {
+ (void) HDfprintf(stderr, err5b, infile);
+ goto error;
+ }
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %s found\n", temp);
+#endif
+ if(!HDstrcmp("/", temp)) { /* / max dims */
+ if ((in->maxsizeOfDimension = (hsize_t *) HDmalloc ((size_t) in->rank * sizeof(hsize_t))) == NULL) {
+ goto error;
+ }
+ if (fscanf(strm, "%s", temp) != 1) { /* start paren */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %s found\n", temp);
+#endif
+ if(!HDstrcmp("(", temp)) { /* start paren */
+ int get_next_dim = 1;
+ int i = 0;
+
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE process max dim values\n");
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* max dim with optional comma */
+ (void) HDfprintf(stderr, err16c, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %s found\n", temp);
+#endif
+ while (get_next_dim) {
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE get max dim value\n");
+#endif
+ if(!HDstrcmp("H5S_UNLIMITED", temp) || !HDstrcmp("H5S_UNLIMITED,", temp)) { /* unlimited */
+ in->maxsizeOfDimension[i] = H5S_UNLIMITED;
+ in->configOptionVector[EXTEND] = 1;
+ }
+ else {
+ char *more = temp;
+ in->maxsizeOfDimension[i] = HDstrtoull(more, &more, 10);
+ }
+ if (fscanf(strm, "%s", temp) != 1) { /* max dim or end paren */
+ (void) HDfprintf(stderr, err16c, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %s found\n", temp);
+#endif
+ if(!HDstrcmp(")", temp)) { /* end paren */
+ get_next_dim = 0;
+ }
+ else { /* comma */
+ i++;
+ if (i > MAX_NUM_DIMENSION) {
+ (void) HDfprintf(stderr, "Invalid value for rank.\n");
+ goto error;
+ }
+ }
+ } /* while (get_next_dim) */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE maxdims:", in->rank);
+ for (pndx = 0; pndx < in->rank; pndx++) {
+ printf(" %d", in->maxsizeOfDimension[pndx]);
+ }
+ printf("\n");
+ printf("h5dump DATASPACE SIMPLE get max dim finished\n");
+#endif
+ } /* if(!HDstrcmp("(", key)) start paren */
+ else {
+ (void) HDfprintf(stderr, err16c, infile);
+ goto error;
+ }
+ scanret = fscanf(strm, "%s", temp); /* end bracket */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATASPACE SIMPLE %s found\n", temp);
+#endif
+ } /* if(!HDstrcmp("/", key)) max dims separator */
+ } /* else if(!HDstrcmp("SIMPLE", key)) */
+ else {
+ (void) HDfprintf(stderr, err5b, infile);
+ goto error;
+ }
+ } /* else if(!HDstrcmp("DATASPACE", key)) RANK and DIMENSIONS */
+ else if(!HDstrcmp("STORAGE_LAYOUT", key)) { /* CHUNKED-DIMENSION-SIZES */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT key\n");
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* start bracket */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT %s found\n", temp);
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* CHUNKED */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT %s found\n", temp);
+#endif
+ if(!HDstrcmp("CHUNKED", temp)) { /* CHUNKED */
+ if ((in->sizeOfChunk = (hsize_t *) HDmalloc ((size_t) in->rank * sizeof(hsize_t))) == NULL) {
+ (void) HDfprintf(stderr, "Unable to allocate dynamic memory.\n");
+ goto error;
+ }
+ if (fscanf(strm, "%s", temp) != 1) { /* start paren */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT CHUNKED %s found\n", temp);
+#endif
+ if(!HDstrcmp("(", temp)) { /* start paren */
+ int get_next_dim = 1;
+ int icount = 0;
+
+ if (fscanf(strm, "%s", temp) != 1) { /* Dimension with optional comma */
+ (void) HDfprintf(stderr, err16c, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT CHUNKED %s found\n", temp);
+#endif
+ while (get_next_dim) {
+ char *more = temp;
+ in->sizeOfChunk[icount] = HDstrtoull(more, &more, 10);
+ if (fscanf(strm, "%s", temp) != 1) { /* Dimension or end paren */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT CHUNKED %s found\n", temp);
+#endif
+ if(!HDstrcmp(")", temp)) { /* end paren */
+ in->configOptionVector[RANK] = 1;
+ get_next_dim = 0;
+ }
+ else { /* Dimension */
+ icount++;
+ if (icount > MAX_NUM_DIMENSION) {
+ (void) HDfprintf(stderr, "Invalid value for rank.\n");
+ goto error;
+ }
+ }
+ } /* while (get_next_dim) */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT CHUNKED dims:", in->rank);
+ for (pndx = 0; pndx < in->rank; pndx++) {
+ printf(" %d", in->sizeOfChunk[pndx]);
+ }
+ printf("\n");
+#endif
+ in->configOptionVector[DIM] = 1;
+ } /* if(!HDstrcmp("(", key)) start paren */
+ else {
+ (void) HDfprintf(stderr, err5b, infile);
+ goto error;
+ }
+ if (fscanf(strm, "%s", temp) != 1) { /* SIZE */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT CHUNKED %s found\n", temp);
+#endif
+ if(!HDstrcmp("SIZE", temp)) { /* SIZE */
+ if (fscanf(strm, "%d", (&ival)) != 1) {
+ (void) HDfprintf(stderr, "%s", err19);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT CHUNKED SIZE %d found\n", ival);
+#endif
+ }
+ while (HDstrcmp("}", temp)) {
+ if (fscanf(strm, "%s", temp) != 1) { /* end bracket */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump STORAGE_LAYOUT CHUNKED %s found\n", temp);
+#endif
+ }
+ in->configOptionVector[CHUNK] = 1;
+ } /* if(!HDstrcmp("CHUNKED", key)) CHUNKED */
+ } /* else if(!HDstrcmp("STORAGE_LAYOUT", key)) CHUNKED-DIMENSION-SIZES */
+ else if(!HDstrcmp("FILTERS", key)) { /* FILTERS */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS key\n");
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* start bracket */
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS %s found\n", temp);
+#endif
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS %s found\n", temp);
+#endif
+ if(!HDstrcmp("COMPRESSION", temp)) { /* COMPRESSION */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS COMPRESSION found\n");
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* DEFLATE */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS COMPRESSION %s found\n", temp);
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* bgin bracket */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS COMPRESSION %s found\n", temp);
+#endif
+ if (fscanf(strm, "%s", temp) != 1) { /* LEVEL */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS COMPRESSION %s found\n", temp);
+#endif
+ if (fscanf(strm, "%d", (&ival)) != 1) {
+ (void) HDfprintf(stderr, "%s", err19);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS COMPRESSION LEVEL %d found\n", ival);
+#endif
+ in->compressionParam = ival;
+ if (fscanf(strm, "%s", temp) != 1) { /* end bracket */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS COMPRESSION %s found\n", temp);
+#endif
+ in->compressionType = 0; /* ONLY GZIP supported */
+ in->configOptionVector[COMPRESS] = 1;
+ }
+ else if(!HDstrcmp("CONTIGUOUS", temp)) { /* CONTIGUOUS */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS CONTIGUOUS found\n");
+#endif
+ in->configOptionVector[COMPRESS] = 0;
+ }
+ else if(!HDstrcmp("NONE", temp)) { /* NONE */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS NONE found\n");
+#endif
+ in->configOptionVector[COMPRESS] = 0;
+ }
+ if (fscanf(strm, "%s", temp) != 1) { /* end bracket */
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump FILTERS %s found\n", temp);
+#endif
+ }
+ else if(!HDstrcmp("DATA", key)) { /* FINSHED */
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATA key\n");
+#endif
+ scanret = 0;
+ break;
+ }
+ scanret = fscanf(strm, "%s", key);
+ }
+#ifdef H5DEBUGIMPORT
+ printf("h5dump path");
+ for (pndx = 0; pndx < in->path.count; pndx++) {
+ printf(" : %s", in->path.group[pndx]);
+ }
+ printf("\n");
+ printf("h5dump inputClass=%d\n", in->inputClass);
+ printf("h5dump inputSize=%d\n", in->inputSize);
+ printf("h5dump rank=%d\n", in->rank);
+ printf("h5dump outputClass=%d\n", in->outputClass);
+ printf("h5dump outputSize=%d\n", in->outputSize);
+ printf("h5dump outputArchitecture=%d\n", in->outputArchitecture);
+ printf("h5dump outputByteOrder=%d\n", in->outputByteOrder);
+ printf("h5dump compressionType=%d\n", in->compressionType);
+ printf("h5dump compressionParam=%d\n", in->compressionParam);
+ printf("h5dump externFilename=%s\n", in->externFilename);
+ printf("h5dump configOptionVector:\n");
+ for (pndx = 0; pndx < NUM_KEYS; pndx++) {
+ printf(" %s=%d\n", keytable[pndx], in->configOptionVector[pndx]);
+ }
+#endif
+ }
+ else {
+ while (scanret == 1) {
+ if ((kindex = mapKeywordToIndex(key)) == -1) {
+ (void) HDfprintf(stderr, err2, infile);
+ goto error;
+ }
+ switch (kindex) {
+ case 0: /* PATH */
+ if (in->configOptionVector[PATH] == 1) {
+ (void) HDfprintf(stderr, err3a, infile);
+ goto error;
+ }
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+ if (parsePathInfo(&in->path, temp) == -1) {
+ (void) HDfprintf(stderr, err3b, infile);
+ goto error;
+ }
+ in->configOptionVector[PATH] = 1;
+ break;
+
+ case 1: /* INPUT-CLASS */
+ if (in->configOptionVector[INPUT_CLASS] == 1) {
+ (void) HDfprintf(stderr, err4a, infile);
+ goto error;
+ }
+
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err18);
+ goto error;
+ }
+ if (getInputClass(in, temp) == -1) {
+ (void) HDfprintf(stderr, err4b, infile);
+ goto error;
+ }
+
+ in->configOptionVector[INPUT_CLASS] = 1;
+
+ /*set default value for output-class */
+ if (in->configOptionVector[OUTPUT_CLASS] == 0) {
+ if (in->inputClass == 0 || in->inputClass == 4)
+ in->outputClass = 0;
+ if (in->inputClass == 1 || in->inputClass == 2
+ || in->inputClass == 3)
+ in->outputClass = 1;
+ if (in->inputClass == 6 || in->inputClass == 7)
+ in->outputClass = 2;
+ }
+ break;
+
+ case 2: /* INPUT-SIZE */
+ if (in->configOptionVector[INPUT_SIZE] == 1) {
+ (void) HDfprintf(stderr, err5a, infile);
+ goto error;
+ }
+ if (fscanf(strm, "%d", (&ival)) != 1) {
+ (void) HDfprintf(stderr, "%s", err19);
+ goto error;
+ }
+ if (getInputSize(in, ival) == -1) {
+ (void) HDfprintf(stderr, err5b, infile);
+ goto error;
+ }
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ /*set default value for output-size */
+ if (in->configOptionVector[OUTPUT_SIZE] == 0)
+ in->outputSize = in->inputSize;
+ break;
+
+ case 3: /* RANK */
+ if (in->configOptionVector[RANK] == 1) {
+ (void) HDfprintf(stderr, err6a, infile);
+ goto error;
+ }
+
+ if (getRank(in, strm) == -1) {
+ (void) HDfprintf(stderr, err6b, infile);
+ goto error;
+ }
+ in->configOptionVector[RANK] = 1;
+ break;
+
+ case 4: /* DIMENSION-SIZES */
+ if (in->configOptionVector[DIM] == 1) {
+ (void) HDfprintf(stderr, err7a, infile);
+ goto error;
+ }
+
+ if (in->configOptionVector[RANK] == 0) {
+ (void) HDfprintf(stderr, err7b, infile);
+ goto error;
+ }
+ if (getDimensionSizes(in, strm) == -1) {
+ (void) HDfprintf(stderr, err7c, infile);
+ goto error;
+ }
+ in->configOptionVector[DIM] = 1;
+ break;
+
+ case 5: /* OUTPUT-CLASS */
+ if (in->configOptionVector[OUTPUT_CLASS] == 1) {
+ (void) HDfprintf(stderr, err8a, infile);
+ goto error;
+ }
+
+ if (getOutputClass(in, strm) == -1) {
+ (void) HDfprintf(stderr, err8b, infile);
+ goto error;
+ }
+ in->configOptionVector[OUTPUT_CLASS] = 1;
+ break;
+
+ case 6: /* OUTPUT-SIZE */
+ if (in->configOptionVector[OUTPUT_SIZE] == 1) {
+ (void) HDfprintf(stderr, err9a, infile);
+ goto error;
+ }
+
+ if (getOutputSize(in, strm) == -1) {
+ (void) HDfprintf(stderr, err9b, infile);
+ goto error;
+ }
+ in->configOptionVector[OUTPUT_SIZE] = 1;
+ break;
+
+ case 7: /* OUTPUT-ARCHITECTURE */
+ if (in->configOptionVector[OUTPUT_ARCH] == 1) {
+ (void) HDfprintf(stderr, err10a, infile);
+ goto error;
+ }
+
+ if (getOutputArchitecture(in, strm) == -1) {
+ (void) HDfprintf(stderr, err10b, infile);
+ goto error;
+ }
+ in->configOptionVector[OUTPUT_ARCH] = 1;
+ break;
+
+ case 8: /* OUTPUT-BYTE-ORDER */
+ if (in->configOptionVector[OUTPUT_B_ORDER] == 1) {
+ (void) HDfprintf(stderr, err11a, infile);
+ goto error;
+ }
+
+ if (getOutputByteOrder(in, strm) == -1) {
+ (void) HDfprintf(stderr, err11b, infile);
+ goto error;
+ }
+ in->configOptionVector[OUTPUT_B_ORDER] = 1;
+ break;
+
+ case 9: /* CHUNKED-DIMENSION-SIZES */
+ if (in->configOptionVector[CHUNK] == 1) {
+ (void) HDfprintf(stderr, err12a, infile);
+ goto error;
+ }
+ /* cant appear before dimension sizes have been provided */
+ if (in->configOptionVector[DIM] == 0) {
+ (void) HDfprintf(stderr, err12b, infile);
+ goto error;
+ }
+
+ if (getChunkedDimensionSizes(in, strm) == -1) {
+ (void) HDfprintf(stderr, err12c, infile);
+ goto error;
+ }
+ in->configOptionVector[CHUNK] = 1;
+ break;
+
+ case 10: /* COMPRESSION-TYPE */
+ if (in->configOptionVector[COMPRESS] == 1) {
+ (void) HDfprintf(stderr, err13a, infile);
+ goto error;
+ }
+
+ if (getCompressionType(in, strm) == -1) {
+ (void) HDfprintf(stderr, err13b, infile);
+ goto error;
+ }
+ in->configOptionVector[COMPRESS] = 1;
+
+ if (in->configOptionVector[COMPRESS_PARAM] == 0) {
+ if (in->compressionType == 0)
+ in->compressionParam = 6; /* default value if compressionType is GZIP */
+ }
+ break;
+
+ case 11: /* COMPRESSION-PARAM */
+ if (in->configOptionVector[COMPRESS_PARAM] == 1) {
+ (void) HDfprintf(stderr, err14a, infile);
+ goto error;
+ }
+
+ if (getCompressionParameter(in, strm) == -1) {
+ (void) HDfprintf(stderr, err14b, infile);
+ goto error;
+ }
+
+ in->configOptionVector[COMPRESS_PARAM] = 1;
+
+ if (in->configOptionVector[COMPRESS] == 0)
+ in->compressionType = 0;
+
+ break;
+
+ case 12: /* EXTERNAL-STORAGE */
+ if (in->configOptionVector[EXTERNALSTORE] == 1) {
+ (void) HDfprintf(stderr, err15a, infile);
+ goto error;
+ }
+
+ if (getExternalFilename(in, strm) == -1) {
+ (void) HDfprintf(stderr, err15b, infile);
+ goto error;
+ }
+ in->configOptionVector[EXTERNALSTORE] = 1;
+ break;
+
+ case 13: /* MAXIMUM-DIMENSIONS */
+ if (in->configOptionVector[EXTEND] == 1) {
+ (void) HDfprintf(stderr, err16a, infile);
+ goto error;
+ }
+ /* cant appear before dimension sizes have been provided */
+ if (in->configOptionVector[DIM] == 0) {
+ (void) HDfprintf(stderr, err16b, infile);
+ goto error;
+ }
+ if (getMaximumDimensionSizes(in, strm) == -1) {
+ (void) HDfprintf(stderr, err16c, infile);
+ goto error;
+ }
+ in->configOptionVector[EXTEND] = 1;
+ break;
+
+ default:
+ break;
+ }
+ scanret = fscanf(strm, "%s", key);
+ }
+ }
+
+ /*
+ check if keywords obtained are valid
+ if yes, return 0 else error
+ */
+
+ if (validateConfigurationParameters(in) == -1) {
+ (void) HDfprintf(stderr, err17, infile);
+ goto error;
+ }
+
+ /* Set success return value */
+ retval = 0;
+
+error:
+ if(strm)
+ HDfclose(strm);
+ return(retval);
+}
+
+static int validateConfigurationParameters(struct Input *in)
+{
+ const char *err1 = "One or more of the required fields (RANK, DIMENSION-SIZES) missing.\n";
+ const char *err2 = "Cannot specify chunking or compression or extendible data sets with the external file option.\n";
+ const char *err3 = "Cannot specify the compression or the extendible data sets without the chunking option.\n";
+ const char *err4a = "OUTPUT-ARCHITECTURE cannot be STD if OUTPUT-CLASS is floating point (FP).\n";
+ const char *err4b = "OUTPUT-ARCHITECTURE cannot be IEEE if OUTPUT-CLASS is integer (IN).\n";
+ const char *err5 = "For OUTPUT-CLASS FP, valid values for OUTPUT-SIZE are (32, 64) .\n";
+#ifndef H5_SIZEOF_LONG_LONG
+ const char *err6 = "No support for reading 64-bit integer (INPUT-CLASS: IN, TEXTIN, UIN, TEXTUIN files\n";
+#endif
+
+ /* for class STR other parameters are ignored */
+ if (in->inputClass == 5) /* STR */
+ return (0);
+
+ if ((in->configOptionVector[DIM] != 1) || (in->configOptionVector[RANK] != 1)) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ if (in->configOptionVector[EXTERNALSTORE] == 1) {
+ if ((in->configOptionVector[COMPRESS] == 1) || (in->configOptionVector[CHUNK] == 1) || (in->configOptionVector[EXTEND] == 1)) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ }
+
+ if ((in->configOptionVector[COMPRESS] == 1) || (in->configOptionVector[EXTEND] == 1)) {
+ if (in->configOptionVector[CHUNK] != 1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ }
+
+ /* Arch cant be STD if O/p class is FP */
+ if (in->outputArchitecture == 1)
+ if (in->outputClass == 1) {
+ (void) HDfprintf(stderr, "%s", err4a);
+ return (-1);
+ }
+
+ /* Arch cant be IEEE if O/p class is IN */
+ if (in->outputArchitecture == 2)
+ if (in->outputClass == 0) {
+ (void) HDfprintf(stderr, "%s", err4b);
+ return (-1);
+ }
+
+ if (in->outputClass == 1)
+ if (in->outputSize != 32 && in->outputSize != 64) {
+ (void) HDfprintf(stderr, "%s", err5);
+ return (-1);
+ }
+
+#ifndef H5_SIZEOF_LONG_LONG
+ if (in->inputSize == 64 && (in->inputClass == 0 || in->inputClass == 4 || in->inputClass == 6 || in->inputClass == 7) ) {
+ (void) HDfprintf(stderr, "%s", err6);
+ return -1;
+ }
+#endif
+ return (0);
+}
+
+static int mapKeywordToIndex(char *key)
+{
+ int i;
+
+ for (i = 0; i < NUM_KEYS; i++)
+ if (!HDstrcmp(keytable[i], key))
+ return i;
+ return -1;
+}
+
+static int parsePathInfo(struct path_info *path, char *temp)
+{
+ const char delimiter[] = "/\"";
+ char *token;
+ int i = 0;
+ const char *err1 = "Path string larger than MAX_PATH_NAME_LENGTH.\n";
+
+ token = HDstrtok (temp, delimiter);
+ if (HDstrlen(token) >= MAX_PATH_NAME_LENGTH) {
+ (void) HDfprintf(stderr, err1);
+ return (-1);
+ }
+ HDstrcpy(path->group[i++],token);
+
+ while (1) {
+ token = HDstrtok (NULL, delimiter);
+ if (token == NULL)
+ break;
+ if (HDstrlen(token) >= MAX_PATH_NAME_LENGTH) {
+ (void) HDfprintf(stderr, err1);
+ return (-1);
+ }
+ HDstrcpy(path->group[i++],token);
+ }
+ path->count = i;
+ return (0);
+}
+
+static int parseDimensions(struct Input *in, char *strm)
+{
+ const char delimiter[] = ",";
+ char temp[255];
+ char *token;
+ int i = 0;
+ const char *err1 = "Unable to allocate dynamic memory.\n";
+
+ HDstrncpy(temp, strm, sizeof(temp));
+ temp[sizeof(temp) - 1] = '\0';
+ HDstrtok (temp, delimiter);
+
+ while (1) {
+ token = HDstrtok (NULL, delimiter);
+ if (token == NULL)
+ break;
+ i++;
+ }
+ in->rank = i + 1;
+ if ((in->sizeOfDimension = (hsize_t *) HDmalloc ((size_t) in->rank * sizeof(hsize_t))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ i = 0;
+ HDstrncpy(temp, strm, sizeof(temp));
+ temp[sizeof(temp) - 1] = '\0';
+ in->sizeOfDimension[i++]
+ = HDstrtoull(HDstrtok (temp, delimiter), NULL, BASE_10);
+
+ while (1) {
+ token = HDstrtok (NULL, delimiter);
+ if (token == NULL)
+ break;
+ in->sizeOfDimension[i++] = HDstrtoull(token, NULL, BASE_10);
+ }
+ return (0);
+}
+
+static int getOutputClass(struct Input *in, FILE *strm)
+{
+ char temp[255];
+ int kindex;
+ const char *err1 = "Unable to get 'string' value.\n";
+ const char *err2 = "Invalid value for output class.\n";
+
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ if ((kindex = OutputClassStrToInt(temp)) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+
+ in->outputClass = kindex;
+ return (0);
+}
+
+static int OutputClassStrToInt(char *temp)
+{
+ int i;
+ char classKeywordTable[3][15] = { "IN", "FP", "UIN" };
+ for (i = 0; i < 3; i++)
+ if (!HDstrcmp(classKeywordTable[i], temp))
+ return i;
+
+ return -1;
+}
+/* same as getInputSize. But defined separately for extensibility */
+static int getOutputSize(struct Input *in, FILE *strm)
+{
+ int ival;
+ int i;
+ int outputSizeValidValues[4] = { 8, 16, 32, 64 };
+ const char *err1 = "Unable to get integer value.\n";
+ const char *err2 = "Invalid value for output size.\n";
+
+ if (fscanf(strm, "%d", (&ival)) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ for (i = 0; i < 4; i++)
+ if (outputSizeValidValues[i] == ival) {
+ in->outputSize = ival;
+ return (0);
+ }
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+}
+
+static int getInputClass(struct Input *in, char * temp)
+{
+ int kindex;
+ const char *err1 = "Invalid value for input class.\n";
+
+ if ((kindex = InputClassStrToInt(temp)) == -1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ in->inputClass = kindex;
+ return (0);
+}
+
+static int getInputClassType(struct Input *in, char * buffer)
+{
+ int kindex = -1;
+ const char *err1 = "Invalid value for input class.\n";
+ const char *err2 = "Invalid value for output architecture.\n";
+ const char *err3 = "Invalid value for output byte-order.\n";
+
+ if (!HDstrcmp(buffer, "H5T_STD_I8BE")) {
+ in->inputSize = 8;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_I8LE")) {
+ in->inputSize = 8;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_I16BE")) {
+ in->inputSize = 16;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_I16LE")) {
+ in->inputSize = 16;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_I32BE")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_I32LE")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_I64BE")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_I64LE")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_U8BE")) {
+ in->inputSize = 8;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_U8LE")) {
+ in->inputSize = 8;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_U16BE")) {
+ in->inputSize = 16;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_U16LE")) {
+ in->inputSize = 16;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_U32BE")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_U32LE")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_U64BE")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_U64LE")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_SCHAR")) {
+ in->inputSize = 8;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_UCHAR")) {
+ in->inputSize = 8;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_SHORT")) {
+ in->inputSize = 16;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_USHORT")) {
+ in->inputSize = 16;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_INT")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_UINT")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_LONG")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_ULONG")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_LLONG")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 4;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_ULLONG")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 7;
+ }
+ else if (!HDstrcmp(buffer, "H5T_IEEE_F32BE")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("IEEE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 3;
+ }
+ else if (!HDstrcmp(buffer, "H5T_IEEE_F32LE")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("IEEE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 3;
+ }
+ else if (!HDstrcmp(buffer, "H5T_IEEE_F64BE")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("IEEE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 3;
+ }
+ else if (!HDstrcmp(buffer, "H5T_IEEE_F64LE")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("IEEE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = 3;
+ }
+ else if (!HDstrcmp(buffer, "H5T_VAX_F32")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ kindex = 3;
+ }
+ else if (!HDstrcmp(buffer, "H5T_VAX_F64")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ kindex = 3;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_FLOAT")) {
+ in->inputSize = 32;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 3;
+ }
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_DOUBLE")) {
+ in->inputSize = 64;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 3;
+ }
+#if H5_SIZEOF_LONG_DOUBLE !=0
+ else if (!HDstrcmp(buffer, "H5T_NATIVE_LDOUBLE")) {
+ in->inputSize = H5_SIZEOF_LONG_DOUBLE;
+ in->configOptionVector[INPUT_SIZE] = 1;
+
+ if ((kindex = OutputArchStrToInt("NATIVE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ kindex = 3;
+ }
+#endif
+ else if(!HDstrcmp(buffer, "H5T_TIME: not yet implemented")) {
+ kindex = -1;
+ }
+ else if(!HDstrcmp(buffer, "H5T_STRING")) {
+ kindex = 5;
+ }
+ /* case H5T_BITFIELD: */
+ else if (!HDstrcmp(buffer, "H5T_STD_B8BE")) {
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = -1;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_B8LE")) {
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = -1;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_B16BE")) {
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = -1;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_B16LE")) {
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = -1;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_B32BE")) {
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = -1;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_B32LE")) {
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = -1;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_B64BE")) {
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("BE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = -1;
+ }
+ else if (!HDstrcmp(buffer, "H5T_STD_B64LE")) {
+
+ if ((kindex = OutputArchStrToInt("STD")) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->outputArchitecture = kindex;
+
+ if ((kindex = OutputByteOrderStrToInt("LE")) == -1) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ in->outputByteOrder = kindex;
+
+ kindex = -1;
+ }
+ /* case H5T_OPAQUE: */
+ else if(!HDstrcmp(buffer, "H5T_OPAQUE")) {
+ kindex = -1;
+ }
+ /* case H5T_COMPOUND: */
+ else if(!HDstrcmp(buffer, "H5T_COMPOUND")) {
+ kindex = -1;
+ }
+ /* case H5T_REFERENCE: */
+ else if(!HDstrcmp(buffer, "H5T_REFERENCE")) {
+ kindex = -1;
+ }
+ /* case H5T_ENUM: */
+ else if(!HDstrcmp(buffer, "H5T_ENUM")) {
+ kindex = -1;
+ }
+ /* case H5T_VLEN: */
+ else if(!HDstrcmp(buffer, "H5T_VLEN")) {
+ kindex = -1;
+ }
+ /* case H5T_ARRAY: */
+ else if(!HDstrcmp(buffer, "H5T_ARRAY")) {
+ kindex = -1;
+ }
+
+ if (kindex == -1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ /*set default value for output-size */
+ if (in->configOptionVector[OUTPUT_SIZE] == 0)
+ in->outputSize = in->inputSize;
+#ifdef H5DEBUGIMPORT
+ printf("h5dump DATATYPE STRING %d inputSize\n", in->inputSize);
+ printf("h5dump DATATYPE STRING %d outputSize\n", in->outputSize);
+#endif
+
+ in->inputClass = kindex;
+ return (0);
+}
+
+static int InputClassStrToInt(char *temp)
+{
+ int i;
+ char classKeywordTable[8][15] = { "TEXTIN", "TEXTFP", "TEXTFPE", "FP", "IN", "STR", "TEXTUIN", "UIN" };
+ for (i = 0; i < 8; i++)
+ if (!HDstrcmp(classKeywordTable[i], temp))
+ return i;
+ return -1;
+}
+
+/* same as getOutputSize. But defined separately for extensibility */
+static int getInputSize(struct Input *in, int ival)
+{
+ int i;
+ int inputSizeValidValues[4] = { 8, 16, 32, 64 };
+ const char *err1 = "Invalid value for input size.\n";
+
+ for (i = 0; i < 4; i++)
+ if (inputSizeValidValues[i] == ival) {
+ in->inputSize = ival;
+ return (0);
+ }
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+}
+
+static int getRank(struct Input *in, FILE *strm)
+{
+ int ival;
+
+ const char *err1 = "Unable to get integer value.\n";
+ const char *err2 = "Invalid value for rank.\n";
+
+ if (fscanf(strm, "%d", (&ival)) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ if (ival >= MIN_NUM_DIMENSION && ival <= MAX_NUM_DIMENSION) {
+ in->rank = ival;
+ return (0);
+ }
+
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+}
+
+/* same as getChunkedDimensionSizes. But defined separately for extensibility */
+static int getDimensionSizes(struct Input *in, FILE *strm)
+{
+ unsigned long long ullval;
+ int i = 0;
+
+ const char *err1 = "Unable to allocate dynamic memory.\n";
+ const char *err2 = "No. of dimensions for which dimension sizes provided is not equal to provided rank.\n";
+
+ if ((in->sizeOfDimension = (hsize_t *) HDmalloc ((size_t) in->rank * sizeof(hsize_t))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ while (fscanf(strm, "%llu", (&ullval)) == 1)
+ in->sizeOfDimension[i++] = ullval;
+
+ if (in->rank != i) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ return (0);
+}
+/* same as getDimensionSizes. But defined separately for extensibility */
+static int getChunkedDimensionSizes(struct Input *in, FILE *strm)
+{
+ unsigned long long ullval;
+ int i = 0;
+
+ const char *err1 = "Unable to allocate dynamic memory.\n";
+ const char *err2 = "No. of dimensions for which chunked dimension sizes provided is not equal to provided rank.\n";
+ const char *err3 = "The CHUNKED-DIMENSION-SIZES cannot exceed the sizes of DIMENSION-SIZES\n";
+
+ if ((in->sizeOfChunk = (hsize_t *) HDmalloc ((size_t) in->rank * sizeof(hsize_t))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ while (fscanf(strm, "%llu", (&ullval)) == 1)
+ in->sizeOfChunk[i++] = ullval;
+
+ if (in->rank != i) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+
+ for (i = 0; i < in->rank; i++)
+ if (in->sizeOfChunk[i] > in->sizeOfDimension[i]) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ return (0);
+}
+
+static int getMaximumDimensionSizes(struct Input *in, FILE *strm)
+{
+ long long llval;
+ int i = 0;
+
+ const char *err1 = "Unable to allocate dynamic memory.\n";
+ const char *err2 = "No. of dimensions for which maximum dimension sizes provided is not equal to provided rank.\n";
+ const char *err3 = "The MAXIMUM-DIMENSIONS cannot be less than the sizes of DIMENSION-SIZES. Exception: can be -1 to indicate unlimited size\n";
+
+ if ((in->maxsizeOfDimension = (hsize_t *) HDmalloc ((size_t) in->rank * sizeof(hsize_t))) == NULL) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ while (fscanf(strm, "%lld", (&llval)) == 1) {
+ if (llval == -1)
+ in->maxsizeOfDimension[i++] = H5S_UNLIMITED;
+ else
+ in->maxsizeOfDimension[i++] = (hsize_t)llval;
+ }
+
+ if (in->rank != i) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+
+ for (i = 0; i < in->rank; i++) {
+ if (in->maxsizeOfDimension[i] != H5S_UNLIMITED)
+ if (in->maxsizeOfDimension[i] < in->sizeOfDimension[i]) {
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+static int getOutputArchitecture(struct Input *in, FILE *strm)
+{
+ char temp[255];
+ int kindex;
+ const char *err1 = "Unable to get 'string' value.\n";
+ const char *err2 = "Invalid value for output architecture.\n";
+
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ if ((kindex = OutputArchStrToInt(temp)) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+
+ in->outputArchitecture = kindex;
+ return (0);
+}
+
+static int OutputArchStrToInt(const char *temp)
+{
+ int i;
+ char outputArchKeywordTable[8][15] = { "NATIVE", "STD", "IEEE", "INTEL",
+ "CRAY", "MIPS", "ALPHA", "UNIX" };
+ for (i = 0; i < 8; i++)
+ if (!HDstrcmp(outputArchKeywordTable[i], temp))
+ return i;
+ return -1;
+}
+
+static int getOutputByteOrder(struct Input *in, FILE *strm)
+{
+ char temp[255];
+ int kindex;
+ const char *err1 = "Unable to get 'string' value.\n";
+ const char *err2 = "Invalid value for output byte-order.\n";
+
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ if ((kindex = OutputByteOrderStrToInt(temp)) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+
+ in->outputByteOrder = kindex;
+ return (0);
+}
+
+static int OutputByteOrderStrToInt(const char *temp)
+{
+ int i;
+ char outputByteOrderKeywordTable[2][15] = { "BE", "LE" };
+ for (i = 0; i < 2; i++)
+ if (!HDstrcmp(outputByteOrderKeywordTable[i], temp))
+ return i;
+ return -1;
+}
+
+static int getCompressionType(struct Input *in, FILE *strm)
+{
+ char temp[255];
+ int kindex;
+ const char *err1 = "Unable to get 'string' value.\n";
+ const char *err2 = "Invalid value for compression.\n";
+
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ if ((kindex = CompressionTypeStrToInt(temp)) == -1) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+
+ in->compressionType = kindex;
+ return (0);
+
+}
+
+static int CompressionTypeStrToInt(char *temp)
+{
+ /* currently supports only GZIP */
+ /* can be extended by adding fields to the table */
+
+ int i;
+ char CompressionTypeKeywordTable[1][15] = { "GZIP" };
+ for (i = 0; i < 1; i++)
+ if (!HDstrcmp(CompressionTypeKeywordTable[i], temp))
+ return i;
+ return -1;
+}
+
+static int getCompressionParameter(struct Input *in, FILE *strm)
+{
+ /* currently supports only GZIP */
+ /* can be extended by adding more values to COMPRESSION-TYPE and */
+ /* handling the paramters here by adding more cases */
+
+ int ival;
+ const char *err1 = "Unable to get integer value.\n";
+ const char *err2 = "Invalid value for compression paramter.\n";
+ const char *err3 = "Unsupported Compression Type.\n";
+
+ switch (in->compressionType) {
+ case 0: /* GZIP */
+ if (fscanf(strm, "%d", (&ival)) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ if (ival < 0 || ival > 9) {
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ in->compressionParam = ival;
+ return (0);
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+}
+
+static int getExternalFilename(struct Input *in, FILE *strm)
+{
+ char temp[255];
+ const char *err1 = "Unable to get 'string' value.\n";
+
+ if (fscanf(strm, "%s", temp) != 1) {
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+
+ in->externFilename = (char *) HDmalloc ((size_t) (HDstrlen(temp)) * sizeof(char));
+ (void) HDstrcpy(in->externFilename, temp);
+ return (0);
+}
+
+void setDefaultValues(struct Input *in, int count)
+{
+ int i;
+ char temp[255];
+ char num[255];
+
+ in->h5dumpInput = 0;
+ in->inputClass = 3; /* FP */
+ in->inputSize = 32;
+ in->outputClass = 1; /* FP */
+ in->outputSize = 32;
+ in->rank = 0;
+ in->path.count = 1;
+
+ HDstrcpy(temp, "dataset");
+ sprintf(num, "%d", count);
+ HDstrcat(temp, num);
+ HDstrcpy(in->path.group[0], temp);
+
+ in->outputArchitecture = 0; /* NATIVE */
+ in->outputByteOrder = -1; /* use default */
+ in->compressionType = 0; /* GZIP */
+ for (i = 0; i < NUM_KEYS; i++)
+ in->configOptionVector[i] = 0;
+}
+
+hid_t createOutputDataType(struct Input *in)
+{
+ hid_t new_type = (-1);
+ const char *err1 = "Invalid value for output class.\n";
+ const char *err2 = "Invalid value for output size.\n";
+ const char *err3 = "Invalid value for output byte order.\n";
+ const char *err4 = "Invalid value for output architecture.\n";
+ const char *err5 = "STD not supported for float.\n";
+ const char *err6 = "IEEE not supported for INT.\n";
+
+ switch (in->outputClass) {
+ case 0:
+ switch (in->outputArchitecture) {
+ case 0: /* NATIVE */
+ switch (in->outputSize) {
+ case 8:
+ new_type = H5Tcopy(H5T_NATIVE_CHAR);
+ break;
+
+ case 16:
+ new_type = H5Tcopy(H5T_NATIVE_SHORT);
+ break;
+
+ case 32:
+ new_type = H5Tcopy(H5T_NATIVE_INT);
+ break;
+
+ case 64:
+ new_type = H5Tcopy(H5T_NATIVE_LLONG);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ switch (in->outputByteOrder) {
+ case -1: /* default */
+ break;
+ case 0:
+ H5Tset_order(new_type, H5T_ORDER_BE);
+ break;
+
+ case 1:
+ H5Tset_order(new_type, H5T_ORDER_LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 1: /* STD */
+ switch (in->outputSize) {
+ case 8:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_STD_I8BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_STD_I8LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 16:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_STD_I16BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_STD_I16LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 32:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_STD_I32BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_STD_I32LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 64:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_STD_I64BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_STD_I64LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err4);
+ return (-1);
+ }
+ break;
+
+ case 1:
+ switch (in->outputArchitecture) {
+ case 0:
+ switch (in->outputSize) {
+ case 32:
+ new_type = H5Tcopy(H5T_NATIVE_FLOAT);
+ break;
+
+ case 64:
+ new_type = H5Tcopy(H5T_NATIVE_DOUBLE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ switch (in->outputByteOrder) {
+ case -1: /* DEFAULT */
+ break;
+ case 0:
+ H5Tset_order(new_type, H5T_ORDER_BE);
+ break;
+
+ case 1:
+ H5Tset_order(new_type, H5T_ORDER_LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 1:
+ (void) HDfprintf(stderr, "%s", err5);
+ return (-1);
+
+ case 2:
+ switch (in->outputSize) {
+ case 32:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_IEEE_F32BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_IEEE_F32LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 64:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_IEEE_F64BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_IEEE_F64LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err4);
+ return (-1);
+ }
+ break;
+
+ case 2:
+ switch (in->outputArchitecture) {
+ case 0:
+ switch (in->outputSize) {
+ case 8:
+ new_type = H5Tcopy(H5T_NATIVE_UCHAR);
+ break;
+
+ case 16:
+ new_type = H5Tcopy(H5T_NATIVE_USHORT);
+ break;
+
+ case 32:
+ new_type = H5Tcopy(H5T_NATIVE_UINT);
+ break;
+
+ case 64:
+ new_type = H5Tcopy(H5T_NATIVE_ULLONG);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ switch (in->outputByteOrder) {
+ case -1: /* Default */
+ break;
+ case 0:
+ H5Tset_order(new_type, H5T_ORDER_BE);
+ break;
+
+ case 1:
+ H5Tset_order(new_type, H5T_ORDER_LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 1:
+ switch (in->outputSize) {
+ case 8:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_STD_U8BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_STD_U8LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 16:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_STD_U16BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_STD_U16LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 32:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_STD_U32BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_STD_U32LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ case 64:
+ switch (in->outputByteOrder) {
+ case -1:
+ case 0:
+ new_type = H5Tcopy(H5T_STD_U64BE);
+ break;
+
+ case 1:
+ new_type = H5Tcopy(H5T_STD_U64LE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err3);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ case 2:
+ (void) HDfprintf(stderr, "%s", err6);
+ return (-1);
+
+ default:
+ (void) HDfprintf(stderr, "%s", err4);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ return new_type;
+}
+
+hid_t createInputDataType(struct Input *in)
+{
+ hid_t new_type = (-1);
+ const char *err1 = "Invalid value for input class.\n";
+ const char *err2 = "Invalid value for output size.\n";
+
+ switch (in->inputClass) {
+ case 0:
+ case 4:
+ switch (in->inputSize) {
+ case 8:
+ new_type = H5Tcopy(H5T_NATIVE_CHAR);
+ break;
+
+ case 16:
+ new_type = H5Tcopy(H5T_NATIVE_SHORT);
+ break;
+
+ case 32:
+ new_type = H5Tcopy(H5T_NATIVE_INT);
+ break;
+
+ case 64:
+ new_type = H5Tcopy(H5T_NATIVE_LLONG);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ switch (in->inputSize) {
+ case 32:
+ new_type = H5Tcopy(H5T_NATIVE_FLOAT);
+ break;
+
+ case 64:
+ new_type = H5Tcopy(H5T_NATIVE_DOUBLE);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ case 5:
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ break;
+
+ case 6:
+ case 7:
+ switch (in->inputSize) {
+ case 8:
+ new_type = H5Tcopy(H5T_NATIVE_UCHAR);
+ break;
+
+ case 16:
+ new_type = H5Tcopy(H5T_NATIVE_USHORT);
+ break;
+
+ case 32:
+ new_type = H5Tcopy(H5T_NATIVE_UINT);
+ break;
+
+ case 64:
+ new_type = H5Tcopy(H5T_NATIVE_ULLONG);
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err2);
+ return (-1);
+ }
+ break;
+
+ default:
+ (void) HDfprintf(stderr, "%s", err1);
+ return (-1);
+ }
+ return new_type;
+}
+
+static int process(struct Options *opt)
+{
+ struct Input *in;
+ FILE *extfile;
+ hid_t file_id;
+ hid_t group_id;
+ hid_t handle;
+ hid_t dataset;
+ hid_t dataspace = (-1);
+ hid_t intype;
+ hid_t outtype;
+ hid_t proplist;
+ hsize_t numOfElements = 1;
+ int j;
+ int k;
+
+ const char *err1 = "Error creating HDF output file: %s.\n";
+ const char *err2 = "Error in processing the configuration file: %s.\n";
+ const char *err3 = "Error in reading the input file: %s.\n";
+ const char *err4 = "Error in creating or opening external file.\n";
+ const char *err5 = "Error in creating the output data set. Dataset with the same name may exist at the specified path\n";
+ const char *err6 = "Error in writing the output data set.\n";
+
+ H5E_BEGIN_TRY
+ {
+ if ((file_id = H5Fopen(opt->outfile, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
+ if ((file_id = H5Fcreate(opt->outfile, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) == FAIL) {
+ (void) HDfprintf(stderr, err1, opt->outfile);
+ return (-1);
+ }
+ }
+ }
+ H5E_END_TRY;
+
+ for (k = 0; k < opt->fcount; k++) {
+ in = &(opt->infiles[k].in);
+ if (opt->infiles[k].config == 1) {
+ if (processConfigurationFile(opt->infiles[k].configfile, in) == -1) {
+ (void) HDfprintf(stderr, err2, opt->infiles[k].configfile);
+ return (-1);
+ }
+ }
+
+ if (processDataFile(opt->infiles[k].datafile, in, file_id) == -1) {
+ (void) HDfprintf(stderr, err3, opt->infiles[k].datafile);
+ return (-1);
+ }
+
+ if (in->inputClass != 5) { /* STR */
+ for (j = 0; j < in->rank; j++)
+ numOfElements *= in->sizeOfDimension[j];
+
+ /* disable error reporting */
+ H5E_BEGIN_TRY
+ {
+ /* create parent groups */
+ if (in->path.count > 1) {
+ j = 0;
+ handle = file_id;
+ while (j < in->path.count - 1) {
+ if ((group_id = H5Gopen2(handle, in->path.group[j], H5P_DEFAULT)) < 0) {
+ group_id = H5Gcreate2(handle, in->path.group[j++], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ for (; j < in->path.count - 1; j++)
+ group_id = H5Gcreate2(group_id, in->path.group[j], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ handle = group_id;
+ break;
+ }
+ handle = group_id;
+ j++;
+ }
+ }
+ else {
+ handle = file_id;
+ j = 0;
+ }
+
+ /*enable error reporting */
+ }
+ H5E_END_TRY;
+
+ /*create data type */
+ intype = createInputDataType(in);
+ outtype = createOutputDataType(in);
+#ifdef H5DEBUGIMPORT
+ printf("process intype %d outtype %d\n", intype, outtype);
+#endif
+
+ /* create property list */
+ proplist = H5Pcreate(H5P_DATASET_CREATE);
+ if (in->configOptionVector[CHUNK] == 1) {
+ H5Pset_layout(proplist, H5D_CHUNKED);
+ /* not reqd chunking is implied if set_chunk is used */
+ H5Pset_chunk(proplist, in->rank, in->sizeOfChunk);
+ }
+
+ if (in->configOptionVector[COMPRESS] == 1) {
+ H5Pset_deflate(proplist, (unsigned) in->compressionParam);
+ }
+
+ if (in->configOptionVector[EXTERNALSTORE] == 1) {
+ /* creating the external file if it doesnt exist */
+ if ((extfile = HDfopen(in->externFilename, "ab")) == NULL) {
+ (void) HDfprintf(stderr, "%s", err4);
+ H5Pclose(proplist);
+ H5Sclose(dataspace);
+ H5Fclose(file_id);
+ return (-1);
+ }
+ HDfclose(extfile);
+ H5Pset_external(proplist, in->externFilename, (off_t)0, numOfElements * (hsize_t)in->inputSize / 8);
+ }
+
+ /* create dataspace */
+ if (in->configOptionVector[EXTEND] == 1)
+ dataspace = H5Screate_simple(in->rank, in->sizeOfDimension, in->maxsizeOfDimension);
+ else
+ dataspace = H5Screate_simple(in->rank, in->sizeOfDimension, NULL);
+
+ /* disable error reporting */
+ H5E_BEGIN_TRY
+ {
+ /* create data set */
+ if ((dataset = H5Dcreate2(handle, in->path.group[j], outtype, dataspace, H5P_DEFAULT, proplist, H5P_DEFAULT)) < 0) {
+ (void) HDfprintf(stderr, "%s", err5);
+ H5Pclose(proplist);
+ H5Sclose(dataspace);
+ H5Fclose(file_id);
+ return (-1);
+ }
+
+ /*enable error reporting */
+ }
+ H5E_END_TRY;
+
+ /* write dataset */
+ if (H5Dwrite(dataset, intype, H5S_ALL, H5S_ALL, H5P_DEFAULT, (VOIDP) in->data) < 0) {
+ (void) HDfprintf(stderr, "%s", err6);
+ H5Dclose(dataset);
+ H5Pclose(proplist);
+ H5Sclose(dataspace);
+ H5Fclose(file_id);
+ return (-1);
+ }
+
+ H5Dclose(dataset);
+ H5Pclose(proplist);
+ H5Sclose(dataspace);
+ }
+
+ } /* STR */
+
+ H5Fclose(file_id);
+ return (0);
+}
+
+/*
+ * Name:
+ * help
+ *
+ * Purpose:
+ * Print a helpful summary of command usage and features.
+ */
+
+void help(char *name)
+{
+ (void) HDfprintf(stdout, "Name:\n\n");
+ (void) HDfprintf(stdout, "\t%s\n\n", name);
+ (void) HDfprintf(stdout, "\t TOOL NAME:\n");
+ (void) HDfprintf(stdout, "\t %s\n", name);
+ (void) HDfprintf(stdout, "\t SYNTAX:\n");
+ (void) HDfprintf(stdout, "\t %s -h[elp], OR\n", name);
+ (void) HDfprintf(stdout,
+ "\t %s <infile> -c[onfig] <configfile> [<infile> -c[config] <configfile>...]", name);
+ (void) HDfprintf(stdout, "\t\t\t\t -o[utfile] <outfile>\n\n");
+ (void) HDfprintf(stdout, "\t PURPOSE:\n");
+ (void) HDfprintf(stdout,
+ "\t To convert data stored in one or more ASCII or binary files\n");
+ (void) HDfprintf(stdout,
+ "\t into one or more datasets (in accordance with the \n");
+ (void) HDfprintf(stdout,
+ "\t user-specified type and storage properties) in an existing \n");
+ (void) HDfprintf(stdout, "\t or new HDF5 file.\n\n");
+ (void) HDfprintf(stdout, "\t DESCRIPTION:\n");
+ (void) HDfprintf(stdout,
+ "\t The primary objective of the utility is to convert floating\n");
+ (void) HDfprintf(stdout,
+ "\t point or integer data stored in ASCII text or binary form \n");
+ (void) HDfprintf(stdout,
+ "\t into a data-set according to the type and storage properties\n");
+ (void) HDfprintf(stdout,
+ "\t specified by the user. The utility can also accept ASCII\n");
+ (void) HDfprintf(stdout,
+ "\t text files and store the contents in a compact form as an\n");
+ (void) HDfprintf(stdout, "\t array of one-dimensional strings.\n\n");
+ (void) HDfprintf(stdout,
+ "\t The input data to be written as a data-set can be provided\n");
+ (void) HDfprintf(stdout, "\t to the utility in one of the following forms:\n");
+ (void) HDfprintf(stdout,
+ "\t 1. ASCII text file with numeric data (floating point or \n");
+ (void) HDfprintf(stdout, "\t integer data). \n");
+ (void) HDfprintf(stdout,
+ "\t 2. Binary file with native floating point data (32-bit or \n");
+ (void) HDfprintf(stdout, "\t 64-bit) \n");
+ (void) HDfprintf(stdout,
+ "\t 3. Binary file with native integer (signed or unsigned)\n");
+ (void) HDfprintf(stdout, "\t data (8-bit or 16-bit or 32-bit or 64-bit). \n");
+ (void) HDfprintf(stdout,
+ "\t 4. ASCII text file containing strings (text data).\n");
+ (void) HDfprintf(stdout, "\t \n");
+ (void) HDfprintf(stdout,
+ "\t Every input file is associated with a configuration file \n");
+ (void) HDfprintf(stdout,
+ "\t also provided as an input to the utility. (See Section \n");
+ (void) HDfprintf(stdout,
+ "\t \"CONFIGURATION FILE\" to know how it is to be organized).\n");
+ (void) HDfprintf(stdout,
+ "\t The class, size and dimensions of the input data is \n");
+ (void) HDfprintf(stdout,
+ "\t specified in this configuration file. A point to note is\n");
+ (void) HDfprintf(stdout,
+ "\t that the floating point data in the ASCII text file may be\n");
+ (void) HDfprintf(stdout,
+ "\t organized in the fixed floating form (for example 323.56)\n");
+ (void) HDfprintf(stdout,
+ "\t or in a scientific notation (for example 3.23E+02). A \n");
+ (void) HDfprintf(stdout,
+ "\t different input-class specification is to be used for both\n");
+ (void) HDfprintf(stdout, "\t forms.\n\n");
+ (void) HDfprintf(stdout,
+ "\t The utility extracts the input data from the input file \n");
+ (void) HDfprintf(stdout,
+ "\t according to the specified parameters and saves it into \n");
+ (void) HDfprintf(stdout, "\t an H5 dataset. \n\n");
+ (void) HDfprintf(stdout,
+ "\t The user can specify output type and storage properties in \n");
+ (void) HDfprintf(stdout,
+ "\t the configuration file. The user is required to specify the \n");
+ (void) HDfprintf(stdout,
+ "\t path of the dataset. If the groups in the path leading to \n");
+ (void) HDfprintf(stdout,
+ "\t the data-set do not exist, the groups will be created by the\n");
+ (void) HDfprintf(stdout,
+ "\t utility. If no group is specified, the dataset will be\n");
+ (void) HDfprintf(stdout, "\t created under the root group.\n\n");
+ (void) HDfprintf(stdout,
+ "\t In addition to the name, the user is also required to \n");
+ (void) HDfprintf(stdout,
+ "\t provide the class and size of output data to be written to \n");
+ (void) HDfprintf(stdout,
+ "\t the dataset and may optionally specify the output-architecture,\n");
+ (void) HDfprintf(stdout,
+ "\t and the output-byte-order. If output-architecture is not \n");
+ (void) HDfprintf(stdout,
+ "\t specified the default is NATIVE. Output-byte-orders are fixed\n");
+ (void) HDfprintf(stdout,
+ "\t for some architectures and may be specified only if output-\n");
+ (void) HDfprintf(stdout, "\t architecture is IEEE, UNIX or STD.\n\n");
+ (void) HDfprintf(stdout,
+ "\t Also, layout and other storage properties such as \n");
+ (void) HDfprintf(stdout,
+ "\t compression, external storage and extendible data-sets may be\n");
+ (void) HDfprintf(stdout,
+ "\t optionally specified. The layout and storage properties \n");
+ (void) HDfprintf(stdout,
+ "\t denote how raw data is to be organized on the disk. If these \n");
+ (void) HDfprintf(stdout,
+ "\t options are not specified the default is Contiguous layout \n");
+ (void) HDfprintf(stdout, "\t and storage.\n\n");
+ (void) HDfprintf(stdout,
+ "\t The dataset can be organized in any of the following ways:\n");
+ (void) HDfprintf(stdout, "\t 1. Contiguous.\n");
+ (void) HDfprintf(stdout, "\t 2. Chunked.\n");
+ (void) HDfprintf(stdout,
+ "\t 3. External Storage File (has to be contiguous)\n");
+ (void) HDfprintf(stdout,
+ "\t 4. Extendible data sets (has to be chunked)\n");
+ (void) HDfprintf(stdout, "\t 5. Compressed. (has to be chunked)\n");
+ (void) HDfprintf(stdout,
+ "\t 6. Compressed & Extendible (has to be chunked)\n\n");
+ (void) HDfprintf(stdout,
+ "\t If the user wants to store raw data in a non-HDF file then \n");
+ (void) HDfprintf(stdout,
+ "\t the external storage file option is to be used and the name \n");
+ (void) HDfprintf(stdout, "\t of the file is to be specified. \n\n");
+ (void) HDfprintf(stdout,
+ "\t If the user wants the dimensions of the data-set to be\n");
+ (void) HDfprintf(stdout,
+ "\t unlimited, the extendible data set option can be chosen. \n\n");
+ (void) HDfprintf(stdout,
+ "\t The user may also specify the type of compression and the \n");
+ (void) HDfprintf(stdout,
+ "\t level to which the data set must be compresses by setting \n");
+ (void) HDfprintf(stdout, "\t the compressed option.\n\n");
+ (void) HDfprintf(stdout, "\t SYNOPSIS:\n");
+ (void) HDfprintf(stdout, "\t h5import -h[elp], OR\n");
+ (void) HDfprintf( stdout,
+ "\t h5import <infile> -c[onfig] <configfile> \
+ [<infile> -c[config] <confile2>...] -o[utfile] <outfile>\n\n");
+ (void) HDfprintf(stdout, "\t -h[elp]:\n");
+ (void) HDfprintf(stdout,
+ "\t Prints this summary of usage, and exits.\n\n");
+ (void) HDfprintf(stdout, "\t <infile(s)>:\n");
+ (void) HDfprintf(stdout,
+ "\t Name of the Input file(s), containing a \n");
+ (void) HDfprintf(stdout,
+ "\t single n-dimensional floating point or integer array \n");
+ (void) HDfprintf(stdout,
+ "\t in either ASCII text, native floating point(32-bit \n");
+ (void) HDfprintf(stdout,
+ "\t or 64-bit) or native integer(8-bit or 16-bit or \n");
+ (void) HDfprintf(stdout,
+ "\t 32-bit or 64-bit). Data to be specified in the order\n");
+ (void) HDfprintf(stdout, "\t of fastest changing dimensions first.\n\n");
+ (void) HDfprintf(stdout, "\t -c[config] <configfile>:\n");
+ (void) HDfprintf(stdout,
+ "\t Every input file should be associated with a \n");
+ (void) HDfprintf(stdout,
+ "\t configuration file and this is done by the -c option.\n");
+ (void) HDfprintf(stdout,
+ "\t <configfile> is the name of the configuration file.\n");
+ (void) HDfprintf(stdout, "\t (See Section \"CONFIGURATION FILE\")\n\n");
+ (void) HDfprintf(stdout, "\t -o[utfile] <outfile>:\n");
+ (void) HDfprintf(stdout,
+ "\t Name of the HDF5 output file. Data from one or more \n");
+ (void) HDfprintf(stdout,
+ "\t input files are stored as one or more data sets in \n");
+ (void) HDfprintf(stdout,
+ "\t <outfile>. The output file may be an existing file or \n");
+ (void) HDfprintf(stdout,
+ "\t it maybe new in which case it will be created.\n\n\n");
+ (void) HDfprintf(stdout, "\t CONFIGURATION FILE:\n");
+ (void) HDfprintf(stdout,
+ "\t The configuration file is an ASCII text file and must be \n");
+ (void) HDfprintf(stdout,
+ "\t the ddl formatted file (without data values) produced by h5dump \n");
+ (void) HDfprintf(stdout,
+ "\t when used with the options '-o outfilename -b' of a single dataset (-d) \n");
+ (void) HDfprintf(stdout,
+ "\t OR organized as \"CONFIG-KEYWORD VALUE\" pairs, one pair on each \n");
+ (void) HDfprintf(stdout, "\t line.\n\n");
+ (void) HDfprintf(stdout,
+ "\t The configuration file may have the following keywords each \n");
+ (void) HDfprintf(stdout, "\t followed by an acceptable value.\n\n");
+ (void) HDfprintf(stdout, "\t Required KEYWORDS:\n");
+ (void) HDfprintf(stdout, "\t PATH\n");
+ (void) HDfprintf(stdout, "\t INPUT-CLASS\n");
+ (void) HDfprintf(stdout, "\t INPUT-SIZE\n");
+ (void) HDfprintf(stdout, "\t RANK\n");
+ (void) HDfprintf(stdout, "\t DIMENSION-SIZES\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-CLASS\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-SIZE\n\n");
+ (void) HDfprintf(stdout, "\t Optional KEYWORDS:\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-ARCHITECTURE\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-BYTE-ORDER\n");
+ (void) HDfprintf(stdout, "\t CHUNKED-DIMENSION-SIZES\n");
+ (void) HDfprintf(stdout, "\t COMPRESSION-TYPE\n");
+ (void) HDfprintf(stdout, "\t COMPRESSION-PARAM\n");
+ (void) HDfprintf(stdout, "\t EXTERNAL-STORAGE\n");
+ (void) HDfprintf(stdout, "\t MAXIMUM-DIMENSIONS\n\n\n");
+ (void) HDfprintf(stdout, "\t Values for keywords:\n");
+ (void) HDfprintf(stdout, "\t PATH:\n");
+ (void) HDfprintf(stdout, "\t Strings separated by spaces to represent\n");
+ (void) HDfprintf(stdout, "\t the path of the data-set. If the groups in\n");
+ (void) HDfprintf(stdout,
+ "\t the path do not exist, they will be created. \n");
+ (void) HDfprintf(stdout, "\t For example,\n");
+ (void) HDfprintf(stdout, "\t PATH grp1/grp2/dataset1\n");
+ (void) HDfprintf(stdout, "\t PATH: keyword\n");
+ (void) HDfprintf(stdout, "\t grp1: group under the root. If\n");
+ (void) HDfprintf(stdout, "\t non-existent will be created.\n");
+ (void) HDfprintf(stdout, "\t grp2: group under grp1. If \n");
+ (void) HDfprintf(stdout, "\t non-existent will be created \n");
+ (void) HDfprintf(stdout, "\t under grp1.\n");
+ (void) HDfprintf(stdout, "\t dataset1: the name of the data-set \n");
+ (void) HDfprintf(stdout, "\t to be created.\n\n");
+ (void) HDfprintf(stdout, "\t INPUT-CLASS:\n");
+ (void) HDfprintf(stdout, "\t String denoting the type of input data.\n");
+ (void) HDfprintf(stdout, "\t (\"TEXTIN\", \"TEXTFP\", \"FP\", \"IN\", \n");
+ (void) HDfprintf(stdout, "\t \"STR\", \"TEXTUIN\", \"UIN\"). \n");
+ (void) HDfprintf(stdout,
+ "\t INPUT-CLASS \"TEXTIN\" denotes an ASCII text \n");
+ (void) HDfprintf(stdout,
+ "\t file with signed integer data in ASCII form,\n");
+ (void) HDfprintf(stdout,
+ "\t INPUT-CLASS \"TEXTUIN\" denotes an ASCII text \n");
+ (void) HDfprintf(stdout,
+ "\t file with unsigned integer data in ASCII form,\n");
+ (void) HDfprintf(stdout,
+ "\t \"TEXTFP\" denotes an ASCII text file containing\n");
+ (void) HDfprintf(stdout, "\t floating point data in the fixed notation\n");
+ (void) HDfprintf(stdout, "\t (325.34),\n");
+ (void) HDfprintf(stdout,
+ "\t \"FP\" denotes a floating point binary file,\n");
+ (void) HDfprintf(stdout,
+ "\t \"IN\" denotes a signed integer binary file,\n");
+ (void) HDfprintf(stdout,
+ "\t \"UIN\" denotes an unsigned integer binary file,\n");
+ (void) HDfprintf(stdout, "\t & \"STR\" denotes an ASCII text file the \n");
+ (void) HDfprintf(stdout,
+ "\t contents of which should be stored as an 1-D \n");
+ (void) HDfprintf(stdout, "\t array of strings.\n");
+ (void) HDfprintf(stdout, "\t If INPUT-CLASS is \"STR\", then RANK, \n");
+ (void) HDfprintf(stdout,
+ "\t DIMENSION-SIZES, OUTPUT-CLASS, OUTPUT-SIZE, \n");
+ (void) HDfprintf(stdout, "\t OUTPUT-ARCHITECTURE and OUTPUT-BYTE-ORDER \n");
+ (void) HDfprintf(stdout, "\t will be ignored.\n\n\n");
+ (void) HDfprintf(stdout, "\t INPUT-SIZE:\n");
+ (void) HDfprintf(stdout,
+ "\t Integer denoting the size of the input data \n");
+ (void) HDfprintf(stdout, "\t (8, 16, 32, 64). \n\n");
+ (void) HDfprintf(stdout, "\t For floating point,\n");
+ (void) HDfprintf(stdout, "\t INPUT-SIZE can be 32 or 64.\n");
+ (void) HDfprintf(stdout, "\t For integers (signed and unsigned)\n");
+ (void) HDfprintf(stdout, "\t INPUT-SIZE can be 8, 16, 32 or 64.\n\n");
+ (void) HDfprintf(stdout, "\t RANK:\n");
+ (void) HDfprintf(stdout,
+ "\t Integer denoting the number of dimensions.\n\n");
+ (void) HDfprintf(stdout, "\t DIMENSION-SIZES:\n");
+ (void) HDfprintf(stdout,
+ "\t Integers separated by spaces to denote the \n");
+ (void) HDfprintf(stdout, "\t dimension sizes for the no. of dimensions \n");
+ (void) HDfprintf(stdout, "\t determined by rank.\n\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-CLASS:\n");
+ (void) HDfprintf(stdout,
+ "\t String dentoting data type of the dataset to \n");
+ (void) HDfprintf(stdout, "\t be written (\"IN\",\"FP\", \"UIN\")\n\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-SIZE:\n");
+ (void) HDfprintf(stdout,
+ "\t Integer denoting the size of the data in the \n");
+ (void) HDfprintf(stdout, "\t output dataset to be written.\n");
+ (void) HDfprintf(stdout,
+ "\t If OUTPUT-CLASS is \"FP\", OUTPUT-SIZE can be \n");
+ (void) HDfprintf(stdout, "\t 32 or 64.\n");
+ (void) HDfprintf(stdout,
+ "\t If OUTPUT-CLASS is \"IN\" or \"UIN\", OUTPUT-SIZE\n");
+ (void) HDfprintf(stdout, "\t can be 8, 16, 32 or 64.\n\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-ARCHITECTURE:\n");
+ (void) HDfprintf(stdout, "\t STRING denoting the type of output \n");
+ (void) HDfprintf(stdout,
+ "\t architecture. Can accept the following values\n");
+ (void) HDfprintf(stdout, "\t STD\n");
+ (void) HDfprintf(stdout, "\t IEEE\n");
+ (void) HDfprintf(stdout, "\t INTEL\n");
+ (void) HDfprintf(stdout, "\t CRAY\n");
+ (void) HDfprintf(stdout, "\t MIPS\n");
+ (void) HDfprintf(stdout, "\t ALPHA\n");
+ (void) HDfprintf(stdout, "\t NATIVE (default)\n");
+ (void) HDfprintf(stdout, "\t UNIX\n\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-BYTE-ORDER:\n");
+ (void) HDfprintf(stdout,
+ "\t String denoting the output-byte-order. Ignored\n");
+ (void) HDfprintf(stdout,
+ "\t if the OUTPUT-ARCHITECTURE is not specified or\n");
+ (void) HDfprintf(stdout, "\t if it is IEEE, UNIX or STD. Can accept the \n");
+ (void) HDfprintf(stdout, "\t following values.\n");
+ (void) HDfprintf(stdout, "\t BE (default)\n");
+ (void) HDfprintf(stdout, "\t LE\n\n");
+ (void) HDfprintf(stdout, "\t CHUNKED-DIMENSION-SIZES:\n");
+ (void) HDfprintf(stdout, "\t Integers separated by spaces to denote the \n");
+ (void) HDfprintf(stdout,
+ "\t dimension sizes of the chunk for the no. of \n");
+ (void) HDfprintf(stdout,
+ "\t dimensions determined by rank. Required field\n");
+ (void) HDfprintf(stdout,
+ "\t to denote that the dataset will be stored with\n");
+ (void) HDfprintf(stdout,
+ "\t chunked storage. If this field is absent the\n");
+ (void) HDfprintf(stdout,
+ "\t dataset will be stored with contiguous storage.\n\n");
+ (void) HDfprintf(stdout, "\t COMPRESSION-TYPE:\n");
+ (void) HDfprintf(stdout,
+ "\t String denoting the type of compression to be\n");
+ (void) HDfprintf(stdout, "\t used with the chunked storage. Requires the\n");
+ (void) HDfprintf(stdout,
+ "\t CHUNKED-DIMENSION-SIZES to be specified. The only \n");
+ (void) HDfprintf(stdout,
+ "\t currently supported compression method is GZIP. \n");
+ (void) HDfprintf(stdout, "\t Will accept the following value\n");
+ (void) HDfprintf(stdout, "\t GZIP\n\n");
+ (void) HDfprintf(stdout, "\t COMPRESSION-PARAM:\n");
+ (void) HDfprintf(stdout,
+ "\t Integer used to denote compression level and \n");
+ (void) HDfprintf(stdout, "\t this option is to be always specified when \n");
+ (void) HDfprintf(stdout,
+ "\t the COMPRESSION-TYPE option is specified. The\n");
+ (void) HDfprintf(stdout, "\t values are applicable only to GZIP \n");
+ (void) HDfprintf(stdout, "\t compression.\n");
+ (void) HDfprintf(stdout, "\t Value 1-9: The level of Compression. \n");
+ (void) HDfprintf(stdout, "\t 1 will result in the fastest \n");
+ (void) HDfprintf(stdout, "\t compression while 9 will result in \n");
+ (void) HDfprintf(stdout, "\t the best compression ratio. The default\n");
+ (void) HDfprintf(stdout, "\t level of compression is 6.\n\n");
+ (void) HDfprintf(stdout, "\t EXTERNAL-STORAGE:\n");
+ (void) HDfprintf(stdout,
+ "\t String to denote the name of the non-HDF5 file \n");
+ (void) HDfprintf(stdout,
+ "\t to store data to. Cannot be used if CHUNKED-\n");
+ (void) HDfprintf(stdout,
+ "\t DIMENSIONS or COMPRESSION-TYPE or EXTENDIBLE-\n");
+ (void) HDfprintf(stdout, "\t DATASET is specified.\n");
+ (void) HDfprintf(stdout, "\t Value <external-filename>: the name of the \n");
+ (void) HDfprintf(stdout, "\t external file as a string to be used.\n\n");
+ (void) HDfprintf(stdout, "\t MAXIMUM-DIMENSIONS:\n");
+ (void) HDfprintf(stdout, "\t Integers separated by spaces to denote the \n");
+ (void) HDfprintf(stdout, "\t maximum dimension sizes of all the \n");
+ (void) HDfprintf(stdout, "\t dimensions determined by rank. Requires the\n");
+ (void) HDfprintf(stdout,
+ "\t CHUNKED-DIMENSION-SIZES to be specified. A value of \n");
+ (void) HDfprintf(stdout, "\t -1 for any dimension implies UNLIMITED \n");
+ (void) HDfprintf(stdout,
+ "\t DIMENSION size for that particular dimension.\n\n");
+ (void) HDfprintf(stdout, "\t EXAMPLES:\n");
+ (void) HDfprintf(stdout, "\t 1. Configuration File may look like:\n\n");
+ (void) HDfprintf(stdout, "\t PATH work h5 pkamat First-set\n");
+ (void) HDfprintf(stdout, "\t INPUT-CLASS TEXTFP\n");
+ (void) HDfprintf(stdout, "\t RANK 3\n");
+ (void) HDfprintf(stdout, "\t DIMENSION-SIZES 5 2 4\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-CLASS FP\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-SIZE 64\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-ARCHITECTURE IEEE\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-BYTE-ORDER LE\n");
+ (void) HDfprintf(stdout, "\t CHUNKED-DIMENSION-SIZES 2 2 2 \n\n");
+ (void) HDfprintf(stdout,
+ "\t The above configuration will accept a floating point array \n");
+ (void) HDfprintf(stdout,
+ "\t (5 x 2 x 4) in an ASCII file with the rank and dimension sizes \n");
+ (void) HDfprintf(stdout,
+ "\t specified and will save it in a chunked data-set (of pattern \n");
+ (void) HDfprintf(stdout,
+ "\t 2 X 2 X 2) of 64-bit floating point in the little-endian order \n");
+ (void) HDfprintf(stdout,
+ "\t and IEEE architecture. The dataset will be stored at\n");
+ (void) HDfprintf(stdout, "\t \"/work/h5/pkamat/First-set\"\n\n");
+ (void) HDfprintf(stdout, "\t 2. Another configuration could be:\n\n");
+ (void) HDfprintf(stdout, "\t PATH Second-set\n");
+ (void) HDfprintf(stdout, "\t INPUT-CLASS IN \n");
+ (void) HDfprintf(stdout, "\t RANK 5\n");
+ (void) HDfprintf(stdout, "\t DIMENSION-SIZES 6 3 5 2 4\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-CLASS IN\n");
+ (void) HDfprintf(stdout, "\t OUTPUT-SIZE 32\n");
+ (void) HDfprintf(stdout, "\t CHUNKED-DIMENSION-SIZES 2 2 2 2 2\n");
+ (void) HDfprintf(stdout, "\t EXTENDIBLE-DATASET 1 3 \n");
+ (void) HDfprintf(stdout, "\t COMPRESSION-TYPE GZIP\n");
+ (void) HDfprintf(stdout, "\t COMPRESSION-PARAM 7\n\n\n");
+ (void) HDfprintf(stdout,
+ "\t The above configuration will accept an integer array \n");
+ (void) HDfprintf(stdout,
+ "\t (6 X 3 X 5 x 2 x 4) in a binary file with the rank and \n");
+ (void) HDfprintf(stdout,
+ "\t dimension sizes specified and will save it in a chunked data-set\n");
+ (void) HDfprintf(stdout,
+ "\t (of pattern 2 X 2 X 2 X 2 X 2) of 32-bit floating point in \n");
+ (void) HDfprintf(stdout,
+ "\t native format (as output-architecture is not specified). The \n");
+ (void) HDfprintf(stdout,
+ "\t first and the third dimension will be defined as unlimited. The \n");
+ (void) HDfprintf(stdout,
+ "\t data-set will be compressed using GZIP and a compression level \n");
+ (void) HDfprintf(stdout, "\t of 7.\n");
+ (void) HDfprintf(stdout,
+ "\t The dataset will be stored at \"/Second-set\"\n\n");
+ return;
+}
+
+void usage(char *name)
+{
+ (void) HDfprintf(stdout, "\nUsage:\t%s -h[elp], OR\n", name);
+ (void) HDfprintf(stdout,
+ "\t%s <infile> -c[onfig] <configfile> \
+ [<infile> -c[config] <configfile>...] -o[utfile] <outfile> \n\n", name);
+ return;
+}
+
diff --git a/tools/src/h5import/h5import.h b/tools/src/h5import/h5import.h
new file mode 100644
index 0000000..c242483
--- /dev/null
+++ b/tools/src/h5import/h5import.h
@@ -0,0 +1,198 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ *
+ * Data and structure definitions for h5import
+ *
+ */
+
+#ifndef H5IMPORT_H__
+#define H5IMPORT_H__
+
+/*
+ * state table tokens
+ */
+#define FILNAME 0
+/* filename */
+#define OPT_o 1
+/* output filename */
+#define OPT_c 2 /* configuration filename */
+#define OPT_h 3 /* request for explanation */
+#define OPT_d 4 /* dimensions */
+#define OPT_p 5 /* pathname */
+#define OPT_t 6 /* data type */
+#define OPT_s 7 /* data size */
+#define ERR 20 /* invalid token */
+
+#define MAX_GROUPS_IN_PATH 20
+#define MAX_PATH_NAME_LENGTH 255
+#define NUM_KEYS 14
+#define MIN_NUM_DIMENSION 1
+#define MAX_NUM_DIMENSION 32
+#define BASE_10 10
+
+#define PATH 0
+#define INPUT_CLASS 1
+#define INPUT_SIZE 2
+#define RANK 3
+#define DIM 4
+#define OUTPUT_CLASS 5
+#define OUTPUT_SIZE 6
+#define OUTPUT_ARCH 7
+#define OUTPUT_B_ORDER 8
+#define CHUNK 9
+#define COMPRESS 10
+#define COMPRESS_PARAM 11
+#define EXTERNALSTORE 12
+#define EXTEND 13
+
+/* data types */
+#define H5DT_INT8 signed char
+#define H5DT_INT16 short
+#define H5DT_INT32 int
+#define H5DT_FLOAT32 float
+#define H5DT_FLOAT64 double
+#define VOIDP void*
+#define H5DT_UINT8 unsigned char
+#define H5DT_UINT16 unsigned short
+#define H5DT_UINT32 unsigned int
+#define H5DT_INT64 long long
+#define H5DT_UINT64 unsigned H5DT_INT64
+
+struct path_info
+{
+ char group[MAX_GROUPS_IN_PATH][MAX_PATH_NAME_LENGTH];
+ int count;
+};
+
+struct Input
+{
+ int h5dumpInput;
+ struct path_info path;
+ int inputClass;
+ int inputSize;
+ int rank;
+ hsize_t* sizeOfDimension;
+ int outputClass;
+ int outputSize;
+ int outputArchitecture;
+ int outputByteOrder;
+ hsize_t* sizeOfChunk;
+ hsize_t* maxsizeOfDimension;
+ int compressionType;
+ int compressionParam;
+ char *externFilename;
+ VOIDP data;
+ int configOptionVector[NUM_KEYS];
+};
+
+struct infilesformat
+{
+ char datafile[255];
+ char configfile[255];
+ struct Input in;
+ int config; /* Configfile present? No - 0. Yes - 1 */
+};
+
+struct Options
+{
+ struct infilesformat infiles[30]; /* structure to hold the list of input file names. Limited to 30*/
+ char outfile[256]; /* output file name */
+ int fcount; /* number of input files */
+};
+
+char keytable[NUM_KEYS][30] = {
+ "PATH",
+ "INPUT-CLASS",
+ "INPUT-SIZE",
+ "RANK",
+ "DIMENSION-SIZES",
+ "OUTPUT-CLASS",
+ "OUTPUT-SIZE",
+ "OUTPUT-ARCHITECTURE",
+ "OUTPUT-BYTE-ORDER",
+ "CHUNKED-DIMENSION-SIZES",
+ "COMPRESSION-TYPE",
+ "COMPRESSION-PARAM",
+ "EXTERNAL-STORAGE",
+ "MAXIMUM-DIMENSIONS"
+};
+
+static int state_table[15][8] =
+{
+ /* token ordering: FILNAME OPT_o OPT_c OPT_h OPT_d OPT_p OPT_t OPT_s */
+
+ /* state 0: start */
+ {1, ERR, ERR, 6, ERR, ERR, ERR, ERR},
+
+ /* state 1: input files */
+ {ERR, ERR, 2, ERR, 7, ERR, ERR, ERR},
+
+ /* state 2: -c[onfigfile] */
+ {3, ERR, ERR, ERR, ERR, ERR, ERR, ERR},
+
+ /* state 3: configfile */
+ {1, 4, ERR, ERR, ERR, ERR, ERR, ERR},
+
+ /* state 4: -o[utfile] */
+ {5, ERR, ERR, ERR, ERR, ERR, ERR, ERR},
+
+ /* state 5: outfile */
+ {ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR},
+
+ /* state 6: -h[elp] */
+ {ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR},
+
+ /* state 7: -d[ims] */
+ {8, ERR, ERR, ERR, ERR, ERR, ERR, ERR},
+
+ /* state 8: dimensions */
+ {1, 4, ERR, ERR, ERR, 9, 11, 13},
+
+ /* state 9: -p[ath] */
+ {10, ERR, ERR, ERR, ERR, ERR, ERR, ERR},
+
+ /* state 10: path name */
+ {1, 4, ERR, ERR, ERR, ERR, 11, 13},
+
+ /* state 11: -t[ype] */
+ {12, ERR, ERR, ERR, ERR, ERR, ERR, ERR},
+
+ /* state 12: data type */
+ {1, 4, ERR, ERR, ERR, ERR, ERR, 13},
+
+ /* state 13: -s[ize] */
+ {14, ERR, ERR, ERR, ERR, ERR, ERR, ERR},
+
+ /* state 14: data size */
+ {1, 4, ERR, ERR, ERR, ERR, ERR, ERR}
+
+};
+
+/*
+ *
+ * Function declarations for h5import
+ *
+ */
+void usage(char *);
+void setDefaultValues(struct Input *in, int count);
+void help(char *);
+
+hid_t createOutputDataType(struct Input *in);
+hid_t createInputDataType(struct Input *in);
+
+#endif /* H5IMPORT_H__ */
+
diff --git a/tools/src/h5jam/CMakeLists.txt b/tools/src/h5jam/CMakeLists.txt
new file mode 100644
index 0000000..cef54c2
--- /dev/null
+++ b/tools/src/h5jam/CMakeLists.txt
@@ -0,0 +1,49 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_H5JAM)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+
+# --------------------------------------------------------------------
+# Add the h5jam executables
+# --------------------------------------------------------------------
+add_executable (h5jam ${HDF5_TOOLS_SRC_H5JAM_SOURCE_DIR}/h5jam.c)
+TARGET_NAMING (h5jam STATIC)
+TARGET_C_PROPERTIES (h5jam STATIC " " " ")
+target_link_libraries (h5jam ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5jam PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5jam")
+
+add_executable (h5unjam ${HDF5_TOOLS_SRC_H5JAM_SOURCE_DIR}/h5unjam.c)
+TARGET_NAMING (h5unjam STATIC)
+TARGET_C_PROPERTIES (h5unjam STATIC " " " ")
+target_link_libraries (h5unjam ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5unjam PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5unjam")
+
+set (H5_DEP_EXECUTABLES
+ h5jam
+ h5unjam
+)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5jam ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5jam h5unjam
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
diff --git a/tools/src/h5jam/Makefile.am b/tools/src/h5jam/Makefile.am
new file mode 100644
index 0000000..e244625
--- /dev/null
+++ b/tools/src/h5jam/Makefile.am
@@ -0,0 +1,35 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src and tools/lib directories
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+bin_PROGRAMS=h5jam h5unjam
+
+# Add h5jam and h5unjam specific linker flags here
+h5jam_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+h5unjam_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# Link against the main HDF5 library and tools library
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/h5jam/h5jam.c b/tools/src/h5jam/h5jam.c
new file mode 100644
index 0000000..ae45714
--- /dev/null
+++ b/tools/src/h5jam/h5jam.c
@@ -0,0 +1,571 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "hdf5.h"
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5jam"
+
+herr_t write_pad(int ofile, hsize_t old_where, hsize_t *new_where);
+hsize_t compute_user_block_size (hsize_t);
+hsize_t copy_some_to_file (int, int, hsize_t, hsize_t, ssize_t);
+void parse_command_line (int, const char *[]);
+
+int do_clobber = FALSE;
+char *output_file = NULL;
+char *input_file = NULL;
+char *ub_file = NULL;
+
+/*
+ * Command-line options: The user can specify short or long-named
+ * parameters. The long-named ones can be partially spelled. When
+ * adding more, make sure that they don't clash with each other.
+ */
+static const char *s_opts = "hi:u:o:c:V"; /* add more later ? */
+static struct long_options l_opts[] = {
+ {"help", no_arg, 'h'},
+ {"hel", no_arg, 'h'},
+ {"i", require_arg, 'i'}, /* input file */
+ {"u", require_arg, 'u'}, /* user block file */
+ {"o", require_arg, 'o'}, /* output file */
+ {"clobber", no_arg, 'c'}, /* clobber existing UB */
+ {"clobbe", no_arg, 'c'},
+ {"clobb", no_arg, 'c'},
+ {"clob", no_arg, 'c'},
+ {"clo", no_arg, 'c'},
+ {"cl", no_arg, 'c'},
+ {NULL, 0, '\0'}
+};
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Print the usage message
+ *
+ * Return: void
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage (const char *prog)
+{
+ HDfflush (stdout);
+ HDfprintf (stdout,
+ "usage: %s -i <in_file.h5> -u <in_user_file> [-o <out_file.h5>] [--clobber]\n", prog);
+ HDfprintf (stdout, "\n");
+ HDfprintf (stdout,
+ "Adds user block to front of an HDF5 file and creates a new concatenated file.\n");
+ HDfprintf (stdout, "\n");
+ HDfprintf (stdout,
+ "OPTIONS\n");
+ HDfprintf (stdout,
+ " -i in_file.h5 Specifies the input HDF5 file.\n");
+ HDfprintf (stdout,
+ " -u in_user_file Specifies the file to be inserted into the user block.\n");
+ HDfprintf (stdout,
+ " Can be any file format except an HDF5 format.\n");
+ HDfprintf (stdout,
+ " -o out_file.h5 Specifies the output HDF5 file.\n");
+ HDfprintf (stdout,
+ " If not specified, the user block will be concatenated in\n");
+ HDfprintf (stdout,
+ " place to the input HDF5 file.\n");
+ HDfprintf (stdout,
+ " --clobber Wipes out any existing user block before concatenating\n");
+ HDfprintf (stdout,
+ " the given user block.\n");
+ HDfprintf (stdout,
+ " The size of the new user block will be the larger of;\n");
+ HDfprintf (stdout,
+ " - the size of existing user block in the input HDF5 file\n");
+ HDfprintf (stdout,
+ " - the size of user block required by new input user file\n");
+ HDfprintf (stdout,
+ " (size = 512 x 2N, N is positive integer.)\n");
+ HDfprintf (stdout, "\n");
+ HDfprintf (stdout,
+ " -h Prints a usage message and exits.\n");
+ HDfprintf (stdout,
+ " -V Prints the HDF5 library version and exits.\n");
+ HDfprintf (stdout, "\n");
+ HDfprintf (stdout,
+ "Exit Status:\n");
+ HDfprintf (stdout,
+ " 0 Succeeded.\n");
+ HDfprintf (stdout,
+ " >0 An error occurred.\n");
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: leave
+ *
+ * Purpose: Shutdown and call exit()
+ *
+ * Return: Does not return
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+leave(int ret)
+{
+ if (ub_file)
+ HDfree (ub_file);
+ if (input_file)
+ HDfree (input_file);
+ if (output_file)
+ HDfree (output_file);
+
+ h5tools_close();
+
+ HDexit(ret);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parse the command line for the h5dumper.
+ *
+ * Return: Success:
+ *
+ * Failure: Exits program with EXIT_FAILURE value.
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+parse_command_line (int argc, const char *argv[])
+{
+ int opt = FALSE;
+
+ /* parse command line options */
+ while ((opt = get_option (argc, argv, s_opts, l_opts)) != EOF)
+ {
+ switch ((char) opt)
+ {
+ case 'o':
+ output_file = HDstrdup (opt_arg);
+ break;
+ case 'i':
+ input_file = HDstrdup (opt_arg);
+ break;
+ case 'u':
+ ub_file = HDstrdup (opt_arg);
+ break;
+ case 'c':
+ do_clobber = TRUE;
+ break;
+ case 'h':
+ usage (h5tools_getprogname());
+ leave (EXIT_SUCCESS);
+ case 'V':
+ print_version (h5tools_getprogname());
+ leave (EXIT_SUCCESS);
+ case '?':
+ default:
+ usage (h5tools_getprogname());
+ leave (EXIT_FAILURE);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: HDF5 user block jammer
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main (int argc, const char *argv[])
+{
+ int ufid = -1;
+ int h5fid = -1;
+ int ofid = -1;
+ void *edata;
+ H5E_auto2_t func;
+ hid_t ifile = -1;
+ hid_t plist = -1;
+ herr_t status;
+ htri_t testval;
+ hsize_t usize;
+ hsize_t h5fsize;
+ hsize_t startub;
+ hsize_t where;
+ hsize_t newubsize;
+ off_t fsize;
+ h5_stat_t sbuf;
+ h5_stat_t sbuf2;
+ int res;
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Disable error reporting */
+ H5Eget_auto2(H5E_DEFAULT, &func, &edata);
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ parse_command_line (argc, argv);
+
+ if (ub_file == NULL) {
+ /* no user block */
+ error_msg("missing arguemnt for -u <user_file>.\n");
+ help_ref_msg(stderr);
+ leave (EXIT_FAILURE);
+ }
+
+ testval = H5Fis_hdf5 (ub_file);
+
+ if (testval > 0) {
+ error_msg("-u <user_file> cannot be HDF5 file, but it appears to be an HDF5 file.\n");
+ help_ref_msg(stderr);
+ leave (EXIT_FAILURE);
+ }
+
+ if (input_file == NULL) {
+ error_msg("missing arguemnt for -i <HDF5 file>.\n");
+ help_ref_msg(stderr);
+ leave (EXIT_FAILURE);
+ }
+
+ testval = H5Fis_hdf5 (input_file);
+
+ if (testval <= 0) {
+ error_msg("Input HDF5 file \"%s\" is not HDF5 format.\n", input_file);
+ help_ref_msg(stderr);
+ leave (EXIT_FAILURE);
+ }
+
+ ifile = H5Fopen (input_file, H5F_ACC_RDONLY, H5P_DEFAULT);
+
+ if (ifile < 0) {
+ error_msg("Can't open input HDF5 file \"%s\"\n", input_file);
+ leave (EXIT_FAILURE);
+ }
+
+ plist = H5Fget_create_plist (ifile);
+ if (plist < 0) {
+ error_msg("Can't get file creation plist for file \"%s\"\n", input_file);
+ H5Fclose(ifile);
+ leave (EXIT_FAILURE);
+ }
+
+ status = H5Pget_userblock (plist, &usize);
+ if (status < 0) {
+ error_msg("Can't get user block for file \"%s\"\n", input_file);
+ H5Pclose(plist);
+ H5Fclose(ifile);
+ leave (EXIT_FAILURE);
+ }
+
+ H5Pclose(plist);
+ H5Fclose(ifile);
+
+ ufid = HDopen(ub_file, O_RDONLY, 0);
+ if(ufid < 0) {
+ error_msg("unable to open user block file \"%s\"\n", ub_file);
+ leave (EXIT_FAILURE);
+ }
+
+ res = HDfstat(ufid, &sbuf);
+ if(res < 0) {
+ error_msg("Can't stat file \"%s\"\n", ub_file);
+ HDclose (ufid);
+ leave (EXIT_FAILURE);
+ }
+
+ fsize = (off_t)sbuf.st_size;
+
+ h5fid = HDopen(input_file, O_RDONLY, 0);
+ if(h5fid < 0) {
+ error_msg("unable to open HDF5 file for read \"%s\"\n", input_file);
+ HDclose (ufid);
+ leave (EXIT_FAILURE);
+ }
+
+ res = HDfstat(h5fid, &sbuf2);
+ if(res < 0) {
+ error_msg("Can't stat file \"%s\"\n", input_file);
+ HDclose (h5fid);
+ HDclose (ufid);
+ leave (EXIT_FAILURE);
+ }
+
+ h5fsize = (hsize_t)sbuf2.st_size;
+
+ if (output_file == NULL) {
+ ofid = HDopen (input_file, O_WRONLY, 0);
+
+ if (ofid < 0) {
+ error_msg("unable to open output file \"%s\"\n", output_file);
+ HDclose (h5fid);
+ HDclose (ufid);
+ leave (EXIT_FAILURE);
+ }
+ }
+ else {
+ ofid = HDopen (output_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+ if (ofid < 0) {
+ error_msg("unable to create output file \"%s\"\n", output_file);
+ HDclose (h5fid);
+ HDclose (ufid);
+ leave (EXIT_FAILURE);
+ }
+ }
+
+ newubsize = compute_user_block_size ((hsize_t) fsize);
+
+ startub = usize;
+
+ if (usize > 0) {
+ if (do_clobber == TRUE) {
+ /* where is max of the current size or the new UB */
+ if (usize > newubsize) {
+ newubsize = usize;
+ }
+ startub = 0; /*blast the old */
+ }
+ else {
+ /* add new ub to current ublock, pad to new offset */
+ newubsize += usize;
+ newubsize = compute_user_block_size ((hsize_t) newubsize);
+ }
+ }
+
+ /* copy the HDF5 from starting at usize to starting at newubsize:
+ * makes room at 'from' for new ub */
+ /* if no current ub, usize is 0 */
+ copy_some_to_file (h5fid, ofid, usize, newubsize, (ssize_t) (h5fsize - usize));
+
+ /* copy the old ub to the beginning of the new file */
+ if (!do_clobber) {
+ where = copy_some_to_file (h5fid, ofid, (hsize_t) 0, (hsize_t) 0, (ssize_t) usize);
+ }
+
+ /* copy the new ub to the end of the ub */
+ where = copy_some_to_file (ufid, ofid, (hsize_t) 0, startub, (ssize_t) - 1);
+
+ /* pad the ub */
+ if(write_pad(ofid, where, &where) < 0) {
+ error_msg("Can't pad file \"%s\"\n", output_file);
+ HDclose (h5fid);
+ HDclose (ufid);
+ HDclose (ofid);
+ leave (EXIT_FAILURE);
+ } /* end if */
+
+ if(ub_file)
+ HDfree (ub_file);
+ if(input_file)
+ HDfree (input_file);
+ if(output_file)
+ HDfree (output_file);
+
+ if(ufid >= 0)
+ HDclose (ufid);
+ if(h5fid >= 0)
+ HDclose (h5fid);
+ if(ofid >= 0)
+ HDclose (ofid);
+
+ return h5tools_getstatus();
+}
+
+/*-------------------------------------------------------------------------
+ * Function: copy_some_to_file
+ *
+ * Purpose: Copy part of the input file to output.
+ * infid: fd of file to read
+ * outfid: fd of file to write
+ * startin: offset of where to read from infid
+ * startout: offset of where to write to outfid
+ * limit: bytes to read/write
+ *
+ * If limit is < 0, the entire input file is copied.
+ *
+ * Note: this routine can be used to copy within
+ * the same file, i.e., infid and outfid can be the
+ * same file.
+ *
+ * Return: Success: last byte written in the output.
+ * Failure: Exits program with EXIT_FAILURE value.
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+copy_some_to_file(int infid, int outfid, hsize_t startin, hsize_t startout,
+ ssize_t limit)
+{
+ char buf[1024];
+ h5_stat_t sbuf;
+ int res;
+ ssize_t tot = 0;
+ ssize_t howmuch = 0;
+ ssize_t nchars = -1;
+ ssize_t to;
+ ssize_t from;
+ ssize_t toend;
+ ssize_t fromend;
+
+ if(startin > startout) {
+ /* this case is prohibited */
+ error_msg("copy_some_to_file: panic: startin > startout?\n");
+ exit (EXIT_FAILURE);
+ } /* end if */
+
+ if(limit < 0) {
+ res = HDfstat(infid, &sbuf);
+ if(res < 0) {
+ error_msg("Can't stat file \n");
+ HDexit(EXIT_FAILURE);
+ } /* end if */
+
+ howmuch = (ssize_t)sbuf.st_size;
+ } else {
+ howmuch = limit;
+ } /* end if */
+
+ if(0 == howmuch)
+ return 0;
+
+ toend = (ssize_t) startout + howmuch;
+ fromend = (ssize_t) startin + howmuch;
+
+ if (howmuch > 512) {
+ to = toend - 512;
+ from = fromend - 512;
+ } else {
+ to = toend - howmuch;
+ from = fromend - howmuch;
+ } /* end if */
+
+ while (howmuch > 0) {
+ HDlseek(outfid, (off_t) to, SEEK_SET);
+ HDlseek(infid, (off_t) from, SEEK_SET);
+
+ if (howmuch > 512) {
+ nchars = HDread(infid, buf, (unsigned) 512);
+ } else {
+ nchars = HDread(infid, buf, (unsigned)howmuch);
+ } /* end if */
+
+ if (nchars <= 0) {
+ error_msg("Read error \n");
+ HDexit(EXIT_FAILURE);
+ } /* end if */
+
+ if(HDwrite (outfid, buf, (unsigned) nchars) < 0) {
+ error_msg("Write error \n");
+ HDexit(EXIT_FAILURE);
+ }
+
+ tot += nchars;
+ howmuch -= nchars;
+ if(howmuch > 512) {
+ to -= nchars;
+ from -= nchars;
+ } else {
+ to -= howmuch;
+ from -= howmuch;
+ } /* end if */
+ } /* end while */
+
+ return (hsize_t)tot + (hsize_t)startout;
+} /* end copy_some_to_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: compute_user_block_size
+ *
+ * Purpose: Find the offset of the HDF5 header after the user block:
+ * align at 0, 512, 1024, etc.
+ * ublock_size: the size of the user block (bytes).
+ *
+ * Return: Success: the location of the header == the size of the
+ * padded user block.
+ * Failure: none
+ *
+ * Return: Success: last byte written in the output.
+ * Failure: Exits program with EXIT_FAILURE value.
+ *-------------------------------------------------------------------------
+ */
+H5_ATTR_CONST hsize_t
+compute_user_block_size(hsize_t ublock_size)
+{
+ hsize_t where = 512;
+
+ if(0 == ublock_size)
+ return 0;
+
+ while(where < ublock_size)
+ where *= 2;
+
+ return where;
+} /* end compute_user_block_size() */
+
+/*
+ * Write zeroes to fill the file from 'where' to 512, 1024, etc. bytes.
+ *
+ * Sets new_where to the size of the padded file and
+ * returns SUCCEED/FAIL.
+ */
+herr_t
+write_pad(int ofile, hsize_t old_where, hsize_t *new_where)
+{
+ unsigned int i;
+ char buf[1];
+ hsize_t psize;
+
+ HDassert(new_where);
+
+ buf[0] = '\0';
+
+ HDlseek(ofile, (off_t)old_where, SEEK_SET);
+
+ psize = compute_user_block_size(old_where);
+ psize -= old_where;
+
+ for(i = 0; i < psize; i++)
+ if(HDwrite(ofile, buf, 1) < 0)
+ return FAIL;
+
+ /* Set the new size of the file. */
+ *new_where = old_where + psize;
+
+ return SUCCEED;
+} /* end write_pad() */
+
diff --git a/tools/src/h5jam/h5unjam.c b/tools/src/h5jam/h5unjam.c
new file mode 100644
index 0000000..8f88398
--- /dev/null
+++ b/tools/src/h5jam/h5unjam.c
@@ -0,0 +1,411 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "hdf5.h"
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5unjam"
+
+#define COPY_BUF_SIZE 1024
+
+hsize_t write_pad( int , hsize_t );
+hsize_t compute_pad( hsize_t );
+herr_t copy_to_file( FILE *, FILE * , ssize_t, ssize_t );
+
+int do_delete = FALSE;
+char *output_file = NULL;
+char *input_file = NULL;
+char *ub_file = NULL;
+
+/*
+ * Command-line options: The user can specify short or long-named
+ * parameters. The long-named ones can be partially spelled. When
+ * adding more, make sure that they don't clash with each other.
+ */
+static const char *s_opts = "hu:i:o:d:V";
+static struct long_options l_opts[] = {
+ { "help", no_arg, 'h' },
+ { "hel", no_arg, 'h' },
+ {"i", require_arg, 'i'}, /* input file */
+ {"u", require_arg, 'u'}, /* user block file */
+ {"o", require_arg, 'o'}, /* output file */
+ {"delete", no_arg, 'd'}, /* delete ub */
+ {"delet", no_arg, 'd'},
+ {"dele", no_arg, 'd'},
+ {"del", no_arg, 'd'},
+ {"de", no_arg, 'd'},
+ { NULL, 0, '\0' }
+};
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Print the usage message
+ *
+ * Return: void
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage(const char *prog)
+{
+ HDfflush(stdout);
+ HDfprintf(stdout,
+ "usage: %s -i <in_file.h5> [-o <out_file.h5> ] [-u <out_user_file> | --delete]\n", prog);
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout,
+ "Splits user file and HDF5 file into two files: user block data and HDF5 data.\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout,
+ "OPTIONS\n");
+ HDfprintf(stdout,
+ " -i in_file.h5 Specifies the HDF5 as input. If the input HDF5 file\n");
+ HDfprintf(stdout,
+ " contains no user block, exit with an error message.\n");
+ HDfprintf(stdout,
+ " -o out_file.h5 Specifies output HDF5 file without a user block.\n");
+ HDfprintf(stdout,
+ " If not specified, the user block will be removed from the\n");
+ HDfprintf(stdout,
+ " input HDF5 file.\n");
+ HDfprintf(stdout,
+ " -u out_user_file\n");
+ HDfprintf(stdout,
+ " Specifies the output file containing the data from the\n");
+ HDfprintf(stdout,
+ " user block.\n");
+ HDfprintf(stdout,
+ " Cannot be used with --delete option.\n");
+ HDfprintf(stdout,
+ " --delete Remove the user block from the input HDF5 file. The content\n");
+ HDfprintf(stdout,
+ " of the user block is discarded.\n");
+ HDfprintf(stdout,
+ " Cannot be used with the -u option.\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout,
+ " -h Prints a usage message and exits.\n");
+ HDfprintf(stdout,
+ " -V Prints the HDF5 library version and exits.\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout,
+ " If neither --delete nor -u is specified, the user block from the input file\n");
+ HDfprintf(stdout,
+ " will be displayed to stdout.\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout,
+ "Exit Status:\n");
+ HDfprintf(stdout,
+ " 0 Succeeded.\n");
+ HDfprintf(stdout,
+ " >0 An error occurred.\n");
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parse the command line for the h5dumper.
+ *
+ * Return: Success: EXIT_SUCCESS;
+ *
+ * Failure: Exits function with EXIT_FAILURE value.
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+parse_command_line(int argc, const char *argv[])
+{
+ int opt = FALSE;
+
+ /* parse command line options */
+ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
+ switch((char)opt) {
+ case 'o':
+ output_file = HDstrdup(opt_arg);
+ if (output_file)
+ h5tools_set_data_output_file(output_file, 1);
+ break;
+
+ case 'i':
+ input_file = HDstrdup(opt_arg);
+ if (input_file)
+ h5tools_set_input_file(input_file, 1);
+ break;;
+
+ case 'u':
+ ub_file = HDstrdup(opt_arg);
+ if (ub_file)
+ h5tools_set_output_file(ub_file, 1);
+ else
+ rawoutstream = stdout;
+ break;
+
+ case 'd':
+ do_delete = TRUE;
+ break;
+
+ case 'h':
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+
+ case 'V':
+ print_version (h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+
+ case '?':
+ default:
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ }
+
+ return EXIT_SUCCESS;
+
+done:
+ if(input_file)
+ HDfree(input_file);
+ if(output_file)
+ HDfree(output_file);
+ if(ub_file)
+ HDfree(ub_file);
+
+ return EXIT_FAILURE;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: HDF5 user block unjammer
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, const char *argv[])
+{
+ void *edata;
+ H5E_auto2_t func;
+ hid_t ifile = -1;
+ hid_t plist = -1;
+ off_t fsize;
+ hsize_t usize;
+ htri_t testval;
+ herr_t status;
+ int res;
+ h5_stat_t sbuf;
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Disable error reporting */
+ H5Eget_auto2(H5E_DEFAULT, &func, &edata);
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ if(EXIT_FAILURE == parse_command_line(argc, argv))
+ goto done;
+
+ if (input_file == NULL) {
+ /* no user block */
+ error_msg("missing arguemnt for HDF5 file input.\n");
+ help_ref_msg(stderr);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ testval = H5Fis_hdf5(input_file);
+
+ if (testval <= 0) {
+ error_msg("Input HDF5 file \"%s\" is not HDF\n", input_file);
+ help_ref_msg (stderr);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ ifile = H5Fopen(input_file, H5F_ACC_RDONLY , H5P_DEFAULT);
+
+ if (ifile < 0) {
+ error_msg("Can't open input HDF5 file \"%s\"\n", input_file);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ plist = H5Fget_create_plist(ifile);
+ if (plist < 0) {
+ error_msg("Can't get file creation plist for file \"%s\"\n", input_file);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ status = H5Pget_userblock(plist, & usize);
+ if (status < 0) {
+ error_msg("Can't get user block for file \"%s\"\n", input_file);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ status = H5Pclose(plist);
+ HDassert(status >= 0);
+ status = H5Fclose(ifile);
+ HDassert(status >= 0);
+
+ if (usize == 0) {
+ /* no user block to remove: message? */
+ error_msg("\"%s\" has no user block: no change to file\n", input_file);
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+ }
+
+ res = HDfstat(HDfileno(rawinstream), &sbuf);
+ if(res < 0) {
+ error_msg("Can't stat file \"%s\"\n", input_file);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ fsize = sbuf.st_size;
+
+ if (do_delete && (ub_file != NULL)) {
+ error_msg("??\"%s\"\n", ub_file);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ if (output_file == NULL) {
+ error_msg("unable to open output HDF5 file \"%s\"\n", input_file);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ /* copy from 0 to 'usize - 1' into ufid */
+ if (!do_delete) {
+ if(copy_to_file(rawinstream, rawoutstream, 0, (ssize_t) usize) < 0) {
+ error_msg("unable to copy user block to output file \"%s\"\n", ub_file);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ }
+
+ /* copy from usize to end of file into h5fid,
+ * starting at end of user block if present */
+ if(copy_to_file(rawinstream, rawdatastream, (ssize_t) usize, (ssize_t)(fsize - (ssize_t)usize)) < 0) {
+ error_msg("unable to copy hdf5 data to output file \"%s\"\n", output_file);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+done:
+ if(input_file)
+ HDfree(input_file);
+
+ if(output_file)
+ HDfree(output_file);
+
+ if(ub_file) {
+ HDfree(ub_file);
+ }
+
+ h5tools_close();
+
+ return h5tools_getstatus();
+}
+
+/*
+ * Copy 'how_much' bytes from the input file to the output file,
+ * starting at byte 'where' in the input file.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+herr_t
+copy_to_file( FILE *infid, FILE *ofid, ssize_t _where, ssize_t show_much )
+{
+ static char buf[COPY_BUF_SIZE];
+ size_t how_much;
+ off_t where = (off_t)_where;
+ off_t to;
+ off_t from;
+ herr_t ret_value = 0;
+
+ /* nothing to copy */
+ if(show_much <= 0)
+ goto done;
+ how_much = (size_t)show_much;
+
+ /* rewind */
+ HDfseek(infid, 0L, 0);
+
+ from = where;
+ to = 0;
+ while(how_much > 0) {
+ size_t bytes_in = 0; /* # of bytes to read */
+ size_t bytes_read = 0; /* # of bytes actually read */
+ size_t bytes_wrote = 0; /* # of bytes written */
+
+ if (how_much > COPY_BUF_SIZE)
+ bytes_in = COPY_BUF_SIZE;
+ else
+ bytes_in = how_much;
+
+ /* Seek to correct position in input file */
+ HDfseek(infid, from, SEEK_SET);
+
+ /* Read data to buffer */
+ bytes_read = HDfread(buf, (size_t)1, bytes_in, infid);
+ if(0 == bytes_read && HDferror(infid)) {
+ ret_value = -1;
+ goto done;
+ } /* end if */
+ if(0 == bytes_read && HDfeof(infid)) {
+ goto done;
+ } /* end if */
+
+ /* Seek to correct position in output file */
+ HDfseek(ofid, to, SEEK_SET);
+
+ /* Update positions/size */
+ how_much -= bytes_read;
+ from += (off_t)bytes_read;
+ to += (off_t)bytes_read;
+
+ /* Write nchars bytes to output file */
+ bytes_wrote = HDfwrite(buf, (size_t)1, bytes_read, ofid);
+ if(bytes_wrote != bytes_read || (0 == bytes_wrote && HDferror(ofid))) { /* error */
+ ret_value = -1;
+ goto done;
+ } /* end if */
+ } /* end while */
+
+done:
+ return ret_value;
+} /* end copy_to_file */
+
diff --git a/tools/src/h5ls/CMakeLists.txt b/tools/src/h5ls/CMakeLists.txt
new file mode 100644
index 0000000..24e11cc
--- /dev/null
+++ b/tools/src/h5ls/CMakeLists.txt
@@ -0,0 +1,41 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_H5LS)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+
+#-----------------------------------------------------------------------------
+# Add the h5ls executable
+#-----------------------------------------------------------------------------
+add_executable (h5ls ${HDF5_TOOLS_SRC_H5LS_SOURCE_DIR}/h5ls.c)
+TARGET_NAMING (h5ls STATIC)
+TARGET_C_PROPERTIES (h5ls STATIC " " " ")
+target_link_libraries (h5ls ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5ls PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5ls")
+
+set (H5_DEP_EXECUTABLES
+ h5ls
+)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5ls ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5ls
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
diff --git a/tools/src/h5ls/Makefile.am b/tools/src/h5ls/Makefile.am
new file mode 100644
index 0000000..dfa8bb6
--- /dev/null
+++ b/tools/src/h5ls/Makefile.am
@@ -0,0 +1,35 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src and tools/lib directories
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+# This is our main target, the h5ls tool
+bin_PROGRAMS=h5ls
+
+# Add h5ls specific linker flags here
+h5ls_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# All programs depend on the hdf5 and h5tools libraries
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/h5ls/h5ls.c b/tools/src/h5ls/h5ls.c
new file mode 100644
index 0000000..a032f08
--- /dev/null
+++ b/tools/src/h5ls/h5ls.c
@@ -0,0 +1,2939 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Monday, March 23, 1998
+ */
+
+
+/*
+ * We include the private header file so we can get to the uniform
+ * programming environment it declares. Other than that, h5ls only calls
+ * HDF5 API functions (except for H5G_basename())
+ */
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+#include "h5tools_dump.h"
+#include "h5trav.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5ls"
+
+#define NAME_BUF_SIZE 2048
+/*
+ * Alternative formating for data dumped by H5LS
+ *
+ * This table only affects H5LS output.
+ */
+static h5tool_format_t ls_dataformat = {
+ 0, /*raw */
+
+ "", /*fmt_raw */
+ "%d", /*fmt_int */
+ "%u", /*fmt_uint */
+ "%hhd", /*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 */
+ ",", /*cmpd_sep */
+ "{", /*cmpd_pre */
+ "}", /*cmpd_suf */
+ "", /*cmpd_end */
+
+ ",", /*vlen_sep */
+ "(", /*vlen_pre */
+ ")", /*vlen_suf */
+ "", /*vlen_end */
+
+ "%s", /*elmt_fmt */
+ ",", /*elmt_suf1 */
+ " ", /*elmt_suf2 */
+
+ HSIZE_T_FORMAT, /*idx_n_fmt */
+ ",", /*idx_sep */
+ "(%s)", /*idx_fmt */
+
+ 65535, /*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 */
+
+ 0, /*skip_first */
+
+ 0, /*obj_hidefileno */
+ "-%lu:"H5_PRINTF_HADDR_FMT, /*obj_format */
+
+ 0, /*dset_hidefileno */
+ "DSET-%s ", /*dset_format */
+ "%sBlk%lu: ", /*dset_blockformat_pre */
+ "%sPt%lu: ", /*dset_ptformat_pre */
+ "%s", /*dset_ptformat */
+ 1, /*array indices */
+ 1 /*escape non printable characters */
+};
+
+/* Struct to pass through to visitors */
+typedef struct {
+ const char *fname; /* Filename */
+ hid_t fid; /* File ID */
+ hid_t gid; /* Group ID */
+ hbool_t symlink_target; /* Whether this is the target of an symbolic link */
+ symlink_trav_t *symlink_list; /* List of visited symbolic links */
+ size_t base_len; /* Length of base path name, if not root */
+ size_t name_start; /* # of leading characters to strip off path names on output */
+}iter_t;
+
+/* Command-line switches */
+static int verbose_g = 0; /* lots of extra output */
+static int width_g = 80; /* output width in characters */
+static hbool_t address_g = FALSE; /* print raw data addresses */
+static hbool_t data_g = FALSE; /* display dataset values? */
+static hbool_t label_g = FALSE; /* label compound values? */
+static hbool_t string_g = FALSE; /* print 1-byte numbers as ASCII? */
+static hbool_t fullname_g = FALSE; /* print full path names */
+static hbool_t recursive_g = FALSE; /* recursive descent listing */
+static hbool_t follow_symlink_g = FALSE; /* follow symbolic links */
+static hbool_t no_dangling_link_g = FALSE; /* treat dangling link is error */
+static hbool_t follow_elink_g = FALSE; /* follow external links */
+static hbool_t grp_literal_g = FALSE; /* list group, not contents */
+static hbool_t hexdump_g = FALSE; /* show data as raw hexadecimal */
+static hbool_t show_errors_g = FALSE; /* print HDF5 error messages */
+static hbool_t simple_output_g = FALSE; /* make output more machine-readable */
+static hbool_t show_file_name_g = FALSE; /* show file name for full names */
+static hbool_t no_line_wrap_g = FALSE; /* show data content without line wrap */
+static hbool_t display_root_g = FALSE; /* show root group in output? */
+
+/* Information about how to display each type of object */
+static struct dispatch_t {
+ const char *name;
+ hid_t (*open)(hid_t loc, const char *name, hid_t apl_id);
+ herr_t (*close)(hid_t obj);
+ herr_t (*list1)(hid_t obj);
+ herr_t (*list2)(hid_t obj, const char *name);
+} dispatch_g[H5O_TYPE_NTYPES];
+
+#define DISPATCH(TYPE, NAME, LIST1, LIST2) { \
+ dispatch_g[TYPE].name = (NAME); \
+ dispatch_g[TYPE].list1 = (LIST1); \
+ dispatch_g[TYPE].list2 = (LIST2); \
+}
+
+static void print_type(h5tools_str_t *buffer, hid_t type, int ind);
+static hbool_t print_int_type(h5tools_str_t *buffer, hid_t type, int ind);
+static hbool_t print_float_type(h5tools_str_t *buffer, hid_t type, int ind);
+static herr_t visit_obj(hid_t file, const char *oname, iter_t *iter);
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Prints a usage message on stderr and then returns.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Thursday, July 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage (void)
+{
+ FLUSHSTREAM(rawoutstream);
+ PRINTVALSTREAM(rawoutstream, "usage: h5ls [OPTIONS] file[/OBJECT] [file[/[OBJECT]...]\n");
+ PRINTVALSTREAM(rawoutstream, " OPTIONS\n");
+ PRINTVALSTREAM(rawoutstream, " -h, -?, --help Print a usage message and exit\n");
+ PRINTVALSTREAM(rawoutstream, " -a, --address Print raw data address. If dataset is contiguous, address\n");
+ PRINTVALSTREAM(rawoutstream, " is offset in file of beginning of raw data. If chunked,\n");
+ PRINTVALSTREAM(rawoutstream, " returned list of addresses indicates offset of each chunk.\n");
+ PRINTVALSTREAM(rawoutstream, " Must be used with -v, --verbose option.\n");
+ PRINTVALSTREAM(rawoutstream, " Provides no information for non-dataset objects.\n");
+ PRINTVALSTREAM(rawoutstream, " -d, --data Print the values of datasets\n");
+ PRINTVALSTREAM(rawoutstream, " --enable-error-stack\n");
+ PRINTVALSTREAM(rawoutstream, " Prints messages from the HDF5 error stack as they occur.\n");
+ PRINTVALSTREAM(rawoutstream, " --follow-symlinks\n");
+ PRINTVALSTREAM(rawoutstream, " Follow symbolic links (soft links and external links)\n");
+ PRINTVALSTREAM(rawoutstream, " to display target object information.\n");
+ PRINTVALSTREAM(rawoutstream, " Without this option, h5ls identifies a symbolic link\n");
+ PRINTVALSTREAM(rawoutstream, " as a soft link or external link and prints the value\n");
+ PRINTVALSTREAM(rawoutstream, " assigned to the symbolic link; it does not provide any\n");
+ PRINTVALSTREAM(rawoutstream, " information regarding the target object or determine\n");
+ PRINTVALSTREAM(rawoutstream, " whether the link is a dangling link.\n");
+ PRINTVALSTREAM(rawoutstream, " --no-dangling-links\n");
+ PRINTVALSTREAM(rawoutstream, " Must be used with --follow-symlinks option;\n");
+ PRINTVALSTREAM(rawoutstream, " otherwise, h5ls shows error message and returns an exit\n");
+ PRINTVALSTREAM(rawoutstream, " code of 1. \n");
+ PRINTVALSTREAM(rawoutstream, " Check for any symbolic links (soft links or external links)\n");
+ PRINTVALSTREAM(rawoutstream, " that do not resolve to an existing object (dataset, group,\n");
+ PRINTVALSTREAM(rawoutstream, " or named datatype).\n");
+ PRINTVALSTREAM(rawoutstream, " If any dangling link is found, this situation is treated\n");
+ PRINTVALSTREAM(rawoutstream, " as an error and h5ls returns an exit code of 1.\n");
+ PRINTVALSTREAM(rawoutstream, " -f, --full Print full path names instead of base names\n");
+ PRINTVALSTREAM(rawoutstream, " -g, --group Show information about a group, not its contents\n");
+ PRINTVALSTREAM(rawoutstream, " -l, --label Label members of compound datasets\n");
+ PRINTVALSTREAM(rawoutstream, " -r, --recursive List all groups recursively, avoiding cycles\n");
+ PRINTVALSTREAM(rawoutstream, " -s, --string Print 1-byte integer datasets as ASCII\n");
+ PRINTVALSTREAM(rawoutstream, " -S, --simple Use a machine-readable output format\n");
+ PRINTVALSTREAM(rawoutstream, " -wN, --width=N Set the number of columns of output\n");
+ PRINTVALSTREAM(rawoutstream, " -v, --verbose Generate more verbose output\n");
+ PRINTVALSTREAM(rawoutstream, " -V, --version Print version number and exit\n");
+ PRINTVALSTREAM(rawoutstream, " --vfd=DRIVER Use the specified virtual file driver\n");
+ PRINTVALSTREAM(rawoutstream, " -x, --hexdump Show raw data in hexadecimal format\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " file/OBJECT\n");
+ PRINTVALSTREAM(rawoutstream, " Each object consists of an HDF5 file name optionally followed by a\n");
+ PRINTVALSTREAM(rawoutstream, " slash and an object name within the file (if no object is specified\n");
+ PRINTVALSTREAM(rawoutstream, " within the file then the contents of the root group are displayed).\n");
+ PRINTVALSTREAM(rawoutstream, " The file name may include a printf(3C) integer format such as\n");
+ PRINTVALSTREAM(rawoutstream, " \"%%05d\" to open a file family.\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " Deprecated Options\n");
+ PRINTVALSTREAM(rawoutstream, " The following options have been deprecated in HDF5. While they remain\n");
+ PRINTVALSTREAM(rawoutstream, " available, they have been superseded as indicated and may be removed\n");
+ PRINTVALSTREAM(rawoutstream, " from HDF5 in the future. Use the indicated replacement option in all\n");
+ PRINTVALSTREAM(rawoutstream, " new work; where possible, existing scripts, et cetera, should also be\n");
+ PRINTVALSTREAM(rawoutstream, " updated to use the replacement option.\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " -E or --external Follow external links.\n");
+ PRINTVALSTREAM(rawoutstream, " Replaced by --follow-symlinks.\n");
+ PRINTVALSTREAM(rawoutstream, " -e, --errors Show all HDF5 error reporting\n");
+ PRINTVALSTREAM(rawoutstream, " Replaced by --enable-error-stack.\n");
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_string
+ *
+ * Purpose: Print a string value by escaping unusual characters. If
+ * STREAM is null then we only count how large the output would
+ * be.
+ *
+ * Return: Number of characters printed.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+print_string(h5tools_str_t *buffer, const char *s, hbool_t escape_spaces)
+{
+ int nprint=0;
+
+ for (/*void*/; s && *s; s++) {
+ switch (*s) {
+ case '"':
+ if (buffer) h5tools_str_append(buffer, "\\\"");
+ nprint += 2;
+ break;
+ case '\\':
+ if (buffer) h5tools_str_append(buffer, "\\\\");
+ nprint += 2;
+ break;
+ case '\b':
+ if (buffer) h5tools_str_append(buffer, "\\b");
+ nprint += 2;
+ break;
+ case '\f':
+ if (buffer) h5tools_str_append(buffer, "\\f");
+ nprint += 2;
+ break;
+ case '\n':
+ if (buffer) h5tools_str_append(buffer, "\\n");
+ nprint += 2;
+ break;
+ case '\r':
+ if (buffer) h5tools_str_append(buffer, "\\r");
+ nprint += 2;
+ break;
+ case '\t':
+ if (buffer) h5tools_str_append(buffer, "\\t");
+ nprint += 2;
+ break;
+ case ' ':
+ if (escape_spaces) {
+ if (buffer) h5tools_str_append(buffer, "\\ ");
+ nprint += 2;
+ }
+ else {
+ if (buffer) h5tools_str_append(buffer, " ");
+ nprint++;
+ }
+ break;
+ default:
+ if (isprint((int)*s)) {
+ if (buffer) h5tools_str_append(buffer, "%c", *s);
+ nprint++;
+ }
+ else {
+ if (buffer) h5tools_str_append(buffer, "\\%03o", *((const unsigned char*)s));
+ nprint += 4;
+ }
+ break;
+ }
+ }
+ return nprint;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_obj_name
+ *
+ * Purpose: Print an object name and another string.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, November 6, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+print_obj_name(h5tools_str_t *buffer, const iter_t *iter, const char *oname,
+ const char *s)
+{
+ static char fullname[NAME_BUF_SIZE]; /* Buffer for file and/or object name */
+ const char *name = fullname; /* Pointer to buffer for printing */
+ int n;
+
+ if(show_file_name_g)
+ HDsnprintf(fullname, sizeof(fullname), "%s/%s", iter->fname, oname + iter->name_start);
+ else
+ name = oname + iter->name_start;
+
+ /* Print the object name, either full name or base name */
+ if(fullname_g)
+ n = print_string(buffer, name, TRUE);
+ else {
+ const char *last_sep; /* The location of the last group separator */
+
+ /* Find the last component of the path name */
+ if(NULL == (last_sep = HDstrrchr(name, '/')))
+ last_sep = name;
+ else {
+ last_sep++;
+ } /* end else */
+ n = print_string(buffer, last_sep, TRUE);
+ } /* end else */
+ h5tools_str_append(buffer, "%*s ", MAX(0, (24 - n)), s);
+
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_native_type
+ *
+ * Purpose: Prints the name of a native C data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ * Robb Matzke, 1999-06-11
+ * Added the C9x types, but we still prefer to display the types
+ * from the C language itself (like `int' vs. `int32_t').
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_native_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ if(!simple_output_g) {
+ if (H5Tequal(type, H5T_NATIVE_SCHAR)==TRUE) {
+ h5tools_str_append(buffer, "native signed char");
+ } else if (H5Tequal(type, H5T_NATIVE_UCHAR)==TRUE) {
+ h5tools_str_append(buffer, "native unsigned char");
+ } else if (H5Tequal(type, H5T_NATIVE_INT)==TRUE) {
+ h5tools_str_append(buffer, "native int");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT)==TRUE) {
+ h5tools_str_append(buffer, "native unsigned int");
+ } else if (H5Tequal(type, H5T_NATIVE_SHORT)==TRUE) {
+ h5tools_str_append(buffer, "native short");
+ } else if (H5Tequal(type, H5T_NATIVE_USHORT)==TRUE) {
+ h5tools_str_append(buffer, "native unsigned short");
+ } else if (H5Tequal(type, H5T_NATIVE_LONG)==TRUE) {
+ h5tools_str_append(buffer, "native long");
+ } else if (H5Tequal(type, H5T_NATIVE_ULONG)==TRUE) {
+ h5tools_str_append(buffer, "native unsigned long");
+ } else if (H5Tequal(type, H5T_NATIVE_LLONG)==TRUE) {
+ h5tools_str_append(buffer, "native long long");
+ } else if (H5Tequal(type, H5T_NATIVE_ULLONG)==TRUE) {
+ h5tools_str_append(buffer, "native unsigned long long");
+ } else if (H5Tequal(type, H5T_NATIVE_FLOAT)==TRUE) {
+ h5tools_str_append(buffer, "native float");
+ } else if (H5Tequal(type, H5T_NATIVE_DOUBLE)==TRUE) {
+ h5tools_str_append(buffer, "native double");
+#if H5_SIZEOF_LONG_DOUBLE !=0
+ } else if (H5Tequal(type, H5T_NATIVE_LDOUBLE)==TRUE) {
+ h5tools_str_append(buffer, "native long double");
+#endif
+ } else if (H5Tequal(type, H5T_NATIVE_INT8)==TRUE) {
+ h5tools_str_append(buffer, "native int8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT8)==TRUE) {
+ h5tools_str_append(buffer, "native uint8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT16)==TRUE) {
+ h5tools_str_append(buffer, "native int16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT16)==TRUE) {
+ h5tools_str_append(buffer, "native uint16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT32)==TRUE) {
+ h5tools_str_append(buffer, "native int32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT32)==TRUE) {
+ h5tools_str_append(buffer, "native uint32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT64)==TRUE) {
+ h5tools_str_append(buffer, "native int64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT64)==TRUE) {
+ h5tools_str_append(buffer, "native uint64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST8)==TRUE) {
+ h5tools_str_append(buffer, "native int_least8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST8)==TRUE) {
+ h5tools_str_append(buffer, "native uint_least8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST16)==TRUE) {
+ h5tools_str_append(buffer, "native int_least16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST16)==TRUE) {
+ h5tools_str_append(buffer, "native uint_least16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST32)==TRUE) {
+ h5tools_str_append(buffer, "native int_least32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST32)==TRUE) {
+ h5tools_str_append(buffer, "native uint_least32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST64)==TRUE) {
+ h5tools_str_append(buffer, "native int_least64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST64)==TRUE) {
+ h5tools_str_append(buffer, "native uint_least64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST8)==TRUE) {
+ h5tools_str_append(buffer, "native int_fast8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST8)==TRUE) {
+ h5tools_str_append(buffer, "native uint_fast8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST16)==TRUE) {
+ h5tools_str_append(buffer, "native int_fast16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST16)==TRUE) {
+ h5tools_str_append(buffer, "native uint_fast16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST32)==TRUE) {
+ h5tools_str_append(buffer, "native int_fast32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST32)==TRUE) {
+ h5tools_str_append(buffer, "native uint_fast32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST64)==TRUE) {
+ h5tools_str_append(buffer, "native int_fast64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST64)==TRUE) {
+ h5tools_str_append(buffer, "native uint_fast64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_B8)==TRUE) {
+ h5tools_str_append(buffer, "native 8-bit field");
+ } else if (H5Tequal(type, H5T_NATIVE_B16)==TRUE) {
+ h5tools_str_append(buffer, "native 16-bit field");
+ } else if (H5Tequal(type, H5T_NATIVE_B32)==TRUE) {
+ h5tools_str_append(buffer, "native 32-bit field");
+ } else if (H5Tequal(type, H5T_NATIVE_B64)==TRUE) {
+ h5tools_str_append(buffer, "native 64-bit field");
+ } else if (H5Tequal(type, H5T_NATIVE_HSIZE)==TRUE) {
+ h5tools_str_append(buffer, "native hsize_t");
+ } else if (H5Tequal(type, H5T_NATIVE_HSSIZE)==TRUE) {
+ h5tools_str_append(buffer, "native hssize_t");
+ } else if (H5Tequal(type, H5T_NATIVE_HERR)==TRUE) {
+ h5tools_str_append(buffer, "native herr_t");
+ } else if (H5Tequal(type, H5T_NATIVE_HBOOL)==TRUE) {
+ h5tools_str_append(buffer, "native hbool_t");
+ } else {
+ return print_int_type(buffer, type, ind);
+ }
+ } else {
+ return print_int_type(buffer, type, ind);
+ }
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_ieee_type
+ *
+ * Purpose: Print the name of an IEEE floating-point data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_ieee_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ if (H5Tequal(type, H5T_IEEE_F32BE)==TRUE) {
+ h5tools_str_append(buffer, "IEEE 32-bit big-endian float");
+ }
+ else if (H5Tequal(type, H5T_IEEE_F32LE)==TRUE) {
+ h5tools_str_append(buffer, "IEEE 32-bit little-endian float");
+ }
+ else if (H5Tequal(type, H5T_IEEE_F64BE)==TRUE) {
+ h5tools_str_append(buffer, "IEEE 64-bit big-endian float");
+ }
+ else if (H5Tequal(type, H5T_IEEE_F64LE)==TRUE) {
+ h5tools_str_append(buffer, "IEEE 64-bit little-endian float");
+ }
+ else {
+ return print_float_type(buffer, type, ind);
+ }
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_precision
+ *
+ * Purpose: Prints information on the next line about precision and
+ * padding if the precision is less than the total data type
+ * size.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+print_precision(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ size_t prec; /* precision */
+ H5T_pad_t plsb, pmsb; /* lsb and msb padding */
+ const char *plsb_s=NULL; /* lsb padding string */
+ const char *pmsb_s=NULL; /* msb padding string */
+ size_t nbits; /* number of bits */
+
+ /* If the precision is less than the total size then show the precision
+ * and offset on the following line. Also display the padding
+ * information. */
+ if(8 * H5Tget_size(type) != (prec = H5Tget_precision(type))) {
+ h5tools_str_append(buffer, "\n%*s(%lu bit%s of precision beginning at bit %lu)",
+ ind, "", (unsigned long)prec, 1 == prec ? "" : "s",
+ (unsigned long)H5Tget_offset(type));
+
+ H5Tget_pad(type, &plsb, &pmsb);
+ if(H5Tget_offset(type) > 0) {
+ switch(plsb) {
+ case H5T_PAD_ZERO:
+ plsb_s = "zero";
+ break;
+ case H5T_PAD_ONE:
+ plsb_s = "one";
+ break;
+ case H5T_PAD_BACKGROUND:
+ plsb_s = "bkg";
+ break;
+ case H5T_PAD_ERROR:
+ case H5T_NPAD:
+ plsb_s = "unknown";
+ break;
+ default:
+ break;
+ }
+ }
+ if((unsigned)H5Tget_offset(type) + prec < 8 * H5Tget_size(type)) {
+ switch(pmsb) {
+ case H5T_PAD_ZERO:
+ pmsb_s = "zero";
+ break;
+ case H5T_PAD_ONE:
+ pmsb_s = "one";
+ break;
+ case H5T_PAD_BACKGROUND:
+ pmsb_s = "bkg";
+ break;
+ case H5T_PAD_ERROR:
+ case H5T_NPAD:
+ pmsb_s = "unknown";
+ break;
+ default:
+ break;
+ }
+ }
+ if (plsb_s || pmsb_s) {
+ h5tools_str_append(buffer, "\n%*s(", ind, "");
+ if (plsb_s) {
+ nbits = (unsigned)H5Tget_offset(type);
+ h5tools_str_append(buffer, "%lu %s bit%s at bit 0",
+ (unsigned long)nbits, plsb_s, 1 == nbits ? "" : "s");
+ }
+ if (plsb_s && pmsb_s) h5tools_str_append(buffer, ", ");
+ if (pmsb_s) {
+ nbits = (8 * H5Tget_size(type)) - ((unsigned)H5Tget_offset(type) + prec);
+ h5tools_str_append(buffer, "%lu %s bit%s at bit %lu",
+ (unsigned long)nbits, pmsb_s, 1 == nbits ? "" : "s",
+ (unsigned long)(8 * H5Tget_size(type) - nbits));
+ }
+ h5tools_str_append(buffer, ")");
+ }
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_int_type
+ *
+ * Purpose: Print the name of an integer data type. Common information
+ * like number of bits, byte order, and sign scheme appear on
+ * the first line. Additional information might appear in
+ * parentheses on the following lines.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_int_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ H5T_order_t order; /* byte order value */
+ const char *order_s=NULL; /* byte order string */
+ H5T_sign_t sign; /* sign scheme value */
+ const char *sign_s=NULL; /* sign scheme string */
+
+ if (H5T_INTEGER!=H5Tget_class(type)) return FALSE;
+
+ /* 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 on first line, precision and padding
+ * information on the subsequent lines */
+ h5tools_str_append(buffer, "%lu-bit%s%s integer",
+ (unsigned long)(8*H5Tget_size(type)), order_s, sign_s);
+ print_precision(buffer, type, ind);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_float_type
+ *
+ * Purpose: Print info about a floating point data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_float_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ H5T_order_t order; /* byte order value */
+ const char *order_s=NULL; /* byte order string */
+ size_t spos; /* sign bit position */
+ size_t esize, epos; /* exponent size and position */
+ size_t msize, mpos; /* significand size and position */
+ size_t ebias; /* exponent bias */
+ H5T_norm_t norm; /* significand normalization */
+ const char *norm_s=NULL; /* normalization string */
+ H5T_pad_t pad; /* internal padding value */
+ const char *pad_s=NULL; /* internal padding string */
+
+ if (H5T_FLOAT!=H5Tget_class(type)) return FALSE;
+
+ /* 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 on first line, precision and padding on
+ * subsequent lines. */
+ h5tools_str_append(buffer, "%lu-bit%s floating-point",
+ (unsigned long)(8*H5Tget_size(type)), order_s);
+ print_precision(buffer, type, ind);
+
+ /* Print sizes, locations, and other information about each field */
+ H5Tget_fields (type, &spos, &epos, &esize, &mpos, &msize);
+ ebias = H5Tget_ebias(type);
+ norm = H5Tget_norm(type);
+ switch (norm) {
+ case H5T_NORM_IMPLIED:
+ norm_s = ", msb implied";
+ break;
+ case H5T_NORM_MSBSET:
+ norm_s = ", msb always set";
+ break;
+ case H5T_NORM_NONE:
+ norm_s = ", no normalization";
+ break;
+ case H5T_NORM_ERROR:
+ norm_s = ", unknown normalization";
+ break;
+ default:
+ ;
+ break;
+ }
+ h5tools_str_append(buffer, "\n%*s(significant for %lu bit%s at bit %lu%s)", ind, "",
+ (unsigned long)msize, 1==msize?"":"s", (unsigned long)mpos,
+ norm_s);
+ h5tools_str_append(buffer, "\n%*s(exponent for %lu bit%s at bit %lu, bias is 0x%lx)",
+ ind, "", (unsigned long)esize, 1==esize?"":"s",
+ (unsigned long)epos, (unsigned long)ebias);
+ h5tools_str_append(buffer, "\n%*s(sign bit at %lu)", ind, "", (unsigned long)spos);
+
+ /* Display internal padding */
+ if (1+esize+msize<H5Tget_precision(type)) {
+ pad = H5Tget_inpad(type);
+ switch (pad) {
+ case H5T_PAD_ZERO:
+ pad_s = "zero";
+ break;
+ case H5T_PAD_ONE:
+ pad_s = "one";
+ break;
+ case H5T_PAD_BACKGROUND:
+ pad_s = "bkg";
+ break;
+ case H5T_PAD_ERROR:
+ case H5T_NPAD:
+ pad_s = "unknown";
+ break;
+ default:
+ ;
+ break;
+ }
+ h5tools_str_append(buffer, "\n%*s(internal padding bits are %s)", ind, "", pad_s);
+ }
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_cmpd_type
+ *
+ * Purpose: Print info about a compound data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_cmpd_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ char *name=NULL; /* member name */
+ size_t size; /* total size of type in bytes */
+ hid_t subtype; /* member data type */
+ int nmembs; /* number of members */
+ int n; /* miscellaneous counters */
+ unsigned i; /* miscellaneous counters */
+
+ if(H5T_COMPOUND != H5Tget_class(type))
+ return FALSE;
+ if((nmembs = H5Tget_nmembers(type)) < 0)
+ return FALSE;
+
+ h5tools_str_append(buffer, "struct {");
+ for(i = 0; i < (unsigned)nmembs; i++) {
+
+ /* Name and offset */
+ name = H5Tget_member_name(type, i);
+ h5tools_str_append(buffer, "\n%*s\"", ind+4, "");
+ n = print_string(buffer, name, FALSE);
+ h5tools_str_append(buffer, "\"%*s +%-4lu ", MAX(0, 16-n), "",
+ (unsigned long)H5Tget_member_offset(type, i));
+ H5free_memory(name);
+
+ /* Member's type */
+ subtype = H5Tget_member_type(type, i);
+ print_type(buffer, subtype, ind+4);
+ H5Tclose(subtype);
+ }
+ size = H5Tget_size(type);
+ h5tools_str_append(buffer, "\n%*s} %lu byte%s",
+ ind, "", (unsigned long)size, 1==size?"":"s");
+
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_enum_type
+ *
+ * Purpose: Print info about an enumeration data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, December 23, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_enum_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ int nmembs; /* number of members */
+ hid_t super; /* enum base integer type */
+
+ if(H5T_ENUM != H5Tget_class(type))
+ return FALSE;
+ if((nmembs = H5Tget_nmembers(type)) < 0)
+ return FALSE;
+
+ super = H5Tget_super(type);
+ h5tools_str_append(buffer, "enum ");
+ print_type(buffer, super, ind + 4);
+ h5tools_str_append(buffer, " {");
+
+ if(nmembs > 0) {
+ char **name; /* member names */
+ unsigned char *value; /* value array */
+ hid_t native = -1; /* native integer data type */
+ size_t dst_size; /* destination value type size */
+ unsigned i; /* miscellaneous counters */
+
+ /* Determine what data type to use for the native values. To simplify
+ * things we entertain three possibilities:
+ * 1. long long -- the largest native signed integer
+ * 2. unsigned long long -- the largest native unsigned integer
+ * 3. raw format */
+ if(H5Tget_size(type) <= sizeof(long long)) {
+ dst_size = sizeof(long long);
+ if(H5T_SGN_NONE == H5Tget_sign(type))
+ native = H5T_NATIVE_ULLONG;
+ else
+ native = H5T_NATIVE_LLONG;
+ } /* end if */
+ else
+ dst_size = H5Tget_size(type);
+
+ /* Get the names and raw values of all members */
+ name = (char **)HDcalloc((size_t)nmembs, sizeof(char *));
+ value = (unsigned char *)HDcalloc((size_t)nmembs, MAX(H5Tget_size(type), dst_size));
+ for(i = 0; i < (unsigned)nmembs; i++) {
+ name[i] = H5Tget_member_name(type, i);
+ H5Tget_member_value(type, i, value + i * H5Tget_size(type));
+ }
+
+ /* Convert values to native data type */
+ if(native > 0)
+ if(H5Tconvert(super, native, (size_t)nmembs, value, NULL, H5P_DEFAULT) < 0) {
+ /* Release resources */
+ for(i = 0; i < (unsigned)nmembs; i++)
+ H5free_memory(name[i]);
+ HDfree(name);
+ HDfree(value);
+
+ return FALSE;
+ }
+
+ /* Sort members by increasing value */
+ /*not implemented yet*/
+
+ /* Print members */
+ for(i = 0; i < (unsigned)nmembs; i++) {
+ unsigned char *copy; /* a pointer to value array */
+ int nchars; /* number of output characters */
+
+ h5tools_str_append(buffer, "\n%*s", ind+4, "");
+ nchars = print_string(buffer, name[i], TRUE);
+ 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, HSIZE_T_FORMAT, *((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)));
+ }
+ }
+
+ /* Release resources */
+ for(i = 0; i < (unsigned)nmembs; i++)
+ H5free_memory(name[i]);
+ HDfree(name);
+ HDfree(value);
+ }
+ else
+ h5tools_str_append(buffer, "\n%*s <empty>", ind+4, "");
+
+ h5tools_str_append(buffer, "\n%*s}", ind, "");
+
+ H5Tclose(super);
+
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_string_type
+ *
+ * Purpose: Print information about a string data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_string_type(h5tools_str_t *buffer, hid_t type, int H5_ATTR_UNUSED ind)
+{
+ H5T_str_t pad;
+ const char *pad_s=NULL;
+ H5T_cset_t cset;
+ const char *cset_s=NULL;
+
+ if (H5T_STRING!=H5Tget_class(type)) return FALSE;
+
+ /* Padding */
+ pad = H5Tget_strpad(type);
+ switch (pad) {
+ case H5T_STR_NULLTERM:
+ pad_s = "null-terminated";
+ break;
+ case H5T_STR_NULLPAD:
+ pad_s = "null-padded";
+ break;
+ case H5T_STR_SPACEPAD:
+ pad_s = "space-padded";
+ break;
+ case H5T_STR_RESERVED_3:
+ case H5T_STR_RESERVED_4:
+ case H5T_STR_RESERVED_5:
+ case H5T_STR_RESERVED_6:
+ case H5T_STR_RESERVED_7:
+ case H5T_STR_RESERVED_8:
+ case H5T_STR_RESERVED_9:
+ case H5T_STR_RESERVED_10:
+ case H5T_STR_RESERVED_11:
+ case H5T_STR_RESERVED_12:
+ case H5T_STR_RESERVED_13:
+ case H5T_STR_RESERVED_14:
+ case H5T_STR_RESERVED_15:
+ case H5T_STR_ERROR:
+ pad_s = "unknown-format";
+ break;
+ default:
+ ;
+ break;
+ }
+
+ /* Character set */
+ cset = H5Tget_cset(type);
+ switch (cset) {
+ case H5T_CSET_ASCII:
+ cset_s = "ASCII";
+ break;
+ case H5T_CSET_UTF8:
+ cset_s = "UTF-8";
+ break;
+ case H5T_CSET_RESERVED_2:
+ case H5T_CSET_RESERVED_3:
+ case H5T_CSET_RESERVED_4:
+ case H5T_CSET_RESERVED_5:
+ case H5T_CSET_RESERVED_6:
+ case H5T_CSET_RESERVED_7:
+ case H5T_CSET_RESERVED_8:
+ case H5T_CSET_RESERVED_9:
+ case H5T_CSET_RESERVED_10:
+ case H5T_CSET_RESERVED_11:
+ case H5T_CSET_RESERVED_12:
+ case H5T_CSET_RESERVED_13:
+ case H5T_CSET_RESERVED_14:
+ case H5T_CSET_RESERVED_15:
+ case H5T_CSET_ERROR:
+ cset_s = "unknown-character-set";
+ break;
+ default:
+ ;
+ break;
+ }
+
+ if (H5Tis_variable_str(type)) {
+ h5tools_str_append(buffer, "variable-length");
+ }
+ else {
+ h5tools_str_append(buffer, "%lu-byte", (unsigned long)H5Tget_size(type));
+ }
+ h5tools_str_append(buffer, " %s %s string", pad_s, cset_s);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_reference_type
+ *
+ * Purpose: Prints information about a reference data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ * Robb Matzke, 1999-06-04
+ * Knows about object and dataset region references.
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_reference_type(h5tools_str_t *buffer, hid_t type, int H5_ATTR_UNUSED ind)
+{
+ if (H5T_REFERENCE!=H5Tget_class(type)) return FALSE;
+
+ if (H5Tequal(type, H5T_STD_REF_OBJ)==TRUE) {
+ h5tools_str_append(buffer, "object reference");
+ }
+ else if (H5Tequal(type, H5T_STD_REF_DSETREG)==TRUE) {
+ h5tools_str_append(buffer, "dataset region reference");
+ }
+ else {
+ h5tools_str_append(buffer, "%lu-byte unknown reference",
+ (unsigned long)H5Tget_size(type));
+ }
+
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_opaque_type
+ *
+ * Purpose: Prints information about an opaque data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 7, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_opaque_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ char *tag;
+ size_t size;
+
+ if (H5T_OPAQUE!=H5Tget_class(type)) return FALSE;
+
+ size = H5Tget_size(type);
+ h5tools_str_append(buffer, "%lu-byte opaque type", (unsigned long)size);
+ if ((tag=H5Tget_tag(type))) {
+ h5tools_str_append(buffer, "\n%*s(tag = \"", ind, "");
+ print_string(buffer, tag, FALSE);
+ h5tools_str_append(buffer, "\")");
+ H5free_memory(tag);
+ }
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_vlen_type
+ *
+ * Purpose: Print information about a variable-length type
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 1, 2000
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_vlen_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ hid_t super;
+
+ if (H5T_VLEN!=H5Tget_class(type)) return FALSE;
+
+ h5tools_str_append(buffer, "variable length of\n%*s", ind+4, "");
+ super = H5Tget_super(type);
+ print_type(buffer, super, ind+4);
+ H5Tclose(super);
+ return TRUE;
+}
+
+
+/*---------------------------------------------------------------------------
+ * Purpose: Print information about an array type
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE
+ *
+ * Programmer: Robb Matzke
+ * Thursday, January 31, 2002
+ *
+ * Modifications:
+ *---------------------------------------------------------------------------
+ */
+static hbool_t
+print_array_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ hid_t super;
+ int ndims, i;
+ hsize_t *dims=NULL;
+
+ if (H5T_ARRAY!=H5Tget_class(type))
+ return FALSE;
+ ndims = H5Tget_array_ndims(type);
+ if (ndims) {
+ dims = (hsize_t *)HDmalloc((unsigned)ndims * sizeof(dims[0]));
+ H5Tget_array_dims2(type, dims);
+
+ /* Print dimensions */
+ for (i=0; i<ndims; i++)
+ h5tools_str_append(buffer, "%s" HSIZE_T_FORMAT , i?",":"[", dims[i]);
+ h5tools_str_append(buffer, "]");
+
+ HDfree(dims);
+ }
+ else
+ h5tools_str_append(buffer, " [SCALAR]\n", rawoutstream);
+
+
+ /* Print parent type */
+ h5tools_str_append(buffer, " ");
+ super = H5Tget_super(type);
+ print_type(buffer, super, ind+4);
+ H5Tclose(super);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_bitfield_type
+ *
+ * Purpose: Print information about a bitfield type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Pedro Vicente
+ * Tuesday, May 20, 2003
+ *
+ * Modifications:
+ * Robb Matzke, LLNL 2003-06-05
+ * Generalized Pedro's original if/then/else. Also display
+ * precision/offset information.
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+print_bitfield_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ H5T_order_t order; /* byte order value */
+ const char *order_s=NULL; /* byte order string */
+
+ if (H5T_BITFIELD!=H5Tget_class(type)) return FALSE;
+ 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 = "";
+ }
+
+ h5tools_str_append(buffer, "%lu-bit%s bitfield",
+ (unsigned long)(8*H5Tget_size(type)), order_s);
+ print_precision(buffer, type, ind);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_type
+ *
+ * Purpose: Prints a data type definition. The definition is printed
+ * without any leading space or trailing line-feed (although
+ * there might be line-feeds inside the type definition). The
+ * first line is assumed to have IND characters before it on
+ * the same line (printed by the caller).
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ * Robb Matzke, 1999-06-11
+ * Prints the OID of shared data types.
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+print_type(h5tools_str_t *buffer, hid_t type, int ind)
+{
+ H5T_class_t data_class = H5Tget_class(type);
+
+ /* Bad data type */
+ if (type<0) {
+ h5tools_str_append(buffer,"<ERROR>");
+ return;
+ }
+
+ /* Shared? If so then print the type's OID */
+ if(H5Tcommitted(type)) {
+ H5O_info_t oi;
+
+ if(H5Oget_info(type, &oi) >= 0)
+ h5tools_str_append(buffer,"shared-%lu:"H5_PRINTF_HADDR_FMT" ",
+ oi.fileno, oi.addr);
+ else
+ h5tools_str_append(buffer,"shared ");
+ } /* end if */
+
+ /* Print the type */
+ if(print_native_type(buffer, type, ind) ||
+ print_ieee_type(buffer, type, ind) ||
+ print_cmpd_type(buffer, type, ind) ||
+ print_enum_type(buffer, type, ind) ||
+ print_string_type(buffer, type, ind) ||
+ print_reference_type(buffer, type, ind) ||
+ print_vlen_type(buffer, type, ind) ||
+ print_array_type(buffer, type, ind) ||
+ print_opaque_type(buffer, type, ind) ||
+ print_bitfield_type(buffer, type, ind))
+ return;
+
+ /* Unknown type */
+ h5tools_str_append(buffer,"%lu-byte class-%u unknown",
+ (unsigned long)H5Tget_size(type), (unsigned)data_class);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_dataset_values
+ *
+ * Purpose: Prints all values of a dataset.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, July 21, 1998
+ *
+ * Modifications:
+ * Robb Matzke, 1999-09-27
+ * Understands the simple_output_g switch which causes data to
+ * be displayed in a more machine-readable format.
+ *-------------------------------------------------------------------------
+ */
+static void
+dump_dataset_values(hid_t dset)
+{
+ char string_prefix[64];
+ static char fmt_double[16];
+ static char fmt_float[16];
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t outputformat;
+ h5tool_format_t *info = &ls_dataformat;
+
+ hid_t f_type = H5Dget_type(dset);
+ size_t size = H5Tget_size(f_type);
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ outputformat = *info;
+ outputformat.line_1st = NULL;
+ if (simple_output_g) {
+ outputformat.idx_fmt = "";
+ outputformat.line_per_line = 1;
+ outputformat.line_multi_new = 0;
+ outputformat.line_pre = " ";
+ outputformat.line_cont = " ";
+
+ outputformat.arr_pre = "";
+ outputformat.arr_suf = "";
+ outputformat.arr_sep = " ";
+
+ if (!label_g) {
+ outputformat.cmpd_pre = "";
+ outputformat.cmpd_suf = "";
+ }
+ outputformat.cmpd_sep = " ";
+
+ if (label_g) outputformat.cmpd_name = "%s=";
+
+ outputformat.elmt_suf1 = " ";
+ outputformat.str_locale = ESCAPE_HTML;
+
+ }
+ else {
+ if (no_line_wrap_g) {
+ outputformat.line_per_line = 1;
+ }
+ else {
+ outputformat.line_ncols = (unsigned)width_g;
+ }
+ if (label_g) outputformat.cmpd_name = "%s=";
+ outputformat.line_pre = " %s ";
+ outputformat.line_cont = " %s ";
+ outputformat.str_repeat = 8;
+
+ outputformat.arr_pre = NULL;
+ outputformat.arr_suf = NULL;
+ outputformat.arr_sep = NULL;
+
+ outputformat.cmpd_pre = NULL;
+ outputformat.cmpd_suf = NULL;
+ outputformat.cmpd_sep = NULL;
+
+ outputformat.vlen_sep = NULL;
+ outputformat.vlen_pre = NULL;
+ outputformat.vlen_suf = NULL;
+ outputformat.vlen_end = NULL;
+ }
+ outputformat.arr_linebreak = 0;
+ /* Floating point types should display full precision */
+ HDsnprintf(fmt_float, sizeof(fmt_float), "%%1.%dg", FLT_DIG);
+ outputformat.fmt_float = fmt_float;
+ HDsnprintf(fmt_double, sizeof(fmt_double), "%%1.%dg", DBL_DIG);
+ outputformat.fmt_double = fmt_double;
+
+ if (hexdump_g) {
+ /* Print all data in hexadecimal format if the `-x' or `--hexdump'
+ * command line switch was given. */
+ outputformat.raw = TRUE;
+ }
+ else if (string_g && 1==size && H5T_INTEGER==H5Tget_class(f_type)) {
+ /* Print 1-byte integer data as an ASCI character string instead of
+ * integers if the `-s' or `--string' command-line option was given. */
+ outputformat.ascii = TRUE;
+ outputformat.elmt_suf1 = "";
+ outputformat.elmt_suf2 = "";
+ HDsnprintf(string_prefix, sizeof(string_prefix), "%s\"", outputformat.line_pre);
+ outputformat.line_pre = string_prefix;
+ outputformat.line_suf = "\"";
+ }
+ info = &outputformat;
+
+ ctx.indent_level = 2;
+ ctx.cur_column = (size_t)curr_pos;
+ /* Print all the values. */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " Data:\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ ctx.need_prefix = TRUE;
+ ctx.cur_column = (size_t)curr_pos;
+ if (h5tools_dump_dset(rawoutstream, info, &ctx, dset, NULL) < 0) {
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " Unable to print data.");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ H5Tclose(f_type);
+
+ h5tools_str_close(&buffer);
+
+ PRINTVALSTREAM(rawoutstream, "\n");
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: list_attr
+ *
+ * Purpose: Prints information about attributes.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Friday, June 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+list_attr(hid_t obj, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *ainfo,
+ void H5_ATTR_UNUSED *op_data)
+{
+ hid_t attr = -1;
+ hid_t space = -1;
+ hid_t type = -1;
+ hid_t p_type = -1;
+ hsize_t size[H5S_MAX_RANK];
+ hsize_t nelmts = 1;
+ hsize_t temp_need;
+ size_t need;
+ int ndims;
+ int i;
+ void *buf;
+ H5S_class_t space_type;
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *info = &ls_dataformat;
+ h5tool_format_t outputformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " Attribute: ");
+
+ print_string(&buffer, attr_name, TRUE);
+
+ if((attr = H5Aopen(obj, attr_name, H5P_DEFAULT))) {
+ space = H5Aget_space(attr);
+ type = H5Aget_type(attr);
+
+ /* Data space */
+ ndims = H5Sget_simple_extent_dims(space, size, NULL);
+ space_type = H5Sget_simple_extent_type(space);
+ switch(space_type) {
+ case H5S_SCALAR:
+ /* scalar dataspace */
+ h5tools_str_append(&buffer, " scalar\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5S_SIMPLE:
+ /* simple dataspace */
+ h5tools_str_append(&buffer, " {");
+ for (i=0; i<ndims; i++) {
+ h5tools_str_append(&buffer, "%s" HSIZE_T_FORMAT, i?", ":"", size[i]);
+ nelmts *= size[i];
+ }
+ h5tools_str_append(&buffer, "}\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5S_NULL:
+ /* null dataspace */
+ h5tools_str_append(&buffer, " null\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+
+ case H5S_NO_CLASS:
+ default:
+ /* Unknown dataspace type */
+ h5tools_str_append(&buffer, " unknown\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ } /* end switch */
+
+ /* Data type */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " Type: ");
+ print_type(&buffer, type, 15);
+ h5tools_str_append(&buffer, "\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* Data */
+ outputformat = *info;
+
+ if(nelmts < 5) {
+ outputformat.idx_fmt = "";
+ outputformat.line_1st = " Data: ";
+ outputformat.line_pre = " ";
+ outputformat.line_cont = " ";
+ outputformat.str_repeat = 8;
+
+ }
+ else {
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " Data:\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ outputformat.line_1st = NULL;
+ outputformat.line_pre = " %s ";
+ outputformat.line_cont = " %s ";
+ outputformat.str_repeat = 8;
+ }
+
+ outputformat.line_ncols = (unsigned)width_g;
+ if(label_g)
+ outputformat.cmpd_name = "%s=";
+ if(string_g && 1==H5Tget_size(type) &&
+ H5T_INTEGER==H5Tget_class(type)) {
+ outputformat.ascii = TRUE;
+ outputformat.elmt_suf1 = "";
+ outputformat.elmt_suf2 = "";
+ outputformat.line_pre = " %s \"";
+ outputformat.line_suf = "\"";
+ } /* end if */
+
+
+ outputformat.arr_pre = NULL;
+ outputformat.arr_suf = NULL;
+ outputformat.arr_sep = NULL;
+
+ outputformat.cmpd_pre = NULL;
+ outputformat.cmpd_suf = NULL;
+ outputformat.cmpd_sep = NULL;
+
+ outputformat.vlen_sep = NULL;
+ outputformat.vlen_pre = NULL;
+ outputformat.vlen_suf = NULL;
+ outputformat.vlen_end = NULL;
+
+ info = &outputformat;
+
+ if(hexdump_g)
+ p_type = H5Tcopy(type);
+ else
+ p_type = h5tools_get_native_type(type);
+
+ if(p_type >= 0) {
+ /* VL data special information */
+ unsigned int vl_data = 0; /* contains VL datatypes */
+
+ /* Check if we have VL data in the dataset's datatype */
+ if (h5tools_detect_vlen(p_type) == TRUE)
+ vl_data = TRUE;
+
+ temp_need= nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type));
+ HDassert(temp_need == (hsize_t)((size_t)temp_need));
+ need = (size_t)temp_need;
+ buf = HDmalloc(need);
+ HDassert(buf);
+ if(H5Aread(attr, p_type, buf) >= 0) {
+ ctx.need_prefix = TRUE;
+ ctx.indent_level = 2;
+ ctx.cur_column = (size_t)curr_pos;
+ h5tools_dump_mem(rawoutstream, info, &ctx, attr, p_type, space, buf);
+ }
+
+ /* Reclaim any VL memory, if necessary */
+ if (vl_data)
+ H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf);
+
+ HDfree(buf);
+ H5Tclose(p_type);
+ } /* end if */
+
+ H5Sclose(space);
+ H5Tclose(type);
+ H5Aclose(attr);
+ }
+ h5tools_str_close(&buffer);
+
+ PRINTVALSTREAM(rawoutstream, "\n");
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dataset_list1
+ *
+ * Purpose: List information about a dataset which should appear on the
+ * same line as the dataset name. This information will precede
+ * information which is applicable to all objects which will be
+ * printed by the caller.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, August 27, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+dataset_list1(hid_t dset)
+{
+ hsize_t cur_size[H5S_MAX_RANK]; /* current dataset dimensions */
+ hsize_t max_size[H5S_MAX_RANK]; /* maximum dataset dimensions */
+ hid_t space; /* data space */
+ int ndims; /* dimensionality */
+ H5S_class_t space_type; /* type of dataspace */
+ int i;
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *info = &ls_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ h5tools_str_reset(&buffer);
+
+ /* Information that goes on the same row as the name. The name has
+ * already been printed. */
+ space = H5Dget_space(dset);
+ space_type = H5Sget_simple_extent_type(space);
+ ndims = H5Sget_simple_extent_dims(space, cur_size, max_size);
+ h5tools_str_append(&buffer, " {");
+ for (i=0; i<ndims; i++) {
+ h5tools_str_append(&buffer, "%s"HSIZE_T_FORMAT, i?", ":"", cur_size[i]);
+ if (max_size[i]==H5S_UNLIMITED) {
+ h5tools_str_append(&buffer, "/%s", "Inf");
+ }
+ else if (max_size[i]!=cur_size[i] || verbose_g>0) {
+ h5tools_str_append(&buffer, "/"HSIZE_T_FORMAT, max_size[i]);
+ }
+ }
+ if (space_type==H5S_SCALAR) h5tools_str_append(&buffer, "SCALAR");
+ else if (space_type==H5S_NULL) h5tools_str_append(&buffer, "NULL");
+ h5tools_str_append(&buffer, "}");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ H5Sclose (space);
+
+ h5tools_str_close(&buffer);
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dataset_list2
+ *
+ * Purpose: List information about a dataset which should appear after
+ * information which is general to all objects.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, August 27, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+dataset_list2(hid_t dset, const char H5_ATTR_UNUSED *name)
+{
+ hid_t dcpl; /* dataset creation property list */
+ hid_t type; /* data type of dataset */
+ hid_t space; /* data space of dataset */
+ int nf; /* number of filters */
+ unsigned filt_flags; /* filter flags */
+ H5Z_filter_t filt_id; /* filter identification number */
+ unsigned cd_values[20]; /* filter client data values */
+ size_t cd_nelmts; /* filter client number of values */
+ size_t cd_num; /* filter client data counter */
+ char f_name[256]; /* filter/file name */
+ char s[64]; /* temporary string buffer */
+ off_t f_offset; /* offset in external file */
+ hsize_t f_size; /* bytes used in external file */
+ hsize_t total, used; /* total size or offset */
+ int ndims; /* dimensionality */
+ int n, max_len; /* max extern file name length */
+ double utilization; /* percent utilization of storage */
+ H5T_class_t tclass; /* datatype class identifier */
+ int i;
+ H5D_layout_t stl;
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *info = &ls_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ h5tools_str_reset(&buffer);
+
+ if(verbose_g > 0) {
+ dcpl = H5Dget_create_plist(dset);
+ space = H5Dget_space(dset);
+ type = H5Dget_type(dset);
+
+ stl = H5Pget_layout(dcpl);
+ switch (stl) {
+ case H5D_CHUNKED:
+ {
+ hsize_t chsize[64]; /* chunk size in elements */
+
+ ndims = H5Pget_chunk(dcpl, (int)NELMTS(chsize), chsize/*out*/);
+ h5tools_str_append(&buffer, " %-10s {", "Chunks:");
+ total = H5Tget_size(type);
+ for (i=0; i<ndims; i++) {
+ h5tools_str_append(&buffer, "%s"HSIZE_T_FORMAT, i?", ":"", chsize[i]);
+ total *= chsize[i];
+ }
+ h5tools_str_append(&buffer, "} "HSIZE_T_FORMAT" bytes\n", total);
+ }
+ break;
+ case H5D_COMPACT:
+ break;
+ case H5D_CONTIGUOUS:
+ /* Print information about external storage */
+ if((nf = H5Pget_external_count(dcpl)) > 0) {
+ for(i = 0, max_len = 0; i < nf; i++) {
+ if(H5Pget_external(dcpl, (unsigned)i, sizeof(f_name), f_name, NULL, NULL) < 0)
+ continue;
+ n = print_string(NULL, f_name, TRUE);
+ max_len = MAX(max_len, n);
+ } /* end for */
+ h5tools_str_append(&buffer, " %-10s %d external file%s\n",
+ "Extern:", nf, 1==nf?"":"s");
+ h5tools_str_append(&buffer, " %4s %10s %10s %10s %s\n",
+ "ID", "DSet-Addr", "File-Addr", "Bytes", "File");
+ h5tools_str_append(&buffer, " %4s %10s %10s %10s ",
+ "----", "----------", "----------", "----------");
+ for (i=0; i<max_len; i++) h5tools_str_append(&buffer, "-");
+ h5tools_str_append(&buffer, "\n");
+ for (i=0, total=0; i<nf; i++) {
+ if (H5Pget_external(dcpl, (unsigned)i, sizeof(f_name), f_name, &f_offset, &f_size)<0) {
+ h5tools_str_append(&buffer,
+ " #%03d %10"H5_PRINTF_LL_WIDTH"u %10s %10s ***ERROR*** %s\n",
+ i, total, "", "",
+ i+1<nf?"Following addresses are incorrect":"");
+ }
+ else if (H5S_UNLIMITED==f_size) {
+ h5tools_str_append(&buffer, " #%03d %10"H5_PRINTF_LL_WIDTH"u %10"H5_PRINTF_LL_WIDTH"u %10s ",
+ i, total, (hsize_t)f_offset, "INF");
+ print_string(&buffer, f_name, TRUE);
+ }
+ else {
+ h5tools_str_append(&buffer, " #%03d %10"H5_PRINTF_LL_WIDTH"u %10"H5_PRINTF_LL_WIDTH"u %10"H5_PRINTF_LL_WIDTH"u ",
+ i, total, (hsize_t)f_offset, f_size);
+ print_string(&buffer, f_name, TRUE);
+ }
+ h5tools_str_append(&buffer, "\n");
+ total += f_size;
+ }
+ h5tools_str_append(&buffer, " %4s %10s %10s %10s ",
+ "----", "----------", "----------", "----------");
+ for (i=0; i<max_len; i++)
+ h5tools_str_append(&buffer, "-");
+ h5tools_str_append(&buffer, "\n");
+ } /* end if */
+ break;
+
+ case H5D_VIRTUAL:
+ {
+ char dset_name[256]; /* Dataset name */
+ size_t vmaps;
+
+ H5Pget_virtual_count(dcpl, &vmaps);
+
+ if (vmaps) {
+ size_t next;
+
+ h5tools_str_append(&buffer, " %-10s {%ld} Source {\n", "Maps:", vmaps);
+ for (next = 0; next < (unsigned) vmaps; next++) {
+ H5Pget_virtual_filename(dcpl, next, f_name, sizeof(f_name));
+ H5Pget_virtual_dsetname(dcpl, next, dset_name, sizeof(dset_name));
+ h5tools_str_append(&buffer, " %-10s ", " ");
+ print_string(&buffer, f_name, TRUE);
+ h5tools_str_append(&buffer, " ");
+ print_string(&buffer, dset_name, TRUE);
+ h5tools_str_append(&buffer, "\n");
+ }
+ h5tools_str_append(&buffer, " %-10s}\n", " ");
+ }
+ }
+ break;
+
+ case H5D_LAYOUT_ERROR:
+ case H5D_NLAYOUTS:
+ default:
+ HDassert(0);
+ break;
+ }
+ /* Print total raw storage size */
+ total = (hsize_t)H5Sget_simple_extent_npoints(space) * H5Tget_size(type);
+ used = H5Dget_storage_size(dset);
+ tclass = H5Tget_class(type);
+ h5tools_str_append(&buffer, " %-10s ", "Storage:");
+ switch (tclass)
+ {
+
+ case H5T_VLEN:
+ h5tools_str_append(&buffer, "information not available");
+ break;
+
+ case H5T_REFERENCE:
+ if ( H5Tequal(type, H5T_STD_REF_DSETREG))
+ {
+ h5tools_str_append(&buffer, "information not available");
+ }
+ break;
+
+ case H5T_NO_CLASS:
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_TIME:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_COMPOUND:
+ case H5T_ENUM:
+ case H5T_ARRAY:
+ case H5T_NCLASSES:
+ default:
+ h5tools_str_append(&buffer, HSIZE_T_FORMAT" logical byte%s, "HSIZE_T_FORMAT" allocated byte%s",
+ total, 1==total?"":"s",
+ used, 1==used?"":"s");
+ if (used>0)
+ {
+ utilization = ((double)total * (double)100.0f) / (double)used;
+ h5tools_str_append(&buffer, ", %1.2f%% utilization", utilization);
+ }
+ }
+
+ h5tools_str_append(&buffer, "\n");
+
+ /* Print information about raw data filters */
+ if((nf = H5Pget_nfilters(dcpl)) > 0) {
+ for(i = 0; i < nf; i++) {
+ cd_nelmts = NELMTS(cd_values);
+ filt_id = H5Pget_filter2(dcpl, (unsigned)i, &filt_flags, &cd_nelmts,
+ cd_values, sizeof(f_name), f_name, NULL);
+ f_name[sizeof(f_name) - 1] = '\0';
+ HDsnprintf(s, sizeof(s), "Filter-%d:", i);
+ h5tools_str_append(&buffer, " %-10s %s-%u %s {", s,
+ (f_name[0] ? f_name : "method"),
+ (unsigned)filt_id,
+ ((filt_flags & H5Z_FLAG_OPTIONAL) ? "OPT" : ""));
+ for(cd_num = 0; cd_num < cd_nelmts; cd_num++)
+ h5tools_str_append(&buffer, "%s%u", (cd_num ? ", " : ""), cd_values[cd_num]);
+ h5tools_str_append(&buffer, "}\n");
+ } /* end for */
+ } /* end if */
+
+ /* Print data type */
+ h5tools_str_append(&buffer, " %-10s ", "Type:");
+ print_type(&buffer, type, 15);
+ h5tools_str_append(&buffer, "\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* Print address information */
+ if(address_g)
+ H5Ddebug(dset);
+
+ /* Close stuff */
+ H5Tclose(type);
+ H5Sclose(space);
+ H5Pclose(dcpl);
+ } /* end if */
+
+ h5tools_str_close(&buffer);
+
+ if(data_g)
+ dump_dataset_values(dset);
+
+ return 0;
+} /* end dataset_list2() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: datatype_list2
+ *
+ * Purpose: List information about a datatype which should appear after
+ * information which is general to all objects.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+datatype_list2(hid_t type, const char H5_ATTR_UNUSED *name)
+{
+ if (verbose_g>0) {
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *info = &ls_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ h5tools_str_reset(&buffer);
+
+ h5tools_str_append(&buffer, " %-10s ", "Type:");
+ print_type(&buffer, type, 15);
+ h5tools_str_append(&buffer, "\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+ }
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: list_obj
+ *
+ * Purpose: Prints information about an object
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, November 6, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void *_iter)
+{
+ H5O_type_t obj_type = oinfo->type; /* Type of the object */
+ iter_t *iter = (iter_t*)_iter;
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *info = &ls_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ h5tools_str_reset(&buffer);
+
+ /* Print the link's name, either full name or base name */
+ if(!iter->symlink_target)
+ print_obj_name(&buffer, iter, name, "");
+
+ /* Check object information */
+ if(oinfo->type < 0 || oinfo->type >= H5O_TYPE_NTYPES) {
+ h5tools_str_append(&buffer, "Unknown type(%d)", (int)oinfo->type);
+ obj_type = H5O_TYPE_UNKNOWN;
+ }
+ if(iter->symlink_target)
+ h5tools_str_append(&buffer, "{");
+ if(obj_type >= 0 && dispatch_g[obj_type].name)
+ h5tools_str_append(&buffer, "%s", dispatch_g[obj_type].name);
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* Check if we've seen this object before */
+ if(first_seen) {
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, ", same as ");
+ print_string(&buffer, first_seen, TRUE);
+ if(!iter->symlink_target) {
+ h5tools_str_append(&buffer, "\n");
+ }
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ } /* end if */
+ else {
+ hid_t obj = (-1); /* ID of object opened */
+
+ /* Open the object. Not all objects can be opened. If this is the case
+ * then return right away.
+ */
+ if(obj_type >= 0 && (obj = H5Oopen(iter->fid, name, H5P_DEFAULT)) < 0) {
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " *ERROR*\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ goto done;
+ } /* end if */
+
+ /* List the first line of information for the object. */
+ if(obj_type >= 0 && dispatch_g[obj_type].list1)
+ (dispatch_g[obj_type].list1)(obj);
+ if(!iter->symlink_target || (verbose_g > 0)) {
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ /* Show detailed information about the object, beginning with information
+ * which is common to all objects. */
+ if(verbose_g > 0) {
+ size_t buf_size = 0;
+ char* comment = NULL;
+ ssize_t cmt_bufsize = -1;
+
+ /* Display attributes */
+ if(obj_type >= 0)
+ H5Aiterate2(obj, H5_INDEX_NAME, H5_ITER_INC, NULL, list_attr, NULL);
+
+ /* Object location & reference count */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " %-10s %lu:"H5_PRINTF_HADDR_FMT"\n", "Location:", oinfo->fileno, oinfo->addr);
+ h5tools_str_append(&buffer, " %-10s %u\n", "Links:", (unsigned)oinfo->rc);
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* Modification time */
+ if(oinfo->mtime > 0) {
+ char buf[256];
+ struct tm *tm;
+
+ if(simple_output_g)
+ tm = HDgmtime(&(oinfo->mtime));
+ else
+ tm = HDlocaltime(&(oinfo->mtime));
+ if(tm) {
+ HDstrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " %-10s %s\n", "Modified:", buf);
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ } /* end if */
+ } /* end if */
+
+ /* Object comment */
+ cmt_bufsize = H5Oget_comment(obj, comment, buf_size);
+
+ /* if the actual length of the comment is longer than cmt_bufsize, then call
+ * H5Oget_comment again with the correct value.
+ * If the call to H5Oget_comment returned an error, skip this block */
+ if (cmt_bufsize > 0) {
+ comment = (char *)HDmalloc((size_t)cmt_bufsize + 1); /* new_size including null terminator */
+ if(comment) {
+ cmt_bufsize = H5Oget_comment(obj, comment, (size_t)cmt_bufsize);
+ if(cmt_bufsize > 0) {
+ comment[cmt_bufsize] = 0;
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " %-10s \"", "Comment:");
+ print_string(&buffer, comment, FALSE);
+ h5tools_str_append(&buffer, "\"\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ } /* end if */
+ HDfree(comment);
+ }
+ }
+ } /* end if */
+
+ /* Detailed list for object */
+ if(obj_type >= 0 && dispatch_g[obj_type].list2)
+ (dispatch_g[obj_type].list2)(obj, name);
+
+ /* Close the object. */
+ if(obj_type >= 0)
+ H5Oclose(obj);
+ } /* end else */
+
+done:
+ if(iter->symlink_target) {
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "}\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ iter->symlink_target = FALSE;
+ }
+ h5tools_str_close(&buffer);
+
+ return 0;
+} /* end list_obj() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: list_lnk
+ *
+ * Purpose: Prints information about a link
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, November 8, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+list_lnk(const char *name, const H5L_info_t *linfo, void *_iter)
+{
+ char *buf=NULL;
+ iter_t *iter = (iter_t*)_iter;
+ int ret;
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tool_link_info_t lnk_info;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *info = &ls_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ h5tools_str_reset(&buffer);
+
+ /* init linkinfo struct */
+ HDmemset(&lnk_info, 0, sizeof(h5tool_link_info_t));
+
+ /* if verbose, make H5tools_get_symlink_info() display more */
+ if (verbose_g)
+ lnk_info.opt.msg_mode=1;
+
+ /* Print the link's name, either full name or base name */
+ print_obj_name(&buffer, iter, name, "");
+
+ switch(linfo->type) {
+ case H5L_TYPE_SOFT:
+ ret = H5tools_get_symlink_info(iter->fid, name, &lnk_info, follow_symlink_g);
+ /* lnk_info.trg_path is malloced in H5tools_get_symlink_info()
+ * so it will be freed via buf later */
+ buf = (char*)lnk_info.trg_path;
+ /* error */
+ if (ret < 0)
+ goto done;
+ /* no dangling link option given and detect dangling link */
+ else if (no_dangling_link_g && ret == 0)
+ iter->symlink_list->dangle_link = TRUE;
+
+ h5tools_str_append(&buffer, "Soft Link {");
+ h5tools_str_append(&buffer, buf);
+ h5tools_str_append(&buffer, "}");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ if(follow_symlink_g)
+ {
+ hbool_t orig_grp_literal = grp_literal_g;
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " ");
+
+ /* Check if we have already seen this softlink */
+ if(symlink_is_visited(iter->symlink_list, linfo->type, NULL, buf))
+ {
+ h5tools_str_append(&buffer, "{Already Visited}\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ goto done;
+ }
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* Add this link to the list of seen softlinks */
+ if(symlink_visit_add(iter->symlink_list, linfo->type, NULL, buf) < 0)
+ goto done;
+
+ /* Adjust user data to specify that we are operating on the
+ * target of an soft link */
+ iter->symlink_target = TRUE;
+
+ /* Prevent recursive listing of soft link target if
+ * recursive_g is off */
+ if(!recursive_g)
+ grp_literal_g = TRUE;
+ /* Recurse through the soft link */
+ if(visit_obj(iter->fid, name, iter) < 0)
+ {
+ grp_literal_g = orig_grp_literal;
+ goto done;
+ }
+
+ grp_literal_g = orig_grp_literal;
+ }
+ else {
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ break;
+
+ case H5L_TYPE_EXTERNAL:
+ {
+ const char *filename;
+ const char *path;
+ hbool_t follow_link = follow_symlink_g || follow_elink_g;
+
+ ret = H5tools_get_symlink_info(iter->fid, name, &lnk_info, follow_link);
+ /* lnk_info.trg_path is malloced in H5tools_get_symlink_info()
+ * so it will be freed via buf later */
+ buf = (char*)lnk_info.trg_path;
+ /* error */
+ if (ret < 0)
+ goto done;
+ /* no dangling link option given and detect dangling link */
+ else if (no_dangling_link_g && ret == 0)
+ iter->symlink_list->dangle_link = TRUE;
+
+ if(H5Lunpack_elink_val(buf, linfo->u.val_size, NULL, &filename, &path) < 0)
+ goto done;
+
+ h5tools_str_append(&buffer, "External Link {");
+ h5tools_str_append(&buffer, filename);
+ h5tools_str_append(&buffer, "/");
+ if(*path != '/')
+ h5tools_str_append(&buffer, "/");
+ h5tools_str_append(&buffer, path);
+ h5tools_str_append(&buffer, "}");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* Recurse through the external link */
+ /* keep the follow_elink_g for backward compatibility with -E */
+ if(follow_link)
+ {
+ hbool_t orig_grp_literal = grp_literal_g;
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, " ");
+
+ /* Check if we have already seen this elink */
+ if(symlink_is_visited(iter->symlink_list, linfo->type, filename, path))
+ {
+ h5tools_str_append(&buffer, "{Already Visited}\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ goto done;
+ }
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* Add this link to the list of seen elinks */
+ if(symlink_visit_add(iter->symlink_list, linfo->type, filename, path) < 0)
+ {
+ goto done;
+ }
+
+ /* Adjust user data to specify that we are operating on the
+ * target of an external link */
+ iter->symlink_target = TRUE;
+
+ /* Prevent recursive listing of external link target if
+ * recursive_g is off */
+ if(!recursive_g)
+ grp_literal_g = TRUE;
+
+ /* Recurse through the external link */
+ if(visit_obj(iter->fid, name, iter) < 0) {
+ grp_literal_g = orig_grp_literal;
+ goto done;
+ }
+
+ grp_literal_g = orig_grp_literal;
+ }
+ else
+ PRINTVALSTREAM(rawoutstream, "\n");
+ }
+ break;
+
+ case H5L_TYPE_ERROR:
+ case H5L_TYPE_HARD:
+ case H5L_TYPE_MAX:
+ default:
+ h5tools_str_append(&buffer, "UD Link {cannot follow UD links}\n");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ break;
+ } /* end switch */
+
+done:
+ h5tools_str_close(&buffer);
+
+ if (buf)
+ HDfree(buf);
+ return 0;
+} /* end list_lnk() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: visit_obj
+ *
+ * Purpose: Begins iteration on an object
+ *
+ * Return:
+ * Success: 0
+ * Failure: -1
+ *
+ * Programmer: Neil Fortner
+ * Wednesday, August 21, 2008
+ * Mostly copied from main()
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+visit_obj(hid_t file, const char *oname, iter_t *iter)
+{
+ int retval = 0;
+ H5O_info_t oi; /* Information for object */
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *info = &ls_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ h5tools_str_reset(&buffer);
+
+ /* Retrieve info for object to list */
+ if(H5Oget_info_by_name(file, oname, &oi, H5P_DEFAULT) < 0) {
+ if(iter->symlink_target) {
+ h5tools_str_append(&buffer, "{**NOT FOUND**}\n");
+ iter->symlink_target = FALSE;
+ }
+ else
+ print_obj_name(&buffer, iter, oname, "**NOT FOUND**");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ retval = -1;
+ goto done;
+ } /* end if */
+
+ /* Check for group iteration */
+ if(H5O_TYPE_GROUP == oi.type && !grp_literal_g) {
+ /* Get ID for group */
+ if(!iter->symlink_target && (iter->gid = H5Gopen2(file, oname, H5P_DEFAULT)) < 0) {
+ h5tools_str_append(&buffer, "%s: unable to open '%s' as group\n", iter->fname, oname);
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ goto done; /* Previously "continue", when this code was in main().
+ * We don't "continue" here in order to close the file
+ * and free the file name properly. */
+ } /* end if */
+
+ /* Delay specifying the name start point so the original object name is
+ * displayed if it is a link or non-group object */
+ iter->name_start = iter->base_len;
+
+ /* Specified name is a group. List the complete contents of the group. */
+ h5trav_visit(file, oname, (hbool_t) (display_root_g || iter->symlink_target), recursive_g, list_obj, list_lnk, iter);
+
+ /* Close group */
+ if(!iter->symlink_target)
+ H5Gclose(iter->gid);
+ } /* end if */
+ else {
+ /* Use file ID for root group ID */
+ iter->gid = file;
+
+ /* Specified name is a non-group object -- list that object */
+ list_obj(oname, &oi, NULL, iter);
+ } /* end else */
+
+done:
+ h5tools_str_close(&buffer);
+
+ return retval;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_width
+ *
+ * Purpose: Figure out how wide the screen is. This is highly
+ * unportable, but the user can always override the width we
+ * detect by giving a command-line option. These code snippets
+ * were borrowed from the GNU less(1).
+ *
+ * Return: Success: Number of columns.
+ *
+ * Failure: Some default number of columms.
+ *
+ * Programmer: Robb Matzke
+ * Friday, November 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+get_width(void)
+{
+ int width = 80; /*the default */
+ char *s;
+
+ /* Try to get it from the COLUMNS environment variable first since it's
+ * value is sometimes wrong. */
+ if ((s=HDgetenv("COLUMNS")) && *s && isdigit((int)*s))
+ width = (int)HDstrtol(s, NULL, 0);
+
+#if defined(H5_HAVE_STRUCT_VIDEOCONFIG) && defined(H5_HAVE__GETVIDEOCONFIG)
+ {
+ /* Microsoft C */
+ struct videoconfig w;
+ _getvideoconfig(&w);
+ width = w.numtextcols;
+ }
+#elif defined(H5_HAVE_STRUCT_TEXT_INFO) && defined(H5_HAVE_GETTEXTINFO)
+ {
+ /* Borland C or DJGPPC */
+ struct text_info w;
+ gettextinfo(&w);
+ width = w.screenwidth;
+ }
+#elif defined(H5_HAVE_GETCONSOLESCREENBUFFERINFO)
+ {
+ /* Win32 C */
+ CONSOLE_SCREEN_BUFFER_INFO scr;
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &scr);
+ width = scr.srWindow.Right - scr.srWindow.Left + 1;
+ }
+#elif defined(H5_HAVE__SCRSIZE)
+ {
+ /* OS/2 */
+ int w[2];
+ _scrsize(w);
+ width = w[0];
+ }
+#elif defined(H5_HAVE_TIOCGWINSZ) && defined(H5_HAVE_IOCTL)
+ {
+ /* Unix with ioctl(TIOCGWINSZ) */
+ struct winsize w;
+ if (ioctl(2, (int)TIOCGWINSZ, &w)>=0 && w.ws_col>0)
+ width = w.ws_col;
+ }
+#elif defined(H5_HAVE_TIOCGETD) && defined(H5_HAVE_IOCTL)
+ {
+ /* Unix with ioctl(TIOCGETD) */
+ struct uwdata w;
+ if (ioctl(2, WIOCGETD, &w)>=0 && w.uw_width>0)
+ width = w.uw_width / w.uw_hs;
+ }
+#endif
+
+ /* Set to at least 1 */
+ if (width<1) width = 1;
+ return width;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: is_valid_args
+ *
+ * Purpose: check if command line arguments are valid
+ *
+ * Return:
+ * Success: TRUE (1)
+ * Failure: FALSE (0)
+ *
+ * Programmer:
+ * Jonathan Kim (06/15/2010)
+ *
+ *-------------------------------------------------------------------------*/
+static hbool_t
+is_valid_args(void)
+{
+ hbool_t ret = TRUE;
+
+ if(recursive_g && grp_literal_g)
+ {
+ HDfprintf(rawerrorstream, "Error: 'recursive' option not compatible with 'group info' option!\n\n");
+ ret = FALSE;
+ goto out;
+ }
+
+ if(no_dangling_link_g && !follow_symlink_g)
+ {
+ HDfprintf(rawerrorstream, "Error: --no-dangling-links must be used along with --follow-symlinks option!\n\n");
+ ret = FALSE;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: leave
+ *
+ * Purpose: Close HDF5 and MPI and call exit()
+ *
+ * Return: Does not return
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, January 31, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+leave(int ret)
+{
+ h5tools_close();
+
+ HDexit(ret);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Opens a file and lists the specified group
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Robb Matzke
+ * Monday, March 23, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, const char *argv[])
+{
+ hid_t file = -1;
+ char *fname = NULL, *oname = NULL, *x;
+ const char *s = NULL;
+ char *rest;
+ int argno;
+ static char root_name[] = "/";
+ char drivername[50];
+ const char *preferred_driver = NULL;
+ int err_exit = 0;
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /* Build object display table */
+ DISPATCH(H5O_TYPE_GROUP, "Group", NULL, NULL);
+ DISPATCH(H5O_TYPE_DATASET, "Dataset", dataset_list1, dataset_list2);
+ DISPATCH(H5O_TYPE_NAMED_DATATYPE, "Type", NULL, datatype_list2);
+
+ /* Default output width */
+ width_g = get_width();
+
+ /* Switches come before non-switch arguments */
+ for(argno = 1; argno < argc && '-' == argv[argno][0]; argno++) {
+ if(!HDstrcmp(argv[argno], "--")) {
+ /* Last switch */
+ argno++;
+ break;
+ } else if(!HDstrcmp(argv[argno], "--help")) {
+ usage();
+ leave(EXIT_SUCCESS);
+ } else if(!HDstrcmp(argv[argno], "--address")) {
+ address_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--data")) {
+ data_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--enable-error-stack")) {
+ show_errors_g = TRUE;
+ /* deprecated --errors */
+ } else if(!HDstrcmp(argv[argno], "--errors")) {
+ show_errors_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--follow-symlinks")) {
+ follow_symlink_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--no-dangling-links")) {
+ no_dangling_link_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--external")) {
+ follow_elink_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--full")) {
+ fullname_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--group")) {
+ grp_literal_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--label")) {
+ label_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--recursive")) {
+ recursive_g = TRUE;
+ fullname_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--simple")) {
+ simple_output_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--string")) {
+ string_g = TRUE;
+ } else if(!HDstrncmp(argv[argno], "--vfd=", (size_t)6)) {
+ preferred_driver = argv[argno]+6;
+ } else if(!HDstrncmp(argv[argno], "--width=", (size_t)8)) {
+ width_g = (int)HDstrtol(argv[argno]+8, &rest, 0);
+
+ if(0 == width_g)
+ no_line_wrap_g = TRUE;
+ else if(width_g < 0 || *rest) {
+ usage();
+ leave(EXIT_FAILURE);
+ }
+ } else if(!HDstrcmp(argv[argno], "--width")) {
+ if((argno + 1) >= argc) {
+ usage();
+ leave(EXIT_FAILURE);
+ } else {
+ s = argv[++argno];
+ }
+ width_g = (int)HDstrtol(s, &rest, 0);
+ if(width_g <= 0 || *rest) {
+ usage();
+ leave(EXIT_FAILURE);
+ }
+ } else if(!HDstrcmp(argv[argno], "--verbose")) {
+ verbose_g++;
+ } else if(!HDstrcmp(argv[argno], "--version")) {
+ print_version(h5tools_getprogname());
+ leave(EXIT_SUCCESS);
+ } else if(!HDstrcmp(argv[argno], "--hexdump")) {
+ hexdump_g = TRUE;
+ } else if(!HDstrncmp(argv[argno], "-w", (size_t)2)) {
+ if(argv[argno][2]) {
+ s = argv[argno] + 2;
+ } else if((argno + 1) >= argc) {
+ usage();
+ leave(EXIT_FAILURE);
+ } else {
+ s = argv[++argno];
+ }
+ width_g = (int)HDstrtol(s, &rest, 0);
+
+ if(0 == width_g)
+ no_line_wrap_g = TRUE;
+ else if(width_g < 0 || *rest) {
+ usage();
+ leave(EXIT_FAILURE);
+ }
+ } else if('-'!=argv[argno][1]) {
+ /* Single-letter switches */
+ for(s = argv[argno] + 1; *s; s++) {
+ switch(*s) {
+ case '?':
+ case 'h': /* --help */
+ usage();
+ leave(EXIT_SUCCESS);
+
+ case 'a': /* --address */
+ address_g = TRUE;
+ break;
+
+ case 'd': /* --data */
+ data_g = TRUE;
+ break;
+
+ /* deprecated -e */
+ case 'e': /* --errors */
+ show_errors_g = TRUE;
+ break;
+
+ case 'E': /* --external */
+ follow_elink_g = TRUE;
+ break;
+
+ case 'f': /* --full */
+ fullname_g = TRUE;
+ break;
+
+ case 'g': /* --group */
+ grp_literal_g = TRUE;
+ break;
+
+ case 'l': /* --label */
+ label_g = TRUE;
+ break;
+
+ case 'r': /* --recursive */
+ recursive_g = TRUE;
+ fullname_g = TRUE;
+ break;
+
+ case 'S': /* --simple */
+ simple_output_g = TRUE;
+ break;
+
+ case 's': /* --string */
+ string_g = TRUE;
+ break;
+
+ case 'v': /* --verbose */
+ verbose_g++;
+ break;
+
+ case 'V': /* --version */
+ print_version(h5tools_getprogname());
+ leave(EXIT_SUCCESS);
+
+ case 'x': /* --hexdump */
+ hexdump_g = TRUE;
+ break;
+
+ default:
+ usage();
+ leave(EXIT_FAILURE);
+ } /* end switch */
+ } /* end for */
+ } else {
+ usage();
+ leave(EXIT_FAILURE);
+ }
+ } /* end for */
+
+ /* If no arguments remain then print a usage message (instead of doing
+ * absolutely nothing ;-) */
+ if(argno >= argc) {
+ usage();
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Check for conflicting arguments */
+ if (!is_valid_args())
+ {
+ usage();
+ leave(EXIT_FAILURE);
+ }
+
+ /* Turn off HDF5's automatic error printing unless you're debugging h5ls */
+ if(!show_errors_g)
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+
+ /* Each remaining argument is an hdf5 file followed by an optional slash
+ * and object name.
+ *
+ * Example: ../dir1/foo/bar/baz
+ * \_________/\______/
+ * file obj
+ *
+ * The dichotomy is determined by calling H5Fopen() repeatedly until it
+ * succeeds. The first call uses the entire name and each subsequent call
+ * chops off the last component. If we reach the beginning of the name
+ * then there must have been something wrong with the file (perhaps it
+ * doesn't exist). */
+ show_file_name_g = (argc-argno > 1); /*show file names if more than one*/
+ while(argno < argc) {
+ H5L_info_t li;
+ iter_t iter;
+ symlink_trav_t symlink_list;
+ size_t u;
+
+ fname = HDstrdup(argv[argno++]);
+ oname = NULL;
+ file = -1;
+
+ while(fname && *fname) {
+ file = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, preferred_driver, drivername, sizeof drivername);
+
+ if(file >= 0) {
+ if(verbose_g)
+ PRINTSTREAM(rawoutstream, "Opened \"%s\" with %s driver.\n", fname, drivername);
+ break; /*success*/
+ } /* end if */
+
+ /* Shorten the file name; lengthen the object name */
+ x = oname;
+ oname = HDstrrchr(fname, '/');
+ if(x)
+ *x = '/';
+ if(!oname)
+ break;
+ *oname = '\0';
+ } /* end while */
+
+ if(file < 0) {
+ HDfprintf(rawerrorstream, "%s: unable to open file\n", argv[argno-1]);
+ HDfree(fname);
+ err_exit = 1;
+ continue;
+ } /* end if */
+ if(oname) {
+ /* Always use absolute paths to avoid confusion, keep track of where
+ * to begin path name output */
+ *oname = '/';
+ iter.base_len = HDstrlen(oname);
+ iter.base_len -= oname[iter.base_len-1] == '/';
+ x = oname;
+ if(NULL == (oname = HDstrdup(oname))) {
+ HDfprintf(rawerrorstream, "memory allocation failed\n");
+ leave(EXIT_FAILURE);
+ }
+ *x = '\0';
+ /* Delay specifying the name start point so the original object name
+ * is displayed if it is a link or non-group object */
+ iter.name_start = 1;
+ }
+ if(!oname || !*oname) {
+ oname = root_name;
+ if(recursive_g)
+ display_root_g = TRUE;
+ iter.base_len = 0;
+ iter.name_start = 0;
+ /* Use x to remember if we have allocated space in oname */
+ x = NULL;
+ } /* end if */
+
+ /* Remember the file information for later */
+ iter.fname = fname;
+ iter.fid = file;
+ iter.gid = -1;
+ iter.symlink_target = FALSE;
+ iter.symlink_list = &symlink_list;
+ iter.symlink_list->dangle_link = FALSE;
+
+ /* Initialize list of visited symbolic links */
+ symlink_list.nused = symlink_list.nalloc = 0;
+ symlink_list.objs = NULL;
+
+ /* Check for root group as object name */
+ if(HDstrcmp(oname, root_name)) {
+ /* Check the type of link given */
+ if(H5Lget_info(file, oname, &li, H5P_DEFAULT) < 0) {
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *info = &ls_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ h5tools_str_reset(&buffer);
+ print_obj_name(&buffer, &iter, oname, "**NOT FOUND**");
+ h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0);
+ leave(EXIT_FAILURE);
+ } /* end if */
+ } /* end if */
+ else
+ li.type = H5L_TYPE_HARD;
+
+ /* Open the object and display it's information */
+ if(li.type == H5L_TYPE_HARD) {
+ if(visit_obj(file, oname, &iter) < 0)
+ leave(EXIT_FAILURE);
+ } /* end if(li.type == H5L_TYPE_HARD) */
+ else {
+ /* Specified name is not for object -- list that link */
+ /* Use file ID for root group ID */
+ iter.gid = file;
+ list_lnk(oname, &li, &iter);
+ }
+ H5Fclose(file);
+ HDfree(fname);
+ if(x)
+ HDfree(oname);
+
+ for(u=0; u < symlink_list.nused; u++)
+ {
+ if (symlink_list.objs[u].type == H5L_TYPE_EXTERNAL)
+ HDfree(symlink_list.objs[u].file);
+
+ HDfree(symlink_list.objs[u].path);
+ }
+ HDfree(symlink_list.objs);
+
+ /* if no-dangling-links option specified and dangling link found */
+ if (no_dangling_link_g && iter.symlink_list->dangle_link)
+ err_exit = 1;
+ } /* end while */
+
+ if (err_exit)
+ leave(EXIT_FAILURE);
+ else
+ leave(EXIT_SUCCESS);
+} /* end main() */
+
diff --git a/tools/src/h5repack/CMakeLists.txt b/tools/src/h5repack/CMakeLists.txt
new file mode 100644
index 0000000..cb7f5f6
--- /dev/null
+++ b/tools/src/h5repack/CMakeLists.txt
@@ -0,0 +1,50 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_H5REPACK)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+INCLUDE_DIRECTORIES (${HDF5_TEST_SRC_DIR})
+
+# --------------------------------------------------------------------
+# Add h5Repack executables
+# --------------------------------------------------------------------
+set (REPACK_COMMON_SOURCES
+ ${HDF5_TOOLS_SRC_H5REPACK_SOURCE_DIR}/h5repack_copy.c
+ ${HDF5_TOOLS_SRC_H5REPACK_SOURCE_DIR}/h5repack_filters.c
+ ${HDF5_TOOLS_SRC_H5REPACK_SOURCE_DIR}/h5repack_opttable.c
+ ${HDF5_TOOLS_SRC_H5REPACK_SOURCE_DIR}/h5repack_parse.c
+ ${HDF5_TOOLS_SRC_H5REPACK_SOURCE_DIR}/h5repack_refs.c
+ ${HDF5_TOOLS_SRC_H5REPACK_SOURCE_DIR}/h5repack_verify.c
+ ${HDF5_TOOLS_SRC_H5REPACK_SOURCE_DIR}/h5repack.c
+)
+
+add_executable (h5repack ${REPACK_COMMON_SOURCES} ${HDF5_TOOLS_SRC_H5REPACK_SOURCE_DIR}/h5repack_main.c)
+TARGET_NAMING (h5repack STATIC)
+TARGET_C_PROPERTIES (h5repack STATIC " " " ")
+target_link_libraries (h5repack ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5repack PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5repack")
+
+set (H5_DEP_EXECUTABLES h5repack)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5repack ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5repack
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
diff --git a/tools/src/h5repack/Makefile.am b/tools/src/h5repack/Makefile.am
new file mode 100644
index 0000000..e6e5a56
--- /dev/null
+++ b/tools/src/h5repack/Makefile.am
@@ -0,0 +1,42 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src, test, and tools/lib directories
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/test -I$(top_srcdir)/tools/lib
+
+# Our main target, h5repack tool
+bin_PROGRAMS=h5repack
+
+# Add h5repack specific linker flags here
+h5repack_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# Depend on the hdf5 library, the tools library, the test library
+LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5)
+
+# Source files
+COMMON_SOURCES=h5repack.c h5repack_copy.c h5repack_filters.c \
+ h5repack_opttable.c h5repack_parse.c h5repack_refs.c \
+ h5repack_verify.c
+
+h5repack_SOURCES=$(COMMON_SOURCES) h5repack_main.c
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/h5repack/h5repack.c b/tools/src/h5repack/h5repack.c
new file mode 100644
index 0000000..ef2085c
--- /dev/null
+++ b/tools/src/h5repack/h5repack.c
@@ -0,0 +1,942 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "H5private.h"
+#include "h5repack.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/*-------------------------------------------------------------------------
+ * File: h5repack.c
+ * Purpose: Public API functions
+ *-------------------------------------------------------------------------
+ */
+
+static int check_options(pack_opt_t *options);
+static int check_objects(const char* fname, pack_opt_t *options);
+static const char* get_sfilter(H5Z_filter_t filtn);
+static int have_request(pack_opt_t *options);
+
+/*-------------------------------------------------------------------------
+ * Function: h5repack
+ *
+ * Purpose: locate all high-level HDF5 objects in the file
+ * and compress/chunk them using options
+ *
+ * Algorithm: 2 traversals are made to the file; the 1st builds a list of
+ * the objects, the 2nd makes a copy of them, using the options;
+ * the reason for the 1st traversal is to check for invalid
+ * object name requests
+ *
+ * Return: 0, ok, -1, fail
+ *
+ * Programmer: pvn@ncsa.uiuc.edu
+ *
+ * Date: September, 22, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+int h5repack(const char* infile, const char* outfile, pack_opt_t *options) {
+ /* check input */
+ if (check_options(options) < 0)
+ return -1;
+
+ /* check for objects in input that are in the file */
+ if (check_objects(infile, options) < 0)
+ return -1;
+
+ /* copy the objects */
+ if (copy_objects(infile, outfile, options) < 0)
+ return -1;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: h5repack_init
+ *
+ * Purpose: initialize options
+ *
+ * Return: 0, ok, -1, fail
+ *
+ *-------------------------------------------------------------------------
+ */
+int h5repack_init(pack_opt_t *options, int verbose, hbool_t latest,
+ H5F_file_space_type_t strategy, hsize_t threshold) {
+ int k, n;
+
+ HDmemset(options, 0, sizeof(pack_opt_t));
+ options->min_comp = 0;
+ options->verbose = verbose;
+ options->latest = latest;
+ options->layout_g = H5D_LAYOUT_ERROR;
+
+ for (n = 0; n < H5_REPACK_MAX_NFILTERS; n++) {
+ options->filter_g[n].filtn = -1;
+ options->filter_g[n].cd_nelmts = 0;
+ for (k = 0; k < CD_VALUES; k++)
+ options->filter_g[n].cd_values[k] = 0;
+ }
+
+ options->fs_strategy = strategy;
+ options->fs_threshold = threshold;
+
+ return (options_table_init(&(options->op_tbl)));
+}
+
+/*-------------------------------------------------------------------------
+ * Function: h5repack_end
+ *
+ * Purpose: free options table
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int h5repack_end(pack_opt_t *options) {
+ return options_table_free(options->op_tbl);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: h5repack_addfilter
+ *
+ * Purpose: add a compression -f option to table
+ * Example: -f dset:GZIP=6
+ *
+ * Return: 0, ok, -1, fail
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+h5repack_addfilter(const char* str, pack_opt_t *options)
+{
+ obj_list_t *obj_list = NULL; /* one object list for the -f and -l option entry */
+ filter_info_t filter; /* filter info for the current -f option entry */
+ unsigned n_objs; /* number of objects in the current -f or -l option entry */
+ int is_glb; /* is the filter global */
+
+ /* parse the -f option */
+ if (NULL == (obj_list = parse_filter(str, &n_objs, &filter, options, &is_glb)))
+ return -1;
+
+ /* if it applies to all objects */
+ if (is_glb) {
+ int n;
+
+ n = options->n_filter_g++; /* increase # of global filters */
+ if (options->n_filter_g > H5_REPACK_MAX_NFILTERS) {
+ error_msg("maximum number of filters exceeded for <%s>\n", str);
+ HDfree(obj_list);
+ return -1;
+ }
+
+ options->filter_g[n] = filter;
+ }
+ else
+ options_add_filter(obj_list, n_objs, filter, options->op_tbl);
+
+ HDfree(obj_list);
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: h5repack_addlayout
+ *
+ * Purpose: add a layout option
+ *
+ * Return: 0, ok, -1, fail
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+h5repack_addlayout(const char* str, pack_opt_t *options)
+{
+ obj_list_t *obj_list = NULL; /*one object list for the -t and -c option entry */
+ unsigned n_objs; /*number of objects in the current -t or -c option entry */
+ pack_info_t pack; /*info about layout to extract from parse */
+ int j;
+ int ret_value = -1;
+
+ init_packobject(&pack);
+
+ if (options->all_layout == 1) {
+ error_msg( "invalid layout input: 'all' option is present with other objects <%s>\n", str);
+ return ret_value;
+ }
+
+ /* parse the layout option */
+ obj_list = parse_layout(str, &n_objs, &pack, options);
+ if (obj_list) {
+ /* set layout option */
+ options->layout_g = pack.layout;
+
+ /* no individual dataset specified */
+ if (options->all_layout == 1) {
+ if (pack.layout == H5D_CHUNKED) {
+ /* -2 means the NONE option, remove chunking
+ and set the global layout to contiguous */
+ if (pack.chunk.rank == -2)
+ options->layout_g = H5D_CONTIGUOUS;
+ /* otherwise set the global chunking type */
+ else {
+ options->chunk_g.rank = pack.chunk.rank;
+ for (j = 0; j < pack.chunk.rank; j++)
+ options->chunk_g.chunk_lengths[j] = pack.chunk.chunk_lengths[j];
+ }
+ }
+ }
+
+ /* individual dataset specified */
+ if (options->all_layout == 0)
+ ret_value = options_add_layout(obj_list, n_objs, &pack, options->op_tbl);
+
+ HDfree(obj_list);
+ ret_value = 0;
+ }
+
+ return ret_value;
+}
+
+/* Note: The below copy_named_datatype(), named_datatype_free(), copy_attr()
+ * were located in h5repack_copy.c as static prior to bugfix1726.
+ * Made shared functions as copy_attr() was needed in h5repack_refs.c.
+ * However copy_attr() may be obsoleted when H5Acopy is available and put back
+ * others to static in h5repack_copy.c.
+ */
+/*-------------------------------------------------------------------------
+ * Function: copy_named_datatype
+ *
+ * Purpose: Copies the specified datatype anonymously, and returns an open
+ * id for that datatype in the output file. The first time this
+ * is called it scans every named datatype in travt into a
+ * private stack, afterwards it simply scans that stack. The id
+ * returned must be closed after it is no longer needed.
+ * named_datatype_free must be called before the program exits
+ * to free the stack.
+ *
+ * Programmer: Neil Fortner
+ *
+ * Date: April 14, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t copy_named_datatype(hid_t type_in, hid_t fidout,
+ named_dt_t **named_dt_head_p, trav_table_t *travt, pack_opt_t *options) {
+ named_dt_t *dt = *named_dt_head_p; /* Stack pointer */
+ named_dt_t *dt_ret = NULL; /* Datatype to return */
+ H5O_info_t oinfo; /* Object info of input dtype */
+ hid_t ret_value = -1; /* The identifier of the named dtype in the out file */
+
+ if (H5Oget_info(type_in, &oinfo) < 0)
+ goto done;
+
+ if (*named_dt_head_p) {
+ /* Stack already exists, search for the datatype */
+ while (dt && dt->addr_in != oinfo.addr)
+ dt = dt->next;
+
+ dt_ret = dt;
+ }
+ else {
+ /* Create the stack */
+ size_t i;
+
+ for (i = 0; i < travt->nobjs; i++) {
+ if (travt->objs[i].type == H5TRAV_TYPE_NAMED_DATATYPE) {
+ /* Push onto the stack */
+ if (NULL == (dt = (named_dt_t *) HDmalloc(sizeof(named_dt_t)))) {
+ goto done;
+ }
+ dt->next = *named_dt_head_p;
+ *named_dt_head_p = dt;
+
+ /* Update the address and id */
+ dt->addr_in = travt->objs[i].objno;
+ dt->id_out = -1;
+
+ /* Check if this type is the one requested */
+ if (oinfo.addr == dt->addr_in) {
+ HDassert(!dt_ret);
+ dt_ret = dt;
+ } /* end if */
+ } /* end if */
+ } /* end for */
+ } /* end else */
+
+ /* Handle the case that the requested datatype was not found. This is
+ * possible if the datatype was committed anonymously in the input file. */
+ if (!dt_ret) {
+ /* Push the new datatype onto the stack */
+ if (NULL == (dt_ret = (named_dt_t *) HDmalloc(sizeof(named_dt_t)))) {
+ goto done;
+ }
+ dt_ret->next = *named_dt_head_p;
+ *named_dt_head_p = dt_ret;
+
+ /* Update the address and id */
+ dt_ret->addr_in = oinfo.addr;
+ dt_ret->id_out = -1;
+ } /* end if */
+
+ /* If the requested datatype does not yet exist in the output file, copy it
+ * anonymously */
+ if (dt_ret->id_out < 0) {
+ if (options->use_native == 1)
+ dt_ret->id_out = h5tools_get_native_type(type_in);
+ else
+ dt_ret->id_out = H5Tcopy(type_in);
+ if (dt_ret->id_out < 0)
+ goto done;
+ if (H5Tcommit_anon(fidout, dt_ret->id_out, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ goto done;
+ } /* end if */
+
+ /* Set return value */
+ ret_value = dt_ret->id_out;
+
+ /* Increment the ref count on id_out, because the calling function will try
+ * to close it */
+ if(H5Iinc_ref(ret_value) < 0) {
+ ret_value = -1;
+ }
+
+done:
+ return (ret_value);
+} /* end copy_named_datatype */
+
+/*-------------------------------------------------------------------------
+ * Function: named_datatype_free
+ *
+ * Purpose: Frees the stack of named datatypes.
+ *
+ * Programmer: Neil Fortner
+ *
+ * Date: April 14, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+int named_datatype_free(named_dt_t **named_dt_head_p, int ignore_err) {
+ named_dt_t *dt = *named_dt_head_p;
+ int ret_value = -1;
+
+ while (dt) {
+ /* Pop the datatype off the stack and free it */
+ if (H5Tclose(dt->id_out) < 0 && !ignore_err)
+ goto done;
+ dt = dt->next;
+ HDfree(*named_dt_head_p);
+ *named_dt_head_p = dt;
+ } /* end while */
+
+ ret_value = 0;
+
+done:
+ return (ret_value);
+} /* end named_datatype_free */
+
+/*-------------------------------------------------------------------------
+ * Function: copy_attr
+ *
+ * Purpose: copy attributes located in LOC_IN, which is obtained either from
+ * loc_id = H5Gopen2( fid, name);
+ * loc_id = H5Dopen2( fid, name);
+ * loc_id = H5Topen2( fid, name);
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: October, 28, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+copy_attr(hid_t loc_in, hid_t loc_out, named_dt_t **named_dt_head_p,
+ trav_table_t *travt, pack_opt_t *options)
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ hid_t attr_id = -1; /* attr ID */
+ hid_t attr_out = -1; /* attr ID */
+ hid_t space_id = -1; /* space ID */
+ hid_t ftype_id = -1; /* file type ID */
+ hid_t wtype_id = -1; /* read/write type ID */
+ size_t msize; /* size of type */
+ void *buf = NULL; /* data buffer */
+ hsize_t nelmts; /* number of elements in dataset */
+ int rank; /* rank of dataset */
+ htri_t is_named; /* Whether the datatype is named */
+ hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */
+ char name[255];
+ H5O_info_t oinfo; /* object info */
+ int j;
+ unsigned u;
+ hbool_t is_ref = 0;
+ H5T_class_t type_class = -1;
+
+ if (H5Oget_info(loc_in, &oinfo) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Oget_info failed");
+
+ /*-------------------------------------------------------------------------
+ * copy all attributes
+ *-------------------------------------------------------------------------
+ */
+ for (u = 0; u < (unsigned) oinfo.num_attrs; u++) {
+ /* open attribute */
+ if ((attr_id = H5Aopen_by_idx(loc_in, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t) u, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aopen_by_idx failed");
+
+ /* get name */
+ if (H5Aget_name(attr_id, (size_t) 255, name) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+
+ /* get the file datatype */
+ if ((ftype_id = H5Aget_type(attr_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aget_type failed");
+
+ /* Check if the datatype is committed */
+ if ((is_named = H5Tcommitted(ftype_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tcommitted failed");
+ if (is_named && travt) {
+ hid_t fidout;
+
+ /* Create out file id */
+ if ((fidout = H5Iget_file_id(loc_out)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Iget_file_id failed");
+
+ /* Copy named dt */
+ if ((wtype_id = copy_named_datatype(ftype_id, fidout, named_dt_head_p, travt, options)) < 0) {
+ H5Fclose(fidout);
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_named_datatype failed");
+ } /* end if */
+
+ if (H5Fclose(fidout) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Fclose failed");
+ } /* end if */
+ else {
+ if (options->use_native == 1)
+ wtype_id = h5tools_get_native_type(ftype_id);
+ else
+ wtype_id = H5Tcopy(ftype_id);
+ } /* end else */
+
+ /* get the dataspace handle */
+ if ((space_id = H5Aget_space(attr_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aget_space failed");
+
+ /* get dimensions */
+ if ((rank = H5Sget_simple_extent_dims(space_id, dims, NULL)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed");
+
+ nelmts = 1;
+ for (j = 0; j < rank; j++)
+ nelmts *= dims[j];
+
+ if ((msize = H5Tget_size(wtype_id)) == 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed");
+
+ /*-------------------------------------------------------------------------
+ * object references are a special case. We cannot just copy the buffers,
+ * but instead we recreate the reference.
+ * This is done on a second sweep of the file that just copies the referenced
+ * objects at copy_refs_attr()
+ *-------------------------------------------------------------------------
+ */
+ type_class = H5Tget_class(wtype_id);
+ is_ref = (type_class == H5T_REFERENCE);
+ if (type_class == H5T_VLEN || type_class == H5T_ARRAY) {
+ hid_t base_type = -1;
+
+ base_type = H5Tget_super(ftype_id);
+ is_ref = (is_ref || (H5Tget_class(base_type) == H5T_REFERENCE));
+ H5Tclose(base_type);
+ }
+
+ if (type_class == H5T_COMPOUND) {
+ int nmembers = H5Tget_nmembers(wtype_id);
+
+ for (j = 0; j < nmembers; j++) {
+ hid_t mtid = H5Tget_member_type(wtype_id, (unsigned) j);
+ H5T_class_t mtclass = H5Tget_class(mtid);
+ H5Tclose(mtid);
+
+ if (mtclass == H5T_REFERENCE) {
+ is_ref = 1;
+ break;
+ }
+ } /* for (j=0; i<nmembers; j++) */
+ } /* if (type_class == H5T_COMPOUND) */
+
+ if (is_ref) {
+ ; /* handled by copy_refs_attr() */
+ }
+ else {
+ /*-------------------------------------------------------------------------
+ * read to memory
+ *-------------------------------------------------------------------------
+ */
+
+ buf = (void *) HDmalloc((size_t)(nelmts * msize));
+ if (buf == NULL) {
+ error_msg("h5repack", "cannot read into memory\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDmalloc failed");
+ } /* end if */
+ if (H5Aread(attr_id, wtype_id, buf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aread failed");
+
+ /*-------------------------------------------------------------------------
+ * copy
+ *-------------------------------------------------------------------------
+ */
+
+ if ((attr_out = H5Acreate2(loc_out, name, wtype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Acreate2 failed");
+ if (H5Awrite(attr_out, wtype_id, buf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Awrite failed");
+
+ /*close*/
+ if (H5Aclose(attr_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aclose failed");
+
+ /* Check if we have VL data and string in the attribute's datatype that must
+ * be reclaimed */
+ if (TRUE == h5tools_detect_vlen(wtype_id))
+ H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf);
+ HDfree(buf);
+ buf = NULL;
+ } /*H5T_REFERENCE*/
+
+ if (options->verbose)
+ printf(FORMAT_OBJ_ATTR, "attr", name);
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+
+ if (H5Tclose(ftype_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if (H5Tclose(wtype_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if (H5Sclose(space_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose failed");
+ if (H5Aclose(attr_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aclose failed");
+ } /* u */
+
+ return 0;
+
+done:
+ H5E_BEGIN_TRY {
+ if (buf) {
+ /* Check if we have VL data and string in the attribute's datatype that must
+ * be reclaimed */
+ if (TRUE == h5tools_detect_vlen(wtype_id))
+ H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf);
+
+ /* Free buf */
+ HDfree(buf);
+ } /* end if */
+
+ H5Tclose(ftype_id);
+ H5Tclose(wtype_id);
+ H5Sclose(space_id);
+ H5Aclose(attr_id);
+ H5Aclose(attr_out);
+ } H5E_END_TRY;
+
+ return ret_value;
+} /* end copy_attr() */
+
+/*-------------------------------------------------------------------------
+ * Function: check_options
+ *
+ * Purpose: print options, checks for invalid options
+ *
+ * Return: void, return -1 on error
+ *
+ * Programmer: pvn@ncsa.uiuc.edu
+ *
+ * Date: September, 22, 2003
+ *
+ * Modification:
+ * Peter Cao, July 9, 2007
+ * Add "-L, --latest" and other options to pack a file with the latest file format
+ *
+ *-------------------------------------------------------------------------
+ */
+static int check_options(pack_opt_t *options) {
+ unsigned int i;
+ int k, j, has_cp = 0, has_ck = 0;
+ char slayout[30];
+
+ /*-------------------------------------------------------------------------
+ * objects to layout
+ *-------------------------------------------------------------------------
+ */
+ if (options->verbose && have_request(options) /* only print if requested */) {
+ printf("Objects to modify layout are...\n");
+ if (options->all_layout == 1) {
+ switch (options->layout_g) {
+ case H5D_COMPACT:
+ strcpy(slayout, "compact");
+ break;
+ case H5D_CONTIGUOUS:
+ strcpy(slayout, "contiguous");
+ break;
+ case H5D_CHUNKED:
+ strcpy(slayout, "chunked");
+ break;
+ case H5D_VIRTUAL:
+ strcpy(slayout, "virtual");
+ break;
+ case H5D_LAYOUT_ERROR:
+ case H5D_NLAYOUTS:
+ error_msg("invalid layout\n");
+ return -1;
+ default:
+ strcpy(slayout, "invalid layout\n");
+ return -1;
+ }
+ printf(" Apply %s layout to all\n", slayout);
+ if (H5D_CHUNKED == options->layout_g) {
+ printf("with dimension [");
+ for (j = 0; j < options->chunk_g.rank; j++)
+ printf("%d ", (int) options->chunk_g.chunk_lengths[j]);
+ printf("]\n");
+ }
+ }
+ }/* verbose */
+
+ for (i = 0; i < options->op_tbl->nelems; i++) {
+ char* name = options->op_tbl->objs[i].path;
+
+ if (options->op_tbl->objs[i].chunk.rank > 0) {
+ if (options->verbose) {
+ printf(" <%s> with chunk size ", name);
+ for (k = 0; k < options->op_tbl->objs[i].chunk.rank; k++)
+ printf("%d ",
+ (int) options->op_tbl->objs[i].chunk.chunk_lengths[k]);
+ printf("\n");
+ }
+ has_ck = 1;
+ }
+ else if (options->op_tbl->objs[i].chunk.rank == -2) {
+ if (options->verbose)
+ printf(" <%s> %s\n", name, "NONE (contigous)");
+ has_ck = 1;
+ }
+ }
+
+ if (options->all_layout == 1 && has_ck) {
+ error_msg(
+ "invalid chunking input: 'all' option\
+ is present with other objects\n");
+ return -1;
+ }
+
+ /*-------------------------------------------------------------------------
+ * objects to filter
+ *-------------------------------------------------------------------------
+ */
+
+ if (options->verbose && have_request(options) /* only print if requested */) {
+ printf("Objects to apply filter are...\n");
+ if (options->all_filter == 1) {
+ for (k = 0; k < options->n_filter_g; k++) {
+ H5Z_filter_t filtn = options->filter_g[k].filtn;
+ switch (filtn) {
+ case H5Z_FILTER_NONE:
+ printf(" Uncompress all\n");
+ break;
+ case H5Z_FILTER_SHUFFLE:
+ case H5Z_FILTER_FLETCHER32:
+ printf(" All with %s\n", get_sfilter(filtn));
+ break;
+ case H5Z_FILTER_SZIP:
+ case H5Z_FILTER_DEFLATE:
+ printf(" All with %s, parameter %d\n", get_sfilter(filtn),
+ options->filter_g[k].cd_values[0]);
+ break;
+ default:
+ printf(" User Defined %d\n", filtn);
+ break;
+ } /* k */
+ };
+ }
+ } /* verbose */
+
+ for (i = 0; i < options->op_tbl->nelems; i++) {
+ pack_info_t pack = options->op_tbl->objs[i];
+ char* name = pack.path;
+
+ for (j = 0; j < pack.nfilters; j++) {
+ if (options->verbose) {
+ printf(" <%s> with %s filter\n", name,
+ get_sfilter(pack.filter[j].filtn));
+ }
+
+ has_cp = 1;
+
+ } /* j */
+ } /* i */
+
+ if (options->all_filter == 1 && has_cp) {
+ error_msg(
+ "invalid compression input: 'all' option\
+ is present with other objects\n");
+ return -1;
+ }
+
+ /*-------------------------------------------------------------------------
+ * check options for the latest format
+ *-------------------------------------------------------------------------
+ */
+
+ if (options->grp_compact < 0) {
+ error_msg(
+ "invalid maximum number of links to store as header messages\n");
+ return -1;
+ }
+ if (options->grp_indexed < 0) {
+ error_msg(
+ "invalid minimum number of links to store in the indexed format\n");
+ return -1;
+ }
+ if (options->grp_indexed > options->grp_compact) {
+ error_msg(
+ "minimum indexed size is greater than the maximum compact size\n");
+ return -1;
+ }
+ for (i = 0; i < 8; i++) {
+ if (options->msg_size[i] < 0) {
+ error_msg("invalid shared message size\n");
+ return -1;
+ }
+ }
+
+ /*--------------------------------------------------------------------------------
+ * verify new user userblock options; file name must be present
+ *---------------------------------------------------------------------------------
+ */
+ if (options->ublock_filename != NULL && options->ublock_size == 0) {
+ if (options->verbose) {
+ printf(
+ "Warning: user block size missing for file %s. Assigning a default size of 1024...\n",
+ options->ublock_filename);
+ options->ublock_size = 1024;
+ }
+ }
+
+ if (options->ublock_filename == NULL && options->ublock_size != 0) {
+ error_msg("file name missing for user block\n",
+ options->ublock_filename);
+ return -1;
+ }
+
+ /*--------------------------------------------------------------------------------
+ * verify alignment options; threshold is zero default but alignment not
+ *---------------------------------------------------------------------------------
+ */
+
+ if (options->alignment == 0 && options->threshold != 0) {
+ error_msg("alignment for H5Pset_alignment missing\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: check_objects
+ *
+ * Purpose: locate all HDF5 objects in the file and compare with user
+ * supplied list
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: September, 23, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+static int check_objects(const char* fname, pack_opt_t *options) {
+ hid_t fid;
+ unsigned int i;
+ trav_table_t *travt = NULL;
+
+ /* nothing to do */
+ if (options->op_tbl->nelems == 0)
+ return 0;
+
+ /*-------------------------------------------------------------------------
+ * open the file
+ *-------------------------------------------------------------------------
+ */
+ if ((fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, 0))
+ < 0) {
+ printf("<%s>: %s\n", fname, H5FOPENERROR);
+ return -1;
+ }
+
+ /*-------------------------------------------------------------------------
+ * get the list of objects in the file
+ *-------------------------------------------------------------------------
+ */
+
+ /* init table */
+ trav_table_init(&travt);
+
+ /* get the list of objects in the file */
+ if (h5trav_gettable(fid, travt) < 0)
+ goto out;
+
+ /*-------------------------------------------------------------------------
+ * compare with user supplied list
+ *-------------------------------------------------------------------------
+ */
+
+ if (options->verbose)
+ printf("Opening file <%s>. Searching for objects to modify...\n",
+ fname);
+
+ for (i = 0; i < options->op_tbl->nelems; i++) {
+ char* name = options->op_tbl->objs[i].path;
+ if (options->verbose)
+ printf(" <%s>", name);
+
+ /* the input object names are present in the file and are valid */
+ if (h5trav_getindext(name, travt) < 0) {
+ error_msg("%s Could not find <%s> in file <%s>. Exiting...\n",
+ (options->verbose ? "\n" : ""), name, fname);
+ goto out;
+ }
+ if (options->verbose)
+ printf("...Found\n");
+
+ /* check for extra filter conditions */
+ switch (options->op_tbl->objs[i].filter->filtn) {
+ /* chunk size must be smaller than pixels per block */
+ case H5Z_FILTER_SZIP:
+ {
+ int j;
+ hsize_t csize = 1;
+ unsigned ppb = options->op_tbl->objs[i].filter->cd_values[0];
+ hsize_t dims[H5S_MAX_RANK];
+ int rank;
+ hid_t did;
+ hid_t sid;
+
+ if (options->op_tbl->objs[i].chunk.rank > 0) {
+ rank = options->op_tbl->objs[i].chunk.rank;
+ for (j = 0; j < rank; j++)
+ csize *= options->op_tbl->objs[i].chunk.chunk_lengths[j];
+ }
+ else {
+ if ((did = H5Dopen2(fid, name, H5P_DEFAULT)) < 0)
+ goto out;
+ if ((sid = H5Dget_space(did)) < 0)
+ goto out;
+ if ((rank = H5Sget_simple_extent_ndims(sid)) < 0)
+ goto out;
+ HDmemset(dims, 0, sizeof dims);
+ if (H5Sget_simple_extent_dims(sid, dims, NULL) < 0)
+ goto out;
+ for (j = 0; j < rank; j++)
+ csize *= dims[j];
+ if (H5Sclose(sid) < 0)
+ goto out;
+ if (H5Dclose(did) < 0)
+ goto out;
+ }
+
+ if (csize < ppb) {
+ printf(
+ " <warning: SZIP settins, chunk size is smaller than pixels per block>\n");
+ goto out;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ } /* i */
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+ H5Fclose(fid);
+ trav_table_free(travt);
+ return 0;
+
+out:
+ H5Fclose(fid);
+ trav_table_free(travt);
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: have_request
+ *
+ * Purpose: check if a filter or layout was requested
+ *
+ * Return: 1 yes, 0 no
+ *
+ * Date: May, 24, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int have_request(pack_opt_t *options) {
+
+ if (options->all_filter || options->all_layout || options->op_tbl->nelems)
+ return 1;
+
+ return 0;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: get_sfilter
+ *
+ * Purpose: return the filter as a string name
+ *
+ * Return: name of filter, exit on error
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static const char* get_sfilter(H5Z_filter_t filtn) {
+ if (filtn == H5Z_FILTER_NONE)
+ return "NONE";
+ else if (filtn == H5Z_FILTER_DEFLATE)
+ return "GZIP";
+ else if (filtn == H5Z_FILTER_SZIP)
+ return "SZIP";
+ else if (filtn == H5Z_FILTER_SHUFFLE)
+ return "SHUFFLE";
+ else if (filtn == H5Z_FILTER_FLETCHER32)
+ return "FLETCHER32";
+ else if (filtn == H5Z_FILTER_NBIT)
+ return "NBIT";
+ else if (filtn == H5Z_FILTER_SCALEOFFSET)
+ return "SOFF";
+ else
+ return "UD";
+}
+
diff --git a/tools/src/h5repack/h5repack.h b/tools/src/h5repack/h5repack.h
new file mode 100644
index 0000000..d2ab923
--- /dev/null
+++ b/tools/src/h5repack/h5repack.h
@@ -0,0 +1,243 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+#ifndef H5REPACK_H__
+#define H5REPACK_H__
+
+#include "H5private.h"
+#include "hdf5.h"
+#include "h5trav.h"
+
+#define H5FOPENERROR "unable to open file"
+#define PFORMAT "%-7s %-7s %-7s\n" /* chunk info, compression info, name*/
+#define PFORMAT1 "%-7s %-7s %-7s" /* chunk info, compression info, name*/
+#define MAX_NC_NAME 256 /* max length of a name */
+#define MAX_VAR_DIMS 32 /* max per variable dimensions */
+#define FORMAT_OBJ " %-27s %s\n" /* obj type, name */
+#define FORMAT_OBJ_ATTR " %-27s %s\n" /* obj type, name */
+#define MAX_COMPACT_DSIZE 64512 /* max data size for compact layout. -1k for header size */
+
+/*-------------------------------------------------------------------------
+ * data structures for command line options
+ *-------------------------------------------------------------------------
+ */
+
+/* a list of names */
+typedef struct {
+ char obj[MAX_NC_NAME];
+} obj_list_t;
+
+/*
+ the type of filter and additional parameter
+ type can be one of the filters
+ H5Z_FILTER_NONE 0, uncompress if compressed
+ H5Z_FILTER_DEFLATE 1 , deflation like gzip
+ H5Z_FILTER_SHUFFLE 2 , shuffle the data
+ H5Z_FILTER_FLETCHER32 3 , letcher32 checksum of EDC
+ H5Z_FILTER_SZIP 4 , szip compression
+ H5Z_FILTER_NBIT 5 , nbit compression
+ H5Z_FILTER_SCALEOFFSET 6 , scaleoffset compression
+*/
+
+#define CD_VALUES 20
+
+typedef struct {
+ H5Z_filter_t filtn; /* filter identification number */
+ unsigned cd_values[CD_VALUES]; /* filter client data values */
+ size_t cd_nelmts; /* filter client number of values */
+} filter_info_t;
+
+/* chunk lengths along each dimension and rank */
+typedef struct {
+ hsize_t chunk_lengths[MAX_VAR_DIMS];
+ int rank;
+} chunk_info_t;
+
+/* we currently define a maximum value for the filters array,
+ that corresponds to the current library filters */
+#define H5_REPACK_MAX_NFILTERS 6
+
+/* information for one object, contains PATH, CHUNK info and FILTER info */
+typedef struct {
+ char path[MAX_NC_NAME]; /* name of object */
+ filter_info_t filter[H5_REPACK_MAX_NFILTERS]; /* filter array */
+ int nfilters; /* current number of filters */
+ H5D_layout_t layout; /* layout information */
+ chunk_info_t chunk; /* chunk information */
+ hid_t refobj_id; /* object ID, references */
+} pack_info_t;
+
+/* store a table of all objects */
+typedef struct {
+ unsigned int size;
+ unsigned int nelems;
+ pack_info_t *objs;
+} pack_opttbl_t;
+
+
+/*-------------------------------------------------------------------------
+ * command line options
+ *-------------------------------------------------------------------------
+ */
+
+/* all the above, ready to go to the hrepack call */
+typedef struct {
+ pack_opttbl_t *op_tbl; /*table with all -c and -f options */
+ int all_layout; /*apply the layout to all objects */
+ int all_filter; /*apply the filter to all objects */
+ filter_info_t filter_g[H5_REPACK_MAX_NFILTERS]; /*global filter array for the ALL case */
+ int n_filter_g; /*number of global filters */
+ chunk_info_t chunk_g; /*global chunk INFO for the ALL case */
+ H5D_layout_t layout_g; /*global layout information for the ALL case */
+ int verbose; /*verbose mode */
+ hsize_t min_comp; /*minimum size to compress, in bytes */
+ int use_native; /*use a native type in write */
+ hbool_t latest; /*pack file with the latest file format */
+ int grp_compact; /* Set the maximum number of links to store as header messages in the group */
+ int grp_indexed; /* Set the minimum number of links to store in the indexed format */
+ int msg_size[8]; /* Minimum size of shared messages: dataspace,
+ datatype, fill value, filter pipleline, attribute */
+ const char *ublock_filename; /* user block file name */
+ hsize_t ublock_size; /* user block size */
+ hsize_t meta_block_size; /* metadata aggregation block size (for H5Pset_meta_block_size) */
+ hsize_t threshold; /* alignment threshold for H5Pset_alignment */
+ hsize_t alignment; /* alignment for H5Pset_alignment */
+ H5F_file_space_type_t fs_strategy; /* File space handling strategy */
+ hsize_t fs_threshold; /* Free space section threshold */
+} pack_opt_t;
+
+
+typedef struct named_dt_t {
+ haddr_t addr_in; /* Address of the named dtype in the in file */
+ hid_t id_out; /* Open identifier for the dtype in the out file */
+ struct named_dt_t *next; /* Next dtype */
+} named_dt_t;
+
+/*-------------------------------------------------------------------------
+ * public functions
+ *-------------------------------------------------------------------------
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int h5repack(const char* infile, const char* outfile, pack_opt_t *options);
+int h5repack_addfilter(const char* str, pack_opt_t *options);
+int h5repack_addlayout(const char* str, pack_opt_t *options);
+int h5repack_init(pack_opt_t *options, int verbose, hbool_t latest,
+ H5F_file_space_type_t strategy, hsize_t threshold);
+int h5repack_end(pack_opt_t *options);
+int h5repack_verify(const char *in_fname, const char *out_fname, pack_opt_t *options);
+int h5repack_cmp_pl(const char *fname1, const char *fname2);
+
+/* Note: The below copy_named_datatype(), named_datatype_free(), copy_attr()
+ * and struct named_dt_t were located in h5repack_copy.c as static prior to
+ * bugfix1726.
+ * Made shared functions as copy_attr() was needed in h5repack_refs.c.
+ * However copy_attr() may be obsoleted when H5Acopy is available and put back
+ * others to static in h5repack_copy.c.
+ */
+hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_head_p, trav_table_t *travt, pack_opt_t *options);
+int named_datatype_free(named_dt_t **named_dt_head_p, int ignore_err);
+int copy_attr(hid_t loc_in, hid_t loc_out, named_dt_t **named_dt_head_p,
+ trav_table_t *travt, pack_opt_t *options);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/*-------------------------------------------------------------------------
+ * private functions
+ *-------------------------------------------------------------------------
+ */
+
+
+/*-------------------------------------------------------------------------
+ * copy module
+ *-------------------------------------------------------------------------
+ */
+
+int copy_objects (const char* fnamein,
+ const char* fnameout,
+ pack_opt_t *options);
+
+int do_copy_refobjs(hid_t fidin,
+ hid_t fidout,
+ trav_table_t *travt,
+ pack_opt_t *options);
+
+/*-------------------------------------------------------------------------
+ * filters and verify module
+ *-------------------------------------------------------------------------
+ */
+void init_packobject(pack_info_t *obj);
+
+
+/*-------------------------------------------------------------------------
+ * filters and copy module
+ *-------------------------------------------------------------------------
+ */
+
+int apply_filters(const char* name, /* object name from traverse list */
+ int rank, /* rank of dataset */
+ hsize_t *dims, /* dimensions of dataset */
+ size_t msize, /* size of type */
+ hid_t dcpl_id, /* dataset creation property list */
+ pack_opt_t *options, /* repack options */
+ int *has_filter); /* (OUT) object NAME has a filter */
+
+
+/*-------------------------------------------------------------------------
+ * options table
+ *-------------------------------------------------------------------------
+ */
+int options_table_init( pack_opttbl_t **tbl );
+int options_table_free( pack_opttbl_t *table );
+int options_add_layout( obj_list_t *obj_list,
+ unsigned n_objs,
+ pack_info_t *pack,
+ pack_opttbl_t *table );
+int options_add_filter ( obj_list_t *obj_list,
+ unsigned n_objs,
+ filter_info_t filt,
+ pack_opttbl_t *table );
+pack_info_t* options_get_object( const char *path,
+ pack_opttbl_t *table);
+
+/*-------------------------------------------------------------------------
+ * parse functions
+ *-------------------------------------------------------------------------
+ */
+
+obj_list_t* parse_filter(const char *str,
+ unsigned *n_objs,
+ filter_info_t *filt,
+ pack_opt_t *options,
+ int *is_glb);
+
+obj_list_t* parse_layout(const char *str,
+ unsigned *n_objs,
+ pack_info_t *pack, /* info about object */
+ pack_opt_t *options);
+
+
+
+
+#endif /* H5REPACK_H__ */
+
diff --git a/tools/src/h5repack/h5repack_copy.c b/tools/src/h5repack/h5repack_copy.c
new file mode 100644
index 0000000..547f61a
--- /dev/null
+++ b/tools/src/h5repack/h5repack_copy.c
@@ -0,0 +1,1581 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "h5repack.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/*-------------------------------------------------------------------------
+ * typedefs
+ *-------------------------------------------------------------------------
+ */
+
+/*-------------------------------------------------------------------------
+ * globals
+ *-------------------------------------------------------------------------
+ */
+
+/*-------------------------------------------------------------------------
+ * macros
+ *-------------------------------------------------------------------------
+ */
+
+/* size of buffer/# of bytes to xfer at a time when copying userblock */
+#define USERBLOCK_XFER_SIZE 512
+
+/* check H5Dread()/H5Dwrite() error, e.g. memory allocation error inside the library. */
+#define CHECK_H5DRW_ERROR(_fun, _fail, _did, _mtid, _msid, _fsid, _pid, _buf) { \
+ H5E_BEGIN_TRY { \
+ if(_fun(_did, _mtid, _msid, _fsid, _pid, _buf) < 0) { \
+ hid_t _err_num = 0; \
+ char _msg[80]; \
+ H5Ewalk2(H5E_DEFAULT, H5E_WALK_DOWNWARD, walk_error_callback, &_err_num); \
+ H5Eget_msg(_err_num, NULL, _msg, (size_t)80); \
+ error_msg("%s %s -- %s\n", #_fun, "failed", _msg); \
+ HGOTO_DONE(_fail) \
+ } \
+ } H5E_END_TRY; \
+}
+
+/*-------------------------------------------------------------------------
+ * local functions
+ *-------------------------------------------------------------------------
+ */
+static int Get_hyperslab(hid_t dcpl_id, int rank_dset, hsize_t dims_dset[],
+ size_t size_datum, hsize_t dims_hslab[], hsize_t * hslab_nbytes_p);
+static void print_dataset_info(hid_t dcpl_id, char *objname, double per, int pr);
+static int do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt,
+ pack_opt_t *options);
+static int copy_user_block(const char *infile, const char *outfile,
+ hsize_t size);
+#if defined (H5REPACK_DEBUG_USER_BLOCK)
+static void print_user_block(const char *filename, hid_t fid);
+#endif
+static herr_t walk_error_callback(unsigned n, const H5E_error2_t *err_desc, void *udata);
+
+/* get the major number from the error stack. */
+static herr_t walk_error_callback(H5_ATTR_UNUSED unsigned n, const H5E_error2_t *err_desc, void *udata) {
+ if (err_desc)
+ *((hid_t *) udata) = err_desc->maj_num;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: copy_objects
+ *
+ * Purpose: duplicate all HDF5 objects in the file
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: October, 23, 2003
+ *
+ * Modification:
+ * Peter Cao, June 13, 2007
+ * Add "-L, --latest" and other options to pack a file with the latest file format
+ *
+ * Peter Cao, September 25, 2007
+ * Copy user block when repacking a file
+ *
+ * Pedro Vicente, August 20, 2008
+ * Add a user block to file if requested
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int copy_objects(const char* fnamein, const char* fnameout, pack_opt_t *options)
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ hid_t fidin;
+ hid_t fidout = -1;
+ trav_table_t *travt = NULL;
+ hsize_t ub_size = 0; /* size of user block */
+ hid_t fcpl = H5P_DEFAULT; /* file creation property list ID */
+ hid_t fapl = H5P_DEFAULT; /* file access property list ID */
+
+ /*-------------------------------------------------------------------------
+ * open input file
+ *-------------------------------------------------------------------------
+ */
+ if ((fidin = h5tools_fopen(fnamein, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, (size_t) 0)) < 0) {
+ error_msg("<%s>: %s\n", fnamein, H5FOPENERROR);
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ /* get user block size and file space strategy/threshold */
+ {
+ hid_t fcpl_in; /* file creation property list ID for input file */
+
+ if ((fcpl_in = H5Fget_create_plist(fidin)) < 0) {
+ error_msg("failed to retrieve file creation property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ if (H5Pget_userblock(fcpl_in, &ub_size) < 0) {
+ error_msg("failed to retrieve userblock size\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ if (!options->fs_strategy) {
+ if (H5Pget_file_space(fcpl_in, &options->fs_strategy, NULL) < 0) {
+ error_msg("failed to retrieve file space strategy\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ if (!options->fs_threshold) {
+ if (H5Pget_file_space(fcpl_in, NULL, &options->fs_threshold) < 0) {
+ error_msg("failed to retrieve file space threshold\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ if (H5Pclose(fcpl_in) < 0) {
+ error_msg("failed to close property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ /* Check if we need to create a non-default file creation property list */
+ if (options->latest || ub_size > 0) {
+ /* Create file creation property list */
+ if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) {
+ error_msg("fail to create a file creation property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ if (ub_size > 0) {
+ if (H5Pset_userblock(fcpl, ub_size) < 0) {
+ error_msg("failed to set non-default userblock size\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ if (options->latest) {
+ unsigned i = 0, nindex = 0, mesg_type_flags[5], min_mesg_sizes[5];
+
+ /* Adjust group creation parameters for root group */
+ /* (So that it is created in "dense storage" form) */
+ if (H5Pset_link_phase_change(fcpl, (unsigned) options->grp_compact,
+ (unsigned) options->grp_indexed) < 0) {
+ error_msg("fail to adjust group creation parameters for root group\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ for (i = 0; i < 5; i++) {
+ if (options->msg_size[i] > 0) {
+ switch (i) {
+ case 0:
+ mesg_type_flags[nindex] = H5O_SHMESG_SDSPACE_FLAG;
+ break;
+
+ case 1:
+ mesg_type_flags[nindex] = H5O_SHMESG_DTYPE_FLAG;
+ break;
+
+ case 2:
+ mesg_type_flags[nindex] = H5O_SHMESG_FILL_FLAG;
+ break;
+
+ case 3:
+ mesg_type_flags[nindex] = H5O_SHMESG_PLINE_FLAG;
+ break;
+
+ case 4:
+ mesg_type_flags[nindex] = H5O_SHMESG_ATTR_FLAG;
+ break;
+
+ default:
+ break;
+ } /* end switch */
+ min_mesg_sizes[nindex] = (unsigned) options->msg_size[i];
+
+ nindex++;
+ } /* end if */
+ } /* end for */
+
+ if (nindex > 0) {
+ if (H5Pset_shared_mesg_nindexes(fcpl, nindex) < 0) {
+ error_msg("fail to set the number of shared object header message indexes\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ /* msg_size[0]=dataspace, 1=datatype, 2=file value, 3=filter pipleline, 4=attribute */
+ for (i = 0; i < (nindex - 1); i++) {
+ if (H5Pset_shared_mesg_index(fcpl, i, mesg_type_flags[i], min_mesg_sizes[i]) < 0) {
+ error_msg("fail to configure the specified shared object header message index\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ } /* end if */
+ } /* end for */
+ } /* if (nindex>0) */
+
+ /* Create file access property list */
+ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
+ error_msg("Could not create file access property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ } /* end if */
+
+ if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) {
+ error_msg("Could not set property for using latest version of the format\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ } /* end if */
+ } /* end if */
+ } /* end if */
+#if defined (H5REPACK_DEBUG_USER_BLOCK)
+print_user_block(fnamein, fidin);
+#endif
+
+ /*-------------------------------------------------------------------------
+ * set the new user userblock options in the FCPL (before H5Fcreate )
+ *-------------------------------------------------------------------------
+ */
+ if (options->ublock_size > 0) {
+ /* either use the FCPL already created or create a new one */
+ if (fcpl == H5P_DEFAULT) {
+ /* create a file creation property list */
+ if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) {
+ error_msg("fail to create a file creation property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ /* set user block size */
+ if (H5Pset_userblock(fcpl, options->ublock_size) < 0) {
+ error_msg("failed to set userblock size\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * set alignment options
+ *-------------------------------------------------------------------------
+ */
+ if (options->alignment > 0) {
+ /* either use the FAPL already created or create a new one */
+ if (fapl == H5P_DEFAULT) {
+ /* create a file access property list */
+ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
+ error_msg("Could not create file access property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ if (H5Pset_alignment(fapl, options->threshold, options->alignment) < 0) {
+ error_msg("failed to set alignment\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * set metadata block size option
+ *-------------------------------------------------------------------------
+ */
+ if (options->meta_block_size > 0) {
+ /* either use the FAPL already created or create a new one */
+ if (fapl == H5P_DEFAULT) {
+ /* create a file access property list */
+ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
+ error_msg("Could not create file access property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ if (H5Pset_meta_block_size(fapl, options->meta_block_size) < 0) {
+ error_msg("failed to set metadata block size\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * set free-space strategy options
+ *-------------------------------------------------------------------------
+ */
+
+ /* either use the FCPL already created or create a new one */
+ if (fcpl == H5P_DEFAULT) {
+ /* create a file creation property list */
+ if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) {
+ error_msg("fail to create a file creation property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ /* set file space strategy and free space threshold */
+ if (H5Pset_file_space(fcpl, options->fs_strategy, options->fs_threshold) < 0) {
+ error_msg("failed to set file space strategy & threshold \n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ /*-------------------------------------------------------------------------
+ * create the output file
+ *-------------------------------------------------------------------------
+ */
+ if (options->verbose)
+ printf("Making file <%s>...\n", fnameout);
+
+ if ((fidout = H5Fcreate(fnameout, H5F_ACC_TRUNC, fcpl, fapl)) < 0) {
+ error_msg("<%s>: Could not create file\n", fnameout);
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ /*-------------------------------------------------------------------------
+ * write a new user block if requested
+ *-------------------------------------------------------------------------
+ */
+ if (options->ublock_size > 0) {
+ if (copy_user_block(options->ublock_filename, fnameout, options->ublock_size) < 0) {
+ error_msg("Could not copy user block. Exiting...\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * get list of objects
+ *-------------------------------------------------------------------------
+ */
+
+ /* init table */
+ trav_table_init(&travt);
+
+ /* get the list of objects in the file */
+ if (h5trav_gettable(fidin, travt) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+
+ /*-------------------------------------------------------------------------
+ * do the copy
+ *-------------------------------------------------------------------------
+ */
+ if (do_copy_objects(fidin, fidout, travt, options) < 0) {
+ error_msg("<%s>: Could not copy data to: %s\n", fnamein, fnameout);
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ } /* end if */
+
+ /*-------------------------------------------------------------------------
+ * do the copy of referenced objects
+ * and create hard links
+ *-------------------------------------------------------------------------
+ */
+ if (do_copy_refobjs(fidin, fidout, travt, options) < 0) {
+ printf("h5repack: <%s>: Could not copy data to: %s\n", fnamein, fnameout);
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+
+ if (fapl > 0)
+ H5Pclose(fapl);
+
+ if (fcpl > 0)
+ H5Pclose(fcpl);
+
+ H5Fclose(fidin);
+ H5Fclose(fidout);
+
+ /* free table */
+ trav_table_free(travt);
+ travt = NULL;
+
+ /*-------------------------------------------------------------------------
+ * write only the input file user block if there is no user block file input
+ *-------------------------------------------------------------------------
+ */
+
+ if (ub_size > 0 && options->ublock_size == 0) {
+ if (copy_user_block(fnamein, fnameout, ub_size) < 0) {
+ error_msg("Could not copy user block. Exiting...\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ return 0;
+
+ /*-------------------------------------------------------------------------
+ * out
+ *-------------------------------------------------------------------------
+ */
+
+done:
+ H5E_BEGIN_TRY {
+ H5Pclose(fapl);
+ H5Pclose(fcpl);
+ H5Fclose(fidin);
+ H5Fclose(fidout);
+ } H5E_END_TRY;
+ if (travt)
+ trav_table_free(travt);
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: Get_hyperslab
+ *
+ * Purpose: Calulate a hyperslab from a dataset for higher performance.
+ * The size of hyperslab is limitted by H5TOOLS_BUFSIZE.
+ * Return the hyperslab dimentions and size in byte.
+ *
+ * Return: 0 - SUCCEED, -1 FAILED
+ *
+ * Parameters:
+ * dcpl_id : [IN] dataset creation property.
+ * rank_dset : [IN] dataset rank
+ * dims_dset[] : [IN] dataset dimentions
+ * size_datum : [IN] size of a data element in byte
+ * dims_hslab[] : [OUT] calculated hyperslab dimentions
+ * * hslab_nbytes_p : [OUT] total byte of the hyperslab
+ *
+ * Programmer: Jonathan Kim
+ * Date: Feburary, 2012
+ * Update:
+ * The hyperslab calucation would be depend on if the dataset is chunked
+ * or not.
+ *
+ * There care 3 conditions to cover:
+ * 1. If chunked and a chunk fits in buffer, each chunk would be a unit of
+ * collection and the boundary would be dataset's dims.
+ * 2. If chunked but a chunk doesn't fit in buffer, each data element would
+ * be a unit of collection and the boundary would be the chunk itself.
+ * 3. If not chunked, each data element would be a unit of collection and
+ * the boundary would be dataset's dims.
+ *
+ * The calulation starts from the last dimention (h5dump dims output).
+ *
+ * Note:
+ * Added for JIRA HDFFV-7862.
+ *-----------------------------------------*/
+
+int Get_hyperslab(hid_t dcpl_id, int rank_dset, hsize_t dims_dset[],
+ size_t size_datum, hsize_t dims_hslab[], hsize_t * hslab_nbytes_p)
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ int k;
+ H5D_layout_t dset_layout;
+ int rank_chunk;
+ hsize_t dims_chunk[H5S_MAX_RANK];
+ hsize_t size_chunk = 1;
+ hsize_t nchunk_fit; /* number of chunks that fits in hyperslab buffer (H5TOOLS_BUFSIZE) */
+ hsize_t ndatum_fit; /* number of dataum that fits in hyperslab buffer (H5TOOLS_BUFSIZE) */
+ hsize_t chunk_dims_map[H5S_MAX_RANK]; /* mapped chunk dimentions */
+ hsize_t hs_dims_map[H5S_MAX_RANK]; /* mapped hyperslab dimentions */
+ hsize_t hslab_nbytes; /* size of hyperslab in byte */
+
+ /* init to set as size of a data element */
+ hslab_nbytes = size_datum;
+
+ /* get layout of dataset */
+ dset_layout = H5Pget_layout(dcpl_id);
+
+ /* if dataset is chunked */
+ if (dset_layout == H5D_CHUNKED) {
+ /* get chunk dims */
+ rank_chunk = H5Pget_chunk(dcpl_id, rank_dset, dims_chunk);
+ if (rank_chunk < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+
+ for (k = rank_dset; k > 0; --k)
+ size_chunk *= dims_chunk[k - 1];
+
+ /* figure out how many chunks can fit in the hyperslab buffer */
+ nchunk_fit = (H5TOOLS_BUFSIZE / size_datum) / size_chunk;
+
+ /* 1. if a chunk fit in hyperslab buffer */
+ if (nchunk_fit >= 1) {
+ /* Calulate a hyperslab that contains as many chunks that can fit
+ * in hyperslab buffer. Hyperslab will be increased starting from
+ * the last dimention of the dataset (see h5dump's dims output).
+ * The calculation boundary is dataset dims.
+ * In the loop, used mapping from a datum to a chunk to figure out
+ * chunk based hyperslab.
+ */
+ for (k = rank_dset; k > 0; --k) {
+ /* map dataset dimentions with a chunk dims */
+ chunk_dims_map[k - 1] = dims_dset[k - 1] / dims_chunk[k - 1];
+
+ /* if reminder exist, increse by 1 to cover partial edge chunks */
+ if (dims_dset[k - 1] % dims_chunk[k - 1] > 0)
+ chunk_dims_map[k - 1]++;
+
+ /* get mapped hyperslab dims */
+ hs_dims_map[k - 1] = MIN (nchunk_fit, chunk_dims_map[k-1]);
+
+ /* prepare next round */
+ nchunk_fit = nchunk_fit / chunk_dims_map[k - 1];
+ /* if a chunk is bigger than the rest of buffer */
+ if (nchunk_fit == 0)
+ nchunk_fit = 1;
+
+ /* get hyperslab dimentions as unmapping to actual size */
+ dims_hslab[k - 1] = MIN( (hs_dims_map[k-1] * dims_chunk[k-1]), dims_dset[k-1]);
+
+ /* calculate total size for the hyperslab */
+ hslab_nbytes *= dims_hslab[k - 1];
+ }
+ }
+ /* 2. if a chunk is bigger than hyperslab buffer */
+ else {
+ /* Calulate a hyperslab that contains as many data elements that
+ * can fit in hyperslab buffer. Hyperslab will be increased
+ * starting from the last dimention of the chunk (see h5dump's dims
+ * output).
+ * The calculation boundary is a chunk dims.
+ */
+ for (k = rank_dset; k > 0; --k) {
+ ndatum_fit = H5TOOLS_BUFSIZE / hslab_nbytes;
+
+ /* if a datum is bigger than rest of buffer */
+ if (ndatum_fit == 0)
+ ndatum_fit = 1;
+ /* get hyperslab dimentions within a chunk boundary */
+ dims_hslab[k - 1] = MIN (dims_chunk[k-1], ndatum_fit);
+
+ /* calculate total size for the hyperslab */
+ hslab_nbytes *= dims_hslab[k - 1];
+
+ if (hslab_nbytes <= 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+ }
+ /* 3. if dataset is not chunked */
+ else {
+ /* Calulate a hyperslab that contains as many data elements that can
+ * fit in hyperslab buffer. Hyperslab will be increased starting from
+ * the last dimention of the dataset (see h5dump's dims output).
+ * The calculation boundary is dataset dims.
+ */
+ for (k = rank_dset; k > 0; --k) {
+ ndatum_fit = H5TOOLS_BUFSIZE / hslab_nbytes;
+
+ /* if a datum is bigger than rest of buffer */
+ if (ndatum_fit == 0)
+ ndatum_fit = 1;
+ /* get hyperslab dimentions within dataset boundary */
+ dims_hslab[k - 1] = MIN(dims_dset[k - 1], ndatum_fit);
+
+ /* calculate total size for the hyperslab */
+ hslab_nbytes *= dims_hslab[k - 1];
+
+ if (hslab_nbytes <= 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+ }
+
+ /* pass out the hyperslab size*/
+ *hslab_nbytes_p = hslab_nbytes;
+
+done:
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: do_copy_objects
+ *
+ * Purpose: duplicate all HDF5 objects in the file
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: October, 23, 2003
+ *
+ * Modifications:
+ *
+ * July 2004: Introduced the extra EC or NN option for SZIP
+ *
+ * December 2004: Added a check for H5Dcreate; if the dataset cannot be created
+ * with the requested filter, use the input one
+ *
+ * October 2006: Read/write using the file type by default.
+ *
+ * October 2006: Read by hyperslabs for big datasets.
+ *
+ * A threshold of H5TOOLS_MALLOCSIZE (128 MB) is the limit upon which I/O hyperslab is done
+ * i.e., if the memory needed to read a dataset is greater than this limit,
+ * then hyperslab I/O is done instead of one operation I/O
+ * For each dataset, the memory needed is calculated according to
+ *
+ * memory needed = number of elements * size of each element
+ *
+ * if the memory needed is lower than H5TOOLS_MALLOCSIZE, then the following operations
+ * are done
+ *
+ * H5Dread( input_dataset1 )
+ * H5Dread( input_dataset2 )
+ *
+ * with all elements in the datasets selected. If the memory needed is greater than
+ * H5TOOLS_MALLOCSIZE, then the following operations are done instead:
+ *
+ * a strip mine is defined for each dimension k (a strip mine is defined as a
+ * hyperslab whose size is memory manageable) according to the formula
+ *
+ * (1) strip_mine_size[k ] = MIN(dimension[k ], H5TOOLS_BUFSIZE / size of memory type)
+ *
+ * where H5TOOLS_BUFSIZE is a constant currently defined as 1MB. This formula assures
+ * that for small datasets (small relative to the H5TOOLS_BUFSIZE constant), the strip
+ * mine size k is simply defined as its dimension k, but for larger datasets the
+ * hyperslab size is still memory manageable.
+ * a cycle is done until the number of elements in the dataset is reached. In each
+ * iteration, two parameters are defined for the function H5Sselect_hyperslab,
+ * the start and size of each hyperslab, according to
+ *
+ * (2) hyperslab_size [k] = MIN(dimension[k] - hyperslab_offset[k], strip_mine_size [k])
+ *
+ * where hyperslab_offset [k] is initially set to zero, and later incremented in
+ * hyperslab_size[k] offsets. The reason for the operation
+ *
+ * dimension[k] - hyperslab_offset[k]
+ *
+ * in (2) is that, when using the strip mine size, it assures that the "remaining" part
+ * of the dataset that does not fill an entire strip mine is processed.
+ *
+ * November 2006: Use H5Ocopy in the copy of objects. The logic for using
+ * H5Ocopy or not is if a change of filters or layout is requested by the user
+ * then use read/write else use H5Ocopy.
+ *
+ * May, 1, 2008: Add a printing of the compression ratio of old size / new size
+ *
+ * Feburary 2012: improve Read/Write by hyperslabs for big datasets.
+ * Programmer: Jonathan Kim
+ *
+ * A threshold of H5TOOLS_MALLOCSIZE is the limit upon which I/O hyperslab is done
+ * i.e., if the memory needed to read a dataset is greater than this limit,
+ * then hyperslab I/O is done instead of one operation I/O
+ * For each dataset, the memory needed is calculated according to
+ *
+ * memory needed = number of elements * size of each element
+ *
+ * if the memory needed is lower than H5TOOLS_MALLOCSIZE, then the following operations
+ * are done
+ *
+ * H5Dread( input_dataset )
+ * H5Dwrite( output_dataset )
+ *
+ * with all elements in the datasets selected. If the memory needed is greater than
+ * H5TOOLS_MALLOCSIZE, then the following operations are done instead:
+ *
+ * 1. figure out a hyperslab (dimentions) and size (refer to Get_hyperslab()).
+ * 2. Calculate the hyperslab selections as the selection is moving forward.
+ * Selection would be same as the hyperslab except for the remaining edge portion
+ * of the dataset. The code take care of the remaining portion if exist.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt,
+ pack_opt_t *options) /* repack options */
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ hid_t grp_in = -1; /* group ID */
+ hid_t grp_out = -1; /* group ID */
+ hid_t dset_in = -1; /* read dataset ID */
+ hid_t dset_out = -1; /* write dataset ID */
+ hid_t gcpl_in = -1; /* group creation property list */
+ hid_t gcpl_out = -1; /* group creation property list */
+ hid_t type_in = -1; /* named type ID */
+ hid_t type_out = -1; /* named type ID */
+ hid_t dcpl_in = -1; /* dataset creation property list ID */
+ hid_t dcpl_out = -1; /* dataset creation property list ID */
+ hid_t f_space_id = -1; /* file space ID */
+ hid_t ftype_id = -1; /* file type ID */
+ hid_t wtype_id = -1; /* read/write type ID */
+ named_dt_t *named_dt_head = NULL; /* Pointer to the stack of named datatypes copied */
+ size_t msize; /* size of type */
+ hsize_t nelmts; /* number of elements in dataset */
+ H5D_space_status_t space_status; /* determines whether space has been allocated for the dataset */
+ int rank; /* rank of dataset */
+ hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */
+ hsize_t dsize_in; /* input dataset size before filter */
+ hsize_t dsize_out; /* output dataset size after filter */
+ int apply_s; /* flag for apply filter to small dataset sizes */
+ int apply_f; /* flag for apply filter to return error on H5Dcreate */
+ void *buf = NULL; /* buffer for raw data */
+ void *hslab_buf = NULL; /* hyperslab buffer for raw data */
+ int has_filter; /* current object has a filter */
+ int req_filter; /* there was a request for a filter */
+ int req_obj_layout = 0; /* request layout to current object */
+ unsigned crt_order_flags; /* group creation order flag */
+ unsigned i;
+ unsigned u;
+ int is_ref = 0;
+ htri_t is_named;
+ hbool_t limit_maxdims;
+ hsize_t size_dset;
+
+ /*-------------------------------------------------------------------------
+ * copy the suppplied object list
+ *-------------------------------------------------------------------------
+ */
+
+ if (options->verbose) {
+ printf("-----------------------------------------\n");
+ printf(" Type Filter (Compression) Name\n");
+ printf("-----------------------------------------\n");
+ }
+
+ for (i = 0; i < travt->nobjs; i++) {
+ /* init variables per obj */
+ buf = NULL;
+ limit_maxdims = FALSE;
+
+ switch (travt->objs[i].type) {
+ case H5TRAV_TYPE_UNKNOWN:
+ HDassert(0);
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5TRAV_TYPE_GROUP
+ *-------------------------------------------------------------------------
+ */
+ case H5TRAV_TYPE_GROUP:
+ if (options->verbose)
+ printf(FORMAT_OBJ, "group", travt->objs[i].name);
+
+ /* open input group */
+ if ((grp_in = H5Gopen2(fidin, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gopen2 failed");
+
+ /* get input group creation property list */
+ if ((gcpl_in = H5Gget_create_plist(grp_in)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gget_create_plist failed");
+
+ /* query and set the group creation properties */
+ if (H5Pget_link_creation_order(gcpl_in, &crt_order_flags) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pget_link_creation_order failed");
+
+ /* set up group creation property list */
+ if ((gcpl_out = H5Pcreate(H5P_GROUP_CREATE)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pcreate failed");
+
+ if (H5Pset_link_creation_order(gcpl_out, crt_order_flags) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pset_link_creation_order failed");
+
+ /*-------------------------------------------------------------------------
+ * the root is a special case, we get an ID for the root group
+ * and copy its attributes using that ID
+ *-------------------------------------------------------------------------
+ */
+ if (HDstrcmp(travt->objs[i].name, "/") == 0) {
+ if ((grp_out = H5Gopen2(fidout, "/", H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gopen2 failed");
+ }
+ else {
+ if (options->grp_compact > 0 || options->grp_indexed > 0)
+ if (H5Pset_link_phase_change(gcpl_out, (unsigned) options->grp_compact, (unsigned) options->grp_indexed) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pset_link_phase_change failed");
+
+ if ((grp_out = H5Gcreate2(fidout, travt->objs[i].name, H5P_DEFAULT, gcpl_out, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gcreate2 failed");
+ }
+
+ /*-------------------------------------------------------------------------
+ * copy attrs
+ *-------------------------------------------------------------------------
+ */
+ if (copy_attr(grp_in, grp_out, &named_dt_head, travt, options) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_attr failed");
+
+ if (H5Pclose(gcpl_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Pclose(gcpl_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Gclose(grp_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gclose failed");
+ if (H5Gclose(grp_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gclose failed");
+
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5TRAV_TYPE_DATASET
+ *-------------------------------------------------------------------------
+ */
+ case H5TRAV_TYPE_DATASET:
+ has_filter = 0;
+ req_filter = 0;
+
+ /* check if global filters were requested */
+ if (options->n_filter_g)
+ req_filter = 1;
+
+ /* check if filters were requested for individual objects */
+ for (u = 0; u < options->op_tbl->nelems; u++)
+ if (HDstrcmp(travt->objs[i].name, options->op_tbl->objs[u].path) == 0)
+ if (options->op_tbl->objs[u].filter->filtn > 0)
+ req_filter = 1;
+
+ /* check if layout change requested individual object */
+ if (options->layout_g != H5D_LAYOUT_ERROR) {
+ pack_info_t *pckinfo;
+
+ /* any dataset is specified */
+ if (options->op_tbl->nelems > 0) {
+ /* check if object exist */
+ pckinfo = options_get_object(travt->objs[i].name, options->op_tbl);
+ if (pckinfo)
+ req_obj_layout = 1;
+ }
+ }
+
+ /* early detection of references */
+ if ((dset_in = H5Dopen2(fidin, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ if ((ftype_id = H5Dget_type(dset_in)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_type failed");
+ if (H5T_REFERENCE == H5Tget_class(ftype_id))
+ is_ref = 1;
+
+ /* Check if the datatype is committed */
+ if ((is_named = H5Tcommitted(ftype_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tcommitted failed");
+ if (is_named)
+ if ((wtype_id = copy_named_datatype(ftype_id, fidout, &named_dt_head, travt, options)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_named_datatype failed");
+
+ if (H5Tclose(ftype_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if (H5Dclose(dset_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+
+ /*-------------------------------------------------------------------------
+ * check if we should use H5Ocopy or not
+ * if there is a request for filters/layout, we read/write the object
+ * otherwise we do a copy using H5Ocopy
+ *-------------------------------------------------------------------------
+ */
+ if (options->op_tbl->nelems || options->all_filter == 1
+ || options->all_layout == 1 || is_ref || is_named) {
+
+ int j;
+
+ if ((dset_in = H5Dopen2(fidin, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ if ((f_space_id = H5Dget_space(dset_in)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_space failed");
+ if ((ftype_id = H5Dget_type(dset_in)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_type failed");
+ if ((dcpl_in = H5Dget_create_plist(dset_in)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_create_plist failed");
+ if ((dcpl_out = H5Pcopy(dcpl_in)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pcopy failed");
+ if ((rank = H5Sget_simple_extent_ndims(f_space_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_ndims failed");
+ HDmemset(dims, 0, sizeof dims);
+ if (H5Sget_simple_extent_dims(f_space_id, dims, NULL) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed");
+ if (H5Dget_space_status(dset_in, &space_status) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_space_status failed");
+
+ nelmts = 1;
+ for (j = 0; j < rank; j++)
+ nelmts *= dims[j];
+
+ /* wtype_id will have already been set if using a named dtype */
+ if (!is_named) {
+ if (options->use_native == 1)
+ wtype_id = h5tools_get_native_type(ftype_id);
+ else
+ wtype_id = H5Tcopy(ftype_id);
+ } /* end if */
+
+ if ((msize = H5Tget_size(wtype_id)) == 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed");
+
+ /* size of current dset */
+ size_dset = nelmts * msize;
+
+ /*-------------------------------------------------------------------------
+ * check if the dataset creation property list has filters that
+ * are not registered in the current configuration
+ * 1) the external filters GZIP and SZIP might not be available
+ * 2) the internal filters might be turned off
+ *-------------------------------------------------------------------------
+ */
+ if (h5tools_canreadf((travt->objs[i].name), dcpl_in) == 1) {
+ apply_s = 1;
+ apply_f = 1;
+
+ /*-------------------------------------------------------------------------
+ * references are a special case
+ * we cannot just copy the buffers, but instead we recreate the reference
+ * in a second traversal of the output file
+ *-------------------------------------------------------------------------
+ */
+ if (H5T_REFERENCE != H5Tget_class(wtype_id)) {
+ /* get the storage size of the input dataset */
+ dsize_in = H5Dget_storage_size(dset_in);
+
+ /* check for small size datasets (less than 1k) except
+ * changing to COMPACT. For the reference, COMPACT is limited
+ * by size 64K by library.
+ */
+ if (options->layout_g != H5D_COMPACT)
+ if (size_dset < options->min_comp)
+ apply_s = 0;
+
+ /* apply the filter */
+ if (apply_s)
+ if (apply_filters(travt->objs[i].name, rank, dims, msize, dcpl_out, options, &has_filter) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "apply_filters failed");
+
+ /* only if layout change requested for entire file or
+ * individual obj */
+ if (options->all_layout > 0 || req_obj_layout == 1)
+ /*-------------------------------------------------
+ * Unset the unlimited max dims if convert to other
+ * than chunk layouts, because unlimited max dims
+ * only can be applied to chunk layout.
+ * Also perform only for targeted dataset
+ * Also check for size limit to convert to compact
+ *-------------------------------------------------*/
+ if (options->layout_g != H5D_CHUNKED) {
+ /* any dataset is specified */
+ if (options->op_tbl->nelems > 0) {
+ /* if current obj match specified obj */
+ if (options_get_object(travt->objs[i].name, options->op_tbl))
+ limit_maxdims = TRUE;
+ }
+ else /* no dataset is specified */
+ limit_maxdims = TRUE;
+
+ /* if convert to COMPACT */
+ if (options->layout_g == H5D_COMPACT)
+ /* should be smaller than 64K */
+ if (size_dset > MAX_COMPACT_DSIZE)
+ limit_maxdims = FALSE;
+
+ /* unset unlimited max dims */
+ if (limit_maxdims)
+ H5Sset_extent_simple(f_space_id, rank, dims, NULL);
+ }
+
+ /*-------------------------------------------------------------------------
+ * create the output dataset;
+ * disable error checking in case the dataset cannot be created with the
+ * modified dcpl; in that case use the original instead
+ *-------------------------------------------------------------------------
+ */
+ dset_out = H5Dcreate2(fidout, travt->objs[i].name, wtype_id, f_space_id, H5P_DEFAULT, dcpl_out, H5P_DEFAULT);
+ if (dset_out == FAIL) {
+ H5Epush2(H5tools_ERR_STACK_g, __FILE__, FUNC, __LINE__, H5tools_ERR_CLS_g, H5E_tools_g, H5E_tools_min_id_g, "H5Dcreate2 failed");
+ if (options->verbose)
+ printf(" warning: could not create dataset <%s>. Applying original settings\n", travt->objs[i].name);
+
+ if ((dset_out = H5Dcreate2(fidout, travt->objs[i].name, wtype_id, f_space_id, H5P_DEFAULT, dcpl_in, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dcreate2 failed");
+ apply_f = 0;
+ }
+
+ /*-------------------------------------------------------------------------
+ * read/write
+ *-------------------------------------------------------------------------
+ */
+ if (nelmts > 0 && space_status != H5D_SPACE_STATUS_NOT_ALLOCATED) {
+ size_t need = (size_t)(nelmts * msize); /* bytes needed */
+
+ /* have to read the whole dataset if there is only one element in the dataset */
+ if (need < H5TOOLS_MALLOCSIZE)
+ buf = HDmalloc(need);
+
+ if (buf != NULL) {
+ /* read/write: use the macro to check error, e.g. memory allocation error inside the library. */
+ CHECK_H5DRW_ERROR(H5Dread, FAIL, dset_in, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
+ CHECK_H5DRW_ERROR(H5Dwrite, FAIL, dset_out, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
+
+ /* Check if we have VL data in the dataset's
+ * datatype that must be reclaimed */
+ if (TRUE == H5Tdetect_class(wtype_id, H5T_VLEN))
+ if (H5Dvlen_reclaim(wtype_id, f_space_id, H5P_DEFAULT, buf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dvlen_reclaim failed");
+ }
+ else { /* possibly not enough memory, read/write by hyperslabs */
+ size_t p_type_nbytes = msize; /*size of memory type */
+ hsize_t p_nelmts = nelmts; /*total elements */
+ hsize_t elmtno; /*counter */
+ int carry; /*counter carry value */
+ unsigned int vl_data = 0; /*contains VL datatypes */
+
+ /* hyperslab info */
+ hsize_t hslab_dims[H5S_MAX_RANK]; /*hyperslab dims */
+ hsize_t hslab_nbytes; /*bytes per hyperslab */
+ hsize_t hslab_nelmts; /*elements per hyperslab*/
+ hid_t hslab_space; /*hyperslab data space */
+
+ /* hyperslab selection info */
+ hsize_t hs_sel_offset[H5S_MAX_RANK];/* selection offset */
+ hsize_t hs_sel_count[H5S_MAX_RANK]; /* selection count */
+ hsize_t hs_select_nelmts; /* selected elements */
+ hsize_t zero[8]; /*vector of zeros */
+ int k;
+ H5D_layout_t dset_layout;
+ hid_t dcpl_tmp = -1; /* dataset creation property list ID */
+
+ /* check if we have VL data in the dataset's datatype */
+ if (H5Tdetect_class(wtype_id, H5T_VLEN) == TRUE)
+ vl_data = TRUE;
+
+ /* check first if writing dataset is chunked,
+ * if so use its chunk layout for better performance. */
+ dset_layout = H5Pget_layout(dcpl_out);
+ if (dset_layout == H5D_CHUNKED)
+ dcpl_tmp = dcpl_out; /* writing dataset */
+ else { /* if reading dataset is chunked */
+ dset_layout = H5Pget_layout(dcpl_in);
+ if (dset_layout == H5D_CHUNKED)
+ dcpl_tmp = dcpl_in; /* reading dataset */
+ }
+
+ /* get hyperslab dims and size in byte */
+ if (Get_hyperslab(dcpl_tmp, rank, dims, p_type_nbytes, hslab_dims, &hslab_nbytes) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Get_hyperslab failed");
+
+ hslab_buf = HDmalloc((size_t)hslab_nbytes);
+
+ hslab_nelmts = hslab_nbytes / p_type_nbytes;
+ hslab_space = H5Screate_simple(1, &hslab_nelmts, NULL);
+
+ /* the hyperslab selection loop */
+ HDmemset(hs_sel_offset, 0, sizeof hs_sel_offset);
+ HDmemset(zero, 0, sizeof zero);
+
+ for (elmtno = 0; elmtno < p_nelmts; elmtno += hs_select_nelmts) {
+ if (rank > 0) {
+ /* calculate the hyperslab selections.
+ * The selection would be same as the hyperslab
+ * except for remaining edge portion of the dataset
+ * which is smaller then the hyperslab.
+ */
+ for (k = 0, hs_select_nelmts = 1; k < rank; k++) {
+ /* MIN() is used to get the remaining edge portion if exist.
+ * "dims[k] - hs_sel_offset[k]" is remaining edge portion that is smaller then the hyperslab.*/
+ hs_sel_count[k] = MIN(dims[k] - hs_sel_offset[k], hslab_dims[k]);
+ hs_select_nelmts *= hs_sel_count[k];
+ }
+
+ if (H5Sselect_hyperslab(f_space_id, H5S_SELECT_SET, hs_sel_offset, NULL, hs_sel_count, NULL) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sselect_hyperslab failed");
+ if (H5Sselect_hyperslab(hslab_space, H5S_SELECT_SET, zero, NULL, &hs_select_nelmts, NULL) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sselect_hyperslab failed");
+ }
+ else {
+ H5Sselect_all(f_space_id);
+ H5Sselect_all(hslab_space);
+ hs_select_nelmts = 1;
+ } /* rank */
+
+ /* read/write: use the macro to check error, e.g. memory allocation error inside the library. */
+ CHECK_H5DRW_ERROR(H5Dread, FAIL, dset_in, wtype_id, hslab_space, f_space_id, H5P_DEFAULT, hslab_buf);
+ CHECK_H5DRW_ERROR(H5Dwrite, FAIL, dset_out, wtype_id, hslab_space, f_space_id, H5P_DEFAULT, hslab_buf);
+
+ /* reclaim any VL memory, if necessary */
+ if (vl_data)
+ H5Dvlen_reclaim(wtype_id, hslab_space, H5P_DEFAULT, hslab_buf);
+
+ /* calculate the next hyperslab offset */
+ for (k = rank, carry = 1; k > 0 && carry; --k) {
+ hs_sel_offset[k - 1] += hs_sel_count[k - 1];
+ /* if reached the end of a dim */
+ if (hs_sel_offset[k - 1] == dims[k - 1])
+ hs_sel_offset[k - 1] = 0;
+ else
+ carry = 0;
+ } /* k */
+ } /* elmtno */
+
+ H5Sclose(hslab_space);
+ /* free */
+ if (hslab_buf != NULL) {
+ HDfree(hslab_buf);
+ hslab_buf = NULL;
+ }
+ } /* hyperslab read */
+ } /* if (nelmts>0 && space_status==H5D_SPACE_STATUS_NOT_ALLOCATED) */
+
+ /*-------------------------------------------------------------------------
+ * amount of compression used
+ *-------------------------------------------------------------------------
+ */
+ if (options->verbose) {
+ double ratio = 0;
+
+ /* only print the compression ration if there was a filter request */
+ if (apply_s && apply_f && req_filter) {
+ /* get the storage size of the output dataset */
+ dsize_out = H5Dget_storage_size(dset_out);
+
+ /* compression ratio = uncompressed size / compressed size */
+ if (dsize_out != 0)
+ ratio = (double) dsize_in / (double) dsize_out;
+ print_dataset_info(dcpl_out, travt->objs[i].name, ratio, 1);
+ }
+ else
+ print_dataset_info(dcpl_in, travt->objs[i].name, ratio, 0);
+
+ /* print a message that the filter was not applied
+ (in case there was a filter)
+ */
+ if (has_filter && apply_s == 0)
+ printf(" <warning: filter not applied to %s. dataset smaller than %d bytes>\n", travt->objs[i].name, (int) options->min_comp);
+
+ if (has_filter && apply_f == 0)
+ printf(" <warning: could not apply the filter to %s>\n", travt->objs[i].name);
+ } /* verbose */
+
+ /*-------------------------------------------------------------------------
+ * copy attrs
+ *-------------------------------------------------------------------------
+ */
+ if (copy_attr(dset_in, dset_out, &named_dt_head, travt, options) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_attr failed");
+
+ /*close */
+ if (H5Dclose(dset_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+ }/*!H5T_REFERENCE*/
+ }/*h5tools_canreadf*/
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+ if (H5Tclose(ftype_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if (H5Tclose(wtype_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if (H5Pclose(dcpl_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Pclose(dcpl_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Sclose(f_space_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose failed");
+ if (H5Dclose(dset_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+ }
+ /*-------------------------------------------------------------------------
+ * we do not have request for filter/chunking use H5Ocopy instead
+ *-------------------------------------------------------------------------
+ */
+ else {
+ hid_t pid;
+
+ /* create property to pass copy options */
+ if ((pid = H5Pcreate(H5P_OBJECT_COPY)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pcreate failed");
+
+ /* set options for object copy */
+ if (H5Pset_copy_object(pid, H5O_COPY_WITHOUT_ATTR_FLAG) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pset_copy_object failed");
+
+ /*-------------------------------------------------------------------------
+ * do the copy
+ *-------------------------------------------------------------------------
+ */
+
+ if (H5Ocopy(fidin, /* Source file or group identifier */
+ travt->objs[i].name, /* Name of the source object to be copied */
+ fidout, /* Destination file or group identifier */
+ travt->objs[i].name, /* Name of the destination object */
+ pid, /* Properties which apply to the copy */
+ H5P_DEFAULT) < 0) /* Properties which apply to the new hard link */
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Ocopy failed");
+
+ /* close property */
+ if (H5Pclose(pid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+
+ /*-------------------------------------------------------------------------
+ * copy attrs manually
+ *-------------------------------------------------------------------------
+ */
+ if ((dset_in = H5Dopen2(fidin, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ if ((dset_out = H5Dopen2(fidout, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ if (copy_attr(dset_in, dset_out, &named_dt_head, travt, options) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_attr failed");
+ if (H5Dclose(dset_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+ if (H5Dclose(dset_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+
+ if (options->verbose)
+ printf(FORMAT_OBJ, "dset", travt->objs[i].name);
+
+ } /* end do we have request for filter/chunking */
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5TRAV_TYPE_NAMED_DATATYPE
+ *-------------------------------------------------------------------------
+ */
+ case H5TRAV_TYPE_NAMED_DATATYPE:
+ if (options->verbose)
+ printf(FORMAT_OBJ, "type", travt->objs[i].name);
+
+ if ((type_in = H5Topen2(fidin, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Topen2 failed");
+
+ /* Copy the datatype anonymously */
+ if ((type_out = copy_named_datatype(type_in, fidout, &named_dt_head, travt, options)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_named_datatype failed");
+
+ /* Link in to group structure */
+ if (H5Lcreate_hard(type_out, ".", fidout, travt->objs[i].name, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Lcreate_hard failed");
+
+ /*-------------------------------------------------------------------------
+ * copy attrs
+ *-------------------------------------------------------------------------
+ */
+ if (copy_attr(type_in, type_out, &named_dt_head, travt, options) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_attr failed");
+
+ if (H5Tclose(type_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if (H5Tclose(type_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5TRAV_TYPE_LINK
+ * H5TRAV_TYPE_UDLINK
+ *
+ * Only handles external links; H5Lcopy will fail for other UD link types
+ * since we don't have creation or copy callbacks for them.
+ *-------------------------------------------------------------------------
+ */
+ case H5TRAV_TYPE_LINK:
+ case H5TRAV_TYPE_UDLINK:
+ if (options->verbose)
+ printf(FORMAT_OBJ, "link", travt->objs[i].name);
+
+ if (H5Lcopy(fidin, travt->objs[i].name, fidout, travt->objs[i].name, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Lcopy failed");
+
+ if (options->verbose)
+ printf(FORMAT_OBJ, "link", travt->objs[i].name);
+ break;
+
+ default:
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Object type not found");
+ } /* switch */
+
+ /* free */
+ if (buf != NULL) {
+ HDfree(buf);
+ buf = NULL;
+ }
+ } /* i */
+
+ /* Finalize (link) the stack of named datatypes (if any) */
+ named_datatype_free(&named_dt_head, 0);
+
+ return ret_value;
+
+done:
+ H5E_BEGIN_TRY
+ {
+ H5Gclose(grp_in);
+ H5Gclose(grp_out);
+ H5Pclose(dcpl_in);
+ H5Pclose(gcpl_in);
+ H5Pclose(gcpl_out);
+ H5Sclose(f_space_id);
+ H5Dclose(dset_in);
+ H5Dclose(dset_out);
+ H5Tclose(ftype_id);
+ H5Tclose(wtype_id);
+ H5Tclose(type_in);
+ H5Tclose(type_out);
+ named_datatype_free(&named_dt_head, 1);
+ }H5E_END_TRY;
+
+ /* free */
+ if (buf != NULL)
+ HDfree(buf);
+ if (hslab_buf != NULL)
+ HDfree(hslab_buf);
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: print_dataset_info
+ *
+ * Purpose: print name, filters, percentage compression of a dataset
+ *
+ *-------------------------------------------------------------------------
+ */
+static void print_dataset_info(hid_t dcpl_id, char *objname, double ratio,
+ int pr)
+{
+ char strfilter[255];
+#if defined (PRINT_DEBUG )
+ char temp[255];
+#endif
+ int nfilters; /* number of filters */
+ unsigned filt_flags; /* filter flags */
+ H5Z_filter_t filtn; /* filter identification number */
+ unsigned cd_values[20]; /* filter client data values */
+ size_t cd_nelmts; /* filter client number of values */
+ char f_objname[256]; /* filter objname */
+ int i;
+
+ HDstrcpy(strfilter, "\0");
+
+ /* get information about input filters */
+ if ((nfilters = H5Pget_nfilters(dcpl_id)) < 0)
+ return;
+
+ for (i = 0; i < nfilters; i++) {
+ cd_nelmts = NELMTS(cd_values);
+
+ filtn = H5Pget_filter2(dcpl_id, (unsigned) i, &filt_flags, &cd_nelmts,
+ cd_values, sizeof(f_objname), f_objname, NULL);
+
+ switch (filtn) {
+ case H5Z_FILTER_NONE:
+ HDstrcat(strfilter, "NONE ");
+ break;
+
+ case H5Z_FILTER_DEFLATE:
+ HDstrcat(strfilter, "GZIP ");
+
+#if defined (PRINT_DEBUG)
+ {
+ unsigned level = cd_values[0];
+
+ sprintf(temp,"(%d)", level);
+ HDstrcat(strfilter, temp);
+ }
+#endif
+ break;
+
+ case H5Z_FILTER_SZIP:
+ HDstrcat(strfilter, "SZIP ");
+
+#if defined (PRINT_DEBUG)
+ {
+ unsigned options_mask = cd_values[0]; /* from dcpl, not filt*/
+ unsigned ppb = cd_values[1];
+
+ sprintf(temp,"(%d,", ppb);
+ HDstrcat(strfilter, temp);
+ if (options_mask & H5_SZIP_EC_OPTION_MASK)
+ HDstrcpy(temp, "EC) ");
+ else if (options_mask & H5_SZIP_NN_OPTION_MASK)
+ HDstrcpy(temp, "NN) ");
+ }
+ HDstrcat(strfilter, temp);
+#endif
+ break;
+
+ case H5Z_FILTER_SHUFFLE:
+ HDstrcat(strfilter, "SHUF ");
+ break;
+
+ case H5Z_FILTER_FLETCHER32:
+ HDstrcat(strfilter, "FLET ");
+ break;
+
+ case H5Z_FILTER_NBIT:
+ HDstrcat(strfilter, "NBIT ");
+ break;
+
+ case H5Z_FILTER_SCALEOFFSET:
+ HDstrcat(strfilter, "SCALEOFFSET ");
+ break;
+
+ default:
+ HDstrcat(strfilter, "UD ");
+ break;
+ } /* switch */
+ }/*i*/
+
+ if (!pr)
+ printf(FORMAT_OBJ, "dset", objname);
+ else {
+ char str[255], temp[28];
+
+ HDstrcpy(str, "dset ");
+ HDstrcat(str, strfilter);
+ sprintf(temp, " (%.3f:1)", ratio);
+ HDstrcat(str, temp);
+ printf(FORMAT_OBJ, str, objname);
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: copy_user_block
+ *
+ * Purpose: copy user block from one file to another
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Peter Cao
+ *
+ * Date: October, 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int copy_user_block(const char *infile, const char *outfile,
+ hsize_t size)
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ int infid = -1, outfid = -1; /* File descriptors */
+
+ /* User block must be any power of 2 equal to 512 or greater (512, 1024, 2048, etc.) */
+ HDassert(size > 0);
+
+ /* Open files */
+ if ((infid = HDopen(infile, O_RDONLY, 0)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDopen failed");
+ if ((outfid = HDopen(outfile, O_WRONLY, 0644)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDopen failed");
+
+ /* Copy the userblock from the input file to the output file */
+ while (size > 0) {
+ ssize_t nread, nbytes; /* # of bytes transfered, etc. */
+ char rbuf[USERBLOCK_XFER_SIZE]; /* Buffer for reading */
+ const char *wbuf; /* Pointer into buffer, for writing */
+
+ /* Read buffer from source file */
+ if (size > USERBLOCK_XFER_SIZE)
+ nread = HDread(infid, rbuf, (size_t)USERBLOCK_XFER_SIZE);
+ else
+ nread = HDread(infid, rbuf, (size_t)size);
+ if (nread < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDread failed");
+
+ /* Write buffer to destination file */
+ /* (compensating for interrupted writes & checking for errors, etc.) */
+ nbytes = nread;
+ wbuf = rbuf;
+ while (nbytes > 0) {
+ ssize_t nwritten; /* # of bytes written */
+
+ do {
+ nwritten = HDwrite(outfid, wbuf, (size_t)nbytes);
+ } while (-1 == nwritten && EINTR == errno);
+ if (-1 == nwritten) /* error */
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDwrite failed");
+ HDassert(nwritten > 0);
+ HDassert(nwritten <= nbytes);
+
+ /* Update # of bytes left & offset in buffer */
+ nbytes -= nwritten;
+ wbuf += nwritten;
+ HDassert(nbytes == 0 || wbuf < (rbuf + USERBLOCK_XFER_SIZE));
+ } /* end while */
+
+ /* Update size of userblock left to transfer */
+ size = size - (hsize_t) nread;
+ } /* end while */
+
+done:
+ if (infid > 0)
+ HDclose(infid);
+ if (outfid > 0)
+ HDclose(outfid);
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: print_user_block
+ *
+ * Purpose: print user block
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Pedro Vicente
+ *
+ * Date: August, 20, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+#if defined (H5REPACK_DEBUG_USER_BLOCK)
+static
+void print_user_block(const char *filename, hid_t fid)
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ int fh; /* file handle */
+ hsize_t ub_size; /* user block size */
+ hsize_t size; /* size read */
+ hid_t fcpl; /* file creation property list ID for HDF5 file */
+ int i;
+
+ /* get user block size */
+ if(( fcpl = H5Fget_create_plist(fid)) < 0) {
+ error_msg("failed to retrieve file creation property list\n");
+ HGOTO_ERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Fget_create_plist failed");
+ }
+
+ if(H5Pget_userblock(fcpl, &ub_size) < 0) {
+ error_msg("failed to retrieve userblock size\n");
+ HGOTO_ERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Pget_userblock failed");
+ }
+
+ if(H5Pclose(fcpl) < 0) {
+ error_msg("failed to close property list\n");
+ HGOTO_ERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Pclose failed");
+ }
+
+ /* open file */
+ if((fh = HDopen(filename, O_RDONLY, 0)) < 0) {
+ HGOTO_ERROR(H5E_tools_g, H5E_tools_min_id_g, "HDopen failed");
+ }
+
+ size = ub_size;
+
+ /* read file */
+ while(size > 0) {
+ ssize_t nread; /* # of bytes read */
+ char rbuf[USERBLOCK_XFER_SIZE]; /* buffer for reading */
+
+ /* read buffer */
+ if(size > USERBLOCK_XFER_SIZE)
+ nread = HDread(fh, rbuf, (size_t)USERBLOCK_XFER_SIZE);
+ else
+ nread = HDread(fh, rbuf, (size_t)size);
+
+ for(i = 0; i < nread; i++) {
+
+ printf("%c ", rbuf[i]);
+
+ }
+ printf("\n");
+
+ if(nread < 0) {
+ HGOTO_ERROR(H5E_tools_g, H5E_tools_min_id_g, "nread < 0");
+ }
+
+ /* update size of userblock left to transfer */
+ size -= nread;
+ }
+
+done:
+ if(fh > 0)
+ HDclose(fh);
+
+ return;
+}
+#endif
+
diff --git a/tools/src/h5repack/h5repack_filters.c b/tools/src/h5repack/h5repack_filters.c
new file mode 100644
index 0000000..e21b829
--- /dev/null
+++ b/tools/src/h5repack/h5repack_filters.c
@@ -0,0 +1,493 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "h5repack.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/* number of members in an array */
+#ifndef NELMTS
+# define NELMTS(X) (sizeof(X)/sizeof(X[0]))
+#endif
+
+/* minimum of two values */
+#undef MIN
+#define MIN(a,b) (((a)<(b)) ? (a) : (b))
+
+/*-------------------------------------------------------------------------
+ * Function: aux_find_obj
+ *
+ * Purpose: find the object name NAME (got from the traverse list)
+ * in the repack options list
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+aux_find_obj(const char* name, /* object name from traverse list */
+ pack_opt_t *options, /* repack options */
+ pack_info_t *obj /*OUT*/) /* info about object to filter */
+{
+ char *pdest;
+ int result;
+ unsigned int i;
+
+ for ( i=0; i<options->op_tbl->nelems; i++)
+ {
+ if (HDstrcmp(options->op_tbl->objs[i].path,name)==0)
+ {
+ *obj = options->op_tbl->objs[i];
+ return (int)i;
+ }
+
+ pdest = HDstrstr(name,options->op_tbl->objs[i].path);
+ result = (int)(pdest - name);
+
+ /* found at position 1, meaning without '/' */
+ if( pdest != NULL && result==1 )
+ {
+ *obj = options->op_tbl->objs[i];
+ return (int)i;
+ }
+ }/*i*/
+
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: aux_assign_obj
+ *
+ * Purpose: find the object name NAME (got from the traverse list)
+ * in the repack options list; assign the filter information OBJ
+ *
+ * Return: 0 not found, 1 found
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+aux_assign_obj(const char* name, /* object name from traverse list */
+ pack_opt_t *options, /* repack options */
+ pack_info_t *obj /*OUT*/) /* info about object to filter */
+{
+
+ int idx, i;
+ pack_info_t tmp;
+
+ init_packobject(&tmp);
+
+ idx = aux_find_obj(name,options,&tmp);
+
+ /* name was on input */
+ if (idx>=0)
+ {
+
+
+ /* applying to all objects */
+ if (options->all_layout)
+ {
+ /* assign the global layout info to the OBJ info */
+ tmp.layout=options->layout_g;
+ switch (options->layout_g)
+ {
+ case H5D_CHUNKED:
+ tmp.chunk.rank=options->chunk_g.rank;
+ for ( i=0; i<tmp.chunk.rank; i++)
+ tmp.chunk.chunk_lengths[i]=options->chunk_g.chunk_lengths[i];
+ break;
+ case H5D_LAYOUT_ERROR:
+ case H5D_COMPACT:
+ case H5D_CONTIGUOUS:
+ case H5D_VIRTUAL:
+ case H5D_NLAYOUTS:
+ break;
+ default:
+ break;
+ }/*switch*/
+ }
+ else
+ {
+ tmp.layout = options->op_tbl->objs[idx].layout;
+ switch (tmp.layout)
+ {
+ case H5D_CHUNKED:
+ tmp.chunk.rank = options->op_tbl->objs[idx].chunk.rank;
+ for ( i=0; i<tmp.chunk.rank; i++)
+ tmp.chunk.chunk_lengths[i]=options->op_tbl->objs[idx].chunk.chunk_lengths[i];
+ break;
+ case H5D_LAYOUT_ERROR:
+ case H5D_COMPACT:
+ case H5D_CONTIGUOUS:
+ case H5D_VIRTUAL:
+ case H5D_NLAYOUTS:
+ break;
+ default:
+ break;
+ }/*switch*/
+
+ }
+
+ /* applying to all objects */
+ if (options->all_filter)
+ {
+ /* assign the global filter */
+ tmp.nfilters=1;
+ tmp.filter[0]=options->filter_g[0];
+ } /* if all */
+ else
+ {
+ tmp.nfilters=options->op_tbl->objs[idx].nfilters;
+ for ( i=0; i<tmp.nfilters; i++)
+ {
+ tmp.filter[i] = options->op_tbl->objs[idx].filter[i];
+ }
+ }
+
+
+ } /* if idx */
+
+
+ /* no input name */
+
+ else
+ {
+
+ if (options->all_filter)
+ {
+ int k;
+
+ /* assign the global filters */
+ tmp.nfilters=options->n_filter_g;
+ for ( k = 0; k < options->n_filter_g; k++)
+ tmp.filter[k]=options->filter_g[k];
+ }
+ if (options->all_layout)
+ {
+ /* assign the global layout info to the OBJ info */
+ tmp.layout=options->layout_g;
+ switch (options->layout_g)
+ {
+ case H5D_CHUNKED:
+ tmp.chunk.rank=options->chunk_g.rank;
+ for ( i=0; i<tmp.chunk.rank; i++)
+ tmp.chunk.chunk_lengths[i]=options->chunk_g.chunk_lengths[i];
+ break;
+ case H5D_LAYOUT_ERROR:
+ case H5D_COMPACT:
+ case H5D_CONTIGUOUS:
+ case H5D_VIRTUAL:
+ case H5D_NLAYOUTS:
+ break;
+ default:
+ break;
+ }/*switch*/
+ }
+ }
+
+ *obj = tmp;
+ return 1;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: apply_filters
+ *
+ * Purpose: apply the filters in the object to the property list;
+ * do extra checking in the case of SZIP; delete all filters in the case
+ * of H5Z_FILTER_NONE present in the PACK_INFO_T filter array
+ *
+ * Return: 0 success, -1 an error occured
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: December 19, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int apply_filters(const char* name, /* object name from traverse list */
+ int rank, /* rank of dataset */
+ hsize_t *dims, /* dimensions of dataset */
+ size_t msize, /* size of type */
+ hid_t dcpl_id, /* dataset creation property list */
+ pack_opt_t *options, /* repack options */
+ int *has_filter) /* (OUT) object NAME has a filter */
+
+
+{
+ int nfilters; /* number of filters in DCPL */
+ hsize_t chsize[64]; /* chunk size in elements */
+ H5D_layout_t layout;
+ int i;
+ pack_info_t obj;
+
+ *has_filter = 0;
+
+ if (rank==0) /* scalar dataset, do not apply */
+ return 0;
+
+ /*-------------------------------------------------------------------------
+ * initialize the assigment object
+ *-------------------------------------------------------------------------
+ */
+ init_packobject(&obj);
+
+ /*-------------------------------------------------------------------------
+ * find options
+ *-------------------------------------------------------------------------
+ */
+ if (aux_assign_obj(name,options,&obj)==0)
+ return 0;
+
+ /* get information about input filters */
+ if ((nfilters = H5Pget_nfilters(dcpl_id))<0)
+ return -1;
+
+ /*-------------------------------------------------------------------------
+ * check if we have filters in the pipeline
+ * we want to replace them with the input filters
+ * only remove if we are inserting new ones
+ *-------------------------------------------------------------------------
+ */
+ if (nfilters && obj.nfilters )
+ {
+ *has_filter = 1;
+ if (H5Premove_filter(dcpl_id,H5Z_FILTER_ALL)<0)
+ return -1;
+ }
+
+ /*-------------------------------------------------------------------------
+ * check if there is an existent chunk
+ * read it only if there is not a requested layout
+ *-------------------------------------------------------------------------
+ */
+ if (obj.layout == -1 )
+ {
+ if ((layout = H5Pget_layout(dcpl_id))<0)
+ return -1;
+
+ if (layout == H5D_CHUNKED)
+ {
+ if ((rank = H5Pget_chunk(dcpl_id,NELMTS(chsize),chsize/*out*/))<0)
+ return -1;
+ obj.layout = H5D_CHUNKED;
+ obj.chunk.rank = rank;
+ for ( i = 0; i < rank; i++)
+ obj.chunk.chunk_lengths[i] = chsize[i];
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * the type of filter and additional parameter
+ * type can be one of the filters
+ * H5Z_FILTER_NONE 0 , uncompress if compressed
+ * H5Z_FILTER_DEFLATE 1 , deflation like gzip
+ * H5Z_FILTER_SHUFFLE 2 , shuffle the data
+ * H5Z_FILTER_FLETCHER32 3 , fletcher32 checksum of EDC
+ * H5Z_FILTER_SZIP 4 , szip compression
+ * H5Z_FILTER_NBIT 5 , nbit compression
+ * H5Z_FILTER_SCALEOFFSET 6 , scaleoffset compression
+ *-------------------------------------------------------------------------
+ */
+
+ if (obj.nfilters)
+ {
+
+ /*-------------------------------------------------------------------------
+ * filters require CHUNK layout; if we do not have one define a default
+ *-------------------------------------------------------------------------
+ */
+ if (obj.layout==-1)
+ {
+
+ /* stripmine info */
+ hsize_t sm_size[H5S_MAX_RANK]; /*stripmine size */
+ hsize_t sm_nbytes; /*bytes per stripmine */
+
+ obj.chunk.rank = rank;
+
+ /*
+ * determine the strip mine size. The strip mine is
+ * a hyperslab whose size is manageable.
+ */
+
+
+
+ sm_nbytes = msize;
+ for ( i = rank; i > 0; --i)
+ {
+ hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes;
+ if ( size == 0) /* datum size > H5TOOLS_BUFSIZE */
+ size = 1;
+ sm_size[i - 1] = MIN(dims[i - 1], size);
+ sm_nbytes *= sm_size[i - 1];
+ HDassert(sm_nbytes > 0);
+
+ }
+
+ for ( i = 0; i < rank; i++)
+ {
+ obj.chunk.chunk_lengths[i] = sm_size[i];
+ }
+
+ }
+
+ for ( i=0; i<obj.nfilters; i++)
+ {
+ switch (obj.filter[i].filtn)
+ {
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_NONE 0 , uncompress if compressed
+ *-------------------------------------------------------------------------
+ */
+ case H5Z_FILTER_NONE:
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_DEFLATE 1 , deflation like gzip
+ *-------------------------------------------------------------------------
+ */
+ case H5Z_FILTER_DEFLATE:
+ {
+ unsigned aggression; /* the deflate level */
+
+ aggression = obj.filter[i].cd_values[0];
+ /* set up for deflated data */
+ if(H5Pset_chunk(dcpl_id, obj.chunk.rank, obj.chunk.chunk_lengths)<0)
+ return -1;
+ if(H5Pset_deflate(dcpl_id,aggression)<0)
+ return -1;
+ }
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_SZIP 4 , szip compression
+ *-------------------------------------------------------------------------
+ */
+ case H5Z_FILTER_SZIP:
+ {
+ unsigned options_mask;
+ unsigned pixels_per_block;
+
+ options_mask = obj.filter[i].cd_values[0];
+ pixels_per_block = obj.filter[i].cd_values[1];
+
+ /* set up for szip data */
+ if(H5Pset_chunk(dcpl_id,obj.chunk.rank,obj.chunk.chunk_lengths)<0)
+ return -1;
+ if (H5Pset_szip(dcpl_id,options_mask,pixels_per_block)<0)
+ return -1;
+
+ }
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_SHUFFLE 2 , shuffle the data
+ *-------------------------------------------------------------------------
+ */
+ case H5Z_FILTER_SHUFFLE:
+ if(H5Pset_chunk(dcpl_id, obj.chunk.rank, obj.chunk.chunk_lengths)<0)
+ return -1;
+ if (H5Pset_shuffle(dcpl_id)<0)
+ return -1;
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_FLETCHER32 3 , fletcher32 checksum of EDC
+ *-------------------------------------------------------------------------
+ */
+ case H5Z_FILTER_FLETCHER32:
+ if(H5Pset_chunk(dcpl_id, obj.chunk.rank, obj.chunk.chunk_lengths)<0)
+ return -1;
+ if (H5Pset_fletcher32(dcpl_id)<0)
+ return -1;
+ break;
+ /*----------- -------------------------------------------------------------
+ * H5Z_FILTER_NBIT , NBIT compression
+ *-------------------------------------------------------------------------
+ */
+ case H5Z_FILTER_NBIT:
+ if(H5Pset_chunk(dcpl_id, obj.chunk.rank, obj.chunk.chunk_lengths)<0)
+ return -1;
+ if (H5Pset_nbit(dcpl_id)<0)
+ return -1;
+ break;
+ /*----------- -------------------------------------------------------------
+ * H5Z_FILTER_SCALEOFFSET , scale+offset compression
+ *-------------------------------------------------------------------------
+ */
+
+ case H5Z_FILTER_SCALEOFFSET:
+ {
+ H5Z_SO_scale_type_t scale_type;
+ int scale_factor;
+
+ scale_type = (H5Z_SO_scale_type_t)obj.filter[i].cd_values[0];
+ scale_factor = (int)obj.filter[i].cd_values[1];
+
+ if(H5Pset_chunk(dcpl_id, obj.chunk.rank, obj.chunk.chunk_lengths)<0)
+ return -1;
+ if (H5Pset_scaleoffset(dcpl_id,scale_type,scale_factor)<0)
+ return -1;
+ }
+ break;
+ default:
+ {
+ if (H5Pset_filter (dcpl_id, obj.filter[i].filtn, H5Z_FLAG_MANDATORY, obj.filter[i].cd_nelmts, obj.filter[i].cd_values)<0)
+ return -1;
+ if(H5Pset_chunk(dcpl_id, obj.chunk.rank, obj.chunk.chunk_lengths)<0)
+ return -1;
+ }
+ break;
+ } /* switch */
+ }/*i*/
+
+ }
+ /*obj.nfilters*/
+
+ /*-------------------------------------------------------------------------
+ * layout
+ *-------------------------------------------------------------------------
+ */
+
+ if (obj.layout>=0)
+ {
+ /* a layout was defined */
+ if (H5Pset_layout(dcpl_id, obj.layout)<0)
+ return -1;
+
+ if (H5D_CHUNKED == obj.layout)
+ {
+ if(H5Pset_chunk(dcpl_id, obj.chunk.rank, obj.chunk.chunk_lengths)<0)
+ return -1;
+ }
+ else if (H5D_COMPACT == obj.layout)
+ {
+ if (H5Pset_alloc_time(dcpl_id, H5D_ALLOC_TIME_EARLY)<0)
+ return -1;
+ }
+ /* remove filters for the H5D_CONTIGUOUS case */
+ else if (H5D_CONTIGUOUS == obj.layout)
+ {
+ if (H5Premove_filter(dcpl_id,H5Z_FILTER_ALL)<0)
+ return -1;
+ }
+
+ }
+
+ return 0;
+}
+
diff --git a/tools/src/h5repack/h5repack_main.c b/tools/src/h5repack/h5repack_main.c
new file mode 100644
index 0000000..2d48a04
--- /dev/null
+++ b/tools/src/h5repack/h5repack_main.c
@@ -0,0 +1,664 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "h5tools.h"
+#include "h5tools_utils.h"
+#include "h5repack.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5repack"
+
+static int parse_command_line(int argc, const char **argv, pack_opt_t* options);
+static void leave(int ret) H5_ATTR_NORETURN;
+
+
+/* module-scoped variables */
+static int has_i_o = 0;
+const char *infile = NULL;
+const char *outfile = NULL;
+
+/*
+ * Command-line options: The user can specify short or long-named
+ * parameters.
+ */
+static const char *s_opts = "hVvf:l:m:e:nLc:d:s:u:b:M:t:a:i:o:S:T:E";
+static struct long_options l_opts[] = {
+ { "help", no_arg, 'h' },
+ { "version", no_arg, 'V' },
+ { "verbose", no_arg, 'v' },
+ { "filter", require_arg, 'f' },
+ { "layout", require_arg, 'l' },
+ { "minimum", require_arg, 'm' },
+ { "file", require_arg, 'e' },
+ { "native", no_arg, 'n' },
+ { "latest", no_arg, 'L' },
+ { "compact", require_arg, 'c' },
+ { "indexed", require_arg, 'd' },
+ { "ssize", require_arg, 's' },
+ { "ublock", require_arg, 'u' },
+ { "block", require_arg, 'b' },
+ { "metadata_block_size", require_arg, 'M' },
+ { "threshold", require_arg, 't' },
+ { "alignment", require_arg, 'a' },
+ { "infile", require_arg, 'i' }, /* -i for backward compability */
+ { "outfile", require_arg, 'o' }, /* -o for backward compability */
+ { "fs_strategy", require_arg, 'S' },
+ { "fs_threshold", require_arg, 'T' },
+ { "enable-error-stack", no_arg, 'E' },
+ { NULL, 0, '\0' }
+};
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: print usage
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+static void usage(const char *prog) {
+ FLUSHSTREAM(rawoutstream);
+ PRINTSTREAM(rawoutstream, "usage: %s [OPTIONS] file1 file2\n", prog);
+ PRINTVALSTREAM(rawoutstream, " file1 Input HDF5 File\n");
+ PRINTVALSTREAM(rawoutstream, " file2 Output HDF5 File\n");
+ PRINTVALSTREAM(rawoutstream, " OPTIONS\n");
+ PRINTVALSTREAM(rawoutstream, " -h, --help Print a usage message and exit\n");
+ PRINTVALSTREAM(rawoutstream, " -v, --verbose Verbose mode, print object information\n");
+ PRINTVALSTREAM(rawoutstream, " -V, --version Print version number and exit\n");
+ PRINTVALSTREAM(rawoutstream, " -n, --native Use a native HDF5 type when repacking\n");
+ PRINTVALSTREAM(rawoutstream, " -L, --latest Use latest version of file format\n");
+ PRINTVALSTREAM(rawoutstream, " -c L1, --compact=L1 Maximum number of links in header messages\n");
+ PRINTVALSTREAM(rawoutstream, " -d L2, --indexed=L2 Minimum number of links in the indexed format\n");
+ PRINTVALSTREAM(rawoutstream, " -s S[:F], --ssize=S[:F] Shared object header message minimum size\n");
+ PRINTVALSTREAM(rawoutstream, " -m M, --minimum=M Do not apply the filter to datasets smaller than M\n");
+ PRINTVALSTREAM(rawoutstream, " -e E, --file=E Name of file E with the -f and -l options\n");
+ PRINTVALSTREAM(rawoutstream, " -u U, --ublock=U Name of file U with user block data to be added\n");
+ PRINTVALSTREAM(rawoutstream, " -b B, --block=B Size of user block to be added\n");
+ PRINTVALSTREAM(rawoutstream, " -M A, --metadata_block_size=A Metadata block size for H5Pset_meta_block_size\n");
+ PRINTVALSTREAM(rawoutstream, " -t T, --threshold=T Threshold value for H5Pset_alignment\n");
+ PRINTVALSTREAM(rawoutstream, " -a A, --alignment=A Alignment value for H5Pset_alignment\n");
+ PRINTVALSTREAM(rawoutstream, " -f FILT, --filter=FILT Filter type\n");
+ PRINTVALSTREAM(rawoutstream, " -l LAYT, --layout=LAYT Layout type\n");
+ PRINTVALSTREAM(rawoutstream, " -S FS_STRGY, --fs_strategy=FS_STRGY File space management strategy\n");
+ PRINTVALSTREAM(rawoutstream, " -T FS_THRD, --fs_threshold=FS_THRD Free-space section threshold\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " M - is an integer greater than 1, size of dataset in bytes (default is 0) \n");
+ PRINTVALSTREAM(rawoutstream, " E - is a filename.\n");
+ PRINTVALSTREAM(rawoutstream, " S - is an integer\n");
+ PRINTVALSTREAM(rawoutstream, " U - is a filename.\n");
+ PRINTVALSTREAM(rawoutstream, " T - is an integer\n");
+ PRINTVALSTREAM(rawoutstream, " A - is an integer greater than zero\n");
+ PRINTVALSTREAM(rawoutstream, " B - is the user block size, any value that is 512 or greater and is\n");
+ PRINTVALSTREAM(rawoutstream, " a power of 2 (1024 default)\n");
+ PRINTVALSTREAM(rawoutstream, " F - is the shared object header message type, any of <dspace|dtype|fill|\n");
+ PRINTVALSTREAM(rawoutstream, " pline|attr>. If F is not specified, S applies to all messages\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " --enable-error-stack Prints messages from the HDF5 error stack as they\n");
+ PRINTVALSTREAM(rawoutstream, " occur.\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " FS_STRGY is the file space management strategy to use for the output file.\n");
+ PRINTVALSTREAM(rawoutstream, " It is a string as listed below:\n");
+ PRINTVALSTREAM(rawoutstream, " ALL_PERSIST - Use persistent free-space managers, aggregators and virtual file driver\n");
+ PRINTVALSTREAM(rawoutstream, " for file space allocation\n");
+ PRINTVALSTREAM(rawoutstream, " ALL - Use non-persistent free-space managers, aggregators and virtual file driver\n");
+ PRINTVALSTREAM(rawoutstream, " for file space allocation\n");
+ PRINTVALSTREAM(rawoutstream, " AGGR_VFD - Use aggregators and virtual file driver for file space allocation\n");
+ PRINTVALSTREAM(rawoutstream, " VFD - Use virtual file driver for file space allocation\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " FS_THRD is the free-space section threshold to use for the output file.\n");
+ PRINTVALSTREAM(rawoutstream, " It is the minimum size (in bytes) of free-space sections to be tracked\n");
+ PRINTVALSTREAM(rawoutstream, " by the the library's free-space managers.\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " FILT - is a string with the format:\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " <list of objects>:<name of filter>=<filter parameters>\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " <list of objects> is a comma separated list of object names, meaning apply\n");
+ PRINTVALSTREAM(rawoutstream, " compression only to those objects. If no names are specified, the filter\n");
+ PRINTVALSTREAM(rawoutstream, " is applied to all objects\n");
+ PRINTVALSTREAM(rawoutstream, " <name of filter> can be:\n");
+ PRINTVALSTREAM(rawoutstream, " GZIP, to apply the HDF5 GZIP filter (GZIP compression)\n");
+ PRINTVALSTREAM(rawoutstream, " SZIP, to apply the HDF5 SZIP filter (SZIP compression)\n");
+ PRINTVALSTREAM(rawoutstream, " SHUF, to apply the HDF5 shuffle filter\n");
+ PRINTVALSTREAM(rawoutstream, " FLET, to apply the HDF5 checksum filter\n");
+ PRINTVALSTREAM(rawoutstream, " NBIT, to apply the HDF5 NBIT filter (NBIT compression)\n");
+ PRINTVALSTREAM(rawoutstream, " SOFF, to apply the HDF5 Scale/Offset filter\n");
+ PRINTVALSTREAM(rawoutstream, " UD, to apply a user defined filter\n");
+ PRINTVALSTREAM(rawoutstream, " NONE, to remove all filters\n");
+ PRINTVALSTREAM(rawoutstream, " <filter parameters> is optional filter parameter information\n");
+ PRINTVALSTREAM(rawoutstream, " GZIP=<deflation level> from 1-9\n");
+ PRINTVALSTREAM(rawoutstream, " SZIP=<pixels per block,coding> pixels per block is a even number in\n");
+ PRINTVALSTREAM(rawoutstream, " 2-32 and coding method is either EC or NN\n");
+ PRINTVALSTREAM(rawoutstream, " SHUF (no parameter)\n");
+ PRINTVALSTREAM(rawoutstream, " FLET (no parameter)\n");
+ PRINTVALSTREAM(rawoutstream, " NBIT (no parameter)\n");
+ PRINTVALSTREAM(rawoutstream, " SOFF=<scale_factor,scale_type> scale_factor is an integer and scale_type\n");
+ PRINTVALSTREAM(rawoutstream, " is either IN or DS\n");
+ PRINTVALSTREAM(rawoutstream, " UD=<filter_number,cd_value_count,value_1[,value_2,...,value_N]>\n");
+ PRINTVALSTREAM(rawoutstream, " required values for filter_number,cd_value_count,value_1\n");
+ PRINTVALSTREAM(rawoutstream, " optional values for value_2 to value_N\n");
+ PRINTVALSTREAM(rawoutstream, " NONE (no parameter)\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " LAYT - is a string with the format:\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " <list of objects>:<layout type>=<layout parameters>\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " <list of objects> is a comma separated list of object names, meaning that\n");
+ PRINTVALSTREAM(rawoutstream, " layout information is supplied for those objects. If no names are\n");
+ PRINTVALSTREAM(rawoutstream, " specified, the layout type is applied to all objects\n");
+ PRINTVALSTREAM(rawoutstream, " <layout type> can be:\n");
+ PRINTVALSTREAM(rawoutstream, " CHUNK, to apply chunking layout\n");
+ PRINTVALSTREAM(rawoutstream, " COMPA, to apply compact layout\n");
+ PRINTVALSTREAM(rawoutstream, " CONTI, to apply contiguous layout\n");
+ PRINTVALSTREAM(rawoutstream, " <layout parameters> is optional layout information\n");
+ PRINTVALSTREAM(rawoutstream, " CHUNK=DIM[xDIM...xDIM], the chunk size of each dimension\n");
+ PRINTVALSTREAM(rawoutstream, " COMPA (no parameter)\n");
+ PRINTVALSTREAM(rawoutstream, " CONTI (no parameter)\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "Examples of use:\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "1) h5repack -v -f GZIP=1 file1 file2\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " GZIP compression with level 1 to all objects\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "2) h5repack -v -f dset1:SZIP=8,NN file1 file2\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " SZIP compression with 8 pixels per block and NN coding method to object dset1\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "3) h5repack -v -l dset1,dset2:CHUNK=20x10 -f dset3,dset4,dset5:NONE file1 file2\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " Chunked layout, with a layout size of 20x10, to objects dset1 and dset2\n");
+ PRINTVALSTREAM(rawoutstream, " and remove filters to objects dset3, dset4, dset5\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "4) h5repack -L -c 10 -s 20:dtype file1 file2 \n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " Using latest file format with maximum compact group size of 10 and\n");
+ PRINTVALSTREAM(rawoutstream, " and minimum shared datatype size of 20\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "5) h5repack -f SHUF -f GZIP=1 file1 file2 \n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " Add both filters SHUF and GZIP in this order to all datasets\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, "6) h5repack -f UD=307,1,9 file1 file2 \n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+ PRINTVALSTREAM(rawoutstream, " Add bzip2 filter to all datasets\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+}
+
+/*-------------------------------------------------------------------------
+ * Function: leave
+ *
+ * Purpose: Shutdown MPI & HDF5 and call exit()
+ *
+ * Return: Does not return
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, 31. January 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void leave(int ret) {
+ h5tools_close();
+
+ HDexit(ret);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: read_info
+ *
+ * Purpose: read comp and chunk options from a file
+ *
+ * Return: void, exit on error
+ *
+ * Programmer: pvn@ncsa.uiuc.edu
+ *
+ * Date: September, 22, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static
+int read_info(const char *filename, pack_opt_t *options) {
+
+ char stype[10];
+ char comp_info[1024];
+ FILE *fp = NULL;
+ char c;
+ int i, rc = 1;
+ int ret_value = EXIT_SUCCESS;
+
+ if ((fp = HDfopen(filename, "r")) == (FILE *) NULL) {
+ error_msg("cannot open options file %s\n", filename);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = EXIT_FAILURE;
+ goto done;
+ }
+
+ /* cycle until end of file reached */
+ while (1) {
+ rc = fscanf(fp, "%s", stype);
+ if (rc == -1)
+ break;
+
+ /*-------------------------------------------------------------------------
+ * filter
+ *-------------------------------------------------------------------------
+ */
+ if (HDstrcmp(stype,"-f") == 0) {
+ /* find begining of info */
+ i = 0;
+ c = '0';
+ while (c != ' ') {
+ if(fscanf(fp, "%c", &c) < 0 && HDferror(fp)) {
+ error_msg("fscanf error\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = EXIT_FAILURE;
+ goto done;
+ } /* end if */
+ if (HDfeof(fp))
+ break;
+ }
+ c = '0';
+ /* go until end */
+ while (c != ' ') {
+ if(fscanf(fp, "%c", &c) < 0 && HDferror(fp)) {
+ error_msg("fscanf error\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = EXIT_FAILURE;
+ goto done;
+ } /* end if */
+ comp_info[i] = c;
+ i++;
+ if (HDfeof(fp))
+ break;
+ if (c == 10 /*eol*/)
+ break;
+ }
+ comp_info[i - 1] = '\0'; /*cut the last " */
+
+ if (h5repack_addfilter(comp_info, options) == -1) {
+ error_msg("could not add compression option\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * layout
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(stype,"-l") == 0) {
+
+ /* find begining of info */
+ i = 0;
+ c = '0';
+ while (c != ' ') {
+ if(fscanf(fp, "%c", &c) < 0 && HDferror(fp)) {
+ error_msg("fscanf error\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = EXIT_FAILURE;
+ goto done;
+ } /* end if */
+ if (HDfeof(fp))
+ break;
+ }
+ c = '0';
+ /* go until end */
+ while (c != ' ') {
+ if(fscanf(fp, "%c", &c) < 0 && HDferror(fp)) {
+ error_msg("fscanf error\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = EXIT_FAILURE;
+ goto done;
+ } /* end if */
+ comp_info[i] = c;
+ i++;
+ if (HDfeof(fp))
+ break;
+ if (c == 10 /*eol*/)
+ break;
+ }
+ comp_info[i - 1] = '\0'; /*cut the last " */
+
+ if (h5repack_addlayout(comp_info, options) == -1) {
+ error_msg("could not add chunck option\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * not valid
+ *-------------------------------------------------------------------------
+ */
+ else {
+ error_msg("bad file format for %s", filename);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = EXIT_FAILURE;
+ goto done;
+ }
+ }
+
+done:
+ if (fp)
+ HDfclose(fp);
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: parse command line input
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static
+int parse_command_line(int argc, const char **argv, pack_opt_t* options) {
+
+ int opt;
+ int ret_value = 0;
+
+ /* parse command line options */
+ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
+ switch ((char) opt) {
+
+ /* -i for backward compability */
+ case 'i':
+ infile = opt_arg;
+ has_i_o = 1;
+ break;
+
+ /* -o for backward compability */
+ case 'o':
+ outfile = opt_arg;
+ has_i_o = 1;
+ break;
+
+ case 'h':
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ ret_value = -1;
+ goto done;
+
+ case 'V':
+ print_version(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ ret_value = -1;
+ goto done;
+
+ case 'v':
+ options->verbose = 1;
+ break;
+
+ case 'f':
+ /* parse the -f filter option */
+ if (h5repack_addfilter(opt_arg, options) < 0) {
+ error_msg("in parsing filter\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = -1;
+ goto done;
+ }
+ break;
+
+ case 'l':
+ /* parse the -l layout option */
+ if (h5repack_addlayout(opt_arg, options) < 0) {
+ error_msg("in parsing layout\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = -1;
+ goto done;
+ }
+ break;
+
+ case 'm':
+ options->min_comp = HDstrtoull(opt_arg , NULL, 0);
+ if ((int) options->min_comp <= 0) {
+ error_msg("invalid minimum compress size <%s>\n", opt_arg);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = -1;
+ goto done;
+ }
+ break;
+
+ case 'e':
+ ret_value = read_info(opt_arg, options);
+ if (ret_value < 0)
+ goto done;
+ break;
+
+ case 'n':
+ options->use_native = 1;
+ break;
+
+ case 'L':
+ options->latest = TRUE;
+ break;
+
+ case 'c':
+ options->grp_compact = HDatoi( opt_arg );
+ if (options->grp_compact > 0)
+ options->latest = TRUE; /* must use latest format */
+ break;
+
+ case 'd':
+ options->grp_indexed = HDatoi( opt_arg );
+ if (options->grp_indexed > 0)
+ options->latest = TRUE; /* must use latest format */
+ break;
+
+ case 's':
+ {
+ int idx = 0;
+ int ssize = 0;
+ char *msgPtr = HDstrchr( opt_arg, ':');
+ options->latest = TRUE; /* must use latest format */
+ if (msgPtr == NULL) {
+ ssize = HDatoi( opt_arg );
+ for (idx = 0; idx < 5; idx++)
+ options->msg_size[idx] = ssize;
+ }
+ else {
+ char msgType[10];
+ HDstrcpy(msgType, msgPtr + 1);
+ msgPtr[0] = '\0';
+ ssize = HDatoi( opt_arg );
+ if (HDstrncmp(msgType, "dspace",6) == 0) {
+ options->msg_size[0] = ssize;
+ }
+ else if (HDstrncmp(msgType, "dtype", 5) == 0) {
+ options->msg_size[1] = ssize;
+ }
+ else if (HDstrncmp(msgType, "fill", 4) == 0) {
+ options->msg_size[2] = ssize;
+ }
+ else if (HDstrncmp(msgType, "pline", 5) == 0) {
+ options->msg_size[3] = ssize;
+ }
+ else if (HDstrncmp(msgType, "attr", 4) == 0) {
+ options->msg_size[4] = ssize;
+ }
+ }
+ }
+ break;
+
+ case 'u':
+ options->ublock_filename = opt_arg;
+ break;
+
+ case 'b':
+ options->ublock_size = (hsize_t) HDatol( opt_arg );
+ break;
+
+ case 'M':
+ options->meta_block_size = (hsize_t) HDatol( opt_arg );
+ break;
+
+ case 't':
+ options->threshold = (hsize_t) HDatol( opt_arg );
+ break;
+
+ case 'a':
+ options->alignment = HDstrtoull(opt_arg , NULL, 0);
+ if (options->alignment < 1) {
+ error_msg("invalid alignment size\n", opt_arg);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = -1;
+ goto done;
+ }
+ break;
+
+ case 'S':
+ {
+ char strategy[MAX_NC_NAME];
+
+ HDstrcpy(strategy, opt_arg);
+ if (!HDstrcmp(strategy, "ALL_PERSIST"))
+ options->fs_strategy = H5F_FILE_SPACE_ALL_PERSIST;
+ else if (!HDstrcmp(strategy, "ALL"))
+ options->fs_strategy = H5F_FILE_SPACE_ALL;
+ else if (!HDstrcmp(strategy, "AGGR_VFD"))
+ options->fs_strategy = H5F_FILE_SPACE_AGGR_VFD;
+ else if (!HDstrcmp(strategy, "VFD"))
+ options->fs_strategy = H5F_FILE_SPACE_VFD;
+ else {
+ error_msg("invalid file space management strategy\n", opt_arg);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = -1;
+ goto done;
+ }
+ }
+ break;
+
+ case 'T':
+ options->fs_threshold = (hsize_t) HDatol( opt_arg );
+ break;
+
+ case 'E':
+ enable_error_stack = TRUE;
+ break;
+
+ default:
+ break;
+ } /* switch */
+
+ } /* while */
+
+ if (has_i_o == 0) {
+ /* check for file names to be processed */
+ if (argc <= opt_ind || argv[opt_ind + 1] == NULL) {
+ error_msg("missing file names\n");
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ ret_value = -1;
+ }
+ }
+
+done:
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: h5repack main program
+ *
+ * Return: Success: EXIT_SUCCESS(0)
+ *
+ * Failure: EXIT_FAILURE(1)
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: May 9, 2003
+ *
+ * Comments:
+ *
+ *-------------------------------------------------------------------------
+ */
+int main(int argc, const char **argv) {
+ H5E_auto2_t func;
+ H5E_auto2_t tools_func;
+ void *edata;
+ void *tools_edata;
+
+ pack_opt_t options; /*the global options */
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Disable error reporting */
+ H5Eget_auto2(H5E_DEFAULT, &func, &edata);
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /* Disable tools error reporting */
+ H5Eget_auto2(H5tools_ERR_STACK_g, &tools_func, &tools_edata);
+ H5Eset_auto2(H5tools_ERR_STACK_g, NULL, NULL);
+
+ /* update hyperslab buffer size from H5TOOLS_BUFSIZE env if exist */
+ if (h5tools_getenv_update_hyperslab_bufsize() < 0) {
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ /* initialize options */
+ h5repack_init(&options, 0, FALSE, H5F_FILE_SPACE_DEFAULT, (hsize_t) 0);
+
+ if (parse_command_line(argc, argv, &options) < 0)
+ goto done;
+
+ /* get file names if they were not yet got */
+ if (has_i_o == 0) {
+
+ if (argv[opt_ind] != NULL && argv[opt_ind + 1] != NULL) {
+ infile = argv[opt_ind];
+ outfile = argv[opt_ind + 1];
+
+ if ( HDstrcmp( infile, outfile ) == 0) {
+ error_msg("file names cannot be the same\n");
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ }
+ else {
+ error_msg("file names missing\n");
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ }
+
+ if (enable_error_stack) {
+ H5Eset_auto2(H5E_DEFAULT, func, edata);
+ H5Eset_auto2(H5tools_ERR_STACK_g, tools_func, tools_edata);
+ }
+
+ /* pack it */
+ h5tools_setstatus(h5repack(infile, outfile, &options));
+
+done:
+ /* free tables */
+ h5repack_end(&options);
+
+ leave(h5tools_getstatus());
+}
+
diff --git a/tools/src/h5repack/h5repack_opttable.c b/tools/src/h5repack/h5repack_opttable.c
new file mode 100644
index 0000000..8c98b76
--- /dev/null
+++ b/tools/src/h5repack/h5repack_opttable.c
@@ -0,0 +1,367 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "h5repack.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/*-------------------------------------------------------------------------
+ * Function: init_packobject
+ *
+ * Purpose: initialize a pack_info_t structure
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void init_packobject(pack_info_t *obj) {
+ int j, k;
+
+ HDstrcpy(obj->path, "\0");
+ for (j = 0; j < H5_REPACK_MAX_NFILTERS; j++) {
+ obj->filter[j].filtn = -1;
+ for (k = 0; k < CD_VALUES; k++)
+ obj->filter[j].cd_values[k] = 0;
+ }
+ obj->chunk.rank = -1;
+ obj->refobj_id = -1;
+ obj->layout = H5D_LAYOUT_ERROR;
+ obj->nfilters = 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: aux_tblinsert_filter
+ *
+ * Purpose: auxiliary function, inserts the filter in object OBJS[ I ]
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void aux_tblinsert_filter(pack_opttbl_t *table, unsigned int I,
+ filter_info_t filt) {
+ if (table->objs[I].nfilters < H5_REPACK_MAX_NFILTERS) {
+ table->objs[I].filter[table->objs[I].nfilters++] = filt;
+ }
+ else {
+ error_msg(
+ "cannot insert the filter in this object.\
+ Maximum capacity exceeded\n");
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: aux_tblinsert_layout
+ *
+ * Purpose: auxiliary function, inserts the layout in object OBJS[ I ]
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void aux_tblinsert_layout(pack_opttbl_t *table, unsigned int I,
+ pack_info_t *pack) {
+ int k;
+
+ table->objs[I].layout = pack->layout;
+ if (H5D_CHUNKED == pack->layout) {
+ /* -2 means the NONE option, remove chunking
+ and set the layout to contiguous */
+ if (pack->chunk.rank == -2) {
+ table->objs[I].layout = H5D_CONTIGUOUS;
+ table->objs[I].chunk.rank = -2;
+ }
+ /* otherwise set the chunking type */
+ else {
+ table->objs[I].chunk.rank = pack->chunk.rank;
+ for (k = 0; k < pack->chunk.rank; k++)
+ table->objs[I].chunk.chunk_lengths[k] =
+ pack->chunk.chunk_lengths[k];
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: aux_inctable
+ *
+ * Purpose: auxiliary function, increases the size of the collection by N_OBJS
+ *
+ * Return: 0, ok, -1, fail
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+aux_inctable(pack_opttbl_t *table, unsigned n_objs)
+{
+ unsigned u;
+
+ table->size += n_objs;
+ table->objs = (pack_info_t*) HDrealloc(table->objs, table->size * sizeof(pack_info_t));
+ if (table->objs == NULL) {
+ error_msg("not enough memory for options table\n");
+ return -1;
+ }
+
+ for (u = table->nelems; u < table->size; u++)
+ init_packobject(&table->objs[u]);
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: options_table_init
+ *
+ * Purpose: init options table
+ *
+ * Return: 0, ok, -1, fail
+ *
+ *-------------------------------------------------------------------------
+ */
+int options_table_init(pack_opttbl_t **tbl) {
+ unsigned int i;
+ pack_opttbl_t *table;
+
+ if (NULL == (table = (pack_opttbl_t *) HDmalloc(sizeof(pack_opttbl_t)))) {
+ error_msg("not enough memory for options table\n");
+ return -1;
+ }
+
+ table->size = 30;
+ table->nelems = 0;
+ if (NULL == (table->objs =
+ (pack_info_t*) HDmalloc(table->size * sizeof(pack_info_t)))) {
+ error_msg("not enough memory for options table\n");
+ HDfree(table);
+ return -1;
+ }
+
+ for (i = 0; i < table->size; i++)
+ init_packobject(&table->objs[i]);
+
+ *tbl = table;
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: options_table_free
+ *
+ * Purpose: free table memory
+ *
+ * Return: 0
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int options_table_free(pack_opttbl_t *table) {
+ HDfree(table->objs);
+ HDfree(table);
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: options_add_layout
+ *
+ * Purpose: add a layout option to the option list
+ *
+ * Return: 0, ok, -1, fail
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+options_add_layout(obj_list_t *obj_list, unsigned n_objs, pack_info_t *pack,
+ pack_opttbl_t *table)
+{
+ unsigned i, j, I;
+ unsigned added = 0;
+ hbool_t found = FALSE;
+
+ /* increase the size of the collection by N_OBJS if necessary */
+ if (table->nelems + n_objs >= table->size)
+ if (aux_inctable(table, n_objs) < 0)
+ return -1;
+
+ /* search if this object is already in the table; "path" is the key */
+ if (table->nelems > 0) {
+ /* go tru the supplied list of names */
+ for (j = 0; j < n_objs; j++) {
+ /* linear table search */
+ for (i = 0; i < table->nelems; i++) {
+ /*already on the table */
+ if (HDstrcmp(obj_list[j].obj,table->objs[i].path) == 0) {
+ /* already chunk info inserted for this one; exit */
+ if (table->objs[i].chunk.rank > 0) {
+ error_msg("chunk information already inserted for <%s>\n", obj_list[j].obj);
+ HDexit(EXIT_FAILURE);
+ }
+ /* insert the layout info */
+ else {
+ aux_tblinsert_layout(table, i, pack);
+ found = TRUE;
+ break;
+ }
+ } /* if */
+ } /* i */
+
+ if (!found) {
+ /* keep the grow in a temp var */
+ I = table->nelems + added;
+ added++;
+ HDstrcpy(table->objs[I].path, obj_list[j].obj);
+ aux_tblinsert_layout(table, I, pack);
+ }
+ /* cases where we have an already inserted name but there is a new name also
+ example:
+ -f dset1:GZIP=1 -l dset1,dset2:CHUNK=20x20
+ dset1 is already inserted, but dset2 must also be
+ */
+ else
+ if(found && HDstrcmp(obj_list[j].obj,table->objs[i].path) != 0) {
+ /* keep the grow in a temp var */
+ I = table->nelems + added;
+ added++;
+ HDstrcpy(table->objs[I].path, obj_list[j].obj);
+ aux_tblinsert_layout(table, I, pack);
+ }
+ } /* j */
+ }
+ /* first time insertion */
+ else {
+ /* go tru the supplied list of names */
+ for (j = 0; j < n_objs; j++) {
+ I = table->nelems + added;
+ added++;
+ HDstrcpy(table->objs[I].path, obj_list[j].obj);
+ aux_tblinsert_layout(table, I, pack);
+ }
+ }
+
+ table->nelems += added;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: options_add_filter
+ *
+ * Purpose: add a compression -f option to the option list
+ *
+ * Return: 0, ok, -1, fail
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+options_add_filter(obj_list_t *obj_list, unsigned n_objs, filter_info_t filt,
+ pack_opttbl_t *table)
+{
+ unsigned int i, j, I;
+ unsigned added = 0;
+ hbool_t found = FALSE;
+
+ /* increase the size of the collection by N_OBJS if necessary */
+ if (table->nelems + n_objs >= table->size)
+ if (aux_inctable(table, n_objs) < 0)
+ return -1;
+
+ /* search if this object is already in the table; "path" is the key */
+ if (table->nelems > 0) {
+ /* go tru the supplied list of names */
+ for (j = 0; j < n_objs; j++) {
+ /* linear table search */
+ for (i = 0; i < table->nelems; i++) {
+ /*already on the table */
+ if (HDstrcmp(obj_list[j].obj, table->objs[i].path) == 0) {
+ /* insert */
+ aux_tblinsert_filter(table, i, filt);
+ found = TRUE;
+ break;
+ } /* if */
+ } /* i */
+
+ if (!found) {
+ /* keep the grow in a temp var */
+ I = table->nelems + added;
+ added++;
+ HDstrcpy(table->objs[I].path, obj_list[j].obj);
+ aux_tblinsert_filter(table, I, filt);
+ }
+ /* cases where we have an already inserted name but there is a new name also
+ example:
+ -l dset1:CHUNK=20x20 -f dset1,dset2:GZIP=1
+ dset1 is already inserted, but dset2 must also be
+ */
+ else
+ if(found && HDstrcmp(obj_list[j].obj,table->objs[i].path) != 0) {
+ /* keep the grow in a temp var */
+ I = table->nelems + added;
+ added++;
+ HDstrcpy(table->objs[I].path, obj_list[j].obj);
+ aux_tblinsert_filter(table, I, filt);
+ }
+ } /* j */
+ }
+
+ /* first time insertion */
+ else {
+ /* go tru the supplied list of names */
+ for (j = 0; j < n_objs; j++) {
+ I = table->nelems + added;
+ added++;
+ HDstrcpy(table->objs[I].path, obj_list[j].obj);
+ aux_tblinsert_filter(table, I, filt);
+ }
+ }
+
+ table->nelems += added;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: options_get_object
+ *
+ * Purpose: get object from table; "path" is the key
+ *
+ * Return: pack_info_t* OBJECT or NULL if not found; PATH is the key
+ *
+ *-------------------------------------------------------------------------
+ */
+
+pack_info_t* options_get_object(const char *path, pack_opttbl_t *table) {
+ unsigned int i;
+ char tbl_path[MAX_NC_NAME + 1]; /* +1 for start with "/" case */
+
+ for (i = 0; i < table->nelems; i++) {
+ /* make full path (start with "/") to compare correctly */
+ if (HDstrncmp(table->objs[i].path, "/", 1)) {
+ HDstrcpy(tbl_path, "/");
+ HDstrcat(tbl_path, table->objs[i].path);
+ }
+ else
+ HDstrcpy(tbl_path, table->objs[i].path);
+
+ /* found it */
+ if (HDstrcmp(tbl_path, path) == 0) {
+ return (&table->objs[i]);
+ }
+ }
+
+ return NULL;
+}
+
diff --git a/tools/src/h5repack/h5repack_parse.c b/tools/src/h5repack/h5repack_parse.c
new file mode 100644
index 0000000..004b9e4
--- /dev/null
+++ b/tools/src/h5repack/h5repack_parse.c
@@ -0,0 +1,616 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "h5repack.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/*-------------------------------------------------------------------------
+ * Function: parse_filter
+ *
+ * Purpose: read filter information
+ *
+ * Return: a list of names, the number of names and its compression type
+ *
+ * <name of filter> can be:
+ * GZIP, to apply the HDF5 GZIP filter (GZIP compression)
+ * SZIP, to apply the HDF5 SZIP filter (SZIP compression)
+ * SHUF, to apply the HDF5 shuffle filter
+ * FLET, to apply the HDF5 checksum filter
+ * NBIT, to apply the HDF5 NBIT filter (NBIT compression)
+ * SOFF, to apply the HDF5 scale+offset filter (compression)
+ * UD, to apply a User Defined filter k,m,n1[,…,nm]
+ * NONE, to remove the filter
+ *
+ * Examples:
+ * "GZIP=6"
+ * "A,B:NONE"
+ *-------------------------------------------------------------------------
+ */
+obj_list_t* parse_filter(const char *str, unsigned *n_objs, filter_info_t *filt,
+ pack_opt_t *options, int *is_glb) {
+ size_t i, m, u;
+ char c;
+ size_t len = HDstrlen(str);
+ int k, l, p, q, end_obj = -1, no_param = 0;
+ unsigned j, n;
+ char sobj[MAX_NC_NAME];
+ char scomp[10];
+ char stype[6];
+ char smask[3];
+ obj_list_t* obj_list = NULL;
+ unsigned pixels_per_block;
+
+ /* initialize compression info */
+ HDmemset(filt, 0, sizeof(filter_info_t));
+ *is_glb = 0;
+
+ /* check for the end of object list and number of objects */
+ for (i = 0, n = 0; i < len; i++) {
+ c = str[i];
+ if (c == ':')
+ end_obj = (int) i;
+ if (c == ',')
+ n++;
+ }
+
+ /* Check for missing : */
+ if (end_obj == -1) {
+ /* apply to all objects */
+ options->all_filter = 1;
+ *is_glb = 1;
+ }
+
+ n++;
+ obj_list = (obj_list_t *) HDmalloc(n * sizeof(obj_list_t));
+ if (obj_list == NULL) {
+ error_msg("could not allocate object list\n");
+ return NULL;
+ }
+ *n_objs = n;
+
+ /* get object list */
+ if (end_obj > 0)
+ for (j = 0, k = 0, n = 0; j < (unsigned) end_obj; j++, k++) {
+ c = str[j];
+ sobj[k] = c;
+ if (c == ',' || j == (unsigned) (end_obj - 1)) {
+ if (c == ',')
+ sobj[k] = '\0';
+ else
+ sobj[k + 1] = '\0';
+ HDstrcpy(obj_list[n].obj, sobj);
+ HDmemset(sobj, 0, sizeof(sobj));
+ n++;
+ k = -1;
+ }
+ }
+ /* nothing after : */
+ if (end_obj + 1 == (int) len) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("input Error: Invalid compression type in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+
+ /* get filter additional parameters */
+ m = 0;
+ for (i = (size_t)(end_obj + 1), k = 0, j = 0; i < len; i++, k++) {
+ c = str[i];
+ scomp[k] = c;
+ if (c == '=' || i == len - 1) {
+ if (c == '=') { /*one more parameter */
+ scomp[k] = '\0'; /*cut space */
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_SZIP
+ * szip has the format SZIP=<pixels per block,coding>
+ * pixels per block is a even number in 2-32 and coding method is 'EC' or 'NN'
+ * example SZIP=8,NN
+ *-------------------------------------------------------------------------
+ */
+ if (HDstrcmp(scomp, "SZIP") == 0) {
+ l = -1; /* mask index check */
+ for (m = 0, u = i + 1; u < len; u++, m++) {
+ if (str[u] == ',') {
+ stype[m] = '\0'; /* end digit of szip */
+ l = 0; /* start EC or NN search */
+ u++; /* skip ',' */
+ }
+ c = str[u];
+ if (!HDisdigit(c) && l == -1) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("compression parameter not digit in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ if (l == -1)
+ stype[m] = c;
+ else {
+ smask[l] = c;
+ l++;
+ if (l == 2) {
+ smask[l] = '\0';
+ i = len - 1; /* end */
+ (*n_objs)--; /* we counted an extra ',' */
+ if (HDstrcmp(smask,"NN") == 0)
+ filt->cd_values[j++] = H5_SZIP_NN_OPTION_MASK;
+ else if (HDstrcmp(smask,"EC") == 0)
+ filt->cd_values[j++] = H5_SZIP_EC_OPTION_MASK;
+ else {
+ error_msg("szip mask must be 'NN' or 'EC' \n");
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ }
+ } /* u */
+ } /*if */
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_SCALEOFFSET
+ * scaleoffset has the format SOFF=<scale_factor,scale_type>
+ * scale_type can be
+ * integer datatype, H5Z_SO_INT (IN)
+ * float datatype using D-scaling method, H5Z_SO_FLOAT_DSCALE (DS)
+ * float datatype using E-scaling method, H5Z_SO_FLOAT_ESCALE (ES) , not yet implemented
+ * for integer datatypes, scale_factor denotes Minimum Bits
+ * for float datatypes, scale_factor denotes decimal scale factor
+ * examples
+ * SOFF=31,IN
+ * SOFF=3,DF
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(scomp, "SOFF") == 0) {
+ l = -1; /* mask index check */
+ for (m = 0, u = i + 1; u < len; u++, m++) {
+ if (str[u] == ',') {
+ stype[m] = '\0'; /* end digit */
+ l = 0; /* start 'IN' , 'DS', or 'ES' search */
+ u++; /* skip ',' */
+ }
+ c = str[u];
+ if (!HDisdigit(c) && l == -1) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("compression parameter is not a digit in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ if (l == -1)
+ stype[m] = c;
+ else {
+ smask[l] = c;
+ l++;
+ if (l == 2) {
+ smask[l] = '\0';
+ i = len - 1; /* end */
+ (*n_objs)--; /* we counted an extra ',' */
+ if (HDstrcmp(smask,"IN") == 0)
+ filt->cd_values[j++] = H5Z_SO_INT;
+ else if (HDstrcmp(smask, "DS") == H5Z_SO_FLOAT_DSCALE)
+ filt->cd_values[j++] = H5Z_SO_FLOAT_DSCALE;
+ else {
+ error_msg("scale type must be 'IN' or 'DS' \n");
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ }
+ } /* u */
+ } /*if */
+
+ /*-------------------------------------------------------------------------
+ * User Defined
+ * has the format UD=<filter_number,cd_value_count,value_1[,value_2,...,value_N]>
+ * BZIP2 example
+ * UD=307,1,9
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(scomp, "UD") == 0) {
+ l = -1; /* filter number index check */
+ p = -1; /* CD_VAL count check */
+ for (m = 0, q = 0, u = i + 1; u < len; u++, m++, q++) {
+ if (str[u] == ',') {
+ stype[q] = '\0'; /* end digit */
+ if (l == -1) {
+ filt->filtn = HDatoi(stype);
+ l = 0;
+ }
+ else if (p == -1) {
+ filt->cd_nelmts = HDstrtoull(stype, NULL, 0);
+ p = 0;
+ }
+ else
+ filt->cd_values[j++] = (unsigned)HDstrtoul(stype, NULL, 0);
+ q = 0;
+ u++; /* skip ',' */
+ }
+ c = str[u];
+ if (!HDisdigit(c) && l == -1) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("filter number parameter is not a digit in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ stype[q] = c;
+ } /* for u */
+ stype[q] = '\0';
+ } /*if */
+
+ /*-------------------------------------------------------------------------
+ * all other filters
+ *-------------------------------------------------------------------------
+ */
+ else {
+ /* here we could have 1 or 2 digits */
+ for (m = 0, u = i + 1; u < len; u++, m++) {
+ c = str[u];
+ if (!HDisdigit(c)) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("compression parameter is not a digit in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ stype[m] = c;
+ } /* u */
+
+ stype[m] = '\0';
+ } /*if */
+
+ filt->cd_values[j++] = (unsigned) HDstrtoul(stype, NULL, 0);
+ if(filt->cd_nelmts == 0)
+ j = 0;
+ i += m; /* jump */
+ }
+ else if (i == len - 1) { /*no more parameters */
+ scomp[k + 1] = '\0';
+ no_param = 1;
+ }
+
+ /*-------------------------------------------------------------------------
+ * translate from string to filter symbol
+ *-------------------------------------------------------------------------
+ */
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_NONE
+ *-------------------------------------------------------------------------
+ */
+ if (HDstrcmp(scomp, "NONE") == 0) {
+ filt->filtn = H5Z_FILTER_NONE;
+ filt->cd_nelmts = 0;
+ }
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_DEFLATE
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(scomp, "GZIP") == 0) {
+ filt->filtn = H5Z_FILTER_DEFLATE;
+ filt->cd_nelmts = 1;
+ if (no_param) { /*no more parameters, GZIP must have parameter */
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("missing compression parameter in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_SZIP
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(scomp, "SZIP") == 0) {
+ filt->filtn = H5Z_FILTER_SZIP;
+ filt->cd_nelmts = 2;
+ if (no_param) { /*no more parameters, SZIP must have parameter */
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("missing compression parameter in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_SHUFFLE
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(scomp, "SHUF") == 0) {
+ filt->filtn = H5Z_FILTER_SHUFFLE;
+ filt->cd_nelmts = 0;
+ if (m > 0) { /*shuffle does not have parameter */
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("extra parameter in SHUF <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_FLETCHER32
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(scomp, "FLET") == 0) {
+ filt->filtn = H5Z_FILTER_FLETCHER32;
+ filt->cd_nelmts = 0;
+ if (m > 0) { /*shuffle does not have parameter */
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("extra parameter in FLET <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_NBIT
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(scomp, "NBIT") == 0) {
+ filt->filtn = H5Z_FILTER_NBIT;
+ filt->cd_nelmts = 0;
+ if (m > 0) { /*nbit does not have parameter */
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("extra parameter in NBIT <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_SCALEOFFSET
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(scomp, "SOFF") == 0) {
+ filt->filtn = H5Z_FILTER_SCALEOFFSET;
+ filt->cd_nelmts = 2;
+ if (no_param) { /*no more parameters, SOFF must have parameter */
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("missing compression parameter in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * User Defined Filter
+ *-------------------------------------------------------------------------
+ */
+ else if (HDstrcmp(scomp, "UD") == 0) {
+ /* parameters does not match count */
+ if (filt->cd_nelmts != j) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("incorrect number of compression parameters in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ else {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("invalid filter type in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ } /*i*/
+
+ /*-------------------------------------------------------------------------
+ * check valid parameters
+ *-------------------------------------------------------------------------
+ */
+
+ switch (filt->filtn) {
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_DEFLATE
+ *-------------------------------------------------------------------------
+ */
+ case H5Z_FILTER_DEFLATE:
+ if (filt->cd_values[0] > 9) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("invalid compression parameter in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ break;
+ /*-------------------------------------------------------------------------
+ * H5Z_FILTER_SZIP
+ *-------------------------------------------------------------------------
+ */
+ case H5Z_FILTER_SZIP:
+ pixels_per_block = filt->cd_values[0];
+ if ((pixels_per_block % 2) == 1) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("pixels_per_block is not even in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ if (pixels_per_block > H5_SZIP_MAX_PIXELS_PER_BLOCK) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("pixels_per_block is too large in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ if ((HDstrcmp(smask,"NN") != 0) && (HDstrcmp(smask,"EC") != 0)) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("szip mask must be 'NN' or 'EC' \n");
+ HDexit(EXIT_FAILURE);
+ }
+ break;
+ default:
+ break;
+ };
+
+ return obj_list;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: parse_layout
+ *
+ * Purpose: read layout info
+ *
+ * Return: a list of names, the number of names and its chunking info for
+ * chunked. NULL, on error
+ * the layout type can be:
+ * CHUNK, to apply chunking layout
+ * CONTI, to apply contiguous layout
+ * COMPA, to apply compact layout
+ *
+ * Example:
+ * "AA,B,CDE:CHUNK=10X10"
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: December 30, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+obj_list_t* parse_layout(const char *str, unsigned *n_objs, pack_info_t *pack, /* info about layout needed */
+pack_opt_t *options) {
+ obj_list_t* obj_list = NULL;
+ unsigned i, j, n;
+ char c;
+ size_t len = HDstrlen(str);
+ int k, end_obj = -1, c_index;
+ char sobj[MAX_NC_NAME];
+ char sdim[10];
+ char slayout[10];
+
+ HDmemset(sdim, '\0', sizeof(sdim));
+ HDmemset(sobj, '\0', sizeof(sobj));
+ HDmemset(slayout, '\0', sizeof(slayout));
+
+ /* check for the end of object list and number of objects */
+ for (i = 0, n = 0; i < len; i++) {
+ c = str[i];
+ if (c == ':')
+ end_obj = (int) i;
+ if (c == ',')
+ n++;
+ }
+
+ if (end_obj == -1) { /* missing : chunk all */
+ options->all_layout = 1;
+ }
+
+ n++;
+ obj_list = (obj_list_t*) HDmalloc(n * sizeof(obj_list_t));
+ if (obj_list == NULL) {
+ error_msg("could not allocate object list\n");
+ return NULL;
+ }
+ *n_objs = n;
+
+ /* get object list */
+ if (end_obj > 0)
+ for (j = 0, k = 0, n = 0; j < (unsigned) end_obj; j++, k++) {
+ c = str[j];
+ sobj[k] = c;
+ if (c == ',' || j == (unsigned) (end_obj - 1)) {
+ if (c == ',')
+ sobj[k] = '\0';
+ else
+ sobj[k + 1] = '\0';
+ HDstrcpy(obj_list[n].obj, sobj);
+ HDmemset(sobj, 0, sizeof(sobj));
+ n++;
+ k = -1;
+ }
+ }
+
+ /* nothing after : */
+ if (end_obj + 1 == (int) len) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("in parse layout, no characters after : in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+
+ /* get layout info */
+ for (j = (unsigned) (end_obj + 1), n = 0; n <= 5; j++, n++) {
+ if (n == 5) {
+ slayout[n] = '\0'; /*cut string */
+ if (HDstrcmp(slayout, "COMPA") == 0)
+ pack->layout = H5D_COMPACT;
+ else if (HDstrcmp(slayout, "CONTI") == 0)
+ pack->layout = H5D_CONTIGUOUS;
+ else if (HDstrcmp(slayout, "CHUNK") == 0)
+ pack->layout = H5D_CHUNKED;
+ else {
+ error_msg("in parse layout, not a valid layout in <%s>\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ else {
+ c = str[j];
+ slayout[n] = c;
+ }
+ } /* j */
+
+ if (pack->layout == H5D_CHUNKED) {
+ /*-------------------------------------------------------------------------
+ * get chunk info
+ *-------------------------------------------------------------------------
+ */
+ k = 0;
+ if (j > len) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("in parse layout, <%s> Chunk dimensions missing\n", str);
+ HDexit(EXIT_FAILURE);
+ }
+
+ for (i = j, c_index = 0; i < len; i++) {
+ c = str[i];
+ sdim[k] = c;
+ k++; /*increment sdim index */
+
+ if (!HDisdigit(c) && c != 'x' && c != 'N' && c != 'O' && c != 'N' && c != 'E') {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("in parse layout, <%s> Not a valid character in <%s>\n", sdim, str);
+ HDexit(EXIT_FAILURE);
+ }
+
+ if (c == 'x' || i == len - 1) {
+ if (c == 'x') {
+ sdim[k - 1] = '\0';
+ k = 0;
+ pack->chunk.chunk_lengths[c_index] = HDstrtoull(sdim, NULL, 0);
+ if (pack->chunk.chunk_lengths[c_index] == 0) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("in parse layout, <%s> conversion to number in <%s>\n", sdim, str);
+ HDexit(EXIT_FAILURE);
+ }
+ c_index++;
+ }
+ else if (i == len - 1) { /*no more parameters */
+ sdim[k] = '\0';
+ k = 0;
+ if (HDstrcmp(sdim,"NONE") == 0) {
+ pack->chunk.rank = -2;
+ }
+ else {
+ pack->chunk.chunk_lengths[c_index] = HDstrtoull(sdim, NULL, 0);
+ if (pack->chunk.chunk_lengths[c_index] == 0) {
+ if (obj_list)
+ HDfree(obj_list);
+ error_msg("in parse layout, <%s> conversion to number in <%s>\n", sdim, str);
+ HDexit(EXIT_FAILURE);
+ }
+ pack->chunk.rank = c_index + 1;
+ }
+ } /*if */
+ } /*if c=='x' || i==len-1 */
+ } /*i*/
+ } /*H5D_CHUNKED*/
+
+ return obj_list;
+}
diff --git a/tools/src/h5repack/h5repack_refs.c b/tools/src/h5repack/h5repack_refs.c
new file mode 100644
index 0000000..f0f32c3
--- /dev/null
+++ b/tools/src/h5repack/h5repack_refs.c
@@ -0,0 +1,877 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "h5repack.h"
+#include "h5diff.h"
+#include "h5tools.h"
+
+
+/*-------------------------------------------------------------------------
+ * local functions
+ *-------------------------------------------------------------------------
+ */
+
+static const char* MapIdToName(hid_t refobj_id,trav_table_t *travt);
+static int copy_refs_attr(hid_t loc_in, hid_t loc_out, pack_opt_t *options,
+ trav_table_t *travt, hid_t fidout);
+static herr_t update_ref_value(hid_t obj_id, H5R_type_t ref_type, void *ref_in,
+ hid_t fid_out, void *ref_out, trav_table_t *travt);
+
+/*-------------------------------------------------------------------------
+ * Function: do_copy_refobjs
+ *
+ * Purpose: duplicate all referenced HDF5 objects in the file
+ * and create hard links
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: December, 10, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int do_copy_refobjs(hid_t fidin,
+ hid_t fidout,
+ trav_table_t *travt,
+ pack_opt_t *options) /* repack options */
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ hid_t grp_in = (-1); /* read group ID */
+ hid_t grp_out = (-1); /* write group ID */
+ hid_t dset_in = (-1); /* read dataset ID */
+ hid_t dset_out = (-1); /* write dataset ID */
+ hid_t type_in = (-1); /* named type ID */
+ hid_t dcpl_id = (-1); /* dataset creation property list ID */
+ hid_t space_id = (-1); /* space ID */
+ hid_t ftype_id = (-1); /* file data type ID */
+ hid_t mtype_id = (-1); /* memory data type ID */
+ size_t msize; /* memory size of memory type */
+ hsize_t nelmts; /* number of elements in dataset */
+ int rank; /* rank of dataset */
+ hsize_t dims[H5S_MAX_RANK]; /* dimensions of dataset */
+ unsigned int i, j;
+ int k;
+ named_dt_t *named_dt_head=NULL; /* Pointer to the stack of named datatypes
+ copied */
+
+ /*-------------------------------------------------------------------------
+ * browse
+ *-------------------------------------------------------------------------
+ */
+ for(i = 0; i < travt->nobjs; i++) {
+ switch(travt->objs[i].type)
+ {
+ /*-------------------------------------------------------------------------
+ * H5TRAV_TYPE_GROUP
+ *-------------------------------------------------------------------------
+ */
+ case H5TRAV_TYPE_GROUP:
+ /*-------------------------------------------------------------------------
+ * copy referenced objects in attributes
+ *-------------------------------------------------------------------------
+ */
+ if((grp_out = H5Gopen2(fidout, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gopen2 failed");
+
+ if((grp_in = H5Gopen2(fidin, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gopen2 failed");
+
+ if(copy_refs_attr(grp_in, grp_out, options, travt, fidout) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_refs_attr failed");
+
+ if(H5Gclose(grp_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gclose failed");
+ if(H5Gclose(grp_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gclose failed");
+
+ /*-------------------------------------------------------------------------
+ * check for hard links
+ *-------------------------------------------------------------------------
+ */
+ if(travt->objs[i].nlinks)
+ for(j = 0; j < travt->objs[i].nlinks; j++)
+ H5Lcreate_hard(fidout, travt->objs[i].name, H5L_SAME_LOC, travt->objs[i].links[j].new_name, H5P_DEFAULT, H5P_DEFAULT);
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5TRAV_TYPE_DATASET
+ *-------------------------------------------------------------------------
+ */
+ case H5TRAV_TYPE_DATASET:
+ if((dset_in = H5Dopen2(fidin, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ if((space_id = H5Dget_space(dset_in)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_space failed");
+ if((ftype_id = H5Dget_type(dset_in)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_type failed");
+ if((dcpl_id = H5Dget_create_plist(dset_in)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_create_plist failed");
+ if((rank = H5Sget_simple_extent_ndims(space_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_ndims failed");
+ if(H5Sget_simple_extent_dims(space_id, dims, NULL) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed");
+ nelmts = 1;
+ for(k = 0; k < rank; k++)
+ nelmts *= dims[k];
+
+ if((mtype_id = h5tools_get_native_type(ftype_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "h5tools_get_native_type failed");
+
+ if((msize = H5Tget_size(mtype_id)) == 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed");
+
+ /*-------------------------------------------------------------------------
+ * check if the dataset creation property list has filters that
+ * are not registered in the current configuration
+ * 1) the external filters GZIP and SZIP might not be available
+ * 2) the internal filters might be turned off
+ *-------------------------------------------------------------------------
+ */
+ if(h5tools_canreadf(NULL, dcpl_id) == 1) {
+ /*-------------------------------------------------------------------------
+ * test for a valid output dataset
+ *-------------------------------------------------------------------------
+ */
+ dset_out = FAIL;
+
+ /*-------------------------------------------------------------------------
+ * object references are a special case
+ * we cannot just copy the buffers, but instead we recreate the reference
+ *-------------------------------------------------------------------------
+ */
+ if(H5Tequal(mtype_id, H5T_STD_REF_OBJ)) {
+ hid_t refobj_id;
+ hobj_ref_t *refbuf = NULL; /* buffer for object references */
+ hobj_ref_t *buf = NULL;
+ const char* refname;
+ unsigned u;
+
+ /*-------------------------------------------------------------------------
+ * read to memory
+ *-------------------------------------------------------------------------
+ */
+ if(nelmts) {
+ buf = (hobj_ref_t *)HDmalloc((unsigned)(nelmts * msize));
+ if(buf==NULL) {
+ printf("cannot read into memory\n" );
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDmalloc failed");
+ } /* end if */
+ if(H5Dread(dset_in, mtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dread failed");
+
+ refbuf = (hobj_ref_t*) HDcalloc((unsigned)nelmts, msize);
+ if(refbuf == NULL){
+ printf("cannot allocate memory\n" );
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDcalloc failed");
+ } /* end if */
+ for(u = 0; u < nelmts; u++) {
+ H5E_BEGIN_TRY {
+ if((refobj_id = H5Rdereference2(dset_in, H5P_DEFAULT, H5R_OBJECT, &buf[u])) < 0)
+ continue;
+ } H5E_END_TRY;
+
+ /* get the name. a valid name could only occur
+ * in the second traversal of the file
+ */
+ if((refname = MapIdToName(refobj_id, travt)) != NULL) {
+ /* create the reference, -1 parameter for objects */
+ if(H5Rcreate(&refbuf[u], fidout, refname, H5R_OBJECT, (hid_t)-1) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Rcreate failed");
+ if(options->verbose)
+ {
+ printf(FORMAT_OBJ,"dset",travt->objs[i].name );
+ printf("object <%s> object reference created to <%s>\n",
+ travt->objs[i].name,
+ refname);
+ }
+ } /*refname*/
+ H5Oclose(refobj_id);
+ } /* u */
+ } /*nelmts*/
+
+ /*-------------------------------------------------------------------------
+ * create/write dataset/close
+ *-------------------------------------------------------------------------
+ */
+ if((dset_out = H5Dcreate2(fidout, travt->objs[i].name, mtype_id, space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dcreate2 failed");
+ if(nelmts)
+ if(H5Dwrite(dset_out, mtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, refbuf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dwrite failed");
+
+ if(buf)
+ HDfree(buf);
+ if(refbuf)
+ HDfree(refbuf);
+
+ /*------------------------------------------------------
+ * copy attrs
+ *----------------------------------------------------*/
+ if(copy_attr(dset_in, dset_out, &named_dt_head, travt, options) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_attr failed");
+ } /*H5T_STD_REF_OBJ*/
+
+ /*-------------------------------------------------------------------------
+ * dataset region references
+ *-------------------------------------------------------------------------
+ */
+ else if(H5Tequal(mtype_id, H5T_STD_REF_DSETREG))
+ {
+ hid_t refobj_id;
+ hdset_reg_ref_t *refbuf = NULL; /* input buffer for region references */
+ hdset_reg_ref_t *buf = NULL; /* output buffer */
+ const char* refname;
+ unsigned u;
+
+ /*-------------------------------------------------------------------------
+ * read input to memory
+ *-------------------------------------------------------------------------
+ */
+ if(nelmts) {
+ buf = (hdset_reg_ref_t *)HDmalloc((unsigned)(nelmts * msize));
+ if(buf == NULL) {
+ printf("cannot read into memory\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDmalloc failed");
+ } /* end if */
+ if(H5Dread(dset_in, mtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dread failed");
+
+ /*-------------------------------------------------------------------------
+ * create output
+ *-------------------------------------------------------------------------
+ */
+ refbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)nelmts); /*init to zero */
+ if(refbuf == NULL) {
+ printf("cannot allocate memory\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDcalloc failed");
+ } /* end if */
+
+ for(u = 0; u < nelmts; u++) {
+ H5E_BEGIN_TRY {
+ if((refobj_id = H5Rdereference2(dset_in, H5P_DEFAULT, H5R_DATASET_REGION, &buf[u])) < 0)
+ continue;
+ } H5E_END_TRY;
+
+ /* get the name. a valid name could only occur
+ * in the second traversal of the file
+ */
+ if((refname = MapIdToName(refobj_id, travt)) != NULL) {
+ hid_t region_id; /* region id of the referenced dataset */
+
+ if((region_id = H5Rget_region(dset_in, H5R_DATASET_REGION, &buf[u])) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Rget_region failed");
+
+ /* create the reference, we need the space_id */
+ if(H5Rcreate(&refbuf[u], fidout, refname, H5R_DATASET_REGION, region_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Rcreate failed");
+ if(H5Sclose(region_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose failed");
+ if(options->verbose)
+ {
+ printf(FORMAT_OBJ,"dset",travt->objs[i].name );
+ printf("object <%s> region reference created to <%s>\n",
+ travt->objs[i].name,
+ refname);
+ }
+ } /*refname*/
+ H5Oclose(refobj_id);
+ } /* u */
+ } /*nelmts*/
+
+ /*-------------------------------------------------------------------------
+ * create/write dataset/close
+ *-------------------------------------------------------------------------
+ */
+ if((dset_out = H5Dcreate2(fidout, travt->objs[i].name, mtype_id, space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dcreate2 failed");
+ if(nelmts)
+ if(H5Dwrite(dset_out, mtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, refbuf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dwrite failed");
+
+ if(buf)
+ HDfree(buf);
+ if(refbuf)
+ HDfree(refbuf);
+
+ /*-----------------------------------------------------
+ * copy attrs
+ *----------------------------------------------------*/
+ if(copy_attr(dset_in, dset_out, &named_dt_head, travt, options) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_attr failed");
+ } /* H5T_STD_REF_DSETREG */
+ /*-------------------------------------------------------------------------
+ * not references, open previously created object in 1st traversal
+ *-------------------------------------------------------------------------
+ */
+ else {
+ if((dset_out = H5Dopen2(fidout, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ } /* end else */
+
+ HDassert(dset_out != FAIL);
+
+ /*-------------------------------------------------------------------------
+ * copy referenced objects in attributes
+ *-------------------------------------------------------------------------
+ */
+ if(copy_refs_attr(dset_in, dset_out, options, travt, fidout) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_refs_attr failed");
+
+ /*-------------------------------------------------------------------------
+ * check for hard links
+ *-------------------------------------------------------------------------
+ */
+ if(travt->objs[i].nlinks)
+ for(j = 0; j < travt->objs[i].nlinks; j++)
+ H5Lcreate_hard(fidout, travt->objs[i].name, H5L_SAME_LOC, travt->objs[i].links[j].new_name, H5P_DEFAULT, H5P_DEFAULT);
+
+ if(H5Dclose(dset_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+ } /*can_read*/
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+ if(H5Tclose(ftype_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if(H5Tclose(mtype_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if(H5Pclose(dcpl_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if(H5Sclose(space_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose failed");
+ if(H5Dclose(dset_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5TRAV_TYPE_NAMED_DATATYPE
+ *-------------------------------------------------------------------------
+ */
+ case H5TRAV_TYPE_NAMED_DATATYPE:
+ if((type_in = H5Topen2(fidin, travt->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Topen2 failed");
+ if(H5Tclose(type_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5TRAV_TYPE_LINK
+ *-------------------------------------------------------------------------
+ */
+ case H5TRAV_TYPE_LINK:
+ /*nothing to do */
+ break;
+
+ case H5TRAV_TYPE_UNKNOWN:
+ case H5TRAV_TYPE_UDLINK:
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5TRAV invalid type");
+
+ default:
+ break;
+ } /* end switch */
+ } /* end for */
+
+ /* Finalize (link) the stack of named datatypes (if any)
+ * This function is paired with copy_named_datatype() which is called
+ * in copy_attr(), so need to free.
+ */
+ named_datatype_free(&named_dt_head, 0);
+
+ return ret_value;
+
+done:
+ H5E_BEGIN_TRY {
+ H5Gclose(grp_in);
+ H5Gclose(grp_out);
+ H5Pclose(dcpl_id);
+ H5Sclose(space_id);
+ H5Dclose(dset_in);
+ H5Dclose(dset_out);
+ H5Tclose(ftype_id);
+ H5Tclose(mtype_id);
+ H5Tclose(type_in);
+ named_datatype_free(&named_dt_head, 0);
+ } H5E_END_TRY;
+
+ return ret_value;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: copy_refs_attr
+ *
+ * Purpose: duplicate all referenced HDF5 located in attributes
+ * relative to LOC_IN, which is obtained either from
+ * loc_id = H5Gopen2(fid, name, H5P_DEFAULT);
+ * loc_id = H5Dopen2(fid, name, H5P_DEFAULT);
+ * loc_id = H5Topen2(fid, name, H5P_DEFAULT);
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Modifier: xcao@hdfgroup.org, 9/12/2011
+ * Update values of references(object and region) for the following types:
+ * 1) References,
+ * 2) ARRAY of reference,
+ * 3) VLEN of references.
+ * 4) COMPOUND of references.
+ * This function does not handle references in other complicated structures,
+ * such as references in nested compound datatypes.
+ *
+ * Date: October, 28, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int copy_refs_attr(hid_t loc_in,
+ hid_t loc_out,
+ pack_opt_t *options,
+ trav_table_t *travt,
+ hid_t fidout /* for saving references */
+ )
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ hid_t attr_id = -1; /* attr ID */
+ hid_t attr_out = -1; /* attr ID */
+ hid_t space_id = -1; /* space ID */
+ hid_t ftype_id = -1; /* file data type ID */
+ hid_t mtype_id = -1; /* memory data type ID */
+ size_t msize; /* memory size of type */
+ hsize_t nelmts; /* number of elements in dataset */
+ hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */
+ char name[255];
+ H5O_info_t oinfo; /* Object info */
+ unsigned u, i, j;
+ int rank;
+ H5T_class_t type_class = -1;
+ hbool_t is_ref=0, is_ref_vlen=0, is_ref_array=0, is_ref_comp=0;
+ void *refbuf = NULL;
+ void *buf = NULL;
+ const char* refname = NULL;
+ unsigned *ref_comp_index = NULL;
+ size_t *ref_comp_size = NULL;
+ int ref_comp_field_n = 0;
+
+
+ if(H5Oget_info(loc_in, &oinfo) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Oget_info failed");
+
+ for(u = 0; u < (unsigned)oinfo.num_attrs; u++) {
+ is_ref = is_ref_vlen = is_ref_array = is_ref_comp = 0;
+
+ /* open attribute */
+ if((attr_id = H5Aopen_by_idx(loc_in, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aopen_by_idx failed");
+
+ /* get the file datatype */
+ if((ftype_id = H5Aget_type(attr_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aget_type failed");
+
+ type_class = H5Tget_class(ftype_id);
+
+ if((mtype_id = h5tools_get_native_type(ftype_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "h5tools_get_native_type failed");
+
+ if((msize = H5Tget_size(mtype_id)) == 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed");
+
+ is_ref = (type_class == H5T_REFERENCE);
+
+ if(type_class == H5T_VLEN ) {
+ hid_t base_type;
+
+ base_type = H5Tget_super(ftype_id);
+ is_ref_vlen = (H5Tget_class(base_type)==H5T_REFERENCE);
+ msize = H5Tget_size(base_type);
+ H5Tclose(base_type);
+ }
+ else if(type_class == H5T_ARRAY ) {
+ hid_t base_type;
+
+ base_type = H5Tget_super(ftype_id);
+ is_ref_array = (H5Tget_class(base_type)==H5T_REFERENCE);
+ msize = H5Tget_size(base_type);
+ H5Tclose(base_type);
+ }
+ else if(type_class == H5T_COMPOUND) {
+ int nmembers = H5Tget_nmembers(ftype_id) ;
+
+ if (nmembers < 1)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_nmembers failed");
+
+ ref_comp_index = (unsigned *)HDmalloc((size_t)nmembers*sizeof(unsigned));
+ ref_comp_size = (size_t *)HDmalloc((size_t)nmembers*sizeof(ref_comp_size));
+ ref_comp_field_n = 0;
+
+ for (i=0; i<(unsigned)nmembers; i++) {
+ hid_t mtid = H5Tget_member_type( ftype_id, i );
+
+ if ((H5Tget_class(mtid)==H5T_REFERENCE)) {
+ ref_comp_index[ref_comp_field_n] = i;
+ ref_comp_size[ref_comp_field_n] = H5Tget_size(mtid);
+ ref_comp_field_n++;
+ }
+ H5Tclose(mtid);
+ }
+
+ /* if compound don't contain reference type member, free the above
+ * mallocs. Otherwise there can be memory leaks by the 'continue'
+ * statement below. */
+ if (!ref_comp_field_n) {
+ if (ref_comp_index) {
+ HDfree(ref_comp_index);
+ ref_comp_index = NULL;
+ }
+
+ if (ref_comp_size) {
+ HDfree(ref_comp_size);
+ ref_comp_size = NULL;
+ }
+ }
+ }
+
+ is_ref_comp = (ref_comp_field_n > 0);
+
+ if (!(is_ref || is_ref_vlen || is_ref_array || is_ref_comp)) {
+ H5Tclose(mtype_id);
+ H5Tclose(ftype_id);
+ H5Aclose(attr_id);
+ continue;
+ }
+
+ /* get name */
+ if(H5Aget_name(attr_id, 255, name) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aget_name failed");
+
+ /* get the dataspace handle */
+ if((space_id = H5Aget_space(attr_id)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aget_space failed");
+
+ /* get dimensions */
+ if((rank = H5Sget_simple_extent_dims(space_id, dims, NULL)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed");
+
+
+ /*-------------------------------------------------------------------------
+ * elements
+ *-------------------------------------------------------------------------
+ */
+ nelmts = 1;
+ for(j = 0; j < (unsigned)rank; j++)
+ nelmts *= dims[j];
+
+ if (is_ref_array) {
+ unsigned array_rank = 0;
+ hsize_t array_size = 1;
+ hsize_t array_dims[H5S_MAX_RANK];
+ hid_t base_type;
+
+ base_type = H5Tget_super(ftype_id);
+ msize = H5Tget_size(base_type);
+ H5Tclose(base_type);
+
+ array_rank = (unsigned)H5Tget_array_ndims(mtype_id);
+ H5Tget_array_dims2(mtype_id, array_dims);
+ for(j = 0; j <array_rank; j++)
+ array_size *= array_dims[j];
+ nelmts *= array_size;
+ }
+
+ if((attr_out = H5Acreate2(loc_out, name, ftype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Acreate2 failed");
+
+ if (nelmts>0) {
+ /* handle object references */
+ if((is_ref || is_ref_array) && (H5R_OBJ_REF_BUF_SIZE==msize)) {
+ buf = (hobj_ref_t *)HDmalloc((unsigned)(nelmts * msize));
+ if(buf == NULL) {
+ printf("cannot read into memory\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDmalloc failed");
+ } /* end if */
+ if(H5Aread(attr_id, mtype_id, buf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aread failed");
+
+ refbuf = (hobj_ref_t *)HDcalloc((unsigned)nelmts, msize);
+ if(refbuf == NULL) {
+ printf("cannot allocate memory\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDcalloc failed");
+ } /* end if */
+
+ for(i = 0; i < (unsigned)nelmts; i++) {
+ if (update_ref_value(attr_id, H5R_OBJECT, &((hobj_ref_t *)buf)[i], fidout, &((hobj_ref_t *)refbuf)[i], travt)<0)
+ continue;
+ if(options->verbose)
+ printf("object <%s> reference created to <%s>\n", name, refname);
+ } /* i */
+ } /* H5T_STD_REF_OBJ */
+ /* handle region references */
+ else if((is_ref || is_ref_array) && (H5R_DSET_REG_REF_BUF_SIZE == msize)) {
+ buf = (hdset_reg_ref_t *)HDmalloc((unsigned)(nelmts * msize));
+
+ if(buf == NULL) {
+ printf( "cannot read into memory\n" );
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDmalloc failed");
+ } /* end if */
+ if(H5Aread(attr_id, mtype_id, buf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aread failed");
+
+ /*-------------------------------------------------------------------------
+ * create output
+ *-------------------------------------------------------------------------
+ */
+ refbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)nelmts); /*init to zero */
+ if(refbuf == NULL) {
+ printf( "cannot allocate memory\n" );
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDcalloc failed");
+ } /* end if */
+
+ for(i = 0; i < (unsigned)nelmts; i++) {
+ if (update_ref_value(attr_id, H5R_DATASET_REGION, &((hdset_reg_ref_t *)buf)[i], fidout, &((hdset_reg_ref_t *)refbuf)[i], travt)<0)
+ continue;
+ if(options->verbose)
+ printf("object <%s> region reference created to <%s>\n", name, refname);
+ }
+ } /* H5T_STD_REF_DSETREG */
+ else if (is_ref_vlen) {
+ /* handle VLEN of references */
+
+ buf = (hvl_t *)HDmalloc((unsigned)(nelmts * sizeof(hvl_t)));
+ refbuf = buf; /* reuse the read buffer for write */
+
+ if(buf == NULL) {
+ printf( "cannot read into memory\n" );
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDmalloc failed");
+ } /* end if */
+
+ if(H5Aread(attr_id, mtype_id, buf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aread failed");
+
+ if (H5R_OBJ_REF_BUF_SIZE==msize) {
+ hobj_ref_t ref_out;
+
+ for (i=0; i<(unsigned)nelmts; i++) {
+ hobj_ref_t *ptr = (hobj_ref_t *)((hvl_t *)buf)[i].p;
+
+ for (j=0; j<((hvl_t *)buf)[i].len; j++ ) {
+ if (update_ref_value(attr_id, H5R_OBJECT, &(ptr[j]), fidout, &ref_out, travt)<0)
+ continue;
+ HDmemcpy(&(ptr[j]), &ref_out, msize);
+ }
+ } /* for (i=0; i<nelems; i++) */
+ } else if (H5R_DSET_REG_REF_BUF_SIZE == msize) {
+ hdset_reg_ref_t ref_out;
+
+ for (i=0; i<(unsigned)nelmts; i++) {
+ hdset_reg_ref_t *ptr = (hdset_reg_ref_t *)((hvl_t *)buf)[i].p;
+
+ for (j=0; j<((hvl_t *)buf)[i].len; j++ ) {
+ if (update_ref_value(attr_id, H5R_DATASET_REGION, &(ptr[j]), fidout, &ref_out, travt)<0)
+ continue;
+ HDmemcpy(&(ptr[j]), &ref_out, msize);
+ }
+ } /* for (i=0; i<nelems; i++) */
+ }
+ } /* else if (is_ref_vlen) */
+ else if (is_ref_comp) {
+ /* handle ref fields in a compound */
+
+ buf = HDmalloc((unsigned)(nelmts * msize));
+ refbuf = buf; /* reuse the read buffer for write */
+
+ if(buf == NULL)
+ {
+ printf( "cannot read into memory\n" );
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDmalloc failed");
+ } /* end if */
+
+ if(H5Aread(attr_id, mtype_id, buf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aread failed");
+
+ for (i=0; i<(unsigned)nelmts; i++) {
+ for (j=0; j<(unsigned)ref_comp_field_n; j++) {
+ if (ref_comp_size[j] == H5R_OBJ_REF_BUF_SIZE) {
+ size_t idx = (i * msize) + H5Tget_member_offset(mtype_id, ref_comp_index[j]);
+ hobj_ref_t ref_out;
+
+ if (update_ref_value(attr_id, H5R_OBJECT, (hobj_ref_t *)(((char *)buf)+idx), fidout, &ref_out, travt)<0)
+ continue;
+ HDmemcpy(((char *)buf)+idx, &ref_out, ref_comp_size[j]);
+ } /* if */
+ else if (ref_comp_size[j] == H5R_DSET_REG_REF_BUF_SIZE) {
+ size_t idx = i * msize + H5Tget_member_offset(mtype_id, ref_comp_index[j]);
+ hdset_reg_ref_t ref_out;
+
+ if (update_ref_value(attr_id, H5R_DATASET_REGION, (hdset_reg_ref_t *)(((char *)buf)+idx), fidout, &ref_out, travt)<0)
+ continue;
+ HDmemcpy(((char *)buf)+idx, &ref_out, ref_comp_size[j]);
+ } /* else if */
+ } /* j */
+ } /* i */
+ } /* else if (is_ref_comp) */
+
+ if(H5Awrite(attr_out, mtype_id, refbuf) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Awrite failed");
+
+ if (is_ref_vlen && buf)
+ H5Dvlen_reclaim (mtype_id, space_id, H5P_DEFAULT, buf);
+ } /* if (nelmts) */
+
+ if (refbuf == buf)
+ refbuf = NULL; /* set it to NULL to avoid double free since buf and refbuf are the same. */
+
+ if(buf) {
+ HDfree(buf);
+ buf = NULL;
+ }
+
+ if(refbuf) {
+ HDfree(refbuf);
+ refbuf = NULL;
+ }
+
+ if (ref_comp_index) {
+ HDfree(ref_comp_index);
+ ref_comp_index = NULL;
+ }
+
+ if (ref_comp_size) {
+ HDfree(ref_comp_size);
+ ref_comp_size = NULL;
+ }
+
+ if(H5Aclose(attr_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aclose failed");
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+ if(H5Tclose(ftype_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if(H5Tclose(mtype_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ if(H5Sclose(space_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose failed");
+ if(H5Aclose(attr_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aclose failed");
+ } /* for(u = 0; u < (unsigned)oinfo.num_attrs; u++) */
+
+ return ret_value;
+
+done:
+ if(refbuf)
+ HDfree(refbuf);
+ if(buf)
+ HDfree(buf);
+
+ if (ref_comp_index)
+ HDfree(ref_comp_index);
+
+ if (ref_comp_size)
+ HDfree(ref_comp_size);
+
+ H5E_BEGIN_TRY {
+ H5Tclose(ftype_id);
+ H5Tclose(mtype_id);
+ H5Sclose(space_id);
+ H5Aclose(attr_id);
+ H5Aclose(attr_out);
+ } H5E_END_TRY;
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: MapIdToName
+ *
+ * Purpose: map a ID from a reference to a dataset name
+ *
+ *-------------------------------------------------------------------------
+ */
+static const char*
+MapIdToName(hid_t refobj_id, trav_table_t *travt)
+{
+ unsigned int u;
+ const char* ret = NULL;
+
+ /* linear search */
+ for(u = 0; u < travt->nobjs; u++) {
+ if(travt->objs[u].type == (h5trav_type_t)H5O_TYPE_DATASET ||
+ travt->objs[u].type == (h5trav_type_t)H5O_TYPE_GROUP ||
+ travt->objs[u].type == (h5trav_type_t)H5O_TYPE_NAMED_DATATYPE) {
+ H5O_info_t ref_oinfo; /* Stat for the refobj id */
+
+ /* obtain information to identify the referenced object uniquely */
+ if(H5Oget_info(refobj_id, &ref_oinfo) < 0)
+ goto out;
+
+ if(ref_oinfo.addr == travt->objs[u].objno) {
+ ret = travt->objs[u].name;
+ goto out;
+ } /* end if */
+ } /* end if */
+ } /* u */
+
+out:
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: Update_Ref_value
+ *
+ * Purpose: Update a reference value
+ *
+ * Programmer: xcao@hdfgroup.org 9/12/2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t update_ref_value(hid_t obj_id, H5R_type_t ref_type, void *ref_in,
+ hid_t fid_out, void *ref_out, trav_table_t *travt)
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ const char* ref_obj_name;
+ hid_t space_id=-1, ref_obj_id=-1;
+
+ ref_obj_id = H5Rdereference2(obj_id, H5P_DEFAULT, ref_type, ref_in);
+ if (ref_obj_id < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Rdereference2 failed");
+
+ ref_obj_name = MapIdToName(ref_obj_id, travt);
+ if (ref_obj_name == NULL)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "MapIdToName failed");
+
+ if (ref_type == H5R_DATASET_REGION) {
+ space_id = H5Rget_region(obj_id, H5R_DATASET_REGION, ref_in);
+ if (space_id < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Rget_region failed");
+ }
+
+ if(H5Rcreate(ref_out, fid_out, ref_obj_name, ref_type, space_id) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Rcreate failed");
+
+done:
+ H5E_BEGIN_TRY {
+ H5Sclose(space_id);
+ H5Oclose(ref_obj_id);
+ } H5E_END_TRY;
+
+ return ret_value;
+}
+
diff --git a/tools/src/h5repack/h5repack_verify.c b/tools/src/h5repack/h5repack_verify.c
new file mode 100644
index 0000000..6765c49
--- /dev/null
+++ b/tools/src/h5repack/h5repack_verify.c
@@ -0,0 +1,675 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "h5repack.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/* number of members in an array */
+#ifndef NELMTS
+# define NELMTS(X) (sizeof(X)/sizeof(X[0]))
+#endif
+
+static int verify_layout(hid_t pid, pack_info_t *obj);
+static int verify_filters(hid_t pid, hid_t tid, int nfilters, filter_info_t *filter);
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5repack_verify
+ *
+ * Purpose: verify if filters and layout in the input file match the output file
+ *
+ * Return:
+ * 1 match
+ * 0 do not match
+ * -1 error
+ *
+ * Programmer: Pedro Vicente, pvn@hdfgroup.org
+ *
+ * Date: December 19, 2003
+ * Modified: December, 19, 2007 (exactly 4 years later :-) )
+ * Separate into 3 cases
+ * 1) no filter input, get all datasets and compare DCPLs. TO DO
+ * 2) filter input on selected datasets, get each one trough OBJ and match
+ * 3) filter input on all datasets, get all objects and match
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int
+h5repack_verify(const char *in_fname, const char *out_fname, pack_opt_t *options)
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ hid_t fidin = -1; /* file ID for input file*/
+ hid_t fidout = -1; /* file ID for output file*/
+ hid_t did = -1; /* dataset ID */
+ hid_t pid = -1; /* dataset creation property list ID */
+ hid_t sid = -1; /* space ID */
+ hid_t tid = -1; /* type ID */
+ unsigned int i;
+ trav_table_t *travt = NULL;
+ int ok = 1;
+ hid_t fcpl_in = -1; /* file creation property for input file */
+ hid_t fcpl_out = -1; /* file creation property for output file */
+ H5F_file_space_type_t in_strat, out_strat; /* file space handling strategy for in/output file */
+ hsize_t in_thresh, out_thresh; /* free space section threshold for in/output file */
+
+ /* open the output file */
+ if((fidout = H5Fopen(out_fname, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0 )
+ return -1;
+
+ for(i = 0; i < options->op_tbl->nelems; i++)
+ {
+ char* name = options->op_tbl->objs[i].path;
+ pack_info_t *obj = &options->op_tbl->objs[i];
+
+ /*-------------------------------------------------------------------------
+ * open
+ *-------------------------------------------------------------------------
+ */
+ if((did = H5Dopen2(fidout, name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ if((sid = H5Dget_space(did)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_space failed");
+ if((pid = H5Dget_create_plist(did)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_create_plist failed");
+ if((tid = H5Dget_type(did)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_type failed");
+
+ /*-------------------------------------------------------------------------
+ * filter check
+ *-------------------------------------------------------------------------
+ */
+ if(verify_filters(pid, tid, obj->nfilters, obj->filter) <= 0)
+ ok = 0;
+
+
+ /*-------------------------------------------------------------------------
+ * layout check
+ *-------------------------------------------------------------------------
+ */
+ if((obj->layout != -1) && (verify_layout(pid, obj) == 0))
+ ok = 0;
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+ if(H5Pclose(pid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Sclose(sid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose failed");
+ if (H5Dclose(did) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+ if (H5Tclose(tid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+
+ }
+
+
+ /*-------------------------------------------------------------------------
+ * check for the "all" objects option
+ *-------------------------------------------------------------------------
+ */
+
+ if(options->all_filter == 1 || options->all_layout == 1)
+ {
+
+ /* init table */
+ trav_table_init(&travt);
+
+ /* get the list of objects in the file */
+ if(h5trav_gettable(fidout, travt) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "h5trav_gettable failed");
+
+ for(i = 0; i < travt->nobjs; i++)
+ {
+ char *name = travt->objs[i].name;
+
+ if(travt->objs[i].type == H5TRAV_TYPE_DATASET)
+ {
+
+ /*-------------------------------------------------------------------------
+ * open
+ *-------------------------------------------------------------------------
+ */
+ if((did = H5Dopen2(fidout, name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ if((sid = H5Dget_space(did)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_space failed");
+ if((pid = H5Dget_create_plist(did)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_create_plist failed");
+ if((tid = H5Dget_type(did)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_type failed");
+
+ /*-------------------------------------------------------------------------
+ * filter check
+ *-------------------------------------------------------------------------
+ */
+ if(options->all_filter == 1)
+ {
+ if(verify_filters(pid, tid, options->n_filter_g, options->filter_g) <= 0)
+ ok = 0;
+ }
+
+ /*-------------------------------------------------------------------------
+ * layout check
+ *-------------------------------------------------------------------------
+ */
+ if(options->all_layout == 1)
+ {
+ pack_info_t pack;
+
+ init_packobject(&pack);
+ pack.layout = options->layout_g;
+ pack.chunk = options->chunk_g;
+ if(verify_layout(pid, &pack) == 0)
+ ok = 0;
+ }
+
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+ if (H5Pclose(pid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Sclose(sid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose failed");
+ if (H5Dclose(did) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+ if (H5Tclose(tid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed");
+ } /* if */
+
+ } /* i */
+
+ /* free table */
+ trav_table_free(travt);
+ }
+
+ /*-------------------------------------------------------------------------
+ * Verify that file space strategy and free space threshold
+ * are set as expected
+ *-------------------------------------------------------------------------
+ */
+
+ /* open the input file */
+ if((fidin = H5Fopen(in_fname, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0 )
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Fopen failed");
+
+ /* Get file creation property list for input file */
+ if((fcpl_in = H5Fget_create_plist(fidin)) < 0) {
+ error_msg("failed to retrieve file creation property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Fget_create_plist failed");
+ }
+
+ /* Get file space management info for input file */
+ if(H5Pget_file_space(fcpl_in, &in_strat, &in_thresh) < 0) {
+ error_msg("failed to retrieve file space strategy & threshold\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pget_file_space failed");
+ }
+
+ /* Output file is already opened */
+ /* Get file creation property list for output file */
+ if((fcpl_out = H5Fget_create_plist(fidout)) < 0) {
+ error_msg("failed to retrieve file creation property list\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Fget_create_plist failed");
+ }
+
+ /* Get file space management info for output file */
+ if(H5Pget_file_space(fcpl_out, &out_strat, &out_thresh) < 0) {
+ error_msg("failed to retrieve file space strategy & threshold\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pget_file_space failed");
+ }
+
+ /*
+ * If the strategy option is not set,
+ * file space handling strategy should be the same for both
+ * input & output files.
+ * If the strategy option is set,
+ * the output file's file space handling strategy should be the same
+ * as what is set via the strategy option
+ */
+ if(!options->fs_strategy && out_strat != in_strat) {
+ error_msg("file space strategy not set as unexpected\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "file space strategy not set as unexpected");
+
+ }
+ else if(options->fs_strategy && out_strat!= options->fs_strategy) {
+ error_msg("file space strategy not set as unexpected\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "file space strategy not set as unexpected");
+ }
+
+ /*
+ * If the threshold option is not set,
+ * the free space section threshold should be the same for both
+ * input & output files.
+ * If the threshold option is set,
+ * the output file's free space section threshold should be the same
+ * as what is set via the threshold option.
+ */
+ if(!options->fs_threshold && out_thresh != in_thresh) {
+ error_msg("free space threshold not set as unexpected\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "free space threshold not set as unexpected");
+ }
+ else if(options->fs_threshold && out_thresh != options->fs_threshold) {
+ error_msg("free space threshold not set as unexpected\n");
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "free space threshold not set as unexpected");
+ }
+
+ /* Closing */
+ if (H5Pclose(fcpl_in) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Pclose(fcpl_out) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Fclose(fidin) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Fclose failed");
+ if (H5Fclose(fidout) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Fclose failed");
+
+ return ok;
+
+done:
+ H5E_BEGIN_TRY {
+ H5Pclose(fcpl_in);
+ H5Pclose(fcpl_out);
+ H5Pclose(pid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Fclose(fidin);
+ H5Fclose(fidout);
+ if (travt)
+ trav_table_free(travt);
+ } H5E_END_TRY;
+
+ return ret_value;
+} /* h5repack_verify() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: verify_layout
+ *
+ * Purpose: verify which layout is present in the property list DCPL_ID
+ *
+ * H5D_COMPACT = 0
+ * H5D_CONTIGUOUS = 1
+ * H5D_CHUNKED = 2
+ *
+ * Return: 1 has, 0 does not, -1 error
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: December 30, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int verify_layout(hid_t pid,
+ pack_info_t *obj)
+{
+ hsize_t chsize[64]; /* chunk size in elements */
+ H5D_layout_t layout; /* layout */
+ int nfilters; /* number of filters */
+ int rank; /* rank */
+ int i; /* index */
+
+ /* check if we have filters in the input object */
+ if ((nfilters = H5Pget_nfilters(pid)) < 0)
+ return -1;
+
+ /* a non chunked layout was requested on a filtered object */
+ if (nfilters && obj->layout!=H5D_CHUNKED)
+ return 0;
+
+ /* get layout */
+ if ((layout = H5Pget_layout(pid)) < 0)
+ return -1;
+
+ if (obj->layout != layout)
+ return 0;
+
+ if (layout==H5D_CHUNKED)
+ {
+ if ((rank = H5Pget_chunk(pid,NELMTS(chsize),chsize/*out*/)) < 0)
+ return -1;
+ if (obj->chunk.rank != rank)
+ return 0;
+ for ( i=0; i<rank; i++)
+ if (chsize[i] != obj->chunk.chunk_lengths[i])
+ return 0;
+ }
+
+ return 1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: h5repack_cmp_pl
+ *
+ * Purpose: compare 2 files for identical property lists of all objects
+ *
+ * Return: 1=identical, 0=not identical, -1=error
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: December 31, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int h5repack_cmp_pl(const char *fname1,
+ const char *fname2)
+{
+ int ret_value = 0; /*no need to LEAVE() on ERROR: HERR_INIT(int, SUCCEED) */
+ hid_t fid1=-1; /* file ID */
+ hid_t fid2=-1; /* file ID */
+ hid_t dset1=-1; /* dataset ID */
+ hid_t dset2=-1; /* dataset ID */
+ hid_t gid=-1; /* group ID */
+ hid_t dcpl1=-1; /* dataset creation property list ID */
+ hid_t dcpl2=-1; /* dataset creation property list ID */
+ hid_t gcplid=-1; /* group creation property list */
+ unsigned crt_order_flag1; /* group creation order flag */
+ unsigned crt_order_flag2; /* group creation order flag */
+ trav_table_t *trav=NULL;
+ int ret=1;
+ unsigned int i;
+
+ /*-------------------------------------------------------------------------
+ * open the files
+ *-------------------------------------------------------------------------
+ */
+
+ /* disable error reporting */
+ H5E_BEGIN_TRY
+ {
+
+ /* Open the files */
+ if ((fid1 = H5Fopen(fname1,H5F_ACC_RDONLY,H5P_DEFAULT)) < 0 )
+ {
+ error_msg("<%s>: %s\n", fname1, H5FOPENERROR );
+ return -1;
+ }
+ if ((fid2 = H5Fopen(fname2,H5F_ACC_RDONLY,H5P_DEFAULT)) < 0 )
+ {
+ error_msg("<%s>: %s\n", fname2, H5FOPENERROR );
+ H5Fclose(fid1);
+ return -1;
+ }
+ /* enable error reporting */
+ } H5E_END_TRY;
+
+ /*-------------------------------------------------------------------------
+ * get file table list of objects
+ *-------------------------------------------------------------------------
+ */
+ trav_table_init(&trav);
+ if(h5trav_gettable(fid1, trav) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "h5trav_gettable failed");
+
+ /*-------------------------------------------------------------------------
+ * traverse the suppplied object list
+ *-------------------------------------------------------------------------
+ */
+ for(i = 0; i < trav->nobjs; i++)
+ {
+
+ if(trav->objs[i].type == H5TRAV_TYPE_GROUP)
+ {
+
+ if ((gid = H5Gopen2(fid1, trav->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gopen2 failed");
+ if ((gcplid = H5Gget_create_plist(gid)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gget_create_plist failed");
+ if (H5Pget_link_creation_order(gcplid, &crt_order_flag1) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pget_link_creation_order failed");
+ if (H5Pclose(gcplid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Gclose(gid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gclose failed");
+
+ if ((gid = H5Gopen2(fid2, trav->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gopen2 failed");
+ if ((gcplid = H5Gget_create_plist(gid)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gget_create_plist failed");
+ if (H5Pget_link_creation_order(gcplid, &crt_order_flag2) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pget_link_creation_order failed");
+ if (H5Pclose(gcplid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if (H5Gclose(gid) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gclose failed");
+
+ if (crt_order_flag1 != crt_order_flag2) {
+ error_msg("property lists for <%s> are different\n",trav->objs[i].name);
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "property lists failed");
+ }
+
+ }
+
+
+
+ else if(trav->objs[i].type == H5TRAV_TYPE_DATASET)
+ {
+ if((dset1 = H5Dopen2(fid1, trav->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ if((dset2 = H5Dopen2(fid2, trav->objs[i].name, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen2 failed");
+ if((dcpl1 = H5Dget_create_plist(dset1)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_create_plist failed");
+ if((dcpl2 = H5Dget_create_plist(dset2)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_create_plist failed");
+
+ /*-------------------------------------------------------------------------
+ * compare the property lists
+ *-------------------------------------------------------------------------
+ */
+ if((ret = H5Pequal(dcpl1, dcpl2)) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pequal failed");
+
+ if(ret == 0) {
+ error_msg("property lists for <%s> are different\n",trav->objs[i].name);
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "property lists failed");
+ }
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+ if(H5Pclose(dcpl1) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if(H5Pclose(dcpl2) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed");
+ if(H5Dclose(dset1) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+ if(H5Dclose(dset2) < 0)
+ HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose failed");
+ } /*if*/
+ } /*i*/
+
+ /*-------------------------------------------------------------------------
+ * free
+ *-------------------------------------------------------------------------
+ */
+
+ trav_table_free(trav);
+
+ /*-------------------------------------------------------------------------
+ * close
+ *-------------------------------------------------------------------------
+ */
+
+ H5Fclose(fid1);
+ H5Fclose(fid2);
+
+ return ret;
+
+/*-------------------------------------------------------------------------
+* error
+*-------------------------------------------------------------------------
+*/
+done:
+ H5E_BEGIN_TRY
+ {
+ H5Pclose(dcpl1);
+ H5Pclose(dcpl2);
+ H5Dclose(dset1);
+ H5Dclose(dset2);
+ H5Fclose(fid1);
+ H5Fclose(fid2);
+ H5Pclose(gcplid);
+ H5Gclose(gid);
+ trav_table_free(trav);
+ } H5E_END_TRY;
+
+ return ret_value;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: verify_filters
+ *
+ * Purpose: verify if all requested filters in the array FILTER obtained
+ * from user input are present in the property list PID obtained from
+ * the output file
+ *
+ * Return:
+ * 1 match
+ * 0 do not match
+ * -1 error
+ *
+ * Programmer: Pedro Vicente, pvn@hdfgroup.org
+ *
+ * Date: December 21, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static
+int verify_filters(hid_t pid, hid_t tid, int nfilters, filter_info_t *filter)
+{
+ int nfilters_dcpl; /* number of filters in DCPL*/
+ unsigned filt_flags; /* filter flags */
+ H5Z_filter_t filtn; /* filter identification number */
+ unsigned cd_values[20]; /* filter client data values */
+ size_t cd_nelmts; /* filter client number of values */
+ char f_name[256]; /* filter name */
+ size_t size; /* type size */
+ int i; /* index */
+ unsigned j; /* index */
+
+ /* get information about filters */
+ if((nfilters_dcpl = H5Pget_nfilters(pid)) < 0)
+ return -1;
+
+ /* if we do not have filters and the requested filter is NONE, return 1 */
+ if(!nfilters_dcpl &&
+ nfilters == 1 &&
+ filter[0].filtn == H5Z_FILTER_NONE )
+ return 1;
+
+ /* else the numbers of filters must match */
+ if (nfilters_dcpl != nfilters )
+ return 0;
+
+ /*-------------------------------------------------------------------------
+ * build a list with DCPL filters
+ *-------------------------------------------------------------------------
+ */
+
+ for( i = 0; i < nfilters_dcpl; i++)
+ {
+ cd_nelmts = NELMTS(cd_values);
+ filtn = H5Pget_filter2(pid, (unsigned)i, &filt_flags, &cd_nelmts,
+ cd_values, sizeof(f_name), f_name, NULL);
+
+ /* filter ID */
+ if (filtn != filter[i].filtn)
+ return 0;
+
+ /* compare client data values. some filters do return local values */
+ switch (filtn)
+ {
+
+ case H5Z_FILTER_NONE:
+ break;
+
+ case H5Z_FILTER_SHUFFLE:
+ /* 1 private client value is returned by DCPL */
+ if ( cd_nelmts != H5Z_SHUFFLE_TOTAL_NPARMS && filter[i].cd_nelmts != H5Z_SHUFFLE_USER_NPARMS )
+ return 0;
+
+ /* get dataset's type size */
+ if((size = H5Tget_size(tid)) <= 0)
+ return -1;
+
+ /* the private client value holds the dataset's type size */
+ if ( size != cd_values[0] )
+ return 0;
+
+ break;
+
+ case H5Z_FILTER_SZIP:
+ /* 4 private client values are returned by DCPL */
+ if ( cd_nelmts != H5Z_SZIP_TOTAL_NPARMS && filter[i].cd_nelmts != H5Z_SZIP_USER_NPARMS )
+ return 0;
+
+ /* "User" parameter for pixels-per-block (index 1) */
+ if ( cd_values[H5Z_SZIP_PARM_PPB] != filter[i].cd_values[H5Z_SZIP_PARM_PPB] )
+ return 0;
+
+ break;
+
+ case H5Z_FILTER_NBIT:
+ /* only client data values number of values checked */
+ if ( H5Z_NBIT_USER_NPARMS != filter[i].cd_nelmts)
+ return 0;
+ break;
+
+ case H5Z_FILTER_SCALEOFFSET:
+ /* only client data values checked */
+ for( j = 0; j < H5Z_SCALEOFFSET_USER_NPARMS; j++)
+ if (cd_values[j] != filter[i].cd_values[j])
+ return 0;
+ break;
+
+ /* for these filters values must match, no local values set in DCPL */
+ case H5Z_FILTER_FLETCHER32:
+ case H5Z_FILTER_DEFLATE:
+
+ if ( cd_nelmts != filter[i].cd_nelmts)
+ return 0;
+
+ for( j = 0; j < cd_nelmts; j++)
+ if (cd_values[j] != filter[i].cd_values[j])
+ return 0;
+
+ break;
+
+ default:
+ if ( cd_nelmts != filter[i].cd_nelmts)
+ return 0;
+
+ for( j = 0; j < cd_nelmts; j++)
+ if (cd_values[j] != filter[i].cd_values[j])
+ return 0;
+ break;
+
+ } /* switch */
+ }
+
+ return 1;
+}
+
diff --git a/tools/src/h5stat/CMakeLists.txt b/tools/src/h5stat/CMakeLists.txt
new file mode 100644
index 0000000..d4e14cb
--- /dev/null
+++ b/tools/src/h5stat/CMakeLists.txt
@@ -0,0 +1,39 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_H5STAT)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+
+# --------------------------------------------------------------------
+# Add the h5stat executables
+# --------------------------------------------------------------------
+add_executable (h5stat ${HDF5_TOOLS_SRC_H5STAT_SOURCE_DIR}/h5stat.c)
+TARGET_NAMING (h5stat STATIC)
+TARGET_C_PROPERTIES (h5stat STATIC " " " ")
+target_link_libraries (h5stat ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5stat PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5stat")
+
+set (H5_DEP_EXECUTABLES h5stat)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5stat ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5stat
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
diff --git a/tools/src/h5stat/Makefile.am b/tools/src/h5stat/Makefile.am
new file mode 100644
index 0000000..b4d81de
--- /dev/null
+++ b/tools/src/h5stat/Makefile.am
@@ -0,0 +1,39 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src directory
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+# These are our main targets, the tools
+bin_PROGRAMS=h5stat
+bin_SCRIPTS=
+
+# Add h5stat specific linker flags here
+h5stat_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# Tell automake to clean h5redeploy script
+CLEANFILES=
+
+# All programs rely on hdf5 library and h5tools library
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/h5stat/h5stat.c b/tools/src/h5stat/h5stat.c
new file mode 100644
index 0000000..a331014
--- /dev/null
+++ b/tools/src/h5stat/h5stat.c
@@ -0,0 +1,1815 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <string.h>
+#include "H5private.h" /* Generic Functions */
+#include "h5tools.h"
+#include "h5tools_utils.h"
+#include "h5tools_ref.h"
+#include "h5trav.h"
+#include "hdf5.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5stat"
+
+/* Parameters to control statistics gathered */
+
+/* Default threshold for small groups/datasets/attributes */
+#define DEF_SIZE_SMALL_GROUPS 10
+#define DEF_SIZE_SMALL_DSETS 10
+#define DEF_SIZE_SMALL_ATTRS 10
+
+#define SIZE_SMALL_SECTS 10
+
+#define H5_NFILTERS_IMPL 8 /* Number of currently implemented filters + one to
+ accommodate for user-define filters + one
+ to accomodate datasets whithout any filters */
+
+/* File space management strategies: see H5Fpublic.h for declarations */
+const char *FS_STRATEGY_NAME[] = {
+ "unknown",
+ "H5F_FILE_SPACE_ALL_PERSIST",
+ "H5F_FILE_SPACE_ALL",
+ "H5F_FILE_SPACE_AGGR_VFD",
+ "H5F_FILE_SPACE_VFD",
+ NULL
+};
+
+/* Datatype statistics for datasets */
+typedef struct dtype_info_t {
+ hid_t tid; /* ID of datatype */
+ unsigned long count; /* Number of types found */
+ unsigned long named; /* Number of types that are named */
+} dtype_info_t;
+
+typedef struct ohdr_info_t {
+ hsize_t total_size; /* Total size of object headers */
+ hsize_t free_size; /* Total free space in object headers */
+} ohdr_info_t;
+
+/* Info to pass to the iteration functions */
+typedef struct iter_t {
+ hid_t fid; /* File ID */
+ hsize_t filesize; /* Size of the file */
+ unsigned long uniq_groups; /* Number of unique groups */
+ unsigned long uniq_dsets; /* Number of unique datasets */
+ unsigned long uniq_dtypes; /* Number of unique named datatypes */
+ unsigned long uniq_links; /* Number of unique links */
+ unsigned long uniq_others; /* Number of other unique objects */
+
+ unsigned long max_links; /* Maximum # of links to an object */
+ hsize_t max_fanout; /* Maximum fanout from a group */
+ unsigned long *num_small_groups; /* Size of small groups tracked */
+ unsigned group_nbins; /* Number of bins for group counts */
+ unsigned long *group_bins; /* Pointer to array of bins for group counts */
+ ohdr_info_t group_ohdr_info; /* Object header information for groups */
+
+ hsize_t max_attrs; /* Maximum attributes from a group */
+ unsigned long *num_small_attrs; /* Size of small attributes tracked */
+ unsigned attr_nbins; /* Number of bins for attribute counts */
+ unsigned long *attr_bins; /* Pointer to array of bins for attribute counts */
+
+ unsigned max_dset_rank; /* Maximum rank of dataset */
+ unsigned long dset_rank_count[H5S_MAX_RANK]; /* Number of datasets of each rank */
+ hsize_t max_dset_dims; /* Maximum dimension size of dataset */
+ unsigned long *small_dset_dims; /* Size of dimensions of small datasets tracked */
+ unsigned long dset_layouts[H5D_NLAYOUTS]; /* Type of storage for each dataset */
+ unsigned long dset_comptype[H5_NFILTERS_IMPL]; /* Number of currently implemented filters */
+ unsigned long dset_ntypes; /* Number of diff. dataset datatypes found */
+ dtype_info_t *dset_type_info; /* Pointer to dataset datatype information found */
+ unsigned dset_dim_nbins; /* Number of bins for dataset dimensions */
+ unsigned long *dset_dim_bins; /* Pointer to array of bins for dataset dimensions */
+ ohdr_info_t dset_ohdr_info; /* Object header information for datasets */
+ hsize_t dset_storage_size; /* Size of raw data for datasets */
+ hsize_t dset_external_storage_size; /* Size of raw data for datasets with external storage */
+ ohdr_info_t dtype_ohdr_info; /* Object header information for datatypes */
+ hsize_t groups_btree_storage_size; /* btree size for group */
+ hsize_t groups_heap_storage_size; /* heap size for group */
+ hsize_t attrs_btree_storage_size; /* btree size for attributes (1.8) */
+ hsize_t attrs_heap_storage_size; /* fractal heap size for attributes (1.8) */
+ hsize_t SM_hdr_storage_size; /* header size for SOHM table (1.8) */
+ hsize_t SM_index_storage_size; /* index (btree & list) size for SOHM table (1.8) */
+ hsize_t SM_heap_storage_size; /* fractal heap size for SOHM table (1.8) */
+ hsize_t super_size; /* superblock size */
+ hsize_t super_ext_size; /* superblock extension size */
+ hsize_t ublk_size; /* user block size (if exists) */
+ H5F_file_space_type_t fs_strategy; /* File space management strategy */
+ hsize_t fs_threshold; /* Free-space section threshold */
+ hsize_t free_space; /* amount of freespace in the file */
+ hsize_t free_hdr; /* size of free space manager metadata in the file */
+ unsigned long num_small_sects[SIZE_SMALL_SECTS]; /* Size of small free-space sections */
+ unsigned sect_nbins; /* Number of bins for free-space section sizes */
+ unsigned long *sect_bins; /* Pointer to array of bins for free-space section sizes */
+ hsize_t datasets_index_storage_size;/* meta size for chunked dataset's indexing type */
+ hsize_t datasets_heap_storage_size; /* heap size for dataset with external storage */
+ unsigned long nexternal; /* Number of external files for a dataset */
+ int local; /* Flag to indicate iteration over the object*/
+} iter_t;
+
+
+static int display_all = TRUE;
+
+/* Enable the printing of selected statistics */
+static int display_file = FALSE; /* display file information */
+static int display_group = FALSE; /* display groups information */
+static int display_dset = FALSE; /* display datasets information */
+static int display_dset_dtype_meta = FALSE; /* display datasets' datatype information */
+static int display_attr = FALSE; /* display attributes information */
+static int display_free_sections = FALSE; /* display free space information */
+static int display_summary = FALSE; /* display summary of file space information */
+
+static int display_file_metadata = FALSE; /* display file space info for file's metadata */
+static int display_group_metadata = FALSE; /* display file space info for groups' metadata */
+static int display_dset_metadata = FALSE; /* display file space info for datasets' metadata */
+
+static int display_object = FALSE; /* not implemented yet */
+
+/* Initialize threshold for small groups/datasets/attributes */
+static int sgroups_threshold = DEF_SIZE_SMALL_GROUPS;
+static int sdsets_threshold = DEF_SIZE_SMALL_DSETS;
+static int sattrs_threshold = DEF_SIZE_SMALL_ATTRS;
+
+/* a structure for handling the order command-line parameters come in */
+struct handler_t {
+ size_t obj_count;
+ char **obj;
+};
+
+static const char *s_opts ="Aa:Ddm:FfhGgl:sSTO:V";
+/* e.g. "filemetadata" has to precede "file"; "groupmetadata" has to precede "group" etc. */
+static struct long_options l_opts[] = {
+ {"help", no_arg, 'h'},
+ {"hel", no_arg, 'h'},
+ {"he", no_arg, 'h'},
+ {"filemetadata", no_arg, 'F'},
+ {"filemetadat", no_arg, 'F'},
+ {"filemetada", no_arg, 'F'},
+ {"filemetad", no_arg, 'F'},
+ {"filemeta", no_arg, 'F'},
+ {"filemet", no_arg, 'F'},
+ {"fileme", no_arg, 'F'},
+ {"filem", no_arg, 'F'},
+ {"file", no_arg, 'f'},
+ {"fil", no_arg, 'f'},
+ {"fi", no_arg, 'f'},
+ {"groupmetadata", no_arg, 'G'},
+ {"groupmetadat", no_arg, 'G'},
+ {"groupmetada", no_arg, 'G'},
+ {"groupmetad", no_arg, 'G'},
+ {"groupmeta", no_arg, 'G'},
+ {"groupmet", no_arg, 'G'},
+ {"groupme", no_arg, 'G'},
+ {"groupm", no_arg, 'G'},
+ {"group", no_arg, 'g'},
+ {"grou", no_arg, 'g'},
+ {"gro", no_arg, 'g'},
+ {"gr", no_arg, 'g'},
+ { "links", require_arg, 'l' },
+ { "link", require_arg, 'l' },
+ { "lin", require_arg, 'l' },
+ { "li", require_arg, 'l' },
+ {"dsetmetadata", no_arg, 'D'},
+ {"dsetmetadat", no_arg, 'D'},
+ {"dsetmetada", no_arg, 'D'},
+ {"dsetmetad", no_arg, 'D'},
+ {"dsetmeta", no_arg, 'D'},
+ {"dsetmet", no_arg, 'D'},
+ {"dsetme", no_arg, 'D'},
+ {"dsetm", no_arg, 'D'},
+ {"dset", no_arg, 'd'},
+ {"dse", no_arg, 'd'},
+ {"ds", no_arg, 'd'},
+ {"dims", require_arg, 'm'},
+ {"dim", require_arg, 'm'},
+ {"di", require_arg, 'm'},
+ {"dtypemetadata", no_arg, 'T'},
+ {"dtypemetadat", no_arg, 'T'},
+ {"dtypemetada", no_arg, 'T'},
+ {"dtypemetad", no_arg, 'T'},
+ {"dtypemeta", no_arg, 'T'},
+ {"dtypemet", no_arg, 'T'},
+ {"dtypeme", no_arg, 'T'},
+ {"dtypem", no_arg, 'T'},
+ {"dtype", no_arg, 'T'},
+ {"dtyp", no_arg, 'T'},
+ {"dty", no_arg, 'T'},
+ {"dt", no_arg, 'T'},
+ { "object", require_arg, 'O' },
+ { "objec", require_arg, 'O' },
+ { "obje", require_arg, 'O' },
+ { "obj", require_arg, 'O' },
+ { "ob", require_arg, 'O' },
+ { "version", no_arg, 'V' },
+ { "versio", no_arg, 'V' },
+ { "versi", no_arg, 'V' },
+ { "vers", no_arg, 'V' },
+ { "ver", no_arg, 'V' },
+ { "ve", no_arg, 'V' },
+ { "attribute", no_arg, 'A' },
+ { "attribut", no_arg, 'A' },
+ { "attribu", no_arg, 'A' },
+ { "attrib", no_arg, 'A' },
+ { "attri", no_arg, 'A' },
+ { "attr", no_arg, 'A' },
+ { "att", no_arg, 'A' },
+ { "at", no_arg, 'A' },
+ { "numattrs", require_arg, 'a' },
+ { "numattr", require_arg, 'a' },
+ { "numatt", require_arg, 'a' },
+ { "numat", require_arg, 'a' },
+ { "numa", require_arg, 'a' },
+ { "num", require_arg, 'a' },
+ { "nu", require_arg, 'a' },
+ { "freespace", no_arg, 's' },
+ { "freespac", no_arg, 's' },
+ { "freespa", no_arg, 's' },
+ { "freesp", no_arg, 's' },
+ { "frees", no_arg, 's' },
+ { "free", no_arg, 's' },
+ { "fre", no_arg, 's' },
+ { "fr", no_arg, 's' },
+ { "summary", no_arg, 'S' },
+ { "summar", no_arg, 'S' },
+ { "summa", no_arg, 'S' },
+ { "summ", no_arg, 'S' },
+ { "sum", no_arg, 'S' },
+ { "su", no_arg, 'S' },
+ { NULL, 0, '\0' }
+};
+
+static void
+leave(int ret)
+{
+ h5tools_close();
+ HDexit(ret);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Compute the ceiling of log_10(x)
+ *
+ * Return: >0 on success, 0 on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static void usage(const char *prog)
+{
+ HDfflush(stdout);
+ HDfprintf(stdout, "Usage: %s [OPTIONS] file\n", prog);
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, " OPTIONS\n");
+ HDfprintf(stdout, " -h, --help Print a usage message and exit\n");
+ HDfprintf(stdout, " -V, --version Print version number and exit\n");
+ HDfprintf(stdout, " -f, --file Print file information\n");
+ HDfprintf(stdout, " -F, --filemetadata Print file space information for file's metadata\n");
+ HDfprintf(stdout, " -g, --group Print group information\n");
+ HDfprintf(stdout, " -l N, --links=N Set the threshold for the # of links when printing\n");
+ HDfprintf(stdout, " information for small groups. N is an integer greater\n");
+ HDfprintf(stdout, " than 0. The default threshold is 10.\n");
+ HDfprintf(stdout, " -G, --groupmetadata Print file space information for groups' metadata\n");
+ HDfprintf(stdout, " -d, --dset Print dataset information\n");
+ HDfprintf(stdout, " -m N, --dims=N Set the threshold for the dimension sizes when printing\n");
+ HDfprintf(stdout, " information for small datasets. N is an integer greater\n");
+ HDfprintf(stdout, " than 0. The default threshold is 10.\n");
+ HDfprintf(stdout, " -D, --dsetmetadata Print file space information for datasets' metadata\n");
+ HDfprintf(stdout, " -T, --dtypemetadata Print datasets' datatype information\n");
+ HDfprintf(stdout, " -A, --attribute Print attribute information\n");
+ HDfprintf(stdout, " -a N, --numattrs=N Set the threshold for the # of attributes when printing\n");
+ HDfprintf(stdout, " information for small # of attributes. N is an integer greater\n");
+ HDfprintf(stdout, " than 0. The default threshold is 10.\n");
+ HDfprintf(stdout, " -s, --freespace Print free space information\n");
+ HDfprintf(stdout, " -S, --summary Print summary of file space information\n");
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: ceil_log10
+ *
+ * Purpose: Compute the ceiling of log_10(x)
+ *
+ * Return: >0 on success, 0 on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 22, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_ATTR_CONST static unsigned
+ceil_log10(unsigned long x)
+{
+ unsigned long pow10 = 1;
+ unsigned ret = 0;
+
+ while(x >= pow10) {
+ pow10 *= 10;
+ ret++;
+ } /* end while */
+
+ return ret;
+} /* ceil_log10() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: attribute_stats
+ *
+ * Purpose: Gather statistics about attributes on an object
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 17, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+attribute_stats(iter_t *iter, const H5O_info_t *oi)
+{
+ unsigned bin; /* "bin" the number of objects falls in */
+
+ /* Update dataset & attribute metadata info */
+ iter->attrs_btree_storage_size += oi->meta_size.attr.index_size;
+ iter->attrs_heap_storage_size += oi->meta_size.attr.heap_size;
+
+ /* Update small # of attribute count & limits */
+ if(oi->num_attrs <= (hsize_t)sattrs_threshold)
+ (iter->num_small_attrs[(size_t)oi->num_attrs])++;
+ if(oi->num_attrs > iter->max_attrs)
+ iter->max_attrs = oi->num_attrs;
+
+ /* Add attribute count to proper bin */
+ bin = ceil_log10((unsigned long)oi->num_attrs);
+ if((bin + 1) > iter->attr_nbins) {
+ iter->attr_bins = (unsigned long *)HDrealloc(iter->attr_bins, (bin + 1) * sizeof(unsigned long));
+ HDassert(iter->attr_bins);
+
+ /* Initialize counts for intermediate bins */
+ while(iter->attr_nbins < bin)
+ iter->attr_bins[iter->attr_nbins++] = 0;
+ iter->attr_nbins++;
+
+ /* Initialize count for new bin */
+ iter->attr_bins[bin] = 1;
+ } /* end if */
+ else
+ (iter->attr_bins[bin])++;
+
+ return 0;
+} /* end attribute_stats() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: group_stats
+ *
+ * Purpose: Gather statistics about the group
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 16, 2005
+ *
+ * Modifications: Refactored code from the walk_function
+ * EIP, Wednesday, August 16, 2006
+ *
+ * Vailin Choi 12 July 2007
+ * 1. Gathered storage info for btree and heap
+ * (groups and attributes)
+ * 2. Gathered info for attributes
+ *
+ * Vailin Choi 14 July 2007
+ * Cast "num_objs" and "num_attrs" to size_t
+ * Due to the -Mbounds problem for the pgi-32 bit compiler on indexing
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+group_stats(iter_t *iter, const char *name, const H5O_info_t *oi)
+{
+ H5G_info_t ginfo; /* Group information */
+ unsigned bin; /* "bin" the number of objects falls in */
+ herr_t ret;
+
+ /* Gather statistics about this type of object */
+ iter->uniq_groups++;
+
+ /* Get object header information */
+ iter->group_ohdr_info.total_size += oi->hdr.space.total;
+ iter->group_ohdr_info.free_size += oi->hdr.space.free;
+
+ /* Get group information */
+ ret = H5Gget_info_by_name(iter->fid, name, &ginfo, H5P_DEFAULT);
+ HDassert(ret >= 0);
+
+ /* Update link stats */
+ /* Collect statistics for small groups */
+ if(ginfo.nlinks < (hsize_t)sgroups_threshold)
+ (iter->num_small_groups[(size_t)ginfo.nlinks])++;
+ /* Determine maximum link count */
+ if(ginfo.nlinks > iter->max_fanout)
+ iter->max_fanout = ginfo.nlinks;
+
+ /* Add group count to proper bin */
+ bin = ceil_log10((unsigned long)ginfo.nlinks);
+ if((bin + 1) > iter->group_nbins) {
+ /* Allocate more storage for info about dataset's datatype */
+ iter->group_bins = (unsigned long *)HDrealloc(iter->group_bins, (bin + 1) * sizeof(unsigned long));
+ HDassert(iter->group_bins);
+
+ /* Initialize counts for intermediate bins */
+ while(iter->group_nbins < bin)
+ iter->group_bins[iter->group_nbins++] = 0;
+ iter->group_nbins++;
+
+ /* Initialize count for new bin */
+ iter->group_bins[bin] = 1;
+ } /* end if */
+ else
+ (iter->group_bins[bin])++;
+
+ /* Update group metadata info */
+ iter->groups_btree_storage_size += oi->meta_size.obj.index_size;
+ iter->groups_heap_storage_size += oi->meta_size.obj.heap_size;
+
+ /* Update attribute metadata info */
+ ret = attribute_stats(iter, oi);
+ HDassert(ret >= 0);
+
+ return 0;
+} /* end group_stats() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: dataset_stats
+ *
+ * Purpose: Gather statistics about the dataset
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 16, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi)
+{
+ unsigned bin; /* "bin" the number of objects falls in */
+ hid_t did; /* Dataset ID */
+ hid_t sid; /* Dataspace ID */
+ hid_t tid; /* Datatype ID */
+ hid_t dcpl; /* Dataset creation property list ID */
+ hsize_t dims[H5S_MAX_RANK];/* Dimensions of dataset */
+ H5D_layout_t lout; /* Layout of dataset */
+ unsigned type_found; /* Whether the dataset's datatype was */
+ /* already found */
+ int ndims; /* Number of dimensions of dataset */
+ hsize_t storage; /* Size of dataset storage */
+ unsigned u; /* Local index variable */
+ int num_ext; /* Number of external files for a dataset */
+ int nfltr; /* Number of filters for a dataset */
+ H5Z_filter_t fltr; /* Filter identifier */
+ herr_t ret;
+
+ /* Gather statistics about this type of object */
+ iter->uniq_dsets++;
+
+ /* Get object header information */
+ iter->dset_ohdr_info.total_size += oi->hdr.space.total;
+ iter->dset_ohdr_info.free_size += oi->hdr.space.free;
+
+ did = H5Dopen2(iter->fid, name, H5P_DEFAULT);
+ HDassert(did > 0);
+
+ /* Update dataset metadata info */
+ iter->datasets_index_storage_size += oi->meta_size.obj.index_size;
+ iter->datasets_heap_storage_size += oi->meta_size.obj.heap_size;
+
+ /* Update attribute metadata info */
+ ret = attribute_stats(iter, oi);
+ HDassert(ret >= 0);
+
+ /* Get storage info */
+ storage = H5Dget_storage_size(did);
+
+ /* Gather layout statistics */
+ dcpl = H5Dget_create_plist(did);
+ HDassert(dcpl > 0);
+
+ lout = H5Pget_layout(dcpl);
+ HDassert(lout >= 0);
+
+ /* Object header's total size for H5D_COMPACT layout includes raw data size */
+ /* "storage" also includes H5D_COMPACT raw data size */
+ if(lout == H5D_COMPACT)
+ iter->dset_ohdr_info.total_size -= storage;
+
+ /* Track the layout type for dataset */
+ (iter->dset_layouts[lout])++;
+
+ /* Get the number of external files for the dataset */
+ num_ext = H5Pget_external_count(dcpl);
+ assert (num_ext >= 0);
+
+ /* Accumulate raw data size accordingly */
+ if(num_ext) {
+ iter->nexternal += (unsigned long)num_ext;
+ iter->dset_external_storage_size += (unsigned long)storage;
+ } else
+ iter->dset_storage_size += storage;
+
+ /* Gather dataspace statistics */
+ sid = H5Dget_space(did);
+ HDassert(sid > 0);
+
+ ndims = H5Sget_simple_extent_dims(sid, dims, NULL);
+ HDassert(ndims >= 0);
+
+ /* Check for larger rank of dataset */
+ if((unsigned)ndims > iter->max_dset_rank)
+ iter->max_dset_rank = (unsigned)ndims;
+
+ /* Track the number of datasets with each rank */
+ (iter->dset_rank_count[ndims])++;
+
+ /* Only gather dim size statistics on 1-D datasets */
+ if(ndims == 1) {
+ /* Determine maximum dimension size */
+ if(dims[0] > iter->max_dset_dims)
+ iter->max_dset_dims = dims[0];
+ /* Collect statistics for small datasets */
+ if(dims[0] < (hsize_t)sdsets_threshold)
+ (iter->small_dset_dims[(size_t)dims[0]])++;
+
+ /* Add dim count to proper bin */
+ bin = ceil_log10((unsigned long)dims[0]);
+ if((bin + 1) > iter->dset_dim_nbins) {
+ /* Allocate more storage for info about dataset's datatype */
+ iter->dset_dim_bins = (unsigned long *)HDrealloc(iter->dset_dim_bins, (bin + 1) * sizeof(unsigned long));
+ HDassert(iter->dset_dim_bins);
+
+ /* Initialize counts for intermediate bins */
+ while(iter->dset_dim_nbins < bin)
+ iter->dset_dim_bins[iter->dset_dim_nbins++] = 0;
+ iter->dset_dim_nbins++;
+
+ /* Initialize count for this bin */
+ iter->dset_dim_bins[bin] = 1;
+ } /* end if */
+ else
+ (iter->dset_dim_bins[bin])++;
+ } /* end if */
+
+ ret = H5Sclose(sid);
+ HDassert(ret >= 0);
+
+ /* Gather datatype statistics */
+ tid = H5Dget_type(did);
+ HDassert(tid > 0);
+
+ type_found = FALSE;
+ for(u = 0; u < iter->dset_ntypes; u++)
+ if(H5Tequal(iter->dset_type_info[u].tid, tid) > 0) {
+ type_found = TRUE;
+ break;
+ } /* end for */
+ if(type_found)
+ (iter->dset_type_info[u].count)++;
+ else {
+ unsigned curr_ntype = (unsigned)iter->dset_ntypes;
+
+ /* Increment # of datatypes seen for datasets */
+ iter->dset_ntypes++;
+
+ /* Allocate more storage for info about dataset's datatype */
+ iter->dset_type_info = (dtype_info_t *)HDrealloc(iter->dset_type_info, iter->dset_ntypes * sizeof(dtype_info_t));
+ HDassert(iter->dset_type_info);
+
+ /* Initialize information about datatype */
+ iter->dset_type_info[curr_ntype].tid = H5Tcopy(tid);
+ HDassert(iter->dset_type_info[curr_ntype].tid > 0);
+ iter->dset_type_info[curr_ntype].count = 1;
+ iter->dset_type_info[curr_ntype].named = 0;
+
+ /* Set index for later */
+ u = curr_ntype;
+ } /* end else */
+
+ /* Check if the datatype is a named datatype */
+ if(H5Tcommitted(tid) > 0)
+ (iter->dset_type_info[u].named)++;
+
+ ret = H5Tclose(tid);
+ HDassert(ret >= 0);
+
+ /* Track different filters */
+ if((nfltr = H5Pget_nfilters(dcpl)) >= 0) {
+ if(nfltr == 0)
+ iter->dset_comptype[0]++;
+ for(u = 0; u < (unsigned)nfltr; u++) {
+ fltr = H5Pget_filter2(dcpl, u, 0, 0, 0, 0, 0, NULL);
+ if(fltr >= 0) {
+ if(fltr < (H5_NFILTERS_IMPL - 1))
+ iter->dset_comptype[fltr]++;
+ else
+ iter->dset_comptype[H5_NFILTERS_IMPL - 1]++; /*other filters*/
+ } /* end if */
+ } /* end for */
+ } /* endif nfltr */
+
+ ret = H5Pclose(dcpl);
+ HDassert(ret >= 0);
+
+ ret = H5Dclose(did);
+ HDassert(ret >= 0);
+
+ return 0;
+} /* end dataset_stats() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: datatype_stats
+ *
+ * Purpose: Gather statistics about the datatype
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Vailin Choi; July 7th, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+datatype_stats(iter_t *iter, const H5O_info_t *oi)
+{
+ herr_t ret;
+
+ /* Gather statistics about this type of object */
+ iter->uniq_dtypes++;
+
+ /* Get object header information */
+ iter->dtype_ohdr_info.total_size += oi->hdr.space.total;
+ iter->dtype_ohdr_info.free_size += oi->hdr.space.free;
+
+ /* Update attribute metadata info */
+ ret = attribute_stats(iter, oi);
+ HDassert(ret >= 0);
+
+ return 0;
+} /* end datatype_stats() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: obj_stats
+ *
+ * Purpose: Gather statistics about an object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, November 6, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+obj_stats(const char *path, const H5O_info_t *oi, const char *already_visited,
+ void *_iter)
+{
+ iter_t *iter = (iter_t *)_iter;
+
+ /* If the object has already been seen then just return */
+ if(NULL == already_visited) {
+ /* Gather some general statistics about the object */
+ if(oi->rc > iter->max_links)
+ iter->max_links = oi->rc;
+
+ switch(oi->type) {
+ case H5O_TYPE_GROUP:
+ group_stats(iter, path, oi);
+ break;
+
+ case H5O_TYPE_DATASET:
+ dataset_stats(iter, path, oi);
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ datatype_stats(iter, oi);
+ break;
+
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ /* Gather statistics about this type of object */
+ iter->uniq_others++;
+ break;
+ } /* end switch */
+ } /* end if */
+
+ return 0;
+} /* end obj_stats() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: lnk_stats
+ *
+ * Purpose: Gather statistics about a link
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, November 6, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+lnk_stats(const char H5_ATTR_UNUSED *path, const H5L_info_t *li, void *_iter)
+{
+ iter_t *iter = (iter_t *)_iter;
+
+ switch(li->type) {
+ case H5L_TYPE_SOFT:
+ case H5L_TYPE_EXTERNAL:
+ /* Gather statistics about links and UD links */
+ iter->uniq_links++;
+ break;
+
+ case H5L_TYPE_HARD:
+ case H5L_TYPE_MAX:
+ case H5L_TYPE_ERROR:
+ default:
+ /* Gather statistics about this type of object */
+ iter->uniq_others++;
+ break;
+ } /* end switch() */
+
+ return 0;
+} /* end lnk_stats() */
+
+/*-------------------------------------------------------------------------
+ * Function: freespace_stats
+ *
+ * Purpose: Gather statistics for free space sections in the file
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Vailin Choi; July 7th, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+freespace_stats(hid_t fid, iter_t *iter)
+{
+ H5F_sect_info_t *sect_info = NULL; /* Free space sections */
+ ssize_t nsects; /* Number of free space sections */
+ size_t u; /* Local index variable */
+
+ /* Query section information */
+ if((nsects = H5Fget_free_sections(fid, H5FD_MEM_DEFAULT, 0, NULL)) < 0)
+ return(FAIL);
+ else if(nsects) {
+ if(NULL == (sect_info = (H5F_sect_info_t *)HDcalloc((size_t)nsects, sizeof(H5F_sect_info_t))))
+ return(FAIL);
+ nsects = H5Fget_free_sections(fid, H5FD_MEM_DEFAULT, (size_t)nsects, sect_info);
+ HDassert(nsects);
+ } /* end else-if */
+
+ for(u = 0; u < (size_t)nsects; u++) {
+ unsigned bin; /* "bin" the number of objects falls in */
+
+ if(sect_info[u].size < SIZE_SMALL_SECTS)
+ (iter->num_small_sects[(size_t)sect_info[u].size])++;
+
+ /* Add section size to proper bin */
+ bin = ceil_log10((unsigned long)sect_info[u].size);
+ if(bin >= iter->sect_nbins) {
+ /* Allocate more storage for section info */
+ iter->sect_bins = (unsigned long *)HDrealloc(iter->sect_bins, (bin + 1) * sizeof(unsigned long));
+ HDassert(iter->sect_bins);
+
+ /* Initialize counts for intermediate bins */
+ while(iter->sect_nbins < bin)
+ iter->sect_bins[iter->sect_nbins++] = 0;
+ iter->sect_nbins++;
+
+ /* Initialize count for this bin */
+ iter->sect_bins[bin] = 1;
+ } /* end if */
+ else
+ (iter->sect_bins[bin])++;
+ } /* end for */
+
+ if(sect_info)
+ HDfree(sect_info);
+
+ return 0;
+} /* end freespace_stats() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: hand_free
+ *
+ * Purpose: Free handler structure
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+hand_free(struct handler_t *hand)
+{
+ if(hand) {
+ unsigned u;
+
+ for(u = 0; u < hand->obj_count; u++)
+ if(hand->obj[u]) {
+ HDfree(hand->obj[u]);
+ hand->obj[u] = NULL;
+ } /* end if */
+ hand->obj_count = 0;
+ HDfree(hand->obj);
+ HDfree(hand);
+ } /* end if */
+} /* end hand_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parses command line and sets up global variable to control output
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Elena Pourmal
+ * Saturday, August 12, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+parse_command_line(int argc, const char *argv[], struct handler_t **hand_ret)
+{
+ int opt;
+ unsigned u;
+ struct handler_t *hand = NULL;
+
+ /* parse command line options */
+ while((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
+ switch((char)opt) {
+ case 'h':
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+ break;
+
+ case 'V':
+ print_version(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+ break;
+
+ case 'F':
+ display_all = FALSE;
+ display_file_metadata = TRUE;
+ break;
+
+ case 'f':
+ display_all = FALSE;
+ display_file = TRUE;
+ break;
+
+ case 'G':
+ display_all = FALSE;
+ display_group_metadata = TRUE;
+ break;
+
+ case 'g':
+ display_all = FALSE;
+ display_group = TRUE;
+ break;
+
+ case 'l':
+ if(opt_arg) {
+ sgroups_threshold = HDatoi(opt_arg);
+ if(sgroups_threshold < 1) {
+ error_msg("Invalid threshold for small groups\n");
+ goto error;
+ }
+ } else
+ error_msg("Missing threshold for small groups\n");
+
+ break;
+
+ case 'D':
+ display_all = FALSE;
+ display_dset_metadata = TRUE;
+ break;
+
+ case 'd':
+ display_all = FALSE;
+ display_dset = TRUE;
+ break;
+
+ case 'm':
+ if(opt_arg) {
+ sdsets_threshold = HDatoi(opt_arg);
+ if(sdsets_threshold < 1) {
+ error_msg("Invalid threshold for small datasets\n");
+ goto error;
+ }
+ } else
+ error_msg("Missing threshold for small datasets\n");
+
+ break;
+
+ case 'T':
+ display_all = FALSE;
+ display_dset_dtype_meta = TRUE;
+ break;
+
+ case 'A':
+ display_all = FALSE;
+ display_attr = TRUE;
+ break;
+
+ case 'a':
+ if(opt_arg) {
+ sattrs_threshold = HDatoi(opt_arg);
+ if(sattrs_threshold < 1) {
+ error_msg("Invalid threshold for small # of attributes\n");
+ goto error;
+ }
+ } else
+ error_msg("Missing threshold for small # of attributes\n");
+
+ break;
+
+ case 's':
+ display_all = FALSE;
+ display_free_sections = TRUE;
+ break;
+
+ case 'S':
+ display_all = FALSE;
+ display_summary = TRUE;
+ break;
+
+ case 'O':
+ display_all = FALSE;
+ display_object = TRUE;
+
+ /* Allocate space to hold the command line info */
+ if(NULL == (hand = (struct handler_t *)HDcalloc((size_t)1, sizeof(struct handler_t)))) {
+ error_msg("unable to allocate memory for object struct\n");
+ goto error;
+ } /* end if */
+
+ /* Allocate space to hold the object strings */
+ hand->obj_count = (size_t)argc;
+ if(NULL == (hand->obj = (char **)HDcalloc((size_t)argc, sizeof(char *)))) {
+ error_msg("unable to allocate memory for object array\n");
+ goto error;
+ } /* end if */
+
+ /* Store object names */
+ for(u = 0; u < hand->obj_count; u++)
+ if(NULL == (hand->obj[u] = HDstrdup(opt_arg))) {
+ error_msg("unable to allocate memory for object name\n");
+ goto error;
+ } /* end if */
+ break;
+
+ default:
+ usage(h5tools_getprogname());
+ goto error;
+ } /* end switch */
+ } /* end while */
+
+ /* check for file name to be processed */
+ if(argc <= opt_ind) {
+ error_msg("missing file name\n");
+ usage(h5tools_getprogname());
+ goto error;
+ } /* end if */
+
+ /* Set handler structure */
+ *hand_ret = hand;
+
+done:
+ return 0;
+
+error:
+ hand_free(hand);
+ h5tools_setstatus(EXIT_FAILURE);
+
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: iter_free
+ *
+ * Purpose: Free iter structure
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+iter_free(iter_t *iter)
+{
+
+ /* Clear array of bins for group counts */
+ if(iter->group_bins) {
+ HDfree(iter->group_bins);
+ iter->group_bins = NULL;
+ } /* end if */
+
+ /* Clear array for tracking small groups */
+ if(iter->num_small_groups) {
+ HDfree(iter->num_small_groups);
+ iter->num_small_groups = NULL;
+ } /* end if */
+
+ /* Clear array of bins for attribute counts */
+ if(iter->attr_bins) {
+ HDfree(iter->attr_bins);
+ iter->attr_bins = NULL;
+ } /* end if */
+
+ /* Clear array for tracking small attributes */
+ if(iter->num_small_attrs) {
+ HDfree(iter->num_small_attrs);
+ iter->num_small_attrs= NULL;
+ } /* end if */
+
+ /* Clear dataset datatype information found */
+ if(iter->dset_type_info) {
+ HDfree(iter->dset_type_info);
+ iter->dset_type_info = NULL;
+ } /* end if */
+
+ /* Clear array of bins for dataset dimensions */
+ if(iter->dset_dim_bins) {
+ HDfree(iter->dset_dim_bins);
+ iter->dset_dim_bins = NULL;
+ } /* end if */
+
+ /* Clear array of tracking 1-D small datasets */
+ if(iter->small_dset_dims) {
+ HDfree(iter->small_dset_dims);
+ iter->small_dset_dims = NULL;
+ } /* end if */
+
+ /* Clear array of bins for free-space section sizes */
+ if(iter->sect_bins) {
+ HDfree(iter->sect_bins);
+ iter->sect_bins = NULL;
+ } /* end if */
+} /* end iter_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_file_info
+ *
+ * Purpose: Prints information about file
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Elena Pourmal
+ * Saturday, August 12, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_file_info(const iter_t *iter)
+{
+ printf("File information\n");
+ printf("\t# of unique groups: %lu\n", iter->uniq_groups);
+ printf("\t# of unique datasets: %lu\n", iter->uniq_dsets);
+ printf("\t# of unique named datatypes: %lu\n", iter->uniq_dtypes);
+ printf("\t# of unique links: %lu\n", iter->uniq_links);
+ printf("\t# of unique other: %lu\n", iter->uniq_others);
+ printf("\tMax. # of links to object: %lu\n", iter->max_links);
+ HDfprintf(stdout, "\tMax. # of objects in group: %Hu\n", iter->max_fanout);
+
+ return 0;
+} /* print_file_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_file_metadata
+ *
+ * Purpose: Prints file space information for file's metadata
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Elena Pourmal
+ * Saturday, August 12, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_file_metadata(const iter_t *iter)
+{
+ HDfprintf(stdout, "File space information for file metadata (in bytes):\n");
+ HDfprintf(stdout, "\tSuperblock: %Hu\n", iter->super_size);
+ HDfprintf(stdout, "\tSuperblock extension: %Hu\n", iter->super_ext_size);
+ HDfprintf(stdout, "\tUser block: %Hu\n", iter->ublk_size);
+
+ HDfprintf(stdout, "\tObject headers: (total/unused)\n");
+ HDfprintf(stdout, "\t\tGroups: %Hu/%Hu\n",
+ iter->group_ohdr_info.total_size,
+ iter->group_ohdr_info.free_size);
+ HDfprintf(stdout, "\t\tDatasets(exclude compact data): %Hu/%Hu\n",
+ iter->dset_ohdr_info.total_size,
+ iter->dset_ohdr_info.free_size);
+ HDfprintf(stdout, "\t\tDatatypes: %Hu/%Hu\n",
+ iter->dtype_ohdr_info.total_size,
+ iter->dtype_ohdr_info.free_size);
+
+ HDfprintf(stdout, "\tGroups:\n");
+ HDfprintf(stdout, "\t\tB-tree/List: %Hu\n", iter->groups_btree_storage_size);
+ HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->groups_heap_storage_size);
+
+ HDfprintf(stdout, "\tAttributes:\n");
+ HDfprintf(stdout, "\t\tB-tree/List: %Hu\n", iter->attrs_btree_storage_size);
+ HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->attrs_heap_storage_size);
+
+ HDfprintf(stdout, "\tChunked datasets:\n");
+ HDfprintf(stdout, "\t\tIndex: %Hu\n", iter->datasets_index_storage_size);
+
+ HDfprintf(stdout, "\tDatasets:\n");
+ HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->datasets_heap_storage_size);
+
+ HDfprintf(stdout, "\tShared Messages:\n");
+ HDfprintf(stdout, "\t\tHeader: %Hu\n", iter->SM_hdr_storage_size);
+ HDfprintf(stdout, "\t\tB-tree/List: %Hu\n", iter->SM_index_storage_size);
+ HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->SM_heap_storage_size);
+
+ HDfprintf(stdout, "\tFree-space managers:\n");
+ HDfprintf(stdout, "\t\tHeader: %Hu\n", iter->free_hdr);
+ HDfprintf(stdout, "\t\tAmount of free space: %Hu\n", iter->free_space);
+
+ return 0;
+} /* print_file_metadata() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_group_info
+ *
+ * Purpose: Prints information about groups in the file
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Elena Pourmal
+ * Saturday, August 12, 2006
+ *
+ * Modifications:
+ * bug #1253; Oct 6th 2008; Vailin Choi
+ * Fixed segmentation fault: print iter->group_bins[0] when
+ * there is iter->group_nbins
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_group_info(const iter_t *iter)
+{
+ unsigned long power; /* Temporary "power" for bins */
+ unsigned long total; /* Total count for various statistics */
+ unsigned u; /* Local index variable */
+
+ printf("Small groups (with 0 to %u links):\n", sgroups_threshold-1);
+ total = 0;
+ for(u = 0; u < (unsigned)sgroups_threshold; u++) {
+ if(iter->num_small_groups[u] > 0) {
+ printf("\t# of groups with %u link(s): %lu\n", u, iter->num_small_groups[u]);
+ total += iter->num_small_groups[u];
+ } /* end if */
+ } /* end for */
+ printf("\tTotal # of small groups: %lu\n", total);
+
+ printf("Group bins:\n");
+ total = 0;
+ if((iter->group_nbins > 0) && (iter->group_bins[0] > 0)) {
+ printf("\t# of groups with 0 link: %lu\n", iter->group_bins[0]);
+ total = iter->group_bins[0];
+ } /* end if */
+ power = 1;
+ for(u = 1; u < iter->group_nbins; u++) {
+ if(iter->group_bins[u] > 0) {
+ printf("\t# of groups with %lu - %lu links: %lu\n", power, (power * 10) - 1,
+ iter->group_bins[u]);
+ total += iter->group_bins[u];
+ } /* end if */
+ power *= 10;
+ } /* end for */
+ printf("\tTotal # of groups: %lu\n", total);
+
+ return 0;
+} /* print_group_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_group_metadata
+ *
+ * Purpose: Prints file space information for groups' metadata
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Vailin Choi; October 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_group_metadata(const iter_t *iter)
+{
+ printf("File space information for groups' metadata (in bytes):\n");
+
+ HDfprintf(stdout, "\tObject headers (total/unused): %Hu/%Hu\n",
+ iter->group_ohdr_info.total_size, iter->group_ohdr_info.free_size);
+
+ HDfprintf(stdout, "\tB-tree/List: %Hu\n", iter->groups_btree_storage_size);
+ HDfprintf(stdout, "\tHeap: %Hu\n", iter->groups_heap_storage_size);
+
+ return 0;
+} /* print_group_metadata() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_dataset_info
+ *
+ * Purpose: Prints information about datasets in the file
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Elena Pourmal
+ * Saturday, August 12, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_dataset_info(const iter_t *iter)
+{
+ unsigned long power; /* Temporary "power" for bins */
+ unsigned long total; /* Total count for various statistics */
+ unsigned u; /* Local index variable */
+
+ if(iter->uniq_dsets > 0) {
+ printf("Dataset dimension information:\n");
+ printf("\tMax. rank of datasets: %u\n", iter->max_dset_rank);
+ printf("\tDataset ranks:\n");
+ for(u = 0; u < H5S_MAX_RANK; u++)
+ if(iter->dset_rank_count[u] > 0)
+ printf("\t\t# of dataset with rank %u: %lu\n", u, iter->dset_rank_count[u]);
+
+ printf("1-D Dataset information:\n");
+ HDfprintf(stdout, "\tMax. dimension size of 1-D datasets: %Hu\n", iter->max_dset_dims);
+ printf("\tSmall 1-D datasets (with dimension sizes 0 to %u):\n", sdsets_threshold - 1);
+ total = 0;
+ for(u = 0; u < (unsigned)sdsets_threshold; u++) {
+ if(iter->small_dset_dims[u] > 0) {
+ printf("\t\t# of datasets with dimension sizes %u: %lu\n", u,
+ iter->small_dset_dims[u]);
+ total += iter->small_dset_dims[u];
+ } /* end if */
+ } /* end for */
+ printf("\t\tTotal # of small datasets: %lu\n", total);
+
+ /* Protect against no datasets in file */
+ if(iter->dset_dim_nbins > 0) {
+ printf("\t1-D Dataset dimension bins:\n");
+ total = 0;
+ if(iter->dset_dim_bins[0] > 0) {
+ printf("\t\t# of datasets with dimension size 0: %lu\n", iter->dset_dim_bins[0]);
+ total = iter->dset_dim_bins[0];
+ } /* end if */
+ power = 1;
+ for(u = 1; u < iter->dset_dim_nbins; u++) {
+ if(iter->dset_dim_bins[u] > 0) {
+ printf("\t\t# of datasets with dimension size %lu - %lu: %lu\n", power, (power * 10) - 1,
+ iter->dset_dim_bins[u]);
+ total += iter->dset_dim_bins[u];
+ } /* end if */
+ power *= 10;
+ } /* end for */
+ printf("\t\tTotal # of datasets: %lu\n", total);
+ } /* end if */
+
+ printf("Dataset storage information:\n");
+ HDfprintf(stdout, "\tTotal raw data size: %Hu\n", iter->dset_storage_size);
+ HDfprintf(stdout, "\tTotal external raw data size: %Hu\n", iter->dset_external_storage_size);
+
+ printf("Dataset layout information:\n");
+ for(u = 0; u < H5D_NLAYOUTS; u++)
+ printf("\tDataset layout counts[%s]: %lu\n", (u == H5D_COMPACT ? "COMPACT" :
+ (u == H5D_CONTIGUOUS ? "CONTIG" : (u == H5D_CHUNKED ? "CHUNKED" : "VIRTUAL"))), iter->dset_layouts[u]);
+ printf("\tNumber of external files : %lu\n", iter->nexternal);
+
+ printf("Dataset filters information:\n");
+ printf("\tNumber of datasets with:\n");
+ printf("\t\tNO filter: %lu\n", iter->dset_comptype[H5Z_FILTER_ERROR+1]);
+ printf("\t\tGZIP filter: %lu\n", iter->dset_comptype[H5Z_FILTER_DEFLATE]);
+ printf("\t\tSHUFFLE filter: %lu\n", iter->dset_comptype[H5Z_FILTER_SHUFFLE]);
+ printf("\t\tFLETCHER32 filter: %lu\n", iter->dset_comptype[H5Z_FILTER_FLETCHER32]);
+ printf("\t\tSZIP filter: %lu\n", iter->dset_comptype[H5Z_FILTER_SZIP]);
+ printf("\t\tNBIT filter: %lu\n", iter->dset_comptype[H5Z_FILTER_NBIT]);
+ printf("\t\tSCALEOFFSET filter: %lu\n", iter->dset_comptype[H5Z_FILTER_SCALEOFFSET]);
+ printf("\t\tUSER-DEFINED filter: %lu\n", iter->dset_comptype[H5_NFILTERS_IMPL-1]);
+ } /* end if */
+
+ return 0;
+} /* print_dataset_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_dataset_metadata
+ *
+ * Purpose: Prints file space information for datasets' metadata
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Vailin Choi; October 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_dset_metadata(const iter_t *iter)
+{
+ printf("File space information for datasets' metadata (in bytes):\n");
+
+ HDfprintf(stdout, "\tObject headers (total/unused): %Hu/%Hu\n",
+ iter->dset_ohdr_info.total_size, iter->dset_ohdr_info.free_size);
+
+ HDfprintf(stdout, "\tIndex for Chunked datasets: %Hu\n",
+ iter->datasets_index_storage_size);
+ HDfprintf(stdout, "\tHeap: %Hu\n", iter->datasets_heap_storage_size);
+
+ return 0;
+} /* print_dset_metadata() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_dset_dtype_meta
+ *
+ * Purpose: Prints datasets' datatype information
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Vailin Choi; October 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_dset_dtype_meta(const iter_t *iter)
+{
+ unsigned long total; /* Total count for various statistics */
+ size_t dtype_size; /* Size of encoded datatype */
+ unsigned u; /* Local index variable */
+
+ if(iter->dset_ntypes) {
+ printf("Dataset datatype information:\n");
+ printf("\t# of unique datatypes used by datasets: %lu\n", iter->dset_ntypes);
+ total = 0;
+ for(u = 0; u < iter->dset_ntypes; u++) {
+ H5Tencode(iter->dset_type_info[u].tid, NULL, &dtype_size);
+ printf("\tDataset datatype #%u:\n", u);
+ printf("\t\tCount (total/named) = (%lu/%lu)\n",
+ iter->dset_type_info[u].count, iter->dset_type_info[u].named);
+ printf("\t\tSize (desc./elmt) = (%lu/%lu)\n", (unsigned long)dtype_size,
+ (unsigned long)H5Tget_size(iter->dset_type_info[u].tid));
+ H5Tclose(iter->dset_type_info[u].tid);
+ total += iter->dset_type_info[u].count;
+ } /* end for */
+ printf("\tTotal dataset datatype count: %lu\n", total);
+ } /* end if */
+
+ return 0;
+} /* print_dset_dtype_meta() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_attr_info
+ *
+ * Purpose: Prints information about attributes in the file
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Vailin Choi
+ * July 12, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_attr_info(const iter_t *iter)
+{
+ unsigned long power; /* Temporary "power" for bins */
+ unsigned long total; /* Total count for various statistics */
+ unsigned u; /* Local index variable */
+
+ printf("Small # of attributes (objects with 1 to %u attributes):\n", sattrs_threshold);
+ total = 0;
+ for(u = 1; u <= (unsigned)sattrs_threshold; u++) {
+ if(iter->num_small_attrs[u] > 0) {
+ printf("\t# of objects with %u attributes: %lu\n", u, iter->num_small_attrs[u]);
+ total += iter->num_small_attrs[u];
+ } /* end if */
+ } /* end for */
+ printf("\tTotal # of objects with small # of attributes: %lu\n", total);
+
+ printf("Attribute bins:\n");
+ total = 0;
+ power = 1;
+ for(u = 1; u < iter->attr_nbins; u++) {
+ if(iter->attr_bins[u] > 0) {
+ printf("\t# of objects with %lu - %lu attributes: %lu\n", power, (power * 10) - 1,
+ iter->attr_bins[u]);
+ total += iter->attr_bins[u];
+ } /* end if */
+ power *= 10;
+ } /* end for */
+ printf("\tTotal # of objects with attributes: %lu\n", total);
+ printf("\tMax. # of attributes to objects: %lu\n", (unsigned long)iter->max_attrs);
+
+ return 0;
+} /* print_attr_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_freespace_info
+ *
+ * Purpose: Prints information about free space in the file
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Vailin Choi; July 7th, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_freespace_info(const iter_t *iter)
+{
+ unsigned long power; /* Temporary "power" for bins */
+ unsigned long total; /* Total count for various statistics */
+ unsigned u; /* Local index variable */
+
+ HDfprintf(stdout, "Free-space section threshold: %Hu bytes\n", iter->fs_threshold);
+ printf("Small size free-space sections (< %u bytes):\n", (unsigned)SIZE_SMALL_SECTS);
+ total = 0;
+ for(u = 0; u < SIZE_SMALL_SECTS; u++) {
+ if(iter->num_small_sects[u] > 0) {
+ printf("\t# of sections of size %u: %lu\n", u, iter->num_small_sects[u]);
+ total += iter->num_small_sects[u];
+ } /* end if */
+ } /* end for */
+ printf("\tTotal # of small size sections: %lu\n", total);
+
+ printf("Free-space section bins:\n");
+
+ total = 0;
+ power = 1;
+ for(u = 1; u < iter->sect_nbins; u++) {
+ if(iter->sect_bins[u] > 0) {
+ printf("\t# of sections of size %lu - %lu: %lu\n", power, (power * 10) - 1,
+ iter->sect_bins[u]);
+ total += iter->sect_bins[u];
+ } /* end if */
+ power *= 10;
+ } /* end for */
+ printf("\tTotal # of sections: %lu\n", total);
+
+ return 0;
+} /* print_freespace_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_storage_summary
+ *
+ * Purpose: Prints file space information for the file
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Vailin Choi; August 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+print_storage_summary(const iter_t *iter)
+{
+ hsize_t total_meta = 0;
+ hsize_t unaccount = 0;
+ double percent = 0.0f;
+
+ HDfprintf(stdout, "File space management strategy: %s\n", FS_STRATEGY_NAME[iter->fs_strategy]);
+ printf("Summary of file space information:\n");
+ total_meta =
+ iter->super_size + iter->super_ext_size + iter->ublk_size +
+ iter->group_ohdr_info.total_size +
+ iter->dset_ohdr_info.total_size +
+ iter->dtype_ohdr_info.total_size +
+ iter->groups_btree_storage_size +
+ iter->groups_heap_storage_size +
+ iter->attrs_btree_storage_size +
+ iter->attrs_heap_storage_size +
+ iter->datasets_index_storage_size +
+ iter->datasets_heap_storage_size +
+ iter->SM_hdr_storage_size +
+ iter->SM_index_storage_size +
+ iter->SM_heap_storage_size +
+ iter->free_hdr;
+
+ HDfprintf(stdout, " File metadata: %Hu bytes\n", total_meta);
+ HDfprintf(stdout, " Raw data: %Hu bytes\n", iter->dset_storage_size);
+
+ percent = ((double)iter->free_space / (double)iter->filesize) * (double)100.0f;
+ HDfprintf(stdout, " Amount/Percent of tracked free space: %Hu bytes/%3.1f%\n",
+ iter->free_space, percent);
+
+ if(iter->filesize < (total_meta + iter->dset_storage_size + iter->free_space)) {
+ unaccount = (total_meta + iter->dset_storage_size + iter->free_space) - iter->filesize;
+ HDfprintf(stdout, " ??? File has %Hu more bytes accounted for than its size! ???\n", unaccount);
+ }
+ else {
+ unaccount = iter->filesize - (total_meta + iter->dset_storage_size + iter->free_space);
+ HDfprintf(stdout, " Unaccounted space: %Hu bytes\n", unaccount);
+ }
+
+ HDfprintf(stdout, "Total space: %Hu bytes\n", total_meta + iter->dset_storage_size + iter->free_space + unaccount);
+
+ if(iter->nexternal)
+ HDfprintf(stdout, "External raw data: %Hu bytes\n", iter->dset_external_storage_size);
+
+ return 0;
+} /* print_storage_summary() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_file_statistics
+ *
+ * Purpose: Prints file statistics
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Elena Pourmal
+ * Saturday, August 12, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+print_file_statistics(const iter_t *iter)
+{
+ if(display_all) {
+ display_file = TRUE;
+ display_group = TRUE;
+ display_dset = TRUE;
+ display_dset_dtype_meta = TRUE;
+ display_attr = TRUE;
+ display_free_sections = TRUE;
+ display_summary = TRUE;
+
+ display_file_metadata = TRUE;
+ display_group_metadata = TRUE;
+ display_dset_metadata = TRUE;
+ }
+
+ if(display_file) print_file_info(iter);
+ if(display_file_metadata) print_file_metadata(iter);
+
+ if(display_group) print_group_info(iter);
+ if(!display_all && display_group_metadata) print_group_metadata(iter);
+
+ if(display_dset) print_dataset_info(iter);
+ if(display_dset_dtype_meta) print_dset_dtype_meta(iter);
+ if(!display_all && display_dset_metadata) print_dset_metadata(iter);
+
+ if(display_attr) print_attr_info(iter);
+ if(display_free_sections) print_freespace_info(iter);
+ if(display_summary) print_storage_summary(iter);
+} /* print_file_statistics() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_object_statistics
+ *
+ * Purpose: Prints object statistics
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Elena Pourmal
+ * Thursday, August 17, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+print_object_statistics(const char *name)
+{
+ printf("Object name %s\n", name);
+} /* print_object_statistics() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_statistics
+ *
+ * Purpose: Prints statistics
+ *
+ * Return: Success: 0
+ *
+ * Failure: Never fails
+ *
+ * Programmer: Elena Pourmal
+ * Thursday, August 17, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+print_statistics(const char *name, const iter_t *iter)
+{
+ if(display_object)
+ print_object_statistics(name);
+ else
+ print_file_statistics(iter);
+} /* print_statistics() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Modifications:
+ * 2/2010; Vailin Choi
+ * Get the size of user block
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, const char *argv[])
+{
+ iter_t iter;
+ const char *fname = NULL;
+ hid_t fid = -1;
+ struct handler_t *hand = NULL;
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Disable error reporting */
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ HDmemset(&iter, 0, sizeof(iter));
+
+ if(parse_command_line(argc, argv, &hand) < 0)
+ goto done;
+
+ fname = argv[opt_ind];
+
+ /* Check for filename given */
+ if(fname) {
+ hid_t fcpl;
+ H5F_info2_t finfo;
+
+ printf("Filename: %s\n", fname);
+
+ fid = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
+ if(fid < 0) {
+ error_msg("unable to open file \"%s\"\n", fname);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ } /* end if */
+
+ /* Initialize iter structure */
+ iter.fid = fid;
+
+ if(H5Fget_filesize(fid, &iter.filesize) < 0)
+ warn_msg("Unable to retrieve file size\n");
+ HDassert(iter.filesize != 0);
+
+ /* Get storge info for file-level structures */
+ if(H5Fget_info2(fid, &finfo) < 0)
+ warn_msg("Unable to retrieve file info\n");
+ else {
+ iter.super_size = finfo.super.super_size;
+ iter.super_ext_size = finfo.super.super_ext_size;
+ iter.SM_hdr_storage_size = finfo.sohm.hdr_size;
+ iter.SM_index_storage_size = finfo.sohm.msgs_info.index_size;
+ iter.SM_heap_storage_size = finfo.sohm.msgs_info.heap_size;
+ iter.free_space = finfo.free.tot_space;
+ iter.free_hdr = finfo.free.meta_size;
+ } /* end else */
+
+ iter.num_small_groups = (unsigned long *)HDcalloc((size_t)sgroups_threshold, sizeof(unsigned long));
+ iter.num_small_attrs = (unsigned long *)HDcalloc((size_t)(sattrs_threshold+1), sizeof(unsigned long));
+ iter.small_dset_dims = (unsigned long *)HDcalloc((size_t)sdsets_threshold, sizeof(unsigned long));
+
+ if(iter.num_small_groups == NULL || iter.num_small_attrs == NULL || iter.small_dset_dims == NULL) {
+ error_msg("Unable to allocate memory for tracking small groups/datasets/attributes\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ if((fcpl = H5Fget_create_plist(fid)) < 0)
+ warn_msg("Unable to retrieve file creation property\n");
+
+ if(H5Pget_userblock(fcpl, &iter.ublk_size) < 0)
+ warn_msg("Unable to retrieve userblock size\n");
+
+ if(H5Pget_file_space(fcpl, &iter.fs_strategy, &iter.fs_threshold) < 0)
+ warn_msg("Unable to retrieve file space information\n");
+ HDassert(iter.fs_strategy != 0 && iter.fs_strategy < H5F_FILE_SPACE_NTYPES);
+
+ /* get information for free-space sections */
+ if(freespace_stats(fid, &iter) < 0)
+ warn_msg("Unable to retrieve freespace info\n");
+
+ /* Walk the objects or all file */
+ if(display_object) {
+ unsigned u;
+
+ for(u = 0; u < hand->obj_count; u++) {
+ if(h5trav_visit(fid, hand->obj[u], TRUE, TRUE, obj_stats, lnk_stats, &iter) < 0)
+ warn_msg("Unable to traverse object \"%s\"\n", hand->obj[u]);
+ else
+ print_statistics(hand->obj[u], &iter);
+ } /* end for */
+ } /* end if */
+ else {
+ if(h5trav_visit(fid, "/", TRUE, TRUE, obj_stats, lnk_stats, &iter) < 0)
+ warn_msg("Unable to traverse objects/links in file \"%s\"\n", fname);
+ else
+ print_statistics("/", &iter);
+ } /* end else */
+ } /* end if */
+
+done:
+ hand_free(hand);
+
+ /* Free iter structure */
+ iter_free(&iter);
+
+ if(fid >= 0 && H5Fclose(fid) < 0) {
+ error_msg("unable to close file \"%s\"\n", fname);
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+
+ leave(h5tools_getstatus());
+} /* end main() */
+
diff --git a/tools/src/h5stat/testh5stat.sh.in b/tools/src/h5stat/testh5stat.sh.in
new file mode 100644
index 0000000..cbb732c
--- /dev/null
+++ b/tools/src/h5stat/testh5stat.sh.in
@@ -0,0 +1,318 @@
+#! /bin/sh
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+#
+# Tests for the h5stat tool
+#
+# Modifcations:
+# Vailin Choi; July 2013
+# Add tests for -l, -m, -a options
+#
+
+srcdir=@srcdir@
+
+# Determine which filters are available
+USE_FILTER_SZIP="@USE_FILTER_SZIP@"
+USE_FILTER_DEFLATE="@USE_FILTER_DEFLATE@"
+
+TESTNAME=h5stat
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+STAT=h5stat # The tool name
+STAT_BIN=`pwd`/$STAT # The path of the tool binary
+
+RM='rm -rf'
+CMP='cmp -s'
+DIFF='diff -c'
+CP='cp'
+DIRNAME='dirname'
+LS='ls'
+AWK='awk'
+
+nerrors=0
+verbose=yes
+
+# source dirs
+SRC_TOOLS="$srcdir/.."
+SRC_TOOLS_TESTFILES="$SRC_TOOLS/testfiles"
+
+# testfiles source dirs for tools
+SRC_H5LS_TESTFILES="$SRC_TOOLS_TESTFILES"
+SRC_H5DUMP_TESTFILES="$SRC_TOOLS_TESTFILES"
+SRC_H5DIFF_TESTFILES="$SRC_TOOLS/h5diff/testfiles"
+SRC_H5COPY_TESTFILES="$SRC_TOOLS/h5copy/testfiles"
+SRC_H5REPACK_TESTFILES="$SRC_TOOLS/h5repack/testfiles"
+SRC_H5JAM_TESTFILES="$SRC_TOOLS/h5jam/testfiles"
+SRC_H5STAT_TESTFILES="$SRC_TOOLS/h5stat/testfiles"
+SRC_H5IMPORT_TESTFILES="$SRC_TOOLS/h5import/testfiles"
+
+TESTDIR=./testfiles
+test -d $TESTDIR || mkdir $TESTDIR
+
+######################################################################
+# test files
+# --------------------------------------------------------------------
+# All the test files copy from source directory to test directory
+# NOTE: Keep this framework to add/remove test files.
+# Any test files from other tools can be used in this framework.
+# This list are also used for checking exist.
+# Comment '#' without space can be used.
+# --------------------------------------------------------------------
+LIST_HDF5_TEST_FILES="
+$SRC_H5STAT_TESTFILES/h5stat_filters.h5
+$SRC_H5STAT_TESTFILES/h5stat_tsohm.h5
+$SRC_H5STAT_TESTFILES/h5stat_newgrat.h5
+$SRC_H5STAT_TESTFILES/h5stat_idx.h5
+$SRC_H5STAT_TESTFILES/h5stat_threshold.h5
+"
+
+LIST_OTHER_TEST_FILES="
+$SRC_H5STAT_TESTFILES/h5stat_help1.ddl
+$SRC_H5STAT_TESTFILES/h5stat_help2.ddl
+$SRC_H5STAT_TESTFILES/h5stat_notexist.ddl
+$SRC_H5STAT_TESTFILES/h5stat_nofile.ddl
+$SRC_H5STAT_TESTFILES/h5stat_filters.ddl
+$SRC_H5STAT_TESTFILES/h5stat_filters-file.ddl
+$SRC_H5STAT_TESTFILES/h5stat_filters-F.ddl
+$SRC_H5STAT_TESTFILES/h5stat_filters-d.ddl
+$SRC_H5STAT_TESTFILES/h5stat_filters-g.ddl
+$SRC_H5STAT_TESTFILES/h5stat_filters-dT.ddl
+$SRC_H5STAT_TESTFILES/h5stat_filters-UD.ddl
+$SRC_H5STAT_TESTFILES/h5stat_filters-UT.ddl
+$SRC_H5STAT_TESTFILES/h5stat_tsohm.ddl
+$SRC_H5STAT_TESTFILES/h5stat_newgrat.ddl
+$SRC_H5STAT_TESTFILES/h5stat_newgrat-UG.ddl
+$SRC_H5STAT_TESTFILES/h5stat_newgrat-UA.ddl
+$SRC_H5STAT_TESTFILES/h5stat_idx.ddl
+$SRC_H5STAT_TESTFILES/h5stat_err1_links.ddl
+$SRC_H5STAT_TESTFILES/h5stat_links1.ddl
+$SRC_H5STAT_TESTFILES/h5stat_links2.ddl
+$SRC_H5STAT_TESTFILES/h5stat_links3.ddl
+$SRC_H5STAT_TESTFILES/h5stat_links4.ddl
+$SRC_H5STAT_TESTFILES/h5stat_links5.ddl
+$SRC_H5STAT_TESTFILES/h5stat_err1_dims.ddl
+$SRC_H5STAT_TESTFILES/h5stat_dims1.ddl
+$SRC_H5STAT_TESTFILES/h5stat_dims2.ddl
+$SRC_H5STAT_TESTFILES/h5stat_err1_numattrs.ddl
+$SRC_H5STAT_TESTFILES/h5stat_err2_numattrs.ddl
+$SRC_H5STAT_TESTFILES/h5stat_numattrs1.ddl
+$SRC_H5STAT_TESTFILES/h5stat_numattrs2.ddl
+$SRC_H5STAT_TESTFILES/h5stat_numattrs3.ddl
+$SRC_H5STAT_TESTFILES/h5stat_numattrs4.ddl
+"
+
+#
+# copy test files and expected output files from source dirs to test dir
+#
+COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_OTHER_TEST_FILES"
+
+COPY_TESTFILES_TO_TESTDIR()
+{
+ # copy test files. Used -f to make sure get a new copy
+ for tstfile in $COPY_TESTFILES
+ do
+ # ignore '#' comment
+ echo $tstfile | tr -d ' ' | grep '^#' > /dev/null
+ RET=$?
+ if [ $RET -eq 1 ]; then
+ # skip cp if srcdir is same as destdir
+ # this occurs when build/test performed in source dir and
+ # make cp fail
+ SDIR=`$DIRNAME $tstfile`
+ INODE_SDIR=`$LS -i -d $SDIR | $AWK -F' ' '{print $1}'`
+ INODE_DDIR=`$LS -i -d $TESTDIR | $AWK -F' ' '{print $1}'`
+ if [ "$INODE_SDIR" != "$INODE_DDIR" ]; then
+ $CP -f $tstfile $TESTDIR
+ if [ $? -ne 0 ]; then
+ echo "Error: FAILED to copy $tstfile ."
+
+ # Comment out this to CREATE expected file
+ exit $EXIT_FAILURE
+ fi
+ fi
+ fi
+ done
+}
+
+CLEAN_TESTFILES_AND_TESTDIR()
+{
+ # skip rm if srcdir is same as destdir
+ # this occurs when build/test performed in source dir and
+ # make cp fail
+ SDIR=$SRC_H5STAT_TESTFILES
+ INODE_SDIR=`$LS -i -d $SDIR | $AWK -F' ' '{print $1}'`
+ INODE_DDIR=`$LS -i -d $TESTDIR | $AWK -F' ' '{print $1}'`
+ if [ "$INODE_SDIR" != "$INODE_DDIR" ]; then
+ $RM $TESTDIR
+ fi
+}
+
+# Print a line-line message left justified in a field of 70 characters
+# beginning with the word "Testing".
+#
+TESTING() {
+ SPACES=" "
+ echo "Testing $* $SPACES" | cut -c1-70 | tr -d '\012'
+}
+
+# Source in the output filter function definitions.
+. $srcdir/../../bin/output_filter.sh
+
+# Run a test and print PASS or *FAIL*. If a test fails then increment
+# the `nerrors' global variable and (if $verbose is set) display the
+# difference between the actual output and the expected output. The
+# expected output is given as the first argument to this function and
+# the actual output file is calculated by replacing the `.ddl' with
+# `.out'. The actual output is not removed if $HDF5_NOCLEANUP has a
+# non-zero value.
+#
+TOOLTEST() {
+ expect="$TESTDIR/$1"
+ actual="$TESTDIR/`basename $1 .ddl`.out"
+ actual_err="$TESTDIR/`basename $1 .ddl`.err"
+ actual_sav=${actual}-sav
+ actual_err_sav=${actual_err}-sav
+ shift
+
+ # Run test.
+ TESTING $STAT $@
+ (
+ cd $TESTDIR
+ $RUNSERIAL $STAT_BIN $@
+ ) >$actual 2>$actual_err
+
+ # save actual and actual_err in case they are needed later.
+ cp $actual $actual_sav
+ STDOUT_FILTER $actual
+ cp $actual_err $actual_err_sav
+ STDERR_FILTER $actual_err
+ cat $actual_err >> $actual
+
+ if [ ! -f $expect ]; then
+ # Create the expect file if it doesn't yet exist.
+ echo " CREATED"
+ cp $actual $expect
+ elif $CMP $expect $actual; then
+ echo " PASSED"
+ else
+ echo "*FAILED*"
+ echo " Expected result (*.ddl) differs from actual result (*.out)"
+ nerrors="`expr $nerrors + 1`"
+ test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /'
+ fi
+
+ # Clean up output file
+ if test -z "$HDF5_NOCLEANUP"; then
+ rm -f $actual $actual_err $actual_sav $actual_err_sav
+ fi
+}
+
+
+# Print a "SKIP" message
+SKIP() {
+ TESTING $STAT $@
+ echo " -SKIP-"
+}
+
+
+
+##############################################################################
+##############################################################################
+### T H E T E S T S ###
+##############################################################################
+##############################################################################
+# prepare for test
+COPY_TESTFILES_TO_TESTDIR
+
+# Test for help flag
+TOOLTEST h5stat_help1.ddl -h
+TOOLTEST h5stat_help2.ddl --help
+# Test when h5stat a file that does not exist
+TOOLTEST h5stat_notexist.ddl notexist.h5
+TOOLTEST h5stat_nofile.ddl ''
+
+# Test file with groups, compressed datasets, user-applied fileters, etc.
+# h5stat_filters.h5 is a copy of ../../testfiles/tfilters.h5 as of release 1.8.0-alpha4
+TOOLTEST h5stat_filters.ddl h5stat_filters.h5
+TOOLTEST h5stat_filters-file.ddl -f h5stat_filters.h5
+TOOLTEST h5stat_filters-F.ddl -F h5stat_filters.h5
+TOOLTEST h5stat_filters-d.ddl -d h5stat_filters.h5
+TOOLTEST h5stat_filters-g.ddl -g h5stat_filters.h5
+TOOLTEST h5stat_filters-dT.ddl -dT h5stat_filters.h5
+TOOLTEST h5stat_filters-UD.ddl -D h5stat_filters.h5
+TOOLTEST h5stat_filters-UT.ddl -T h5stat_filters.h5
+#
+# h5stat_tsohm.h5 is a copy of ../../../test/tsohm.h5 generated by tsohm.c
+# as of release 1.8.7-snap0 (on a 64-bit machine)
+TOOLTEST h5stat_tsohm.ddl h5stat_tsohm.h5
+# h5stat_newgrat.h5 is generated by h5stat_gentest.c
+TOOLTEST h5stat_newgrat.ddl h5stat_newgrat.h5
+TOOLTEST h5stat_newgrat-UG.ddl -G h5stat_newgrat.h5
+TOOLTEST h5stat_newgrat-UA.ddl -A h5stat_newgrat.h5
+# h5stat_idx.h5 is generated by h5stat_gentest.c
+TOOLTEST h5stat_idx.ddl h5stat_idx.h5
+#
+# Tests for -l (--links) option on h5stat_threshold.h5:
+# -l 0 (incorrect threshold value)
+# -g -l 8
+# --links=8
+# --links=20 -g
+TOOLTEST h5stat_err1_links.ddl -l 0 h5stat_threshold.h5
+TOOLTEST h5stat_links1.ddl -g -l 8 h5stat_threshold.h5
+TOOLTEST h5stat_links2.ddl --links=8 h5stat_threshold.h5
+TOOLTEST h5stat_links3.ddl --links=20 -g h5stat_threshold.h5
+#
+# Tests for -l (--links) option on h5stat_newgrat.h5:
+# -g
+# -g -l 40000
+TOOLTEST h5stat_links4.ddl -g h5stat_newgrat.h5
+TOOLTEST h5stat_links5.ddl -g -l 40000 h5stat_newgrat.h5
+#
+# Tests for -m (--dims) option on h5stat_threshold.h5
+# -d --dims=-1 (incorrect threshold value)
+# -gd -m 5
+# -d --di=15
+TOOLTEST h5stat_err1_dims.ddl -d --dims=-1 h5stat_threshold.h5
+TOOLTEST h5stat_dims1.ddl -gd -m 5 h5stat_threshold.h5
+TOOLTEST h5stat_dims2.ddl -d --di=15 h5stat_threshold.h5
+#
+# Tests for -a option on h5stat_threshold.h5
+# -a -2 (incorrect threshold value)
+# --numattrs (without threshold value)
+# -AS -a 10
+# -a 1
+# -A --numattrs=25
+TOOLTEST h5stat_err1_numattrs.ddl -a -2 h5stat_threshold.h5
+TOOLTEST h5stat_err2_numattrs.ddl --numattrs h5stat_threshold.h5
+TOOLTEST h5stat_numattrs1.ddl -AS -a 10 h5stat_threshold.h5
+TOOLTEST h5stat_numattrs2.ddl -a 1 h5stat_threshold.h5
+TOOLTEST h5stat_numattrs3.ddl -A --numattrs=25 h5stat_threshold.h5
+#
+# Tests for -a option on h5stat_newgrat.h5
+# -A -a 100
+TOOLTEST h5stat_numattrs4.ddl -A -a 100 h5stat_newgrat.h5
+#
+
+# Clean up temporary files/directories
+CLEAN_TESTFILES_AND_TESTDIR
+
+if test $nerrors -eq 0 ; then
+ echo "All $TESTNAME tests passed."
+ exit $EXIT_SUCCESS
+else
+ echo "$TESTNAME tests failed with $nerrors errors."
+ exit $EXIT_FAILURE
+fi
+
diff --git a/tools/src/misc/CMakeLists.txt b/tools/src/misc/CMakeLists.txt
new file mode 100644
index 0000000..6fcff9c
--- /dev/null
+++ b/tools/src/misc/CMakeLists.txt
@@ -0,0 +1,67 @@
+cmake_minimum_required (VERSION 3.1.0)
+PROJECT (HDF5_TOOLS_SRC_MISC)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib)
+
+# --------------------------------------------------------------------
+# Add the misc executables
+# --------------------------------------------------------------------
+#-- Misc Executables
+add_executable (h5debug ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5debug.c)
+TARGET_NAMING (h5debug STATIC)
+TARGET_C_PROPERTIES (h5debug STATIC " " " ")
+target_link_libraries (h5debug ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET})
+set_target_properties (h5debug PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5debug")
+
+add_executable (h5repart ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5repart.c)
+TARGET_NAMING (h5repart STATIC)
+TARGET_C_PROPERTIES (h5repart STATIC " " " ")
+target_link_libraries (h5repart ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET})
+set_target_properties (h5repart PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5repart")
+
+add_executable (h5mkgrp ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5mkgrp.c)
+TARGET_NAMING (h5mkgrp STATIC)
+TARGET_C_PROPERTIES (h5mkgrp STATIC " " " ")
+target_link_libraries (h5mkgrp ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+set_target_properties (h5mkgrp PROPERTIES FOLDER tools)
+set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5mkgrp")
+
+set (H5_DEP_EXECUTABLES
+ h5debug
+ h5repart
+ h5mkgrp
+)
+
+#-----------------------------------------------------------------------------
+# Generate the h5cc file containing settings needed to compile programs
+#-----------------------------------------------------------------------------
+#if (NOT WIN32)
+# configure_file (${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5cc.in ${HDF5_BINARY_DIR}/h5cc @ONLY)
+#endif (NOT WIN32)
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+
+#INSTALL_PROGRAM_PDB (h5debug ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+#INSTALL_PROGRAM_PDB (h5repart ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+#INSTALL_PROGRAM_PDB (h5mkgrp ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+
+install (
+ TARGETS
+ h5debug h5repart h5mkgrp
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+)
diff --git a/tools/src/misc/Makefile.am b/tools/src/misc/Makefile.am
new file mode 100644
index 0000000..c069e9a
--- /dev/null
+++ b/tools/src/misc/Makefile.am
@@ -0,0 +1,61 @@
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src directory
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+# These are our main targets, the tools
+bin_PROGRAMS=h5debug h5repart h5mkgrp
+bin_SCRIPTS=h5redeploy
+
+# Add h5debug, h5repart, and h5mkgrp specific linker flags here
+h5debug_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+h5repart_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+h5mkgrp_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# Tell automake to clean h5redeploy script
+CLEANFILES=h5redeploy
+
+# These were generated by configure. Remove them only when distclean.
+DISTCLEANFILES=h5cc
+
+# All programs rely on hdf5 library and h5tools library
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+# h5cc needs custom install and uninstall rules, since it may be
+# named h5pcc if hdf5 is being built in parallel mode.
+if BUILD_PARALLEL_CONDITIONAL
+ H5CC_NAME=h5pcc
+else
+ H5CC_NAME=h5cc
+endif
+
+install-exec-local:
+ @$(INSTALL) h5cc $(DESTDIR)$(bindir)/$(H5CC_NAME)
+uninstall-local:
+ @$(RM) $(DESTDIR)$(bindir)/$(H5CC_NAME)
+
+# How to build h5redeploy script
+h5redeploy: h5redeploy.in
+ @cp $(srcdir)/$@.in $@
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/misc/h5cc.in b/tools/src/misc/h5cc.in
new file mode 100644
index 0000000..1645855
--- /dev/null
+++ b/tools/src/misc/h5cc.in
@@ -0,0 +1,401 @@
+#! /bin/sh
+##
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+##
+
+# This tool is adapted from the mpicc command of the MPICH Software.
+
+############################################################################
+## ##
+## Things You May Have to Modify: ##
+## ##
+## If the following paths don't point to the place were HDF5 is installed ##
+## on your system (i.e., you received a binary distribution or moved the ##
+## files from the originally installed directory to another directory) ##
+## then modify them accordingly to represent the new paths. ##
+## ##
+############################################################################
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+libdir="@libdir@"
+includedir="@includedir@"
+HL="@HL@"
+
+############################################################################
+## ##
+## Things You Can Modify to Override HDF5 Library Build Components: ##
+## ##
+## (Advanced usage - know what you're doing - you're on your own here.) ##
+## The four variables below can be used to insert paths and flags in ##
+## CPPFLAGS, CFLAGS, LDFLAGS, or LIBS in the h5cc compile line: ##
+## $CLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CFLAGS $CFLAGS $LDFLAGS ##
+## $LIBS $clibpath $link_objs $link_args $shared_link ##
+## ##
+## These settings can be overriden by setting HDF5_CFLAGS, ##
+## HDF5_CPPFLAGS, HDF5_LDFLAGS, or HDF5_LIBS in the environment. ##
+## ##
+############################################################################
+CFLAGSBASE=""
+CPPFLAGSBASE=""
+LDFLAGSBASE=""
+LIBSBASE=""
+
+############################################################################
+## ##
+## You shouldn't have to modify anything below this line. ##
+## ##
+############################################################################
+
+# Constants definitions
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+host_os="@host_os@"
+
+prog_name="`basename $0`"
+
+allargs=""
+compile_args=""
+libraries=""
+link_args=""
+link_objs=""
+clibpath=""
+
+do_link="yes"
+do_compile="no"
+dash_o="no"
+dash_c="no"
+get_output_file="no"
+
+SHOW="eval"
+CCBASE="@CC@"
+CLINKERBASE="@CC@"
+
+# CFLAGS, CPPFLAGS and LDFLAGS are reserved for use by the script user.
+# FLAGS brought from the hdf5 build are put in H5BLD_*FLAGS.
+
+# User's CPPFLAGS and CFLAGS come after their H5BLD counterparts. User's
+# LDFLAGS come just before clibpath, user's LIBS come after $link_objs and
+# before the hdf5 libraries in $link_args, followed by any external library
+# paths and libraries from AM_LDFLAGS, LDFLAGS, AM_LIBS or LIBS carried in
+# from the hdf5 build. The order of the flags is intended to give precedence
+# to the user's flags.
+H5BLD_CFLAGS="@AM_CFLAGS@ @CFLAGS@"
+H5BLD_CPPFLAGS="@AM_CPPFLAGS@ @CPPFLAGS@"
+H5BLD_LDFLAGS="@AM_LDFLAGS@ @LDFLAGS@"
+H5BLD_LIBS="@LIBS@"
+
+CC="${HDF5_CC:-$CCBASE}"
+CLINKER="${HDF5_CLINKER:-$CLINKERBASE}"
+CFLAGS="${HDF5_CFLAGS:-$CFLAGSBASE}"
+CPPFLAGS="${HDF5_CPPFLAGS:-$CPPFLAGSBASE}"
+LDFLAGS="${HDF5_LDFLAGS:-$LDFLAGSBASE}"
+LIBS="${HDF5_LIBS:-$LIBSBASE}"
+
+# If a static library is available, the default will be to use it. If the only
+# available library is shared, it will be used by default. The user can
+# override either default, although choosing an unavailable library will result
+# in link errors.
+STATIC_AVAILABLE="@enable_static@"
+if test "${STATIC_AVAILABLE}" = "yes"; then
+ USE_SHARED_LIB="${HDF5_USE_SHLIB:-no}"
+else
+ USE_SHARED_LIB="${HDF5_USE_SHLIB:-yes}"
+fi
+
+
+usage() {
+ # A wonderfully informative "usage" message.
+ echo "usage: $prog_name [OPTIONS] <compile line>"
+ echo " OPTIONS:"
+ echo " -help This help message."
+ echo " -echo Show all the shell commands executed"
+ echo " -prefix=DIR Prefix directory to find HDF5 lib/ and include/"
+ echo " subdirectories [default: $prefix]"
+ # A wonderfully informative "usage" message.
+ echo "usage: $prog_name [OPTIONS] <compile line>"
+ echo " OPTIONS:"
+ echo " -help This help message."
+ echo " -echo Show all the shell commands executed"
+ echo " -prefix=DIR Prefix directory to find HDF5 lib/ and include/"
+ echo " subdirectories [default: $prefix]"
+ echo " -show Show the commands without executing them"
+ echo " -showconfig Show the HDF5 library configuration summary"
+ echo " -shlib Compile with shared HDF5 libraries [default for hdf5 built"
+ echo " without static libraries]"
+ echo " -noshlib Compile with static HDF5 libraries [default for hdf5 built"
+ echo " with static libraries]"
+ echo " "
+ echo " <compile line> - the normal compile line options for your compiler."
+ echo " $prog_name uses the same compiler you used to compile"
+ echo " HDF5. Check with your compiler's man pages for more"
+ echo " information on which options are needed."
+ echo " "
+ echo " You can override the compiler, linker, and whether or not to use static"
+ echo " or shared libraries to compile your program by setting the following"
+ echo " environment variables accordingly:"
+ echo " "
+ echo " HDF5_CC - use a different C compiler"
+ echo " HDF5_CLINKER - use a different linker"
+ echo " HDF5_USE_SHLIB=[yes|no] - use shared or static version of the HDF5 library"
+ echo " [default: no except when built with only"
+ echo " shared libraries]"
+ echo " "
+ echo " You can also add or change paths and flags to the compile line using"
+ echo " the following environment varibles or by assigning them to their counterparts"
+ echo " in the 'Things You Can Modify to Override...'" section of $prog_name
+ echo " "
+ echo " Variable Current value to be replaced"
+ echo " HDF5_CPPFLAGS \"$CPPFLAGSBASE\""
+ echo " HDF5_CFLAGS \"$CFLAGSBASE\""
+ echo " HDF5_LDFLAGS \"$LDFLAGSBASE\""
+ echo " HDF5_LIBS \"$LIBSBASE\""
+ echo " "
+ echo " Note that adding library paths to HDF5_LDFLAGS where another hdf5 version"
+ echo " is located may link your program with that other hdf5 library version."
+ echo " "
+ exit $EXIT_FAILURE
+}
+
+# Show the configuration summary of the library recorded in the
+# libhdf5.settings file reside in the lib directory.
+showconfigure()
+{
+ cat ${libdir}/libhdf5.settings
+ status=$?
+}
+
+# Main
+status=$EXIT_SUCCESS
+
+if test "$#" = "0"; then
+ # No parameters specified, issue usage statement and exit.
+ usage
+fi
+
+case "$CC" in
+ gcc)
+ kind="gcc"
+ ;;
+ mpicc|mpcc|mpicc_r)
+ # Is this gcc masquarading as an MPI compiler?
+ if test "`${CC} -v 2>&1 | sed -n 2p | cut -c1-3`" = "gcc"; then
+ kind="gcc"
+ else
+ # Nope
+ kind="$host_os"
+ fi
+ ;;
+ *)
+ kind="$host_os"
+ ;;
+esac
+
+for arg in $@ ; do
+ if test "x$get_output_file" = "xyes"; then
+ link_args="$link_args $arg"
+ output_file="$arg"
+ get_output_file="no"
+ continue
+ fi
+
+ case "$arg" in
+ -c)
+ allargs="$allargs $arg"
+ compile_args="$compile_args $arg"
+
+ if test "x$do_link" = "xyes" -a -n "$output_file"; then
+ compile_args="$compile_args -o $output_file"
+ fi
+
+ do_link="no"
+ dash_c="yes"
+ ;;
+ -o)
+ allargs="$allargs $arg"
+ dash_o="yes"
+
+ if test "x$dash_c" = "xyes"; then
+ compile_args="$compile_args $arg"
+ else
+ link_args="$link_args $arg"
+ do_link="yes"
+ get_output_file="yes"
+ fi
+ ;;
+ -E|-M|-MT)
+ allargs="$allargs $arg"
+ compile_args="$compile_args $arg"
+ dash_c="yes"
+ do_link="no"
+ ;;
+ -l*)
+ libraries=" $libraries $arg "
+ allargs="$allargs $arg"
+ ;;
+ -prefix=*)
+ prefix="`expr "$arg" : '-prefix=\(.*\)'`"
+ ;;
+ -echo)
+ set -x
+ ;;
+ -show)
+ SHOW="echo"
+ ;;
+ -showconfig)
+ showconfigure
+ exit $status
+ ;;
+ -shlib)
+ USE_SHARED_LIB="yes"
+ ;;
+ -noshlib)
+ USE_SHARED_LIB="no"
+ ;;
+ -help)
+ usage
+ ;;
+ *\"*)
+ qarg="'"$arg"'"
+ allargs="$allargs $qarg"
+ ;;
+ *\'*)
+ qarg='\"'"$arg"'\"'
+ allargs="$allargs $qarg"
+ ;;
+ *)
+ allargs="$allargs $qarg"
+
+ if test -s "$arg"; then
+ ext=`expr "$arg" : '.*\(\..*\)'`
+
+ if test "x$ext" = "x.c"; then
+ do_compile="yes"
+ compile_args="$compile_args $arg"
+ fname=`basename $arg .c`
+ link_objs="$link_objs $fname.o"
+ elif test "x$ext" = "x.o"; then
+ if test "x$dash_c" = "xyes"; then
+ compile_args="$compile_args $arg"
+ else
+ do_link="yes"
+ link_objs="$link_objs $arg"
+ fi
+ elif test "x$ext" = "x.a"; then
+ # This is an archive that we're linking in
+ libraries=" $libraries $arg "
+ else
+ compile_args="$compile_args $arg"
+ link_args="$link_args $arg"
+ fi
+ else
+ compile_args="$compile_args $arg"
+ link_args="$link_args $arg"
+ fi
+ ;;
+ esac
+done
+
+if test "$dash_c" = "yes" -a "$do_compile" = no -a "$do_link" = no ; then
+ # -c was specified. Force do_compile on.
+ do_compile=yes
+fi
+
+if test "x$do_compile" = "xyes"; then
+ if test "x$dash_c" != "xyes"; then
+ compile_args="-c $compile_args"
+ fi
+
+ $SHOW $CC -I$includedir $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CFLAGS $CFLAGS $compile_args
+ status=$?
+
+ if test "$status" != "0"; then
+ exit $status
+ fi
+fi
+
+if test "x$do_link" = "xyes"; then
+ shared_link=""
+# conditionnaly link with the hl library
+ if test "X$HL" = "Xhl"; then
+ libraries=" $libraries -lhdf5_hl -lhdf5 "
+ else
+ libraries=" $libraries -lhdf5 "
+ fi
+ link_args="$link_args -L${libdir}"
+
+ case "$kind" in
+ gcc|linux*)
+ # MacOS X doesn't support the "-Wl,-rpath -Wl," style of linker flags.
+ # It appears to want none of them specified.
+ case "$host_os" in
+ darwin*) flag="" ;;
+ *) flag="-Wl,-rpath -Wl," ;;
+ esac
+ ;;
+ hpux*) flag="-Wl,+b -Wl," ;;
+ freebsd*|solaris*) flag="-R" ;;
+ rs6000*|aix*) flag="-L" ;;
+ sgi) flag="-rpath " ;;
+ *) flag="" ;;
+ esac
+
+ if test -n "$flag"; then
+ shared_link="${flag}${libdir}"
+ fi
+
+ if test "x$USE_SHARED_LIB" != "xyes"; then
+ # The "-lhdf5" & "-lhdf5_hl" flags are in here already...This is a static
+ # compile though, so change it to the static version (.a) of the library.
+ new_libraries=""
+ for lib in $libraries; do
+ case "$lib" in
+ -lhdf5)
+ new_libraries="$new_libraries ${libdir}/libhdf5.a"
+ ;;
+ -lhdf5_hl)
+ new_libraries="$new_libraries ${libdir}/libhdf5_hl.a"
+ ;;
+ *)
+ new_libraries="$new_libraries $lib"
+ ;;
+ esac
+ done
+ libraries="$new_libraries"
+ fi
+
+ for lib in $libraries; do
+ if echo $link_args | grep " $lib " > /dev/null ||
+ echo $link_args | grep " $lib$" > /dev/null; then
+ :
+ else
+ link_args="$link_args $lib "
+ fi
+ done
+
+ # The LIBS are just a bunch of -l* libraries necessary for the HDF5
+ # module. It's okay if they're included twice in the compile line.
+ link_args="$link_args $H5BLD_LDFLAGS $H5BLD_LIBS"
+
+ # User's CPPFLAGS and CFLAGS come after their H5BLD counterparts. User's
+ # LDFLAGS come just before clibpath, user's LIBS come after $link_objs and
+ # before the hdf5 libraries in $link_args, followed by any external library
+ # paths and libraries from AM_LDFLAGS, LDFLAGS, AM_LIBS or LIBS carried in
+ # from the hdf5 build. The order of the flags is intended to give precedence
+ # to the user's flags.
+ $SHOW $CLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CFLAGS $CFLAGS $LDFLAGS $clibpath $link_objs $LIBS $link_args $shared_link
+ status=$?
+fi
+
+exit $status
diff --git a/tools/src/misc/h5debug.c b/tools/src/misc/h5debug.c
new file mode 100644
index 0000000..ae64952
--- /dev/null
+++ b/tools/src/misc/h5debug.c
@@ -0,0 +1,723 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: debug.c
+ * Jul 18 1997
+ * Robb Matzke <matzke@llnl.gov>
+ *
+ * Purpose: Debugs an existing HDF5 file at a low level.
+ *
+ *-------------------------------------------------------------------------
+ */
+#define H5A_FRIEND /*suppress error about including H5Apkg */
+#define H5B2_FRIEND /*suppress error about including H5B2pkg */
+#define H5B2_TESTING /*suppress warning about H5B2 testing funcs*/
+#define H5D_FRIEND /*suppress error about including H5Dpkg */
+#define H5EA_FRIEND /*suppress error about including H5EApkg */
+#define H5EA_TESTING /*suppress warning about H5EA testing funcs*/
+#define H5FA_FRIEND /*suppress error about including H5FApkg */
+#define H5FA_TESTING /*suppress warning about H5FA testing funcs*/
+#define H5F_FRIEND /*suppress error about including H5Fpkg */
+#define H5G_FRIEND /*suppress error about including H5Gpkg */
+#define H5HF_FRIEND /*suppress error about including H5HFpkg */
+#define H5O_FRIEND /*suppress error about including H5Opkg */
+#define H5SM_FRIEND /*suppress error about including H5SMpkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Apkg.h" /* Attributes */
+#include "H5B2pkg.h" /* v2 B-trees */
+#include "H5Dpkg.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5EApkg.h" /* Extensible Arrays */
+#include "H5FApkg.h" /* Fixed Arrays */
+#include "H5Fpkg.h" /* File access */
+#include "H5FSprivate.h" /* Free space manager */
+#include "H5Gpkg.h" /* Groups */
+#include "H5HFpkg.h" /* Fractal heaps */
+#include "H5HGprivate.h" /* Global Heaps */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Opkg.h" /* Object headers */
+#include "H5SMpkg.h" /* Implicitly shared messages */
+
+/* File drivers */
+#include "H5FDfamily.h"
+
+#define VCOL 50
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_H5B2_class
+ *
+ * Purpose: Determine the v2 B-tree class from the buffer read in.
+ * B-trees are debugged through the B-tree subclass. The subclass
+ * identifier is two bytes after the B-tree signature.
+ *
+ * Return: Non-NULL on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static const H5B2_class_t *
+get_H5B2_class(const uint8_t *sig)
+{
+ H5B2_subid_t subtype = (H5B2_subid_t)sig[H5_SIZEOF_MAGIC + 1];
+ const H5B2_class_t *cls;
+
+ switch(subtype) {
+ case H5B2_TEST_ID:
+ cls = H5B2_TEST;
+ break;
+
+ case H5B2_FHEAP_HUGE_INDIR_ID:
+ cls = H5HF_HUGE_BT2_INDIR;
+ break;
+
+ case H5B2_FHEAP_HUGE_FILT_INDIR_ID:
+ cls = H5HF_HUGE_BT2_FILT_INDIR;
+ break;
+
+ case H5B2_FHEAP_HUGE_DIR_ID:
+ cls = H5HF_HUGE_BT2_DIR;
+ break;
+
+ case H5B2_FHEAP_HUGE_FILT_DIR_ID:
+ cls = H5HF_HUGE_BT2_FILT_DIR;
+ break;
+
+ case H5B2_GRP_DENSE_NAME_ID:
+ cls = H5G_BT2_NAME;
+ break;
+
+ case H5B2_GRP_DENSE_CORDER_ID:
+ cls = H5G_BT2_CORDER;
+ break;
+
+ case H5B2_SOHM_INDEX_ID:
+ cls = H5SM_INDEX;
+ break;
+
+ case H5B2_ATTR_DENSE_NAME_ID:
+ cls = H5A_BT2_NAME;
+ break;
+
+ case H5B2_ATTR_DENSE_CORDER_ID:
+ cls = H5A_BT2_CORDER;
+ break;
+
+ case H5B2_CDSET_ID:
+ cls = H5D_BT2;
+ break;
+
+ case H5B2_CDSET_FILT_ID:
+ cls = H5D_BT2_FILT;
+ break;
+
+ case H5B2_TEST2_ID:
+ cls = H5B2_TEST2;
+ break;
+
+ case H5B2_NUM_BTREE_ID:
+ default:
+ HDfprintf(stderr, "Unknown v2 B-tree subtype %u\n", (unsigned)(subtype));
+ HDexit(4);
+ } /* end switch */
+
+ return(cls);
+} /* end get_H5B2_class() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_H5EA_class
+ *
+ * Purpose: Determine the extensible array class from the buffer read in.
+ * Extensible arrays are debugged through the array subclass.
+ * The subclass identifier is two bytes after the signature.
+ *
+ * Return: Non-NULL on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static const H5EA_class_t *
+get_H5EA_class(const uint8_t *sig)
+{
+ H5EA_cls_id_t clsid = (H5EA_cls_id_t)sig[H5_SIZEOF_MAGIC + 1];
+ const H5EA_class_t *cls;
+
+ switch(clsid) {
+ case H5EA_CLS_TEST_ID:
+ cls = H5EA_CLS_TEST;
+ break;
+
+ case H5EA_CLS_CHUNK_ID:
+ cls = H5EA_CLS_CHUNK;
+ break;
+
+ case H5EA_CLS_FILT_CHUNK_ID:
+ cls = H5EA_CLS_FILT_CHUNK;
+ break;
+
+ case H5EA_NUM_CLS_ID:
+ default:
+ HDfprintf(stderr, "Unknown extensible array class %u\n", (unsigned)(clsid));
+ HDexit(4);
+ } /* end switch */
+
+ return(cls);
+} /* end get_H5EA_class() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_H5FA_class
+ *
+ * Purpose: Determine the fixed array class from the buffer read in.
+ * Extensible arrays are debugged through the array subclass.
+ * The subclass identifier is two bytes after the signature.
+ *
+ * Return: Non-NULL on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static const H5FA_class_t *
+get_H5FA_class(const uint8_t *sig)
+{
+ H5FA_cls_id_t clsid = (H5FA_cls_id_t)sig[H5_SIZEOF_MAGIC + 1];
+ const H5FA_class_t *cls;
+
+ switch(clsid) {
+ case H5FA_CLS_TEST_ID:
+ cls = H5FA_CLS_TEST;
+ break;
+
+ case H5FA_CLS_CHUNK_ID:
+ cls = H5FA_CLS_CHUNK;
+ break;
+
+ case H5FA_CLS_FILT_CHUNK_ID:
+ cls = H5FA_CLS_FILT_CHUNK;
+ break;
+
+ case H5FA_NUM_CLS_ID:
+ default:
+ HDfprintf(stderr, "Unknown fixed array class %u\n", (unsigned)(clsid));
+ HDexit(4);
+ } /* end switch */
+
+ return(cls);
+} /* end get_H5FA_class() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Usage: debug FILENAME [OFFSET]
+ *
+ * Return: Success: exit (0)
+ *
+ * Failure: exit (non-zero)
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Jul 18 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, char *argv[])
+{
+ hid_t fid, fapl, dxpl;
+ H5F_t *f;
+ haddr_t addr = 0, extra = 0, extra2 = 0, extra3 = 0, extra4 = 0;
+ uint8_t sig[H5F_SIGNATURE_LEN];
+ size_t u;
+ H5E_auto2_t func;
+ void *edata;
+ herr_t status = SUCCEED;
+
+ if(argc == 1) {
+ HDfprintf(stderr, "Usage: %s filename [signature-addr [extra]]\n", argv[0]);
+ HDexit(1);
+ } /* end if */
+
+ /* Initialize the library */
+ if(H5open() < 0) {
+ HDfprintf(stderr, "cannot initialize the library\n");
+ HDexit(1);
+ } /* end if */
+
+ /* Disable error reporting */
+ H5Eget_auto2(H5E_DEFAULT, &func, &edata);
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /*
+ * Open the file and get the file descriptor.
+ */
+ dxpl = H5AC_ind_read_dxpl_id;
+ if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
+ HDfprintf(stderr, "cannot create file access property list\n");
+ HDexit(1);
+ } /* end if */
+ if(HDstrchr(argv[1], '%'))
+ if(H5Pset_fapl_family (fapl, (hsize_t)0, H5P_DEFAULT) < 0) {
+ fprintf(stderr, "cannot set file access property list\n");
+ HDexit(1);
+ }
+ if((fid = H5Fopen(argv[1], H5F_ACC_RDONLY, fapl)) < 0) {
+ HDfprintf(stderr, "cannot open file\n");
+ HDexit(1);
+ } /* end if */
+ if(NULL == (f = (H5F_t *)H5I_object(fid))) {
+ HDfprintf(stderr, "cannot obtain H5F_t pointer\n");
+ HDexit(2);
+ } /* end if */
+
+ /* Ignore metadata tags while using h5debug */
+ if(H5AC_ignore_tags(f) < 0) {
+ HDfprintf(stderr, "cannot ignore metadata tags\n");
+ HDexit(1);
+ }
+
+ /*
+ * Parse command arguments.
+ */
+ if(argc > 2)
+ addr = (haddr_t)HDstrtoll(argv[2], NULL, 0);
+ if(argc > 3)
+ extra = (haddr_t)HDstrtoll(argv[3], NULL, 0);
+ if(argc > 4)
+ extra2 = (haddr_t)HDstrtoll(argv[4], NULL, 0);
+ if(argc > 5)
+ extra3 = (haddr_t)HDstrtoll(argv[5], NULL, 0);
+ if(argc > 6)
+ extra4 = (haddr_t)HDstrtoll(argv[6], NULL, 0);
+
+ /*
+ * Read the signature at the specified file position.
+ */
+ HDfprintf(stdout, "Reading signature at address %a (rel)\n", addr);
+ if(H5F_block_read(f, H5FD_MEM_SUPER, addr, sizeof(sig), dxpl, sig) < 0) {
+ HDfprintf(stderr, "cannot read signature\n");
+ HDexit(3);
+ }
+ if(!HDmemcmp(sig, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN)) {
+ /*
+ * Debug the file's super block.
+ */
+ status = H5F_debug(f, stdout, 0, VCOL);
+
+ } else if(!HDmemcmp(sig, H5HL_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a local heap.
+ */
+ status = H5HL_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL);
+
+ } else if(!HDmemcmp (sig, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a global heap collection.
+ */
+ status = H5HG_debug (f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL);
+
+ } else if(!HDmemcmp(sig, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a symbol table node.
+ */
+
+ /* Check for extra parameters */
+ if(extra == 0) {
+ HDfprintf(stderr, "\nWarning: Providing the group's local heap address will give more information\n");
+ HDfprintf(stderr, "Symbol table node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <Symbol table node address> <address of local heap>\n\n");
+ } /* end if */
+
+ status = H5G_node_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra);
+
+ } else if(!HDmemcmp(sig, H5B_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a B-tree. B-trees are debugged through the B-tree
+ * subclass. The subclass identifier is the byte immediately
+ * after the B-tree signature.
+ */
+ H5B_subid_t subtype = (H5B_subid_t)sig[H5_SIZEOF_MAGIC];
+ unsigned ndims;
+ uint32_t dim[H5O_LAYOUT_NDIMS];
+
+ switch(subtype) {
+ case H5B_SNODE_ID:
+ /* Check for extra parameters */
+ if(extra == 0) {
+ HDfprintf(stderr, "\nWarning: Providing the group's local heap address will give more information\n");
+ HDfprintf(stderr, "B-tree symbol table node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <address of local heap>\n\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5G_node_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra);
+ break;
+
+ case H5B_CHUNK_ID:
+ /* Check for extra parameters */
+ if(extra == 0) {
+ HDfprintf(stderr, "ERROR: Need number of dimensions of chunk in order to dump chunk B-tree node\n");
+ HDfprintf(stderr, "B-tree chunked storage node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <# of dimensions> <slowest chunk dim>...<fastest chunk dim>\n");
+ HDexit(4);
+ } /* end if */
+
+ /* Build array of chunk dimensions */
+ ndims = (unsigned)extra;
+ dim[0] = (uint32_t)extra2;
+ if(ndims > 1)
+ dim[1] = (uint32_t)extra3;
+ if(ndims > 2)
+ dim[2] = (uint32_t)extra4;
+
+ /* Check for dimension error */
+ if(ndims > 3) {
+ HDfprintf(stderr, "ERROR: Only 3 dimensions support currently (fix h5debug)\n");
+ HDfprintf(stderr, "B-tree chunked storage node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <# of dimensions> <slowest chunk dim>...<fastest chunk dim>\n");
+ HDexit(4);
+ } /* end for */
+ for(u = 0; u < ndims; u++)
+ if(0 == dim[u]) {
+ HDfprintf(stderr, "ERROR: Chunk dimensions should be >0\n");
+ HDfprintf(stderr, "B-tree chunked storage node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <# of dimensions> <slowest chunk dim>...<fastest chunk dim>\n");
+ HDexit(4);
+ } /* end if */
+
+ /* Set the last dimension (the element size) to zero */
+ dim[ndims] = 0;
+
+ status = H5D_btree_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, ndims, dim);
+ break;
+
+ case H5B_NUM_BTREE_ID:
+ default:
+ HDfprintf(stderr, "Unknown v1 B-tree subtype %u\n", (unsigned)(subtype));
+ HDexit(4);
+ }
+
+ } else if(!HDmemcmp(sig, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a v2 B-tree header.
+ */
+ const H5B2_class_t *cls = get_H5B2_class(sig);
+ HDassert(cls);
+
+ if((cls == H5D_BT2 || cls == H5D_BT2_FILT) && extra == 0) {
+ HDfprintf(stderr, "ERROR: Need v2 B-tree header address and object header address containing the layout message in order to dump header\n");
+ HDfprintf(stderr, "v2 B-tree hdr usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <v2 B-tree header address> <object header address>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5B2__hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, (haddr_t)extra);
+
+ } else if(!HDmemcmp(sig, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a v2 B-tree internal node.
+ */
+ const H5B2_class_t *cls = get_H5B2_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if((cls == H5D_BT2 || cls == H5D_BT2_FILT) &&
+ (extra == 0 || extra2 == 0 || extra3 == 0 || extra4 == 0)) {
+
+ fprintf(stderr, "ERROR: Need v2 B-tree header address, the node's number of records, depth, and object header address containing the layout message in order to dump internal node\n");
+ fprintf(stderr, "NOTE: Leaf nodes are depth 0, the internal nodes above them are depth 1, etc.\n");
+ fprintf(stderr, "v2 B-tree internal node usage:\n");
+ fprintf(stderr, "\th5debug <filename> <internal node address> <v2 B-tree header address> <number of records> <depth> <object header address>\n");
+ HDexit(4);
+
+ } else if(extra == 0 || extra2 == 0 || extra3 == 0) {
+ HDfprintf(stderr, "ERROR: Need v2 B-tree header address and the node's number of records and depth in order to dump internal node\n");
+ HDfprintf(stderr, "NOTE: Leaf nodes are depth 0, the internal nodes above them are depth 1, etc.\n");
+ HDfprintf(stderr, "v2 B-tree internal node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <internal node address> <v2 B-tree header address> <number of records> <depth>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5B2__int_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, (unsigned)extra3, (haddr_t)extra4);
+
+ } else if(!HDmemcmp(sig, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a v2 B-tree leaf node.
+ */
+ const H5B2_class_t *cls = get_H5B2_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if((cls == H5D_BT2 || cls == H5D_BT2_FILT) &&
+ (extra == 0 || extra2 == 0 || extra3 == 0 )) {
+
+ fprintf(stderr, "ERROR: Need v2 B-tree header address, number of records, and object header address containing the layout message in order to dump leaf node\n");
+ fprintf(stderr, "v2 B-tree leaf node usage:\n");
+ fprintf(stderr, "\th5debug <filename> <leaf node address> <v2 B-tree header address> <number of records> <object header address>\n");
+ HDexit(4);
+
+ } else if(extra == 0 || extra2 == 0) {
+ HDfprintf(stderr, "ERROR: Need v2 B-tree header address and number of records in order to dump leaf node\n");
+ HDfprintf(stderr, "v2 B-tree leaf node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <leaf node address> <v2 B-tree header address> <number of records>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5B2__leaf_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, (haddr_t)extra3);
+
+ } else if(!HDmemcmp(sig, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fractal heap header.
+ */
+ status = H5HF_hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL);
+
+ } else if(!HDmemcmp(sig, H5HF_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fractal heap direct block.
+ */
+
+ /* Check for enough valid parameters */
+ if(extra == 0 || extra2 == 0) {
+ HDfprintf(stderr, "ERROR: Need fractal heap header address and size of direct block in order to dump direct block\n");
+ HDfprintf(stderr, "Fractal heap direct block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <direct block address> <heap header address> <size of direct block>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5HF_dblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra, (size_t)extra2);
+
+ } else if(!HDmemcmp(sig, H5HF_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fractal heap indirect block.
+ */
+
+ /* Check for enough valid parameters */
+ if(extra == 0 || extra2 == 0) {
+ HDfprintf(stderr, "ERROR: Need fractal heap header address and number of rows in order to dump indirect block\n");
+ HDfprintf(stderr, "Fractal heap indirect block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <indirect block address> <heap header address> <number of rows>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5HF_iblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra, (unsigned)extra2);
+
+ } else if(!HDmemcmp(sig, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a free space header.
+ */
+
+ status = H5FS_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL);
+
+ } else if(!HDmemcmp(sig, H5FS_SINFO_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug free space serialized sections.
+ */
+
+ /* Check for enough valid parameters */
+ if(extra == 0 || extra2 == 0) {
+ HDfprintf(stderr, "ERROR: Need free space header address and client address in order to dump serialized sections\n");
+ HDfprintf(stderr, "Free space serialized sections usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <serialized sections address> <free space header address> <client address>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5FS_sects_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra, extra2);
+
+ } else if(!HDmemcmp(sig, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug shared message master table.
+ */
+
+ status = H5SM_table_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, (unsigned) UFAIL, (unsigned) UFAIL);
+
+ } else if(!HDmemcmp(sig, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug shared message list index.
+ */
+
+ /* Check for enough valid parameters */
+ if(extra == 0) {
+ HDfprintf(stderr, "ERROR: Need shared message header address in order to shared message list\n");
+ HDfprintf(stderr, "Shared message list usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <shared message list address> <shared message header address>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5SM_list_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, (haddr_t)extra);
+
+ } else if(!HDmemcmp(sig, H5EA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug an extensible aray header.
+ */
+ const H5EA_class_t *cls = get_H5EA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if(extra == 0) {
+ HDfprintf(stderr, "ERROR: Need object header address containing the layout message in order to dump header\n");
+ HDfprintf(stderr, "Extensible array header block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <Extensible Array header address> <object header address>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5EA__hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra);
+
+ } else if(!HDmemcmp(sig, H5EA_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug an extensible aray index block.
+ */
+ const H5EA_class_t *cls = get_H5EA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if(extra == 0 || extra2 == 0) {
+ HDfprintf(stderr, "ERROR: Need extensible array header address and object header address containing the layout message in order to dump index block\n");
+ HDfprintf(stderr, "Extensible array index block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <index block address> <array header address> <object header address\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5EA__iblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, extra2);
+
+ } else if(!HDmemcmp(sig, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug an extensible aray super block.
+ */
+ const H5EA_class_t *cls = get_H5EA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if(extra == 0 || extra2 == 0 || extra3 == 0) {
+ HDfprintf(stderr, "ERROR: Need extensible array header address, super block index and object header address containing the layout message in order to dump super block\n");
+ HDfprintf(stderr, "Extensible array super block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <super block address> <array header address> <super block index> <object header address>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5EA__sblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, extra3);
+
+ } else if(!HDmemcmp(sig, H5EA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug an extensible aray data block.
+ */
+ const H5EA_class_t *cls = get_H5EA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if(extra == 0 || extra2 == 0 || extra3 == 0) {
+ HDfprintf(stderr, "ERROR: Need extensible array header address, # of elements in data block and object header address containing the layout message in order to dump data block\n");
+ HDfprintf(stderr, "Extensible array data block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <data block address> <array header address> <# of elements in data block> <object header address\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5EA__dblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (size_t)extra2, extra3);
+
+ } else if(!HDmemcmp(sig, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fixed array header.
+ */
+ const H5FA_class_t *cls = get_H5FA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if(extra == 0) {
+ HDfprintf(stderr, "ERROR: Need object header address containing the layout message in order to dump header\n");
+ HDfprintf(stderr, "Fixed array header block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <Fixed Array header address> <object header address>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5FA__hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra);
+
+ } else if(!HDmemcmp(sig, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fixed array data block.
+ */
+ const H5FA_class_t *cls = get_H5FA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if(extra == 0 || extra2 == 0) {
+ HDfprintf(stderr, "ERROR: Need fixed array header address and object header address containing the layout message in order to dump data block\n");
+ HDfprintf(stderr, "fixed array data block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <data block address> <array header address> <object header address>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5FA__dblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, extra2);
+
+ } else if(!HDmemcmp(sig, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug v2 object header (which have signatures).
+ */
+
+ status = H5O_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL);
+
+ } else if(sig[0] == H5O_VERSION_1) {
+ /*
+ * This could be a v1 object header. Since they don't have a signature
+ * it's a somewhat "ify" detection.
+ */
+ status = H5O_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL);
+
+ } else {
+ /*
+ * Got some other unrecognized signature.
+ */
+ printf("%-*s ", VCOL, "Signature:");
+ for (u = 0; u < sizeof(sig); u++) {
+ if (sig[u] > ' ' && sig[u] <= '~' && '\\' != sig[u])
+ HDputchar(sig[u]);
+ else if ('\\' == sig[u]) {
+ HDputchar('\\');
+ HDputchar('\\');
+ } else
+ printf("\\%03o", sig[u]);
+ }
+ HDputchar('\n');
+
+ HDfprintf(stderr, "unknown signature\n");
+ HDexit(4);
+ } /* end else */
+
+ /* Check for an error when dumping information */
+ if(status < 0) {
+ HDfprintf(stderr, "An error occurred!\n");
+ H5Eprint2(H5E_DEFAULT, stderr);
+ HDexit(5);
+ } /* end if */
+
+ H5Pclose(fapl);
+ H5Fclose(fid);
+
+ H5Eset_auto2(H5E_DEFAULT, func, edata);
+
+ return 0;
+} /* main() */
+
diff --git a/tools/src/misc/h5mkgrp.c b/tools/src/misc/h5mkgrp.c
new file mode 100644
index 0000000..ad2d306
--- /dev/null
+++ b/tools/src/misc/h5mkgrp.c
@@ -0,0 +1,336 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+#include <string.h>
+#include <stdlib.h>
+
+/* Name of tool */
+#define PROGRAMNAME "h5mkgrp"
+
+/* Exit status for tools library routines */
+int d_status = EXIT_SUCCESS;
+
+/* command-line options: short and long-named parameters */
+static const char *s_opts = "hlpvV";
+static struct long_options l_opts[] = {
+ { "help", no_arg, 'h' },
+ { "latest", no_arg, 'l' },
+ { "parents", no_arg, 'p' },
+ { "verbose", no_arg, 'v' },
+ { "version", no_arg, 'V' },
+ { NULL, 0, '\0' }
+};
+
+/* Command line parameter settings */
+typedef struct {
+ char *fname; /* File name to operate on */
+ hbool_t latest; /* Whether file should use latest format versions */
+ hbool_t verbose; /* Whether output should be verbose */
+ hbool_t parents; /* Whether to create intermediate groups */
+ size_t ngroups; /* Number of groups to create */
+ char **groups; /* Pointer to array of group names */
+} param_t;
+param_t params; /* Command line parameter settings */
+
+
+/*-------------------------------------------------------------------------
+ * Function: leave
+ *
+ * Purpose: Shutdown MPI and/or HDF5 and call exit()
+ *
+ * Return: Does not return
+ *
+ * Programmer: Quincey Koziol, 2/13/2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+leave(int ret)
+{
+ size_t curr_group;
+
+ if (params.fname)
+ HDfree (params.fname);
+ if (params.ngroups) {
+ for(curr_group = 0; curr_group < params.ngroups; curr_group++)
+ HDfree (params.groups[curr_group]);
+ HDfree (params.groups);
+ }
+ h5tools_close();
+ HDexit(ret);
+} /* end leave() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Prints a usage message on stderr and then returns.
+ *
+ * Return: void
+ *
+ * Programmer: Quincey Koziol, 2/13/2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage(void)
+{
+ HDfprintf(stdout, "\
+usage: h5mkgrp [OPTIONS] FILE GROUP...\n\
+ OPTIONS\n\
+ -h, --help Print a usage message and exit\n\
+ -l, --latest Use latest version of file format to create groups\n\
+ -p, --parents No error if existing, make parent groups as needed\n\
+ -v, --verbose Print information about OBJECTS and OPTIONS\n\
+ -V, --version Print version number and exit\n");
+} /* end usage() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parses command line and sets up global variable to control output
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol, 2/13/2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+parse_command_line(int argc, const char *argv[], param_t *parms)
+{
+ int opt; /* Option from command line */
+ size_t curr_group; /* Current group name to copy */
+
+ /* Check for empty command line */
+ if(argc == 1) {
+ usage();
+ leave(EXIT_SUCCESS);
+ } /* end if */
+
+ /* Parse command line options */
+ while((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
+ switch((char)opt) {
+ /* Display 'help' */
+ case 'h':
+ usage();
+ leave(EXIT_SUCCESS);
+
+ /* Create objects with the latest version of the format */
+ case 'l':
+ parms->latest = TRUE;
+ break;
+
+ /* Create parent groups */
+ case 'p':
+ parms->parents = TRUE;
+ break;
+
+ /* Verbose output */
+ case 'v':
+ parms->verbose = TRUE;
+ break;
+
+ /* Display version */
+ case 'V':
+ print_version(h5tools_getprogname());
+ leave(EXIT_SUCCESS);
+
+ /* Bad command line argument */
+ default:
+ usage();
+ leave(EXIT_FAILURE);
+ } /* end switch */
+ } /* end while */
+
+ /* Check for file name to be processed */
+ if(argc <= opt_ind) {
+ error_msg("missing file name\n");
+ usage();
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Retrieve file name */
+ parms->fname = HDstrdup(argv[opt_ind]);
+ opt_ind++;
+
+ /* Check for group(s) to be created */
+ if(argc <= opt_ind) {
+ error_msg("missing group name(s)\n");
+ usage();
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Allocate space for the group name pointers */
+ parms->ngroups = (size_t)(argc - opt_ind);
+ parms->groups = (char **)HDmalloc(parms->ngroups * sizeof(char *));
+
+ /* Retrieve the group names */
+ curr_group = 0;
+ while(opt_ind < argc) {
+ parms->groups[curr_group] = HDstrdup(argv[opt_ind]);
+ curr_group++;
+ opt_ind++;
+ } /* end while */
+
+#ifdef QAK
+HDfprintf(stderr, "parms->parents = %t\n", parms->parents);
+HDfprintf(stderr, "parms->verbose = %t\n", parms->verbose);
+HDfprintf(stderr, "parms->fname = '%s'\n", parms->fname);
+HDfprintf(stderr, "parms->ngroups = %Zu\n", parms->ngroups);
+for(curr_group = 0; curr_group < parms->ngroups; curr_group++)
+ HDfprintf(stderr, "parms->group[%Zu] = '%s'\n", curr_group, parms->groups[curr_group]);
+#endif /* QAK */
+
+ return(0);
+} /* parse_command_line() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Create group(s) in an HDF5 file
+ *
+ * Programmer: Quincey Koziol, 2/13/2007
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, const char *argv[])
+{
+ hid_t fid; /* HDF5 file ID */
+ hid_t fapl_id; /* File access property list ID */
+ hid_t lcpl_id; /* Link creation property list ID */
+ size_t curr_group; /* Current group to create */
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Disable the HDF5 library's error reporting */
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /* Parse command line */
+ HDmemset(&params, 0, sizeof(params));
+ if(parse_command_line(argc, argv, &params) < 0) {
+ error_msg("unable to parse command line arguments\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Create file access property list */
+ if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
+ error_msg("Could not create file access property list\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Check for creating groups with new format version */
+ if(params.latest) {
+ /* Set the "use the latest version of the format" bounds */
+ if(H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) {
+ error_msg("Could not set property for using latest version of the format\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Display some output if requested */
+ if(params.verbose)
+ printf("%s: Creating groups with latest version of the format\n", h5tools_getprogname());
+ } /* end if */
+
+ /* Attempt to open an existing HDF5 file first */
+ fid = h5tools_fopen(params.fname, H5F_ACC_RDWR, fapl_id, NULL, NULL, 0);
+
+ /* If we couldn't open an existing file, try creating file */
+ /* (use "EXCL" instead of "TRUNC", so we don't blow away existing non-HDF5 file) */
+ if(fid < 0)
+ fid = H5Fcreate(params.fname, H5F_ACC_EXCL, H5P_DEFAULT, fapl_id);
+
+ /* Test for error in opening file */
+ if(fid < 0) {
+ error_msg("Could not open output file '%s'\n", params.fname);
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Create link creation property list */
+ if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) {
+ error_msg("Could not create link creation property list\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Check for creating intermediate groups */
+ if(params.parents) {
+ /* Set the intermediate group creation property */
+ if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) {
+ error_msg("Could not set property for creating parent groups\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Display some output if requested */
+ if(params.verbose)
+ printf("%s: Creating parent groups\n", h5tools_getprogname());
+ } /* end if */
+
+ /* Loop over creating requested groups */
+ for(curr_group = 0; curr_group < params.ngroups; curr_group++) {
+ hid_t gid; /* Group ID */
+
+ /* Attempt to create a group */
+ if((gid = H5Gcreate2(fid, params.groups[curr_group], lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
+ error_msg("Could not create group '%s'\n", params.groups[curr_group]);
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Close the group */
+ if(H5Gclose(gid) < 0) {
+ error_msg("Could not close group '%s'??\n", params.groups[curr_group]);
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Display some output if requested */
+ if(params.verbose)
+ printf("%s: created group '%s'\n", h5tools_getprogname(), params.groups[curr_group]);
+ } /* end for */
+
+ /* Close link creation property list */
+ if(H5Pclose(lcpl_id) < 0) {
+ error_msg("Could not close link creation property list\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) {
+ error_msg("Could not close output file '%s'??\n", params.fname);
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Close file access property list */
+ if(H5Pclose(fapl_id) < 0) {
+ error_msg("Could not close file access property list\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Shut down h5tools lib */
+ h5tools_close();
+
+ leave(EXIT_SUCCESS);
+} /* end main() */
+
diff --git a/tools/src/misc/h5redeploy.in b/tools/src/misc/h5redeploy.in
new file mode 100644
index 0000000..6b6ef87
--- /dev/null
+++ b/tools/src/misc/h5redeploy.in
@@ -0,0 +1,218 @@
+#! /bin/sh
+#
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic HDF5 document set and
+# is linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from help@hdfgroup.org.
+#
+
+## Update HDF5 compiler tools after the HDF5 software has been installed ##
+## in a new location. ##
+## For help page, use "h5redeploy -help" ##
+## ##
+
+# Constants definitions
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+# Function definitions
+
+# show help page
+usage() {
+ # A wonderfully informative "usage" message.
+ echo "usage: $prog_name [OPTIONS]"
+ echo " OPTIONS:"
+ echo " -help|help This help message"
+ echo " -echo Show all the shell commands executed"
+ echo " -force No prompt, just do it"
+ echo " -prefix=DIR New directory to find HDF5 lib/ and include/"
+ echo " subdirectories [default: current directory]"
+ echo " -exec-prefix=DIR New directory to find HDF5 lib/"
+ echo " subdirectory [default: <prefix>]"
+ echo " -libdir=DIR New directory for the HDF5 lib directory"
+ echo " [default: <exec-prefix>/lib]"
+ echo " -includedir=DIR New directory for the HDF5 header files"
+ echo " [default: <prefix>/include]"
+ echo " -tool=TOOL Tool to update. TOOL must be in the current"
+ echo " directory and writable. [default: $h5tools]"
+ echo " -show Show the commands without executing them"
+ echo " "
+ exit $EXIT_FAILURE
+}
+
+# display variable values
+dump_vars(){
+ echo "====Showing all variable values====="
+ echo prefix=$prefix
+ echo h5tools=$h5tools
+ echo "====End Showing====="
+}
+
+# show actions to be taken
+show_action()
+{
+ echo "Update the following tools because they are now installed at a new directory"
+ for t in $foundtools; do
+ echo "${t}:"
+ echo " current setting=`sed -e '/^prefix=/s/prefix=//p' -e d $t`"
+ echo " new setting="\""$prefix"\"
+ done
+}
+
+
+# Report Error message
+ERROR()
+{
+ echo "***ERROR***"
+ echo "$1"
+}
+
+# Main
+#
+############################################################################
+## Installation directories: ##
+## prefix architecture-independent files. ##
+## exec_prefix architecture-dependent files, default is <prefix>. ##
+## libdir libraries, default is <exec_prefix>/lib. ##
+## includedir header files, default is <prefix/include>. ##
+## Not used here: ##
+## bindir executables, <exec_prefix/bin>. ##
+############################################################################
+# Initialization
+h5tools="h5cc h5pcc h5fc h5pfc h5c++" # possible hdf5 tools
+foundtools= # tools found and will be modified
+fmode= # force mode, default is off
+prefix=
+exec_prefix=
+libdir=
+includedir=
+
+# Parse options
+for arg in $@ ; do
+ case "$arg" in
+ -prefix=*)
+ prefix="`echo $arg | cut -f2 -d=`"
+ ;;
+ -exec-prefix=*)
+ exec_prefix="`echo $arg | cut -f2 -d=`"
+ ;;
+ -libdir=*)
+ libdir="`echo $arg | cut -f2 -d=`"
+ ;;
+ -includedir=*)
+ includedir="`echo $arg | cut -f2 -d=`"
+ ;;
+ -echo)
+ set -x
+ ;;
+ -show)
+ SHOW="echo"
+ ;;
+ -tool=*)
+ h5tools="`echo $arg | cut -f2 -d=`"
+ ;;
+ -help|help)
+ usage
+ ;;
+ -force)
+ fmode=yes
+ ;;
+ *)
+ ERROR "Unknown Option($arg)"
+ usage
+ exit $EXIT_FAILURE
+ ;;
+ esac
+done
+
+# Set to default value, one above where i am, if not given by user
+if [ -z "$prefix" ]; then
+ prefix=`(cd ..;pwd)`
+fi
+if [ -z "$exec_prefix" ]; then
+ exec_prefix='${prefix}' # use single quotes to prevent expansion of $
+fi
+if [ -z "$libdir" ]; then
+ libdir='${exec_prefix}'/lib # use single quotes to prevent expansion of $
+fi
+if [ -z "$includedir" ]; then
+ includedir='${prefix}'/include # use single quotes to prevent expansion of $
+fi
+
+for x in $h5tools; do
+ if [ -f $x ]; then
+ foundtools="$foundtools $x"
+ if [ ! -w $x ]; then
+ ERROR "h5tool($x) is not writable"
+ exit $EXIT_FAILURE
+ fi
+ fi
+done
+
+if [ -z "$foundtools" ]; then
+ ERROR "found no tools to modify"
+ exit $EXIT_FAILURE
+fi
+
+# Show actions to be taken and get consent
+show_action
+# Ask confirmation unless fmode is on
+if [ x-$fmode = x- ]; then
+ echo "Continue? (yes/no)"
+ read ansx
+ ans=`echo $ansx | tr "[A-Z]" "[a-z]"`
+ if [ x-$ans != x-yes ]; then
+ echo ABORT. No tools changed.
+ exit $EXIT_FAILURE
+ fi
+fi
+
+
+# Create the update commands
+CMDFILE=/tmp/h5redeploy.$$
+touch $CMDFILE
+chmod 0600 $CMDFILE
+echo "/^prefix=/c" >> $CMDFILE
+echo prefix=\""$prefix"\" >> $CMDFILE
+echo . >> $CMDFILE
+echo "/^exec_prefix=/c" >> $CMDFILE
+echo exec_prefix=\""$exec_prefix"\" >> $CMDFILE
+echo . >> $CMDFILE
+echo "/^libdir=/c" >> $CMDFILE
+echo libdir=\""$libdir"\" >> $CMDFILE
+echo . >> $CMDFILE
+echo "/^includedir=/c" >> $CMDFILE
+echo includedir=\""$includedir"\" >> $CMDFILE
+echo . >> $CMDFILE
+(echo w; echo q) >> $CMDFILE
+
+
+# Update them
+if [ "$SHOW" = "echo" ]; then
+ echo "===Update commands are:===="
+ cat $CMDFILE
+ echo "===End Update commands====="
+fi
+
+for t in $foundtools; do
+ echo Update $t ...
+ COMMAND="ed - $t"
+ if [ "$SHOW" = "echo" ]; then
+ echo $COMMAND
+ else
+ $COMMAND < $CMDFILE
+ fi
+done
+
+
+# Cleanup
+rm -f $CMDFILE
+exit $EXIT_SUCCESS
diff --git a/tools/src/misc/h5repart.c b/tools/src/misc/h5repart.c
new file mode 100644
index 0000000..e44c957
--- /dev/null
+++ b/tools/src/misc/h5repart.c
@@ -0,0 +1,510 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Wednesday, May 13, 1998
+ *
+ * Purpose: Repartitions a file family. This program can be used to
+ * split a single file into a family of files, join a family of
+ * files into a single file, or copy one family to another while
+ * changing the size of the family members. It can also be used
+ * to copy a single file to a single file with holes.
+ */
+
+/* See H5private.h for how to include system headers */
+#include "hdf5.h"
+#include "H5private.h"
+#ifdef H5_STDC_HEADERS
+# include <ctype.h>
+# include <errno.h>
+# include <fcntl.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+#endif
+
+#ifdef H5_HAVE_UNISTD_H
+# include <sys/types.h>
+# include <unistd.h>
+#endif
+
+#ifdef H5_HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+#ifndef TRUE
+# define TRUE 1
+#endif
+# define NAMELEN 4096
+#define GB *1024*1024*1024
+
+#ifndef MIN
+# define MIN(X,Y) ((X)<(Y)?(X):(Y))
+#endif
+#ifndef MIN3
+# define MIN3(X,Y,Z) MIN(MIN(X,Y),Z)
+#endif
+
+/*Make these 2 private properties(defined in H5Fprivate.h) available to h5repart.
+ *The first one updates the member file size in the superblock. The second one
+ *change file driver from family to sec2. */
+#define H5F_ACS_FAMILY_NEWSIZE_NAME "family_newsize"
+#define H5F_ACS_FAMILY_TO_SEC2_NAME "family_to_sec2"
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Prints a usage message.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, May 13, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage (const char *progname)
+{
+ fprintf(stderr, "usage: %s [-v] [-V] [-[b|m] N[g|m|k]] [-family_to_sec2] SRC DST\n",
+ progname);
+ fprintf(stderr, " -v Produce verbose output\n");
+ fprintf(stderr, " -V Print a version number and exit\n");
+ fprintf(stderr, " -b N The I/O block size, defaults to 1kB\n");
+ fprintf(stderr, " -m N The destination member size or 1GB\n");
+ fprintf(stderr, " -family_to_sec2 Change file driver from family to sec2\n");
+ fprintf(stderr, " SRC The name of the source file\n");
+ fprintf(stderr, " DST The name of the destination files\n");
+ fprintf(stderr, "Sizes may be suffixed with `g' for GB, `m' for MB or "
+ "`k' for kB.\n");
+ fprintf(stderr, "File family names include an integer printf "
+ "format such as `%%d'\n");
+ exit (EXIT_FAILURE);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_size
+ *
+ * Purpose: Reads a size option of the form `-XNS' where `X' is any
+ * letter, `N' is a multi-character positive decimal number, and
+ * `S' is an optional suffix letter in the set [GgMmk]. The
+ * option may also be split among two arguments as: `-X NS'.
+ * The input value of ARGNO is the argument number for the
+ * switch in the ARGV vector and ARGC is the number of entries
+ * in that vector.
+ *
+ * Return: Success: The value N multiplied according to the
+ * suffix S. On return ARGNO will be the number
+ * of the next argument to process.
+ *
+ * Failure: Calls usage() which exits with a non-zero
+ * status.
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, May 13, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static off_t
+get_size (const char *progname, int *argno, int argc, char *argv[])
+{
+ off_t retval=-1;
+ char *suffix;
+
+ if (isdigit ((int)(argv[*argno][2]))) {
+ retval = strtol (argv[*argno]+2, &suffix, 10);
+ (*argno)++;
+ } else if (argv[*argno][2] || *argno+1>=argc) {
+ usage (progname);
+ } else {
+ retval = strtol (argv[*argno+1], &suffix, 0);
+ if (suffix==argv[*argno+1]) usage (progname);
+ *argno += 2;
+ }
+ if (suffix && suffix[0] && !suffix[1]) {
+ switch (*suffix) {
+ case 'G':
+ case 'g':
+ retval *= 1024 * 1024 * 1024;
+ break;
+ case 'M':
+ case 'm':
+ retval *= 1024 * 1024;
+ break;
+ case 'k':
+ retval *= 1024;
+ break;
+ default:
+ usage (progname);
+ }
+ } else if (suffix && suffix[0]) {
+ usage (progname);
+ }
+ return retval;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Split an hdf5 file
+ *
+ * Return: Success:
+ *
+ * Failure:
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, May 13, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main (int argc, char *argv[])
+{
+ const char *prog_name; /*program name */
+ size_t blk_size=1024; /*size of each I/O block */
+ char *buf=NULL; /*I/O block buffer */
+ size_t n, i; /*counters */
+ ssize_t nio; /*I/O return value */
+ int argno=1; /*program argument number */
+ int src, dst=-1; /*source & destination files */
+ int need_seek=FALSE; /*destination needs to seek? */
+ int need_write; /*data needs to be written? */
+ h5_stat_t sb; /*temporary file stat buffer */
+
+ int verbose=FALSE; /*display file names? */
+
+ const char *src_gen_name; /*general source name */
+ char *src_name=NULL; /*source member name */
+
+ int src_is_family; /*is source name a family name? */
+ int src_membno=0; /*source member number */
+
+ const char *dst_gen_name; /*general destination name */
+ char *dst_name=NULL; /*destination member name */
+ int dst_is_family; /*is dst name a family name? */
+ int dst_membno=0; /*destination member number */
+
+ off_t left_overs=0; /*amount of zeros left over */
+ off_t src_offset=0; /*offset in source member */
+ off_t dst_offset=0; /*offset in destination member */
+ off_t src_size; /*source logical member size */
+ off_t src_act_size; /*source actual member size */
+ off_t dst_size=1 GB; /*destination logical memb size */
+ hid_t fapl; /*file access property list */
+ hid_t file;
+ hsize_t hdsize; /*destination logical memb size */
+ hbool_t family_to_sec2=FALSE; /*change family to sec2 driver? */
+
+ /*
+ * Get the program name from argv[0]. Use only the last component.
+ */
+ if ((prog_name=strrchr (argv[0], '/'))) prog_name++;
+ else prog_name = argv[0];
+
+ /*
+ * Parse switches.
+ */
+ while (argno<argc && '-'==argv[argno][0]) {
+ if (!strcmp (argv[argno], "-v")) {
+ verbose = TRUE;
+ argno++;
+ } else if (!strcmp(argv[argno], "-V")) {
+ printf("This is %s version %u.%u release %u\n",
+ prog_name, H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE);
+ exit(EXIT_SUCCESS);
+ } else if (!strcmp (argv[argno], "-family_to_sec2")) {
+ family_to_sec2 = TRUE;
+ argno++;
+ } else if ('b'==argv[argno][1]) {
+ blk_size = (size_t)get_size (prog_name, &argno, argc, argv);
+ } else if ('m'==argv[argno][1]) {
+ dst_size = get_size (prog_name, &argno, argc, argv);
+ } else {
+ usage (prog_name);
+ } /* end if */
+ } /* end while */
+
+ /* allocate names */
+ if(NULL == (src_name = (char *)HDcalloc((size_t)NAMELEN, sizeof(char))))
+ exit(EXIT_FAILURE);
+ if(NULL == (dst_name = (char *)HDcalloc((size_t)NAMELEN, sizeof(char))))
+ exit(EXIT_FAILURE);
+
+ /*
+ * Get the name for the source file and open the first member. The size
+ * of the first member determines the logical size of all the members.
+ */
+ if (argno>=argc) usage (prog_name);
+ src_gen_name = argv[argno++];
+ sprintf (src_name, src_gen_name, src_membno);
+ src_is_family = strcmp (src_name, src_gen_name);
+
+ if ((src=HDopen(src_name, O_RDONLY,0))<0) {
+ perror (src_name);
+ exit (EXIT_FAILURE);
+ }
+
+ if (HDfstat(src, &sb)<0) {
+ perror ("fstat");
+ exit (EXIT_FAILURE);
+ }
+ src_size = src_act_size = sb.st_size;
+ if (verbose) fprintf (stderr, "< %s\n", src_name);
+
+ /*
+ * Get the name for the destination file and open the first member.
+ */
+ if (argno>=argc) usage (prog_name);
+ dst_gen_name = argv[argno++];
+ sprintf (dst_name, dst_gen_name, dst_membno);
+ dst_is_family = strcmp (dst_name, dst_gen_name);
+
+ if ((dst=HDopen (dst_name, O_RDWR|O_CREAT|O_TRUNC, 0666))<0) {
+ perror (dst_name);
+ exit (EXIT_FAILURE);
+ }
+ if (verbose) fprintf (stderr, "> %s\n", dst_name);
+
+ /* No more arguments */
+ if (argno<argc) usage (prog_name);
+
+ /* Now the real work, split the file */
+ buf = (char *)HDmalloc(blk_size);
+ while (src_offset<src_size) {
+
+ /* Read a block. The amount to read is the minimum of:
+ * 1. The I/O block size
+ * 2. What's left to write in the destination member
+ * 3. Left over zeros or what's left in the source member.
+ */
+ n = blk_size;
+ if (dst_is_family) n = (size_t)MIN((off_t)n, dst_size-dst_offset);
+ if (left_overs) {
+ n = (size_t)MIN ((off_t)n, left_overs);
+ left_overs = left_overs - (off_t)n;
+ need_write = FALSE;
+ } else if (src_offset<src_act_size) {
+ n = (size_t)MIN ((off_t)n, src_act_size-src_offset);
+ if ((nio=HDread (src, buf, n))<0) {
+ perror ("read");
+ exit (EXIT_FAILURE);
+ } else if ((size_t)nio!=n) {
+ fprintf (stderr, "%s: short read\n", src_name);
+ exit (EXIT_FAILURE);
+ }
+ for (i=0; i<n; i++) {
+ if (buf[i]) break;
+ }
+ need_write = (i<n);
+ } else {
+ n = 0;
+ left_overs = src_size - src_act_size;
+ need_write = FALSE;
+ }
+
+ /*
+ * If the block contains non-zero data then write it to the
+ * destination, otherwise just remember that we'll have to do a seek
+ * later in the destination when we finally get non-zero data.
+ */
+ if (need_write) {
+ if (need_seek && HDlseek (dst, dst_offset, SEEK_SET)<0) {
+ perror ("HDlseek");
+ exit (EXIT_FAILURE);
+ }
+ if ((nio=HDwrite (dst, buf, n))<0) {
+ perror ("write");
+ exit (EXIT_FAILURE);
+ } else if ((size_t)nio!=n) {
+ fprintf (stderr, "%s: short write\n", dst_name);
+ exit (EXIT_FAILURE);
+ }
+ need_seek = FALSE;
+ } else {
+ need_seek = TRUE;
+ }
+
+ /*
+ * Update the source offset and open the next source family member if
+ * necessary. The source stream ends at the first member which
+ * cannot be opened because it doesn't exist. At the end of the
+ * source stream, update the destination offset and break out of the
+ * loop. The destination offset must be updated so we can fix
+ * trailing holes.
+ */
+ src_offset = src_offset + (off_t)n;
+ if (src_offset==src_act_size) {
+ HDclose (src);
+ if (!src_is_family) {
+ dst_offset = dst_offset + (off_t)n;
+ break;
+ }
+ sprintf (src_name, src_gen_name, ++src_membno);
+ if ((src=HDopen (src_name, O_RDONLY,0))<0 && ENOENT==errno) {
+ dst_offset = dst_offset + (off_t)n;
+ break;
+ } else if (src<0) {
+ perror (src_name);
+ exit (EXIT_FAILURE);
+ }
+ if (HDfstat (src, &sb)<0) {
+ perror ("fstat");
+ exit (EXIT_FAILURE);
+ }
+ src_act_size = sb.st_size;
+ if (src_act_size>src_size) {
+ fprintf (stderr, "%s: member truncated to %lu bytes\n",
+ src_name, (unsigned long)src_size);
+ }
+ src_offset = 0;
+ if (verbose) fprintf (stderr, "< %s\n", src_name);
+ }
+
+ /*
+ * Update the destination offset, opening a new member if one will be
+ * needed. The first member is extended to the logical member size
+ * but other members might be smaller if they end with a hole.
+ */
+ dst_offset = dst_offset + (off_t)n;
+ if (dst_is_family && dst_offset==dst_size) {
+ if (0==dst_membno) {
+ if (HDlseek (dst, dst_size-1, SEEK_SET)<0) {
+ perror ("HDHDlseek");
+ exit (EXIT_FAILURE);
+ }
+ if (HDread (dst, buf, 1)<0) {
+ perror ("read");
+ exit (EXIT_FAILURE);
+ }
+ if (HDlseek (dst, dst_size-1, SEEK_SET)<0) {
+ perror ("HDlseek");
+ exit (EXIT_FAILURE);
+ }
+ if (HDwrite (dst, buf, 1)<0) {
+ perror ("write");
+ exit (EXIT_FAILURE);
+ }
+ }
+ HDclose (dst);
+ sprintf (dst_name, dst_gen_name, ++dst_membno);
+ if ((dst=HDopen (dst_name, O_RDWR|O_CREAT|O_TRUNC, 0666))<0) {
+ perror (dst_name);
+ exit (EXIT_FAILURE);
+ }
+ dst_offset = 0;
+ need_seek = FALSE;
+ if (verbose) fprintf (stderr, "> %s\n", dst_name);
+ }
+ }
+
+ /*
+ * Make sure the last family member is the right size and then close it.
+ * The last member can't end with a hole or hdf5 will think that the
+ * family has been truncated.
+ */
+ if (need_seek) {
+ if (HDlseek (dst, dst_offset-1, SEEK_SET)<0) {
+ perror ("HDlseek");
+ exit (EXIT_FAILURE);
+ }
+ if (HDread (dst, buf, 1)<0) {
+ perror ("read");
+ exit (EXIT_FAILURE);
+ }
+ if (HDlseek (dst, dst_offset-1, SEEK_SET)<0) {
+ perror ("HDlseek");
+ exit (EXIT_FAILURE);
+ }
+ if (HDwrite (dst, buf, 1)<0) {
+ perror ("write");
+ exit (EXIT_FAILURE);
+ }
+ }
+ HDclose (dst);
+
+ /* Modify family driver information saved in superblock through private property.
+ * These private properties are for this tool only. */
+ if ((fapl=H5Pcreate(H5P_FILE_ACCESS))<0) {
+ perror ("H5Pcreate");
+ exit (EXIT_FAILURE);
+ }
+
+ if(family_to_sec2) {
+ /* The user wants to change file driver from family to sec2. Open the file
+ * with sec2 driver. This property signals the library to ignore the family
+ * driver information saved in the superblock. */
+ if(H5Pset(fapl, H5F_ACS_FAMILY_TO_SEC2_NAME, &family_to_sec2) < 0) {
+ perror ("H5Pset");
+ exit (EXIT_FAILURE);
+ }
+ } else {
+ /* Modify family size saved in superblock through private property. It signals
+ * library to save the new member size(specified in command line) in superblock.
+ * This private property is for this tool only. */
+ if(H5Pset_fapl_family(fapl, H5F_FAMILY_DEFAULT, H5P_DEFAULT) < 0) {
+ perror ("H5Pset_fapl_family");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Set the property of the new member size as hsize_t */
+ hdsize = (hsize_t)dst_size;
+ if(H5Pset(fapl, H5F_ACS_FAMILY_NEWSIZE_NAME, &hdsize) < 0) {
+ perror ("H5Pset");
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ /* If the new file is a family file, try to open file for "read and write" to
+ * flush metadata. Flushing metadata will update the superblock to the new
+ * member size. If the original file is a family file and the new file is a sec2
+ * file, the property FAMILY_TO_SEC2 will signal the library to switch to sec2
+ * driver when the new file is opened. If the original file is a sec2 file and the
+ * new file can only be a sec2 file, reopen the new file should fail. There's
+ * nothing to do in this case. */
+ H5E_BEGIN_TRY {
+ file=H5Fopen(dst_gen_name, H5F_ACC_RDWR, fapl);
+ } H5E_END_TRY;
+
+ if(file>=0) {
+ if(H5Fclose(file)<0) {
+ perror ("H5Fclose");
+ exit (EXIT_FAILURE);
+ } /* end if */
+ } /* end if */
+
+ if(H5Pclose(fapl)<0) {
+ perror ("H5Pclose");
+ exit (EXIT_FAILURE);
+ } /* end if */
+
+ /* Free resources and return */
+ HDfree(src_name);
+ HDfree(dst_name);
+ HDfree(buf);
+ return EXIT_SUCCESS;
+} /* end main */