From d0739f13c131fd8d85c4b3247c26ca2bca515ece Mon Sep 17 00:00:00 2001 From: Larry Knox Date: Tue, 26 Jul 2022 14:30:04 -0500 Subject: Revert "1.12 eliminate unnecessary errors in the error stack (#1880)" (#1935) This reverts commit f6997681335f0b5fe2e8904f9108a71c5200fb2d. --- CODE_OF_CONDUCT.md | 128 +++ autogen.sh | 5 +- config/sanitizer/code-coverage.cmake | 10 +- configure.ac | 3 +- doxygen/dox/ReferenceManual.dox | 31 +- doxygen/dox/high_level/extension.dox | 654 +++++++++++++++ doxygen/dox/high_level/high_level.dox | 29 + doxygen/examples/H5DO_examples.c | 220 +++++ doxygen/examples/H5LDget_dset_elmts.c | 143 ++++ doxygen/examples/H5LT_examples.c | 27 + doxygen/examples/H5TBAget_fill.c | 43 + hl/src/H5DOpublic.h | 198 +++++ hl/src/H5DSpublic.h | 357 +++++++- hl/src/H5IMpublic.h | 292 +++++++ hl/src/H5LDpublic.h | 138 +++ hl/src/H5LTpublic.h | 1400 ++++++++++++++++++++++++++++++- hl/src/H5PTpublic.h | 415 +++++++++ hl/src/H5TBpublic.h | 543 ++++++++++++ java/src/hdf/hdf5lib/H5.java | 50 +- java/src/hdf/hdf5lib/HDF5Constants.java | 65 +- java/src/jni/h5aImp.c | 818 +++++++++++++++--- java/src/jni/h5aImp.h | 18 +- java/src/jni/h5dImp.c | 805 +++++++++++++----- java/src/jni/h5dImp.h | 4 +- java/src/jni/h5rImp.c | 61 ++ java/src/jni/h5rImp.h | 7 + java/src/jni/h5util.c | 461 +++++++--- java/src/jni/h5util.h | 2 + java/src/jni/nativeData.c | 3 +- java/test/TestH5A.java | 243 +++++- java/test/TestH5D.java | 221 ++++- java/test/TestH5R.java | 469 +++++++++++ java/test/testfiles/JUnit-TestH5A.txt | 3 +- java/test/testfiles/JUnit-TestH5D.txt | 5 +- java/test/testfiles/JUnit-TestH5R.txt | 4 +- release_docs/RELEASE.txt | 47 +- tools/lib/h5tools_str.c | 34 +- tools/lib/h5tools_str.h | 3 +- 38 files changed, 7356 insertions(+), 603 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 doxygen/dox/high_level/extension.dox create mode 100644 doxygen/dox/high_level/high_level.dox create mode 100644 doxygen/examples/H5DO_examples.c create mode 100644 doxygen/examples/H5LDget_dset_elmts.c create mode 100644 doxygen/examples/H5LT_examples.c create mode 100644 doxygen/examples/H5TBAget_fill.c diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..b3aa7ab --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +help@hdfgroup.org. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/autogen.sh b/autogen.sh index 4676ee0..7c3cbcf 100755 --- a/autogen.sh +++ b/autogen.sh @@ -236,7 +236,10 @@ ${automake_cmd} || exit 1 echo # AUTOCONF -autoconf_cmd="${HDF5_AUTOCONF} --force" +# The "obsolete" warnings category flags our Java macros as obsolete. +# Since there is no clear way to upgrade them (Java support in the Autotools +# is not great) and they work well enough for now, we suppress those warnings. +autoconf_cmd="${HDF5_AUTOCONF} --force --warnings=no-obsolete" echo "${autoconf_cmd}" if [ "$verbose" = true ] ; then ${HDF5_AUTOCONF} --version diff --git a/config/sanitizer/code-coverage.cmake b/config/sanitizer/code-coverage.cmake index e71bfd7..3a99024 100644 --- a/config/sanitizer/code-coverage.cmake +++ b/config/sanitizer/code-coverage.cmake @@ -214,7 +214,7 @@ function(target_code_coverage TARGET_NAME) # Add code coverage instrumentation to the target's linker command if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") target_compile_options(${TARGET_NAME} PRIVATE -fprofile-instr-generate - -fcoverage-mapping) + -fcoverage-mapping --coverage) set_property( TARGET ${TARGET_NAME} APPEND_STRING @@ -225,7 +225,7 @@ function(target_code_coverage TARGET_NAME) PROPERTY LINK_FLAGS "-fcoverage-mapping ") elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") target_compile_options(${TARGET_NAME} PRIVATE -fprofile-arcs - -ftest-coverage) + -ftest-coverage --coverage) target_link_libraries(${TARGET_NAME} PRIVATE gcov) endif() @@ -413,10 +413,10 @@ endfunction() # use `target_code_coverage`. function(add_code_coverage) if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") - add_compile_options(-fprofile-instr-generate -fcoverage-mapping) - add_link_options(-fprofile-instr-generate -fcoverage-mapping) + add_compile_options(-fprofile-instr-generate -fcoverage-mapping --coverage) + add_link_options(-fprofile-instr-generate -fcoverage-mapping --coverage) elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") - add_compile_options(-fprofile-arcs -ftest-coverage) + add_compile_options(-fprofile-arcs -ftest-coverage --coverage) link_libraries(gcov) endif() endfunction() diff --git a/configure.ac b/configure.ac index d32fdd5..e3d8971 100644 --- a/configure.ac +++ b/configure.ac @@ -1366,8 +1366,9 @@ case "`uname`" in UNAME_CYGWIN="yes" ;; MINGW*) + # The Winsock library AC_CHECK_HEADERS([io.h winsock2.h sys/timeb.h]) - AC_HAVE_LIBRARY([ws2_32]) + AC_CHECK_LIB([ws2_32], [GetUserName]) ;; *) AC_CHECK_HEADERS([io.h winsock2.h sys/timeb.h]) diff --git a/doxygen/dox/ReferenceManual.dox b/doxygen/dox/ReferenceManual.dox index c477813..ad10ba1 100644 --- a/doxygen/dox/ReferenceManual.dox +++ b/doxygen/dox/ReferenceManual.dox @@ -29,23 +29,30 @@ The functions provided by the HDF5 C-API are grouped into the following \li \ref H5PL "Dynamically-loaded Plugins (H5PL)" \li \ref H5R "References (H5R)" \li \ref H5VL "Virtual Object Layer (H5VL)" - -\li Functions with \ref ASYNC "asynchronous variants" -\li \ref api-compat-macros -\li Deprecated functions -\li High-level Extensions + +\li \ref high_level -\ref H5 \ref H5A \ref H5D \ref H5E \ref H5ES \ref H5F \ref H5G \ref H5I \ref H5L +\a Core \a library: \ref H5 \ref H5A \ref H5D \ref H5E \ref H5ES \ref H5F \ref H5G \ref H5I \ref H5L \ref H5M \ref H5O \ref H5P \ref H5PL \ref H5R \ref H5S \ref H5T \ref H5VL \ref H5Z + +\a High-level \a library: \ref H5LT \ref H5IM \ref H5TB \ref H5PT \ref H5DS \ref H5DO \ref H5LR + + +Deprecated functions +Functions with \ref ASYNC +\ref api-compat-macros + @@ -86,4 +93,4 @@ Break a leg! pull request !\n See the \ref RMT for general guidance. -*/ \ No newline at end of file +*/ diff --git a/doxygen/dox/high_level/extension.dox b/doxygen/dox/high_level/extension.dox new file mode 100644 index 0000000..c81ac6e --- /dev/null +++ b/doxygen/dox/high_level/extension.dox @@ -0,0 +1,654 @@ +/** \defgroup H5LR Extensions + * + * Working with region references, hyperslab selections, + * and bit-fields (H5LR, H5LT) + * + * The following reference manual entries describe high-level HDF5 C and Fortran APIs + * for working with region references, hyperslab selections, and bit-fields. + * These functions were created as part of a project supporting + * NPP/NPOESS Data Production and Exploitation ( + * + * project , + * + * software ). + * While they were written to facilitate access to NPP, NPOESS, and JPSS + * data in the HDF5 format, these functions may be useful to anyone working + * with region references, hyperslab selections, or bit-fields. + * + * Note that these functions are not part of the standard HDF5 distribution; + * the + * + * software + * must be separately downloaded and installed. + * + * A comprehensive guide to this library, + * + * User Guide to the HDF5 High-level Library for Handling Region References and Hyperslab Selections + * is available at + * https://support.hdfgroup.org/projects/jpss/documentation/HL/UG/NPOESS_HL-UG.pdf. + * + * - \ref H5LRcopy_reference + * \n Copies data from the specified dataset to a new location and + * creates a reference to it. + * - \ref H5LRcopy_region + * \n Copies data from a referenced region to a region in a + * destination dataset. + * - \ref H5LRcreate_ref_to_all + * \n Creates a dataset with the region references to the data in all + * datasets located under a specified group in a file or creates a + * dataset with object references to all objects (groups or datasets) + * located under a specified group in a file. + * - \ref H5LRcreate_region_references + * \n Creates an array of region references using an array of paths to + * datasets and an array of corresponding hyperslab descriptions. + * - \ref H5LRget_region_info + * \n Retrieves information about the data a region reference points to. + * - \ref H5LRmake_dataset + * \n Creates and writes a dataset containing a list of + * region references. + * - \ref H5LRread_region + * \n Retrieves raw data pointed to by a region reference to + * an application buffer. + * - \ref H5LTcopy_region + * \n Copies data from a specified region in a source dataset + * to a specified region in a destination dataset. + * - \ref H5LTread_bitfield_value + * \n Retrieves the values of quality flags for each element + * to the application provided buffer. + * - \ref H5LTread_region + * \n Reads selected data to an application buffer. + * + */ + +/*------------------------------------------------------------------------- + * + * Make dataset functions + * + *------------------------------------------------------------------------- + */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Creates and writes a dataset containing a list of region references. + * + * \fgdta_loc_id + * \param[in] path Path to the dataset being created + * \param[in] type_id Datatype of the dataset + * \param[in] buf_size Size of the \p loc_id_ref and \p buf arrays + * \param[in] loc_id_ref Array of object identifiers; each identifier + * describes to which HDF5 file the corresponding + * region reference belongs to + * \param[in] buf Array of region references + * + * \return \herr_t + * + * \details Given an array of size \p buf_size of region references \p buf, + * the function will create a dataset with path \p path, at location + * specified by \p loc_id and of a datatype specified by \p type_id, + * and will write data associated with each region reference in the order + * corresponding to the order of the region references in the buffer. + * It is assumed that all referenced hyperslabs have the same dimensionality, + * and only the size of the slowest changing dimension may differ. + * Each reference in the \p buf array belongs to the file identified + * by the corresponding object identifiers in the array \p loc_id_ref. + * + * If \p path does not exist in \p loc_id then the function will + * create the path specified by \p path automatically. + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LRmake_dataset(hid_t loc_id, + const char *path, + hid_t type_id, const size_t buf_size, + const hid_t *loc_id_ref, + const hdset_reg_ref_t *buf); + +/*------------------------------------------------------------------------- + * + * Make and manipulate dataset region references functions + * + *------------------------------------------------------------------------- + */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Creates an array of region references using an array of paths to + * datasets and an array of corresponding hyperslab descriptions. + * + * \param[in] obj_id File identifier for the HDF5 file containing + * the referenced regions or an object identifier + * for any object in that file + * \param[in] num_elem Number of elements in the \p path and + * \p buf arrays + * \param[in] path Array of pointers to strings, which contain + * the paths to the target datasets for the + * region references + * \param[in] block_coord Array of hyperslab coordinate + * \param[out] buf Buffer for returning an array of region + * references + * + * \return \herr_t + * + * \note **Motivation:** + * \note H5LRcreate_region_references() is useful when creating + * large numbers of similar region references. + * + * \details H5LRcreate_region_references() creates a list of region references + * given an array of paths to datasets and another array listing the + * corner coordinates of the corresponding hyperslabs. + * + * \p path parameter is an array of pointers to strings. + * + * \p num_elem specifies the number of region references to be created, + * thus specifying the size of the \p path and \p _buf arrays. + * + * Buffer \p block_coord has size 2*rank and is the coordinates of the + * starting point following by the coordinates of the ending point of + * the hyperslab, repeated \p num_elem times for each hyperslab. + * For example, creating two region references to two hyperslabs, + * one with a rectangular hyperslab region starting at element (2,2) + * to element (5,4) and the second rectangular region starting at + * element (7,7) to element (9,10), results in \p block_coord + * being {2,2,5,4, 7,7,9,10}. + * + * The rank of the hyperslab will be the same as the rank of the + * target dataset. H5LRcreate_region_references() will retrieve + * the rank for each dataset and will use those values to interpret + * the values in the buffer. Please note that rank may vary from one + * dataset to another. + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LRcreate_region_references(hid_t obj_id, + size_t num_elem, + const char **path, + const hsize_t *block_coord, + hdset_reg_ref_t *buf); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Copies data from the specified dataset to a new location and + * creates a reference to it. + * + * \param[in] obj_id Identifier of any object in a file an + * HDF5 reference belongs to + * \param[in] ref Reference to the datasets region + * \param[in] file Name of the destination file + * \param[in] path Full path to the destination dataset + * \param[in] block_coord Hyperslab coordinates in the destination + * dataset + * \param[out] ref_new Region reference to the new location of + * data + * + * \return \herr_t + * + * \details Given a data set pointed to by a region reference, the function + * H5LRcopy_reference() will copy the hyperslab data referenced by + * a datasets region reference into existing dataset specified by + * its path \p path in the file with the name \p file, and to location + * specified by the hyperslab coordinates \p block_coord. It will + * create the region reference \p ref_new to point to the new location. + * The number of elements in the old and newly specified regions has + * to be the same. + * + * Buffer \p block_coord has size 2*rank and is the coordinates of + * the starting point following by the coordinates of the ending + * point of the hyperslab. For example, to extract a rectangular + * hyperslab region starting at element (2,2) to element (5,4) + * then \p block_coord would be {2, 2, 5, 4}. + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LRcopy_reference(hid_t obj_id, hdset_reg_ref_t *ref, const char *file, + const char *path, const hsize_t *block_coord, + hdset_reg_ref_t *ref_new); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Copies data from a referenced region to a region in a + * destination dataset. + * + * \param[in] obj_id Identifier of any object in a file + * dataset region reference belongs to + * \param[in] ref Dataset region reference + * \param[in] file Name of the destination file + * \param[in] path Full path to the destination dataset + * \param[in] block_coord Hyperslab coordinates in the destination + * dataset + * + * \return \herr_t + * + * \details Given a dataset region reference \p ref in a source file + * specified by an identifier of any object in that file + * \p obj_id, the function will write data to the existing + * dataset \p path in file \p file to the simple hyperslab + * specified by \p block_coord. + * + * Buffer \p block_coord has size 2*rank and is the coordinates + * of the starting point following by the coordinates of the + * ending point of the hyperslab. For example, to specify a + * rectangular hyperslab destination region starting at element + * (2,2) to element (5,4) then \p block_coord would be {2, 2, 5, 4}. + * + * If \p path does not exist in the destination file (as may be + * the case when writing to a new file) then the dataset will be + * copied directly to the \p path and \p block_coord will be + * disregarded. + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LRcopy_region(hid_t obj_id, + hdset_reg_ref_t *ref, + const char *file, + const char *path, + const hsize_t *block_coord); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Creates a dataset with the region references to the data + * in all datasets located under a specified group in a file + * or creates a dataset with object references to all objects + * (groups or datasets) located under a specified group in a file. + * + * \fg_loc_id + * \param[in] group_path Absolute or relative path to the group + * at which traversal starts + * \param[in] ds_path Absolute or relative path to the dataset + * with region references to be created + * \param[in] index_type Index_type; + * see valid values below in description + * \param[in] order Order in which index is traversed; + * see valid values below in description + * \param[in] ref_type Reference type; + * see valid values below in description + * + * \return \herr_t + * + * \details H5LRcreate_ref_to_all() creates a dataset with the + * region references to the data in all datasets located + * under a specified group in a file or creates a dataset with + * object references to all objects (groups or datasets) located + * under a specified group in a file. + * + * Given a dataset path \p ds_path in a file specified by the + * \p loc_id identifier, the function H5LRcreate_ref_to_all() + * will create a contiguous one-dimensional dataset with the + * region references or object references depending on the value + * of the \p ref_type parameter. When \p ref_type is + * #H5R_DATASET_REGION, each region reference points to all data + * in a dataset encountered by an internally called H5Lvisit() + * routine, which starts at the group specified by the \p loc_id + * and \p group_path parameters. In a like manner, when + * \p ref_type is #H5R_OBJECT, each object reference points to + * an object (a group or a dataset) encountered by H5Lvisit(). + * + * If \p ds_path does not exist in \p loc_id then the function + * will create the path specified by \p ds_path automatically. + * + * \p index_type specifies the index to be used. + * Valid values include the following: + * - #H5_INDEX_NAME Alphanumeric index on name + * - #H5_INDEX_CRT_ORDER Index on creation order + * + * \p order specifies the order in which objects are to be + * inspected along the index specified in \p index_type. + * Valid values include the following: + * - #H5_ITER_INC Increasing order + * - #H5_ITER_DEC Decreasing order + * - #H5_ITER_NATIVE Fastest available order + * + * For more detailed information on these two parameters, + * see H5Lvisit(). + * + * \p ref_type specifies the type of the reference to be used. + * Valid values include the following: + * - #H5R_DATASET_REGION Dataset region reference + * - #H5R_OBJECT Object reference + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LRcreate_ref_to_all(hid_t loc_id, const char *group_path, + const char *ds_path, H5_index_t index_type, H5_iter_order_t order, H5R_type_t ref_type); + +/*------------------------------------------------------------------------- + * + * Read dataset functions + * + *------------------------------------------------------------------------- + */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Retrieves raw data pointed to by a region reference + * to an application buffer. + * + * \param[in] obj_id File identifier for the HDF5 file containing + * the dataset with the referenced region or an + * object identifier for any object in that file + * \param[in] ref Region reference specifying data to be read + * in + * \param[in] mem_type Memory datatype of data read from referenced + * region into the application buffer + * \param[in,out] numelem Number of elements to be read into buffer + * \p buf + * \param[out] buf Buffer in which data is returned to the + * application + * + * \return \herr_t + * + * \details H5LRread_region() reads data pointed to by the region + * reference \p ref into the buffer \p buf. + * + * \p numelem specifies the number of elements to be read + * into \p buf. When the size of the reference region is unknown, + * H5LRread_region() can be called with \p buf set to NULL; + * the number of elements in the referenced region will be returned + * in \p numelem. + * + * The buffer buf must be big enough to hold \p numelem elements + * of type \p mem_type. For example, if data is read from the referenced + * region into an integer buffer, \p mem_type should be #H5T_NATIVE_INT + * and the buffer must be at least \c sizeof(int) * \p numelem bytes + * in size. This buffer must be allocated by the application. + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LRread_region(hid_t obj_id, + const hdset_reg_ref_t *ref, + hid_t mem_type, + size_t *numelem, + void *buf ); + +/*------------------------------------------------------------------------- + * + * Query dataset functions + * + *------------------------------------------------------------------------- + */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Retrieves information about the data a region reference + * points to. + * + * \param[in] obj_id Identifier of any object in an HDF5 file + * the region reference belongs to. + * \param[in] ref Region reference to query + * \param[in,out] len Size of the buffer to store \p path in. + * NOTE: if \p *path is not NULL then \p *len + * must be the appropriate length + * \param[out] path Full path that a region reference points to + * \param[out] rank The number of dimensions of the dataset + * dimensions of the dataset pointed by + * region reference. + * \param[out] dtype Datatype of the dataset pointed by the + * region reference. + * \param[out] sel_type Type of the selection (point or hyperslab) + * \param[in,out] numelem Number of coordinate blocks or + * selected elements. + * \param[out] buf Buffer containing description of the region + * pointed by region reference + * + * \return \herr_t + * + * \details H5LRget_region_info() queries information about the data + * pointed by a region reference \p ref. It returns one of the + * absolute paths to a dataset, length of the path, dataset’s rank + * and datatype, description of the referenced region and type of + * the referenced region. Any output argument can be NULL if that + * argument does not need to be returned. + * + * The parameter \p obj_id is an identifier for any object in the + * HDF5 file containing the referenced object. For example, it can + * be an identifier of a dataset the region reference belongs to + * or an identifier of an HDF5 file the dataset with region references + * is stored in. + * + * The parameter \p ref is a region reference to query. + * + * The parameter \p path is a pointer to application allocated + * buffer of size \p len+1 to return an absolute path to a dataset + * the region reference points to. + * + * The parameter \p len is a length of absolute path string plus + * the \0 string terminator. If path parameter is NULL, actual + * length of the path (+1 for \0 string terminator) is returned to + * application and can be used to allocate buffer path of an + * appropriate length \p len. + * + * The parameter \p sel_type describes the type of the selected + * region. Possible values can be #H5S_SEL_POINTS for point + * selection and #H5S_SEL_HYPERSLABS for hyperslab selection. + * + * The parameter \p numelem describes how many elements will be + * placed in the buffer \p buf. The number should be interpreted + * using the value of \p sel_type. + * + * If value of \p sel_type is #H5S_SEL_HYPERSLABS, the parameter + * \p buf contains \p numelem blocks of the coordinates for each + * simple hyperslab of the referenced region. Each block has + * length \c 2*\p rank and is organized as follows: <"start" coordinate>, + * immediately followed by <"opposite" corner coordinate>. + * The total size of the buffer to hold the description of the + * region will be \c 2*\p rank*\p numelem. If region reference + * points to a contiguous sub-array, then the value of \p numelem + * is 1 and the block contains coordinates of the upper left and + * lower right corners of the sub-array (or simple hyperslab). + * + * If value of \p sel_type is #H5S_SEL_POINTS, the parameter \p buf + * contains \p numelem blocks of the coordinates for each selected + * point of the referenced region. Each block has length \p rank + * and contains coordinates of the element. The total size of the + * buffer to hold the description of the region will be + * \p rank* \p numelem. + * + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LRget_region_info(hid_t obj_id, + const hdset_reg_ref_t *ref, + size_t *len, + char *path, + int *rank, + hid_t *dtype, + H5S_sel_type *sel_type, + size_t *numelem, + hsize_t *buf ); + + + +/*------------------------------------------------------------------------- + * + * Make dataset functions + * + *------------------------------------------------------------------------- + */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Copies data from a specified region in a source dataset + * to a specified region in a destination dataset + * + * \param[in] file_src Name of the source file + * \param[in] path_src Full path to the source dataset + * \param[in] block_coord_src Hyperslab coordinates in the + * source dataset + * \param[in] file_dest Name of the destination file + * \param[in] path_dest Full path to the destination dataset + * \param[in] block_coord_dset Hyperslab coordinates in the + * destination dataset + * + * \return \herr_t + * + * \details Given a path to a dataset \p path_src in a file with the + * name \p file_src, and description of a simple hyperslab of + * the source \p block_coord_src, the function will write data + * to the dataset \p path_dest in file \p file_dest to the + * simple hyperslab specified by \p block_coord_dset. + * The arrays \p block_coord_src and \p block_coord_dset have + * a length of 2*rank and are the coordinates of the starting + * point following by the coordinates of the ending point of the + * hyperslab. For example, to specify a rectangular hyperslab + * destination region starting at element (2,2) to element (5,4) + * then \p block_coord_dset would be {2, 2, 5, 4}. + * + * If \p path_dest does not exist in the destination file + * (as may be the case when writing to a new file) then the + * dataset will be copied directly to the \p path_dest and + * \p block_coord_dset will be disregarded. + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LTcopy_region(const char *file_src, + const char *path_src, + const hsize_t *block_coord_src, + const char *file_dest, + const char *path_dest, + const hsize_t *block_coord_dset); + +/*------------------------------------------------------------------------- + * + * Read dataset functions + * + *------------------------------------------------------------------------- + */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Reads selected data to an application buffer. + * + * \param[in] file Name of file + * \param[in] path Full path to a dataset + * \param[in] block_coord Hyperslab coordinates + * \param[in] mem_type Memory datatype, describing the buffer + * the referenced data will be read into + * \param[out] buf Buffer containing data from the + * referenced region + * + * \return \herr_t + * + * \details H5LTread_region() reads data from a region described by + * the hyperslab coordinates in \p block_coord, located in + * the dataset specified by its absolute path \p path in a + * file specified by its name \p file. Data is read into a + * buffer \p buf of the datatype that corresponds to the + * HDF5 datatype specified by \p mem_type. + * + * Buffer \p block_coord has size 2*rank and is the coordinates + * of the starting point following by the coordinates of the + * ending point of the hyperslab. For example, to extract a + * rectangular hyperslab region starting at element (2,2) to + * element (5,4) then \p block_coord would be {2, 2, 5, 4}. + * + * Buffer \p buf should be big enough to hold selected elements + * of the type that corresponds to the \p mem_type + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LTread_region(const char *file, + const char *path, + const hsize_t *block_coord, + hid_t mem_type, + void *buf ); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5LR + * + * \brief Retrieves the values of quality flags for each element + * to the application provided buffer. + * + * \param[in] dset_id Identifier of the dataset with bit-field values + * \param[in] num_values Number of the values to be extracted + * \param[in] offset Array of staring bits to be extracted from + * the element; valid values: 0 (zero) through 7 + * \param[in] lengths Array of the number of bits to be extracted + * for each value + * \param[in] space Dataspace identifier, describing the elements + * to be read from the dataset with bit-field + * values + * \param[out] buf Buffer to read the values in + * + * \return \herr_t + * + * \details H5LTread_bitfield_value() reads selected elements from a + * dataset specified by its identifier \p dset_id, and unpacks + * the bit-field values to a buffer \p buf. + * + * The parameter \p space is a space identifier that indicates + * which elements of the dataset should be read. + * + * The parameter \p offset is an array of length \p num_values; + * the ith element of the array holds the value of the + * starting bit of the ith bit-field value. + * Valid values are: 0 (zero) through 7. + * + * The parameter \p lengths is an array of length \p num_values; + * the ith element of the array holds the number of + * bits to be extracted for the ith bit-field value. + * Extracted bits will be interpreted as a base-2 integer value. + * Each value will be converted to the base-10 integer value and + * stored in the application buffer. + * + * Buffer \p buf is allocated by the application and should be big + * enough to hold \c num_sel_elem * \p num_values elements of the + * specified type, where \c num_sel_elem is a number of the elements + * to be read from the dataset. Data in the buffer is organized + * as \p num_values values for the first element, followed by the + * \p num_values values for the second element, ... , followed by + * the \p num_values values for the + * \c num_selected_elemth element. + * + * \version 1.1 Fortran wrapper introduced in this release. + * + * \since 1.0 + * + */ +H5_HLRDLL herr_t H5LTread_bitfield_value(hid_t dset_id, int num_values, const unsigned *offset, + const unsigned *lengths, hid_t space, int *buf); + diff --git a/doxygen/dox/high_level/high_level.dox b/doxygen/dox/high_level/high_level.dox new file mode 100644 index 0000000..c53d298 --- /dev/null +++ b/doxygen/dox/high_level/high_level.dox @@ -0,0 +1,29 @@ +/** \page high_level High-level library + * The high-level HDF5 library includes several sets of convenience and standard-use APIs to + * facilitate common HDF5 operations. + * + * + * + */ diff --git a/doxygen/examples/H5DO_examples.c b/doxygen/examples/H5DO_examples.c new file mode 100644 index 0000000..7a33c6b --- /dev/null +++ b/doxygen/examples/H5DO_examples.c @@ -0,0 +1,220 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +//! + +#include +#include +#define DEFLATE_SIZE_ADJUST(s) (ceil(((double)(s)) * 1.001) + 12) + : + : +size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); + const Bytef *z_src = (const Bytef *)(direct_buf); + Bytef * z_dst; /* Destination buffer */ + uLongf z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); + uLong z_src_nbytes = (uLong)buf_size; + int aggression = 9; /* Compression aggression setting */ + uint32_t filter_mask = 0; + size_t buf_size = CHUNK_NX * CHUNK_NY * sizeof(int); + + /* Create the data space */ + if ((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) + goto error; + + /* Create a new file */ + if ((file = H5Fcreate(FILE_NAME5, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + + /* Modify dataset creation properties, i.e. enable chunking and compression */ + if ((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + + if ((status = H5Pset_chunk(cparms, RANK, chunk_dims)) < 0) + goto error; + + if ((status = H5Pset_deflate(cparms, aggression)) < 0) + goto error; + + /* Create a new dataset within the file using cparms creation properties */ + if ((dset_id = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, cparms, + H5P_DEFAULT)) < 0) + goto error; + + /* Initialize data for one chunk */ + for (i = n = 0; i < CHUNK_NX; i++) + for (j = 0; j < CHUNK_NY; j++) + direct_buf[i][j] = n++; + + /* Allocate output (compressed) buffer */ + outbuf = malloc(z_dst_nbytes); + z_dst = (Bytef *)outbuf; + + /* Perform compression from the source to the destination buffer */ + ret = compress2(z_dst, &z_dst_nbytes, z_src, z_src_nbytes, aggression); + + /* Check for various zlib errors */ + if (Z_BUF_ERROR == ret) { + fprintf(stderr, "overflow"); + goto error; + } + else if (Z_MEM_ERROR == ret) { + fprintf(stderr, "deflate memory error"); + goto error; + } + else if (Z_OK != ret) { + fprintf(stderr, "other deflate error"); + goto error; + } + + /* Write the compressed chunk data repeatedly to cover all the + * * chunks in the dataset, using the direct write function. */ + for (i = 0; i < NX / CHUNK_NX; i++) { + for (j = 0; j < NY / CHUNK_NY; j++) { + status = + H5DOwrite_chunk(dset_id, H5P_DEFAULT, filter_mask, offset, z_dst_nbytes, outbuf); + offset[1] += CHUNK_NY; + } + offset[0] += CHUNK_NX; + offset[1] = 0; + } + + /* Overwrite the first chunk with uncompressed data. Set the filter mask to + * * indicate the compression filter is skipped */ + filter_mask = 0x00000001; + offset[0] = offset[1] = 0; + if (H5DOwrite_chunk(dset_id, H5P_DEFAULT, filter_mask, offset, buf_size, direct_buf) < 0) + goto error; + + /* Read the entire dataset back for data verification converting ints to longs */ + if (H5Dread(dataset, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, outbuf_long) < 0) + goto error; + + /* Data verification here */ + : + : + + //! + + //! + +#include +#include +#define DEFLATE_SIZE_ADJUST(s) (ceil(((double)(s)) * 1.001) + 12) + : + : +size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); + const Bytef *z_src = (const Bytef *)(direct_buf); + Bytef * z_dst; /* Destination buffer */ + uLongf z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); + uLong z_src_nbytes = (uLong)buf_size; + int aggression = 9; /* Compression aggression setting */ + uint32_t filter_mask = 0; + size_t buf_size = CHUNK_NX * CHUNK_NY * sizeof(int); + /* For H5DOread_chunk() */ + void * readbuf = NULL; /* Buffer for reading data */ + const Bytef *pt_readbuf; /* Point to the buffer for data read */ + hsize_t read_chunk_nbytes; /* Size of chunk on disk */ + int read_dst_buf[CHUNK_NX][CHUNK_NY]; /* Buffer to hold un-compressed data */ + + /* Create the data space */ + if ((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) + goto error; + + /* Create a new file */ + if ((file = H5Fcreate(FILE_NAME5, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + + /* Modify dataset creation properties, i.e. enable chunking and compression */ + if ((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + + if ((status = H5Pset_chunk(cparms, RANK, chunk_dims)) < 0) + goto error; + + if ((status = H5Pset_deflate(cparms, aggression)) < 0) + goto error; + + /* Create a new dataset within the file using cparms creation properties */ + if ((dset_id = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, cparms, + H5P_DEFAULT)) < 0) + goto error; + + /* Initialize data for one chunk */ + for (i = n = 0; i < CHUNK_NX; i++) + for (j = 0; j < CHUNK_NY; j++) + direct_buf[i][j] = n++; + + /* Allocate output (compressed) buffer */ + outbuf = malloc(z_dst_nbytes); + z_dst = (Bytef *)outbuf; + + /* Perform compression from the source to the destination buffer */ + ret = compress2(z_dst, &z_dst_nbytes, z_src, z_src_nbytes, aggression); + + /* Check for various zlib errors */ + if (Z_BUF_ERROR == ret) { + fprintf(stderr, "overflow"); + goto error; + } + else if (Z_MEM_ERROR == ret) { + fprintf(stderr, "deflate memory error"); + goto error; + } + else if (Z_OK != ret) { + fprintf(stderr, "other deflate error"); + goto error; + } + + /* Write the compressed chunk data repeatedly to cover all the + * * chunks in the dataset, using the direct write function. */ + for (i = 0; i < NX / CHUNK_NX; i++) { + for (j = 0; j < NY / CHUNK_NY; j++) { + status = H5DOwrite_chunk(dset_id, H5P_DEFAULT, filter_mask, offset, z_dst_nbytes, outbuf); + offset[1] += CHUNK_NY; + } + offset[0] += CHUNK_NX; + offset[1] = 0; + } + + if (H5Fflush(dataset, H5F_SCOPE_LOCAL) < 0) + goto error; + + if (H5Dclose(dataset) < 0) + goto error; + + if ((dataset = H5Dopen2(file, DATASETNAME1, H5P_DEFAULT)) < 0) + goto error; + + offset[0] = CHUNK_NX; + offset[1] = CHUNK_NY; + + /* Get the size of the compressed chunk */ + ret = H5Dget_chunk_storage_size(dataset, offset, &read_chunk_nbytes); + + readbuf = HDmalloc(read_chunk_nbytes); + pt_readbuf = (const Bytef *)readbuf; + + /* Use H5DOread_chunk() to read the chunk back */ + if ((status = H5DOread_chunk(dataset, H5P_DEFAULT, offset, &read_filter_mask, readbuf)) < 0) + goto error; + + ret = + uncompress((Bytef *)read_dst_buf, (uLongf *)&buf_size, pt_readbuf, (uLong)read_chunk_nbytes); + + /* Check for various zlib errors */ + if (Z_BUF_ERROR == ret) { + fprintf(stderr, "error: not enough room in output buffer"); + goto error; + } + else if (Z_MEM_ERROR == ret) { + fprintf(stderr, "error: not enough memory"); + goto error; + } + else if (Z_OK != ret) { + fprintf(stderr, "error: corrupted input data"); + goto error; + } + + /* Data verification here */ + : + : +//! diff --git a/doxygen/examples/H5LDget_dset_elmts.c b/doxygen/examples/H5LDget_dset_elmts.c new file mode 100644 index 0000000..e23299a --- /dev/null +++ b/doxygen/examples/H5LDget_dset_elmts.c @@ -0,0 +1,143 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +//! + +DATASET "DSET1" {DATATYPE H5T_STD_I32LE DATASPACE SIMPLE{(4, 13) / (60, 100)} : : } + +//! + +//! + +/* open the HDF5 file */ +fid = H5Fopen(FILE, H5F_ACC_RDWR, H5P_DEFAULT); + +/* open the dataset */ +did = H5Dopen2(fid, "DSET1", H5P_DEFAULT); + : + : + /* define hsize_t dims[2]; */ + /* define hsize_t new_dims[2]; */ + /* get the dataset's current dimension sizes */ + H5LDget_dset_dims(did, dims); + + /* extend the dataset by 2 */ + new_dims[0] = dims[0] + 2; + new_dims[1] = dims[1] + 2; + H5Dset_extent(did, new_dims) + + /* write data to the extended dataset */ + : : + /* get the size of the dataset's data type */ + type_size = H5LDget_dset_type_size(did, NULL); + : + : + /* allocate buffer for storing selected data elements from the dataset */ + /* calculate # of selected elements from dims & new_dims */ + /* buffer size = type_size * number of selected elements */ + : + : + /* read the selected elements from the dataset into buf */ + H5LDget_dset_elmts(did, dims, new_dims, NULL, buf); + : + : + H5Dclose(did); + H5Fclose(fid); + + //! + + //! + + data for elements (0, 13), (0, 14) + data for elements (1, 13), (1, 14) + data for elements (2, 13), (2, 14) + data for elements (3, 13), (3, 14) + data for elements (4, 0), (4, 1), (4, 2)......................(4, 13), (4, 14) + data for elements (5, 0), (5, 1), (5, 2)......................(5, 13), (5, 14) + +//! + + +//! + + DATASET "DSET2" { + DATATYPE H5T_COMPOUND { + H5T_STD_I32LE "a"; + H5T_STD_I32LE "b"; + H5T_ARRAY + { + [4] H5T_STD_I32LE + } + "c"; + H5T_STD_I32LE "d"; + H5T_STD_I32LE "e"; + H5T_COMPOUND + { + H5T_STD_I32LE "a"; + H5T_STD_I32LE "b"; + H5T_ARRAY + { + [4] H5T_STD_I32LE + } + "c"; + H5T_STD_I32LE "d"; + H5T_STD_I32LE "e"; + } + "s2"; + } + DATASPACE SIMPLE + { + (5) / (5) + } + :: + } + + //! + + //! + + /* open the HDF5 file */ + fid = H5Fopen(FILE, H5F_ACC_RDWR, H5P_DEFAULT); + + /* open the dataset */ + did = H5Dopen2(fid, "DSET2", H5P_DEFAULT); + + /* define hsize_t dims[1]; */ + /* define hsize_t new_dims[1]; */ + : + : + /* get the dataset's current dimension size */ + H5LDget_dset_dims(did, dims); + + /* extend the dataset by 2 */ + new_dims[0] = dims[0] + 2; + H5Dset_extent(did, new_dims); + : + : + /* write data to the extended part of the dataset */ + : + : + /* #define fields "d,s2.c" */ + /* get the size of the dataset's data type for the selected fields */ + type_size = H5LDget_dset_type_size(did, fields); + : + : + /* allocate buffer for storing selected data elements from the dataset */ + /* calculate # of selected elements from dims & new_dims */ + /* buffer size = type_size * number of selected elements */ + : + : + /* read the selected elements from the dataset into buf */ + H5LD_get_dset_elmts(did, dims, new_dims, fields, buf); + : + : + H5Dclose(did); + H5Fclose(fid); + + //! + + //! + + Data for element (5): integer value for "d", 4 integer values for array "s2.c" + Data for element (6): integer value for "d", 4 integer values for array "s2.c" + +//! diff --git a/doxygen/examples/H5LT_examples.c b/doxygen/examples/H5LT_examples.c new file mode 100644 index 0000000..5ed4c29 --- /dev/null +++ b/doxygen/examples/H5LT_examples.c @@ -0,0 +1,27 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +//! + +H5T_class_t type_class; +size_t type_size; +hsize_t dims[0]; +... status = H5LTget_attribute_info(file_id, "/", STRNAME, dims, &type_class, &type_size); +if (type_class == H5T_STRING) { + printf("Attribute is a string.\n"); + printf("String size: %i\n", type_size); + + //! + + //! + + “H5T_ENUM + { + H5T_NATIVE_INT; + “Bob” 0; + “Elena” 1; + “Quincey” 2; + “Frank” 3; + } + ” + +//! diff --git a/doxygen/examples/H5TBAget_fill.c b/doxygen/examples/H5TBAget_fill.c new file mode 100644 index 0000000..15eae8b --- /dev/null +++ b/doxygen/examples/H5TBAget_fill.c @@ -0,0 +1,43 @@ +unsigned char tmp_fill_buf[40]; +... + + file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT); +dataset_id = H5Dopen(file_id, TABLE_NAME, H5P_DEFAULT); +datatype_id = H5Dget_type(dataset_id); + +status = H5TBget_table_info(file_id, TABLE_NAME, &nfields, &nrecords); + +hasfill = H5TBAget_fill(file_id, TABLE_NAME, dataset_id, tmp_fill_buf); + +for (i = 0; i < nfields; i++) { + member_type_id = H5Tget_member_type(datatype_id, (unsigned)i); + native_mem_type_id = H5Tget_native_type(member_type_id, H5T_DIR_ASCEND); + member_offset = H5Tget_member_offset(datatype_id, (unsigned)i); + printf("member_offset: %i\n", member_offset); + memb_class = H5Tget_class(member_type_id); + switch (memb_class) { + case H5T_INTEGER: + /* convert unsigned char array to integer */ + break; + case H5T_FLOAT: + /* convert unsigned char array to double or float */ + + if (H5Tequal(native_mem_type_id, H5T_NATIVE_DOUBLE)) { + } + else if (H5Tequal(native_mem_type_id, H5T_NATIVE_FLOAT)) { + f.i = tmp_fill_buf[member_offset] | (tmp_fill_buf[member_offset + 1] << 8) | + (tmp_fill_buf[member_offset + 2] << 16) | (tmp_fill_buf[member_offset + 3] << 24); + printf("Field %i Fill Value: %lf\n", i, f.f); + } + break; + + case H5T_STRING: + /* convert unsigned char array to string */ + strsize = H5Tget_size(member_type_id); + + printf("Field %i Fill Value: ", i); + for (j = 0; j < strsize; j++) + printf("%c", tmp_fill_buf[member_offset + j]); + printf("\n"); + break; + } diff --git a/hl/src/H5DOpublic.h b/hl/src/H5DOpublic.h index 88616a3..13b2422 100644 --- a/hl/src/H5DOpublic.h +++ b/hl/src/H5DOpublic.h @@ -18,6 +18,28 @@ extern "C" { #endif +/**\defgroup H5DO Optimizations + * + * Bypassing default HDF5 behavior in order to optimize for specific + * use cases (H5DO) + * + * HDF5 functions described is this section are implemented in the HDF5 High-level + * library as optimized functions. These functions generally require careful setup + * and testing as they enable an application to bypass portions of the HDF5 + * library’s I/O pipeline for performance purposes. + * + * These functions are distributed in the standard HDF5 distribution and are + * available any time the HDF5 High-level library is available. + * + * - \ref H5DOappend + * \n Appends data to a dataset along a specified dimension. + * - \ref H5DOread_chunk + * \n Reads a raw data chunk directly from a dataset in a file into a buffer (DEPRECATED) + * - \ref H5DOwrite_chunk + * \n Writes a raw data chunk from a buffer directly to a dataset in a file (DEPRECATED) + * + */ + /*------------------------------------------------------------------------- * * "Optimized dataset" routines. @@ -25,6 +47,48 @@ extern "C" { *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5DO + * + * \brief Appends data to a dataset along a specified dimension. + * + * \param[in] dset_id Dataset identifier + * \param[in] dxpl_id Dataset transfer property list identifier + * \param[in] axis Dataset Dimension (0-based) for the append + * \param[in] extension Number of elements to append for the + * axis-th dimension + * \param[in] memtype The memory datatype identifier + * \param[in] buf Buffer with data for the append + * + * \return \herr_t + * + * \details The H5DOappend() routine extends a dataset by \p extension + * number of elements along a dimension specified by a + * dimension \p axis and writes \p buf of elements to the + * dataset. Dimension \p axis is 0-based. Elements’ type + * is described by \p memtype. + * + * This routine combines calling H5Dset_extent(), + * H5Sselect_hyperslab(), and H5Dwrite() into a single routine + * that simplifies application development for the common case + * of appending elements to an existing dataset. + * + * For a multi-dimensional dataset, appending to one dimension + * will write a contiguous hyperslab over the other dimensions. + * For example, if a 3-D dataset has dimension sizes (3, 5, 8), + * extending the 0th dimension (currently of size 3) by 3 will + * append 3*5*8 = 120 elements (which must be pointed to by the + * \p buffer parameter) to the dataset, making its final + * dimension sizes (6, 5, 8). + * + * If a dataset has more than one unlimited dimension, any of + * those dimensions may be appended to, although only along + * one dimension per call to H5DOappend(). + * + * \since 1.10.0 + * + */ H5_HLDLL herr_t H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, hid_t memtype, const void *buf); @@ -35,8 +99,142 @@ H5_HLDLL herr_t H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t e #ifndef H5_NO_DEPRECATED_SYMBOLS /* Compatibility wrappers for functionality moved to H5D */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5DO + * + * \brief Writes a raw data chunk from a buffer directly to a dataset in a file. + * + * \param[in] dset_id Identifier for the dataset to write to + * \param[in] dxpl_id Transfer property list identifier for + * this I/O operation + * \param[in] filters Mask for identifying the filters in use + * \param[in] offset Logical position of the chunk’s first element + * in the dataspace + * \param[in] data_size Size of the actual data to be written in bytes + * \param[in] buf Buffer containing data to be written to the chunk + * + * \return \herr_t + * + * \deprecated This function was deprecated in favor of the function + * H5Dwrite_chunk() of HDF5-1.10.3. + * The functionality of H5DOwrite_chunk() was moved + * to H5Dwrite_chunk(). + * \deprecated For compatibility, this API call has been left as a stub which + * simply calls H5Dwrite_chunk(). New code should use H5Dwrite_chunk(). + * + * \details The H5DOwrite_chunk() writes a raw data chunk as specified by its + * logical \p offset in a chunked dataset \p dset_id from the application + * memory buffer \p buf to the dataset in the file. Typically, the data + * in \p buf is preprocessed in memory by a custom transformation, such as + * compression. The chunk will bypass the library’s internal data + * transfer pipeline, including filters, and will be written directly to the file. + * + * \p dxpl_id is a data transfer property list identifier. + * + * \p filters is a mask providing a record of which filters are used + * with the chunk. The default value of the mask is zero (\c 0), + * indicating that all enabled filters are applied. A filter is skipped + * if the bit corresponding to the filter’s position in the pipeline + * (0 ≤ position < 32) is turned on. This mask is saved + * with the chunk in the file. + * + * \p offset is an array specifying the logical position of the first + * element of the chunk in the dataset’s dataspace. The length of the + * offset array must equal the number of dimensions, or rank, of the + * dataspace. The values in \p offset must not exceed the dimension limits + * and must specify a point that falls on a dataset chunk boundary. + * + * \p data_size is the size in bytes of the chunk, representing the number of + * bytes to be read from the buffer \p buf. If the data chunk has been + * precompressed, \p data_size should be the size of the compressed data. + * + * \p buf is the memory buffer containing data to be written to the chunk in the file. + * + * \attention Exercise caution when using H5DOread_chunk() and H5DOwrite_chunk(), + * as they read and write data chunks directly in a file. + * H5DOwrite_chunk() bypasses hyperslab selection, the conversion of data + * from one datatype to another, and the filter pipeline to write the chunk. + * Developers should have experience with these processes before + * using this function. Please see + * + * Using the Direct Chunk Write Function + * for more information. + * + * \note H5DOread_chunk() and H5DOwrite_chunk() are not + * supported under parallel and do not support variable length types. + * + * \par Example + * The following code illustrates the use of H5DOwrite_chunk to write + * an entire dataset, chunk by chunk: + * \snippet H5DO_examples.c H5DOwrite + * + * \version 1.10.3 Function deprecated in favor of H5Dwrite_chunk. + * + * \since 1.8.11 + */ H5_HLDLL herr_t H5DOwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *offset, size_t data_size, const void *buf); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5DO + * + * \brief Reads a raw data chunk directly from a dataset in a file into a buffer. + * + * \param[in] dset_id Identifier for the dataset to be read + * \param[in] dxpl_id Transfer property list identifier for + * this I/O operation + * \param[in] offset Logical position of the chunk’s first + element in the dataspace + * \param[in,out] filters Mask for identifying the filters used + * with the chunk + * \param[in] buf Buffer containing the chunk read from + * the dataset + * + * \return \herr_t + * + * \deprecated This function was deprecated in favor of the function + * H5Dread_chunk() as of HDF5-1.10.3. + * In HDF5 1.10.3, the functionality of H5DOread_chunk() + * was moved to H5Dread_chunk(). + * \deprecated For compatibility, this API call has been left as a stub which + * simply calls H5Dread_chunk(). New code should use H5Dread_chunk(). + * + * \details The H5DOread_chunk() reads a raw data chunk as specified + * by its logical \p offset in a chunked dataset \p dset_id + * from the dataset in the file into the application memory + * buffer \p buf. The data in \p buf is read directly from the file + * bypassing the library’s internal data transfer pipeline, + * including filters. + * + * \p dxpl_id is a data transfer property list identifier. + * + * The mask \p filters indicates which filters are used with the + * chunk when written. A zero value indicates that all enabled filters + * are applied on the chunk. A filter is skipped if the bit corresponding + * to the filter’s position in the pipeline + * (0 ≤ position < 32) is turned on. + * + * \p offset is an array specifying the logical position of the first + * element of the chunk in the dataset’s dataspace. The length of the + * offset array must equal the number of dimensions, or rank, of the + * dataspace. The values in \p offset must not exceed the dimension + * limits and must specify a point that falls on a dataset chunk boundary. + * + * \p buf is the memory buffer containing the chunk read from the dataset + * in the file. + * + * \par Example + * The following code illustrates the use of H5DOread_chunk() + * to read a chunk from a dataset: + * \snippet H5DO_examples.c H5DOread + * + * \version 1.10.3 Function deprecated in favor of H5Dread_chunk. + * + * \since 1.10.2, 1.8.19 + */ H5_HLDLL herr_t H5DOread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters /*out*/, void *buf /*out*/); diff --git a/hl/src/H5DSpublic.h b/hl/src/H5DSpublic.h index 979a173..e34535d 100644 --- a/hl/src/H5DSpublic.h +++ b/hl/src/H5DSpublic.h @@ -19,33 +19,388 @@ #define REFERENCE_LIST "REFERENCE_LIST" #define DIMENSION_LABELS "DIMENSION_LABELS" +/** + * \brief Prototype for H5DSiterate_scales() operator + * + */ +//! typedef herr_t (*H5DS_iterate_t)(hid_t dset, unsigned dim, hid_t scale, void *visitor_data); +//! #ifdef __cplusplus extern "C" { #endif +/**\defgroup H5DS Dimension Scales + * + * Creating and manipulating HDF5 datasets that are associated with + * the dimension of another HDF5 dataset (H5DS) + * + * \note \Bold{Programming hints:} + * \note To use any of these functions or subroutines, + * you must first include the relevant include file (C) or + * module (Fortran) in your application. + * \note The following line includes the HDF5 Dimension Scale package, + * H5DS, in C applications: + * \code #include "hdf5_hl.h" \endcode + * \note This line includes the H5DS module in Fortran applications: + * \code use h5ds \endcode + * + * - \ref H5DSwith_new_ref + * \n Determines if new references are used with dimension scales. + * - \ref H5DSattach_scale + * \n Attach dimension scale dsid to dimension idx of dataset did. + * - \ref H5DSdetach_scale + * \n Detach dimension scale dsid from the dimension idx of Dataset did. + * - \ref H5DSget_label + * \n Read the label for dimension idx of did into buffer label. + * - \ref H5DSget_num_scales + * \n Determines how many Dimension Scales are attached + * to dimension idx of did. + * - \ref H5DSget_scale_name + * \n Retrieves name of scale did into buffer name. + * - \ref H5DSis_attached + * \n Report if dimension scale dsid is currently attached + * to dimension idx of dataset did. + * - \ref H5DSis_scale + * \n Determines whether dset is a Dimension Scale. + * - \ref H5DSiterate_scales + * \n Iterates the operation visitor through the scales + * attached to dimension dim. + * - \ref H5DSset_label + * \n Set label for the dimension idx of did to the value label. + * - \ref H5DSset_scale + * \n Convert dataset dsid to a dimension scale, + * with optional name, dimname. + * + */ + +/* THIS IS A NEW ROUTINE NOT ON OLD PORTAL */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Determines if new references are used with dimension scales. + * + * \param[in] obj_id Object identifier + * \param[out] with_new_ref New references are used or not + * + * \return \herr_t + * + * \details H5DSwith_new_ref() takes any object identifier and checks + * if new references are used for dimension scales. Currently, + * new references are used when non-native VOL connector is + * used or when H5_DIMENSION_SCALES_WITH_NEW_REF is set up + * via configure option. + * + */ H5_HLDLL herr_t H5DSwith_new_ref(hid_t obj_id, hbool_t *with_new_ref); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Attach dimension scale \p dsid to dimension \p idx of + * dataset did. + * + * \param[in] did The dataset + * \param[in] dsid The scale to be attached + * \param[in] idx The dimension of \p did that \p dsid is associated with + * + * \return \herr_t + * + * \details Define Dimension Scale \p dsid to be associated with + * dimension \p idx of dataset \p did. + * + * Entries are created in the #DIMENSION_LIST and + * #REFERENCE_LIST attributes, as defined in section 4.2 of + * + * HDF5 Dimension Scale Specification. + * + * Fails if: + * - Bad arguments + * - If \p dsid is not a Dimension Scale + * - If \p did is a Dimension Scale + * (A Dimension Scale cannot have scales.) + * + * \note The Dimension Scale \p dsid can be attached to the + * same dimension more than once, which has no effect. + */ H5_HLDLL herr_t H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Detach dimension scale \p dsid from the dimension \p idx of dataset \p did. + * + * \param[in] did The dataset + * \param[in] dsid The scale to be detached + * \param[in] idx The dimension of \p did to detach + * + * \return \herr_t + * + * \details If possible, deletes association of Dimension Scale \p dsid with + * dimension \p idx of dataset \p did. This deletes the entries in the + * #DIMENSION_LIST and #REFERENCE_LIST attributes, + * as defined in section 4.2 of + * + * HDF5 Dimension Scale Specification. + * + * Fails if: + * - Bad arguments + * - The dataset \p did or \p dsid do not exist + * - The \p dsid is not a Dimension Scale + * - \p dsid is not attached to \p did + * + * \note A scale may be associated with more than dimension of the + * same dataset. If so, the detach operation only deletes one + * of the associations, for \p did. + * + */ H5_HLDLL herr_t H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Convert dataset \p dsid to a dimension scale, + * with optional name, \p dimname. + * + * \param[in] dsid The dataset to be made a Dimemsion Scale + * \param[in] dimname The dimension name (optional), NULL if the + * dimension has no name. + * + * \return \herr_t + * + * \details The dataset \p dsid is converted to a Dimension Scale dataset, + * as defined above. Creates the CLASS attribute, set to the value + * "DIMENSION_SCALE" and an empty #REFERENCE_LIST attribute, + * as described in + * + * HDF5 Dimension Scale Specification. + * (PDF, see section 4.2). + * + * If \p dimname is specified, then an attribute called NAME + * is created, with the value \p dimname. + * + * Fails if: + * - Bad arguments + * - If \p dsid is already a scale + * - If \p dsid is a dataset which already has dimension scales + * + * If the dataset was created with the Table, Image, or Palette interface [9], + * it is not recommended to convert to a Dimension Scale. + * (These Datasets will have a CLASS Table, Image, or Palette.) + * + * \todo what is [9] after Palette interface? + */ H5_HLDLL herr_t H5DSset_scale(hid_t dsid, const char *dimname); -H5_HLDLL int H5DSget_num_scales(hid_t did, unsigned int dim); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Determines how many Dimension Scales are attached + * to dimension \p idx of \p did. + * + * \param[in] did The dataset to query + * \param[in] idx The dimension of \p did to query + * + * \return Returns the number of Dimension Scales associated + * with \p did, if successful, otherwise returns a + * negative value. + * + * \details H5DSget_num_scales() determines how many Dimension + * Scales are attached to dimension \p idx of + * dataset \p did. + * + */ +H5_HLDLL int H5DSget_num_scales(hid_t did, unsigned int idx); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Set label for the dimension \p idx of \p did + * to the value \p label. + * + * \param[in] did The dataset + * \param[in] idx The dimension + * \param[in] label The label + * + * \return \herr_t + * + * \details Sets the #DIMENSION_LABELS for dimension \p idx of + * dataset \p did. If the dimension had a label, + * the new value replaces the old. + * + * Fails if: + * - Bad arguments + * + */ H5_HLDLL herr_t H5DSset_label(hid_t did, unsigned int idx, const char *label); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Read the label for dimension \p idx of \p did into buffer \p label. + * + * \param[in] did The dataset + * \param[in] idx The dimension + * \param[out] label The label + * \param[in] size The length of the label buffer + * + * \return Upon success, size of label or zero if no label found. + * Negative if fail. + * + * \details Returns the value of the #DIMENSION_LABELS for + * dimension \p idx of dataset \p did, if set. + * Up to \p size characters of the name are copied into + * the buffer \p label. If the label is longer than + * \p size, it will be truncated to fit. The parameter + * \p size is set to the size of the returned \p label. + * + * If \p did has no label, the return value of + * \p label is NULL. + * + * Fails if: + * - Bad arguments + * + */ H5_HLDLL ssize_t H5DSget_label(hid_t did, unsigned int idx, char *label, size_t size); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Retrieves name of scale \p did into buffer \p name. + * + * \param[in] did Dimension scale identifier + * \param[out] name Buffer to contain the returned name + * \param[in] size Size in bytes, of the \p name buffer + * + * \return Upon success, the length of the scale name or zero if no name found. + * Negative if fail. + * + * \details H5DSget_scale_name() retrieves the name attribute + * for scale \p did. + * + * Up to \p size characters of the scale name are returned + * in \p name; additional characters, if any, are not returned + * to the user application. + * + * If the length of the name, which determines the required value of + * \p size, is unknown, a preliminary H5DSget_scale_name() call can + * be made by setting \p name to NULL. The return value of this call + * will be the size of the scale name; that value plus one (1) can then + * be assigned to \p size for a second H5DSget_scale_name() call, + * which will retrieve the actual name. (The value passed in with the + * parameter \p size must be one greater than size in bytes of the actual + * name in order to accommodate the null terminator; + * if \p size is set to the exact size of the name, the last byte + * passed back will contain the null terminator and the last character + * will be missing from the name passed back to the calling application.) + */ H5_HLDLL ssize_t H5DSget_scale_name(hid_t did, char *name, size_t size); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Determines whether \p did is a Dimension Scale. + * + * \param[in] did The dataset to query + * + * \return \htri_t + * + * \details H5DSis_scale() determines if \p did is a Dimension Scale, + * i.e., has class="DIMENSION_SCALE"). + * + */ H5_HLDLL htri_t H5DSis_scale(hid_t did); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Iterates the operation visitor through the scales + * attached to dimension \p dim. + * + * \param[in] did The dataset + * \param[in] dim The dimension of dataset \p did + * \param[in,out] idx Input the index to start iterating, + * output the next index to visit. + * If NULL, start at the first position. + * \param[in] visitor The visitor function + * \param[in] visitor_data Arbitrary data to pass to the + * visitor function + * + * \return Returns the return value of the last operator if it was + * non-zero, or zero if all scales were processed. + * + * \details H5DSiterate_scales() iterates over the scales attached to + * dimension \p dim of dataset \p did. For each scale in the + * list, the \p visitor_data and some additional information, + * specified below, are passed to the \p visitor function. + * The iteration begins with the \p idx object in the + * group and the next element to be processed by the operator + * is returned in \p idx. If \p idx is NULL, then the + * iterator starts at the first group member; since no + * stopping point is returned in this case, + * the iterator cannot be restarted if one of the calls + * to its operator returns non-zero. + * + * The prototype for \ref H5DS_iterate_t is: + * \snippet this H5DS_iterate_t_snip + * + * The operation receives the Dimension Scale dataset + * identifier, \p scale, and the pointer to the operator + * data passed in to H5DSiterate_scales(), \p visitor_data. + * + * The return values from an operator are: + * + * - Zero causes the iterator to continue, returning zero + * when all group members have been processed. + * - Positive causes the iterator to immediately return that + * positive value, indicating short-circuit success. + * The iterator can be restarted at the next group member. + * - Negative causes the iterator to immediately return + * that value, indicating failure. The iterator can be + * restarted at the next group member. + * + * H5DSiterate_scales() assumes that the scales of the + * dimension identified by \p dim remain unchanged through + * the iteration. If the membership changes during the iteration, + * the function's behavior is undefined. + */ H5_HLDLL herr_t H5DSiterate_scales(hid_t did, unsigned int dim, int *idx, H5DS_iterate_t visitor, void *visitor_data); +/** + * -------------------------------------------------------------------------- + * \ingroup H5DS + * + * \brief Report if dimension scale \p dsid is currently attached to + * dimension \p idx of dataset \p did. + * + * \param[in] did The dataset + * \param[in] dsid The scale to be attached + * \param[in] idx The dimension of \p did that \p dsid is associated with + * + * \return \htri_t + * + * \details Report if dimension scale \p dsid is currently attached to + * dimension \p idx of dataset \p did. + * + * Fails if: + * - Bad arguments + * - If \p dsid is not a Dimension Scale + * - The \p dsid is not a Dimension Scale + * - If \p did is a Dimension Scale (A Dimension Scale cannot have scales.) + * + */ H5_HLDLL htri_t H5DSis_attached(hid_t did, hid_t dsid, unsigned int idx); #ifdef __cplusplus diff --git a/hl/src/H5IMpublic.h b/hl/src/H5IMpublic.h index 2843942..b5426d6 100644 --- a/hl/src/H5IMpublic.h +++ b/hl/src/H5IMpublic.h @@ -18,33 +18,325 @@ extern "C" { #endif +/**\defgroup H5IM Images + * + * Creating and manipulating HDF5 datasets intended to be + * interpreted as images (H5IM) + * + * The specification for the Images API is presented in another + * document: \ref IMG + * This version of the API is primarily concerned with two dimensional raster + * data similar to HDF4 Raster Images. + * The HDF5 Images API uses the \ref H5LT HDF5 API. + * + * \note \Bold{Programming hints:} + * \note To use any of these functions or subroutines, + * you must first include the relevant include file (C) or + * module (Fortran) in your application. + * \note The following line includes the HDF5 Images package, H5IM, + * in C applications: + * \code #include "hdf5_hl.h" \endcode + * \note This line includes the H5IM module in Fortran applications: + * \code use h5im \endcode + * + * - \ref H5IMget_image_info + * \n Gets information about an image dataset (dimensions, + * interlace mode and number of associated palettes). + * - \ref H5IMget_npalettes + * \n Gets the number of palettes associated to an image. + * - \ref H5IMget_palette + * \n Gets the palette dataset. + * - \ref H5IMget_palette_info + * \n Gets information about a palette dataset (dimensions). + * - \ref H5IMis_image + * \n Inquires if a dataset is an image + * - \ref H5IMis_palette + * \n Inquires if a dataset is a palette. + * - \ref H5IMlink_palette + * \n Attaches a palette to an image. + * - \ref H5IMmake_image_8bit + * \n Creates and writes an image. + * - \ref H5IMmake_image_24bit + * \n Creates and writes a true color image. + * - \ref H5IMmake_palette + * \n Creates and writes a palette. + * - \ref H5IMread_image + * \n Reads image data from disk. + * - \ref H5IMunlink_palette + * \n Dettaches a palette from an image. + * + */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Creates and writes an image. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to create + * \param[in] width The width of the image + * \param[in] height The height of the image + * \param[in] buffer Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5IMmake_image_8bit() creates and writes a dataset named + * \p dset_name attached to the file or group specified by the + * identifier \p loc_id. Attributes conforming to the HDF5 Image + * and Palette specification for an indexed image are attached to + * the dataset, thus identifying it as an image. The image data is + * of the type #H5T_NATIVE_UCHAR. An indexed image is an image in + * which each each pixel information storage is an index to a + * table palette. + * + */ H5_HLDLL herr_t H5IMmake_image_8bit(hid_t loc_id, const char *dset_name, hsize_t width, hsize_t height, const unsigned char *buffer); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Creates and writes a true color image. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to create + * \param[in] width The width of the image + * \param[in] height The height of the image + * \param[in] interlace String defining the interlace mode + * \param[in] buffer Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5IMmake_image_24bit() creates and writes a dataset named + * \p dset_name attached to the file or group specified by the + * identifier \p loc_id. This function defines a true color image + * conforming to the HDF5 Image and Palette specification. + * The function assumes that the image data is of the type + * #H5T_NATIVE_UCHAR. + * + * A true color image is an image where the pixel storage contains + * several color planes. In a 24 bit RGB color model, these planes + * are red, green and blue. In a true color image the stream of bytes + * can be stored in several different ways, thus defining the + * interlace (or interleaving) mode. The 2 most used types of interlace mode + * are interlace by pixel and interlace by plane. In the 24 bit RGB color + * model example, interlace by plane means all the red components for the + * entire dataset are stored first, followed by all the green components, + * and then by all the blue components. Interlace by pixel in this example + * means that for each pixel the sequence red, green, blue is defined. + * In this function, the interlace mode is defined in the parameter + * \p interlace, a string that can have the values INTERLACE_PIXEL + * or INTERLACE_PLANE. + * + */ H5_HLDLL herr_t H5IMmake_image_24bit(hid_t loc_id, const char *dset_name, hsize_t width, hsize_t height, const char *interlace, const unsigned char *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Gets information about an image dataset + * (dimensions, interlace mode and number of associated palettes). + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset + * \param[out] width The width of the image + * \param[out] height The height of the image + * \param[out] planes The number of color planes of the image + * \param[out] interlace The interlace mode of the image + * \param[out] npals The number of palettes associated to the image + * + * \return \herr_t + * + * \details H5IMget_image_info() gets information about an image + * named \p dset_name attached to the file or group specified + * by the identifier \p loc_id. + * + */ H5_HLDLL herr_t H5IMget_image_info(hid_t loc_id, const char *dset_name, hsize_t *width, hsize_t *height, hsize_t *planes, char *interlace, hssize_t *npals); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Reads image data from disk. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to create + * \param[out] buffer Buffer with data to store the image + * + * \return \herr_t + * + * \details H5IMread_image() reads a dataset named \p dset_name + * attached to the file or group specified by the + * identifier \p loc_id. + * + */ H5_HLDLL herr_t H5IMread_image(hid_t loc_id, const char *dset_name, unsigned char *buffer); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Creates and writes a palette. + * + * \fg_loc_id + * \param[in] pal_name The name of the palette + * \param[in] pal_dims An array of the size of the palette dimensions + * \param[in] pal_data Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5IMmake_palette() creates and writes a dataset + * named \p pal_name. Attributes conforming to the HDF5 Image and + * Palette specification are attached to the dataset, thus + * identifying it as a palette. The palette data is of the + * type #H5T_NATIVE_UCHAR. + * + */ H5_HLDLL herr_t H5IMmake_palette(hid_t loc_id, const char *pal_name, const hsize_t *pal_dims, const unsigned char *pal_data); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Attaches a palette to an image. + * + * \fg_loc_id + * \param[in] image_name The name of the dataset to attach the palette to + * \param[in] pal_name The name of the palette + * + * \return \herr_t + * + * \details H5IMlink_palette() attaches a palette named \p pal_name + * to an image specified by \p image_name. The image dataset + * may or not already have an attached palette. If it has, + * the array of palette references is extended to hold the reference + * to the new palette. + * + */ H5_HLDLL herr_t H5IMlink_palette(hid_t loc_id, const char *image_name, const char *pal_name); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Dettaches a palette from an image. + * + * \fg_loc_id + * \param[in] image_name The name of the image dataset + * \param[in] pal_name The name of the palette + * + * \return \herr_t + * + * \details H5IMunlink_palette() dettaches a palette from an image + * specified by \p image_name. + * + */ H5_HLDLL herr_t H5IMunlink_palette(hid_t loc_id, const char *image_name, const char *pal_name); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Gets the number of palettes associated to an image. + * + * \fg_loc_id + * \param[in] image_name The name of the image dataset + * \param[out] npals The number of palettes + * + * \return \herr_t + * + * \details H5IMget_npalettes() gets the number of palettes associated to + * an image specified by \p image_name. + * + */ H5_HLDLL herr_t H5IMget_npalettes(hid_t loc_id, const char *image_name, hssize_t *npals); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Gets information about a palette dataset (dimensions). + * + * \fg_loc_id + * \param[in] image_name The name of the image dataset + * \param[in] pal_number The zero based index that identifies + * the palette + * \param[out] pal_dims The dimensions of the palette dataset + * + * \return \herr_t + * + * \details H5IMget_palette_info() gets the dimensions of the palette + * dataset identified by \p pal_number (a zero based index) + * associated to an image specified by \p image_name. + * + */ H5_HLDLL herr_t H5IMget_palette_info(hid_t loc_id, const char *image_name, int pal_number, hsize_t *pal_dims); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Gets the palette dataset. + * + * \fg_loc_id + * \param[in] image_name The name of the image dataset + * \param[in] pal_number The zero based index that identifies + * the palette + * \param[out] pal_data The palette dataset + * + * \return \herr_t + * + * \details H5IMget_palette() gets the palette dataset identified + * by \p pal_number (a zero based index) associated to an + * image specified by \p image_name. + * + */ H5_HLDLL herr_t H5IMget_palette(hid_t loc_id, const char *image_name, int pal_number, unsigned char *pal_data); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Inquires if a dataset is an image. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset + * + * \return \htri_t + * + * \details H5IMis_image() inquires if a dataset named \p dset_name, + * attached to the file or group specified by the identifier + * \p loc_id, is an image based on the HDF5 Image and Palette + * Specification. + * + */ H5_HLDLL herr_t H5IMis_image(hid_t loc_id, const char *dset_name); +/** + * -------------------------------------------------------------------------- + * \ingroup H5IM + * + * \brief Inquires if a dataset is a palette + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset + * + * \return \htri_t + * + * \details H5IMis_palette() inquires if a dataset named \p dset_name, + * attached to the file or group specified by the + * identifier \p loc_id, is a palette based on the HDF5 + * Image and Palette Specification. + * + */ H5_HLDLL herr_t H5IMis_palette(hid_t loc_id, const char *dset_name); #ifdef __cplusplus diff --git a/hl/src/H5LDpublic.h b/hl/src/H5LDpublic.h index 011b208..e42c8d8 100644 --- a/hl/src/H5LDpublic.h +++ b/hl/src/H5LDpublic.h @@ -18,8 +18,146 @@ extern "C" { #endif +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Retrieves the current dimension sizes of a dataset. + * + * \param[in] did The dataset identifier + * \param[out] cur_dims The current dimension sizes of the dataset + * + * \return \herr_t + * + * \details H5LDget_dset_dims() retrieves the current dimension sizes + * for the dataset \p did through the parameter \p cur_dims. + * It will return failure if \p cur_dims is NULL. + * + * \note See Also: + * \note Dataset Watch functions (used with \ref h5watch): + * - H5LDget_dset_dims() + * - H5LDget_dset_elmts() + * - H5LDget_dset_type_size() + * + * \par Example: + * See the example code in H5LDget_dset_elmts() for usage of this routine. + * + * \since 1.10.0 + * + */ H5_HLDLL herr_t H5LDget_dset_dims(hid_t did, hsize_t *cur_dims); + +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Returns the size in bytes of the dataset’s datatype + * + * \param[in] did The dataset identifier + * \param[in] fields The pointer to a comma-separated list of fields for a compound datatype + * + * \return If successful, returns the size in bytes of the + * dataset’s datatype. Otherwise, returns 0. + * + * \details H5LDget_dset_type_size() allows the user to find out the datatype + * size for the dataset associated with \p did. If the + * parameter \p fields is NULL, this routine just returns the size + * of the dataset’s datatype. If the dataset has a compound datatype + * and \p fields is non-NULL, this routine returns the size of the + * datatype(s) for the selected fields specified in \p fields. + * Note that ’,’ is the separator for the fields of a compound + * datatype while ’.’ (dot) is the separator for a nested field. + * Use a backslash ( \ ) to escape characters in field names that + * conflict with these two separators. + * + * \note See Also: + * \note Dataset Watch functions (used with \ref h5watch): + * - H5LDget_dset_dims() + * - H5LDget_dset_elmts() + * - H5LDget_dset_type_size() + * + * \par Example: + * See the example code in H5LDget_dset_elmts() for usage of this routine. + * + * \since 1.10.0 + * + */ H5_HLDLL size_t H5LDget_dset_type_size(hid_t did, const char *fields); + +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Retrieves selected data from the dataset + * + * \param[in] did The dataset identifier + * \param[in] prev_dims The previous dimension size of the dataset + * \param[in] cur_dims The current dimension sizes of the dataset + * \param[in] fields A string containing a comma-separated list + * of fields for a compound datatype + * \param[out] buf Buffer for storing data retrieved from the + * dataset + * + * \return \herr_t + * + * \details H5LDget_dset_dims() retrieves selected data of the dataset + * \p did and stores the data in the parameter \p buf. + * The difference between the parameters \p prev_dims and + * \p cur_dims indicates the dimension sizes of the data to be + * selected from the dataset. Note that \p cur_dims must have + * at least one dimension whose size is greater than the + * corresponding dimension in \p prev_dims. Users can + * determine the size of buf by multipling the datatype + * size of the dataset by the number of selected elements. + * + * If the parameter \p fields is NULL, this routine returns + * data for the selected elements of the dataset. If \p fields + * is not NULL and the dataset has a compound datatype, \p fields + * is a string containing a comma-separated list of fields. + * Each name in \p fields specifies a field in the compound + * datatype, and this routine returns data of the selected fields + * for the dataset's selected elements. Note that ’,’ is the + * separator for the fields of a compound datatype while + * ’.’ is the separator for a nested field. Use backslash to + * escape characters in field names that conflict with these + * two separators. + * + * \note See Also: + * \note Dataset Watch functions (used with \ref h5watch): + * - H5LDget_dset_dims() + * - H5LDget_dset_elmts() + * - H5LDget_dset_type_size() + * + * \par Examples: + * + * For the first example, \c DSET1 is a two-dimensional chunked dataset with atomic type defined below: + * \snippet H5LDget_dset_elmts.c first_declare + * + * The following coding sample illustrates the reading of + * data elements appended to the dataset \c DSET1: + * \snippet H5LDget_dset_elmts.c first_reading + * + * The output buffer will contain data elements selected from + * \c DSET1 as follows: + * \snippet H5LDget_dset_elmts.c first_output + * + * For the second example, DSET2 is a one-dimensional chunked dataset + * with compound type defined below: + * \snippet H5LDget_dset_elmts.c second_declare + * + * The following coding sample illustrates the reading of data elements + * appended to the dataset \c DSET2 with compound datatype. + * This example selects only 2 fields: the fourth field \c d and a + * subfield of the sixth field \c s2.c: + * \snippet H5LDget_dset_elmts.c second_reading + * + * The output buffer will contain data for \c d and \c s2.c + * selected from \c DSET2 as follows: + * \snippet H5LDget_dset_elmts.c second_output + * + * \since 1.10.0 + * + */ H5_HLDLL herr_t H5LDget_dset_elmts(hid_t did, const hsize_t *prev_dims, const hsize_t *cur_dims, const char *fields, void *buf); diff --git a/hl/src/H5LTpublic.h b/hl/src/H5LTpublic.h index a6c7c84..53cd38e 100644 --- a/hl/src/H5LTpublic.h +++ b/hl/src/H5LTpublic.h @@ -35,6 +35,120 @@ typedef enum H5LT_lang_t { extern "C" { #endif +/**\defgroup H5LT Lite + * Functions used to simplify creating and manipulating datasets, + * attributes and other features (H5LT, H5LD) + * + * The HDF5 Lite API consists of higher-level functions which do + * more operations per call than the basic HDF5 interface. + * The purpose is to wrap intuitive functions around certain sets + * of features in the existing APIs. + * It has the following sets of functions listed below. + * + * \note \Bold{Programming hints:} + * \note To use any of these functions or subroutines, + * you must first include the relevant include file (C) or + * module (Fortran) in your application. + * \note The following line includes the HDF5 Lite package, H5LT, + * in C applications: + * \code #include "hdf5_hl.h" \endcode + * \note This line includes the H5LT module in Fortran applications: + * \code use h5lt \endcode + * + * + * + *
+ * + * - Dataset Functions + * - Make dataset functions + * - \ref H5LTmake_dataset + * - \ref H5LTmake_dataset_char + * - \ref H5LTmake_dataset_short + * - \ref H5LTmake_dataset_int + * - \ref H5LTmake_dataset_long + * - \ref H5LTmake_dataset_float + * - \ref H5LTmake_dataset_double + * - \ref H5LTmake_dataset_string + * + * - Read dataset functions + * - \ref H5LTread_dataset + * - \ref H5LTread_dataset_char + * - \ref H5LTread_dataset_short + * - \ref H5LTread_dataset_int + * - \ref H5LTread_dataset_long + * - \ref H5LTread_dataset_float + * - \ref H5LTread_dataset_double + * - \ref H5LTread_dataset_string + * + * - Query dataset functions + * - \ref H5LTfind_dataset + * - \ref H5LTget_dataset_ndims + * - \ref H5LTget_dataset_info + * + * - Dataset watch functions + * - \ref H5LDget_dset_dims + * - \ref H5LDget_dset_elmts + * - \ref H5LDget_dset_type_size + * + * + * + * - Attribute Functions + * - Set attribute functions + * - \ref H5LTset_attribute_string + * - \ref H5LTset_attribute_char + * - \ref H5LTset_attribute_uchar + * - \ref H5LTset_attribute_short + * - \ref H5LTset_attribute_ushort + * - \ref H5LTset_attribute_int + * - \ref H5LTset_attribute_uint + * - \ref H5LTset_attribute_long + * - \ref H5LTset_attribute_long_long + * - \ref H5LTset_attribute_ulong + * - \ref H5LTset_attribute_ullong + * - \ref H5LTset_attribute_float + * - \ref H5LTset_attribute_double + * - H5LTset_attribute_f (fortran ONLY) + * + * - Get attribute functions + * - \ref H5LTget_attribute + * - \ref H5LTget_attribute_string + * - \ref H5LTget_attribute_char + * - \ref H5LTget_attribute_uchar + * - \ref H5LTget_attribute_short + * - \ref H5LTget_attribute_ushort + * - \ref H5LTget_attribute_int + * - \ref H5LTget_attribute_uint + * - \ref H5LTget_attribute_long + * - \ref H5LTget_attribute_long_long + * - \ref H5LTget_attribute_ulong + * - \ref H5LTget_attribute_ullong + * - \ref H5LTget_attribute_float + * - \ref H5LTget_attribute_double + * + * - Query attribute functions + * - \ref H5LTfind_attribute + * - \ref H5LTget_attribute_info + * - \ref H5LTget_attribute_ndims + * + * + * + * - Datatype Functions + * - Datatype translation functions + * - \ref H5LTtext_to_dtype + * - \ref H5LTdtype_to_text + * + * - File image function + * - Open file image function + * - \ref H5LTopen_file_image + * + * - Path and object function + * - Query path and object function + * - \ref H5LTpath_valid + * + *
+ * + */ + /*------------------------------------------------------------------------- * * Make dataset functions @@ -42,27 +156,214 @@ extern "C" { *------------------------------------------------------------------------- */ +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes a dataset of a type \p type_id. + * + * \fg_loc_id + * \param[in] dset_name The Name of the dataset to create + * \param[in] rank Number of dimensions of dataspace + * \param[in] dims An array of the size of each dimension + * \param[in] type_id Identifier of the datatype to use when creating the dataset + * \param[in] buffer Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5LTmake_dataset() creates and writes a dataset named + * \p dset_name attached to the object specified by the + * identifier \p loc_id. + * + * The parameter \p type_id can be any valid HDF5 Prdefined \ref PDTNAT; + * For example, setting \p type_id to #H5T_NATIVE_INT will result in a dataset + * of signed \e integer datatype. + * + * \version 1.10.0 Fortran 2003 subroutine added to accept a C address of the data buffer. + * \version 1.8.7 Fortran subroutine modified in this release to accommodate arrays + * with more than three dimensions. + * + */ H5_HLDLL herr_t H5LTmake_dataset(hid_t loc_id, const char *dset_name, int rank, const hsize_t *dims, hid_t type_id, const void *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes a dataset. + * + * \fg_loc_id + * \param[in] dset_name The Name of the dataset to create + * \param[in] rank Number of dimensions of dataspace + * \param[in] dims An array of the size of each dimension + * \param[in] buffer Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5LTmake_dataset_char() creates and writes a dataset + * named \p dset_name attached to the object specified by + * the identifier \p loc_id. + * + * The dataset’s datatype will be \e character, #H5T_NATIVE_CHAR. + * + */ H5_HLDLL herr_t H5LTmake_dataset_char(hid_t loc_id, const char *dset_name, int rank, const hsize_t *dims, const char *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes a dataset. + * + * \fg_loc_id + * \param[in] dset_name The Name of the dataset to create + * \param[in] rank Number of dimensions of dataspace + * \param[in] dims An array of the size of each dimension + * \param[in] buffer Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5LTmake_dataset_short() creates and writes a dataset + * named \p dset_name attached to the object specified by + * the identifier \p loc_id. + * + * The dataset’s datatype will be short signed integer, + * #H5T_NATIVE_SHORT. + * + */ H5_HLDLL herr_t H5LTmake_dataset_short(hid_t loc_id, const char *dset_name, int rank, const hsize_t *dims, const short *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes a dataset. + * + * \fg_loc_id + * \param[in] dset_name The Name of the dataset to create + * \param[in] rank Number of dimensions of dataspace + * \param[in] dims An array of the size of each dimension + * \param[in] buffer Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5LTmake_dataset_int() creates and writes a dataset + * named \p dset_name attached to the object specified by + * the identifier \p loc_id. + * + * The dataset’s datatype will be native signed integer, + * #H5T_NATIVE_INT. + * + * \version Fortran subroutine modified in this release to accommodate + * arrays with more than three dimensions. + * + */ H5_HLDLL herr_t H5LTmake_dataset_int(hid_t loc_id, const char *dset_name, int rank, const hsize_t *dims, const int *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes a dataset. + * + * \fg_loc_id + * \param[in] dset_name The Name of the dataset to create + * \param[in] rank Number of dimensions of dataspace + * \param[in] dims An array of the size of each dimension + * \param[in] buffer Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5LTmake_dataset_long() creates and writes a dataset + * named \p dset_name attached to the object specified by + * the identifier \p loc_id. + * + * The dataset’s datatype will be long signed integer, + * #H5T_NATIVE_LONG. + * + */ H5_HLDLL herr_t H5LTmake_dataset_long(hid_t loc_id, const char *dset_name, int rank, const hsize_t *dims, const long *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes a dataset. + * + * \fg_loc_id + * \param[in] dset_name The Name of the dataset to create + * \param[in] rank Number of dimensions of dataspace + * \param[in] dims An array of the size of each dimension + * \param[in] buffer Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5LTmake_dataset_float() creates and writes a dataset + * named \p dset_name attached to the object specified by + * the identifier \p loc_id. + * + * The dataset’s datatype will be native floating point, + * #H5T_NATIVE_FLOAT. + * + * \version 1.8.7 Fortran subroutine modified in this release to accommodate + * arrays with more than three dimensions. + * + */ H5_HLDLL herr_t H5LTmake_dataset_float(hid_t loc_id, const char *dset_name, int rank, const hsize_t *dims, const float *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes a dataset. + * + * \fg_loc_id + * \param[in] dset_name The Name of the dataset to create + * \param[in] rank Number of dimensions of dataspace + * \param[in] dims An array of the size of each dimension + * \param[in] buffer Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5LTmake_dataset_double() creates and writes a dataset + * named \p dset_name attached to the object specified by + * the identifier \p loc_id. + * + * The dataset’s datatype will be + * native floating-point double, #H5T_NATIVE_DOUBLE. + * + * \version 1.8.7 Fortran subroutine modified in this release to accommodate + * arrays with more than three dimensions. + * + */ H5_HLDLL herr_t H5LTmake_dataset_double(hid_t loc_id, const char *dset_name, int rank, const hsize_t *dims, const double *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes a dataset with string datatype. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to create + * \param[in] buf Buffer with data to be written to the dataset + * + * \return \herr_t + * + * \details H5LTmake_dataset_string() creates and writes a dataset + * named \p dset_name attached to the object specified by + * the identifier \p loc_id. + * + * The dataset’s datatype will be C string, #H5T_C_S1. + * + */ H5_HLDLL herr_t H5LTmake_dataset_string(hid_t loc_id, const char *dset_name, const char *buf); /*------------------------------------------------------------------------- @@ -72,20 +373,169 @@ H5_HLDLL herr_t H5LTmake_dataset_string(hid_t loc_id, const char *dset_name, con *------------------------------------------------------------------------- */ +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads a dataset from disk. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[in] type_id Identifier of the datatype to use when reading + * the dataset + * \param[out] buffer Buffer with data + * + * \return \herr_t + * + * \details H5LTread_dataset() reads a dataset named \p dset_name + * attached to the object specified by the identifier \p loc_id. + * + * \version 1.10.0 Fortran 2003 subroutine added to accept a C + * address of the data buffer. + * \version 1.8.7 Fortran subroutine modified in this release to + * accommodate arrays with more than three dimensions. + * + */ H5_HLDLL herr_t H5LTread_dataset(hid_t loc_id, const char *dset_name, hid_t type_id, void *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads a dataset from disk. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[out] buffer Buffer with data + * + * \return \herr_t + * + * \details H5LTread_dataset_char() reads a dataset named \p dset_name + * attached to the object specified by the identifier \p loc_id. + * The HDF5 datatype is #H5T_NATIVE_CHAR. + * + */ H5_HLDLL herr_t H5LTread_dataset_char(hid_t loc_id, const char *dset_name, char *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads a dataset from disk. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[out] buffer Buffer with data + * + * \return \herr_t + * + * \details H5LTread_dataset_short() reads a dataset named \p dset_name + * attached to the object specified by the identifier \p loc_id. + * The HDF5 datatype is #H5T_NATIVE_SHORT. + * + */ H5_HLDLL herr_t H5LTread_dataset_short(hid_t loc_id, const char *dset_name, short *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads a dataset from disk. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[out] buffer Buffer with data + * + * \return \herr_t + * + * \details H5LTread_dataset_int() reads a dataset named \p dset_name + * attached to the object specified by the identifier \p loc_id. + * The HDF5 datatype is #H5T_NATIVE_INT. + * + * \version 1.8.7 Fortran subroutine modified in this release to + * accommodate arrays with more than three dimensions. + * + */ H5_HLDLL herr_t H5LTread_dataset_int(hid_t loc_id, const char *dset_name, int *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads a dataset from disk. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[out] buffer Buffer with data + * + * \return \herr_t + * + * \details H5LTread_dataset_long() reads a dataset named \p dset_name + * attached to the object specified by the identifier \p loc_id. + * The HDF5 datatype is #H5T_NATIVE_LONG. + * + */ H5_HLDLL herr_t H5LTread_dataset_long(hid_t loc_id, const char *dset_name, long *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads a dataset from disk. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[out] buffer Buffer with data + * + * \return \herr_t + * + * \details H5LTread_dataset_float() reads a dataset named \p dset_name + * attached to the object specified by the identifier \p loc_id. + * The HDF5 datatype is #H5T_NATIVE_FLOAT. + * + * \version 1.8.7 Fortran subroutine modified in this release to + * accommodate arrays with more than three dimensions. + */ H5_HLDLL herr_t H5LTread_dataset_float(hid_t loc_id, const char *dset_name, float *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads a dataset from disk. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[out] buffer Buffer with data + * + * \return \herr_t + * + * \details H5LTread_dataset_double() reads a dataset named \p dset_name + * attached to the object specified by the identifier \p loc_id. + * The HDF5 datatype is #H5T_NATIVE_DOUBLE. + * + * \version 1.8.7 Fortran subroutine modified in this release to + * accommodate arrays with more than three dimensions. + */ H5_HLDLL herr_t H5LTread_dataset_double(hid_t loc_id, const char *dset_name, double *buffer); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads a dataset from disk. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[out] buf Buffer with data + * + * \return \herr_t + * + * \details H5LTread_dataset_string() reads a dataset named \p dset_name + * attached to the object specified by the identifier \p loc_id. + * The HDF5 datatype is #H5T_C_S1. + * + */ H5_HLDLL herr_t H5LTread_dataset_string(hid_t loc_id, const char *dset_name, char *buf); /*------------------------------------------------------------------------- @@ -95,11 +545,67 @@ H5_HLDLL herr_t H5LTread_dataset_string(hid_t loc_id, const char *dset_name, cha *------------------------------------------------------------------------- */ +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Gets the dimensionality of a dataset + * + * \param[in] loc_id Identifier of the object to + * locate the dataset within + * \param[in] dset_name The dataset name + * \param[out] rank The dimensionality of the dataset + * + * \return \herr_t + * + * \details H5LTget_dataset_ndims() gets the dimensionality of a dataset + * named \p dset_name exists attached to the object \p loc_id. + * + */ H5_HLDLL herr_t H5LTget_dataset_ndims(hid_t loc_id, const char *dset_name, int *rank); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Retrieves information about a dataset + * + * \param[in] loc_id Identifier of the object to locate + * the dataset within + * \param[in] dset_name The dataset name + * \param[out] dims The dimensions of the dataset + * \param[out] type_class The class identifier. #H5T_class_t is defined in + * H5Tpublic.h. See H5Tget_class() for a list + * of class types. + * \param[out] type_size The size of the datatype in bytes + * + * \return \herr_t + * + * \details H5LTget_dataset_info() retrieves information about a dataset + * named \p dset_name attached to the object \p loc_id. + * + */ H5_HLDLL herr_t H5LTget_dataset_info(hid_t loc_id, const char *dset_name, hsize_t *dims, H5T_class_t *type_class, size_t *type_size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Determines whether a dataset exists. + * + * \param[in] loc_id Identifier of the group containing the dataset + * \param[in] name Dataset name + * + * \return \htri_t + * + * \details H5LTfind_dataset() determines whether a dataset named + * \p name exists in the group specified by \p loc_id. + * + * \p loc_id must be a group identifier and \p name must + * specify a dataset that is a member of that group. + * + */ H5_HLDLL herr_t H5LTfind_dataset(hid_t loc_id, const char *name); /*------------------------------------------------------------------------- @@ -109,42 +615,343 @@ H5_HLDLL herr_t H5LTfind_dataset(hid_t loc_id, const char *name); *------------------------------------------------------------------------- */ +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes a string attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] attr_data Buffer with data to be written to the attribute + * + * \return \herr_t + * + * \details H5LTset_attribute_string() creates and writes a string attribute + * named \p attr_name and attaches it to the object specified by + * the name \p obj_name. If the attribute already exists, + * it is overwritten. + * + */ H5_HLDLL herr_t H5LTset_attribute_string(hid_t loc_id, const char *obj_name, const char *attr_name, const char *attr_data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_char() creates and writes a numerical attribute + * named \p attr_name and attaches it to the object specified by the + * name \p obj_name. The attribute has a dimensionality of 1. + * The HDF5 datatype of the attribute is #H5T_NATIVE_CHAR. + * + */ H5_HLDLL herr_t H5LTset_attribute_char(hid_t loc_id, const char *obj_name, const char *attr_name, const char *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_uchar() creates and writes a numerical attribute + * named \p attr_name and attaches it to the object specified by the + * name \p obj_name. The attribute has a dimensionality of 1. + * The HDF5 datatype of the attribute is #H5T_NATIVE_UCHAR. + * + */ H5_HLDLL herr_t H5LTset_attribute_uchar(hid_t loc_id, const char *obj_name, const char *attr_name, const unsigned char *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_short() creates and writes a numerical attribute + * named \p attr_name and attaches it to the object specified by the + * name \p obj_name. The attribute has a dimensionality of 1. + * The HDF5 datatype of the attribute is #H5T_NATIVE_SHORT. + * + */ H5_HLDLL herr_t H5LTset_attribute_short(hid_t loc_id, const char *obj_name, const char *attr_name, const short *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_ushort() creates and writes a numerical attribute + * named \p attr_name and attaches it to the object specified by the + * name \p obj_name. The attribute has a dimensionality of 1. + * The HDF5 datatype of the attribute is #H5T_NATIVE_USHORT. + * + */ H5_HLDLL herr_t H5LTset_attribute_ushort(hid_t loc_id, const char *obj_name, const char *attr_name, const unsigned short *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_int() creates and writes a numerical integer + * attribute named \p attr_name and attaches it to the object + * specified by the name \p obj_name. The attribute has a + * dimensionality of 1. The HDF5 datatype of the attribute + * is #H5T_NATIVE_INT. + * + */ H5_HLDLL herr_t H5LTset_attribute_int(hid_t loc_id, const char *obj_name, const char *attr_name, const int *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_uint() creates and writes a numerical integer + * attribute named \p attr_name and attaches it to the object specified + * by the name \p obj_name. The attribute has a dimensionality of 1. + * The HDF5 datatype of the attribute is #H5T_NATIVE_UINT. + * + */ H5_HLDLL herr_t H5LTset_attribute_uint(hid_t loc_id, const char *obj_name, const char *attr_name, const unsigned int *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_long() creates and writes a numerical + * attribute named \p attr_name and attaches it to the object + * specified by the name \p obj_name. The attribute has a + * dimensionality of 1. The HDF5 datatype of the attribute + * is #H5T_NATIVE_LONG. + * + */ H5_HLDLL herr_t H5LTset_attribute_long(hid_t loc_id, const char *obj_name, const char *attr_name, const long *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Location of the object to which the attribute + * is to be attached + * \param[in] obj_name That object's name + * \param[in] attr_name Attribute name + * \param[in] buffer Attribute value + * \param[in] size Attribute size + * + * \return \herr_t + * + * \details H5LTset_attribute_long_long() creates and writes a numerical + * attribute named \p attr_name and attaches it to the object + * specified by the name \p obj_name. + * + * The attribute has a dimensionality of 1 and its HDF5 datatype + * is #H5T_NATIVE_LLONG. + * + */ H5_HLDLL herr_t H5LTset_attribute_long_long(hid_t loc_id, const char *obj_name, const char *attr_name, const long long *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_ulong() creates and writes a numerical + * attribute named \p attr_name and attaches it to the object + * specified by the name \p obj_name. The attribute has a + * dimensionality of 1. The HDF5 datatype of the attribute + * is #H5T_NATIVE_ULONG. + * + */ H5_HLDLL herr_t H5LTset_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_name, const unsigned long *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Location of the object to which the attribute + * is to be attached + * \param[in] obj_name That object's name + * \param[in] attr_name Attribute name + * \param[in] buffer Attribute value + * \param[in] size Attribute size + * + * \return \herr_t + * + * \details H5LTset_attribute_ullong() creates and writes a numerical + * attribute named \p attr_name and attaches it to the object + * specified by the name \p obj_name. + * + * The attribute has a dimensionality of 1 and its HDF5 datatype + * is #H5T_NATIVE_ULLONG. + * + */ H5_HLDLL herr_t H5LTset_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, const unsigned long long *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_float() creates and writes a numerical + * floating point attribute named \p attr_name and attaches + * it to the object specified by the name \p obj_name. + * The attribute has a dimensionality of 1. The HDF5 datatype + * of the attribute is #H5T_NATIVE_FLOAT. + * + */ H5_HLDLL herr_t H5LTset_attribute_float(hid_t loc_id, const char *obj_name, const char *attr_name, const float *buffer, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates and writes an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to create the attribute within + * \param[in] obj_name The name of the object to attach the attribute + * \param[in] attr_name The attribute name + * \param[in] buffer Buffer with data to be written to the attribute + * \param[in] size The size of the 1D array (one in the case of a + * scalar attribute). This value is used by + * H5Screate_simple() to create the dataspace. + * + * \return \herr_t + * + * \details H5LTset_attribute_double() creates and writes a numerical + * attribute named \p attr_name and attaches + * it to the object specified by the name \p obj_name. + * The attribute has a dimensionality of 1. The HDF5 datatype + * of the attribute is #H5T_NATIVE_DOUBLE. + * + */ H5_HLDLL herr_t H5LTset_attribute_double(hid_t loc_id, const char *obj_name, const char *attr_name, const double *buffer, size_t size); @@ -155,42 +962,337 @@ H5_HLDLL herr_t H5LTset_attribute_double(hid_t loc_id, const char *obj_name, con *------------------------------------------------------------------------- */ +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[in] mem_type_id Identifier of the memory datatype + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute() reads an attribute named + * \p attr_name with the memory type \p mem_type_id. + * + */ H5_HLDLL herr_t H5LTget_attribute(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t mem_type_id, void *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_string() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The datatype is a string. + * + * \version 1.8.9 The content of the buffer returned by the Fortran + * subroutine has changed in this release:\n + * If the returned buffer requires padding, + * h5ltget_attribute_string_f() now employs space + * padding; this buffer was previously returned with a C NULL terminator. + * + */ H5_HLDLL herr_t H5LTget_attribute_string(hid_t loc_id, const char *obj_name, const char *attr_name, char *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_char() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The datatype of the attribute + * is #H5T_NATIVE_CHAR. + * + */ H5_HLDLL herr_t H5LTget_attribute_char(hid_t loc_id, const char *obj_name, const char *attr_name, char *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_uchar() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_UCHAR + * + */ H5_HLDLL herr_t H5LTget_attribute_uchar(hid_t loc_id, const char *obj_name, const char *attr_name, unsigned char *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_short() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_SHORT + * + */ H5_HLDLL herr_t H5LTget_attribute_short(hid_t loc_id, const char *obj_name, const char *attr_name, short *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_ushort() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_USHORT. + * + */ H5_HLDLL herr_t H5LTget_attribute_ushort(hid_t loc_id, const char *obj_name, const char *attr_name, unsigned short *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_int() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_INT. + * + */ H5_HLDLL herr_t H5LTget_attribute_int(hid_t loc_id, const char *obj_name, const char *attr_name, int *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_uint() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_INT. + * + */ H5_HLDLL herr_t H5LTget_attribute_uint(hid_t loc_id, const char *obj_name, const char *attr_name, unsigned int *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_long() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_LONG. + * + */ H5_HLDLL herr_t H5LTget_attribute_long(hid_t loc_id, const char *obj_name, const char *attr_name, long *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads a \e long \e long attribute. + * + * \param[in] loc_id Location of the object to which + * the attribute is attached + * \param[in] obj_name That object's name + * \param[in] attr_name Attribute name + * \param[out] data Attribute value + * + * \return \herr_t + * + * \details H5LTget_attribute_long_long() reads the attribute + * specified by \p loc_id and \p obj_name. + * + */ H5_HLDLL herr_t H5LTget_attribute_long_long(hid_t loc_id, const char *obj_name, const char *attr_name, long long *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_ulong() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_ULONG. + * + */ H5_HLDLL herr_t H5LTget_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_name, unsigned long *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_ullong() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_ULLONG. + * + */ H5_HLDLL herr_t H5LTget_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, unsigned long long *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_float() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_FLOAT. + * + */ H5_HLDLL herr_t H5LTget_attribute_float(hid_t loc_id, const char *obj_name, const char *attr_name, float *data); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Reads an attribute from disk. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] data Buffer with data + * + * \return \herr_t + * + * \details H5LTget_attribute_double() reads an attribute named + * \p attr_name that is attached to the object specified + * by the name \p obj_name. The HDF5 datatype of the + * attribute is #H5T_NATIVE_DOUBLE. + * + */ H5_HLDLL herr_t H5LTget_attribute_double(hid_t loc_id, const char *obj_name, const char *attr_name, double *data); @@ -201,8 +1303,55 @@ H5_HLDLL herr_t H5LTget_attribute_double(hid_t loc_id, const char *obj_name, con *------------------------------------------------------------------------- */ +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Gets the dimensionality of an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] rank The dimensionality of the attribute + * + * \return \herr_t + * + * \details H5LTget_attribute_ndims() gets the dimensionality of an attribute + * named \p attr_name that is attached to the object specified + * by the name \p obj_name. + * + */ H5_HLDLL herr_t H5LTget_attribute_ndims(hid_t loc_id, const char *obj_name, const char *attr_name, int *rank); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Gets information about an attribute. + * + * \param[in] loc_id Identifier of the object (dataset or group) + * to read the attribute from + * \param[in] obj_name The name of the object that the attribute is + * attached to + * \param[in] attr_name The attribute name + * \param[out] dims The dimensions of the attribute + * \param[out] type_class The class identifier. #H5T_class_t is + * defined in H5Tpublic.h. For a list of valid class + * types see: H5Tget_class(). + * \param[out] type_size The size of the datatype in bytes + * + * \return \herr_t + * + * \details H5LTget_attribute_info() gets information about an attribute + * named \p attr_name attached to the object specified by + * the name \p obj_name. + * + * \par Example + * \snippet H5LT_examples.c get_attribute_info + * + */ H5_HLDLL herr_t H5LTget_attribute_info(hid_t loc_id, const char *obj_name, const char *attr_name, hsize_t *dims, H5T_class_t *type_class, size_t *type_size); @@ -213,7 +1362,74 @@ H5_HLDLL herr_t H5LTget_attribute_info(hid_t loc_id, const char *obj_name, const *------------------------------------------------------------------------- */ -H5_HLDLL hid_t H5LTtext_to_dtype(const char *text, H5LT_lang_t lang_type); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates an HDF5 datatype given a text description. + * + * \param[in] text A character string containing a DDL + * definition of the datatype to be created + * \param[in] lang_type The language used to describe the datatype. + * The only currently supported language is + * #H5LT_DDL. + * + * \return Returns the datatype identifier(non-negative) if successful; + * otherwise returns a negative value. + * + * \details Given a text description of a datatype, this function creates + * an HDF5 datatype and returns the datatype identifier. + * The text description of the datatype has to comply with the + * \p lang_type definition of HDF5 datatypes. + * Currently, only the DDL(#H5LT_DDL) is supported. + * The complete DDL definition of HDF5 datatypes can be found in + * the last chapter of the + * + * HDF5 User's Guide. + * + * \par Example + * An example of DDL definition of \c enum type is shown as follows. + * \snippet H5LT_examples.c enum + * + */ +H5_HLDLL hid_t H5LTtext_to_dtype(const char *text, H5LT_lang_t lang_type); + +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Creates a text description of an HDF5 datatype. + * + * \param[in] dtype Identifier of the datatype to be converted + * \param[out] str Buffer for the text description of the datatype + * \param[in] lang_type The language used to describe the datatype. + * The currently supported language is #H5LT_DDL. + * \param[out] len The size of buffer needed to store the text description + * + * \return \herr_t + * + * \details Given an HDF5 datatype identifier, this function creates + * a description of this datatype in \p lang_type language format. + * A preliminary H5LTdtype_to_text() call can be made to determine + * the size of the buffer needed with a NULL passed in for \p str. + * This value is returned as \p len. That value can then be assigned + * to len for a second H5Ttype_to_text() call, which will + * retrieve the actual text description for the datatype. + * + * If \p len is not big enough for the description, the text + * description will be truncated to fit in the buffer. + * + * Currently only DDL (#H5LT_DDL) is supported for \p lang_type. + * The complete DDL definition of HDF5 data types can be found in + * the last chapter of the + * + * HDF5 User's Guide. + * + * \par Example + * An example of DDL definition of \c enum type is shown as follows. + * \snippet H5LT_examples.c enum + * + */ H5_HLDLL herr_t H5LTdtype_to_text(hid_t dtype, char *str, H5LT_lang_t lang_type, size_t *len); /*------------------------------------------------------------------------- @@ -223,8 +1439,116 @@ H5_HLDLL herr_t H5LTdtype_to_text(hid_t dtype, char *str, H5LT_lang_t lang_type, *------------------------------------------------------------------------- */ +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Determines whether an attribute exists. + * + * \param[in] loc_id Identifier of the object to which the attribute + * is expected to be attached + * \param[in] name Attribute name + * + * \return \htri_t + * + * \details H5LTfind_attribute() determines whether an attribute named + * \p name exists attached to the object specified + * by \p loc_id. + * + * \p loc_id must be an object identifier and \p name + * must specify an attribute that is expected to be attached + * to that object. + * + */ H5_HLDLL herr_t H5LTfind_attribute(hid_t loc_id, const char *name); +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Determines whether an HDF5 path is valid and, optionally, + * whether the path resolves to an HDF5 object. + * + * \param[in] loc_id Identifier of an object in the file + * \param[in] path The path to the object to check; + * links in \p path may be of any type. + * \param[in] check_object_valid If TRUE, determine whether the final + * component of \p path resolves to + * an object; if FALSE, do not check. + * + * \return Upon success: + * \return If \p check_object_valid is set to \c FALSE: + * \return Returns \c TRUE if the path is valid; + * otherwise returns \c FALSE. + * \return If \p check_object_valid is set to \c TRUE: + * \return Returns \c TRUE if the path is valid and + * resolves to an HDF5 object; + * otherwise returns \c FALSE. + * + * \return Upon error, returns a negative value. + * + * \details H5LTpath_valid() checks the validity of \p path relative + * to the identifier of an object, \p loc_id. Optionally, + * \p check_object_valid can be set to determine whether the + * final component of \p path resolves to an HDF5 object; + * if not, the final component is a dangling link. + * + * The meaning of the function’s return value depends on the + * value of \p check_object_valid: + * + * If \p check_object_valid is set to \c FALSE, H5LTpath_valid() + * will check all links in \p path to verify that they exist. + * If all the links in \p path exist, the function will + * return \c TRUE; otherwise the function will return \c FALSE. + * + * If \p check_object_valid is set to \c TRUE, + * H5LTpath_valid() will first check the links in \p path, + * as described above. If all the links exist, + * \p check_object_valid will then determine whether the final + * component of \p path resolves to an actual HDF5 object. + * H5LTpath_valid() will return \c TRUE if all the links in + * \p path exist and the final component resolves to an + * actual object; otherwise, it will return \c FALSE. + * + * \p path can be any one of the following: + * + * - An absolute path, which starts with a slash (\c /) + * indicating the file’s root group, followed by the members + * - A relative path with respect to \p loc_id + * - A dot (\c .), if \p loc_id is the object identifier for + * the object itself + * . + * + * If \p path is an absolute path, then \p loc_id can be an + * identifier for any object in the file as it is used only to + * identify the file. If \p path is a relative path, then + * \p loc_id must be a file or a group identifier. + * + * \note + * Note on Behavior Change: + * The behavior of H5LTpath_valid() was changed in the 1.10.0 release + * in the case where the root group, “/”, is the value of path. + * This change is described below: + * - Let \p loc_id denote a valid HDF5 file identifier, and let + * \p check_object_valid be set to true or false. + * A call to H5LTpath_valid() with arguments \p loc_id, “/”, + * and \p check_object_valid returns a positive value; + * in other words, H5LTpath_valid(loc_id, "/", check_object_valid) + * returns a positive value. + * In HDF5 version 1.8.16, this function returns 0. + * - Let ‘root’ denote a valid HDF5 group identifier that refers + * to the root group of an HDF5 file, and let \p check_object_valid + * be set to true or false. + * A call to H5LTpath_valid() with arguments ‘root’, “/”, and + * \p check_object_valid returns a positive value; + * in other words, H5LTpath_valid(root, "/", check_object_valid) + * returns a positive value. + * In HDF5 version 1.8.16, this function returns 0. + * + * \version 1.10.0 Function behavior changed in this release. + * See the “Note on Behavior Change” section above. + * + */ H5_HLDLL htri_t H5LTpath_valid(hid_t loc_id, const char *path, hbool_t check_object_valid); /*------------------------------------------------------------------------- @@ -234,6 +1558,80 @@ H5_HLDLL htri_t H5LTpath_valid(hid_t loc_id, const char *path, hbool_t check_obj *------------------------------------------------------------------------- */ +/** + *------------------------------------------------------------------------- + * \ingroup H5LT + * + * \brief Opens an HDF5 file image in memory. + * + * \param[in] buf_ptr A pointer to the supplied initial image + * \param[in] buf_size Size of the supplied buffer + * \param[in] flags Flags specifying whether to open the image + * read-only or read/write, whether HDF5 is to + * take control of the buffer, and instruction + * regarding releasing the buffer. + * + * \return Returns a file identifier if successful; + * otherwise returns a negative value. + * \warning \Bold{Failure Modes:} + * \warning H5LTopen_file_image() will fail if either \p buf_ptr is NULL + * or \p buf_size equals 0 (zero). + * + * + * \details H5LTopen_file_image() opens the HDF5 file image that is + * located in system memory at the address indicated by + * \p buf_ptr of size \p buf_size. + * H5LTopen_file_image() opens a file image with the + * Core driver, #H5FD_CORE. + * + * A value of NULL for \p buf_ptr is invalid and will + * cause the function to fail. + * + * A value of 0 for \p buf_size is invalid and will cause + * the function to fail. + * + * The flags passed in \p flags specify whether to open the image + * read-only or read/write, whether HDF5 is to take control of the + * buffer, and instruction regarding releasing the buffer. + * Valid values are: + * - #H5LT_FILE_IMAGE_OPEN_RW + * - Specifies opening the file image in read/write mode. + * - Default without this flag: File image will be opened read-only. + * + * - #H5LT_FILE_IMAGE_DONT_COPY + * - Specifies to not copy the provided file image buffer; + * the buffer will be used directly. HDF5 will release the + * file image when finished. + * - Default without this flag: Copy the file image buffer and + * open the copied file image. + * + * - #H5LT_FILE_IMAGE_DONT_RELEASE + * - Specifies that HDF5 is not to release the buffer when + * the file opened with H5LTopen_file_image() is closed; + * releasing the buffer will be left to the application. + * - Default without this flag: HDF5 will automatically + * release the file image buffer after the file image is + * closed. This flag is valid only when used with + * #H5LT_FILE_IMAGE_DONT_COPY. + * + * \note **Motivation:** + * \note H5LTopen_file_image() and other elements of HDF5 + * are used to load an image of an HDF5 file into system memory + * and open that image as a regular HDF5 file. An application can + * then use the file without the overhead of disk I/O. + * + * \note **Recommended Reading:** + * \note This function is part of the file image operations feature set. + * It is highly recommended to study the guide + * + * HDF5 File Image Operations before using this feature set.\n + * See the “See Also” section below for links to other elements of + * HDF5 file image operations. + * + * \todo There is no "See Also" section??? + * + * \since 1.8.9 + */ H5_HLDLL hid_t H5LTopen_file_image(void *buf_ptr, size_t buf_size, unsigned flags); #ifdef __cplusplus diff --git a/hl/src/H5PTpublic.h b/hl/src/H5PTpublic.h index d74baa5..185e4a4 100644 --- a/hl/src/H5PTpublic.h +++ b/hl/src/H5PTpublic.h @@ -18,19 +18,200 @@ extern "C" { #endif +/**\defgroup H5PT Packet Table + * + * Creating and manipulating HDF5 datasets to support append- + * and read-only operations on table data (H5PT) + * + * The HDF5 Packet Table API is designed to allow records to be + * appended to and read from a table. Packet Table datasets are + * chunked, allowing them to grow as needed. + * + * The Packet Table API, with the H5PT prefix, is not to be confused with + * the H5TB Table API (H5TB prefix). The H5TB APIs are stateless + * (H5TB Tables do not need to be opened or closed) but H5PT Packet Tables + * require less performance overhead. Also, H5TB Tables support insertions + * and deletions, while H5PT Packet Tables support only append operations. + * H5TB functions should not be called on tables created with the + * H5PT API, or vice versa. + * + * Packet Tables are datasets in an HDF5 file, so while their contents + * should not be changed outside of the H5PT API calls, the datatypes of + * Packet Tables can be queried using \ref H5Dget_type. + * Packet Tables can also be given attributes using the normal HDF5 APIs. + * + * \note \Bold{Programming hints:} + * \note The following line includes the HDF5 Packet Table package, H5PT, + * in C applications: + * \code #include "hdf5_hl.h" \endcode + * Without this include, an application will not have access to + * these functions. + * + * - \ref H5PTappend + * \n Appends packets to the end of a packet table. + * - \ref H5PTclose + * \n Closes an open packet table. + * - \ref H5PTcreate + * \n Creates a packet table to store fixed-length + * or variable-length packets. + * - \ref H5PTcreate_fl + * \n Creates a packet table to store fixed-length packets. + * - \ref H5PTcreate_index + * \n Resets a packet table's index to the first packet. + * - \ref H5PTfree_vlen_buff + * \n Releases memory allocated in the process of + * reading variable-length packets. + * - \ref H5PTget_dataset + * \n Returns the backend dataset of this packet table. + * - \ref H5PTget_index + * \n Gets the current record index for a packet table + * - \ref H5PTget_next + * \n Reads packets from a packet table starting at the + * current index. + * - \ref H5PTget_num_packets + * \n Returns the number of packets in a packet table. + * - \ref H5PTget_type + * \n Returns the backend datatype of this packet table. + * - \ref H5PTis_valid + * \n Determines whether an identifier points to a packet table. + * - \ref H5PTis_varlen + * \n Determines whether a packet table contains variable-length + * or fixed-length packets. + * - \ref H5PTopen + * \n Opens an existing packet table. + * - \ref H5PTread_packets + * \n Reads a number of packets from a packet table. + * - \ref H5PTset_index + * \n Sets a packet table's index. + * + */ + /*------------------------------------------------------------------------- * Create/Open/Close functions *------------------------------------------------------------------------- */ /* NOTE: H5PTcreate is replacing H5PTcreate_fl for better name due to the removal of H5PTcreate_vl. H5PTcreate_fl may be retired in 1.8.19. */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Creates a packet table to store fixed-length or + * variable-length packets. + * + * \fg_loc_id + * \param[in] dset_name The name of the packet table to create + * \param[in] dtype_id The datatype of the packet + * \param[in] chunk_size The size in number of table entries per chunk + * \param[in] plist_id Identifier of the property list. Can be used to + * specify the compression of the packet table. + * + * \return Returns an identifier for the new packet table or + * #H5I_INVALID_HID on error. + * + * \details The H5PTcreate() creates and opens a packet table named + * \p dset_name attached to the object specified by the + * identifier \p loc_id. The created packet table should be closed + * with H5PTclose(), eventually. + * + * The datatype, \p dtype_id, may specify any datatype, including + * variable-length data. If \p dtype_id specifies a compound + * datatype, one or more fields in that compound type may be + * variable-length. + * + * \p chunk_size is the size in number of table entries per chunk. + * Packet table datasets use HDF5 chunked storage + * to allow them to grow. This value allows the user + * to set the size of a chunk. The chunk size affects + * performance. + * + * \since 1.10.0 and 1.8.17 + * + */ H5_HLDLL hid_t H5PTcreate(hid_t loc_id, const char *dset_name, hid_t dtype_id, hsize_t chunk_size, hid_t plist_id); +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Opens an existing packet table. + * + * \fg_loc_id + * \param[in] dset_name The name of the packet table to open + * + * \return Returns an identifier for the packet table or + * #H5I_INVALID_HID on error. + * + * \details H5PTopen() opens an existing packet table in the file or group + * specified by \p loc_id. \p dset_name is the name of the packet + * table and is used to identify it in the file. This function is + * used to open both fixed-length packet tables and variable-length + * packet tables. The packet table should later be closed with + * H5PTclose(). + * + */ H5_HLDLL hid_t H5PTopen(hid_t loc_id, const char *dset_name); +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Closes an open packet table. + * + * \param[in] table_id Identifier of packet table to be closed + * + * \return \herr_t + * + * \details The H5PTclose() ends access to a packet table specified + * by \p table_id. + * + */ H5_HLDLL herr_t H5PTclose(hid_t table_id); +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Creates a packet table to store fixed-length packets + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to create + * \param[in] dtype_id The datatype of a packet. + * \param[in] chunk_size The size in number of table entries per + * chunk. + * \param[in] compression The compression level; + * a value of 0 through 9. + * + * \return Returns an identifier for the packet table or + * #H5I_INVALID_HID on error. + * + * \deprecated This function was deprecated in favor of the function + * H5PTcreate(). + * + * \details The H5PTcreate_fl() creates and opens a packet table + * named \p dset_name attached to the object specified by + * the identifier \p loc_id. It should be closed + * with H5PTclose(). + * + * The datatype, \p dtype_id, may specify any datatype, + * including variable-length data. If \p dtype_id specifies a + * compound datatype, one or more fields in that compound type + * may be variable-length. + * + * \p chunk_size is the size in number of table entries per chunk. + * Packet table datasets use HDF5 chunked storage + * to allow them to grow. This value allows the user + * to set the size of a chunk. The chunk size affects + * performance. + * + * \p compression is the compression level, a value of 0 through 9. + * Level 0 is faster but offers the least compression; + * level 9 is slower but offers maximum compression. + * A setting of -1 indicates that no compression is desired. + * + */ /* This function may be removed from the packet table in release 1.8.19. */ H5_HLDLL hid_t H5PTcreate_fl(hid_t loc_id, const char *dset_name, hid_t dtype_id, hsize_t chunk_size, int compression); @@ -39,24 +220,148 @@ H5_HLDLL hid_t H5PTcreate_fl(hid_t loc_id, const char *dset_name, hid_t dtype_id * Write functions *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Appends packets to the end of a packet table. + * + * \param[in] table_id Identifier of packet table to which + * packets should be appended + * \param[in] nrecords Number of packets to be appended + * \param[in] data Buffer holding data to write + * + * \return \herr_t + * + * \details The H5PTappend() writes \p nrecords packets to the end of a + * packet table specified by \p table_id. \p data is a buffer + * containing the data to be written. For a packet table holding + * fixed-length packets, this data should be in the packet + * table's datatype. For a variable-length packet table, + * the data should be in the form of #hvl_t structs. + * + */ H5_HLDLL herr_t H5PTappend(hid_t table_id, size_t nrecords, const void *data); /*------------------------------------------------------------------------- * Read functions *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Reads packets from a packet table starting at the current index. + * + * \param[in] table_id Identifier of packet table to read from + * \param[in] nrecords Number of packets to be read + * \param[out] data Buffer into which to read data + * + * \return \herr_t + * + * \details The H5PTget_next() reads \p nrecords packets starting with + * the "current index" from a packet table specified by \p table_id. + * The packet table's index is set and reset with H5PTset_index() + * and H5PTcreate_index(). \p data is a buffer into which the + * data should be read. + * + * For a packet table holding variable-length records, the data + * returned in the buffer will be in form of a #hvl_t struct + * containing the length of the data and a pointer to it in memory. + * The memory used by this data must be freed using H5PTfree_vlen_buff(). + * + */ H5_HLDLL herr_t H5PTget_next(hid_t table_id, size_t nrecords, void *data); +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Reads a number of packets from a packet table. + * + * \param[in] table_id Identifier of packet table to read from + * \param[in] start Packet to start reading from + * \param[in] nrecords Number of packets to be read + * \param[out] data Buffer into which to read data. + * + * \return \herr_t + * + * \details The H5PTread_packets() reads \p nrecords packets starting at + * packet number \p start from a packet table specified by + * \p table_id. \p data is a buffer into which the data should + * be read. + * + * For a packet table holding variable-length records, the data + * returned in the buffer will be in form of #hvl_t structs, + * each containing the length of the data and a pointer to it in + * memory. The memory used by this data must be freed using + * H5PTfree_vlen_buff(). + * + */ H5_HLDLL herr_t H5PTread_packets(hid_t table_id, hsize_t start, size_t nrecords, void *data); /*------------------------------------------------------------------------- * Inquiry functions *------------------------------------------------------------------------- */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Returns the number of packets in a packet table. + * + * \param[in] table_id Identifier of packet table to query + * \param[out] nrecords Number of packets in packet table + * + * \return \herr_t + * + * \details The H5PTget_num_packets() returns by reference the number + * of packets in a packet table specified by \p table_id. + * + */ H5_HLDLL herr_t H5PTget_num_packets(hid_t table_id, hsize_t *nrecords); +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Determines whether an identifier points to a packet table. + * + * \param[in] table_id Identifier to query + * + * \return Returns a non-negative value if \p table_id is + * a valid packet table, otherwise returns a negative value. + * + * \details The H5PTis_valid() returns a non-negative value if + * \p table_id corresponds to an open packet table, + * and returns a negative value otherwise. + * + */ H5_HLDLL herr_t H5PTis_valid(hid_t table_id); +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Determines whether a packet table contains + * variable-length or fixed-length packets. + * + * \param[in] table_id Packet table to query + * + * \return Returns 1 for a variable-length packet table, + * 0 for fixed-length, or a negative value on error. + * + * \details The H5PTis_varlen() returns 1 (TRUE) if \p table_id is + * a packet table containing variable-length records. + * It returns 0 (FALSE) if \p table_id is a packet table + * containing fixed-length records. If \p table_id is not a + * packet table, a negative value is returned. + * + * \version 1.10.0 and 1.8.17 Function re-introduced. + * Function had been removed in 1.8.3. + * + */ H5_HLDLL herr_t H5PTis_varlen(hid_t table_id); /*------------------------------------------------------------------------- @@ -66,8 +371,42 @@ H5_HLDLL herr_t H5PTis_varlen(hid_t table_id); *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Returns the backend dataset of this packet table. + * + * \param[in] table_id Identifier of the packet table + * + * \return Returns a dataset identifier or H5I_INVALID_HID on error. + * + * \details The H5PTget_dataset() returns the identifier of the dataset + * storing the packet table \p table_id. This dataset identifier + * will be closed by H5PTclose(). + * + * \since 1.10.0 and 1.8.17 + * + */ H5_HLDLL hid_t H5PTget_dataset(hid_t table_id); +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Returns the backend datatype of this packet table. + * + * \param[in] table_id Identifier of the packet table + * + * \return Returns a datatype identifier or H5I_INVALID_HID on error. + * + * \details The H5PTget_type() returns the identifier of the datatype + * used by the packet table \p table_id. This datatype + * identifier will be closed by H5PTclose(). + * + * \since 1.10.0 and 1.8.17 + * + */ H5_HLDLL hid_t H5PTget_type(hid_t table_id); /*------------------------------------------------------------------------- @@ -77,10 +416,63 @@ H5_HLDLL hid_t H5PTget_type(hid_t table_id); *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Resets a packet table's index to the first packet. + * + * \param[in] table_id Identifier of packet table whose index + * should be initialized. + * + * \return \herr_t + * + * \details Each packet table keeps an index of the "current" packet + * so that \c get_next can iterate through the packets in order. + * H5PTcreate_index() initializes a packet table's index, and + * should be called before using \c get_next. The index must be + * initialized every time a packet table is created or opened; + * this information is lost when the packet table is closed. + * + */ H5_HLDLL herr_t H5PTcreate_index(hid_t table_id); +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Sets a packet table's index. + * + * \param[in] table_id Identifier of packet table whose index is to be set + * \param[in] pt_index The packet to which the index should point + * + * \return \herr_t + * + * \details Each packet table keeps an index of the "current" packet + * so that \c get_next can iterate through the packets in order. + * H5PTset_index() sets this index to point to a user-specified + * packet (the packets are zero-indexed). + * + */ H5_HLDLL herr_t H5PTset_index(hid_t table_id, hsize_t pt_index); +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Gets the current record index for a packet table. + * + * \param[in] table_id Table identifier + * \param[out] pt_index Current record index + * + * \return \herr_t + * + * \details The H5PTget_index() returns the current record index + * \p pt_index for the table identified by \p table_id. + * + * \since 1.8.0 + * + */ H5_HLDLL herr_t H5PTget_index(hid_t table_id, hsize_t *pt_index); /*------------------------------------------------------------------------- @@ -90,6 +482,29 @@ H5_HLDLL herr_t H5PTget_index(hid_t table_id, hsize_t *pt_index); *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5PT + * + * \brief Releases memory allocated in the process of reading + * variable-length packets. + * + * \param[in] table_id Packet table whose memory should be freed. + * \param[in] bufflen Size of \p buff + * \param[in] buff Buffer that was used to read in variable-length + * packets + * + * \return \herr_t + * + * \details When variable-length packets are read, memory is automatically + * allocated to hold them, and must be freed. H5PTfree_vlen_buff() + * frees this memory, and should be called whenever packets are + * read from a variable-length packet table. + * + * \version 1.10.0 and 1.8.17 Function re-introduced. + * Function had been removed in 1.8.3. + * + */ H5_HLDLL herr_t H5PTfree_vlen_buff(hid_t table_id, size_t bufflen, void *buff); #ifdef __cplusplus diff --git a/hl/src/H5TBpublic.h b/hl/src/H5TBpublic.h index 1750490..dc0e31a 100644 --- a/hl/src/H5TBpublic.h +++ b/hl/src/H5TBpublic.h @@ -18,6 +18,70 @@ extern "C" { #endif +/**\defgroup H5TB Table + * + * Creating and manipulating HDF5 datasets intended to be + * interpreted as tables (H5TB) + * + * The HDF5 Table API defines a standard storage for HDF5 datasets + * that are intended to be interpreted as tables. A table is defined + * as a collection of records whose values are stored in fixed-length + * fields. All records have the same structure, and all values in + * each field have the same data type. + * + * \note \Bold{Programming hints:} + * \note To use any of these functions or subroutines, + * you must first include the relevant include file (C) or + * module (Fortran) in your application. + * \note The following line includes the HDF5 Table package, H5TB, + * in C applications: + * \code #include "hdf5_hl.h" \endcode + * \note To include the H5TB module in Fortran applications specify: + * \code use h5tb \endcode + * Fortran applications must also include \ref H5open before + * any HDF5 calls to initialize global variables and \ref H5close + * after all HDF5 calls to close the Fortran interface. + * + * + * + *
+ * + * - Creation + * - \ref H5TBmake_table + * - Storage + * - \ref H5TBappend_records (No Fortran) + * - \ref H5TBwrite_records (No Fortran) + * - \ref H5TBwrite_fields_name + * - \ref H5TBwrite_fields_index + * + * - Modification + * - \ref H5TBdelete_record (No Fortran) + * - \ref H5TBinsert_record (No Fortran) + * - \ref H5TBadd_records_from (No Fortran) + * - \ref H5TBcombine_tables (No Fortran) + * - \ref H5TBinsert_field + * - \ref H5TBdelete_field + * + * + * + * - Retrieval + * - \ref H5TBread_table + * - \ref H5TBread_records (No Fortran) + * - \ref H5TBread_fields_name + * - \ref H5TBread_fields_index + * + * - Query + * - \ref H5TBget_table_info + * - \ref H5TBget_field_info + * + * - Query Table Attributes + * - \ref H5TBAget_fill + * - \ref H5TBAget_title + * + *
+ * + */ + /*------------------------------------------------------------------------- * * Create functions @@ -25,6 +89,38 @@ extern "C" { *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * \brief Creates and writes a table + * + * \param[in] table_title The title of the table + * \fg_loc_id + * \param[in] dset_name The name of the dataset to create + * \param[in] nfields The number of fields + * \param[in] nrecords The number of records + * \param[in] type_size The size in bytes of the structure + * associated with the table; + * This value is obtained with \c sizeof(). + * \param[in] field_names An array containing the names of + * the fields + * \param[in] field_offset An array containing the offsets of + * the fields + * \param[in] field_types An array containing the type of + * the fields + * \param[in] chunk_size The chunk size + * \param[in] fill_data Fill values data + * \param[in] compress Flag that turns compression on or off + * \param[in] buf Buffer with data to be written to the table + * + * \return \herr_t + * + * \details H5TBmake_table() creates and writes a dataset named + * \p dset_name attached to the object specified by the + * identifier loc_id. + * + */ H5_HLDLL herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char *dset_name, hsize_t nfields, hsize_t nrecords, size_t type_size, const char *field_names[], const size_t *field_offset, const hid_t *field_types, hsize_t chunk_size, @@ -37,17 +133,128 @@ H5_HLDLL herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * \brief Adds records to the end of the table + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to overwrite + * \param[in] nrecords The number of records to append + * \param[in] type_size The size of the structure type, + * as calculated by \c sizeof(). + * \param[in] field_offset An array containing the offsets of + * the fields. These offsets can be + * calculated with the #HOFFSET macro + * \param[in] dst_sizes An array containing the sizes of + * the fields + * \param[in] buf Buffer with data + * + * \return \herr_t + * + * \details H5TBappend_records() adds records to the end of the table + * named \p dset_name attached to the object specified by the + * identifier \p loc_id. The dataset is extended to hold the + * new records. + * + */ H5_HLDLL herr_t H5TBappend_records(hid_t loc_id, const char *dset_name, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, const void *buf); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * \brief Overwrites records + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to overwrite + * \param[in] start The zero index record to start writing + * \param[in] nrecords The number of records to write + * \param[in] type_size The size of the structure type, as + * calculated by \c sizeof(). + * \param[in] field_offset An array containing the offsets of + * the fields. These offsets can be + * calculated with the #HOFFSET macro + * \param[in] dst_sizes An array containing the sizes of + * the fields + * \param[in] buf Buffer with data + * + * \return \herr_t + * + * \details H5TBwrite_records() overwrites records starting at the zero + * index position start of the table named \p dset_name attached + * to the object specified by the identifier \p loc_id. + * + */ H5_HLDLL herr_t H5TBwrite_records(hid_t loc_id, const char *dset_name, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, const void *buf); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * \brief Overwrites fields + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to overwrite + * \param[in] field_names The names of the fields to write + * \param[in] start The zero index record to start writing + * \param[in] nrecords The number of records to write + * \param[in] type_size The size of the structure type, as + * calculated by \c sizeof(). + * \param[in] field_offset An array containing the offsets of + * the fields. These offsets can be + * calculated with the #HOFFSET macro + * \param[in] dst_sizes An array containing the sizes of + * the fields + * \param[in] buf Buffer with data + * + * \return \herr_t + * + * \details H5TBwrite_fields_name() overwrites one or several fields + * specified by \p field_names with data in \p buf from a + * dataset named \p dset_name attached to the object specified + * by the identifier \p loc_id. + * + */ H5_HLDLL herr_t H5TBwrite_fields_name(hid_t loc_id, const char *dset_name, const char *field_names, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, const void *buf); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * \brief Overwrites fields + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to overwrite + * \param[in] nfields The number of fields to overwrite. + * This parameter is also the size of the + * \p field_index array. + * \param[in] field_index The indexes of the fields to write + * \param[in] start The zero based index record to start writing + * \param[in] nrecords The number of records to write + * \param[in] type_size The size of the structure type, as + * calculated by \c sizeof(). + * \param[in] field_offset An array containing the offsets of + * the fields. These offsets can be + * calculated with the #HOFFSET macro + * \param[in] dst_sizes An array containing the sizes of + * the fields + * \param[in] buf Buffer with data + * + * \return \herr_t + * + * \details H5TBwrite_fields_index() overwrites one or several fields + * specified by \p field_index with a buffer \p buf from a + * dataset named \p dset_name attached to the object + * specified by the identifier \p loc_id. + * + */ H5_HLDLL herr_t H5TBwrite_fields_index(hid_t loc_id, const char *dset_name, hsize_t nfields, const int *field_index, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, @@ -60,18 +267,128 @@ H5_HLDLL herr_t H5TBwrite_fields_index(hid_t loc_id, const char *dset_name, hsiz *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * \brief Reads a table + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[in] dst_size The size of the structure type, + * as calculated by \c sizeof() + * \param[in] dst_offset An array containing the offsets of + * the fields. These offsets can be + * calculated with the #HOFFSET macro + * \param[in] dst_sizes An array containing the sizes of + * the fields. These sizes can be + * calculated with the sizeof() macro. + * \param[in] dst_buf Buffer with data + * + * \return \herr_t + * + * \details H5TBread_table() reads a table named + * \p dset_name attached to the object specified by + * the identifier \p loc_id. + * + */ H5_HLDLL herr_t H5TBread_table(hid_t loc_id, const char *dset_name, size_t dst_size, const size_t *dst_offset, const size_t *dst_sizes, void *dst_buf); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * \brief Reads one or several fields. The fields are identified by name. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[in] field_names An array containing the names of the + * fields to read + * \param[in] start The start record to read from + * \param[in] nrecords The number of records to read + * \param[in] type_size The size in bytes of the structure associated + * with the table + * (This value is obtained with \c sizeof().) + * \param[in] field_offset An array containing the offsets of the fields + * \param[in] dst_sizes An array containing the size in bytes of + * the fields + * \param[out] buf Buffer with data + * + * \return \herr_t + * + * \details H5TBread_fields_name() reads the fields identified + * by \p field_names from a dataset named \p dset_name + * attached to the object specified by the identifier \p loc_id. + * + */ H5_HLDLL herr_t H5TBread_fields_name(hid_t loc_id, const char *dset_name, const char *field_names, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, void *buf); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Reads one or several fields. The fields are identified by index. + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[in] nfields The number of fields to read + * (This parameter is also the size of the + * \p field_index array.) + * fields to read + * \param[in] field_index The indexes of the fields to read + * \param[in] start The start record to read from + * \param[in] nrecords The number of records to read + * \param[in] type_size The size in bytes of the structure associated + * with the table + * (This value is obtained with \c sizeof()) + * \param[in] field_offset An array containing the offsets of the fields + * \param[in] dst_sizes An array containing the size in bytes of + * the fields + * \param[out] buf Buffer with data + * + * \return \herr_t + * + * \details H5TBread_fields_index() reads the fields identified + * by \p field_index from a dataset named \p dset_name attached + * to the object specified by the identifier \p loc_id. + * + */ H5_HLDLL herr_t H5TBread_fields_index(hid_t loc_id, const char *dset_name, hsize_t nfields, const int *field_index, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, void *buf); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Reads records + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[in] start The start record to read from + * \param[in] nrecords The number of records to read + * \param[in] type_size The size of the structure type, + * as calculated by \c sizeof() + * \param[in] dst_offset An array containing the offsets of the + * fields. These offsets can be calculated + * with the #HOFFSET macro + * \param[in] dst_sizes An array containing the size in bytes of + * the fields + * \param[out] buf Buffer with data + * + * \return \herr_t + * + * \details H5TBread_records() reads some records identified from a dataset + * named \p dset_name attached to the object specified by the + * identifier \p loc_id. + * + */ H5_HLDLL herr_t H5TBread_records(hid_t loc_id, const char *dset_name, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *dst_offset, const size_t *dst_sizes, void *buf); @@ -83,8 +400,52 @@ H5_HLDLL herr_t H5TBread_records(hid_t loc_id, const char *dset_name, hsize_t st *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Gets the table dimensions + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[out] nfields The number of fields + * \param[out] nrecords The number of records + * + * \return \herr_t + * + * \details H5TBget_table_info() retrieves the table dimensions from a + * dataset named \p dset_name attached to the object specified + * by the identifier \p loc_id. + * + */ H5_HLDLL herr_t H5TBget_table_info(hid_t loc_id, const char *dset_name, hsize_t *nfields, hsize_t *nrecords); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Gets information about a table + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset to read + * \param[out] field_names An array containing the names of the fields + * \param[out] field_sizes An array containing the size of the fields + * \param[out] field_offsets An array containing the offsets of the fields + * \param[out] type_size The size of the HDF5 datatype associated + * with the table. (More specifically, + * the size in bytes of the HDF5 compound + * datatype used to define a row, or record, + * in the table) + * + * \return \herr_t + * + * \details H5TBget_field_info() gets information about a dataset + * named \p dset_name attached to the object specified + * by the identifier \p loc_id. + * + */ H5_HLDLL herr_t H5TBget_field_info(hid_t loc_id, const char *dset_name, char *field_names[], size_t *field_sizes, size_t *field_offsets, size_t *type_size); @@ -95,21 +456,162 @@ H5_HLDLL herr_t H5TBget_field_info(hid_t loc_id, const char *dset_name, char *fi *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Delete records + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset + * \param[in] start The start record to delete from + * \param[in] nrecords The number of records to delete + * + * \return \herr_t + * + * \details H5TBdelete_record() deletes nrecords number of records starting + * from \p start from the middle of the table \p dset_name + * ("pulling up" all the records after it). + * + */ H5_HLDLL herr_t H5TBdelete_record(hid_t loc_id, const char *dset_name, hsize_t start, hsize_t nrecords); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Insert records + * + * \fg_loc_id + * \param[in] dset_name The name of the dataset + * \param[in] start The position to insert + * \param[in] nrecords The number of records to insert + * \param[in] dst_size The size in bytes of the structure + * associated with the table + * \param[in] dst_offset An array containing the offsets of the + * fields + * \param[in] dst_sizes An array containing the size in bytes of + * the fields + * \param[in] buf Buffer with data + * + * \return \herr_t + * + * \details H5TBinsert_record() inserts records into the middle of the table + * ("pushing down" all the records after it) + * + */ H5_HLDLL herr_t H5TBinsert_record(hid_t loc_id, const char *dset_name, hsize_t start, hsize_t nrecords, size_t dst_size, const size_t *dst_offset, const size_t *dst_sizes, void *buf); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Add records from first table to second table + * + * \fg_loc_id + * \param[in] dset_name1 The name of the dataset to read the records + * \param[in] start1 The position to read the records from the + * first table + * \param[in] nrecords The number of records to read from the first + * table + * \param[in] dset_name2 The name of the dataset to write the records + * \param[in] start2 The position to write the records on the + * second table + * + * \return \herr_t + * + * \details H5TBadd_records_from() adds records from a dataset named + * \p dset_name1 to a dataset named \p dset_name2. Both tables + * are attached to the object specified by the identifier loc_id. + * + */ H5_HLDLL herr_t H5TBadd_records_from(hid_t loc_id, const char *dset_name1, hsize_t start1, hsize_t nrecords, const char *dset_name2, hsize_t start2); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Combines records from two tables into a third + * + * \param[in] loc_id1 Identifier of the file or group in which + * the first table is located + * \param[in] dset_name1 The name of the first table to combine + * \param[in] loc_id2 Identifier of the file or group in which + * the second table is located + * \param[in] dset_name2 The name of the second table to combine + * \param[in] dset_name3 The name of the new table + * + * \return \herr_t + * + * \details H5TBcombine_tables() combines records from two datasets named + * \p dset_name1 and \p dset_name2, to a new table named + * \p dset_name3. These tables can be located on different files, + * identified by \p loc_id1 and \p loc_id2 (identifiers obtained + * with H5Fcreate()). They can also be located on the same file. + * In this case one uses the same identifier for both parameters + * \p loc_id1 and \p loc_id2. If two files are used, the third + * table is written in the first file. + * + */ H5_HLDLL herr_t H5TBcombine_tables(hid_t loc_id1, const char *dset_name1, hid_t loc_id2, const char *dset_name2, const char *dset_name3); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Insert a new field into a table + * + * \fg_loc_id + * \param[in] dset_name The name of the table + * \param[in] field_name The name of the field to insert + * \param[in] field_type The data type of the field + * \param[in] position The zero based index position where to + * insert the field + * \param[in] fill_data Fill value data for the field. This parameter + * can be NULL + * \param[in] buf Buffer with data + * + * \return \herr_t + * + * \details H5TBinsert_field() inserts a new field named \p field_name into + * the table \p dset_name. Note: this function requires the table + * to be re-created and rewritten in its entirety, and this can result + * in some unused space in the file, and can also take a great deal of + * time if the table is large. + * + */ H5_HLDLL herr_t H5TBinsert_field(hid_t loc_id, const char *dset_name, const char *field_name, hid_t field_type, hsize_t position, const void *fill_data, const void *buf); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Deletes a field from a table + * + * \fg_loc_id + * \param[in] dset_name The name of the table + * \param[in] field_name The name of the field to delete + * + * \return \herr_t + * + * \details H5TBdelete_field() deletes a field named \p field_name from the + * table \p dset_name. Note: this function requires the table to be + * re-created and rewritten in its entirety, and this can result in + * some unused space in the file, and can also take a great deal of + * time if the table is large. + * + */ H5_HLDLL herr_t H5TBdelete_field(hid_t loc_id, const char *dset_name, const char *field_name); /*------------------------------------------------------------------------- @@ -119,8 +621,49 @@ H5_HLDLL herr_t H5TBdelete_field(hid_t loc_id, const char *dset_name, const char *------------------------------------------------------------------------- */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Reads a table's title + * + * \fg_loc_id + * \param[out] table_title Buffer for title name + * + * \return \herr_t + * + * \details H5TBget_title() returns the title of the table identified + * by \p loc_id in a buffer \p table_title. + * + */ H5_HLDLL herr_t H5TBAget_title(hid_t loc_id, char *table_title); +/** + * -------------------------------------------------------------------------- + * \ingroup H5TB + * + * + * \brief Reads the table attribute fill values + * + * \fg_loc_id + * \param[in] dset_name Name of table + * \param[in] dset_id Table identifier + * \param[out] dst_buf Buffer of fill values for table fields + * + * \return + * \return A return value of 1 indicates that a fill value is present. + * \return A return value of 0 indicates a fill value is not present. + * \return A return value <0 indicates an error. + * + * \details H5TBget_fill() reads the table attribute fill values into + * the buffer \p dst_buf for the table specified by \p dset_id + * and \p dset_name located in \p loc_id. + * + * \par Example + * \include H5TBAget_fill.c + * + */ H5_HLDLL htri_t H5TBAget_fill(hid_t loc_id, const char *dset_name, hid_t dset_id, unsigned char *dst_buf); #ifdef __cplusplus diff --git a/java/src/hdf/hdf5lib/H5.java b/java/src/hdf/hdf5lib/H5.java index 133cd2c..25a1f8d 100644 --- a/java/src/hdf/hdf5lib/H5.java +++ b/java/src/hdf/hdf5lib/H5.java @@ -1242,6 +1242,10 @@ public class H5 implements java.io.Serializable { log.trace("H5Aread_string type"); status = H5Aread_string(attr_id, mem_type_id, (String[])obj); } + else if (H5.H5Tget_class(mem_type_id) == HDF5Constants.H5T_VLEN) { + log.trace("H5AreadVL type"); + status = H5AreadVL(attr_id, mem_type_id, (Object[])obj); + } else { // Create a data buffer to hold the data into a Java Array HDFArray theArray = new HDFArray(obj); @@ -1788,6 +1792,10 @@ public class H5 implements java.io.Serializable { log.trace("H5Dwrite_string type"); status = H5Awrite_string(attr_id, mem_type_id, (String[])obj); } + else if (H5.H5Tget_class(mem_type_id) == HDF5Constants.H5T_VLEN) { + log.trace("H5AwriteVL type"); + status = H5AwriteVL(attr_id, mem_type_id, (Object[])obj); + } else { HDFArray theArray = new HDFArray(obj); byte[] buf = theArray.byteify(); @@ -2772,6 +2780,11 @@ public class H5 implements java.io.Serializable { status = H5Dread_string(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, (String[])obj); } + else if (H5.H5Tget_class(mem_type_id) == HDF5Constants.H5T_VLEN) { + log.trace("H5DreadVL type"); + status = + H5DreadVL(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, (Object[])obj); + } else { // Create a data buffer to hold the data into a Java Array HDFArray theArray = new HDFArray(obj); @@ -3450,6 +3463,11 @@ public class H5 implements java.io.Serializable { status = H5Dwrite_string(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, (String[])obj); } + else if (H5.H5Tget_class(mem_type_id) == HDF5Constants.H5T_VLEN) { + log.trace("H5DwriteVL type"); + status = H5DwriteVL(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, + (Object[])obj); + } else { HDFArray theArray = new HDFArray(obj); byte[] buf = theArray.byteify(); @@ -9356,9 +9374,8 @@ public class H5 implements java.io.Serializable { byte[] buf = theArray.emptyBytes(); int status = H5Pget_fill_value(plist_id, type_id, buf); - if (status >= 0) { + if (status >= 0) obj = theArray.arrayify(buf); - } return status; } @@ -11018,8 +11035,6 @@ public class H5 implements java.io.Serializable { public synchronized static native void H5Rdestroy(byte[] ref_ptr) throws HDF5LibraryException, NullPointerException, IllegalArgumentException; - // Info // - /** * H5Rget_type retrieves the type of a reference. * @@ -11076,8 +11091,6 @@ public class H5 implements java.io.Serializable { public synchronized static native byte[] H5Rcopy(byte[] src_ref_ptr) throws HDF5LibraryException, NullPointerException, IllegalArgumentException; - // Dereference // - /** * H5Ropen_object opens that object and returns an identifier. * The object opened with this function should be closed when it is no longer needed @@ -11224,8 +11237,6 @@ public class H5 implements java.io.Serializable { public synchronized static native int H5Rget_obj_type3(byte[] ref_ptr, long rapl_id) throws HDF5LibraryException, NullPointerException, IllegalArgumentException; - // Get name // - /** * H5Rget_file_name retrieves the file name for the object, region or attribute reference pointed to. * @@ -11400,6 +11411,29 @@ public class H5 implements java.io.Serializable { throws HDF5LibraryException, NullPointerException, IllegalArgumentException; /** + * H5Rget_name_string retrieves a name for the object identified by ref. + * + * @param loc_id + * IN: Identifier for the dataset containing the reference or for the group that dataset is in. + * @param ref_type + * IN: Type of reference. + * @param ref + * IN: An object or dataset region reference. + * + * @return Returns the name if successful, returning null if no name is associated with + * the identifier. + * + * @exception HDF5LibraryException + * Error from the HDF-5 Library. + * @exception NullPointerException + * size is null. + * @exception IllegalArgumentException + * Argument is illegal. + **/ + public synchronized static native String H5Rget_name_string(long loc_id, int ref_type, byte[] ref) + throws HDF5LibraryException, NullPointerException, IllegalArgumentException; + + /** * H5Rget_obj_type Given a reference to an object ref, H5Rget_obj_type returns the type of the object * pointed to. * diff --git a/java/src/hdf/hdf5lib/HDF5Constants.java b/java/src/hdf/hdf5lib/HDF5Constants.java index 1b85c1f..2f5ec91 100644 --- a/java/src/hdf/hdf5lib/HDF5Constants.java +++ b/java/src/hdf/hdf5lib/HDF5Constants.java @@ -16,7 +16,7 @@ package hdf.hdf5lib; import hdf.hdf5lib.structs.H5O_token_t; /** - * /** This class contains C constants and enumerated types of HDF5 library. The + * This class contains C constants and enumerated types of HDF5 library. The * values of these constants are obtained from the library by calling J2C(int * jconstant), where jconstant is any of the private constants which start their * name with "JH5" need to be converted. @@ -62,31 +62,62 @@ public class HDF5Constants { public static final int H5_ITER_NATIVE = H5_ITER_NATIVE(); /** Common iteration orders, Number of iteration orders */ public static final int H5_ITER_N = H5_ITER_N(); - /** */ + /** The version of the H5AC_cache_config_t in use */ public static final int H5AC_CURR_CACHE_CONFIG_VERSION = H5AC_CURR_CACHE_CONFIG_VERSION(); - /** */ + /** The maximum length of the trace file path */ public static final int H5AC_MAX_TRACE_FILE_NAME_LEN = H5AC_MAX_TRACE_FILE_NAME_LEN(); - /** */ + /** + * When metadata_write_strategy is set to this value, only process + * zero is allowed to write dirty metadata to disk. All other + * processes must retain dirty metadata until they are informed at + * a sync point that the dirty metadata in question has been written + * to disk. + */ public static final int H5AC_METADATA_WRITE_STRATEGY_PROCESS_ZERO_ONLY = H5AC_METADATA_WRITE_STRATEGY_PROCESS_ZERO_ONLY(); - /** */ + /** + * In the distributed metadata write strategy, process zero still makes + * the decisions as to what entries should be flushed, but the actual + * flushes are distributed across the processes in the computation to + * the extent possible. + */ public static final int H5AC_METADATA_WRITE_STRATEGY_DISTRIBUTED = H5AC_METADATA_WRITE_STRATEGY_DISTRIBUTED(); - /** */ + /** Don't attempt to increase the size of the cache automatically */ public static final int H5C_incr_off = H5C_incr_off(); - /** */ + /** + * Attempt to increase the size of the cache + * whenever the average hit rate over the last epoch drops + * below the value supplied in the lower_hr_threshold + * field + */ public static final int H5C_incr_threshold = H5C_incr_threshold(); - /** */ + /** Don't perform flash increases in the size of the cache */ public static final int H5C_flash_incr_off = H5C_flash_incr_off(); - /** */ + /** increase the current maximum cache size by x * flash_multiple less any free space in the cache */ public static final int H5C_flash_incr_add_space = H5C_flash_incr_add_space(); - /** */ + /** Don't attempt to decrease the size of the cache automatically */ public static final int H5C_decr_off = H5C_decr_off(); - /** */ + /** + * Attempt to decrease the size of the cache + * whenever the average hit rate over the last epoch rises + * above the value supplied in the upper_hr_threshold + * field + */ public static final int H5C_decr_threshold = H5C_decr_threshold(); - /** */ + /** + * At the end of each epoch, search the cache for + * entries that have not been accessed for at least the number + * of epochs specified in the epochs_before_eviction field, and + * evict these entries + */ public static final int H5C_decr_age_out = H5C_decr_age_out(); - /** */ + /** + * Same as age_out, but we only + * attempt to reduce the cache size when the hit rate observed + * over the last epoch exceeds the value provided in the + * upper_hr_threshold field + */ public static final int H5C_decr_age_out_with_threshold = H5C_decr_age_out_with_threshold(); /** */ public static final int H5D_CHUNK_IDX_BTREE = H5D_CHUNK_IDX_BTREE(); @@ -910,11 +941,11 @@ public class HDF5Constants { /** */ public static final int H5R_MAXTYPE = H5R_MAXTYPE(); /** */ - public static final int H5R_REF_BUF_SIZE = H5R_REF_BUF_SIZE(); + public static final int H5R_DSET_REG_REF_BUF_SIZE = H5R_DSET_REG_REF_BUF_SIZE(); /** */ public static final int H5R_OBJ_REF_BUF_SIZE = H5R_OBJ_REF_BUF_SIZE(); /** */ - public static final int H5R_DSET_REG_REF_BUF_SIZE = H5R_DSET_REG_REF_BUF_SIZE(); + public static final int H5R_REF_BUF_SIZE = H5R_REF_BUF_SIZE(); /** */ public static final int H5R_OBJECT = H5R_OBJECT(); /** */ @@ -2393,11 +2424,11 @@ public class HDF5Constants { private static native final int H5R_MAXTYPE(); - private static native final int H5R_REF_BUF_SIZE(); + private static native final int H5R_DSET_REG_REF_BUF_SIZE(); private static native final int H5R_OBJ_REF_BUF_SIZE(); - private static native final int H5R_DSET_REG_REF_BUF_SIZE(); + private static native final int H5R_REF_BUF_SIZE(); private static native final int H5R_OBJECT(); diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index 6bf86d0..32bae07 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -56,7 +56,7 @@ static herr_t H5A_iterate_cb(hid_t g_id, const char *name, const H5A_info_t *inf /* * Class: hdf_hdf5lib_H5 - * Method: H5Acreate + * Method: _H5Acreate * Signature: (JLjava/lang/String;JJJ)J */ JNIEXPORT jlong JNICALL @@ -86,7 +86,7 @@ done: /* * Class: hdf_hdf5lib_H5 - * Method: H5Aopen_name + * Method: _H5Aopen_name * Signature: (JLjava/lang/String;)J */ JNIEXPORT jlong JNICALL @@ -124,7 +124,7 @@ done: /* * Class: hdf_hdf5lib_H5 - * Method: H5Aopen_idx + * Method: _H5Aopen_idx * Signature: (JI)J */ JNIEXPORT jlong JNICALL @@ -158,7 +158,10 @@ Java_hdf_hdf5lib_H5_H5Aread(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_t { jboolean readBufIsCopy; jbyte * readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -166,18 +169,20 @@ Java_hdf_hdf5lib_H5_H5Aread(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_t if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_BYTE_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -187,11 +192,17 @@ Java_hdf_hdf5lib_H5_H5Aread(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_t PIN_BYTE_ARRAY(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Aread: read buffer not pinned"); } - if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, readBuf)) < 0) + if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, (void *)readBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -214,7 +225,10 @@ Java_hdf_hdf5lib_H5_H5Awrite(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_ { jboolean writeBufIsCopy; jbyte * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -222,18 +236,18 @@ Java_hdf_hdf5lib_H5_H5Awrite(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_ if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_BYTE_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -248,6 +262,9 @@ Java_hdf_hdf5lib_H5_H5Awrite(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_ done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -270,7 +287,10 @@ Java_hdf_hdf5lib_H5_H5Aread_1short(JNIEnv *env, jclass clss, jlong attr_id, jlon { jboolean readBufIsCopy; jshort * readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -278,18 +298,20 @@ Java_hdf_hdf5lib_H5_H5Aread_1short(JNIEnv *env, jclass clss, jlong attr_id, jlon if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_short: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_short: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_short: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_SHORT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -304,6 +326,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1short(JNIEnv *env, jclass clss, jlong attr_id, jlon done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -326,7 +354,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1short(JNIEnv *env, jclass clss, jlong attr_id, jlo { jboolean writeBufIsCopy; jshort * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -334,18 +365,18 @@ Java_hdf_hdf5lib_H5_H5Awrite_1short(JNIEnv *env, jclass clss, jlong attr_id, jlo if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_short: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_short: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_short: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_SHORT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -360,6 +391,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1short(JNIEnv *env, jclass clss, jlong attr_id, jlo done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -381,27 +415,32 @@ Java_hdf_hdf5lib_H5_H5Aread_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jint * readBuf = NULL; - herr_t status = FAIL; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (buf == NULL) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_int: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_int: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_int: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_INT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -416,6 +455,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -438,7 +483,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong { jboolean writeBufIsCopy; jint * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -446,18 +494,18 @@ Java_hdf_hdf5lib_H5_H5Awrite_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong if (buf == NULL) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_int: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_int: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_int: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_INT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -472,6 +520,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -494,7 +545,10 @@ Java_hdf_hdf5lib_H5_H5Aread_1long(JNIEnv *env, jclass clss, jlong attr_id, jlong { jboolean readBufIsCopy; jlong * readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -502,18 +556,20 @@ Java_hdf_hdf5lib_H5_H5Aread_1long(JNIEnv *env, jclass clss, jlong attr_id, jlong if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_long: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_long: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_long: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_LONG_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -528,6 +584,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1long(JNIEnv *env, jclass clss, jlong attr_id, jlong done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -550,7 +612,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1long(JNIEnv *env, jclass clss, jlong attr_id, jlon { jboolean writeBufIsCopy; jlong * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -558,18 +623,18 @@ Java_hdf_hdf5lib_H5_H5Awrite_1long(JNIEnv *env, jclass clss, jlong attr_id, jlon if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_long: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_long: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_long: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_LONG_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -584,6 +649,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1long(JNIEnv *env, jclass clss, jlong attr_id, jlon done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -606,7 +674,10 @@ Java_hdf_hdf5lib_H5_H5Aread_1float(JNIEnv *env, jclass clss, jlong attr_id, jlon { jboolean readBufIsCopy; jfloat * readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -614,18 +685,20 @@ Java_hdf_hdf5lib_H5_H5Aread_1float(JNIEnv *env, jclass clss, jlong attr_id, jlon if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_float: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_float: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_float: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_FLOAT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -640,6 +713,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1float(JNIEnv *env, jclass clss, jlong attr_id, jlon done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -662,7 +741,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1float(JNIEnv *env, jclass clss, jlong attr_id, jlo { jboolean writeBufIsCopy; jfloat * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -670,18 +752,18 @@ Java_hdf_hdf5lib_H5_H5Awrite_1float(JNIEnv *env, jclass clss, jlong attr_id, jlo if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_float: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_float: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_float: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_FLOAT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -696,6 +778,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1float(JNIEnv *env, jclass clss, jlong attr_id, jlo done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -718,7 +803,10 @@ Java_hdf_hdf5lib_H5_H5Aread_1double(JNIEnv *env, jclass clss, jlong attr_id, jlo { jboolean readBufIsCopy; jdouble *readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -726,18 +814,20 @@ Java_hdf_hdf5lib_H5_H5Aread_1double(JNIEnv *env, jclass clss, jlong attr_id, jlo if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_double: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_double: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_double: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_DOUBLE_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -752,6 +842,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1double(JNIEnv *env, jclass clss, jlong attr_id, jlo done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -774,7 +870,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1double(JNIEnv *env, jclass clss, jlong attr_id, jl { jboolean writeBufIsCopy; jdouble *writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -782,18 +881,17 @@ Java_hdf_hdf5lib_H5_H5Awrite_1double(JNIEnv *env, jclass clss, jlong attr_id, jl if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_double: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_double: variable length type not supported"); + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_double: buf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_double: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_DOUBLE_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -808,6 +906,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1double(JNIEnv *env, jclass clss, jlong attr_id, jl done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -958,12 +1059,456 @@ done: /* * Class: hdf_hdf5lib_H5 * Method: H5AreadVL - * Signature: (JJ[Ljava/lang/String;)I + * Signature: (JJ[java/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) { H5T_class_t type_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; + jboolean readBufIsCopy; + jbyteArray *readBuf = NULL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5AreadVL: read buffer is NULL"); + + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } + + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + + if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (type_class == H5T_VLEN) { + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void * rawBuf = NULL; + jobject * jList = NULL; + + size_t i, j, x; + char * cp_vp = NULL; + + if (!(typeSize = H5Tget_size(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(memb = H5Tget_super(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + if ((vlClass = H5Tget_class((hid_t)memb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(vlSize = H5Tget_size(memb))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (rawBuf = HDcalloc((size_t)n, typeSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AreadVL: failed to allocate raw VL read buffer"); + + if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, (void *)rawBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Cache class types */ + jclass cBool = ENVPTR->FindClass(ENVONLY, "java/lang/Boolean"); + jclass cByte = ENVPTR->FindClass(ENVONLY, "java/lang/Byte"); + jclass cShort = ENVPTR->FindClass(ENVONLY, "java/lang/Short"); + jclass cInt = ENVPTR->FindClass(ENVONLY, "java/lang/Integer"); + jclass cLong = ENVPTR->FindClass(ENVONLY, "java/lang/Long"); + jclass cFloat = ENVPTR->FindClass(ENVONLY, "java/lang/Float"); + jclass cDouble = ENVPTR->FindClass(ENVONLY, "java/lang/Double"); + + jmethodID boolValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cBool, "valueOf", "(Z)Ljava/lang/Boolean;"); + jmethodID byteValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cByte, "valueOf", "(B)Ljava/lang/Byte;"); + jmethodID shortValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cShort, "valueOf", "(S)Ljava/lang/Short;"); + jmethodID intValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cInt, "valueOf", "(I)Ljava/lang/Integer;"); + jmethodID longValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cLong, "valueOf", "(J)Ljava/lang/Long;"); + jmethodID floatValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cFloat, "valueOf", "(F)Ljava/lang/Float;"); + jmethodID doubleValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cDouble, "valueOf", "(D)Ljava/lang/Double;"); + + // retrieve the java.util.List interface class + jclass cList = ENVPTR->FindClass(ENVONLY, "java/util/List"); + jmethodID addMethod = ENVPTR->GetMethodID(ENVONLY, cList, "add", "(Ljava/lang/Object;)Z"); + + /* Convert each element to a list */ + for (i = 0; i < (size_t)n; i++) { + // The list we're going to return: + if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cp_vp = (char *)rawBuf + i * typeSize; + /* Get the number of sequence elements */ + jsize nelmts = ((hvl_t *)cp_vp)->len; + + jobject jobj = NULL; + for (j = 0; j < nelmts; j++) { + switch (vlClass) { + /* case H5T_BOOL: { + jboolean boolValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&boolValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j*vlSize+x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cBool, boolValueMid, boolValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } */ + case H5T_INTEGER: { + switch (vlSize) { + case sizeof(jbyte): { + jbyte byteValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&byteValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = + ENVPTR->CallStaticObjectMethod(ENVONLY, cByte, byteValueMid, byteValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jshort): { + jshort shortValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&shortValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cShort, shortValueMid, + shortValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jint): { + jint intValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&intValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cInt, intValueMid, intValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jlong): { + jlong longValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&longValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = + ENVPTR->CallStaticObjectMethod(ENVONLY, cLong, longValueMid, longValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + } + break; + } + case H5T_FLOAT: { + switch (vlSize) { + case sizeof(jfloat): { + jfloat floatValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&floatValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cFloat, floatValueMid, + floatValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jdouble): { + jdouble doubleValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&doubleValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cDouble, doubleValueMid, + doubleValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + } + break; + } + case H5T_REFERENCE: { + jboolean bb; + jbyte * barray = NULL; + if (NULL == (jobj = ENVPTR->NewByteArray(ENVONLY, vlSize))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, &bb, + "readVL reference: byte array not pinned"); + + for (x = 0; x < (int)vlSize; x++) { + barray[x] = ((jbyte *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, jobj ? 0 : JNI_ABORT); + break; + } + default: + H5_UNIMPLEMENTED(ENVONLY, "H5AreadVL: invalid class type"); + break; + } + + // Add it to the list + ENVPTR->CallBooleanMethod(ENVONLY, jList, addMethod, jobj); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + } /* end for */ + + if (rawBuf) + HDfree(rawBuf); + } + else { + if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, (void *)readBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + + UNPIN_BYTE_ARRAY(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); + } + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5AreadVL */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5AwriteVL + * Signature: (JJ[java/util/ArrayList;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) +{ + H5T_class_t type_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; + jboolean writeBufIsCopy; + jbyteArray *writeBuf = NULL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5AwriteVL: write buffer is NULL"); + + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5AwriteVL: readBuf length < 0"); + } + + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (type_class == H5T_VLEN) { + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void * rawBuf = NULL; + jobject * jList = NULL; + + size_t i, j, x; + char * cp_vp = NULL; + + if (!(typeSize = H5Tget_size(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(memb = H5Tget_super(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + if ((vlClass = H5Tget_class((hid_t)memb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(vlSize = H5Tget_size(memb))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (rawBuf = HDcalloc((size_t)n, typeSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL: failed to allocate raw VL write buffer"); + + /* Cache class types */ + jclass cBool = ENVPTR->FindClass(ENVONLY, "java/lang/Boolean"); + jclass cByte = ENVPTR->FindClass(ENVONLY, "java/lang/Byte"); + jclass cShort = ENVPTR->FindClass(ENVONLY, "java/lang/Short"); + jclass cInt = ENVPTR->FindClass(ENVONLY, "java/lang/Integer"); + jclass cLong = ENVPTR->FindClass(ENVONLY, "java/lang/Long"); + jclass cFloat = ENVPTR->FindClass(ENVONLY, "java/lang/Float"); + jclass cDouble = ENVPTR->FindClass(ENVONLY, "java/lang/Double"); + + jmethodID boolValueMid = ENVPTR->GetMethodID(ENVONLY, cBool, "booleanValue", "()Z"); + jmethodID byteValueMid = ENVPTR->GetMethodID(ENVONLY, cByte, "byteValue", "()B"); + jmethodID shortValueMid = ENVPTR->GetMethodID(ENVONLY, cShort, "shortValue", "()S"); + jmethodID intValueMid = ENVPTR->GetMethodID(ENVONLY, cInt, "intValue", "()I"); + jmethodID longValueMid = ENVPTR->GetMethodID(ENVONLY, cLong, "longValue", "()J"); + jmethodID floatValueMid = ENVPTR->GetMethodID(ENVONLY, cFloat, "floatValue", "()F"); + jmethodID doubleValueMid = ENVPTR->GetMethodID(ENVONLY, cDouble, "doubleValue", "()D"); + + /* Convert each list to a vlen element */ + for (i = 0; i < (size_t)n; i++) { + if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + // retrieve the java.util.List interface class + jclass cList = ENVPTR->FindClass(ENVONLY, "java/util/List"); + + // retrieve the toArray method and invoke it + jmethodID mToArray = ENVPTR->GetMethodID(ENVONLY, cList, "toArray", "()[Ljava/lang/Object;"); + if (mToArray == NULL) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + jobjectArray array = (jobjectArray)ENVPTR->CallObjectMethod(ENVONLY, jList, mToArray); + jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, array); + + cp_vp = (char *)rawBuf + i * typeSize; + ((hvl_t *)cp_vp)->len = jnelmts; + + if (NULL == (((hvl_t *)cp_vp)->p = HDmalloc(jnelmts * vlSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL: failed to allocate vlen ptr buffer"); + + jobject jobj = NULL; + for (j = 0; j < (int)jnelmts; j++) { + if (NULL == (jobj = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)array, (jsize)j))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + switch (vlClass) { + /* case H5T_BOOL: { + jboolean boolValue = ENVPTR->CallBooleanMethod(ENVONLY, jobj, boolValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&boolValue)[x]; + } + break; + } */ + case H5T_INTEGER: { + switch (vlSize) { + case sizeof(jbyte): { + jbyte byteValue = ENVPTR->CallByteMethod(ENVONLY, jobj, byteValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&byteValue)[x]; + } + break; + } + case sizeof(jshort): { + jshort shortValue = ENVPTR->CallShortMethod(ENVONLY, jobj, shortValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&shortValue)[x]; + } + break; + } + case sizeof(jint): { + jint intValue = ENVPTR->CallIntMethod(ENVONLY, jobj, intValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&intValue)[x]; + } + break; + } + case sizeof(jlong): { + jlong longValue = ENVPTR->CallLongMethod(ENVONLY, jobj, longValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&longValue)[x]; + } + break; + } + } + break; + } + case H5T_FLOAT: { + switch (vlSize) { + case sizeof(jfloat): { + jfloat floatValue = ENVPTR->CallFloatMethod(ENVONLY, jobj, floatValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&floatValue)[x]; + } + break; + } + case sizeof(jdouble): { + jdouble doubleValue = ENVPTR->CallDoubleMethod(ENVONLY, jobj, doubleValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&doubleValue)[x]; + } + break; + } + } + break; + } + case H5T_REFERENCE: { + jbyte *barray = (jbyte *)ENVPTR->GetByteArrayElements(ENVONLY, jobj, 0); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)barray)[x]; + } + ENVPTR->ReleaseByteArrayElements(ENVONLY, jobj, barray, 0); + break; + } + default: + H5_UNIMPLEMENTED(ENVONLY, "H5AwriteVL: invalid class type"); + break; + } + ENVPTR->DeleteLocalRef(ENVONLY, jobj); + } + ENVPTR->DeleteLocalRef(ENVONLY, jList); + } /* end for (i = 0; i < n; i++) */ + + if ((status = H5Awrite((hid_t)attr_id, (hid_t)mem_type_id, rawBuf)) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (rawBuf) + HDfree(rawBuf); + } + else { + PIN_BYTE_ARRAY(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5AwriteVL: write buffer not pinned"); + if ((status = H5Awrite((hid_t)attr_id, (hid_t)mem_type_id, writeBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + + if (type_class != H5T_VLEN) + UNPIN_BYTE_ARRAY(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); + } + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5AwriteVL */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Aread_VLStrings + * Signature: (JJ[Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Aread_1VLStrings(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, + jobjectArray buf) +{ + H5T_class_t type_class; htri_t isStr = 0; htri_t isVlenStr = 0; htri_t isComplex = 0; @@ -974,7 +1519,7 @@ Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem UNUSED(clss); if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5AreadVL: read buffer is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_VLStrings: read buffer is NULL"); if ((isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1024,7 +1569,7 @@ done: H5Tclose(nested_tid); return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Aread_1VL */ +} /* end Java_hdf_hdf5lib_H5_H5Aread_1VLStrings */ /* * Helper method to read in a buffer of variable-length strings from an HDF5 @@ -1160,11 +1705,12 @@ done: /* * Class: hdf_hdf5lib_H5 - * Method: H5AwriteVL + * Method: H5Awrite_VLStrings * Signature: (JJ[Ljava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) +Java_hdf_hdf5lib_H5_H5Awrite_1VLStrings(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, + jobjectArray buf) { H5T_class_t type_class; htri_t isStr = 0; @@ -1177,7 +1723,7 @@ Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *env, jclass clss, jlong attr_id, jlong me UNUSED(clss); if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5AwriteVL: write buffer is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_VLStrings: write buffer is NULL"); if ((isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1227,7 +1773,7 @@ done: H5Tclose(nested_tid); return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Awrite_1VL */ +} /* end Java_hdf_hdf5lib_H5_H5Awrite_1VLStrings */ /* * Helper method to convert an array of Java strings into a buffer of C-strings. @@ -1273,7 +1819,7 @@ H5AwriteVL_str(JNIEnv *env, hid_t aid, hid_t tid, jobjectArray buf) if (NULL == (writeBuf[i] = (char *)HDmalloc((size_t)length + 1))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL_str: failed to allocate string buffer"); - HDstrncpy(writeBuf[i], utf8, (size_t)length); + HDstrncpy(writeBuf[i], utf8, (size_t)length + 1); writeBuf[i][length] = '\0'; UNPIN_JAVA_STRING(ENVONLY, obj, utf8); @@ -1297,8 +1843,8 @@ done: HDfree(writeBuf); } - return (jint)status; -} + return status; +} /* end H5AwriteVL_str */ /* * Helper method to convert an array of Java strings into a buffer of @@ -1385,7 +1931,7 @@ done: H5Sclose(sid); return status; -} /* end H5AwriteVL_str */ +} /* end H5AwriteVL_asstr */ /* * Class: hdf_hdf5lib_H5 diff --git a/java/src/jni/h5aImp.h b/java/src/jni/h5aImp.h index aee0e40..094f990 100644 --- a/java/src/jni/h5aImp.h +++ b/java/src/jni/h5aImp.h @@ -22,7 +22,7 @@ extern "C" { /* * Class: hdf_hdf5lib_H5 - * Method: H5Acreate + * Method: _H5Acreate * Signature: (JLjava/lang/String;JJJ)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Acreate(JNIEnv *, jclass, jlong, jstring, jlong, jlong, @@ -30,14 +30,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Acreate(JNIEnv *, jclass, jlong, /* * Class: hdf_hdf5lib_H5 - * Method: H5Aopen_name + * Method: _H5Aopen_name * Signature: (JLjava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aopen_1name(JNIEnv *, jclass, jlong, jstring); /* * Class: hdf_hdf5lib_H5 - * Method: H5Aopen_idx + * Method: _H5Aopen_idx * Signature: (JI)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aopen_1idx(JNIEnv *, jclass, jlong, jint); @@ -137,14 +137,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Awrite_1double(JNIEnv *, jclass, jl /* * Class: hdf_hdf5lib_H5 * Method: H5AreadVL - * Signature: (JJ[Ljava/lang/String;)I + * Signature: (JJ[Ljava/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *, jclass, jlong, jlong, jobjectArray); /* * Class: hdf_hdf5lib_H5 * Method: H5AwriteVL - * Signature: (JJ[Ljava/lang/String;)I + * Signature: (JJ[Ljava/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *, jclass, jlong, jlong, jobjectArray); @@ -185,14 +185,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Aread_1reg_1ref(JNIEnv *, jclass, j /* * Class: hdf_hdf5lib_H5 - * Method: H5Aget_space + * Method: _H5Aget_space * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aget_1space(JNIEnv *, jclass, jlong); /* * Class: hdf_hdf5lib_H5 - * Method: H5Aget_type + * Method: _H5Aget_type * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aget_1type(JNIEnv *, jclass, jlong); @@ -220,7 +220,7 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Adelete(JNIEnv *, jclass, jlong, js /* * Class: hdf_hdf5lib_H5 - * Method: H5Aclose + * Method: _H5Aclose * Signature: (J)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5__1H5Aclose(JNIEnv *, jclass, jlong); @@ -350,7 +350,7 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aopen_1by_1name(JNIEnv *, jclass /* * Class: hdf_hdf5lib_H5 - * Method: H5Aget_create_plist + * Method: _H5Aget_create_plist * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aget_1create_1plist(JNIEnv *, jclass, jlong); diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index 73b252a..a20bb6c 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -183,28 +183,24 @@ Java_hdf_hdf5lib_H5_H5Dread(JNIEnv *env, jclass clss, jlong dataset_id, jlong me jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jbyte * readBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: variable length type not supported"); - if (isCriticalPinning) { PIN_BYTE_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread: read buffer not critically pinned"); @@ -219,6 +215,9 @@ Java_hdf_hdf5lib_H5_H5Dread(JNIEnv *env, jclass clss, jlong dataset_id, jlong me done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -241,28 +240,24 @@ Java_hdf_hdf5lib_H5_H5Dwrite(JNIEnv *env, jclass clss, jlong dataset_id, jlong m jboolean isCriticalPinning) { jboolean writeBufIsCopy; - htri_t data_class; jbyte * writeBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite: variable length type not supported"); - if (isCriticalPinning) { PIN_BYTE_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite: write buffer not critically pinned"); @@ -277,6 +272,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite(JNIEnv *env, jclass clss, jlong dataset_id, jlong m done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -383,7 +381,7 @@ Java_hdf_hdf5lib_H5_H5Dread_1short(JNIEnv *env, jclass clss, jlong dataset_id, j { jboolean readBufIsCopy; jshort * readBuf = NULL; - htri_t data_class; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -391,19 +389,15 @@ Java_hdf_hdf5lib_H5_H5Dread_1short(JNIEnv *env, jclass clss, jlong dataset_id, j if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_short: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_short: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_short: variable length type not supported"); - if (isCriticalPinning) { PIN_SHORT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_short: read buffer not critically pinned"); @@ -418,6 +412,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1short(JNIEnv *env, jclass clss, jlong dataset_id, j done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -441,7 +438,7 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1short(JNIEnv *env, jclass clss, jlong dataset_id, { jboolean writeBufIsCopy; jshort * writeBuf = NULL; - htri_t data_class; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -449,19 +446,15 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1short(JNIEnv *env, jclass clss, jlong dataset_id, if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_short: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_short: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_short: variable length type not supported"); - if (isCriticalPinning) { PIN_SHORT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite_short: write buffer not critically pinned"); @@ -476,6 +469,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1short(JNIEnv *env, jclass clss, jlong dataset_id, done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -498,28 +494,24 @@ Java_hdf_hdf5lib_H5_H5Dread_1int(JNIEnv *env, jclass clss, jlong dataset_id, jlo jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jint * readBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_int: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_int: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_int: variable length type not supported"); - if (isCriticalPinning) { PIN_INT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_int: read buffer not critically pinned"); @@ -534,6 +526,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1int(JNIEnv *env, jclass clss, jlong dataset_id, jlo done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -556,28 +551,24 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1int(JNIEnv *env, jclass clss, jlong dataset_id, jl jboolean isCriticalPinning) { jboolean writeBufIsCopy; - htri_t data_class; jint * writeBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_int: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_int: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_int: variable length type not supported"); - if (isCriticalPinning) { PIN_INT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite_int: write buffer not critically pinned"); @@ -592,6 +583,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1int(JNIEnv *env, jclass clss, jlong dataset_id, jl done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -614,28 +608,24 @@ Java_hdf_hdf5lib_H5_H5Dread_1long(JNIEnv *env, jclass clss, jlong dataset_id, jl jlongArray buf, jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jlong * readBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_long: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_long: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_long: variable length type not supported"); - if (isCriticalPinning) { PIN_LONG_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_long: read buffer not critically pinned"); @@ -650,6 +640,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1long(JNIEnv *env, jclass clss, jlong dataset_id, jl done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -672,28 +665,24 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1long(JNIEnv *env, jclass clss, jlong dataset_id, j jlongArray buf, jboolean isCriticalPinning) { jboolean writeBufIsCopy; - htri_t data_class; jlong * writeBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_long: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_long: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_long: variable length type not supported"); - if (isCriticalPinning) { PIN_LONG_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite_long: write buffer not critically pinned"); @@ -708,6 +697,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1long(JNIEnv *env, jclass clss, jlong dataset_id, j done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -730,28 +722,24 @@ Java_hdf_hdf5lib_H5_H5Dread_1float(JNIEnv *env, jclass clss, jlong dataset_id, j jfloatArray buf, jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jfloat * readBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_float: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_float: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_float: variable length type not supported"); - if (isCriticalPinning) { PIN_FLOAT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_float: read buffer not critically pinned"); @@ -766,6 +754,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1float(JNIEnv *env, jclass clss, jlong dataset_id, j done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -788,27 +779,23 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1float(JNIEnv *env, jclass clss, jlong dataset_id, jfloatArray buf, jboolean isCriticalPinning) { jboolean writeBufIsCopy; - htri_t data_class; jfloat * writeBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_float: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_float: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_float: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } if (isCriticalPinning) { PIN_FLOAT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -824,6 +811,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1float(JNIEnv *env, jclass clss, jlong dataset_id, done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -847,7 +837,7 @@ Java_hdf_hdf5lib_H5_H5Dread_1double(JNIEnv *env, jclass clss, jlong dataset_id, { jboolean readBufIsCopy; jdouble *readBuf = NULL; - htri_t data_class; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -855,19 +845,15 @@ Java_hdf_hdf5lib_H5_H5Dread_1double(JNIEnv *env, jclass clss, jlong dataset_id, if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_double: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_double: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_double: variable length type not supported"); - if (isCriticalPinning) { PIN_DOUBLE_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_double: read buffer not critically pinned"); @@ -882,6 +868,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1double(JNIEnv *env, jclass clss, jlong dataset_id, done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -905,7 +894,7 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1double(JNIEnv *env, jclass clss, jlong dataset_id, { jboolean writeBufIsCopy; jdouble *writeBuf = NULL; - htri_t data_class; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -913,19 +902,14 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1double(JNIEnv *env, jclass clss, jlong dataset_id, if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_double: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_double: variable length type not supported"); + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_double: buf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_double: variable length type not supported"); - if (isCriticalPinning) { PIN_DOUBLE_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite_double: write buffer not critically pinned"); @@ -940,6 +924,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1double(JNIEnv *env, jclass clss, jlong dataset_id, done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -1094,13 +1081,445 @@ done: /* * Class: hdf_hdf5lib_H5 * Method: H5DreadVL - * Signature: (JJJJJ[Ljava/lang/String;)I + * Signature: (JJJJJ[java/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, jobjectArray buf) { H5T_class_t type_class; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; + jboolean readBufIsCopy; + jbyteArray *readBuf = NULL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DreadVL: read buffer is NULL"); + + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5DreadVL: readBuf length < 0"); + } + + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (type_class == H5T_VLEN) { + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void * rawBuf = NULL; + jobject * jList = NULL; + + size_t i, j, x; + char * cp_vp = NULL; + + if (!(typeSize = H5Tget_size(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(memb = H5Tget_super(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + if ((vlClass = H5Tget_class((hid_t)memb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(vlSize = H5Tget_size(memb))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (rawBuf = HDcalloc((size_t)n, typeSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DreadVL: failed to allocate raw VL read buffer"); + + if ((status = H5Dread((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, + (hid_t)file_space_id, (hid_t)xfer_plist_id, (void *)rawBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Cache class types */ + jclass cBool = ENVPTR->FindClass(ENVONLY, "java/lang/Boolean"); + jclass cByte = ENVPTR->FindClass(ENVONLY, "java/lang/Byte"); + jclass cShort = ENVPTR->FindClass(ENVONLY, "java/lang/Short"); + jclass cInt = ENVPTR->FindClass(ENVONLY, "java/lang/Integer"); + jclass cLong = ENVPTR->FindClass(ENVONLY, "java/lang/Long"); + jclass cFloat = ENVPTR->FindClass(ENVONLY, "java/lang/Float"); + jclass cDouble = ENVPTR->FindClass(ENVONLY, "java/lang/Double"); + + jmethodID boolValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cBool, "valueOf", "(Z)Ljava/lang/Boolean;"); + jmethodID byteValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cByte, "valueOf", "(B)Ljava/lang/Byte;"); + jmethodID shortValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cShort, "valueOf", "(S)Ljava/lang/Short;"); + jmethodID intValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cInt, "valueOf", "(I)Ljava/lang/Integer;"); + jmethodID longValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cLong, "valueOf", "(J)Ljava/lang/Long;"); + jmethodID floatValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cFloat, "valueOf", "(F)Ljava/lang/Float;"); + jmethodID doubleValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cDouble, "valueOf", "(D)Ljava/lang/Double;"); + + // retrieve the java.util.List interface class + jclass cList = ENVPTR->FindClass(ENVONLY, "java/util/List"); + jmethodID addMethod = ENVPTR->GetMethodID(ENVONLY, cList, "add", "(Ljava/lang/Object;)Z"); + + /* Convert each element to a list */ + for (i = 0; i < (size_t)n; i++) { + // The list we're going to return: + if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cp_vp = (char *)rawBuf + i * typeSize; + /* Get the number of sequence elements */ + jsize nelmts = ((hvl_t *)cp_vp)->len; + + jobject jobj = NULL; + for (j = 0; j < nelmts; j++) { + switch (vlClass) { + /*case H5T_BOOL: { + jboolean boolValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&boolValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j*vlSize+x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cBool, boolValueMid, boolValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } */ + case H5T_INTEGER: { + switch (vlSize) { + case sizeof(jbyte): { + jbyte byteValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&byteValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = + ENVPTR->CallStaticObjectMethod(ENVONLY, cByte, byteValueMid, byteValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jshort): { + jshort shortValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&shortValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cShort, shortValueMid, + shortValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jint): { + jint intValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&intValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cInt, intValueMid, intValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jlong): { + jlong longValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&longValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = + ENVPTR->CallStaticObjectMethod(ENVONLY, cLong, longValueMid, longValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + } + break; + } + case H5T_FLOAT: { + switch (vlSize) { + case sizeof(jfloat): { + jfloat floatValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&floatValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cFloat, floatValueMid, + floatValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jdouble): { + jdouble doubleValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&doubleValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cDouble, doubleValueMid, + doubleValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + } + break; + } + case H5T_REFERENCE: { + jboolean bb; + jbyte * barray = NULL; + if (NULL == (jobj = ENVPTR->NewByteArray(ENVONLY, vlSize))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, &bb, + "readVL reference: byte array not pinned"); + + for (x = 0; x < (int)vlSize; x++) { + barray[x] = ((jbyte *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, jobj ? 0 : JNI_ABORT); + break; + } + default: + H5_UNIMPLEMENTED(ENVONLY, "H5DreadVL: invalid class type"); + break; + } + + // Add it to the list + ENVPTR->CallBooleanMethod(ENVONLY, jList, addMethod, jobj); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + } /* end for */ + + if (rawBuf) + HDfree(rawBuf); + } + else { + if ((status = H5Dread((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, + (hid_t)file_space_id, (hid_t)xfer_plist_id, (void *)readBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + + UNPIN_BYTE_ARRAY(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); + } + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5DreadVL */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5DwriteVL + * Signature: (JJJJJ[java/util/ArrayList;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, + jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, jobjectArray buf) +{ + H5T_class_t type_class; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; + jboolean writeBufIsCopy; + jbyteArray *writeBuf = NULL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DwriteVL: write buffer is NULL"); + + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5DwriteVL: readBuf length < 0"); + } + + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (type_class == H5T_VLEN) { + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void * rawBuf = NULL; + jobject * jList = NULL; + + size_t i, j, x; + char * cp_vp = NULL; + + if (!(typeSize = H5Tget_size(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(memb = H5Tget_super(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + if ((vlClass = H5Tget_class((hid_t)memb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(vlSize = H5Tget_size(memb))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (rawBuf = HDcalloc((size_t)n, typeSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DwriteVL: failed to allocate raw VL write buffer"); + + /* Cache class types */ + jclass cBool = ENVPTR->FindClass(ENVONLY, "java/lang/Boolean"); + jclass cByte = ENVPTR->FindClass(ENVONLY, "java/lang/Byte"); + jclass cShort = ENVPTR->FindClass(ENVONLY, "java/lang/Short"); + jclass cInt = ENVPTR->FindClass(ENVONLY, "java/lang/Integer"); + jclass cLong = ENVPTR->FindClass(ENVONLY, "java/lang/Long"); + jclass cFloat = ENVPTR->FindClass(ENVONLY, "java/lang/Float"); + jclass cDouble = ENVPTR->FindClass(ENVONLY, "java/lang/Double"); + + jmethodID boolValueMid = ENVPTR->GetMethodID(ENVONLY, cBool, "booleanValue", "()Z"); + jmethodID byteValueMid = ENVPTR->GetMethodID(ENVONLY, cByte, "byteValue", "()B"); + jmethodID shortValueMid = ENVPTR->GetMethodID(ENVONLY, cShort, "shortValue", "()S"); + jmethodID intValueMid = ENVPTR->GetMethodID(ENVONLY, cInt, "intValue", "()I"); + jmethodID longValueMid = ENVPTR->GetMethodID(ENVONLY, cLong, "longValue", "()J"); + jmethodID floatValueMid = ENVPTR->GetMethodID(ENVONLY, cFloat, "floatValue", "()F"); + jmethodID doubleValueMid = ENVPTR->GetMethodID(ENVONLY, cDouble, "doubleValue", "()D"); + + /* Convert each list to a vlen element */ + for (i = 0; i < (size_t)n; i++) { + if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + // retrieve the java.util.List interface class + jclass cList = ENVPTR->FindClass(ENVONLY, "java/util/List"); + + // retrieve the toArray method and invoke it + jmethodID mToArray = ENVPTR->GetMethodID(ENVONLY, cList, "toArray", "()[Ljava/lang/Object;"); + if (mToArray == NULL) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + jobjectArray array = (jobjectArray)ENVPTR->CallObjectMethod(ENVONLY, jList, mToArray); + jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, array); + + cp_vp = (char *)rawBuf + i * typeSize; + ((hvl_t *)cp_vp)->len = jnelmts; + + if (NULL == (((hvl_t *)cp_vp)->p = HDmalloc(jnelmts * vlSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DwriteVL: failed to allocate vlen ptr buffer"); + jobject jobj = NULL; + for (j = 0; j < (int)jnelmts; j++) { + if (NULL == (jobj = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)array, (jsize)j))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + switch (vlClass) { + /* case H5T_BOOL: { + jboolean boolValue = ENVPTR->CallBooleanMethod(ENVONLY, jobj, boolValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&boolValue)[x]; + } + break; + } */ + case H5T_INTEGER: { + switch (vlSize) { + case sizeof(jbyte): { + jbyte byteValue = ENVPTR->CallByteMethod(ENVONLY, jobj, byteValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&byteValue)[x]; + } + break; + } + case sizeof(jshort): { + jshort shortValue = ENVPTR->CallShortMethod(ENVONLY, jobj, shortValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&shortValue)[x]; + } + break; + } + case sizeof(jint): { + jint intValue = ENVPTR->CallIntMethod(ENVONLY, jobj, intValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&intValue)[x]; + } + break; + } + case sizeof(jlong): { + jlong longValue = ENVPTR->CallLongMethod(ENVONLY, jobj, longValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&longValue)[x]; + } + break; + } + } + break; + } + case H5T_FLOAT: { + switch (vlSize) { + case sizeof(jfloat): { + jfloat floatValue = ENVPTR->CallFloatMethod(ENVONLY, jobj, floatValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&floatValue)[x]; + } + break; + } + case sizeof(jdouble): { + jdouble doubleValue = ENVPTR->CallDoubleMethod(ENVONLY, jobj, doubleValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&doubleValue)[x]; + } + break; + } + } + break; + } + case H5T_REFERENCE: { + jbyte *barray = (jbyte *)ENVPTR->GetByteArrayElements(ENVONLY, jobj, 0); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)barray)[x]; + } + ENVPTR->ReleaseByteArrayElements(ENVONLY, jobj, barray, 0); + break; + } + default: + H5_UNIMPLEMENTED(ENVONLY, "H5DwriteVL: invalid class type"); + break; + } + ENVPTR->DeleteLocalRef(ENVONLY, jobj); + } + ENVPTR->DeleteLocalRef(ENVONLY, jList); + } /* end for (i = 0; i < n; i++) */ + + if ((status = H5Dwrite((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, + (hid_t)file_space_id, (hid_t)xfer_plist_id, rawBuf)) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (rawBuf) + HDfree(rawBuf); + } + else { + PIN_BYTE_ARRAY(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5DwriteVL: write buffer not pinned"); + if ((status = H5Dwrite((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, + (hid_t)file_space_id, (hid_t)xfer_plist_id, writeBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + + if (type_class != H5T_VLEN) + UNPIN_BYTE_ARRAY(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); + } + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5DwriteVL */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Dread_VLStrings + * Signature: (JJJJJ[Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Dread_1VLStrings(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, + jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, + jobjectArray buf) +{ + H5T_class_t type_class; htri_t isStr = 0; htri_t isVlenStr = 0; htri_t isComplex = 0; @@ -1111,7 +1530,7 @@ Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong UNUSED(clss); if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DreadVL: read buffer is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DreadVLStrings: read buffer is NULL"); if ((isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1163,7 +1582,7 @@ done: H5Tclose(nested_tid); return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Dread_1VL */ +} /* end Java_hdf_hdf5lib_H5_H5Dread_1VLStrings */ /* * Helper method to read in a buffer of variable-length strings from an HDF5 @@ -1315,54 +1734,15 @@ done: return status; } -/** - * Read VLEN data into array of arrays. - * Object[] buf contains VL arrays of data points - * Currently only deal with variable length of atomic data types - */ -/* old version */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Dread_VLStrings - * Signature: (JJJJJ[Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Dread_1VLStrings(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, - jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, - jobjectArray buf) -{ - htri_t isVlenStr = 0; - herr_t status = FAIL; - - UNUSED(clss); - - if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_VLStrings: read buffer is NULL"); - - if ((isVlenStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (isVlenStr) { - if ((status = H5DreadVL_str(env, (hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, - (hid_t)file_space_id, (hid_t)xfer_plist_id, buf)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } - else - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_VLStrings: datatype is not variable length String"); - -done: - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Dread_1VLStrings */ - /* * Class: hdf_hdf5lib_H5 - * Method: H5DwriteVL + * Method: H5Dwrite_VLStrings * Signature: (JJJJJ[Ljava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, - jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, jobjectArray buf) +Java_hdf_hdf5lib_H5_H5Dwrite_1VLStrings(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, + jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, + jobjectArray buf) { H5T_class_t type_class; htri_t isStr = 0; @@ -1375,7 +1755,7 @@ Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong UNUSED(clss); if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DwriteVL: write buffer is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DwriteVLStrings: write buffer is NULL"); if ((isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1427,7 +1807,7 @@ done: H5Tclose(nested_tid); return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Dwrite_1VL */ +} /* end Java_hdf_hdf5lib_H5_H5Dwrite_1VLStrings */ /* * Helper method to convert an array of Java strings into a buffer of C-strings. @@ -1440,7 +1820,7 @@ H5DwriteVL_str(JNIEnv *env, hid_t dataset_id, hid_t mem_type_id, hid_t mem_space const char *utf8 = NULL; jstring obj; jsize size; - jsize i; + jint i; char ** writeBuf = NULL; herr_t status = FAIL; @@ -1512,7 +1892,7 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si jobjectArray buf) { const char *utf8 = NULL; - jstring obj = NULL; + jstring jstr = NULL; hbool_t close_mem_space = FALSE; size_t typeSize; size_t i; @@ -1549,7 +1929,7 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL_asstr: failed to allocate write buffer"); for (i = 0; i < (size_t)n; ++i) { - if (NULL == (obj = (jstring)ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) { + if (NULL == (jstr = (jstring)ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); /* @@ -1560,11 +1940,11 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si } /* - * length = ENVPTR->GetStringUTFLength(ENVONLY, obj); + * length = ENVPTR->GetStringUTFLength(ENVONLY, jstr); * CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); */ - PIN_JAVA_STRING(ENVONLY, obj, utf8, NULL, "H5DwriteVL_asstr: failed to pin string buffer"); + PIN_JAVA_STRING(ENVONLY, jstr, utf8, NULL, "H5DwriteVL_asstr: failed to pin string buffer"); /* * TODO: If the string isn't a copy, we should probably make @@ -1574,10 +1954,10 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si if (!h5str_convert(ENVONLY, (char **)&utf8, did, tid, &(((char *)writeBuf)[i * typeSize]), 0)) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - UNPIN_JAVA_STRING(ENVONLY, obj, utf8); + UNPIN_JAVA_STRING(ENVONLY, jstr, utf8); utf8 = NULL; - ENVPTR->DeleteLocalRef(ENVONLY, obj); + ENVPTR->DeleteLocalRef(ENVONLY, jstr); } /* end for (i = 0; i < size; ++i) */ if ((status = H5Dwrite(did, tid, mem_sid, file_sid, xfer_plist_id, writeBuf)) < 0) @@ -1585,7 +1965,7 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si done: if (utf8) - UNPIN_JAVA_STRING(ENVONLY, obj, utf8); + UNPIN_JAVA_STRING(ENVONLY, jstr, utf8); if (writeBuf) { H5Treclaim(tid, mem_space, xfer_plist_id, writeBuf); HDfree(writeBuf); @@ -1598,39 +1978,6 @@ done: /* * Class: hdf_hdf5lib_H5 - * Method: H5Dwrite_VLStrings - * Signature: (JJJJJ[Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Dwrite_1VLStrings(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, - jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, - jobjectArray buf) -{ - htri_t isVlenStr = 0; - herr_t status = FAIL; - - UNUSED(clss); - - if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_VLStrings: write buffer is NULL"); - - if ((isVlenStr = H5Tis_variable_str((hid_t)mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (isVlenStr) { - if ((status = H5DwriteVL_str(env, (hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, - (hid_t)file_space_id, (hid_t)xfer_plist_id, buf)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } /* end if */ - else - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_VLStrings: datatype is not variable length String"); - -done: - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Dwrite_1VLStrings */ - -/* - * Class: hdf_hdf5lib_H5 * Method: H5Dread_reg_ref * Signature: (JJJJJ[Ljava/lang/String;)I */ diff --git a/java/src/jni/h5dImp.h b/java/src/jni/h5dImp.h index e339dad..f79cc2c 100644 --- a/java/src/jni/h5dImp.h +++ b/java/src/jni/h5dImp.h @@ -177,7 +177,7 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Dwrite_1double(JNIEnv *, jclass, jl /* * Class: hdf_hdf5lib_H5 * Method: H5DreadVL - * Signature: (JJJJJ[Ljava/lang/String;)I + * Signature: (JJJJJ[Ljava/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *, jclass, jlong, jlong, jlong, jlong, jlong, jobjectArray); @@ -185,7 +185,7 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *, jclass, jlong, jl /* * Class: hdf_hdf5lib_H5 * Method: H5DwriteVL - * Signature: (JJJJJ[Ljava/lang/String;)I + * Signature: (JJJJJ[Ljava/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *, jclass, jlong, jlong, jlong, jlong, jlong, jobjectArray); diff --git a/java/src/jni/h5rImp.c b/java/src/jni/h5rImp.c index 9fe0701..58b5522 100644 --- a/java/src/jni/h5rImp.c +++ b/java/src/jni/h5rImp.c @@ -877,6 +877,67 @@ done: return ret_val; } /* end Java_hdf_hdf5lib_H5_H5Rget_1name */ +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Rget_name_string + * Signature: (JI[B)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Rget_1name_1string(JNIEnv *env, jclass clss, jlong loc_id, jint ref_type, + jbyteArray ref) +{ + jboolean isCopy; + jstring str; + jsize refBufLen; + jbyte * refBuf = NULL; + char * aName = NULL; + ssize_t buf_size = -1; + jlong ret_val = -1; + + UNUSED(clss); + + if (NULL == ref) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: reference buffer is NULL"); + + if ((refBufLen = ENVPTR->GetArrayLength(ENVONLY, ref)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: ref array length < 0"); + } + + if ((H5R_OBJECT == ref_type) && (refBufLen != H5R_OBJ_REF_BUF_SIZE)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: reference input array length != H5R_OBJ_REF_BUF_SIZE"); + else if ((H5R_DATASET_REGION == ref_type) && (refBufLen != H5R_DSET_REG_REF_BUF_SIZE)) + H5_BAD_ARGUMENT_ERROR( + ENVONLY, "H5Rget_name: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE"); + else if ((H5R_OBJECT != ref_type) && (H5R_DATASET_REGION != ref_type)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: unknown reference type"); + + PIN_BYTE_ARRAY(ENVONLY, ref, refBuf, &isCopy, "H5Rget_name: reference buffer not pinned"); + + /* Get the length of the name */ + if ((buf_size = H5Rget_name((hid_t)loc_id, (H5R_type_t)ref_type, refBuf, NULL, 0)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (aName = HDmalloc(sizeof(char) * (size_t)buf_size + 1))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Rget_name: failed to allocate referenced object name buffer"); + + if ((ret_val = (jlong)H5Rget_name((hid_t)loc_id, (H5R_type_t)ref_type, refBuf, aName, + (size_t)buf_size + 1)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + aName[(size_t)buf_size] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, aName))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (aName) + HDfree(aName); + if (refBuf) + UNPIN_BYTE_ARRAY(ENVONLY, ref, refBuf, JNI_ABORT); + + return str; +} /* end Java_hdf_hdf5lib_H5_H5Rget_1name_1string */ + #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ diff --git a/java/src/jni/h5rImp.h b/java/src/jni/h5rImp.h index ffd7737..5865495 100644 --- a/java/src/jni/h5rImp.h +++ b/java/src/jni/h5rImp.h @@ -170,6 +170,13 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Rget_1obj_1type2(JNIEnv *, jclass, JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5Rget_1name(JNIEnv *, jclass, jlong, jint, jbyteArray, jobjectArray, jlong); +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Rget_name_string + * Signature: (JI[B)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_hdf_hdf5lib_H5_H5Rget_1name_1string(JNIEnv *, jclass, jlong, jint, jbyteArray); + #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index 2de5d87..a1a1eda 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -52,6 +52,7 @@ void * edata; /* Local Prototypes */ /********************/ +int h5str_old_region_dataset(JNIEnv *env, h5str_t *out_str, hid_t container, void *ref_buf, int expand_data); int h5str_region_dataset(JNIEnv *env, h5str_t *out_str, H5R_ref_t *ref_vp, int expand_data); static int h5str_dump_region_blocks(JNIEnv *env, h5str_t *str, hid_t region, hid_t region_obj, @@ -63,7 +64,6 @@ static int h5str_is_zero(const void *_mem, size_t size); static hid_t h5str_get_native_type(hid_t type); static hid_t h5str_get_little_endian_type(hid_t type); static hid_t h5str_get_big_endian_type(hid_t type); -static htri_t h5str_detect_vlen(hid_t tid); static htri_t h5str_detect_vlen_str(hid_t tid); static int h5str_dump_simple_data(JNIEnv *env, FILE *stream, hid_t container, hid_t type, void *_mem, hsize_t nelmts); @@ -642,6 +642,33 @@ done: } /* end h5str_convert */ /*------------------------------------------------------------------------- + * Function: h5str_sprint_old_reference + * + * Purpose: Object reference -- show the name of the 1.10 referenced object. + * + * Return: SUCCEED or FAIL + *------------------------------------------------------------------------- + */ +int +h5str_sprint_old_reference(JNIEnv *env, h5str_t *out_str, hid_t region_obj, void *ref_buf) +{ + hid_t region = H5I_INVALID_HID; + char ref_name[1024]; + + int ret_value = FAIL; + + if ((H5Rget_name(region_obj, H5R_DATASET_REGION, ref_buf, (char *)ref_name, 1024)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!h5str_append(out_str, ref_name)) + H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); + + ret_value = SUCCEED; +done: + + return ret_value; +} /* h5str_sprint_reference */ + +/*------------------------------------------------------------------------- * Function: h5str_sprint_reference * * Purpose: Object reference -- show the name of the referenced object. @@ -705,6 +732,48 @@ done: } /* h5str_sprint_reference */ int +h5str_old_region_dataset(JNIEnv *env, h5str_t *out_str, hid_t container, void *ref_buf, int expand_data) +{ + H5S_sel_type region_type = H5S_SEL_ERROR; + hid_t region_obj = H5I_INVALID_HID; + hid_t region_sid = H5I_INVALID_HID; + + int ret_value = FAIL; + + if ((region_obj = H5Rdereference2(container, H5P_DEFAULT, H5R_DATASET_REGION, ref_buf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((region_sid = H5Rget_region(container, H5R_DATASET_REGION, ref_buf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (expand_data == 0) + if (h5str_sprint_old_reference(ENVONLY, out_str, region_obj, ref_buf) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if ((region_type = H5Sget_select_type(region_sid)) > H5S_SEL_ERROR) { + if (H5S_SEL_POINTS == region_type) { + if (h5str_dump_region_points(ENVONLY, out_str, region_sid, region_obj, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + else if (H5S_SEL_HYPERSLABS == region_type) { + if (h5str_dump_region_blocks(ENVONLY, out_str, region_sid, region_obj, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + } + + ret_value = SUCCEED; +done: + if (region_sid >= 0) + if (H5Sclose(region_sid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (region_obj >= 0) + if (H5Dclose(region_obj) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + return ret_value; +} + +int h5str_region_dataset(JNIEnv *env, h5str_t *out_str, H5R_ref_t *ref_vp, int expand_data) { hid_t new_obj_id = H5I_INVALID_HID; @@ -1106,125 +1175,217 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i } case H5T_REFERENCE: { - /* H5T_STD_REF */ - hid_t new_obj_id = H5I_INVALID_HID; - H5O_type_t obj_type = -1; /* Object type */ - H5R_type_t ref_type; /* Reference type */ - - H5R_ref_t *ref_vp = (H5R_ref_t *)cptr; - - ref_type = H5Rget_type(ref_vp); - if (!h5str_is_zero(ref_vp, H5Tget_size(H5T_STD_REF))) { - switch (ref_type) { - case H5R_OBJECT1: - if (H5Rget_obj_type3(ref_vp, H5P_DEFAULT, &obj_type) >= 0) { - switch (obj_type) { - case H5O_TYPE_DATASET: - if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - break; - - case H5O_TYPE_GROUP: - case H5O_TYPE_NAMED_DATATYPE: - case H5O_TYPE_MAP: - case H5O_TYPE_UNKNOWN: - case H5O_TYPE_NTYPES: - default: { - /* Object references -- show the type and OID of the referenced object. */ - H5O_info2_t oi; - char * obj_tok_str = NULL; - if ((new_obj_id = H5Ropen_object(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= - 0) { - H5Oget_info3(new_obj_id, &oi, H5O_INFO_BASIC); - H5Otoken_to_str(new_obj_id, &oi.token, &obj_tok_str); - if (H5Dclose(new_obj_id) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } - else - H5_LIBRARY_ERROR(ENVONLY); - - size_t this_len = 14; - if (NULL == (this_str = (char *)HDmalloc(this_len))) - H5_OUT_OF_MEMORY_ERROR( - ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsnprintf(this_str, this_len, "%u-", (unsigned)oi.type) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); - if (!h5str_append(out_str, this_str)) - H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); - HDfree(this_str); - this_str = NULL; - - /* Print OID */ - { - char *token_str; - - H5Otoken_to_str(tid, &oi.token, &token_str); - - size_t that_len = 64 + strlen(token_str) + 1; - if (NULL == (this_str = HDmalloc(that_len))) - H5_OUT_OF_MEMORY_ERROR( - ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsnprintf(this_str, that_len, "%lu:%s", oi.fileno, token_str) < - 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); - - H5free_memory(token_str); - } - } break; - } /* end switch */ - } - else - H5_LIBRARY_ERROR(ENVONLY); - break; - case H5R_DATASET_REGION1: - if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - break; - case H5R_OBJECT2: - if (H5Rget_obj_type3(ref_vp, H5P_DEFAULT, &obj_type) >= 0) { - switch (obj_type) { - case H5O_TYPE_GROUP: - break; - - case H5O_TYPE_DATASET: - if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - break; - - case H5O_TYPE_NAMED_DATATYPE: - break; - - case H5O_TYPE_MAP: - case H5O_TYPE_UNKNOWN: - case H5O_TYPE_NTYPES: - default: - break; - } /* end switch */ - } - else - H5_ASSERTION_ERROR(ENVONLY, "h5str_sprintf: H5R_OBJECT2 failed"); + if (H5R_DSET_REG_REF_BUF_SIZE == typeSize) { + if (h5str_old_region_dataset(ENVONLY, out_str, container, cptr, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + else if (H5R_OBJ_REF_BUF_SIZE == typeSize) { + H5O_info2_t oi; + hid_t obj = H5I_INVALID_HID; + char * obj_tok_str = NULL; + + /* + * Object references -- show the type and OID of the referenced + * object. + */ + + if (NULL == (this_str = (char *)HDmalloc(64))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if ((obj = H5Rdereference2(container, H5P_DEFAULT, H5R_OBJECT, cptr)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (H5Oget_info3(obj, &oi, H5O_INFO_ALL) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Print object data and close object */ + H5Otoken_to_str(obj, &oi.token, &obj_tok_str); + + switch (oi.type) { + case H5O_TYPE_GROUP: + if (HDsprintf(this_str, "%s %s", H5_TOOLS_GROUP, obj_tok_str) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); break; - case H5R_DATASET_REGION2: - if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + case H5O_TYPE_DATASET: + if (HDsprintf(this_str, "%s %s", H5_TOOLS_DATASET, obj_tok_str) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); break; - case H5R_ATTR: - if ((new_obj_id = H5Ropen_attr(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= 0) { - if (h5str_dump_region_attribute(ENVONLY, out_str, new_obj_id) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - if (H5Aclose(new_obj_id) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } + + case H5O_TYPE_NAMED_DATATYPE: + if (HDsprintf(this_str, "%s %s", H5_TOOLS_DATATYPE, obj_tok_str) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); break; - case H5R_BADTYPE: - case H5R_MAXTYPE: + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: default: + if (HDsprintf(this_str, "%u-%s", (unsigned)oi.type, obj_tok_str) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); break; - } /* end switch */ + } + + if (obj_tok_str) { + H5free_memory(obj_tok_str); + obj_tok_str = NULL; + } + + if (H5Oclose(obj) < 0) + H5_LIBRARY_ERROR(ENVONLY); + obj = H5I_INVALID_HID; } + else { + /* H5T_STD_REF */ + hid_t new_obj_id = H5I_INVALID_HID; + H5O_type_t obj_type = -1; /* Object type */ + H5R_type_t ref_type; /* Reference type */ + + H5R_ref_t *ref_vp = (H5R_ref_t *)cptr; + + ref_type = H5Rget_type(ref_vp); + if (!h5str_is_zero(ref_vp, H5Tget_size(H5T_STD_REF))) { + switch (ref_type) { + case H5R_OBJECT1: + if (H5Rget_obj_type3(ref_vp, H5P_DEFAULT, &obj_type) >= 0) { + switch (obj_type) { + case H5O_TYPE_DATASET: + if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + + case H5O_TYPE_GROUP: + case H5O_TYPE_NAMED_DATATYPE: + case H5O_TYPE_MAP: + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: { + /* Object references -- show the type and + * OID of the referenced object. */ + H5O_info2_t oi; + char * obj_tok_str = NULL; + if ((new_obj_id = H5Ropen_object(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= + 0) { + H5Oget_info3(new_obj_id, &oi, H5O_INFO_BASIC); + H5Otoken_to_str(new_obj_id, &oi.token, &obj_tok_str); + if (H5Dclose(new_obj_id) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + else + H5_LIBRARY_ERROR(ENVONLY); - if (H5Rdestroy(ref_vp) < 0) - H5_LIBRARY_ERROR(ENVONLY); + size_t this_len = 14; + if (NULL == (this_str = (char *)HDmalloc(this_len))) + H5_OUT_OF_MEMORY_ERROR( + ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + switch (oi.type) { + case H5O_TYPE_GROUP: + if (HDsnprintf(this_str, this_len, "%s ", H5_TOOLS_GROUP) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + break; + + case H5O_TYPE_DATASET: + if (HDsnprintf(this_str, this_len, "%s ", H5_TOOLS_DATASET) < + 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + break; + + case H5O_TYPE_NAMED_DATATYPE: + if (HDsnprintf(this_str, this_len, "%s ", H5_TOOLS_DATATYPE) < + 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + break; + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + if (HDsnprintf(this_str, this_len, "%u-", (unsigned)oi.type) < + 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + break; + } /* end switch */ + if (!h5str_append(out_str, this_str)) + H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); + HDfree(this_str); + this_str = NULL; + + /* Print OID */ + { + char *token_str; + + H5Otoken_to_str(tid, &oi.token, &token_str); + + size_t that_len = 64 + strlen(token_str) + 1; + if (NULL == (this_str = HDmalloc(that_len))) + H5_OUT_OF_MEMORY_ERROR( + ENVONLY, + "h5str_sprintf: failed to allocate string buffer"); + if (HDsnprintf(this_str, that_len, "%lu:%s", oi.fileno, + token_str) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + + H5free_memory(token_str); + } + } break; + } /* end switch */ + } + else + H5_LIBRARY_ERROR(ENVONLY); + break; + case H5R_DATASET_REGION1: + if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + case H5R_OBJECT2: + if (H5Rget_obj_type3(ref_vp, H5P_DEFAULT, &obj_type) >= 0) { + switch (obj_type) { + case H5O_TYPE_GROUP: + break; + + case H5O_TYPE_DATASET: + if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + + case H5O_TYPE_NAMED_DATATYPE: + break; + + case H5O_TYPE_MAP: + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + break; + } /* end switch */ + } + else + H5_ASSERTION_ERROR(ENVONLY, "h5str_sprintf: H5R_OBJECT2 failed"); + break; + case H5R_DATASET_REGION2: + if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + case H5R_ATTR: + if ((new_obj_id = H5Ropen_attr(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= 0) { + if (h5str_dump_region_attribute(ENVONLY, out_str, new_obj_id) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + if (H5Aclose(new_obj_id) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + break; + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + break; + } /* end switch */ + } + + if (H5Rdestroy(ref_vp) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } break; } @@ -1761,7 +1922,7 @@ h5str_is_zero(const void *_mem, size_t size) * Negative value: error occurred *------------------------------------------------------------------------- */ -static htri_t +htri_t h5str_detect_vlen(hid_t tid) { htri_t ret = FAIL; @@ -3118,29 +3279,65 @@ done: return ret_value; } +/*------------------------------------------------------------------------- + * Function: H5Tdetect_variable_str + * + * Purpose: Recursive check for variable length string of a datatype. + * + * Return: TRUE : type contains any variable length string + * FALSE : type doesn't contain any variable length string + * Negative value: failed + *------------------------------------------------------------------------- + */ htri_t H5Tdetect_variable_str(hid_t tid) { - htri_t ret_val = 0; - - if (H5Tget_class(tid) == H5T_COMPOUND) { - unsigned i; - unsigned nm = (unsigned)H5Tget_nmembers(tid); - for (i = 0; i < nm; i++) { - htri_t status = 0; - hid_t mtid = 0; - if ((mtid = H5Tget_member_type(tid, i)) < 0) - return FAIL; /* exit immediately on error */ - if ((status = H5Tdetect_variable_str(mtid)) < 0) - return status; /* exit immediately on error */ - ret_val |= status; + H5T_class_t tclass = -1; + htri_t ret = FALSE; + + ret = H5Tis_variable_str(tid); + if ((ret == TRUE) || (ret < 0)) + goto done; + + tclass = H5Tget_class(tid); + if (tclass == H5T_ARRAY || tclass == H5T_VLEN) { + hid_t btid = H5Tget_super(tid); + + if (btid < 0) { + ret = (htri_t)btid; + goto done; + } + ret = H5Tdetect_variable_str(btid); + if ((ret == TRUE) || (ret < 0)) { + H5Tclose(btid); + goto done; + } + } + else if (tclass == H5T_COMPOUND) { + unsigned nmembs; + int snmembs = H5Tget_nmembers(tid); + unsigned u; + + if (snmembs < 0) { + ret = FAIL; + goto done; + } + nmembs = (unsigned)snmembs; + + for (u = 0; u < nmembs; u++) { + hid_t mtid = H5Tget_member_type(tid, u); + + ret = H5Tdetect_variable_str(mtid); + if ((ret == TRUE) || (ret < 0)) { + H5Tclose(mtid); + goto done; + } H5Tclose(mtid); - } /* end for */ - } /* end if */ - else - ret_val = H5Tis_variable_str(tid); + } + } - return ret_val; +done: + return ret; } /* end H5Tdetect_variable_str */ static int diff --git a/java/src/jni/h5util.h b/java/src/jni/h5util.h index 6c568e1..3146c06 100644 --- a/java/src/jni/h5util.h +++ b/java/src/jni/h5util.h @@ -39,8 +39,10 @@ extern void h5str_new(h5str_t *str, size_t len); extern void h5str_free(h5str_t *str); extern void h5str_resize(h5str_t *str, size_t new_len); extern char * h5str_append(h5str_t *str, const char *cstr); +extern htri_t h5str_detect_vlen(hid_t tid); extern size_t h5str_convert(JNIEnv *env, char **in_str, hid_t container, hid_t tid, void *out_buf, size_t out_buf_offset); +extern int h5str_sprint_old_reference(JNIEnv *env, h5str_t *out_str, hid_t region_obj, void *ref_buf); extern int h5str_sprint_reference(JNIEnv *env, h5str_t *out_str, void *ref_p); extern size_t h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *in_buf, int expand_data); diff --git a/java/src/jni/nativeData.c b/java/src/jni/nativeData.c index 9e63f4f..ac9168b 100644 --- a/java/src/jni/nativeData.c +++ b/java/src/jni/nativeData.c @@ -46,8 +46,7 @@ extern "C" { /* returns int [] */ JNIEXPORT jintArray JNICALL -Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B(JNIEnv *env, jclass clss, - jbyteArray bdata) /* IN: array of bytes */ +Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B(JNIEnv *env, jclass clss, jbyteArray bdata) { jintArray rarray = NULL; jboolean bb; diff --git a/java/test/TestH5A.java b/java/test/TestH5A.java index fed13ce..96ce5b5 100644 --- a/java/test/TestH5A.java +++ b/java/test/TestH5A.java @@ -20,6 +20,8 @@ import static org.junit.Assert.fail; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; @@ -637,9 +639,8 @@ public class TestH5A { attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_INC, 0, lapl_id); assertNotNull(attr_info); - assertTrue("Corder ", - attr_info.corder == - 0); // should equal 0 as this is the order of 1st attribute created. + assertTrue("Corder ", attr_info.corder == + 0); // should equal 0 as this is the order of 1st attribute created. assertEquals(attr_info.data_size, H5.H5Aget_storage_size(attr_id)); // Verify info for 2nd attribute, in increasing creation order @@ -653,33 +654,29 @@ public class TestH5A { attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_DEC, 0, lapl_id); assertNotNull(attr_info); - assertTrue("Corder", - attr_info.corder == - 1); // should equal 1 as this is the order of 2nd attribute created. + assertTrue("Corder", attr_info.corder == + 1); // should equal 1 as this is the order of 2nd attribute created. // verify info for 1st attribute, in decreasing creation order attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_DEC, 1, lapl_id); assertNotNull(attr_info); - assertTrue("Corder", - attr_info.corder == - 0); // should equal 0 as this is the order of 1st attribute created. + assertTrue("Corder", attr_info.corder == + 0); // should equal 0 as this is the order of 1st attribute created. // verify info for 1st attribute, in increasing name order attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 1, lapl_id); assertNotNull(attr_info); - assertTrue("Corder", - attr_info.corder == - 0); // should equal 0 as this is the order of 1st attribute created. + assertTrue("Corder", attr_info.corder == + 0); // should equal 0 as this is the order of 1st attribute created. // verify info for 2nd attribute, in decreasing name order attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_DEC, 1, lapl_id); assertNotNull(attr_info); - assertTrue("Corder", - attr_info.corder == - 1); // should equal 1 as this is the order of 2nd attribute created. + assertTrue("Corder", attr_info.corder == + 1); // should equal 1 as this is the order of 2nd attribute created. } catch (Throwable err) { err.printStackTrace(); @@ -1075,7 +1072,7 @@ public class TestH5A { HDF5Constants.H5P_DEFAULT); assertTrue("testH5Awrite_readVL: ", attr_id >= 0); - H5.H5AwriteVL(attr_id, atype_id, str_data); + H5.H5Awrite_VLStrings(attr_id, atype_id, str_data); H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); @@ -1087,7 +1084,7 @@ public class TestH5A { strs[j] = ""; } try { - H5.H5AreadVL(attr_id, atype_id, strs); + H5.H5Aread_VLStrings(attr_id, atype_id, strs); } catch (Exception ex) { ex.printStackTrace(); @@ -1162,12 +1159,12 @@ public class TestH5A { fail("H5.H5Acreate: " + err); } - /* Close the property list, and get the attribute's property list */ + // Close the property list, and get the attribute's property list H5.H5Pclose(plist_id); plist_id = H5.H5Aget_create_plist(attribute_id); assertTrue(plist_id > 0); - /* Get the character encoding and ensure that it is the default (ASCII) */ + // Get the character encoding and ensure that it is the default (ASCII) try { char_encoding = H5.H5Pget_char_encoding(plist_id); } @@ -1371,4 +1368,212 @@ public class TestH5A { } } } + + @Test + public void testH5AVLwr() + { + String attr_int_name = "VLIntdata"; + String attr_dbl_name = "VLDbldata"; + long attr_int_id = HDF5Constants.H5I_INVALID_HID; + long attr_dbl_id = HDF5Constants.H5I_INVALID_HID; + long atype_int_id = HDF5Constants.H5I_INVALID_HID; + long atype_dbl_id = HDF5Constants.H5I_INVALID_HID; + long aspace_id = HDF5Constants.H5I_INVALID_HID; + long[] dims = {4}; + long lsize = 1; + + ArrayList[] vl_int_data = new ArrayList[4]; + ArrayList[] vl_dbl_data = new ArrayList[4]; + try { + // Write Integer data + vl_int_data[0] = new ArrayList(Arrays.asList(1)); + vl_int_data[1] = new ArrayList(Arrays.asList(2, 3)); + vl_int_data[2] = new ArrayList(Arrays.asList(4, 5, 6)); + vl_int_data[3] = new ArrayList(Arrays.asList(7, 8, 9, 10)); + Class dataClass = vl_int_data.getClass(); + assertTrue("testH5AVLwr.getClass: " + dataClass, dataClass.isArray()); + + try { + atype_int_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_U32LE); + assertTrue("testH5AVLwr.H5Tvlen_create: ", atype_int_id >= 0); + } + catch (Exception err) { + if (atype_int_id > 0) + try { + H5.H5Tclose(atype_int_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + + try { + aspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(aspace_id > 0); + attr_int_id = H5.H5Acreate(H5did, attr_int_name, atype_int_id, aspace_id, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5AVLwr: ", attr_int_id >= 0); + + H5.H5AwriteVL(attr_int_id, atype_int_id, vl_int_data); + } + catch (Exception err) { + if (attr_int_id > 0) + try { + H5.H5Aclose(attr_int_id); + } + catch (Exception ex) { + } + if (atype_int_id > 0) + try { + H5.H5Tclose(atype_int_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + finally { + if (aspace_id > 0) + try { + H5.H5Sclose(aspace_id); + } + catch (Exception ex) { + } + } + + // Write Double data + vl_dbl_data[0] = new ArrayList(Arrays.asList(1.1)); + vl_dbl_data[1] = new ArrayList(Arrays.asList(2.2, 3.3)); + vl_dbl_data[2] = new ArrayList(Arrays.asList(4.4, 5.5, 6.6)); + vl_dbl_data[3] = new ArrayList(Arrays.asList(7.7, 8.8, 9.9, 10.0)); + dataClass = vl_dbl_data.getClass(); + assertTrue("testH5AVLwr.getClass: " + dataClass, dataClass.isArray()); + + try { + atype_dbl_id = H5.H5Tvlen_create(HDF5Constants.H5T_NATIVE_DOUBLE); + assertTrue("testH5AVLwr.H5Tvlen_create: ", atype_dbl_id >= 0); + } + catch (Exception err) { + if (atype_dbl_id > 0) + try { + H5.H5Tclose(atype_dbl_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + + try { + aspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(aspace_id > 0); + attr_dbl_id = H5.H5Acreate(H5did, attr_dbl_name, atype_dbl_id, aspace_id, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5AVLwr: ", attr_dbl_id >= 0); + + H5.H5AwriteVL(attr_dbl_id, atype_dbl_id, vl_dbl_data); + } + catch (Exception err) { + if (attr_dbl_id > 0) + try { + H5.H5Aclose(attr_dbl_id); + } + catch (Exception ex) { + } + if (atype_dbl_id > 0) + try { + H5.H5Tclose(atype_dbl_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + finally { + if (aspace_id > 0) + try { + H5.H5Sclose(aspace_id); + } + catch (Exception ex) { + } + } + + H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); + + for (int j = 0; j < dims.length; j++) { + lsize *= dims[j]; + } + + // Read Integer data + ArrayList[] vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5AreadVL(attr_int_id, atype_int_id, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5AVLwr:" + vl_readbuf[0].get(0), + vl_int_data[0].get(0).equals(vl_readbuf[0].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[1].get(0), + vl_int_data[1].get(0).equals(vl_readbuf[1].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[2].get(0), + vl_int_data[2].get(0).equals(vl_readbuf[2].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[3].get(0), + vl_int_data[3].get(0).equals(vl_readbuf[3].get(0))); + + // Read Double data + vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5AreadVL(attr_dbl_id, atype_dbl_id, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5AVLwr:" + vl_readbuf[0].get(0), + vl_dbl_data[0].get(0).equals(vl_readbuf[0].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[1].get(0), + vl_dbl_data[1].get(0).equals(vl_readbuf[1].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[2].get(0), + vl_dbl_data[2].get(0).equals(vl_readbuf[2].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[3].get(0), + vl_dbl_data[3].get(0).equals(vl_readbuf[3].get(0))); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + finally { + if (attr_dbl_id > 0) + try { + H5.H5Aclose(attr_dbl_id); + } + catch (Exception ex) { + } + if (attr_int_id > 0) + try { + H5.H5Aclose(attr_int_id); + } + catch (Exception ex) { + } + if (atype_dbl_id > 0) + try { + H5.H5Tclose(atype_dbl_id); + } + catch (Exception ex) { + } + if (atype_int_id > 0) + try { + H5.H5Tclose(atype_int_id); + } + catch (Exception ex) { + } + } + } } diff --git a/java/test/TestH5D.java b/java/test/TestH5D.java index 4bab1a9..f7e5702 100644 --- a/java/test/TestH5D.java +++ b/java/test/TestH5D.java @@ -17,6 +17,9 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; @@ -961,8 +964,8 @@ public class TestH5D { assertTrue("H5Dvlen_get_buf_size " + vl_size + " == " + str_data_bytes, vl_size == str_data_bytes); } - @Test(expected = IllegalArgumentException.class) - public void testH5Dvlen_read_invalid_buffer() throws Throwable + @Test + public void testH5Dvlen_read_default_buffer() throws Throwable { String[] str_data = {"Parting", "is such", "sweet", "sorrow.", "Testing", "one", "two", "three.", "Dog,", "man's", "best", "friend.", "Diamonds", "are", "a", "girls!", @@ -1013,4 +1016,218 @@ public class TestH5D { assertTrue("testH5Dvlen_write_read " + str_wdata[v] + " == " + str_rdata[v], str_wdata[v] == str_wdata[v]); } + + @Test + public void testH5DVLwr() + { + String dset_int_name = "VLIntdata"; + String dset_dbl_name = "VLDbldata"; + long dset_int_id = HDF5Constants.H5I_INVALID_HID; + long dset_dbl_id = HDF5Constants.H5I_INVALID_HID; + long dtype_int_id = HDF5Constants.H5I_INVALID_HID; + long dtype_dbl_id = HDF5Constants.H5I_INVALID_HID; + long dspace_id = HDF5Constants.H5I_INVALID_HID; + long[] dims = {4}; + long lsize = 1; + + ArrayList[] vl_int_data = new ArrayList[4]; + ArrayList[] vl_dbl_data = new ArrayList[4]; + try { + // Write Integer data + vl_int_data[0] = new ArrayList(Arrays.asList(1)); + vl_int_data[1] = new ArrayList(Arrays.asList(2, 3)); + vl_int_data[2] = new ArrayList(Arrays.asList(4, 5, 6)); + vl_int_data[3] = new ArrayList(Arrays.asList(7, 8, 9, 10)); + Class dataClass = vl_int_data.getClass(); + assertTrue("testH5DVLwr.getClass: " + dataClass, dataClass.isArray()); + + try { + dtype_int_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_U32LE); + assertTrue("testH5DVLwr.H5Tvlen_create: ", dtype_int_id >= 0); + } + catch (Exception err) { + if (dtype_int_id > 0) + try { + H5.H5Tclose(dtype_int_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + + try { + dspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(dspace_id > 0); + dset_int_id = + H5.H5Dcreate(H5fid, dset_int_name, dtype_int_id, dspace_id, HDF5Constants.H5P_DEFAULT, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5DVLwr: ", dset_int_id >= 0); + + H5.H5DwriteVL(dset_int_id, dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_int_data); + } + catch (Exception err) { + if (dset_int_id > 0) + try { + H5.H5Dclose(dset_int_id); + } + catch (Exception ex) { + } + if (dtype_int_id > 0) + try { + H5.H5Tclose(dtype_int_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + finally { + if (dspace_id > 0) + try { + H5.H5Sclose(dspace_id); + } + catch (Exception ex) { + } + } + + // Write Double data + vl_dbl_data[0] = new ArrayList(Arrays.asList(1.1)); + vl_dbl_data[1] = new ArrayList(Arrays.asList(2.2, 3.3)); + vl_dbl_data[2] = new ArrayList(Arrays.asList(4.4, 5.5, 6.6)); + vl_dbl_data[3] = new ArrayList(Arrays.asList(7.7, 8.8, 9.9, 10.0)); + dataClass = vl_dbl_data.getClass(); + assertTrue("testH5DVLwr.getClass: " + dataClass, dataClass.isArray()); + + try { + dtype_dbl_id = H5.H5Tvlen_create(HDF5Constants.H5T_NATIVE_DOUBLE); + assertTrue("testH5DVLwr.H5Tvlen_create: ", dtype_dbl_id >= 0); + } + catch (Exception err) { + if (dtype_dbl_id > 0) + try { + H5.H5Tclose(dtype_dbl_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + + try { + dspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(dspace_id > 0); + dset_dbl_id = + H5.H5Dcreate(H5fid, dset_dbl_name, dtype_dbl_id, dspace_id, HDF5Constants.H5P_DEFAULT, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5DVLwr: ", dset_dbl_id >= 0); + + H5.H5DwriteVL(dset_dbl_id, dtype_dbl_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_dbl_data); + } + catch (Exception err) { + if (dset_dbl_id > 0) + try { + H5.H5Dclose(dset_dbl_id); + } + catch (Exception ex) { + } + if (dtype_dbl_id > 0) + try { + H5.H5Tclose(dtype_dbl_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + finally { + if (dspace_id > 0) + try { + H5.H5Sclose(dspace_id); + } + catch (Exception ex) { + } + } + + H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); + + for (int j = 0; j < dims.length; j++) { + lsize *= dims[j]; + } + + // Read Integer data + ArrayList[] vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5DreadVL(dset_int_id, dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5DVLwr:" + vl_readbuf[0].get(0), + vl_int_data[0].get(0).equals(vl_readbuf[0].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[1].get(0), + vl_int_data[1].get(0).equals(vl_readbuf[1].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[2].get(0), + vl_int_data[2].get(0).equals(vl_readbuf[2].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[3].get(0), + vl_int_data[3].get(0).equals(vl_readbuf[3].get(0))); + + // Read Double data + vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5DreadVL(dset_dbl_id, dtype_dbl_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5DVLwr:" + vl_readbuf[0].get(0), + vl_dbl_data[0].get(0).equals(vl_readbuf[0].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[1].get(0), + vl_dbl_data[1].get(0).equals(vl_readbuf[1].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[2].get(0), + vl_dbl_data[2].get(0).equals(vl_readbuf[2].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[3].get(0), + vl_dbl_data[3].get(0).equals(vl_readbuf[3].get(0))); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + finally { + if (dset_dbl_id > 0) + try { + H5.H5Dclose(dset_dbl_id); + } + catch (Exception ex) { + } + if (dset_int_id > 0) + try { + H5.H5Dclose(dset_int_id); + } + catch (Exception ex) { + } + if (dtype_dbl_id > 0) + try { + H5.H5Tclose(dtype_dbl_id); + } + catch (Exception ex) { + } + if (dtype_int_id > 0) + try { + H5.H5Tclose(dtype_int_id); + } + catch (Exception ex) { + } + } + } } diff --git a/java/test/TestH5R.java b/java/test/TestH5R.java index 4e610bc..dd8634b 100644 --- a/java/test/TestH5R.java +++ b/java/test/TestH5R.java @@ -19,6 +19,9 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; @@ -528,4 +531,470 @@ public class TestH5R { byte[] ref = null; H5.H5Rget_attr_name(ref); } + + @Test + public void testH5RVLattr_ref() + { + String attr_obj_name = "VLObjRefdata"; + String attr_reg_name = "VLRegRefdata"; + long attr_obj_id = HDF5Constants.H5I_INVALID_HID; + long attr_reg_id = HDF5Constants.H5I_INVALID_HID; + long atype_obj_id = HDF5Constants.H5I_INVALID_HID; + long atype_reg_id = HDF5Constants.H5I_INVALID_HID; + long aspace_id = HDF5Constants.H5I_INVALID_HID; + long[] dims = {4}; + long lsize = 1; + byte[] ref1 = null; + byte[] ref2 = null; + byte[] ref3 = null; + byte[] ref4 = null; + + try { + // Create reference on dataset + ref1 = H5.H5Rcreate(H5fid, "/dset", HDF5Constants.H5R_DATASET_REGION, H5dsid); + assertNotNull(ref1); + ref2 = H5.H5Rcreate(H5gid, "dset2", HDF5Constants.H5R_DATASET_REGION, H5dsid); + assertNotNull(ref2); + ref3 = H5.H5Rcreate(H5gid, "/dset", HDF5Constants.H5R_OBJECT, -1); + assertNotNull(ref3); + + // Create reference on group + ref4 = H5.H5Rcreate(H5gid, "/Group1", HDF5Constants.H5R_OBJECT, -1); + assertNotNull(ref3); + } + catch (Throwable err) { + err.printStackTrace(); + fail("testH5RVLattr_ref: " + err); + } + + ArrayList[] vl_obj_data = new ArrayList[4]; + ArrayList[] vl_reg_data = new ArrayList[4]; + try { + // Write Object Reference data + vl_obj_data[0] = new ArrayList(Arrays.asList(ref3)); + vl_obj_data[1] = new ArrayList(Arrays.asList(ref3, ref4)); + vl_obj_data[2] = new ArrayList(Arrays.asList(ref3, ref3, ref3)); + vl_obj_data[3] = new ArrayList(Arrays.asList(ref4, ref4, ref4, ref4)); + Class dataClass = vl_obj_data.getClass(); + assertTrue("testH5RVLattr_ref.getClass: " + dataClass, dataClass.isArray()); + + try { + atype_obj_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_REF_OBJ); + assertTrue("testH5RVLattr_ref.H5Tvlen_create: ", atype_obj_id >= 0); + } + catch (Exception err) { + if (atype_obj_id > 0) + try { + H5.H5Tclose(atype_obj_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + + try { + aspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(aspace_id > 0); + attr_obj_id = H5.H5Acreate(H5did, attr_obj_name, atype_obj_id, aspace_id, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5RVLattr_ref: ", attr_obj_id >= 0); + + H5.H5AwriteVL(attr_obj_id, atype_obj_id, vl_obj_data); + } + catch (Exception err) { + if (attr_obj_id > 0) + try { + H5.H5Aclose(attr_obj_id); + } + catch (Exception ex) { + } + if (atype_obj_id > 0) + try { + H5.H5Tclose(atype_obj_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + finally { + if (aspace_id > 0) + try { + H5.H5Sclose(aspace_id); + } + catch (Exception ex) { + } + } + + // Write Region Reference data + vl_reg_data[0] = new ArrayList(Arrays.asList(ref1)); + vl_reg_data[1] = new ArrayList(Arrays.asList(ref1, ref2)); + vl_reg_data[2] = new ArrayList(Arrays.asList(ref1, ref1, ref1)); + vl_reg_data[3] = new ArrayList(Arrays.asList(ref2, ref2, ref2, ref2)); + dataClass = vl_reg_data.getClass(); + assertTrue("testH5RVLattr_ref.getClass: " + dataClass, dataClass.isArray()); + + try { + atype_reg_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_REF_DSETREG); + assertTrue("testH5RVLattr_ref.H5Tvlen_create: ", atype_reg_id >= 0); + } + catch (Exception err) { + if (atype_reg_id > 0) + try { + H5.H5Tclose(atype_reg_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + + try { + aspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(aspace_id > 0); + attr_reg_id = H5.H5Acreate(H5did, attr_reg_name, atype_reg_id, aspace_id, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5RVLattr_ref: ", attr_reg_id >= 0); + + H5.H5AwriteVL(attr_reg_id, atype_reg_id, vl_reg_data); + } + catch (Exception err) { + if (attr_reg_id > 0) + try { + H5.H5Aclose(attr_reg_id); + } + catch (Exception ex) { + } + if (atype_reg_id > 0) + try { + H5.H5Tclose(atype_reg_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + finally { + if (aspace_id > 0) + try { + H5.H5Sclose(aspace_id); + } + catch (Exception ex) { + } + } + + H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); + + for (int j = 0; j < dims.length; j++) { + lsize *= dims[j]; + } + + // Read Object Reference data + ArrayList[] vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5AreadVL(attr_obj_id, atype_obj_id, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[0].get(0))[0], + ((byte[])vl_obj_data[0].get(0))[0] == ((byte[])vl_readbuf[0].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[1].get(0))[0], + ((byte[])vl_obj_data[1].get(0))[0] == ((byte[])vl_readbuf[1].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[2].get(0))[0], + ((byte[])vl_obj_data[2].get(0))[0] == ((byte[])vl_readbuf[2].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[3].get(0))[0], + ((byte[])vl_obj_data[3].get(0))[0] == ((byte[])vl_readbuf[3].get(0))[0]); + + // Read Region Reference data + vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5AreadVL(attr_reg_id, atype_reg_id, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[0].get(0))[0], + ((byte[])vl_reg_data[0].get(0))[0] == ((byte[])vl_readbuf[0].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[1].get(0))[0], + ((byte[])vl_reg_data[1].get(0))[0] == ((byte[])vl_readbuf[1].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[2].get(0))[0], + ((byte[])vl_reg_data[2].get(0))[0] == ((byte[])vl_readbuf[2].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[3].get(0))[0], + ((byte[])vl_reg_data[3].get(0))[0] == ((byte[])vl_readbuf[3].get(0))[0]); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + finally { + if (attr_reg_id > 0) + try { + H5.H5Aclose(attr_reg_id); + } + catch (Exception ex) { + } + if (attr_obj_id > 0) + try { + H5.H5Aclose(attr_obj_id); + } + catch (Exception ex) { + } + if (atype_reg_id > 0) + try { + H5.H5Tclose(atype_reg_id); + } + catch (Exception ex) { + } + if (atype_obj_id > 0) + try { + H5.H5Tclose(atype_obj_id); + } + catch (Exception ex) { + } + } + } + + @Test + public void testH5RVLdset_ref() + { + String dset_obj_name = "VLObjRefdata"; + String dset_reg_name = "VLRegRefdata"; + long dset_obj_id = HDF5Constants.H5I_INVALID_HID; + long dset_reg_id = HDF5Constants.H5I_INVALID_HID; + long dtype_obj_id = HDF5Constants.H5I_INVALID_HID; + long dtype_reg_id = HDF5Constants.H5I_INVALID_HID; + long dspace_id = HDF5Constants.H5I_INVALID_HID; + long[] dims = {4}; + long lsize = 1; + byte[] ref1 = null; + byte[] ref2 = null; + byte[] ref3 = null; + byte[] ref4 = null; + + try { + // Create reference on dataset + ref1 = H5.H5Rcreate(H5fid, "/dset", HDF5Constants.H5R_DATASET_REGION, H5dsid); + assertNotNull(ref1); + ref2 = H5.H5Rcreate(H5gid, "dset2", HDF5Constants.H5R_DATASET_REGION, H5dsid); + assertNotNull(ref2); + ref3 = H5.H5Rcreate(H5gid, "/dset", HDF5Constants.H5R_OBJECT, -1); + assertNotNull(ref3); + + // Create reference on group + ref4 = H5.H5Rcreate(H5gid, "/Group1", HDF5Constants.H5R_OBJECT, -1); + assertNotNull(ref3); + } + catch (Throwable err) { + err.printStackTrace(); + fail("testH5RVLattr_ref: " + err); + } + + ArrayList[] vl_obj_data = new ArrayList[4]; + ArrayList[] vl_reg_data = new ArrayList[4]; + try { + // Write Object Reference data + vl_obj_data[0] = new ArrayList(Arrays.asList(ref3)); + vl_obj_data[1] = new ArrayList(Arrays.asList(ref3, ref4)); + vl_obj_data[2] = new ArrayList(Arrays.asList(ref3, ref3, ref3)); + vl_obj_data[3] = new ArrayList(Arrays.asList(ref4, ref4, ref4, ref4)); + Class dataClass = vl_obj_data.getClass(); + assertTrue("testH5RVLdset_ref.getClass: " + dataClass, dataClass.isArray()); + + try { + dtype_obj_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_REF_OBJ); + assertTrue("testH5RVLdset_ref.H5Tvlen_create: ", dtype_obj_id >= 0); + } + catch (Exception err) { + if (dtype_obj_id > 0) + try { + H5.H5Tclose(dtype_obj_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + + try { + dspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(dspace_id > 0); + dset_obj_id = + H5.H5Dcreate(H5fid, dset_obj_name, dtype_obj_id, dspace_id, HDF5Constants.H5P_DEFAULT, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5RVLdset_ref: ", dset_obj_id >= 0); + + H5.H5DwriteVL(dset_obj_id, dtype_obj_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_obj_data); + } + catch (Exception err) { + if (dset_obj_id > 0) + try { + H5.H5Dclose(dset_obj_id); + } + catch (Exception ex) { + } + if (dtype_obj_id > 0) + try { + H5.H5Tclose(dtype_obj_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + finally { + if (dspace_id > 0) + try { + H5.H5Sclose(dspace_id); + } + catch (Exception ex) { + } + } + + // Write Region Reference data + vl_reg_data[0] = new ArrayList(Arrays.asList(ref1)); + vl_reg_data[1] = new ArrayList(Arrays.asList(ref1, ref2)); + vl_reg_data[2] = new ArrayList(Arrays.asList(ref1, ref1, ref1)); + vl_reg_data[3] = new ArrayList(Arrays.asList(ref2, ref2, ref2, ref2)); + dataClass = vl_reg_data.getClass(); + assertTrue("testH5RVLdset_ref.getClass: " + dataClass, dataClass.isArray()); + + try { + dtype_reg_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_REF_DSETREG); + assertTrue("testH5RVLdset_ref.H5Tvlen_create: ", dtype_reg_id >= 0); + } + catch (Exception err) { + if (dtype_reg_id > 0) + try { + H5.H5Tclose(dtype_reg_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + + try { + dspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(dspace_id > 0); + dset_reg_id = + H5.H5Dcreate(H5fid, dset_reg_name, dtype_reg_id, dspace_id, HDF5Constants.H5P_DEFAULT, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5RVLdset_ref: ", dset_reg_id >= 0); + + H5.H5DwriteVL(dset_reg_id, dtype_reg_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_reg_data); + } + catch (Exception err) { + if (dset_reg_id > 0) + try { + H5.H5Dclose(dset_reg_id); + } + catch (Exception ex) { + } + if (dtype_reg_id > 0) + try { + H5.H5Tclose(dtype_reg_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + finally { + if (dspace_id > 0) + try { + H5.H5Sclose(dspace_id); + } + catch (Exception ex) { + } + } + + H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); + + for (int j = 0; j < dims.length; j++) { + lsize *= dims[j]; + } + + // Read Object Reference data + ArrayList[] vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5DreadVL(dset_obj_id, dtype_obj_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[0].get(0))[0], + ((byte[])vl_obj_data[0].get(0))[0] == ((byte[])vl_readbuf[0].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[1].get(0))[0], + ((byte[])vl_obj_data[1].get(0))[0] == ((byte[])vl_readbuf[1].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[2].get(0))[0], + ((byte[])vl_obj_data[2].get(0))[0] == ((byte[])vl_readbuf[2].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[3].get(0))[0], + ((byte[])vl_obj_data[3].get(0))[0] == ((byte[])vl_readbuf[3].get(0))[0]); + + // Read Region Reference data + vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5DreadVL(dset_reg_id, dtype_reg_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[0].get(0))[0], + ((byte[])vl_reg_data[0].get(0))[0] == ((byte[])vl_readbuf[0].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[1].get(0))[0], + ((byte[])vl_reg_data[1].get(0))[0] == ((byte[])vl_readbuf[1].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[2].get(0))[0], + ((byte[])vl_reg_data[2].get(0))[0] == ((byte[])vl_readbuf[2].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[3].get(0))[0], + ((byte[])vl_reg_data[3].get(0))[0] == ((byte[])vl_readbuf[3].get(0))[0]); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + finally { + if (dset_reg_id > 0) + try { + H5.H5Dclose(dset_reg_id); + } + catch (Exception ex) { + } + if (dset_obj_id > 0) + try { + H5.H5Dclose(dset_obj_id); + } + catch (Exception ex) { + } + if (dtype_reg_id > 0) + try { + H5.H5Tclose(dtype_reg_id); + } + catch (Exception ex) { + } + if (dtype_obj_id > 0) + try { + H5.H5Tclose(dtype_obj_id); + } + catch (Exception ex) { + } + } + } } diff --git a/java/test/testfiles/JUnit-TestH5A.txt b/java/test/testfiles/JUnit-TestH5A.txt index 2026d21..efdd4a2 100644 --- a/java/test/testfiles/JUnit-TestH5A.txt +++ b/java/test/testfiles/JUnit-TestH5A.txt @@ -6,6 +6,7 @@ JUnit version 4.11 .testH5Aiterate .testH5Aopen_by_idx .testH5Aopen_invalidname +.testH5AVLwr .testH5Aopen .testH5Aget_info_by_name .testH5Aget_create_plist @@ -30,5 +31,5 @@ JUnit version 4.11 Time: XXXX -OK (28 tests) +OK (29 tests) diff --git a/java/test/testfiles/JUnit-TestH5D.txt b/java/test/testfiles/JUnit-TestH5D.txt index 987655b..288e6d0 100644 --- a/java/test/testfiles/JUnit-TestH5D.txt +++ b/java/test/testfiles/JUnit-TestH5D.txt @@ -4,6 +4,7 @@ JUnit version 4.11 .testH5Dcreate .testH5Dget_offset .testH5Dget_type +.testH5DVLwr .testH5Dfill .testH5Dopen .testH5Dcreate_anon @@ -11,15 +12,15 @@ JUnit version 4.11 .testH5Dget_storage_size_empty .testH5Diterate .testH5Dget_access_plist -.testH5Dvlen_read_invalid_buffer .testH5Dvlen_get_buf_size .testH5Dget_space_closed .testH5Dget_space_status .testH5Dvlen_write_read .testH5Dget_space .testH5Dget_type_closed +.testH5Dvlen_read_default_buffer Time: XXXX -OK (19 tests) +OK (20 tests) diff --git a/java/test/testfiles/JUnit-TestH5R.txt b/java/test/testfiles/JUnit-TestH5R.txt index a96fbb4..2420d62 100644 --- a/java/test/testfiles/JUnit-TestH5R.txt +++ b/java/test/testfiles/JUnit-TestH5R.txt @@ -4,6 +4,8 @@ JUnit version 4.11 .testH5Ropen_region_Nullref .testH5Requal_Nullref1 .testH5Requal_Nullref2 +.testH5RVLdset_ref +.testH5RVLattr_ref .testH5Rget_object .testH5Rget_obj_type3_Nullref .testH5Ropen_object_Nullref @@ -24,5 +26,5 @@ JUnit version 4.11 Time: XXXX -OK (22 tests) +OK (24 tests) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 8fe0df8..e545cc7 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -72,12 +72,55 @@ New Features Java Library: ------------- - - + - Added version of H5Rget_name to return the name as a Java string. + + Other functions that get_name process the get_size then get the name + within the JNI implementation. Now H5Rget_name has a H5Rget_name_string. + + (ADB - 2022/07/12) + + - Added reference support to H5A and H5D read write vlen JNI functions. + + Added the implementation to handle VL references as an Array of Lists + of byte arrays. + + The JNI wrappers translate the Array of Lists to/from the hvl_t vlen + structures. The wrappers use the specified datatype arguments for the + List type translation, it is expected that the Java type is correct. + + (ADB - 2022/07/11, HDFFV-11318) + + - H5A and H5D read write vlen JNI functions were incorrect. + + Corrected the vlen function implementations for the basic primitive types. + The VLStrings functions now correctly use the implementation that had been + the VL functions. (VLStrings functions did not have an implementation.) + The new VL functions implementation now expect an Array of Lists between + Java and the JNI wrapper. + + The JNI wrappers translate the Array of Lists to/from the hvl_t vlen + structures. The wrappers use the specified datatype arguments for the + List type translation, it is expected that the Java type is correct. + + (ADB - 2022/07/07, HDFFV-11310) + + - H5A and H5D read write JNI functions had flawed vlen datatype check. + + Adapted tools function for JNI utils file. This reduced multiple calls + to a single check and variable. The variable can then be used to call + the H5Treclaim function. Adjusted existing test and added new test. + + (ADB - 2022/06/22) Tools: ------ - - + - 1.10 References in containers were not displayed properly by h5dump. + + Ported 1.10 tools display function to provide ability to inspect and + display 1.10 reference data. + + (ADB - 2022/06/22) High-Level APIs: diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index daeeb95..626adfa 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -1182,7 +1182,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai /* if(nsize == H5R_DSET_REG_REF_BUF_SIZE) */ H5TOOLS_DEBUG("H5T_REFERENCE:H5T_STD_REF_DSETREG"); h5tools_str_append(str, H5_TOOLS_DATASET); - h5tools_str_sprint_old_reference(str, container, H5R_DATASET_REGION, vp); + h5tools_str_sprint_old_reference(str, container, vp); } else if (H5Tequal(type, H5T_STD_REF_OBJ)) { /* if (nsize == H5R_OBJ_REF_BUF_SIZE) */ @@ -1231,7 +1231,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai obj_tok_str = NULL; } - h5tools_str_sprint_old_reference(str, container, H5R_OBJECT, vp); + h5tools_str_sprint_old_reference(str, container, vp); } /* end else if (H5Tequal(type, H5T_STD_REF_OBJ)) */ } break; @@ -1382,7 +1382,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai *------------------------------------------------------------------------- */ void -h5tools_str_sprint_old_reference(h5tools_str_t *str, hid_t container, H5R_type_t ref_type, void *vp) +h5tools_str_sprint_old_reference(h5tools_str_t *str, hid_t container, void *vp) { hid_t obj = H5I_INVALID_HID; hid_t region = H5I_INVALID_HID; @@ -1391,23 +1391,21 @@ h5tools_str_sprint_old_reference(h5tools_str_t *str, hid_t container, H5R_type_t H5TOOLS_START_DEBUG(" "); h5tools_str_append(str, " \""); - if (ref_type == H5R_DATASET_REGION) { - obj = H5Rdereference2(container, H5P_DEFAULT, ref_type, vp); - if (obj >= 0) { - region = H5Rget_region(container, ref_type, vp); - if (region >= 0) { - H5Rget_name(obj, ref_type, vp, (char *)ref_name, 1024); - h5tools_str_append(str, "%s", ref_name); + obj = H5Rdereference2(container, H5P_DEFAULT, H5R_DATASET_REGION, vp); + if (obj >= 0) { + region = H5Rget_region(container, H5R_DATASET_REGION, vp); + if (region >= 0) { + H5Rget_name(obj, H5R_DATASET_REGION, vp, (char *)ref_name, 1024); + h5tools_str_append(str, "%s", ref_name); - H5Sclose(region); - } /* end if (region >= 0) */ - H5Dclose(obj); - } /* end if (obj >= 0) */ - } - else if (ref_type == H5R_OBJECT) { - obj = H5Rdereference2(container, H5P_DEFAULT, ref_type, vp); + H5Sclose(region); + } /* end if (region >= 0) */ + H5Dclose(obj); + } /* end if (obj >= 0) */ + else { + obj = H5Rdereference2(container, H5P_DEFAULT, H5R_OBJECT, vp); if (obj >= 0) { - H5Rget_name(obj, ref_type, vp, (char *)ref_name, 1024); + H5Rget_name(obj, H5R_OBJECT, vp, (char *)ref_name, 1024); h5tools_str_append(str, "%s", ref_name); H5Dclose(obj); } diff --git a/tools/lib/h5tools_str.h b/tools/lib/h5tools_str.h index 27adf46..15834bb 100644 --- a/tools/lib/h5tools_str.h +++ b/tools/lib/h5tools_str.h @@ -41,8 +41,7 @@ H5TOOLS_DLL void h5tools_str_dump_space_slabs(h5tools_str_t *, hid_t, const h5t h5tools_context_t *ctx); H5TOOLS_DLL void h5tools_str_dump_space_blocks(h5tools_str_t *, hid_t, const h5tool_format_t *); H5TOOLS_DLL void h5tools_str_dump_space_points(h5tools_str_t *, hid_t, const h5tool_format_t *); -H5TOOLS_DLL void h5tools_str_sprint_old_reference(h5tools_str_t *str, hid_t container, H5R_type_t ref_type, - void *vp); +H5TOOLS_DLL void h5tools_str_sprint_old_reference(h5tools_str_t *str, hid_t container, void *vp); H5TOOLS_DLL void h5tools_str_sprint_reference(h5tools_str_t *str, H5R_ref_t *vp); H5TOOLS_DLL char *h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t container, hid_t type, void *vp, h5tools_context_t *ctx); -- cgit v0.12