1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*
15 * Programmer: Raymond Lu <slu@ncsa.uiuc.edu>
16 * August 5, 2002
17 *
18 * Purpose: Compact dataset I/O functions. These routines are similar
19 * H5D_contig_* and H5D_chunk_*.
20 */
21
22 /****************/
23 /* Module Setup */
24 /****************/
25
26 #include "H5Dmodule.h" /* This source code file is part of the H5D module */
27
28
29 /***********/
30 /* Headers */
31 /***********/
32 #include "H5private.h" /* Generic Functions */
33 #include "H5Dpkg.h" /* Dataset functions */
34 #include "H5Eprivate.h" /* Error handling */
35 #include "H5Fprivate.h" /* Files */
36 #include "H5FDprivate.h" /* File drivers */
37 #include "H5FLprivate.h" /* Free Lists */
38 #include "H5Iprivate.h" /* IDs */
39 #include "H5MMprivate.h" /* Memory management */
40 #include "H5Oprivate.h" /* Object headers */
41 #include "H5VMprivate.h" /* Vector and array functions */
42
43
44 /****************/
45 /* Local Macros */
46 /****************/
47
48
49 /******************/
50 /* Local Typedefs */
51 /******************/
52
53
54 /********************/
55 /* Local Prototypes */
56 /********************/
57
58 /* Layout operation callbacks */
59 static herr_t H5D__compact_construct(H5F_t *f, H5D_t *dset);
60 static hbool_t H5D__compact_is_space_alloc(const H5O_storage_t *storage);
61 static herr_t H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
62 hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
63 H5D_chunk_map_t *cm);
64 static ssize_t H5D__compact_readvv(const H5D_io_info_t *io_info,
65 size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
66 size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]);
67 static ssize_t H5D__compact_writevv(const H5D_io_info_t *io_info,
68 size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
69 size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]);
70 static herr_t H5D__compact_flush(H5D_t *dset);
71 static herr_t H5D__compact_dest(H5D_t *dset);
72
73
74 /*********************/
75 /* Package Variables */
76 /*********************/
77
78 /* Compact storage layout I/O ops */
79 const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{
80 H5D__compact_construct,
81 NULL,
82 H5D__compact_is_space_alloc,
83 NULL,
84 H5D__compact_io_init,
85 H5D__contig_read,
86 H5D__contig_write,
87 #ifdef H5_HAVE_PARALLEL
88 NULL,
89 NULL,
90 #endif /* H5_HAVE_PARALLEL */
91 H5D__compact_readvv,
92 H5D__compact_writevv,
93 H5D__compact_flush,
94 NULL,
95 H5D__compact_dest
96 }};
97
98
99 /*******************/
100 /* Local Variables */
101 /*******************/
102
103 /* Declare extern the free list to manage blocks of type conversion data */
104 H5FL_BLK_EXTERN(type_conv);
105
106
107
108 /*-------------------------------------------------------------------------
109 * Function: H5D__compact_fill
110 *
111 * Purpose: Write fill values to a compactly stored dataset.
112 *
113 * Return: Non-negative on success/Negative on failure
114 *
115 * Programmer: Quincey Koziol
116 * May 6, 2007
117 *
118 *-------------------------------------------------------------------------
119 */
120 herr_t
H5D__compact_fill(const H5D_t * dset)121 H5D__compact_fill(const H5D_t *dset)
122 {
123 H5D_fill_buf_info_t fb_info; /* Dataset's fill buffer info */
124 hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
125 herr_t ret_value = SUCCEED; /* Return value */
126
127 FUNC_ENTER_PACKAGE
128
129 /* Check args */
130 HDassert(dset && H5D_COMPACT == dset->shared->layout.type);
131 HDassert(dset->shared->layout.storage.u.compact.buf);
132 HDassert(dset->shared->type);
133 HDassert(dset->shared->space);
134
135 /* Initialize the fill value buffer */
136 /* (use the compact dataset storage buffer as the fill value buffer) */
137 if(H5D__fill_init(&fb_info, dset->shared->layout.storage.u.compact.buf,
138 NULL, NULL, NULL, NULL,
139 &dset->shared->dcpl_cache.fill, dset->shared->type,
140 dset->shared->type_id, (size_t)0, dset->shared->layout.storage.u.compact.size) < 0)
141 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill buffer info")
142 fb_info_init = TRUE;
143
144 /* Check for VL datatype & non-default fill value */
145 if(fb_info.has_vlen_fill_type)
146 /* Fill the buffer with VL datatype fill values */
147 if(H5D__fill_refill_vl(&fb_info, fb_info.elmts_per_buf) < 0)
148 HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't refill fill value buffer")
149
150 done:
151 /* Release the fill buffer info, if it's been initialized */
152 if(fb_info_init && H5D__fill_term(&fb_info) < 0)
153 HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release fill buffer info")
154
155 FUNC_LEAVE_NOAPI(ret_value)
156 } /* end H5D__compact_fill() */
157
158
159 /*-------------------------------------------------------------------------
160 * Function: H5D__compact_construct
161 *
162 * Purpose: Constructs new compact layout information for dataset
163 *
164 * Return: Non-negative on success/Negative on failure
165 *
166 * Programmer: Quincey Koziol
167 * Thursday, May 22, 2008
168 *
169 *-------------------------------------------------------------------------
170 */
171 static herr_t
H5D__compact_construct(H5F_t * f,H5D_t * dset)172 H5D__compact_construct(H5F_t *f, H5D_t *dset)
173 {
174 hssize_t stmp_size; /* Temporary holder for raw data size */
175 hsize_t tmp_size; /* Temporary holder for raw data size */
176 hsize_t max_comp_data_size; /* Max. allowed size of compact data */
177 unsigned u; /* Local index variable */
178 herr_t ret_value = SUCCEED; /* Return value */
179
180 FUNC_ENTER_STATIC
181
182 /* Sanity checks */
183 HDassert(f);
184 HDassert(dset);
185
186 /* Check for invalid dataset dimensions */
187 for(u = 0; u < dset->shared->ndims; u++)
188 if(dset->shared->max_dims[u] > dset->shared->curr_dims[u])
189 HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "extendible compact dataset not allowed")
190
191 /*
192 * Compact dataset is stored in dataset object header message of
193 * layout.
194 */
195 stmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space);
196 HDassert(stmp_size >= 0);
197 tmp_size = H5T_get_size(dset->shared->type);
198 HDassert(tmp_size > 0);
199 tmp_size = tmp_size * (hsize_t)stmp_size;
200 H5_CHECKED_ASSIGN(dset->shared->layout.storage.u.compact.size, size_t, tmp_size, hssize_t);
201
202 /* Verify data size is smaller than maximum header message size
203 * (64KB) minus other layout message fields.
204 */
205 max_comp_data_size = H5O_MESG_MAX_SIZE - H5D__layout_meta_size(f, &(dset->shared->layout), FALSE);
206 if(dset->shared->layout.storage.u.compact.size > max_comp_data_size)
207 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "compact dataset size is bigger than header message maximum size")
208
209 done:
210 FUNC_LEAVE_NOAPI(ret_value)
211 } /* end H5D__compact_construct() */
212
213
214 /*-------------------------------------------------------------------------
215 * Function: H5D__compact_is_space_alloc
216 *
217 * Purpose: Query if space is allocated for layout
218 *
219 * Return: Non-negative on success/Negative on failure
220 *
221 * Programmer: Quincey Koziol
222 * Thursday, January 15, 2009
223 *
224 *-------------------------------------------------------------------------
225 */
226 static hbool_t
H5D__compact_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED * storage)227 H5D__compact_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage)
228 {
229 FUNC_ENTER_STATIC_NOERR
230
231 /* Sanity checks */
232 HDassert(storage);
233
234 /* Compact storage is currently always allocated */
235 FUNC_LEAVE_NOAPI(TRUE)
236 } /* end H5D__compact_is_space_alloc() */
237
238
239 /*-------------------------------------------------------------------------
240 * Function: H5D__compact_io_init
241 *
242 * Purpose: Performs initialization before any sort of I/O on the raw data
243 *
244 * Return: Non-negative on success/Negative on failure
245 *
246 * Programmer: Quincey Koziol
247 * Thursday, March 20, 2008
248 *
249 *-------------------------------------------------------------------------
250 */
251 static herr_t
H5D__compact_io_init(const H5D_io_info_t * io_info,const H5D_type_info_t H5_ATTR_UNUSED * type_info,hsize_t H5_ATTR_UNUSED nelmts,const H5S_t H5_ATTR_UNUSED * file_space,const H5S_t H5_ATTR_UNUSED * mem_space,H5D_chunk_map_t H5_ATTR_UNUSED * cm)252 H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
253 hsize_t H5_ATTR_UNUSED nelmts, const H5S_t H5_ATTR_UNUSED *file_space, const H5S_t H5_ATTR_UNUSED *mem_space,
254 H5D_chunk_map_t H5_ATTR_UNUSED *cm)
255 {
256 FUNC_ENTER_STATIC_NOERR
257
258 io_info->store->compact.buf = io_info->dset->shared->layout.storage.u.compact.buf;
259 io_info->store->compact.dirty = &io_info->dset->shared->layout.storage.u.compact.dirty;
260
261 FUNC_LEAVE_NOAPI(SUCCEED)
262 } /* end H5D__compact_io_init() */
263
264
265 /*-------------------------------------------------------------------------
266 * Function: H5D__compact_readvv
267 *
268 * Purpose: Reads some data vectors from a dataset into a buffer.
269 * The data is in compact dataset. The address is relative
270 * to the beginning address of the dataset. The offsets and
271 * sequence lengths are in bytes.
272 *
273 * Return: Non-negative on success/Negative on failure
274 *
275 * Programmer: Quincey Koziol
276 * May 7, 2003
277 *
278 * Notes:
279 * Offsets in the sequences must be monotonically increasing
280 *
281 *-------------------------------------------------------------------------
282 */
283 static ssize_t
H5D__compact_readvv(const H5D_io_info_t * io_info,size_t dset_max_nseq,size_t * dset_curr_seq,size_t dset_size_arr[],hsize_t dset_offset_arr[],size_t mem_max_nseq,size_t * mem_curr_seq,size_t mem_size_arr[],hsize_t mem_offset_arr[])284 H5D__compact_readvv(const H5D_io_info_t *io_info,
285 size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
286 size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[])
287 {
288 ssize_t ret_value = -1; /* Return value */
289
290 FUNC_ENTER_STATIC
291
292 HDassert(io_info);
293
294 /* Use the vectorized memory copy routine to do actual work */
295 if((ret_value = H5VM_memcpyvv(io_info->u.rbuf, mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr, io_info->store->compact.buf, dset_max_nseq, dset_curr_seq, dset_size_arr, dset_offset_arr)) < 0)
296 HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
297
298 done:
299 FUNC_LEAVE_NOAPI(ret_value)
300 } /* end H5D__compact_readvv() */
301
302
303 /*-------------------------------------------------------------------------
304 * Function: H5D__compact_writevv
305 *
306 * Purpose: Writes some data vectors from a dataset into a buffer.
307 * The data is in compact dataset. The address is relative
308 * to the beginning address for the file. The offsets and
309 * sequence lengths are in bytes. This function only copies
310 * data into the buffer in the LAYOUT struct and mark it
311 * as DIRTY. Later in H5D_close, the data is copied into
312 * header message in memory.
313 *
314 * Return: Non-negative on success/Negative on failure
315 *
316 * Programmer: Quincey Koziol
317 * May 2, 2003
318 *
319 * Notes:
320 * Offsets in the sequences must be monotonically increasing
321 *
322 *-------------------------------------------------------------------------
323 */
324 static ssize_t
H5D__compact_writevv(const H5D_io_info_t * io_info,size_t dset_max_nseq,size_t * dset_curr_seq,size_t dset_size_arr[],hsize_t dset_offset_arr[],size_t mem_max_nseq,size_t * mem_curr_seq,size_t mem_size_arr[],hsize_t mem_offset_arr[])325 H5D__compact_writevv(const H5D_io_info_t *io_info,
326 size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
327 size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[])
328 {
329 ssize_t ret_value = -1; /* Return value */
330
331 FUNC_ENTER_STATIC
332
333 HDassert(io_info);
334
335 /* Use the vectorized memory copy routine to do actual work */
336 if((ret_value = H5VM_memcpyvv(io_info->store->compact.buf, dset_max_nseq, dset_curr_seq, dset_size_arr, dset_offset_arr, io_info->u.wbuf, mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr)) < 0)
337 HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
338
339 /* Mark the compact dataset's buffer as dirty */
340 *io_info->store->compact.dirty = TRUE;
341
342 done:
343 FUNC_LEAVE_NOAPI(ret_value)
344 } /* end H5D__compact_writevv() */
345
346
347 /*-------------------------------------------------------------------------
348 * Function: H5D__compact_flush
349 *
350 * Purpose: Writes dirty compact data to object header
351 *
352 * Return: Non-negative on success/Negative on failure
353 *
354 * Programmer: Quincey Koziol
355 * Monday, July 27, 2009
356 *
357 *-------------------------------------------------------------------------
358 */
359 static herr_t
H5D__compact_flush(H5D_t * dset)360 H5D__compact_flush(H5D_t *dset)
361 {
362 herr_t ret_value = SUCCEED; /* Return value */
363
364 FUNC_ENTER_STATIC
365
366 /* Sanity check */
367 HDassert(dset);
368
369 /* Check if the buffered compact information is dirty */
370 if(dset->shared->layout.storage.u.compact.dirty) {
371 dset->shared->layout.storage.u.compact.dirty = FALSE;
372 if(H5O_msg_write(&(dset->oloc), H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &(dset->shared->layout)) < 0) {
373 dset->shared->layout.storage.u.compact.dirty = TRUE;
374 HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message")
375 }
376 } /* end if */
377
378 done:
379 FUNC_LEAVE_NOAPI(ret_value)
380 } /* end H5D__compact_flush() */
381
382
383 /*-------------------------------------------------------------------------
384 * Function: H5D__compact_dest
385 *
386 * Purpose: Free the compact buffer
387 *
388 * Return: Non-negative on success/Negative on failure
389 *
390 * Programmer: Quincey Koziol
391 * Thursday, Sept 3, 2015
392 *
393 *-------------------------------------------------------------------------
394 */
395 static herr_t
H5D__compact_dest(H5D_t * dset)396 H5D__compact_dest(H5D_t *dset)
397 {
398 FUNC_ENTER_STATIC_NOERR
399
400 /* Sanity check */
401 HDassert(dset);
402
403 /* Free the buffer for the raw data for compact datasets */
404 dset->shared->layout.storage.u.compact.buf = H5MM_xfree(dset->shared->layout.storage.u.compact.buf);
405
406 FUNC_LEAVE_NOAPI(SUCCEED)
407 } /* end H5D__compact_dest() */
408
409
410 /*-------------------------------------------------------------------------
411 * Function: H5D__compact_copy
412 *
413 * Purpose: Copy compact storage raw data from SRC file to DST file.
414 *
415 * Return: Non-negative on success, negative on failure.
416 *
417 * Programmer: Peter Cao
418 * December 11, 2005
419 *
420 *-------------------------------------------------------------------------
421 */
422 herr_t
H5D__compact_copy(H5F_t * f_src,H5O_storage_compact_t * _storage_src,H5F_t * f_dst,H5O_storage_compact_t * storage_dst,H5T_t * dt_src,H5O_copy_t * cpy_info)423 H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *_storage_src, H5F_t *f_dst,
424 H5O_storage_compact_t *storage_dst, H5T_t *dt_src, H5O_copy_t *cpy_info)
425 {
426 hid_t tid_src = -1; /* Datatype ID for source datatype */
427 hid_t tid_dst = -1; /* Datatype ID for destination datatype */
428 hid_t tid_mem = -1; /* Datatype ID for memory datatype */
429 void *buf = NULL; /* Buffer for copying data */
430 void *bkg = NULL; /* Temporary buffer for copying data */
431 void *reclaim_buf = NULL; /* Buffer for reclaiming data */
432 hid_t buf_sid = -1; /* ID for buffer dataspace */
433 H5D_shared_t *shared_fo = (H5D_shared_t *)cpy_info->shared_fo; /* Pointer to the shared struct for dataset object */
434 H5O_storage_compact_t *storage_src = _storage_src; /* Pointer to storage_src */
435 herr_t ret_value = SUCCEED; /* Return value */
436
437 FUNC_ENTER_PACKAGE
438
439 /* Check args */
440 HDassert(f_src);
441 HDassert(storage_src);
442 HDassert(f_dst);
443 HDassert(storage_dst);
444 HDassert(storage_dst->buf);
445 HDassert(dt_src);
446
447 /* If the dataset is open in the file, point to "layout" in the shared struct */
448 if(shared_fo != NULL)
449 storage_src = &(shared_fo->layout.storage.u.compact);
450
451 /* Create datatype ID for src datatype, so it gets freed */
452 if((tid_src = H5I_register(H5I_DATATYPE, dt_src, FALSE)) < 0)
453 HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register source file datatype")
454
455 /* If there's a VLEN source datatype, do type conversion information */
456 if(H5T_detect_class(dt_src, H5T_VLEN, FALSE) > 0) {
457 H5T_path_t *tpath_src_mem, *tpath_mem_dst; /* Datatype conversion paths */
458 H5T_t *dt_dst; /* Destination datatype */
459 H5T_t *dt_mem; /* Memory datatype */
460 H5S_t *buf_space; /* Dataspace describing buffer */
461 size_t buf_size; /* Size of copy buffer */
462 size_t nelmts; /* Number of elements in buffer */
463 size_t src_dt_size; /* Source datatype size */
464 size_t tmp_dt_size; /* Temporary datatype size */
465 size_t max_dt_size; /* Max atatype size */
466 hsize_t buf_dim; /* Dimension for buffer */
467
468 /* create a memory copy of the variable-length datatype */
469 if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
470 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
471 if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem, FALSE)) < 0) {
472 (void)H5T_close_real(dt_mem);
473 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
474 } /* end if */
475
476 /* create variable-length datatype at the destinaton file */
477 if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
478 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
479 if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0) {
480 (void)H5T_close_real(dt_dst);
481 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
482 } /* end if */
483 if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst, FALSE)) < 0) {
484 (void)H5T_close_real(dt_dst);
485 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype")
486 } /* end if */
487
488 /* Set up the conversion functions */
489 if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem)))
490 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
491 if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst)))
492 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes")
493
494 /* Determine largest datatype size */
495 if(0 == (src_dt_size = H5T_get_size(dt_src)))
496 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
497 if(0 == (tmp_dt_size = H5T_get_size(dt_mem)))
498 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
499 max_dt_size = MAX(src_dt_size, tmp_dt_size);
500 if(0 == (tmp_dt_size = H5T_get_size(dt_dst)))
501 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
502 max_dt_size = MAX(max_dt_size, tmp_dt_size);
503
504 /* Set number of whole elements that fit in buffer */
505 if(0 == (nelmts = storage_src->size / src_dt_size))
506 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "element size too large")
507
508 /* Set up number of bytes to copy, and initial buffer size */
509 buf_size = nelmts * max_dt_size;
510
511 /* Create dataspace for number of elements in buffer */
512 buf_dim = nelmts;
513
514 /* Create the space and set the initial extent */
515 if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL)))
516 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
517
518 /* Atomize */
519 if((buf_sid = H5I_register(H5I_DATASPACE, buf_space, FALSE)) < 0) {
520 H5S_close(buf_space);
521 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
522 } /* end if */
523
524 /* Allocate memory for recclaim buf */
525 if(NULL == (reclaim_buf = H5FL_BLK_MALLOC(type_conv, buf_size)))
526 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
527
528 /* Allocate memory for copying the chunk */
529 if(NULL == (buf = H5FL_BLK_MALLOC(type_conv, buf_size)))
530 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
531
532 HDmemcpy(buf, storage_src->buf, storage_src->size);
533
534 /* allocate temporary bkg buff for data conversion */
535 if(NULL == (bkg = H5FL_BLK_MALLOC(type_conv, buf_size)))
536 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
537
538 /* Convert from source file to memory */
539 if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg) < 0)
540 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
541
542 /* Copy into another buffer, to reclaim memory later */
543 HDmemcpy(reclaim_buf, buf, buf_size);
544
545 /* Set background buffer to all zeros */
546 HDmemset(bkg, 0, buf_size);
547
548 /* Convert from memory to destination file */
549 if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg) < 0)
550 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
551
552 HDmemcpy(storage_dst->buf, buf, storage_dst->size);
553
554 if(H5D_vlen_reclaim(tid_mem, buf_space, reclaim_buf) < 0)
555 HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data")
556 } /* end if */
557 else if(H5T_get_class(dt_src, FALSE) == H5T_REFERENCE) {
558 if(f_src != f_dst) {
559 /* Check for expanding references */
560 if(cpy_info->expand_ref) {
561 size_t ref_count;
562
563 /* Determine # of reference elements to copy */
564 ref_count = storage_src->size / H5T_get_size(dt_src);
565
566 /* Copy objects referenced in source buffer to destination file and set destination elements */
567 if(H5O_copy_expand_ref(f_src, storage_src->buf, f_dst,
568 storage_dst->buf, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0)
569 HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute")
570 } /* end if */
571 else
572 /* Reset value to zero */
573 HDmemset(storage_dst->buf, 0, storage_src->size);
574 } /* end if */
575 else
576 /* Type conversion not necessary */
577 HDmemcpy(storage_dst->buf, storage_src->buf, storage_src->size);
578 } /* end if */
579 else
580 /* Type conversion not necessary */
581 HDmemcpy(storage_dst->buf, storage_src->buf, storage_src->size);
582
583 /* Mark destination buffer as dirty */
584 storage_dst->dirty = TRUE;
585
586 done:
587 if(buf_sid > 0 && H5I_dec_ref(buf_sid) < 0)
588 HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't decrement temporary dataspace ID")
589 if(tid_src > 0 && H5I_dec_ref(tid_src) < 0)
590 HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
591 if(tid_dst > 0 && H5I_dec_ref(tid_dst) < 0)
592 HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
593 if(tid_mem > 0 && H5I_dec_ref(tid_mem) < 0)
594 HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
595 if(buf)
596 buf = H5FL_BLK_FREE(type_conv, buf);
597 if(reclaim_buf)
598 reclaim_buf = H5FL_BLK_FREE(type_conv, reclaim_buf);
599 if(bkg)
600 bkg = H5FL_BLK_FREE(type_conv, bkg);
601
602 FUNC_LEAVE_NOAPI(ret_value)
603 } /* end H5D__compact_copy() */
604
605