MED fichier
med_memfile.hxx
Aller à la documentation de ce fichier.
1 /* -*- mode:C; coding:utf-8 -*- */
2 /* This file is part of MED.
3  *
4  * COPYRIGHT (C) 1999 - 2023 EDF R&D, CEA/DEN
5  * MED is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * MED is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with MED. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef MED_MEMFILE_H
20 #define MED_MEMFILE_H
21 
22 #include <hdf5.h>
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 /* Data structure to pass application data to callbacks. */
29 typedef struct {
30  void *app_image_ptr; /* Pointer to application buffer */
31  size_t app_image_size; /* Size of application buffer */
32  void *fapl_image_ptr; /* Pointer to FAPL buffer */
33  size_t fapl_image_size; /* Size of FAPL buffer */
34  int fapl_ref_count; /* Reference counter for FAPL buffer */
35  void *vfd_image_ptr; /* Pointer to VFD buffer */
36  size_t vfd_image_size; /* Size of VFD buffer */
37  int vfd_ref_count; /* Reference counter for VFD buffer */
38  unsigned flags; /* Flags indicate how the file image will */
39  /* be open */
40  int ref_count; /* Reference counter on udata struct */
42 
43 /* callbacks prototypes for file image ops */
44 static void *image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *udata);
45 static void *image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
46 static void *image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
47 static herr_t image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *udata);
48 static void *udata_copy(void *udata);
49 static herr_t udata_free(void *udata);
50 
51 /* Definition of callbacks for file image operations. */
52 
53 /*-------------------------------------------------------------------------
54 * Function: image_malloc
55 *
56 * Purpose: Simulates malloc() function to avoid copying file images.
57 * The application buffer is set to the buffer on only one FAPL.
58 * Then the FAPL buffer can be copied to other FAPL buffers or
59 * to only one VFD buffer.
60 *
61 * Return: Address of "allocated" buffer, if successful. Otherwise, it returns
62 * NULL.
63 *
64 * Programmer: Christian Chilan
65 *
66 * Date: October 3, 2011
67 *
68 *-------------------------------------------------------------------------
69 */
70 /* Data structure to pass application data to callbacks. */
71 typedef struct {
72  void *app_image_ptr; /* Pointer to application buffer */
73  size_t app_image_size; /* Size of application buffer */
74  void *fapl_image_ptr; /* Pointer to FAPL buffer */
75  size_t fapl_image_size; /* Size of FAPL buffer */
76  int fapl_ref_count; /* Reference counter for FAPL buffer */
77  void *vfd_image_ptr; /* Pointer to VFD buffer */
78  size_t vfd_image_size; /* Size of VFD buffer */
79  int vfd_ref_count; /* Reference counter for VFD buffer */
80  unsigned flags; /* Flags indicate how the file image will */
81  /* be open */
82  int ref_count; /* Reference counter on udata struct */
84 
85 /* callbacks prototypes for file image ops */
86 static void *image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *udata);
87 static void *image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
88 static void *image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
89 static herr_t image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *udata);
90 static void *udata_copy(void *udata);
91 static herr_t udata_free(void *udata);
92 
93 static void *
94 image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *_udata)
95 {
96  H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
97  void * return_value = NULL;
98 
99  /* callback is only used if the application buffer is not actually copied */
100  // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
101  // goto out;
102 
103  switch ( file_image_op ) {
104  /* the app buffer is "copied" to only one FAPL. Afterwards, FAPLs can be "copied" */
105  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
106  if (udata->app_image_ptr == NULL)
107  goto out;
108  if (udata->app_image_size != size)
109  goto out;
110  if (udata->fapl_image_ptr != NULL)
111  goto out;
112  if (udata->fapl_image_size != 0)
113  goto out;
114  if (udata->fapl_ref_count != 0)
115  goto out;
116 
117  udata->fapl_image_ptr = udata->app_image_ptr;
118  udata->fapl_image_size = udata->app_image_size;
119  return_value = udata->fapl_image_ptr;
120  udata->fapl_ref_count++;
121  break;
122 
123  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
124  if (udata->fapl_image_ptr == NULL)
125  goto out;
126  if (udata->fapl_image_size != size)
127  goto out;
128  if (udata->fapl_ref_count == 0)
129  goto out;
130 
131  return_value = udata->fapl_image_ptr;
132  udata->fapl_ref_count++;
133  break;
134 
135  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
136  goto out;
137 
138  case H5FD_FILE_IMAGE_OP_FILE_OPEN:
139  /* FAPL buffer is "copied" to only one VFD buffer */
140  if (udata->vfd_image_ptr != NULL)
141  goto out;
142  if (udata->vfd_image_size != 0)
143  goto out;
144  if (udata->vfd_ref_count != 0)
145  goto out;
146  if (udata->fapl_image_ptr == NULL)
147  goto out;
148  if (udata->fapl_image_size != size)
149  goto out;
150  if (udata->fapl_ref_count == 0)
151  goto out;
152 
153  udata->vfd_image_ptr = udata->fapl_image_ptr;
154  udata->vfd_image_size = size;
155  udata->vfd_ref_count++;
156  return_value = udata->vfd_image_ptr;
157  break;
158 
159  /* added unused labels to shut the compiler up */
160  case H5FD_FILE_IMAGE_OP_NO_OP:
161  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
162  case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
163  case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
164  default:
165  goto out;
166  } /* end switch */
167 
168  return(return_value);
169 
170 out:
171  return NULL;
172 } /* end image_malloc() */
173 
174 
175 /*-------------------------------------------------------------------------
176 * Function: image_memcpy
177 *
178 * Purpose: Simulates memcpy() function to avoid copying file images.
179 * The image buffer can be set to only one FAPL buffer, and
180 * "copied" to only one VFD buffer. The FAPL buffer can be
181 * "copied" to other FAPLs buffers.
182 *
183 * Return: The address of the destination buffer, if successful. Otherwise, it
184 * returns NULL.
185 *
186 * Programmer: Christian Chilan
187 *
188 * Date: October 3, 2011
189 *
190 *-------------------------------------------------------------------------
191 */
192 static void *
193 image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op,
194  void *_udata)
195 {
196  H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
197 
198  /* callback is only used if the application buffer is not actually copied */
199  // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
200  // goto out;
201 
202  switch(file_image_op) {
203  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
204  if (dest != udata->fapl_image_ptr)
205  goto out;
206  if (src != udata->app_image_ptr)
207  goto out;
208  if (size != udata->fapl_image_size)
209  goto out;
210  if (size != udata->app_image_size)
211  goto out;
212  if (udata->fapl_ref_count == 0)
213  goto out;
214  break;
215 
216  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
217  if (dest != udata->fapl_image_ptr)
218  goto out;
219  if (src != udata->fapl_image_ptr)
220  goto out;
221  if (size != udata->fapl_image_size)
222  goto out;
223  if (udata->fapl_ref_count < 2)
224  goto out;
225  break;
226 
227  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
228  goto out;
229 
230  case H5FD_FILE_IMAGE_OP_FILE_OPEN:
231  if (dest != udata->vfd_image_ptr)
232  goto out;
233  if (src != udata->fapl_image_ptr)
234  goto out;
235  if (size != udata->vfd_image_size)
236  goto out;
237  if (size != udata->fapl_image_size)
238  goto out;
239  if (udata->fapl_ref_count == 0)
240  goto out;
241  if (udata->vfd_ref_count != 1)
242  goto out;
243  break;
244 
245  /* added unused labels to shut the compiler up */
246  case H5FD_FILE_IMAGE_OP_NO_OP:
247  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
248  case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
249  case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
250  default:
251  goto out;
252  } /* end switch */
253 
254  return(dest);
255 
256 out:
257  return NULL;
258 } /* end image_memcpy() */
259 
260 
261 /*-------------------------------------------------------------------------
262 * Function: image_realloc
263 *
264 * Purpose: Reallocates the shared application image buffer and updates data
265 * structures that manage buffer "copying".
266 *
267 * Return: Address of reallocated buffer, if successful. Otherwise, it returns
268 * NULL.
269 *
270 * Programmer: Christian Chilan
271 *
272 * Date: October 3, 2011
273 *
274 *-------------------------------------------------------------------------
275 */
276 static void *
277 image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *_udata)
278 {
279  H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
280  void * return_value = NULL;
281 
282  /* callback is only used if the application buffer is not actually copied */
283  // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
284  // goto out;
285 
286  /* realloc() is not allowed when the HDF5 library won't release the image
287  buffer because reallocation may change the address of the buffer. The
288  new address cannot be communicated to the application to release it. */
289  // if (udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)
290  // goto out;
291 
292  /* realloc() is not allowed if the image is open in read-only mode */
293  if (!(udata->flags & H5LT_FILE_IMAGE_OPEN_RW))
294  goto out;
295 
296  if (file_image_op == H5FD_FILE_IMAGE_OP_FILE_RESIZE) {
297  XSCRUTE(ptr);
298  XSCRUTE(udata->vfd_image_ptr);
299  ISCRUTE_long(size);
300  ISCRUTE_long( udata->vfd_image_size);
301  if (udata->vfd_image_ptr != ptr)
302  goto out;
303 
304  if (udata->vfd_ref_count != 1)
305  goto out;
306 
307  if (NULL == (udata->vfd_image_ptr = realloc(ptr, size)))
308  goto out;
309 
310  udata->vfd_image_size = size;
311  return_value = udata->vfd_image_ptr;
312  } /* end if */
313  else
314  goto out;
315 
316  return(return_value);
317 
318 out:
319  return NULL;
320 } /* end image_realloc() */
321 
322 
323 /*-------------------------------------------------------------------------
324 * Function: image_free
325 *
326 * Purpose: Simulates deallocation of FAPL and VFD buffers by decreasing
327 * reference counters. Shared application buffer is actually
328 * deallocated if there are no outstanding references.
329 *
330 * Return: SUCCEED or FAIL
331 *
332 * Programmer: Christian Chilan
333 *
334 * Date: October 3, 2011
335 *
336 *-------------------------------------------------------------------------
337 */
338 static herr_t
339 image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *_udata)
340 {
341  H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
342 
343  /* callback is only used if the application buffer is not actually copied */
344  // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
345  // goto out;
346 
347  switch(file_image_op) {
348  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
349  if (udata->fapl_image_ptr != ptr)
350  goto out;
351  if (udata->fapl_ref_count == 0)
352  goto out;
353 
354  udata->fapl_ref_count--;
355 
356  /* release the shared buffer only if indicated by the respective flag and there are no outstanding references */
357  // if (udata->fapl_ref_count == 0 && udata->vfd_ref_count == 0 &&
358  // !(udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)) {
359  // HDfree(udata->fapl_image_ptr);
360  // udata->app_image_ptr = NULL;
361  // udata->fapl_image_ptr = NULL;
362  // udata->vfd_image_ptr = NULL;
363  // } /* end if */
364  break;
365 
366  case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
367  if (udata->vfd_image_ptr != ptr)
368  goto out;
369  if (udata->vfd_ref_count != 1)
370  goto out;
371 
372  udata->vfd_ref_count--;
373 
374  /* release the shared buffer only if indicated by the respective flag and there are no outstanding references */
375  // if (udata->fapl_ref_count == 0 && udata->vfd_ref_count == 0 &&
376  // !(udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)) {
377  // HDfree(udata->vfd_image_ptr);
378  // udata->app_image_ptr = NULL;
379  // udata->fapl_image_ptr = NULL;
380  // udata->vfd_image_ptr = NULL;
381  // } /* end if */
382  break;
383 
384  /* added unused labels to keep the compiler quite */
385  case H5FD_FILE_IMAGE_OP_NO_OP:
386  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
387  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
388  case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
389  case H5FD_FILE_IMAGE_OP_FILE_OPEN:
390  case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
391  default:
392  goto out;
393  } /* end switch */
394 
395  return(SUCCEED);
396 
397 out:
398  return(FAIL);
399 } /* end image_free() */
400 
401 
402 /*-------------------------------------------------------------------------
403 * Function: udata_copy
404 *
405 * Purpose: Simulates the copying of the user data structure utilized in the
406 * management of the "copying" of file images.
407 *
408 * Return: Address of "newly allocated" structure, if successful. Otherwise, it
409 * returns NULL.
410 *
411 * Programmer: Christian Chilan
412 *
413 * Date: October 3, 2011
414 *
415 *-------------------------------------------------------------------------
416 */
417 static void *
418 udata_copy(void *_udata)
419 {
420  H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
421 
422  /* callback is only used if the application buffer is not actually copied */
423  // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
424  // goto out;
425  if (udata->ref_count == 0)
426  goto out;
427 
428  udata->ref_count++;
429 
430  return(udata);
431 
432 out:
433  return NULL;
434 } /* end udata_copy */
435 
436 
437 /*-------------------------------------------------------------------------
438 * Function: udata_free
439 *
440 * Purpose: Simulates deallocation of the user data structure utilized in the
441 * management of the "copying" of file images. The data structure is
442 * actually deallocated when there are no outstanding references.
443 *
444 * Return: SUCCEED or FAIL
445 *
446 * Programmer: Christian Chilan
447 *
448 * Date: October 3, 2011
449 *
450 *-------------------------------------------------------------------------
451 */
452 static herr_t
453 udata_free(void *_udata)
454 {
455  H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
456 
457  /* callback is only used if the application buffer is not actually copied */
458  // if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
459  // goto out;
460  if (udata->ref_count == 0)
461  goto out;
462 
463  udata->ref_count--;
464 
465  /* checks that there are no references outstanding before deallocating udata */
466  if (udata->ref_count == 0 && udata->fapl_ref_count == 0 &&
467  udata->vfd_ref_count == 0)
468  HDfree(udata);
469 
470  return(SUCCEED);
471 
472 out:
473  return(FAIL);
474 } /* end udata_free */
475 
476 /* End of callbacks definitions for file image operations */
477 
478 
479 #ifdef __cplusplus
480 }
481 #endif
482 
483 #endif /* MED_MEMFILE_H */
udata_copy
static void * udata_copy(void *udata)
Definition: med_memfile.hxx:418
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
udata_free
static herr_t udata_free(void *udata)
Definition: med_memfile.hxx:453
H5LT_file_image_ud_t::fapl_ref_count
int fapl_ref_count
Definition: med_memfile.hxx:34
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
herr_t
int herr_t
Definition: H5public_extract.h:27
H5LT_file_image_ud_t::vfd_image_size
size_t vfd_image_size
Definition: med_memfile.hxx:36
H5LT_file_image_ud_t::app_image_size
size_t app_image_size
Definition: med_memfile.hxx:31
H5LT_file_image_ud_t::flags
unsigned flags
Definition: med_memfile.hxx:38
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
H5LT_file_image_ud_t::ref_count
int ref_count
Definition: med_memfile.hxx:40
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
Definition: med_memfile.hxx:29
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