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 /* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
15 *
16 * Purpose: Generic Property Functions
17 */
18
19 /****************/
20 /* Module Setup */
21 /****************/
22
23 #include "H5Pmodule.h" /* This source code file is part of the H5P module */
24
25
26 /***********/
27 /* Headers */
28 /***********/
29 #include "H5private.h" /* Generic Functions */
30 #ifdef H5_HAVE_PARALLEL
31 #include "H5ACprivate.h" /* Metadata cache */
32 #endif /* H5_HAVE_PARALLEL */
33 #include "H5Eprivate.h" /* Error handling */
34 #include "H5Fprivate.h" /* File access */
35 #include "H5FLprivate.h" /* Free lists */
36 #include "H5Iprivate.h" /* IDs */
37 #include "H5MMprivate.h" /* Memory management */
38 #include "H5Ppkg.h" /* Property lists */
39
40
41 /****************/
42 /* Local Macros */
43 /****************/
44
45
46 /******************/
47 /* Local Typedefs */
48 /******************/
49
50 /* Typedef for checking for duplicate class names in parent class */
51 typedef struct {
52 const H5P_genclass_t *parent; /* Pointer to parent class */
53 const char *name; /* Pointer to name to check */
54 H5P_genclass_t *new_class; /* Pointer to class during path traversal */
55 } H5P_check_class_t;
56
57 /* Typedef for property list iterator callback */
58 typedef struct {
59 H5P_iterate_int_t cb_func; /* Iterator callback */
60 void *udata; /* Iterator callback pointer */
61 const H5P_genplist_t *plist; /* Property list pointer */
62 H5SL_t *seen; /* Skip list to hold names of properties already seen */
63 int *curr_idx_ptr; /* Pointer to current iteration index */
64 int prev_idx; /* Previous iteration index */
65 } H5P_iter_plist_ud_t;
66
67 /* Typedef for property list class iterator callback */
68 typedef struct {
69 H5P_iterate_int_t cb_func; /* Iterator callback */
70 void *udata; /* Iterator callback pointer */
71 int *curr_idx_ptr; /* Pointer to current iteration index */
72 int prev_idx; /* Previous iteration index */
73 } H5P_iter_pclass_ud_t;
74
75 /* Typedef for property list comparison callback */
76 typedef struct {
77 const H5P_genplist_t *plist2; /* Pointer to second property list */
78 int cmp_value; /* Value from property comparison */
79 } H5P_plist_cmp_ud_t;
80
81 /* Typedef for property list set/poke callbacks */
82 typedef struct {
83 const void *value; /* Pointer to value to set */
84 } H5P_prop_set_ud_t;
85
86 /* Typedef for property list get/peek callbacks */
87 typedef struct {
88 void *value; /* Pointer for retrieved value */
89 } H5P_prop_get_ud_t;
90
91 /* Typedef for H5P__do_prop() callbacks */
92 typedef herr_t (*H5P_do_plist_op_t)(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
93 void *udata);
94 typedef herr_t (*H5P_do_pclass_op_t)(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
95 void *udata);
96
97
98 /********************/
99 /* Local Prototypes */
100 /********************/
101
102 /* General helper routines */
103 static H5P_genprop_t *H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type);
104 static herr_t H5P_free_prop(H5P_genprop_t *prop);
105 static int H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2);
106 static herr_t H5P__do_prop(H5P_genplist_t *plist, const char *name, H5P_do_plist_op_t plist_op,
107 H5P_do_pclass_op_t pclass_op, void *udata);
108
109
110 /*********************/
111 /* Package Variables */
112 /*********************/
113
114 /*
115 * Predefined property list classes. These are initialized at runtime by
116 * H5P__init_package() in this source file.
117 */
118 hid_t H5P_CLS_ROOT_ID_g = FAIL;
119 H5P_genclass_t *H5P_CLS_ROOT_g = NULL;
120 hid_t H5P_CLS_OBJECT_CREATE_ID_g = FAIL;
121 H5P_genclass_t *H5P_CLS_OBJECT_CREATE_g = NULL;
122 hid_t H5P_CLS_FILE_CREATE_ID_g = FAIL;
123 H5P_genclass_t *H5P_CLS_FILE_CREATE_g = NULL;
124 hid_t H5P_CLS_FILE_ACCESS_ID_g = FAIL;
125 H5P_genclass_t *H5P_CLS_FILE_ACCESS_g = NULL;
126 hid_t H5P_CLS_DATASET_CREATE_ID_g = FAIL;
127 H5P_genclass_t *H5P_CLS_DATASET_CREATE_g = NULL;
128 hid_t H5P_CLS_DATASET_ACCESS_ID_g = FAIL;
129 H5P_genclass_t *H5P_CLS_DATASET_ACCESS_g = NULL;
130 hid_t H5P_CLS_DATASET_XFER_ID_g = FAIL;
131 H5P_genclass_t *H5P_CLS_DATASET_XFER_g = NULL;
132 hid_t H5P_CLS_FILE_MOUNT_ID_g = FAIL;
133 H5P_genclass_t *H5P_CLS_FILE_MOUNT_g = NULL;
134 hid_t H5P_CLS_GROUP_CREATE_ID_g = FAIL;
135 H5P_genclass_t *H5P_CLS_GROUP_CREATE_g = NULL;
136 hid_t H5P_CLS_GROUP_ACCESS_ID_g = FAIL;
137 H5P_genclass_t *H5P_CLS_GROUP_ACCESS_g = NULL;
138 hid_t H5P_CLS_DATATYPE_CREATE_ID_g = FAIL;
139 H5P_genclass_t *H5P_CLS_DATATYPE_CREATE_g = NULL;
140 hid_t H5P_CLS_DATATYPE_ACCESS_ID_g = FAIL;
141 H5P_genclass_t *H5P_CLS_DATATYPE_ACCESS_g = NULL;
142 hid_t H5P_CLS_ATTRIBUTE_CREATE_ID_g = FAIL;
143 H5P_genclass_t *H5P_CLS_ATTRIBUTE_CREATE_g = NULL;
144 hid_t H5P_CLS_ATTRIBUTE_ACCESS_ID_g = FAIL;
145 H5P_genclass_t *H5P_CLS_ATTRIBUTE_ACCESS_g = NULL;
146 hid_t H5P_CLS_OBJECT_COPY_ID_g = FAIL;
147 H5P_genclass_t *H5P_CLS_OBJECT_COPY_g = NULL;
148 hid_t H5P_CLS_LINK_CREATE_ID_g = FAIL;
149 H5P_genclass_t *H5P_CLS_LINK_CREATE_g = NULL;
150 hid_t H5P_CLS_LINK_ACCESS_ID_g = FAIL;
151 H5P_genclass_t *H5P_CLS_LINK_ACCESS_g = NULL;
152 hid_t H5P_CLS_STRING_CREATE_ID_g = FAIL;
153 H5P_genclass_t *H5P_CLS_STRING_CREATE_g = NULL;
154
155 /*
156 * Predefined property lists for each predefined class. These are initialized
157 * at runtime by H5P__init_package() in this source file.
158 */
159 hid_t H5P_LST_FILE_CREATE_ID_g = FAIL;
160 hid_t H5P_LST_FILE_ACCESS_ID_g = FAIL;
161 hid_t H5P_LST_DATASET_CREATE_ID_g = FAIL;
162 hid_t H5P_LST_DATASET_ACCESS_ID_g = FAIL;
163 hid_t H5P_LST_DATASET_XFER_ID_g = FAIL;
164 hid_t H5P_LST_FILE_MOUNT_ID_g = FAIL;
165 hid_t H5P_LST_GROUP_CREATE_ID_g = FAIL;
166 hid_t H5P_LST_GROUP_ACCESS_ID_g = FAIL;
167 hid_t H5P_LST_DATATYPE_CREATE_ID_g = FAIL;
168 hid_t H5P_LST_DATATYPE_ACCESS_ID_g = FAIL;
169 hid_t H5P_LST_ATTRIBUTE_CREATE_ID_g = FAIL;
170 hid_t H5P_LST_ATTRIBUTE_ACCESS_ID_g = FAIL;
171 hid_t H5P_LST_OBJECT_COPY_ID_g = FAIL;
172 hid_t H5P_LST_LINK_CREATE_ID_g = FAIL;
173 hid_t H5P_LST_LINK_ACCESS_ID_g = FAIL;
174
175 /* Root property list class library initialization object */
176 const H5P_libclass_t H5P_CLS_ROOT[1] = {{
177 "root", /* Class name for debugging */
178 H5P_TYPE_ROOT, /* Class type */
179
180 NULL, /* Parent class */
181 &H5P_CLS_ROOT_g, /* Pointer to class */
182 &H5P_CLS_ROOT_ID_g, /* Pointer to class ID */
183 NULL, /* Pointer to default property list ID */
184 NULL, /* Default property registration routine */
185
186 NULL, /* Class creation callback */
187 NULL, /* Class creation callback info */
188 NULL, /* Class copy callback */
189 NULL, /* Class copy callback info */
190 NULL, /* Class close callback */
191 NULL /* Class close callback info */
192 }};
193
194 /* Attribute access property list class library initialization object */
195 /* (move to proper source code file when used for real) */
196 const H5P_libclass_t H5P_CLS_AACC[1] = {{
197 "attribute access", /* Class name for debugging */
198 H5P_TYPE_ATTRIBUTE_ACCESS, /* Class type */
199
200 &H5P_CLS_LINK_ACCESS_g, /* Parent class */
201 &H5P_CLS_ATTRIBUTE_ACCESS_g, /* Pointer to class */
202 &H5P_CLS_ATTRIBUTE_ACCESS_ID_g, /* Pointer to class ID */
203 &H5P_LST_ATTRIBUTE_ACCESS_ID_g, /* Pointer to default property list ID */
204 NULL, /* Default property registration routine */
205
206 NULL, /* Class creation callback */
207 NULL, /* Class creation callback info */
208 NULL, /* Class copy callback */
209 NULL, /* Class copy callback info */
210 NULL, /* Class close callback */
211 NULL /* Class close callback info */
212 }};
213
214 /* Group access property list class library initialization object */
215 /* (move to proper source code file when used for real) */
216 const H5P_libclass_t H5P_CLS_GACC[1] = {{
217 "group access", /* Class name for debugging */
218 H5P_TYPE_GROUP_ACCESS, /* Class type */
219
220 &H5P_CLS_LINK_ACCESS_g, /* Parent class */
221 &H5P_CLS_GROUP_ACCESS_g, /* Pointer to class */
222 &H5P_CLS_GROUP_ACCESS_ID_g, /* Pointer to class ID */
223 &H5P_LST_GROUP_ACCESS_ID_g, /* Pointer to default property list ID */
224 NULL, /* Default property registration routine */
225
226 NULL, /* Class creation callback */
227 NULL, /* Class creation callback info */
228 NULL, /* Class copy callback */
229 NULL, /* Class copy callback info */
230 NULL, /* Class close callback */
231 NULL /* Class close callback info */
232 }};
233
234 /* Datatype creation property list class library initialization object */
235 /* (move to proper source code file when used for real) */
236 const H5P_libclass_t H5P_CLS_TCRT[1] = {{
237 "datatype create", /* Class name for debugging */
238 H5P_TYPE_DATATYPE_CREATE, /* Class type */
239
240 &H5P_CLS_OBJECT_CREATE_g, /* Parent class */
241 &H5P_CLS_DATATYPE_CREATE_g, /* Pointer to class */
242 &H5P_CLS_DATATYPE_CREATE_ID_g, /* Pointer to class ID */
243 &H5P_LST_DATATYPE_CREATE_ID_g, /* Pointer to default property list ID */
244 NULL, /* Default property registration routine */
245
246 NULL, /* Class creation callback */
247 NULL, /* Class creation callback info */
248 NULL, /* Class copy callback */
249 NULL, /* Class copy callback info */
250 NULL, /* Class close callback */
251 NULL /* Class close callback info */
252 }};
253
254 /* Datatype access property list class library initialization object */
255 /* (move to proper source code file when used for real) */
256 const H5P_libclass_t H5P_CLS_TACC[1] = {{
257 "datatype access", /* Class name for debugging */
258 H5P_TYPE_DATATYPE_ACCESS, /* Class type */
259
260 &H5P_CLS_LINK_ACCESS_g, /* Parent class */
261 &H5P_CLS_DATATYPE_ACCESS_g, /* Pointer to class */
262 &H5P_CLS_DATATYPE_ACCESS_ID_g, /* Pointer to class ID */
263 &H5P_LST_DATATYPE_ACCESS_ID_g, /* Pointer to default property list ID */
264 NULL, /* Default property registration routine */
265
266 NULL, /* Class creation callback */
267 NULL, /* Class creation callback info */
268 NULL, /* Class copy callback */
269 NULL, /* Class copy callback info */
270 NULL, /* Class close callback */
271 NULL /* Class close callback info */
272 }};
273
274
275 /* Library property list classes defined in other code modules */
276 H5_DLLVAR const H5P_libclass_t H5P_CLS_OCRT[1]; /* Object creation */
277 H5_DLLVAR const H5P_libclass_t H5P_CLS_STRCRT[1]; /* String create */
278 H5_DLLVAR const H5P_libclass_t H5P_CLS_GCRT[1]; /* Group create */
279 H5_DLLVAR const H5P_libclass_t H5P_CLS_OCPY[1]; /* Object copy */
280 H5_DLLVAR const H5P_libclass_t H5P_CLS_FCRT[1]; /* File creation */
281 H5_DLLVAR const H5P_libclass_t H5P_CLS_DCRT[1]; /* Dataset creation */
282 H5_DLLVAR const H5P_libclass_t H5P_CLS_DXFR[1]; /* Data transfer */
283 H5_DLLVAR const H5P_libclass_t H5P_CLS_FMNT[1]; /* File mount */
284 H5_DLLVAR const H5P_libclass_t H5P_CLS_ACRT[1]; /* Attribute creation */
285 H5_DLLVAR const H5P_libclass_t H5P_CLS_LCRT[1]; /* Link creation */
286
287
288 /*****************************/
289 /* Library Private Variables */
290 /*****************************/
291
292
293 /*******************/
294 /* Local Variables */
295 /*******************/
296
297 /* Track the revision count of a class, to make comparisons faster */
298 static unsigned H5P_next_rev = 0;
299 #define H5P_GET_NEXT_REV (H5P_next_rev++)
300
301 /* List of all property list classes in the library */
302 /* (order here is not important, they will be initialized in the proper
303 * order according to their parent class dependencies)
304 */
305 static H5P_libclass_t const * const init_class[] = {
306 H5P_CLS_ROOT, /* Root */
307 H5P_CLS_OCRT, /* Object create */
308 H5P_CLS_STRCRT, /* String create */
309 H5P_CLS_LACC, /* Link access */
310 H5P_CLS_GCRT, /* Group create */
311 H5P_CLS_OCPY, /* Object copy */
312 H5P_CLS_GACC, /* Group access */
313 H5P_CLS_FCRT, /* File creation */
314 H5P_CLS_FACC, /* File access */
315 H5P_CLS_DCRT, /* Dataset creation */
316 H5P_CLS_DACC, /* Dataset access */
317 H5P_CLS_DXFR, /* Data transfer */
318 H5P_CLS_FMNT, /* File mount */
319 H5P_CLS_TCRT, /* Datatype creation */
320 H5P_CLS_TACC, /* Datatype access */
321 H5P_CLS_ACRT, /* Attribute creation */
322 H5P_CLS_AACC, /* Attribute access */
323 H5P_CLS_LCRT /* Link creation */
324 };
325
326 /* Declare a free list to manage the H5P_genclass_t struct */
327 H5FL_DEFINE_STATIC(H5P_genclass_t);
328
329 /* Declare a free list to manage the H5P_genprop_t struct */
330 H5FL_DEFINE_STATIC(H5P_genprop_t);
331
332 /* Declare a free list to manage the H5P_genplist_t struct */
333 H5FL_DEFINE_STATIC(H5P_genplist_t);
334
335 /* Generic Property Class ID class */
336 static const H5I_class_t H5I_GENPROPCLS_CLS[1] = {{
337 H5I_GENPROP_CLS, /* ID class value */
338 0, /* Class flags */
339 0, /* # of reserved IDs for class */
340 (H5I_free_t)H5P_close_class /* Callback routine for closing objects of this class */
341 }};
342
343 /* Generic Property List ID class */
344 static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{
345 H5I_GENPROP_LST, /* ID class value */
346 0, /* Class flags */
347 0, /* # of reserved IDs for class */
348 (H5I_free_t)H5P_close /* Callback routine for closing objects of this class */
349 }};
350
351
352
353 /*-------------------------------------------------------------------------
354 * Function: H5P_init
355 *
356 * Purpose: Initialize the interface from some other layer.
357 *
358 * Return: Success: non-negative
359 * Failure: negative
360 *
361 * Programmer: Quincey Koziol
362 * Saturday, March 4, 2000
363 *
364 *-------------------------------------------------------------------------
365 */
366 herr_t
H5P_init(void)367 H5P_init(void)
368 {
369 herr_t ret_value = SUCCEED; /* Return value */
370
371 FUNC_ENTER_NOAPI(FAIL)
372 /* FUNC_ENTER() does all the work */
373
374 done:
375 FUNC_LEAVE_NOAPI(ret_value)
376 } /* end H5P_init() */
377
378
379 /*--------------------------------------------------------------------------
380 NAME
381 H5P__init_package -- Initialize interface-specific information
382 USAGE
383 herr_t H5P__init_package()
384 RETURNS
385 Non-negative on success/Negative on failure
386 DESCRIPTION
387 Initializes any interface-specific data or routines.
388 --------------------------------------------------------------------------*/
389 herr_t
H5P__init_package(void)390 H5P__init_package(void)
391 {
392 size_t tot_init; /* Total # of classes initialized */
393 size_t pass_init; /* # of classes initialized in each pass */
394 herr_t ret_value = SUCCEED; /* Return value */
395
396 FUNC_ENTER_PACKAGE
397
398 /*
399 * Initialize the Generic Property class & object groups.
400 */
401 if(H5I_register_type(H5I_GENPROPCLS_CLS) < 0)
402 HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group")
403 if(H5I_register_type(H5I_GENPROPLST_CLS) < 0)
404 HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group")
405
406 /* Repeatedly pass over the list of property list classes for the library,
407 * initializing each class if it's parent class is initialized, until no
408 * more progress is made.
409 */
410 tot_init = 0;
411 do {
412 size_t u; /* Local index variable */
413
414 /* Reset pass initialization counter */
415 pass_init = 0;
416
417 /* Make a pass over all the library's property list classes */
418 for(u = 0; u < NELMTS(init_class); u++) {
419 H5P_libclass_t const *lib_class = init_class[u]; /* Current class to operate on */
420
421 /* Check if the current class hasn't been initialized and can be now */
422 HDassert(lib_class->class_id);
423 if(*lib_class->class_id == (-1) && (lib_class->par_pclass == NULL
424 || *lib_class->par_pclass != NULL)) {
425 /* Sanity check - only the root class is not allowed to have a parent class */
426 HDassert(lib_class->par_pclass || lib_class == H5P_CLS_ROOT);
427
428 /* Allocate the new class */
429 if(NULL == (*lib_class->pclass = H5P_create_class(lib_class->par_pclass ? *lib_class->par_pclass : NULL, lib_class->name, lib_class->type, lib_class->create_func, lib_class->create_data, lib_class->copy_func, lib_class->copy_data, lib_class->close_func, lib_class->close_data)))
430 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed")
431
432 /* Call routine to register properties for class */
433 if(lib_class->reg_prop_func && (*lib_class->reg_prop_func)(*lib_class->pclass) < 0)
434 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register properties")
435
436 /* Register the new class */
437 if((*lib_class->class_id = H5I_register(H5I_GENPROP_CLS, *lib_class->pclass, FALSE)) < 0)
438 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class")
439
440 /* Only register the default property list if it hasn't been created yet */
441 if(lib_class->def_plist_id && *lib_class->def_plist_id == (-1)) {
442 /* Register the default property list for the new class*/
443 if((*lib_class->def_plist_id = H5P_create_id(*lib_class->pclass, FALSE)) < 0)
444 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default property list for class")
445 } /* end if */
446
447 /* Increment class initialization counters */
448 pass_init++;
449 tot_init++;
450 } /* end if */
451 } /* end for */
452 } while(pass_init > 0);
453
454 /* Verify that all classes were initialized */
455 HDassert(tot_init == NELMTS(init_class));
456
457 done:
458 FUNC_LEAVE_NOAPI(ret_value)
459 } /* end H5P__init_package() */
460
461
462 /*--------------------------------------------------------------------------
463 NAME
464 H5P_term_package
465 PURPOSE
466 Terminate various H5P objects
467 USAGE
468 void H5P_term_package()
469 RETURNS
470 Non-negative on success/Negative on failure
471 DESCRIPTION
472 Release the atom group and any other resources allocated.
473 GLOBAL VARIABLES
474 COMMENTS, BUGS, ASSUMPTIONS
475 Can't report errors...
476 EXAMPLES
477 REVISION LOG
478 --------------------------------------------------------------------------*/
479 int
H5P_term_package(void)480 H5P_term_package(void)
481 {
482 int n = 0;
483
484 FUNC_ENTER_NOAPI_NOINIT_NOERR
485
486 if(H5_PKG_INIT_VAR) {
487 int64_t nlist, nclass;
488
489 /* Destroy HDF5 library property classes & lists */
490
491 /* Check if there are any open property list classes or lists */
492 nclass = H5I_nmembers(H5I_GENPROP_CLS);
493 nlist = H5I_nmembers(H5I_GENPROP_LST);
494
495 /* If there are any open classes or groups, attempt to get rid of them. */
496 if((nclass + nlist) > 0) {
497 /* Clear the lists */
498 if(nlist > 0) {
499 (void)H5I_clear_type(H5I_GENPROP_LST, FALSE, FALSE);
500
501 /* Reset the default property lists, if they've been closed */
502 if(H5I_nmembers(H5I_GENPROP_LST) == 0) {
503 H5P_LST_FILE_CREATE_ID_g =
504 H5P_LST_FILE_ACCESS_ID_g =
505 H5P_LST_DATASET_CREATE_ID_g =
506 H5P_LST_DATASET_ACCESS_ID_g =
507 H5P_LST_DATASET_XFER_ID_g =
508 H5P_LST_GROUP_CREATE_ID_g =
509 H5P_LST_GROUP_ACCESS_ID_g =
510 H5P_LST_DATATYPE_CREATE_ID_g =
511 H5P_LST_DATATYPE_ACCESS_ID_g =
512 H5P_LST_ATTRIBUTE_CREATE_ID_g =
513 H5P_LST_ATTRIBUTE_ACCESS_ID_g =
514 H5P_LST_OBJECT_COPY_ID_g =
515 H5P_LST_LINK_CREATE_ID_g =
516 H5P_LST_LINK_ACCESS_ID_g =
517 H5P_LST_FILE_MOUNT_ID_g = (-1);
518 } /* end if */
519 } /* end if */
520
521 /* Only attempt to close the classes after all the lists are closed */
522 if(nlist == 0 && nclass > 0) {
523 (void)H5I_clear_type(H5I_GENPROP_CLS, FALSE, FALSE);
524
525 /* Reset the default property classes, if they've been closed */
526 if(H5I_nmembers(H5I_GENPROP_CLS) == 0) {
527 H5P_CLS_ROOT_g =
528 H5P_CLS_OBJECT_CREATE_g =
529 H5P_CLS_FILE_CREATE_g =
530 H5P_CLS_FILE_ACCESS_g =
531 H5P_CLS_DATASET_CREATE_g =
532 H5P_CLS_DATASET_ACCESS_g =
533 H5P_CLS_DATASET_XFER_g =
534 H5P_CLS_GROUP_CREATE_g =
535 H5P_CLS_GROUP_ACCESS_g =
536 H5P_CLS_DATATYPE_CREATE_g =
537 H5P_CLS_DATATYPE_ACCESS_g =
538 H5P_CLS_STRING_CREATE_g =
539 H5P_CLS_ATTRIBUTE_CREATE_g =
540 H5P_CLS_ATTRIBUTE_ACCESS_g =
541 H5P_CLS_OBJECT_COPY_g =
542 H5P_CLS_LINK_CREATE_g =
543 H5P_CLS_LINK_ACCESS_g =
544 H5P_CLS_FILE_MOUNT_g = NULL;
545
546 H5P_CLS_ROOT_ID_g =
547 H5P_CLS_OBJECT_CREATE_ID_g =
548 H5P_CLS_FILE_CREATE_ID_g =
549 H5P_CLS_FILE_ACCESS_ID_g =
550 H5P_CLS_DATASET_CREATE_ID_g =
551 H5P_CLS_DATASET_ACCESS_ID_g =
552 H5P_CLS_DATASET_XFER_ID_g =
553 H5P_CLS_GROUP_CREATE_ID_g =
554 H5P_CLS_GROUP_ACCESS_ID_g =
555 H5P_CLS_DATATYPE_CREATE_ID_g =
556 H5P_CLS_DATATYPE_ACCESS_ID_g =
557 H5P_CLS_STRING_CREATE_ID_g =
558 H5P_CLS_ATTRIBUTE_CREATE_ID_g =
559 H5P_CLS_ATTRIBUTE_ACCESS_ID_g =
560 H5P_CLS_OBJECT_COPY_ID_g =
561 H5P_CLS_LINK_CREATE_ID_g =
562 H5P_CLS_LINK_ACCESS_ID_g =
563 H5P_CLS_FILE_MOUNT_ID_g = (-1);
564 } /* end if */
565 } /* end if */
566
567 n++; /*H5I*/
568 } else {
569 /* Destroy the property list and class id groups */
570 n += (H5I_dec_type_ref(H5I_GENPROP_LST) > 0);
571 n += (H5I_dec_type_ref(H5I_GENPROP_CLS) > 0);
572
573 /* Mark closed */
574 if(0 == n)
575 H5_PKG_INIT_VAR = FALSE;
576 } /* end else */
577 } /* end if */
578
579 FUNC_LEAVE_NOAPI(n)
580 } /* end H5P_term_package() */
581
582
583 /*--------------------------------------------------------------------------
584 NAME
585 H5P__do_prop_cb1
586 PURPOSE
587 Internal routine to call a property list callback routine and update
588 the property list accordingly.
589 USAGE
590 herr_t H5P__do_prop_cb1(slist,prop,cb)
591 H5SL_t *slist; IN/OUT: Skip list to hold changed properties
592 H5P_genprop_t *prop; IN: Property to call callback for
593 H5P_prp_cb1_t *cb; IN: Callback routine to call
594 RETURNS
595 Returns non-negative on success, negative on failure.
596 DESCRIPTION
597 Calls the callback routine passed in. If the callback routine changes
598 the property value, then the property is duplicated and added to skip list.
599
600 GLOBAL VARIABLES
601 COMMENTS, BUGS, ASSUMPTIONS
602 EXAMPLES
603 REVISION LOG
604 --------------------------------------------------------------------------*/
605 static herr_t
H5P__do_prop_cb1(H5SL_t * slist,H5P_genprop_t * prop,H5P_prp_cb1_t cb)606 H5P__do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb)
607 {
608 void *tmp_value = NULL; /* Temporary value buffer */
609 H5P_genprop_t *pcopy = NULL; /* Copy of property to insert into skip list */
610 herr_t ret_value = SUCCEED; /* Return value */
611
612 FUNC_ENTER_STATIC
613
614 /* Sanity check */
615 HDassert(slist);
616 HDassert(prop);
617 HDassert(prop->cmp);
618 HDassert(cb);
619
620 /* Allocate space for a temporary copy of the property value */
621 if(NULL == (tmp_value = H5MM_malloc(prop->size)))
622 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for temporary property value")
623 HDmemcpy(tmp_value, prop->value, prop->size);
624
625 /* Call "type 1" callback ('create', 'copy' or 'close') */
626 if(cb(prop->name, prop->size, tmp_value) < 0)
627 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Property callback failed")
628
629 /* Make a copy of the class's property */
630 if(NULL == (pcopy = H5P_dup_prop(prop, H5P_PROP_WITHIN_LIST)))
631 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property")
632
633 /* Copy the changed value into the new property */
634 HDmemcpy(pcopy->value, tmp_value, prop->size);
635
636 /* Insert the changed property into the property list */
637 if(H5P_add_prop(slist, pcopy) < 0)
638 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "Can't insert property into skip list")
639
640 done:
641 /* Release the temporary value buffer */
642 if(tmp_value)
643 H5MM_xfree(tmp_value);
644
645 /* Cleanup on failure */
646 if(ret_value < 0)
647 if(pcopy)
648 H5P_free_prop(pcopy);
649
650 FUNC_LEAVE_NOAPI(ret_value)
651 } /* end H5P__do_prop_cb1() */
652
653
654 /*--------------------------------------------------------------------------
655 NAME
656 H5P_copy_pclass
657 PURPOSE
658 Internal routine to copy a generic property class
659 USAGE
660 hid_t H5P_copy_pclass(pclass)
661 H5P_genclass_t *pclass; IN: Property class to copy
662 RETURNS
663 Success: valid property class ID on success (non-negative)
664 Failure: negative
665 DESCRIPTION
666 Copy a property class and return the ID. This routine does not make
667 any callbacks. (They are only make when operating on property lists).
668
669 GLOBAL VARIABLES
670 COMMENTS, BUGS, ASSUMPTIONS
671 EXAMPLES
672 REVISION LOG
673 --------------------------------------------------------------------------*/
674 H5P_genclass_t *
H5P_copy_pclass(H5P_genclass_t * pclass)675 H5P_copy_pclass(H5P_genclass_t *pclass)
676 {
677 H5P_genclass_t *new_pclass = NULL; /* Property list class copied */
678 H5P_genprop_t *pcopy; /* Copy of property to insert into class */
679 H5P_genclass_t *ret_value=NULL; /* return value */
680
681 FUNC_ENTER_NOAPI_NOINIT
682
683 HDassert(pclass);
684
685 /*
686 * Create new property class object
687 */
688
689 /* Create the new property list class */
690 if(NULL == (new_pclass = H5P_create_class(pclass->parent, pclass->name, pclass->type, pclass->create_func, pclass->create_data, pclass->copy_func, pclass->copy_data, pclass->close_func, pclass->close_data)))
691 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list class")
692
693 /* Copy the properties registered for this class */
694 if(pclass->nprops > 0) {
695 H5SL_node_t *curr_node; /* Current node in skip list */
696
697 /* Walk through the properties in the old class */
698 curr_node=H5SL_first(pclass->props);
699 while(curr_node!=NULL) {
700 /* Make a copy of the class's property */
701 if(NULL == (pcopy = H5P_dup_prop((H5P_genprop_t *)H5SL_item(curr_node), H5P_PROP_WITHIN_CLASS)))
702 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property")
703
704 /* Insert the initialized property into the property list */
705 if(H5P_add_prop(new_pclass->props,pcopy) < 0)
706 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class")
707
708 /* Increment property count for class */
709 new_pclass->nprops++;
710
711 /* Get the next property node in the list */
712 curr_node=H5SL_next(curr_node);
713 } /* end while */
714 } /* end if */
715
716 /* Set the return value */
717 ret_value=new_pclass;
718
719 done:
720 if(ret_value==NULL && new_pclass)
721 H5P_close_class(new_pclass);
722
723 FUNC_LEAVE_NOAPI(ret_value)
724 } /* H5P_copy_pclass() */
725
726
727 /*--------------------------------------------------------------------------
728 NAME
729 H5P_copy_plist
730 PURPOSE
731 Internal routine to copy a generic property list
732 USAGE
733 hid_t H5P_copy_plist(old_plist_id)
734 hid_t old_plist_id; IN: Property list ID to copy
735 RETURNS
736 Success: valid property list ID on success (non-negative)
737 Failure: negative
738 DESCRIPTION
739 Copy a property list and return the ID. This routine calls the
740 class 'copy' callback after any property 'copy' callbacks are called
741 (assuming all property 'copy' callbacks return successfully).
742
743 GLOBAL VARIABLES
744 COMMENTS, BUGS, ASSUMPTIONS
745 EXAMPLES
746 REVISION LOG
747 --------------------------------------------------------------------------*/
748 hid_t
H5P_copy_plist(const H5P_genplist_t * old_plist,hbool_t app_ref)749 H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref)
750 {
751 H5P_genclass_t *tclass; /* Temporary class pointer */
752 H5P_genplist_t *new_plist=NULL; /* New property list generated from copy */
753 H5P_genprop_t *tmp; /* Temporary pointer to properties */
754 H5P_genprop_t *new_prop; /* New property created for copy */
755 hid_t new_plist_id; /* Property list ID of new list created */
756 H5SL_node_t *curr_node; /* Current node in skip list */
757 H5SL_t *seen=NULL; /* Skip list containing properties already seen */
758 size_t nseen; /* Number of items 'seen' */
759 hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */
760 hid_t ret_value=FAIL; /* return value */
761
762 FUNC_ENTER_NOAPI(FAIL)
763
764 HDassert(old_plist);
765
766 /*
767 * Create new property list object
768 */
769
770 /* Allocate room for the property list */
771 if(NULL==(new_plist = H5FL_CALLOC(H5P_genplist_t)))
772 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,"memory allocation failed")
773
774 /* Set class state */
775 new_plist->pclass = old_plist->pclass;
776 new_plist->nprops = 0; /* Initially the plist has the same number of properties as the class */
777 new_plist->class_init = FALSE; /* Initially, wait until the class callback finishes to set */
778
779 /* Initialize the skip list to hold the changed properties */
780 if((new_plist->props = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
781 HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for changed properties")
782
783 /* Create the skip list for deleted properties */
784 if((new_plist->del = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
785 HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for deleted properties")
786
787 /* Create the skip list to hold names of properties already seen
788 * (This prevents a property in the class hierarchy from having it's
789 * 'create' callback called, if a property in the class hierarchy has
790 * already been seen)
791 */
792 if((seen = H5SL_create(H5SL_TYPE_STR, NULL))== NULL)
793 HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties")
794 nseen = 0;
795
796 /* Cycle through the deleted properties & copy them into the new list's deleted section */
797 if(H5SL_count(old_plist->del)>0) {
798 curr_node=H5SL_first(old_plist->del);
799 while(curr_node) {
800 char *new_name; /* Pointer to new name */
801
802 /* Duplicate string for insertion into new deleted property skip list */
803 if((new_name=H5MM_xstrdup((char *)H5SL_item(curr_node))) == NULL)
804 HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed")
805
806 /* Insert property name into deleted list */
807 if(H5SL_insert(new_plist->del,new_name,new_name) < 0)
808 HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list")
809
810 /* Add property name to "seen" list */
811 if(H5SL_insert(seen,new_name,new_name) < 0)
812 HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list")
813 nseen++;
814
815 /* Get the next property node in the skip list */
816 curr_node=H5SL_next(curr_node);
817 } /* end while */
818 } /* end if */
819
820 /* Cycle through the properties and copy them also */
821 if(H5SL_count(old_plist->props)>0) {
822 curr_node=H5SL_first(old_plist->props);
823 while(curr_node) {
824 /* Get a pointer to the node's property */
825 tmp = (H5P_genprop_t *)H5SL_item(curr_node);
826
827 /* Make a copy of the list's property */
828 if(NULL == (new_prop = H5P_dup_prop(tmp, H5P_PROP_WITHIN_LIST)))
829 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property")
830
831 /* Call property copy callback, if it exists */
832 if(new_prop->copy) {
833 if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value) < 0) {
834 H5P_free_prop(new_prop);
835 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property")
836 } /* end if */
837 } /* end if */
838
839 /* Insert the initialized property into the property list */
840 if(H5P_add_prop(new_plist->props,new_prop) < 0) {
841 H5P_free_prop(new_prop);
842 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list")
843 } /* end if */
844
845 /* Add property name to "seen" list */
846 if(H5SL_insert(seen,new_prop->name,new_prop->name) < 0)
847 HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list")
848 nseen++;
849
850 /* Increment the number of properties in list */
851 new_plist->nprops++;
852
853 /* Get the next property node in the skip list */
854 curr_node=H5SL_next(curr_node);
855 } /* end while */
856 } /* end if */
857
858 /*
859 * Check for copying class properties (up through list of parent classes also),
860 * initialize each with default value & make property 'copy' callback.
861 */
862 tclass=old_plist->pclass;
863 has_parent_class = (hbool_t)(tclass != NULL && tclass->parent != NULL && tclass->parent->nprops > 0);
864 while(tclass!=NULL) {
865 if(tclass->nprops>0) {
866 /* Walk through the properties in the old class */
867 curr_node=H5SL_first(tclass->props);
868 while(curr_node!=NULL) {
869 /* Get pointer to property from node */
870 tmp = (H5P_genprop_t *)H5SL_item(curr_node);
871
872 /* Only "copy" properties we haven't seen before */
873 if(nseen==0 || H5SL_search(seen,tmp->name) == NULL) {
874 /* Call property copy callback, if it exists */
875 if(tmp->copy) {
876 /* Call the callback & insert changed value into skip list (if necessary) */
877 if(H5P__do_prop_cb1(new_plist->props, tmp, tmp->copy) < 0)
878 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't create property")
879 } /* end if */
880
881 /* Add property name to "seen" list, if we have other classes to work on */
882 if(has_parent_class) {
883 if(H5SL_insert(seen,tmp->name,tmp->name) < 0)
884 HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list")
885 nseen++;
886 } /* end if */
887
888 /* Increment the number of properties in list */
889 new_plist->nprops++;
890 } /* end if */
891
892 /* Get the next property node in the skip list */
893 curr_node=H5SL_next(curr_node);
894 } /* end while */
895 } /* end if */
896
897 /* Go up to parent class */
898 tclass=tclass->parent;
899 } /* end while */
900
901 /* Increment the number of property lists derived from class */
902 if(H5P_access_class(new_plist->pclass, H5P_MOD_INC_LST) < 0)
903 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "Can't increment class ref count")
904
905 /* Get an atom for the property list */
906 if((new_plist_id = H5I_register(H5I_GENPROP_LST, new_plist, app_ref)) < 0)
907 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list")
908
909 /* Save the property list ID in the property list struct, for use in the property class's 'close' callback */
910 new_plist->plist_id=new_plist_id;
911
912 /* Call the class callback (if it exists) now that we have the property list ID
913 * (up through chain of parent classes also)
914 */
915 tclass = new_plist->pclass;
916 while(NULL != tclass) {
917 if(NULL != tclass->copy_func) {
918 if((tclass->copy_func)(new_plist_id, old_plist->plist_id, old_plist->pclass->copy_data) < 0) {
919 /* Delete ID, ignore return value */
920 H5I_remove(new_plist_id);
921 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property")
922 } /* end if */
923 } /* end if */
924
925 /* Go up to parent class */
926 tclass = tclass->parent;
927 } /* end while */
928
929 /* Set the class initialization flag */
930 new_plist->class_init = TRUE;
931
932 /* Set the return value */
933 ret_value=new_plist_id;
934
935 done:
936 /* Release the list of 'seen' properties */
937 if(seen!=NULL)
938 H5SL_close(seen);
939
940 if(ret_value<0 && new_plist)
941 H5P_close(new_plist);
942
943 FUNC_LEAVE_NOAPI(ret_value)
944 } /* H5P_copy_plist() */
945
946
947 /*--------------------------------------------------------------------------
948 NAME
949 H5P_dup_prop
950 PURPOSE
951 Internal routine to duplicate a property
952 USAGE
953 H5P_genprop_t *H5P_dup_prop(oprop)
954 H5P_genprop_t *oprop; IN: Pointer to property to copy
955 H5P_prop_within_t type; IN: Type of object the property will be inserted into
956 RETURNS
957 Returns a pointer to the newly created duplicate of a property on success,
958 NULL on failure.
959 DESCRIPTION
960 Allocates memory and copies property information into a new property object.
961 GLOBAL VARIABLES
962 COMMENTS, BUGS, ASSUMPTIONS
963 EXAMPLES
964 REVISION LOG
965 --------------------------------------------------------------------------*/
966 static H5P_genprop_t *
H5P_dup_prop(H5P_genprop_t * oprop,H5P_prop_within_t type)967 H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type)
968 {
969 H5P_genprop_t *prop = NULL; /* Pointer to new property copied */
970 H5P_genprop_t *ret_value = NULL; /* Return value */
971
972 FUNC_ENTER_NOAPI_NOINIT
973
974 HDassert(oprop);
975 HDassert(type != H5P_PROP_WITHIN_UNKNOWN);
976
977 /* Allocate the new property */
978 if(NULL == (prop = H5FL_MALLOC(H5P_genprop_t)))
979 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
980
981 /* Copy basic property information */
982 HDmemcpy(prop, oprop, sizeof(H5P_genprop_t));
983
984 /* Check if we should duplicate the name or share it */
985
986 /* Duplicating property for a class */
987 if(type == H5P_PROP_WITHIN_CLASS) {
988 HDassert(oprop->type == H5P_PROP_WITHIN_CLASS);
989 HDassert(oprop->shared_name == FALSE);
990
991 /* Duplicate name */
992 prop->name = H5MM_xstrdup(oprop->name);
993 } /* end if */
994 /* Duplicating property for a list */
995 else {
996 /* Check if we are duplicating a property from a list or a class */
997
998 /* Duplicating a property from a list */
999 if(oprop->type == H5P_PROP_WITHIN_LIST) {
1000 /* If the old property's name wasn't shared, we have to copy it here also */
1001 if(!oprop->shared_name)
1002 prop->name = H5MM_xstrdup(oprop->name);
1003 } /* end if */
1004 /* Duplicating a property from a class */
1005 else {
1006 HDassert(oprop->type == H5P_PROP_WITHIN_CLASS);
1007 HDassert(oprop->shared_name == FALSE);
1008
1009 /* Share the name */
1010 prop->shared_name = TRUE;
1011
1012 /* Set the type */
1013 prop->type = type;
1014 } /* end else */
1015 } /* end else */
1016
1017 /* Duplicate current value, if it exists */
1018 if(oprop->value != NULL) {
1019 HDassert(prop->size > 0);
1020 if(NULL == (prop->value = H5MM_malloc(prop->size)))
1021 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
1022 HDmemcpy(prop->value, oprop->value, prop->size);
1023 } /* end if */
1024
1025 /* Set return value */
1026 ret_value = prop;
1027
1028 done:
1029 /* Free any resources allocated */
1030 if(ret_value == NULL) {
1031 if(prop != NULL) {
1032 if(prop->name != NULL)
1033 H5MM_xfree(prop->name);
1034 if(prop->value != NULL)
1035 H5MM_xfree(prop->value);
1036 prop = H5FL_FREE(H5P_genprop_t, prop);
1037 } /* end if */
1038 } /* end if */
1039
1040 FUNC_LEAVE_NOAPI(ret_value)
1041 } /* H5P_dup_prop() */
1042
1043
1044 /*--------------------------------------------------------------------------
1045 NAME
1046 H5P_create_prop
1047 PURPOSE
1048 Internal routine to create a new property
1049 USAGE
1050 H5P_genprop_t *H5P_create_prop(name,size,type,value,prp_create,prp_set,
1051 prp_get,prp_delete,prp_close, prp_encode, prp_decode)
1052 const char *name; IN: Name of property to register
1053 size_t size; IN: Size of property in bytes
1054 H5P_prop_within_t type; IN: Type of object the property will be inserted into
1055 void *value; IN: Pointer to buffer containing value for property
1056 H5P_prp_create_func_t prp_create; IN: Function pointer to property
1057 creation callback
1058 H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
1059 H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
1060 H5P_prp_encode_func_t prp_encode; IN: Function pointer to property encode
1061 H5P_prp_decode_func_t prp_decode; IN: Function pointer to property decode
1062 H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
1063 H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
1064 H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback
1065 H5P_prp_close_func_t prp_close; IN: Function pointer to property close
1066 callback
1067 RETURNS
1068 Returns a pointer to the newly created property on success,
1069 NULL on failure.
1070 DESCRIPTION
1071 Allocates memory and copies property information into a new property object.
1072 GLOBAL VARIABLES
1073 COMMENTS, BUGS, ASSUMPTIONS
1074 EXAMPLES
1075 REVISION LOG
1076 --------------------------------------------------------------------------*/
1077 static H5P_genprop_t *
H5P_create_prop(const char * name,size_t size,H5P_prop_within_t type,const void * value,H5P_prp_create_func_t prp_create,H5P_prp_set_func_t prp_set,H5P_prp_get_func_t prp_get,H5P_prp_encode_func_t prp_encode,H5P_prp_decode_func_t prp_decode,H5P_prp_delete_func_t prp_delete,H5P_prp_copy_func_t prp_copy,H5P_prp_compare_func_t prp_cmp,H5P_prp_close_func_t prp_close)1078 H5P_create_prop(const char *name, size_t size, H5P_prop_within_t type,
1079 const void *value, H5P_prp_create_func_t prp_create,
1080 H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
1081 H5P_prp_encode_func_t prp_encode, H5P_prp_decode_func_t prp_decode,
1082 H5P_prp_delete_func_t prp_delete,
1083 H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp,
1084 H5P_prp_close_func_t prp_close)
1085 {
1086 H5P_genprop_t *prop = NULL; /* Pointer to new property copied */
1087 H5P_genprop_t *ret_value = NULL; /* Return value */
1088
1089 FUNC_ENTER_NOAPI_NOINIT
1090
1091 HDassert(name);
1092 HDassert((size > 0 && value != NULL) || (size == 0));
1093 HDassert(type != H5P_PROP_WITHIN_UNKNOWN);
1094
1095 /* Allocate the new property */
1096 if(NULL == (prop = H5FL_MALLOC(H5P_genprop_t)))
1097 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
1098
1099 /* Set the property initial values */
1100 prop->name = H5MM_xstrdup(name); /* Duplicate name */
1101 prop->shared_name = FALSE;
1102 prop->size = size;
1103 prop->type = type;
1104
1105 /* Duplicate value, if it exists */
1106 if(value != NULL) {
1107 if(NULL == (prop->value = H5MM_malloc (prop->size)))
1108 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
1109 HDmemcpy(prop->value, value, prop->size);
1110 } /* end if */
1111 else
1112 prop->value = NULL;
1113
1114 /* Set the function pointers */
1115 prop->create = prp_create;
1116 prop->set = prp_set;
1117 prop->get = prp_get;
1118 prop->encode = prp_encode;
1119 prop->decode = prp_decode;
1120 prop->del = prp_delete;
1121 prop->copy = prp_copy;
1122 /* Use custom comparison routine if available, otherwise default to memcmp() */
1123 if(prp_cmp != NULL)
1124 prop->cmp = prp_cmp;
1125 else
1126 prop->cmp = &memcmp;
1127 prop->close = prp_close;
1128
1129 /* Set return value */
1130 ret_value = prop;
1131
1132 done:
1133 /* Free any resources allocated */
1134 if(ret_value == NULL) {
1135 if(prop != NULL) {
1136 if(prop->name != NULL)
1137 H5MM_xfree(prop->name);
1138 if(prop->value != NULL)
1139 H5MM_xfree(prop->value);
1140 prop = H5FL_FREE(H5P_genprop_t, prop);
1141 } /* end if */
1142 } /* end if */
1143
1144 FUNC_LEAVE_NOAPI(ret_value)
1145 } /* H5P_create_prop() */
1146
1147
1148 /*--------------------------------------------------------------------------
1149 NAME
1150 H5P_add_prop
1151 PURPOSE
1152 Internal routine to insert a property into a property skip list
1153 USAGE
1154 herr_t H5P_add_prop(slist, prop)
1155 H5SL_t *slist; IN/OUT: Pointer to skip list of properties
1156 H5P_genprop_t *prop; IN: Pointer to property to insert
1157 RETURNS
1158 Returns non-negative on success, negative on failure.
1159 DESCRIPTION
1160 Inserts a property into a skip list of properties.
1161 GLOBAL VARIABLES
1162 COMMENTS, BUGS, ASSUMPTIONS
1163 EXAMPLES
1164 REVISION LOG
1165 --------------------------------------------------------------------------*/
1166 herr_t
H5P_add_prop(H5SL_t * slist,H5P_genprop_t * prop)1167 H5P_add_prop(H5SL_t *slist, H5P_genprop_t *prop)
1168 {
1169 herr_t ret_value = SUCCEED; /* Return value */
1170
1171 FUNC_ENTER_NOAPI(FAIL)
1172
1173 HDassert(slist);
1174 HDassert(prop);
1175 HDassert(prop->type != H5P_PROP_WITHIN_UNKNOWN);
1176
1177 /* Insert property into skip list */
1178 if(H5SL_insert(slist, prop, prop->name) < 0)
1179 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into skip list")
1180
1181 done:
1182 FUNC_LEAVE_NOAPI(ret_value)
1183 } /* H5P_add_prop() */
1184
1185
1186 /*--------------------------------------------------------------------------
1187 NAME
1188 H5P__find_prop_plist
1189 PURPOSE
1190 Internal routine to check for a property in a property list's skip list
1191 USAGE
1192 H5P_genprop_t *H5P_find_prop(plist, name)
1193 const H5P_genplist_t *plist; IN: Pointer to property list to check
1194 const char *name; IN: Name of property to check for
1195 RETURNS
1196 Returns pointer to property on success, NULL on failure.
1197 DESCRIPTION
1198 Checks for a property in a property list's skip list of properties.
1199 GLOBAL VARIABLES
1200 COMMENTS, BUGS, ASSUMPTIONS
1201 EXAMPLES
1202 REVISION LOG
1203 --------------------------------------------------------------------------*/
1204 H5P_genprop_t *
H5P__find_prop_plist(const H5P_genplist_t * plist,const char * name)1205 H5P__find_prop_plist(const H5P_genplist_t *plist, const char *name)
1206 {
1207 H5P_genprop_t *ret_value = NULL; /* Return value */
1208
1209 FUNC_ENTER_PACKAGE
1210
1211 HDassert(plist);
1212 HDassert(name);
1213
1214 /* Check if the property has been deleted from list */
1215 if(H5SL_search(plist->del,name) != NULL) {
1216 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "property deleted from skip list")
1217 } /* end if */
1218 else {
1219 /* Get the property data from the skip list */
1220 if(NULL == (ret_value = (H5P_genprop_t *)H5SL_search(plist->props, name))) {
1221 H5P_genclass_t *tclass; /* Temporary class pointer */
1222
1223 /* Couldn't find property in list itself, start searching through class info */
1224 tclass = plist->pclass;
1225 while(tclass != NULL) {
1226 /* Find the property in the class */
1227 if(NULL != (ret_value = (H5P_genprop_t *)H5SL_search(tclass->props, name)))
1228 /* Got pointer to property - leave now */
1229 break;
1230
1231 /* Go up to parent class */
1232 tclass = tclass->parent;
1233 } /* end while */
1234
1235 /* Check if we haven't found the property */
1236 if(ret_value == NULL)
1237 HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list")
1238 } /* end else */
1239 } /* end else */
1240
1241 done:
1242 FUNC_LEAVE_NOAPI(ret_value)
1243 } /* H5P__find_prop_plist() */
1244
1245
1246 /*--------------------------------------------------------------------------
1247 NAME
1248 H5P_find_prop_pclass
1249 PURPOSE
1250 Internal routine to check for a property in a class skip list
1251 USAGE
1252 H5P_genprop_t *H5P_find_prop_class(pclass, name)
1253 H5P_genclass *pclass; IN: Pointer generic property class to check
1254 const char *name; IN: Name of property to check for
1255 RETURNS
1256 Returns pointer to property on success, NULL on failure.
1257 DESCRIPTION
1258 Checks for a property in a class's skip list of properties.
1259 GLOBAL VARIABLES
1260 COMMENTS, BUGS, ASSUMPTIONS
1261 EXAMPLES
1262 REVISION LOG
1263 --------------------------------------------------------------------------*/
1264 static H5P_genprop_t *
H5P_find_prop_pclass(H5P_genclass_t * pclass,const char * name)1265 H5P_find_prop_pclass(H5P_genclass_t *pclass, const char *name)
1266 {
1267 H5P_genprop_t *ret_value = NULL; /* Return value */
1268
1269 FUNC_ENTER_NOAPI_NOINIT
1270
1271 HDassert(pclass);
1272 HDassert(name);
1273
1274 /* Get the property from the skip list */
1275 if(NULL == (ret_value = (H5P_genprop_t *)H5SL_search(pclass->props, name)))
1276 HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list")
1277
1278 done:
1279 FUNC_LEAVE_NOAPI(ret_value)
1280 } /* H5P_find_prop_pclass() */
1281
1282
1283 /*--------------------------------------------------------------------------
1284 NAME
1285 H5P_free_prop
1286 PURPOSE
1287 Internal routine to destroy a property node
1288 USAGE
1289 herr_t H5P_free_prop(prop)
1290 H5P_genprop_t *prop; IN: Pointer to property to destroy
1291 RETURNS
1292 Returns non-negative on success, negative on failure.
1293 DESCRIPTION
1294 Releases all the memory for a property list. Does _not_ call the
1295 properties 'close' callback, that should already have been done.
1296 GLOBAL VARIABLES
1297 COMMENTS, BUGS, ASSUMPTIONS
1298 EXAMPLES
1299 REVISION LOG
1300 --------------------------------------------------------------------------*/
1301 static herr_t
H5P_free_prop(H5P_genprop_t * prop)1302 H5P_free_prop(H5P_genprop_t *prop)
1303 {
1304 FUNC_ENTER_NOAPI_NOINIT_NOERR
1305
1306 HDassert(prop);
1307
1308 /* Release the property value if it exists */
1309 if(prop->value)
1310 H5MM_xfree(prop->value);
1311
1312 /* Only free the name if we own it */
1313 if(!prop->shared_name)
1314 H5MM_xfree(prop->name);
1315
1316 prop = H5FL_FREE(H5P_genprop_t, prop);
1317
1318 FUNC_LEAVE_NOAPI(SUCCEED)
1319 } /* H5P_free_prop() */
1320
1321
1322 /*--------------------------------------------------------------------------
1323 NAME
1324 H5P_free_prop_cb
1325 PURPOSE
1326 Internal routine to properties from a property skip list
1327 USAGE
1328 herr_t H5P_free_prop_cb(item, key, op_data)
1329 void *item; IN/OUT: Pointer to property
1330 void *key; IN/OUT: Pointer to property key
1331 void *_make_cb; IN: Whether to make property callbacks or not
1332 RETURNS
1333 Returns zero on success, negative on failure.
1334 DESCRIPTION
1335 Calls the property 'close' callback for a property & frees property
1336 info.
1337 GLOBAL VARIABLES
1338 COMMENTS, BUGS, ASSUMPTIONS
1339 EXAMPLES
1340 REVISION LOG
1341 --------------------------------------------------------------------------*/
1342 static herr_t
H5P_free_prop_cb(void * item,void H5_ATTR_UNUSED * key,void * op_data)1343 H5P_free_prop_cb(void *item, void H5_ATTR_UNUSED *key, void *op_data)
1344 {
1345 H5P_genprop_t *tprop=(H5P_genprop_t *)item; /* Temporary pointer to property */
1346 hbool_t make_cb = *(hbool_t *)op_data; /* Whether to make property 'close' callback */
1347
1348 FUNC_ENTER_NOAPI_NOINIT_NOERR
1349
1350 HDassert(tprop);
1351
1352 /* Call the close callback and ignore the return value, there's nothing we can do about it */
1353 if(make_cb && tprop->close != NULL)
1354 (tprop->close)(tprop->name, tprop->size, tprop->value);
1355
1356 /* Free the property, ignoring return value, nothing we can do */
1357 H5P_free_prop(tprop);
1358
1359 FUNC_LEAVE_NOAPI(0)
1360 } /* H5P_free_prop_cb() */
1361
1362
1363 /*--------------------------------------------------------------------------
1364 NAME
1365 H5P_free_del_name_cb
1366 PURPOSE
1367 Internal routine to free 'deleted' property name
1368 USAGE
1369 herr_t H5P_free_del_name_cb(item, key, op_data)
1370 void *item; IN/OUT: Pointer to deleted name
1371 void *key; IN/OUT: Pointer to key
1372 void *op_data; IN: Operator callback data (unused)
1373 RETURNS
1374 Returns zero on success, negative on failure.
1375 DESCRIPTION
1376 Frees the deleted property name
1377 GLOBAL VARIABLES
1378 COMMENTS, BUGS, ASSUMPTIONS
1379 EXAMPLES
1380 REVISION LOG
1381 --------------------------------------------------------------------------*/
1382 static herr_t
H5P_free_del_name_cb(void * item,void H5_ATTR_UNUSED * key,void H5_ATTR_UNUSED * op_data)1383 H5P_free_del_name_cb(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data)
1384 {
1385 char *del_name=(char *)item; /* Temporary pointer to deleted name */
1386
1387 FUNC_ENTER_NOAPI_NOINIT_NOERR
1388
1389 HDassert(del_name);
1390
1391 /* Free the name */
1392 H5MM_xfree(del_name);
1393
1394 FUNC_LEAVE_NOAPI(0)
1395 } /* H5P_free_del_name_cb() */
1396
1397
1398 /*--------------------------------------------------------------------------
1399 NAME
1400 H5P_access_class
1401 PURPOSE
1402 Internal routine to increment or decrement list & class dependancies on a
1403 property list class
1404 USAGE
1405 herr_t H5P_access_class(pclass,mod)
1406 H5P_genclass_t *pclass; IN: Pointer to class to modify
1407 H5P_class_mod_t mod; IN: Type of modification to class
1408 RETURNS
1409 Returns non-negative on success, negative on failure.
1410 DESCRIPTION
1411 Increment/Decrement the class or list dependancies for a given class.
1412 This routine is the final arbiter on decisions about actually releasing a
1413 class in memory, such action is only taken when the reference counts for
1414 both dependent classes & lists reach zero.
1415 GLOBAL VARIABLES
1416 COMMENTS, BUGS, ASSUMPTIONS
1417 EXAMPLES
1418 REVISION LOG
1419 --------------------------------------------------------------------------*/
1420 herr_t
H5P_access_class(H5P_genclass_t * pclass,H5P_class_mod_t mod)1421 H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
1422 {
1423 FUNC_ENTER_NOAPI_NOINIT_NOERR
1424
1425 HDassert(pclass);
1426 HDassert(mod > H5P_MOD_ERR && mod < H5P_MOD_MAX);
1427
1428 switch(mod) {
1429 case H5P_MOD_INC_CLS: /* Increment the dependant class count*/
1430 pclass->classes++;
1431 break;
1432
1433 case H5P_MOD_DEC_CLS: /* Decrement the dependant class count*/
1434 pclass->classes--;
1435 break;
1436
1437 case H5P_MOD_INC_LST: /* Increment the dependant list count*/
1438 pclass->plists++;
1439 break;
1440
1441 case H5P_MOD_DEC_LST: /* Decrement the dependant list count*/
1442 pclass->plists--;
1443 break;
1444
1445 case H5P_MOD_INC_REF: /* Increment the ID reference count*/
1446 /* Reset the deleted flag if incrementing the reference count */
1447 if(pclass->deleted)
1448 pclass->deleted = FALSE;
1449 pclass->ref_count++;
1450 break;
1451
1452 case H5P_MOD_DEC_REF: /* Decrement the ID reference count*/
1453 pclass->ref_count--;
1454
1455 /* Mark the class object as deleted if reference count drops to zero */
1456 if(pclass->ref_count == 0)
1457 pclass->deleted = TRUE;
1458 break;
1459
1460 case H5P_MOD_ERR:
1461 case H5P_MOD_MAX:
1462 default:
1463 HDassert(0 && "Invalid H5P class modification");
1464 } /* end switch */
1465
1466 /* Check if we can release the class information now */
1467 if(pclass->deleted && pclass->plists == 0 && pclass->classes == 0) {
1468 H5P_genclass_t *par_class = pclass->parent; /* Pointer to class's parent */
1469
1470 HDassert(pclass->name);
1471 H5MM_xfree(pclass->name);
1472
1473 /* Free the class properties without making callbacks */
1474 if(pclass->props) {
1475 hbool_t make_cb = FALSE;
1476
1477 H5SL_destroy(pclass->props, H5P_free_prop_cb, &make_cb);
1478 } /* end if */
1479
1480 pclass = H5FL_FREE(H5P_genclass_t, pclass);
1481
1482 /* Reduce the number of dependent classes on parent class also */
1483 if(par_class != NULL)
1484 H5P_access_class(par_class, H5P_MOD_DEC_CLS);
1485 } /* end if */
1486
1487 FUNC_LEAVE_NOAPI(SUCCEED)
1488 } /* H5P_access_class() */
1489
1490
1491 /*--------------------------------------------------------------------------
1492 NAME
1493 H5P_open_class_path_cb
1494 PURPOSE
1495 Internal callback routine to check for duplicated names in parent class.
1496 USAGE
1497 int H5P_open_class_path_cb(obj, id, key)
1498 H5P_genclass_t *obj; IN: Pointer to class
1499 hid_t id; IN: ID of object being looked at
1500 const void *key; IN: Pointer to information used to compare
1501 classes.
1502 RETURNS
1503 Returns >0 on match, 0 on no match and <0 on failure.
1504 DESCRIPTION
1505 Checks whether a property list class has the same parent and name as a
1506 new class being created. This is a callback routine for H5I_search()
1507 GLOBAL VARIABLES
1508 COMMENTS, BUGS, ASSUMPTIONS
1509 EXAMPLES
1510 REVISION LOG
1511 --------------------------------------------------------------------------*/
1512 static int
H5P_open_class_path_cb(void * _obj,hid_t H5_ATTR_UNUSED id,void * _key)1513 H5P_open_class_path_cb(void *_obj, hid_t H5_ATTR_UNUSED id, void *_key)
1514 {
1515 H5P_genclass_t *obj = (H5P_genclass_t *)_obj; /* Pointer to the class for this ID */
1516 H5P_check_class_t *key = (H5P_check_class_t *)_key; /* Pointer to key information for comparison */
1517 int ret_value = 0; /* Return value */
1518
1519 FUNC_ENTER_NOAPI_NOINIT_NOERR
1520
1521 HDassert(obj);
1522 HDassert(H5I_GENPROP_CLS == H5I_get_type(id));
1523 HDassert(key);
1524
1525 /* Check if the class object has the same parent as the new class */
1526 if(obj->parent == key->parent) {
1527 /* Check if they have the same name */
1528 if(HDstrcmp(obj->name, key->name) == 0) {
1529 key->new_class = obj;
1530 ret_value = 1; /* Indicate a match */
1531 } /* end if */
1532 } /* end if */
1533
1534 FUNC_LEAVE_NOAPI(ret_value)
1535 } /* end H5P_open_class_path_cb() */
1536
1537
1538 /*--------------------------------------------------------------------------
1539 NAME
1540 H5P_create_class
1541 PURPOSE
1542 Internal routine to create a new property list class.
1543 USAGE
1544 H5P_genclass_t H5P_create_class(par_class, name, type,
1545 cls_create, create_data, cls_close, close_data)
1546 H5P_genclass_t *par_class; IN: Pointer to parent class
1547 const char *name; IN: Name of class we are creating
1548 H5P_plist_type_t type; IN: Type of class we are creating
1549 H5P_cls_create_func_t; IN: The callback function to call when each
1550 property list in this class is created.
1551 void *create_data; IN: Pointer to user data to pass along to class
1552 creation callback.
1553 H5P_cls_copy_func_t; IN: The callback function to call when each
1554 property list in this class is copied.
1555 void *copy_data; IN: Pointer to user data to pass along to class
1556 copy callback.
1557 H5P_cls_close_func_t; IN: The callback function to call when each
1558 property list in this class is closed.
1559 void *close_data; IN: Pointer to user data to pass along to class
1560 close callback.
1561 RETURNS
1562 Returns a pointer to the newly created property list class on success,
1563 NULL on failure.
1564 DESCRIPTION
1565 Allocates memory and attaches a class to the property list class hierarchy.
1566 GLOBAL VARIABLES
1567 COMMENTS, BUGS, ASSUMPTIONS
1568 EXAMPLES
1569 REVISION LOG
1570 --------------------------------------------------------------------------*/
1571 H5P_genclass_t *
H5P_create_class(H5P_genclass_t * par_class,const char * name,H5P_plist_type_t type,H5P_cls_create_func_t cls_create,void * create_data,H5P_cls_copy_func_t cls_copy,void * copy_data,H5P_cls_close_func_t cls_close,void * close_data)1572 H5P_create_class(H5P_genclass_t *par_class, const char *name, H5P_plist_type_t type,
1573 H5P_cls_create_func_t cls_create, void *create_data,
1574 H5P_cls_copy_func_t cls_copy, void *copy_data,
1575 H5P_cls_close_func_t cls_close, void *close_data)
1576 {
1577 H5P_genclass_t *pclass = NULL; /* Property list class created */
1578 H5P_genclass_t *ret_value = NULL; /* Return value */
1579
1580 FUNC_ENTER_NOAPI(NULL)
1581
1582 HDassert(name);
1583 /* Allow internal classes to break some rules */
1584 /* (This allows the root of the tree to be created with this routine -QAK) */
1585 if(type == H5P_TYPE_USER)
1586 HDassert(par_class);
1587
1588 /* Allocate room for the class */
1589 if(NULL == (pclass = H5FL_CALLOC(H5P_genclass_t)))
1590 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, NULL, "propery list class allocation failed")
1591
1592 /* Set class state */
1593 pclass->parent = par_class;
1594 if(NULL == (pclass->name = H5MM_xstrdup(name)))
1595 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, NULL, "propery list class name allocation failed")
1596 pclass->type = type;
1597 pclass->nprops = 0; /* Classes are created without properties initially */
1598 pclass->plists = 0; /* No properties lists of this class yet */
1599 pclass->classes = 0; /* No classes derived from this class yet */
1600 pclass->ref_count = 1; /* This is the first reference to the new class */
1601 pclass->deleted = FALSE; /* Not deleted yet... :-) */
1602 pclass->revision = H5P_GET_NEXT_REV; /* Get a revision number for the class */
1603
1604 /* Create the skip list for properties */
1605 if(NULL == (pclass->props = H5SL_create(H5SL_TYPE_STR, NULL)))
1606 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "can't create skip list for properties")
1607
1608 /* Set callback functions and pass-along data */
1609 pclass->create_func = cls_create;
1610 pclass->create_data = create_data;
1611 pclass->copy_func = cls_copy;
1612 pclass->copy_data = copy_data;
1613 pclass->close_func = cls_close;
1614 pclass->close_data = close_data;
1615
1616 /* Increment parent class's derived class value */
1617 if(par_class != NULL) {
1618 if(H5P_access_class(par_class, H5P_MOD_INC_CLS) < 0)
1619 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, NULL, "Can't increment parent class ref count")
1620 } /* end if */
1621
1622 /* Set return value */
1623 ret_value = pclass;
1624
1625 done:
1626 /* Free any resources allocated */
1627 if(ret_value == NULL)
1628 if(pclass) {
1629 if(pclass->name)
1630 H5MM_xfree(pclass->name);
1631 if(pclass->props) {
1632 hbool_t make_cb = FALSE;
1633
1634 H5SL_destroy(pclass->props, H5P_free_prop_cb, &make_cb);
1635 } /* end if */
1636 pclass = H5FL_FREE(H5P_genclass_t, pclass);
1637 } /* end if */
1638
1639 FUNC_LEAVE_NOAPI(ret_value)
1640 } /* H5P_create_class() */
1641
1642
1643 /*--------------------------------------------------------------------------
1644 NAME
1645 H5P_create
1646 PURPOSE
1647 Internal routine to create a new property list of a property list class.
1648 USAGE
1649 H5P_genplist_t *H5P_create(class)
1650 H5P_genclass_t *class; IN: Property list class create list from
1651 RETURNS
1652 Returns a pointer to the newly created property list on success,
1653 NULL on failure.
1654 DESCRIPTION
1655 Creates a property list of a given class. If a 'create' callback
1656 exists for the property list class, it is called before the
1657 property list is passed back to the user.
1658
1659 GLOBAL VARIABLES
1660 COMMENTS, BUGS, ASSUMPTIONS
1661 If this routine is called from a library routine other than
1662 H5P_c, the calling routine is responsible for getting an ID for
1663 the property list and calling the class 'create' callback (if one exists)
1664 and also setting the "class_init" flag.
1665 EXAMPLES
1666 REVISION LOG
1667 --------------------------------------------------------------------------*/
1668 static H5P_genplist_t *
H5P_create(H5P_genclass_t * pclass)1669 H5P_create(H5P_genclass_t *pclass)
1670 {
1671 H5P_genclass_t *tclass; /* Temporary class pointer */
1672 H5P_genplist_t *plist = NULL; /* New property list created */
1673 H5P_genprop_t *tmp; /* Temporary pointer to parent class properties */
1674 H5SL_t *seen = NULL; /* Skip list to hold names of properties already seen */
1675 H5P_genplist_t *ret_value = NULL; /* Return value */
1676
1677 FUNC_ENTER_NOAPI_NOINIT
1678
1679 HDassert(pclass);
1680
1681 /*
1682 * Create new property list object
1683 */
1684
1685 /* Allocate room for the property list */
1686 if(NULL==(plist = H5FL_CALLOC(H5P_genplist_t)))
1687 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed")
1688
1689 /* Set class state */
1690 plist->pclass = pclass;
1691 plist->nprops = 0; /* Initially the plist has the same number of properties as the class */
1692 plist->class_init = FALSE; /* Initially, wait until the class callback finishes to set */
1693
1694 /* Create the skip list for changed properties */
1695 if((plist->props = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
1696 HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for changed properties")
1697
1698 /* Create the skip list for deleted properties */
1699 if((plist->del = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
1700 HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for deleted properties")
1701
1702 /* Create the skip list to hold names of properties already seen
1703 * (This prevents a property in the class hierarchy from having it's
1704 * 'create' callback called, if a property in the class hierarchy has
1705 * already been seen)
1706 */
1707 if((seen = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
1708 HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for seen properties")
1709
1710 /*
1711 * Check if we should copy class properties (up through list of parent classes also),
1712 * initialize each with default value & make property 'create' callback.
1713 */
1714 tclass=pclass;
1715 while(tclass!=NULL) {
1716 if(tclass->nprops>0) {
1717 H5SL_node_t *curr_node; /* Current node in skip list */
1718
1719 /* Walk through the properties in the old class */
1720 curr_node=H5SL_first(tclass->props);
1721 while(curr_node!=NULL) {
1722 /* Get pointer to property from node */
1723 tmp = (H5P_genprop_t *)H5SL_item(curr_node);
1724
1725 /* Only "create" properties we haven't seen before */
1726 if(H5SL_search(seen,tmp->name) == NULL) {
1727 /* Call property creation callback, if it exists */
1728 if(tmp->create) {
1729 /* Call the callback & insert changed value into skip list (if necessary) */
1730 if(H5P__do_prop_cb1(plist->props, tmp, tmp->create) < 0)
1731 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL,"Can't create property")
1732 } /* end if */
1733
1734 /* Add property name to "seen" list */
1735 if(H5SL_insert(seen,tmp->name,tmp->name) < 0)
1736 HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen skip list")
1737
1738 /* Increment the number of properties in list */
1739 plist->nprops++;
1740 } /* end if */
1741
1742 /* Get the next property node in the skip list */
1743 curr_node=H5SL_next(curr_node);
1744 } /* end while */
1745 } /* end if */
1746
1747 /* Go up to parent class */
1748 tclass=tclass->parent;
1749 } /* end while */
1750
1751 /* Increment the number of property lists derived from class */
1752 if(H5P_access_class(plist->pclass,H5P_MOD_INC_LST) < 0)
1753 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment class ref count")
1754
1755 /* Set return value */
1756 ret_value=plist;
1757
1758 done:
1759 /* Release the skip list of 'seen' properties */
1760 if(seen!=NULL)
1761 H5SL_close(seen);
1762
1763 /* Release resources allocated on failure */
1764 if(ret_value==NULL) {
1765 if(plist!=NULL) {
1766 /* Close & free any changed properties */
1767 if(plist->props) {
1768 unsigned make_cb=1;
1769
1770 H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb);
1771 } /* end if */
1772
1773 /* Close the deleted property skip list */
1774 if(plist->del)
1775 H5SL_close(plist->del);
1776
1777 /* Release the property list itself */
1778 plist = H5FL_FREE(H5P_genplist_t, plist);
1779 } /* end if */
1780 } /* end if */
1781
1782 FUNC_LEAVE_NOAPI(ret_value)
1783 } /* H5P_create() */
1784
1785
1786 /*--------------------------------------------------------------------------
1787 NAME
1788 H5P_create_id
1789 PURPOSE
1790 Internal routine to create a new property list of a property list class.
1791 USAGE
1792 hid_t H5P_create_id(pclass)
1793 H5P_genclass_t *pclass; IN: Property list class create list from
1794 RETURNS
1795 Returns a valid property list ID on success, FAIL on failure.
1796 DESCRIPTION
1797 Creates a property list of a given class. If a 'create' callback
1798 exists for the property list class, it is called before the
1799 property list is passed back to the user. If 'create' callbacks exist for
1800 any individual properties in the property list, they are called before the
1801 class 'create' callback.
1802
1803 GLOBAL VARIABLES
1804 COMMENTS, BUGS, ASSUMPTIONS
1805 EXAMPLES
1806 REVISION LOG
1807 --------------------------------------------------------------------------*/
1808 hid_t
H5P_create_id(H5P_genclass_t * pclass,hbool_t app_ref)1809 H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref)
1810 {
1811 H5P_genclass_t *tclass; /* Temporary class pointer */
1812 H5P_genplist_t *plist = NULL; /* Property list created */
1813 hid_t plist_id = FAIL; /* Property list ID */
1814 hid_t ret_value = H5I_INVALID_HID; /* return value */
1815
1816 FUNC_ENTER_NOAPI(FAIL)
1817
1818 HDassert(pclass);
1819
1820 /* Create the new property list */
1821 if((plist=H5P_create(pclass)) == NULL)
1822 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list")
1823
1824 /* Get an atom for the property list */
1825 if((plist_id = H5I_register(H5I_GENPROP_LST, plist, app_ref)) < 0)
1826 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list")
1827
1828 /* Save the property list ID in the property list struct, for use in the property class's 'close' callback */
1829 plist->plist_id=plist_id;
1830
1831 /* Call the class callback (if it exists) now that we have the property list ID
1832 * (up through chain of parent classes also)
1833 */
1834 tclass = plist->pclass;
1835 while(NULL != tclass) {
1836 if(NULL != tclass->create_func) {
1837 if((tclass->create_func)(plist_id, tclass->create_data) < 0) {
1838 /* Delete ID, ignore return value */
1839 H5I_remove(plist_id);
1840 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property")
1841 } /* end if */
1842 } /* end if */
1843
1844 /* Go up to parent class */
1845 tclass = tclass->parent;
1846 } /* end while */
1847
1848 /* Set the class initialization flag */
1849 plist->class_init = TRUE;
1850
1851 /* Set the return value */
1852 ret_value=plist_id;
1853
1854 done:
1855 if(ret_value<0 && plist)
1856 H5P_close(plist);
1857
1858 FUNC_LEAVE_NOAPI(ret_value)
1859 } /* H5P_create_id() */
1860
1861
1862 /*--------------------------------------------------------------------------
1863 NAME
1864 H5P_register_real
1865 PURPOSE
1866 Internal routine to register a new property in a property list class.
1867 USAGE
1868 herr_t H5P_register_real(class, name, size, default, prp_create, prp_set,
1869 prp_get, prp_close, prp_encode, prp_decode)
1870 H5P_genclass_t *class; IN: Property list class to modify
1871 const char *name; IN: Name of property to register
1872 size_t size; IN: Size of property in bytes
1873 void *def_value; IN: Pointer to buffer containing default value
1874 for property in newly created property lists
1875 H5P_prp_create_func_t prp_create; IN: Function pointer to property
1876 creation callback
1877 H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
1878 H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
1879 H5P_prp_encode_func_t prp_encode; IN: Function pointer to property encode
1880 H5P_prp_decode_func_t prp_decode; IN: Function pointer to property decode
1881 H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
1882 H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
1883 H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback
1884 H5P_prp_close_func_t prp_close; IN: Function pointer to property close
1885 callback
1886 RETURNS
1887 Returns non-negative on success, negative on failure.
1888 DESCRIPTION
1889 Registers a new property with a property list class. The property will
1890 exist in all property list objects of that class after this routine is
1891 finished. The name of the property must not already exist. The default
1892 property value must be provided and all new property lists created with this
1893 property will have the property value set to the default provided. Any of
1894 the callback routines may be set to NULL if they are not needed.
1895
1896 Zero-sized properties are allowed and do not store any data in the
1897 property list. These may be used as flags to indicate the presence or
1898 absence of a particular piece of information. The 'default' pointer for a
1899 zero-sized property may be set to NULL. The property 'create' & 'close'
1900 callbacks are called for zero-sized properties, but the 'set' and 'get'
1901 callbacks are never called.
1902
1903 The 'create' callback is called when a new property list with this
1904 property is being created. H5P_prp_create_func_t is defined as:
1905 typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name,
1906 size_t size, void *initial_value);
1907 where the parameters to the callback function are:
1908 hid_t prop_id; IN: The ID of the property list being created.
1909 const char *name; IN: The name of the property being modified.
1910 size_t size; IN: The size of the property value
1911 void *initial_value; IN/OUT: The initial value for the property being created.
1912 (The 'default' value passed to H5Pregister2)
1913 The 'create' routine may modify the value to be set and those changes will
1914 be stored as the initial value of the property. If the 'create' routine
1915 returns a negative value, the new property value is not copied into the
1916 property and the property list creation routine returns an error value.
1917
1918 The 'set' callback is called before a new value is copied into the
1919 property. H5P_prp_set_func_t is defined as:
1920 typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
1921 size_t size, void *value);
1922 where the parameters to the callback function are:
1923 hid_t prop_id; IN: The ID of the property list being modified.
1924 const char *name; IN: The name of the property being modified.
1925 size_t size; IN: The size of the property value
1926 void *new_value; IN/OUT: The value being set for the property.
1927 The 'set' routine may modify the value to be set and those changes will be
1928 stored as the value of the property. If the 'set' routine returns a
1929 negative value, the new property value is not copied into the property and
1930 the property list set routine returns an error value.
1931
1932 The 'get' callback is called before a value is retrieved from the
1933 property. H5P_prp_get_func_t is defined as:
1934 typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
1935 size_t size, void *value);
1936 where the parameters to the callback function are:
1937 hid_t prop_id; IN: The ID of the property list being queried.
1938 const char *name; IN: The name of the property being queried.
1939 size_t size; IN: The size of the property value
1940 void *value; IN/OUT: The value being retrieved for the property.
1941 The 'get' routine may modify the value to be retrieved and those changes
1942 will be returned to the calling function. If the 'get' routine returns a
1943 negative value, the property value is returned and the property list get
1944 routine returns an error value.
1945
1946 The 'delete' callback is called when a property is deleted from a
1947 property list. H5P_prp_del_func_t is defined as:
1948 typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
1949 size_t size, void *value);
1950 where the parameters to the callback function are:
1951 hid_t prop_id; IN: The ID of the property list the property is deleted from.
1952 const char *name; IN: The name of the property being deleted.
1953 size_t size; IN: The size of the property value
1954 void *value; IN/OUT: The value of the property being deleted.
1955 The 'delete' routine may modify the value passed in, but the value is not
1956 used by the library when the 'delete' routine returns. If the
1957 'delete' routine returns a negative value, the property list deletion
1958 routine returns an error value but the property is still deleted.
1959
1960 The 'copy' callback is called when a property list with this
1961 property is copied. H5P_prp_copy_func_t is defined as:
1962 typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
1963 void *value);
1964 where the parameters to the callback function are:
1965 const char *name; IN: The name of the property being copied.
1966 size_t size; IN: The size of the property value
1967 void *value; IN: The value of the property being copied.
1968 The 'copy' routine may modify the value to be copied and those changes will be
1969 stored as the value of the property. If the 'copy' routine returns a
1970 negative value, the new property value is not copied into the property and
1971 the property list copy routine returns an error value.
1972
1973 The 'compare' callback is called when a property list with this
1974 property is compared to another property list. H5P_prp_compare_func_t is
1975 defined as:
1976 typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
1977 size_t size);
1978 where the parameters to the callback function are:
1979 const void *value1; IN: The value of the first property being compared.
1980 const void *value2; IN: The value of the second property being compared.
1981 size_t size; IN: The size of the property value
1982 The 'compare' routine may not modify the values to be compared. The
1983 'compare' routine should return a positive value if VALUE1 is greater than
1984 VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1
1985 and VALUE2 are equal.
1986
1987 The 'close' callback is called when a property list with this
1988 property is being destroyed. H5P_prp_close_func_t is defined as:
1989 typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
1990 void *value);
1991 where the parameters to the callback function are:
1992 const char *name; IN: The name of the property being closed.
1993 size_t size; IN: The size of the property value
1994 void *value; IN: The value of the property being closed.
1995 The 'close' routine may modify the value passed in, but the value is not
1996 used by the library when the 'close' routine returns. If the
1997 'close' routine returns a negative value, the property list close
1998 routine returns an error value but the property list is still closed.
1999
2000 The 'encode' callback is called when a property list with this
2001 property is being encoded. H5P_prp_encode_func_t is defined as:
2002 typedef herr_t (*H5P_prp_encode_func_t)(void *f, size_t *size,
2003 void *value, void *plist, uint8_t **buf);
2004 where the parameters to the callback function are:
2005 void *f; IN: A fake file structure used to encode.
2006 size_t *size; IN/OUT: The size of the buffer to encode the property.
2007 void *value; IN: The value of the property being encoded.
2008 void *plist; IN: The property list structure.
2009 uint8_t **buf; OUT: The buffer that holds the encoded property;
2010 The 'encode' routine returns the size needed to encode the property value
2011 if the buffer passed in is NULL or the size is zero. Otherwise it encodes
2012 the property value into binary in buf.
2013
2014 The 'decode' callback is called when a property list with this
2015 property is being decoded. H5P_prp_encode_func_t is defined as:
2016 typedef herr_t (*H5P_prp_encode_func_t)(void *f, size_t *size,
2017 void *value, void *plist, uint8_t **buf);
2018 where the parameters to the callback function are:
2019 void *f; IN: A fake file structure used to decode.
2020 size_t *size; IN: H5_ATTR_UNUSED
2021 void *value; IN: H5_ATTR_UNUSED
2022 void *plist; IN: The property list structure.
2023 uint8_t **buf; IN: The buffer that holds the binary encoded property;
2024 The 'decode' routine decodes the binary buffer passed in and transforms it into
2025 corresponding property values that are set in the property list passed in.
2026
2027 GLOBAL VARIABLES
2028 COMMENTS, BUGS, ASSUMPTIONS
2029 The 'set' callback function may be useful to range check the value being
2030 set for the property or may perform some tranformation/translation of the
2031 value set. The 'get' callback would then [probably] reverse the
2032 transformation, etc. A single 'get' or 'set' callback could handle
2033 multiple properties by performing different actions based on the property
2034 name or other properties in the property list.
2035
2036 I would like to say "the property list is not closed" when a 'close'
2037 routine fails, but I don't think that's possible due to other properties in
2038 the list being successfully closed & removed from the property list. I
2039 suppose that it would be possible to just remove the properties which have
2040 successful 'close' callbacks, but I'm not happy with the ramifications
2041 of a mangled, un-closable property list hanging around... Any comments? -QAK
2042
2043 EXAMPLES
2044 REVISION LOG
2045 --------------------------------------------------------------------------*/
2046 herr_t
H5P_register_real(H5P_genclass_t * pclass,const char * name,size_t size,const void * def_value,H5P_prp_create_func_t prp_create,H5P_prp_set_func_t prp_set,H5P_prp_get_func_t prp_get,H5P_prp_encode_func_t prp_encode,H5P_prp_decode_func_t prp_decode,H5P_prp_delete_func_t prp_delete,H5P_prp_copy_func_t prp_copy,H5P_prp_compare_func_t prp_cmp,H5P_prp_close_func_t prp_close)2047 H5P_register_real(H5P_genclass_t *pclass, const char *name, size_t size,
2048 const void *def_value, H5P_prp_create_func_t prp_create,
2049 H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
2050 H5P_prp_encode_func_t prp_encode, H5P_prp_decode_func_t prp_decode,
2051 H5P_prp_delete_func_t prp_delete,
2052 H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp,
2053 H5P_prp_close_func_t prp_close)
2054 {
2055 H5P_genprop_t *new_prop = NULL; /* Temporary property pointer */
2056 herr_t ret_value = SUCCEED; /* Return value */
2057
2058 FUNC_ENTER_NOAPI(FAIL)
2059
2060 HDassert(pclass);
2061 HDassert(0 == pclass->plists);
2062 HDassert(0 == pclass->classes);
2063 HDassert(name);
2064 HDassert((size > 0 && def_value != NULL) || (size == 0));
2065
2066 /* Check for duplicate named properties */
2067 if(NULL != H5SL_search(pclass->props, name))
2068 HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists")
2069
2070 /* Create property object from parameters */
2071 if(NULL == (new_prop = H5P_create_prop(name, size, H5P_PROP_WITHIN_CLASS,
2072 def_value, prp_create, prp_set, prp_get, prp_encode, prp_decode,
2073 prp_delete, prp_copy, prp_cmp, prp_close)))
2074 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property")
2075
2076 /* Insert property into property list class */
2077 if(H5P_add_prop(pclass->props, new_prop) < 0)
2078 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class")
2079
2080 /* Increment property count for class */
2081 pclass->nprops++;
2082
2083 /* Update the revision for the class */
2084 pclass->revision = H5P_GET_NEXT_REV;
2085
2086 done:
2087 if(ret_value < 0)
2088 if(new_prop && H5P_free_prop(new_prop) < 0)
2089 HDONE_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close property")
2090
2091 FUNC_LEAVE_NOAPI(ret_value)
2092 } /* H5P_register_real() */
2093
2094
2095 /*--------------------------------------------------------------------------
2096 NAME
2097 H5P_register
2098 PURPOSE
2099 Internal routine to register a new property in a property list class.
2100 USAGE
2101 herr_t H5P_register(class, name, size, default, prp_create, prp_set, prp_get, prp_close)
2102 H5P_genclass_t **class; IN: Property list class to modify
2103 const char *name; IN: Name of property to register
2104 size_t size; IN: Size of property in bytes
2105 void *def_value; IN: Pointer to buffer containing default value
2106 for property in newly created property lists
2107 H5P_prp_create_func_t prp_create; IN: Function pointer to property
2108 creation callback
2109 H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
2110 H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
2111 H5P_prp_encode_func_t prp_encode; IN: Function pointer to property encode
2112 H5P_prp_decode_func_t prp_decode; IN: Function pointer to property decode
2113 H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
2114 H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
2115 H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback
2116 H5P_prp_close_func_t prp_close; IN: Function pointer to property close
2117 callback
2118 RETURNS
2119 Returns non-negative on success, negative on failure.
2120 DESCRIPTION
2121 Registers a new property with a property list class. The property will
2122 exist in all property list objects of that class after this routine is
2123 finished. The name of the property must not already exist. The default
2124 property value must be provided and all new property lists created with this
2125 property will have the property value set to the default provided. Any of
2126 the callback routines may be set to NULL if they are not needed.
2127
2128 Zero-sized properties are allowed and do not store any data in the
2129 property list. These may be used as flags to indicate the presence or
2130 absence of a particular piece of information. The 'default' pointer for a
2131 zero-sized property may be set to NULL. The property 'create' & 'close'
2132 callbacks are called for zero-sized properties, but the 'set' and 'get'
2133 callbacks are never called.
2134
2135 The 'create' callback is called when a new property list with this
2136 property is being created. H5P_prp_create_func_t is defined as:
2137 typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name,
2138 size_t size, void *initial_value);
2139 where the parameters to the callback function are:
2140 hid_t prop_id; IN: The ID of the property list being created.
2141 const char *name; IN: The name of the property being modified.
2142 size_t size; IN: The size of the property value
2143 void *initial_value; IN/OUT: The initial value for the property being created.
2144 (The 'default' value passed to H5Pregister2)
2145 The 'create' routine may modify the value to be set and those changes will
2146 be stored as the initial value of the property. If the 'create' routine
2147 returns a negative value, the new property value is not copied into the
2148 property and the property list creation routine returns an error value.
2149
2150 The 'set' callback is called before a new value is copied into the
2151 property. H5P_prp_set_func_t is defined as:
2152 typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
2153 size_t size, void *value);
2154 where the parameters to the callback function are:
2155 hid_t prop_id; IN: The ID of the property list being modified.
2156 const char *name; IN: The name of the property being modified.
2157 size_t size; IN: The size of the property value
2158 void *new_value; IN/OUT: The value being set for the property.
2159 The 'set' routine may modify the value to be set and those changes will be
2160 stored as the value of the property. If the 'set' routine returns a
2161 negative value, the new property value is not copied into the property and
2162 the property list set routine returns an error value.
2163
2164 The 'get' callback is called before a value is retrieved from the
2165 property. H5P_prp_get_func_t is defined as:
2166 typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
2167 size_t size, void *value);
2168 where the parameters to the callback function are:
2169 hid_t prop_id; IN: The ID of the property list being queried.
2170 const char *name; IN: The name of the property being queried.
2171 size_t size; IN: The size of the property value
2172 void *value; IN/OUT: The value being retrieved for the property.
2173 The 'get' routine may modify the value to be retrieved and those changes
2174 will be returned to the calling function. If the 'get' routine returns a
2175 negative value, the property value is returned and the property list get
2176 routine returns an error value.
2177
2178 The 'encode' callback is called when a property list with this
2179 property is being encoded. H5P_prp_encode_func_t is defined as:
2180 typedef herr_t (*H5P_prp_encode_func_t)(void *f, size_t *size,
2181 void *value, void *plist, uint8_t **buf);
2182 where the parameters to the callback function are:
2183 void *f; IN: A fake file structure used to encode.
2184 size_t *size; IN/OUT: The size of the buffer to encode the property.
2185 void *value; IN: The value of the property being encoded.
2186 void *plist; IN: The property list structure.
2187 uint8_t **buf; OUT: The buffer that holds the encoded property;
2188 The 'encode' routine returns the size needed to encode the property value
2189 if the buffer passed in is NULL or the size is zero. Otherwise it encodes
2190 the property value into binary in buf.
2191
2192 The 'decode' callback is called when a property list with this
2193 property is being decoded. H5P_prp_encode_func_t is defined as:
2194 typedef herr_t (*H5P_prp_encode_func_t)(void *f, size_t *size,
2195 void *value, void *plist, uint8_t **buf);
2196 where the parameters to the callback function are:
2197 void *f; IN: A fake file structure used to decode.
2198 size_t *size; IN: H5_ATTR_UNUSED
2199 void *value; IN: H5_ATTR_UNUSED
2200 void *plist; IN: The property list structure.
2201 uint8_t **buf; IN: The buffer that holds the binary encoded property;
2202 The 'decode' routine decodes the binary buffer passed in and transforms it into
2203 corresponding property values that are set in the property list passed in.
2204
2205 The 'delete' callback is called when a property is deleted from a
2206 property list. H5P_prp_del_func_t is defined as:
2207 typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
2208 size_t size, void *value);
2209 where the parameters to the callback function are:
2210 hid_t prop_id; IN: The ID of the property list the property is deleted from.
2211 const char *name; IN: The name of the property being deleted.
2212 size_t size; IN: The size of the property value
2213 void *value; IN/OUT: The value of the property being deleted.
2214 The 'delete' routine may modify the value passed in, but the value is not
2215 used by the library when the 'delete' routine returns. If the
2216 'delete' routine returns a negative value, the property list deletion
2217 routine returns an error value but the property is still deleted.
2218
2219 The 'copy' callback is called when a property list with this
2220 property is copied. H5P_prp_copy_func_t is defined as:
2221 typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
2222 void *value);
2223 where the parameters to the callback function are:
2224 const char *name; IN: The name of the property being copied.
2225 size_t size; IN: The size of the property value
2226 void *value; IN: The value of the property being copied.
2227 The 'copy' routine may modify the value to be copied and those changes will be
2228 stored as the value of the property. If the 'copy' routine returns a
2229 negative value, the new property value is not copied into the property and
2230 the property list copy routine returns an error value.
2231
2232 The 'compare' callback is called when a property list with this
2233 property is compared to another property list. H5P_prp_compare_func_t is
2234 defined as:
2235 typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
2236 size_t size);
2237 where the parameters to the callback function are:
2238 const void *value1; IN: The value of the first property being compared.
2239 const void *value2; IN: The value of the second property being compared.
2240 size_t size; IN: The size of the property value
2241 The 'compare' routine may not modify the values to be compared. The
2242 'compare' routine should return a positive value if VALUE1 is greater than
2243 VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1
2244 and VALUE2 are equal.
2245
2246 The 'close' callback is called when a property list with this
2247 property is being destroyed. H5P_prp_close_func_t is defined as:
2248 typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
2249 void *value);
2250 where the parameters to the callback function are:
2251 const char *name; IN: The name of the property being closed.
2252 size_t size; IN: The size of the property value
2253 void *value; IN: The value of the property being closed.
2254 The 'close' routine may modify the value passed in, but the value is not
2255 used by the library when the 'close' routine returns. If the
2256 'close' routine returns a negative value, the property list close
2257 routine returns an error value but the property list is still closed.
2258
2259 GLOBAL VARIABLES
2260 COMMENTS, BUGS, ASSUMPTIONS
2261 The 'set' callback function may be useful to range check the value being
2262 set for the property or may perform some tranformation/translation of the
2263 value set. The 'get' callback would then [probably] reverse the
2264 transformation, etc. A single 'get' or 'set' callback could handle
2265 multiple properties by performing different actions based on the property
2266 name or other properties in the property list.
2267
2268 I would like to say "the property list is not closed" when a 'close'
2269 routine fails, but I don't think that's possible due to other properties in
2270 the list being successfully closed & removed from the property list. I
2271 suppose that it would be possible to just remove the properties which have
2272 successful 'close' callbacks, but I'm not happy with the ramifications
2273 of a mangled, un-closable property list hanging around... Any comments? -QAK
2274
2275 EXAMPLES
2276 REVISION LOG
2277 --------------------------------------------------------------------------*/
2278 herr_t
H5P_register(H5P_genclass_t ** ppclass,const char * name,size_t size,const void * def_value,H5P_prp_create_func_t prp_create,H5P_prp_set_func_t prp_set,H5P_prp_get_func_t prp_get,H5P_prp_encode_func_t prp_encode,H5P_prp_decode_func_t prp_decode,H5P_prp_delete_func_t prp_delete,H5P_prp_copy_func_t prp_copy,H5P_prp_compare_func_t prp_cmp,H5P_prp_close_func_t prp_close)2279 H5P_register(H5P_genclass_t **ppclass, const char *name, size_t size,
2280 const void *def_value, H5P_prp_create_func_t prp_create,
2281 H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
2282 H5P_prp_encode_func_t prp_encode, H5P_prp_decode_func_t prp_decode,
2283 H5P_prp_delete_func_t prp_delete,
2284 H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp,
2285 H5P_prp_close_func_t prp_close)
2286 {
2287 H5P_genclass_t *pclass = *ppclass; /* Pointer to class to modify */
2288 H5P_genclass_t *new_class = NULL; /* New class pointer */
2289 herr_t ret_value = SUCCEED; /* Return value */
2290
2291 FUNC_ENTER_NOAPI(FAIL)
2292
2293 /* Sanity check */
2294 HDassert(ppclass);
2295 HDassert(pclass);
2296
2297 /* Check if class needs to be split because property lists or classes have
2298 * been created since the last modification was made to the class.
2299 */
2300 if(pclass->plists > 0 || pclass->classes > 0) {
2301 if(NULL == (new_class = H5P_create_class(pclass->parent, pclass->name,
2302 pclass->type, pclass->create_func, pclass->create_data,
2303 pclass->copy_func, pclass->copy_data,
2304 pclass->close_func, pclass->close_data)))
2305 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy class")
2306
2307 /* Walk through the skip list of the old class and copy properties */
2308 if(pclass->nprops > 0) {
2309 H5SL_node_t *curr_node; /* Current node in skip list */
2310
2311 /* Walk through the properties in the old class */
2312 curr_node = H5SL_first(pclass->props);
2313 while(curr_node != NULL) {
2314 H5P_genprop_t *pcopy; /* Property copy */
2315
2316 /* Make a copy of the class's property */
2317 if(NULL == (pcopy = H5P_dup_prop((H5P_genprop_t *)H5SL_item(curr_node), H5P_PROP_WITHIN_CLASS)))
2318 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property")
2319
2320 /* Insert the initialized property into the property class */
2321 if(H5P_add_prop(new_class->props, pcopy) < 0)
2322 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class")
2323
2324 /* Increment property count for class */
2325 new_class->nprops++;
2326
2327 /* Get the next property node in the skip list */
2328 curr_node = H5SL_next(curr_node);
2329 } /* end while */
2330 } /* end if */
2331
2332 /* Use the new class instead of the old one */
2333 pclass = new_class;
2334 } /* end if */
2335
2336 /* Really register the property in the class */
2337 if(H5P_register_real(pclass, name, size, def_value, prp_create, prp_set, prp_get,
2338 prp_encode, prp_decode, prp_delete, prp_copy, prp_cmp, prp_close) < 0)
2339 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "can't register property")
2340
2341 /* Update pointer to pointer to class, if a new one was generated */
2342 if(new_class)
2343 *ppclass = pclass;
2344
2345 done:
2346 if(ret_value < 0)
2347 if(new_class && H5P_close_class(new_class) < 0)
2348 HDONE_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close new property class")
2349
2350 FUNC_LEAVE_NOAPI(ret_value)
2351 } /* H5P_register() */
2352
2353
2354 /*--------------------------------------------------------------------------
2355 NAME
2356 H5P_insert
2357 PURPOSE
2358 Internal routine to insert a new property in a property list.
2359 USAGE
2360 herr_t H5P_insert(plist, name, size, value, prp_set, prp_get, prp_close,
2361 prp_encode, prp_decode)
2362 H5P_genplist_t *plist; IN: Property list to add property to
2363 const char *name; IN: Name of property to add
2364 size_t size; IN: Size of property in bytes
2365 void *value; IN: Pointer to the value for the property
2366 H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
2367 H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
2368 H5P_prp_encode_func_t prp_encode; IN: Function pointer to property encode
2369 H5P_prp_decode_func_t prp_decode; IN: Function pointer to property decode
2370 H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
2371 H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
2372 H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback
2373 H5P_prp_close_func_t prp_close; IN: Function pointer to property close
2374 callback
2375 RETURNS
2376 Returns non-negative on success, negative on failure.
2377 DESCRIPTION
2378 Inserts a temporary property into a property list. The property will
2379 exist only in this property list object. The name of the property must not
2380 already exist. The value must be provided unless the property is zero-
2381 sized. Any of the callback routines may be set to NULL if they are not
2382 needed.
2383
2384 Zero-sized properties are allowed and do not store any data in the
2385 property list. These may be used as flags to indicate the presence or
2386 absence of a particular piece of information. The 'value' pointer for a
2387 zero-sized property may be set to NULL. The property 'close' callback is
2388 called for zero-sized properties, but the 'set' and 'get' callbacks are
2389 never called.
2390
2391 The 'set' callback is called before a new value is copied into the
2392 property. H5P_prp_set_func_t is defined as:
2393 typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
2394 size_t size, void *value);
2395 where the parameters to the callback function are:
2396 hid_t prop_id; IN: The ID of the property list being modified.
2397 const char *name; IN: The name of the property being modified.
2398 size_t size; IN: The size of the property value
2399 void *new_value; IN/OUT: The value being set for the property.
2400 The 'set' routine may modify the value to be set and those changes will be
2401 stored as the value of the property. If the 'set' routine returns a
2402 negative value, the new property value is not copied into the property and
2403 the property list set routine returns an error value.
2404
2405 The 'get' callback is called before a value is retrieved from the
2406 property. H5P_prp_get_func_t is defined as:
2407 typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
2408 size_t size, void *value);
2409 where the parameters to the callback function are:
2410 hid_t prop_id; IN: The ID of the property list being queried.
2411 const char *name; IN: The name of the property being queried.
2412 size_t size; IN: The size of the property value
2413 void *value; IN/OUT: The value being retrieved for the property.
2414 The 'get' routine may modify the value to be retrieved and those changes
2415 will be returned to the calling function. If the 'get' routine returns a
2416 negative value, the property value is returned and the property list get
2417 routine returns an error value.
2418
2419 The 'encode' callback is called when a property list with this
2420 property is being encoded. H5P_prp_encode_func_t is defined as:
2421 typedef herr_t (*H5P_prp_encode_func_t)(void *f, size_t *size,
2422 void *value, void *plist, uint8_t **buf);
2423 where the parameters to the callback function are:
2424 void *f; IN: A fake file structure used to encode.
2425 size_t *size; IN/OUT: The size of the buffer to encode the property.
2426 void *value; IN: The value of the property being encoded.
2427 void *plist; IN: The property list structure.
2428 uint8_t **buf; OUT: The buffer that holds the encoded property;
2429 The 'encode' routine returns the size needed to encode the property value
2430 if the buffer passed in is NULL or the size is zero. Otherwise it encodes
2431 the property value into binary in buf.
2432
2433 The 'decode' callback is called when a property list with this
2434 property is being decoded. H5P_prp_encode_func_t is defined as:
2435 typedef herr_t (*H5P_prp_encode_func_t)(void *f, size_t *size,
2436 void *value, void *plist, uint8_t **buf);
2437 where the parameters to the callback function are:
2438 void *f; IN: A fake file structure used to decode.
2439 size_t *size; IN: H5_ATTR_UNUSED
2440 void *value; IN: H5_ATTR_UNUSED
2441 void *plist; IN: The property list structure.
2442 uint8_t **buf; IN: The buffer that holds the binary encoded property;
2443 The 'decode' routine decodes the binary buffer passed in and transforms it into
2444 corresponding property values that are set in the property list passed in.
2445
2446 The 'delete' callback is called when a property is deleted from a
2447 property list. H5P_prp_del_func_t is defined as:
2448 typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
2449 size_t size, void *value);
2450 where the parameters to the callback function are:
2451 hid_t prop_id; IN: The ID of the property list the property is deleted from.
2452 const char *name; IN: The name of the property being deleted.
2453 size_t size; IN: The size of the property value
2454 void *value; IN/OUT: The value of the property being deleted.
2455 The 'delete' routine may modify the value passed in, but the value is not
2456 used by the library when the 'delete' routine returns. If the
2457 'delete' routine returns a negative value, the property list deletion
2458 routine returns an error value but the property is still deleted.
2459
2460 The 'copy' callback is called when a property list with this
2461 property is copied. H5P_prp_copy_func_t is defined as:
2462 typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
2463 void *value);
2464 where the parameters to the callback function are:
2465 const char *name; IN: The name of the property being copied.
2466 size_t size; IN: The size of the property value
2467 void *value; IN: The value of the property being copied.
2468 The 'copy' routine may modify the value to be copied and those changes will be
2469 stored as the value of the property. If the 'copy' routine returns a
2470 negative value, the new property value is not copied into the property and
2471 the property list copy routine returns an error value.
2472
2473 The 'compare' callback is called when a property list with this
2474 property is compared to another property list. H5P_prp_compare_func_t is
2475 defined as:
2476 typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
2477 size_t size);
2478 where the parameters to the callback function are:
2479 const void *value1; IN: The value of the first property being compared.
2480 const void *value2; IN: The value of the second property being compared.
2481 size_t size; IN: The size of the property value
2482 The 'compare' routine may not modify the values to be compared. The
2483 'compare' routine should return a positive value if VALUE1 is greater than
2484 VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1
2485 and VALUE2 are equal.
2486
2487 The 'close' callback is called when a property list with this
2488 property is being destroyed. H5P_prp_close_func_t is defined as:
2489 typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
2490 void *value);
2491 where the parameters to the callback function are:
2492 const char *name; IN: The name of the property being closed.
2493 size_t size; IN: The size of the property value
2494 void *value; IN: The value of the property being closed.
2495 The 'close' routine may modify the value passed in, but the value is not
2496 used by the library when the 'close' routine returns. If the
2497 'close' routine returns a negative value, the property list close
2498 routine returns an error value but the property list is still closed.
2499
2500 GLOBAL VARIABLES
2501 COMMENTS, BUGS, ASSUMPTIONS
2502 The 'set' callback function may be useful to range check the value being
2503 set for the property or may perform some tranformation/translation of the
2504 value set. The 'get' callback would then [probably] reverse the
2505 transformation, etc. A single 'get' or 'set' callback could handle
2506 multiple properties by performing different actions based on the property
2507 name or other properties in the property list.
2508
2509 There is no 'create' callback routine for temporary property list
2510 objects, the initial value is assumed to have any necessary setup already
2511 performed on it.
2512
2513 I would like to say "the property list is not closed" when a 'close'
2514 routine fails, but I don't think that's possible due to other properties in
2515 the list being successfully closed & removed from the property list. I
2516 suppose that it would be possible to just remove the properties which have
2517 successful 'close' callbacks, but I'm not happy with the ramifications
2518 of a mangled, un-closable property list hanging around... Any comments? -QAK
2519
2520 EXAMPLES
2521 REVISION LOG
2522 --------------------------------------------------------------------------*/
2523 herr_t
H5P_insert(H5P_genplist_t * plist,const char * name,size_t size,void * value,H5P_prp_set_func_t prp_set,H5P_prp_get_func_t prp_get,H5P_prp_encode_func_t prp_encode,H5P_prp_decode_func_t prp_decode,H5P_prp_delete_func_t prp_delete,H5P_prp_copy_func_t prp_copy,H5P_prp_compare_func_t prp_cmp,H5P_prp_close_func_t prp_close)2524 H5P_insert(H5P_genplist_t *plist, const char *name, size_t size,
2525 void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
2526 H5P_prp_encode_func_t prp_encode, H5P_prp_decode_func_t prp_decode,
2527 H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
2528 H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close)
2529 {
2530 H5P_genprop_t *new_prop = NULL; /* Temporary property pointer */
2531 herr_t ret_value = SUCCEED; /* Return value */
2532
2533 FUNC_ENTER_NOAPI_NOINIT
2534
2535 HDassert(plist);
2536 HDassert(name);
2537 HDassert((size > 0 && value != NULL) || (size == 0));
2538
2539 /* Check for duplicate named properties */
2540 if(NULL != H5SL_search(plist->props, name))
2541 HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists")
2542
2543 /* Check if the property has been deleted */
2544 if(NULL != H5SL_search(plist->del, name)) {
2545 char *temp_name = NULL;
2546
2547 /* Remove the property name from the deleted property skip list */
2548 if(NULL == (temp_name = (char *)H5SL_remove(plist->del, name)))
2549 HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from deleted skip list")
2550
2551 /* free the name of the removed property */
2552 H5MM_xfree(temp_name);
2553 } /* end if */
2554 else {
2555 H5P_genclass_t *tclass; /* Temporary class pointer */
2556
2557 /* Check if the property is already in the class hierarchy */
2558 tclass = plist->pclass;
2559 while(tclass) {
2560 if(tclass->nprops > 0) {
2561 /* Find the property in the class */
2562 if(NULL != H5SL_search(tclass->props, name))
2563 HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists")
2564 } /* end if */
2565
2566 /* Go up to parent class */
2567 tclass = tclass->parent;
2568 } /* end while */
2569 } /* end else */
2570
2571 /* Ok to add to property list */
2572
2573 /* Create property object from parameters */
2574 if(NULL == (new_prop = H5P_create_prop(name, size, H5P_PROP_WITHIN_LIST, value, NULL,
2575 prp_set, prp_get, prp_encode, prp_decode, prp_delete, prp_copy,
2576 prp_cmp, prp_close)))
2577 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "Can't create property")
2578
2579 /* Insert property into property list class */
2580 if(H5P_add_prop(plist->props, new_prop) < 0)
2581 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "Can't insert property into class")
2582
2583 /* Increment property count for class */
2584 plist->nprops++;
2585
2586 done:
2587 if(ret_value < 0)
2588 if(new_prop && H5P_free_prop(new_prop) < 0)
2589 HDONE_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close property")
2590
2591 FUNC_LEAVE_NOAPI(ret_value)
2592 } /* H5P_insert() */
2593
2594
2595 /*--------------------------------------------------------------------------
2596 NAME
2597 H5P__do_prop
2598 PURPOSE
2599 Internal routine to perform an operation on a property in a property list
2600 USAGE
2601 herr_t H5P__do_prop(plist, name, cb, udata)
2602 H5P_genplist_t *plist; IN: Property list to find property in
2603 const char *name; IN: Name of property to set
2604 H5P_do_plist_op_t plist_op; IN: Pointer to the callback to invoke when the
2605 property is found in the property list
2606 H5P_do_pclass_op_t pclass_op; IN: Pointer to the callback to invoke when the
2607 property is found in the property class
2608 void *udata; IN: Pointer to the user data for the callback
2609 RETURNS
2610 Returns non-negative on success, negative on failure.
2611 DESCRIPTION
2612 Finds a property in a property list and calls the callback with it.
2613 GLOBAL VARIABLES
2614 COMMENTS, BUGS, ASSUMPTIONS
2615 EXAMPLES
2616 REVISION LOG
2617 --------------------------------------------------------------------------*/
2618 static herr_t
H5P__do_prop(H5P_genplist_t * plist,const char * name,H5P_do_plist_op_t plist_op,H5P_do_pclass_op_t pclass_op,void * udata)2619 H5P__do_prop(H5P_genplist_t *plist, const char *name, H5P_do_plist_op_t plist_op,
2620 H5P_do_pclass_op_t pclass_op, void *udata)
2621 {
2622 H5P_genclass_t *tclass; /* Temporary class pointer */
2623 H5P_genprop_t *prop; /* Temporary property pointer */
2624 herr_t ret_value = SUCCEED; /* Return value */
2625
2626 FUNC_ENTER_STATIC
2627
2628 /* Sanity check */
2629 HDassert(plist);
2630 HDassert(name);
2631 HDassert(plist_op);
2632 HDassert(pclass_op);
2633
2634 /* Check if the property has been deleted */
2635 if(NULL != H5SL_search(plist->del, name))
2636 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist")
2637
2638 /* Find property in changed list */
2639 if(NULL != (prop = (H5P_genprop_t *)H5SL_search(plist->props, name))) {
2640 /* Call the 'found in propery list' callback */
2641 if((*plist_op)(plist, name, prop, udata) < 0)
2642 HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on property")
2643 } /* end if */
2644 else {
2645 /*
2646 * Check if we should set class properties (up through list of parent classes also),
2647 * & make property 'set' callback.
2648 */
2649 tclass = plist->pclass;
2650 while(NULL != tclass) {
2651 if(tclass->nprops > 0) {
2652 /* Find the property in the class */
2653 if(NULL != (prop = (H5P_genprop_t *)H5SL_search(tclass->props, name))) {
2654 /* Call the 'found in class' callback */
2655 if((*pclass_op)(plist, name, prop, udata) < 0)
2656 HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on property")
2657
2658 /* Leave */
2659 break;
2660 } /* end if */
2661 } /* end if */
2662
2663 /* Go up to parent class */
2664 tclass = tclass->parent;
2665 } /* end while */
2666
2667 /* If we get this far, then it wasn't in the list of changed properties,
2668 * nor in the properties in the class hierarchy, indicate an error
2669 */
2670 if(NULL == tclass)
2671 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't find property in skip list")
2672 } /* end else */
2673
2674 done:
2675 FUNC_LEAVE_NOAPI(ret_value)
2676 } /* H5P__do_prop() */
2677
2678
2679 /*--------------------------------------------------------------------------
2680 NAME
2681 H5P__poke_plist_cb
2682 PURPOSE
2683 Internal callback for H5P__do_prop, to overwrite a property's value in a property list.
2684 USAGE
2685 herr_t H5P__poke_plist_cb(plist, name, value)
2686 H5P_genplist_t *plist; IN: Property list to overwrite property in
2687 const char *name; IN: Name of property to overwrite
2688 H5P_genprop_t *prop; IN: Property to overwrite
2689 void *udata; IN: User data for operation
2690 RETURNS
2691 Returns non-negative on success, negative on failure.
2692 DESCRIPTION
2693 Overwrite a value for a property in a property list.
2694 GLOBAL VARIABLES
2695 COMMENTS, BUGS, ASSUMPTIONS
2696 Called when the property is found in the property list.
2697 EXAMPLES
2698 REVISION LOG
2699 --------------------------------------------------------------------------*/
2700 static herr_t
H5P__poke_plist_cb(H5P_genplist_t * plist,const char * name,H5P_genprop_t * prop,void * _udata)2701 H5P__poke_plist_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
2702 void *_udata)
2703 {
2704 H5P_prop_set_ud_t *udata = (H5P_prop_set_ud_t *)_udata; /* User data for callback */
2705 herr_t ret_value = SUCCEED; /* Return value */
2706
2707 FUNC_ENTER_STATIC
2708
2709 /* Sanity check */
2710 HDassert(plist);
2711 HDassert(name);
2712 HDassert(prop);
2713
2714 /* Check for property size >0 */
2715 if(0 == prop->size)
2716 HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size")
2717
2718 /* Overwrite value in property */
2719 HDmemcpy(prop->value, udata->value, prop->size);
2720
2721 done:
2722 FUNC_LEAVE_NOAPI(ret_value)
2723 } /* H5P__poke_plist_cb() */
2724
2725
2726 /*--------------------------------------------------------------------------
2727 NAME
2728 H5P__poke_pclass_cb
2729 PURPOSE
2730 Internal callback for H5P__do_prop, to overwrite a property's value in a property list.
2731 USAGE
2732 herr_t H5P__poke_pclass_cb(plist, name, value)
2733 H5P_genplist_t *plist; IN: Property list to overwrite property in
2734 const char *name; IN: Name of property to overwrite
2735 H5P_genprop_t *prop; IN: Property to overwrite
2736 void *udata; IN: User data for operation
2737 RETURNS
2738 Returns non-negative on success, negative on failure.
2739 DESCRIPTION
2740 Overwrite a value for a property in a property list.
2741 GLOBAL VARIABLES
2742 COMMENTS, BUGS, ASSUMPTIONS
2743 Called when the property is found in the property class.
2744 EXAMPLES
2745 REVISION LOG
2746 --------------------------------------------------------------------------*/
2747 static herr_t
H5P__poke_pclass_cb(H5P_genplist_t * plist,const char * name,H5P_genprop_t * prop,void * _udata)2748 H5P__poke_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
2749 void *_udata)
2750 {
2751 H5P_prop_set_ud_t *udata = (H5P_prop_set_ud_t *)_udata; /* User data for callback */
2752 H5P_genprop_t *pcopy = NULL; /* Copy of property to insert into skip list */
2753 herr_t ret_value = SUCCEED; /* Return value */
2754
2755 FUNC_ENTER_STATIC
2756
2757 /* Sanity check */
2758 HDassert(plist);
2759 HDassert(name);
2760 HDassert(prop);
2761 HDassert(prop->cmp);
2762
2763 /* Check for property size >0 */
2764 if(0 == prop->size)
2765 HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size")
2766
2767 /* Make a copy of the class's property */
2768 if(NULL == (pcopy = H5P_dup_prop(prop, H5P_PROP_WITHIN_LIST)))
2769 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property")
2770
2771 HDmemcpy(pcopy->value, udata->value, pcopy->size);
2772
2773 /* Insert the changed property into the property list */
2774 if(H5P_add_prop(plist->props, pcopy) < 0)
2775 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list")
2776
2777 done:
2778 /* Cleanup on failure */
2779 if(ret_value < 0)
2780 if(pcopy)
2781 H5P_free_prop(pcopy);
2782
2783 FUNC_LEAVE_NOAPI(ret_value)
2784 } /* H5P__poke_pclass_cb() */
2785
2786
2787 /*--------------------------------------------------------------------------
2788 NAME
2789 H5P_poke
2790 PURPOSE
2791 Internal routine to overwrite a property's value in a property list.
2792 USAGE
2793 herr_t H5P_poke(plist, name, value)
2794 H5P_genplist_t *plist; IN: Property list to find property in
2795 const char *name; IN: Name of property to overwrite
2796 void *value; IN: Pointer to the value for the property
2797 RETURNS
2798 Returns non-negative on success, negative on failure.
2799 DESCRIPTION
2800 Overwrites a property in a property list (i.e. a "shallow" copy over
2801 the property value). The property name must exist or this routine will
2802 fail. If there is a setget' callback routine registered for this property,
2803 it is _NOT_ called.
2804 GLOBAL VARIABLES
2805 COMMENTS, BUGS, ASSUMPTIONS
2806 This routine may not be called for zero-sized properties and will
2807 return an error in that case.
2808 EXAMPLES
2809 REVISION LOG
2810 --------------------------------------------------------------------------*/
2811 herr_t
H5P_poke(H5P_genplist_t * plist,const char * name,const void * value)2812 H5P_poke(H5P_genplist_t *plist, const char *name, const void *value)
2813 {
2814 H5P_prop_set_ud_t udata; /* User data for callback */
2815 herr_t ret_value = SUCCEED; /* Return value */
2816
2817 FUNC_ENTER_NOAPI(FAIL)
2818
2819 /* Sanity check */
2820 HDassert(plist);
2821 HDassert(name);
2822 HDassert(value);
2823
2824 /* Find the property and set the value */
2825 udata.value = value;
2826 if(H5P__do_prop(plist, name, H5P__poke_plist_cb, H5P__poke_pclass_cb, &udata) < 0)
2827 HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to overwrite value")
2828
2829 done:
2830 FUNC_LEAVE_NOAPI(ret_value)
2831 } /* H5P_poke() */
2832
2833
2834 /*--------------------------------------------------------------------------
2835 NAME
2836 H5P__set_plist_cb
2837 PURPOSE
2838 Internal callback for H5P__do_prop, to set a property's value in a property list.
2839 USAGE
2840 herr_t H5P__set_plist_cb(plist, name, value)
2841 H5P_genplist_t *plist; IN: Property list to set property in
2842 const char *name; IN: Name of property to set
2843 H5P_genprop_t *prop; IN: Property to set
2844 void *udata; IN: User data for operation
2845 RETURNS
2846 Returns non-negative on success, negative on failure.
2847 DESCRIPTION
2848 Sets a new value for a property in a property list.
2849 GLOBAL VARIABLES
2850 COMMENTS, BUGS, ASSUMPTIONS
2851 Called when the property is found in the property list.
2852 EXAMPLES
2853 REVISION LOG
2854 --------------------------------------------------------------------------*/
2855 static herr_t
H5P__set_plist_cb(H5P_genplist_t * plist,const char * name,H5P_genprop_t * prop,void * _udata)2856 H5P__set_plist_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
2857 void *_udata)
2858 {
2859 H5P_prop_set_ud_t *udata = (H5P_prop_set_ud_t *)_udata; /* User data for callback */
2860 void *tmp_value = NULL; /* Temporary value for property */
2861 herr_t ret_value = SUCCEED; /* Return value */
2862
2863 FUNC_ENTER_STATIC
2864
2865 /* Sanity check */
2866 HDassert(plist);
2867 HDassert(name);
2868 HDassert(prop);
2869
2870 /* Check for property size >0 */
2871 if(0 == prop->size)
2872 HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size")
2873
2874 /* Make a copy of the value and pass to 'set' callback */
2875 if(NULL != prop->set) {
2876 /* Make a copy of the current value, in case the callback fails */
2877 if(NULL == (tmp_value = H5MM_malloc(prop->size)))
2878 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed temporary property value")
2879 HDmemcpy(tmp_value, udata->value, prop->size);
2880
2881 /* Call user's callback */
2882 if((*(prop->set))(plist->plist_id, name, prop->size, tmp_value) < 0)
2883 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value")
2884 } /* end if */
2885 /* No 'set' callback, just copy value */
2886 else
2887 tmp_value = (void *)udata->value; /* Casting away const OK -QAK */
2888
2889 /* Free any previous value for the property */
2890 if(NULL != prop->del) {
2891 /* Call user's 'delete' callback */
2892 if((*(prop->del))(plist->plist_id, name, prop->size, prop->value) < 0)
2893 HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release property value")
2894 } /* end if */
2895
2896 /* Copy new [possibly unchanged] value into property value */
2897 HDmemcpy(prop->value, tmp_value, prop->size);
2898
2899 done:
2900 /* Free the temporary value buffer */
2901 if(tmp_value != NULL && tmp_value != udata->value)
2902 H5MM_xfree(tmp_value);
2903
2904 FUNC_LEAVE_NOAPI(ret_value)
2905 } /* H5P__set_plist_cb() */
2906
2907
2908 /*--------------------------------------------------------------------------
2909 NAME
2910 H5P__set_pclass_cb
2911 PURPOSE
2912 Internal callback for H5P__do_prop, to set a property's value in a property list.
2913 USAGE
2914 herr_t H5P__set_pclass_cb(plist, name, value)
2915 H5P_genplist_t *plist; IN: Property list to set property in
2916 const char *name; IN: Name of property to set
2917 H5P_genprop_t *prop; IN: Property to set
2918 void *udata; IN: User data for operation
2919 RETURNS
2920 Returns non-negative on success, negative on failure.
2921 DESCRIPTION
2922 Sets a new value for a property in a property list.
2923 GLOBAL VARIABLES
2924 COMMENTS, BUGS, ASSUMPTIONS
2925 Called when the property is found in the property class.
2926 EXAMPLES
2927 REVISION LOG
2928 --------------------------------------------------------------------------*/
2929 static herr_t
H5P__set_pclass_cb(H5P_genplist_t * plist,const char * name,H5P_genprop_t * prop,void * _udata)2930 H5P__set_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
2931 void *_udata)
2932 {
2933 H5P_prop_set_ud_t *udata = (H5P_prop_set_ud_t *)_udata; /* User data for callback */
2934 H5P_genprop_t *pcopy = NULL; /* Copy of property to insert into skip list */
2935 void *tmp_value = NULL; /* Temporary value for property */
2936 herr_t ret_value = SUCCEED; /* Return value */
2937
2938 FUNC_ENTER_STATIC
2939
2940 /* Sanity check */
2941 HDassert(plist);
2942 HDassert(name);
2943 HDassert(prop);
2944 HDassert(prop->cmp);
2945
2946 /* Check for property size >0 */
2947 if(0 == prop->size)
2948 HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size")
2949
2950 /* Make a copy of the value and pass to 'set' callback */
2951 if(NULL != prop->set) {
2952 /* Make a copy of the current value, in case the callback fails */
2953 if(NULL == (tmp_value = H5MM_malloc(prop->size)))
2954 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed temporary property value")
2955 HDmemcpy(tmp_value, udata->value, prop->size);
2956
2957 /* Call user's callback */
2958 if((*(prop->set))(plist->plist_id, name, prop->size, tmp_value) < 0)
2959 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value")
2960 } /* end if */
2961 /* No 'set' callback, just copy value */
2962 else
2963 tmp_value = (void *)udata->value; /* Casting away const OK -QAK */
2964
2965 /* Make a copy of the class's property */
2966 if(NULL == (pcopy = H5P_dup_prop(prop, H5P_PROP_WITHIN_LIST)))
2967 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property")
2968
2969 HDmemcpy(pcopy->value, tmp_value, pcopy->size);
2970
2971 /* Insert the changed property into the property list */
2972 if(H5P_add_prop(plist->props, pcopy) < 0)
2973 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list")
2974
2975 done:
2976 /* Free the temporary value buffer */
2977 if(tmp_value != NULL && tmp_value != udata->value)
2978 H5MM_xfree(tmp_value);
2979
2980 /* Cleanup on failure */
2981 if(ret_value < 0)
2982 if(pcopy)
2983 H5P_free_prop(pcopy);
2984
2985 FUNC_LEAVE_NOAPI(ret_value)
2986 } /* H5P__set_pclass_cb() */
2987
2988
2989 /*--------------------------------------------------------------------------
2990 NAME
2991 H5P_set
2992 PURPOSE
2993 Internal routine to set a property's value in a property list.
2994 USAGE
2995 herr_t H5P_set(plist, name, value)
2996 H5P_genplist_t *plist; IN: Property list to find property in
2997 const char *name; IN: Name of property to set
2998 const void *value; IN: Pointer to the value for the property
2999 RETURNS
3000 Returns non-negative on success, negative on failure.
3001 DESCRIPTION
3002 Sets a new value for a property in a property list. The property name
3003 must exist or this routine will fail. If there is a 'set' callback routine
3004 registered for this property, the 'value' will be passed to that routine and
3005 any changes to the 'value' will be used when setting the property value.
3006 The information pointed at by the 'value' pointer (possibly modified by the
3007 'set' callback) is copied into the property list value and may be changed
3008 by the application making the H5Pset call without affecting the property
3009 value.
3010
3011 If the 'set' callback routine returns an error, the property value will
3012 not be modified. This routine may not be called for zero-sized properties
3013 and will return an error in that case.
3014
3015 GLOBAL VARIABLES
3016 COMMENTS, BUGS, ASSUMPTIONS
3017 EXAMPLES
3018 REVISION LOG
3019 --------------------------------------------------------------------------*/
3020 herr_t
H5P_set(H5P_genplist_t * plist,const char * name,const void * value)3021 H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
3022 {
3023 H5P_prop_set_ud_t udata; /* User data for callback */
3024 herr_t ret_value = SUCCEED; /* Return value */
3025
3026 FUNC_ENTER_NOAPI(FAIL)
3027
3028 /* Sanity check */
3029 HDassert(plist);
3030 HDassert(name);
3031 HDassert(value);
3032
3033 /* Find the property and set the value */
3034 udata.value = value;
3035 if(H5P__do_prop(plist, name, H5P__set_plist_cb, H5P__set_pclass_cb, &udata) < 0)
3036 HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to set value")
3037
3038 done:
3039 FUNC_LEAVE_NOAPI(ret_value)
3040 } /* H5P_set() */
3041
3042
3043 /*--------------------------------------------------------------------------
3044 NAME
3045 H5P_exist_plist
3046 PURPOSE
3047 Internal routine to query the existance of a property in a property list.
3048 USAGE
3049 htri_t H5P_exist_plist(plist, name)
3050 const H5P_genplist_t *plist; IN: Property list to check
3051 const char *name; IN: Name of property to check for
3052 RETURNS
3053 Success: Positive if the property exists in the property list, zero
3054 if the property does not exist.
3055 Failure: negative value
3056 DESCRIPTION
3057 This routine checks if a property exists within a property list.
3058
3059 GLOBAL VARIABLES
3060 COMMENTS, BUGS, ASSUMPTIONS
3061 EXAMPLES
3062 REVISION LOG
3063 --------------------------------------------------------------------------*/
3064 htri_t
H5P_exist_plist(const H5P_genplist_t * plist,const char * name)3065 H5P_exist_plist(const H5P_genplist_t *plist, const char *name)
3066 {
3067 htri_t ret_value = FAIL; /* return value */
3068
3069 FUNC_ENTER_NOAPI_NOINIT_NOERR
3070
3071 HDassert(plist);
3072 HDassert(name);
3073
3074 /* Check for property in deleted property list */
3075 if(H5SL_search(plist->del, name) != NULL)
3076 ret_value = FALSE;
3077 else {
3078 /* Check for property in changed property list */
3079 if(H5SL_search(plist->props, name) != NULL)
3080 ret_value = TRUE;
3081 else {
3082 H5P_genclass_t *tclass; /* Temporary class pointer */
3083
3084 tclass = plist->pclass;
3085 while(tclass != NULL) {
3086 if(H5SL_search(tclass->props, name) != NULL)
3087 HGOTO_DONE(TRUE)
3088
3089 /* Go up to parent class */
3090 tclass = tclass->parent;
3091 } /* end while */
3092
3093 /* If we've reached here, we couldn't find the property */
3094 ret_value = FALSE;
3095 } /* end else */
3096 } /* end else */
3097
3098 done:
3099 FUNC_LEAVE_NOAPI(ret_value)
3100 } /* H5P_exist_plist() */
3101
3102
3103 /*--------------------------------------------------------------------------
3104 NAME
3105 H5P_exist_pclass
3106 PURPOSE
3107 Internal routine to query the existance of a property in a property class.
3108 USAGE
3109 herr_t H5P_exist_pclass(pclass, name)
3110 H5P_genclass_t *pclass; IN: Property class to check
3111 const char *name; IN: Name of property to check for
3112 RETURNS
3113 Success: Positive if the property exists in the property class, zero
3114 if the property does not exist.
3115 Failure: negative value
3116 DESCRIPTION
3117 This routine checks if a property exists within a property class.
3118
3119 GLOBAL VARIABLES
3120 COMMENTS, BUGS, ASSUMPTIONS
3121 EXAMPLES
3122 REVISION LOG
3123 --------------------------------------------------------------------------*/
3124 htri_t
H5P_exist_pclass(H5P_genclass_t * pclass,const char * name)3125 H5P_exist_pclass(H5P_genclass_t *pclass, const char *name)
3126 {
3127 htri_t ret_value = FAIL; /* return value */
3128
3129 FUNC_ENTER_NOAPI_NOINIT_NOERR
3130
3131 HDassert(pclass);
3132 HDassert(name);
3133
3134 /* Check for property in property list */
3135 if(H5SL_search(pclass->props, name) != NULL)
3136 ret_value = TRUE;
3137 else {
3138 H5P_genclass_t *tclass; /* Temporary class pointer */
3139
3140 tclass = pclass->parent;
3141 while(tclass != NULL) {
3142 if(H5SL_search(tclass->props, name) != NULL)
3143 HGOTO_DONE(TRUE)
3144
3145 /* Go up to parent class */
3146 tclass = tclass->parent;
3147 } /* end while */
3148
3149 /* If we've reached here, we couldn't find the property */
3150 ret_value = FALSE;
3151 } /* end else */
3152
3153 done:
3154 FUNC_LEAVE_NOAPI(ret_value)
3155 } /* H5P_exist_pclass() */
3156
3157
3158 /*--------------------------------------------------------------------------
3159 NAME
3160 H5P_get_size_plist
3161 PURPOSE
3162 Internal routine to query the size of a property in a property list.
3163 USAGE
3164 herr_t H5P_get_size_plist(plist, name)
3165 const H5P_genplist_t *plist; IN: Property list to check
3166 const char *name; IN: Name of property to query
3167 size_t *size; OUT: Size of property
3168 RETURNS
3169 Success: non-negative value
3170 Failure: negative value
3171 DESCRIPTION
3172 This routine retrieves the size of a property's value in bytes. Zero-
3173 sized properties are allowed and return a value of 0.
3174
3175 GLOBAL VARIABLES
3176 COMMENTS, BUGS, ASSUMPTIONS
3177 EXAMPLES
3178 REVISION LOG
3179 --------------------------------------------------------------------------*/
3180 herr_t
H5P_get_size_plist(const H5P_genplist_t * plist,const char * name,size_t * size)3181 H5P_get_size_plist(const H5P_genplist_t *plist, const char *name, size_t *size)
3182 {
3183 H5P_genprop_t *prop; /* Temporary property pointer */
3184 herr_t ret_value=SUCCEED; /* return value */
3185
3186 FUNC_ENTER_NOAPI_NOINIT
3187
3188 HDassert(plist);
3189 HDassert(name);
3190 HDassert(size);
3191
3192 /* Find property */
3193 if(NULL == (prop = H5P__find_prop_plist(plist, name)))
3194 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist")
3195
3196 /* Get property size */
3197 *size = prop->size;
3198
3199 done:
3200 FUNC_LEAVE_NOAPI(ret_value)
3201 } /* H5P_get_size_plist() */
3202
3203
3204 /*--------------------------------------------------------------------------
3205 NAME
3206 H5P_get_size_pclass
3207 PURPOSE
3208 Internal routine to query the size of a property in a property class.
3209 USAGE
3210 herr_t H5P_get_size_pclass(pclass, name)
3211 H5P_genclass_t *pclass; IN: Property class to check
3212 const char *name; IN: Name of property to query
3213 size_t *size; OUT: Size of property
3214 RETURNS
3215 Success: non-negative value
3216 Failure: negative value
3217 DESCRIPTION
3218 This routine retrieves the size of a property's value in bytes. Zero-
3219 sized properties are allowed and return a value of 0.
3220
3221 GLOBAL VARIABLES
3222 COMMENTS, BUGS, ASSUMPTIONS
3223 EXAMPLES
3224 REVISION LOG
3225 --------------------------------------------------------------------------*/
3226 herr_t
H5P_get_size_pclass(H5P_genclass_t * pclass,const char * name,size_t * size)3227 H5P_get_size_pclass(H5P_genclass_t *pclass, const char *name, size_t *size)
3228 {
3229 H5P_genprop_t *prop; /* Temporary property pointer */
3230 herr_t ret_value=SUCCEED; /* return value */
3231
3232 FUNC_ENTER_NOAPI_NOINIT
3233
3234 HDassert(pclass);
3235 HDassert(name);
3236 HDassert(size);
3237
3238 /* Find property */
3239 if((prop=H5P_find_prop_pclass(pclass,name)) == NULL)
3240 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist")
3241
3242 /* Get property size */
3243 *size=prop->size;
3244
3245 done:
3246 FUNC_LEAVE_NOAPI(ret_value)
3247 } /* H5P_get_size_pclass() */
3248
3249
3250 /*--------------------------------------------------------------------------
3251 NAME
3252 H5P_get_nprops_plist
3253 PURPOSE
3254 Internal routine to query the number of properties in a property list
3255 USAGE
3256 herr_t H5P_get_nprops_plist(plist, nprops)
3257 H5P_genplist_t *plist; IN: Property list to check
3258 size_t *nprops; OUT: Number of properties in the property list
3259 RETURNS
3260 Success: non-negative value
3261 Failure: negative value
3262 DESCRIPTION
3263 This routine retrieves the number of a properties in a property list.
3264
3265 GLOBAL VARIABLES
3266 COMMENTS, BUGS, ASSUMPTIONS
3267 EXAMPLES
3268 REVISION LOG
3269 --------------------------------------------------------------------------*/
3270 herr_t
H5P_get_nprops_plist(const H5P_genplist_t * plist,size_t * nprops)3271 H5P_get_nprops_plist(const H5P_genplist_t *plist, size_t *nprops)
3272 {
3273 FUNC_ENTER_NOAPI_NOINIT_NOERR
3274
3275 HDassert(plist);
3276 HDassert(nprops);
3277
3278 /* Get property size */
3279 *nprops = plist->nprops;
3280
3281 FUNC_LEAVE_NOAPI(SUCCEED)
3282 } /* H5P_get_nprops_plist() */
3283
3284
3285 /*--------------------------------------------------------------------------
3286 NAME
3287 H5P_get_nprops_pclass
3288 PURPOSE
3289 Internal routine to query the number of properties in a property class
3290 USAGE
3291 herr_t H5P_get_nprops_pclass(pclass, nprops)
3292 H5P_genclass_t *pclass; IN: Property class to check
3293 size_t *nprops; OUT: Number of properties in the property list
3294 hbool_t recurse; IN: Include properties in parent class(es) also
3295 RETURNS
3296 Success: non-negative value (can't fail)
3297 Failure: negative value
3298 DESCRIPTION
3299 This routine retrieves the number of a properties in a property class.
3300
3301 GLOBAL VARIABLES
3302 COMMENTS, BUGS, ASSUMPTIONS
3303 EXAMPLES
3304 REVISION LOG
3305 --------------------------------------------------------------------------*/
3306 herr_t
H5P_get_nprops_pclass(const H5P_genclass_t * pclass,size_t * nprops,hbool_t recurse)3307 H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, hbool_t recurse)
3308 {
3309 herr_t ret_value = SUCCEED; /* Return value */
3310
3311 FUNC_ENTER_NOAPI(FAIL)
3312
3313 HDassert(pclass);
3314 HDassert(nprops);
3315
3316 /* Get number of properties */
3317 *nprops = pclass->nprops;
3318
3319 /* Check if the class is derived, and walk up the chain, if so */
3320 if(recurse)
3321 while(pclass->parent != NULL) {
3322 pclass = pclass->parent;
3323 *nprops += pclass->nprops;
3324 } /* end while */
3325
3326 done:
3327 FUNC_LEAVE_NOAPI(ret_value)
3328 } /* H5P_get_nprops_pclass() */
3329
3330
3331 /*--------------------------------------------------------------------------
3332 NAME
3333 H5P_cmp_prop
3334 PURPOSE
3335 Internal routine to compare two generic properties
3336 USAGE
3337 int H5P_cmp_prop(prop1, prop2)
3338 H5P_genprop_t *prop1; IN: 1st property to compare
3339 H5P_genprop_t *prop1; IN: 2nd property to compare
3340 RETURNS
3341 Success: negative if prop1 "less" than prop2, positive if prop1 "greater"
3342 than prop2, zero if prop1 is "equal" to prop2
3343 Failure: can't fail
3344 DESCRIPTION
3345 This function compares two generic properties together to see if
3346 they are the same property.
3347
3348 GLOBAL VARIABLES
3349 COMMENTS, BUGS, ASSUMPTIONS
3350 EXAMPLES
3351 REVISION LOG
3352 --------------------------------------------------------------------------*/
3353 static int
H5P_cmp_prop(const H5P_genprop_t * prop1,const H5P_genprop_t * prop2)3354 H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2)
3355 {
3356 int cmp_value; /* Value from comparison */
3357 int ret_value = 0; /* return value */
3358
3359 FUNC_ENTER_NOAPI_NOINIT_NOERR
3360
3361 HDassert(prop1);
3362 HDassert(prop2);
3363
3364 /* Check the name */
3365 if((cmp_value = HDstrcmp(prop1->name, prop2->name)) != 0)
3366 HGOTO_DONE(cmp_value);
3367
3368 /* Check the size of properties */
3369 if(prop1->size < prop2->size) HGOTO_DONE(-1);
3370 if(prop1->size > prop2->size) HGOTO_DONE(1);
3371
3372 /* Check if they both have the same 'create' callback */
3373 if(prop1->create == NULL && prop2->create != NULL) HGOTO_DONE(-1);
3374 if(prop1->create != NULL && prop2->create == NULL) HGOTO_DONE(1);
3375 if(prop1->create != prop2->create) HGOTO_DONE(-1);
3376
3377 /* Check if they both have the same 'set' callback */
3378 if(prop1->set == NULL && prop2->set != NULL) HGOTO_DONE(-1);
3379 if(prop1->set != NULL && prop2->set == NULL) HGOTO_DONE(1);
3380 if(prop1->set != prop2->set) HGOTO_DONE(-1);
3381
3382 /* Check if they both have the same 'get' callback */
3383 if(prop1->get == NULL && prop2->get != NULL) HGOTO_DONE(-1);
3384 if(prop1->get != NULL && prop2->get == NULL) HGOTO_DONE(1);
3385 if(prop1->get != prop2->get) HGOTO_DONE(-1);
3386
3387 /* Check if they both have the same 'encode' callback */
3388 if(prop1->encode == NULL && prop2->encode != NULL) HGOTO_DONE(-1);
3389 if(prop1->encode != NULL && prop2->encode == NULL) HGOTO_DONE(1);
3390 if(prop1->encode != prop2->encode) HGOTO_DONE(-1);
3391
3392 /* Check if they both have the same 'decode' callback */
3393 if(prop1->decode == NULL && prop2->decode != NULL) HGOTO_DONE(-1);
3394 if(prop1->decode != NULL && prop2->decode == NULL) HGOTO_DONE(1);
3395 if(prop1->decode != prop2->decode) HGOTO_DONE(-1);
3396
3397 /* Check if they both have the same 'delete' callback */
3398 if(prop1->del == NULL && prop2->del != NULL) HGOTO_DONE(-1);
3399 if(prop1->del != NULL && prop2->del == NULL) HGOTO_DONE(1);
3400 if(prop1->del != prop2->del) HGOTO_DONE(-1);
3401
3402 /* Check if they both have the same 'copy' callback */
3403 if(prop1->copy == NULL && prop2->copy != NULL) HGOTO_DONE(-1);
3404 if(prop1->copy != NULL && prop2->copy == NULL) HGOTO_DONE(1);
3405 if(prop1->copy != prop2->copy) HGOTO_DONE(-1);
3406
3407 /* Check if they both have the same 'compare' callback */
3408 if(prop1->cmp == NULL && prop2->cmp != NULL) HGOTO_DONE(-1);
3409 if(prop1->cmp != NULL && prop2->cmp == NULL) HGOTO_DONE(1);
3410 if(prop1->cmp != prop2->cmp) HGOTO_DONE(-1);
3411
3412 /* Check if they both have the same 'close' callback */
3413 if(prop1->close == NULL && prop2->close != NULL) HGOTO_DONE(-1);
3414 if(prop1->close != NULL && prop2->close == NULL) HGOTO_DONE(1);
3415 if(prop1->close != prop2->close) HGOTO_DONE(-1);
3416
3417 /* Check if they both have values allocated (or not allocated) */
3418 if(prop1->value == NULL && prop2->value != NULL) HGOTO_DONE(-1);
3419 if(prop1->value != NULL && prop2->value == NULL) HGOTO_DONE(1);
3420 if(prop1->value != NULL) {
3421 /* Call comparison routine */
3422 if((cmp_value = prop1->cmp(prop1->value, prop2->value, prop1->size)) != 0)
3423 HGOTO_DONE(cmp_value);
3424 } /* end if */
3425
3426 done:
3427 FUNC_LEAVE_NOAPI(ret_value)
3428 } /* H5P_cmp_prop() */
3429
3430
3431 /*--------------------------------------------------------------------------
3432 NAME
3433 H5P_cmp_class
3434 PURPOSE
3435 Internal routine to compare two generic property classes
3436 USAGE
3437 int H5P_cmp_class(pclass1, pclass2)
3438 H5P_genclass_t *pclass1; IN: 1st property class to compare
3439 H5P_genclass_t *pclass2; IN: 2nd property class to compare
3440 RETURNS
3441 Success: negative if class1 "less" than class2, positive if class1 "greater"
3442 than class2, zero if class1 is "equal" to class2
3443 Failure: can't fail
3444 DESCRIPTION
3445 This function compares two generic property classes together to see if
3446 they are the same class.
3447
3448 GLOBAL VARIABLES
3449 COMMENTS, BUGS, ASSUMPTIONS
3450 EXAMPLES
3451 REVISION LOG
3452 --------------------------------------------------------------------------*/
3453 int
H5P_cmp_class(const H5P_genclass_t * pclass1,const H5P_genclass_t * pclass2)3454 H5P_cmp_class(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2)
3455 {
3456 H5SL_node_t *tnode1, *tnode2; /* Temporary pointer to property nodes */
3457 int cmp_value; /* Value from comparison */
3458 int ret_value = 0; /* Return value */
3459
3460 FUNC_ENTER_NOAPI_NOINIT_NOERR
3461
3462 HDassert(pclass1);
3463 HDassert(pclass2);
3464
3465 /* Use the revision number to quickly check for identical classes */
3466 if(pclass1->revision == pclass2->revision)
3467 HGOTO_DONE(0);
3468
3469 /* Check the name */
3470 if((cmp_value = HDstrcmp(pclass1->name, pclass2->name)) != 0)
3471 HGOTO_DONE(cmp_value);
3472
3473 /* Check the number of properties */
3474 if(pclass1->nprops < pclass2->nprops) HGOTO_DONE(-1);
3475 if(pclass1->nprops > pclass2->nprops) HGOTO_DONE(1);
3476
3477 /* Check the number of property lists created from the class */
3478 if(pclass1->plists < pclass2->plists) HGOTO_DONE(-1);
3479 if(pclass1->plists > pclass2->plists) HGOTO_DONE(1);
3480
3481 /* Check the number of classes derived from the class */
3482 if(pclass1->classes < pclass2->classes) HGOTO_DONE(-1);
3483 if(pclass1->classes > pclass2->classes) HGOTO_DONE(1);
3484
3485 /* Check the number of ID references open on the class */
3486 if(pclass1->ref_count < pclass2->ref_count) HGOTO_DONE(-1);
3487 if(pclass1->ref_count > pclass2->ref_count) HGOTO_DONE(1);
3488
3489 /* Check the property list types */
3490 if(pclass1->type < pclass2->type) HGOTO_DONE(-1);
3491 if(pclass1->type > pclass2->type) HGOTO_DONE(1);
3492
3493 /* Check whether they are deleted or not */
3494 if(pclass1->deleted < pclass2->deleted) HGOTO_DONE(-1);
3495 if(pclass1->deleted > pclass2->deleted) HGOTO_DONE(1);
3496
3497 /* Check whether they have creation callback functions & data */
3498 if(pclass1->create_func == NULL && pclass2->create_func != NULL) HGOTO_DONE(-1);
3499 if(pclass1->create_func != NULL && pclass2->create_func == NULL) HGOTO_DONE(1);
3500 if(pclass1->create_func != pclass2->create_func) HGOTO_DONE(-1);
3501 if(pclass1->create_data < pclass2->create_data) HGOTO_DONE(-1);
3502 if(pclass1->create_data > pclass2->create_data) HGOTO_DONE(1);
3503
3504 /* Check whether they have close callback functions & data */
3505 if(pclass1->close_func == NULL && pclass2->close_func != NULL) HGOTO_DONE(-1);
3506 if(pclass1->close_func != NULL && pclass2->close_func == NULL) HGOTO_DONE(1);
3507 if(pclass1->close_func != pclass2->close_func) HGOTO_DONE(-1);
3508 if(pclass1->close_data < pclass2->close_data) HGOTO_DONE(-1);
3509 if(pclass1->close_data > pclass2->close_data) HGOTO_DONE(1);
3510
3511 /* Cycle through the properties and compare them also */
3512 tnode1 = H5SL_first(pclass1->props);
3513 tnode2 = H5SL_first(pclass2->props);
3514 while(tnode1 || tnode2) {
3515 H5P_genprop_t *prop1, *prop2; /* Property for node */
3516
3517 /* Check if they both have properties in this skip list node */
3518 if(tnode1 == NULL && tnode2 != NULL) HGOTO_DONE(-1);
3519 if(tnode1 != NULL && tnode2 == NULL) HGOTO_DONE(1);
3520
3521 /* Compare the two properties */
3522 prop1 = (H5P_genprop_t *)H5SL_item(tnode1);
3523 prop2 = (H5P_genprop_t *)H5SL_item(tnode2);
3524 if((cmp_value = H5P_cmp_prop(prop1, prop2)) != 0)
3525 HGOTO_DONE(cmp_value);
3526
3527 /* Advance the pointers */
3528 tnode1 = H5SL_next(tnode1);
3529 tnode2 = H5SL_next(tnode2);
3530 } /* end while */
3531
3532 done:
3533 FUNC_LEAVE_NOAPI(ret_value)
3534 } /* H5P_cmp_class() */
3535
3536
3537 /*--------------------------------------------------------------------------
3538 NAME
3539 H5P__cmp_plist_cb
3540 PURPOSE
3541 Internal callback routine when iterating over properties in property list
3542 to compare them for equality
3543 USAGE
3544 int H5P__cmp_plist_cb(prop, udata)
3545 H5P_genprop_t *prop; IN: Pointer to the property
3546 void *udata; IN/OUT: Pointer to iteration data from user
3547 RETURNS
3548 Success: Returns whether to continue (H5_ITER_CONT) or stop (H5_ITER_STOP)
3549 iterating over the property lists.
3550 Failure: Negative value (H5_ITER_ERROR)
3551 DESCRIPTION
3552 This routine compares a property from one property list (the one being
3553 iterated over, to a property from the second property list (which is
3554 looked up). Iteration is stopped if the comparison is non-equal.
3555 GLOBAL VARIABLES
3556 COMMENTS, BUGS, ASSUMPTIONS
3557 EXAMPLES
3558 REVISION LOG
3559 --------------------------------------------------------------------------*/
3560 static int
H5P__cmp_plist_cb(H5P_genprop_t * prop,void * _udata)3561 H5P__cmp_plist_cb(H5P_genprop_t *prop, void *_udata)
3562 {
3563 H5P_plist_cmp_ud_t *udata = (H5P_plist_cmp_ud_t *)_udata; /* Pointer to user data */
3564 htri_t prop2_exist; /* Whether the property exists in the second property list */
3565 int ret_value = H5_ITER_CONT; /* Return value */
3566
3567 FUNC_ENTER_STATIC
3568
3569 /* Sanity check */
3570 HDassert(prop);
3571 HDassert(udata);
3572
3573 /* Check if the property exists in the second property list */
3574 if((prop2_exist = H5P_exist_plist(udata->plist2, prop->name)) < 0)
3575 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, H5_ITER_ERROR, "can't lookup existance of property?")
3576 if(prop2_exist) {
3577 const H5P_genprop_t *prop2; /* Pointer to property in second plist */
3578
3579 /* Look up same property in second property list */
3580 if(NULL == (prop2 = H5P__find_prop_plist(udata->plist2, prop->name)))
3581 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, H5_ITER_ERROR, "property doesn't exist")
3582
3583 /* Compare the two properties */
3584 if((udata->cmp_value = H5P_cmp_prop(prop, prop2)) != 0)
3585 HGOTO_DONE(H5_ITER_STOP);
3586 } /* end if */
3587 else {
3588 /* Property exists in first list, but not second */
3589 udata->cmp_value = 1;
3590 HGOTO_DONE(H5_ITER_STOP);
3591 } /* end else */
3592
3593 done:
3594 FUNC_LEAVE_NOAPI(ret_value)
3595 } /* end H5P__cmp_plist_cb() */
3596
3597
3598 /*--------------------------------------------------------------------------
3599 NAME
3600 H5P_cmp_plist
3601 PURPOSE
3602 Internal routine to compare two generic property lists
3603 USAGE
3604 herr_t H5P_cmp_plist(plist1, plist2, cmp_ret)
3605 H5P_genplist_t *plist1; IN: 1st property list to compare
3606 H5P_genplist_t *plist2; IN: 2nd property list to compare
3607 int *cmp_ret; OUT: Comparison value for two property lists
3608 Negative if list1 "less" than list2,
3609 positive if list1 "greater" than list2,
3610 zero if list1 is "equal" to list2
3611 RETURNS
3612 Success: non-negative value
3613 Failure: negative value
3614 DESCRIPTION
3615 This function compares two generic property lists together to see if
3616 they are equal.
3617 GLOBAL VARIABLES
3618 COMMENTS, BUGS, ASSUMPTIONS
3619 EXAMPLES
3620 REVISION LOG
3621 --------------------------------------------------------------------------*/
3622 herr_t
H5P_cmp_plist(const H5P_genplist_t * plist1,const H5P_genplist_t * plist2,int * cmp_ret)3623 H5P_cmp_plist(const H5P_genplist_t *plist1, const H5P_genplist_t *plist2,
3624 int *cmp_ret)
3625 {
3626 H5P_plist_cmp_ud_t udata; /* User data for callback */
3627 int idx = 0; /* Index of property to begin with */
3628 herr_t ret_value = SUCCEED; /* Return value */
3629
3630 FUNC_ENTER_NOAPI_NOINIT
3631
3632 HDassert(plist1);
3633 HDassert(plist2);
3634 HDassert(cmp_ret);
3635
3636 /* Check the number of properties */
3637 if(plist1->nprops < plist2->nprops) {
3638 *cmp_ret = -1;
3639 HGOTO_DONE(SUCCEED);
3640 } /* end if */
3641 if(plist1->nprops > plist2->nprops) {
3642 *cmp_ret = 1;
3643 HGOTO_DONE(SUCCEED);
3644 } /* end if */
3645
3646 /* Check whether they've been initialized */
3647 if(plist1->class_init < plist2->class_init) {
3648 *cmp_ret = -1;
3649 HGOTO_DONE(SUCCEED);
3650 } /* end if */
3651 if(plist1->class_init > plist2->class_init) {
3652 *cmp_ret = 1;
3653 HGOTO_DONE(SUCCEED);
3654 } /* end if */
3655
3656 /* Set up iterator callback info */
3657 udata.cmp_value = 0;
3658 udata.plist2 = plist2;
3659
3660 /* Iterate over properties in first property list */
3661 if((ret_value = H5P_iterate_plist(plist1, TRUE, &idx, H5P__cmp_plist_cb, &udata)) < 0)
3662 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to iterate over list")
3663 if(ret_value != 0) {
3664 *cmp_ret = udata.cmp_value;
3665 HGOTO_DONE(SUCCEED);
3666 } /* end if */
3667
3668 /* Check the parent classes */
3669 if((*cmp_ret = H5P_cmp_class(plist1->pclass, plist2->pclass)) != 0)
3670 HGOTO_DONE(SUCCEED);
3671
3672 /* Property lists must be equal, set comparison value to 0 */
3673 *cmp_ret = 0;
3674
3675 done:
3676 FUNC_LEAVE_NOAPI(ret_value)
3677 } /* H5P_cmp_plist() */
3678
3679
3680 /*--------------------------------------------------------------------------
3681 NAME
3682 H5P_class_isa
3683 PURPOSE
3684 Internal routine to query whether a property class is the same as another
3685 class.
3686 USAGE
3687 htri_t H5P_class_isa(pclass1, pclass2)
3688 H5P_genclass_t *pclass1; IN: Property class to check
3689 H5P_genclass_t *pclass2; IN: Property class to compare with
3690 RETURNS
3691 Success: TRUE (1) or FALSE (0)
3692 Failure: negative value
3693 DESCRIPTION
3694 This routine queries whether a property class is the same as another class,
3695 and walks up the hierarchy of derived classes, checking if the first class
3696 is derived from the second class also.
3697
3698 GLOBAL VARIABLES
3699 COMMENTS, BUGS, ASSUMPTIONS
3700 EXAMPLES
3701 REVISION LOG
3702 --------------------------------------------------------------------------*/
3703 htri_t
H5P_class_isa(const H5P_genclass_t * pclass1,const H5P_genclass_t * pclass2)3704 H5P_class_isa(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2)
3705 {
3706 htri_t ret_value = FAIL; /* Return value */
3707
3708 FUNC_ENTER_NOAPI(FAIL)
3709
3710 HDassert(pclass1);
3711 HDassert(pclass2);
3712
3713 /* Compare property classes */
3714 if(H5P_cmp_class(pclass1, pclass2) == 0) {
3715 HGOTO_DONE(TRUE);
3716 } else {
3717 /* Check if the class is derived, and walk up the chain, if so */
3718 if(pclass1->parent != NULL)
3719 ret_value = H5P_class_isa(pclass1->parent, pclass2);
3720 else
3721 HGOTO_DONE(FALSE);
3722 } /* end else */
3723
3724 done:
3725 FUNC_LEAVE_NOAPI(ret_value)
3726 } /* H5P_class_isa() */
3727
3728
3729 /*--------------------------------------------------------------------------
3730 NAME
3731 H5P_isa_class
3732 PURPOSE
3733 Internal routine to query whether a property list is a certain class
3734 USAGE
3735 hid_t H5P_isa_class(plist_id, pclass_id)
3736 hid_t plist_id; IN: Property list to query
3737 hid_t pclass_id; IN: Property class to query
3738 RETURNS
3739 Success: TRUE (1) or FALSE (0)
3740 Failure: negative
3741 DESCRIPTION
3742 This routine queries whether a property list is a member of the property
3743 list class.
3744
3745 GLOBAL VARIABLES
3746 COMMENTS, BUGS, ASSUMPTIONS
3747 This function is special in that it is an internal library function, but
3748 accepts hid_t's as parameters. Since it is used in basically the same way
3749 as the H5I functions, this should be OK. Don't make more library functions
3750 which accept hid_t's without thorough discussion. -QAK
3751 EXAMPLES
3752 REVISION LOG
3753 --------------------------------------------------------------------------*/
3754 htri_t
H5P_isa_class(hid_t plist_id,hid_t pclass_id)3755 H5P_isa_class(hid_t plist_id, hid_t pclass_id)
3756 {
3757 H5P_genplist_t *plist; /* Property list to query */
3758 H5P_genclass_t *pclass; /* Property list class */
3759 htri_t ret_value = FAIL; /* Return value */
3760
3761 FUNC_ENTER_NOAPI(FAIL)
3762
3763 /* Check arguments. */
3764 if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
3765 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
3766 if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
3767 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class")
3768
3769 /* Compare the property list's class against the other class */
3770 if((ret_value = H5P_class_isa(plist->pclass, pclass)) < 0)
3771 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes")
3772
3773 done:
3774 FUNC_LEAVE_NOAPI(ret_value)
3775 } /* H5P_isa_class() */
3776
3777
3778 /*--------------------------------------------------------------------------
3779 NAME
3780 H5P_object_verify
3781 PURPOSE
3782 Internal routine to query whether a property list is a certain class and
3783 retrieve the property list object associated with it.
3784 USAGE
3785 void *H5P_object_verify(plist_id, pclass_id)
3786 hid_t plist_id; IN: Property list to query
3787 hid_t pclass_id; IN: Property class to query
3788 RETURNS
3789 Success: valid pointer to a property list object
3790 Failure: NULL
3791 DESCRIPTION
3792 This routine queries whether a property list is member of a certain class
3793 and retrieves the property list object associated with it.
3794
3795 GLOBAL VARIABLES
3796 COMMENTS, BUGS, ASSUMPTIONS
3797 This function is special in that it is an internal library function, but
3798 accepts hid_t's as parameters. Since it is used in basically the same way
3799 as the H5I functions, this should be OK. Don't make more library functions
3800 which accept hid_t's without thorough discussion. -QAK
3801
3802 This function is similar (in spirit) to H5I_object_verify()
3803 EXAMPLES
3804 REVISION LOG
3805 --------------------------------------------------------------------------*/
3806 H5P_genplist_t *
H5P_object_verify(hid_t plist_id,hid_t pclass_id)3807 H5P_object_verify(hid_t plist_id, hid_t pclass_id)
3808 {
3809 H5P_genplist_t *ret_value = NULL; /* Return value */
3810
3811 FUNC_ENTER_NOAPI(NULL)
3812
3813 /* Compare the property list's class against the other class */
3814 if(H5P_isa_class(plist_id, pclass_id) != TRUE)
3815 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, NULL, "property list is not a member of the class")
3816
3817 /* Get the plist structure */
3818 if(NULL == (ret_value = (H5P_genplist_t *)H5I_object(plist_id)))
3819 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID")
3820
3821 done:
3822 FUNC_LEAVE_NOAPI(ret_value)
3823 } /* H5P_object_verify() */
3824
3825
3826 /*--------------------------------------------------------------------------
3827 NAME
3828 H5P__iterate_plist_cb
3829 PURPOSE
3830 Internal callback routine when iterating over properties in property list
3831 USAGE
3832 int H5P__iterate_plist_cb(item, key, udata)
3833 void *item; IN: Pointer to the property
3834 void *key; IN: Pointer to the property's name
3835 void *udata; IN/OUT: Pointer to iteration data from user
3836 RETURNS
3837 Success: Returns the return value of the last call to ITER_FUNC
3838 DESCRIPTION
3839 This routine calls the actual callback routine for the property in the
3840 property list.
3841 GLOBAL VARIABLES
3842 COMMENTS, BUGS, ASSUMPTIONS
3843 EXAMPLES
3844 REVISION LOG
3845 --------------------------------------------------------------------------*/
3846 static int
H5P__iterate_plist_cb(void * _item,void * _key,void * _udata)3847 H5P__iterate_plist_cb(void *_item, void *_key, void *_udata)
3848 {
3849 H5P_genprop_t *item = (H5P_genprop_t *)_item; /* Pointer to the property */
3850 char *key = (char *)_key; /* Pointer to the property's name */
3851 H5P_iter_plist_ud_t *udata = (H5P_iter_plist_ud_t *)_udata; /* Pointer to user data */
3852 int ret_value = H5_ITER_CONT; /* Return value */
3853
3854 FUNC_ENTER_STATIC
3855
3856 /* Sanity check */
3857 HDassert(item);
3858 HDassert(key);
3859
3860 /* Check if we've found the correctly indexed property */
3861 if(*udata->curr_idx_ptr >= udata->prev_idx) {
3862 /* Call the callback function */
3863 ret_value = (*udata->cb_func)(item, udata->udata);
3864 if(ret_value != 0)
3865 HGOTO_DONE(ret_value);
3866 } /* end if */
3867
3868 /* Increment the current index */
3869 (*udata->curr_idx_ptr)++;
3870
3871 /* Add property name to 'seen' list */
3872 if(H5SL_insert(udata->seen, key, key) < 0)
3873 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, H5_ITER_ERROR, "can't insert property into 'seen' skip list")
3874
3875 done:
3876 FUNC_LEAVE_NOAPI(ret_value)
3877 } /* end H5P__iterate_plist_cb() */
3878
3879
3880 /*--------------------------------------------------------------------------
3881 NAME
3882 H5P__iterate_plist_pclass_cb
3883 PURPOSE
3884 Internal callback routine when iterating over properties in property class
3885 USAGE
3886 int H5P__iterate_plist_pclass_cb(item, key, udata)
3887 void *item; IN: Pointer to the property
3888 void *key; IN: Pointer to the property's name
3889 void *udata; IN/OUT: Pointer to iteration data from user
3890 RETURNS
3891 Success: Returns the return value of the last call to ITER_FUNC
3892 DESCRIPTION
3893 This routine verifies that the property hasn't already been seen or was
3894 deleted, and then chains to the property list callback.
3895 GLOBAL VARIABLES
3896 COMMENTS, BUGS, ASSUMPTIONS
3897 EXAMPLES
3898 REVISION LOG
3899 --------------------------------------------------------------------------*/
3900 static int
H5P__iterate_plist_pclass_cb(void * _item,void * _key,void * _udata)3901 H5P__iterate_plist_pclass_cb(void *_item, void *_key, void *_udata)
3902 {
3903 H5P_genprop_t *item = (H5P_genprop_t *)_item; /* Pointer to the property */
3904 char *key = (char *)_key; /* Pointer to the property's name */
3905 H5P_iter_plist_ud_t *udata = (H5P_iter_plist_ud_t *)_udata; /* Pointer to user data */
3906 int ret_value = H5_ITER_CONT; /* Return value */
3907
3908 FUNC_ENTER_STATIC_NOERR
3909
3910 /* Sanity check */
3911 HDassert(item);
3912 HDassert(key);
3913
3914 /* Only call iterator callback for properties we haven't seen
3915 * before and that haven't been deleted.
3916 */
3917 if(NULL == H5SL_search(udata->seen, key) &&
3918 NULL == H5SL_search(udata->plist->del, key))
3919 ret_value = H5P__iterate_plist_cb(item, key, udata);
3920
3921 FUNC_LEAVE_NOAPI(ret_value)
3922 } /* end H5P__iterate_plist_pclass_cb() */
3923
3924
3925 /*--------------------------------------------------------------------------
3926 NAME
3927 H5P_iterate_plist
3928 PURPOSE
3929 Internal routine to iterate over the properties in a property list
3930 USAGE
3931 int H5P_iterate_plist(plist, iter_all_prop, idx, cb_func, iter_data)
3932 const H5P_genplist_t *plist; IN: Property list to iterate over
3933 hbool_t iter_all_prop; IN: Whether to iterate over all properties
3934 (TRUE), or just non-default (i.e. changed)
3935 properties (FALSE).
3936 int *idx; IN/OUT: Index of the property to begin with
3937 H5P_iterate_t cb_func; IN: Function pointer to function to be
3938 called with each property iterated over.
3939 void *iter_data; IN/OUT: Pointer to iteration data from user
3940 RETURNS
3941 Success: Returns the return value of the last call to ITER_FUNC if it was
3942 non-zero, or zero if all properties have been processed.
3943 Failure: negative value
3944 DESCRIPTION
3945 This routine iterates over the properties in the property object specified
3946 with PLIST_ID. For each property in the object, the ITER_DATA and some
3947 additional information, specified below, are passed to the ITER_FUNC function.
3948 The iteration begins with the IDX property in the object and the next element
3949 to be processed by the operator is returned in IDX. If IDX is NULL, then the
3950 iterator starts at the first property; since no stopping point is returned in
3951 this case, the iterator cannot be restarted if one of the calls to its operator
3952 returns non-zero.
3953
3954 The prototype for H5P_iterate_t is:
3955 typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
3956 The operation receives the property list or class identifier for the object
3957 being iterated over, ID, the name of the current property within the object,
3958 NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA.
3959
3960 The return values from an operator are:
3961 Zero causes the iterator to continue, returning zero when all properties
3962 have been processed.
3963 Positive causes the iterator to immediately return that positive value,
3964 indicating short-circuit success. The iterator can be restarted at the
3965 index of the next property.
3966 Negative causes the iterator to immediately return that value, indicating
3967 failure. The iterator can be restarted at the index of the next
3968 property.
3969
3970 H5Piterate assumes that the properties in the object identified by ID remains
3971 unchanged through the iteration. If the membership changes during the
3972 iteration, the function's behavior is undefined.
3973
3974 GLOBAL VARIABLES
3975 COMMENTS, BUGS, ASSUMPTIONS
3976 EXAMPLES
3977 REVISION LOG
3978 --------------------------------------------------------------------------*/
3979 int
H5P_iterate_plist(const H5P_genplist_t * plist,hbool_t iter_all_prop,int * idx,H5P_iterate_int_t cb_func,void * udata)3980 H5P_iterate_plist(const H5P_genplist_t *plist, hbool_t iter_all_prop, int *idx,
3981 H5P_iterate_int_t cb_func, void *udata)
3982 {
3983 H5P_genclass_t *tclass; /* Temporary class pointer */
3984 H5P_iter_plist_ud_t udata_int; /* User data for skip list iterator */
3985 H5SL_t *seen = NULL; /* Skip list to hold names of properties already seen */
3986 int curr_idx = 0; /* Current iteration index */
3987 int ret_value = 0; /* Return value */
3988
3989 FUNC_ENTER_NOAPI_NOINIT
3990
3991 /* Sanity check */
3992 HDassert(plist);
3993 HDassert(idx);
3994 HDassert(cb_func);
3995
3996 /* Create the skip list to hold names of properties already seen */
3997 if(NULL == (seen = H5SL_create(H5SL_TYPE_STR, NULL)))
3998 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "can't create skip list for seen properties")
3999
4000 /* Set up iterator callback info */
4001 udata_int.plist = plist;
4002 udata_int.cb_func = cb_func;
4003 udata_int.udata = udata;
4004 udata_int.seen = seen;
4005 udata_int.curr_idx_ptr = &curr_idx;
4006 udata_int.prev_idx = *idx;
4007
4008 /* Iterate over properties in property list proper */
4009 /* (Will be only the non-default (i.e. changed) properties) */
4010 ret_value = H5SL_iterate(plist->props, H5P__iterate_plist_cb, &udata_int);
4011 if(ret_value != 0)
4012 HGOTO_DONE(ret_value);
4013
4014 /* Check for iterating over all properties, or just non-default ones */
4015 if(iter_all_prop) {
4016 /* Walk up the class hiearchy */
4017 tclass = plist->pclass;
4018 while(tclass != NULL) {
4019 /* Iterate over properties in property list class */
4020 ret_value = H5SL_iterate(tclass->props, H5P__iterate_plist_pclass_cb, &udata_int);
4021 if(ret_value != 0)
4022 HGOTO_DONE(ret_value);
4023
4024 /* Go up to parent class */
4025 tclass = tclass->parent;
4026 } /* end while */
4027 } /* end if */
4028
4029 done:
4030 /* Set the index we stopped at */
4031 *idx = curr_idx;
4032
4033 /* Release the skip list of 'seen' properties */
4034 if(seen != NULL)
4035 H5SL_close(seen);
4036
4037 FUNC_LEAVE_NOAPI(ret_value)
4038 } /* H5P_iterate_plist() */
4039
4040
4041 /*--------------------------------------------------------------------------
4042 NAME
4043 H5P__iterate_pclass_cb
4044 PURPOSE
4045 Internal callback routine when iterating over properties in property list
4046 class
4047 USAGE
4048 int H5P__iterate_pclass_cb(item, key, udata)
4049 void *item; IN: Pointer to the property
4050 void *key; IN: Pointer to the property's name
4051 void *udata; IN/OUT: Pointer to iteration data from user
4052 RETURNS
4053 Success: Returns the return value of the last call to ITER_FUNC
4054 DESCRIPTION
4055 This routine calls the actual callback routine for the property in the
4056 property list class.
4057 GLOBAL VARIABLES
4058 COMMENTS, BUGS, ASSUMPTIONS
4059 EXAMPLES
4060 REVISION LOG
4061 --------------------------------------------------------------------------*/
4062 static int
H5P__iterate_pclass_cb(void * _item,void * _key,void * _udata)4063 H5P__iterate_pclass_cb(void *_item, void *_key, void *_udata)
4064 {
4065 H5P_genprop_t *item = (H5P_genprop_t *)_item; /* Pointer to the property */
4066 char *key = (char *)_key; /* Pointer to the property's name */
4067 H5P_iter_pclass_ud_t *udata = (H5P_iter_pclass_ud_t *)_udata; /* Pointer to user data */
4068 int ret_value = 0; /* Return value */
4069
4070 FUNC_ENTER_STATIC_NOERR
4071
4072 /* Sanity check */
4073 HDassert(item);
4074 HDassert(key);
4075
4076 /* Check if we've found the correctly indexed property */
4077 if(*udata->curr_idx_ptr >= udata->prev_idx) {
4078 /* Call the callback function */
4079 ret_value = (*udata->cb_func)(item, udata->udata);
4080 if(ret_value != 0)
4081 HGOTO_DONE(ret_value);
4082 } /* end if */
4083
4084 /* Increment the current index */
4085 (*udata->curr_idx_ptr)++;
4086
4087 done:
4088 FUNC_LEAVE_NOAPI(ret_value)
4089 } /* end H5P__iterate_pclass_cb() */
4090
4091
4092 /*--------------------------------------------------------------------------
4093 NAME
4094 H5P_iterate_pclass
4095 PURPOSE
4096 Internal routine to iterate over the properties in a property class
4097 USAGE
4098 herr_t H5P_iterate_pclass(pclass, idx, cb_func, iter_data)
4099 const H5P_genpclass_t *pclass; IN: Property list class to iterate over
4100 int *idx; IN/OUT: Index of the property to begin with
4101 H5P_iterate_t cb_func; IN: Function pointer to function to be
4102 called with each property iterated over.
4103 void *iter_data; IN/OUT: Pointer to iteration data from user
4104 RETURNS
4105 Success: Returns the return value of the last call to ITER_FUNC if it was
4106 non-zero, or zero if all properties have been processed.
4107 Failure: negative value
4108 DESCRIPTION
4109 This routine iterates over the properties in the property object specified
4110 with PCLASS_ID. For each property in the object, the ITER_DATA and some
4111 additional information, specified below, are passed to the ITER_FUNC function.
4112 The iteration begins with the IDX property in the object and the next element
4113 to be processed by the operator is returned in IDX. If IDX is NULL, then the
4114 iterator starts at the first property; since no stopping point is returned in
4115 this case, the iterator cannot be restarted if one of the calls to its operator
4116 returns non-zero.
4117
4118 The prototype for H5P_iterate_t is:
4119 typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
4120 The operation receives the property list or class identifier for the object
4121 being iterated over, ID, the name of the current property within the object,
4122 NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA.
4123
4124 The return values from an operator are:
4125 Zero causes the iterator to continue, returning zero when all properties
4126 have been processed.
4127 Positive causes the iterator to immediately return that positive value,
4128 indicating short-circuit success. The iterator can be restarted at the
4129 index of the next property.
4130 Negative causes the iterator to immediately return that value, indicating
4131 failure. The iterator can be restarted at the index of the next
4132 property.
4133
4134 H5Piterate assumes that the properties in the object identified by ID remains
4135 unchanged through the iteration. If the membership changes during the
4136 iteration, the function's behavior is undefined.
4137
4138 GLOBAL VARIABLES
4139 COMMENTS, BUGS, ASSUMPTIONS
4140 EXAMPLES
4141 REVISION LOG
4142 --------------------------------------------------------------------------*/
4143 int
H5P_iterate_pclass(const H5P_genclass_t * pclass,int * idx,H5P_iterate_int_t cb_func,void * udata)4144 H5P_iterate_pclass(const H5P_genclass_t *pclass, int *idx,
4145 H5P_iterate_int_t cb_func, void *udata)
4146 {
4147 H5P_iter_pclass_ud_t udata_int; /* User data for skip list iterator */
4148 int curr_idx = 0; /* Current iteration index */
4149 int ret_value = 0; /* Return value */
4150
4151 FUNC_ENTER_NOAPI_NOINIT_NOERR
4152
4153 /* Sanity check */
4154 HDassert(pclass);
4155 HDassert(idx);
4156 HDassert(cb_func);
4157
4158 /* Set up iterator callback info */
4159 udata_int.cb_func = cb_func;
4160 udata_int.udata = udata;
4161 udata_int.curr_idx_ptr = &curr_idx;
4162 udata_int.prev_idx = *idx;
4163
4164 /* Iterate over properties in property list class proper */
4165 ret_value = H5SL_iterate(pclass->props, H5P__iterate_pclass_cb, &udata_int);
4166 if(ret_value != 0)
4167 HGOTO_DONE(ret_value);
4168
4169 done:
4170 /* Set the index we stopped at */
4171 *idx = curr_idx;
4172
4173 FUNC_LEAVE_NOAPI(ret_value)
4174 } /* H5P_iterate_pclass() */
4175
4176
4177 /*--------------------------------------------------------------------------
4178 NAME
4179 H5P__peek_cb
4180 PURPOSE
4181 Internal callback for H5P__do_prop, to peek at a property's value in a property list.
4182 USAGE
4183 herr_t H5P__peek_plist_cb(plist, name, value)
4184 H5P_genplist_t *plist; IN: Property list to peek property in
4185 const char *name; IN: Name of property to peek
4186 H5P_genprop_t *prop; IN: Property to peek
4187 void *udata; IN: User data for operation
4188 RETURNS
4189 Returns non-negative on success, negative on failure.
4190 DESCRIPTION
4191 Peeks at a new value for a property in a property list.
4192 GLOBAL VARIABLES
4193 COMMENTS, BUGS, ASSUMPTIONS
4194 Called when the property is found in the property list and when it's found
4195 for the property class.
4196 EXAMPLES
4197 REVISION LOG
4198 --------------------------------------------------------------------------*/
4199 static herr_t
H5P__peek_cb(H5P_genplist_t * plist,const char * name,H5P_genprop_t * prop,void * _udata)4200 H5P__peek_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
4201 void *_udata)
4202 {
4203 H5P_prop_get_ud_t *udata = (H5P_prop_get_ud_t *)_udata; /* User data for callback */
4204 herr_t ret_value = SUCCEED; /* Return value */
4205
4206 FUNC_ENTER_STATIC
4207
4208 /* Sanity check */
4209 HDassert(plist);
4210 HDassert(name);
4211 HDassert(prop);
4212
4213 /* Check for property size >0 */
4214 if(0 == prop->size)
4215 HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size")
4216
4217 /* Make a (shallow) copy of the value */
4218 HDmemcpy(udata->value, prop->value, prop->size);
4219
4220 done:
4221 FUNC_LEAVE_NOAPI(ret_value)
4222 } /* H5P__peek_cb() */
4223
4224
4225 /*--------------------------------------------------------------------------
4226 NAME
4227 H5P_peek
4228 PURPOSE
4229 Internal routine to look at the value of a property in a property list.
4230 USAGE
4231 herr_t H5P_peek(plist, name, value)
4232 H5P_genplist_t *plist; IN: Property list to check
4233 const char *name; IN: Name of property to query
4234 void *value; OUT: Pointer to the buffer for the property value
4235 RETURNS
4236 Returns non-negative on success, negative on failure.
4237 DESCRIPTION
4238 Retrieves a "shallow" copy of the value for a property in a property
4239 list. The property name must exist or this routine will fail. If there
4240 is a 'get' callback routine registered for this property, it is _NOT_
4241 called.
4242 GLOBAL VARIABLES
4243 COMMENTS, BUGS, ASSUMPTIONS
4244 This routine may not be called for zero-sized properties and will
4245 return an error in that case.
4246 EXAMPLES
4247 REVISION LOG
4248 --------------------------------------------------------------------------*/
4249 herr_t
H5P_peek(H5P_genplist_t * plist,const char * name,void * value)4250 H5P_peek(H5P_genplist_t *plist, const char *name, void *value)
4251 {
4252 H5P_prop_get_ud_t udata; /* User data for callback */
4253 herr_t ret_value = SUCCEED; /* Return value */
4254
4255 FUNC_ENTER_NOAPI(FAIL)
4256
4257 /* Sanity check */
4258 HDassert(plist);
4259 HDassert(name);
4260 HDassert(value);
4261
4262 /* Find the property and peek at the value */
4263 udata.value = value;
4264 if(H5P__do_prop(plist, name, H5P__peek_cb, H5P__peek_cb, &udata) < 0)
4265 HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to peek at value")
4266
4267 done:
4268 FUNC_LEAVE_NOAPI(ret_value)
4269 } /* H5P_peek() */
4270
4271
4272 /*--------------------------------------------------------------------------
4273 NAME
4274 H5P__get_cb
4275 PURPOSE
4276 Internal callback for H5P__do_prop, to get a property's value in a property list.
4277 USAGE
4278 herr_t H5P__get_plist_cb(plist, name, value)
4279 H5P_genplist_t *plist; IN: Property list to get property in
4280 const char *name; IN: Name of property to get
4281 H5P_genprop_t *prop; IN: Property to get
4282 void *udata; IN: User data for operation
4283 RETURNS
4284 Returns non-negative on success, negative on failure.
4285 DESCRIPTION
4286 Gets a new value for a property in a property list.
4287 GLOBAL VARIABLES
4288 COMMENTS, BUGS, ASSUMPTIONS
4289 Called when the property is found in the property list and when it's found
4290 for the property class.
4291 EXAMPLES
4292 REVISION LOG
4293 --------------------------------------------------------------------------*/
4294 static herr_t
H5P__get_cb(H5P_genplist_t * plist,const char * name,H5P_genprop_t * prop,void * _udata)4295 H5P__get_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
4296 void *_udata)
4297 {
4298 H5P_prop_get_ud_t *udata = (H5P_prop_get_ud_t *)_udata; /* User data for callback */
4299 void *tmp_value = NULL; /* Temporary value for property */
4300 herr_t ret_value = SUCCEED; /* Return value */
4301
4302 FUNC_ENTER_STATIC
4303
4304 /* Sanity check */
4305 HDassert(plist);
4306 HDassert(name);
4307 HDassert(prop);
4308
4309 /* Check for property size >0 */
4310 if(0 == prop->size)
4311 HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size")
4312
4313 /* Call the 'get' callback, if there is one */
4314 if(NULL != prop->get) {
4315 /* Make a copy of the current value, in case the callback fails */
4316 if(NULL == (tmp_value = H5MM_malloc(prop->size)))
4317 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed temporary property value")
4318 HDmemcpy(tmp_value, prop->value, prop->size);
4319
4320 /* Call user's callback */
4321 if((*(prop->get))(plist->plist_id, name, prop->size, tmp_value) < 0)
4322 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value")
4323
4324 /* Copy new [possibly unchanged] value into return value */
4325 HDmemcpy(udata->value, tmp_value, prop->size);
4326 } /* end if */
4327 /* No 'get' callback, just copy value */
4328 else
4329 HDmemcpy(udata->value, prop->value, prop->size);
4330
4331 done:
4332 /* Free the temporary value buffer */
4333 if(tmp_value)
4334 H5MM_xfree(tmp_value);
4335
4336 FUNC_LEAVE_NOAPI(ret_value)
4337 } /* H5P__get_cb() */
4338
4339
4340 /*--------------------------------------------------------------------------
4341 NAME
4342 H5P_get
4343 PURPOSE
4344 Internal routine to query the value of a property in a property list.
4345 USAGE
4346 herr_t H5P_get(plist, name, value)
4347 H5P_genplist_t *plist; IN: Property list to check
4348 const char *name; IN: Name of property to query
4349 void *value; OUT: Pointer to the buffer for the property value
4350 RETURNS
4351 Returns non-negative on success, negative on failure.
4352 DESCRIPTION
4353 Retrieves a copy of the value for a property in a property list. The
4354 property name must exist or this routine will fail. If there is a
4355 'get' callback routine registered for this property, the copy of the
4356 value of the property will first be passed to that routine and any changes
4357 to the copy of the value will be used when returning the property value
4358 from this routine.
4359 If the 'get' callback routine returns an error, 'value' will not be
4360 modified and this routine will return an error. This routine may not be
4361 called for zero-sized properties.
4362
4363 GLOBAL VARIABLES
4364 COMMENTS, BUGS, ASSUMPTIONS
4365 EXAMPLES
4366 REVISION LOG
4367 --------------------------------------------------------------------------*/
4368 herr_t
H5P_get(H5P_genplist_t * plist,const char * name,void * value)4369 H5P_get(H5P_genplist_t *plist, const char *name, void *value)
4370 {
4371 H5P_prop_get_ud_t udata; /* User data for callback */
4372 herr_t ret_value = SUCCEED; /* Return value */
4373
4374 FUNC_ENTER_NOAPI(FAIL)
4375
4376 /* Sanity check */
4377 HDassert(plist);
4378 HDassert(name);
4379 HDassert(value);
4380
4381 /* Find the property and get the value */
4382 udata.value = value;
4383 if(H5P__do_prop(plist, name, H5P__get_cb, H5P__get_cb, &udata) < 0)
4384 HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to get value")
4385
4386 done:
4387 FUNC_LEAVE_NOAPI(ret_value)
4388 } /* H5P_get() */
4389
4390
4391 /*--------------------------------------------------------------------------
4392 NAME
4393 H5P__del_plist_cb
4394 PURPOSE
4395 Internal callback for H5P__do_prop, to remove a property's value in a property list.
4396 USAGE
4397 herr_t H5P__del_plist_cb(plist, name, value)
4398 H5P_genplist_t *plist; IN: Property list to remove property from
4399 const char *name; IN: Name of property to remove
4400 H5P_genprop_t *prop; IN: Property to remove
4401 void *udata; IN: User data for operation
4402 RETURNS
4403 Returns non-negative on success, negative on failure.
4404 DESCRIPTION
4405 Remove a property in a property list. Called when the
4406 property is found in the property list.
4407 GLOBAL VARIABLES
4408 COMMENTS, BUGS, ASSUMPTIONS
4409 EXAMPLES
4410 REVISION LOG
4411 --------------------------------------------------------------------------*/
4412 static herr_t
H5P__del_plist_cb(H5P_genplist_t * plist,const char * name,H5P_genprop_t * prop,void H5_ATTR_UNUSED * _udata)4413 H5P__del_plist_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
4414 void H5_ATTR_UNUSED *_udata)
4415 {
4416 char *del_name = NULL; /* Pointer to deleted name */
4417 herr_t ret_value = SUCCEED; /* Return value */
4418
4419 FUNC_ENTER_STATIC
4420
4421 /* Sanity check */
4422 HDassert(plist);
4423 HDassert(name);
4424 HDassert(prop);
4425
4426 /* Pass value to 'close' callback, if it exists */
4427 if(NULL != prop->del) {
4428 /* Call user's callback */
4429 if((*(prop->del))(plist->plist_id, name, prop->size, prop->value) < 0)
4430 HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release property value")
4431 } /* end if */
4432
4433 /* Duplicate string for insertion into new deleted property skip list */
4434 if(NULL == (del_name = H5MM_xstrdup(name)))
4435 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed")
4436
4437 /* Insert property name into deleted list */
4438 if(H5SL_insert(plist->del, del_name, del_name) < 0)
4439 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into deleted skip list")
4440
4441 /* Remove the property from the skip list */
4442 if(NULL == H5SL_remove(plist->props, prop->name))
4443 HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "can't remove property from skip list")
4444
4445 /* Free the property, ignoring return value, nothing we can do */
4446 H5P_free_prop(prop);
4447
4448 /* Decrement the number of properties in list */
4449 plist->nprops--;
4450
4451 done:
4452 /* Error cleanup */
4453 if(ret_value < 0)
4454 if(del_name)
4455 H5MM_xfree(del_name);
4456
4457 FUNC_LEAVE_NOAPI(ret_value)
4458 } /* H5P__del_plist_cb() */
4459
4460
4461 /*--------------------------------------------------------------------------
4462 NAME
4463 H5P__del_pclass_cb
4464 PURPOSE
4465 Internal callback for H5P__do_prop, to remove a property's value in a property list.
4466 USAGE
4467 herr_t H5P__del_pclass_cb(plist, name, value)
4468 H5P_genplist_t *plist; IN: Property list to remove property from
4469 const char *name; IN: Name of property to remove
4470 H5P_genprop_t *prop; IN: Property to remove
4471 void *udata; IN: User data for operation
4472 RETURNS
4473 Returns non-negative on success, negative on failure.
4474 DESCRIPTION
4475 Remove a property in a property list. Called when the
4476 property is found in the property class.
4477 GLOBAL VARIABLES
4478 COMMENTS, BUGS, ASSUMPTIONS
4479 EXAMPLES
4480 REVISION LOG
4481 --------------------------------------------------------------------------*/
4482 static herr_t
H5P__del_pclass_cb(H5P_genplist_t * plist,const char * name,H5P_genprop_t * prop,void H5_ATTR_UNUSED * _udata)4483 H5P__del_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop,
4484 void H5_ATTR_UNUSED *_udata)
4485 {
4486 char *del_name = NULL; /* Pointer to deleted name */
4487 void *tmp_value = NULL; /* Temporary value for property */
4488 herr_t ret_value = SUCCEED; /* Return value */
4489
4490 FUNC_ENTER_STATIC
4491
4492 /* Sanity check */
4493 HDassert(plist);
4494 HDassert(name);
4495 HDassert(prop);
4496
4497 /* Pass value to 'del' callback, if it exists */
4498 if(NULL != prop->del) {
4499 /* Allocate space for a temporary copy of the property value */
4500 if(NULL == (tmp_value = H5MM_malloc(prop->size)))
4501 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for temporary property value")
4502 HDmemcpy(tmp_value, prop->value, prop->size);
4503
4504 /* Call user's callback */
4505 if((*(prop->del))(plist->plist_id, name, prop->size, tmp_value) < 0)
4506 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value")
4507 } /* end if */
4508
4509 /* Duplicate string for insertion into new deleted property skip list */
4510 if(NULL == (del_name = H5MM_xstrdup(name)))
4511 HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed")
4512
4513 /* Insert property name into deleted list */
4514 if(H5SL_insert(plist->del, del_name, del_name) < 0)
4515 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into deleted skip list")
4516
4517 /* Decrement the number of properties in list */
4518 plist->nprops--;
4519
4520 done:
4521 /* Free the temporary value buffer */
4522 if(tmp_value)
4523 H5MM_xfree(tmp_value);
4524
4525 /* Error cleanup */
4526 if(ret_value < 0)
4527 if(del_name)
4528 H5MM_xfree(del_name);
4529
4530 FUNC_LEAVE_NOAPI(ret_value)
4531 } /* H5P__del_pclass_cb() */
4532
4533
4534 /*--------------------------------------------------------------------------
4535 NAME
4536 H5P_remove
4537 PURPOSE
4538 Internal routine to remove a property from a property list.
4539 USAGE
4540 herr_t H5P_remove(plist, name)
4541 H5P_genplist_t *plist; IN: Property list to modify
4542 const char *name; IN: Name of property to remove
4543 RETURNS
4544 Returns non-negative on success, negative on failure.
4545 DESCRIPTION
4546 Removes a property from a property list. Both properties which were
4547 in existance when the property list was created (i.e. properties registered
4548 with H5Pregister2) and properties added to the list after it was created
4549 (i.e. added with H5Pinsert2) may be removed from a property list.
4550 Properties do not need to be removed a property list before the list itself
4551 is closed, they will be released automatically when H5Pclose is called.
4552 The 'close' callback for this property is called before the property is
4553 release, if the callback exists.
4554
4555 GLOBAL VARIABLES
4556 COMMENTS, BUGS, ASSUMPTIONS
4557 EXAMPLES
4558 REVISION LOG
4559 --------------------------------------------------------------------------*/
4560 herr_t
H5P_remove(H5P_genplist_t * plist,const char * name)4561 H5P_remove(H5P_genplist_t *plist, const char *name)
4562 {
4563 herr_t ret_value = SUCCEED; /* Return value */
4564
4565 FUNC_ENTER_NOAPI(FAIL)
4566
4567 /* Sanity check */
4568 HDassert(plist);
4569 HDassert(name);
4570
4571 /* Find the property and get the value */
4572 if(H5P__do_prop(plist, name, H5P__del_plist_cb, H5P__del_pclass_cb, NULL) < 0)
4573 HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to remove value")
4574
4575 done:
4576 FUNC_LEAVE_NOAPI(ret_value)
4577 } /* H5P_remove() */
4578
4579
4580 /*--------------------------------------------------------------------------
4581 NAME
4582 H5P_copy_prop_plist
4583 PURPOSE
4584 Internal routine to copy a property from one list to another
4585 USAGE
4586 herr_t H5P_copy_prop_plist(dst_plist, src_plist, name)
4587 hid_t dst_id; IN: ID of destination property list or class
4588 hid_t src_id; IN: ID of source property list or class
4589 const char *name; IN: Name of property to copy
4590 RETURNS
4591 Success: non-negative value.
4592 Failure: negative value.
4593 DESCRIPTION
4594 Copies a property from one property list to another.
4595
4596 If a property is copied from one list to another, the property will be
4597 first deleted from the destination list (generating a call to the 'close'
4598 callback for the property, if one exists) and then the property is copied
4599 from the source list to the destination list (generating a call to the
4600 'copy' callback for the property, if one exists).
4601
4602 If the property does not exist in the destination list, this call is
4603 equivalent to calling H5Pinsert2 and the 'create' callback will be called
4604 (if such a callback exists for the property).
4605
4606 GLOBAL VARIABLES
4607 COMMENTS, BUGS, ASSUMPTIONS
4608 EXAMPLES
4609 REVISION LOG
4610 --------------------------------------------------------------------------*/
4611 herr_t
H5P_copy_prop_plist(hid_t dst_id,hid_t src_id,const char * name)4612 H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name)
4613 {
4614 H5P_genplist_t *dst_plist; /* Pointer to destination property list */
4615 H5P_genplist_t *src_plist; /* Pointer to source property list */
4616 H5P_genprop_t *prop; /* Temporary property pointer */
4617 H5P_genprop_t *new_prop=NULL; /* Pointer to new property */
4618 herr_t ret_value=SUCCEED; /* return value */
4619
4620 FUNC_ENTER_NOAPI_NOINIT
4621
4622 HDassert(name);
4623
4624 /* Get the objects to operate on */
4625 if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_id)) || NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_id)))
4626 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist")
4627
4628 /* If the property exists in the destination alread */
4629 if(NULL != H5P__find_prop_plist(dst_plist, name)) {
4630 /* Delete the property from the destination list, calling the 'close' callback if necessary */
4631 if(H5P_remove(dst_plist, name) < 0)
4632 HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property")
4633
4634 /* Get the pointer to the source property */
4635 prop = H5P__find_prop_plist(src_plist, name);
4636
4637 /* Make a copy of the source property */
4638 if((new_prop=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL)
4639 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property")
4640
4641 /* Call property copy callback, if it exists */
4642 if(new_prop->copy) {
4643 if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value) < 0)
4644 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property")
4645 } /* end if */
4646
4647 /* Insert the initialized property into the property list */
4648 if(H5P_add_prop(dst_plist->props,new_prop) < 0)
4649 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list")
4650
4651 /* Increment the number of properties in list */
4652 dst_plist->nprops++;
4653 } /* end if */
4654 /* If not, get the information required to do an H5Pinsert2 with the property into the destination list */
4655 else {
4656 /* Get the pointer to the source property */
4657 prop = H5P__find_prop_plist(src_plist, name);
4658
4659 /* Create property object from parameters */
4660 if(NULL == (new_prop = H5P_create_prop(prop->name, prop->size, H5P_PROP_WITHIN_LIST, prop->value,
4661 prop->create, prop->set, prop->get, prop->encode, prop->decode,
4662 prop->del, prop->copy, prop->cmp, prop->close)))
4663 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property")
4664
4665 /* Call property creation callback, if it exists */
4666 if(new_prop->create) {
4667 if((new_prop->create)(new_prop->name, new_prop->size, new_prop->value) < 0)
4668 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property")
4669 } /* end if */
4670
4671 /* Insert property into property list class */
4672 if(H5P_add_prop(dst_plist->props, new_prop) < 0)
4673 HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class")
4674
4675 /* Increment property count for class */
4676 dst_plist->nprops++;
4677 } /* end else */
4678
4679 done:
4680 /* Cleanup, if necessary */
4681 if(ret_value<0) {
4682 if(new_prop!=NULL)
4683 H5P_free_prop(new_prop);
4684 } /* end if */
4685
4686 FUNC_LEAVE_NOAPI(ret_value)
4687 } /* H5P_copy_prop_plist() */
4688
4689
4690 /*--------------------------------------------------------------------------
4691 NAME
4692 H5P_copy_prop_pclass
4693 PURPOSE
4694 Internal routine to copy a property from one class to another
4695 USAGE
4696 herr_t H5P_copy_prop_pclass(dst_pclass, src_pclass, name)
4697 H5P_genclass_t *dst_pclass; IN: Pointer to destination class
4698 H5P_genclass_t *src_pclass; IN: Pointer to source class
4699 const char *name; IN: Name of property to copy
4700 RETURNS
4701 Success: non-negative value.
4702 Failure: negative value.
4703 DESCRIPTION
4704 Copies a property from one property class to another.
4705
4706 If a property is copied from one class to another, all the property
4707 information will be first deleted from the destination class and then the
4708 property information will be copied from the source class into the
4709 destination class.
4710
4711 If the property does not exist in the destination class or list, this call
4712 is equivalent to calling H5Pregister2.
4713
4714 GLOBAL VARIABLES
4715 COMMENTS, BUGS, ASSUMPTIONS
4716 EXAMPLES
4717 REVISION LOG
4718 --------------------------------------------------------------------------*/
4719 herr_t
H5P_copy_prop_pclass(hid_t dst_id,hid_t src_id,const char * name)4720 H5P_copy_prop_pclass(hid_t dst_id, hid_t src_id, const char *name)
4721 {
4722 H5P_genclass_t *src_pclass; /* Source property class, containing property to copy */
4723 H5P_genclass_t *dst_pclass; /* Destination property class */
4724 H5P_genclass_t *orig_dst_pclass; /* Original destination property class */
4725 H5P_genprop_t *prop; /* Temporary property pointer */
4726 herr_t ret_value = SUCCEED; /* return value */
4727
4728 FUNC_ENTER_NOAPI_NOINIT
4729
4730 /* Sanity check */
4731 HDassert(name);
4732
4733 /* Get propery list classes */
4734 if(NULL == (src_pclass = (H5P_genclass_t *)H5I_object(src_id)))
4735 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "source property class object doesn't exist")
4736 if(NULL == (dst_pclass = (H5P_genclass_t *)H5I_object(dst_id)))
4737 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "destination property class object doesn't exist")
4738
4739 /* Get the property from the source */
4740 if(NULL == (prop = H5P_find_prop_pclass(src_pclass, name)))
4741 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to locate property")
4742
4743 /* If the property exists in the destination already */
4744 if(H5P_exist_pclass(dst_pclass, name)) {
4745 /* Delete the old property from the destination class */
4746 if(H5P_unregister(dst_pclass, name) < 0)
4747 HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property")
4748 } /* end if */
4749
4750 /* Register the property into the destination */
4751 orig_dst_pclass = dst_pclass;
4752 if(H5P_register(&dst_pclass, name, prop->size, prop->value, prop->create, prop->set, prop->get,
4753 prop->encode, prop->decode, prop->del, prop->copy, prop->cmp, prop->close) < 0)
4754 HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property")
4755
4756 /* Check if the property class changed and needs to be substituted in the ID */
4757 if(dst_pclass != orig_dst_pclass) {
4758 H5P_genclass_t *old_dst_pclass; /* Old destination property class */
4759
4760 /* Substitute the new destination property class in the ID */
4761 if(NULL == (old_dst_pclass = (H5P_genclass_t *)H5I_subst(dst_id, dst_pclass)))
4762 HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to substitute property class in ID")
4763 HDassert(old_dst_pclass == orig_dst_pclass);
4764
4765 /* Close the previous class */
4766 if(H5P_close_class(old_dst_pclass) < 0)
4767 HGOTO_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "unable to close original property class after substitution")
4768 } /* end if */
4769
4770 done:
4771 /* Cleanup, if necessary */
4772
4773 FUNC_LEAVE_NOAPI(ret_value)
4774 } /* H5P_copy_prop_pclass() */
4775
4776
4777 /*--------------------------------------------------------------------------
4778 NAME
4779 H5P_unregister
4780 PURPOSE
4781 Internal routine to remove a property from a property list class.
4782 USAGE
4783 herr_t H5P_unregister(pclass, name)
4784 H5P_genclass_t *pclass; IN: Property list class to modify
4785 const char *name; IN: Name of property to remove
4786 RETURNS
4787 Returns non-negative on success, negative on failure.
4788 DESCRIPTION
4789 Removes a property from a property list class. Future property lists
4790 created of that class will not contain this property. Existing property
4791 lists containing this property are not affected.
4792
4793 GLOBAL VARIABLES
4794 COMMENTS, BUGS, ASSUMPTIONS
4795 EXAMPLES
4796 REVISION LOG
4797 --------------------------------------------------------------------------*/
4798 herr_t
H5P_unregister(H5P_genclass_t * pclass,const char * name)4799 H5P_unregister(H5P_genclass_t *pclass, const char *name)
4800 {
4801 H5P_genprop_t *prop; /* Temporary property pointer */
4802 herr_t ret_value=SUCCEED; /* Return value */
4803
4804 FUNC_ENTER_NOAPI_NOINIT
4805
4806 HDassert(pclass);
4807 HDassert(name);
4808
4809 /* Get the property node from the skip list */
4810 if((prop = (H5P_genprop_t *)H5SL_search(pclass->props,name)) == NULL)
4811 HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list")
4812
4813 /* Remove the property from the skip list */
4814 if(H5SL_remove(pclass->props,prop->name) == NULL)
4815 HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list")
4816
4817 /* Free the property, ignoring return value, nothing we can do */
4818 H5P_free_prop(prop);
4819
4820 /* Decrement the number of registered properties in class */
4821 pclass->nprops--;
4822
4823 /* Update the revision for the class */
4824 pclass->revision = H5P_GET_NEXT_REV;
4825
4826 done:
4827 FUNC_LEAVE_NOAPI(ret_value)
4828 } /* H5P_unregister() */
4829
4830
4831 /*--------------------------------------------------------------------------
4832 NAME
4833 H5P_close
4834 PURPOSE
4835 Internal routine to close a property list.
4836 USAGE
4837 herr_t H5P_close(plist)
4838 H5P_genplist_t *plist; IN: Property list to close
4839 RETURNS
4840 Returns non-negative on success, negative on failure.
4841 DESCRIPTION
4842 Closes a property list. If a 'close' callback exists for the property
4843 list class, it is called before the property list is destroyed. If 'close'
4844 callbacks exist for any individual properties in the property list, they are
4845 called after the class 'close' callback.
4846
4847 GLOBAL VARIABLES
4848 COMMENTS, BUGS, ASSUMPTIONS
4849 The property list class 'close' callback routine is not called from
4850 here, it must have been check for and called properly prior to this routine
4851 being called
4852 EXAMPLES
4853 REVISION LOG
4854 --------------------------------------------------------------------------*/
4855 herr_t
H5P_close(void * _plist)4856 H5P_close(void *_plist)
4857 {
4858 H5P_genclass_t *tclass; /* Temporary class pointer */
4859 H5P_genplist_t *plist=(H5P_genplist_t *)_plist;
4860 H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */
4861 size_t nseen; /* Number of items 'seen' */
4862 hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */
4863 size_t ndel; /* Number of items deleted */
4864 H5SL_node_t *curr_node; /* Current node in skip list */
4865 H5P_genprop_t *tmp; /* Temporary pointer to properties */
4866 unsigned make_cb=0; /* Operator data for property free callback */
4867 herr_t ret_value=SUCCEED; /* return value */
4868
4869 FUNC_ENTER_NOAPI_NOINIT
4870
4871 HDassert(plist);
4872
4873 /* Make call to property list class close callback, if needed
4874 * (up through chain of parent classes also)
4875 */
4876 if(plist->class_init) {
4877 tclass = plist->pclass;
4878 while(NULL != tclass) {
4879 if(NULL != tclass->close_func) {
4880 /* Call user's "close" callback function, ignoring return value */
4881 (tclass->close_func)(plist->plist_id, tclass->close_data);
4882 } /* end if */
4883
4884 /* Go up to parent class */
4885 tclass = tclass->parent;
4886 } /* end while */
4887 } /* end if */
4888
4889 /* Create the skip list to hold names of properties already seen
4890 * (This prevents a property in the class hierarchy from having it's
4891 * 'close' callback called, if a property in the class hierarchy has
4892 * already been seen)
4893 */
4894 if((seen = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
4895 HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties")
4896 nseen = 0;
4897
4898 /* Walk through the changed properties in the list */
4899 if(H5SL_count(plist->props)>0) {
4900 curr_node=H5SL_first(plist->props);
4901 while(curr_node!=NULL) {
4902 /* Get pointer to property from node */
4903 tmp = (H5P_genprop_t *)H5SL_item(curr_node);
4904
4905 /* Call property close callback, if it exists */
4906 if(tmp->close) {
4907 /* Call the 'close' callback */
4908 (tmp->close)(tmp->name,tmp->size,tmp->value);
4909 } /* end if */
4910
4911 /* Add property name to "seen" list */
4912 if(H5SL_insert(seen,tmp->name,tmp->name) < 0)
4913 HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list")
4914 nseen++;
4915
4916 /* Get the next property node in the skip list */
4917 curr_node=H5SL_next(curr_node);
4918 } /* end while */
4919 } /* end if */
4920
4921 /* Determine number of deleted items from property list */
4922 ndel=H5SL_count(plist->del);
4923
4924 /*
4925 * Check if we should remove class properties (up through list of parent classes also),
4926 * initialize each with default value & make property 'remove' callback.
4927 */
4928 tclass=plist->pclass;
4929 has_parent_class = (hbool_t)(tclass != NULL && tclass->parent != NULL && tclass->parent->nprops > 0);
4930 while(tclass!=NULL) {
4931 if(tclass->nprops>0) {
4932 /* Walk through the properties in the class */
4933 curr_node=H5SL_first(tclass->props);
4934 while(curr_node!=NULL) {
4935 /* Get pointer to property from node */
4936 tmp = (H5P_genprop_t *)H5SL_item(curr_node);
4937
4938 /* Only "delete" properties we haven't seen before
4939 * and that haven't already been deleted
4940 */
4941 if((nseen==0 || H5SL_search(seen,tmp->name) == NULL) &&
4942 (ndel==0 || H5SL_search(plist->del,tmp->name) == NULL)) {
4943
4944 /* Call property close callback, if it exists */
4945 if(tmp->close) {
4946 void *tmp_value; /* Temporary value buffer */
4947
4948 /* Allocate space for a temporary copy of the property value */
4949 if(NULL==(tmp_value=H5MM_malloc(tmp->size)))
4950 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value")
4951 HDmemcpy(tmp_value,tmp->value,tmp->size);
4952
4953 /* Call the 'close' callback */
4954 (tmp->close)(tmp->name,tmp->size,tmp_value);
4955
4956 /* Release the temporary value buffer */
4957 H5MM_xfree(tmp_value);
4958 } /* end if */
4959
4960 /* Add property name to "seen" list, if we have other classes to work on */
4961 if(has_parent_class) {
4962 if(H5SL_insert(seen,tmp->name,tmp->name) < 0)
4963 HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list")
4964 nseen++;
4965 } /* end if */
4966 } /* end if */
4967
4968 /* Get the next property node in the skip list */
4969 curr_node=H5SL_next(curr_node);
4970 } /* end while */
4971 } /* end if */
4972
4973 /* Go up to parent class */
4974 tclass=tclass->parent;
4975 } /* end while */
4976
4977 /* Decrement class's dependant property list value! */
4978 if(H5P_access_class(plist->pclass,H5P_MOD_DEC_LST) < 0)
4979 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "Can't decrement class ref count")
4980
4981 /* Free the list of 'seen' properties */
4982 H5SL_close(seen);
4983 seen=NULL;
4984
4985 /* Free the list of deleted property names */
4986 H5SL_destroy(plist->del,H5P_free_del_name_cb,NULL);
4987
4988 /* Free the properties */
4989 H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb);
4990
4991 /* Destroy property list object */
4992 plist = H5FL_FREE(H5P_genplist_t, plist);
4993
4994 done:
4995 /* Release the skip list of 'seen' properties */
4996 if(seen != NULL)
4997 H5SL_close(seen);
4998
4999 FUNC_LEAVE_NOAPI(ret_value)
5000 } /* H5P_close() */
5001
5002
5003 /*--------------------------------------------------------------------------
5004 NAME
5005 H5P_get_class_name
5006 PURPOSE
5007 Internal routine to query the name of a generic property list class
5008 USAGE
5009 char *H5P_get_class_name(pclass)
5010 H5P_genclass_t *pclass; IN: Property list class to check
5011 RETURNS
5012 Success: Pointer to a malloc'ed string containing the class name
5013 Failure: NULL
5014 DESCRIPTION
5015 This routine retrieves the name of a generic property list class.
5016 The pointer to the name must be free'd by the user for successful calls.
5017
5018 GLOBAL VARIABLES
5019 COMMENTS, BUGS, ASSUMPTIONS
5020 EXAMPLES
5021 REVISION LOG
5022 --------------------------------------------------------------------------*/
5023 char *
H5P_get_class_name(H5P_genclass_t * pclass)5024 H5P_get_class_name(H5P_genclass_t *pclass)
5025 {
5026 char *ret_value = NULL; /* Return value */
5027
5028 FUNC_ENTER_NOAPI(NULL)
5029
5030 HDassert(pclass);
5031
5032 /* Get class name */
5033 ret_value=H5MM_xstrdup(pclass->name);
5034
5035 done:
5036 FUNC_LEAVE_NOAPI(ret_value)
5037 } /* H5P_get_class_name() */
5038
5039
5040 /*--------------------------------------------------------------------------
5041 NAME
5042 H5P_get_class_path
5043 PURPOSE
5044 Internal routine to query the full path of a generic property list class
5045 USAGE
5046 char *H5P_get_class_name(pclass)
5047 H5P_genclass_t *pclass; IN: Property list class to check
5048 RETURNS
5049 Success: Pointer to a malloc'ed string containing the full path of class
5050 Failure: NULL
5051 DESCRIPTION
5052 This routine retrieves the full path name of a generic property list
5053 class, starting with the root of the class hierarchy.
5054 The pointer to the name must be free'd by the user for successful calls.
5055
5056 GLOBAL VARIABLES
5057 COMMENTS, BUGS, ASSUMPTIONS
5058 EXAMPLES
5059 REVISION LOG
5060 --------------------------------------------------------------------------*/
5061 char *
H5P_get_class_path(H5P_genclass_t * pclass)5062 H5P_get_class_path(H5P_genclass_t *pclass)
5063 {
5064 char *ret_value = NULL; /* Return value */
5065
5066 FUNC_ENTER_NOAPI_NOINIT
5067
5068 HDassert(pclass);
5069
5070 /* Recursively build the full path */
5071 if(pclass->parent != NULL) {
5072 char *par_path; /* Parent class's full path */
5073
5074 /* Get the parent class's path */
5075 par_path = H5P_get_class_path(pclass->parent);
5076 if(par_path != NULL) {
5077 size_t ret_str_len;
5078
5079 /* Allocate enough space for the parent class's path, plus the '/'
5080 * separator, this class's name and the string terminator
5081 */
5082 ret_str_len = HDstrlen(par_path) + 1 + HDstrlen(pclass->name) + 1;
5083 if(NULL == (ret_value = (char *)H5MM_malloc(ret_str_len)))
5084 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for class name")
5085
5086 /* Build the full path for this class */
5087 HDsnprintf(ret_value, ret_str_len, "%s/%s", par_path, pclass->name);
5088
5089 /* Free the parent class's path */
5090 H5MM_xfree(par_path);
5091 } /* end if */
5092 else
5093 ret_value = H5MM_xstrdup(pclass->name);
5094 } /* end if */
5095 else
5096 ret_value = H5MM_xstrdup(pclass->name);
5097
5098 done:
5099 FUNC_LEAVE_NOAPI(ret_value)
5100 } /* H5P_get_class_path() */
5101
5102
5103 /*--------------------------------------------------------------------------
5104 NAME
5105 H5P_open_class_path
5106 PURPOSE
5107 Internal routine to open [a copy of] a class with its full path name
5108 USAGE
5109 H5P_genclass_t *H5P_open_class_path(path)
5110 const char *path; IN: Full path name of class to open [copy of]
5111 RETURNS
5112 Success: Pointer to a generic property class object
5113 Failure: NULL
5114 DESCRIPTION
5115 This routine opens [a copy] of the class indicated by the full path.
5116
5117 GLOBAL VARIABLES
5118 COMMENTS, BUGS, ASSUMPTIONS
5119 EXAMPLES
5120 REVISION LOG
5121 --------------------------------------------------------------------------*/
5122 H5P_genclass_t *
H5P_open_class_path(const char * path)5123 H5P_open_class_path(const char *path)
5124 {
5125 char *tmp_path = NULL; /* Temporary copy of the path */
5126 char *curr_name; /* Pointer to current component of path name */
5127 char *delimit; /* Pointer to path delimiter during traversal */
5128 H5P_genclass_t *curr_class; /* Pointer to class during path traversal */
5129 H5P_check_class_t check_info; /* Structure to hold the information for checking duplicate names */
5130 H5P_genclass_t *ret_value = NULL; /* Return value */
5131
5132 FUNC_ENTER_NOAPI_NOINIT
5133
5134 HDassert(path);
5135
5136 /* Duplicate the path to use */
5137 tmp_path = H5MM_xstrdup(path);
5138 HDassert(tmp_path);
5139
5140 /* Find the generic property class with this full path */
5141 curr_name = tmp_path;
5142 curr_class = NULL;
5143 while(NULL != (delimit = HDstrchr(curr_name, '/'))) {
5144 /* Change the delimiter to terminate the string */
5145 *delimit = '\0';
5146
5147 /* Set up the search structure */
5148 check_info.parent = curr_class;
5149 check_info.name = curr_name;
5150 check_info.new_class = NULL;
5151
5152 /* Find the class with this name & parent by iterating over the open classes */
5153 if(H5I_iterate(H5I_GENPROP_CLS, H5P_open_class_path_cb, &check_info, FALSE) < 0)
5154 HGOTO_ERROR(H5E_PLIST, H5E_BADITER, NULL, "can't iterate over classes")
5155 else if(NULL == check_info.new_class)
5156 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
5157
5158 /* Advance the pointer in the path to the start of the next component */
5159 curr_class = check_info.new_class;
5160 curr_name = delimit + 1;
5161 } /* end while */
5162
5163 /* Should be pointing to the last component in the path name now... */
5164
5165 /* Set up the search structure */
5166 check_info.parent = curr_class;
5167 check_info.name = curr_name;
5168 check_info.new_class = NULL;
5169
5170 /* Find the class with this name & parent by iterating over the open classes */
5171 if(H5I_iterate(H5I_GENPROP_CLS, H5P_open_class_path_cb, &check_info, FALSE) < 0)
5172 HGOTO_ERROR(H5E_PLIST, H5E_BADITER, NULL, "can't iterate over classes")
5173 else if(NULL == check_info.new_class)
5174 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
5175
5176 /* Copy it */
5177 if(NULL == (ret_value = H5P_copy_pclass(check_info.new_class)))
5178 HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL, "can't copy property class")
5179
5180 done:
5181 /* Free the duplicated path */
5182 H5MM_xfree(tmp_path);
5183
5184 FUNC_LEAVE_NOAPI(ret_value)
5185 } /* H5P_open_class_path() */
5186
5187
5188 /*--------------------------------------------------------------------------
5189 NAME
5190 H5P_get_class_parent
5191 PURPOSE
5192 Internal routine to query the parent class of a generic property class
5193 USAGE
5194 H5P_genclass_t *H5P_get_class_parent(pclass)
5195 H5P_genclass_t *pclass; IN: Property class to check
5196 RETURNS
5197 Success: Pointer to the parent class of a property class
5198 Failure: NULL
5199 DESCRIPTION
5200 This routine retrieves a pointer to the parent class for a property class.
5201
5202 GLOBAL VARIABLES
5203 COMMENTS, BUGS, ASSUMPTIONS
5204 EXAMPLES
5205 REVISION LOG
5206 --------------------------------------------------------------------------*/
5207 H5P_genclass_t *
H5P_get_class_parent(const H5P_genclass_t * pclass)5208 H5P_get_class_parent(const H5P_genclass_t *pclass)
5209 {
5210 H5P_genclass_t *ret_value = NULL; /* Return value */
5211
5212 FUNC_ENTER_NOAPI_NOINIT_NOERR
5213
5214 HDassert(pclass);
5215
5216 /* Get property size */
5217 ret_value = pclass->parent;
5218
5219 FUNC_LEAVE_NOAPI(ret_value)
5220 } /* H5P_get_class_parent() */
5221
5222
5223 /*--------------------------------------------------------------------------
5224 NAME
5225 H5P_close_class
5226 PURPOSE
5227 Internal routine to close a property list class.
5228 USAGE
5229 herr_t H5P_close_class(class)
5230 H5P_genclass_t *class; IN: Property list class to close
5231 RETURNS
5232 Returns non-negative on success, negative on failure.
5233 DESCRIPTION
5234 Releases memory and de-attach a class from the property list class hierarchy.
5235 GLOBAL VARIABLES
5236 COMMENTS, BUGS, ASSUMPTIONS
5237 EXAMPLES
5238 REVISION LOG
5239 --------------------------------------------------------------------------*/
5240 herr_t
H5P_close_class(void * _pclass)5241 H5P_close_class(void *_pclass)
5242 {
5243 H5P_genclass_t *pclass = (H5P_genclass_t *)_pclass;
5244 herr_t ret_value = SUCCEED; /* Return value */
5245
5246 FUNC_ENTER_NOAPI_NOINIT
5247
5248 HDassert(pclass);
5249
5250 /* Decrement the reference count & check if the object should go away */
5251 if(H5P_access_class(pclass, H5P_MOD_DEC_REF) < 0)
5252 HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't decrement ID ref count")
5253
5254 done:
5255 FUNC_LEAVE_NOAPI(ret_value)
5256 } /* H5P_close_class() */
5257
5258
5259 /*-------------------------------------------------------------------------
5260 * Function: H5P__new_plist_of_type
5261 *
5262 * Purpose: Create a new property list, of a given type
5263 *
5264 * Return: Success: ID of new property list
5265 * Failure: Negative
5266 *
5267 * Programmer: Quincey Koziol
5268 * Thursday, August 2, 2012
5269 *
5270 *-------------------------------------------------------------------------
5271 */
5272 hid_t
H5P__new_plist_of_type(H5P_plist_type_t type)5273 H5P__new_plist_of_type(H5P_plist_type_t type)
5274 {
5275 H5P_genclass_t *pclass; /* Class of property list to create */
5276 hid_t class_id; /* ID of class to create */
5277 hid_t ret_value = H5I_INVALID_HID; /* Return value */
5278
5279 FUNC_ENTER_PACKAGE
5280
5281 /* Sanity checks */
5282 HDcompile_assert(H5P_TYPE_ATTRIBUTE_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
5283 HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_LINK_ACCESS);
5284
5285 /* Check arguments */
5286 if(type == H5P_TYPE_USER)
5287 HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't create user property list");
5288 if(type == H5P_TYPE_ROOT)
5289 HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "shouldn't be creating root class property list");
5290
5291 /* Instantiate a property list of the proper type */
5292 switch(type) {
5293 case H5P_TYPE_OBJECT_CREATE:
5294 class_id = H5P_CLS_OBJECT_CREATE_ID_g;
5295 break;
5296
5297 case H5P_TYPE_FILE_CREATE:
5298 class_id = H5P_CLS_FILE_CREATE_ID_g;
5299 break;
5300
5301 case H5P_TYPE_FILE_ACCESS:
5302 class_id = H5P_CLS_FILE_ACCESS_ID_g;
5303 break;
5304
5305 case H5P_TYPE_DATASET_CREATE:
5306 class_id = H5P_CLS_DATASET_CREATE_ID_g;
5307 break;
5308
5309 case H5P_TYPE_DATASET_ACCESS:
5310 class_id = H5P_CLS_DATASET_ACCESS_ID_g;
5311 break;
5312
5313 case H5P_TYPE_DATASET_XFER:
5314 class_id = H5P_CLS_DATASET_XFER_ID_g;
5315 break;
5316
5317 case H5P_TYPE_FILE_MOUNT:
5318 class_id = H5P_CLS_FILE_MOUNT_ID_g;
5319 break;
5320
5321 case H5P_TYPE_GROUP_CREATE:
5322 class_id = H5P_CLS_GROUP_CREATE_ID_g;
5323 break;
5324
5325 case H5P_TYPE_GROUP_ACCESS:
5326 class_id = H5P_CLS_GROUP_ACCESS_ID_g;
5327 break;
5328
5329 case H5P_TYPE_DATATYPE_CREATE:
5330 class_id = H5P_CLS_DATATYPE_CREATE_ID_g;
5331 break;
5332
5333 case H5P_TYPE_DATATYPE_ACCESS:
5334 class_id = H5P_CLS_DATATYPE_ACCESS_ID_g;
5335 break;
5336
5337 case H5P_TYPE_STRING_CREATE:
5338 class_id = H5P_CLS_STRING_CREATE_ID_g;
5339 break;
5340
5341 case H5P_TYPE_ATTRIBUTE_CREATE:
5342 class_id = H5P_CLS_ATTRIBUTE_CREATE_ID_g;
5343 break;
5344
5345 case H5P_TYPE_ATTRIBUTE_ACCESS:
5346 class_id = H5P_CLS_ATTRIBUTE_ACCESS_ID_g;
5347 break;
5348
5349 case H5P_TYPE_OBJECT_COPY:
5350 class_id = H5P_CLS_OBJECT_COPY_ID_g;
5351 break;
5352
5353 case H5P_TYPE_LINK_CREATE:
5354 class_id = H5P_CLS_LINK_CREATE_ID_g;
5355 break;
5356
5357 case H5P_TYPE_LINK_ACCESS:
5358 class_id = H5P_CLS_LINK_ACCESS_ID_g;
5359 break;
5360
5361 case H5P_TYPE_USER: /* shut compiler warnings up */
5362 case H5P_TYPE_ROOT:
5363 case H5P_TYPE_MAX_TYPE:
5364 default:
5365 HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "invalid property list type: %u\n", (unsigned)type);
5366 } /* end switch */
5367
5368 /* Get the class object */
5369 if(NULL == (pclass = (H5P_genclass_t *)H5I_object(class_id)))
5370 HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property class")
5371
5372 /* Create the new property list */
5373 if((ret_value = H5P_create_id(pclass, TRUE)) < 0)
5374 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list")
5375
5376 done:
5377 FUNC_LEAVE_NOAPI(ret_value)
5378 } /* end H5P__new_plist_of_type() */
5379
5380
5381 /*-------------------------------------------------------------------------
5382 * Function: H5P_get_plist_id
5383 *
5384 * Purpose: Quick and dirty routine to retrieve property list ID from
5385 * property list structure.
5386 * (Mainly added to stop non-file routines from poking about in the
5387 * H5P_genplist_t data structure)
5388 *
5389 * Return: Success: Non-negative ID of property list.
5390 * Failure: negative.
5391 *
5392 * Programmer: Quincey Koziol <koziol@hdfgroup.org>
5393 * April 22, 2014
5394 *
5395 *-------------------------------------------------------------------------
5396 */
5397 hid_t
H5P_get_plist_id(const H5P_genplist_t * plist)5398 H5P_get_plist_id(const H5P_genplist_t *plist)
5399 {
5400 /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
5401 FUNC_ENTER_NOAPI_NOINIT_NOERR
5402
5403 HDassert(plist);
5404
5405 FUNC_LEAVE_NOAPI(plist->plist_id)
5406 } /* end H5P_get_plist_id() */
5407
5408
5409 /*-------------------------------------------------------------------------
5410 * Function: H5P_get_class
5411 *
5412 * Purpose: Quick and dirty routine to retrieve property list class from
5413 * property list structure.
5414 * (Mainly added to stop non-file routines from poking about in the
5415 * H5P_genplist_t data structure)
5416 *
5417 * Return: Success: Non-NULL class of property list.
5418 * Failure: NULL
5419 *
5420 * Programmer: Quincey Koziol <koziol@hdfgroup.org>
5421 * April 22, 2014
5422 *
5423 *-------------------------------------------------------------------------
5424 */
5425 H5P_genclass_t *
H5P_get_class(const H5P_genplist_t * plist)5426 H5P_get_class(const H5P_genplist_t *plist)
5427 {
5428 /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
5429 FUNC_ENTER_NOAPI_NOINIT_NOERR
5430
5431 HDassert(plist);
5432
5433 FUNC_LEAVE_NOAPI(plist->pclass)
5434 } /* end H5P_get_class() */
5435
5436
5437 /*-------------------------------------------------------------------------
5438 * Function: H5P_verify_apl_and_dxpl
5439 *
5440 * Purpose: Validate access property list and/or switch from generic
5441 * property list to default of correct type.
5442 *
5443 * Also, if using internal DXPL and collective flag is set,
5444 * switch to internal collective DXPL.
5445 *
5446 * Return: Non-negative on success/Negative on failure
5447 *
5448 * Programmer: Mohamad Chaarawi
5449 * Sunday, June 21, 2015
5450 *
5451 *-------------------------------------------------------------------------
5452 */
5453 herr_t
H5P_verify_apl_and_dxpl(hid_t * acspl_id,const H5P_libclass_t * libclass,hid_t * dxpl_id,hid_t H5_ATTR_UNUSED loc_id,hbool_t H5_ATTR_UNUSED is_collective)5454 H5P_verify_apl_and_dxpl(hid_t *acspl_id, const H5P_libclass_t *libclass, hid_t *dxpl_id,
5455 hid_t
5456 #ifndef H5_HAVE_PARALLEL
5457 H5_ATTR_UNUSED
5458 #endif /* H5_HAVE_PARALLEL */
5459 loc_id, hbool_t
5460 #ifndef H5_HAVE_PARALLEL
5461 H5_ATTR_UNUSED
5462 #endif /* H5_HAVE_PARALLEL */
5463 is_collective)
5464 {
5465 herr_t ret_value = SUCCEED; /* Return value */
5466
5467 FUNC_ENTER_NOAPI_NOINIT
5468
5469 /* Sanity check */
5470 HDassert(acspl_id);
5471 HDassert(libclass);
5472 HDassert(dxpl_id);
5473
5474 #ifdef H5_HAVE_PARALLEL
5475 /* If parallel is enabled and the file driver used in the MPI-IO
5476 VFD, issue an MPI barrier for easier debugging if the API function
5477 calling this is supposed to be called collectively. Note that this
5478 happens only when the environment variable H5_COLL_BARRIER is set
5479 to non 0. */
5480 if(is_collective && H5_coll_api_sanity_check_g) {
5481 MPI_Comm mpi_comm; /* file communicator */
5482
5483 /* retrieve the MPI communicator from the loc_id or the fapl_id */
5484 if(H5F_mpi_retrieve_comm(loc_id, *acspl_id, &mpi_comm) < 0)
5485 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator")
5486
5487 /* issue the barrier */
5488 if(mpi_comm != MPI_COMM_NULL)
5489 MPI_Barrier(mpi_comm);
5490 }
5491 #endif /* H5_HAVE_PARALLEL */
5492
5493 /* Set access plist to the default property list of the appropriate class if it's the generic default */
5494 if(H5P_DEFAULT == *acspl_id)
5495 *acspl_id = *libclass->def_plist_id;
5496 else {
5497 #ifdef H5_HAVE_PARALLEL
5498 H5P_coll_md_read_flag_t md_coll_read; /* Collective metadata read flag */
5499 H5P_genplist_t *plist; /* Property list pointer */
5500 #endif /* H5_HAVE_PARALLEL */
5501
5502 /* Sanity check the access property list class */
5503 if(TRUE != H5P_isa_class(*acspl_id, *libclass->class_id))
5504 HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not the required access property list")
5505
5506 #ifdef H5_HAVE_PARALLEL
5507 /* Get the plist structure for the access property list */
5508 if(NULL == (plist = (H5P_genplist_t *)H5I_object(*acspl_id)))
5509 HGOTO_ERROR(H5E_PLIST, H5E_BADATOM, FAIL, "can't find object for ID")
5510
5511 /* Get the collective metadata read flag */
5512 if(H5P_peek(plist, H5_COLL_MD_READ_FLAG_NAME, &md_coll_read) < 0)
5513 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get core collective metadata read flag")
5514
5515 /* If collective metadata read requested and using internal DXPL, switch to internal collective DXPL */
5516 if(H5P_USER_TRUE == md_coll_read)
5517 *dxpl_id = H5AC_coll_read_dxpl_id;
5518 #endif /* H5_HAVE_PARALLEL */
5519 } /* end else */
5520
5521 done:
5522 FUNC_LEAVE_NOAPI(ret_value)
5523 } /* end H5P_verify_apl_and_dxpl() */
5524
5525