med_memfile.hxx

Aller à la documentation de ce fichier.
00001 /* -*- mode:C; coding:utf-8 -*- */
00002 /*  This file is part of MED.
00003  *
00004  *  COPYRIGHT (C) 1999 - 2013  EDF R&D, CEA/DEN
00005  *  MED is free software: you can redistribute it and/or modify
00006  *  it under the terms of the GNU Lesser General Public License as published by
00007  *  the Free Software Foundation, either version 3 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  MED is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU Lesser General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Lesser General Public License
00016  *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #ifndef MED_MEMFILE_H
00020 #define MED_MEMFILE_H
00021 
00022 #include <hdf5.h>
00023 
00024 #ifdef __cplusplus
00025 extern "C" {
00026 #endif
00027 
00028 /* Data structure to pass application data to callbacks. */ 
00029 typedef struct {
00030     void *app_image_ptr;        /* Pointer to application buffer */ 
00031     size_t app_image_size;      /* Size of application buffer */
00032     void *fapl_image_ptr;       /* Pointer to FAPL buffer */
00033     size_t fapl_image_size;     /* Size of FAPL buffer */
00034     int fapl_ref_count;         /* Reference counter for FAPL buffer */
00035     void *vfd_image_ptr;        /* Pointer to VFD buffer */
00036     size_t vfd_image_size;      /* Size of VFD buffer */
00037     int vfd_ref_count;          /* Reference counter for VFD buffer */
00038     unsigned flags;             /* Flags indicate how the file image will */
00039                                 /* be open */
00040     int ref_count;              /* Reference counter on udata struct */
00041 } H5LT_file_image_ud_t;
00042 
00043 /* callbacks prototypes for file image ops */
00044 static void *image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *udata);
00045 static void *image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
00046 static void *image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
00047 static herr_t image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *udata);
00048 static void *udata_copy(void *udata);
00049 static herr_t udata_free(void *udata);
00050 
00051 /* Definition of callbacks for file image operations. */
00052 
00053 /*-------------------------------------------------------------------------
00054 * Function: image_malloc 
00055 *
00056 * Purpose: Simulates malloc() function to avoid copying file images.
00057 *          The application buffer is set to the buffer on only one FAPL.
00058 *          Then the FAPL buffer can be copied to other FAPL buffers or
00059 *          to only one VFD buffer. 
00060 *
00061 * Return: Address of "allocated" buffer, if successful. Otherwise, it returns
00062 *         NULL.
00063 *
00064 * Programmer: Christian Chilan 
00065 *
00066 * Date: October 3, 2011
00067 *
00068 *-------------------------------------------------------------------------
00069 */
00070 /* Data structure to pass application data to callbacks. */ 
00071 typedef struct {
00072     void *app_image_ptr;        /* Pointer to application buffer */ 
00073     size_t app_image_size;      /* Size of application buffer */
00074     void *fapl_image_ptr;       /* Pointer to FAPL buffer */
00075     size_t fapl_image_size;     /* Size of FAPL buffer */
00076     int fapl_ref_count;         /* Reference counter for FAPL buffer */
00077     void *vfd_image_ptr;        /* Pointer to VFD buffer */
00078     size_t vfd_image_size;      /* Size of VFD buffer */
00079     int vfd_ref_count;          /* Reference counter for VFD buffer */
00080     unsigned flags;             /* Flags indicate how the file image will */
00081                                 /* be open */
00082     int ref_count;              /* Reference counter on udata struct */
00083 } H5LT_file_image_ud_t;
00084 
00085 /* callbacks prototypes for file image ops */
00086 static void *image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *udata);
00087 static void *image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
00088 static void *image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
00089 static herr_t image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *udata);
00090 static void *udata_copy(void *udata);
00091 static herr_t udata_free(void *udata);
00092 
00093 static void *
00094 image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *_udata)
00095 {
00096     H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
00097     void * return_value = NULL;
00098     
00099     /* callback is only used if the application buffer is not actually copied */
00100     // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) 
00101     //     goto out;
00102 
00103     switch ( file_image_op ) {
00104         /* the app buffer is "copied" to only one FAPL. Afterwards, FAPLs can be "copied" */
00105         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
00106             if (udata->app_image_ptr == NULL) 
00107                 goto out;
00108             if (udata->app_image_size != size) 
00109                 goto out;
00110             if (udata->fapl_image_ptr != NULL) 
00111                 goto out;
00112             if (udata->fapl_image_size != 0) 
00113                 goto out;
00114             if (udata->fapl_ref_count != 0) 
00115                 goto out;
00116 
00117             udata->fapl_image_ptr = udata->app_image_ptr;
00118             udata->fapl_image_size = udata->app_image_size;
00119             return_value = udata->fapl_image_ptr;
00120             udata->fapl_ref_count++;
00121             break;
00122 
00123         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
00124             if (udata->fapl_image_ptr == NULL) 
00125                 goto out;
00126             if (udata->fapl_image_size != size) 
00127                 goto out;
00128             if (udata->fapl_ref_count == 0) 
00129                 goto out;
00130 
00131             return_value = udata->fapl_image_ptr;
00132             udata->fapl_ref_count++;
00133             break;
00134 
00135         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
00136             goto out;
00137 
00138         case H5FD_FILE_IMAGE_OP_FILE_OPEN:
00139             /* FAPL buffer is "copied" to only one VFD buffer */
00140             if (udata->vfd_image_ptr != NULL) 
00141                 goto out;
00142             if (udata->vfd_image_size != 0) 
00143                 goto out;
00144             if (udata->vfd_ref_count != 0) 
00145                 goto out;
00146             if (udata->fapl_image_ptr == NULL) 
00147                 goto out;
00148             if (udata->fapl_image_size != size) 
00149                 goto out;
00150             if (udata->fapl_ref_count == 0) 
00151                 goto out;
00152 
00153             udata->vfd_image_ptr = udata->fapl_image_ptr;
00154             udata->vfd_image_size = size;
00155             udata->vfd_ref_count++;
00156             return_value = udata->vfd_image_ptr;
00157             break;
00158 
00159         /* added unused labels to shut the compiler up */
00160         case H5FD_FILE_IMAGE_OP_NO_OP:
00161         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
00162         case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
00163         case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
00164         default:
00165             goto out;
00166     } /* end switch */
00167 
00168     return(return_value);
00169 
00170 out:
00171     return NULL;
00172 } /* end image_malloc() */
00173 
00174 
00175 /*-------------------------------------------------------------------------
00176 * Function: image_memcpy
00177 *
00178 * Purpose:  Simulates memcpy() function to avoid copying file images. 
00179 *           The image buffer can be set to only one FAPL buffer, and
00180 *           "copied" to only one VFD buffer. The FAPL buffer can be
00181 *           "copied" to other FAPLs buffers. 
00182 *
00183 * Return: The address of the destination buffer, if successful. Otherwise, it
00184 *         returns NULL.
00185 *
00186 * Programmer: Christian Chilan 
00187 *
00188 * Date: October 3, 2011
00189 *
00190 *-------------------------------------------------------------------------
00191 */
00192 static void *
00193 image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op,
00194     void *_udata)
00195 {
00196     H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
00197 
00198     /* callback is only used if the application buffer is not actually copied */
00199     // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) 
00200     //     goto out;
00201 
00202     switch(file_image_op) {
00203         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
00204             if (dest != udata->fapl_image_ptr) 
00205                 goto out;
00206             if (src != udata->app_image_ptr) 
00207                 goto out;
00208             if (size != udata->fapl_image_size) 
00209                 goto out;
00210             if (size != udata->app_image_size) 
00211                 goto out;
00212             if (udata->fapl_ref_count == 0) 
00213                 goto out;
00214             break;
00215 
00216         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
00217             if (dest != udata->fapl_image_ptr) 
00218                 goto out;
00219             if (src != udata->fapl_image_ptr) 
00220                 goto out;
00221             if (size != udata->fapl_image_size) 
00222                 goto out;
00223             if (udata->fapl_ref_count < 2) 
00224                 goto out;
00225             break;
00226 
00227         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
00228             goto out;
00229 
00230         case H5FD_FILE_IMAGE_OP_FILE_OPEN:
00231             if (dest != udata->vfd_image_ptr) 
00232                 goto out;
00233             if (src != udata->fapl_image_ptr) 
00234                 goto out;
00235             if (size != udata->vfd_image_size) 
00236                 goto out;
00237             if (size != udata->fapl_image_size) 
00238                 goto out;
00239             if (udata->fapl_ref_count == 0) 
00240                 goto out;
00241             if (udata->vfd_ref_count != 1) 
00242                 goto out;
00243             break;
00244 
00245         /* added unused labels to shut the compiler up */
00246         case H5FD_FILE_IMAGE_OP_NO_OP:
00247         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
00248         case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
00249         case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
00250         default:
00251             goto out;
00252     } /* end switch */
00253 
00254     return(dest);
00255 
00256 out:
00257     return NULL;
00258 } /* end image_memcpy() */
00259 
00260 
00261 /*-------------------------------------------------------------------------
00262 * Function: image_realloc 
00263 *
00264 * Purpose: Reallocates the shared application image buffer and updates data
00265 *          structures that manage buffer "copying". 
00266 *           
00267 * Return: Address of reallocated buffer, if successful. Otherwise, it returns
00268 *         NULL.  
00269 *
00270 * Programmer: Christian Chilan 
00271 *
00272 * Date: October 3, 2011
00273 *
00274 *-------------------------------------------------------------------------
00275 */
00276 static void *
00277 image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *_udata)
00278 {
00279     H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
00280     void * return_value = NULL;
00281 
00282     /* callback is only used if the application buffer is not actually copied */
00283     // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) 
00284     //     goto out;
00285 
00286     /* realloc() is not allowed when the HDF5 library won't release the image 
00287        buffer because reallocation may change the address of the buffer. The
00288        new address cannot be communicated to the application to release it. */
00289     // if (udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE) 
00290     //     goto out; 
00291 
00292     /* realloc() is not allowed if the image is open in read-only mode */
00293     if (!(udata->flags & H5LT_FILE_IMAGE_OPEN_RW)) 
00294         goto out; 
00295 
00296     if (file_image_op == H5FD_FILE_IMAGE_OP_FILE_RESIZE) {
00297  XSCRUTE(ptr);
00298  XSCRUTE(udata->vfd_image_ptr);
00299  ISCRUTE_long(size);
00300  ISCRUTE_long( udata->vfd_image_size);
00301     if (udata->vfd_image_ptr != ptr) 
00302             goto out; 
00303 
00304         if (udata->vfd_ref_count != 1) 
00305             goto out;
00306 
00307         if (NULL == (udata->vfd_image_ptr = realloc(ptr, size)))
00308             goto out; 
00309             
00310         udata->vfd_image_size = size;
00311         return_value = udata->vfd_image_ptr;
00312     } /* end if */
00313     else
00314         goto out;
00315 
00316     return(return_value);
00317 
00318 out:
00319     return NULL;
00320 } /* end image_realloc() */
00321 
00322 
00323 /*-------------------------------------------------------------------------
00324 * Function: image_free
00325 *
00326 * Purpose: Simulates deallocation of FAPL and VFD buffers by decreasing
00327 *          reference counters. Shared application buffer is actually
00328 *          deallocated if there are no outstanding references.
00329 *
00330 * Return: SUCCEED or FAIL 
00331 *
00332 * Programmer: Christian Chilan 
00333 *
00334 * Date: October 3, 2011
00335 *
00336 *-------------------------------------------------------------------------
00337 */
00338 static herr_t
00339 image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *_udata)
00340 {
00341     H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
00342 
00343     /* callback is only used if the application buffer is not actually copied */
00344     // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) 
00345     //     goto out;
00346 
00347     switch(file_image_op) {
00348         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
00349             if (udata->fapl_image_ptr != ptr) 
00350                 goto out;
00351             if (udata->fapl_ref_count == 0) 
00352                 goto out;
00353 
00354             udata->fapl_ref_count--;
00355 
00356             /* release the shared buffer only if indicated by the respective flag and there are no outstanding references */ 
00357             // if (udata->fapl_ref_count == 0 && udata->vfd_ref_count == 0 &&
00358             //         !(udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)) {
00359             //     HDfree(udata->fapl_image_ptr);
00360             //     udata->app_image_ptr = NULL;
00361             //     udata->fapl_image_ptr = NULL;
00362             //     udata->vfd_image_ptr = NULL;
00363             // } /* end if */
00364             break;
00365 
00366         case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
00367             if (udata->vfd_image_ptr != ptr) 
00368                 goto out;
00369             if (udata->vfd_ref_count != 1) 
00370                 goto out;
00371 
00372             udata->vfd_ref_count--;
00373 
00374             /* release the shared buffer only if indicated by the respective flag and there are no outstanding references */ 
00375             // if (udata->fapl_ref_count == 0 && udata->vfd_ref_count == 0 &&
00376             //         !(udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)) {
00377             //     HDfree(udata->vfd_image_ptr);
00378             //     udata->app_image_ptr = NULL;
00379             //     udata->fapl_image_ptr = NULL;
00380             //     udata->vfd_image_ptr = NULL;
00381             // } /* end if */
00382             break;
00383 
00384         /* added unused labels to keep the compiler quite */
00385         case H5FD_FILE_IMAGE_OP_NO_OP:
00386         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
00387         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
00388         case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
00389         case H5FD_FILE_IMAGE_OP_FILE_OPEN:
00390         case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
00391         default:
00392             goto out;
00393     } /* end switch */
00394 
00395     return(SUCCEED);
00396 
00397 out:
00398     return(FAIL);
00399 } /* end image_free() */
00400 
00401 
00402 /*-------------------------------------------------------------------------
00403 * Function: udata_copy 
00404 *
00405 * Purpose: Simulates the copying of the user data structure utilized in the
00406 *          management of the "copying" of file images.
00407 *
00408 * Return: Address of "newly allocated" structure, if successful. Otherwise, it
00409 *         returns NULL.
00410 *
00411 * Programmer: Christian Chilan 
00412 *
00413 * Date: October 3, 2011
00414 *
00415 *-------------------------------------------------------------------------
00416 */
00417 static void *
00418 udata_copy(void *_udata)
00419 {
00420     H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
00421 
00422     /* callback is only used if the application buffer is not actually copied */
00423     // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) 
00424     //     goto out;
00425     if (udata->ref_count == 0) 
00426         goto out;
00427 
00428     udata->ref_count++;
00429 
00430     return(udata);
00431 
00432 out:
00433     return NULL;
00434 } /* end udata_copy */
00435 
00436 
00437 /*-------------------------------------------------------------------------
00438 * Function: udata_free
00439 *
00440 * Purpose: Simulates deallocation of the user data structure utilized in the
00441 *          management of the "copying" of file images. The data structure is
00442 *          actually deallocated when there are no outstanding references. 
00443 *
00444 * Return: SUCCEED or FAIL 
00445 *
00446 * Programmer: Christian Chilan 
00447 *
00448 * Date: October 3, 2011
00449 *
00450 *-------------------------------------------------------------------------
00451 */
00452 static herr_t
00453 udata_free(void *_udata)
00454 {
00455     H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
00456 
00457     /* callback is only used if the application buffer is not actually copied */
00458     // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) 
00459     //     goto out;
00460     if (udata->ref_count == 0) 
00461         goto out;
00462 
00463     udata->ref_count--;
00464 
00465     /* checks that there are no references outstanding before deallocating udata */
00466     if (udata->ref_count == 0 && udata->fapl_ref_count == 0 &&
00467             udata->vfd_ref_count == 0)
00468         HDfree(udata);
00469 
00470     return(SUCCEED);
00471 
00472 out:        
00473     return(FAIL);
00474 } /* end udata_free */
00475 
00476 /* End of callbacks definitions for file image operations */
00477 
00478 
00479 #ifdef __cplusplus
00480 }
00481 #endif
00482 
00483 #endif  /* MED_MEMFILE_H */

Généré le Thu Oct 8 14:26:16 2015 pour MED fichier par  doxygen 1.6.1