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