mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-04-12 17:31:09 +08:00
[svn-r22219] Description:
Merge "file image" changes from feature branch back to trunk. Tested on: Mac OSX/64 10.7.3 (amazon) w/debug (h5committest upcoming)
This commit is contained in:
parent
b51ffb25fe
commit
c2a9dcb897
47
MANIFEST
47
MANIFEST
@ -963,32 +963,35 @@
|
||||
./test/filespace_1_8.h5
|
||||
./test/filespace_1_6.h5
|
||||
./test/freespace.c
|
||||
./test/file_image.c
|
||||
./test/file_image_core_test.h5
|
||||
./test/fill_old.h5
|
||||
./test/fillval.c
|
||||
./test/filter_fail.c
|
||||
./test/flush1.c
|
||||
./test/flush2.c
|
||||
./test/gen_bad_ohdr.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_bad_compound.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_bogus.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_cross.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_deflate.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_filespace.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_mergemsg.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_array.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_fill.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_group.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_mtime.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_super.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_noencoder.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_nullspace.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_old_array.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_old_group.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_old_layout.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_old_mtime.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_sizes_lheap.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_specmetaread.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_udlinks.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_bad_ohdr.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_bad_compound.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_bogus.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_cross.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_deflate.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_file_image.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_filespace.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_mergemsg.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_array.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_fill.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_group.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_mtime.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_new_super.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_noencoder.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_nullspace.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_old_array.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_old_group.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_old_layout.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_old_mtime.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_sizes_lheap.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_specmetaread.c _DO_NOT_DISTRIBUTE_
|
||||
./test/gen_udlinks.c _DO_NOT_DISTRIBUTE_
|
||||
./test/getname.c
|
||||
./test/gheap.c
|
||||
./test/group_old.h5
|
||||
@ -1083,6 +1086,7 @@
|
||||
./testpar/t_cache.c
|
||||
./testpar/t_dset.c
|
||||
./testpar/t_file.c
|
||||
./testpar/t_file_image.c
|
||||
./testpar/t_mdset.c
|
||||
./testpar/t_mpi.c
|
||||
./testpar/t_ph5basic.c
|
||||
@ -2075,6 +2079,7 @@
|
||||
./hl/test/sepia.pal
|
||||
./hl/test/gen_test_ds.c
|
||||
./hl/test/test_ds.c
|
||||
./hl/test/test_file_image.c
|
||||
./hl/test/test_image.c
|
||||
./hl/test/test_lite.c
|
||||
./hl/test/test_packet.c
|
||||
|
@ -109,6 +109,7 @@ $Source = "";
|
||||
"H5FD_t" => "x",
|
||||
"H5FD_class_t" => "x",
|
||||
"H5FD_stream_fapl_t" => "x",
|
||||
"H5FD_file_image_callbacks_t" => "x",
|
||||
"H5G_iterate_t" => "x",
|
||||
"H5G_info_t" => "x",
|
||||
"H5I_free_t" => "x",
|
||||
|
571
hl/src/H5LT.c
571
hl/src/H5LT.c
@ -17,6 +17,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "H5LTprivate.h"
|
||||
#include "H5private.h"
|
||||
|
||||
@ -31,7 +32,461 @@ char *myinput;
|
||||
size_t indent = 0;
|
||||
|
||||
|
||||
/* File Image operations
|
||||
|
||||
A file image is a representation of an HDF5 file in a memory
|
||||
buffer. In order to perform operations on an image in a similar way
|
||||
to a file, the application buffer is copied to a FAPL buffer, which
|
||||
in turn is copied to a VFD buffer. Buffer copying can decrease
|
||||
performance, especially when using large file images. A solution to
|
||||
this issue is to simulate the copying of the application buffer,
|
||||
when actually the same buffer is used for the FAPL and the VFD.
|
||||
This is implemented by using callbacks that simulate the standard
|
||||
functions for memory management (additional callbacks are used for
|
||||
the management of associated data structures). From the application
|
||||
standpoint, a file handle can be obtained from a file image by using
|
||||
the API routine H5LTopen_file_image(). This function takes a flag
|
||||
argument that indicates the HDF5 library how to handle the given image;
|
||||
several flag values can be combined by using the bitwise OR operator.
|
||||
Valid flag values include:
|
||||
|
||||
H5LT_FILE_IMAGE_OPEN_RW indicates the HDF5 library to open the file
|
||||
image in read/write mode. Default is read-only mode.
|
||||
|
||||
H5LT_FILE_IMAGE_DONT_COPY indicates the HDF5 library to not copy the
|
||||
supplied user buffer; the same buffer will be handled by the FAPL and
|
||||
the VFD driver. Default operation copies the user buffer to the FAPL and
|
||||
VFD driver.
|
||||
|
||||
H5LT_FILE_IMAGE_DONT_RELEASE indicates the HDF5 library to not release
|
||||
the buffer handled by the FAPL and the VFD upon closing. This flag value
|
||||
is only applicable when the flag value H5LT_FILE_IMAGE_DONT_COPY is set as
|
||||
well. The application is responsible to release the image buffer.
|
||||
*/
|
||||
|
||||
/* Data structure to pass application data to callbacks. */
|
||||
typedef struct {
|
||||
void *app_image_ptr; /* Pointer to application buffer */
|
||||
size_t app_image_size; /* Size of application buffer */
|
||||
void *fapl_image_ptr; /* Pointer to FAPL buffer */
|
||||
size_t fapl_image_size; /* Size of FAPL buffer */
|
||||
int fapl_ref_count; /* Reference counter for FAPL buffer */
|
||||
void *vfd_image_ptr; /* Pointer to VFD buffer */
|
||||
size_t vfd_image_size; /* Size of VFD buffer */
|
||||
int vfd_ref_count; /* Reference counter for VFD buffer */
|
||||
unsigned flags; /* Flags indicate how the file image will */
|
||||
/* be open */
|
||||
int ref_count; /* Reference counter on udata struct */
|
||||
} H5LT_file_image_ud_t;
|
||||
|
||||
/* callbacks prototypes for file image ops */
|
||||
static void *image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *udata);
|
||||
static void *image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
|
||||
static void *image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
|
||||
static herr_t image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *udata);
|
||||
static void *udata_copy(void *udata);
|
||||
static herr_t udata_free(void *udata);
|
||||
|
||||
/* Definition of callbacks for file image operations. */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: image_malloc
|
||||
*
|
||||
* Purpose: Simulates malloc() function to avoid copying file images.
|
||||
* The application buffer is set to the buffer on only one FAPL.
|
||||
* Then the FAPL buffer can be copied to other FAPL buffers or
|
||||
* to only one VFD buffer.
|
||||
*
|
||||
* Return: Address of "allocated" buffer, if successful. Otherwise, it returns
|
||||
* NULL.
|
||||
*
|
||||
* Programmer: Christian Chilan
|
||||
*
|
||||
* Date: October 3, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void *
|
||||
image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *_udata)
|
||||
{
|
||||
H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
|
||||
void * return_value = NULL;
|
||||
|
||||
/* callback is only used if the application buffer is not actually copied */
|
||||
if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
|
||||
goto out;
|
||||
|
||||
switch ( file_image_op ) {
|
||||
/* the app buffer is "copied" to only one FAPL. Afterwards, FAPLs can be "copied" */
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
|
||||
if (udata->app_image_ptr == NULL)
|
||||
goto out;
|
||||
if (udata->app_image_size != size)
|
||||
goto out;
|
||||
if (udata->fapl_image_ptr != NULL)
|
||||
goto out;
|
||||
if (udata->fapl_image_size != 0)
|
||||
goto out;
|
||||
if (udata->fapl_ref_count != 0)
|
||||
goto out;
|
||||
|
||||
udata->fapl_image_ptr = udata->app_image_ptr;
|
||||
udata->fapl_image_size = udata->app_image_size;
|
||||
return_value = udata->fapl_image_ptr;
|
||||
udata->fapl_ref_count++;
|
||||
break;
|
||||
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
|
||||
if (udata->fapl_image_ptr == NULL)
|
||||
goto out;
|
||||
if (udata->fapl_image_size != size)
|
||||
goto out;
|
||||
if (udata->fapl_ref_count == 0)
|
||||
goto out;
|
||||
|
||||
return_value = udata->fapl_image_ptr;
|
||||
udata->fapl_ref_count++;
|
||||
break;
|
||||
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
|
||||
goto out;
|
||||
|
||||
case H5FD_FILE_IMAGE_OP_FILE_OPEN:
|
||||
/* FAPL buffer is "copied" to only one VFD buffer */
|
||||
if (udata->vfd_image_ptr != NULL)
|
||||
goto out;
|
||||
if (udata->vfd_image_size != 0)
|
||||
goto out;
|
||||
if (udata->vfd_ref_count != 0)
|
||||
goto out;
|
||||
if (udata->fapl_image_ptr == NULL)
|
||||
goto out;
|
||||
if (udata->fapl_image_size != size)
|
||||
goto out;
|
||||
if (udata->fapl_ref_count == 0)
|
||||
goto out;
|
||||
|
||||
udata->vfd_image_ptr = udata->fapl_image_ptr;
|
||||
udata->vfd_image_size = size;
|
||||
udata->vfd_ref_count++;
|
||||
return_value = udata->vfd_image_ptr;
|
||||
break;
|
||||
|
||||
/* added unused labels to shut the compiler up */
|
||||
case H5FD_FILE_IMAGE_OP_NO_OP:
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
|
||||
case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
|
||||
case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
|
||||
default:
|
||||
goto out;
|
||||
} /* end switch */
|
||||
|
||||
return(return_value);
|
||||
|
||||
out:
|
||||
return NULL;
|
||||
} /* end image_malloc() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: image_memcpy
|
||||
*
|
||||
* Purpose: Simulates memcpy() function to avoid copying file images.
|
||||
* The image buffer can be set to only one FAPL buffer, and
|
||||
* "copied" to only one VFD buffer. The FAPL buffer can be
|
||||
* "copied" to other FAPLs buffers.
|
||||
*
|
||||
* Return: The address of the destination buffer, if successful. Otherwise, it
|
||||
* returns NULL.
|
||||
*
|
||||
* Programmer: Christian Chilan
|
||||
*
|
||||
* Date: October 3, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void *
|
||||
image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op,
|
||||
void *_udata)
|
||||
{
|
||||
H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
|
||||
|
||||
/* callback is only used if the application buffer is not actually copied */
|
||||
if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
|
||||
goto out;
|
||||
|
||||
switch(file_image_op) {
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
|
||||
if (dest != udata->fapl_image_ptr)
|
||||
goto out;
|
||||
if (src != udata->app_image_ptr)
|
||||
goto out;
|
||||
if (size != udata->fapl_image_size)
|
||||
goto out;
|
||||
if (size != udata->app_image_size)
|
||||
goto out;
|
||||
if (udata->fapl_ref_count == 0)
|
||||
goto out;
|
||||
break;
|
||||
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
|
||||
if (dest != udata->fapl_image_ptr)
|
||||
goto out;
|
||||
if (src != udata->fapl_image_ptr)
|
||||
goto out;
|
||||
if (size != udata->fapl_image_size)
|
||||
goto out;
|
||||
if (udata->fapl_ref_count < 2)
|
||||
goto out;
|
||||
break;
|
||||
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
|
||||
goto out;
|
||||
|
||||
case H5FD_FILE_IMAGE_OP_FILE_OPEN:
|
||||
if (dest != udata->vfd_image_ptr)
|
||||
goto out;
|
||||
if (src != udata->fapl_image_ptr)
|
||||
goto out;
|
||||
if (size != udata->vfd_image_size)
|
||||
goto out;
|
||||
if (size != udata->fapl_image_size)
|
||||
goto out;
|
||||
if (udata->fapl_ref_count == 0)
|
||||
goto out;
|
||||
if (udata->vfd_ref_count != 1)
|
||||
goto out;
|
||||
break;
|
||||
|
||||
/* added unused labels to shut the compiler up */
|
||||
case H5FD_FILE_IMAGE_OP_NO_OP:
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
|
||||
case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
|
||||
case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
|
||||
default:
|
||||
goto out;
|
||||
} /* end switch */
|
||||
|
||||
return(dest);
|
||||
|
||||
out:
|
||||
return NULL;
|
||||
} /* end image_memcpy() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: image_realloc
|
||||
*
|
||||
* Purpose: Reallocates the shared application image buffer and updates data
|
||||
* structures that manage buffer "copying".
|
||||
*
|
||||
* Return: Address of reallocated buffer, if successful. Otherwise, it returns
|
||||
* NULL.
|
||||
*
|
||||
* Programmer: Christian Chilan
|
||||
*
|
||||
* Date: October 3, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void *
|
||||
image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *_udata)
|
||||
{
|
||||
H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
|
||||
void * return_value = NULL;
|
||||
|
||||
/* callback is only used if the application buffer is not actually copied */
|
||||
if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
|
||||
goto out;
|
||||
|
||||
/* realloc() is not allowed when the HDF5 library won't release the image
|
||||
buffer because reallocation may change the address of the buffer. The
|
||||
new address cannot be communicated to the application to release it. */
|
||||
if (udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)
|
||||
goto out;
|
||||
|
||||
/* realloc() is not allowed if the image is open in read-only mode */
|
||||
if (!(udata->flags & H5LT_FILE_IMAGE_OPEN_RW))
|
||||
goto out;
|
||||
|
||||
if (file_image_op == H5FD_FILE_IMAGE_OP_FILE_RESIZE) {
|
||||
if (udata->vfd_image_ptr != ptr)
|
||||
goto out;
|
||||
|
||||
if (udata->vfd_ref_count != 1)
|
||||
goto out;
|
||||
|
||||
if (NULL == (udata->vfd_image_ptr = HDrealloc(ptr, size)))
|
||||
goto out;
|
||||
|
||||
udata->vfd_image_size = size;
|
||||
return_value = udata->vfd_image_ptr;
|
||||
} /* end if */
|
||||
else
|
||||
goto out;
|
||||
|
||||
return(return_value);
|
||||
|
||||
out:
|
||||
return NULL;
|
||||
} /* end image_realloc() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: image_free
|
||||
*
|
||||
* Purpose: Simulates deallocation of FAPL and VFD buffers by decreasing
|
||||
* reference counters. Shared application buffer is actually
|
||||
* deallocated if there are no outstanding references.
|
||||
*
|
||||
* Return: SUCCEED or FAIL
|
||||
*
|
||||
* Programmer: Christian Chilan
|
||||
*
|
||||
* Date: October 3, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *_udata)
|
||||
{
|
||||
H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
|
||||
|
||||
/* callback is only used if the application buffer is not actually copied */
|
||||
if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
|
||||
goto out;
|
||||
|
||||
switch(file_image_op) {
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
|
||||
if (udata->fapl_image_ptr != ptr)
|
||||
goto out;
|
||||
if (udata->fapl_ref_count == 0)
|
||||
goto out;
|
||||
|
||||
udata->fapl_ref_count--;
|
||||
|
||||
/* release the shared buffer only if indicated by the respective flag and there are no outstanding references */
|
||||
if (udata->fapl_ref_count == 0 && udata->vfd_ref_count == 0 &&
|
||||
!(udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)) {
|
||||
HDfree(udata->fapl_image_ptr);
|
||||
udata->app_image_ptr = NULL;
|
||||
udata->fapl_image_ptr = NULL;
|
||||
udata->vfd_image_ptr = NULL;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
|
||||
if (udata->vfd_image_ptr != ptr)
|
||||
goto out;
|
||||
if (udata->vfd_ref_count != 1)
|
||||
goto out;
|
||||
|
||||
udata->vfd_ref_count--;
|
||||
|
||||
/* release the shared buffer only if indicated by the respective flag and there are no outstanding references */
|
||||
if (udata->fapl_ref_count == 0 && udata->vfd_ref_count == 0 &&
|
||||
!(udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)) {
|
||||
HDfree(udata->vfd_image_ptr);
|
||||
udata->app_image_ptr = NULL;
|
||||
udata->fapl_image_ptr = NULL;
|
||||
udata->vfd_image_ptr = NULL;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
/* added unused labels to keep the compiler quite */
|
||||
case H5FD_FILE_IMAGE_OP_NO_OP:
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
|
||||
case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
|
||||
case H5FD_FILE_IMAGE_OP_FILE_OPEN:
|
||||
case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
|
||||
default:
|
||||
goto out;
|
||||
} /* end switch */
|
||||
|
||||
return(SUCCEED);
|
||||
|
||||
out:
|
||||
return(FAIL);
|
||||
} /* end image_free() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: udata_copy
|
||||
*
|
||||
* Purpose: Simulates the copying of the user data structure utilized in the
|
||||
* management of the "copying" of file images.
|
||||
*
|
||||
* Return: Address of "newly allocated" structure, if successful. Otherwise, it
|
||||
* returns NULL.
|
||||
*
|
||||
* Programmer: Christian Chilan
|
||||
*
|
||||
* Date: October 3, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void *
|
||||
udata_copy(void *_udata)
|
||||
{
|
||||
H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
|
||||
|
||||
/* callback is only used if the application buffer is not actually copied */
|
||||
if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
|
||||
goto out;
|
||||
if (udata->ref_count == 0)
|
||||
goto out;
|
||||
|
||||
udata->ref_count++;
|
||||
|
||||
return(udata);
|
||||
|
||||
out:
|
||||
return NULL;
|
||||
} /* end udata_copy */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: udata_free
|
||||
*
|
||||
* Purpose: Simulates deallocation of the user data structure utilized in the
|
||||
* management of the "copying" of file images. The data structure is
|
||||
* actually deallocated when there are no outstanding references.
|
||||
*
|
||||
* Return: SUCCEED or FAIL
|
||||
*
|
||||
* Programmer: Christian Chilan
|
||||
*
|
||||
* Date: October 3, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
udata_free(void *_udata)
|
||||
{
|
||||
H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
|
||||
|
||||
/* callback is only used if the application buffer is not actually copied */
|
||||
if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
|
||||
goto out;
|
||||
if (udata->ref_count == 0)
|
||||
goto out;
|
||||
|
||||
udata->ref_count--;
|
||||
|
||||
/* checks that there are no references outstanding before deallocating udata */
|
||||
if (udata->ref_count == 0 && udata->fapl_ref_count == 0 &&
|
||||
udata->vfd_ref_count == 0)
|
||||
HDfree(udata);
|
||||
|
||||
return(SUCCEED);
|
||||
|
||||
out:
|
||||
return(FAIL);
|
||||
} /* end udata_free */
|
||||
|
||||
/* End of callbacks definitions for file image operations */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
@ -388,6 +843,120 @@ out:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5LTopen_file_image
|
||||
*
|
||||
* Purpose: Open a user supplied file image using the core file driver.
|
||||
*
|
||||
* Return: File identifier, Failure: -1
|
||||
*
|
||||
* Programmer: Christian Chilan
|
||||
*
|
||||
* Date: October 3, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
hid_t H5LTopen_file_image(void *buf_ptr, size_t buf_size, unsigned flags)
|
||||
{
|
||||
hid_t fapl, file_id; /* HDF5 identifiers */
|
||||
unsigned file_open_flags;/* Flags for image open */
|
||||
char file_name[64]; /* Filename buffer */
|
||||
size_t alloc_incr; /* Buffer allocation increment */
|
||||
size_t min_incr = 65536; /* Minimum buffer increment */
|
||||
double buf_prcnt = 0.1f; /* Percentage of buffer size to set
|
||||
as increment */
|
||||
static long file_name_counter;
|
||||
H5FD_file_image_callbacks_t callbacks = {&image_malloc, &image_memcpy,
|
||||
&image_realloc, &image_free,
|
||||
&udata_copy, &udata_free,
|
||||
(void *)NULL};
|
||||
|
||||
/* check arguments */
|
||||
if (buf_ptr == NULL)
|
||||
goto out;
|
||||
if (buf_size == 0)
|
||||
goto out;
|
||||
if (flags & (unsigned)~(H5LT_FILE_IMAGE_ALL))
|
||||
goto out;
|
||||
|
||||
/* Create FAPL to transmit file image */
|
||||
if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
||||
goto out;
|
||||
|
||||
/* set allocation increment to a percentage of the supplied buffer size, or
|
||||
* a pre-defined minimum increment value, whichever is larger
|
||||
*/
|
||||
if ((buf_prcnt * buf_size) > min_incr)
|
||||
alloc_incr = (size_t)(buf_prcnt * buf_size);
|
||||
else
|
||||
alloc_incr = min_incr;
|
||||
|
||||
/* Configure FAPL to use the core file driver */
|
||||
if (H5Pset_fapl_core(fapl, alloc_incr, FALSE) < 0)
|
||||
goto out;
|
||||
|
||||
/* Set callbacks for file image ops ONLY if the file image is NOT copied */
|
||||
if (flags & H5LT_FILE_IMAGE_DONT_COPY) {
|
||||
H5LT_file_image_ud_t *udata; /* Pointer to udata structure */
|
||||
|
||||
/* Allocate buffer to communicate user data to callbacks */
|
||||
if (NULL == (udata = (H5LT_file_image_ud_t *)HDmalloc(sizeof(H5LT_file_image_ud_t))))
|
||||
goto out;
|
||||
|
||||
/* Initialize udata with info about app buffer containing file image and flags */
|
||||
udata->app_image_ptr = buf_ptr;
|
||||
udata->app_image_size = buf_size;
|
||||
udata->fapl_image_ptr = NULL;
|
||||
udata->fapl_image_size = 0;
|
||||
udata->fapl_ref_count = 0;
|
||||
udata->vfd_image_ptr = NULL;
|
||||
udata->vfd_image_size = 0;
|
||||
udata->vfd_ref_count = 0;
|
||||
udata->flags = flags;
|
||||
udata->ref_count = 1; /* corresponding to the first FAPL */
|
||||
|
||||
/* copy address of udata into callbacks */
|
||||
callbacks.udata = (void *)udata;
|
||||
|
||||
/* Set file image callbacks */
|
||||
if (H5Pset_file_image_callbacks(fapl, &callbacks) < 0) {
|
||||
HDfree(udata);
|
||||
goto out;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/* Assign file image in user buffer to FAPL */
|
||||
if (H5Pset_file_image(fapl, buf_ptr, buf_size) < 0)
|
||||
goto out;
|
||||
|
||||
/* set file open flags */
|
||||
if (flags & H5LT_FILE_IMAGE_OPEN_RW)
|
||||
file_open_flags = H5F_ACC_RDWR;
|
||||
else
|
||||
file_open_flags = H5F_ACC_RDONLY;
|
||||
|
||||
/* define a unique file name */
|
||||
snprintf(file_name, (sizeof(file_name) - 1), "file_image_%ld", file_name_counter++);
|
||||
|
||||
/* Assign file image in FAPL to the core file driver */
|
||||
if ((file_id = H5Fopen(file_name, file_open_flags, fapl)) < 0)
|
||||
goto out;
|
||||
|
||||
/* Close FAPL */
|
||||
if (H5Pclose(fapl) < 0)
|
||||
goto out;
|
||||
|
||||
/* Return file identifier */
|
||||
return file_id;
|
||||
|
||||
out:
|
||||
H5E_BEGIN_TRY {
|
||||
H5Pclose(fapl);
|
||||
} H5E_END_TRY;
|
||||
return -1;
|
||||
} /* end H5LTopen_file_image() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5LT_read_dataset
|
||||
@ -1801,7 +2370,7 @@ print_enum(hid_t type, char* str, size_t *str_len, hbool_t no_ubuf, size_t indt)
|
||||
out:
|
||||
|
||||
if(0 == nmembs) {
|
||||
HDsnprintf(tmp_str, TMP_LEN, "\n%*s <empty>", indt + 4, "");
|
||||
HDsnprintf(tmp_str, TMP_LEN, "\n%*s <empty>", (int)(indt + 4), "");
|
||||
str = realloc_and_append(no_ubuf, str_len, str, tmp_str);
|
||||
} /* end if */
|
||||
|
||||
|
@ -16,6 +16,15 @@
|
||||
#ifndef _H5LTpublic_H
|
||||
#define _H5LTpublic_H
|
||||
|
||||
/* Flag definitions for H5LTopen_file_image() */
|
||||
#define H5LT_FILE_IMAGE_OPEN_RW 0x0001 /* Open image for read-write */
|
||||
#define H5LT_FILE_IMAGE_DONT_COPY 0x0002 /* The HDF5 lib won't copy */
|
||||
/* user supplied image buffer. The same image is open with the core driver. */
|
||||
#define H5LT_FILE_IMAGE_DONT_RELEASE 0x0004 /* The HDF5 lib won't */
|
||||
/* deallocate user supplied image buffer. The user application is reponsible */
|
||||
/* for doing so. */
|
||||
#define H5LT_FILE_IMAGE_ALL 0x0007
|
||||
|
||||
typedef enum H5LT_lang_t {
|
||||
H5LT_LANG_ERR = -1, /*this is the first*/
|
||||
H5LT_DDL = 0, /*for DDL*/
|
||||
@ -344,6 +353,15 @@ H5_HLDLL herr_t H5LTfind_attribute( hid_t loc_id, const char *name );
|
||||
|
||||
H5_HLDLL htri_t H5LTpath_valid(hid_t loc_id, const char *path, hbool_t check_object_valid);
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* File image operations functions
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
H5_HLDLL hid_t H5LTopen_file_image(void *buf_ptr, size_t buf_size, unsigned flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@ LDADD=$(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5)
|
||||
|
||||
# Test programs. These are our main targets. They should be listed in the
|
||||
# order to be executed, generally most specific tests to least specific tests.
|
||||
TEST_PROG=test_lite test_image test_table test_ds test_packet
|
||||
TEST_PROG=test_lite test_image test_file_image test_table test_ds test_packet
|
||||
check_PROGRAMS=$(TEST_PROG)
|
||||
|
||||
# These programs generate test files for the tests. They don't need to be
|
||||
@ -45,7 +45,7 @@ endif
|
||||
|
||||
# Temporary files. These files are the ones created by running `make test'.
|
||||
CHECK_CLEANFILES+=combine_tables[1-2].h5 test_ds[1-9].h5 test_image[1-3].h5 \
|
||||
test_lite[1-2].h5 test_table.h5 test_packet_table.h5 \
|
||||
file_img[1-2].h5 test_lite[1-2].h5 test_table.h5 test_packet_table.h5 \
|
||||
test_packet_compress.h5 test_detach.h5
|
||||
|
||||
include $(top_srcdir)/config/conclude.am
|
||||
|
@ -69,7 +69,8 @@ CONFIG_HEADER = $(top_builddir)/src/H5config.h
|
||||
CONFIG_CLEAN_FILES = H5srcdir_str.h
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__EXEEXT_1 = test_lite$(EXEEXT) test_image$(EXEEXT) \
|
||||
test_table$(EXEEXT) test_ds$(EXEEXT) test_packet$(EXEEXT)
|
||||
test_file_image$(EXEEXT) test_table$(EXEEXT) test_ds$(EXEEXT) \
|
||||
test_packet$(EXEEXT)
|
||||
am__EXEEXT_2 = gen_test_ds$(EXEEXT)
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
gen_test_ds_SOURCES = gen_test_ds.c
|
||||
@ -83,6 +84,10 @@ test_ds_SOURCES = test_ds.c
|
||||
test_ds_OBJECTS = test_ds.$(OBJEXT)
|
||||
test_ds_LDADD = $(LDADD)
|
||||
test_ds_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5)
|
||||
test_file_image_SOURCES = test_file_image.c
|
||||
test_file_image_OBJECTS = test_file_image.$(OBJEXT)
|
||||
test_file_image_LDADD = $(LDADD)
|
||||
test_file_image_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5)
|
||||
test_image_SOURCES = test_image.c
|
||||
test_image_OBJECTS = test_image.$(OBJEXT)
|
||||
test_image_LDADD = $(LDADD)
|
||||
@ -125,10 +130,10 @@ am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
AM_V_GEN = $(am__v_GEN_$(V))
|
||||
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
SOURCES = gen_test_ds.c test_ds.c test_image.c test_lite.c \
|
||||
test_packet.c test_table.c
|
||||
DIST_SOURCES = gen_test_ds.c test_ds.c test_image.c test_lite.c \
|
||||
test_packet.c test_table.c
|
||||
SOURCES = gen_test_ds.c test_ds.c test_file_image.c test_image.c \
|
||||
test_lite.c test_packet.c test_table.c
|
||||
DIST_SOURCES = gen_test_ds.c test_ds.c test_file_image.c test_image.c \
|
||||
test_lite.c test_packet.c test_table.c
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__tty_colors = \
|
||||
@ -422,16 +427,16 @@ TRACE = perl $(top_srcdir)/bin/trace
|
||||
|
||||
# Temporary files. These files are the ones created by running `make test'.
|
||||
CHECK_CLEANFILES = *.chkexe *.chklog *.clog combine_tables[1-2].h5 \
|
||||
test_ds[1-9].h5 test_image[1-3].h5 test_lite[1-2].h5 \
|
||||
test_table.h5 test_packet_table.h5 test_packet_compress.h5 \
|
||||
test_detach.h5
|
||||
test_ds[1-9].h5 test_image[1-3].h5 file_img[1-2].h5 \
|
||||
test_lite[1-2].h5 test_table.h5 test_packet_table.h5 \
|
||||
test_packet_compress.h5 test_detach.h5
|
||||
|
||||
# The tests depend on the hdf5, hdf5 test, and hdf5_hl libraries
|
||||
LDADD = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5)
|
||||
|
||||
# Test programs. These are our main targets. They should be listed in the
|
||||
# order to be executed, generally most specific tests to least specific tests.
|
||||
TEST_PROG = test_lite test_image test_table test_ds test_packet
|
||||
TEST_PROG = test_lite test_image test_file_image test_table test_ds test_packet
|
||||
|
||||
# These programs generate test files for the tests. They don't need to be
|
||||
# compiled every time we want to test the library. However, putting
|
||||
@ -515,6 +520,9 @@ gen_test_ds$(EXEEXT): $(gen_test_ds_OBJECTS) $(gen_test_ds_DEPENDENCIES)
|
||||
test_ds$(EXEEXT): $(test_ds_OBJECTS) $(test_ds_DEPENDENCIES)
|
||||
@rm -f test_ds$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(test_ds_OBJECTS) $(test_ds_LDADD) $(LIBS)
|
||||
test_file_image$(EXEEXT): $(test_file_image_OBJECTS) $(test_file_image_DEPENDENCIES)
|
||||
@rm -f test_file_image$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(test_file_image_OBJECTS) $(test_file_image_LDADD) $(LIBS)
|
||||
test_image$(EXEEXT): $(test_image_OBJECTS) $(test_image_DEPENDENCIES)
|
||||
@rm -f test_image$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(test_image_OBJECTS) $(test_image_LDADD) $(LIBS)
|
||||
@ -536,6 +544,7 @@ distclean-compile:
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_test_ds.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ds.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_file_image.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_image.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lite.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_packet.Po@am__quote@
|
||||
|
@ -23,9 +23,6 @@
|
||||
#ifndef _H5HLTEST_H
|
||||
#define _H5HLTEST_H
|
||||
|
||||
/* Get the HDF5 public header */
|
||||
#include "hdf5.h"
|
||||
|
||||
/* Get the HDF5 test header */
|
||||
#include "h5test.h"
|
||||
|
||||
@ -36,5 +33,8 @@
|
||||
#define TESTING2(WHAT) {printf("%-70s", "Testing " WHAT); fflush(stdout);}
|
||||
#define TESTING3(WHAT) {printf("%-70s", "" WHAT); fflush(stdout);}
|
||||
|
||||
/* Implrements verbose 'assert' with 'goto error' exit */
|
||||
#define VERIFY(condition, string) do { if (!(condition)) FAIL_PUTS_ERROR(string) } while(0)
|
||||
|
||||
#endif /* _H5HLTEST_H */
|
||||
|
||||
|
518
hl/test/test_file_image.c
Normal file
518
hl/test/test_file_image.c
Normal file
@ -0,0 +1,518 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "h5hltest.h"
|
||||
#include "H5LTpublic.h"
|
||||
|
||||
#define DSET_NAME "dset"
|
||||
|
||||
#define RANK 2
|
||||
|
||||
/* Test of file image operations.
|
||||
|
||||
The following code provides a means to thoroughly test the file image
|
||||
operations. Main objectives are testing operations with multiple open
|
||||
images and using all possible flag combinations, which are set in the
|
||||
main calling routine. Since the number of open images and flag combinations
|
||||
may differ, the flag combinations are assigned to the images in round-robin
|
||||
fashion. In order to simulate a realistic operation environment, the code
|
||||
operates on as many open objects as possible by using several for-loops
|
||||
instead of using a single loop that opens image i, accesses it, and closes
|
||||
it. The first loop creates the files and obtains images using the function
|
||||
H5Fget_file_image(); two images are set incorrectly (one image is filled
|
||||
with "wrong" data while the other image is not valid). The second loop opens
|
||||
the images using the function H5LTopen_file_image(), and test whether the
|
||||
images have been copied in accordance to the H5LT_FILE_IMAGE_DONT_COPY flag.
|
||||
The third loop reads the open images and verifies that the contents are
|
||||
correct. The fourth loop first perform writes in the images that do not
|
||||
extend the image, and then performs writes that extend the images. The fifth
|
||||
loop reads the extended images and verify that the content are correct. The
|
||||
sixth and final loop closes the file images and deallocates the image
|
||||
buffers if appropriate. */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* test file image operations
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
test_file_image(size_t open_images, size_t nflags, unsigned *flags)
|
||||
{
|
||||
hid_t *file_id, *dset_id, file_space, plist; /* HDF5 ids */
|
||||
hsize_t dims1[RANK] = {2,3}; /* original dimension of datasets */
|
||||
hsize_t max_dims[RANK] = {H5S_UNLIMITED, H5S_UNLIMITED};
|
||||
int data1[6] = {1,2,3,4,5,6}; /* original contents of dataset */
|
||||
int data2[6] = {7,8,9,10,11,12}; /* "wrong" contents of dataset */
|
||||
hsize_t dims3[RANK]; /* array to read dataset dimensions */
|
||||
int data3[15]; /* array to read dataset contents */
|
||||
hsize_t dims4[RANK] = {3,5}; /* extended dimensions of datasets */
|
||||
int data4[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
|
||||
/* extended contents of dataset */
|
||||
ssize_t *buf_size; /* pointer to array of buffer sizes */
|
||||
void **buf_ptr; /* pointer to array of pointers to image buffers */
|
||||
char **filename; /* pointer to array of pointers to filenames */
|
||||
unsigned *input_flags; /* pointer to array of flag combinations */
|
||||
size_t i, j, k, nrow, n_values;
|
||||
herr_t status1;
|
||||
void *handle_ptr = NULL; /* pointers to driver buffer */
|
||||
unsigned char **core_buf_ptr_ptr = NULL;
|
||||
|
||||
VERIFY(open_images > 1 , "The number of open images must be greater than 1");
|
||||
|
||||
VERIFY(nflags > 0, "The number of flag combinations must be greater than 0");
|
||||
|
||||
/* allocate array of flags for open images */
|
||||
if (NULL == (input_flags = (unsigned *)HDmalloc(sizeof(unsigned) * open_images)))
|
||||
FAIL_PUTS_ERROR("malloc() failed");
|
||||
|
||||
/* allocate array of pointers for each of the open images */
|
||||
if (NULL == (buf_ptr = (void **)malloc(sizeof(void *) * open_images)))
|
||||
FAIL_PUTS_ERROR("malloc() failed");
|
||||
|
||||
/* allocate array to store the name of each of the open images */
|
||||
if (NULL == (filename = (char **)malloc(sizeof(char *) * open_images)))
|
||||
FAIL_PUTS_ERROR("malloc() failed");
|
||||
|
||||
/* allocate array to store the size of each of the open images */
|
||||
if (NULL == (buf_size = (ssize_t *)malloc(sizeof(ssize_t) * open_images)))
|
||||
FAIL_PUTS_ERROR("malloc() failed");
|
||||
|
||||
/* allocate array for each of the file identifiers */
|
||||
if (NULL == (file_id = (hid_t *)malloc(sizeof(hid_t) * open_images)))
|
||||
FAIL_PUTS_ERROR("malloc() failed");
|
||||
|
||||
/* allocate array for each of the dataset identifiers */
|
||||
if (NULL == (dset_id = (hid_t *)malloc(sizeof(hid_t) * open_images)))
|
||||
FAIL_PUTS_ERROR("malloc() failed");
|
||||
|
||||
TESTING("get file images");
|
||||
|
||||
/* create several file images */
|
||||
for (i = 0; i < open_images; i++) {
|
||||
|
||||
/* populate array for flags combinations */
|
||||
input_flags[i] = flags[(nflags + i) % nflags];
|
||||
|
||||
/* allocate name buffer for image i */
|
||||
filename[i] = (char *)HDmalloc(sizeof(char) * 32);
|
||||
|
||||
/* create file name */
|
||||
sprintf(filename[i], "image_file%d.h5", (int)i);
|
||||
|
||||
/* create file */
|
||||
if ((file_id[i] = H5Fcreate(filename[i], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
FAIL_PUTS_ERROR("H5Fcreate() failed");
|
||||
|
||||
/* define dataspace for the dataset */
|
||||
if ((file_space = H5Screate_simple(RANK, dims1, max_dims)) < 0)
|
||||
FAIL_PUTS_ERROR("H5Screate_simple() failed");
|
||||
|
||||
/* create dataset property list */
|
||||
if ((plist = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
||||
FAIL_PUTS_ERROR("H5Pcreate() failed");
|
||||
|
||||
/* set property list to create chunked dataset */
|
||||
if (H5Pset_chunk(plist, RANK, dims1) < 0)
|
||||
FAIL_PUTS_ERROR("H5Pset_chunk() failed");
|
||||
|
||||
/* create and write an integer type dataset named "dset" */
|
||||
if ((dset_id[i] = H5Dcreate2(file_id[i], DSET_NAME, H5T_NATIVE_INT, file_space, H5P_DEFAULT, plist, H5P_DEFAULT)) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dcreate() failed");
|
||||
|
||||
/* dataset in open image 1 is written with "wrong" data */
|
||||
if (i == 1) {
|
||||
if (H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data2) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dwrite() failed");
|
||||
} /* end if*/
|
||||
/* dataset in the rest of the open images is written with correct data */
|
||||
else {
|
||||
if (H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data1) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dwrite() failed");
|
||||
} /* end else */
|
||||
|
||||
/* flush into the file */
|
||||
if (H5Fflush(file_id[i], H5F_SCOPE_LOCAL) < 0)
|
||||
FAIL_PUTS_ERROR("H5Fflush() failed");
|
||||
|
||||
/* close dataset property list */
|
||||
if (H5Pclose(plist) < 0)
|
||||
FAIL_PUTS_ERROR("H5Pclose() failed");
|
||||
|
||||
/* close dataspace */
|
||||
if (H5Sclose(file_space) < 0)
|
||||
FAIL_PUTS_ERROR("H5Sclose() failed");
|
||||
|
||||
/* close dataset */
|
||||
if (H5Dclose(dset_id[i]) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dclose() failed");
|
||||
|
||||
/* get size of the file image i */
|
||||
if ((buf_size[i] = H5Fget_file_image(file_id[i], NULL, 0)) < 0)
|
||||
FAIL_PUTS_ERROR("H5Fget_file_image() failed");
|
||||
|
||||
/* allocate buffer for the file image i */
|
||||
if (NULL == (buf_ptr[i] = (void *)HDmalloc((size_t)buf_size[i])))
|
||||
FAIL_PUTS_ERROR("malloc() failed");
|
||||
|
||||
/* buffer for file image 2 is filled with counter data (non-valid image) */
|
||||
if (i == 2) {
|
||||
for (j = 0; j < (size_t)buf_size[i]; j++)
|
||||
((char*)(buf_ptr[i]))[j] = (char)j;
|
||||
} /* end if */
|
||||
/* buffers for the rest of the file images are filled with data from the respective files */
|
||||
else {
|
||||
if ((buf_size[i] = H5Fget_file_image(file_id[i], buf_ptr[i], (size_t)buf_size[i])) < 0)
|
||||
FAIL_PUTS_ERROR("H5Fget_file_image() failed");
|
||||
} /* end else */
|
||||
|
||||
/* file close */
|
||||
if (H5Fclose (file_id[i]) < 0)
|
||||
FAIL_PUTS_ERROR("H5Fclose() failed");
|
||||
} /* end for */
|
||||
|
||||
PASSED();
|
||||
|
||||
TESTING("open file images and check image copies");
|
||||
|
||||
/* open the file images with the core driver for data access */
|
||||
for (i = 0; i < open_images; i++) {
|
||||
/* open file image 2 filled with counter data (non-valid image) */
|
||||
if (i == 2) {
|
||||
H5E_BEGIN_TRY {
|
||||
/* attempt to set file image in the core driver */
|
||||
file_id[i] = H5LTopen_file_image(buf_ptr[i], (size_t)buf_size[i], input_flags[i]);
|
||||
} H5E_END_TRY
|
||||
|
||||
VERIFY(file_id[i] < 0, "H5LTopen_file_image() should have failed");
|
||||
} /* end if */
|
||||
/* open rest of valid file images */
|
||||
else {
|
||||
/* set file image in the core driver */
|
||||
if ((file_id[i] = H5LTopen_file_image(buf_ptr[i], (size_t)buf_size[i], input_flags[i])) < 0)
|
||||
FAIL_PUTS_ERROR("H5LTopen_file_image() failed");
|
||||
|
||||
/* get pointer to the image buffer of the core driver */
|
||||
if (H5Fget_vfd_handle(file_id[i], H5P_DEFAULT, &handle_ptr) < 0)
|
||||
FAIL_PUTS_ERROR("H5Fget_vfd_handle() failed");
|
||||
|
||||
core_buf_ptr_ptr = (unsigned char **)handle_ptr;
|
||||
|
||||
/* test whether the user buffer has been copied or not */
|
||||
if (input_flags[i] & H5LT_FILE_IMAGE_DONT_COPY)
|
||||
VERIFY(*core_buf_ptr_ptr == buf_ptr[i], "vfd buffer and user buffer should have been the same");
|
||||
else
|
||||
VERIFY(*core_buf_ptr_ptr != buf_ptr[i], "vfd buffer and user buffer should be different");
|
||||
|
||||
/* test whether the contents of the user buffer and driver buffer */
|
||||
/* are equal. */
|
||||
if (HDmemcmp(*core_buf_ptr_ptr, buf_ptr[i], (size_t)buf_size[i]) != 0)
|
||||
FAIL_PUTS_ERROR("comparison of vfd and user buffer failed");
|
||||
} /* end else */
|
||||
} /* end for */
|
||||
|
||||
PASSED();
|
||||
|
||||
TESTING("read file images");
|
||||
|
||||
/* read open file images and verify data */
|
||||
for (i = 0; i < open_images; i++) {
|
||||
/* if opening the file image failed, continue next iteration */
|
||||
if (file_id[i] < 0) {
|
||||
HDassert(i == 2);
|
||||
continue;
|
||||
} /* end if */
|
||||
|
||||
/* open dataset in file image */
|
||||
if ((dset_id[i] = H5Dopen2(file_id[i], DSET_NAME, H5P_DEFAULT)) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dopen() failed");
|
||||
|
||||
/* get dataspace for the dataset */
|
||||
if ((file_space = H5Dget_space(dset_id[i])) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dget_space() failed");
|
||||
|
||||
/* get dimensions for the dataset */
|
||||
if (H5Sget_simple_extent_dims(file_space, dims3, NULL) < 0)
|
||||
FAIL_PUTS_ERROR("H5Sget_simple_extent_dims() failed");
|
||||
|
||||
/* read dataset */
|
||||
if (H5Dread(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data3) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dread() failed");
|
||||
|
||||
/* compute number of elements in dataset */
|
||||
n_values = (size_t)(dims3[0] * dims3[1]);
|
||||
|
||||
/* determine the number of rows in dataset */
|
||||
nrow = (size_t)dims3[1];
|
||||
|
||||
/* verify contents for file image 1 with "wrong" data */
|
||||
if (i == 1) {
|
||||
/* compare file image values with original data */
|
||||
for (j = 0; j < n_values / nrow; j++)
|
||||
for (k = 0; k < nrow; k++)
|
||||
if (data3[j * nrow + k ] == data1[j * nrow + k ])
|
||||
FAIL_PUTS_ERROR("comparison of image values with original data should have failed");
|
||||
} /* end if */
|
||||
/* verify contents for the rest of the file images */
|
||||
else {
|
||||
/* compare file image values with original data */
|
||||
for (j = 0; j < n_values / nrow; j++)
|
||||
for (k = 0; k < nrow; k++)
|
||||
if (data3[j * nrow + k ] != data1[j * nrow + k ])
|
||||
FAIL_PUTS_ERROR("comparison of image values with original data failed");
|
||||
} /* end else */
|
||||
|
||||
/* close dataspace */
|
||||
if (H5Sclose (file_space) < 0)
|
||||
FAIL_PUTS_ERROR("H5Sclose() failed");
|
||||
} /* end for */
|
||||
|
||||
PASSED();
|
||||
|
||||
TESTING("write and extend file images");
|
||||
|
||||
/* write open file images and verify data */
|
||||
for (i = 0; i < open_images; i++) {
|
||||
/* if opening the file image failed, continue next iteration */
|
||||
if (file_id[i] < 0) {
|
||||
HDassert(i == 2);
|
||||
continue;
|
||||
} /* end if */
|
||||
|
||||
/* test data write when file image access is read-only */
|
||||
if (!(input_flags[i] & H5LT_FILE_IMAGE_OPEN_RW)) {
|
||||
/* write dataset without extending it */
|
||||
H5E_BEGIN_TRY {
|
||||
status1 = H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data1);
|
||||
} H5E_END_TRY;
|
||||
|
||||
VERIFY(status1 < 0, "H5Dwrite() should have failed");
|
||||
|
||||
/* extend dimensions of dataset */
|
||||
H5E_BEGIN_TRY {
|
||||
status1 = H5Dset_extent(dset_id[i], dims4);
|
||||
} H5E_END_TRY;
|
||||
|
||||
VERIFY(status1 < 0, "H5Dset_extent() should have failed");
|
||||
|
||||
/* write extended dataset */
|
||||
H5E_BEGIN_TRY {
|
||||
status1 = H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data4);
|
||||
} H5E_END_TRY;
|
||||
|
||||
VERIFY(status1 < 0, "H5Dwrite() should have failed");
|
||||
|
||||
/* close dataset */
|
||||
if (H5Dclose(dset_id[i]) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dclose() failed");
|
||||
} /* end if */
|
||||
/* test data write where file image access is read-write */
|
||||
else {
|
||||
if ((input_flags[i] & H5LT_FILE_IMAGE_DONT_COPY) && (input_flags[i] & H5LT_FILE_IMAGE_DONT_RELEASE)) {
|
||||
/* This test is disabled currently, since the new attribute causes the file
|
||||
* to increase in size, but the realloc call in H5FD_core_write() fails, causing
|
||||
* the flush operation to fail and the file to fail to close, eventually
|
||||
* triggering the "infinite loop shutting down the library" problem.
|
||||
*
|
||||
* In theory, we could address this through a variety of methods, ranging from
|
||||
* ignoring failures in H5F_dest() (when called from H5F_try_close()), to
|
||||
* allocating space more aggressively when creating the attribute, etc.
|
||||
*
|
||||
* For now, we will just leave the test commented out and assume that
|
||||
* application developers who mark their file image as "don't copy" won't
|
||||
* be likely candidates for modifying their data. - QAK - March 29, 2012
|
||||
*/
|
||||
#if 0
|
||||
int attr_rank = 1;
|
||||
hsize_t attr_dims[] = {4096};
|
||||
int attr_data[4096];
|
||||
hid_t attr_space_id = -1;
|
||||
hid_t attr_id = -1;
|
||||
herr_t status2;
|
||||
size_t l;
|
||||
|
||||
if ((attr_space_id = H5Screate_simple(attr_rank, attr_dims, attr_dims)) < 0)
|
||||
FAIL_PUTS_ERROR("attr_space H5Screate_simple() failed");
|
||||
|
||||
if((attr_id = H5Acreate_by_name(dset_id[i], ".", "int array_addr", H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
FAIL_PUTS_ERROR("H5Acreate_by_name() failed");
|
||||
|
||||
for(l = 0; l < 4096; l++)
|
||||
attr_data[l] = (int)l;
|
||||
|
||||
/* write data to the attribute and then flush the file. One or the other should
|
||||
* should trigger an extension to the EOA, which in turn should cause the realloc
|
||||
* callback to fail.
|
||||
*/
|
||||
H5E_BEGIN_TRY {
|
||||
status1 = status2 = -1;
|
||||
|
||||
status1 = H5Awrite(attr_id, H5T_NATIVE_INT, (const void *)attr_data);
|
||||
if(status1 >= 0)
|
||||
status2 = H5Fflush(file_id[i], H5F_SCOPE_GLOBAL);
|
||||
|
||||
VERIFY(status1 < 0 || status2 < 0, "writing and flushing attr should have failed");
|
||||
} H5E_END_TRY;
|
||||
|
||||
/* close attr and attr_space -- expect errors on close */
|
||||
H5E_BEGIN_TRY {
|
||||
H5Sclose(attr_space_id);
|
||||
H5Aclose(attr_id);
|
||||
} H5E_END_TRY;
|
||||
#endif
|
||||
file_id[i] = -1;
|
||||
} /* end if */
|
||||
else {
|
||||
/* write dataset without extending it */
|
||||
if (H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data1) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dwrite() failed");
|
||||
|
||||
/* extend dimensions of dataset */
|
||||
if (H5Dset_extent(dset_id[i], dims4) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dset_extent() failed");
|
||||
|
||||
/* write extended dataset */
|
||||
if (H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data4) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dwrite() failed");
|
||||
|
||||
/* close dataset */
|
||||
if (H5Dclose(dset_id[i]) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dclose() failed");
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
} /* end for */
|
||||
|
||||
PASSED();
|
||||
|
||||
TESTING("read extended file images");
|
||||
|
||||
/* read open file images and verify data */
|
||||
for (i = 0; i < open_images; i++) {
|
||||
/* if opening the file image failed, continue next iteration */
|
||||
if ((file_id[i] < 0) || (!(input_flags[i] & H5LT_FILE_IMAGE_OPEN_RW )))
|
||||
continue;
|
||||
|
||||
/* open dataset in file image */
|
||||
if ((dset_id[i] = H5Dopen2(file_id[i], DSET_NAME, H5P_DEFAULT)) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dopen() failed");
|
||||
|
||||
/* get dataspace for the dataset */
|
||||
if ((file_space = H5Dget_space(dset_id[i])) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dget_space() failed");
|
||||
|
||||
/* get dimensions for the dataset */
|
||||
if (H5Sget_simple_extent_dims(file_space, dims3, NULL) < 0)
|
||||
FAIL_PUTS_ERROR("H5Sget_simple_extent_dims() failed");
|
||||
|
||||
/* read dataset */
|
||||
if (H5Dread(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data3) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dread() failed");
|
||||
|
||||
/* compute number of elements in dataset */
|
||||
n_values = (size_t)(dims3[0] * dims3[1]);
|
||||
|
||||
/* determine the number of rows in dataset */
|
||||
nrow = (size_t)dims3[1];
|
||||
|
||||
/* verify contents for the file images */
|
||||
for (j = 0; j < n_values / nrow; j++)
|
||||
for (k = 0; k < nrow; k++)
|
||||
if (data3[j * nrow + k ] != data4[j * nrow + k ])
|
||||
FAIL_PUTS_ERROR("comparison of image values with original data failed");
|
||||
|
||||
/* close dataspace */
|
||||
if (H5Sclose (file_space) < 0)
|
||||
FAIL_PUTS_ERROR("H5Sclose() failed");
|
||||
|
||||
/* close dataset */
|
||||
if (H5Dclose(dset_id[i]) < 0)
|
||||
FAIL_PUTS_ERROR("H5Dclose() failed");
|
||||
} /* end for */
|
||||
|
||||
PASSED()
|
||||
|
||||
TESTING("close file images");
|
||||
|
||||
/* close file images and release buffer if appropriate */
|
||||
for (i = 0; i < open_images; i++) {
|
||||
/* close file is appropriate */
|
||||
if (file_id[i] >= 0) {
|
||||
/* close file image */
|
||||
if (H5Fclose(file_id[i]) < 0)
|
||||
FAIL_PUTS_ERROR("H5Fclose() failed");
|
||||
} /* end if */
|
||||
|
||||
/* delete test data files */
|
||||
if (HDremove(filename[i]) < 0)
|
||||
FAIL_PUTS_ERROR("HDremove() failed");
|
||||
|
||||
/* free shared buffer if appropriate */
|
||||
if (!(input_flags[i] & H5LT_FILE_IMAGE_DONT_COPY) || (input_flags[i] & H5LT_FILE_IMAGE_DONT_RELEASE)) {
|
||||
VERIFY(buf_ptr[i] != NULL, "buffer pointer must be non NULL");
|
||||
HDfree(buf_ptr[i]);
|
||||
} /* end if */
|
||||
|
||||
} /* end for */
|
||||
|
||||
/* release temporary working buffers */
|
||||
HDfree(filename);
|
||||
HDfree(file_id);
|
||||
HDfree(dset_id);
|
||||
HDfree(buf_ptr);
|
||||
HDfree(buf_size);
|
||||
HDfree(input_flags);
|
||||
|
||||
PASSED();
|
||||
|
||||
H5close();
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5_FAILED();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* the main program
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int main( void )
|
||||
{
|
||||
int nerrors = 0;
|
||||
size_t open_images = 10; /* number of open file images */
|
||||
size_t nflags = 8; /* number of flag combinations */
|
||||
unsigned flags[8]; /* array with flag combinations */
|
||||
|
||||
/* set flag combinations for testing */
|
||||
flags[0] = 0;
|
||||
flags[1] = H5LT_FILE_IMAGE_DONT_RELEASE;
|
||||
flags[2] = H5LT_FILE_IMAGE_DONT_COPY;
|
||||
flags[3] = H5LT_FILE_IMAGE_DONT_COPY | H5LT_FILE_IMAGE_DONT_RELEASE;
|
||||
flags[4] = H5LT_FILE_IMAGE_OPEN_RW;
|
||||
flags[5] = H5LT_FILE_IMAGE_OPEN_RW | H5LT_FILE_IMAGE_DONT_RELEASE;
|
||||
flags[6] = H5LT_FILE_IMAGE_OPEN_RW | H5LT_FILE_IMAGE_DONT_COPY;
|
||||
flags[7] = H5LT_FILE_IMAGE_OPEN_RW | H5LT_FILE_IMAGE_DONT_COPY | H5LT_FILE_IMAGE_DONT_RELEASE;
|
||||
|
||||
/* Test file image operations. The flag combinations are assigned to file images in round-robin fashion */
|
||||
nerrors += test_file_image(open_images, nflags, flags) < 0? 1 : 0;
|
||||
|
||||
if (nerrors) goto error;
|
||||
printf("File image tests passed.\n");
|
||||
return 0;
|
||||
|
||||
error:
|
||||
printf("***** %d IMAGE TEST%s FAILED! *****\n",nerrors, 1 == nerrors ? "" : "S");
|
||||
return 1;
|
||||
}
|
||||
|
@ -2436,7 +2436,8 @@ H5D_flush(const H5F_t *f, hid_t dxpl_id)
|
||||
udata.dxpl_id = dxpl_id;
|
||||
|
||||
/* Iterate over all the open datasets */
|
||||
H5I_search(H5I_DATASET, H5D_flush_cb, &udata, FALSE);
|
||||
if(H5I_iterate(H5I_DATASET, H5D_flush_cb, &udata, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to flush cached dataset info")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
12
src/H5E.c
12
src/H5E.c
@ -107,7 +107,7 @@ static H5E_cls_t *H5E_register_class(const char *cls_name, const char *lib_name,
|
||||
const char *version);
|
||||
static herr_t H5E_unregister_class(H5E_cls_t *cls);
|
||||
static ssize_t H5E_get_class_name(const H5E_cls_t *cls, char *name, size_t size);
|
||||
static int H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *key);
|
||||
static int H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata);
|
||||
static herr_t H5E_close_msg(H5E_msg_t *err);
|
||||
static H5E_msg_t *H5E_create_msg(H5E_cls_t *cls, H5E_type_t msg_type, const char *msg);
|
||||
static H5E_t *H5E_get_current_stack(void);
|
||||
@ -543,8 +543,8 @@ H5E_unregister_class(H5E_cls_t *cls)
|
||||
HDassert(cls);
|
||||
|
||||
/* Iterate over all the messages and delete those in this error class */
|
||||
/* (Ignore return value, since callback isn't designed to return a particular object) */
|
||||
(void)H5I_search(H5I_ERROR_MSG, H5E_close_msg_cb, cls, FALSE);
|
||||
if(H5I_iterate(H5I_ERROR_MSG, H5E_close_msg_cb, cls, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_BADITER, FAIL, "unable to free all messages in this error class")
|
||||
|
||||
/* Free error class structure */
|
||||
if(H5E_free_class(cls) < 0)
|
||||
@ -631,7 +631,7 @@ H5E_get_class_name(const H5E_cls_t *cls, char *name, size_t size)
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5E_close_msg_cb
|
||||
*
|
||||
* Purpose: H5I_search callback function to close error messages in the
|
||||
* Purpose: H5I_iterate callback function to close error messages in the
|
||||
* error class.
|
||||
*
|
||||
* Return: Non-negative value on success/Negative on failure
|
||||
@ -642,10 +642,10 @@ H5E_get_class_name(const H5E_cls_t *cls, char *name, size_t size)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *key)
|
||||
H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata)
|
||||
{
|
||||
H5E_msg_t *err_msg = (H5E_msg_t*)obj_ptr;
|
||||
H5E_cls_t *cls = (H5E_cls_t*)key;
|
||||
H5E_cls_t *cls = (H5E_cls_t*)udata;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
@ -93,6 +93,7 @@ hid_t H5E_CANTRELEASE_g = FAIL; /* Unable to release object */
|
||||
hid_t H5E_CANTGET_g = FAIL; /* Can't get value */
|
||||
hid_t H5E_CANTSET_g = FAIL; /* Can't set value */
|
||||
hid_t H5E_DUPCLASS_g = FAIL; /* Duplicate class name in parent class */
|
||||
hid_t H5E_SETDISALLOWED_g = FAIL; /* Disallowed operation */
|
||||
|
||||
/* Free space errors */
|
||||
hid_t H5E_CANTMERGE_g = FAIL; /* Can't merge objects */
|
||||
|
@ -339,6 +339,11 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Duplicate class name in parent class")
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_DUPCLASS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
assert(H5E_SETDISALLOWED_g==(-1));
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Disallowed operation"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_SETDISALLOWED_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
|
||||
/* Free space errors */
|
||||
assert(H5E_CANTMERGE_g==(-1));
|
||||
|
@ -155,9 +155,11 @@ H5_DLLVAR hid_t H5E_CANTRELEASE_g; /* Unable to release object */
|
||||
#define H5E_CANTGET (H5OPEN H5E_CANTGET_g)
|
||||
#define H5E_CANTSET (H5OPEN H5E_CANTSET_g)
|
||||
#define H5E_DUPCLASS (H5OPEN H5E_DUPCLASS_g)
|
||||
#define H5E_SETDISALLOWED (H5OPEN H5E_SETDISALLOWED_g)
|
||||
H5_DLLVAR hid_t H5E_CANTGET_g; /* Can't get value */
|
||||
H5_DLLVAR hid_t H5E_CANTSET_g; /* Can't set value */
|
||||
H5_DLLVAR hid_t H5E_DUPCLASS_g; /* Duplicate class name in parent class */
|
||||
H5_DLLVAR hid_t H5E_SETDISALLOWED_g; /* Disallowed operation */
|
||||
|
||||
/* Free space errors */
|
||||
#define H5E_CANTMERGE (H5OPEN H5E_CANTMERGE_g)
|
||||
|
@ -94,7 +94,8 @@ H5E_CANTRELEASE_g=
|
||||
/* Property list errors */
|
||||
H5E_CANTGET_g=
|
||||
H5E_CANTSET_g=
|
||||
H5E_DUPCLASS_g=
|
||||
H5E_DUPCLASS_g=
|
||||
H5E_SETDISALLOWED_g=
|
||||
|
||||
/* Free space errors */
|
||||
H5E_CANTMERGE_g=
|
||||
|
284
src/H5F.c
284
src/H5F.c
@ -52,7 +52,7 @@ typedef struct H5F_olist_t {
|
||||
} H5F_olist_t;
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref);
|
||||
static herr_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr);
|
||||
static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
|
||||
static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id,
|
||||
H5FD_t *lf);
|
||||
@ -363,11 +363,6 @@ done:
|
||||
*
|
||||
* Programmer: Raymond Lu
|
||||
* Wednesday, Dec 5, 2001
|
||||
* Modification:
|
||||
* Raymond Lu
|
||||
* 24 September 2008
|
||||
* Changed the return value to ssize_t to accommadate
|
||||
* potential large number of objects.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -375,18 +370,24 @@ ssize_t
|
||||
H5Fget_obj_count(hid_t file_id, unsigned types)
|
||||
{
|
||||
H5F_t *f = NULL; /* File to query */
|
||||
ssize_t ret_value; /* Return value */
|
||||
size_t obj_count = 0; /* Number of opened objects */
|
||||
ssize_t ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE2("Zs", "iIu", file_id, types);
|
||||
|
||||
/* Check arguments */
|
||||
if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id")
|
||||
if(0 == (types & H5F_OBJ_ALL))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type")
|
||||
|
||||
/* H5F_get_obj_count doesn't fail */
|
||||
ret_value = (ssize_t)H5F_get_obj_count(f, types, TRUE);
|
||||
/* Perform the query */
|
||||
if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed")
|
||||
|
||||
/* Set the return value */
|
||||
ret_value = (ssize_t)obj_count;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
@ -399,31 +400,30 @@ done:
|
||||
* Purpose: Private function return the number of opened object IDs
|
||||
* (files, datasets, groups, datatypes) in the same file.
|
||||
*
|
||||
* Return: Non-negative on success; can't fail.
|
||||
* Return: SUCCEED on success, FAIL on failure.
|
||||
*
|
||||
* Programmer: Raymond Lu
|
||||
* Wednesday, Dec 5, 2001
|
||||
*
|
||||
* Modification:
|
||||
* Raymond Lu
|
||||
* 24 September 2008
|
||||
* Changed the return value to size_t to accommadate
|
||||
* potential large number of objects.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
size_t
|
||||
H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref)
|
||||
herr_t
|
||||
H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr)
|
||||
{
|
||||
size_t ret_value; /* Return value */
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOERR
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* H5F_get_objects doesn't fail */
|
||||
ret_value = H5F_get_objects(f, types, 0, NULL, app_ref);
|
||||
/* Sanity check */
|
||||
HDassert(obj_id_count_ptr);
|
||||
|
||||
/* Perform the query */
|
||||
if((ret_value = H5F_get_objects(f, types, 0, NULL, app_ref, obj_id_count_ptr)) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
} /* end H5F_get_obj_count() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -448,19 +448,25 @@ ssize_t
|
||||
H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list)
|
||||
{
|
||||
H5F_t *f = NULL; /* File to query */
|
||||
ssize_t ret_value; /* Return value */
|
||||
size_t obj_id_count = 0; /* Number of open objects */
|
||||
ssize_t ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE4("Zs", "iIuz*i", file_id, types, max_objs, oid_list);
|
||||
|
||||
/* Check arguments */
|
||||
if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id")
|
||||
if(0 == (types & H5F_OBJ_ALL))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type")
|
||||
HDassert(oid_list);
|
||||
|
||||
/* H5F_get_objects doesn't fail */
|
||||
ret_value = (ssize_t)H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE);
|
||||
/* Perform the query */
|
||||
if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_id_count) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed")
|
||||
|
||||
/* Set the return value */
|
||||
ret_value = (ssize_t)obj_id_count;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
@ -477,26 +483,25 @@ done:
|
||||
* Programmer: Raymond Lu
|
||||
* Wednesday, Dec 5, 2001
|
||||
*
|
||||
* Modification:
|
||||
* Raymond Lu
|
||||
* 24 September 2008
|
||||
* Changed the return value and MAX_OBJTS to size_t to accommadate
|
||||
* potential large number of objects.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
size_t
|
||||
H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref)
|
||||
herr_t
|
||||
H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref, size_t *obj_id_count_ptr)
|
||||
{
|
||||
size_t ret_value; /* Return value */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOERR
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* H5F_get_objects doesn't fail */
|
||||
ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref);
|
||||
/* Sanity check */
|
||||
HDassert(obj_id_count_ptr);
|
||||
|
||||
/* Perform the query */
|
||||
if((ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref, obj_id_count_ptr)) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
} /* end H5F_get_obj_ids() */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
@ -512,14 +517,18 @@ H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
static size_t
|
||||
H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref)
|
||||
static herr_t
|
||||
H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr)
|
||||
{
|
||||
size_t obj_id_count=0; /* Number of open IDs */
|
||||
H5F_olist_t olist; /* Structure to hold search results */
|
||||
size_t ret_value; /* Return value */
|
||||
htri_t type_exists; /* Whether objects of a type are open */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOERR
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(obj_id_count_ptr);
|
||||
|
||||
/* Set up search information */
|
||||
olist.obj_id_list = (max_index==0 ? NULL : obj_id_list);
|
||||
@ -537,45 +546,50 @@ H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_
|
||||
olist.file_info.ptr.shared = f ? f->shared : NULL;
|
||||
} /* end else */
|
||||
|
||||
/* Search through file IDs to count the number, and put their
|
||||
* IDs on the object list. H5I_search returns NULL if no object
|
||||
* is found, so don't return failure in this function. */
|
||||
/* Iterate through file IDs to count the number, and put their
|
||||
* IDs on the object list. */
|
||||
if(types & H5F_OBJ_FILE) {
|
||||
olist.obj_type = H5I_FILE;
|
||||
(void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist, app_ref);
|
||||
if(H5I_iterate(H5I_FILE, H5F_get_objects_cb, &olist, app_ref) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(1)")
|
||||
} /* end if */
|
||||
|
||||
/* Search through dataset IDs to count number of datasets, and put their
|
||||
* IDs on the object list */
|
||||
if(types & H5F_OBJ_DATASET) {
|
||||
olist.obj_type = H5I_DATASET;
|
||||
(void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref);
|
||||
}
|
||||
if(H5I_iterate(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(2)")
|
||||
} /* end if */
|
||||
|
||||
/* Search through group IDs to count number of groups, and put their
|
||||
* IDs on the object list */
|
||||
if(types & H5F_OBJ_GROUP) {
|
||||
olist.obj_type = H5I_GROUP;
|
||||
(void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref);
|
||||
}
|
||||
if(H5I_iterate(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(3)")
|
||||
} /* end if */
|
||||
|
||||
/* Search through datatype IDs to count number of named datatypes, and put their
|
||||
* IDs on the object list */
|
||||
if(types & H5F_OBJ_DATATYPE) {
|
||||
olist.obj_type = H5I_DATATYPE;
|
||||
(void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref);
|
||||
}
|
||||
if(H5I_iterate(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(4)")
|
||||
} /* end if */
|
||||
|
||||
/* Search through attribute IDs to count number of attributes, and put their
|
||||
* IDs on the object list */
|
||||
if(types & H5F_OBJ_ATTR) {
|
||||
olist.obj_type = H5I_ATTR;
|
||||
(void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref);
|
||||
}
|
||||
if(H5I_iterate(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(5)")
|
||||
} /* end if */
|
||||
|
||||
/* Set the number of objects currently open */
|
||||
ret_value = obj_id_count;
|
||||
*obj_id_count_ptr = obj_id_count;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_get_objects() */
|
||||
|
||||
@ -593,8 +607,6 @@ H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_
|
||||
* Programmer: Raymond Lu
|
||||
* Wednesday, Dec 5, 2001
|
||||
*
|
||||
* Modification:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
@ -626,8 +638,8 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
|
||||
|
||||
/* Check if we've filled up the array. Return TRUE only if
|
||||
* we have filled up the array. Otherwise return FALSE(RET_VALUE is
|
||||
* preset to FALSE) because H5I_search needs the return value of FALSE
|
||||
* to continue searching. */
|
||||
* preset to FALSE) because H5I_iterate needs the return value of
|
||||
* FALSE to continue the iteration. */
|
||||
if(olist->max_index>0 && olist->list_index>=olist->max_index)
|
||||
HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */
|
||||
}
|
||||
@ -691,8 +703,8 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
|
||||
|
||||
/* Check if we've filled up the array. Return TRUE only if
|
||||
* we have filled up the array. Otherwise return FALSE(RET_VALUE is
|
||||
* preset to FALSE) because H5I_search needs the return value of FALSE
|
||||
* to continue searching. */
|
||||
* preset to FALSE) because H5I_iterate needs the return value of
|
||||
* FALSE to continue iterating. */
|
||||
if(olist->max_index>0 && olist->list_index>=olist->max_index)
|
||||
HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */
|
||||
} /* end if */
|
||||
@ -1785,8 +1797,6 @@ done:
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
@ -1868,27 +1878,36 @@ H5F_try_close(H5F_t *f)
|
||||
if(f->nopen_objs > 0) {
|
||||
size_t obj_count; /* # of open objects */
|
||||
hid_t objs[128]; /* Array of objects to close */
|
||||
herr_t result; /* Local result from obj ID query */
|
||||
size_t u; /* Local index variable */
|
||||
|
||||
/* Get the list of IDs of open dataset, group, & attribute objects */
|
||||
while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) {
|
||||
while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_ATTR, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0
|
||||
&& obj_count != 0 ) {
|
||||
|
||||
/* Try to close all the open objects in this file */
|
||||
for(u = 0; u < obj_count; u++)
|
||||
if(H5I_dec_ref(objs[u]) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
|
||||
} /* end while */
|
||||
if(result < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(1)")
|
||||
|
||||
/* Get the list of IDs of open named datatype objects */
|
||||
/* (Do this separately from the dataset & attribute IDs, because
|
||||
* they could be using one of the named datatypes and then the
|
||||
* open named datatype ID will get closed twice)
|
||||
*/
|
||||
while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) {
|
||||
while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATATYPE, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0
|
||||
&& obj_count != 0) {
|
||||
|
||||
/* Try to close all the open objects in this file */
|
||||
for(u = 0; u < obj_count; u++)
|
||||
if(H5I_dec_ref(objs[u]) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
|
||||
} /* end while */
|
||||
if(result < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(2)")
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
@ -2549,6 +2568,139 @@ done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Fget_filesize() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Fget_file_image
|
||||
*
|
||||
* Purpose: If a buffer is provided (via the buf_ptr argument) and is
|
||||
* big enough (size in buf_len argument), load *buf_ptr with
|
||||
* an image of the open file whose ID is provided in the
|
||||
* file_id parameter, and return the number of bytes copied
|
||||
* to the buffer.
|
||||
*
|
||||
* If the buffer exists, but is too small to contain an image
|
||||
* of the indicated file, return a negative number.
|
||||
*
|
||||
* Finally, if no buffer is provided, return the size of the
|
||||
* buffer needed. This value is simply the eoa of the target
|
||||
* file.
|
||||
*
|
||||
* Note that any user block is skipped.
|
||||
*
|
||||
* Also note that the function may not be used on files
|
||||
* opened with either the split/multi file driver or the
|
||||
* family file driver.
|
||||
*
|
||||
* In the former case, the sparse address space makes the
|
||||
* get file image operation impractical, due to the size of
|
||||
* the image typically required.
|
||||
*
|
||||
* In the case of the family file driver, the problem is
|
||||
* the driver message in the super block, which will prevent
|
||||
* the image being opened with any driver other than the
|
||||
* family file driver -- which negates the purpose of the
|
||||
* operation. This can be fixed, but no resources for
|
||||
* this now.
|
||||
*
|
||||
* Return: Success: Bytes copied / number of bytes needed.
|
||||
* Failure: negative value
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* 11/15/11
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
ssize_t
|
||||
H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len)
|
||||
{
|
||||
H5F_t *file; /* File object for file ID */
|
||||
H5FD_t *fd_ptr; /* file driver */
|
||||
haddr_t eoa; /* End of file address */
|
||||
ssize_t ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE3("Zs", "i*xz", file_id, buf_ptr, buf_len);
|
||||
|
||||
/* Check args */
|
||||
if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
|
||||
if(!file || !file->shared || !file->shared->lf)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file_id yields invalid file pointer")
|
||||
fd_ptr = file->shared->lf;
|
||||
if(!fd_ptr->cls)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "fd_ptr yields invalid class pointer")
|
||||
|
||||
/* the address space used by the split and multi file drivers is not
|
||||
* a good fit for this call. Since the plan is to depreciate these
|
||||
* drivers anyway, don't bother to do a "force fit".
|
||||
*
|
||||
* The following clause tests for the multi file driver, and fails
|
||||
* if the supplied file has the multi file driver as its top level
|
||||
* file driver. However, this test will not work if there is some
|
||||
* other file driver sitting on top of the multi file driver.
|
||||
*
|
||||
* I'm not sure if this is possible at present, but in all likelyhood,
|
||||
* it will become possible in the future. On the other hand, we may
|
||||
* remove the split/multi file drivers before then.
|
||||
*
|
||||
* I am leaving this solution in for now, but we should review it,
|
||||
* and improve the solution if necessary.
|
||||
*
|
||||
* JRM -- 11/11/22
|
||||
*/
|
||||
if(HDstrcmp(fd_ptr->cls->name, "multi") == 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not supported for multi file driver.")
|
||||
|
||||
/* While the family file driver is conceptually fully compatible
|
||||
* with the get file image operation, it sets a file driver message
|
||||
* in the super block that prevents the image being opened with any
|
||||
* driver other than the family file driver. Needless to say, this
|
||||
* rather defeats the purpose of the get file image operation.
|
||||
*
|
||||
* While this problem is quire solvable, the required time and
|
||||
* resources are lacking at present. Hence, for now, we don't
|
||||
* allow the get file image operation to be perfomed on files
|
||||
* opened with the family file driver.
|
||||
*
|
||||
* Observe that the following test only looks at the top level
|
||||
* driver, and fails if there is some other driver sitting on to
|
||||
* of the family file driver.
|
||||
*
|
||||
* I don't think this can happen at present, but that may change
|
||||
* in the future.
|
||||
* JRM -- 12/21/11
|
||||
*/
|
||||
if(HDstrcmp(fd_ptr->cls->name, "family") == 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "Not supported for family file driver.")
|
||||
|
||||
|
||||
/* Go get the actual file size */
|
||||
if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT)))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size")
|
||||
|
||||
/* set ret_value = to eoa -- will overwrite this if appropriate */
|
||||
ret_value = (ssize_t)eoa;
|
||||
|
||||
/* test to see if a buffer was provided -- if not, we are done */
|
||||
if(buf_ptr != NULL) {
|
||||
size_t space_needed; /* size of file image */
|
||||
|
||||
/* Check for buffer too small */
|
||||
if((haddr_t)buf_len < eoa)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "supplied buffer too small")
|
||||
|
||||
space_needed = (size_t)eoa;
|
||||
|
||||
/* read in the file image */
|
||||
/* (Note compensation for base address addition in internal routine) */
|
||||
if(H5FD_read(fd_ptr, H5AC_ind_dxpl_id, H5FD_MEM_DEFAULT, 0, space_needed, buf_ptr) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "file image read request failed")
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* H5Fget_file_image() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Fget_mdc_config
|
||||
|
82
src/H5FD.c
82
src/H5FD.c
@ -70,6 +70,10 @@ static herr_t H5FD_pl_copy(void *(*copy_func)(const void *), size_t pl_size,
|
||||
static herr_t H5FD_pl_close(hid_t driver_id, herr_t (*free_func)(void *),
|
||||
void *pl);
|
||||
static herr_t H5FD_free_cls(H5FD_class_t *cls);
|
||||
static herr_t H5FD_fapl_copy(hid_t driver_id, const void *fapl, void **copied_fapl);
|
||||
static herr_t H5FD_dxpl_copy(hid_t driver_id, const void *dxpl, void **copied_dxpl);
|
||||
static int H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/);
|
||||
static int H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags/*out*/);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@ -750,17 +754,15 @@ done:
|
||||
* Programmer: Robb Matzke
|
||||
* Tuesday, August 3, 1999
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
static herr_t
|
||||
H5FD_fapl_copy(hid_t driver_id, const void *old_fapl, void **copied_fapl)
|
||||
{
|
||||
H5FD_class_t *driver;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
/* Check args */
|
||||
if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
|
||||
@ -871,17 +873,15 @@ done:
|
||||
* Programmer: Robb Matzke
|
||||
* Tuesday, August 3, 1999
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
static herr_t
|
||||
H5FD_dxpl_copy(hid_t driver_id, const void *old_dxpl, void **copied_dxpl)
|
||||
{
|
||||
H5FD_class_t *driver;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
/* Check args */
|
||||
if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
|
||||
@ -1039,6 +1039,8 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
|
||||
H5FD_t *file = NULL; /* VFD file struct */
|
||||
hid_t driver_id = -1; /* VFD ID */
|
||||
H5P_genplist_t *plist; /* Property list pointer */
|
||||
unsigned long driver_flags = 0; /* File-inspecific driver feature flags */
|
||||
H5FD_file_image_info_t file_image_info; /* Initial file image */
|
||||
H5FD_t *ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(NULL)
|
||||
@ -1061,6 +1063,19 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
|
||||
if(NULL == driver->open)
|
||||
HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file driver has no `open' method")
|
||||
|
||||
/* Query driver flag */
|
||||
H5FD_driver_query(driver, &driver_flags);
|
||||
|
||||
/* Get initial file image info */
|
||||
if(H5P_get(plist, H5F_ACS_FILE_IMAGE_INFO_NAME, &file_image_info) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file image info")
|
||||
|
||||
/* If an image is provided, make sure the driver supports this feature */
|
||||
HDassert(((file_image_info.buffer != NULL) && (file_image_info.size > 0)) ||
|
||||
((file_image_info.buffer == NULL) && (file_image_info.size == 0)));
|
||||
if((file_image_info.buffer != NULL) && !(driver_flags & H5FD_FEAT_ALLOW_FILE_IMAGE))
|
||||
HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file image set, but not supported.")
|
||||
|
||||
/* Dispatch to file driver */
|
||||
if(HADDR_UNDEF == maxaddr)
|
||||
maxaddr = driver->maxaddr;
|
||||
@ -1318,19 +1333,17 @@ done:
|
||||
* Programmer: Quincey Koziol
|
||||
* Friday, August 25, 2000
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
static int
|
||||
H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/)
|
||||
{
|
||||
int ret_value=0;
|
||||
int ret_value = 0; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
assert(f);
|
||||
assert(flags);
|
||||
HDassert(f);
|
||||
HDassert(flags);
|
||||
|
||||
/* Check for query driver and call it */
|
||||
if(f->cls->query)
|
||||
@ -1340,7 +1353,44 @@ H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/)
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
} /* end H5FD_query() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FD_driver_query
|
||||
*
|
||||
* Purpose: Similar to H5FD_query(), but intended for cases when we don't
|
||||
* have a file available (e.g. before one is opened). Since we
|
||||
* can't use the file to get the driver, the driver is passed in
|
||||
* as a parameter.
|
||||
*
|
||||
* Return: Success: non-negative
|
||||
* Failure: negative
|
||||
*
|
||||
* Programmer: Jacob Gruber
|
||||
* Wednesday, August 17, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags/*out*/)
|
||||
{
|
||||
int ret_value = 0; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
HDassert(driver);
|
||||
HDassert(flags);
|
||||
|
||||
/* Check for the driver to query and then query it */
|
||||
if(driver->query)
|
||||
ret_value = (driver->query)(NULL, flags);
|
||||
else
|
||||
*flags = 0;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5FD_driver_query() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
285
src/H5FDcore.c
285
src/H5FDcore.c
@ -101,6 +101,7 @@ typedef struct H5FD_core_t {
|
||||
HANDLE hFile; /* Native windows file handle */
|
||||
#endif /* H5_HAVE_WIN32_API */
|
||||
hbool_t dirty; /*changes not saved? */
|
||||
H5FD_file_image_callbacks_t fi_callbacks; /* file image callbacks */
|
||||
} H5FD_core_t;
|
||||
|
||||
/* Driver-specific file access properties */
|
||||
@ -412,6 +413,7 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
|
||||
#endif
|
||||
h5_stat_t sb;
|
||||
int fd=-1;
|
||||
H5FD_file_image_info_t file_image_info;
|
||||
H5FD_t *ret_value;
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
@ -434,10 +436,32 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
|
||||
if(H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
|
||||
if(H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
|
||||
|
||||
/* Retrieve initial file image info */
|
||||
if(H5P_get(plist, H5F_ACS_FILE_IMAGE_INFO_NAME, &file_image_info) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial file image info")
|
||||
|
||||
/* If the file image exists and this is an open, make sure the file doesn't exist */
|
||||
HDassert(((file_image_info.buffer != NULL) && (file_image_info.size > 0)) ||
|
||||
((file_image_info.buffer == NULL) && (file_image_info.size == 0)));
|
||||
if((file_image_info.buffer != NULL) && !(H5F_ACC_CREAT & flags)) {
|
||||
if(HDopen(name, o_flags, 0666) >= 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file already exists")
|
||||
|
||||
/* If backing store is requested, create and stat the file
|
||||
* Note: We are forcing the O_CREAT flag here, even though this is
|
||||
* technically an open.
|
||||
*/
|
||||
if(fa->backing_store) {
|
||||
if((fd = HDopen(name, o_flags | O_CREAT, 0666)) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create file")
|
||||
if(HDfstat(fd, &sb) < 0)
|
||||
HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
/* Open backing store, and get stat() from file. The only case that backing
|
||||
* store is off is when the backing_store flag is off and H5F_ACC_CREAT is
|
||||
* on. */
|
||||
if(fa->backing_store || !(H5F_ACC_CREAT & flags)) {
|
||||
else if(fa->backing_store || !(H5F_ACC_CREAT & flags)) {
|
||||
if(fa && (fd = HDopen(name, o_flags, 0666)) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
|
||||
if(HDfstat(fd, &sb) < 0)
|
||||
@ -460,6 +484,9 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
|
||||
/* If save data in backing store. */
|
||||
file->backing_store = fa->backing_store;
|
||||
|
||||
/* Save file image callbacks */
|
||||
file->fi_callbacks = file_image_info.callbacks;
|
||||
|
||||
if(fd >= 0) {
|
||||
/* Retrieve information for determining uniqueness of file */
|
||||
#ifdef H5_HAVE_WIN32_API
|
||||
@ -491,51 +518,70 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
|
||||
size_t size;
|
||||
|
||||
/* Retrieve file size */
|
||||
size = (size_t)sb.st_size;
|
||||
if(file_image_info.buffer && file_image_info.size > 0)
|
||||
size = file_image_info.size;
|
||||
else
|
||||
size = (size_t)sb.st_size;
|
||||
|
||||
/* Check if we should allocate the memory buffer and read in existing data */
|
||||
if(size) {
|
||||
/* Allocate memory for the file's data */
|
||||
if(NULL == (file->mem = (unsigned char*)H5MM_malloc(size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory block")
|
||||
/* Allocate memory for the file's data, using the file image callback if available. */
|
||||
if(file->fi_callbacks.image_malloc) {
|
||||
if(NULL == (file->mem = (unsigned char*)file->fi_callbacks.image_malloc(size, H5FD_FILE_IMAGE_OP_FILE_OPEN, file->fi_callbacks.udata)))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "image malloc callback failed")
|
||||
} /* end if */
|
||||
else {
|
||||
if(NULL == (file->mem = (unsigned char*)H5MM_malloc(size)))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "unable to allocate memory block")
|
||||
} /* end else */
|
||||
|
||||
/* Set up data structures */
|
||||
file->eof = size;
|
||||
|
||||
/* Read in existing data, being careful of interrupted system calls,
|
||||
* partial results, and the end of the file.
|
||||
*/
|
||||
while(size > 0) {
|
||||
|
||||
h5_core_io_t bytes_in = 0; /* # of bytes to read */
|
||||
h5_core_io_ret_t bytes_read = -1; /* # of bytes actually read */
|
||||
|
||||
/* Trying to read more bytes than the return type can handle is
|
||||
* undefined behavior in POSIX.
|
||||
*/
|
||||
if(size > H5_CORE_MAX_IO_BYTES_g)
|
||||
bytes_in = H5_CORE_MAX_IO_BYTES_g;
|
||||
else
|
||||
bytes_in = (h5_core_io_t)size;
|
||||
|
||||
do {
|
||||
bytes_read = HDread(file->fd, file->mem, bytes_in);
|
||||
} while(-1 == bytes_read && EINTR == errno);
|
||||
|
||||
if(-1 == bytes_read) { /* error */
|
||||
int myerrno = errno;
|
||||
time_t mytime = HDtime(NULL);
|
||||
HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR);
|
||||
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', file->mem = %p, size = %lu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), file->mem, (unsigned long)size, (unsigned long long)myoffset);
|
||||
/* If there is an initial file image, copy it, using the callback if possible */
|
||||
if(file_image_info.buffer && file_image_info.size > 0) {
|
||||
if(file->fi_callbacks.image_memcpy) {
|
||||
if(file->mem != file->fi_callbacks.image_memcpy(file->mem, file_image_info.buffer, size, H5FD_FILE_IMAGE_OP_FILE_OPEN, file->fi_callbacks.udata))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, NULL, "image_memcpy callback failed")
|
||||
} /* end if */
|
||||
|
||||
HDassert(bytes_read >= 0);
|
||||
HDassert((size_t)bytes_read <= size);
|
||||
|
||||
size -= (size_t)bytes_read;
|
||||
|
||||
} /* end while */
|
||||
else
|
||||
HDmemcpy(file->mem, file_image_info.buffer, size);
|
||||
} /* end if */
|
||||
/* Read in existing data from the file if there is no image */
|
||||
else {
|
||||
/* Read in existing data, being careful of interrupted system calls,
|
||||
* partial results, and the end of the file.
|
||||
*/
|
||||
while(size > 0) {
|
||||
h5_core_io_t bytes_in = 0; /* # of bytes to read */
|
||||
h5_core_io_ret_t bytes_read = -1; /* # of bytes actually read */
|
||||
|
||||
/* Trying to read more bytes than the return type can handle is
|
||||
* undefined behavior in POSIX.
|
||||
*/
|
||||
if(size > H5_CORE_MAX_IO_BYTES_g)
|
||||
bytes_in = H5_CORE_MAX_IO_BYTES_g;
|
||||
else
|
||||
bytes_in = (h5_core_io_t)size;
|
||||
|
||||
do {
|
||||
bytes_read = HDread(file->fd, file->mem, bytes_in);
|
||||
} while(-1 == bytes_read && EINTR == errno);
|
||||
|
||||
if(-1 == bytes_read) { /* error */
|
||||
int myerrno = errno;
|
||||
time_t mytime = HDtime(NULL);
|
||||
HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR);
|
||||
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', file->mem = %p, size = %lu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), file->mem, (unsigned long)size, (unsigned long long)myoffset);
|
||||
} /* end if */
|
||||
|
||||
HDassert(bytes_read >= 0);
|
||||
HDassert((size_t)bytes_read <= size);
|
||||
|
||||
size -= (size_t)bytes_read;
|
||||
} /* end while */
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
@ -578,8 +624,15 @@ H5FD_core_close(H5FD_t *_file)
|
||||
HDclose(file->fd);
|
||||
if(file->name)
|
||||
H5MM_xfree(file->name);
|
||||
if(file->mem)
|
||||
H5MM_xfree(file->mem);
|
||||
if(file->mem) {
|
||||
/* Use image callback if available */
|
||||
if(file->fi_callbacks.image_free) {
|
||||
if(file->fi_callbacks.image_free(file->mem, H5FD_FILE_IMAGE_OP_FILE_CLOSE, file->fi_callbacks.udata) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "image_free callback failed")
|
||||
} /* end if */
|
||||
else
|
||||
H5MM_xfree(file->mem);
|
||||
} /* end if */
|
||||
HDmemset(file, 0, sizeof(H5FD_core_t));
|
||||
H5MM_xfree(file);
|
||||
|
||||
@ -700,9 +753,11 @@ H5FD_core_query(const H5FD_t * _file, unsigned long *flags /* out */)
|
||||
*flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
|
||||
*flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
|
||||
*flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
|
||||
*flags |= H5FD_FEAT_ALLOW_FILE_IMAGE; /* OK to use file image feature with this VFD */
|
||||
*flags |= H5FD_FEAT_CAN_USE_FILE_IMAGE_CALLBACKS; /* OK to use file image callbacks with this VFD */
|
||||
|
||||
/* If the backing store is open, a POSIX file handle is available */
|
||||
if(file->fd >= 0 && file->backing_store)
|
||||
if(file && file->fd >= 0 && file->backing_store)
|
||||
*flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
|
||||
} /* end if */
|
||||
|
||||
@ -976,9 +1031,16 @@ H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had
|
||||
if((addr + size) % file->increment)
|
||||
new_eof += file->increment;
|
||||
|
||||
/* (Re)allocate memory for the file buffer */
|
||||
if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block of %llu bytes", (unsigned long long)new_eof)
|
||||
/* (Re)allocate memory for the file buffer, using callbacks if available */
|
||||
if(file->fi_callbacks.image_realloc) {
|
||||
if(NULL == (x = (unsigned char *)file->fi_callbacks.image_realloc(file->mem, new_eof, H5FD_FILE_IMAGE_OP_FILE_RESIZE, file->fi_callbacks.udata)))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate memory block of %llu bytes with callback", (unsigned long long)new_eof)
|
||||
} /* end if */
|
||||
else {
|
||||
if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate memory block of %llu bytes", (unsigned long long)new_eof)
|
||||
} /* end else */
|
||||
|
||||
#ifdef H5_CLEAR_MEMORY
|
||||
HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
|
||||
#endif /* H5_CLEAR_MEMORY */
|
||||
@ -989,6 +1051,8 @@ HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
|
||||
|
||||
/* Write from BUF to memory */
|
||||
HDmemcpy(file->mem + addr, buf, size);
|
||||
|
||||
/* Mark memory buffer as modified */
|
||||
file->dirty = TRUE;
|
||||
|
||||
done:
|
||||
@ -1075,6 +1139,28 @@ done:
|
||||
* Purpose: Makes sure that the true file size is the same (or larger)
|
||||
* than the end-of-address.
|
||||
*
|
||||
* Addendum -- 12/2/11
|
||||
* For file images opened with the core file driver, it is
|
||||
* necessary that we avoid reallocating the core file driver's
|
||||
* buffer uneccessarily.
|
||||
*
|
||||
* To this end, I have made the following functional changes
|
||||
* to this function.
|
||||
*
|
||||
* If we are closing, and there is no backing store, this
|
||||
* function becomes a no-op.
|
||||
*
|
||||
* If we are closing, and there is backing store, we set the
|
||||
* eof to equal the eoa, and truncate the backing store to
|
||||
* the new eof
|
||||
*
|
||||
* If we are not closing, we realloc the buffer to size equal
|
||||
* to the smallest multiple of the allocation increment that
|
||||
* equals or exceeds the eoa and set the eof accordingly.
|
||||
* Note that we no longer truncate the backing store to the
|
||||
* new eof if applicable.
|
||||
* -- JRM
|
||||
*
|
||||
* Return: Success: Non-negative
|
||||
* Failure: Negative
|
||||
*
|
||||
@ -1085,7 +1171,7 @@ done:
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static herr_t
|
||||
H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
|
||||
H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t closing)
|
||||
{
|
||||
H5FD_core_t *file = (H5FD_core_t*)_file;
|
||||
size_t new_eof; /* New size of memory buffer */
|
||||
@ -1095,68 +1181,83 @@ H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
|
||||
|
||||
HDassert(file);
|
||||
|
||||
/* Determine new size of memory buffer */
|
||||
H5_ASSIGN_OVERFLOW(new_eof, file->increment * (file->eoa / file->increment), hsize_t, size_t);
|
||||
if(file->eoa % file->increment)
|
||||
new_eof += file->increment;
|
||||
/* if we are closing and not using backing store, do nothing */
|
||||
if(!closing || file->backing_store) {
|
||||
if(closing) /* set eof to eoa */
|
||||
new_eof = file->eoa;
|
||||
else { /* set eof to smallest multiple of increment that exceeds eoa */
|
||||
/* Determine new size of memory buffer */
|
||||
H5_ASSIGN_OVERFLOW(new_eof, file->increment * (file->eoa / file->increment), hsize_t, size_t);
|
||||
if(file->eoa % file->increment)
|
||||
new_eof += file->increment;
|
||||
} /* end else */
|
||||
|
||||
/* Extend the file to make sure it's large enough */
|
||||
if(!H5F_addr_eq(file->eof, (haddr_t)new_eof)) {
|
||||
unsigned char *x; /* Pointer to new buffer for file data */
|
||||
/* Extend the file to make sure it's large enough */
|
||||
if(!H5F_addr_eq(file->eof, (haddr_t)new_eof)) {
|
||||
unsigned char *x; /* Pointer to new buffer for file data */
|
||||
|
||||
/* (Re)allocate memory for the file buffer, using callback if available */
|
||||
if(file->fi_callbacks.image_realloc) {
|
||||
if(NULL == (x = (unsigned char *)file->fi_callbacks.image_realloc(file->mem, new_eof, H5FD_FILE_IMAGE_OP_FILE_RESIZE, file->fi_callbacks.udata)))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate memory block with callback")
|
||||
} /* end if */
|
||||
else {
|
||||
if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate memory block")
|
||||
} /* end else */
|
||||
|
||||
/* (Re)allocate memory for the file buffer */
|
||||
if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
|
||||
#ifdef H5_CLEAR_MEMORY
|
||||
if(file->eof < new_eof)
|
||||
HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
|
||||
if(file->eof < new_eof)
|
||||
HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
|
||||
#endif /* H5_CLEAR_MEMORY */
|
||||
file->mem = x;
|
||||
file->mem = x;
|
||||
|
||||
/* Update backing store, if using it */
|
||||
if(file->fd >= 0 && file->backing_store) {
|
||||
/* Update backing store, if using it and if closing */
|
||||
if(closing && (file->fd >= 0) && file->backing_store) {
|
||||
#ifdef H5_HAVE_WIN32_API
|
||||
LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */
|
||||
DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer()
|
||||
* Only used as an error code here.
|
||||
*/
|
||||
DWORD dwError; /* DWORD error code from GetLastError() */
|
||||
BOOL bError; /* Boolean error flag */
|
||||
LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */
|
||||
DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer()
|
||||
* Only used as an error code here.
|
||||
*/
|
||||
DWORD dwError; /* DWORD error code from GetLastError() */
|
||||
BOOL bError; /* Boolean error flag */
|
||||
|
||||
/* Windows uses this odd QuadPart union for 32/64-bit portability */
|
||||
li.QuadPart = (__int64)file->eoa;
|
||||
/* Windows uses this odd QuadPart union for 32/64-bit portability */
|
||||
li.QuadPart = (__int64)file->eoa;
|
||||
|
||||
/* Extend the file to make sure it's large enough.
|
||||
*
|
||||
* Since INVALID_SET_FILE_POINTER can technically be a valid return value
|
||||
* from SetFilePointer(), we also need to check GetLastError().
|
||||
*/
|
||||
dwPtrLow = SetFilePointer(file->hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
|
||||
if(INVALID_SET_FILE_POINTER == dwPtrLow) {
|
||||
dwError = GetLastError();
|
||||
if(dwError != NO_ERROR )
|
||||
HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to set file pointer")
|
||||
}
|
||||
/* Extend the file to make sure it's large enough.
|
||||
*
|
||||
* Since INVALID_SET_FILE_POINTER can technically be a valid return value
|
||||
* from SetFilePointer(), we also need to check GetLastError().
|
||||
*/
|
||||
dwPtrLow = SetFilePointer(file->hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
|
||||
if(INVALID_SET_FILE_POINTER == dwPtrLow) {
|
||||
dwError = GetLastError();
|
||||
if(dwError != NO_ERROR )
|
||||
HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to set file pointer")
|
||||
}
|
||||
|
||||
bError = SetEndOfFile(file->hFile);
|
||||
if(0 == bError)
|
||||
HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
|
||||
bError = SetEndOfFile(file->hFile);
|
||||
if(0 == bError)
|
||||
HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
|
||||
#else /* H5_HAVE_WIN32_API */
|
||||
#ifdef H5_VMS
|
||||
/* Reset seek offset to the beginning of the file, so that the file isn't
|
||||
* re-extended later. This may happen on Open VMS. */
|
||||
if(-1 == HDlseek(file->fd, (HDoff_t)0, SEEK_SET))
|
||||
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
|
||||
/* Reset seek offset to the beginning of the file, so that the file isn't
|
||||
* re-extended later. This may happen on Open VMS. */
|
||||
if(-1 == HDlseek(file->fd, (HDoff_t)0, SEEK_SET))
|
||||
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
|
||||
#endif /* H5_VMS */
|
||||
if(-1 == HDftruncate(file->fd, (HDoff_t)new_eof))
|
||||
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
|
||||
if(-1 == HDftruncate(file->fd, (HDoff_t)new_eof))
|
||||
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
|
||||
#endif /* H5_HAVE_WIN32_API */
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/* Update the eof value */
|
||||
file->eof = new_eof;
|
||||
} /* end if */
|
||||
/* Update the eof value */
|
||||
file->eof = new_eof;
|
||||
} /* end if */
|
||||
} /* end if(file->eof < file->eoa) */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5FD_core_truncate() */
|
||||
|
||||
|
@ -995,7 +995,7 @@ H5FD_family_query(const H5FD_t * _file, unsigned long *flags /* out */)
|
||||
*flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
|
||||
|
||||
/* Check for flags that are set by h5repart */
|
||||
if(file->repart_members)
|
||||
if(file && file->repart_members)
|
||||
*flags |= H5FD_FEAT_DIRTY_SBLK_LOAD; /* Mark the superblock dirty when it is loaded (so the family member sizes are rewritten) */
|
||||
} /* end if */
|
||||
|
||||
|
@ -918,7 +918,7 @@ H5FD_log_query(const H5FD_t *_file, unsigned long *flags /* out */)
|
||||
*flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
|
||||
|
||||
/* Check for flags that are set by h5repart */
|
||||
if(file->fam_to_sec2)
|
||||
if(file && file->fam_to_sec2)
|
||||
*flags |= H5FD_FEAT_IGNORE_DRVRINFO; /* Ignore the driver info when file is opened (which eliminates it) */
|
||||
} /* end if */
|
||||
|
||||
|
@ -52,6 +52,29 @@ typedef enum {
|
||||
} H5FD_file_op_t;
|
||||
|
||||
|
||||
/* Define structure to hold initial file image and other relevant information */
|
||||
typedef struct {
|
||||
void *buffer;
|
||||
size_t size;
|
||||
H5FD_file_image_callbacks_t callbacks;
|
||||
} H5FD_file_image_info_t;
|
||||
|
||||
/* Define default file image info */
|
||||
#define H5FD_DEFAULT_FILE_IMAGE_INFO { \
|
||||
/* file image buffer */ NULL, \
|
||||
/* buffer size */ 0, \
|
||||
{ /* Callbacks */ \
|
||||
/* image_malloc */ NULL, \
|
||||
/* image_memcpy */ NULL, \
|
||||
/* image_realloc */ NULL, \
|
||||
/* image_free */ NULL, \
|
||||
/* udata_copy */ NULL, \
|
||||
/* udata_free */ NULL, \
|
||||
/* udata */ NULL, \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/*****************************/
|
||||
/* Library Private Variables */
|
||||
/*****************************/
|
||||
@ -72,17 +95,14 @@ H5_DLL herr_t H5FD_sb_encode(H5FD_t *file, char *name/*out*/, uint8_t *buf);
|
||||
H5_DLL herr_t H5FD_sb_decode(H5FD_t *file, const char *name, const uint8_t *buf);
|
||||
H5_DLL void *H5FD_fapl_get(H5FD_t *file);
|
||||
H5_DLL herr_t H5FD_fapl_open(struct H5P_genplist_t *plist, hid_t driver_id, const void *driver_info);
|
||||
H5_DLL herr_t H5FD_fapl_copy(hid_t driver_id, const void *fapl, void **copied_fapl);
|
||||
H5_DLL herr_t H5FD_fapl_close(hid_t driver_id, void *fapl);
|
||||
H5_DLL herr_t H5FD_dxpl_open(struct H5P_genplist_t *plist, hid_t driver_id, const void *driver_info);
|
||||
H5_DLL herr_t H5FD_dxpl_copy(hid_t driver_id, const void *dxpl, void **copied_dxpl);
|
||||
H5_DLL herr_t H5FD_dxpl_close(hid_t driver_id, void *dxpl);
|
||||
H5_DLL hid_t H5FD_register(const void *cls, size_t size, hbool_t app_ref);
|
||||
H5_DLL H5FD_t *H5FD_open(const char *name, unsigned flags, hid_t fapl_id,
|
||||
haddr_t maxaddr);
|
||||
H5_DLL herr_t H5FD_close(H5FD_t *file);
|
||||
H5_DLL int H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2);
|
||||
H5_DLL int H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/);
|
||||
H5_DLL haddr_t H5FD_alloc(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, struct H5F_t *f,
|
||||
hsize_t size, haddr_t *align_addr, hsize_t *align_size);
|
||||
H5_DLL herr_t H5FD_free(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, struct H5F_t *f,
|
||||
|
@ -222,6 +222,19 @@ typedef enum H5F_mem_t H5FD_mem_t;
|
||||
* instead of the default H5D_ALLOC_TIME_LATE
|
||||
*/
|
||||
#define H5FD_FEAT_ALLOCATE_EARLY 0x00000200
|
||||
/*
|
||||
* Defining the H5FD_FEAT_ALLOW_FILE_IMAGE for a VFL driver means that
|
||||
* the driver is able to use a file image in the fapl as the initial
|
||||
* contents of a file.
|
||||
*/
|
||||
#define H5FD_FEAT_ALLOW_FILE_IMAGE 0x00000400
|
||||
/*
|
||||
* Defining the H5FD_FEAT_CAN_USE_FILE_IMAGE_CALLBACKS for a VFL driver
|
||||
* means that the driver is able to use callbacks to make a copy of the
|
||||
* image to store in memory.
|
||||
*/
|
||||
#define H5FD_FEAT_CAN_USE_FILE_IMAGE_CALLBACKS 0x00000800
|
||||
|
||||
|
||||
/* Forward declaration */
|
||||
typedef struct H5FD_t H5FD_t;
|
||||
@ -291,6 +304,33 @@ struct H5FD_t {
|
||||
hsize_t alignment; /* Allocation alignment */
|
||||
};
|
||||
|
||||
/* Define enum for the source of file image callbacks */
|
||||
typedef enum {
|
||||
H5FD_FILE_IMAGE_OP_NO_OP,
|
||||
H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET,
|
||||
H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY,
|
||||
H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET,
|
||||
H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE,
|
||||
H5FD_FILE_IMAGE_OP_FILE_OPEN,
|
||||
H5FD_FILE_IMAGE_OP_FILE_RESIZE,
|
||||
H5FD_FILE_IMAGE_OP_FILE_CLOSE,
|
||||
} H5FD_file_image_op_t;
|
||||
|
||||
/* Define structure to hold file image callbacks */
|
||||
typedef struct {
|
||||
void *(*image_malloc)(size_t size, H5FD_file_image_op_t file_image_op,
|
||||
void *udata);
|
||||
void *(*image_memcpy)(void *dest, const void *src, size_t size,
|
||||
H5FD_file_image_op_t file_image_op, void *udata);
|
||||
void *(*image_realloc)(void *ptr, size_t size,
|
||||
H5FD_file_image_op_t file_image_op, void *udata);
|
||||
herr_t (*image_free)(void *ptr, H5FD_file_image_op_t file_image_op,
|
||||
void *udata);
|
||||
void *(*udata_copy)(void *udata);
|
||||
herr_t (*udata_free)(void *udata);
|
||||
void *udata;
|
||||
} H5FD_file_image_callbacks_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -560,7 +560,7 @@ H5FD_sec2_query(const H5FD_t *_file, unsigned long *flags /* out */)
|
||||
*flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
|
||||
|
||||
/* Check for flags that are set by h5repart */
|
||||
if(file->fam_to_sec2)
|
||||
if(file && file->fam_to_sec2)
|
||||
*flags |= H5FD_FEAT_IGNORE_DRVRINFO; /* Ignore the driver info when file is opened (which eliminates it) */
|
||||
} /* end if */
|
||||
|
||||
|
@ -417,6 +417,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t;
|
||||
#define H5F_ACS_LATEST_FORMAT_NAME "latest_format" /* 'Use latest format version' flag */
|
||||
#define H5F_ACS_WANT_POSIX_FD_NAME "want_posix_fd" /* Internal: query the file descriptor from the core VFD, instead of the memory address */
|
||||
#define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */
|
||||
#define H5F_ACS_FILE_IMAGE_INFO_NAME "file_image_info" /* struct containing initial file image and callback info */
|
||||
|
||||
/* ======================== File Mount properties ====================*/
|
||||
#define H5F_MNT_SYM_LOCAL_NAME "local" /* Whether absolute symlinks local to file. */
|
||||
@ -528,8 +529,8 @@ H5_DLL H5F_t *H5F_get_parent(const H5F_t *f);
|
||||
H5_DLL unsigned H5F_get_nmounts(const H5F_t *f);
|
||||
H5_DLL hid_t H5F_get_access_plist(H5F_t *f, hbool_t app_ref);
|
||||
H5_DLL hid_t H5F_get_id(H5F_t *file, hbool_t app_ref);
|
||||
H5_DLL size_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref);
|
||||
H5_DLL size_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref);
|
||||
H5_DLL herr_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr);
|
||||
H5_DLL herr_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref, size_t *obj_id_count_ptr);
|
||||
|
||||
/* Functions than retrieve values set/cached from the superblock/FCPL */
|
||||
H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f);
|
||||
|
@ -192,6 +192,7 @@ H5_DLL herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist);
|
||||
H5_DLL herr_t H5Funmount(hid_t loc, const char *name);
|
||||
H5_DLL hssize_t H5Fget_freespace(hid_t file_id);
|
||||
H5_DLL herr_t H5Fget_filesize(hid_t file_id, hsize_t *size);
|
||||
H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void * buf_ptr, size_t buf_len);
|
||||
H5_DLL herr_t H5Fget_mdc_config(hid_t file_id,
|
||||
H5AC_cache_config_t * config_ptr);
|
||||
H5_DLL herr_t H5Fset_mdc_config(hid_t file_id,
|
||||
|
@ -782,7 +782,7 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_name_replace_cb
|
||||
*
|
||||
* Purpose: H5I_search callback function to replace group entry names
|
||||
* Purpose: H5I_iterate callback function to replace group entry names
|
||||
*
|
||||
* Return: Success: 0, Failure: -1
|
||||
*
|
||||
@ -1166,15 +1166,18 @@ H5G_name_replace(const H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file,
|
||||
|
||||
/* Search through group IDs */
|
||||
if(search_group)
|
||||
H5I_search(H5I_GROUP, H5G_name_replace_cb, &names, FALSE);
|
||||
if(H5I_iterate(H5I_GROUP, H5G_name_replace_cb, &names, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over groups")
|
||||
|
||||
/* Search through dataset IDs */
|
||||
if(search_dataset)
|
||||
H5I_search(H5I_DATASET, H5G_name_replace_cb, &names, FALSE);
|
||||
if(H5I_iterate(H5I_DATASET, H5G_name_replace_cb, &names, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over datasets")
|
||||
|
||||
/* Search through datatype IDs */
|
||||
if(search_datatype)
|
||||
H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names, FALSE);
|
||||
if(H5I_iterate(H5I_DATATYPE, H5G_name_replace_cb, &names, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over datatypes")
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
|
144
src/H5I.c
144
src/H5I.c
@ -108,6 +108,11 @@ typedef struct {
|
||||
H5I_id_info_t **id_list; /*pointer to an array of ptrs to IDs */
|
||||
} H5I_id_type_t;
|
||||
|
||||
typedef struct {
|
||||
H5I_search_func_t app_cb; /* Application's callback routine */
|
||||
void *app_key; /* Application's "key" (user data) */
|
||||
void *ret_obj; /* Object to return */
|
||||
} H5I_search_ud_t;
|
||||
|
||||
/*-------------------- Locally scoped variables -----------------------------*/
|
||||
|
||||
@ -127,6 +132,7 @@ H5FL_DEFINE_STATIC(H5I_id_info_t);
|
||||
|
||||
/*--------------------- Local function prototypes ---------------------------*/
|
||||
static H5I_id_info_t *H5I_find_id(hid_t id);
|
||||
static int H5I_search_cb(void *obj, hid_t id, void *udata);
|
||||
#ifdef H5I_DEBUG_OUTPUT
|
||||
static herr_t H5I_debug(H5I_type_t type);
|
||||
#endif /* H5I_DEBUG_OUTPUT */
|
||||
@ -1903,6 +1909,40 @@ done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Iis_valid() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5I_search_cb
|
||||
*
|
||||
* Purpose: Callback routine for H5Isearch, when it calls H5I_iterate.
|
||||
* Calls "user" callback search function, and then sets return
|
||||
* value, based on the result of that callback.
|
||||
*
|
||||
* Return: Success: The first object in the type for which FUNC
|
||||
* returns non-zero. NULL if FUNC returned zero
|
||||
* for every object in the type.
|
||||
* Failure: NULL
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Friday, March 30, 2012
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
H5I_search_cb(void *obj, hid_t id, void *_udata)
|
||||
{
|
||||
H5I_search_ud_t *udata = (H5I_search_ud_t *)_udata; /* User data for callback */
|
||||
int ret_value; /* Callback return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
ret_value = (*udata->app_cb)(obj, id, udata->app_key);
|
||||
if(ret_value > 0)
|
||||
udata->ret_obj = obj;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5I_search_cb() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Isearch
|
||||
@ -1931,14 +1971,27 @@ done:
|
||||
void *
|
||||
H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key)
|
||||
{
|
||||
void * ret_value; /* Return value */
|
||||
H5I_search_ud_t udata; /* Context for iteration */
|
||||
void *ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(NULL)
|
||||
|
||||
/* Check arguments */
|
||||
if(H5I_IS_LIB_TYPE(type))
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
|
||||
|
||||
ret_value = H5I_search(type, func, key, TRUE);
|
||||
/* Set up udata struct */
|
||||
udata.app_cb = func;
|
||||
udata.app_key = key;
|
||||
udata.ret_obj = NULL;
|
||||
|
||||
/* Note that H5I_iterate returns an error code. We ignore it
|
||||
* here, as we can't do anything with it without revising the API.
|
||||
*/
|
||||
H5I_iterate(type, H5I_search_cb, &udata, TRUE);
|
||||
|
||||
/* Set return value */
|
||||
ret_value = udata.ret_obj;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
@ -1946,62 +1999,71 @@ done:
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5I_search
|
||||
* Function: H5I_iterate
|
||||
*
|
||||
* Purpose: Apply function FUNC to each member of type TYPE and return a
|
||||
* pointer to the first object for which FUNC returns non-zero.
|
||||
* The FUNC should take a pointer to the object and the KEY as
|
||||
* arguments and return non-zero to terminate the search (zero
|
||||
* to continue).
|
||||
* Purpose: Apply function FUNC to each member of type TYPE (with
|
||||
* non-zero application reference count if app_ref is TRUE).
|
||||
* Stop if FUNC returns a non zero value (i.e. anything
|
||||
* other than H5_ITER_CONT).
|
||||
*
|
||||
* Limitation: Currently there is no way to start searching from where a
|
||||
* previous search left off.
|
||||
* If FUNC returns a positive value (i.e. H5_ITER_STOP),
|
||||
* return SUCCEED.
|
||||
*
|
||||
* Return: Success: The first object in the type for which FUNC
|
||||
* returns non-zero. NULL if FUNC returned zero
|
||||
* for every object in the type.
|
||||
* Failure: NULL
|
||||
* If FUNC returns a negative value (i.e. H5_ITER_ERROR),
|
||||
* return FAIL.
|
||||
*
|
||||
* The FUNC should take a pointer to the object and the
|
||||
* udata as arguments and return non-zero to terminate
|
||||
* siteration, and zero to continue.
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, February 19, 1999
|
||||
* Limitation: Currently there is no way to start the iteration from
|
||||
* where a previous iteration left off.
|
||||
*
|
||||
* Modifications: Neil Fortner
|
||||
* Wednesday, October 1, 2008
|
||||
* Added app_ref parameter. When set to TRUE, the function will only
|
||||
* operate on ids that have a nonzero application reference count.
|
||||
* Return: Success: SUCCEED
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* Monday, December 6, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
void *
|
||||
H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref)
|
||||
herr_t
|
||||
H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_ref)
|
||||
{
|
||||
H5I_id_type_t *type_ptr; /*ptr to the type */
|
||||
void *ret_value = NULL; /*return value */
|
||||
H5I_id_type_t *type_ptr; /*ptr to the type */
|
||||
herr_t ret_value = SUCCEED; /*return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(NULL)
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* Check arguments */
|
||||
if(type <= H5I_BADID || type >= H5I_next_type)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number")
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
|
||||
type_ptr = H5I_id_type_list_g[type];
|
||||
if(type_ptr == NULL || type_ptr->count <= 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type")
|
||||
|
||||
/* Only iterate through hash table if there are IDs in group */
|
||||
if(type_ptr->ids > 0) {
|
||||
H5I_id_info_t *id_ptr; /*ptr to the new ID */
|
||||
H5I_id_info_t *next_id; /*ptr to the next ID */
|
||||
unsigned i; /*counter */
|
||||
/* Only iterate through hash table if it is initialized and there are IDs in group */
|
||||
if(type_ptr && type_ptr->count > 0 && type_ptr->ids > 0) {
|
||||
unsigned u; /* Counter */
|
||||
|
||||
/* Start at the beginning of the array */
|
||||
for(i = 0; i < type_ptr->hash_size; i++) {
|
||||
id_ptr = type_ptr->id_list[i];
|
||||
for(u = 0; u < type_ptr->hash_size; u++) {
|
||||
H5I_id_info_t *id_ptr; /* Ptr to the new ID */
|
||||
|
||||
id_ptr = type_ptr->id_list[u];
|
||||
while(id_ptr) {
|
||||
next_id = id_ptr->next; /* Protect against ID being deleted in callback */
|
||||
/* (Casting away const OK -QAK) */
|
||||
if((!app_ref || id_ptr->app_count) && (*func)((void *)id_ptr->obj_ptr, id_ptr->id, key))
|
||||
/* (Casting away const OK -QAK) */
|
||||
HGOTO_DONE((void *)id_ptr->obj_ptr); /*found the item*/
|
||||
H5I_id_info_t *next_id; /* Ptr to the next ID */
|
||||
|
||||
/* Protect against ID being deleted in callback */
|
||||
next_id = id_ptr->next;
|
||||
if((!app_ref) || (id_ptr->app_count > 0)) {
|
||||
herr_t cb_ret_val; /* Callback return value */
|
||||
|
||||
/* (Casting away const OK) */
|
||||
cb_ret_val = (*func)((void *)id_ptr->obj_ptr, id_ptr->id, udata);
|
||||
if(cb_ret_val > 0)
|
||||
HGOTO_DONE(SUCCEED) /* terminate iteration early */
|
||||
else if(cb_ret_val < 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "func failed")
|
||||
} /* end if */
|
||||
id_ptr = next_id;
|
||||
} /* end while */
|
||||
} /* end for */
|
||||
@ -2009,7 +2071,7 @@ H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref)
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5I_search() */
|
||||
} /* end H5I_iterate() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
@ -62,7 +62,7 @@ H5_DLL H5I_type_t H5I_get_type(hid_t id);
|
||||
H5_DLL hid_t H5I_get_file_id(hid_t obj_id, hbool_t app_ref);
|
||||
H5_DLL void *H5I_remove(hid_t id);
|
||||
H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type);
|
||||
H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref);
|
||||
H5_DLL herr_t H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_ref);
|
||||
H5_DLL int H5I_get_ref(hid_t id, hbool_t app_ref);
|
||||
H5_DLL int H5I_inc_ref(hid_t id, hbool_t app_ref);
|
||||
H5_DLL int H5I_dec_ref(hid_t id);
|
||||
|
@ -703,18 +703,23 @@ H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* name_t
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number")
|
||||
|
||||
/* Count all opened attributes */
|
||||
num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, FALSE);
|
||||
if(H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, FALSE, &num_open_attr) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't count opened attributes")
|
||||
|
||||
/* Find out whether the attribute has been opened */
|
||||
if(num_open_attr) {
|
||||
size_t check_num_attr; /* Number of open attribute IDs */
|
||||
size_t u; /* Local index variable */
|
||||
|
||||
/* Allocate space for the attribute ID list */
|
||||
if(NULL == (attr_id_list = (hid_t *)H5MM_malloc(num_open_attr * sizeof(hid_t))))
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "unable to allocate memory for attribute ID list")
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "unable to allocate memory for attribute ID list")
|
||||
|
||||
/* Retrieve the IDs of all opened attributes */
|
||||
H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list, FALSE);
|
||||
if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list, FALSE, &check_num_attr) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get IDs of opened attributes")
|
||||
if(check_num_attr != num_open_attr)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "open attribute count mismatch")
|
||||
|
||||
/* Iterate over the attributes */
|
||||
for(u = 0; u < num_open_attr; u++) {
|
||||
|
497
src/H5Pfapl.c
497
src/H5Pfapl.c
@ -40,6 +40,7 @@
|
||||
#include "H5Fprivate.h" /* Files */
|
||||
#include "H5FDprivate.h" /* File drivers */
|
||||
#include "H5Iprivate.h" /* IDs */
|
||||
#include "H5MMprivate.h" /* Memory Management */
|
||||
#include "H5Ppkg.h" /* Property lists */
|
||||
|
||||
/* Includes needed to set as default file driver */
|
||||
@ -122,6 +123,12 @@
|
||||
/* Definition for external file cache size */
|
||||
#define H5F_ACS_EFC_SIZE_SIZE sizeof(unsigned)
|
||||
#define H5F_ACS_EFC_SIZE_DEF 0
|
||||
/* Definition of pointer to initial file image info */
|
||||
#define H5F_ACS_FILE_IMAGE_INFO_SIZE sizeof(H5FD_file_image_info_t)
|
||||
#define H5F_ACS_FILE_IMAGE_INFO_DEF H5FD_DEFAULT_FILE_IMAGE_INFO
|
||||
#define H5F_ACS_FILE_IMAGE_INFO_DEL H5P_file_image_info_del
|
||||
#define H5F_ACS_FILE_IMAGE_INFO_COPY H5P_file_image_info_copy
|
||||
#define H5F_ACS_FILE_IMAGE_INFO_CLOSE H5P_file_image_info_close
|
||||
|
||||
|
||||
/******************/
|
||||
@ -149,6 +156,10 @@ static herr_t H5P_facc_reg_prop(H5P_genclass_t *pclass);
|
||||
static herr_t H5P_facc_create(hid_t fapl_id, void *copy_data);
|
||||
static herr_t H5P_facc_copy(hid_t new_plist_t, hid_t old_plist_t, void *copy_data);
|
||||
|
||||
/* File image info property callbacks */
|
||||
static herr_t H5P_file_image_info_del(hid_t prop_id, const char *name, size_t size, void *value);
|
||||
static herr_t H5P_file_image_info_copy(const char *name, size_t size, void *value);
|
||||
static herr_t H5P_file_image_info_close(const char *name, size_t size, void *value);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@ -215,6 +226,7 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
|
||||
hbool_t latest_format = H5F_ACS_LATEST_FORMAT_DEF; /* Default setting for "use the latest version of the format" flag */
|
||||
hbool_t want_posix_fd = H5F_ACS_WANT_POSIX_FD_DEF; /* Default setting for retrieving 'handle' from core VFD */
|
||||
unsigned efc_size = H5F_ACS_EFC_SIZE_DEF; /* Default external file cache size */
|
||||
H5FD_file_image_info_t file_image_info = H5F_ACS_FILE_IMAGE_INFO_DEF; /* Default file image info and callbacks */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
@ -300,6 +312,10 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
|
||||
if(H5P_register_real(pclass, H5F_ACS_EFC_SIZE_NAME, H5F_ACS_EFC_SIZE_SIZE, &efc_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
|
||||
|
||||
/* Register the initial file image info */
|
||||
if(H5P_register_real(pclass, H5F_ACS_FILE_IMAGE_INFO_NAME, H5F_ACS_FILE_IMAGE_INFO_SIZE, &file_image_info, NULL, NULL, NULL, H5F_ACS_FILE_IMAGE_INFO_DEL, H5F_ACS_FILE_IMAGE_INFO_COPY, NULL, H5F_ACS_FILE_IMAGE_INFO_CLOSE) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5P_facc_reg_prop() */
|
||||
@ -2101,3 +2117,484 @@ done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Pget_elink_file_cache_size() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Pset_file_image
|
||||
*
|
||||
* Purpose: Sets the initial file image. Some file drivers can initialize
|
||||
* the starting data in a file from a buffer.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Jacob Gruber
|
||||
* Thurday, August 11, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len)
|
||||
{
|
||||
H5P_genplist_t *fapl; /* Property list pointer */
|
||||
H5FD_file_image_info_t image_info; /* File image info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE3("e", "i*xz", fapl_id, buf_ptr, buf_len);
|
||||
|
||||
/* validate parameters */
|
||||
if(!(((buf_ptr == NULL) && (buf_len == 0)) || ((buf_ptr != NULL) && (buf_len > 0))))
|
||||
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "inconsistant buf_ptr and buf_len");
|
||||
|
||||
/* Get the plist structure */
|
||||
if(NULL == (fapl = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
|
||||
|
||||
/* Get old image info */
|
||||
if(H5P_get(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &image_info) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get old file image pointer")
|
||||
|
||||
/* Release previous buffer, if it exists */
|
||||
if(image_info.buffer != NULL) {
|
||||
if(image_info.callbacks.image_free) {
|
||||
if(SUCCEED != image_info.callbacks.image_free(image_info.buffer, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET, image_info.callbacks.udata))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "image_free callback failed")
|
||||
} /* end if */
|
||||
else
|
||||
H5MM_xfree(image_info.buffer);
|
||||
} /* end if */
|
||||
|
||||
/* Update struct */
|
||||
if(buf_ptr) {
|
||||
/* Allocate memory */
|
||||
if(image_info.callbacks.image_malloc) {
|
||||
if(NULL == (image_info.buffer = image_info.callbacks.image_malloc(buf_len,
|
||||
H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET, image_info.callbacks.udata)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "image malloc callback failed")
|
||||
} /* end if */
|
||||
else
|
||||
if(NULL == (image_info.buffer = H5MM_malloc(buf_len)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
|
||||
|
||||
/* Copy data */
|
||||
if(image_info.callbacks.image_memcpy) {
|
||||
if(image_info.buffer != image_info.callbacks.image_memcpy(image_info.buffer,
|
||||
buf_ptr, buf_len, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET,
|
||||
image_info.callbacks.udata))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "image_memcpy callback failed")
|
||||
} /* end if */
|
||||
else
|
||||
HDmemcpy(image_info.buffer, buf_ptr, buf_len);
|
||||
} /* end if */
|
||||
else
|
||||
image_info.buffer = NULL;
|
||||
|
||||
image_info.size = buf_len;
|
||||
|
||||
/* Set values */
|
||||
if(H5P_set(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &image_info) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file image info")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Pset_file_image() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Pget_file_image
|
||||
*
|
||||
* Purpose: If the file image exists and buf_ptr_ptr is not NULL,
|
||||
* allocate a buffer of the correct size, copy the image into
|
||||
* the new buffer, and return the buffer to the caller in
|
||||
* *buf_ptr_ptr. Do this using the file image callbacks
|
||||
* if defined.
|
||||
*
|
||||
* NB: It is the responsibility of the caller to free the
|
||||
* buffer whose address is returned in *buf_ptr_ptr. Do
|
||||
* this using free if the file image callbacks are not
|
||||
* defined, or with whatever method is appropriate if
|
||||
* the callbacks are defined.
|
||||
*
|
||||
* If buf_ptr_ptr is not NULL, and no image exists, set
|
||||
* *buf_ptr_ptr to NULL.
|
||||
*
|
||||
* If buf_len_ptr is not NULL, set *buf_len_ptr equal
|
||||
* to the length of the file image if it exists, and
|
||||
* to 0 if it does not.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Jacob Gruber
|
||||
* Thurday, August 11, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_len_ptr)
|
||||
{
|
||||
H5P_genplist_t *fapl; /* Property list pointer */
|
||||
H5FD_file_image_info_t image_info; /* File image info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE3("e", "i**x*z", fapl_id, buf_ptr_ptr, buf_len_ptr);
|
||||
|
||||
/* Get the plist structure */
|
||||
if(NULL == (fapl = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
|
||||
|
||||
/* Get values */
|
||||
if(H5P_get(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &image_info) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file image info")
|
||||
|
||||
/* verify file image field consistancy */
|
||||
HDassert(((image_info.buffer != NULL) && (image_info.size > 0)) ||
|
||||
((image_info.buffer == NULL) && (image_info.size == 0)));
|
||||
|
||||
/* Set output size */
|
||||
if(buf_len_ptr != NULL)
|
||||
*buf_len_ptr = image_info.size;
|
||||
|
||||
/* Duplicate the image if desired, using callbacks if available */
|
||||
if(buf_ptr_ptr != NULL) {
|
||||
void * copy_ptr = NULL; /* Copy of memory image */
|
||||
|
||||
if(image_info.buffer != NULL) {
|
||||
/* Allocate memory */
|
||||
if(image_info.callbacks.image_malloc) {
|
||||
if(NULL == (copy_ptr = image_info.callbacks.image_malloc(image_info.size,
|
||||
H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET, image_info.callbacks.udata)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "image malloc callback failed")
|
||||
} /* end if */
|
||||
else
|
||||
if(NULL == (copy_ptr = H5MM_malloc(image_info.size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate copy")
|
||||
|
||||
/* Copy data */
|
||||
if(image_info.callbacks.image_memcpy) {
|
||||
if(copy_ptr != image_info.callbacks.image_memcpy(copy_ptr, image_info.buffer,
|
||||
image_info.size, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET,
|
||||
image_info.callbacks.udata))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "image_memcpy callback failed")
|
||||
} /* end if */
|
||||
else
|
||||
HDmemcpy(copy_ptr, image_info.buffer, image_info.size);
|
||||
} /* end if */
|
||||
|
||||
*buf_ptr_ptr = copy_ptr;
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Pget_file_image */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Pset_file_image_callbacks
|
||||
*
|
||||
* Purpose: Sets the callbacks for file images. Some file drivers allow
|
||||
* the use of user-defined callbacks for allocating, freeing and
|
||||
* copying the drivers internal buffer, potentially allowing a
|
||||
* clever user to do optimizations such as avoiding large mallocs
|
||||
* and memcpys or to perform detailed logging.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Jacob Gruber
|
||||
* Thurday, August 11, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Pset_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr)
|
||||
{
|
||||
H5P_genplist_t *fapl; /* Property list pointer */
|
||||
H5FD_file_image_info_t info; /* File image info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE2("e", "i*x", fapl_id, callbacks_ptr);
|
||||
|
||||
/* Get the plist structure */
|
||||
if(NULL == (fapl = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
|
||||
|
||||
/* Get old info */
|
||||
if(H5P_get(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &info) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get old file image info")
|
||||
|
||||
/* verify file image field consistancy */
|
||||
HDassert(((info.buffer != NULL) && (info.size > 0)) ||
|
||||
((info.buffer == NULL) && (info.size == 0)));
|
||||
|
||||
/* Make sure a file image hasn't already been set */
|
||||
if(info.buffer != NULL || info.size > 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_SETDISALLOWED, FAIL, "setting callbacks when an image is already set is forbidden. It could cause memory leaks.")
|
||||
|
||||
/* verify that callbacks_ptr is not NULL */
|
||||
if(NULL == callbacks_ptr)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL callbacks_ptr")
|
||||
|
||||
/* Make sure udata callbacks are going to be set if udata is going to be set */
|
||||
if(callbacks_ptr->udata)
|
||||
if(callbacks_ptr->udata_copy == NULL || callbacks_ptr->udata_free == NULL)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_SETDISALLOWED, FAIL, "udata callbacks must be set if udata is set")
|
||||
|
||||
/* Release old udata if it exists */
|
||||
if(info.callbacks.udata != NULL) {
|
||||
HDassert(info.callbacks.udata_free);
|
||||
if(info.callbacks.udata_free(info.callbacks.udata) < 0)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "udata_free callback failed")
|
||||
} /* end if */
|
||||
|
||||
/* Update struct */
|
||||
info.callbacks = *callbacks_ptr;
|
||||
|
||||
if(callbacks_ptr->udata) {
|
||||
HDassert(callbacks_ptr->udata_copy);
|
||||
HDassert(callbacks_ptr->udata_free);
|
||||
if((info.callbacks.udata = callbacks_ptr->udata_copy(callbacks_ptr->udata)) == NULL)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't copy the suppplied udata")
|
||||
} /* end if */
|
||||
|
||||
/* Set values */
|
||||
if(H5P_set(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &info) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file image info")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Pset_file_image_callbacks() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Pget_file_image_callbacks
|
||||
*
|
||||
* Purpose: Sets the callbacks for file images. Some file drivers allow
|
||||
* the use of user-defined callbacks for allocating, freeing and
|
||||
* copying the drivers internal buffer, potentially allowing a
|
||||
* clever user to do optimizations such as avoiding large mallocs
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Jacob Gruber
|
||||
* Thurday, August 11, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Pget_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr)
|
||||
{
|
||||
H5P_genplist_t *fapl; /* Property list pointer */
|
||||
H5FD_file_image_info_t info; /* File image info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE2("e", "i*x", fapl_id, callbacks_ptr);
|
||||
|
||||
/* Get the plist structure */
|
||||
if(NULL == (fapl = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
|
||||
|
||||
/* Get old info */
|
||||
if(H5P_get(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &info) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file image info")
|
||||
|
||||
/* verify file image field consistancy */
|
||||
HDassert(((info.buffer != NULL) && (info.size > 0)) ||
|
||||
((info.buffer == NULL) && (info.size == 0)));
|
||||
|
||||
/* verify that callbacks_ptr is not NULL */
|
||||
if(NULL == callbacks_ptr)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL callbacks_ptr")
|
||||
|
||||
/* Transfer values to parameters */
|
||||
*callbacks_ptr = info.callbacks;
|
||||
|
||||
/* Copy udata if it exists */
|
||||
if(info.callbacks.udata != NULL) {
|
||||
HDassert(info.callbacks.udata_copy);
|
||||
if((callbacks_ptr->udata = info.callbacks.udata_copy(info.callbacks.udata)) == 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't copy udata")
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Pget_file_image_callbacks() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5P_file_image_info_del
|
||||
*
|
||||
* Purpose: Delete callback for the file image info property, called
|
||||
* when the property is deleted from the plist. The buffer
|
||||
* and udata may need to be freed, possibly using their
|
||||
* respective callbacks so the default free won't work.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Jacob Gruber
|
||||
* Thurday, August 11, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5P_file_image_info_del(hid_t UNUSED prop_id, const char UNUSED *name, size_t UNUSED size, void *value)
|
||||
{
|
||||
H5FD_file_image_info_t info; /* Image info struct */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
if(value) {
|
||||
info = *(H5FD_file_image_info_t *)value;
|
||||
|
||||
/* verify file image field consistancy */
|
||||
HDassert(((info.buffer != NULL) && (info.size > 0)) ||
|
||||
((info.buffer == NULL) && (info.size == 0)));
|
||||
|
||||
if(info.buffer && info.size > 0) {
|
||||
/* Free buffer */
|
||||
if(info.callbacks.image_free) {
|
||||
if(info.callbacks.image_free(info.buffer, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE, info.callbacks.udata) < 0)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "image_free callback failed")
|
||||
} /* end if */
|
||||
else
|
||||
free(info.buffer);
|
||||
} /* end if */
|
||||
|
||||
/* Free udata if it exists */
|
||||
if(info.callbacks.udata) {
|
||||
if(NULL == info.callbacks.udata_free)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_free not defined")
|
||||
|
||||
if(info.callbacks.udata_free(info.callbacks.udata) < 0)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "udata_free callback failed")
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5P_file_image_info_del() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5P_file_image_info_copy
|
||||
*
|
||||
* Purpose: Copy callback for the file image info property. The buffer
|
||||
* and udata may need to be copied, possibly using their
|
||||
* respective callbacks so the default copy won't work.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Jacob Gruber
|
||||
* Thurday, August 11, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5P_file_image_info_copy(const char UNUSED *name, size_t UNUSED size, void *value)
|
||||
{
|
||||
H5FD_file_image_info_t *info; /* Image info struct */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
if(value) {
|
||||
info = (H5FD_file_image_info_t *)value;
|
||||
|
||||
/* verify file image field consistancy */
|
||||
HDassert(((info->buffer != NULL) && (info->size > 0)) ||
|
||||
((info->buffer == NULL) && (info->size == 0)));
|
||||
|
||||
if(info->buffer && info->size > 0) {
|
||||
void *old_buffer; /* Pointer to old image buffer */
|
||||
|
||||
/* Store the old buffer */
|
||||
old_buffer = info->buffer;
|
||||
|
||||
/* Allocate new buffer */
|
||||
if(info->callbacks.image_malloc) {
|
||||
if(NULL == (info->buffer = info->callbacks.image_malloc(info->size,
|
||||
H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY, info->callbacks.udata)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "image malloc callback failed")
|
||||
} /* end if */
|
||||
else {
|
||||
if(NULL == (info->buffer = H5MM_malloc(info->size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
|
||||
} /* end else */
|
||||
|
||||
/* Copy data to new buffer */
|
||||
if(info->callbacks.image_memcpy) {
|
||||
if(info->buffer != info->callbacks.image_memcpy(info->buffer, old_buffer,
|
||||
info->size, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY,
|
||||
info->callbacks.udata))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "image_memcpy callback failed")
|
||||
} /* end if */
|
||||
else
|
||||
HDmemcpy(info->buffer, old_buffer, info->size);
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/* Copy udata if it exists */
|
||||
if(info->callbacks.udata) {
|
||||
void *old_udata = info->callbacks.udata;
|
||||
|
||||
if(NULL == info->callbacks.udata_copy)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_copy not defined")
|
||||
|
||||
info->callbacks.udata = info->callbacks.udata_copy(old_udata);
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5P_file_image_info_copy() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5P_file_image_info_close
|
||||
*
|
||||
* Purpose: Close callback for the file image info property. The buffer
|
||||
* and udata may need to be freed, possibly using their
|
||||
* respective callbacks so the standard free won't work.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Jacob Gruber
|
||||
* Thurday, August 11, 2011
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5P_file_image_info_close(const char UNUSED *name, size_t UNUSED size, void *value)
|
||||
{
|
||||
H5FD_file_image_info_t info; /* Image info struct */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
if(value) {
|
||||
info = *(H5FD_file_image_info_t *)value;
|
||||
|
||||
if(info.buffer != NULL && info.size > 0) {
|
||||
/* Free buffer */
|
||||
if(info.callbacks.image_free) {
|
||||
if(info.callbacks.image_free(info.buffer, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE,
|
||||
info.callbacks.udata) < 0)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "image_free callback failed")
|
||||
} /* end if */
|
||||
else
|
||||
H5MM_xfree(info.buffer);
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/* Free udata if it exists */
|
||||
if(info.callbacks.udata) {
|
||||
if(NULL == info.callbacks.udata_free)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_free not defined")
|
||||
if(info.callbacks.udata_free(info.callbacks.udata) < 0)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "udata_free callback failed")
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5P_file_image_info_close() */
|
||||
|
||||
|
54
src/H5Pint.c
54
src/H5Pint.c
@ -51,6 +51,7 @@
|
||||
typedef struct {
|
||||
const H5P_genclass_t *parent; /* Pointer to parent class */
|
||||
const char *name; /* Pointer to name to check */
|
||||
H5P_genclass_t *new_class; /* Pointer to class during path traversal */
|
||||
} H5P_check_class_t;
|
||||
|
||||
|
||||
@ -1358,11 +1359,11 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5P_check_class
|
||||
H5P_open_class_path_cb
|
||||
PURPOSE
|
||||
Internal callback routine to check for duplicated names in parent class.
|
||||
USAGE
|
||||
int H5P_check_class(obj, id, key)
|
||||
int H5P_open_class_path_cb(obj, id, key)
|
||||
H5P_genclass_t *obj; IN: Pointer to class
|
||||
hid_t id; IN: ID of object being looked at
|
||||
const void *key; IN: Pointer to information used to compare
|
||||
@ -1378,27 +1379,29 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
static int
|
||||
H5P_check_class(void *_obj, hid_t UNUSED id, void *_key)
|
||||
H5P_open_class_path_cb(void *_obj, hid_t UNUSED id, void *_key)
|
||||
{
|
||||
H5P_genclass_t *obj=(H5P_genclass_t *)_obj; /* Pointer to the class for this ID */
|
||||
const H5P_check_class_t *key=(const H5P_check_class_t *)_key; /* Pointer to key information for comparison */
|
||||
int ret_value=0; /* Return value */
|
||||
H5P_genclass_t *obj = (H5P_genclass_t *)_obj; /* Pointer to the class for this ID */
|
||||
H5P_check_class_t *key = (H5P_check_class_t *)_key; /* Pointer to key information for comparison */
|
||||
int ret_value = 0; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOERR
|
||||
|
||||
HDassert(obj);
|
||||
HDassert(H5I_GENPROP_CLS==H5I_get_type(id));
|
||||
HDassert(H5I_GENPROP_CLS == H5I_get_type(id));
|
||||
HDassert(key);
|
||||
|
||||
/* Check if the class object has the same parent as the new class */
|
||||
if(obj->parent==key->parent) {
|
||||
if(obj->parent == key->parent) {
|
||||
/* Check if they have the same name */
|
||||
if(HDstrcmp(obj->name,key->name)==0)
|
||||
ret_value=1; /* Indicate a match */
|
||||
if(HDstrcmp(obj->name, key->name) == 0) {
|
||||
key->new_class = obj;
|
||||
ret_value = 1; /* Indicate a match */
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5P_check_class() */
|
||||
} /* end H5P_open_class_path_cb() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
@ -4555,8 +4558,8 @@ H5P_open_class_path(const char *path)
|
||||
char *curr_name; /* Pointer to current component of path name */
|
||||
char *delimit; /* Pointer to path delimiter during traversal */
|
||||
H5P_genclass_t *curr_class; /* Pointer to class during path traversal */
|
||||
H5P_genclass_t *ret_value; /* Return value */
|
||||
H5P_check_class_t check_info; /* Structure to hold the information for checking duplicate names */
|
||||
H5P_genclass_t *ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
@ -4569,20 +4572,24 @@ H5P_open_class_path(const char *path)
|
||||
/* Find the generic property class with this full path */
|
||||
curr_name = tmp_path;
|
||||
curr_class = NULL;
|
||||
while((delimit=HDstrchr(curr_name,'/'))!=NULL) {
|
||||
while(NULL != (delimit = HDstrchr(curr_name, '/'))) {
|
||||
/* Change the delimiter to terminate the string */
|
||||
*delimit='\0';
|
||||
*delimit = '\0';
|
||||
|
||||
/* Set up the search structure */
|
||||
check_info.parent=curr_class;
|
||||
check_info.name=curr_name;
|
||||
check_info.parent = curr_class;
|
||||
check_info.name = curr_name;
|
||||
check_info.new_class = NULL;
|
||||
|
||||
/* Find the class with this name & parent by iterating over the open classes */
|
||||
if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE)))
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
|
||||
if(H5I_iterate(H5I_GENPROP_CLS, H5P_open_class_path_cb, &check_info, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_BADITER, NULL, "can't iterate over classes")
|
||||
else if(NULL == check_info.new_class)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
|
||||
|
||||
/* Advance the pointer in the path to the start of the next component */
|
||||
curr_name=delimit+1;
|
||||
curr_class = check_info.new_class;
|
||||
curr_name = delimit + 1;
|
||||
} /* end while */
|
||||
|
||||
/* Should be pointing to the last component in the path name now... */
|
||||
@ -4590,13 +4597,16 @@ H5P_open_class_path(const char *path)
|
||||
/* Set up the search structure */
|
||||
check_info.parent = curr_class;
|
||||
check_info.name = curr_name;
|
||||
check_info.new_class = NULL;
|
||||
|
||||
/* Find the class with this name & parent by iterating over the open classes */
|
||||
if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE)))
|
||||
if(H5I_iterate(H5I_GENPROP_CLS, H5P_open_class_path_cb, &check_info, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_BADITER, NULL, "can't iterate over classes")
|
||||
else if(NULL == check_info.new_class)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
|
||||
|
||||
/* Copy it */
|
||||
if(NULL == (ret_value = H5P_copy_pclass(curr_class)))
|
||||
if(NULL == (ret_value = H5P_copy_pclass(check_info.new_class)))
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL, "can't copy property class")
|
||||
|
||||
done:
|
||||
@ -4604,7 +4614,7 @@ done:
|
||||
H5MM_xfree(tmp_path);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5P_open_class_path() */
|
||||
} /* H5P_open_class_path() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
@ -322,6 +322,12 @@ H5_DLL herr_t H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low,
|
||||
H5F_libver_t *high);
|
||||
H5_DLL herr_t H5Pset_elink_file_cache_size(hid_t plist_id, unsigned efc_size);
|
||||
H5_DLL herr_t H5Pget_elink_file_cache_size(hid_t plist_id, unsigned *efc_size);
|
||||
H5_DLL herr_t H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len);
|
||||
H5_DLL herr_t H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_len_ptr);
|
||||
H5_DLL herr_t H5Pset_file_image_callbacks(hid_t fapl_id,
|
||||
H5FD_file_image_callbacks_t *callbacks_ptr);
|
||||
H5_DLL herr_t H5Pget_file_image_callbacks(hid_t fapl_id,
|
||||
H5FD_file_image_callbacks_t *callbacks_ptr);
|
||||
|
||||
/* Dataset creation property list (DCPL) routines */
|
||||
H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout);
|
||||
|
@ -1449,7 +1449,8 @@ H5T_term_interface(void)
|
||||
H5T_g.asoft = 0;
|
||||
|
||||
/* Unlock all datatypes, then free them */
|
||||
H5I_search(H5I_DATATYPE, H5T_unlock_cb, NULL, FALSE);
|
||||
/* note that we are ignoring the return value from H5I_iterate() */
|
||||
H5I_iterate(H5I_DATATYPE, H5T_unlock_cb, NULL, FALSE);
|
||||
H5I_dec_type_ref(H5I_DATATYPE);
|
||||
|
||||
/* Reset all the datatype IDs */
|
||||
|
@ -220,6 +220,7 @@ MINOR, DSPACE, H5E_CANTCOMPARE, Can't compare objects
|
||||
MINOR, PLIST, H5E_CANTGET, Can't get value
|
||||
MINOR, PLIST, H5E_CANTSET, Can't set value
|
||||
MINOR, PLIST, H5E_DUPCLASS, Duplicate class name in parent class
|
||||
MINOR, PLIST, H5E_SETDISALLOWED, Disallowed operation
|
||||
|
||||
# Link errors
|
||||
MINOR, LINK, H5E_TRAVERSE, Link traversal failure
|
||||
|
@ -42,7 +42,7 @@ TEST_PROG= testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \
|
||||
big mtime fillval mount flush1 flush2 app_ref enum \
|
||||
set_extent ttsafe \
|
||||
getname vfd ntypes dangle dtransform reserved cross_read \
|
||||
freespace mf farray earray btree2 fheap
|
||||
freespace mf farray earray btree2 fheap file_image
|
||||
|
||||
# List programs to be built when testing here. error_test and err_compat are
|
||||
# built at the same time as the other tests, but executed by testerror.sh.
|
||||
@ -63,7 +63,7 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version testmeta links_
|
||||
BUILD_ALL_PROGS=gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_new_array \
|
||||
gen_new_fill gen_new_group gen_new_mtime gen_new_super gen_noencoder \
|
||||
gen_nullspace gen_udlinks space_overflow gen_filespace gen_specmetaread \
|
||||
gen_sizes_lheap
|
||||
gen_sizes_lheap gen_file_image
|
||||
|
||||
if BUILD_ALL_CONDITIONAL
|
||||
noinst_PROGRAMS=$(BUILD_ALL_PROGS)
|
||||
|
@ -92,7 +92,8 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \
|
||||
ttsafe$(EXEEXT) getname$(EXEEXT) vfd$(EXEEXT) ntypes$(EXEEXT) \
|
||||
dangle$(EXEEXT) dtransform$(EXEEXT) reserved$(EXEEXT) \
|
||||
cross_read$(EXEEXT) freespace$(EXEEXT) mf$(EXEEXT) \
|
||||
farray$(EXEEXT) earray$(EXEEXT) btree2$(EXEEXT) fheap$(EXEEXT)
|
||||
farray$(EXEEXT) earray$(EXEEXT) btree2$(EXEEXT) fheap$(EXEEXT) \
|
||||
file_image$(EXEEXT)
|
||||
am__EXEEXT_2 = gen_bad_ohdr$(EXEEXT) gen_bogus$(EXEEXT) \
|
||||
gen_cross$(EXEEXT) gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \
|
||||
gen_new_array$(EXEEXT) gen_new_fill$(EXEEXT) \
|
||||
@ -100,7 +101,7 @@ am__EXEEXT_2 = gen_bad_ohdr$(EXEEXT) gen_bogus$(EXEEXT) \
|
||||
gen_new_super$(EXEEXT) gen_noencoder$(EXEEXT) \
|
||||
gen_nullspace$(EXEEXT) gen_udlinks$(EXEEXT) \
|
||||
space_overflow$(EXEEXT) gen_filespace$(EXEEXT) \
|
||||
gen_specmetaread$(EXEEXT) gen_sizes_lheap$(EXEEXT)
|
||||
gen_specmetaread$(EXEEXT) gen_sizes_lheap$(EXEEXT) gen_file_image$(EXEEXT)
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
accum_SOURCES = accum.c
|
||||
accum_OBJECTS = accum.$(OBJEXT)
|
||||
@ -198,6 +199,10 @@ fheap_SOURCES = fheap.c
|
||||
fheap_OBJECTS = fheap.$(OBJEXT)
|
||||
fheap_LDADD = $(LDADD)
|
||||
fheap_DEPENDENCIES = libh5test.la $(LIBHDF5)
|
||||
file_image_SOURCES = file_image.c
|
||||
file_image_OBJECTS = file_image.$(OBJEXT)
|
||||
file_image_LDADD = $(LDADD)
|
||||
file_image_DEPENDENCIES = libh5test.la $(LIBHDF5)
|
||||
fillval_SOURCES = fillval.c
|
||||
fillval_OBJECTS = fillval.$(OBJEXT)
|
||||
fillval_LDADD = $(LDADD)
|
||||
@ -282,6 +287,10 @@ gen_udlinks_SOURCES = gen_udlinks.c
|
||||
gen_udlinks_OBJECTS = gen_udlinks.$(OBJEXT)
|
||||
gen_udlinks_LDADD = $(LDADD)
|
||||
gen_udlinks_DEPENDENCIES = libh5test.la $(LIBHDF5)
|
||||
gen_file_image_SOURCES = gen_file_image.c
|
||||
gen_file_image_OBJECTS = gen_file_image.$(OBJEXT)
|
||||
gen_file_image_LDADD = $(LDADD)
|
||||
gen_file_image_DEPENDENCIES = libh5test.la $(LIBHDF5)
|
||||
getname_SOURCES = getname.c
|
||||
getname_OBJECTS = getname.$(OBJEXT)
|
||||
getname_LDADD = $(LDADD)
|
||||
@ -418,31 +427,32 @@ SOURCES = $(libh5test_la_SOURCES) accum.c app_ref.c big.c bittests.c \
|
||||
btree2.c cache.c cache_api.c cache_tagging.c cmpd_dset.c \
|
||||
cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c \
|
||||
earray.c efc.c enum.c err_compat.c error_test.c extend.c \
|
||||
external.c farray.c fheap.c fillval.c filter_fail.c flush1.c \
|
||||
flush2.c freespace.c gen_bad_ohdr.c gen_bogus.c gen_cross.c \
|
||||
gen_deflate.c gen_filespace.c gen_filters.c gen_new_array.c \
|
||||
gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c \
|
||||
gen_noencoder.c gen_nullspace.c gen_sizes_lheap.c \
|
||||
gen_specmetaread.c gen_udlinks.c getname.c gheap.c hyperslab.c \
|
||||
istore.c lheap.c links.c links_env.c mf.c mount.c mtime.c \
|
||||
ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \
|
||||
space_overflow.c stab.c tcheck_version.c $(testhdf5_SOURCES) \
|
||||
testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
|
||||
DIST_SOURCES = $(libh5test_la_SOURCES) accum.c app_ref.c big.c \
|
||||
bittests.c btree2.c cache.c cache_api.c cache_tagging.c \
|
||||
cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c \
|
||||
dtransform.c dtypes.c earray.c efc.c enum.c err_compat.c \
|
||||
error_test.c extend.c external.c farray.c fheap.c fillval.c \
|
||||
external.c farray.c fheap.c file_image.c fillval.c \
|
||||
filter_fail.c flush1.c flush2.c freespace.c gen_bad_ohdr.c \
|
||||
gen_bogus.c gen_cross.c gen_deflate.c gen_filespace.c \
|
||||
gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c \
|
||||
gen_new_mtime.c gen_new_super.c gen_noencoder.c \
|
||||
gen_nullspace.c gen_sizes_lheap.c gen_specmetaread.c \
|
||||
gen_udlinks.c getname.c gheap.c hyperslab.c istore.c lheap.c \
|
||||
gen_udlinks.c gen_file_image.c getname.c gheap.c hyperslab.c istore.c lheap.c \
|
||||
links.c links_env.c mf.c mount.c mtime.c ntypes.c objcopy.c \
|
||||
ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c \
|
||||
tcheck_version.c $(testhdf5_SOURCES) testmeta.c \
|
||||
$(ttsafe_SOURCES) unlink.c vfd.c
|
||||
DIST_SOURCES = $(libh5test_la_SOURCES) accum.c app_ref.c big.c \
|
||||
bittests.c btree2.c cache.c cache_api.c cache_tagging.c \
|
||||
cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c \
|
||||
dtransform.c dtypes.c earray.c efc.c enum.c err_compat.c \
|
||||
error_test.c extend.c external.c farray.c fheap.c file_image.c \
|
||||
fillval.c filter_fail.c flush1.c flush2.c freespace.c \
|
||||
gen_bad_ohdr.c gen_bogus.c gen_cross.c gen_deflate.c \
|
||||
gen_filespace.c gen_filters.c gen_new_array.c gen_new_fill.c \
|
||||
gen_new_group.c gen_new_mtime.c gen_new_super.c \
|
||||
gen_noencoder.c gen_nullspace.c gen_sizes_lheap.c \
|
||||
gen_specmetaread.c gen_udlinks.c gen_file_image.c getname.c gheap.c hyperslab.c \
|
||||
istore.c lheap.c links.c links_env.c mf.c mount.c mtime.c \
|
||||
ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \
|
||||
space_overflow.c stab.c tcheck_version.c $(testhdf5_SOURCES) \
|
||||
testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__tty_colors = \
|
||||
@ -778,7 +788,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \
|
||||
big mtime fillval mount flush1 flush2 app_ref enum \
|
||||
set_extent ttsafe \
|
||||
getname vfd ntypes dangle dtransform reserved cross_read \
|
||||
freespace mf farray earray btree2 fheap
|
||||
freespace mf farray earray btree2 fheap file_image
|
||||
|
||||
|
||||
# These programs generate test files for the tests. They don't need to be
|
||||
@ -791,7 +801,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \
|
||||
BUILD_ALL_PROGS = gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_new_array \
|
||||
gen_new_fill gen_new_group gen_new_mtime gen_new_super gen_noencoder \
|
||||
gen_nullspace gen_udlinks space_overflow gen_filespace gen_specmetaread \
|
||||
gen_sizes_lheap
|
||||
gen_sizes_lheap gen_file_image
|
||||
|
||||
|
||||
# The libh5test library provides common support code for the tests.
|
||||
@ -978,6 +988,9 @@ farray$(EXEEXT): $(farray_OBJECTS) $(farray_DEPENDENCIES)
|
||||
fheap$(EXEEXT): $(fheap_OBJECTS) $(fheap_DEPENDENCIES)
|
||||
@rm -f fheap$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(fheap_OBJECTS) $(fheap_LDADD) $(LIBS)
|
||||
file_image$(EXEEXT): $(file_image_OBJECTS) $(file_image_DEPENDENCIES)
|
||||
@rm -f file_image$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(file_image_OBJECTS) $(file_image_LDADD) $(LIBS)
|
||||
fillval$(EXEEXT): $(fillval_OBJECTS) $(fillval_DEPENDENCIES)
|
||||
@rm -f fillval$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(fillval_OBJECTS) $(fillval_LDADD) $(LIBS)
|
||||
@ -1041,6 +1054,9 @@ gen_specmetaread$(EXEEXT): $(gen_specmetaread_OBJECTS) $(gen_specmetaread_DEPEND
|
||||
gen_udlinks$(EXEEXT): $(gen_udlinks_OBJECTS) $(gen_udlinks_DEPENDENCIES)
|
||||
@rm -f gen_udlinks$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(gen_udlinks_OBJECTS) $(gen_udlinks_LDADD) $(LIBS)
|
||||
gen_file_image$(EXEEXT): $(gen_file_image_OBJECTS) $(gen_file_image_DEPENDENCIES)
|
||||
@rm -f gen_file_image$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(gen_file_image_OBJECTS) $(gen_file_image_LDADD) $(LIBS)
|
||||
getname$(EXEEXT): $(getname_OBJECTS) $(getname_DEPENDENCIES)
|
||||
@rm -f getname$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(getname_OBJECTS) $(getname_LDADD) $(LIBS)
|
||||
@ -1145,6 +1161,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/external.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farray.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fheap.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_image.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fillval.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter_fail.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush1.Po@am__quote@
|
||||
@ -1166,6 +1183,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_sizes_lheap.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_specmetaread.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_udlinks.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_file_image.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getname.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gheap.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5test.Plo@am__quote@
|
||||
|
1335
test/file_image.c
Normal file
1335
test/file_image.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test/file_image_core_test.h5
Normal file
BIN
test/file_image_core_test.h5
Normal file
Binary file not shown.
91
test/gen_file_image.c
Normal file
91
test/gen_file_image.c
Normal file
@ -0,0 +1,91 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*
|
||||
* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
|
||||
* Friday, March 30, 2012
|
||||
*
|
||||
* Purpose: Create a simple file for use with the file image tests.
|
||||
*
|
||||
*/
|
||||
#include "hdf5.h"
|
||||
|
||||
#define TESTFILE "file_image_core_test.h5"
|
||||
|
||||
/* 2-D dataset with fixed dimensions */
|
||||
#define SPACE_RANK 2
|
||||
#define SPACE_DIM1 128
|
||||
#define SPACE_DIM2 32
|
||||
|
||||
/* Dataset data */
|
||||
int data[SPACE_DIM1][SPACE_DIM2];
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Return: Success:
|
||||
*
|
||||
* Failure:
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Friday, March 30, 2012
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
hid_t file, space, dset;
|
||||
hsize_t dims[SPACE_RANK] = {SPACE_DIM1, SPACE_DIM2};
|
||||
size_t i, j; /* Local index variables */
|
||||
|
||||
/* Initialize the data */
|
||||
for(i = 0; i < SPACE_DIM1; i++)
|
||||
for(j = 0; j < SPACE_DIM2; j++)
|
||||
data[i][j] = (int)(j % 5);
|
||||
|
||||
/* Create the file */
|
||||
file = H5Fcreate(TESTFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
||||
if(file < 0)
|
||||
printf("file < 0!\n");
|
||||
|
||||
/* Create the dataspace */
|
||||
space = H5Screate_simple(SPACE_RANK, dims, NULL);
|
||||
if(space < 0)
|
||||
printf("space < 0!\n");
|
||||
|
||||
/* Create the compressed dataset */
|
||||
dset = H5Dcreate2(file, "Dataset1", H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
|
||||
if(dset < 0)
|
||||
printf("dset < 0!\n");
|
||||
|
||||
/* Write the data to the dataset */
|
||||
if(H5Dwrite(dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0)
|
||||
printf("H5Dwrite() failed!\n");
|
||||
|
||||
/* Close everything */
|
||||
if(H5Dclose(dset) < 0)
|
||||
printf("H5Dclose() failed!\n");
|
||||
if(H5Sclose(space) < 0)
|
||||
printf("H5Sclose() failed!\n");
|
||||
if(H5Fclose(file) < 0)
|
||||
printf("H5Fclose() failed!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ TEST_SCRIPT_PARA=testph5.sh
|
||||
check_PROGRAMS = $(TEST_PROG_PARA)
|
||||
check_SCRIPTS= $(TEST_SCRIPT)
|
||||
|
||||
testphdf5_SOURCES=testphdf5.c t_dset.c t_file.c t_mdset.c t_ph5basic.c \
|
||||
t_coll_chunk.c t_span_tree.c t_chunk_alloc.c t_filter_read.c
|
||||
testphdf5_SOURCES=testphdf5.c t_dset.c t_file.c t_file_image.c t_mdset.c \
|
||||
t_ph5basic.c t_coll_chunk.c t_span_tree.c t_chunk_alloc.c t_filter_read.c
|
||||
|
||||
# The tests all depend on the hdf5 library and the test library
|
||||
LDADD = $(LIBH5TEST) $(LIBHDF5)
|
||||
|
@ -95,9 +95,10 @@ t_shapesame_OBJECTS = t_shapesame.$(OBJEXT)
|
||||
t_shapesame_LDADD = $(LDADD)
|
||||
t_shapesame_DEPENDENCIES = $(LIBH5TEST) $(LIBHDF5)
|
||||
am_testphdf5_OBJECTS = testphdf5.$(OBJEXT) t_dset.$(OBJEXT) \
|
||||
t_file.$(OBJEXT) t_mdset.$(OBJEXT) t_ph5basic.$(OBJEXT) \
|
||||
t_coll_chunk.$(OBJEXT) t_span_tree.$(OBJEXT) \
|
||||
t_chunk_alloc.$(OBJEXT) t_filter_read.$(OBJEXT)
|
||||
t_file.$(OBJEXT) t_file_image.$(OBJEXT) t_mdset.$(OBJEXT) \
|
||||
t_ph5basic.$(OBJEXT) t_coll_chunk.$(OBJEXT) \
|
||||
t_span_tree.$(OBJEXT) t_chunk_alloc.$(OBJEXT) \
|
||||
t_filter_read.$(OBJEXT)
|
||||
testphdf5_OBJECTS = $(am_testphdf5_OBJECTS)
|
||||
testphdf5_LDADD = $(LDADD)
|
||||
testphdf5_DEPENDENCIES = $(LIBH5TEST) $(LIBHDF5)
|
||||
@ -431,8 +432,8 @@ INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/test
|
||||
TEST_PROG_PARA = t_mpi t_posix_compliant testphdf5 t_cache t_pflush1 t_pflush2 t_shapesame
|
||||
TEST_SCRIPT_PARA = testph5.sh
|
||||
check_SCRIPTS = $(TEST_SCRIPT)
|
||||
testphdf5_SOURCES = testphdf5.c t_dset.c t_file.c t_mdset.c t_ph5basic.c \
|
||||
t_coll_chunk.c t_span_tree.c t_chunk_alloc.c t_filter_read.c
|
||||
testphdf5_SOURCES = testphdf5.c t_dset.c t_file.c t_file_image.c t_mdset.c \
|
||||
t_ph5basic.c t_coll_chunk.c t_span_tree.c t_chunk_alloc.c t_filter_read.c
|
||||
|
||||
|
||||
# The tests all depend on the hdf5 library and the test library
|
||||
@ -532,6 +533,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_coll_chunk.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_dset.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_file.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_file_image.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_filter_read.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_mdset.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_mpi.Po@am__quote@
|
||||
|
395
testpar/t_file_image.c
Normal file
395
testpar/t_file_image.c
Normal file
@ -0,0 +1,395 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*
|
||||
* Parallel tests for file image operations
|
||||
*/
|
||||
|
||||
#include "testphdf5.h"
|
||||
|
||||
/* file_image_daisy_chain_test
|
||||
*
|
||||
* Process zero:
|
||||
*
|
||||
* 1) Creates a core file with an integer vector data set of
|
||||
* length n (= mpi_size),
|
||||
*
|
||||
* 2) Initializes the vector to zero in * location 0, and to -1
|
||||
* everywhere else.
|
||||
*
|
||||
* 3) Flushes the core file, and gets an image of it. Closes
|
||||
* the core file.
|
||||
*
|
||||
* 4) Sends the image to process 1.
|
||||
*
|
||||
* 5) Awaits receipt on a file image from process n-1.
|
||||
*
|
||||
* 6) opens the image received from process n-1, verifies that
|
||||
* it contains a vector of length equal to mpi_size, and
|
||||
* that the vector contains (0, 1, 2, ... n-1)
|
||||
*
|
||||
* 7) closes the core file and exits.
|
||||
*
|
||||
* Process i (0 < i < n)
|
||||
*
|
||||
* 1) Await receipt of file image from process (i - 1).
|
||||
*
|
||||
* 2) Open the image with the core file driver, verify that i
|
||||
* contains a vector v of length, and that v[j] = j for
|
||||
* 0 <= j < i, and that v[j] == -1 for i <= j < n
|
||||
*
|
||||
* 3) Set v[i] = i in the core file.
|
||||
*
|
||||
* 4) Flush the core file and send it to process (i + 1) % n.
|
||||
*
|
||||
* 5) close the core file and exit.
|
||||
*
|
||||
* Test fails on a hang (if an image is not received), or on invalid data.
|
||||
*
|
||||
* JRM -- 11/28/11
|
||||
*/
|
||||
void
|
||||
file_image_daisy_chain_test(void)
|
||||
{
|
||||
char file_name[1024] = "\0";
|
||||
int mpi_size, mpi_rank;
|
||||
int mpi_result;
|
||||
int i;
|
||||
int space_ndims;
|
||||
MPI_Status rcvstat;
|
||||
int * vector_ptr = NULL;
|
||||
hid_t fapl_id = -1;
|
||||
hid_t file_id; /* file IDs */
|
||||
hid_t dset_id = -1;
|
||||
hid_t dset_type_id = -1;
|
||||
hid_t space_id = -1;
|
||||
herr_t err;
|
||||
hsize_t dims[1];
|
||||
void * image_ptr = NULL;
|
||||
ssize_t bytes_read;
|
||||
ssize_t image_len;
|
||||
hbool_t vector_ok = TRUE;
|
||||
htri_t tri_result;
|
||||
|
||||
|
||||
/* set up MPI parameters */
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
|
||||
|
||||
/* setup file name */
|
||||
HDsnprintf(file_name, 1024, "file_image_daisy_chain_test_%05d.h5",
|
||||
(int)mpi_rank);
|
||||
|
||||
if(mpi_rank == 0) {
|
||||
|
||||
/* 1) Creates a core file with an integer vector data set
|
||||
* of length mpi_size,
|
||||
*/
|
||||
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
|
||||
VRFY((fapl_id >= 0), "creating fapl");
|
||||
|
||||
err = H5Pset_fapl_core(fapl_id, (size_t)(64 *1024), FALSE);
|
||||
VRFY((err >= 0), "setting core file driver in fapl.");
|
||||
|
||||
file_id = H5Fcreate(file_name, 0, H5P_DEFAULT, fapl_id);
|
||||
VRFY((file_id >= 0), "created core file");
|
||||
|
||||
dims[0] = (hsize_t)mpi_size;
|
||||
space_id = H5Screate_simple(1, dims, dims);
|
||||
VRFY((space_id >= 0), "created data space");
|
||||
|
||||
dset_id = H5Dcreate2(file_id, "v", H5T_NATIVE_INT, space_id,
|
||||
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
|
||||
VRFY((dset_id >= 0), "created data set");
|
||||
|
||||
|
||||
/* 2) Initialize the vector to zero in location 0, and
|
||||
* to -1 everywhere else.
|
||||
*/
|
||||
|
||||
vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int));
|
||||
VRFY((vector_ptr != NULL), "allocated in memory representation of vector");
|
||||
|
||||
vector_ptr[0] = 0;
|
||||
for(i = 1; i < mpi_size; i++)
|
||||
vector_ptr[i] = -1;
|
||||
|
||||
err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
|
||||
H5P_DEFAULT, (void *)vector_ptr);
|
||||
VRFY((err >= 0), "wrote initial data to vector.");
|
||||
|
||||
HDfree(vector_ptr);
|
||||
vector_ptr = NULL;
|
||||
|
||||
|
||||
/* 3) Flush the core file, and get an image of it. Close
|
||||
* the core file.
|
||||
*/
|
||||
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
|
||||
VRFY((err >= 0), "flushed core file.");
|
||||
|
||||
image_len = H5Fget_file_image(file_id, NULL, (size_t)0);
|
||||
VRFY((image_len > 0), "got image file size");
|
||||
|
||||
image_ptr = (void *)HDmalloc((size_t)image_len);
|
||||
VRFY(image_ptr != NULL, "allocated file image buffer.");
|
||||
|
||||
bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)image_len);
|
||||
VRFY(bytes_read == image_len, "wrote file into image buffer");
|
||||
|
||||
err = H5Sclose(space_id);
|
||||
VRFY((err >= 0), "closed data space.");
|
||||
|
||||
err = H5Dclose(dset_id);
|
||||
VRFY((err >= 0), "closed data set.");
|
||||
|
||||
err = H5Fclose(file_id);
|
||||
VRFY((err >= 0), "closed core file(1).");
|
||||
|
||||
err = H5Pclose(fapl_id);
|
||||
VRFY((err >= 0), "closed fapl(1).");
|
||||
|
||||
|
||||
/* 4) Send the image to process 1. */
|
||||
|
||||
mpi_result = MPI_Ssend((void *)(&image_len), (int)sizeof(ssize_t),
|
||||
MPI_BYTE, 1, 0, MPI_COMM_WORLD);
|
||||
VRFY((mpi_result == MPI_SUCCESS), "sent image size to process 1");
|
||||
|
||||
mpi_result = MPI_Ssend((void *)image_ptr, (int)image_len,
|
||||
MPI_BYTE, 1, 0, MPI_COMM_WORLD);
|
||||
VRFY((mpi_result == MPI_SUCCESS), "sent image to process 1");
|
||||
|
||||
HDfree(image_ptr);
|
||||
image_ptr = NULL;
|
||||
image_len = 0;
|
||||
|
||||
|
||||
/* 5) Await receipt on a file image from process n-1. */
|
||||
|
||||
mpi_result = MPI_Recv((void *)(&image_len), (int)sizeof(ssize_t),
|
||||
MPI_BYTE, mpi_size - 1, 0, MPI_COMM_WORLD,
|
||||
&rcvstat);
|
||||
VRFY((mpi_result == MPI_SUCCESS), "received image len from process n-1");
|
||||
|
||||
image_ptr = (void *)HDmalloc((size_t)image_len);
|
||||
VRFY(image_ptr != NULL, "allocated file image receive buffer.");
|
||||
|
||||
mpi_result = MPI_Recv((void *)image_ptr, (int)image_len,
|
||||
MPI_BYTE, mpi_size - 1, 0, MPI_COMM_WORLD,
|
||||
&rcvstat);
|
||||
VRFY((mpi_result == MPI_SUCCESS), \
|
||||
"received file image from process n-1");
|
||||
|
||||
/* 6) open the image received from process n-1, verify that
|
||||
* it contains a vector of length equal to mpi_size, and
|
||||
* that the vector contains (0, 1, 2, ... n-1).
|
||||
*/
|
||||
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
|
||||
VRFY((fapl_id >= 0), "creating fapl");
|
||||
|
||||
err = H5Pset_fapl_core(fapl_id, (size_t)(64 *1024), FALSE);
|
||||
VRFY((err >= 0), "setting core file driver in fapl.");
|
||||
|
||||
err = H5Pset_file_image(fapl_id, image_ptr, (size_t)image_len);
|
||||
VRFY((err >= 0), "set file image in fapl.");
|
||||
|
||||
file_id = H5Fopen(file_name, H5F_ACC_RDWR, fapl_id);
|
||||
VRFY((file_id >= 0), "opened received file image file");
|
||||
|
||||
dset_id = H5Dopen1(file_id, "v");
|
||||
VRFY((dset_id >= 0), "opened data set");
|
||||
|
||||
dset_type_id = H5Dget_type(dset_id);
|
||||
VRFY((dset_type_id >= 0), "obtained data set type");
|
||||
|
||||
tri_result = H5Tequal(dset_type_id, H5T_NATIVE_INT);
|
||||
VRFY((tri_result == TRUE), "verified data set type");
|
||||
|
||||
space_id = H5Dget_space(dset_id);
|
||||
VRFY((space_id >= 0), "opened data space");
|
||||
|
||||
space_ndims = H5Sget_simple_extent_ndims(space_id);
|
||||
VRFY((space_ndims == 1), "verified data space num dims(1)");
|
||||
|
||||
space_ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
|
||||
VRFY((space_ndims == 1), "verified data space num dims(2)");
|
||||
VRFY((dims[0] == (hsize_t)mpi_size), "verified data space dims");
|
||||
|
||||
vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int));
|
||||
VRFY((vector_ptr != NULL), "allocated in memory rep of vector");
|
||||
|
||||
err = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
|
||||
H5P_DEFAULT, (void *)vector_ptr);
|
||||
VRFY((err >= 0), "read received vector.");
|
||||
|
||||
vector_ok = TRUE;
|
||||
for(i = 0; i < mpi_size; i++)
|
||||
if(vector_ptr[i] != i)
|
||||
vector_ok = FALSE;
|
||||
VRFY((vector_ok), "verified received vector.");
|
||||
|
||||
/* 7) closes the core file and exit. */
|
||||
|
||||
err = H5Sclose(space_id);
|
||||
VRFY((err >= 0), "closed data space.");
|
||||
|
||||
err = H5Dclose(dset_id);
|
||||
VRFY((err >= 0), "closed data set.");
|
||||
|
||||
err = H5Fclose(file_id);
|
||||
VRFY((err >= 0), "closed core file(1).");
|
||||
|
||||
err = H5Pclose(fapl_id);
|
||||
VRFY((err >= 0), "closed fapl(1).");
|
||||
|
||||
HDfree(image_ptr);
|
||||
image_ptr = NULL;
|
||||
image_len = 0;
|
||||
} else {
|
||||
/* 1) Await receipt of file image from process (i - 1). */
|
||||
|
||||
mpi_result = MPI_Recv((void *)(&image_len), (int)sizeof(ssize_t),
|
||||
MPI_BYTE, mpi_rank - 1, 0, MPI_COMM_WORLD,
|
||||
&rcvstat);
|
||||
VRFY((mpi_result == MPI_SUCCESS), \
|
||||
"received image size from process mpi_rank-1");
|
||||
|
||||
image_ptr = (void *)HDmalloc((size_t)image_len);
|
||||
VRFY(image_ptr != NULL, "allocated file image receive buffer.");
|
||||
|
||||
mpi_result = MPI_Recv((void *)image_ptr, (int)image_len,
|
||||
MPI_BYTE, mpi_rank - 1, 0, MPI_COMM_WORLD,
|
||||
&rcvstat);
|
||||
VRFY((mpi_result == MPI_SUCCESS), \
|
||||
"received file image from process mpi_rank-1");
|
||||
|
||||
/* 2) Open the image with the core file driver, verify that it
|
||||
* contains a vector v of length, and that v[j] = j for
|
||||
* 0 <= j < i, and that v[j] == -1 for i <= j < n
|
||||
*/
|
||||
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
|
||||
VRFY((fapl_id >= 0), "creating fapl");
|
||||
|
||||
err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), FALSE);
|
||||
VRFY((err >= 0), "setting core file driver in fapl.");
|
||||
|
||||
err = H5Pset_file_image(fapl_id, image_ptr, (size_t)image_len);
|
||||
VRFY((err >= 0), "set file image in fapl.");
|
||||
|
||||
file_id = H5Fopen(file_name, H5F_ACC_RDWR, fapl_id);
|
||||
H5Eprint1(stderr);
|
||||
VRFY((file_id >= 0), "opened received file image file");
|
||||
|
||||
dset_id = H5Dopen1(file_id, "v");
|
||||
VRFY((dset_id >= 0), "opened data set");
|
||||
|
||||
dset_type_id = H5Dget_type(dset_id);
|
||||
VRFY((dset_type_id >= 0), "obtained data set type");
|
||||
|
||||
tri_result = H5Tequal(dset_type_id, H5T_NATIVE_INT);
|
||||
VRFY((tri_result == TRUE), "verified data set type");
|
||||
|
||||
space_id = H5Dget_space(dset_id);
|
||||
VRFY((space_id >= 0), "opened data space");
|
||||
|
||||
space_ndims = H5Sget_simple_extent_ndims(space_id);
|
||||
VRFY((space_ndims == 1), "verified data space num dims(1)");
|
||||
|
||||
space_ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
|
||||
VRFY((space_ndims == 1), "verified data space num dims(2)");
|
||||
VRFY((dims[0] == (hsize_t)mpi_size), "verified data space dims");
|
||||
|
||||
vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int));
|
||||
VRFY((vector_ptr != NULL), "allocated in memory rep of vector");
|
||||
|
||||
err = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
|
||||
H5P_DEFAULT, (void *)vector_ptr);
|
||||
VRFY((err >= 0), "read received vector.");
|
||||
|
||||
vector_ok = TRUE;
|
||||
for(i = 0; i < mpi_size; i++){
|
||||
if(i < mpi_rank) {
|
||||
if(vector_ptr[i] != i)
|
||||
vector_ok = FALSE;
|
||||
} else {
|
||||
if(vector_ptr[i] != -1)
|
||||
vector_ok = FALSE;
|
||||
}
|
||||
}
|
||||
VRFY((vector_ok), "verified received vector.");
|
||||
|
||||
|
||||
/* 3) Set v[i] = i in the core file. */
|
||||
|
||||
vector_ptr[mpi_rank] = mpi_rank;
|
||||
|
||||
err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
|
||||
H5P_DEFAULT, (void *)vector_ptr);
|
||||
VRFY((err >= 0), "wrote modified data to vector.");
|
||||
|
||||
HDfree(vector_ptr);
|
||||
vector_ptr = NULL;
|
||||
|
||||
|
||||
/* 4) Flush the core file and send it to process (mpi_rank + 1) % n. */
|
||||
|
||||
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
|
||||
VRFY((err >= 0), "flushed core file.");
|
||||
|
||||
image_len = H5Fget_file_image(file_id, NULL, (size_t)0);
|
||||
VRFY((image_len > 0), "got (possibly modified) image file len");
|
||||
|
||||
image_ptr = (void *)HDrealloc((void *)image_ptr, (size_t)image_len);
|
||||
VRFY(image_ptr != NULL, "re-allocated file image buffer.");
|
||||
|
||||
bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)image_len);
|
||||
VRFY(bytes_read == image_len, "wrote file into image buffer");
|
||||
|
||||
mpi_result = MPI_Ssend((void *)(&image_len), (int)sizeof(ssize_t),
|
||||
MPI_BYTE, (mpi_rank + 1) % mpi_size, 0,
|
||||
MPI_COMM_WORLD);
|
||||
VRFY((mpi_result == MPI_SUCCESS), \
|
||||
"sent image size to process (mpi_rank + 1) % mpi_size");
|
||||
|
||||
mpi_result = MPI_Ssend((void *)image_ptr, (int)image_len,
|
||||
MPI_BYTE, (mpi_rank + 1) % mpi_size, 0,
|
||||
MPI_COMM_WORLD);
|
||||
VRFY((mpi_result == MPI_SUCCESS), \
|
||||
"sent image to process (mpi_rank + 1) % mpi_size");
|
||||
|
||||
HDfree(image_ptr);
|
||||
image_ptr = NULL;
|
||||
image_len = 0;
|
||||
|
||||
/* 5) close the core file and exit. */
|
||||
|
||||
err = H5Sclose(space_id);
|
||||
VRFY((err >= 0), "closed data space.");
|
||||
|
||||
err = H5Dclose(dset_id);
|
||||
VRFY((err >= 0), "closed data set.");
|
||||
|
||||
err = H5Fclose(file_id);
|
||||
VRFY((err >= 0), "closed core file(1).");
|
||||
|
||||
err = H5Pclose(fapl_id);
|
||||
VRFY((err >= 0), "closed fapl(1).");
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} /* file_image_daisy_chain_test() */
|
||||
|
@ -502,6 +502,13 @@ int main(int argc, char **argv)
|
||||
"test actual io mode proprerty",
|
||||
PARATESTFILE);
|
||||
|
||||
if((mpi_size < 2) && MAINPROCESS) {
|
||||
printf("File Image Ops daisy chain test needs at least 2 processes.\n");
|
||||
printf("File Image Ops daisy chain test will be skipped \n");
|
||||
}
|
||||
AddTest((mpi_size < 2)? "-fiodc" : "fiodc", file_image_daisy_chain_test, NULL,
|
||||
"file image ops daisy chain", NULL);
|
||||
|
||||
/* Display testing information */
|
||||
TestInfo(argv[0]);
|
||||
|
||||
|
@ -269,6 +269,7 @@ void lower_dim_size_comp_test(void);
|
||||
void link_chunk_collective_io_test(void);
|
||||
void contig_hyperslab_dr_pio_test(ShapeSameTestMethods sstest_type);
|
||||
void checker_board_hyperslab_dr_pio_test(ShapeSameTestMethods sstest_type);
|
||||
void file_image_daisy_chain_test(void);
|
||||
#ifdef H5_HAVE_FILTER_DEFLATE
|
||||
void compress_readAll(void);
|
||||
#endif /* H5_HAVE_FILTER_DEFLATE */
|
||||
|
Loading…
x
Reference in New Issue
Block a user