H5::FileAccPropList copy constructor issue when using H5::FileAccPropList::DEFAULT
For some reason, we need to use the Core VFD to get memory-only HDF5 access. While playing with the C++ API, we found something strange in the H5::FileAccPropList(const FileAccPropList& original)
constructor usage. The reference documentation states:
original - IN: FileAccPropList instance to copy
for the original
parameter.
As a consequence, we had used this constructor with the H5::FileAccPropList::DEFAULT
, thinking that we would have a sane copy to start with, modifying it afterward to fit our needs (use the Core VFD and so on).
Unfortunately, by using this constructor with H5::FileAccPropList::DEFAULT
, our modifications on the FileAccPropList are in fact repercuted on the H5::FileAccPropList::DEFAULT
global variable, making further implicit usage of this global variable unpredictable.
Here is a minimal use case of the issue (we assume here we have a table.h5
file around):
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <H5Cpp.h>
int main(int argc, char** argv) {
H5::Exception::dontPrint();
std::ifstream is("./table.h5", std::ifstream::binary);
if (is) {
H5::H5File h5f;
// get length of file:
is.seekg(0, is.end);
int length = is.tellg();
is.seekg(0, is.beg);
unsigned char* buffer = new unsigned char[length];
is.read(reinterpret_cast<char*>(buffer), length);
if (!is) {
throw std::runtime_error("Failed to read table.h5 file!");
}
is.close();
try {
const H5::FileAccPropList fapl(H5::FileAccPropList::DEFAULT);
std::cout << "Using H5::FileAccPropList fapl(H5::FileAccPropList::DEFAULT),\n"
<< "fapl will have the very same id than H5::FileAccPropList::DEFAULT:" << std::endl;
std::cout << "fapl.getId() = " << fapl.getId() << std::endl;
std::cout << "H5::FileAccPropList::DEFAULT.getId() = "
<< H5::FileAccPropList::DEFAULT.getId() << std::endl;
fapl.setCore(10240, false);
H5Pset_file_image(fapl.getId(), buffer, length);
h5f.openFile("nonesuch", H5F_ACC_RDONLY, fapl);
} catch (H5::Exception& err) {
std::cerr << "Failed to load table.h5 file to a memory buffer and use it as a H5File\n";
}
delete[] buffer;
}
std::cout << "Thus, previous modifications on fapl will result in modification\n"
<< "on H5::FileAccPropList::DEFAULT and the next call to H5File ctor for which\n"
<< "we really want the default behavior will fail!!!" << std::endl;
{
try {
H5::H5File h5f("./table.h5", H5F_ACC_RDONLY);
} catch (H5::Exception& err) {
std::cerr << std::string("HDF5 Error in ")
+ err.getFuncName()
+ ": "
+ err.getDetailMsg();
}
}
std::cout << "The solution is to use const H5::FileAccPropList fapl;\n"
<< "instead of const H5::FileAccPropList fapl(H5::FileAccPropList::DEFAULT);"
<< std::endl;
return 0;
}
We figured out a solution by not using the H5::FileAccPropList::DEFAULT
variable but we are not sure if this is an API issue or just a documentation problem, so we choose to share this here.
Another issue: FileAccPropList H5::H5File::getAccessPlist() returns a copy of the actual FileAccPropList
We discover another issue by investigating the first one.
Consider the following code
//--------------------------------------------------------------------------
// Function: H5File::getAccessPlist
///\brief Returns the access property list of this file
///\return FileAccPropList object
///\exception H5::FileIException
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
FileAccPropList H5File::getAccessPlist() const
{
hid_t access_plist_id = H5Fget_access_plist(id);
[...]
The documentation states that we’ll get the current access property list of the given file, but, when we use getId
on the returned FileAccPropList
we obtain an incremented hid_t
!!!
Consulting the C source H5F.c
, we find the following documentation block:
/*-------------------------------------------------------------------------
* Function: H5Fget_access_plist
*
* Purpose: Returns a copy of the file access property list of the
* specified file.
*
* NOTE: Make sure that, if you are going to overwrite
* information in the copied property list that was
* previously opened and assigned to the property list, then
* you must close it before overwriting the values.
*
* Return: Success: Object ID for a copy of the file access
* property list.
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Wednesday, February 18, 1998
*
*-------------------------------------------------------------------------
*/
We don’t push further our investigations but the API doesn’t behave as expected, at least to our appreciation.
Let us know if this is the result of a misuse of the API or if we can help to adapt/fix the API or the associated documentation.
Best regards,
Renaud