I am having trouble to set up an image into a memory backed file. I’d like to set up a memory file, copy some data into it and then extract the a file image which will be set in another memory backed file (this last step seems to be the issue). Below code works but it is extracting the image from the disk file and I’d like to use the memory one. The only way I found to make this work is to relaxing the version bounding to the earliest (H5F_LIBVER_EARLIEST).
Am I doing something wrong or not allowed? Is this a bug? I am using the C API and need to keep it for now.
HDF5 version is 1.12.1
herr_t copy_group( hid_t groupId, const char* name, H5L_info_t const* info, void* operatorData )
{
if (!operatorData) {
return -1;
}
hid_t targetFileId = ((hid_t)operatorData);
if (targetFileId <= 0) {
return -1;
}
H5O_info_t objInfo;
H5Oget_info(groupId, &objInfo, H5O_INFO_ALL);
if (objInfo.type == H5O_TYPE_GROUP) {
return H5Ocopy(groupId,name,targetFileId,name,H5P_DEFAULT,H5P_DEFAULT);
}
return 0; // do nothing if not a group
}
void workflow()
{
size_t memory_increments = 10485760; //10 MB
std::pair<hid_t,hid_t> fapl_id_disk (-1,-1);
std::pair<hid_t,hid_t> fapl_id_memory1 (-1,-1);
std::pair<hid_t,hid_t> fapl_id_memory2 (-1,-1);
unsigned char * file_image_memory;
size_t file_image_memory_size;
unsigned char * file_image_disk;
size_t file_image_disk_size;
herr_t ret;
auto convert_h5_array = [&](hid_t fapl_id, unsigned char **buffer, size_t &buffer_size)
{
herr_t err = -1;
*buffer = nullptr;
buffer_size = 0;
if(fapl_id < 0)
return err;
H5Fflush(fapl_id,H5F_SCOPE_GLOBAL);
//getting a copy of the file_image
int64_t sbyteCount = H5Fget_file_image(fapl_id, NULL,0);
if(sbyteCount < 0)
return err;
size_t size = (size_t)sbyteCount;
unsigned char *file_image = (unsigned char *)malloc(size);
if(file_image){
err = H5Fget_file_image(fapl_id, file_image, size);
if((size_t)err == size){
*buffer = (unsigned char *)malloc(size);
buffer_size = size;
memcpy(*buffer, file_image,size);
return err;
}
}
return herr_t(-1);
};
auto close_h5 =[&](std::pair<hid_t,hid_t> &file_apl_id)
{
herr_t err = H5Pclose(file_apl_id.second);
assert(err >= 0);
file_apl_id.second = -1;
err = H5Fclose(file_apl_id.first);
assert(err >= 0);
file_apl_id.first = -1;
};
// open a good hdf5 file from the disk
fapl_id_disk.second = H5Pcreate(H5P_FILE_ACCESS);
assert(fapl_id_disk.second >= 0);
ret = H5Pset_fclose_degree(fapl_id_disk.second, H5F_CLOSE_STRONG); //needed for close file and all open objects
assert(ret >= 0);
fapl_id_disk.first = H5Fopen("file_image_core_test.h5", H5F_ACC_RDONLY, fapl_id_disk.second);
assert(fapl_id_disk.first >= 0);
// create file memory backed file
fapl_id_memory1.second = H5Pcreate(H5P_FILE_ACCESS);
assert(fapl_id_memory1.second >= 0);
ret = H5Pset_fclose_degree(fapl_id_memory1.second, H5F_CLOSE_STRONG); //needed for close file and all open objects
assert(ret >= 0);
ret = H5Pset_libver_bounds(fapl_id_memory1.second, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
assert(ret >= 0);
/* Set up the core VFD */
ret = H5Pset_fapl_core(fapl_id_memory1.second, memory_increments, false);
assert(ret >= 0);
fapl_id_memory1.first = H5Fcreate("dne.h5", H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id_memory1.second);
assert(fapl_id_memory1.first >= 0);
// copy from disk file to memory file
hid_t rootGroupId, memRootGroupId;
rootGroupId = H5Gopen(fapl_id_disk.first,"/",H5P_DEFAULT);
assert(rootGroupId > 0);
memRootGroupId = H5Gopen(fapl_id_memory1.first,"/",H5P_DEFAULT);
assert(memRootGroupId > 0);
H5Literate(rootGroupId,H5_INDEX_NAME,H5_ITER_NATIVE,NULL,copy_group,(void*)&memRootGroupId);
// assumption is that both file images (disk and memory) must be identical
// images are not identical and only when extracting from disk file the second memory file is created successfully
convert_h5_array(fapl_id_memory1.first, &file_image_memory, file_image_memory_size);
convert_h5_array(fapl_id_disk.first, &file_image_disk, file_image_disk_size);
// assert(file_image_disk_size == file_image_memory_size);
// assert(0 == memcmp(file_image_disk, file_image_memory, file_image_disk_size));
close_h5(fapl_id_disk);
close_h5(fapl_id_memory1);
/* Create the second memory backed file */
fapl_id_memory2.second = H5Pcreate(H5P_FILE_ACCESS);
assert(fapl_id_memory2.second >= 0);
ret = H5Pset_fclose_degree(fapl_id_memory2.second, H5F_CLOSE_STRONG); //needed for close file and all open objects
assert(ret >= 0);
ret = H5Pset_libver_bounds(fapl_id_memory2.second, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
assert(ret >= 0);
/* Set up the core VFD */
ret = H5Pset_fapl_core(fapl_id_memory2.second, memory_increments, false);
assert(ret >= 0);
/* Set file image in plist */
// ret = H5Pset_file_image(fapl_id_memory2.second, file_image_memory, file_image_memory_size); // this doesn’t work, why??!!
** ret = H5Pset_file_image(fapl_id_memory2.second, file_image_disk, file_image_disk_size);**
assert(ret >= 0);
/* Test open with file image */
fapl_id_memory2.first = H5Fopen("dne2.h5", H5F_ACC_RDONLY, fapl_id_memory2.second);
assert(fapl_id_memory2.first >= 0);
close_h5(fapl_id_memory2);
/* Release resources */
free(file_image_memory);
}