/src/gdal/netcdf-c-4.7.4/libhdf5/nc4memcb.c
Line | Count | Source |
1 | | /********************************************************************* |
2 | | * Copyright 2018, UCAR/Unidata |
3 | | * See netcdf/COPYRIGHT file for copying and redistribution conditions. |
4 | | * ********************************************************************/ |
5 | | |
6 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
7 | | * Copyright by The HDF Group. * |
8 | | * Copyright by the Board of Trustees of the University of Illinois. * |
9 | | * All rights reserved. * |
10 | | * * |
11 | | * This file is part of HDF5. The full HDF5 copyright notice, including * |
12 | | * terms governing use, modification, and redistribution, is contained in * |
13 | | * the COPYING file, which can be found at the root of the source code * |
14 | | * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * |
15 | | * If you do not have access to either file, you may request a copy from * |
16 | | * help@hdfgroup.org. * |
17 | | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
18 | | |
19 | | /* |
20 | | * @internal Inmemory support |
21 | | * |
22 | | * This code is derived from H5LT.c#H5LTopen_file_image. |
23 | | * In order to make the netcdf inmemory code work, it is necessary |
24 | | * to modify some of the callback functions; specifically |
25 | | * image_malloc, image_realloc, and image_memcpy. |
26 | | * <p> |
27 | | * The changes are directed at allowing the caller to |
28 | | * specify two things. |
29 | | * <ol> |
30 | | * <li> To specify (indirectly) the H5LT_FILE_IMAGE_DONT_COPY flag. |
31 | | * This means that no attempt to realloc the caller provided memory |
32 | | * should be made. This also means that the memory block pointer |
33 | | * provided by the caller will be thesame returned by <em>nc_close_memio()</em>. |
34 | | * <li> The caller overallocates the memory so that there is space |
35 | | * to allow the file to be modified in place. |
36 | | * </ol> |
37 | | * <p> |
38 | | * The existing implementation of H5LTopen_file_image has two flaws |
39 | | * with respect to these properties. |
40 | | * <ol> |
41 | | * <li> The image_realloc callback fails if |
42 | | * H5LT_FILE_IMAGE_DONT_COPY flag is set even if there is room |
43 | | * to allow the memory block to pretend to expand (because |
44 | | * of overallocation). |
45 | | * <li> When the caller attempts to get the final memory block, |
46 | | * the HDF5 library makes a copy, unless theH5LT_FILE_IMAGE_DONT_COPY |
47 | | * flag is set. This is unnecessary. Note that in this situation, |
48 | | * the HDF5 library will use |
49 | | * <em>image_malloc()</em> |
50 | | * followed by |
51 | | * <em>image_memcpy()</em> |
52 | | * </ol> |
53 | | * <p> |
54 | | * So, the callback changes to support this properly are as follows. |
55 | | * <dl> |
56 | | * <dt>image_realloc</dt> |
57 | | * <dd>If there is sufficient space (because of overallocation), |
58 | | * the pretend to realloc and return the incoming memory block |
59 | | * instead of taking the chance of doing a real realloc.</dd> |
60 | | * <dt>image_malloc</dt> |
61 | | * <dd>If the operation being performed is to obtain |
62 | | * the space to copy the final memory, then just return |
63 | | * the original memory block. Note that this case is detectable |
64 | | * because the callback is given the value |
65 | | * H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET.</dd> |
66 | | * <dt>image_memcpy</dt> |
67 | | * <dd>Similar to the image_malloc change. |
68 | | * Namely, if the operation being performed is to copy |
69 | | * out the final memory contents, and the final memory block |
70 | | * is the same as that provided by the caller originally, then |
71 | | * just do nothing. Again, this case can be detected |
72 | | * by the occurrence of H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET.</dd> |
73 | | * </dl> |
74 | | * @author Dennis Heimbigner |
75 | | */ |
76 | | |
77 | | #include <string.h> |
78 | | #include <stdlib.h> |
79 | | #include <assert.h> |
80 | | #include <stdio.h> |
81 | | |
82 | | #include <hdf5.h> |
83 | | #include <hdf5_hl.h> |
84 | | |
85 | | #include "nc4internal.h" |
86 | | |
87 | | #ifndef HDrealloc |
88 | | #define HDrealloc(x,y) realloc(x,y) |
89 | | #endif |
90 | | #ifndef SUCCEED |
91 | 0 | #define SUCCEED 0 |
92 | 0 | #define FAIL -1 |
93 | | #endif |
94 | | #ifndef FALSE |
95 | 0 | #define FALSE 0 |
96 | | #endif |
97 | | |
98 | | #undef TRACE |
99 | | #undef CATCH |
100 | | #undef TRACE_UDATA |
101 | | |
102 | | #ifdef TRACE |
103 | | #define CATCH |
104 | | #endif |
105 | | |
106 | | #ifdef TRACE |
107 | | #include <stdarg.h> |
108 | | static void trace(const char* fcn, H5FD_file_image_op_t op, void* _udata, ...); |
109 | | static void traceend(const char* fcn, void* _udata, uintptr_t retval); |
110 | | static const char* traceop(H5FD_file_image_op_t op); |
111 | | static char* traceflags(int flags); |
112 | | |
113 | | /* In case we do not have variadic macros */ |
114 | | #define TRACE0(fcn,op,udata) trace(fcn,op,udata) |
115 | | #define TRACE1(fcn,op,udata,x1) trace(fcn,op,udata,x1) |
116 | | #define TRACE2(fcn,op,udata,x1,x2) trace(fcn,op,udata,x1,x2) |
117 | | #define TRACE3(fcn,op,udata,x1,x2,x3) trace(fcn,op,udata,x1,x2,x3) |
118 | | #define TRACEEND(fcn,udata,retval) traceend(fcn,udata,(uintptr_t)retval); |
119 | | #else /*!TRACE*/ |
120 | | #define TRACE0(fcn,op,udata) |
121 | | #define TRACE1(fcn,op,udata,x1) |
122 | | #define TRACE2(fcn,op,udata,x1,x2) |
123 | | #define TRACE3(fcn,op,udata,x1,x2,x3) |
124 | | #define TRACEEND(fcn,udata,retval) |
125 | | #endif |
126 | | |
127 | | #ifdef CATCH |
128 | | static void tracefail(const char* fcn); |
129 | | #define TRACEFAIL(fcn) tracefail(fcn) |
130 | | #else |
131 | | #define TRACEFAIL(fcn) |
132 | | #endif |
133 | | |
134 | 0 | #define DEFAULT_CREATE_MEMSIZE ((size_t)1<<16) |
135 | | |
136 | | #ifndef H5LT_FILE_IMAGE_DONT_COPY |
137 | | |
138 | | /* Flag definitions for H5LTopen_file_image() */ |
139 | | #define H5LT_FILE_IMAGE_OPEN_RW 0x0001 /* Open image for read-write */ |
140 | | #define H5LT_FILE_IMAGE_DONT_COPY 0x0002 /* The HDF5 lib won't copy */ |
141 | | /* user supplied image buffer. The same image is open with the core driver. */ |
142 | | #define H5LT_FILE_IMAGE_DONT_RELEASE 0x0004 /* The HDF5 lib won't */ |
143 | | /* deallocate user supplied image buffer. The user application is responsible */ |
144 | | /* for doing so. */ |
145 | | #define H5LT_FILE_IMAGE_ALL 0x0007 |
146 | | |
147 | | #endif /*H5LT_FILE_IMAGE_DONT_COPY*/ |
148 | | |
149 | | |
150 | | #if 0 |
151 | | /* For Lex and Yacc */ |
152 | | #define COL 3 |
153 | | #define LIMIT 512 |
154 | | #define INCREMENT 1024 |
155 | | #define TMP_LEN 256 |
156 | | #define MAX(a,b) (((a)>(b)) ? (a) : (b)) |
157 | | size_t input_len; |
158 | | char *myinput; |
159 | | size_t indent = 0; |
160 | | #endif /*0*/ |
161 | | |
162 | | /* File Image operations |
163 | | |
164 | | A file image is a representation of an HDF5 file in a memory |
165 | | buffer. In order to perform operations on an image in a similar way |
166 | | to a file, the application buffer is copied to a FAPL buffer, which |
167 | | in turn is copied to a VFD buffer. Buffer copying can decrease |
168 | | performance, especially when using large file images. A solution to |
169 | | this issue is to simulate the copying of the application buffer, |
170 | | when actually the same buffer is used for the FAPL and the VFD. |
171 | | This is implemented by using callbacks that simulate the standard |
172 | | functions for memory management (additional callbacks are used for |
173 | | the management of associated data structures). From the application |
174 | | standpoint, a file handle can be obtained from a file image by using |
175 | | the API routine H5LTopen_file_image(). This function takes a flag |
176 | | argument that indicates the HDF5 library how to handle the given image; |
177 | | several flag values can be combined by using the bitwise OR operator. |
178 | | Valid flag values include: |
179 | | |
180 | | H5LT_FILE_IMAGE_OPEN_RW indicates the HDF5 library to open the file |
181 | | image in read/write mode. Default is read-only mode. |
182 | | |
183 | | H5LT_FILE_IMAGE_DONT_COPY indicates the HDF5 library to not copy the |
184 | | supplied user buffer; the same buffer will be handled by the FAPL and |
185 | | the VFD driver. Default operation copies the user buffer to the FAPL and |
186 | | VFD driver. |
187 | | |
188 | | H5LT_FILE_IMAGE_DONT_RELEASE indicates the HDF5 library to not release |
189 | | the buffer handled by the FAPL and the VFD upon closing. This flag value |
190 | | is only applicable when the flag value H5LT_FILE_IMAGE_DONT_COPY is set as |
191 | | well. The application is responsible to release the image buffer. |
192 | | */ |
193 | | |
194 | | /* Data structure to pass application data to callbacks. */ |
195 | | /* Modified to add NC_FILE_INFO_T ptr */ |
196 | | typedef struct { |
197 | | void *app_image_ptr; /* Pointer to application buffer */ |
198 | | size_t app_image_size; /* Size of application buffer */ |
199 | | void *fapl_image_ptr; /* Pointer to FAPL buffer */ |
200 | | size_t fapl_image_size; /* Size of FAPL buffer */ |
201 | | int fapl_ref_count; /* Reference counter for FAPL buffer */ |
202 | | void *vfd_image_ptr; /* Pointer to VFD buffer */ |
203 | | size_t vfd_image_size; /* Size of VFD buffer */ |
204 | | int vfd_ref_count; /* Reference counter for VFD buffer */ |
205 | | unsigned flags; /* Flags indicate how the file image will */ |
206 | | /* be open */ |
207 | | int ref_count; /* Reference counter on udata struct */ |
208 | | NC_FILE_INFO_T* h5; |
209 | | } H5LT_file_image_ud_t; |
210 | | |
211 | | /* Unique id for file name */ |
212 | | static long file_name_counter; |
213 | | |
214 | | /* callbacks prototypes for file image ops */ |
215 | | static void *local_image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *udata); |
216 | | static void *local_image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op, void *udata); |
217 | | static herr_t local_image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *udata); |
218 | | static void *local_udata_copy(void *udata); |
219 | | static herr_t local_udata_free(void *udata); |
220 | | |
221 | | /* Definition of callbacks for file image operations. */ |
222 | | |
223 | | |
224 | | /*------------------------------------------------------------------------- |
225 | | * Function: image_malloc |
226 | | * |
227 | | * Purpose: Simulates malloc() function to avoid copying file images. |
228 | | * The application buffer is set to the buffer on only one FAPL. |
229 | | * Then the FAPL buffer can be copied to other FAPL buffers or |
230 | | * to only one VFD buffer. |
231 | | * |
232 | | * Return: Address of "allocated" buffer, if successful. Otherwise, it returns |
233 | | * NULL. |
234 | | * |
235 | | * Programmer: Christian Chilan |
236 | | * |
237 | | * Date: October 3, 2011 |
238 | | * |
239 | | *------------------------------------------------------------------------- |
240 | | */ |
241 | | static void * |
242 | | local_image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *_udata) |
243 | 0 | { |
244 | 0 | H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata; |
245 | 0 | void * return_value = NULL; |
246 | |
|
247 | 0 | TRACE1("malloc", file_image_op, _udata, size); |
248 | |
|
249 | | #if 0 |
250 | | /* callback is only used if the application buffer is not actually copied */ |
251 | | if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) |
252 | | goto out; |
253 | | #endif |
254 | |
|
255 | 0 | switch ( file_image_op ) { |
256 | | /* the app buffer is "copied" to only one FAPL. Afterwards, FAPLs can be "copied" */ |
257 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET: |
258 | | /* It appears that the fapl memory is never created as we use it, so |
259 | | we expect the udata ptr to be either null or same as the app buffer.*/ |
260 | 0 | assert(udata->fapl_image_ptr == NULL || udata->fapl_image_ptr == udata->app_image_ptr); |
261 | |
|
262 | 0 | if (udata->app_image_ptr == NULL) |
263 | 0 | goto out; |
264 | 0 | if (udata->app_image_size != size) |
265 | 0 | goto out; |
266 | 0 | if (udata->fapl_image_ptr != NULL) |
267 | 0 | goto out; |
268 | 0 | if (udata->fapl_image_size != 0) |
269 | 0 | goto out; |
270 | 0 | if (udata->fapl_ref_count != 0) |
271 | 0 | goto out; |
272 | | |
273 | 0 | udata->fapl_image_ptr = udata->app_image_ptr; |
274 | 0 | udata->fapl_image_size = udata->app_image_size; |
275 | 0 | return_value = udata->fapl_image_ptr; |
276 | 0 | udata->fapl_ref_count++; |
277 | 0 | return_value = udata->fapl_image_ptr; |
278 | 0 | break; |
279 | | |
280 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY: |
281 | 0 | if (udata->fapl_image_ptr == NULL) |
282 | 0 | goto out; |
283 | 0 | if (udata->fapl_image_size != size) |
284 | 0 | goto out; |
285 | 0 | if (udata->fapl_ref_count == 0) |
286 | 0 | goto out; |
287 | | |
288 | 0 | return_value = udata->fapl_image_ptr; |
289 | 0 | udata->fapl_ref_count++; |
290 | 0 | break; |
291 | | |
292 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET: |
293 | 0 | if (udata->fapl_image_ptr == NULL) |
294 | 0 | goto out; |
295 | | /* fake the malloc by returning the current memory */ |
296 | 0 | return_value = udata->fapl_image_ptr; |
297 | 0 | break; |
298 | | |
299 | 0 | case H5FD_FILE_IMAGE_OP_FILE_OPEN: |
300 | | /* FAPL buffer is "copied" to only one VFD buffer */ |
301 | 0 | if (udata->vfd_image_ptr != NULL) |
302 | 0 | goto out; |
303 | 0 | if (udata->vfd_image_size != 0) |
304 | 0 | goto out; |
305 | 0 | if (udata->vfd_ref_count != 0) |
306 | 0 | goto out; |
307 | 0 | if (udata->fapl_image_ptr == NULL) |
308 | 0 | goto out; |
309 | 0 | if (udata->fapl_image_size != size) |
310 | 0 | goto out; |
311 | 0 | if (udata->fapl_ref_count == 0) |
312 | 0 | goto out; |
313 | | |
314 | 0 | udata->vfd_image_ptr = udata->fapl_image_ptr; |
315 | 0 | udata->vfd_image_size = size; |
316 | 0 | udata->vfd_ref_count++; |
317 | 0 | return_value = udata->vfd_image_ptr; |
318 | 0 | break; |
319 | | |
320 | | /* added unused labels to shut the compiler up */ |
321 | 0 | case H5FD_FILE_IMAGE_OP_NO_OP: |
322 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE: |
323 | 0 | case H5FD_FILE_IMAGE_OP_FILE_RESIZE: |
324 | 0 | case H5FD_FILE_IMAGE_OP_FILE_CLOSE: |
325 | 0 | default: |
326 | 0 | goto out; |
327 | 0 | } /* end switch */ |
328 | | |
329 | 0 | TRACEEND("malloc",_udata,return_value); |
330 | |
|
331 | 0 | return(return_value); |
332 | | |
333 | 0 | out: |
334 | 0 | TRACEFAIL("malloc"); |
335 | 0 | return NULL; |
336 | 0 | } /* end image_malloc() */ |
337 | | |
338 | | |
339 | | /*------------------------------------------------------------------------- |
340 | | * Function: image_memcpy |
341 | | * |
342 | | * Purpose: Simulates memcpy() function to avoid copying file images. |
343 | | * The image buffer can be set to only one FAPL buffer, and |
344 | | * "copied" to only one VFD buffer. The FAPL buffer can be |
345 | | * "copied" to other FAPLs buffers. |
346 | | * |
347 | | * Return: The address of the destination buffer, if successful. Otherwise, it |
348 | | * returns NULL. |
349 | | * |
350 | | * Programmer: Christian Chilan |
351 | | * |
352 | | * Date: October 3, 2011 |
353 | | * |
354 | | *------------------------------------------------------------------------- |
355 | | */ |
356 | | static void * |
357 | | local_image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op, |
358 | | void *_udata) |
359 | 0 | { |
360 | 0 | H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata; |
361 | |
|
362 | 0 | TRACE3("memcpy", file_image_op, _udata,dest,src,size); |
363 | |
|
364 | | #if 0 |
365 | | /* callback is only used if the application buffer is not actually copied */ |
366 | | if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) |
367 | | goto out; |
368 | | #endif |
369 | |
|
370 | 0 | switch(file_image_op) { |
371 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET: |
372 | 0 | if (dest != udata->fapl_image_ptr) |
373 | 0 | goto out; |
374 | 0 | if (src != udata->app_image_ptr) |
375 | 0 | goto out; |
376 | 0 | if (size != udata->fapl_image_size) |
377 | 0 | goto out; |
378 | 0 | if (size != udata->app_image_size) |
379 | 0 | goto out; |
380 | 0 | if (udata->fapl_ref_count == 0) |
381 | 0 | goto out; |
382 | 0 | if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) { |
383 | 0 | if(src != dest) { |
384 | 0 | memcpy(dest,src,size); |
385 | | #ifdef TRACE |
386 | | fprintf(stderr,"\t>>>> memcpy(%p,%p,%ld)\n", |
387 | | dest,src,(unsigned long)size); |
388 | | #endif |
389 | 0 | } |
390 | 0 | } |
391 | 0 | break; |
392 | | |
393 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY: |
394 | 0 | if (dest != udata->fapl_image_ptr) |
395 | 0 | goto out; |
396 | 0 | if (src != udata->fapl_image_ptr) |
397 | 0 | goto out; |
398 | 0 | if (size != udata->fapl_image_size) |
399 | 0 | goto out; |
400 | 0 | if (udata->fapl_ref_count < 2) |
401 | 0 | goto out; |
402 | 0 | break; |
403 | | |
404 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET: |
405 | 0 | if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) |
406 | 0 | goto out; |
407 | | /* test: src == dest == original */ |
408 | 0 | if(src != dest || src != udata->fapl_image_ptr) |
409 | 0 | goto out; |
410 | 0 | break; |
411 | | |
412 | 0 | case H5FD_FILE_IMAGE_OP_FILE_OPEN: |
413 | 0 | if (dest != udata->vfd_image_ptr) |
414 | 0 | goto out; |
415 | 0 | if (src != udata->fapl_image_ptr) |
416 | 0 | goto out; |
417 | 0 | if (size != udata->vfd_image_size) |
418 | 0 | goto out; |
419 | 0 | if (size != udata->fapl_image_size) |
420 | 0 | goto out; |
421 | 0 | if (udata->fapl_ref_count == 0) |
422 | 0 | goto out; |
423 | 0 | if (udata->vfd_ref_count != 1) |
424 | 0 | goto out; |
425 | 0 | break; |
426 | | |
427 | | /* added unused labels to shut the compiler up */ |
428 | 0 | case H5FD_FILE_IMAGE_OP_NO_OP: |
429 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE: |
430 | 0 | case H5FD_FILE_IMAGE_OP_FILE_RESIZE: |
431 | 0 | case H5FD_FILE_IMAGE_OP_FILE_CLOSE: |
432 | 0 | default: |
433 | 0 | goto out; |
434 | 0 | } /* end switch */ |
435 | | |
436 | 0 | TRACEEND("memcpy",_udata,dest); |
437 | 0 | return(dest); |
438 | | |
439 | 0 | out: |
440 | 0 | TRACEFAIL("memcpy"); |
441 | 0 | return NULL; |
442 | 0 | } /* end image_memcpy() */ |
443 | | |
444 | | |
445 | | /*------------------------------------------------------------------------- |
446 | | * Function: image_realloc |
447 | | * |
448 | | * Purpose: Reallocates the shared application image buffer and updates data |
449 | | * structures that manage buffer "copying". |
450 | | * |
451 | | * Return: Address of reallocated buffer, if successful. Otherwise, it returns |
452 | | * NULL. |
453 | | * |
454 | | * Programmer: Christian Chilan |
455 | | * |
456 | | * Date: October 3, 2011 |
457 | | * |
458 | | *------------------------------------------------------------------------- |
459 | | */ |
460 | | |
461 | | /* This warning is from H5FDcore.c" |
462 | | Be careful of non-Posix realloc() that doesn't understand |
463 | | what to do when the first argument is null. |
464 | | */ |
465 | | |
466 | | /* Modified: |
467 | | 1. If the realloc new size is <= existing size, |
468 | | then pretend we did a realloc and return success. |
469 | | This avoids unnecessary heap operations. |
470 | | 2. If the H5LT_FILE_IMAGE_DONT_COPY or |
471 | | H5LT_FILE_IMAGE_DONT_RELEASE flag is set and the |
472 | | realloc new size is > existing size, then fail |
473 | | because the realloc() call may change the address |
474 | | of the buffer. The new address cannot be |
475 | | communicated to the application to release it. |
476 | | 3. Otherwise, use realloc(). Note that this may have the |
477 | | side effect of freeing the previous memory chunk. |
478 | | */ |
479 | | static void * |
480 | | local_image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *_udata) |
481 | 0 | { |
482 | 0 | H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata; |
483 | 0 | void * return_value = NULL; |
484 | |
|
485 | 0 | TRACE2("realloc", file_image_op, _udata, ptr, size); |
486 | |
|
487 | | #if 0 |
488 | | /* callback is only used if the application buffer is not actually copied */ |
489 | | if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) |
490 | | goto out; |
491 | | #endif |
492 | | |
493 | | /* realloc() is not allowed if the image is open in read-only mode */ |
494 | 0 | if (!(udata->flags & H5LT_FILE_IMAGE_OPEN_RW)) |
495 | 0 | goto out; |
496 | | |
497 | | /* DONT_COPY => DONT_RELEASE */ |
498 | 0 | assert(((udata->flags & H5LT_FILE_IMAGE_DONT_COPY)?(udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE):1)); |
499 | | |
500 | | /* Note that the fapl pointer is never realloc'd */ |
501 | 0 | if (file_image_op == H5FD_FILE_IMAGE_OP_FILE_RESIZE) { |
502 | |
|
503 | 0 | if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) { /* buffer modification is allowed */ |
504 | | /* Divide code based on whether ptr == NULL or not */ |
505 | 0 | if(ptr == NULL) { |
506 | | /* From realloc man page: If ptr is NULL, then the call is equivalent to malloc(size), |
507 | | for all values of size; if size is equal to zero, and ptr is not NULL, then the call |
508 | | is equivalent to free(ptr). */ |
509 | | /* if the app_image != NULL then free it to simulate effect of realloc */ |
510 | 0 | if(udata->app_image_ptr != NULL) |
511 | 0 | free(udata->app_image_ptr); |
512 | 0 | udata->vfd_image_ptr = malloc(size); |
513 | 0 | udata->vfd_ref_count++; |
514 | 0 | } else { /* ptr != NULL */ |
515 | 0 | if(udata->vfd_image_ptr != ptr) |
516 | 0 | goto out; |
517 | 0 | if (udata->vfd_ref_count != 1) |
518 | 0 | goto out; |
519 | 0 | udata->vfd_image_ptr = realloc(ptr, size); |
520 | 0 | if(NULL == udata->vfd_image_ptr) { |
521 | 0 | LOG((0,"image_realloc: unable to allocate memory block of size: %lu bytes",(unsigned long)size)); |
522 | 0 | goto out; |
523 | 0 | } |
524 | | #ifdef TRACE |
525 | | fprintf(stderr,"\t>>>> realloc(%p,%ld)=>%p\n",ptr,(unsigned long)size,udata->vfd_image_ptr); |
526 | | #endif |
527 | 0 | } |
528 | 0 | udata->vfd_image_size = size; |
529 | | |
530 | | /* Make sure other pointers are consistent */ |
531 | 0 | udata->app_image_ptr = udata->vfd_image_ptr; |
532 | 0 | udata->fapl_image_ptr = udata->vfd_image_ptr; |
533 | |
|
534 | 0 | } else { /* Cannot realloc, so fake it */ |
535 | 0 | if(size <= udata->vfd_image_size) { |
536 | | /* Ok, pretend we did a realloc but just change size*/ |
537 | 0 | udata->vfd_image_size = size; |
538 | 0 | } else |
539 | 0 | goto out; |
540 | 0 | } |
541 | 0 | return_value = udata->vfd_image_ptr; |
542 | 0 | } /* end if */ |
543 | 0 | else |
544 | 0 | goto out; |
545 | | |
546 | 0 | TRACEEND("realloc",_udata,return_value); |
547 | 0 | return(return_value); |
548 | | |
549 | 0 | out: |
550 | 0 | TRACEFAIL("realloc"); |
551 | 0 | return NULL; |
552 | 0 | } /* end local_image_realloc() */ |
553 | | |
554 | | /*------------------------------------------------------------------------- |
555 | | * Function: image_free |
556 | | * |
557 | | * Purpose: Simulates deallocation of FAPL and VFD buffers by decreasing |
558 | | * reference counters. Shared application buffer is actually |
559 | | * deallocated if there are no outstanding references. |
560 | | * |
561 | | * Return: SUCCEED or FAIL |
562 | | * |
563 | | * Programmer: Christian Chilan |
564 | | * |
565 | | * Date: October 3, 2011 |
566 | | * |
567 | | *------------------------------------------------------------------------- |
568 | | */ |
569 | | static herr_t |
570 | | local_image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *_udata) |
571 | 0 | { |
572 | 0 | H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata; |
573 | |
|
574 | 0 | TRACE1("free", file_image_op, _udata, ptr); |
575 | |
|
576 | | #if 0 |
577 | | /* callback is only used if the application buffer is not actually copied */ |
578 | | if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) |
579 | | goto out; |
580 | | #endif |
581 | |
|
582 | 0 | switch(file_image_op) { |
583 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE: |
584 | 0 | if (udata->fapl_image_ptr != ptr) |
585 | 0 | goto out; |
586 | 0 | if (udata->fapl_ref_count == 0) |
587 | 0 | goto out; |
588 | | |
589 | 0 | udata->fapl_ref_count--; |
590 | | |
591 | | /* For the way we use it, it should still be the case that |
592 | | the fapl pointer is same as image_ptr, so we do not need |
593 | | to do anything */ |
594 | 0 | assert(udata->fapl_image_ptr == udata->app_image_ptr); |
595 | | /* clean up */ |
596 | | #if 0 |
597 | | udata->app_image_ptr = NULL; |
598 | | udata->fapl_image_ptr = NULL; |
599 | | #endif |
600 | 0 | break; |
601 | | |
602 | 0 | case H5FD_FILE_IMAGE_OP_FILE_CLOSE: |
603 | 0 | if (udata->vfd_image_ptr != ptr) |
604 | 0 | goto out; |
605 | 0 | if (udata->vfd_ref_count != 1) |
606 | 0 | goto out; |
607 | | |
608 | 0 | udata->vfd_ref_count--; |
609 | |
|
610 | 0 | break; |
611 | | |
612 | | /* added unused labels to keep the compiler quiet */ |
613 | 0 | case H5FD_FILE_IMAGE_OP_NO_OP: |
614 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET: |
615 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY: |
616 | 0 | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET: |
617 | 0 | case H5FD_FILE_IMAGE_OP_FILE_OPEN: |
618 | 0 | case H5FD_FILE_IMAGE_OP_FILE_RESIZE: |
619 | 0 | default: |
620 | 0 | goto out; |
621 | 0 | } /* end switch */ |
622 | | |
623 | 0 | TRACEEND("free",_udata,1); |
624 | 0 | return(SUCCEED); |
625 | | |
626 | 0 | out: |
627 | 0 | TRACEFAIL("free"); |
628 | 0 | return(FAIL); |
629 | 0 | } /* end image_free() */ |
630 | | |
631 | | |
632 | | /*------------------------------------------------------------------------- |
633 | | * Function: udata_copy |
634 | | * |
635 | | * Purpose: Simulates the copying of the user data structure utilized in the |
636 | | * management of the "copying" of file images. |
637 | | * |
638 | | * Return: Address of "newly allocated" structure, if successful. Otherwise, it |
639 | | * returns NULL. |
640 | | * |
641 | | * Programmer: Christian Chilan |
642 | | * |
643 | | * Date: October 3, 2011 |
644 | | * |
645 | | *------------------------------------------------------------------------- |
646 | | */ |
647 | | static void * |
648 | | local_udata_copy(void *_udata) |
649 | 0 | { |
650 | 0 | H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata; |
651 | |
|
652 | 0 | TRACE0("udata_copy", 0, _udata); |
653 | |
|
654 | | #if 0 |
655 | | /* callback is only used if the application buffer is not actually copied */ |
656 | | if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) |
657 | | goto out; |
658 | | #endif |
659 | | |
660 | | /* never copy so we only have one instance */ |
661 | 0 | if (udata->ref_count == 0) |
662 | 0 | goto out; |
663 | 0 | udata->ref_count++; |
664 | |
|
665 | 0 | TRACEEND("udata_copy",udata,1); |
666 | 0 | return(udata); |
667 | | |
668 | 0 | out: |
669 | 0 | TRACEFAIL("udata_copy"); |
670 | 0 | return NULL; |
671 | 0 | } /* end udata_copy */ |
672 | | |
673 | | |
674 | | /*------------------------------------------------------------------------- |
675 | | * Function: udata_free |
676 | | * |
677 | | * Purpose: Simulates deallocation of the user data structure utilized in the |
678 | | * management of the "copying" of file images. The data structure is |
679 | | * actually deallocated when there are no outstanding references. |
680 | | * |
681 | | * Return: SUCCEED or FAIL |
682 | | * |
683 | | * Programmer: Christian Chilan |
684 | | * |
685 | | * Date: October 3, 2011 |
686 | | * |
687 | | *------------------------------------------------------------------------- |
688 | | */ |
689 | | static herr_t |
690 | | local_udata_free(void *_udata) |
691 | 0 | { |
692 | 0 | H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata; |
693 | |
|
694 | 0 | TRACE0("udata_free", 0, _udata); |
695 | |
|
696 | | #if 0 |
697 | | /* callback is only used if the application buffer is not actually copied */ |
698 | | if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY)) |
699 | | goto out; |
700 | | #endif |
701 | |
|
702 | 0 | if (udata->ref_count == 0) |
703 | 0 | goto out; |
704 | 0 | udata->ref_count--; |
705 | |
|
706 | 0 | TRACEEND("udata_free",udata,1); |
707 | 0 | return(SUCCEED); |
708 | | |
709 | 0 | out: |
710 | 0 | TRACEFAIL("udata_free"); |
711 | 0 | return(FAIL); |
712 | 0 | } /* end udata_free */ |
713 | | |
714 | | |
715 | | /* End of callbacks definitions for file image operations */ |
716 | | |
717 | | hid_t |
718 | | NC4_image_init(NC_FILE_INFO_T* h5) |
719 | 0 | { |
720 | 0 | hid_t fapl = -1, file_id = -1; /* HDF5 identifiers */ |
721 | 0 | unsigned file_open_flags = 0;/* Flags for hdf5 open */ |
722 | 0 | char file_name[64]; /* Filename buffer */ |
723 | 0 | size_t alloc_incr; /* Buffer allocation increment */ |
724 | 0 | size_t min_incr = 65536; /* Minimum buffer increment */ |
725 | 0 | double buf_prcnt = 0.1f; /* Percentage of buffer size to set |
726 | | as increment */ |
727 | 0 | unsigned imageflags; |
728 | 0 | int create = 0; |
729 | 0 | H5LT_file_image_ud_t *udata = NULL; /* Pointer to udata structure */ |
730 | |
|
731 | 0 | H5FD_file_image_callbacks_t callbacks = {&local_image_malloc, &local_image_memcpy, |
732 | 0 | &local_image_realloc, &local_image_free, |
733 | 0 | &local_udata_copy, &local_udata_free, |
734 | 0 | (void *)NULL}; |
735 | 0 | imageflags = h5->mem.imageflags; |
736 | 0 | create = h5->mem.created; |
737 | | |
738 | | /* check arguments */ |
739 | 0 | if (h5->mem.memio.memory == NULL) { |
740 | 0 | if(create) { |
741 | 0 | if(h5->mem.memio.size == 0) h5->mem.memio.size = DEFAULT_CREATE_MEMSIZE; |
742 | 0 | h5->mem.memio.memory = malloc(h5->mem.memio.size); |
743 | 0 | } else |
744 | 0 | goto out; /* open requires an input buffer */ |
745 | 0 | } else if(h5->mem.memio.size == 0) |
746 | 0 | goto out; |
747 | | |
748 | | /* Create FAPL to transmit file image */ |
749 | 0 | if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) |
750 | 0 | goto out; |
751 | | |
752 | | /* set allocation increment to a percentage of the supplied buffer size, or |
753 | | * a pre-defined minimum increment value, whichever is larger |
754 | | */ |
755 | 0 | if ((buf_prcnt * h5->mem.memio.size) > min_incr) |
756 | 0 | alloc_incr = (size_t)(buf_prcnt * h5->mem.memio.size); |
757 | 0 | else |
758 | 0 | alloc_incr = min_incr; |
759 | | |
760 | | /* Configure FAPL to use the core file driver */ |
761 | 0 | if (H5Pset_fapl_core(fapl, alloc_incr, FALSE) < 0) |
762 | 0 | goto out; |
763 | | |
764 | | /* Set callbacks for file image ops always */ |
765 | 0 | { |
766 | | /* Allocate buffer to communicate user data to callbacks */ |
767 | 0 | if (NULL == (udata = (H5LT_file_image_ud_t *)calloc(1,sizeof(H5LT_file_image_ud_t)))) |
768 | 0 | goto out; |
769 | | |
770 | | /* Initialize udata with info about app buffer containing file image and flags */ |
771 | 0 | udata->app_image_ptr = h5->mem.memio.memory; |
772 | 0 | udata->app_image_size = h5->mem.memio.size; |
773 | 0 | h5->mem.memio.memory = NULL; /* move control */ |
774 | 0 | h5->mem.memio.size = 0; |
775 | 0 | udata->fapl_image_ptr = NULL; |
776 | 0 | udata->fapl_image_size = 0; |
777 | 0 | udata->fapl_ref_count = 0; |
778 | 0 | udata->vfd_image_ptr = NULL; |
779 | 0 | udata->vfd_image_size = 0; |
780 | 0 | udata->vfd_ref_count = 0; |
781 | 0 | udata->flags = imageflags; |
782 | 0 | udata->ref_count = 1; /* corresponding to the first FAPL */ |
783 | 0 | udata->h5 = h5; |
784 | | |
785 | | /* copy address of udata into callbacks */ |
786 | 0 | callbacks.udata = (void *)udata; |
787 | | /* Set file image callbacks */ |
788 | 0 | if (H5Pset_file_image_callbacks(fapl, &callbacks) < 0) |
789 | 0 | goto out; |
790 | 0 | } |
791 | | |
792 | | /* Assign file image in user buffer to FAPL */ |
793 | 0 | if (H5Pset_file_image(fapl, udata->app_image_ptr, udata->app_image_size) < 0) |
794 | 0 | goto out; |
795 | | |
796 | | /* define a unique file name */ |
797 | 0 | snprintf(file_name, (sizeof(file_name) - 1), "file_image_%ld", file_name_counter++); |
798 | | |
799 | | /* set file open/create flags */ |
800 | 0 | if(create) |
801 | 0 | file_open_flags = H5F_ACC_TRUNC; /* H5Fcreate does not like H5F_ACC_RDWR */ |
802 | 0 | else if (imageflags & H5LT_FILE_IMAGE_OPEN_RW) |
803 | 0 | file_open_flags = H5F_ACC_RDWR; |
804 | 0 | else |
805 | 0 | file_open_flags = H5F_ACC_RDONLY; |
806 | | |
807 | | /* Assign file image in FAPL to the core file driver */ |
808 | 0 | if(create) { |
809 | 0 | if ((file_id = H5Fcreate(file_name, file_open_flags, H5P_DEFAULT, fapl)) < 0) |
810 | 0 | goto out; |
811 | 0 | } else { |
812 | 0 | if ((file_id = H5Fopen(file_name, file_open_flags, fapl)) < 0) |
813 | 0 | goto out; |
814 | 0 | } |
815 | | |
816 | | /* Maintain a backward link */ |
817 | 0 | h5->mem.udata = (void*)udata; |
818 | 0 | udata = NULL; |
819 | |
|
820 | 0 | done: |
821 | | /* Reclaim the fapl object */ |
822 | 0 | H5E_BEGIN_TRY { |
823 | 0 | if(fapl >= 0) |
824 | 0 | H5Pclose(fapl); |
825 | 0 | } H5E_END_TRY; |
826 | | /* Return file identifier */ |
827 | 0 | return file_id; |
828 | | |
829 | 0 | out: |
830 | | /* free up udata only on error */ |
831 | 0 | if(udata != NULL) free(udata); |
832 | 0 | file_id = -1; |
833 | 0 | goto done; |
834 | 0 | } /* end H5LTopen_file_image() */ |
835 | | |
836 | | void |
837 | | NC4_image_finalize(void* _udata) |
838 | 0 | { |
839 | 0 | if(_udata != NULL) { |
840 | 0 | H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t*)_udata; |
841 | | /* checks reference counts before deallocating udata */ |
842 | | #if 0 |
843 | | assert(udata->ref_count == 1 && udata->fapl_ref_count == 0 && udata->vfd_ref_count == 0); |
844 | | if(udata->app_image_ptr != NULL) free(udata->app_image_ptr); |
845 | | if(udata->fapl_image_ptr != NULL) free(udata->fapl_image_ptr); |
846 | | if(udata->vfd_image_ptr != NULL) free(udata->vfd_image_ptr); |
847 | | #endif |
848 | 0 | free(udata); |
849 | | #ifdef TRACE_UDATA |
850 | | fprintf(stderr,"\t>>>> freed: udata=%p\n",udata); |
851 | | #endif |
852 | 0 | } |
853 | 0 | } |
854 | | |
855 | | int |
856 | | NC4_extract_file_image(NC_FILE_INFO_T* h5) |
857 | 0 | { |
858 | 0 | int stat = NC_NOERR; |
859 | 0 | H5LT_file_image_ud_t *udata; |
860 | |
|
861 | 0 | udata = (H5LT_file_image_ud_t *)h5->mem.udata; |
862 | 0 | assert(udata != NULL); |
863 | | |
864 | | /* Fill in h5->mem.memio from udata */ |
865 | 0 | h5->mem.memio.memory = udata->vfd_image_ptr; |
866 | 0 | h5->mem.memio.size = udata->vfd_image_size; |
867 | | |
868 | | /* Move control */ |
869 | 0 | udata->vfd_image_ptr = NULL; |
870 | 0 | udata->vfd_image_size = 0; |
871 | | |
872 | 0 | return stat; |
873 | 0 | } |
874 | | |
875 | | #ifdef TRACE |
876 | | |
877 | | static char* |
878 | | printudata(H5LT_file_image_ud_t* udata) |
879 | | { |
880 | | char buf[8192]; |
881 | | char tmp[8192]; |
882 | | char* flags = ""; |
883 | | |
884 | | buf[0] = '\0'; |
885 | | if(udata == NULL) return strdup(""); |
886 | | strlcat(buf,"flags=",sizeof(buf)); |
887 | | flags = traceflags(udata->flags); |
888 | | strlcat(buf,flags,sizeof(buf)); |
889 | | if(flags != NULL) free(flags); |
890 | | snprintf(tmp,sizeof(tmp)," ref_count=%d",udata->ref_count); |
891 | | strlcat(buf,tmp,sizeof(tmp)); |
892 | | snprintf(tmp,sizeof(tmp)," app=(%p,%lld)",udata->app_image_ptr,(long long)udata->app_image_size); |
893 | | strlcat(buf,tmp,sizeof(tmp)); |
894 | | snprintf(tmp,sizeof(tmp)," fapl=(%p,%lld)[%d]",udata->fapl_image_ptr,(long long)udata->fapl_image_size,udata->fapl_ref_count); |
895 | | strlcat(buf,tmp,sizeof(tmp)); |
896 | | snprintf(tmp,sizeof(tmp)," vfd=(%p,%lld)[%d]",udata->vfd_image_ptr,(long long)udata->vfd_image_size,udata->vfd_ref_count); |
897 | | strlcat(buf,tmp,sizeof(tmp)); |
898 | | return strdup(buf); |
899 | | } |
900 | | |
901 | | static void |
902 | | trace(const char* fcn, H5FD_file_image_op_t op, void* _udata, ...) |
903 | | { |
904 | | H5LT_file_image_ud_t *udata = NULL; |
905 | | va_list ap; |
906 | | char buf[16000]; |
907 | | char tmp[8192]; |
908 | | char* ud; |
909 | | |
910 | | va_start(ap, _udata); /* Requires the last fixed parameter (to get the address) */ |
911 | | udata = (H5LT_file_image_ud_t *)_udata; |
912 | | buf[0] = '\0'; |
913 | | snprintf(tmp,sizeof(tmp),"trace [ %s: op=%s: ",fcn,traceop(op)); |
914 | | strlcat(buf,tmp,sizeof(tmp)); |
915 | | if(strcmp("malloc",fcn)==0) { |
916 | | size_t size = va_arg(ap,size_t); |
917 | | snprintf(tmp,sizeof(tmp),"size=%lld",(long long)size); |
918 | | } else if(strcmp("realloc",fcn)==0) { |
919 | | void* ptr = va_arg(ap,void*); |
920 | | size_t size = va_arg(ap,size_t); |
921 | | snprintf(tmp,sizeof(tmp),"ptr=%p, size=%lld",ptr,(long long)size); |
922 | | } else if(strcmp("free",fcn)==0) { |
923 | | void* ptr = va_arg(ap,void*); |
924 | | snprintf(tmp,sizeof(tmp),"ptr=%p",ptr); |
925 | | } else if(strcmp("memcpy",fcn)==0) { |
926 | | void* dest = va_arg(ap,void*); |
927 | | void* src = va_arg(ap,void*); |
928 | | size_t size = va_arg(ap,size_t); |
929 | | snprintf(tmp,sizeof(tmp),"dest=%p, src=%p, size=%lld",dest,src,(long long)size); |
930 | | } else if(strcmp("udata_copy",fcn)==0) { |
931 | | #ifdef TRACE_UDATA |
932 | | snprintf(tmp,sizeof(tmp),"udata=%p",udata); |
933 | | #endif |
934 | | } else if(strcmp("udata_free",fcn)==0) { |
935 | | #ifdef TRACE_UDATA |
936 | | snprintf(tmp,sizeof(tmp),"udata=%p",udata); |
937 | | #endif |
938 | | } else { |
939 | | snprintf(tmp,sizeof(tmp),"unknown fcn: %s",fcn); |
940 | | } |
941 | | strlcat(buf,tmp,sizeof(buf)); |
942 | | ud = printudata(udata); |
943 | | strlcat(buf,"\n\tudata=",sizeof(buf)); |
944 | | strlcat(buf,ud,sizeof(tmp)); |
945 | | free(ud); |
946 | | strlcat(buf,"\n",sizeof(buf)); |
947 | | va_end(ap); |
948 | | fprintf(stderr,"%s",buf); |
949 | | fflush(stderr); |
950 | | } |
951 | | |
952 | | static void |
953 | | traceend(const char* fcn, void* _udata, uintptr_t retval) |
954 | | { |
955 | | char buf[16000]; |
956 | | char tmp[8192]; |
957 | | char* ud; |
958 | | const char* tab = " "; |
959 | | |
960 | | buf[0] = '\0'; |
961 | | H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata; |
962 | | snprintf(tmp,sizeof(tmp),"%s]: retval=%p",tab,(void*)retval); |
963 | | strlcat(buf,tmp,sizeof(buf)); |
964 | | strlcat(buf," udata=",sizeof(buf)); |
965 | | ud = printudata(udata); |
966 | | strlcat(buf,ud,sizeof(tmp)); |
967 | | free(ud); |
968 | | strlcat(buf,"\n",sizeof(buf)); |
969 | | fprintf(stderr,"%s",buf); |
970 | | fflush(stderr); |
971 | | } |
972 | | |
973 | | #endif /*TRACE*/ |
974 | | |
975 | | #ifdef CATCH |
976 | | static void |
977 | | tracefail(const char* fcn) |
978 | | { |
979 | | fprintf(stderr,"fail: %s\n",fcn); |
980 | | fflush(stderr); |
981 | | } |
982 | | #endif /*CATCH*/ |
983 | | |
984 | | #ifdef TRACE |
985 | | static char* |
986 | | traceflags(int flags) |
987 | | { |
988 | | int i; |
989 | | char buf[8192]; |
990 | | char tmp[8192]; |
991 | | buf[0] = '\0'; |
992 | | for(i=0;i<16;i++) { |
993 | | tmp[0] = '\0'; |
994 | | if((flags & 1<<i) == 0) continue; |
995 | | if(i > 0) strlcat(tmp,"|",sizeof(tmp)); |
996 | | switch(1<<i) { |
997 | | case H5LT_FILE_IMAGE_OPEN_RW: /* 0x0001 Open image for read-write */ |
998 | | strlcat(tmp,"OPEN_RW",sizeof(tmp)); |
999 | | break; |
1000 | | case H5LT_FILE_IMAGE_DONT_COPY: /*0x0002 the HDF5 lib won't copy */ |
1001 | | strlcat(tmp,"DONT_COPY",sizeof(tmp)); |
1002 | | break; |
1003 | | case H5LT_FILE_IMAGE_DONT_RELEASE: /* 0x0004 The HDF5 lib won't |
1004 | | deallocate user supplied image |
1005 | | buffer. The user application |
1006 | | is responsible for doing so. */ |
1007 | | strlcat(tmp,"DONT_RELEASE",sizeof(tmp)); |
1008 | | break; |
1009 | | default: break; |
1010 | | } |
1011 | | strlcat(buf,tmp,sizeof(buf)); |
1012 | | } |
1013 | | return strdup(buf); |
1014 | | } |
1015 | | |
1016 | | static const char* |
1017 | | traceop(H5FD_file_image_op_t op) |
1018 | | { |
1019 | | const char* sop = NULL; |
1020 | | switch ( op ) { |
1021 | | case H5FD_FILE_IMAGE_OP_NO_OP: |
1022 | | sop = "NO_OP"; break; |
1023 | | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET: |
1024 | | sop = "PROPERTY_LIST_SET"; break; |
1025 | | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY: |
1026 | | sop = "PROPERTY_LIST_COPY"; break; |
1027 | | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET: |
1028 | | sop = "PROPERTY_LIST_GET"; break; |
1029 | | case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE: |
1030 | | sop = "PROPERTY_LIST_CLOSE"; break; |
1031 | | case H5FD_FILE_IMAGE_OP_FILE_OPEN: |
1032 | | sop = "FILE_OPEN"; break; |
1033 | | case H5FD_FILE_IMAGE_OP_FILE_RESIZE: |
1034 | | sop = "FILE_RESIZE"; break; |
1035 | | case H5FD_FILE_IMAGE_OP_FILE_CLOSE: |
1036 | | sop = "FILE_CLOSE"; break; |
1037 | | default: break; |
1038 | | } |
1039 | | return sop; |
1040 | | } |
1041 | | |
1042 | | #endif |
1043 | | |