1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Copyright by the Board of Trustees of the University of Illinois. *
3
* All rights reserved. *
5
* This file is part of HDF5. The full HDF5 copyright notice, including *
6
* terms governing use, modification, and redistribution, is contained in *
7
* the files COPYING and Copyright.html. COPYING can be found at the root *
8
* of the source code distribution tree; Copyright.html can be found at the *
9
* root level of an installed copy of the electronic HDF5 document set and *
10
* is linked from the top-level documents page. It can also be found at *
11
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
12
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
13
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15
/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
17
* Purpose: Generic Property Functions
20
#define H5P_PACKAGE /*suppress error about including H5Ppkg */
22
/* Interface initialization */
23
#define H5_INTERFACE_INIT_FUNC H5P_init_interface
26
/* Private header files */
27
#include "H5private.h" /* Generic Functions */
28
#include "H5Dprivate.h" /* Datasets */
29
#include "H5Eprivate.h" /* Error handling */
30
#include "H5Fprivate.h" /* Files */
31
#include "H5FLprivate.h" /* Free lists */
32
#include "H5Iprivate.h" /* IDs */
33
#include "H5MMprivate.h" /* Memory management */
34
#include "H5Ppkg.h" /* Property lists */
37
#define H5P_DEFAULT_SKIPLIST_HEIGHT 8
42
* Predefined property list classes. These are initialized at runtime by
43
* H5P_init_interface() in this source file.
45
hid_t H5P_CLS_NO_CLASS_g = FAIL;
46
hid_t H5P_CLS_FILE_CREATE_g = FAIL;
47
hid_t H5P_CLS_FILE_ACCESS_g = FAIL;
48
hid_t H5P_CLS_DATASET_CREATE_g = FAIL;
49
hid_t H5P_CLS_DATASET_XFER_g = FAIL;
50
hid_t H5P_CLS_MOUNT_g = FAIL;
53
* Predefined property lists for each predefined class. These are initialized
54
* at runtime by H5P_init_interface() in this source file.
56
hid_t H5P_LST_NO_CLASS_g = FAIL;
57
hid_t H5P_LST_FILE_CREATE_g = FAIL;
58
hid_t H5P_LST_FILE_ACCESS_g = FAIL;
59
hid_t H5P_LST_DATASET_CREATE_g = FAIL;
60
hid_t H5P_LST_DATASET_XFER_g = FAIL;
61
hid_t H5P_LST_MOUNT_g = FAIL;
63
/* Track the revision count of a class, to make comparisons faster */
64
static unsigned H5P_next_rev=0;
65
#define H5P_GET_NEXT_REV (H5P_next_rev++)
67
/* Declare a free list to manage the H5P_genprop_t struct */
68
H5FL_DEFINE(H5P_genprop_t);
70
/* Declare a free list to manage the H5P_genplist_t struct */
71
H5FL_DEFINE(H5P_genplist_t);
73
/* Declare a free list to manage the H5P_genclass_t struct */
74
H5FL_DEFINE_STATIC(H5P_genclass_t);
78
/* Typedef for checking for duplicate class names in parent class */
80
const H5P_genclass_t *parent; /* Pointer to parent class */
81
const char *name; /* Pointer to name to check */
84
/* Local static functions */
85
static H5P_genclass_t *H5P_create_class(H5P_genclass_t *par_class,
86
const char *name, unsigned internal,
87
H5P_cls_create_func_t cls_create, void *create_data,
88
H5P_cls_copy_func_t cls_copy, void *copy_data,
89
H5P_cls_close_func_t cls_close, void *close_data);
90
static herr_t H5P_unregister(H5P_genclass_t *pclass, const char *name);
91
static H5P_genprop_t *H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type);
92
static herr_t H5P_free_prop(H5P_genprop_t *prop);
95
/*--------------------------------------------------------------------------
99
Internal routine to call a property list callback routine and update
100
the property list accordingly.
102
herr_t H5P_do_prop_cb1(slist,prop,cb)
103
H5SL_t *slist; IN/OUT: Skip list to hold changed properties
104
H5P_genprop_t *prop; IN: Property to call callback for
105
H5P_prp_cb1_t *cb; IN: Callback routine to call
107
Returns non-negative on success, negative on failure.
109
Calls the callback routine passed in. If the callback routine changes
110
the property value, then the property is duplicated and added to skip list.
113
COMMENTS, BUGS, ASSUMPTIONS
116
--------------------------------------------------------------------------*/
118
H5P_do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb)
120
void *tmp_value=NULL; /* Temporary value buffer */
121
H5P_genprop_t *pcopy=NULL; /* Copy of property to insert into skip list */
122
herr_t ret_value=SUCCEED; /* Return value */
124
FUNC_ENTER_NOAPI_NOINIT(H5P_do_prop_cb1);
126
/* Allocate space for a temporary copy of the property value */
127
if (NULL==(tmp_value=H5MM_malloc(prop->size)))
128
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value");
129
HDmemcpy(tmp_value,prop->value,prop->size);
131
/* Call "type 1" callback ('create', 'copy' or 'close') */
132
if(cb(prop->name,prop->size,tmp_value)<0)
133
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Property callback failed");
135
/* Check if the property value changed */
136
if(HDmemcmp(tmp_value,prop->value,prop->size)) {
137
/* Make a copy of the class's property */
138
if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
139
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
141
/* Copy the changed value into the new property */
142
HDmemcpy(pcopy->value,tmp_value,prop->size);
144
/* Insert the changed property into the property list */
145
if(H5P_add_prop(slist,pcopy)<0)
146
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into skip list");
150
/* Release the temporary value buffer */
152
H5MM_xfree(tmp_value);
154
/* Cleanup on failure */
157
H5P_free_prop(pcopy);
160
FUNC_LEAVE_NOAPI(ret_value);
161
} /* end H5P_do_prop_cb1() */
164
/*-------------------------------------------------------------------------
167
* Purpose: Initialize the interface from some other layer.
169
* Return: Success: non-negative
173
* Programmer: Quincey Koziol
174
* Saturday, March 4, 2000
178
*-------------------------------------------------------------------------
183
herr_t ret_value=SUCCEED; /* Return value */
185
FUNC_ENTER_NOAPI(H5P_init, FAIL);
186
/* FUNC_ENTER() does all the work */
189
FUNC_LEAVE_NOAPI(ret_value);
193
/*--------------------------------------------------------------------------
195
H5P_init_interface -- Initialize interface-specific information
197
herr_t H5P_init_interface()
200
Non-negative on success/Negative on failure
202
Initializes any interface-specific data or routines.
204
--------------------------------------------------------------------------*/
206
H5P_init_interface(void)
208
H5P_genclass_t *root_class; /* Pointer to root property list class created */
209
H5P_genclass_t *pclass; /* Pointer to property list class to create */
210
herr_t ret_value = SUCCEED;
212
FUNC_ENTER_NOAPI_NOINIT(H5P_init_interface);
215
* Initialize the Generic Property class & object groups.
217
if (H5I_init_group(H5I_GENPROP_CLS, H5I_GENPROPCLS_HASHSIZE, 0, (H5I_free_t)H5P_close_class) < 0)
218
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize atom group");
219
if (H5I_init_group(H5I_GENPROP_LST, H5I_GENPROPOBJ_HASHSIZE, 0, (H5I_free_t)H5P_close) < 0)
220
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize atom group");
222
/* Create root property list class */
224
/* Allocate the root class */
225
assert(H5P_CLS_NO_CLASS_g==(-1));
226
if (NULL==(root_class = H5P_create_class (NULL,"root",1,NULL,NULL,NULL,NULL,NULL,NULL)))
227
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
229
/* Register the root class */
230
if ((H5P_CLS_NO_CLASS_g = H5I_register (H5I_GENPROP_CLS, root_class))<0)
231
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
233
/* Register the file creation and file access property classes */
235
/* Allocate the file creation class */
236
assert(H5P_CLS_FILE_CREATE_g==(-1));
237
if (NULL==(pclass = H5P_create_class (root_class,"file create",1,NULL,NULL,NULL,NULL,NULL,NULL)))
238
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
240
/* Register the file creation class */
241
if ((H5P_CLS_FILE_CREATE_g = H5I_register (H5I_GENPROP_CLS, pclass))<0)
242
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
244
/* Allocate the file access class */
245
assert(H5P_CLS_FILE_ACCESS_g==(-1));
246
if (NULL==(pclass = H5P_create_class (root_class,"file access",1,H5F_acs_create,NULL,H5F_acs_copy,NULL,H5F_acs_close,NULL)))
247
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
249
/* Register the file access class */
250
if ((H5P_CLS_FILE_ACCESS_g = H5I_register (H5I_GENPROP_CLS, pclass))<0)
251
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
253
/* Register the dataset creation and data xfer property classes */
255
/* Allocate the dataset creation class */
256
assert(H5P_CLS_DATASET_CREATE_g==(-1));
257
if (NULL==(pclass = H5P_create_class (root_class,"dataset create",1,NULL,NULL,H5D_crt_copy,NULL,H5D_crt_close,NULL)))
258
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
260
/* Register the dataset creation class */
261
if ((H5P_CLS_DATASET_CREATE_g = H5I_register (H5I_GENPROP_CLS, pclass))<0)
262
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
264
/* Allocate the data xfer class */
265
assert(H5P_CLS_DATASET_XFER_g==(-1));
266
if (NULL==(pclass = H5P_create_class (root_class,"data xfer",1,H5D_xfer_create,NULL,H5D_xfer_copy,NULL,H5D_xfer_close,NULL)))
267
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
269
/* Register the data xfer class */
270
if ((H5P_CLS_DATASET_XFER_g = H5I_register (H5I_GENPROP_CLS, pclass))<0)
271
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
273
/* Allocate the mount class */
274
assert(H5P_CLS_MOUNT_g==(-1));
275
if (NULL==(pclass = H5P_create_class (root_class,"file mount",1,NULL,NULL,NULL,NULL,NULL,NULL)))
276
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
278
/* Register the mount class */
279
if ((H5P_CLS_MOUNT_g = H5I_register (H5I_GENPROP_CLS, pclass))<0)
280
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
283
FUNC_LEAVE_NOAPI(ret_value);
287
/*--------------------------------------------------------------------------
291
Terminate various H5P objects
293
void H5P_term_interface()
295
Non-negative on success/Negative on failure
297
Release the atom group and any other resources allocated.
299
COMMENTS, BUGS, ASSUMPTIONS
300
Can't report errors...
303
--------------------------------------------------------------------------*/
305
H5P_term_interface(void)
311
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_term_interface);
313
if (H5_interface_initialize_g) {
314
/* Destroy HDF5 library property classes & lists */
316
/* Check if there are any open property list classes or lists */
317
nclass = H5I_nmembers(H5I_GENPROP_CLS);
318
nlist = H5I_nmembers(H5I_GENPROP_LST);
321
/* If there are any open classes or groups, attempt to get rid of them. */
323
/* Clear the lists */
325
H5I_clear_group(H5I_GENPROP_LST, FALSE);
327
/* Reset the default property lists, if they've been closed */
328
if(H5I_nmembers(H5I_GENPROP_LST)==0) {
330
H5P_LST_FILE_CREATE_g =
331
H5P_LST_FILE_ACCESS_g =
332
H5P_LST_DATASET_CREATE_g =
333
H5P_LST_DATASET_XFER_g =
334
H5P_LST_MOUNT_g = (-1);
338
/* Only attempt to close the classes after all the lists are closed */
339
if(nlist==0 && nclass>0) {
340
H5I_clear_group(H5I_GENPROP_CLS, FALSE);
342
/* Reset the default property lists, if they've been closed */
343
if(H5I_nmembers(H5I_GENPROP_CLS)==0) {
345
H5P_CLS_FILE_CREATE_g =
346
H5P_CLS_FILE_ACCESS_g =
347
H5P_CLS_DATASET_CREATE_g =
348
H5P_CLS_DATASET_XFER_g =
349
H5P_CLS_MOUNT_g = (-1);
353
H5I_destroy_group(H5I_GENPROP_LST);
355
H5I_destroy_group(H5I_GENPROP_CLS);
358
H5_interface_initialize_g = 0;
365
/*--------------------------------------------------------------------------
369
Internal routine to copy a generic property class
371
hid_t H5P_copy_pclass(pclass)
372
H5P_genclass_t *pclass; IN: Property class to copy
374
Success: valid property class ID on success (non-negative)
377
Copy a property class and return the ID. This routine does not make
378
any callbacks. (They are only make when operating on property lists).
381
COMMENTS, BUGS, ASSUMPTIONS
384
--------------------------------------------------------------------------*/
385
static H5P_genclass_t *
386
H5P_copy_pclass(H5P_genclass_t *pclass)
388
H5P_genclass_t *new_pclass = NULL; /* Property list class copied */
389
H5P_genprop_t *pcopy; /* Copy of property to insert into class */
390
H5P_genclass_t *ret_value=NULL; /* return value */
392
FUNC_ENTER_NOAPI_NOINIT(H5P_copy_pclass);
397
* Create new property class object
400
/* Create the new property list class */
401
if (NULL==(new_pclass=H5P_create_class(pclass->parent, pclass->name, 0, pclass->create_func, pclass->create_data, pclass->copy_func, pclass->copy_data, pclass->close_func, pclass->close_data)))
402
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list class");
404
/* Copy the properties registered for this class */
405
if(pclass->nprops>0) {
406
H5SL_node_t *curr_node; /* Current node in skip list */
408
/* Walk through the properties in the old class */
409
curr_node=H5SL_first(pclass->props);
410
while(curr_node!=NULL) {
411
/* Make a copy of the class's property */
412
if((pcopy=H5P_dup_prop(H5SL_item(curr_node),H5P_PROP_WITHIN_CLASS))==NULL)
413
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property");
415
/* Insert the initialized property into the property list */
416
if(H5P_add_prop(new_pclass->props,pcopy)<0)
417
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class");
419
/* Increment property count for class */
420
new_pclass->nprops++;
422
/* Get the next property node in the list */
423
curr_node=H5SL_next(curr_node);
427
/* Set the return value */
428
ret_value=new_pclass;
431
if (ret_value==NULL && new_pclass)
432
H5P_close_class(new_pclass);
434
FUNC_LEAVE_NOAPI(ret_value);
435
} /* H5P_copy_pclass() */
438
/*--------------------------------------------------------------------------
442
Internal routine to copy a generic property list
444
hid_t H5P_copy_plist(old_plist_id)
445
hid_t old_plist_id; IN: Property list ID to copy
447
Success: valid property list ID on success (non-negative)
450
Copy a property list and return the ID. This routine calls the
451
class 'copy' callback after any property 'copy' callbacks are called
452
(assuming all property 'copy' callbacks return successfully).
455
COMMENTS, BUGS, ASSUMPTIONS
458
--------------------------------------------------------------------------*/
460
H5P_copy_plist(H5P_genplist_t *old_plist)
462
H5P_genclass_t *tclass; /* Temporary class pointer */
463
H5P_genplist_t *new_plist=NULL; /* New property list generated from copy */
464
H5P_genprop_t *tmp; /* Temporary pointer to properties */
465
H5P_genprop_t *new_prop; /* New property created for copy */
466
hid_t new_plist_id; /* Property list ID of new list created */
467
H5SL_node_t *curr_node; /* Current node in skip list */
468
H5SL_t *seen=NULL; /* Skip list containing properties already seen */
469
size_t nseen; /* Number of items 'seen' */
470
hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */
471
hid_t ret_value=FAIL; /* return value */
473
FUNC_ENTER_NOAPI(H5P_copy_plist, FAIL);
478
* Create new property list object
481
/* Allocate room for the property list */
482
if (NULL==(new_plist = H5FL_CALLOC(H5P_genplist_t)))
483
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,"memory allocation failed");
485
/* Set class state */
486
new_plist->pclass = old_plist->pclass;
487
new_plist->nprops = 0; /* Initially the plist has the same number of properties as the class */
488
new_plist->class_init = 0; /* Initially, wait until the class callback finishes to set */
490
/* Initialize the skip list to hold the changed properties */
491
if((new_plist->props=H5SL_create(H5SL_TYPE_STR,0.5,H5P_DEFAULT_SKIPLIST_HEIGHT))==NULL)
492
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for changed properties");
494
/* Create the skip list for deleted properties */
495
if((new_plist->del=H5SL_create(H5SL_TYPE_STR,0.5,H5P_DEFAULT_SKIPLIST_HEIGHT))==NULL)
496
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for deleted properties");
498
/* Create the skip list to hold names of properties already seen
499
* (This prevents a property in the class hierarchy from having it's
500
* 'create' callback called, if a property in the class hierarchy has
503
if((seen=H5SL_create(H5SL_TYPE_STR,0.5,H5P_DEFAULT_SKIPLIST_HEIGHT))==NULL)
504
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties");
507
/* Cycle through the deleted properties & copy them into the new list's deleted section */
508
if(H5SL_count(old_plist->del)>0) {
509
curr_node=H5SL_first(old_plist->del);
511
char *new_name; /* Pointer to new name */
513
/* Duplicate string for insertion into new deleted property skip list */
514
if((new_name=H5MM_xstrdup((char *)H5SL_item(curr_node)))==NULL)
515
HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
517
/* Insert property name into deleted list */
518
if(H5SL_insert(new_plist->del,new_name,new_name)<0)
519
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list");
521
/* Add property name to "seen" list */
522
if(H5SL_insert(seen,new_name,new_name)<0)
523
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list");
526
/* Get the next property node in the skip list */
527
curr_node=H5SL_next(curr_node);
531
/* Cycle through the properties and copy them also */
532
if(H5SL_count(old_plist->props)>0) {
533
curr_node=H5SL_first(old_plist->props);
535
/* Get a pointer to the node's property */
536
tmp=H5SL_item(curr_node);
538
/* Make a copy of the list's property */
539
if((new_prop=H5P_dup_prop(tmp,H5P_PROP_WITHIN_LIST))==NULL)
540
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
542
/* Call property copy callback, if it exists */
544
if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value)<0) {
545
H5P_free_prop(new_prop);
546
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
550
/* Insert the initialized property into the property list */
551
if(H5P_add_prop(new_plist->props,new_prop)<0) {
552
H5P_free_prop(new_prop);
553
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list");
556
/* Add property name to "seen" list */
557
if(H5SL_insert(seen,new_prop->name,new_prop->name)<0)
558
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list");
561
/* Increment the number of properties in list */
564
/* Get the next property node in the skip list */
565
curr_node=H5SL_next(curr_node);
570
* Check for copying class properties (up through list of parent classes also),
571
* initialize each with default value & make property 'copy' callback.
573
tclass=old_plist->pclass;
574
has_parent_class=(tclass!=NULL && tclass->parent!=NULL && tclass->parent->nprops>0);
575
while(tclass!=NULL) {
576
if(tclass->nprops>0) {
577
/* Walk through the properties in the old class */
578
curr_node=H5SL_first(tclass->props);
579
while(curr_node!=NULL) {
580
/* Get pointer to property from node */
581
tmp=H5SL_item(curr_node);
583
/* Only "copy" properties we haven't seen before */
584
if(nseen==0 || H5SL_search(seen,tmp->name)==NULL) {
585
/* Call property creation callback, if it exists */
587
/* Call the callback & insert changed value into skip list (if necessary) */
588
if(H5P_do_prop_cb1(new_plist->props,tmp,tmp->copy)<0)
589
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't create property");
592
/* Add property name to "seen" list, if we have other classes to work on */
593
if(has_parent_class) {
594
if(H5SL_insert(seen,tmp->name,tmp->name)<0)
595
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list");
599
/* Increment the number of properties in list */
603
/* Get the next property node in the skip list */
604
curr_node=H5SL_next(curr_node);
608
/* Go up to parent class */
609
tclass=tclass->parent;
612
/* Increment the number of property lists derived from class */
613
if(H5P_access_class(new_plist->pclass,H5P_MOD_INC_LST)<0)
614
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ref count");
616
/* Get an atom for the property list */
617
if ((new_plist_id = H5I_register(H5I_GENPROP_LST, new_plist))<0)
618
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list");
620
/* Save the property list ID in the property list struct, for use in the property class's 'close' callback */
621
new_plist->plist_id=new_plist_id;
623
/* Call the class callback (if it exists) now that we have the property list ID */
624
if(new_plist->pclass->copy_func!=NULL) {
625
if((new_plist->pclass->copy_func)(new_plist_id,old_plist->plist_id,old_plist->pclass->copy_data)<0) {
626
/* Delete ID, ignore return value */
627
H5I_remove(new_plist_id);
628
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property");
632
/* Set the class initialization flag */
633
new_plist->class_init=1;
635
/* Set the return value */
636
ret_value=new_plist_id;
639
/* Release the list of 'seen' properties */
643
if (ret_value<0 && new_plist)
644
H5P_close(new_plist);
646
FUNC_LEAVE_NOAPI(ret_value);
647
} /* H5P_copy_plist() */
650
/*--------------------------------------------------------------------------
654
Routine to copy a property list or class
657
hid_t id; IN: Property list or class ID to copy
659
Success: valid property list ID on success (non-negative)
662
Copy a property list or class and return the ID. This routine calls the
663
class 'copy' callback after any property 'copy' callbacks are called
664
(assuming all property 'copy' callbacks return successfully).
667
COMMENTS, BUGS, ASSUMPTIONS
670
--------------------------------------------------------------------------*/
674
void *obj; /* Property object to copy */
675
hid_t ret_value=FALSE; /* return value */
677
FUNC_ENTER_API(H5Pcopy, FAIL);
678
H5TRACE1("i","i",id);
681
HGOTO_DONE(H5P_DEFAULT);
683
/* Check arguments. */
684
if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
685
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property object");
686
if(NULL == (obj = H5I_object(id)))
687
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist");
689
/* Compare property lists */
690
if(H5I_GENPROP_LST == H5I_get_type(id)) {
691
if((ret_value=H5P_copy_plist(obj))<0)
692
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property list");
694
/* Must be property classes */
696
H5P_genclass_t *copy_class; /* Copy of class */
699
if((copy_class=H5P_copy_pclass(obj))==NULL)
700
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property class");
702
/* Get an atom for the copied class */
703
if ((ret_value = H5I_register(H5I_GENPROP_CLS, copy_class))<0) {
704
H5P_close_class(copy_class);
705
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
710
FUNC_LEAVE_API(ret_value);
714
/*--------------------------------------------------------------------------
718
Internal routine to duplicate a property
720
H5P_genprop_t *H5P_dup_prop(oprop)
721
H5P_genprop_t *oprop; IN: Pointer to property to copy
722
H5P_prop_within_t type; IN: Type of object the property will be inserted into
724
Returns a pointer to the newly created duplicate of a property on success,
727
Allocates memory and copies property information into a new property object.
729
COMMENTS, BUGS, ASSUMPTIONS
732
--------------------------------------------------------------------------*/
733
static H5P_genprop_t *
734
H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type)
736
H5P_genprop_t *prop=NULL; /* Pointer to new property copied */
737
H5P_genprop_t *ret_value; /* Return value */
739
FUNC_ENTER_NOAPI_NOINIT(H5P_dup_prop);
742
assert(type!=H5P_PROP_WITHIN_UNKNOWN);
744
/* Allocate the new property */
745
if (NULL==(prop = H5FL_MALLOC (H5P_genprop_t)))
746
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
748
/* Copy basic property information */
749
HDmemcpy(prop,oprop,sizeof(H5P_genprop_t));
751
/* Check if we should duplicate the name or share it */
753
/* Duplicating property for a class */
754
if(type==H5P_PROP_WITHIN_CLASS) {
755
assert(oprop->type==H5P_PROP_WITHIN_CLASS);
756
assert(oprop->shared_name==0);
759
prop->name = H5MM_xstrdup(oprop->name);
761
/* Duplicating property for a list */
763
/* Check if we are duplicating a property from a list or a class */
765
/* Duplicating a property from a list */
766
if(oprop->type==H5P_PROP_WITHIN_LIST) {
767
/* If the old property's name wasn't shared, we have to copy it here also */
768
if(!oprop->shared_name)
769
prop->name = H5MM_xstrdup(oprop->name);
771
/* Duplicating a property from a class */
773
assert(oprop->type==H5P_PROP_WITHIN_CLASS);
774
assert(oprop->shared_name==0);
784
/* Duplicate current value, if it exists */
785
if(oprop->value!=NULL) {
786
assert(prop->size>0);
787
if (NULL==(prop->value = H5MM_malloc (prop->size)))
788
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
789
HDmemcpy(prop->value,oprop->value,prop->size);
792
/* Set return value */
796
/* Free any resources allocated */
797
if(ret_value==NULL) {
800
H5MM_xfree(prop->name);
801
if(prop->value!=NULL)
802
H5MM_xfree(prop->value);
803
H5FL_FREE(H5P_genprop_t,prop);
807
FUNC_LEAVE_NOAPI(ret_value);
808
} /* H5P_dup_prop() */
811
/*--------------------------------------------------------------------------
815
Internal routine to create a new property
817
H5P_genprop_t *H5P_create_prop(name,size,type,value,prp_create,prp_set,
818
prp_get,prp_delete,prp_close)
819
const char *name; IN: Name of property to register
820
size_t size; IN: Size of property in bytes
821
H5P_prop_within_t type; IN: Type of object the property will be inserted into
822
void *value; IN: Pointer to buffer containing value for property
823
H5P_prp_create_func_t prp_create; IN: Function pointer to property
825
H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
826
H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
827
H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
828
H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
829
H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback
830
H5P_prp_close_func_t prp_close; IN: Function pointer to property close
833
Returns a pointer to the newly created property on success,
836
Allocates memory and copies property information into a new property object.
838
COMMENTS, BUGS, ASSUMPTIONS
841
--------------------------------------------------------------------------*/
842
static H5P_genprop_t *
843
H5P_create_prop(const char *name, size_t size, H5P_prop_within_t type,
845
H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set,
846
H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete,
847
H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp,
848
H5P_prp_close_func_t prp_close)
850
H5P_genprop_t *prop=NULL; /* Pointer to new property copied */
851
H5P_genprop_t *ret_value; /* Return value */
853
FUNC_ENTER_NOAPI_NOINIT(H5P_create_prop);
856
assert((size>0 && value!=NULL) || (size==0));
857
assert(type!=H5P_PROP_WITHIN_UNKNOWN);
859
/* Allocate the new property */
860
if (NULL==(prop = H5FL_MALLOC (H5P_genprop_t)))
861
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
863
/* Set the property initial values */
864
prop->name = H5MM_xstrdup(name); /* Duplicate name */
869
/* Duplicate value, if it exists */
871
if (NULL==(prop->value = H5MM_malloc (prop->size)))
872
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
873
HDmemcpy(prop->value,value,prop->size);
878
/* Set the function pointers */
879
prop->create=prp_create;
882
prop->del=prp_delete;
884
/* Use custom comparison routine if available, otherwise default to memcmp() */
889
prop->close=prp_close;
891
/* Set return value */
895
/* Free any resources allocated */
896
if(ret_value==NULL) {
899
H5MM_xfree(prop->name);
900
if(prop->value!=NULL)
901
H5MM_xfree(prop->value);
902
H5FL_FREE(H5P_genprop_t,prop);
906
FUNC_LEAVE_NOAPI(ret_value);
907
} /* H5P_create_prop() */
910
/*--------------------------------------------------------------------------
914
Internal routine to insert a property into a property skip list
916
herr_t H5P_add_prop(slist, prop)
917
H5SL_t *slist; IN/OUT: Pointer to skip list of properties
918
H5P_genprop_t *prop; IN: Pointer to property to insert
920
Returns non-negative on success, negative on failure.
922
Inserts a property into a skip list of properties.
924
COMMENTS, BUGS, ASSUMPTIONS
927
--------------------------------------------------------------------------*/
929
H5P_add_prop(H5SL_t *slist, H5P_genprop_t *prop)
931
herr_t ret_value=SUCCEED; /* Return value */
933
FUNC_ENTER_NOAPI(H5P_add_prop,FAIL);
937
assert(prop->type!=H5P_PROP_WITHIN_UNKNOWN);
939
/* Insert property into skip list */
940
if(H5SL_insert(slist,prop,prop->name)<0)
941
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into skip list");
944
FUNC_LEAVE_NOAPI(ret_value);
945
} /* H5P_add_prop() */
948
/*--------------------------------------------------------------------------
952
Internal routine to check for a property in a property list's skip list
954
H5P_genprop_t *H5P_find_prop(plist, name)
955
H5P_genplist_t *plist; IN: Pointer to property list to check
956
const char *name; IN: Name of property to check for
958
Returns pointer to property on success, NULL on failure.
960
Checks for a property in a property list's skip list of properties.
962
COMMENTS, BUGS, ASSUMPTIONS
965
--------------------------------------------------------------------------*/
966
static H5P_genprop_t *
967
H5P_find_prop_plist(H5P_genplist_t *plist, const char *name)
969
H5P_genprop_t *ret_value; /* Property pointer return value */
971
FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_plist);
976
/* Check if the property has been deleted from list */
977
if(H5SL_search(plist->del,name)!=NULL) {
978
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list");
981
/* Get the property data from the skip list */
982
if((ret_value=H5SL_search(plist->props,name))==NULL) {
983
H5P_genclass_t *tclass; /* Temporary class pointer */
985
/* Couldn't find property in list itself, start searching through class info */
986
tclass=plist->pclass;
987
while(tclass!=NULL) {
988
/* Find the property in the class */
989
if((ret_value=H5SL_search(tclass->props,name))!=NULL)
990
/* Got pointer to property - leave now */
993
/* Go up to parent class */
994
tclass=tclass->parent;
997
/* Check if we haven't found the property */
999
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list");
1004
FUNC_LEAVE_NOAPI(ret_value);
1005
} /* H5P_find_prop_plist() */
1008
/*--------------------------------------------------------------------------
1010
H5P_find_prop_pclass
1012
Internal routine to check for a property in a class skip list
1014
H5P_genprop_t *H5P_find_prop_class(pclass, name)
1015
H5P_genclass *pclass; IN: Pointer generic property class to check
1016
const char *name; IN: Name of property to check for
1018
Returns pointer to property on success, NULL on failure.
1020
Checks for a property in a class's skip list of properties.
1022
COMMENTS, BUGS, ASSUMPTIONS
1025
--------------------------------------------------------------------------*/
1026
static H5P_genprop_t *
1027
H5P_find_prop_pclass(H5P_genclass_t *pclass, const char *name)
1029
H5P_genprop_t *ret_value; /* Property pointer return value */
1031
FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_pclass);
1036
/* Get the property from the skip list */
1037
if((ret_value=H5SL_search(pclass->props,name))==NULL)
1038
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list");
1041
FUNC_LEAVE_NOAPI(ret_value);
1042
} /* H5P_find_prop_pclass() */
1045
/*--------------------------------------------------------------------------
1049
Internal routine to destroy a property node
1051
herr_t H5P_free_prop(prop)
1052
H5P_genprop_t *prop; IN: Pointer to property to destroy
1054
Returns non-negative on success, negative on failure.
1056
Releases all the memory for a property list. Does _not_ call the
1057
properties 'close' callback, that should already have been done.
1059
COMMENTS, BUGS, ASSUMPTIONS
1062
--------------------------------------------------------------------------*/
1064
H5P_free_prop(H5P_genprop_t *prop)
1066
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop);
1070
/* Release the property value if it exists */
1072
H5MM_xfree(prop->value);
1074
/* Only free the name if we own it */
1075
if(prop->shared_name==0)
1076
H5MM_xfree(prop->name);
1078
H5FL_FREE(H5P_genprop_t,prop);
1080
FUNC_LEAVE_NOAPI(SUCCEED);
1081
} /* H5P_free_prop() */
1084
/*--------------------------------------------------------------------------
1088
Internal routine to properties from a property skip list
1090
herr_t H5P_free_prop_cb(item, key, op_data)
1091
void *item; IN/OUT: Pointer to property
1092
void *key; IN/OUT: Pointer to property key
1093
void *_make_cb; IN: Whether to make property callbacks or not
1095
Returns zero on success, negative on failure.
1097
Calls the property 'close' callback for a property & frees property
1100
COMMENTS, BUGS, ASSUMPTIONS
1103
--------------------------------------------------------------------------*/
1105
H5P_free_prop_cb(void *item, void UNUSED *key, void *op_data)
1107
H5P_genprop_t *tprop=(H5P_genprop_t *)item; /* Temporary pointer to property */
1108
unsigned make_cb=*(unsigned *)op_data; /* Whether to make property 'close' callback */
1110
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop_cb);
1114
/* Call the close callback and ignore the return value, there's nothing we can do about it */
1115
if(make_cb && tprop->close!=NULL)
1116
(tprop->close)(tprop->name,tprop->size,tprop->value);
1118
/* Free the property, ignoring return value, nothing we can do */
1119
H5P_free_prop(tprop);
1121
FUNC_LEAVE_NOAPI(0);
1122
} /* H5P_free_prop_cb() */
1125
/*--------------------------------------------------------------------------
1127
H5P_free_del_name_cb
1129
Internal routine to free 'deleted' property name
1131
herr_t H5P_free_del_name_cb(item, key, op_data)
1132
void *item; IN/OUT: Pointer to deleted name
1133
void *key; IN/OUT: Pointer to key
1134
void *op_data; IN: Operator callback data (unused)
1136
Returns zero on success, negative on failure.
1138
Frees the deleted property name
1140
COMMENTS, BUGS, ASSUMPTIONS
1143
--------------------------------------------------------------------------*/
1145
H5P_free_del_name_cb(void *item, void UNUSED *key, void UNUSED *op_data)
1147
char *del_name=(char *)item; /* Temporary pointer to deleted name */
1149
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_del_name_cb);
1154
H5MM_xfree(del_name);
1156
FUNC_LEAVE_NOAPI(0);
1157
} /* H5P_free_del_name_cb() */
1160
/*--------------------------------------------------------------------------
1164
Internal routine to increment or decrement list & class dependancies on a
1167
herr_t H5P_access_class(pclass,mod)
1168
H5P_genclass_t *pclass; IN: Pointer to class to modify
1169
H5P_class_mod_t mod; IN: Type of modification to class
1171
Returns non-negative on success, negative on failure.
1173
Increment/Decrement the class or list dependancies for a given class.
1174
This routine is the final arbiter on decisions about actually releasing a
1175
class in memory, such action is only taken when the reference counts for
1176
both dependent classes & lists reach zero.
1178
COMMENTS, BUGS, ASSUMPTIONS
1181
--------------------------------------------------------------------------*/
1183
H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
1185
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_access_class);
1188
assert(mod>H5P_MOD_ERR && mod<H5P_MOD_MAX);
1191
case H5P_MOD_INC_CLS: /* Increment the dependant class count*/
1195
case H5P_MOD_DEC_CLS: /* Decrement the dependant class count*/
1199
case H5P_MOD_INC_LST: /* Increment the dependant list count*/
1203
case H5P_MOD_DEC_LST: /* Decrement the dependant list count*/
1207
case H5P_MOD_INC_REF: /* Increment the ID reference count*/
1208
/* Reset the deleted flag if incrementing the reference count */
1211
pclass->ref_count++;
1214
case H5P_MOD_DEC_REF: /* Decrement the ID reference count*/
1215
pclass->ref_count--;
1217
/* Mark the class object as deleted if reference count drops to zero */
1218
if(pclass->ref_count==0)
1224
assert(0 && "Invalid H5P class modification");
1227
/* Check if we can release the class information now */
1228
if(pclass->deleted && pclass->plists==0 && pclass->classes==0 ) {
1229
H5P_genclass_t *par_class=pclass->parent; /* Pointer to class's parent */
1231
assert(pclass->name);
1232
H5MM_xfree(pclass->name);
1234
/* Free the class properties without making callbacks */
1238
H5SL_destroy(pclass->props,H5P_free_prop_cb,&make_cb);
1241
H5FL_FREE(H5P_genclass_t,pclass);
1243
/* Reduce the number of dependent classes on parent class also */
1245
H5P_access_class(par_class, H5P_MOD_DEC_CLS);
1248
FUNC_LEAVE_NOAPI(SUCCEED);
1249
} /* H5P_access_class() */
1252
/*--------------------------------------------------------------------------
1256
Internal callback routine to check for duplicated names in parent class.
1258
int H5P_check_class(obj, id, key)
1259
H5P_genclass_t *obj; IN: Pointer to class
1260
hid_t id; IN: ID of object being looked at
1261
const void *key; IN: Pointer to information used to compare
1264
Returns >0 on match, 0 on no match and <0 on failure.
1266
Checks whether a property list class has the same parent and name as a
1267
new class being created. This is a callback routine for H5I_search()
1269
COMMENTS, BUGS, ASSUMPTIONS
1272
--------------------------------------------------------------------------*/
1274
H5P_check_class(void *_obj, hid_t UNUSED id, void *_key)
1276
H5P_genclass_t *obj=(H5P_genclass_t *)_obj; /* Pointer to the class for this ID */
1277
const H5P_check_class_t *key=(const H5P_check_class_t *)_key; /* Pointer to key information for comparison */
1278
int ret_value=0; /* Return value */
1280
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_check_class);
1283
assert(H5I_GENPROP_CLS==H5I_get_type(id));
1286
/* Check if the class object has the same parent as the new class */
1287
if(obj->parent==key->parent) {
1288
/* Check if they have the same name */
1289
if(HDstrcmp(obj->name,key->name)==0)
1290
ret_value=1; /* Indicate a match */
1293
FUNC_LEAVE_NOAPI(ret_value);
1294
} /* end H5P_check_class() */
1297
/*--------------------------------------------------------------------------
1301
Internal routine to create a new property list class.
1303
H5P_genclass_t H5P_create_class(par_class, name, internal,
1304
cls_create, create_data, cls_close, close_data)
1305
H5P_genclass_t *par_class; IN: Pointer to parent class
1306
const char *name; IN: Name of class we are creating
1307
unsigned internal; IN: Whether this is an internal class or not
1308
H5P_cls_create_func_t; IN: The callback function to call when each
1309
property list in this class is created.
1310
void *create_data; IN: Pointer to user data to pass along to class
1312
H5P_cls_copy_func_t; IN: The callback function to call when each
1313
property list in this class is copied.
1314
void *copy_data; IN: Pointer to user data to pass along to class
1316
H5P_cls_close_func_t; IN: The callback function to call when each
1317
property list in this class is closed.
1318
void *close_data; IN: Pointer to user data to pass along to class
1321
Returns a pointer to the newly created property list class on success,
1324
Allocates memory and attaches a class to the property list class hierarchy.
1326
COMMENTS, BUGS, ASSUMPTIONS
1329
--------------------------------------------------------------------------*/
1330
static H5P_genclass_t *
1331
H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned internal,
1332
H5P_cls_create_func_t cls_create, void *create_data,
1333
H5P_cls_copy_func_t cls_copy, void *copy_data,
1334
H5P_cls_close_func_t cls_close, void *close_data
1337
H5P_genclass_t *pclass=NULL; /* Property list class created */
1338
H5P_genclass_t *ret_value; /* return value */
1340
FUNC_ENTER_NOAPI_NOINIT(H5P_create_class);
1343
/* Allow internal classes to break some rules */
1344
/* (This allows the root of the tree to be created with this routine -QAK) */
1349
/* Allocate room for the class */
1350
if (NULL==(pclass = H5FL_CALLOC(H5P_genclass_t)))
1351
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed");
1353
/* Set class state */
1354
pclass->parent = par_class;
1355
pclass->name = H5MM_xstrdup(name);
1356
pclass->nprops = 0; /* Classes are created without properties initially */
1357
pclass->plists = 0; /* No properties lists of this class yet */
1358
pclass->classes = 0; /* No classes derived from this class yet */
1359
pclass->ref_count = 1; /* This is the first reference to the new class */
1360
pclass->internal = internal;
1361
pclass->deleted = 0; /* Not deleted yet... :-) */
1362
pclass->revision = H5P_GET_NEXT_REV; /* Get a revision number for the class */
1364
/* Create the skip list for properties */
1365
if((pclass->props=H5SL_create(H5SL_TYPE_STR,0.5,H5P_DEFAULT_SKIPLIST_HEIGHT))==NULL)
1366
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for properties");
1368
/* Set callback functions and pass-along data */
1369
pclass->create_func = cls_create;
1370
pclass->create_data = create_data;
1371
pclass->copy_func = cls_copy;
1372
pclass->copy_data = copy_data;
1373
pclass->close_func = cls_close;
1374
pclass->close_data = close_data;
1376
/* Increment parent class's derived class value */
1377
if(par_class!=NULL) {
1378
if(H5P_access_class(par_class,H5P_MOD_INC_CLS)<0)
1379
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment parent class ref count");
1382
/* Set return value */
1386
/* Free any resources allocated */
1387
if(ret_value==NULL) {
1389
H5FL_FREE(H5P_genclass_t,pclass);
1392
FUNC_LEAVE_NOAPI(ret_value);
1393
} /* H5P_create_class() */
1396
/*--------------------------------------------------------------------------
1400
Create a new property list class.
1402
hid_t H5Pcreate_class(parent, name, cls_create, create_data,
1403
cls_close, close_data)
1404
hid_t parent; IN: Property list class ID of parent class
1405
const char *name; IN: Name of class we are creating
1406
H5P_cls_create_func_t cls_create; IN: The callback function to call
1407
when each property list in this class is
1409
void *create_data; IN: Pointer to user data to pass along to class
1411
H5P_cls_copy_func_t cls_copy; IN: The callback function to call
1412
when each property list in this class is
1414
void *copy_data; IN: Pointer to user data to pass along to class
1416
H5P_cls_close_func_t cls_close; IN: The callback function to call
1417
when each property list in this class is
1419
void *close_data; IN: Pointer to user data to pass along to class
1422
Returns a valid property list class ID on success, NULL on failure.
1424
Allocates memory and attaches a class to the property list class hierarchy.
1426
COMMENTS, BUGS, ASSUMPTIONS
1429
--------------------------------------------------------------------------*/
1431
H5Pcreate_class(hid_t parent, const char *name,
1432
H5P_cls_create_func_t cls_create, void *create_data,
1433
H5P_cls_copy_func_t cls_copy, void *copy_data,
1434
H5P_cls_close_func_t cls_close, void *close_data
1437
H5P_genclass_t *par_class = NULL; /* Pointer to the parent class */
1438
H5P_genclass_t *pclass = NULL; /* Property list class created */
1439
hid_t ret_value; /* Return value */
1441
FUNC_ENTER_API(H5Pcreate_class, FAIL);
1442
H5TRACE8("i","isxxxxxx",parent,name,cls_create,create_data,cls_copy,
1443
copy_data,cls_close,close_data);
1445
/* Check arguments. */
1446
if (H5P_DEFAULT!=parent && (H5I_GENPROP_CLS!=H5I_get_type(parent)))
1447
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
1448
if (!name || !*name)
1449
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name");
1450
if ((create_data!=NULL && cls_create==NULL)
1451
|| (copy_data!=NULL && cls_copy==NULL)
1452
|| (close_data!=NULL && cls_close==NULL))
1453
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data specified, but no callback provided");
1455
/* Get the pointer to the parent class */
1456
if(parent==H5P_DEFAULT)
1458
else if (NULL == (par_class = H5I_object(parent)))
1459
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't retrieve parent class");
1461
/* Create the new property list class */
1462
if (NULL==(pclass=H5P_create_class(par_class, name, 0, cls_create, create_data, cls_copy, copy_data, cls_close, close_data)))
1463
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list class");
1465
/* Get an atom for the class */
1466
if ((ret_value = H5I_register(H5I_GENPROP_CLS, pclass))<0)
1467
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
1470
if (ret_value<0 && pclass)
1471
H5P_close_class(pclass);
1473
FUNC_LEAVE_API(ret_value);
1474
} /* H5Pcreate_class() */
1477
/*--------------------------------------------------------------------------
1481
Internal routine to create a new property list of a property list class.
1483
H5P_genplist_t *H5P_create(class)
1484
H5P_genclass_t *class; IN: Property list class create list from
1486
Returns a pointer to the newly created property list on success,
1489
Creates a property list of a given class. If a 'create' callback
1490
exists for the property list class, it is called before the
1491
property list is passed back to the user.
1494
COMMENTS, BUGS, ASSUMPTIONS
1495
If this routine is called from a library routine other than
1496
H5P_c, the calling routine is responsible for getting an ID for
1497
the property list and calling the class 'create' callback (if one exists)
1498
and also setting the "class_init" flag.
1501
--------------------------------------------------------------------------*/
1502
static H5P_genplist_t *
1503
H5P_create(H5P_genclass_t *pclass)
1505
H5P_genclass_t *tclass; /* Temporary class pointer */
1506
H5P_genplist_t *plist=NULL; /* New property list created */
1507
H5P_genprop_t *tmp; /* Temporary pointer to parent class properties */
1508
H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */
1509
H5P_genplist_t *ret_value; /* Return value */
1511
FUNC_ENTER_NOAPI_NOINIT(H5P_create);
1516
* Create new property list object
1519
/* Allocate room for the property list */
1520
if (NULL==(plist = H5FL_CALLOC(H5P_genplist_t)))
1521
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed");
1523
/* Set class state */
1524
plist->pclass = pclass;
1525
plist->nprops = 0; /* Initially the plist has the same number of properties as the class */
1526
plist->class_init = 0; /* Initially, wait until the class callback finishes to set */
1528
/* Create the skip list for changed properties */
1529
if((plist->props=H5SL_create(H5SL_TYPE_STR,0.5,H5P_DEFAULT_SKIPLIST_HEIGHT))==NULL)
1530
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for changed properties");
1532
/* Create the skip list for deleted properties */
1533
if((plist->del=H5SL_create(H5SL_TYPE_STR,0.5,H5P_DEFAULT_SKIPLIST_HEIGHT))==NULL)
1534
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for deleted properties");
1536
/* Create the skip list to hold names of properties already seen
1537
* (This prevents a property in the class hierarchy from having it's
1538
* 'create' callback called, if a property in the class hierarchy has
1539
* already been seen)
1541
if((seen=H5SL_create(H5SL_TYPE_STR,0.5,H5P_DEFAULT_SKIPLIST_HEIGHT))==NULL)
1542
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for seen properties");
1545
* Check if we should copy class properties (up through list of parent classes also),
1546
* initialize each with default value & make property 'create' callback.
1549
while(tclass!=NULL) {
1550
if(tclass->nprops>0) {
1551
H5SL_node_t *curr_node; /* Current node in skip list */
1553
/* Walk through the properties in the old class */
1554
curr_node=H5SL_first(tclass->props);
1555
while(curr_node!=NULL) {
1556
/* Get pointer to property from node */
1557
tmp=H5SL_item(curr_node);
1559
/* Only "create" properties we haven't seen before */
1560
if(H5SL_search(seen,tmp->name)==NULL) {
1561
/* Call property creation callback, if it exists */
1563
/* Call the callback & insert changed value into skip list (if necessary) */
1564
if(H5P_do_prop_cb1(plist->props,tmp,tmp->create)<0)
1565
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't create property");
1568
/* Add property name to "seen" list */
1569
if(H5SL_insert(seen,tmp->name,tmp->name)<0)
1570
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen skip list");
1572
/* Increment the number of properties in list */
1576
/* Get the next property node in the skip list */
1577
curr_node=H5SL_next(curr_node);
1581
/* Go up to parent class */
1582
tclass=tclass->parent;
1585
/* Increment the number of property lists derived from class */
1586
if(H5P_access_class(plist->pclass,H5P_MOD_INC_LST)<0)
1587
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment class ref count");
1589
/* Set return value */
1593
/* Release the skip list of 'seen' properties */
1597
/* Release resources allocated on failure */
1598
if(ret_value==NULL) {
1600
/* Close & free any changed properties */
1604
H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb);
1607
/* Close the deleted property skip list */
1609
H5SL_close(plist->del);
1611
/* Release the property list itself */
1612
H5FL_FREE(H5P_genplist_t,plist);
1616
FUNC_LEAVE_NOAPI(ret_value);
1617
} /* H5P_create() */
1620
/*--------------------------------------------------------------------------
1624
Internal routine to create a new property list of a property list class.
1626
hid_t H5P_create_id(pclass)
1627
H5P_genclass_t *pclass; IN: Property list class create list from
1629
Returns a valid property list ID on success, FAIL on failure.
1631
Creates a property list of a given class. If a 'create' callback
1632
exists for the property list class, it is called before the
1633
property list is passed back to the user. If 'create' callbacks exist for
1634
any individual properties in the property list, they are called before the
1635
class 'create' callback.
1638
COMMENTS, BUGS, ASSUMPTIONS
1641
--------------------------------------------------------------------------*/
1643
H5P_create_id(H5P_genclass_t *pclass)
1645
H5P_genplist_t *plist=NULL; /* Property list created */
1646
hid_t plist_id=FAIL; /* Property list ID */
1647
hid_t ret_value; /* return value */
1649
FUNC_ENTER_NOAPI(H5P_create_id, FAIL);
1653
/* Create the new property list */
1654
if ((plist=H5P_create(pclass))==NULL)
1655
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list");
1657
/* Get an atom for the property list */
1658
if ((plist_id = H5I_register(H5I_GENPROP_LST, plist))<0)
1659
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list");
1661
/* Save the property list ID in the property list struct, for use in the property class's 'close' callback */
1662
plist->plist_id=plist_id;
1664
/* Call the class callback (if it exists) now that we have the property list ID */
1665
if(plist->pclass->create_func!=NULL) {
1666
if((plist->pclass->create_func)(plist_id,plist->pclass->create_data)<0) {
1667
/* Delete ID, ignore return value */
1668
H5I_remove(plist_id);
1669
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property");
1673
/* Set the class initialization flag */
1674
plist->class_init=1;
1676
/* Set the return value */
1680
if (ret_value<0 && plist)
1683
FUNC_LEAVE_NOAPI(ret_value);
1684
} /* H5P_create_id() */
1687
/*--------------------------------------------------------------------------
1691
Routine to create a new property list of a property list class.
1693
hid_t H5Pcreate(cls_id)
1694
hid_t cls_id; IN: Property list class create list from
1696
Returns a valid property list ID on success, FAIL on failure.
1698
Creates a property list of a given class. If a 'create' callback
1699
exists for the property list class, it is called before the
1700
property list is passed back to the user. If 'create' callbacks exist for
1701
any individual properties in the property list, they are called before the
1702
class 'create' callback.
1705
COMMENTS, BUGS, ASSUMPTIONS
1708
--------------------------------------------------------------------------*/
1710
H5Pcreate(hid_t cls_id)
1712
H5P_genclass_t *pclass; /* Property list class to modify */
1713
hid_t ret_value; /* return value */
1715
FUNC_ENTER_API(H5Pcreate, FAIL);
1716
H5TRACE1("i","i",cls_id);
1718
/* Check arguments. */
1719
if (NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
1720
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
1722
/* Create the new property list */
1723
if((ret_value=H5P_create_id(pclass))<0)
1724
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list");
1727
FUNC_LEAVE_API(ret_value);
1731
/*--------------------------------------------------------------------------
1735
Internal routine to register a new property in a property list class.
1737
herr_t H5P_register(class, name, size, default, prp_create, prp_set, prp_get, prp_close)
1738
H5P_genclass_t *class; IN: Property list class to close
1739
const char *name; IN: Name of property to register
1740
size_t size; IN: Size of property in bytes
1741
void *def_value; IN: Pointer to buffer containing default value
1742
for property in newly created property lists
1743
H5P_prp_create_func_t prp_create; IN: Function pointer to property
1745
H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
1746
H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
1747
H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
1748
H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
1749
H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback
1750
H5P_prp_close_func_t prp_close; IN: Function pointer to property close
1753
Returns non-negative on success, negative on failure.
1755
Registers a new property with a property list class. The property will
1756
exist in all property list objects of that class after this routine is
1757
finished. The name of the property must not already exist. The default
1758
property value must be provided and all new property lists created with this
1759
property will have the property value set to the default provided. Any of
1760
the callback routines may be set to NULL if they are not needed.
1762
Zero-sized properties are allowed and do not store any data in the
1763
property list. These may be used as flags to indicate the presence or
1764
absence of a particular piece of information. The 'default' pointer for a
1765
zero-sized property may be set to NULL. The property 'create' & 'close'
1766
callbacks are called for zero-sized properties, but the 'set' and 'get'
1767
callbacks are never called.
1769
The 'create' callback is called when a new property list with this
1770
property is being created. H5P_prp_create_func_t is defined as:
1771
typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name,
1772
size_t size, void *initial_value);
1773
where the parameters to the callback function are:
1774
hid_t prop_id; IN: The ID of the property list being created.
1775
const char *name; IN: The name of the property being modified.
1776
size_t size; IN: The size of the property value
1777
void *initial_value; IN/OUT: The initial value for the property being created.
1778
(The 'default' value passed to H5Pregister)
1779
The 'create' routine may modify the value to be set and those changes will
1780
be stored as the initial value of the property. If the 'create' routine
1781
returns a negative value, the new property value is not copied into the
1782
property and the property list creation routine returns an error value.
1784
The 'set' callback is called before a new value is copied into the
1785
property. H5P_prp_set_func_t is defined as:
1786
typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
1787
size_t size, void *value);
1788
where the parameters to the callback function are:
1789
hid_t prop_id; IN: The ID of the property list being modified.
1790
const char *name; IN: The name of the property being modified.
1791
size_t size; IN: The size of the property value
1792
void *new_value; IN/OUT: The value being set for the property.
1793
The 'set' routine may modify the value to be set and those changes will be
1794
stored as the value of the property. If the 'set' routine returns a
1795
negative value, the new property value is not copied into the property and
1796
the property list set routine returns an error value.
1798
The 'get' callback is called before a value is retrieved from the
1799
property. H5P_prp_get_func_t is defined as:
1800
typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
1801
size_t size, void *value);
1802
where the parameters to the callback function are:
1803
hid_t prop_id; IN: The ID of the property list being queried.
1804
const char *name; IN: The name of the property being queried.
1805
size_t size; IN: The size of the property value
1806
void *value; IN/OUT: The value being retrieved for the property.
1807
The 'get' routine may modify the value to be retrieved and those changes
1808
will be returned to the calling function. If the 'get' routine returns a
1809
negative value, the property value is returned and the property list get
1810
routine returns an error value.
1812
The 'delete' callback is called when a property is deleted from a
1813
property list. H5P_prp_del_func_t is defined as:
1814
typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
1815
size_t size, void *value);
1816
where the parameters to the callback function are:
1817
hid_t prop_id; IN: The ID of the property list the property is deleted from.
1818
const char *name; IN: The name of the property being deleted.
1819
size_t size; IN: The size of the property value
1820
void *value; IN/OUT: The value of the property being deleted.
1821
The 'delete' routine may modify the value passed in, but the value is not
1822
used by the library when the 'delete' routine returns. If the
1823
'delete' routine returns a negative value, the property list deletion
1824
routine returns an error value but the property is still deleted.
1826
The 'copy' callback is called when a property list with this
1827
property is copied. H5P_prp_copy_func_t is defined as:
1828
typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
1830
where the parameters to the callback function are:
1831
const char *name; IN: The name of the property being copied.
1832
size_t size; IN: The size of the property value
1833
void *value; IN: The value of the property being copied.
1834
The 'copy' routine may modify the value to be copied and those changes will be
1835
stored as the value of the property. If the 'copy' routine returns a
1836
negative value, the new property value is not copied into the property and
1837
the property list copy routine returns an error value.
1839
The 'compare' callback is called when a property list with this
1840
property is compared to another property list. H5P_prp_compare_func_t is
1842
typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
1844
where the parameters to the callback function are:
1845
const void *value1; IN: The value of the first property being compared.
1846
const void *value2; IN: The value of the second property being compared.
1847
size_t size; IN: The size of the property value
1848
The 'compare' routine may not modify the values to be compared. The
1849
'compare' routine should return a positive value if VALUE1 is greater than
1850
VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1
1851
and VALUE2 are equal.
1853
The 'close' callback is called when a property list with this
1854
property is being destroyed. H5P_prp_close_func_t is defined as:
1855
typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
1857
where the parameters to the callback function are:
1858
const char *name; IN: The name of the property being closed.
1859
size_t size; IN: The size of the property value
1860
void *value; IN: The value of the property being closed.
1861
The 'close' routine may modify the value passed in, but the value is not
1862
used by the library when the 'close' routine returns. If the
1863
'close' routine returns a negative value, the property list close
1864
routine returns an error value but the property list is still closed.
1867
COMMENTS, BUGS, ASSUMPTIONS
1868
The 'set' callback function may be useful to range check the value being
1869
set for the property or may perform some tranformation/translation of the
1870
value set. The 'get' callback would then [probably] reverse the
1871
transformation, etc. A single 'get' or 'set' callback could handle
1872
multiple properties by performing different actions based on the property
1873
name or other properties in the property list.
1875
I would like to say "the property list is not closed" when a 'close'
1876
routine fails, but I don't think that's possible due to other properties in
1877
the list being successfully closed & removed from the property list. I
1878
suppose that it would be possible to just remove the properties which have
1879
successful 'close' callbacks, but I'm not happy with the ramifications
1880
of a mangled, un-closable property list hanging around... Any comments? -QAK
1884
--------------------------------------------------------------------------*/
1886
H5P_register(H5P_genclass_t *pclass, const char *name, size_t size,
1887
void *def_value, H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set,
1888
H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete,
1889
H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp,
1890
H5P_prp_close_func_t prp_close)
1892
H5P_genclass_t *new_class; /* New class pointer */
1893
H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */
1894
H5P_genprop_t *pcopy; /* Property copy */
1895
herr_t ret_value=SUCCEED; /* Return value */
1897
FUNC_ENTER_NOAPI(H5P_register, FAIL);
1901
assert((size>0 && def_value!=NULL) || (size==0));
1903
/* Check for duplicate named properties */
1904
if(H5SL_search(pclass->props,name)!=NULL)
1905
HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists");
1907
/* Check if class needs to be split because property lists or classes have
1908
* been created since the last modification was made to the class.
1910
if(pclass->plists>0 || pclass->classes>0) {
1911
if((new_class=H5P_create_class(pclass->parent,pclass->name,
1912
pclass->internal,pclass->create_func,pclass->create_data,
1913
pclass->copy_func,pclass->copy_data,
1914
pclass->close_func,pclass->close_data))==NULL)
1915
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy class");
1917
/* Walk through the skip list of the old class and copy properties */
1918
if(pclass->nprops>0) {
1919
H5SL_node_t *curr_node; /* Current node in skip list */
1921
/* Walk through the properties in the old class */
1922
curr_node=H5SL_first(pclass->props);
1923
while(curr_node!=NULL) {
1924
/* Make a copy of the class's property */
1925
if((pcopy=H5P_dup_prop(H5SL_item(curr_node),H5P_PROP_WITHIN_CLASS))==NULL)
1926
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
1928
/* Insert the initialized property into the property list */
1929
if(H5P_add_prop(new_class->props,pcopy)<0)
1930
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class");
1932
/* Increment property count for class */
1933
new_class->nprops++;
1935
/* Get the next property node in the skip list */
1936
curr_node=H5SL_next(curr_node);
1940
/* Use the new class instead of the old one */
1944
/* Create property object from parameters */
1945
if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_CLASS,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close))==NULL)
1946
HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property");
1948
/* Insert property into property list class */
1949
if(H5P_add_prop(pclass->props,new_prop)<0)
1950
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class");
1952
/* Increment property count for class */
1955
/* Update the revision for the class */
1956
pclass->revision = H5P_GET_NEXT_REV;
1959
if(ret_value==FAIL) {
1960
if(new_prop!=NULL) {
1961
if(new_prop->name!=NULL)
1962
H5MM_xfree(new_prop->name);
1963
if(new_prop->value!=NULL)
1964
H5MM_xfree(new_prop->value);
1965
H5FL_FREE(H5P_genprop_t,new_prop);
1968
FUNC_LEAVE_NOAPI(ret_value);
1969
} /* H5P_register() */
1972
/*--------------------------------------------------------------------------
1976
Routine to register a new property in a property list class.
1978
herr_t H5Pregister(class, name, size, default, prp_create, prp_set, prp_get, prp_close)
1979
hid_t class; IN: Property list class to close
1980
const char *name; IN: Name of property to register
1981
size_t size; IN: Size of property in bytes
1982
void *def_value; IN: Pointer to buffer containing default value
1983
for property in newly created property lists
1984
H5P_prp_create_func_t prp_create; IN: Function pointer to property
1986
H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
1987
H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
1988
H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
1989
H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
1990
H5P_prp_close_func_t prp_close; IN: Function pointer to property close
1993
Returns non-negative on success, negative on failure.
1995
Registers a new property with a property list class. The property will
1996
exist in all property list objects of that class after this routine is
1997
finished. The name of the property must not already exist. The default
1998
property value must be provided and all new property lists created with this
1999
property will have the property value set to the default provided. Any of
2000
the callback routines may be set to NULL if they are not needed.
2002
Zero-sized properties are allowed and do not store any data in the
2003
property list. These may be used as flags to indicate the presence or
2004
absence of a particular piece of information. The 'default' pointer for a
2005
zero-sized property may be set to NULL. The property 'create' & 'close'
2006
callbacks are called for zero-sized properties, but the 'set' and 'get'
2007
callbacks are never called.
2009
The 'create' callback is called when a new property list with this
2010
property is being created. H5P_prp_create_func_t is defined as:
2011
typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name,
2012
size_t size, void *initial_value);
2013
where the parameters to the callback function are:
2014
hid_t prop_id; IN: The ID of the property list being created.
2015
const char *name; IN: The name of the property being modified.
2016
size_t size; IN: The size of the property value
2017
void *initial_value; IN/OUT: The initial value for the property being created.
2018
(The 'default' value passed to H5Pregister)
2019
The 'create' routine may modify the value to be set and those changes will
2020
be stored as the initial value of the property. If the 'create' routine
2021
returns a negative value, the new property value is not copied into the
2022
property and the property list creation routine returns an error value.
2024
The 'set' callback is called before a new value is copied into the
2025
property. H5P_prp_set_func_t is defined as:
2026
typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
2027
size_t size, void *value);
2028
where the parameters to the callback function are:
2029
hid_t prop_id; IN: The ID of the property list being modified.
2030
const char *name; IN: The name of the property being modified.
2031
size_t size; IN: The size of the property value
2032
void *new_value; IN/OUT: The value being set for the property.
2033
The 'set' routine may modify the value to be set and those changes will be
2034
stored as the value of the property. If the 'set' routine returns a
2035
negative value, the new property value is not copied into the property and
2036
the property list set routine returns an error value.
2038
The 'get' callback is called before a value is retrieved from the
2039
property. H5P_prp_get_func_t is defined as:
2040
typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
2041
size_t size, void *value);
2042
where the parameters to the callback function are:
2043
hid_t prop_id; IN: The ID of the property list being queried.
2044
const char *name; IN: The name of the property being queried.
2045
size_t size; IN: The size of the property value
2046
void *value; IN/OUT: The value being retrieved for the property.
2047
The 'get' routine may modify the value to be retrieved and those changes
2048
will be returned to the calling function. If the 'get' routine returns a
2049
negative value, the property value is returned and the property list get
2050
routine returns an error value.
2052
The 'delete' callback is called when a property is deleted from a
2053
property list. H5P_prp_del_func_t is defined as:
2054
typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
2055
size_t size, void *value);
2056
where the parameters to the callback function are:
2057
hid_t prop_id; IN: The ID of the property list the property is deleted from.
2058
const char *name; IN: The name of the property being deleted.
2059
size_t size; IN: The size of the property value
2060
void *value; IN/OUT: The value of the property being deleted.
2061
The 'delete' routine may modify the value passed in, but the value is not
2062
used by the library when the 'delete' routine returns. If the
2063
'delete' routine returns a negative value, the property list deletion
2064
routine returns an error value but the property is still deleted.
2066
The 'copy' callback is called when a property list with this
2067
property is copied. H5P_prp_copy_func_t is defined as:
2068
typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
2070
where the parameters to the callback function are:
2071
const char *name; IN: The name of the property being copied.
2072
size_t size; IN: The size of the property value
2073
void *value; IN: The value of the property being copied.
2074
The 'copy' routine may modify the value to be copied and those changes will be
2075
stored as the value of the property. If the 'copy' routine returns a
2076
negative value, the new property value is not copied into the property and
2077
the property list copy routine returns an error value.
2079
The 'close' callback is called when a property list with this
2080
property is being destroyed. H5P_prp_close_func_t is defined as:
2081
typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
2083
where the parameters to the callback function are:
2084
const char *name; IN: The name of the property being closed.
2085
size_t size; IN: The size of the property value
2086
void *value; IN: The value of the property being closed.
2087
The 'close' routine may modify the value passed in, but the value is not
2088
used by the library when the 'close' routine returns. If the
2089
'close' routine returns a negative value, the property list close
2090
routine returns an error value but the property list is still closed.
2093
COMMENTS, BUGS, ASSUMPTIONS
2094
The 'set' callback function may be useful to range check the value being
2095
set for the property or may perform some tranformation/translation of the
2096
value set. The 'get' callback would then [probably] reverse the
2097
transformation, etc. A single 'get' or 'set' callback could handle
2098
multiple properties by performing different actions based on the property
2099
name or other properties in the property list.
2101
I would like to say "the property list is not closed" when a 'close'
2102
routine fails, but I don't think that's possible due to other properties in
2103
the list being successfully closed & removed from the property list. I
2104
suppose that it would be possible to just remove the properties which have
2105
successful 'close' callbacks, but I'm not happy with the ramifications
2106
of a mangled, un-closable property list hanging around... Any comments? -QAK
2110
--------------------------------------------------------------------------*/
2112
H5Pregister(hid_t cls_id, const char *name, size_t size, void *def_value,
2113
H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set,
2114
H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete,
2115
H5P_prp_copy_func_t prp_copy, H5P_prp_close_func_t prp_close)
2117
H5P_genclass_t *pclass; /* Property list class to modify */
2118
herr_t ret_value; /* return value */
2120
FUNC_ENTER_API(H5Pregister, FAIL);
2121
H5TRACE10("e","iszxxxxxxx",cls_id,name,size,def_value,prp_create,prp_set,
2122
prp_get,prp_delete,prp_copy,prp_close);
2124
/* Check arguments. */
2125
if (NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
2126
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
2127
if (!name || !*name)
2128
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name");
2129
if (size>0 && def_value==NULL)
2130
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default");
2132
/* Create the new property list class */
2133
if ((ret_value=H5P_register(pclass,name,size,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,NULL,prp_close))<0)
2134
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class");
2137
FUNC_LEAVE_API(ret_value);
2138
} /* H5Pregister() */
2141
/*--------------------------------------------------------------------------
2145
Internal routine to insert a new property in a property list.
2147
herr_t H5P_insert(plist, name, size, value, prp_set, prp_get, prp_close)
2148
H5P_genplist_t *plist; IN: Property list to add property to
2149
const char *name; IN: Name of property to add
2150
size_t size; IN: Size of property in bytes
2151
void *value; IN: Pointer to the value for the property
2152
H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
2153
H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
2154
H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
2155
H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
2156
H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback
2157
H5P_prp_close_func_t prp_close; IN: Function pointer to property close
2160
Returns non-negative on success, negative on failure.
2162
Inserts a temporary property into a property list. The property will
2163
exist only in this property list object. The name of the property must not
2164
already exist. The value must be provided unless the property is zero-
2165
sized. Any of the callback routines may be set to NULL if they are not
2168
Zero-sized properties are allowed and do not store any data in the
2169
property list. These may be used as flags to indicate the presence or
2170
absence of a particular piece of information. The 'value' pointer for a
2171
zero-sized property may be set to NULL. The property 'close' callback is
2172
called for zero-sized properties, but the 'set' and 'get' callbacks are
2175
The 'set' callback is called before a new value is copied into the
2176
property. H5P_prp_set_func_t is defined as:
2177
typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
2178
size_t size, void *value);
2179
where the parameters to the callback function are:
2180
hid_t prop_id; IN: The ID of the property list being modified.
2181
const char *name; IN: The name of the property being modified.
2182
size_t size; IN: The size of the property value
2183
void *new_value; IN/OUT: The value being set for the property.
2184
The 'set' routine may modify the value to be set and those changes will be
2185
stored as the value of the property. If the 'set' routine returns a
2186
negative value, the new property value is not copied into the property and
2187
the property list set routine returns an error value.
2189
The 'get' callback is called before a value is retrieved from the
2190
property. H5P_prp_get_func_t is defined as:
2191
typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
2192
size_t size, void *value);
2193
where the parameters to the callback function are:
2194
hid_t prop_id; IN: The ID of the property list being queried.
2195
const char *name; IN: The name of the property being queried.
2196
size_t size; IN: The size of the property value
2197
void *value; IN/OUT: The value being retrieved for the property.
2198
The 'get' routine may modify the value to be retrieved and those changes
2199
will be returned to the calling function. If the 'get' routine returns a
2200
negative value, the property value is returned and the property list get
2201
routine returns an error value.
2203
The 'delete' callback is called when a property is deleted from a
2204
property list. H5P_prp_del_func_t is defined as:
2205
typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
2206
size_t size, void *value);
2207
where the parameters to the callback function are:
2208
hid_t prop_id; IN: The ID of the property list the property is deleted from.
2209
const char *name; IN: The name of the property being deleted.
2210
size_t size; IN: The size of the property value
2211
void *value; IN/OUT: The value of the property being deleted.
2212
The 'delete' routine may modify the value passed in, but the value is not
2213
used by the library when the 'delete' routine returns. If the
2214
'delete' routine returns a negative value, the property list deletion
2215
routine returns an error value but the property is still deleted.
2217
The 'copy' callback is called when a property list with this
2218
property is copied. H5P_prp_copy_func_t is defined as:
2219
typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
2221
where the parameters to the callback function are:
2222
const char *name; IN: The name of the property being copied.
2223
size_t size; IN: The size of the property value
2224
void *value; IN: The value of the property being copied.
2225
The 'copy' routine may modify the value to be copied and those changes will be
2226
stored as the value of the property. If the 'copy' routine returns a
2227
negative value, the new property value is not copied into the property and
2228
the property list copy routine returns an error value.
2230
The 'compare' callback is called when a property list with this
2231
property is compared to another property list. H5P_prp_compare_func_t is
2233
typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
2235
where the parameters to the callback function are:
2236
const void *value1; IN: The value of the first property being compared.
2237
const void *value2; IN: The value of the second property being compared.
2238
size_t size; IN: The size of the property value
2239
The 'compare' routine may not modify the values to be compared. The
2240
'compare' routine should return a positive value if VALUE1 is greater than
2241
VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1
2242
and VALUE2 are equal.
2244
The 'close' callback is called when a property list with this
2245
property is being destroyed. H5P_prp_close_func_t is defined as:
2246
typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
2248
where the parameters to the callback function are:
2249
const char *name; IN: The name of the property being closed.
2250
size_t size; IN: The size of the property value
2251
void *value; IN: The value of the property being closed.
2252
The 'close' routine may modify the value passed in, but the value is not
2253
used by the library when the 'close' routine returns. If the
2254
'close' routine returns a negative value, the property list close
2255
routine returns an error value but the property list is still closed.
2258
COMMENTS, BUGS, ASSUMPTIONS
2259
The 'set' callback function may be useful to range check the value being
2260
set for the property or may perform some tranformation/translation of the
2261
value set. The 'get' callback would then [probably] reverse the
2262
transformation, etc. A single 'get' or 'set' callback could handle
2263
multiple properties by performing different actions based on the property
2264
name or other properties in the property list.
2266
There is no 'create' callback routine for temporary property list
2267
objects, the initial value is assumed to have any necessary setup already
2270
I would like to say "the property list is not closed" when a 'close'
2271
routine fails, but I don't think that's possible due to other properties in
2272
the list being successfully closed & removed from the property list. I
2273
suppose that it would be possible to just remove the properties which have
2274
successful 'close' callbacks, but I'm not happy with the ramifications
2275
of a mangled, un-closable property list hanging around... Any comments? -QAK
2279
--------------------------------------------------------------------------*/
2281
H5P_insert(H5P_genplist_t *plist, const char *name, size_t size,
2282
void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
2283
H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
2284
H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close)
2286
H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */
2287
herr_t ret_value=SUCCEED; /* Return value */
2289
FUNC_ENTER_NOAPI_NOINIT(H5P_insert);
2293
assert((size>0 && value!=NULL) || (size==0));
2295
/* Check for duplicate named properties */
2296
if(H5SL_search(plist->props,name)!=NULL)
2297
HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists");
2299
/* Check if the property has been deleted */
2300
if(H5SL_search(plist->del,name)!=NULL) {
2301
/* Remove the property name from the deleted property skip list */
2302
if(H5SL_remove(plist->del,name)==NULL)
2303
HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from deleted skip list");
2305
/* Fall through to add property to list */
2308
H5P_genclass_t *tclass; /* Temporary class pointer */
2310
/* Check if the property is already in the class hierarchy */
2311
tclass=plist->pclass;
2312
while(tclass!=NULL) {
2313
if(tclass->nprops>0) {
2314
/* Find the property in the class */
2315
if(H5SL_search(tclass->props,name)!=NULL)
2316
HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists");
2319
/* Go up to parent class */
2320
tclass=tclass->parent;
2323
/* Fall through to add property to list */
2326
/* Ok to add to property list */
2328
/* Create property object from parameters */
2329
if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_LIST,value,NULL,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close))==NULL)
2330
HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property");
2332
/* Insert property into property list class */
2333
if(H5P_add_prop(plist->props,new_prop)<0)
2334
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class");
2336
/* Increment property count for class */
2340
if(ret_value==FAIL) {
2341
if(new_prop!=NULL) {
2342
if(new_prop->name!=NULL)
2343
H5MM_xfree(new_prop->name);
2344
if(new_prop->value!=NULL)
2345
H5MM_xfree(new_prop->value);
2346
H5FL_FREE(H5P_genprop_t,new_prop);
2350
FUNC_LEAVE_NOAPI(ret_value);
2351
} /* H5P_insert() */
2354
/*--------------------------------------------------------------------------
2358
Routine to insert a new property in a property list.
2360
herr_t H5Pinsert(plist, name, size, value, prp_set, prp_get, prp_close)
2361
hid_t plist; IN: Property list to add property to
2362
const char *name; IN: Name of property to add
2363
size_t size; IN: Size of property in bytes
2364
void *value; IN: Pointer to the value for the property
2365
H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
2366
H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
2367
H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
2368
H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
2369
H5P_prp_close_func_t prp_close; IN: Function pointer to property close
2372
Returns non-negative on success, negative on failure.
2374
Inserts a temporary property into a property list. The property will
2375
exist only in this property list object. The name of the property must not
2376
already exist. The value must be provided unless the property is zero-
2377
sized. Any of the callback routines may be set to NULL if they are not
2380
Zero-sized properties are allowed and do not store any data in the
2381
property list. These may be used as flags to indicate the presence or
2382
absence of a particular piece of information. The 'value' pointer for a
2383
zero-sized property may be set to NULL. The property 'close' callback is
2384
called for zero-sized properties, but the 'set' and 'get' callbacks are
2387
The 'set' callback is called before a new value is copied into the
2388
property. H5P_prp_set_func_t is defined as:
2389
typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
2390
size_t size, void *value);
2391
where the parameters to the callback function are:
2392
hid_t prop_id; IN: The ID of the property list being modified.
2393
const char *name; IN: The name of the property being modified.
2394
size_t size; IN: The size of the property value
2395
void *new_value; IN/OUT: The value being set for the property.
2396
The 'set' routine may modify the value to be set and those changes will be
2397
stored as the value of the property. If the 'set' routine returns a
2398
negative value, the new property value is not copied into the property and
2399
the property list set routine returns an error value.
2401
The 'get' callback is called before a value is retrieved from the
2402
property. H5P_prp_get_func_t is defined as:
2403
typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
2404
size_t size, void *value);
2405
where the parameters to the callback function are:
2406
hid_t prop_id; IN: The ID of the property list being queried.
2407
const char *name; IN: The name of the property being queried.
2408
size_t size; IN: The size of the property value
2409
void *value; IN/OUT: The value being retrieved for the property.
2410
The 'get' routine may modify the value to be retrieved and those changes
2411
will be returned to the calling function. If the 'get' routine returns a
2412
negative value, the property value is returned and the property list get
2413
routine returns an error value.
2415
The 'delete' callback is called when a property is deleted from a
2416
property list. H5P_prp_del_func_t is defined as:
2417
typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
2418
size_t size, void *value);
2419
where the parameters to the callback function are:
2420
hid_t prop_id; IN: The ID of the property list the property is deleted from.
2421
const char *name; IN: The name of the property being deleted.
2422
size_t size; IN: The size of the property value
2423
void *value; IN/OUT: The value of the property being deleted.
2424
The 'delete' routine may modify the value passed in, but the value is not
2425
used by the library when the 'delete' routine returns. If the
2426
'delete' routine returns a negative value, the property list deletion
2427
routine returns an error value but the property is still deleted.
2429
The 'copy' callback is called when a property list with this
2430
property is copied. H5P_prp_copy_func_t is defined as:
2431
typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
2433
where the parameters to the callback function are:
2434
const char *name; IN: The name of the property being copied.
2435
size_t size; IN: The size of the property value
2436
void *value; IN: The value of the property being copied.
2437
The 'copy' routine may modify the value to be copied and those changes will be
2438
stored as the value of the property. If the 'copy' routine returns a
2439
negative value, the new property value is not copied into the property and
2440
the property list copy routine returns an error value.
2442
The 'close' callback is called when a property list with this
2443
property is being destroyed. H5P_prp_close_func_t is defined as:
2444
typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
2446
where the parameters to the callback function are:
2447
const char *name; IN: The name of the property being closed.
2448
size_t size; IN: The size of the property value
2449
void *value; IN: The value of the property being closed.
2450
The 'close' routine may modify the value passed in, but the value is not
2451
used by the library when the 'close' routine returns. If the
2452
'close' routine returns a negative value, the property list close
2453
routine returns an error value but the property list is still closed.
2456
COMMENTS, BUGS, ASSUMPTIONS
2457
The 'set' callback function may be useful to range check the value being
2458
set for the property or may perform some tranformation/translation of the
2459
value set. The 'get' callback would then [probably] reverse the
2460
transformation, etc. A single 'get' or 'set' callback could handle
2461
multiple properties by performing different actions based on the property
2462
name or other properties in the property list.
2464
There is no 'create' callback routine for temporary property list
2465
objects, the initial value is assumed to have any necessary setup already
2468
I would like to say "the property list is not closed" when a 'close'
2469
routine fails, but I don't think that's possible due to other properties in
2470
the list being successfully closed & removed from the property list. I
2471
suppose that it would be possible to just remove the properties which have
2472
successful 'close' callbacks, but I'm not happy with the ramifications
2473
of a mangled, un-closable property list hanging around... Any comments? -QAK
2477
--------------------------------------------------------------------------*/
2479
H5Pinsert(hid_t plist_id, const char *name, size_t size, void *value,
2480
H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
2481
H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
2482
H5P_prp_close_func_t prp_close)
2484
H5P_genplist_t *plist; /* Property list to modify */
2485
herr_t ret_value; /* return value */
2487
FUNC_ENTER_API(H5Pinsert, FAIL);
2488
H5TRACE9("e","iszxxxxxx",plist_id,name,size,value,prp_set,prp_get,
2489
prp_delete,prp_copy,prp_close);
2491
/* Check arguments. */
2492
if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
2493
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
2494
if (!name || !*name)
2495
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
2496
if (size>0 && value==NULL)
2497
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default");
2499
/* Create the new property list class */
2500
if ((ret_value=H5P_insert(plist,name,size,value,prp_set,prp_get,prp_delete,prp_copy,NULL,prp_close))<0)
2501
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in plist");
2504
FUNC_LEAVE_API(ret_value);
2508
/*--------------------------------------------------------------------------
2512
Internal routine to set a property's value in a property list.
2514
herr_t H5P_set(plist, name, value)
2515
H5P_genplist_t *plist; IN: Property list to find property in
2516
const char *name; IN: Name of property to set
2517
void *value; IN: Pointer to the value for the property
2519
Returns non-negative on success, negative on failure.
2521
Sets a new value for a property in a property list. The property name
2522
must exist or this routine will fail. If there is a 'set' callback routine
2523
registered for this property, the 'value' will be passed to that routine and
2524
any changes to the 'value' will be used when setting the property value.
2525
The information pointed at by the 'value' pointer (possibly modified by the
2526
'set' callback) is copied into the property list value and may be changed
2527
by the application making the H5Pset call without affecting the property
2530
If the 'set' callback routine returns an error, the property value will
2531
not be modified. This routine may not be called for zero-sized properties
2532
and will return an error in that case.
2535
COMMENTS, BUGS, ASSUMPTIONS
2538
--------------------------------------------------------------------------*/
2540
H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
2542
H5P_genclass_t *tclass; /* Temporary class pointer */
2543
H5P_genprop_t *prop; /* Temporary property pointer */
2544
herr_t ret_value=SUCCEED; /* Return value */
2546
FUNC_ENTER_NOAPI(H5P_set, FAIL);
2552
/* Check if the property has been deleted */
2553
if(H5SL_search(plist->del,name)!=NULL)
2554
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
2556
/* Find property in changed list */
2557
if((prop=H5SL_search(plist->props,name))!=NULL) {
2558
/* Check for property size >0 */
2560
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
2562
/* Make a copy of the value and pass to 'set' callback */
2563
if(prop->set!=NULL) {
2564
void *tmp_value; /* Temporary value for property */
2566
/* Make a copy of the current value, in case the callback fails */
2567
if (NULL==(tmp_value=H5MM_malloc(prop->size)))
2568
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
2569
HDmemcpy(tmp_value,value,prop->size);
2571
/* Call user's callback */
2572
if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value)<0) {
2573
H5MM_xfree(tmp_value);
2574
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value");
2577
/* Copy new [possibly unchanged] value into property value */
2578
HDmemcpy(prop->value,tmp_value,prop->size);
2580
/* Free the temporary value buffer */
2581
H5MM_xfree(tmp_value);
2583
/* No 'set' callback, just copy value */
2585
HDmemcpy(prop->value,value,prop->size);
2589
* Check if we should set class properties (up through list of parent classes also),
2590
* & make property 'set' callback.
2592
tclass=plist->pclass;
2593
while(tclass!=NULL) {
2594
if(tclass->nprops>0) {
2595
/* Find the property in the class */
2596
if((prop=H5SL_search(tclass->props,name))!=NULL) {
2597
H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */
2599
/* Check for property size >0 */
2601
HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size");
2603
/* Make a copy of the value and pass to 'set' callback */
2604
if(prop->set!=NULL) {
2605
void *tmp_value; /* Temporary value for property */
2607
/* Make a copy of the current value, in case the callback fails */
2608
if (NULL==(tmp_value=H5MM_malloc(prop->size)))
2609
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
2610
HDmemcpy(tmp_value,value,prop->size);
2612
/* Call user's callback */
2613
if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value)<0) {
2614
H5MM_xfree(tmp_value);
2615
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value");
2618
if(HDmemcmp(tmp_value,prop->value,prop->size)) {
2619
/* Make a copy of the class's property */
2620
if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
2621
HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property");
2623
/* Copy new value into property value */
2624
HDmemcpy(pcopy->value,tmp_value,pcopy->size);
2626
/* Insert the changed property into the property list */
2627
if(H5P_add_prop(plist->props,pcopy)<0)
2628
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list");
2631
/* Free the temporary value buffer */
2632
H5MM_xfree(tmp_value);
2634
/* No 'set' callback, just copy value */
2636
if(HDmemcmp(value,prop->value,prop->size)) {
2637
/* Make a copy of the class's property */
2638
if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
2639
HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property");
2641
HDmemcpy(pcopy->value,value,pcopy->size);
2643
/* Insert the changed property into the property list */
2644
if(H5P_add_prop(plist->props,pcopy)<0)
2645
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list");
2650
HGOTO_DONE(SUCCEED);
2654
/* Go up to parent class */
2655
tclass=tclass->parent;
2658
/* If we get this far, then it wasn't in the list of changed properties,
2659
* nor in the properties in the class hierarchy, indicate an error
2661
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
2665
FUNC_LEAVE_NOAPI(ret_value);
2669
/*--------------------------------------------------------------------------
2673
Routine to set a property's value in a property list.
2675
herr_t H5P_set(plist_id, name, value)
2676
hid_t plist_id; IN: Property list to find property in
2677
const char *name; IN: Name of property to set
2678
void *value; IN: Pointer to the value for the property
2680
Returns non-negative on success, negative on failure.
2682
Sets a new value for a property in a property list. The property name
2683
must exist or this routine will fail. If there is a 'set' callback routine
2684
registered for this property, the 'value' will be passed to that routine and
2685
any changes to the 'value' will be used when setting the property value.
2686
The information pointed at by the 'value' pointer (possibly modified by the
2687
'set' callback) is copied into the property list value and may be changed
2688
by the application making the H5Pset call without affecting the property
2691
If the 'set' callback routine returns an error, the property value will
2692
not be modified. This routine may not be called for zero-sized properties
2693
and will return an error in that case.
2696
COMMENTS, BUGS, ASSUMPTIONS
2699
--------------------------------------------------------------------------*/
2701
H5Pset(hid_t plist_id, const char *name, void *value)
2703
H5P_genplist_t *plist; /* Property list to modify */
2704
herr_t ret_value=SUCCEED; /* return value */
2706
FUNC_ENTER_API(H5Pset, FAIL);
2707
H5TRACE3("e","isx",plist_id,name,value);
2709
/* Check arguments. */
2710
if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
2711
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
2712
if (!name || !*name)
2713
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
2715
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value");
2717
/* Go set the value */
2718
if(H5P_set(plist,name,value)<0)
2719
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to set value in plist");
2722
FUNC_LEAVE_API(ret_value);
2726
/*--------------------------------------------------------------------------
2730
Internal routine to query the existance of a property in a property list.
2732
herr_t H5P_exist_plist(plist, name)
2733
H5P_genplist_t *plist; IN: Property list to check
2734
const char *name; IN: Name of property to check for
2736
Success: Positive if the property exists in the property list, zero
2737
if the property does not exist.
2738
Failure: negative value
2740
This routine checks if a property exists within a property list.
2743
COMMENTS, BUGS, ASSUMPTIONS
2746
--------------------------------------------------------------------------*/
2748
H5P_exist_plist(H5P_genplist_t *plist, const char *name)
2750
htri_t ret_value=FAIL; /* return value */
2752
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_plist);
2757
/* Check for property in deleted property list */
2758
if(H5SL_search(plist->del,name)!=NULL)
2761
/* Check for property in changed property list */
2762
if(H5SL_search(plist->props,name)!=NULL)
2765
H5P_genclass_t *tclass; /* Temporary class pointer */
2767
tclass=plist->pclass;
2768
while(tclass!=NULL) {
2769
if(H5SL_search(tclass->props,name)!=NULL)
2772
/* Go up to parent class */
2773
tclass=tclass->parent;
2776
/* If we've reached here, we couldn't find the property */
2782
FUNC_LEAVE_NOAPI(ret_value);
2783
} /* H5P_exist_plist() */
2786
/*--------------------------------------------------------------------------
2790
Internal routine to query the existance of a property in a property class.
2792
herr_t H5P_exist_pclass(pclass, name)
2793
H5P_genclass_t *pclass; IN: Property class to check
2794
const char *name; IN: Name of property to check for
2796
Success: Positive if the property exists in the property list, zero
2797
if the property does not exist.
2798
Failure: negative value
2800
This routine checks if a property exists within a property list.
2803
COMMENTS, BUGS, ASSUMPTIONS
2806
--------------------------------------------------------------------------*/
2808
H5P_exist_pclass(H5P_genclass_t *pclass, const char *name)
2810
htri_t ret_value=FAIL; /* return value */
2812
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_pclass);
2817
/* Check for property in property list */
2818
if(H5SL_search(pclass->props,name)==NULL)
2823
FUNC_LEAVE_NOAPI(ret_value);
2824
} /* H5P_exist_pclass() */
2827
/*--------------------------------------------------------------------------
2831
Routine to query the existance of a property in a property object.
2833
htri_t H5P_exist(id, name)
2834
hid_t id; IN: Property object ID to check
2835
const char *name; IN: Name of property to check for
2837
Success: Positive if the property exists in the property object, zero
2838
if the property does not exist.
2839
Failure: negative value
2841
This routine checks if a property exists within a property list or
2845
COMMENTS, BUGS, ASSUMPTIONS
2848
--------------------------------------------------------------------------*/
2850
H5Pexist(hid_t id, const char *name)
2852
H5P_genplist_t *plist; /* Property list to query */
2853
H5P_genclass_t *pclass; /* Property class to query */
2854
htri_t ret_value; /* return value */
2856
FUNC_ENTER_API(H5Pexist, FAIL);
2857
H5TRACE2("t","is",id,name);
2859
/* Check arguments. */
2860
if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
2861
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
2862
if (!name || !*name)
2863
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
2865
/* Check for the existance of the property in the list or class */
2866
if(H5I_GENPROP_LST == H5I_get_type(id)) {
2867
if (NULL == (plist = H5I_object(id)))
2868
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
2869
if ((ret_value=H5P_exist_plist(plist,name))<0)
2870
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in list");
2873
if(H5I_GENPROP_CLS == H5I_get_type(id)) {
2874
if (NULL == (pclass = H5I_object(id)))
2875
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
2876
if ((ret_value=H5P_exist_pclass(pclass,name))<0)
2877
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in class");
2880
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
2883
FUNC_LEAVE_API(ret_value);
2887
/*--------------------------------------------------------------------------
2891
Internal routine to query the size of a property in a property list.
2893
herr_t H5P_get_size_plist(plist, name)
2894
H5P_genplist_t *plist; IN: Property list to check
2895
const char *name; IN: Name of property to query
2896
size_t *size; OUT: Size of property
2898
Success: non-negative value
2899
Failure: negative value
2901
This routine retrieves the size of a property's value in bytes. Zero-
2902
sized properties are allowed and return a value of 0.
2905
COMMENTS, BUGS, ASSUMPTIONS
2908
--------------------------------------------------------------------------*/
2910
H5P_get_size_plist(H5P_genplist_t *plist, const char *name, size_t *size)
2912
H5P_genprop_t *prop; /* Temporary property pointer */
2913
herr_t ret_value=SUCCEED; /* return value */
2915
FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_plist);
2922
if((prop=H5P_find_prop_plist(plist,name))==NULL)
2923
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
2925
/* Get property size */
2929
FUNC_LEAVE_NOAPI(ret_value);
2930
} /* H5P_get_size_plist() */
2933
/*--------------------------------------------------------------------------
2937
Internal routine to query the size of a property in a property class.
2939
herr_t H5P_get_size_pclass(pclass, name)
2940
H5P_genclass_t *pclass; IN: Property class to check
2941
const char *name; IN: Name of property to query
2942
size_t *size; OUT: Size of property
2944
Success: non-negative value
2945
Failure: negative value
2947
This routine retrieves the size of a property's value in bytes. Zero-
2948
sized properties are allowed and return a value of 0.
2951
COMMENTS, BUGS, ASSUMPTIONS
2954
--------------------------------------------------------------------------*/
2956
H5P_get_size_pclass(H5P_genclass_t *pclass, const char *name, size_t *size)
2958
H5P_genprop_t *prop; /* Temporary property pointer */
2959
herr_t ret_value=SUCCEED; /* return value */
2961
FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_pclass);
2968
if((prop=H5P_find_prop_pclass(pclass,name))==NULL)
2969
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
2971
/* Get property size */
2975
FUNC_LEAVE_NOAPI(ret_value);
2976
} /* H5P_get_size_pclass() */
2979
/*--------------------------------------------------------------------------
2983
Routine to query the size of a property in a property list or class.
2985
herr_t H5Pget_size(id, name)
2986
hid_t id; IN: ID of property list or class to check
2987
const char *name; IN: Name of property to query
2988
size_t *size; OUT: Size of property
2990
Success: non-negative value
2991
Failure: negative value
2993
This routine retrieves the size of a property's value in bytes. Zero-
2994
sized properties are allowed and return a value of 0. This function works
2995
for both property lists and classes.
2998
COMMENTS, BUGS, ASSUMPTIONS
3001
--------------------------------------------------------------------------*/
3003
H5Pget_size(hid_t id, const char *name, size_t *size)
3005
H5P_genclass_t *pclass; /* Property class to query */
3006
H5P_genplist_t *plist; /* Property list to query */
3007
herr_t ret_value; /* return value */
3009
FUNC_ENTER_API(H5Pget_size, FAIL);
3010
H5TRACE3("e","is*z",id,name,size);
3012
/* Check arguments. */
3013
if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
3014
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
3015
if (!name || !*name)
3016
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
3018
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property size");
3020
if (H5I_GENPROP_LST == H5I_get_type(id)) {
3021
if (NULL == (plist = H5I_object(id)))
3022
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
3024
/* Check the property size */
3025
if ((ret_value=H5P_get_size_plist(plist,name,size))<0)
3026
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query size in plist");
3029
if (H5I_GENPROP_CLS == H5I_get_type(id)) {
3030
if (NULL == (pclass = H5I_object(id)))
3031
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
3033
/* Check the property size */
3034
if ((ret_value=H5P_get_size_pclass(pclass,name,size))<0)
3035
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query size in plist");
3038
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
3041
FUNC_LEAVE_API(ret_value);
3042
} /* H5Pget_size() */
3045
/*--------------------------------------------------------------------------
3049
Internal routine to query the class of a generic property list
3051
H5P_genclass_t *H5P_get_class(plist)
3052
H5P_genplist_t *plist; IN: Property list to check
3054
Success: Pointer to the class for a property list
3057
This routine retrieves a pointer to the class for a property list.
3060
COMMENTS, BUGS, ASSUMPTIONS
3063
--------------------------------------------------------------------------*/
3064
static H5P_genclass_t *
3065
H5P_get_class(H5P_genplist_t *plist)
3067
H5P_genclass_t *ret_value; /* return value */
3069
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class);
3073
/* Get property size */
3074
ret_value=plist->pclass;
3076
FUNC_LEAVE_NOAPI(ret_value);
3077
} /* H5P_get_class() */
3080
/*--------------------------------------------------------------------------
3084
Routine to query the class of a generic property list
3086
hid_t H5Pget_class(plist_id)
3087
hid_t plist_id; IN: Property list to query
3089
Success: ID of class object
3092
This routine retrieves the class of a property list.
3095
COMMENTS, BUGS, ASSUMPTIONS
3096
Change the name of this function to H5Pget_class (and remove old H5Pget_class)
3099
--------------------------------------------------------------------------*/
3101
H5Pget_class(hid_t plist_id)
3103
H5P_genplist_t *plist; /* Property list to query */
3104
H5P_genclass_t *pclass=NULL; /* Property list class */
3105
hid_t ret_value=FAIL; /* return value */
3107
FUNC_ENTER_API(H5Pget_class, FAIL);
3108
H5TRACE1("i","i",plist_id);
3110
/* Check arguments. */
3111
if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
3112
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
3114
/* Retrieve the property list class */
3115
if ((pclass=H5P_get_class(plist))==NULL)
3116
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to query class of property list");
3118
/* Increment the outstanding references to the class object */
3119
if(H5P_access_class(pclass,H5P_MOD_INC_REF)<0)
3120
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count");
3122
/* Get an atom for the class */
3123
if ((ret_value = H5I_register(H5I_GENPROP_CLS, pclass))<0)
3124
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
3127
if (ret_value<0 && pclass)
3128
H5P_close_class(pclass);
3130
FUNC_LEAVE_API(ret_value);
3131
} /* H5Pget_class() */
3134
/*--------------------------------------------------------------------------
3136
H5P_get_nprops_plist
3138
Internal routine to query the number of properties in a property list
3140
herr_t H5P_get_nprops_plist(plist, nprops)
3141
H5P_genplist_t *plist; IN: Property list to check
3142
size_t *nprops; OUT: Number of properties in the property list
3144
Success: non-negative value
3145
Failure: negative value
3147
This routine retrieves the number of a properties in a property list.
3150
COMMENTS, BUGS, ASSUMPTIONS
3153
--------------------------------------------------------------------------*/
3155
H5P_get_nprops_plist(H5P_genplist_t *plist, size_t *nprops)
3157
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_nprops_plist);
3162
/* Get property size */
3163
*nprops=plist->nprops;
3165
FUNC_LEAVE_NOAPI(SUCCEED);
3166
} /* H5P_get_nprops_plist() */
3169
/*--------------------------------------------------------------------------
3171
H5P_get_nprops_pclass
3173
Internal routine to query the number of properties in a property class
3175
herr_t H5P_get_nprops_pclass(pclass, nprops)
3176
H5P_genclass_t *pclass; IN: Property class to check
3177
size_t *nprops; OUT: Number of properties in the property list
3179
Success: non-negative value (can't fail)
3180
Failure: negative value
3182
This routine retrieves the number of a properties in a property class.
3185
COMMENTS, BUGS, ASSUMPTIONS
3188
--------------------------------------------------------------------------*/
3190
H5P_get_nprops_pclass(H5P_genclass_t *pclass, size_t *nprops)
3192
herr_t ret_value = SUCCEED; /* Return value */
3194
FUNC_ENTER_NOAPI(H5P_get_nprops_pclass, FAIL)
3199
/* Get number of properties */
3200
*nprops=pclass->nprops;
3203
FUNC_LEAVE_NOAPI(ret_value)
3204
} /* H5P_get_nprops_pclass() */
3207
/*--------------------------------------------------------------------------
3211
Routine to query the size of a property in a property list or class.
3213
herr_t H5Pget_nprops(id, nprops)
3214
hid_t id; IN: ID of Property list or class to check
3215
size_t *nprops; OUT: Number of properties in the property object
3217
Success: non-negative value
3218
Failure: negative value
3220
This routine retrieves the number of properties in a property list or
3221
class. If a property class ID is given, the number of registered properties
3222
in the class is returned in NPROPS. If a property list ID is given, the
3223
current number of properties in the list is returned in NPROPS.
3226
COMMENTS, BUGS, ASSUMPTIONS
3229
--------------------------------------------------------------------------*/
3231
H5Pget_nprops(hid_t id, size_t *nprops)
3233
H5P_genplist_t *plist; /* Property list to query */
3234
H5P_genclass_t *pclass; /* Property class to query */
3235
herr_t ret_value=SUCCEED; /* return value */
3237
FUNC_ENTER_API(H5Pget_nprops, FAIL);
3238
H5TRACE2("e","i*z",id,nprops);
3240
/* Check arguments. */
3241
if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
3242
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
3244
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property nprops pointer");
3246
if(H5I_GENPROP_LST == H5I_get_type(id)) {
3247
if (NULL == (plist = H5I_object(id)))
3248
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
3249
if (H5P_get_nprops_plist(plist,nprops)<0)
3250
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in plist");
3253
if(H5I_GENPROP_CLS == H5I_get_type(id)) {
3254
if (NULL == (pclass = H5I_object(id)))
3255
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
3256
if (H5P_get_nprops_pclass(pclass,nprops)<0)
3257
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in pclass");
3260
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
3263
FUNC_LEAVE_API(ret_value);
3264
} /* H5Pget_nprops() */
3267
/*--------------------------------------------------------------------------
3271
Internal routine to compare two generic properties
3273
int H5P_cmp_prop(prop1, prop2)
3274
H5P_genprop_t *prop1; IN: 1st property to compare
3275
H5P_genprop_t *prop1; IN: 2nd property to compare
3277
Success: negative if prop1 "less" than prop2, positive if prop1 "greater"
3278
than prop2, zero if prop1 is "equal" to prop2
3281
This function compares two generic properties together to see if
3282
they are the same property.
3285
COMMENTS, BUGS, ASSUMPTIONS
3288
--------------------------------------------------------------------------*/
3290
H5P_cmp_prop(H5P_genprop_t *prop1, H5P_genprop_t *prop2)
3292
int cmp_value; /* Value from comparison */
3293
int ret_value=0; /* return value */
3295
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_prop);
3300
/* Check the name */
3301
if((cmp_value=HDstrcmp(prop1->name,prop2->name))!=0)
3302
HGOTO_DONE(cmp_value);
3304
/* Check the size of properties */
3305
if(prop1->size < prop2->size) HGOTO_DONE(-1);
3306
if(prop1->size > prop2->size) HGOTO_DONE(1);
3308
/* Check if they both have the same 'create' callback */
3309
if(prop1->create==NULL && prop2->create!=NULL) HGOTO_DONE(-1);
3310
if(prop1->create!=NULL && prop2->create==NULL) HGOTO_DONE(1);
3311
if(prop1->create!=prop2->create) HGOTO_DONE(-1);
3313
/* Check if they both have the same 'set' callback */
3314
if(prop1->set==NULL && prop2->set!=NULL) HGOTO_DONE(-1);
3315
if(prop1->set!=NULL && prop2->set==NULL) HGOTO_DONE(1);
3316
if(prop1->set!=prop2->set) HGOTO_DONE(-1);
3318
/* Check if they both have the same 'get' callback */
3319
if(prop1->get==NULL && prop2->get!=NULL) HGOTO_DONE(-1);
3320
if(prop1->get!=NULL && prop2->get==NULL) HGOTO_DONE(1);
3321
if(prop1->get!=prop2->get) HGOTO_DONE(-1);
3323
/* Check if they both have the same 'delete' callback */
3324
if(prop1->del==NULL && prop2->del!=NULL) HGOTO_DONE(-1);
3325
if(prop1->del!=NULL && prop2->del==NULL) HGOTO_DONE(1);
3326
if(prop1->del!=prop2->del) HGOTO_DONE(-1);
3328
/* Check if they both have the same 'copy' callback */
3329
if(prop1->copy==NULL && prop2->copy!=NULL) HGOTO_DONE(-1);
3330
if(prop1->copy!=NULL && prop2->copy==NULL) HGOTO_DONE(1);
3331
if(prop1->copy!=prop2->copy) HGOTO_DONE(-1);
3333
/* Check if they both have the same 'compare' callback */
3334
if(prop1->cmp==NULL && prop2->cmp!=NULL) HGOTO_DONE(-1);
3335
if(prop1->cmp!=NULL && prop2->cmp==NULL) HGOTO_DONE(1);
3336
if(prop1->cmp!=prop2->cmp) HGOTO_DONE(-1);
3338
/* Check if they both have the same 'close' callback */
3339
if(prop1->close==NULL && prop2->close!=NULL) HGOTO_DONE(-1);
3340
if(prop1->close!=NULL && prop2->close==NULL) HGOTO_DONE(1);
3341
if(prop1->close!=prop2->close) HGOTO_DONE(-1);
3343
/* Check if they both have values allocated (or not allocated) */
3344
if(prop1->value==NULL && prop2->value!=NULL) HGOTO_DONE(-1);
3345
if(prop1->value!=NULL && prop2->value==NULL) HGOTO_DONE(1);
3346
if(prop1->value!=NULL) {
3347
/* Call comparison routine */
3348
if((cmp_value=prop1->cmp(prop1->value,prop2->value,prop1->size))!=0)
3349
HGOTO_DONE(cmp_value);
3353
FUNC_LEAVE_NOAPI(ret_value);
3354
} /* H5P_cmp_prop() */
3357
/*--------------------------------------------------------------------------
3361
Internal routine to compare two generic property classes
3363
int H5P_cmp_class(pclass1, pclass2)
3364
H5P_genclass_t *pclass1; IN: 1st property class to compare
3365
H5P_genclass_t *pclass2; IN: 2nd property class to compare
3367
Success: negative if class1 "less" than class2, positive if class1 "greater"
3368
than class2, zero if class1 is "equal" to class2
3371
This function compares two generic property classes together to see if
3372
they are the same class.
3375
COMMENTS, BUGS, ASSUMPTIONS
3378
--------------------------------------------------------------------------*/
3380
H5P_cmp_class(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2)
3382
H5SL_node_t *tnode1,*tnode2; /* Temporary pointer to property nodes */
3383
int cmp_value; /* Value from comparison */
3384
int ret_value=0; /* Return value */
3386
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_class);
3391
/* Use the revision number to quickly check for identical classes */
3392
if(pclass1->revision==pclass2->revision)
3395
/* Check the name */
3396
if((cmp_value=HDstrcmp(pclass1->name,pclass2->name))!=0)
3397
HGOTO_DONE(cmp_value);
3399
/* Check the number of properties */
3400
if(pclass1->nprops < pclass2->nprops) HGOTO_DONE(-1);
3401
if(pclass1->nprops > pclass2->nprops) HGOTO_DONE(1);
3403
/* Check the number of property lists created from the class */
3404
if(pclass1->plists < pclass2->plists) HGOTO_DONE(-1);
3405
if(pclass1->plists > pclass2->plists) HGOTO_DONE(1);
3407
/* Check the number of classes derived from the class */
3408
if(pclass1->classes < pclass2->classes) HGOTO_DONE(-1);
3409
if(pclass1->classes > pclass2->classes) HGOTO_DONE(1);
3411
/* Check the number of ID references open on the class */
3412
if(pclass1->ref_count < pclass2->ref_count) HGOTO_DONE(-1);
3413
if(pclass1->ref_count > pclass2->ref_count) HGOTO_DONE(1);
3415
/* Check whether they are internal or not */
3416
if(pclass1->internal < pclass2->internal) HGOTO_DONE(-1);
3417
if(pclass1->internal > pclass2->internal) HGOTO_DONE(1);
3419
/* Check whether they are deleted or not */
3420
if(pclass1->deleted < pclass2->deleted) HGOTO_DONE(-1);
3421
if(pclass1->deleted > pclass2->deleted) HGOTO_DONE(1);
3423
/* Check whether they have creation callback functions & data */
3424
if(pclass1->create_func==NULL && pclass2->create_func!=NULL) HGOTO_DONE(-1);
3425
if(pclass1->create_func!=NULL && pclass2->create_func==NULL) HGOTO_DONE(1);
3426
if(pclass1->create_func!=pclass2->create_func) HGOTO_DONE(-1);
3427
if(pclass1->create_data < pclass2->create_data) HGOTO_DONE(-1);
3428
if(pclass1->create_data > pclass2->create_data) HGOTO_DONE(1);
3430
/* Check whether they have close callback functions & data */
3431
if(pclass1->close_func==NULL && pclass2->close_func!=NULL) HGOTO_DONE(-1);
3432
if(pclass1->close_func!=NULL && pclass2->close_func==NULL) HGOTO_DONE(1);
3433
if(pclass1->close_func!=pclass2->close_func) HGOTO_DONE(-1);
3434
if(pclass1->close_data < pclass2->close_data) HGOTO_DONE(-1);
3435
if(pclass1->close_data > pclass2->close_data) HGOTO_DONE(1);
3437
/* Cycle through the properties and compare them also */
3438
tnode1=H5SL_first(pclass1->props);
3439
tnode2=H5SL_first(pclass2->props);
3440
while(tnode1 || tnode2) {
3441
H5P_genprop_t *prop1, *prop2; /* Property for node */
3443
/* Check if they both have properties in this skip list node */
3444
if(tnode1==NULL && tnode2!=NULL) HGOTO_DONE(-1);
3445
if(tnode1!=NULL && tnode2==NULL) HGOTO_DONE(1);
3447
/* Compare the two properties */
3448
prop1=H5SL_item(tnode1);
3449
prop2=H5SL_item(tnode2);
3450
if((cmp_value=H5P_cmp_prop(prop1,prop2))!=0)
3451
HGOTO_DONE(cmp_value);
3453
/* Advance the pointers */
3454
tnode1=H5SL_next(tnode1);
3455
tnode2=H5SL_next(tnode2);
3459
FUNC_LEAVE_NOAPI(ret_value);
3460
} /* H5P_cmp_class() */
3463
/*--------------------------------------------------------------------------
3467
Internal routine to compare two generic property lists
3469
int H5P_cmp_plist(plist1, plist2)
3470
H5P_genplist_t *plist1; IN: 1st property list to compare
3471
H5P_genplist_t *plist2; IN: 2nd property list to compare
3473
Success: negative if list1 "less" than list2, positive if list1 "greater"
3474
than list2, zero if list1 is "equal" to list2
3477
This function compares two generic property lists together to see if
3478
they are the same list.
3481
COMMENTS, BUGS, ASSUMPTIONS
3484
--------------------------------------------------------------------------*/
3486
H5P_cmp_plist(H5P_genplist_t *plist1, H5P_genplist_t *plist2)
3488
H5SL_node_t *tnode1,*tnode2; /* Temporary pointer to property nodes */
3489
int cmp_value; /* Value from comparison */
3490
int ret_value=0; /* return value */
3492
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_plist);
3497
/* Check the number of properties */
3498
if(plist1->nprops < plist2->nprops) HGOTO_DONE(-1);
3499
if(plist1->nprops > plist2->nprops) HGOTO_DONE(1);
3501
/* Check whether they've been initialized */
3502
if(plist1->class_init < plist2->class_init) HGOTO_DONE(-1);
3503
if(plist1->class_init > plist2->class_init) HGOTO_DONE(1);
3505
/* Check for identical deleted properties */
3506
if(H5SL_count(plist1->del)>0) {
3507
/* Check for no deleted properties in plist2 */
3508
if(H5SL_count(plist2->del)==0) HGOTO_DONE(1);
3510
tnode1=H5SL_first(plist1->del);
3511
tnode2=H5SL_first(plist2->del);
3512
while(tnode1 || tnode2) {
3513
const char *name1, *name2; /* Name for node */
3515
/* Check if they both have properties in this node */
3516
if(tnode1==NULL && tnode2!=NULL) HGOTO_DONE(-1);
3517
if(tnode1!=NULL && tnode2==NULL) HGOTO_DONE(1);
3519
/* Compare the two deleted properties */
3520
name1=H5SL_item(tnode1);
3521
name2=H5SL_item(tnode2);
3522
if((cmp_value=HDstrcmp(name1,name2))!=0)
3523
HGOTO_DONE(cmp_value);
3525
/* Advance the pointers */
3526
tnode1=H5SL_next(tnode1);
3527
tnode2=H5SL_next(tnode2);
3531
if(H5SL_count(plist2->del)>0) HGOTO_DONE (-1);
3533
/* Cycle through the changed properties and compare them also */
3534
if(H5SL_count(plist1->props)>0) {
3535
/* Check for no changed properties in plist2 */
3536
if(H5SL_count(plist2->props)==0) HGOTO_DONE(1);
3538
tnode1=H5SL_first(plist1->props);
3539
tnode2=H5SL_first(plist2->props);
3540
while(tnode1 || tnode2) {
3541
H5P_genprop_t *prop1, *prop2; /* Property for node */
3543
/* Check if they both have properties in this node */
3544
if(tnode1==NULL && tnode2!=NULL) HGOTO_DONE(-1);
3545
if(tnode1!=NULL && tnode2==NULL) HGOTO_DONE(1);
3547
/* Compare the two properties */
3548
prop1=H5SL_item(tnode1);
3549
prop2=H5SL_item(tnode2);
3550
if((cmp_value=H5P_cmp_prop(prop1,prop2))!=0)
3551
HGOTO_DONE(cmp_value);
3553
/* Advance the pointers */
3554
tnode1=H5SL_next(tnode1);
3555
tnode2=H5SL_next(tnode2);
3559
if(H5SL_count(plist2->props)>0) HGOTO_DONE (-1);
3561
/* Check the parent classes */
3562
if((cmp_value=H5P_cmp_class(plist1->pclass,plist2->pclass))!=0)
3563
HGOTO_DONE(cmp_value);
3566
FUNC_LEAVE_NOAPI(ret_value);
3567
} /* H5P_cmp_plist() */
3570
/*--------------------------------------------------------------------------
3574
Routine to query whether two property lists or two property classes are equal
3576
htri_t H5Pequal(id1, id2)
3577
hid_t id1; IN: Property list or class ID to compare
3578
hid_t id2; IN: Property list or class ID to compare
3580
Success: TRUE if equal, FALSE if unequal
3583
Determines whether two property lists or two property classes are equal.
3586
COMMENTS, BUGS, ASSUMPTIONS
3589
--------------------------------------------------------------------------*/
3591
H5Pequal(hid_t id1, hid_t id2)
3593
void *obj1, *obj2; /* Property objects to compare */
3594
htri_t ret_value=FALSE; /* return value */
3596
FUNC_ENTER_API(H5Pequal, FAIL);
3597
H5TRACE2("t","ii",id1,id2);
3599
/* Check arguments. */
3600
if ((H5I_GENPROP_LST != H5I_get_type(id1) && H5I_GENPROP_CLS != H5I_get_type(id1))
3601
|| (H5I_GENPROP_LST != H5I_get_type(id2) && H5I_GENPROP_CLS != H5I_get_type(id2)))
3602
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property objects");
3603
if (H5I_get_type(id1) != H5I_get_type(id2))
3604
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not the same kind of property objects");
3605
if(NULL == (obj1 = H5I_object(id1)) || NULL == (obj2 = H5I_object(id2)))
3606
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist");
3608
/* Compare property lists */
3609
if(H5I_GENPROP_LST == H5I_get_type(id1)) {
3610
if(H5P_cmp_plist(obj1,obj2)==0)
3613
/* Must be property classes */
3615
if(H5P_cmp_class(obj1,obj2)==0)
3620
FUNC_LEAVE_API(ret_value);
3624
/*--------------------------------------------------------------------------
3628
Internal routine to query whether a property class is the same as another
3631
htri_t H5P_isa_class_real(pclass1, pclass2)
3632
H5P_genclass_t *pclass1; IN: Property class to check
3633
H5P_genclass_t *pclass2; IN: Property class to compare with
3635
Success: TRUE (1) or FALSE (0)
3636
Failure: negative value
3638
This routine queries whether a property class is the same as another class,
3639
and walks up the hierarchy of derived classes, checking if the first class
3640
is derived from the second class also.
3643
COMMENTS, BUGS, ASSUMPTIONS
3646
--------------------------------------------------------------------------*/
3648
H5P_isa_class_real(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2)
3652
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_isa_class_real);
3657
/* Compare property classes */
3658
if(H5P_cmp_class(pclass1,pclass2)==0) {
3661
/* Check if the class is derived, and walk up the chain, if so */
3662
if(pclass1->parent!=NULL)
3663
ret_value=H5P_isa_class_real(pclass1->parent,pclass2);
3669
FUNC_LEAVE_NOAPI(ret_value);
3670
} /* H5P_isa_class_real() */
3673
/*--------------------------------------------------------------------------
3677
Internal routine to query whether a property list is a certain class
3679
hid_t H5P_isa_class(plist_id, pclass_id)
3680
hid_t plist_id; IN: Property list to query
3681
hid_t pclass_id; IN: Property class to query
3683
Success: TRUE (1) or FALSE (0)
3686
This routine queries whether a property list is a member of the property
3690
COMMENTS, BUGS, ASSUMPTIONS
3691
This function is special in that it is an internal library function, but
3692
accepts hid_t's as parameters. Since it is used in basically the same way
3693
as the H5I functions, this should be OK. Don't make more library functions
3694
which accept hid_t's without thorough discussion. -QAK
3697
--------------------------------------------------------------------------*/
3699
H5P_isa_class(hid_t plist_id, hid_t pclass_id)
3701
H5P_genplist_t *plist; /* Property list to query */
3702
H5P_genclass_t *pclass; /* Property list class */
3703
htri_t ret_value; /* return value */
3705
FUNC_ENTER_NOAPI(H5P_isa_class, FAIL);
3707
/* Check arguments. */
3708
if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
3709
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
3710
if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
3711
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
3713
/* Compare the property list's class against the other class */
3714
if ((ret_value = H5P_isa_class_real(plist->pclass, pclass))<0)
3715
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes");
3718
FUNC_LEAVE_NOAPI(ret_value);
3719
} /* H5P_isa_class() */
3722
/*--------------------------------------------------------------------------
3726
Routine to query whether a property list is a certain class
3728
hid_t H5Pisa_class(plist_id, pclass_id)
3729
hid_t plist_id; IN: Property list to query
3730
hid_t pclass_id; IN: Property class to query
3732
Success: TRUE (1) or FALSE (0)
3735
This routine queries whether a property list is a member of the property
3739
COMMENTS, BUGS, ASSUMPTIONS
3740
What about returning a value indicating that the property class is further
3741
up the class hierarchy?
3744
--------------------------------------------------------------------------*/
3746
H5Pisa_class(hid_t plist_id, hid_t pclass_id)
3748
htri_t ret_value; /* return value */
3750
FUNC_ENTER_API(H5Pisa_class, FAIL);
3751
H5TRACE2("t","ii",plist_id,pclass_id);
3753
/* Check arguments. */
3754
if (H5I_GENPROP_LST != H5I_get_type(plist_id))
3755
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
3756
if (H5I_GENPROP_CLS != H5I_get_type(pclass_id))
3757
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
3759
/* Compare the property list's class against the other class */
3760
if ((ret_value = H5P_isa_class(plist_id, pclass_id))<0)
3761
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes");
3764
FUNC_LEAVE_API(ret_value);
3765
} /* H5Pisa_class() */
3768
/*--------------------------------------------------------------------------
3772
Internal routine to query whether a property list is a certain class and
3773
retrieve the property list object associated with it.
3775
void *H5P_object_verify(plist_id, pclass_id)
3776
hid_t plist_id; IN: Property list to query
3777
hid_t pclass_id; IN: Property class to query
3779
Success: valid pointer to a property list object
3782
This routine queries whether a property list is member of a certain class
3783
and retrieves the property list object associated with it.
3786
COMMENTS, BUGS, ASSUMPTIONS
3787
This function is special in that it is an internal library function, but
3788
accepts hid_t's as parameters. Since it is used in basically the same way
3789
as the H5I functions, this should be OK. Don't make more library functions
3790
which accept hid_t's without thorough discussion. -QAK
3792
This function is similar (in spirit) to H5I_object_verify()
3795
--------------------------------------------------------------------------*/
3797
H5P_object_verify(hid_t plist_id, hid_t pclass_id)
3799
void *ret_value; /* return value */
3801
FUNC_ENTER_NOAPI(H5P_object_verify, NULL);
3803
/* Compare the property list's class against the other class */
3804
if (H5P_isa_class(plist_id,pclass_id)!=TRUE)
3805
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, NULL, "property list is not a member of the class");
3807
/* Get the plist structure */
3808
if(NULL == (ret_value = H5I_object(plist_id)))
3809
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
3812
FUNC_LEAVE_NOAPI(ret_value);
3813
} /* H5P_object_verify() */
3816
/*--------------------------------------------------------------------------
3820
Internal routine to iterate over the properties in a property list
3822
herr_t H5P_iterate_plist(plist_id, idx, iter_func, iter_data)
3823
hid_t plist_id; IN: ID of property list to iterate over
3824
int *idx; IN/OUT: Index of the property to begin with
3825
H5P_iterate_t iter_func; IN: Function pointer to function to be
3826
called with each property iterated over.
3827
void *iter_data; IN/OUT: Pointer to iteration data from user
3829
Success: Returns the return value of the last call to ITER_FUNC if it was
3830
non-zero, or zero if all properties have been processed.
3831
Failure: negative value
3833
This routine iterates over the properties in the property object specified
3834
with PLIST_ID. For each property in the object, the ITER_DATA and some
3835
additional information, specified below, are passed to the ITER_FUNC function.
3836
The iteration begins with the IDX property in the object and the next element
3837
to be processed by the operator is returned in IDX. If IDX is NULL, then the
3838
iterator starts at the first property; since no stopping point is returned in
3839
this case, the iterator cannot be restarted if one of the calls to its operator
3842
The prototype for H5P_iterate_t is:
3843
typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
3844
The operation receives the property list or class identifier for the object
3845
being iterated over, ID, the name of the current property within the object,
3846
NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA.
3848
The return values from an operator are:
3849
Zero causes the iterator to continue, returning zero when all properties
3850
have been processed.
3851
Positive causes the iterator to immediately return that positive value,
3852
indicating short-circuit success. The iterator can be restarted at the
3853
index of the next property.
3854
Negative causes the iterator to immediately return that value, indicating
3855
failure. The iterator can be restarted at the index of the next
3858
H5Piterate assumes that the properties in the object identified by ID remains
3859
unchanged through the iteration. If the membership changes during the
3860
iteration, the function's behavior is undefined.
3863
COMMENTS, BUGS, ASSUMPTIONS
3866
--------------------------------------------------------------------------*/
3868
H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_data)
3870
H5P_genclass_t *tclass; /* Temporary class pointer */
3871
H5P_genplist_t *plist; /* Property list pointer */
3872
H5P_genprop_t *tmp; /* Temporary pointer to properties */
3873
H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */
3874
H5SL_node_t *curr_node; /* Current node in skip list */
3875
int curr_idx=0; /* Current iteration index */
3876
int ret_value=FAIL; /* Return value */
3878
FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_plist);
3883
/* Get the property list object */
3884
if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
3885
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
3887
/* Create the skip list to hold names of properties already seen */
3888
if((seen=H5SL_create(H5SL_TYPE_STR,0.5,H5P_DEFAULT_SKIPLIST_HEIGHT))==NULL)
3889
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties");
3891
/* Walk through the changed properties in the list */
3892
if(H5SL_count(plist->props)>0) {
3893
curr_node=H5SL_first(plist->props);
3894
while(curr_node!=NULL) {
3895
/* Get pointer to property from node */
3896
tmp=H5SL_item(curr_node);
3898
/* Check if we've found the correctly indexed property */
3899
if(curr_idx>=*idx) {
3900
/* Call the callback function */
3901
ret_value=(*iter_func)(plist_id,tmp->name,iter_data);
3904
HGOTO_DONE(ret_value);
3907
/* Increment the current index */
3910
/* Add property name to "seen" list */
3911
if(H5SL_insert(seen,tmp->name,tmp->name)<0)
3912
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list");
3914
/* Get the next property node in the skip list */
3915
curr_node=H5SL_next(curr_node);
3919
/* Walk up the class hiearchy */
3920
tclass=plist->pclass;
3921
while(tclass!=NULL) {
3922
if(tclass->nprops>0) {
3923
/* Walk through the properties in the class */
3924
curr_node=H5SL_first(tclass->props);
3925
while(curr_node!=NULL) {
3926
/* Get pointer to property from node */
3927
tmp=H5SL_item(curr_node);
3929
/* Only call iterator callback for properties we haven't seen
3930
* before and that haven't been deleted
3932
if(H5SL_search(seen,tmp->name)==NULL &&
3933
H5SL_search(plist->del,tmp->name)==NULL) {
3936
/* Check if we've found the correctly indexed property */
3937
if(curr_idx>=*idx) {
3938
/* Call the callback function */
3939
ret_value=(*iter_func)(plist_id,tmp->name,iter_data);
3942
HGOTO_DONE(ret_value);
3945
/* Increment the current index */
3948
/* Add property name to "seen" list */
3949
if(H5SL_insert(seen,tmp->name,tmp->name)<0)
3950
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list");
3953
/* Get the next property node in the skip list */
3954
curr_node=H5SL_next(curr_node);
3958
/* Go up to parent class */
3959
tclass=tclass->parent;
3963
/* Set the index we stopped at */
3966
/* Release the skip list of 'seen' properties */
3970
FUNC_LEAVE_NOAPI(ret_value);
3971
} /* H5P_iterate_plist() */
3974
/*--------------------------------------------------------------------------
3978
Internal routine to iterate over the properties in a property class
3980
herr_t H5P_iterate_pclass(pclass_id, idx, iter_func, iter_data)
3981
hid_t pclass_id; IN: ID of property class to iterate over
3982
int *idx; IN/OUT: Index of the property to begin with
3983
H5P_iterate_t iter_func; IN: Function pointer to function to be
3984
called with each property iterated over.
3985
void *iter_data; IN/OUT: Pointer to iteration data from user
3987
Success: Returns the return value of the last call to ITER_FUNC if it was
3988
non-zero, or zero if all properties have been processed.
3989
Failure: negative value
3991
This routine iterates over the properties in the property object specified
3992
with PCLASS_ID. For each property in the object, the ITER_DATA and some
3993
additional information, specified below, are passed to the ITER_FUNC function.
3994
The iteration begins with the IDX property in the object and the next element
3995
to be processed by the operator is returned in IDX. If IDX is NULL, then the
3996
iterator starts at the first property; since no stopping point is returned in
3997
this case, the iterator cannot be restarted if one of the calls to its operator
4000
The prototype for H5P_iterate_t is:
4001
typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
4002
The operation receives the property list or class identifier for the object
4003
being iterated over, ID, the name of the current property within the object,
4004
NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA.
4006
The return values from an operator are:
4007
Zero causes the iterator to continue, returning zero when all properties
4008
have been processed.
4009
Positive causes the iterator to immediately return that positive value,
4010
indicating short-circuit success. The iterator can be restarted at the
4011
index of the next property.
4012
Negative causes the iterator to immediately return that value, indicating
4013
failure. The iterator can be restarted at the index of the next
4016
H5Piterate assumes that the properties in the object identified by ID remains
4017
unchanged through the iteration. If the membership changes during the
4018
iteration, the function's behavior is undefined.
4021
COMMENTS, BUGS, ASSUMPTIONS
4024
--------------------------------------------------------------------------*/
4026
H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *iter_data)
4028
H5P_genclass_t *pclass; /* Property list pointer */
4029
H5SL_node_t *curr_node; /* Current node in skip list */
4030
H5P_genprop_t *prop; /* Temporary property pointer */
4031
int curr_idx=0; /* Current iteration index */
4032
int ret_value=FAIL; /* Return value */
4034
FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_pclass);
4039
/* Get the property list object */
4040
if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
4041
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
4043
/* Cycle through the properties and call the callback */
4045
curr_node=H5SL_first(pclass->props);
4046
while(curr_node!=NULL) {
4047
if(curr_idx>=*idx) {
4048
/* Get the property for the node */
4049
prop=H5SL_item(curr_node);
4051
/* Call the callback function */
4052
ret_value=(*iter_func)(pclass_id,prop->name,iter_data);
4054
/* Check if iteration function succeeded */
4056
HGOTO_DONE(ret_value);
4059
/* Increment the iteration index */
4062
/* Get the next property node in the skip list */
4063
curr_node=H5SL_next(curr_node);
4067
/* Set the index we stopped at */
4070
FUNC_LEAVE_NOAPI(ret_value);
4071
} /* H5P_iterate_pclass() */
4074
/*--------------------------------------------------------------------------
4078
Routine to iterate over the properties in a property list or class
4080
int H5Piterate(pclass_id, idx, iter_func, iter_data)
4081
hid_t id; IN: ID of property object to iterate over
4082
int *idx; IN/OUT: Index of the property to begin with
4083
H5P_iterate_t iter_func; IN: Function pointer to function to be
4084
called with each property iterated over.
4085
void *iter_data; IN/OUT: Pointer to iteration data from user
4087
Success: Returns the return value of the last call to ITER_FUNC if it was
4088
non-zero, or zero if all properties have been processed.
4089
Failure: negative value
4091
This routine iterates over the properties in the property object specified
4092
with ID. The properties in both property lists and classes may be iterated
4093
over with this function. For each property in the object, the ITER_DATA and
4094
some additional information, specified below, are passed to the ITER_FUNC
4095
function. The iteration begins with the IDX property in the object and the
4096
next element to be processed by the operator is returned in IDX. If IDX is
4097
NULL, then the iterator starts at the first property; since no stopping point
4098
is returned in this case, the iterator cannot be restarted if one of the calls
4099
to its operator returns non-zero. The IDX value is 0-based (ie. to start at
4100
the "first" property, the IDX value should be 0).
4102
The prototype for H5P_iterate_t is:
4103
typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
4104
The operation receives the property list or class identifier for the object
4105
being iterated over, ID, the name of the current property within the object,
4106
NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA.
4108
The return values from an operator are:
4109
Zero causes the iterator to continue, returning zero when all properties
4110
have been processed.
4111
Positive causes the iterator to immediately return that positive value,
4112
indicating short-circuit success. The iterator can be restarted at the
4113
index of the next property.
4114
Negative causes the iterator to immediately return that value, indicating
4115
failure. The iterator can be restarted at the index of the next
4118
H5Piterate assumes that the properties in the object identified by ID remains
4119
unchanged through the iteration. If the membership changes during the
4120
iteration, the function's behavior is undefined.
4123
COMMENTS, BUGS, ASSUMPTIONS
4126
--------------------------------------------------------------------------*/
4128
H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func, void *iter_data)
4130
int fake_idx=0; /* Index when user doesn't provide one */
4131
int ret_value; /* return value */
4133
FUNC_ENTER_API(H5Piterate, FAIL);
4134
H5TRACE4("Is","i*Isxx",id,idx,iter_func,iter_data);
4136
/* Check arguments. */
4137
if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
4138
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
4139
if (iter_func==NULL)
4140
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration callback");
4142
if (H5I_GENPROP_LST == H5I_get_type(id)) {
4143
/* Iterate over a property list */
4144
if ((ret_value=H5P_iterate_plist(id,(idx ? idx : &fake_idx),iter_func,iter_data))<0)
4145
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to iterate over list");
4148
if (H5I_GENPROP_CLS == H5I_get_type(id)) {
4149
/* Iterate over a property class */
4150
if ((ret_value=H5P_iterate_pclass(id,(idx ? idx : &fake_idx),iter_func,iter_data))<0)
4151
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to iterate over class");
4154
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
4157
FUNC_LEAVE_API(ret_value);
4158
} /* H5Piterate() */
4161
/*--------------------------------------------------------------------------
4165
Internal routine to quickly retrieve the value of a property in a property list.
4167
int H5P_peek_unsigned(plist, name)
4168
H5P_genplist_t *plist; IN: Property list to check
4169
const char *name; IN: Name of property to query
4171
Directly returns the value of the property in the list
4173
This function directly returns the value of a property in a property
4174
list. Because this function is only able to just copy a particular property
4175
value to the return value, there is no way to check for errors. We attempt
4176
to make certain that bad things don't happen by validating that the size of
4177
the property is the same as the size of the return type, but that can't
4179
This function does call the user's 'get' callback routine still.
4182
COMMENTS, BUGS, ASSUMPTIONS
4187
--------------------------------------------------------------------------*/
4189
H5P_peek_unsigned(H5P_genplist_t *plist, const char *name)
4191
unsigned ret_value; /* return value */
4193
FUNC_ENTER_NOAPI(H5P_peek_unsigned, UFAIL);
4198
/* Get the value to return, don't worry about the return value, we can't return it */
4199
H5P_get(plist,name,&ret_value);
4202
FUNC_LEAVE_NOAPI(ret_value);
4203
} /* H5P_peek_unsigned() */
4206
/*--------------------------------------------------------------------------
4210
Internal routine to quickly retrieve the value of a property in a property list.
4212
hid_t H5P_peek_hid_t(plist, name)
4213
H5P_genplist_t *plist; IN: Property list to check
4214
const char *name; IN: Name of property to query
4216
Directly returns the value of the property in the list
4218
This function directly returns the value of a property in a property
4219
list. Because this function is only able to just copy a particular property
4220
value to the return value, there is no way to check for errors. We attempt
4221
to make certain that bad things don't happen by validating that the size of
4222
the property is the same as the size of the return type, but that can't
4224
This function does call the user's 'get' callback routine still.
4227
COMMENTS, BUGS, ASSUMPTIONS
4232
--------------------------------------------------------------------------*/
4234
H5P_peek_hid_t(H5P_genplist_t *plist, const char *name)
4236
hid_t ret_value; /* return value */
4238
FUNC_ENTER_NOAPI(H5P_peek_hid_t, FAIL);
4243
/* Get the value to return, don't worry about the return value, we can't return it */
4244
H5P_get(plist,name,&ret_value);
4247
FUNC_LEAVE_NOAPI(ret_value);
4248
} /* H5P_peek_hid_t() */
4251
/*--------------------------------------------------------------------------
4255
Internal routine to quickly retrieve the value of a property in a property list.
4257
void *H5P_peek_voidp(plist, name)
4258
H5P_genplist_t *plist; IN: Property list to check
4259
const char *name; IN: Name of property to query
4261
Directly returns the value of the property in the list
4263
This function directly returns the value of a property in a property
4264
list. Because this function is only able to just copy a particular property
4265
value to the return value, there is no way to check for errors. We attempt
4266
to make certain that bad things don't happen by validating that the size of
4267
the property is the same as the size of the return type, but that can't
4269
This function does call the user's 'get' callback routine still.
4272
COMMENTS, BUGS, ASSUMPTIONS
4277
--------------------------------------------------------------------------*/
4279
H5P_peek_voidp(H5P_genplist_t *plist, const char *name)
4281
void * ret_value; /* return value */
4283
FUNC_ENTER_NOAPI(H5P_peek_voidp, NULL);
4288
/* Get the value to return, don't worry about the return value, we can't return it */
4289
H5P_get(plist,name,&ret_value);
4292
FUNC_LEAVE_NOAPI(ret_value);
4293
} /* H5P_peek_voidp() */
4296
/*--------------------------------------------------------------------------
4300
Internal routine to quickly retrieve the value of a property in a property list.
4302
hsize_t H5P_peek_size_t(plist, name)
4303
H5P_genplist_t *plist; IN: Property list to check
4304
const char *name; IN: Name of property to query
4306
Directly returns the value of the property in the list
4308
This function directly returns the value of a property in a property
4309
list. Because this function is only able to just copy a particular property
4310
value to the return value, there is no way to check for errors. We attempt
4311
to make certain that bad things don't happen by validating that the size of
4312
the property is the same as the size of the return type, but that can't
4314
This function does call the user's 'get' callback routine still.
4317
COMMENTS, BUGS, ASSUMPTIONS
4322
--------------------------------------------------------------------------*/
4324
H5P_peek_size_t(H5P_genplist_t *plist, const char *name)
4326
size_t ret_value; /* return value */
4328
FUNC_ENTER_NOAPI(H5P_peek_size_t, UFAIL);
4333
/* Get the value to return, don't worry about the return value, we can't return it */
4334
H5P_get(plist,name,&ret_value);
4337
FUNC_LEAVE_NOAPI(ret_value);
4338
} /* H5P_peek_size_t() */
4341
/*--------------------------------------------------------------------------
4345
Internal routine to query the value of a property in a property list.
4347
herr_t H5P_get(plist, name, value)
4348
H5P_genplist_t *plist; IN: Property list to check
4349
const char *name; IN: Name of property to query
4350
void *value; OUT: Pointer to the buffer for the property value
4352
Returns non-negative on success, negative on failure.
4354
Retrieves a copy of the value for a property in a property list. The
4355
property name must exist or this routine will fail. If there is a
4356
'get' callback routine registered for this property, the copy of the
4357
value of the property will first be passed to that routine and any changes
4358
to the copy of the value will be used when returning the property value
4360
If the 'get' callback routine returns an error, 'value' will not be
4361
modified and this routine will return an error. This routine may not be
4362
called for zero-sized properties.
4365
COMMENTS, BUGS, ASSUMPTIONS
4368
--------------------------------------------------------------------------*/
4370
H5P_get(H5P_genplist_t *plist, const char *name, void *value)
4372
H5P_genclass_t *tclass; /* Temporary class pointer */
4373
H5P_genprop_t *prop; /* Temporary property pointer */
4374
herr_t ret_value=SUCCEED; /* Return value */
4376
FUNC_ENTER_NOAPI(H5P_get, FAIL);
4382
/* Check if the property has been deleted */
4383
if(H5SL_search(plist->del,name)!=NULL)
4384
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
4387
if((prop=H5SL_search(plist->props,name))!=NULL) {
4388
/* Check for property size >0 */
4390
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
4392
/* Make a copy of the value and pass to 'get' callback */
4393
if(prop->get!=NULL) {
4394
void *tmp_value; /* Temporary value for property */
4396
/* Make a copy of the current value, in case the callback fails */
4397
if (NULL==(tmp_value=H5MM_malloc(prop->size)))
4398
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
4399
HDmemcpy(tmp_value,prop->value,prop->size);
4401
/* Call user's callback */
4402
if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value)<0)
4403
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't get property value");
4405
/* Copy new [possibly unchanged] value into return value */
4406
HDmemcpy(value,tmp_value,prop->size);
4408
/* Free the temporary value buffer */
4409
H5MM_xfree(tmp_value);
4411
/* No 'get' callback, just copy value */
4413
HDmemcpy(value,prop->value,prop->size);
4417
* Check if we should get class properties (up through list of parent classes also),
4418
* & make property 'get' callback.
4420
tclass=plist->pclass;
4421
while(tclass!=NULL) {
4422
if(tclass->nprops>0) {
4423
/* Find the property in the class */
4424
if((prop=H5SL_search(tclass->props,name))!=NULL) {
4425
/* Check for property size >0 */
4427
HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size");
4429
/* Call the 'get' callback, if there is one */
4430
if(prop->get!=NULL) {
4431
void *tmp_value; /* Temporary value for property */
4433
/* Make a copy of the current value, in case the callback fails */
4434
if (NULL==(tmp_value=H5MM_malloc(prop->size)))
4435
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
4436
HDmemcpy(tmp_value,prop->value,prop->size);
4438
/* Call user's callback */
4439
if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value)<0) {
4440
H5MM_xfree(tmp_value);
4441
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value");
4444
if(HDmemcmp(tmp_value,prop->value,prop->size)) {
4445
H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */
4447
/* Make a copy of the class's property */
4448
if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
4449
HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property");
4451
/* Copy new value into property value */
4452
HDmemcpy(pcopy->value,tmp_value,prop->size);
4454
/* Insert the changed property into the property list */
4455
if(H5P_add_prop(plist->props,pcopy)<0)
4456
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list");
4459
/* Copy new [possibly unchanged] value into return value */
4460
HDmemcpy(value,tmp_value,prop->size);
4462
/* Free the temporary value buffer */
4463
H5MM_xfree(tmp_value);
4465
/* No 'get' callback, just copy value */
4467
HDmemcpy(value,prop->value,prop->size);
4470
HGOTO_DONE(SUCCEED);
4474
/* Go up to parent class */
4475
tclass=tclass->parent;
4478
/* If we get this far, then it wasn't in the list of changed properties,
4479
* nor in the properties in the class hierarchy, indicate an error
4481
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
4485
FUNC_LEAVE_NOAPI(ret_value);
4489
/*--------------------------------------------------------------------------
4493
Routine to query the value of a property in a property list.
4495
herr_t H5Pget(plist_id, name, value)
4496
hid_t plist_id; IN: Property list to check
4497
const char *name; IN: Name of property to query
4498
void *value; OUT: Pointer to the buffer for the property value
4500
Returns non-negative on success, negative on failure.
4502
Retrieves a copy of the value for a property in a property list. The
4503
property name must exist or this routine will fail. If there is a
4504
'get' callback routine registered for this property, the copy of the
4505
value of the property will first be passed to that routine and any changes
4506
to the copy of the value will be used when returning the property value
4508
If the 'get' callback routine returns an error, 'value' will not be
4509
modified and this routine will return an error. This routine may not be
4510
called for zero-sized properties.
4513
COMMENTS, BUGS, ASSUMPTIONS
4516
--------------------------------------------------------------------------*/
4518
H5Pget(hid_t plist_id, const char *name, void *value)
4520
H5P_genplist_t *plist; /* Property list pointer */
4521
herr_t ret_value=SUCCEED; /* return value */
4523
FUNC_ENTER_API(H5Pget, FAIL);
4524
H5TRACE3("e","isx",plist_id,name,value);
4526
/* Check arguments. */
4527
if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
4528
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
4529
if (!name || !*name)
4530
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
4532
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value");
4534
/* Go get the value */
4535
if(H5P_get(plist,name,value)<0)
4536
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query property value");
4539
FUNC_LEAVE_API(ret_value);
4543
/*--------------------------------------------------------------------------
4547
Internal routine to remove a property from a property list.
4549
herr_t H5P_remove(plist, name)
4550
H5P_genplist_t *plist; IN: Property list to modify
4551
const char *name; IN: Name of property to remove
4553
Returns non-negative on success, negative on failure.
4555
Removes a property from a property list. Both properties which were
4556
in existance when the property list was created (i.e. properties registered
4557
with H5Pregister) and properties added to the list after it was created
4558
(i.e. added with H5Pinsert) may be removed from a property list.
4559
Properties do not need to be removed a property list before the list itself
4560
is closed, they will be released automatically when H5Pclose is called.
4561
The 'close' callback for this property is called before the property is
4562
release, if the callback exists.
4565
COMMENTS, BUGS, ASSUMPTIONS
4568
--------------------------------------------------------------------------*/
4570
H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name)
4572
H5P_genclass_t *tclass; /* Temporary class pointer */
4573
H5P_genprop_t *prop; /* Temporary property pointer */
4574
char *del_name; /* Pointer to deleted name */
4575
herr_t ret_value=SUCCEED; /* Return value */
4577
FUNC_ENTER_NOAPI(H5P_remove,FAIL);
4582
/* Indicate that the property isn't in the list if it has been deleted already */
4583
if(H5SL_search(plist->del,name)!=NULL)
4584
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
4586
/* Get the property node from the changed property skip list */
4587
if((prop=H5SL_search(plist->props,name))!=NULL) {
4588
/* Pass value to 'close' callback, if it exists */
4589
if(prop->del!=NULL) {
4590
/* Call user's callback */
4591
if((*(prop->del))(plist_id,name,prop->size,prop->value)<0)
4592
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value");
4595
/* Duplicate string for insertion into new deleted property skip list */
4596
if((del_name=H5MM_xstrdup(name))==NULL)
4597
HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
4599
/* Insert property name into deleted list */
4600
if(H5SL_insert(plist->del,del_name,del_name)<0)
4601
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list");
4603
/* Remove the property from the skip list */
4604
if(H5SL_remove(plist->props,prop->name)==NULL)
4605
HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list");
4607
/* Free the property, ignoring return value, nothing we can do */
4608
H5P_free_prop(prop);
4610
/* Decrement the number of properties in list */
4613
/* Walk through all the properties in the class hierarchy, looking for the property */
4616
* Check if we should delete class properties (up through list of parent classes also),
4617
* & make property 'delete' callback.
4619
tclass=plist->pclass;
4620
while(tclass!=NULL) {
4621
if(tclass->nprops>0) {
4622
/* Find the property in the class */
4623
if((prop=H5P_find_prop_pclass(tclass,name))!=NULL) {
4624
/* Pass value to 'del' callback, if it exists */
4625
if(prop->del!=NULL) {
4626
void *tmp_value; /* Temporary value buffer */
4628
/* Allocate space for a temporary copy of the property value */
4629
if (NULL==(tmp_value=H5MM_malloc(prop->size)))
4630
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value");
4631
HDmemcpy(tmp_value,prop->value,prop->size);
4633
/* Call user's callback */
4634
if((*(prop->del))(plist_id,name,prop->size,tmp_value)<0) {
4635
H5MM_xfree(tmp_value);
4636
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value");
4639
/* Release the temporary value buffer */
4640
H5MM_xfree(tmp_value);
4643
/* Duplicate string for insertion into new deleted property skip list */
4644
if((del_name=H5MM_xstrdup(name))==NULL)
4645
HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
4647
/* Insert property name into deleted list */
4648
if(H5SL_insert(plist->del,del_name,del_name)<0)
4649
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list");
4651
/* Decrement the number of properties in list */
4655
HGOTO_DONE(SUCCEED);
4659
/* Go up to parent class */
4660
tclass=tclass->parent;
4663
/* If we get this far, then it wasn't in the list of changed properties,
4664
* nor in the properties in the class hierarchy, indicate an error
4666
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
4670
FUNC_LEAVE_NOAPI(ret_value);
4671
} /* H5P_remove() */
4674
/*--------------------------------------------------------------------------
4678
Routine to remove a property from a property list.
4680
herr_t H5Premove(plist_id, name)
4681
hid_t plist_id; IN: Property list to modify
4682
const char *name; IN: Name of property to remove
4684
Returns non-negative on success, negative on failure.
4686
Removes a property from a property list. Both properties which were
4687
in existance when the property list was created (i.e. properties registered
4688
with H5Pregister) and properties added to the list after it was created
4689
(i.e. added with H5Pinsert) may be removed from a property list.
4690
Properties do not need to be removed a property list before the list itself
4691
is closed, they will be released automatically when H5Pclose is called.
4692
The 'close' callback for this property is called before the property is
4693
release, if the callback exists.
4696
COMMENTS, BUGS, ASSUMPTIONS
4699
--------------------------------------------------------------------------*/
4701
H5Premove(hid_t plist_id, const char *name)
4703
H5P_genplist_t *plist; /* Property list to modify */
4704
herr_t ret_value; /* return value */
4706
FUNC_ENTER_API(H5Premove, FAIL);
4707
H5TRACE2("e","is",plist_id,name);
4709
/* Check arguments. */
4710
if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
4711
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
4712
if (!name || !*name)
4713
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
4715
/* Create the new property list class */
4716
if ((ret_value=H5P_remove(plist_id,plist,name))<0)
4717
HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property");
4720
FUNC_LEAVE_API(ret_value);
4724
/*--------------------------------------------------------------------------
4728
Internal routine to copy a property from one list to another
4730
herr_t H5P_copy_prop_plist(dst_plist, src_plist, name)
4731
hid_t dst_id; IN: ID of destination property list or class
4732
hid_t src_id; IN: ID of source property list or class
4733
const char *name; IN: Name of property to copy
4735
Success: non-negative value.
4736
Failure: negative value.
4738
Copies a property from one property list to another.
4740
If a property is copied from one list to another, the property will be
4741
first deleted from the destination list (generating a call to the 'close'
4742
callback for the property, if one exists) and then the property is copied
4743
from the source list to the destination list (generating a call to the
4744
'copy' callback for the property, if one exists).
4746
If the property does not exist in the destination list, this call is
4747
equivalent to calling H5Pinsert and the 'create' callback will be called
4748
(if such a callback exists for the property).
4751
COMMENTS, BUGS, ASSUMPTIONS
4754
--------------------------------------------------------------------------*/
4756
H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name)
4758
H5P_genplist_t *dst_plist; /* Pointer to destination property list */
4759
H5P_genplist_t *src_plist; /* Pointer to source property list */
4760
H5P_genprop_t *prop; /* Temporary property pointer */
4761
H5P_genprop_t *new_prop=NULL; /* Pointer to new property */
4762
herr_t ret_value=SUCCEED; /* return value */
4764
FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_plist);
4768
/* Get the objects to operate on */
4769
if(NULL == (src_plist = H5I_object(src_id)) || NULL == (dst_plist = H5I_object(dst_id)))
4770
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist");
4772
/* If the property exists in the destination alread */
4773
if(H5P_find_prop_plist(dst_plist,name)!=NULL) {
4774
/* Delete the property from the destination list, calling the 'close' callback if necessary */
4775
if(H5P_remove(dst_id,dst_plist,name)<0)
4776
HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property");
4778
/* Get the pointer to the source property */
4779
prop=H5P_find_prop_plist(src_plist,name);
4781
/* Make a copy of the source property */
4782
if((new_prop=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
4783
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
4785
/* Call property copy callback, if it exists */
4786
if(new_prop->copy) {
4787
if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value)<0)
4788
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
4791
/* Insert the initialized property into the property list */
4792
if(H5P_add_prop(dst_plist->props,new_prop)<0)
4793
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list");
4795
/* Increment the number of properties in list */
4796
dst_plist->nprops++;
4798
/* If not, get the information required to do an H5Pinsert with the property into the destination list */
4800
/* Get the pointer to the source property */
4801
prop=H5P_find_prop_plist(src_plist,name);
4803
/* Create property object from parameters */
4804
if((new_prop=H5P_create_prop(prop->name,prop->size,H5P_PROP_WITHIN_LIST,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->cmp,prop->close))==NULL)
4805
HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property");
4807
/* Call property creation callback, if it exists */
4808
if(new_prop->create) {
4809
if((new_prop->create)(new_prop->name,new_prop->size,new_prop->value)<0)
4810
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property");
4813
/* Insert property into property list class */
4814
if(H5P_add_prop(dst_plist->props,new_prop)<0)
4815
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class");
4817
/* Increment property count for class */
4818
dst_plist->nprops++;
4823
/* Cleanup, if necessary */
4826
H5P_free_prop(new_prop);
4829
FUNC_LEAVE_NOAPI(ret_value);
4830
} /* H5P_copy_prop_plist() */
4833
/*--------------------------------------------------------------------------
4835
H5P_copy_prop_pclass
4837
Internal routine to copy a property from one class to another
4839
herr_t H5P_copy_prop_pclass(dst_pclass, src_pclass, name)
4840
H5P_genclass_t *dst_pclass; IN: Pointer to destination class
4841
H5P_genclass_t *src_pclass; IN: Pointer to source class
4842
const char *name; IN: Name of property to copy
4844
Success: non-negative value.
4845
Failure: negative value.
4847
Copies a property from one property class to another.
4849
If a property is copied from one class to another, all the property
4850
information will be first deleted from the destination class and then the
4851
property information will be copied from the source class into the
4854
If the property does not exist in the destination class or list, this call
4855
is equivalent to calling H5Pregister.
4858
COMMENTS, BUGS, ASSUMPTIONS
4861
--------------------------------------------------------------------------*/
4863
H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t *src_pclass, const char *name)
4865
H5P_genprop_t *prop; /* Temporary property pointer */
4866
herr_t ret_value=SUCCEED; /* return value */
4868
FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_pclass);
4874
/* If the property exists in the destination already */
4875
if(H5P_exist_pclass(dst_pclass,name)) {
4876
/* Delete the old property from the destination class */
4877
if(H5P_unregister(dst_pclass,name)<0)
4878
HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property");
4881
/* Get the property from the source */
4882
if((prop=H5P_find_prop_pclass(src_pclass,name))==NULL)
4883
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to locate property");
4885
/* Register the property into the destination */
4886
if(H5P_register(dst_pclass,name,prop->size,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->cmp,prop->close)<0)
4887
HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property");
4890
/* Cleanup, if necessary */
4892
FUNC_LEAVE_NOAPI(ret_value);
4893
} /* H5P_copy_prop_pclass() */
4896
/*--------------------------------------------------------------------------
4900
Routine to copy a property from one list or class to another
4902
herr_t H5Pcopy_prop(dst_id, src_id, name)
4903
hid_t dst_id; IN: ID of destination property list or class
4904
hid_t src_id; IN: ID of source property list or class
4905
const char *name; IN: Name of property to copy
4907
Success: non-negative value.
4908
Failure: negative value.
4910
Copies a property from one property list or class to another.
4912
If a property is copied from one class to another, all the property
4913
information will be first deleted from the destination class and then the
4914
property information will be copied from the source class into the
4917
If a property is copied from one list to another, the property will be
4918
first deleted from the destination list (generating a call to the 'close'
4919
callback for the property, if one exists) and then the property is copied
4920
from the source list to the destination list (generating a call to the
4921
'copy' callback for the property, if one exists).
4923
If the property does not exist in the destination class or list, this call
4924
is equivalent to calling H5Pregister or H5Pinsert (for a class or list, as
4925
appropriate) and the 'create' callback will be called in the case of the
4926
property being copied into a list (if such a callback exists for the
4930
COMMENTS, BUGS, ASSUMPTIONS
4933
--------------------------------------------------------------------------*/
4935
H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name)
4937
void *src_obj, *dst_obj; /* Property objects to copy between */
4938
herr_t ret_value=SUCCEED; /* return value */
4940
FUNC_ENTER_API(H5Pcopy_prop, FAIL);
4941
H5TRACE3("e","iis",dst_id,src_id,name);
4943
/* Check arguments. */
4944
if ((H5I_GENPROP_LST != H5I_get_type(src_id) && H5I_GENPROP_CLS != H5I_get_type(src_id))
4945
|| (H5I_GENPROP_LST != H5I_get_type(dst_id) && H5I_GENPROP_CLS != H5I_get_type(dst_id)))
4946
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property objects");
4947
if (H5I_get_type(src_id) != H5I_get_type(dst_id))
4948
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not the same kind of property objects");
4949
if (!name || !*name)
4950
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name given");
4951
if(NULL == (src_obj = H5I_object(src_id)) || NULL == (dst_obj = H5I_object(dst_id)))
4952
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist");
4954
/* Compare property lists */
4955
if(H5I_GENPROP_LST == H5I_get_type(src_id)) {
4956
if(H5P_copy_prop_plist(dst_id,src_id,name)<0)
4957
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between lists");
4959
/* Must be property classes */
4961
if(H5P_copy_prop_pclass(dst_obj,src_obj,name)<0)
4962
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between classes");
4966
FUNC_LEAVE_API(ret_value);
4967
} /* H5Pcopy_prop() */
4970
/*--------------------------------------------------------------------------
4974
Internal routine to remove a property from a property list class.
4976
herr_t H5P_unregister(pclass, name)
4977
H5P_genclass_t *pclass; IN: Property list class to modify
4978
const char *name; IN: Name of property to remove
4980
Returns non-negative on success, negative on failure.
4982
Removes a property from a property list class. Future property lists
4983
created of that class will not contain this property. Existing property
4984
lists containing this property are not affected.
4987
COMMENTS, BUGS, ASSUMPTIONS
4990
--------------------------------------------------------------------------*/
4992
H5P_unregister(H5P_genclass_t *pclass, const char *name)
4994
H5P_genprop_t *prop; /* Temporary property pointer */
4995
herr_t ret_value=SUCCEED; /* Return value */
4997
FUNC_ENTER_NOAPI_NOINIT(H5P_unregister);
5002
/* Get the property node from the skip list */
5003
if((prop=H5SL_search(pclass->props,name))==NULL)
5004
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
5006
/* Remove the property from the skip list */
5007
if(H5SL_remove(pclass->props,prop->name)==NULL)
5008
HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list");
5010
/* Free the property, ignoring return value, nothing we can do */
5011
H5P_free_prop(prop);
5013
/* Decrement the number of registered properties in class */
5016
/* Update the revision for the class */
5017
pclass->revision = H5P_GET_NEXT_REV;
5020
FUNC_LEAVE_NOAPI(ret_value);
5021
} /* H5P_unregister() */
5024
/*--------------------------------------------------------------------------
5028
Routine to remove a property from a property list class.
5030
herr_t H5Punregister(pclass_id, name)
5031
hid_t pclass_id; IN: Property list class to modify
5032
const char *name; IN: Name of property to remove
5034
Returns non-negative on success, negative on failure.
5036
Removes a property from a property list class. Future property lists
5037
created of that class will not contain this property. Existing property
5038
lists containing this property are not affected.
5041
COMMENTS, BUGS, ASSUMPTIONS
5044
--------------------------------------------------------------------------*/
5046
H5Punregister(hid_t pclass_id, const char *name)
5048
H5P_genclass_t *pclass; /* Property list class to modify */
5049
herr_t ret_value; /* return value */
5051
FUNC_ENTER_API(H5Punregister, FAIL);
5052
H5TRACE2("e","is",pclass_id,name);
5054
/* Check arguments. */
5055
if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
5056
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
5057
if (!name || !*name)
5058
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
5060
/* Remove the property list from class */
5061
if ((ret_value=H5P_unregister(pclass,name))<0)
5062
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to remove property from class");
5065
FUNC_LEAVE_API(ret_value);
5066
} /* H5Punregister() */
5069
/*--------------------------------------------------------------------------
5073
Internal routine to close a property list.
5075
herr_t H5P_close(plist)
5076
H5P_genplist_t *plist; IN: Property list to close
5078
Returns non-negative on success, negative on failure.
5080
Closes a property list. If a 'close' callback exists for the property
5081
list class, it is called before the property list is destroyed. If 'close'
5082
callbacks exist for any individual properties in the property list, they are
5083
called after the class 'close' callback.
5086
COMMENTS, BUGS, ASSUMPTIONS
5087
The property list class 'close' callback routine is not called from
5088
here, it must have been check for and called properly prior to this routine
5092
--------------------------------------------------------------------------*/
5094
H5P_close(void *_plist)
5096
H5P_genclass_t *tclass; /* Temporary class pointer */
5097
H5P_genplist_t *plist=(H5P_genplist_t *)_plist;
5098
H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */
5099
size_t nseen; /* Number of items 'seen' */
5100
hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */
5101
size_t ndel; /* Number of items deleted */
5102
H5SL_node_t *curr_node; /* Current node in skip list */
5103
H5P_genprop_t *tmp; /* Temporary pointer to properties */
5104
unsigned make_cb=0; /* Operator data for property free callback */
5105
herr_t ret_value=SUCCEED; /* return value */
5107
FUNC_ENTER_NOAPI_NOINIT(H5P_close);
5111
/* Make call to property list class close callback, if needed */
5112
if(plist->class_init!=0 && plist->pclass->close_func!=NULL) {
5113
/* Call user's "close" callback function, ignoring return value */
5114
(plist->pclass->close_func)(plist->plist_id,plist->pclass->close_data);
5117
/* Create the skip list to hold names of properties already seen
5118
* (This prevents a property in the class hierarchy from having it's
5119
* 'close' callback called, if a property in the class hierarchy has
5120
* already been seen)
5122
if((seen=H5SL_create(H5SL_TYPE_STR,0.5,H5P_DEFAULT_SKIPLIST_HEIGHT))==NULL)
5123
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties");
5126
/* Walk through the changed properties in the list */
5127
if(H5SL_count(plist->props)>0) {
5128
curr_node=H5SL_first(plist->props);
5129
while(curr_node!=NULL) {
5130
/* Get pointer to property from node */
5131
tmp=H5SL_item(curr_node);
5133
/* Call property close callback, if it exists */
5135
/* Call the 'close' callback */
5136
(tmp->close)(tmp->name,tmp->size,tmp->value);
5139
/* Add property name to "seen" list */
5140
if(H5SL_insert(seen,tmp->name,tmp->name)<0)
5141
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list");
5144
/* Get the next property node in the skip list */
5145
curr_node=H5SL_next(curr_node);
5149
/* Determine number of deleted items from property list */
5150
ndel=H5SL_count(plist->del);
5153
* Check if we should remove class properties (up through list of parent classes also),
5154
* initialize each with default value & make property 'remove' callback.
5156
tclass=plist->pclass;
5157
has_parent_class=(tclass!=NULL && tclass->parent!=NULL && tclass->parent->nprops>0);
5158
while(tclass!=NULL) {
5159
if(tclass->nprops>0) {
5160
/* Walk through the properties in the class */
5161
curr_node=H5SL_first(tclass->props);
5162
while(curr_node!=NULL) {
5163
/* Get pointer to property from node */
5164
tmp=H5SL_item(curr_node);
5166
/* Only "delete" properties we haven't seen before
5167
* and that haven't already been deleted
5169
if((nseen==0 || H5SL_search(seen,tmp->name)==NULL) &&
5170
(ndel==0 || H5SL_search(plist->del,tmp->name)==NULL)) {
5172
/* Call property close callback, if it exists */
5174
void *tmp_value; /* Temporary value buffer */
5176
/* Allocate space for a temporary copy of the property value */
5177
if (NULL==(tmp_value=H5MM_malloc(tmp->size)))
5178
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value");
5179
HDmemcpy(tmp_value,tmp->value,tmp->size);
5181
/* Call the 'close' callback */
5182
(tmp->close)(tmp->name,tmp->size,tmp_value);
5184
/* Release the temporary value buffer */
5185
H5MM_xfree(tmp_value);
5188
/* Add property name to "seen" list, if we have other classes to work on */
5189
if(has_parent_class) {
5190
if(H5SL_insert(seen,tmp->name,tmp->name)<0)
5191
HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list");
5196
/* Get the next property node in the skip list */
5197
curr_node=H5SL_next(curr_node);
5201
/* Go up to parent class */
5202
tclass=tclass->parent;
5205
/* Decrement class's dependant property list value! */
5206
if(H5P_access_class(plist->pclass,H5P_MOD_DEC_LST)<0)
5207
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "Can't decrement class ref count");
5209
/* Free the list of 'seen' properties */
5213
/* Free the list of deleted property names */
5214
H5SL_destroy(plist->del,H5P_free_del_name_cb,NULL);
5216
/* Free the properties */
5217
H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb);
5219
/* Destroy property list object */
5220
H5FL_FREE(H5P_genplist_t,plist);
5223
/* Release the skip list of 'seen' properties */
5227
FUNC_LEAVE_NOAPI(ret_value);
5231
/*--------------------------------------------------------------------------
5235
Routine to close a property list.
5237
herr_t H5Pclose(plist_id)
5238
hid_t plist_id; IN: Property list to close
5240
Returns non-negative on success, negative on failure.
5242
Closes a property list. If a 'close' callback exists for the property
5243
list class, it is called before the property list is destroyed. If 'close'
5244
callbacks exist for any individual properties in the property list, they are
5245
called after the class 'close' callback.
5248
COMMENTS, BUGS, ASSUMPTIONS
5251
--------------------------------------------------------------------------*/
5253
H5Pclose(hid_t plist_id)
5255
herr_t ret_value=SUCCEED; /* return value */
5257
FUNC_ENTER_API(H5Pclose, FAIL);
5258
H5TRACE1("e","i",plist_id);
5260
if (plist_id==H5P_DEFAULT)
5261
HGOTO_DONE(SUCCEED);
5263
/* Check arguments. */
5264
if (H5I_GENPROP_LST != H5I_get_type(plist_id))
5265
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
5267
/* Close the property list */
5268
if (H5I_dec_ref(plist_id) < 0)
5269
HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close");
5272
FUNC_LEAVE_API(ret_value);
5276
/*--------------------------------------------------------------------------
5280
Internal routine to query the name of a generic property list class
5282
char *H5P_get_class_name(pclass)
5283
H5P_genclass_t *pclass; IN: Property list class to check
5285
Success: Pointer to a malloc'ed string containing the class name
5288
This routine retrieves the name of a generic property list class.
5289
The pointer to the name must be free'd by the user for successful calls.
5292
COMMENTS, BUGS, ASSUMPTIONS
5295
--------------------------------------------------------------------------*/
5297
H5P_get_class_name(H5P_genclass_t *pclass)
5299
char *ret_value; /* return value */
5301
FUNC_ENTER_NOAPI(H5P_get_class_name, NULL);
5305
/* Get class name */
5306
ret_value=H5MM_xstrdup(pclass->name);
5309
FUNC_LEAVE_NOAPI(ret_value);
5310
} /* H5P_get_class_name() */
5313
/*--------------------------------------------------------------------------
5317
Routine to query the name of a generic property list class
5319
char *H5Pget_class_name(pclass_id)
5320
hid_t pclass_id; IN: Property class to query
5322
Success: Pointer to a malloc'ed string containing the class name
5325
This routine retrieves the name of a generic property list class.
5326
The pointer to the name must be free'd by the user for successful calls.
5329
COMMENTS, BUGS, ASSUMPTIONS
5332
--------------------------------------------------------------------------*/
5334
H5Pget_class_name(hid_t pclass_id)
5336
H5P_genclass_t *pclass; /* Property class to query */
5337
char *ret_value; /* return value */
5339
FUNC_ENTER_API(H5Pget_class_name, NULL);
5341
/* Check arguments. */
5342
if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
5343
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property class");
5345
/* Get the property list class name */
5346
if ((ret_value=H5P_get_class_name(pclass))==NULL)
5347
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "unable to query name of class");
5350
FUNC_LEAVE_API(ret_value);
5351
} /* H5Pget_class_name() */
5354
/*--------------------------------------------------------------------------
5358
Internal routine to query the full path of a generic property list class
5360
char *H5P_get_class_name(pclass)
5361
H5P_genclass_t *pclass; IN: Property list class to check
5363
Success: Pointer to a malloc'ed string containing the full path of class
5366
This routine retrieves the full path name of a generic property list
5367
class, starting with the root of the class hierarchy.
5368
The pointer to the name must be free'd by the user for successful calls.
5371
COMMENTS, BUGS, ASSUMPTIONS
5374
--------------------------------------------------------------------------*/
5376
H5P_get_class_path(H5P_genclass_t *pclass)
5378
char *par_path; /* Parent class's full path */
5379
size_t par_path_len;/* Parent class's full path's length */
5380
size_t my_path_len; /* This class's name's length */
5381
char *ret_value; /* return value */
5383
FUNC_ENTER_NOAPI_NOINIT(H5P_get_class_path);
5387
/* Recursively build the full path */
5388
if(pclass->parent!=NULL) {
5389
/* Get the parent class's path */
5390
par_path=H5P_get_class_path(pclass->parent);
5391
if(par_path!=NULL) {
5392
/* Get the string lengths we need to allocate space */
5393
par_path_len=HDstrlen(par_path);
5394
my_path_len=HDstrlen(pclass->name);
5396
/* Allocate enough space for the parent class's path, plus the '/'
5397
* separator, this class's name and the string terminator
5399
if(NULL==(ret_value=H5MM_malloc(par_path_len+1+my_path_len+1)))
5400
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for class name");
5402
/* Build the full path for this class */
5403
HDstrcpy(ret_value,par_path);
5404
HDstrcat(ret_value,"/");
5405
HDstrcat(ret_value,pclass->name);
5407
/* Free the parent class's path */
5408
H5MM_xfree(par_path);
5411
ret_value=H5MM_xstrdup(pclass->name);
5414
ret_value=H5MM_xstrdup(pclass->name);
5417
FUNC_LEAVE_NOAPI(ret_value);
5418
} /* H5P_get_class_path() */
5421
/*--------------------------------------------------------------------------
5425
Internal routine to open [a copy of] a class with its full path name
5427
H5P_genclass_t *H5P_open_class_path(path)
5428
const char *path; IN: Full path name of class to open [copy of]
5430
Success: Pointer to a generic property class object
5433
This routine opens [a copy] of the class indicated by the full path.
5436
COMMENTS, BUGS, ASSUMPTIONS
5439
--------------------------------------------------------------------------*/
5441
H5P_open_class_path(const char *path)
5443
char *tmp_path=NULL; /* Temporary copy of the path */
5444
char *curr_name; /* Pointer to current component of path name */
5445
char *delimit; /* Pointer to path delimiter during traversal */
5446
H5P_genclass_t *curr_class; /* Pointer to class during path traversal */
5447
H5P_genclass_t *ret_value; /* Return value */
5448
H5P_check_class_t check_info; /* Structure to hold the information for checking duplicate names */
5450
FUNC_ENTER_NOAPI_NOINIT(H5P_open_class_path);
5454
/* Duplicate the path to use */
5455
tmp_path=HDstrdup(path);
5458
/* Find the generic property class with this full path */
5461
while((delimit=HDstrchr(curr_name,'/'))!=NULL) {
5462
/* Change the delimiter to terminate the string */
5465
/* Set up the search structure */
5466
check_info.parent=curr_class;
5467
check_info.name=curr_name;
5469
/* Find the class with this name & parent by iterating over the open classes */
5470
if((curr_class=H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info))==NULL)
5471
HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class");
5473
/* Advance the pointer in the path to the start of the next component */
5474
curr_name=delimit+1;
5477
/* Should be pointing to the last component in the path name now... */
5479
/* Set up the search structure */
5480
check_info.parent=curr_class;
5481
check_info.name=curr_name;
5483
/* Find the class with this name & parent by iterating over the open classes */
5484
if((curr_class=H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info))==NULL)
5485
HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class");
5488
if((ret_value=H5P_copy_pclass(curr_class))==NULL)
5489
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL, "can't copy property class");
5492
/* Free the duplicated path */
5493
H5MM_xfree(tmp_path);
5495
FUNC_LEAVE_NOAPI(ret_value);
5496
} /* H5P_open_class_path() */
5499
/*--------------------------------------------------------------------------
5501
H5P_get_class_parent
5503
Internal routine to query the parent class of a generic property class
5505
H5P_genclass_t *H5P_get_class_parent(pclass)
5506
H5P_genclass_t *pclass; IN: Property class to check
5508
Success: Pointer to the parent class of a property class
5511
This routine retrieves a pointer to the parent class for a property class.
5514
COMMENTS, BUGS, ASSUMPTIONS
5517
--------------------------------------------------------------------------*/
5518
static H5P_genclass_t *
5519
H5P_get_class_parent(H5P_genclass_t *pclass)
5521
H5P_genclass_t *ret_value; /* return value */
5523
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class_parent);
5527
/* Get property size */
5528
ret_value=pclass->parent;
5530
FUNC_LEAVE_NOAPI(ret_value);
5531
} /* H5P_get_class_parent() */
5534
/*--------------------------------------------------------------------------
5538
routine to query the parent class of a generic property class
5540
hid_t H5Pget_class_parent(pclass_id)
5541
hid_t pclass_id; IN: Property class to query
5543
Success: ID of parent class object
5546
This routine retrieves an ID for the parent class of a property class.
5549
COMMENTS, BUGS, ASSUMPTIONS
5552
--------------------------------------------------------------------------*/
5554
H5Pget_class_parent(hid_t pclass_id)
5556
H5P_genclass_t *pclass; /* Property class to query */
5557
H5P_genclass_t *parent=NULL; /* Parent's property class */
5558
hid_t ret_value; /* return value */
5560
FUNC_ENTER_API(H5Pget_class_parent, FAIL);
5561
H5TRACE1("i","i",pclass_id);
5563
/* Check arguments. */
5564
if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
5565
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
5567
/* Retrieve the property class's parent */
5568
if ((parent=H5P_get_class_parent(pclass))==NULL)
5569
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to query class of property list");
5571
/* Increment the outstanding references to the class object */
5572
if(H5P_access_class(parent,H5P_MOD_INC_REF)<0)
5573
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count");
5575
/* Get an atom for the class */
5576
if ((ret_value = H5I_register(H5I_GENPROP_CLS, parent))<0)
5577
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
5580
if (ret_value<0 && parent)
5581
H5P_close_class(parent);
5583
FUNC_LEAVE_API(ret_value);
5584
} /* H5Pget_class_parent() */
5587
/*--------------------------------------------------------------------------
5591
Internal routine to close a property list class.
5593
herr_t H5P_close_class(class)
5594
H5P_genclass_t *class; IN: Property list class to close
5596
Returns non-negative on success, negative on failure.
5598
Releases memory and de-attach a class from the property list class hierarchy.
5600
COMMENTS, BUGS, ASSUMPTIONS
5603
--------------------------------------------------------------------------*/
5605
H5P_close_class(void *_pclass)
5607
H5P_genclass_t *pclass=(H5P_genclass_t *)_pclass;
5608
herr_t ret_value=SUCCEED; /* Return value */
5610
FUNC_ENTER_NOAPI_NOINIT(H5P_close_class);
5614
/* Decrement the reference count & check if the object should go away */
5615
if(H5P_access_class(pclass,H5P_MOD_DEC_REF)<0)
5616
HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, FAIL, "Can't decrement ID ref count");
5619
FUNC_LEAVE_NOAPI(ret_value);
5620
} /* H5P_close_class() */
5623
/*--------------------------------------------------------------------------
5627
Close a property list class.
5629
herr_t H5Pclose_class(cls_id)
5630
hid_t cls_id; IN: Property list class ID to class
5633
Returns non-negative on success, negative on failure.
5635
Releases memory and de-attach a class from the property list class hierarchy.
5637
COMMENTS, BUGS, ASSUMPTIONS
5640
--------------------------------------------------------------------------*/
5642
H5Pclose_class(hid_t cls_id)
5644
hid_t ret_value = SUCCEED; /* Return value */
5646
FUNC_ENTER_API(H5Pclose_class, FAIL);
5647
H5TRACE1("e","i",cls_id);
5649
/* Check arguments */
5650
if (H5I_GENPROP_CLS != H5I_get_type(cls_id))
5651
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
5653
/* Close the property list class */
5654
if (H5I_dec_ref(cls_id) < 0)
5655
HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close");
5658
FUNC_LEAVE_API(ret_value);
5659
} /* H5Pclose_class() */