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 - 2021 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 */
41 } H5LT_file_image_ud_t;
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 */
83 } H5LT_file_image_ud_t;
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 */
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