med_memfile.hxx
Aller à la documentation de ce fichier.
/* -*- mode:C; coding:utf-8 -*- */
/* This file is part of MED.
*
* COPYRIGHT (C) 1999 - 2021 EDF R&D, CEA/DEN
* MED is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MED is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with MED. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MED_MEMFILE_H
#define MED_MEMFILE_H
#include <hdf5.h>
#ifdef __cplusplus
extern "C" {
#endif
/* 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
*
*-------------------------------------------------------------------------
*/
/* 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);
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) {
XSCRUTE(ptr);
XSCRUTE(udata->vfd_image_ptr);
ISCRUTE_long(size);
ISCRUTE_long( udata->vfd_image_size);
if (udata->vfd_image_ptr != ptr)
goto out;
if (udata->vfd_ref_count != 1)
goto out;
if (NULL == (udata->vfd_image_ptr = realloc(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 */
#ifdef __cplusplus
}
#endif
#endif /* MED_MEMFILE_H */
image_memcpy
static void * image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op, void *udata)
Definition: med_memfile.hxx:193
H5LT_file_image_ud_t::fapl_ref_count
int fapl_ref_count
Definition: med_memfile.hxx:34
udata_free
static herr_t udata_free(void *udata)
Definition: med_memfile.hxx:453
herr_t
int herr_t
Definition: H5public_extract.h:27
H5LT_file_image_ud_t
Definition: med_memfile.hxx:29
image_realloc
static void * image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *udata)
Definition: med_memfile.hxx:277
H5LT_file_image_ud_t::vfd_image_size
size_t vfd_image_size
Definition: med_memfile.hxx:36
H5LT_file_image_ud_t::flags
unsigned flags
Definition: med_memfile.hxx:38
H5LT_file_image_ud_t::app_image_size
size_t app_image_size
Definition: med_memfile.hxx:31
image_free
static herr_t image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *udata)
Definition: med_memfile.hxx:339
XSCRUTE
#define XSCRUTE(pointeur)
Definition: med_utils.h:320
H5LT_file_image_ud_t::fapl_image_ptr
void * fapl_image_ptr
Definition: med_memfile.hxx:32
H5LT_file_image_ud_t::vfd_ref_count
int vfd_ref_count
Definition: med_memfile.hxx:37
ISCRUTE_long
#define ISCRUTE_long(entier)
Definition: med_utils.h:316
image_malloc
static void * image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *udata)
Definition: med_memfile.hxx:94
H5LT_file_image_ud_t::ref_count
int ref_count
Definition: med_memfile.hxx:40
H5LT_file_image_ud_t::app_image_ptr
void * app_image_ptr
Definition: med_memfile.hxx:30
H5LT_file_image_ud_t::fapl_image_size
size_t fapl_image_size
Definition: med_memfile.hxx:33
H5LT_file_image_ud_t::vfd_image_ptr
void * vfd_image_ptr
Definition: med_memfile.hxx:35
udata_copy
static void * udata_copy(void *udata)
Definition: med_memfile.hxx:418