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://www.hdfgroup.org/licenses. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*-------------------------------------------------------------------------
15 *
16 * Created: H5Pocpypl.c
17 * Mar 13 2006
18 * Peter Cao
19 *
20 * Purpose: Object copying property list class routines
21 *
22 *-------------------------------------------------------------------------
23 */
24
25 /****************/
26 /* Module Setup */
27 /****************/
28
29 #include "H5Pmodule.h" /* This source code file is part of the H5P module */
30
31 /***********/
32 /* Headers */
33 /***********/
34 #include "H5private.h" /* Generic Functions */
35 #include "H5Eprivate.h" /* Error handling */
36 #include "H5FLprivate.h" /* Free Lists */
37 #include "H5Iprivate.h" /* IDs */
38 #include "H5MMprivate.h" /* Memory management */
39 #include "H5Oprivate.h" /* Object headers */
40 #include "H5Ppkg.h" /* Property lists */
41
42 /****************/
43 /* Local Macros */
44 /****************/
45
46 /* ========= Object Copy properties ============ */
47 /* Definitions for copy options */
48 #define H5O_CPY_OPTION_SIZE sizeof(unsigned)
49 #define H5O_CPY_OPTION_DEF 0
50 #define H5O_CPY_OPTION_ENC H5P__encode_unsigned
51 #define H5O_CPY_OPTION_DEC H5P__decode_unsigned
52 /* Definitions for merge committed dtype list */
53 #define H5O_CPY_MERGE_COMM_DT_LIST_SIZE sizeof(H5O_copy_dtype_merge_list_t *)
54 #define H5O_CPY_MERGE_COMM_DT_LIST_DEF NULL
55 #define H5O_CPY_MERGE_COMM_DT_LIST_SET H5P__ocpy_merge_comm_dt_list_set
56 #define H5O_CPY_MERGE_COMM_DT_LIST_GET H5P__ocpy_merge_comm_dt_list_get
57 #define H5O_CPY_MERGE_COMM_DT_LIST_ENC H5P__ocpy_merge_comm_dt_list_enc
58 #define H5O_CPY_MERGE_COMM_DT_LIST_DEC H5P__ocpy_merge_comm_dt_list_dec
59 #define H5O_CPY_MERGE_COMM_DT_LIST_DEL H5P__ocpy_merge_comm_dt_list_del
60 #define H5O_CPY_MERGE_COMM_DT_LIST_COPY H5P__ocpy_merge_comm_dt_list_copy
61 #define H5O_CPY_MERGE_COMM_DT_LIST_CMP H5P__ocpy_merge_comm_dt_list_cmp
62 #define H5O_CPY_MERGE_COMM_DT_LIST_CLOSE H5P__ocpy_merge_comm_dt_list_close
63 /* Definitions for callback function when completing the search for a matching committed datatype from the
64 * committed dtype list */
65 #define H5O_CPY_MCDT_SEARCH_CB_SIZE sizeof(H5O_mcdt_cb_info_t)
66 #define H5O_CPY_MCDT_SEARCH_CB_DEF \
67 { \
68 NULL, NULL \
69 }
70
71 /******************/
72 /* Local Typedefs */
73 /******************/
74
75 /********************/
76 /* Package Typedefs */
77 /********************/
78
79 /********************/
80 /* Local Prototypes */
81 /********************/
82
83 /* General routines */
84 static H5O_copy_dtype_merge_list_t *H5P__free_merge_comm_dtype_list(H5O_copy_dtype_merge_list_t *dt_list);
85 static herr_t H5P__copy_merge_comm_dt_list(H5O_copy_dtype_merge_list_t **value);
86
87 /* Property class callbacks */
88 static herr_t H5P__ocpy_reg_prop(H5P_genclass_t *pclass);
89
90 /* Property callbacks */
91 static herr_t H5P__ocpy_merge_comm_dt_list_set(hid_t prop_id, const char *name, size_t size, void *value);
92 static herr_t H5P__ocpy_merge_comm_dt_list_get(hid_t prop_id, const char *name, size_t size, void *value);
93 static herr_t H5P__ocpy_merge_comm_dt_list_enc(const void *value, void **_pp, size_t *size, void *udata);
94 static herr_t H5P__ocpy_merge_comm_dt_list_dec(const void **_pp, void *value);
95 static herr_t H5P__ocpy_merge_comm_dt_list_del(hid_t prop_id, const char *name, size_t size, void *value);
96 static herr_t H5P__ocpy_merge_comm_dt_list_copy(const char *name, size_t size, void *value);
97 static int H5P__ocpy_merge_comm_dt_list_cmp(const void *value1, const void *value2, size_t size);
98 static herr_t H5P__ocpy_merge_comm_dt_list_close(const char *name, size_t size, void *value);
99
100 /*********************/
101 /* Package Variables */
102 /*********************/
103
104 /* Object copy property list class library initialization object */
105 const H5P_libclass_t H5P_CLS_OCPY[1] = {{
106 "object copy", /* Class name for debugging */
107 H5P_TYPE_OBJECT_COPY, /* Class type */
108
109 &H5P_CLS_ROOT_g, /* Parent class */
110 &H5P_CLS_OBJECT_COPY_g, /* Pointer to class */
111 &H5P_CLS_OBJECT_COPY_ID_g, /* Pointer to class ID */
112 &H5P_LST_OBJECT_COPY_ID_g, /* Pointer to default property list ID */
113 H5P__ocpy_reg_prop, /* Default property registration routine */
114
115 NULL, /* Class creation callback */
116 NULL, /* Class creation callback info */
117 NULL, /* Class copy callback */
118 NULL, /* Class copy callback info */
119 NULL, /* Class close callback */
120 NULL /* Class close callback info */
121 }};
122
123 /*****************************/
124 /* Library Private Variables */
125 /*****************************/
126
127 /*******************/
128 /* Local Variables */
129 /*******************/
130
131 /* Property value defaults */
132 static const unsigned H5O_def_ocpy_option_g = H5O_CPY_OPTION_DEF; /* Default object copy flags */
133 static const H5O_copy_dtype_merge_list_t *H5O_def_merge_comm_dtype_list_g =
134 H5O_CPY_MERGE_COMM_DT_LIST_DEF; /* Default merge committed dtype list */
135 static const H5O_mcdt_cb_info_t H5O_def_mcdt_cb_g =
136 H5O_CPY_MCDT_SEARCH_CB_DEF; /* Default callback before searching the global list of committed datatypes at
137 destination */
138
139 /* Declare a free list to manage the H5O_copy_dtype_merge_list_t struct */
140 H5FL_DEFINE(H5O_copy_dtype_merge_list_t);
141
142 /*-------------------------------------------------------------------------
143 * Function: H5P__ocpy_reg_prop
144 *
145 * Purpose: Initialize the object copy property list class
146 *
147 * Return: Non-negative on success/Negative on failure
148 *
149 * Programmer: Quincey Koziol
150 * October 31, 2006
151 *-------------------------------------------------------------------------
152 */
153 static herr_t
H5P__ocpy_reg_prop(H5P_genclass_t * pclass)154 H5P__ocpy_reg_prop(H5P_genclass_t *pclass)
155 {
156 herr_t ret_value = SUCCEED; /* Return value */
157
158 FUNC_ENTER_STATIC
159
160 /* Register copy options property */
161 if (H5P__register_real(pclass, H5O_CPY_OPTION_NAME, H5O_CPY_OPTION_SIZE, &H5O_def_ocpy_option_g, NULL,
162 NULL, NULL, H5O_CPY_OPTION_ENC, H5O_CPY_OPTION_DEC, NULL, NULL, NULL, NULL) < 0)
163 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
164
165 /* Register merge named dtype list property */
166 if (H5P__register_real(pclass, H5O_CPY_MERGE_COMM_DT_LIST_NAME, H5O_CPY_MERGE_COMM_DT_LIST_SIZE,
167 &H5O_def_merge_comm_dtype_list_g, NULL, H5O_CPY_MERGE_COMM_DT_LIST_SET,
168 H5O_CPY_MERGE_COMM_DT_LIST_GET, H5O_CPY_MERGE_COMM_DT_LIST_ENC,
169 H5O_CPY_MERGE_COMM_DT_LIST_DEC, H5O_CPY_MERGE_COMM_DT_LIST_DEL,
170 H5O_CPY_MERGE_COMM_DT_LIST_COPY, H5O_CPY_MERGE_COMM_DT_LIST_CMP,
171 H5O_CPY_MERGE_COMM_DT_LIST_CLOSE) < 0)
172 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
173
174 /* Register property for callback when completing the search for a matching named datatype from the named
175 * dtype list */
176 /* (Note: this property should not have an encode/decode callback -QAK) */
177 if (H5P__register_real(pclass, H5O_CPY_MCDT_SEARCH_CB_NAME, H5O_CPY_MCDT_SEARCH_CB_SIZE,
178 &H5O_def_mcdt_cb_g, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
179 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
180
181 done:
182 FUNC_LEAVE_NOAPI(ret_value)
183 } /* end H5P__ocpy_reg_prop() */
184
185 /*-------------------------------------------------------------------------
186 * Function: H5P__free_merge_comm_dtype_list
187 *
188 * Purpose: Frees the provided merge named dtype list
189 *
190 * Return: NULL
191 *
192 * Programmer: Neil Fortner
193 * October 27, 2011
194 *
195 *-------------------------------------------------------------------------
196 */
197 static H5O_copy_dtype_merge_list_t *
H5P__free_merge_comm_dtype_list(H5O_copy_dtype_merge_list_t * dt_list)198 H5P__free_merge_comm_dtype_list(H5O_copy_dtype_merge_list_t *dt_list)
199 {
200 FUNC_ENTER_STATIC_NOERR
201
202 /* Free the list */
203 while (dt_list) {
204 H5O_copy_dtype_merge_list_t *tmp_node;
205
206 tmp_node = dt_list->next;
207
208 (void)H5MM_xfree(dt_list->path);
209 (void)H5FL_FREE(H5O_copy_dtype_merge_list_t, dt_list);
210
211 dt_list = tmp_node;
212 } /* end while */
213
214 FUNC_LEAVE_NOAPI(NULL);
215 } /* H5P__free_merge_comm_dtype_list */
216
217 /*--------------------------------------------------------------------------
218 * Function: H5P__copy_merge_comm_dt_list
219 *
220 * Purpose: Copy a merge committed datatype list
221 *
222 * Return: Success: Non-negative
223 * Failure: Negative
224 *
225 * Programmer: Quincey Koziol
226 * Wednesday, September 2, 2015
227 *
228 *--------------------------------------------------------------------------
229 */
230 static herr_t
H5P__copy_merge_comm_dt_list(H5O_copy_dtype_merge_list_t ** value)231 H5P__copy_merge_comm_dt_list(H5O_copy_dtype_merge_list_t **value)
232 {
233 const H5O_copy_dtype_merge_list_t *src_dt_list; /* Source merge named datatype lists */
234 H5O_copy_dtype_merge_list_t * dst_dt_list = NULL; /* Destination merge named datatype lists */
235 H5O_copy_dtype_merge_list_t * dst_dt_list_tail = NULL,
236 *tmp_dt_list = NULL; /* temporary merge named datatype lists */
237 herr_t ret_value = SUCCEED;
238
239 FUNC_ENTER_STATIC
240
241 /* Sanity check */
242 HDassert(value);
243
244 /* Make copy of merge committed dtype list */
245 src_dt_list = *value;
246 while (src_dt_list) {
247 /* Copy src_dt_list */
248 if (NULL == (tmp_dt_list = H5FL_CALLOC(H5O_copy_dtype_merge_list_t)))
249 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed")
250 if (NULL == (tmp_dt_list->path = H5MM_strdup(src_dt_list->path)))
251 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed")
252
253 /* Add copied node to dest dtype list */
254 if (dst_dt_list_tail) {
255 dst_dt_list_tail->next = tmp_dt_list;
256 dst_dt_list_tail = tmp_dt_list;
257 } /* end if */
258 else {
259 dst_dt_list = tmp_dt_list;
260 dst_dt_list_tail = tmp_dt_list;
261 } /* end else */
262 tmp_dt_list = NULL;
263
264 /* Advance src_dt_list pointer */
265 src_dt_list = src_dt_list->next;
266 } /* end while */
267
268 /* Set the merge named dtype list property for the destination property list */
269 *value = dst_dt_list;
270
271 done:
272 if (ret_value < 0) {
273 dst_dt_list = H5P__free_merge_comm_dtype_list(dst_dt_list);
274 if (tmp_dt_list) {
275 tmp_dt_list->path = (char *)H5MM_xfree(tmp_dt_list->path);
276 tmp_dt_list = H5FL_FREE(H5O_copy_dtype_merge_list_t, tmp_dt_list);
277 } /* end if */
278 } /* end if */
279
280 FUNC_LEAVE_NOAPI(ret_value)
281 } /* end H5P__copy_merge_comm_dt_list() */
282
283 /*-------------------------------------------------------------------------
284 * Function: H5P__ocpy_merge_comm_dt_list_set
285 *
286 * Purpose: Copies a merge committed datatype list property when it's set for a property list
287 *
288 * Return: Success: Non-negative
289 * Failure: Negative
290 *
291 * Programmer: Quincey Koziol
292 * Wednesday, Sept 2, 2015
293 *
294 *-------------------------------------------------------------------------
295 */
296 static herr_t
H5P__ocpy_merge_comm_dt_list_set(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)297 H5P__ocpy_merge_comm_dt_list_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
298 size_t H5_ATTR_UNUSED size, void *value)
299 {
300 herr_t ret_value = SUCCEED; /* Return value */
301
302 FUNC_ENTER_STATIC
303
304 /* Sanity check */
305 HDassert(value);
306
307 /* Make copy of merge committed dtype list */
308 if (H5P__copy_merge_comm_dt_list((H5O_copy_dtype_merge_list_t **)value) < 0)
309 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy merge committed dtype list")
310
311 done:
312 FUNC_LEAVE_NOAPI(ret_value)
313 } /* end H5P__ocpy_merge_comm_dt_list_set() */
314
315 /*-------------------------------------------------------------------------
316 * Function: H5P__ocpy_merge_comm_dt_list_get
317 *
318 * Purpose: Copies a merge committed datatype list property when it's retrieved from a property list
319 *
320 * Return: Success: Non-negative
321 * Failure: Negative
322 *
323 * Programmer: Quincey Koziol
324 * Wednesday, Sept 2, 2015
325 *
326 *-------------------------------------------------------------------------
327 */
328 static herr_t
H5P__ocpy_merge_comm_dt_list_get(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)329 H5P__ocpy_merge_comm_dt_list_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
330 size_t H5_ATTR_UNUSED size, void *value)
331 {
332 herr_t ret_value = SUCCEED; /* Return value */
333
334 FUNC_ENTER_STATIC
335
336 /* Sanity check */
337 HDassert(value);
338
339 /* Make copy of merge committed dtype list */
340 if (H5P__copy_merge_comm_dt_list((H5O_copy_dtype_merge_list_t **)value) < 0)
341 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy merge committed dtype list")
342
343 done:
344 FUNC_LEAVE_NOAPI(ret_value)
345 } /* end H5P__ocpy_merge_comm_dt_list_get() */
346
347 /*-------------------------------------------------------------------------
348 * Function: H5P__ocpy_merge_comm_dt_list_enc
349 *
350 * Purpose: Callback routine which is called whenever the common
351 * datatype property in the object copy property list is
352 * decoded.
353 *
354 * Return: Success: Non-negative
355 * Failure: Negative
356 *
357 * Programmer: Quincey Koziol
358 * Friday, August 31, 2012
359 *
360 *-------------------------------------------------------------------------
361 */
362 static herr_t
H5P__ocpy_merge_comm_dt_list_enc(const void * value,void ** _pp,size_t * size,void * udata)363 H5P__ocpy_merge_comm_dt_list_enc(const void *value, void **_pp, size_t *size, void* udata)
364 {
365 const H5O_copy_dtype_merge_list_t *const *dt_list_ptr = (const H5O_copy_dtype_merge_list_t *const *)value;
366 uint8_t ** pp = (uint8_t **)_pp;
367 const H5O_copy_dtype_merge_list_t * dt_list; /* Pointer to merge named datatype list */
368 size_t len; /* Length of path component */
369 (void)udata;
370
371 FUNC_ENTER_STATIC_NOERR
372
373 HDassert(dt_list_ptr);
374 HDassert(size);
375
376 /* Iterate over merge committed dtype list */
377 dt_list = *dt_list_ptr;
378 while (dt_list) {
379 /* Get length of encoded path */
380 len = HDstrlen(dt_list->path) + 1;
381
382 /* Encode merge committed dtype list */
383 if (*pp) {
384 H5MM_memcpy(*(char **)pp, dt_list->path, len);
385 *pp += len;
386 } /* end if */
387
388 /* Increment the size of the buffer */
389 *size += len;
390
391 /* Advance to the next node */
392 dt_list = dt_list->next;
393 } /* end while */
394
395 /* Encode the terminator for the string sequence */
396 if (*pp)
397 *(*pp)++ = (uint8_t)'\0';
398
399 /* Account for the string sequence terminator */
400 *size += 1;
401
402 FUNC_LEAVE_NOAPI(SUCCEED)
403 } /* end H5P__ocpy_merge_comm_dt_list_enc() */
404
405 /*-------------------------------------------------------------------------
406 * Function: H5P__ocpy_merge_comm_dt_list_dec
407 *
408 * Purpose: Callback routine which is called whenever the common
409 * datatype property in the dataset access property list is
410 * decoded.
411 *
412 * Return: Success: Non-negative
413 * Failure: Negative
414 *
415 * Programmer: Quincey Koziol
416 * Friday, August 31, 2012
417 *
418 *-------------------------------------------------------------------------
419 */
420 static herr_t
H5P__ocpy_merge_comm_dt_list_dec(const void ** _pp,void * _value)421 H5P__ocpy_merge_comm_dt_list_dec(const void **_pp, void *_value)
422 {
423 H5O_copy_dtype_merge_list_t **dt_list =
424 (H5O_copy_dtype_merge_list_t **)_value; /* Pointer to merge named datatype list */
425 const uint8_t ** pp = (const uint8_t **)_pp;
426 H5O_copy_dtype_merge_list_t *dt_list_tail = NULL,
427 *tmp_dt_list = NULL; /* temporary merge named datatype lists */
428 size_t len; /* Length of path component */
429 herr_t ret_value = SUCCEED; /* Return value */
430
431 FUNC_ENTER_STATIC
432
433 /* Sanity check */
434 HDassert(pp);
435 HDassert(*pp);
436 HDassert(dt_list);
437
438 /* Start off with NULL (default value) */
439 *dt_list = NULL;
440
441 /* Decode the string sequence */
442 len = HDstrlen(*(const char **)pp);
443 while (len > 0) {
444 /* Create new node & duplicate string */
445 if (NULL == (tmp_dt_list = H5FL_CALLOC(H5O_copy_dtype_merge_list_t)))
446 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed")
447 if (NULL == (tmp_dt_list->path = H5MM_strdup(*(const char **)pp)))
448 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed")
449 *pp += len + 1;
450 HDassert(len == HDstrlen(tmp_dt_list->path));
451
452 /* Add copied node to dtype list */
453 if (dt_list_tail) {
454 dt_list_tail->next = tmp_dt_list;
455 dt_list_tail = tmp_dt_list;
456 } /* end if */
457 else {
458 *dt_list = tmp_dt_list;
459 dt_list_tail = tmp_dt_list;
460 } /* end else */
461 tmp_dt_list = NULL;
462
463 /* Compute length of next string */
464 len = HDstrlen(*(const char **)pp);
465 } /* end while */
466
467 /* Advance past terminator for string sequence */
468 *pp += 1;
469
470 done:
471 if (ret_value < 0) {
472 *dt_list = H5P__free_merge_comm_dtype_list(*dt_list);
473 if (tmp_dt_list) {
474 tmp_dt_list->path = (char *)H5MM_xfree(tmp_dt_list->path);
475 tmp_dt_list = H5FL_FREE(H5O_copy_dtype_merge_list_t, tmp_dt_list);
476 } /* end if */
477 } /* end if */
478
479 FUNC_LEAVE_NOAPI(ret_value)
480 } /* H5P__ocpy_merge_comm_dt_list_dec() */
481
482 /*--------------------------------------------------------------------------
483 * Function: H5P__ocpy_merge_comm_dt_list_del
484 *
485 * Purpose: Frees memory used to store the merge committed datatype list property
486 *
487 * Return: Success: Non-negative
488 * Failure: Negative
489 *
490 * Programmer: Quincey Koziol
491 * Wednesday, September 2, 2015
492 *
493 *--------------------------------------------------------------------------
494 */
495 static herr_t
H5P__ocpy_merge_comm_dt_list_del(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)496 H5P__ocpy_merge_comm_dt_list_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
497 size_t H5_ATTR_UNUSED size, void *value)
498 {
499 FUNC_ENTER_STATIC_NOERR
500
501 /* Sanity check */
502 HDassert(value);
503
504 /* Free the merge named dtype list */
505 H5P__free_merge_comm_dtype_list(*(H5O_copy_dtype_merge_list_t **)value);
506
507 FUNC_LEAVE_NOAPI(SUCCEED)
508 } /* end H5P__ocpy_merge_comm_dt_list_del() */
509
510 /*--------------------------------------------------------------------------
511 * Function: H5P__ocpy_merge_comm_dt_list_copy
512 *
513 * Purpose: Copy the merge committed datatype list
514 *
515 * Return: Success: Non-negative
516 * Failure: Negative
517 *
518 * Programmer: Quincey Koziol
519 * Friday, August 31, 2012
520 *
521 *--------------------------------------------------------------------------
522 */
523 static herr_t
H5P__ocpy_merge_comm_dt_list_copy(const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)524 H5P__ocpy_merge_comm_dt_list_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
525 {
526 herr_t ret_value = SUCCEED;
527
528 FUNC_ENTER_STATIC
529
530 /* Sanity check */
531 HDassert(value);
532
533 /* Make copy of merge committed dtype list */
534 if (H5P__copy_merge_comm_dt_list((H5O_copy_dtype_merge_list_t **)value) < 0)
535 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy merge committed dtype list")
536
537 done:
538 FUNC_LEAVE_NOAPI(ret_value)
539 } /* end H5P__ocpy_merge_comm_dt_list_copy() */
540
541 /*-------------------------------------------------------------------------
542 * Function: H5P__ocpy_merge_comm_dt_list_cmp
543 *
544 * Purpose: Callback routine which is called whenever the merge
545 * named dtype property in the object copy property list
546 * is compared.
547 *
548 * Return: positive if VALUE1 is greater than VALUE2, negative if
549 * VALUE2 is greater than VALUE1 and zero if VALUE1 and
550 * VALUE2 are equal.
551 *
552 * Programmer: Neil Fortner
553 * Friday, October 28, 2011
554 *
555 *-------------------------------------------------------------------------
556 */
557 static int
H5P__ocpy_merge_comm_dt_list_cmp(const void * _dt_list1,const void * _dt_list2,size_t H5_ATTR_UNUSED size)558 H5P__ocpy_merge_comm_dt_list_cmp(const void *_dt_list1, const void *_dt_list2, size_t H5_ATTR_UNUSED size)
559 {
560 const H5O_copy_dtype_merge_list_t *dt_list1 = *(H5O_copy_dtype_merge_list_t *const *)
561 _dt_list1, /* Create local aliases for values */
562 *dt_list2 = *(H5O_copy_dtype_merge_list_t *const *)_dt_list2;
563 herr_t ret_value = 0; /* Return value */
564
565 FUNC_ENTER_STATIC_NOERR
566
567 /* Sanity check */
568 HDassert(_dt_list1);
569 HDassert(_dt_list2);
570 HDassert(size == sizeof(H5O_copy_dtype_merge_list_t *));
571
572 /* Walk through the lists, comparing each path. For the lists to be the
573 * same, the paths must be in the same order. */
574 while (dt_list1 && dt_list2) {
575 HDassert(dt_list1->path);
576 HDassert(dt_list2->path);
577
578 /* Compare paths */
579 ret_value = HDstrcmp(dt_list1->path, dt_list2->path);
580 if (ret_value != 0)
581 HGOTO_DONE(ret_value)
582
583 /* Advance to next node */
584 dt_list1 = dt_list1->next;
585 dt_list2 = dt_list2->next;
586 } /* end while */
587
588 /* Check if one list is longer than the other */
589 if (dt_list1)
590 HGOTO_DONE(1)
591 if (dt_list2)
592 HGOTO_DONE(-1)
593
594 done:
595 FUNC_LEAVE_NOAPI(ret_value)
596 } /* end H5P__ocpy_merge_comm_dt_list_cmp() */
597
598 /*--------------------------------------------------------------------------
599 * Function: H5P__ocpy_merge_comm_dt_list_close
600 *
601 * Purpose: Close the merge common datatype list property
602 *
603 * Return: Success: Non-negative
604 * Failure: Negative
605 *
606 * Programmer: Quincey Koziol
607 * Friday, August 31, 2012
608 *
609 *---------------------------------------------------------------------------
610 */
611 static herr_t
H5P__ocpy_merge_comm_dt_list_close(const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)612 H5P__ocpy_merge_comm_dt_list_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
613 {
614 FUNC_ENTER_STATIC_NOERR
615
616 HDassert(value);
617
618 /* Free the merge named dtype list */
619 H5P__free_merge_comm_dtype_list(*(H5O_copy_dtype_merge_list_t **)value);
620
621 FUNC_LEAVE_NOAPI(SUCCEED)
622 } /* end H5P__ocpy_merge_comm_dt_list_close() */
623
624 /*-------------------------------------------------------------------------
625 * Function: H5Pset_copy_object
626 *
627 * Purpose: Set properties when copying an object (group, dataset, and datatype)
628 * from one location to another
629 *
630 * Usage: H5Pset_copy_group(plist_id, cpy_option)
631 * hid_t plist_id; IN: Property list to copy object
632 * unsigned cpy_option; IN: Options to copy object such as
633 * H5O_COPY_SHALLOW_HIERARCHY_FLAG -- Copy only immediate members
634 * H5O_COPY_EXPAND_SOFT_LINK_FLAG -- Expand soft links into new objects/
635 * H5O_COPY_EXPAND_EXT_LINK_FLAG -- Expand external links into new objects
636 * H5O_COPY_EXPAND_REFERENCE_FLAG -- Copy objects that are pointed by references
637 * H5O_COPY_WITHOUT_ATTR_FLAG -- Copy object without copying attributes
638 *
639 * Return: Non-negative on success/Negative on failure
640 *
641 * Programmer: Peter Cao
642 * March 13, 2006
643 *-------------------------------------------------------------------------
644 */
645 herr_t
H5Pset_copy_object(hid_t plist_id,unsigned cpy_option)646 H5Pset_copy_object(hid_t plist_id, unsigned cpy_option)
647 {
648 H5P_genplist_t *plist; /* Property list pointer */
649 herr_t ret_value = SUCCEED; /* Return value */
650
651 FUNC_ENTER_API(FAIL)
652 H5TRACE2("e", "iIu", plist_id, cpy_option);
653
654 /* Check parameters */
655 if (cpy_option & ~H5O_COPY_ALL)
656 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown option specified")
657
658 /* Get the plist structure */
659 if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
660 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
661
662 /* Set value */
663 if (H5P_set(plist, H5O_CPY_OPTION_NAME, &cpy_option) < 0)
664 HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set copy object flag")
665
666 done:
667 FUNC_LEAVE_API(ret_value)
668 } /* end H5Pset_copy_object() */
669
670 /*-------------------------------------------------------------------------
671 * Function: H5Pget_copy_object
672 *
673 * Purpose: Returns the cpy_option, which is set for H5Ocopy(hid_t loc_id,
674 * const char* name, ... ) for copying objects
675 *
676 * Return: Non-negative on success/Negative on failure
677 *
678 * Programmer: Peter Cao
679 * March 13, 2006
680 *-------------------------------------------------------------------------
681 */
682 herr_t
H5Pget_copy_object(hid_t plist_id,unsigned * cpy_option)683 H5Pget_copy_object(hid_t plist_id, unsigned *cpy_option /*out*/)
684 {
685 H5P_genplist_t *plist; /* Property list pointer */
686 herr_t ret_value = SUCCEED; /* return value */
687
688 FUNC_ENTER_API(FAIL)
689 H5TRACE2("e", "ix", plist_id, cpy_option);
690
691 /* Get the plist structure */
692 if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
693 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
694
695 /* Get values */
696 if (cpy_option)
697 if (H5P_get(plist, H5O_CPY_OPTION_NAME, cpy_option) < 0)
698 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object copy flag")
699
700 done:
701 FUNC_LEAVE_API(ret_value)
702 } /* end H5Pget_copy_object() */
703
704 /*-------------------------------------------------------------------------
705 * Function: H5Padd_merge_committed_dtype_path
706 *
707 * Purpose: Adds path to the list of paths to search first in the
708 * target file when merging committed datatypes during H5Ocopy
709 * (i.e. when using the H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG flag
710 * as set by H5Pset_copy_object). If the source named
711 * dataype is not found in the list of paths created by this
712 * function, the entire file will be searched.
713 *
714 * Usage: H5Padd_merge_committed_dtype_path(plist_id, path)
715 * hid_t plist_id; IN: Property list to copy object
716 * const char *path; IN: Path to add to list
717 *
718 * Return: Non-negative on success/Negative on failure
719 *
720 * Programmer: Neil Fortner
721 * October 27, 2011
722 *-------------------------------------------------------------------------
723 */
724 herr_t
H5Padd_merge_committed_dtype_path(hid_t plist_id,const char * path)725 H5Padd_merge_committed_dtype_path(hid_t plist_id, const char *path)
726 {
727 H5P_genplist_t * plist; /* Property list pointer */
728 H5O_copy_dtype_merge_list_t *old_list; /* Merge committed dtype list currently present */
729 H5O_copy_dtype_merge_list_t *new_obj = NULL; /* New object to add to list */
730 herr_t ret_value = SUCCEED; /* Return value */
731
732 FUNC_ENTER_API(FAIL)
733 H5TRACE2("e", "i*s", plist_id, path);
734
735 /* Check parameters */
736 if (!path)
737 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no path specified")
738 if (path[0] == '\0')
739 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "path is empty string")
740
741 /* Get the plist structure */
742 if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
743 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
744
745 /* Get dtype list */
746 if (H5P_peek(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &old_list) < 0)
747 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge named dtype list")
748
749 /* Add the new path to the list */
750 if (NULL == (new_obj = H5FL_CALLOC(H5O_copy_dtype_merge_list_t)))
751 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
752 if (NULL == (new_obj->path = H5MM_strdup(path)))
753 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
754 new_obj->next = old_list;
755
756 /* Update the list stored in the property list */
757 if (H5P_poke(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &new_obj) < 0)
758 HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set merge named dtype list")
759
760 done:
761 if (ret_value < 0)
762 if (new_obj) {
763 new_obj->path = (char *)H5MM_xfree(new_obj->path);
764 new_obj = H5FL_FREE(H5O_copy_dtype_merge_list_t, new_obj);
765 } /* end if */
766
767 FUNC_LEAVE_API(ret_value)
768 } /* end H5Padd_merge_committed_dtype_path() */
769
770 /*-------------------------------------------------------------------------
771 * Function: H5Pfree_merge_committed_dtype_paths
772 *
773 * Purpose: Frees and clears the list of paths created by
774 * H5Padd_merge_committed_dtype_path. A new list may then be
775 * created by calling H5Padd_merge_committed_dtype_path again.
776 *
777 * Usage: H5Pfree_merge_committed_dtype_paths(plist_id)
778 * hid_t plist_id; IN: Property list to copy object
779 *
780 * Return: Non-negative on success/Negative on failure
781 *
782 * Programmer: Neil Fortner
783 * October 27, 2011
784 *-------------------------------------------------------------------------
785 */
786 herr_t
H5Pfree_merge_committed_dtype_paths(hid_t plist_id)787 H5Pfree_merge_committed_dtype_paths(hid_t plist_id)
788 {
789 H5P_genplist_t * plist; /* Property list pointer */
790 H5O_copy_dtype_merge_list_t *dt_list; /* Merge committed dtype list currently present */
791 herr_t ret_value = SUCCEED; /* Return value */
792
793 FUNC_ENTER_API(FAIL)
794 H5TRACE1("e", "i", plist_id);
795
796 /* Get the plist structure */
797 if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
798 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
799
800 /* Get dtype list */
801 if (H5P_peek(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
802 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge committed dtype list")
803
804 /* Free dtype list */
805 dt_list = H5P__free_merge_comm_dtype_list(dt_list);
806
807 /* Update the list stored in the property list (to NULL) */
808 if (H5P_poke(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
809 HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set merge committed dtype list")
810
811 done:
812 FUNC_LEAVE_API(ret_value)
813 } /* end H5Pfree_merge_committed_dtype_paths() */
814
815 /*-------------------------------------------------------------------------
816 * Function: H5Pset_mcdt_search_cb
817 *
818 * Purpose: Set the callback function when a matching committed datatype is not found
819 * from the list of paths stored in the object copy property list.
820 * H5Ocopy will invoke this callback before searching all committed datatypes
821 * at destination.
822 *
823 * Usage: H5Pset_mcdt_search_cb(plist_id, H5O_mcdt_search_cb_t func, void *op_data)
824 * hid_t plist_id; IN: Property list to copy object
825 * H5O_mcdt_search_cb_t func; IN: The callback function
826 * void *op_data; IN: The user data
827 *
828 * Return: Non-negative on success/Negative on failure
829 *
830 * Programmer: Vailin Choi; November 28, 2011
831 *-------------------------------------------------------------------------
832 */
833 herr_t
H5Pset_mcdt_search_cb(hid_t plist_id,H5O_mcdt_search_cb_t func,void * op_data)834 H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, void *op_data)
835 {
836 H5P_genplist_t * plist; /* Property list pointer */
837 H5O_mcdt_cb_info_t cb_info; /* Callback info struct */
838 herr_t ret_value = SUCCEED; /* Return value */
839
840 FUNC_ENTER_API(FAIL)
841 H5TRACE3("e", "ix*x", plist_id, func, op_data);
842
843 /* Check if the callback function is NULL and the user data is non-NULL.
844 * This is almost certainly an error as the user data will not be used. */
845 if (!func && op_data)
846 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not")
847
848 /* Get the plist structure */
849 if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
850 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
851
852 /* Populate the callback info struct */
853 cb_info.func = func;
854 cb_info.user_data = op_data;
855
856 /* Set callback info */
857 if (H5P_set(plist, H5O_CPY_MCDT_SEARCH_CB_NAME, &cb_info) < 0)
858 HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set callback info")
859
860 done:
861 FUNC_LEAVE_API(ret_value)
862 } /* end H5Pset_mcdt_search_cb() */
863
864 /*-------------------------------------------------------------------------
865 * Function: H5Pget_mcdt_search_cb
866 *
867 * Purpose: Retrieves the callback function and user data from the specified
868 * object copy property list.
869 *
870 * Usage: H5Pget_mcdt_search_cb(plist_id, H5O_mcdt_search_cb_t *func, void **op_data)
871 * hid_t plist_id; IN: Property list to copy object
872 * H5O_mcdt_search_cb_t *func; OUT: The callback function
873 * void **op_data; OUT: The user data
874 *
875 * Return: Non-negative on success/Negative on failure
876 *
877 * Programmer: Vailin Choi; November 29, 2011
878 *
879 *-------------------------------------------------------------------------
880 */
881 herr_t
H5Pget_mcdt_search_cb(hid_t plist_id,H5O_mcdt_search_cb_t * func,void ** op_data)882 H5Pget_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t *func, void **op_data)
883 {
884 H5P_genplist_t * plist; /* Property list pointer */
885 H5O_mcdt_cb_info_t cb_info; /* Callback info struct */
886 herr_t ret_value = SUCCEED; /* Return value */
887
888 FUNC_ENTER_API(FAIL)
889 H5TRACE3("e", "i*x**x", plist_id, func, op_data);
890
891 /* Get the plist structure */
892 if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
893 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
894
895 /* Get callback info */
896 if (H5P_get(plist, H5O_CPY_MCDT_SEARCH_CB_NAME, &cb_info) < 0)
897 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get callback info")
898
899 if (func)
900 *func = cb_info.func;
901
902 if (op_data)
903 *op_data = cb_info.user_data;
904
905 done:
906 FUNC_LEAVE_API(ret_value)
907 } /* end H5Pget_mcdt_search_cb() */
908