~ubuntu-branches/ubuntu/karmic/paraview/karmic

« back to all changes in this revision

Viewing changes to Utilities/hdf5/H5P.c

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Prud'homme
  • Date: 2008-06-15 22:04:41 UTC
  • Revision ID: james.westby@ubuntu.com-20080615220441-8us51vf6ra2umcov
Tags: upstream-3.2.2
ImportĀ upstreamĀ versionĀ 3.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
2
 * Copyright by the Board of Trustees of the University of Illinois.         *
 
3
 * All rights reserved.                                                      *
 
4
 *                                                                           *
 
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
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
14
 
 
15
/* Programmer:  Quincey Koziol <koziol@ncsa.uiuc.edu>
 
16
 *
 
17
 * Purpose:  Generic Property Functions
 
18
 */
 
19
 
 
20
#define H5P_PACKAGE    /*suppress error about including H5Ppkg    */
 
21
 
 
22
/* Interface initialization */
 
23
#define H5_INTERFACE_INIT_FUNC  H5P_init_interface
 
24
 
 
25
 
 
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        */
 
35
 
 
36
/* Local macros */
 
37
#define H5P_DEFAULT_SKIPLIST_HEIGHT     8
 
38
 
 
39
/* Local variables */
 
40
 
 
41
/*
 
42
 * Predefined property list classes. These are initialized at runtime by
 
43
 * H5P_init_interface() in this source file.
 
44
 */
 
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;
 
51
 
 
52
/*
 
53
 * Predefined property lists for each predefined class. These are initialized
 
54
 * at runtime by H5P_init_interface() in this source file.
 
55
 */
 
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;
 
62
 
 
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++)
 
66
 
 
67
/* Declare a free list to manage the H5P_genprop_t struct */
 
68
H5FL_DEFINE(H5P_genprop_t);
 
69
 
 
70
/* Declare a free list to manage the H5P_genplist_t struct */
 
71
H5FL_DEFINE(H5P_genplist_t);
 
72
 
 
73
/* Declare a free list to manage the H5P_genclass_t struct */
 
74
H5FL_DEFINE_STATIC(H5P_genclass_t);
 
75
 
 
76
/* Local typedefs */
 
77
 
 
78
/* Typedef for checking for duplicate class names in parent class */
 
79
typedef struct {
 
80
    const H5P_genclass_t *parent;       /* Pointer to parent class */
 
81
    const char *name;                   /* Pointer to name to check */
 
82
} H5P_check_class_t;
 
83
 
 
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);
 
93
 
 
94
 
 
95
/*--------------------------------------------------------------------------
 
96
 NAME
 
97
    H5P_do_prop_cb1
 
98
 PURPOSE
 
99
    Internal routine to call a property list callback routine and update
 
100
    the property list accordingly.
 
101
 USAGE
 
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
 
106
 RETURNS
 
107
    Returns non-negative on success, negative on failure.
 
108
 DESCRIPTION
 
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.
 
111
 
 
112
 GLOBAL VARIABLES
 
113
 COMMENTS, BUGS, ASSUMPTIONS
 
114
 EXAMPLES
 
115
 REVISION LOG
 
116
--------------------------------------------------------------------------*/
 
117
static herr_t
 
118
H5P_do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb)
 
119
{
 
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 */
 
123
 
 
124
    FUNC_ENTER_NOAPI_NOINIT(H5P_do_prop_cb1);
 
125
 
 
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);
 
130
 
 
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");
 
134
 
 
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");
 
140
 
 
141
        /* Copy the changed value into the new property */
 
142
        HDmemcpy(pcopy->value,tmp_value,prop->size);
 
143
 
 
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");
 
147
    } /* end if */
 
148
 
 
149
done:
 
150
    /* Release the temporary value buffer */
 
151
    if(tmp_value!=NULL)
 
152
        H5MM_xfree(tmp_value);
 
153
 
 
154
    /* Cleanup on failure */
 
155
    if(ret_value<0) {
 
156
        if(pcopy!=NULL)
 
157
            H5P_free_prop(pcopy);
 
158
    } /* end if */
 
159
 
 
160
    FUNC_LEAVE_NOAPI(ret_value);
 
161
} /* end H5P_do_prop_cb1() */
 
162
 
 
163
 
 
164
/*-------------------------------------------------------------------------
 
165
 * Function:  H5P_init
 
166
 *
 
167
 * Purpose:  Initialize the interface from some other layer.
 
168
 *
 
169
 * Return:  Success:  non-negative
 
170
 *
 
171
 *    Failure:  negative
 
172
 *
 
173
 * Programmer:  Quincey Koziol
 
174
 *              Saturday, March 4, 2000
 
175
 *
 
176
 * Modifications:
 
177
 *
 
178
 *-------------------------------------------------------------------------
 
179
 */
 
180
herr_t
 
181
H5P_init(void)
 
182
{
 
183
    herr_t ret_value=SUCCEED;   /* Return value */
 
184
 
 
185
    FUNC_ENTER_NOAPI(H5P_init, FAIL);
 
186
    /* FUNC_ENTER() does all the work */
 
187
 
 
188
done:
 
189
    FUNC_LEAVE_NOAPI(ret_value);
 
190
}
 
191
 
 
192
 
 
193
/*--------------------------------------------------------------------------
 
194
NAME
 
195
   H5P_init_interface -- Initialize interface-specific information
 
196
USAGE
 
197
    herr_t H5P_init_interface()
 
198
 
 
199
RETURNS
 
200
    Non-negative on success/Negative on failure
 
201
DESCRIPTION
 
202
    Initializes any interface-specific data or routines.
 
203
 
 
204
--------------------------------------------------------------------------*/
 
205
static herr_t
 
206
H5P_init_interface(void)
 
207
{
 
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;
 
211
 
 
212
    FUNC_ENTER_NOAPI_NOINIT(H5P_init_interface);
 
213
 
 
214
    /*
 
215
     * Initialize the Generic Property class & object groups.
 
216
     */
 
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");
 
221
 
 
222
    /* Create root property list class */
 
223
 
 
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");
 
228
 
 
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");
 
232
 
 
233
    /* Register the file creation and file access property classes */
 
234
 
 
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");
 
239
 
 
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");
 
243
 
 
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");
 
248
 
 
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");
 
252
 
 
253
    /* Register the dataset creation and data xfer property classes */
 
254
 
 
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");
 
259
 
 
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");
 
263
 
 
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");
 
268
 
 
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");
 
272
 
 
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");
 
277
 
 
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");
 
281
 
 
282
done:
 
283
    FUNC_LEAVE_NOAPI(ret_value);
 
284
}
 
285
 
 
286
 
 
287
/*--------------------------------------------------------------------------
 
288
 NAME
 
289
    H5P_term_interface
 
290
 PURPOSE
 
291
    Terminate various H5P objects
 
292
 USAGE
 
293
    void H5P_term_interface()
 
294
 RETURNS
 
295
    Non-negative on success/Negative on failure
 
296
 DESCRIPTION
 
297
    Release the atom group and any other resources allocated.
 
298
 GLOBAL VARIABLES
 
299
 COMMENTS, BUGS, ASSUMPTIONS
 
300
     Can't report errors...
 
301
 EXAMPLES
 
302
 REVISION LOG
 
303
--------------------------------------------------------------------------*/
 
304
int
 
305
H5P_term_interface(void)
 
306
{
 
307
    int  nlist=0;
 
308
    int  nclass=0;
 
309
    int  n=0;
 
310
 
 
311
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_term_interface);
 
312
 
 
313
    if (H5_interface_initialize_g) {
 
314
        /* Destroy HDF5 library property classes & lists */
 
315
 
 
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);
 
319
        n=nclass+nlist;
 
320
 
 
321
        /* If there are any open classes or groups, attempt to get rid of them. */
 
322
        if (n) {
 
323
            /* Clear the lists */
 
324
            if(nlist>0) {
 
325
                H5I_clear_group(H5I_GENPROP_LST, FALSE);
 
326
 
 
327
                /* Reset the default property lists, if they've been closed */
 
328
                if(H5I_nmembers(H5I_GENPROP_LST)==0) {
 
329
                    H5P_LST_NO_CLASS_g =
 
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);
 
335
                } /* end if */
 
336
            } /* end if */
 
337
 
 
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);
 
341
 
 
342
                /* Reset the default property lists, if they've been closed */
 
343
                if(H5I_nmembers(H5I_GENPROP_CLS)==0) {
 
344
                    H5P_CLS_NO_CLASS_g =
 
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);
 
350
                } /* end if */
 
351
            } /* end if */
 
352
        } else {
 
353
            H5I_destroy_group(H5I_GENPROP_LST);
 
354
            n++; /*H5I*/
 
355
            H5I_destroy_group(H5I_GENPROP_CLS);
 
356
            n++; /*H5I*/
 
357
 
 
358
            H5_interface_initialize_g = 0;
 
359
        }
 
360
    }
 
361
    FUNC_LEAVE_NOAPI(n);
 
362
}
 
363
 
 
364
 
 
365
/*--------------------------------------------------------------------------
 
366
 NAME
 
367
    H5P_copy_pclass
 
368
 PURPOSE
 
369
    Internal routine to copy a generic property class
 
370
 USAGE
 
371
    hid_t H5P_copy_pclass(pclass)
 
372
        H5P_genclass_t *pclass;      IN: Property class to copy
 
373
 RETURNS
 
374
    Success: valid property class ID on success (non-negative)
 
375
    Failure: negative
 
376
 DESCRIPTION
 
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).
 
379
 
 
380
 GLOBAL VARIABLES
 
381
 COMMENTS, BUGS, ASSUMPTIONS
 
382
 EXAMPLES
 
383
 REVISION LOG
 
384
--------------------------------------------------------------------------*/
 
385
static H5P_genclass_t *
 
386
H5P_copy_pclass(H5P_genclass_t *pclass)
 
387
{
 
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 */
 
391
 
 
392
    FUNC_ENTER_NOAPI_NOINIT(H5P_copy_pclass);
 
393
 
 
394
    assert(pclass);
 
395
 
 
396
    /*
 
397
     * Create new property class object
 
398
     */
 
399
 
 
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");
 
403
 
 
404
    /* Copy the properties registered for this class */
 
405
    if(pclass->nprops>0) {
 
406
        H5SL_node_t *curr_node;   /* Current node in skip list */
 
407
 
 
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");
 
414
 
 
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");
 
418
 
 
419
            /* Increment property count for class */
 
420
            new_pclass->nprops++;
 
421
 
 
422
            /* Get the next property node in the list */
 
423
            curr_node=H5SL_next(curr_node);
 
424
        } /* end while */
 
425
    } /* end if */
 
426
 
 
427
    /* Set the return value */
 
428
    ret_value=new_pclass;
 
429
 
 
430
done:
 
431
    if (ret_value==NULL && new_pclass)
 
432
        H5P_close_class(new_pclass);
 
433
 
 
434
    FUNC_LEAVE_NOAPI(ret_value);
 
435
}   /* H5P_copy_pclass() */
 
436
 
 
437
 
 
438
/*--------------------------------------------------------------------------
 
439
 NAME
 
440
    H5P_copy_plist
 
441
 PURPOSE
 
442
    Internal routine to copy a generic property list
 
443
 USAGE
 
444
        hid_t H5P_copy_plist(old_plist_id)
 
445
            hid_t old_plist_id;             IN: Property list ID to copy
 
446
 RETURNS
 
447
    Success: valid property list ID on success (non-negative)
 
448
    Failure: negative
 
449
 DESCRIPTION
 
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).
 
453
 
 
454
 GLOBAL VARIABLES
 
455
 COMMENTS, BUGS, ASSUMPTIONS
 
456
 EXAMPLES
 
457
 REVISION LOG
 
458
--------------------------------------------------------------------------*/
 
459
hid_t
 
460
H5P_copy_plist(H5P_genplist_t *old_plist)
 
461
{
 
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 */
 
472
 
 
473
    FUNC_ENTER_NOAPI(H5P_copy_plist, FAIL);
 
474
 
 
475
    assert(old_plist);
 
476
 
 
477
    /*
 
478
     * Create new property list object
 
479
     */
 
480
 
 
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");
 
484
 
 
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 */
 
489
 
 
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");
 
493
 
 
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");
 
497
 
 
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
 
501
     * already been seen)
 
502
     */
 
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");
 
505
    nseen=0;
 
506
 
 
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);
 
510
        while(curr_node) {
 
511
            char *new_name;   /* Pointer to new name */
 
512
 
 
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");
 
516
 
 
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");
 
520
 
 
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");
 
524
            nseen++;
 
525
 
 
526
            /* Get the next property node in the skip list */
 
527
            curr_node=H5SL_next(curr_node);
 
528
        } /* end while */
 
529
    } /* end if */
 
530
 
 
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);
 
534
        while(curr_node) {
 
535
            /* Get a pointer to the node's property */
 
536
            tmp=H5SL_item(curr_node);
 
537
 
 
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");
 
541
 
 
542
            /* Call property copy callback, if it exists */
 
543
            if(new_prop->copy) {
 
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");
 
547
                } /* end if */
 
548
            } /* end if */
 
549
 
 
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");
 
554
            } /* end if */
 
555
 
 
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");
 
559
            nseen++;
 
560
 
 
561
            /* Increment the number of properties in list */
 
562
            new_plist->nprops++;
 
563
 
 
564
            /* Get the next property node in the skip list */
 
565
            curr_node=H5SL_next(curr_node);
 
566
        } /* end while */
 
567
    } /* end if */
 
568
 
 
569
    /*
 
570
     * Check for copying class properties (up through list of parent classes also),
 
571
     * initialize each with default value & make property 'copy' callback.
 
572
     */
 
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);
 
582
 
 
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 */
 
586
                    if(tmp->copy) {
 
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");
 
590
                    } /* end if */
 
591
 
 
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");
 
596
                        nseen++;
 
597
                    } /* end if */
 
598
 
 
599
                    /* Increment the number of properties in list */
 
600
                    new_plist->nprops++;
 
601
                } /* end if */
 
602
 
 
603
                /* Get the next property node in the skip list */
 
604
                curr_node=H5SL_next(curr_node);
 
605
            } /* end while */
 
606
        } /* end if */
 
607
 
 
608
        /* Go up to parent class */
 
609
        tclass=tclass->parent;
 
610
    } /* end while */
 
611
 
 
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");
 
615
 
 
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");
 
619
 
 
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;
 
622
 
 
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");
 
629
        } /* end if */
 
630
    } /* end if */
 
631
 
 
632
    /* Set the class initialization flag */
 
633
    new_plist->class_init=1;
 
634
 
 
635
    /* Set the return value */
 
636
    ret_value=new_plist_id;
 
637
 
 
638
done:
 
639
    /* Release the list of 'seen' properties */
 
640
    if(seen!=NULL)
 
641
        H5SL_close(seen);
 
642
 
 
643
    if (ret_value<0 && new_plist)
 
644
        H5P_close(new_plist);
 
645
 
 
646
    FUNC_LEAVE_NOAPI(ret_value);
 
647
}   /* H5P_copy_plist() */
 
648
 
 
649
 
 
650
/*--------------------------------------------------------------------------
 
651
 NAME
 
652
    H5Pcopy
 
653
 PURPOSE
 
654
    Routine to copy a property list or class
 
655
 USAGE
 
656
    hid_t H5Pcopy(id)
 
657
        hid_t id;           IN: Property list or class ID to copy
 
658
 RETURNS
 
659
    Success: valid property list ID on success (non-negative)
 
660
    Failure: negative
 
661
 DESCRIPTION
 
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).
 
665
 
 
666
 GLOBAL VARIABLES
 
667
 COMMENTS, BUGS, ASSUMPTIONS
 
668
 EXAMPLES
 
669
 REVISION LOG
 
670
--------------------------------------------------------------------------*/
 
671
hid_t
 
672
H5Pcopy(hid_t id)
 
673
{
 
674
    void *obj;                 /* Property object to copy */
 
675
    hid_t ret_value=FALSE;      /* return value */
 
676
 
 
677
    FUNC_ENTER_API(H5Pcopy, FAIL);
 
678
    H5TRACE1("i","i",id);
 
679
 
 
680
    if (H5P_DEFAULT==id)
 
681
        HGOTO_DONE(H5P_DEFAULT);
 
682
 
 
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");
 
688
 
 
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");
 
693
    } /* end if */
 
694
    /* Must be property classes */
 
695
    else {
 
696
        H5P_genclass_t *copy_class;      /* Copy of class */
 
697
 
 
698
        /* Copy the class */
 
699
        if((copy_class=H5P_copy_pclass(obj))==NULL)
 
700
            HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property class");
 
701
 
 
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");
 
706
        } /* end if */
 
707
    } /* end else */
 
708
 
 
709
done:
 
710
    FUNC_LEAVE_API(ret_value);
 
711
}   /* H5Pcopy() */
 
712
 
 
713
 
 
714
/*--------------------------------------------------------------------------
 
715
 NAME
 
716
    H5P_dup_prop
 
717
 PURPOSE
 
718
    Internal routine to duplicate a property
 
719
 USAGE
 
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
 
723
 RETURNS
 
724
    Returns a pointer to the newly created duplicate of a property on success,
 
725
        NULL on failure.
 
726
 DESCRIPTION
 
727
    Allocates memory and copies property information into a new property object.
 
728
 GLOBAL VARIABLES
 
729
 COMMENTS, BUGS, ASSUMPTIONS
 
730
 EXAMPLES
 
731
 REVISION LOG
 
732
--------------------------------------------------------------------------*/
 
733
static H5P_genprop_t *
 
734
H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type)
 
735
{
 
736
    H5P_genprop_t *prop=NULL;        /* Pointer to new property copied */
 
737
    H5P_genprop_t *ret_value;        /* Return value */
 
738
 
 
739
    FUNC_ENTER_NOAPI_NOINIT(H5P_dup_prop);
 
740
 
 
741
    assert(oprop);
 
742
    assert(type!=H5P_PROP_WITHIN_UNKNOWN);
 
743
 
 
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");
 
747
 
 
748
    /* Copy basic property information */
 
749
    HDmemcpy(prop,oprop,sizeof(H5P_genprop_t));
 
750
 
 
751
    /* Check if we should duplicate the name or share it */
 
752
 
 
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);
 
757
 
 
758
        /* Duplicate name */
 
759
        prop->name = H5MM_xstrdup(oprop->name);
 
760
    } /* end if */
 
761
    /* Duplicating property for a list */
 
762
    else {
 
763
        /* Check if we are duplicating a property from a list or a class */
 
764
 
 
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);
 
770
        } /* end if */
 
771
        /* Duplicating a property from a class */
 
772
        else {
 
773
            assert(oprop->type==H5P_PROP_WITHIN_CLASS);
 
774
            assert(oprop->shared_name==0);
 
775
 
 
776
            /* Share the name */
 
777
            prop->shared_name=1;
 
778
 
 
779
            /* Set the type */
 
780
            prop->type=type;
 
781
        } /* end else */
 
782
    } /* end else */
 
783
 
 
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);
 
790
    } /* end if */
 
791
 
 
792
    /* Set return value */
 
793
    ret_value=prop;
 
794
 
 
795
done:
 
796
    /* Free any resources allocated */
 
797
    if(ret_value==NULL) {
 
798
        if(prop!=NULL) {
 
799
            if(prop->name!=NULL)
 
800
                H5MM_xfree(prop->name);
 
801
            if(prop->value!=NULL)
 
802
                H5MM_xfree(prop->value);
 
803
            H5FL_FREE(H5P_genprop_t,prop);
 
804
        } /* end if */
 
805
    } /* end if */
 
806
 
 
807
    FUNC_LEAVE_NOAPI(ret_value);
 
808
}   /* H5P_dup_prop() */
 
809
 
 
810
 
 
811
/*--------------------------------------------------------------------------
 
812
 NAME
 
813
    H5P_create_prop
 
814
 PURPOSE
 
815
    Internal routine to create a new property
 
816
 USAGE
 
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
 
824
                                    creation callback
 
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
 
831
                                    callback
 
832
 RETURNS
 
833
    Returns a pointer to the newly created property on success,
 
834
        NULL on failure.
 
835
 DESCRIPTION
 
836
    Allocates memory and copies property information into a new property object.
 
837
 GLOBAL VARIABLES
 
838
 COMMENTS, BUGS, ASSUMPTIONS
 
839
 EXAMPLES
 
840
 REVISION LOG
 
841
--------------------------------------------------------------------------*/
 
842
static H5P_genprop_t *
 
843
H5P_create_prop(const char *name, size_t size, H5P_prop_within_t type,
 
844
    void *value,
 
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)
 
849
{
 
850
    H5P_genprop_t *prop=NULL;        /* Pointer to new property copied */
 
851
    H5P_genprop_t *ret_value;        /* Return value */
 
852
 
 
853
    FUNC_ENTER_NOAPI_NOINIT(H5P_create_prop);
 
854
 
 
855
    assert(name);
 
856
    assert((size>0 && value!=NULL) || (size==0));
 
857
    assert(type!=H5P_PROP_WITHIN_UNKNOWN);
 
858
 
 
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");
 
862
 
 
863
    /* Set the property initial values */
 
864
    prop->name = H5MM_xstrdup(name); /* Duplicate name */
 
865
    prop->shared_name=0;
 
866
    prop->size=size;
 
867
    prop->type=type;
 
868
 
 
869
    /* Duplicate value, if it exists */
 
870
    if(value!=NULL) {
 
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);
 
874
    } /* end if */
 
875
    else
 
876
        prop->value=NULL;
 
877
 
 
878
    /* Set the function pointers */
 
879
    prop->create=prp_create;
 
880
    prop->set=prp_set;
 
881
    prop->get=prp_get;
 
882
    prop->del=prp_delete;
 
883
    prop->copy=prp_copy;
 
884
    /* Use custom comparison routine if available, otherwise default to memcmp() */
 
885
    if(prp_cmp!=NULL)
 
886
        prop->cmp=prp_cmp;
 
887
    else
 
888
        prop->cmp=&memcmp;
 
889
    prop->close=prp_close;
 
890
 
 
891
    /* Set return value */
 
892
    ret_value=prop;
 
893
 
 
894
done:
 
895
    /* Free any resources allocated */
 
896
    if(ret_value==NULL) {
 
897
        if(prop!=NULL) {
 
898
            if(prop->name!=NULL)
 
899
                H5MM_xfree(prop->name);
 
900
            if(prop->value!=NULL)
 
901
                H5MM_xfree(prop->value);
 
902
            H5FL_FREE(H5P_genprop_t,prop);
 
903
        } /* end if */
 
904
    } /* end if */
 
905
 
 
906
    FUNC_LEAVE_NOAPI(ret_value);
 
907
}   /* H5P_create_prop() */
 
908
 
 
909
 
 
910
/*--------------------------------------------------------------------------
 
911
 NAME
 
912
    H5P_add_prop
 
913
 PURPOSE
 
914
    Internal routine to insert a property into a property skip list
 
915
 USAGE
 
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
 
919
 RETURNS
 
920
    Returns non-negative on success, negative on failure.
 
921
 DESCRIPTION
 
922
    Inserts a property into a skip list of properties.
 
923
 GLOBAL VARIABLES
 
924
 COMMENTS, BUGS, ASSUMPTIONS
 
925
 EXAMPLES
 
926
 REVISION LOG
 
927
--------------------------------------------------------------------------*/
 
928
herr_t
 
929
H5P_add_prop(H5SL_t *slist, H5P_genprop_t *prop)
 
930
{
 
931
    herr_t      ret_value=SUCCEED;       /* Return value */
 
932
 
 
933
    FUNC_ENTER_NOAPI(H5P_add_prop,FAIL);
 
934
 
 
935
    assert(slist);
 
936
    assert(prop);
 
937
    assert(prop->type!=H5P_PROP_WITHIN_UNKNOWN);
 
938
 
 
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");
 
942
 
 
943
done:
 
944
    FUNC_LEAVE_NOAPI(ret_value);
 
945
}   /* H5P_add_prop() */
 
946
 
 
947
 
 
948
/*--------------------------------------------------------------------------
 
949
 NAME
 
950
    H5P_find_prop_plist
 
951
 PURPOSE
 
952
    Internal routine to check for a property in a property list's skip list
 
953
 USAGE
 
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
 
957
 RETURNS
 
958
    Returns pointer to property on success, NULL on failure.
 
959
 DESCRIPTION
 
960
    Checks for a property in a property list's skip list of properties.
 
961
 GLOBAL VARIABLES
 
962
 COMMENTS, BUGS, ASSUMPTIONS
 
963
 EXAMPLES
 
964
 REVISION LOG
 
965
--------------------------------------------------------------------------*/
 
966
static H5P_genprop_t *
 
967
H5P_find_prop_plist(H5P_genplist_t *plist, const char *name)
 
968
{
 
969
    H5P_genprop_t *ret_value;   /* Property pointer return value */
 
970
 
 
971
    FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_plist);
 
972
 
 
973
    assert(plist);
 
974
    assert(name);
 
975
 
 
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");
 
979
    } /* end if */
 
980
    else {
 
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 */
 
984
 
 
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 */
 
991
                    break;
 
992
 
 
993
                /* Go up to parent class */
 
994
                tclass=tclass->parent;
 
995
            } /* end while */
 
996
 
 
997
            /* Check if we haven't found the property */
 
998
            if(ret_value==NULL)
 
999
                HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list");
 
1000
        } /* end else */
 
1001
    } /* end else */
 
1002
 
 
1003
done:
 
1004
    FUNC_LEAVE_NOAPI(ret_value);
 
1005
}   /* H5P_find_prop_plist() */
 
1006
 
 
1007
 
 
1008
/*--------------------------------------------------------------------------
 
1009
 NAME
 
1010
    H5P_find_prop_pclass
 
1011
 PURPOSE
 
1012
    Internal routine to check for a property in a class skip list
 
1013
 USAGE
 
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
 
1017
 RETURNS
 
1018
    Returns pointer to property on success, NULL on failure.
 
1019
 DESCRIPTION
 
1020
    Checks for a property in a class's skip list of properties.
 
1021
 GLOBAL VARIABLES
 
1022
 COMMENTS, BUGS, ASSUMPTIONS
 
1023
 EXAMPLES
 
1024
 REVISION LOG
 
1025
--------------------------------------------------------------------------*/
 
1026
static H5P_genprop_t *
 
1027
H5P_find_prop_pclass(H5P_genclass_t *pclass, const char *name)
 
1028
{
 
1029
    H5P_genprop_t *ret_value;   /* Property pointer return value */
 
1030
 
 
1031
    FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_pclass);
 
1032
 
 
1033
    assert(pclass);
 
1034
    assert(name);
 
1035
 
 
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");
 
1039
 
 
1040
done:
 
1041
    FUNC_LEAVE_NOAPI(ret_value);
 
1042
}   /* H5P_find_prop_pclass() */
 
1043
 
 
1044
 
 
1045
/*--------------------------------------------------------------------------
 
1046
 NAME
 
1047
    H5P_free_prop
 
1048
 PURPOSE
 
1049
    Internal routine to destroy a property node
 
1050
 USAGE
 
1051
    herr_t H5P_free_prop(prop)
 
1052
        H5P_genprop_t *prop;    IN: Pointer to property to destroy
 
1053
 RETURNS
 
1054
    Returns non-negative on success, negative on failure.
 
1055
 DESCRIPTION
 
1056
    Releases all the memory for a property list.  Does _not_ call the
 
1057
    properties 'close' callback, that should already have been done.
 
1058
 GLOBAL VARIABLES
 
1059
 COMMENTS, BUGS, ASSUMPTIONS
 
1060
 EXAMPLES
 
1061
 REVISION LOG
 
1062
--------------------------------------------------------------------------*/
 
1063
static herr_t
 
1064
H5P_free_prop(H5P_genprop_t *prop)
 
1065
{
 
1066
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop);
 
1067
 
 
1068
    assert(prop);
 
1069
 
 
1070
    /* Release the property value if it exists */
 
1071
    if(prop->value)
 
1072
        H5MM_xfree(prop->value);
 
1073
 
 
1074
    /* Only free the name if we own it */
 
1075
    if(prop->shared_name==0)
 
1076
        H5MM_xfree(prop->name);
 
1077
 
 
1078
    H5FL_FREE(H5P_genprop_t,prop);
 
1079
 
 
1080
    FUNC_LEAVE_NOAPI(SUCCEED);
 
1081
}   /* H5P_free_prop() */
 
1082
 
 
1083
 
 
1084
/*--------------------------------------------------------------------------
 
1085
 NAME
 
1086
    H5P_free_prop_cb
 
1087
 PURPOSE
 
1088
    Internal routine to properties from a property skip list
 
1089
 USAGE
 
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
 
1094
 RETURNS
 
1095
    Returns zero on success, negative on failure.
 
1096
 DESCRIPTION
 
1097
        Calls the property 'close' callback for a property & frees property
 
1098
    info.
 
1099
 GLOBAL VARIABLES
 
1100
 COMMENTS, BUGS, ASSUMPTIONS
 
1101
 EXAMPLES
 
1102
 REVISION LOG
 
1103
--------------------------------------------------------------------------*/
 
1104
static herr_t
 
1105
H5P_free_prop_cb(void *item, void UNUSED *key, void *op_data)
 
1106
{
 
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 */
 
1109
 
 
1110
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop_cb);
 
1111
 
 
1112
    assert(tprop);
 
1113
 
 
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);
 
1117
 
 
1118
    /* Free the property, ignoring return value, nothing we can do */
 
1119
    H5P_free_prop(tprop);
 
1120
 
 
1121
    FUNC_LEAVE_NOAPI(0);
 
1122
}   /* H5P_free_prop_cb() */
 
1123
 
 
1124
 
 
1125
/*--------------------------------------------------------------------------
 
1126
 NAME
 
1127
    H5P_free_del_name_cb
 
1128
 PURPOSE
 
1129
    Internal routine to free 'deleted' property name
 
1130
 USAGE
 
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)
 
1135
 RETURNS
 
1136
    Returns zero on success, negative on failure.
 
1137
 DESCRIPTION
 
1138
    Frees the deleted property name
 
1139
 GLOBAL VARIABLES
 
1140
 COMMENTS, BUGS, ASSUMPTIONS
 
1141
 EXAMPLES
 
1142
 REVISION LOG
 
1143
--------------------------------------------------------------------------*/
 
1144
static herr_t
 
1145
H5P_free_del_name_cb(void *item, void UNUSED *key, void UNUSED *op_data)
 
1146
{
 
1147
    char *del_name=(char *)item;       /* Temporary pointer to deleted name */
 
1148
 
 
1149
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_del_name_cb);
 
1150
 
 
1151
    assert(del_name);
 
1152
 
 
1153
    /* Free the name */
 
1154
    H5MM_xfree(del_name);
 
1155
 
 
1156
    FUNC_LEAVE_NOAPI(0);
 
1157
}   /* H5P_free_del_name_cb() */
 
1158
 
 
1159
 
 
1160
/*--------------------------------------------------------------------------
 
1161
 NAME
 
1162
    H5P_access_class
 
1163
 PURPOSE
 
1164
    Internal routine to increment or decrement list & class dependancies on a
 
1165
        property list class
 
1166
 USAGE
 
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
 
1170
 RETURNS
 
1171
    Returns non-negative on success, negative on failure.
 
1172
 DESCRIPTION
 
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.
 
1177
 GLOBAL VARIABLES
 
1178
 COMMENTS, BUGS, ASSUMPTIONS
 
1179
 EXAMPLES
 
1180
 REVISION LOG
 
1181
--------------------------------------------------------------------------*/
 
1182
herr_t
 
1183
H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
 
1184
{
 
1185
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_access_class);
 
1186
 
 
1187
    assert(pclass);
 
1188
    assert(mod>H5P_MOD_ERR && mod<H5P_MOD_MAX);
 
1189
 
 
1190
    switch(mod) {
 
1191
        case H5P_MOD_INC_CLS:        /* Increment the dependant class count*/
 
1192
            pclass->classes++;
 
1193
            break;
 
1194
 
 
1195
        case H5P_MOD_DEC_CLS:        /* Decrement the dependant class count*/
 
1196
            pclass->classes--;
 
1197
            break;
 
1198
 
 
1199
        case H5P_MOD_INC_LST:        /* Increment the dependant list count*/
 
1200
            pclass->plists++;
 
1201
            break;
 
1202
 
 
1203
        case H5P_MOD_DEC_LST:        /* Decrement the dependant list count*/
 
1204
            pclass->plists--;
 
1205
            break;
 
1206
 
 
1207
        case H5P_MOD_INC_REF:        /* Increment the ID reference count*/
 
1208
            /* Reset the deleted flag if incrementing the reference count */
 
1209
            if(pclass->deleted)
 
1210
                pclass->deleted=0;
 
1211
            pclass->ref_count++;
 
1212
            break;
 
1213
 
 
1214
        case H5P_MOD_DEC_REF:        /* Decrement the ID reference count*/
 
1215
            pclass->ref_count--;
 
1216
 
 
1217
            /* Mark the class object as deleted if reference count drops to zero */
 
1218
            if(pclass->ref_count==0)
 
1219
                pclass->deleted=1;
 
1220
            break;
 
1221
 
 
1222
        case H5P_MOD_ERR:
 
1223
        case H5P_MOD_MAX:
 
1224
            assert(0 && "Invalid H5P class modification");
 
1225
    } /* end switch */
 
1226
 
 
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 */
 
1230
 
 
1231
        assert(pclass->name);
 
1232
        H5MM_xfree(pclass->name);
 
1233
 
 
1234
        /* Free the class properties without making callbacks */
 
1235
        if(pclass->props) {
 
1236
            unsigned make_cb=0;
 
1237
 
 
1238
            H5SL_destroy(pclass->props,H5P_free_prop_cb,&make_cb);
 
1239
        } /* end if */
 
1240
 
 
1241
        H5FL_FREE(H5P_genclass_t,pclass);
 
1242
 
 
1243
        /* Reduce the number of dependent classes on parent class also */
 
1244
        if(par_class!=NULL)
 
1245
            H5P_access_class(par_class, H5P_MOD_DEC_CLS);
 
1246
    } /* end if */
 
1247
 
 
1248
    FUNC_LEAVE_NOAPI(SUCCEED);
 
1249
}   /* H5P_access_class() */
 
1250
 
 
1251
 
 
1252
/*--------------------------------------------------------------------------
 
1253
 NAME
 
1254
    H5P_check_class
 
1255
 PURPOSE
 
1256
    Internal callback routine to check for duplicated names in parent class.
 
1257
 USAGE
 
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
 
1262
                                    classes.
 
1263
 RETURNS
 
1264
    Returns >0 on match, 0 on no match and <0 on failure.
 
1265
 DESCRIPTION
 
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()
 
1268
 GLOBAL VARIABLES
 
1269
 COMMENTS, BUGS, ASSUMPTIONS
 
1270
 EXAMPLES
 
1271
 REVISION LOG
 
1272
--------------------------------------------------------------------------*/
 
1273
static int
 
1274
H5P_check_class(void *_obj, hid_t UNUSED id, void *_key)
 
1275
{
 
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 */
 
1279
 
 
1280
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_check_class);
 
1281
 
 
1282
    assert(obj);
 
1283
    assert(H5I_GENPROP_CLS==H5I_get_type(id));
 
1284
    assert(key);
 
1285
 
 
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 */
 
1291
    } /* end if */
 
1292
 
 
1293
    FUNC_LEAVE_NOAPI(ret_value);
 
1294
} /* end H5P_check_class() */
 
1295
 
 
1296
 
 
1297
/*--------------------------------------------------------------------------
 
1298
 NAME
 
1299
    H5P_create_class
 
1300
 PURPOSE
 
1301
    Internal routine to create a new property list class.
 
1302
 USAGE
 
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
 
1311
                                    creation callback.
 
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
 
1315
                                    copy callback.
 
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
 
1319
                                    close callback.
 
1320
 RETURNS
 
1321
    Returns a pointer to the newly created property list class on success,
 
1322
        NULL on failure.
 
1323
 DESCRIPTION
 
1324
    Allocates memory and attaches a class to the property list class hierarchy.
 
1325
 GLOBAL VARIABLES
 
1326
 COMMENTS, BUGS, ASSUMPTIONS
 
1327
 EXAMPLES
 
1328
 REVISION LOG
 
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
 
1335
    )
 
1336
{
 
1337
    H5P_genclass_t *pclass=NULL;   /* Property list class created */
 
1338
    H5P_genclass_t *ret_value;     /* return value */
 
1339
 
 
1340
    FUNC_ENTER_NOAPI_NOINIT(H5P_create_class);
 
1341
 
 
1342
    assert(name);
 
1343
    /* Allow internal classes to break some rules */
 
1344
    /* (This allows the root of the tree to be created with this routine -QAK) */
 
1345
    if(!internal) {
 
1346
        assert(par_class);
 
1347
    }
 
1348
 
 
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");
 
1352
 
 
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 */
 
1363
 
 
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");
 
1367
 
 
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;
 
1375
 
 
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");
 
1380
    } /* end if */
 
1381
 
 
1382
    /* Set return value */
 
1383
    ret_value=pclass;
 
1384
 
 
1385
done:
 
1386
    /* Free any resources allocated */
 
1387
    if(ret_value==NULL) {
 
1388
        if(pclass!=NULL)
 
1389
            H5FL_FREE(H5P_genclass_t,pclass);
 
1390
    }
 
1391
 
 
1392
    FUNC_LEAVE_NOAPI(ret_value);
 
1393
}   /* H5P_create_class() */
 
1394
 
 
1395
 
 
1396
/*--------------------------------------------------------------------------
 
1397
 NAME
 
1398
    H5Pcreate_class
 
1399
 PURPOSE
 
1400
    Create a new property list class.
 
1401
 USAGE
 
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
 
1408
                                    created.
 
1409
        void *create_data;  IN: Pointer to user data to pass along to class
 
1410
                                    creation callback.
 
1411
        H5P_cls_copy_func_t cls_copy;   IN: The callback function to call
 
1412
                                    when each property list in this class is
 
1413
                                    copied.
 
1414
        void *copy_data;  IN: Pointer to user data to pass along to class
 
1415
                                    copy callback.
 
1416
        H5P_cls_close_func_t cls_close;     IN: The callback function to call
 
1417
                                    when each property list in this class is
 
1418
                                    closed.
 
1419
        void *close_data;   IN: Pointer to user data to pass along to class
 
1420
                                    close callback.
 
1421
 RETURNS
 
1422
    Returns a valid property list class ID on success, NULL on failure.
 
1423
 DESCRIPTION
 
1424
    Allocates memory and attaches a class to the property list class hierarchy.
 
1425
 GLOBAL VARIABLES
 
1426
 COMMENTS, BUGS, ASSUMPTIONS
 
1427
 EXAMPLES
 
1428
 REVISION LOG
 
1429
--------------------------------------------------------------------------*/
 
1430
hid_t
 
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
 
1435
    )
 
1436
{
 
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       */
 
1440
 
 
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);
 
1444
 
 
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");
 
1454
 
 
1455
    /* Get the pointer to the parent class */
 
1456
    if(parent==H5P_DEFAULT)
 
1457
        par_class=NULL;
 
1458
    else if (NULL == (par_class = H5I_object(parent)))
 
1459
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't retrieve parent class");
 
1460
 
 
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");
 
1464
 
 
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");
 
1468
 
 
1469
done:
 
1470
    if (ret_value<0 && pclass)
 
1471
        H5P_close_class(pclass);
 
1472
 
 
1473
    FUNC_LEAVE_API(ret_value);
 
1474
}   /* H5Pcreate_class() */
 
1475
 
 
1476
 
 
1477
/*--------------------------------------------------------------------------
 
1478
 NAME
 
1479
    H5P_create
 
1480
 PURPOSE
 
1481
    Internal routine to create a new property list of a property list class.
 
1482
 USAGE
 
1483
    H5P_genplist_t *H5P_create(class)
 
1484
        H5P_genclass_t *class;  IN: Property list class create list from
 
1485
 RETURNS
 
1486
    Returns a pointer to the newly created property list on success,
 
1487
        NULL on failure.
 
1488
 DESCRIPTION
 
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.
 
1492
 
 
1493
 GLOBAL VARIABLES
 
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.
 
1499
 EXAMPLES
 
1500
 REVISION LOG
 
1501
--------------------------------------------------------------------------*/
 
1502
static H5P_genplist_t *
 
1503
H5P_create(H5P_genclass_t *pclass)
 
1504
{
 
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 */
 
1510
 
 
1511
    FUNC_ENTER_NOAPI_NOINIT(H5P_create);
 
1512
 
 
1513
    assert(pclass);
 
1514
 
 
1515
    /*
 
1516
     * Create new property list object
 
1517
     */
 
1518
 
 
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");
 
1522
 
 
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 */
 
1527
 
 
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");
 
1531
 
 
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");
 
1535
 
 
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)
 
1540
     */
 
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");
 
1543
 
 
1544
    /*
 
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.
 
1547
     */
 
1548
    tclass=pclass;
 
1549
    while(tclass!=NULL) {
 
1550
        if(tclass->nprops>0) {
 
1551
            H5SL_node_t *curr_node;   /* Current node in skip list */
 
1552
 
 
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);
 
1558
 
 
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 */
 
1562
                    if(tmp->create) {
 
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");
 
1566
                    } /* end if */
 
1567
 
 
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");
 
1571
 
 
1572
                    /* Increment the number of properties in list */
 
1573
                    plist->nprops++;
 
1574
                } /* end if */
 
1575
 
 
1576
                /* Get the next property node in the skip list */
 
1577
                curr_node=H5SL_next(curr_node);
 
1578
            } /* end while */
 
1579
        } /* end if */
 
1580
 
 
1581
        /* Go up to parent class */
 
1582
        tclass=tclass->parent;
 
1583
    } /* end while */
 
1584
 
 
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");
 
1588
 
 
1589
    /* Set return value */
 
1590
    ret_value=plist;
 
1591
 
 
1592
done:
 
1593
    /* Release the skip list of 'seen' properties */
 
1594
    if(seen!=NULL)
 
1595
        H5SL_close(seen);
 
1596
 
 
1597
    /* Release resources allocated on failure */
 
1598
    if(ret_value==NULL) {
 
1599
        if(plist!=NULL) {
 
1600
            /* Close & free any changed properties */
 
1601
            if(plist->props) {
 
1602
                unsigned make_cb=1;
 
1603
 
 
1604
                H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb);
 
1605
            } /* end if */
 
1606
 
 
1607
            /* Close the deleted property skip list */
 
1608
            if(plist->del)
 
1609
                H5SL_close(plist->del);
 
1610
 
 
1611
            /* Release the property list itself */
 
1612
            H5FL_FREE(H5P_genplist_t,plist);
 
1613
        } /* end if */
 
1614
    } /* end if */
 
1615
 
 
1616
    FUNC_LEAVE_NOAPI(ret_value);
 
1617
}   /* H5P_create() */
 
1618
 
 
1619
 
 
1620
/*--------------------------------------------------------------------------
 
1621
 NAME
 
1622
    H5P_create_id
 
1623
 PURPOSE
 
1624
    Internal routine to create a new property list of a property list class.
 
1625
 USAGE
 
1626
    hid_t H5P_create_id(pclass)
 
1627
        H5P_genclass_t *pclass;       IN: Property list class create list from
 
1628
 RETURNS
 
1629
    Returns a valid property list ID on success, FAIL on failure.
 
1630
 DESCRIPTION
 
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.
 
1636
 
 
1637
 GLOBAL VARIABLES
 
1638
 COMMENTS, BUGS, ASSUMPTIONS
 
1639
 EXAMPLES
 
1640
 REVISION LOG
 
1641
--------------------------------------------------------------------------*/
 
1642
hid_t
 
1643
H5P_create_id(H5P_genclass_t *pclass)
 
1644
{
 
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 */
 
1648
 
 
1649
    FUNC_ENTER_NOAPI(H5P_create_id, FAIL);
 
1650
 
 
1651
    assert(pclass);
 
1652
 
 
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");
 
1656
 
 
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");
 
1660
 
 
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;
 
1663
 
 
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");
 
1670
        } /* end if */
 
1671
    } /* end if */
 
1672
 
 
1673
    /* Set the class initialization flag */
 
1674
    plist->class_init=1;
 
1675
 
 
1676
    /* Set the return value */
 
1677
    ret_value=plist_id;
 
1678
 
 
1679
done:
 
1680
    if (ret_value<0 && plist)
 
1681
        H5P_close(plist);
 
1682
 
 
1683
    FUNC_LEAVE_NOAPI(ret_value);
 
1684
}   /* H5P_create_id() */
 
1685
 
 
1686
 
 
1687
/*--------------------------------------------------------------------------
 
1688
 NAME
 
1689
    H5Pcreate
 
1690
 PURPOSE
 
1691
    Routine to create a new property list of a property list class.
 
1692
 USAGE
 
1693
    hid_t H5Pcreate(cls_id)
 
1694
        hid_t cls_id;       IN: Property list class create list from
 
1695
 RETURNS
 
1696
    Returns a valid property list ID on success, FAIL on failure.
 
1697
 DESCRIPTION
 
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.
 
1703
 
 
1704
 GLOBAL VARIABLES
 
1705
 COMMENTS, BUGS, ASSUMPTIONS
 
1706
 EXAMPLES
 
1707
 REVISION LOG
 
1708
--------------------------------------------------------------------------*/
 
1709
hid_t
 
1710
H5Pcreate(hid_t cls_id)
 
1711
{
 
1712
    H5P_genclass_t  *pclass;   /* Property list class to modify */
 
1713
    hid_t ret_value;               /* return value */
 
1714
 
 
1715
    FUNC_ENTER_API(H5Pcreate, FAIL);
 
1716
    H5TRACE1("i","i",cls_id);
 
1717
 
 
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");
 
1721
 
 
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");
 
1725
 
 
1726
done:
 
1727
    FUNC_LEAVE_API(ret_value);
 
1728
}   /* H5Pcreate() */
 
1729
 
 
1730
 
 
1731
/*--------------------------------------------------------------------------
 
1732
 NAME
 
1733
    H5P_register
 
1734
 PURPOSE
 
1735
    Internal routine to register a new property in a property list class.
 
1736
 USAGE
 
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
 
1744
                                    creation callback
 
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
 
1751
                                    callback
 
1752
 RETURNS
 
1753
    Returns non-negative on success, negative on failure.
 
1754
 DESCRIPTION
 
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.
 
1761
 
 
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.
 
1768
 
 
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.
 
1783
 
 
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.
 
1797
 
 
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.
 
1811
 
 
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.
 
1825
 
 
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,
 
1829
            void *value);
 
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.
 
1838
 
 
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
 
1841
    defined as:
 
1842
        typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
 
1843
            size_t size);
 
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.
 
1852
 
 
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,
 
1856
            void *value);
 
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.
 
1865
 
 
1866
 GLOBAL VARIABLES
 
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.
 
1874
 
 
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
 
1881
 
 
1882
 EXAMPLES
 
1883
 REVISION LOG
 
1884
--------------------------------------------------------------------------*/
 
1885
herr_t
 
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)
 
1891
{
 
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 */
 
1896
 
 
1897
    FUNC_ENTER_NOAPI(H5P_register, FAIL);
 
1898
 
 
1899
    assert(pclass);
 
1900
    assert(name);
 
1901
    assert((size>0 && def_value!=NULL) || (size==0));
 
1902
 
 
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");
 
1906
 
 
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.
 
1909
     */
 
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");
 
1916
 
 
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 */
 
1920
 
 
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");
 
1927
 
 
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");
 
1931
 
 
1932
                /* Increment property count for class */
 
1933
                new_class->nprops++;
 
1934
 
 
1935
                /* Get the next property node in the skip list */
 
1936
                curr_node=H5SL_next(curr_node);
 
1937
            } /* end while */
 
1938
        } /* end if */
 
1939
 
 
1940
        /* Use the new class instead of the old one */
 
1941
        pclass=new_class;
 
1942
    } /* end if */
 
1943
 
 
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");
 
1947
 
 
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");
 
1951
 
 
1952
    /* Increment property count for class */
 
1953
    pclass->nprops++;
 
1954
 
 
1955
    /* Update the revision for the class */
 
1956
    pclass->revision = H5P_GET_NEXT_REV;
 
1957
 
 
1958
done:
 
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);
 
1966
        } /* end if */
 
1967
    }  /* end if */
 
1968
    FUNC_LEAVE_NOAPI(ret_value);
 
1969
}   /* H5P_register() */
 
1970
 
 
1971
 
 
1972
/*--------------------------------------------------------------------------
 
1973
 NAME
 
1974
    H5Pregister
 
1975
 PURPOSE
 
1976
    Routine to register a new property in a property list class.
 
1977
 USAGE
 
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
 
1985
                                    creation callback
 
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
 
1991
                                    callback
 
1992
 RETURNS
 
1993
    Returns non-negative on success, negative on failure.
 
1994
 DESCRIPTION
 
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.
 
2001
 
 
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.
 
2008
 
 
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.
 
2023
 
 
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.
 
2037
 
 
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.
 
2051
 
 
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.
 
2065
 
 
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,
 
2069
            void *value);
 
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.
 
2078
 
 
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,
 
2082
            void *value);
 
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.
 
2091
 
 
2092
 GLOBAL VARIABLES
 
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.
 
2100
 
 
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
 
2107
 
 
2108
 EXAMPLES
 
2109
 REVISION LOG
 
2110
--------------------------------------------------------------------------*/
 
2111
herr_t
 
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)
 
2116
{
 
2117
    H5P_genclass_t  *pclass;   /* Property list class to modify */
 
2118
    herr_t ret_value;     /* return value */
 
2119
 
 
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);
 
2123
 
 
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");
 
2131
 
 
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");
 
2135
 
 
2136
done:
 
2137
    FUNC_LEAVE_API(ret_value);
 
2138
}   /* H5Pregister() */
 
2139
 
 
2140
 
 
2141
/*--------------------------------------------------------------------------
 
2142
 NAME
 
2143
    H5P_insert
 
2144
 PURPOSE
 
2145
    Internal routine to insert a new property in a property list.
 
2146
 USAGE
 
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
 
2158
                                    callback
 
2159
 RETURNS
 
2160
    Returns non-negative on success, negative on failure.
 
2161
 DESCRIPTION
 
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
 
2166
    needed.
 
2167
 
 
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
 
2173
    never called.
 
2174
 
 
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.
 
2188
 
 
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.
 
2202
 
 
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.
 
2216
 
 
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,
 
2220
            void *value);
 
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.
 
2229
 
 
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
 
2232
    defined as:
 
2233
        typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
 
2234
            size_t size);
 
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.
 
2243
 
 
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,
 
2247
            void *value);
 
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.
 
2256
 
 
2257
 GLOBAL VARIABLES
 
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.
 
2265
 
 
2266
        There is no 'create' callback routine for temporary property list
 
2267
    objects, the initial value is assumed to have any necessary setup already
 
2268
    performed on it.
 
2269
 
 
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
 
2276
 
 
2277
 EXAMPLES
 
2278
 REVISION LOG
 
2279
--------------------------------------------------------------------------*/
 
2280
herr_t
 
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)
 
2285
{
 
2286
    H5P_genprop_t *new_prop=NULL;       /* Temporary property pointer */
 
2287
    herr_t ret_value=SUCCEED;           /* Return value */
 
2288
 
 
2289
    FUNC_ENTER_NOAPI_NOINIT(H5P_insert);
 
2290
 
 
2291
    assert(plist);
 
2292
    assert(name);
 
2293
    assert((size>0 && value!=NULL) || (size==0));
 
2294
 
 
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");
 
2298
 
 
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");
 
2304
 
 
2305
        /* Fall through to add property to list */
 
2306
    } /* end if */
 
2307
    else {
 
2308
        H5P_genclass_t *tclass;     /* Temporary class pointer */
 
2309
 
 
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");
 
2317
            } /* end if */
 
2318
 
 
2319
            /* Go up to parent class */
 
2320
            tclass=tclass->parent;
 
2321
        } /* end while */
 
2322
 
 
2323
        /* Fall through to add property to list */
 
2324
    } /* end else */
 
2325
 
 
2326
    /* Ok to add to property list */
 
2327
 
 
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");
 
2331
 
 
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");
 
2335
 
 
2336
    /* Increment property count for class */
 
2337
    plist->nprops++;
 
2338
 
 
2339
done:
 
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);
 
2347
        } /* end if */
 
2348
    }  /* end if */
 
2349
 
 
2350
    FUNC_LEAVE_NOAPI(ret_value);
 
2351
}   /* H5P_insert() */
 
2352
 
 
2353
 
 
2354
/*--------------------------------------------------------------------------
 
2355
 NAME
 
2356
    H5Pinsert
 
2357
 PURPOSE
 
2358
    Routine to insert a new property in a property list.
 
2359
 USAGE
 
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
 
2370
                                    callback
 
2371
 RETURNS
 
2372
    Returns non-negative on success, negative on failure.
 
2373
 DESCRIPTION
 
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
 
2378
    needed.
 
2379
 
 
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
 
2385
    never called.
 
2386
 
 
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.
 
2400
 
 
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.
 
2414
 
 
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.
 
2428
 
 
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,
 
2432
            void *value);
 
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.
 
2441
 
 
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,
 
2445
            void *value);
 
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.
 
2454
 
 
2455
 GLOBAL VARIABLES
 
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.
 
2463
 
 
2464
        There is no 'create' callback routine for temporary property list
 
2465
    objects, the initial value is assumed to have any necessary setup already
 
2466
    performed on it.
 
2467
 
 
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
 
2474
 
 
2475
 EXAMPLES
 
2476
 REVISION LOG
 
2477
--------------------------------------------------------------------------*/
 
2478
herr_t
 
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)
 
2483
{
 
2484
    H5P_genplist_t  *plist;    /* Property list to modify */
 
2485
    herr_t ret_value;           /* return value */
 
2486
 
 
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);
 
2490
 
 
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");
 
2498
 
 
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");
 
2502
 
 
2503
done:
 
2504
    FUNC_LEAVE_API(ret_value);
 
2505
}   /* H5Pinsert() */
 
2506
 
 
2507
 
 
2508
/*--------------------------------------------------------------------------
 
2509
 NAME
 
2510
    H5P_set
 
2511
 PURPOSE
 
2512
    Internal routine to set a property's value in a property list.
 
2513
 USAGE
 
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
 
2518
 RETURNS
 
2519
    Returns non-negative on success, negative on failure.
 
2520
 DESCRIPTION
 
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
 
2528
    value.
 
2529
 
 
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.
 
2533
 
 
2534
 GLOBAL VARIABLES
 
2535
 COMMENTS, BUGS, ASSUMPTIONS
 
2536
 EXAMPLES
 
2537
 REVISION LOG
 
2538
--------------------------------------------------------------------------*/
 
2539
herr_t
 
2540
H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
 
2541
{
 
2542
    H5P_genclass_t *tclass;     /* Temporary class pointer */
 
2543
    H5P_genprop_t *prop;        /* Temporary property pointer */
 
2544
    herr_t      ret_value=SUCCEED;       /* Return value */
 
2545
 
 
2546
    FUNC_ENTER_NOAPI(H5P_set, FAIL);
 
2547
 
 
2548
    assert(plist);
 
2549
    assert(name);
 
2550
    assert(value);
 
2551
 
 
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");
 
2555
 
 
2556
    /* Find property in changed list */
 
2557
    if((prop=H5SL_search(plist->props,name))!=NULL) {
 
2558
        /* Check for property size >0 */
 
2559
        if(prop->size==0)
 
2560
            HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
 
2561
 
 
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 */
 
2565
 
 
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);
 
2570
 
 
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");
 
2575
            } /* end if */
 
2576
 
 
2577
            /* Copy new [possibly unchanged] value into property value */
 
2578
            HDmemcpy(prop->value,tmp_value,prop->size);
 
2579
 
 
2580
            /* Free the temporary value buffer */
 
2581
            H5MM_xfree(tmp_value);
 
2582
        } /* end if */
 
2583
        /* No 'set' callback, just copy value */
 
2584
        else
 
2585
            HDmemcpy(prop->value,value,prop->size);
 
2586
    } /* end if */
 
2587
    else {
 
2588
        /*
 
2589
         * Check if we should set class properties (up through list of parent classes also),
 
2590
         * & make property 'set' callback.
 
2591
         */
 
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 */
 
2598
 
 
2599
                    /* Check for property size >0 */
 
2600
                    if(prop->size==0)
 
2601
                        HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size");
 
2602
 
 
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 */
 
2606
 
 
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);
 
2611
 
 
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");
 
2616
                        } /* end if */
 
2617
 
 
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");
 
2622
 
 
2623
                            /* Copy new value into property value */
 
2624
                            HDmemcpy(pcopy->value,tmp_value,pcopy->size);
 
2625
 
 
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");
 
2629
                        } /* end if */
 
2630
 
 
2631
                        /* Free the temporary value buffer */
 
2632
                        H5MM_xfree(tmp_value);
 
2633
                    } /* end if */
 
2634
                    /* No 'set' callback, just copy value */
 
2635
                    else {
 
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");
 
2640
 
 
2641
                            HDmemcpy(pcopy->value,value,pcopy->size);
 
2642
 
 
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");
 
2646
                        } /* end if */
 
2647
                    } /* end else */
 
2648
 
 
2649
                    /* Leave */
 
2650
                    HGOTO_DONE(SUCCEED);
 
2651
                } /* end while */
 
2652
            } /* end if */
 
2653
 
 
2654
            /* Go up to parent class */
 
2655
            tclass=tclass->parent;
 
2656
        } /* end while */
 
2657
 
 
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
 
2660
         */
 
2661
        HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
 
2662
    } /* end else */
 
2663
 
 
2664
done:
 
2665
    FUNC_LEAVE_NOAPI(ret_value);
 
2666
}   /* H5P_set() */
 
2667
 
 
2668
 
 
2669
/*--------------------------------------------------------------------------
 
2670
 NAME
 
2671
    H5Pset
 
2672
 PURPOSE
 
2673
    Routine to set a property's value in a property list.
 
2674
 USAGE
 
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
 
2679
 RETURNS
 
2680
    Returns non-negative on success, negative on failure.
 
2681
 DESCRIPTION
 
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
 
2689
    value.
 
2690
 
 
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.
 
2694
 
 
2695
 GLOBAL VARIABLES
 
2696
 COMMENTS, BUGS, ASSUMPTIONS
 
2697
 EXAMPLES
 
2698
 REVISION LOG
 
2699
--------------------------------------------------------------------------*/
 
2700
herr_t
 
2701
H5Pset(hid_t plist_id, const char *name, void *value)
 
2702
{
 
2703
    H5P_genplist_t *plist;      /* Property list to modify */
 
2704
    herr_t ret_value=SUCCEED;   /* return value */
 
2705
 
 
2706
    FUNC_ENTER_API(H5Pset, FAIL);
 
2707
    H5TRACE3("e","isx",plist_id,name,value);
 
2708
 
 
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");
 
2714
    if (value==NULL)
 
2715
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value");
 
2716
 
 
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");
 
2720
 
 
2721
done:
 
2722
    FUNC_LEAVE_API(ret_value);
 
2723
}   /* H5Pset() */
 
2724
 
 
2725
 
 
2726
/*--------------------------------------------------------------------------
 
2727
 NAME
 
2728
    H5P_exist_plist
 
2729
 PURPOSE
 
2730
    Internal routine to query the existance of a property in a property list.
 
2731
 USAGE
 
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
 
2735
 RETURNS
 
2736
    Success: Positive if the property exists in the property list, zero
 
2737
            if the property does not exist.
 
2738
    Failure: negative value
 
2739
 DESCRIPTION
 
2740
        This routine checks if a property exists within a property list.
 
2741
 
 
2742
 GLOBAL VARIABLES
 
2743
 COMMENTS, BUGS, ASSUMPTIONS
 
2744
 EXAMPLES
 
2745
 REVISION LOG
 
2746
--------------------------------------------------------------------------*/
 
2747
htri_t
 
2748
H5P_exist_plist(H5P_genplist_t *plist, const char *name)
 
2749
{
 
2750
    htri_t ret_value=FAIL;     /* return value */
 
2751
 
 
2752
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_plist);
 
2753
 
 
2754
    assert(plist);
 
2755
    assert(name);
 
2756
 
 
2757
    /* Check for property in deleted property list */
 
2758
    if(H5SL_search(plist->del,name)!=NULL)
 
2759
        ret_value=0;
 
2760
    else {
 
2761
        /* Check for property in changed property list */
 
2762
        if(H5SL_search(plist->props,name)!=NULL)
 
2763
            ret_value=1;
 
2764
        else {
 
2765
            H5P_genclass_t *tclass;     /* Temporary class pointer */
 
2766
 
 
2767
            tclass=plist->pclass;
 
2768
            while(tclass!=NULL) {
 
2769
                if(H5SL_search(tclass->props,name)!=NULL)
 
2770
                    HGOTO_DONE(1);
 
2771
 
 
2772
                /* Go up to parent class */
 
2773
                tclass=tclass->parent;
 
2774
            } /* end while */
 
2775
 
 
2776
            /* If we've reached here, we couldn't find the property */
 
2777
            ret_value=0;
 
2778
        } /* end else */
 
2779
    } /* end else */
 
2780
 
 
2781
done:
 
2782
    FUNC_LEAVE_NOAPI(ret_value);
 
2783
}   /* H5P_exist_plist() */
 
2784
 
 
2785
 
 
2786
/*--------------------------------------------------------------------------
 
2787
 NAME
 
2788
    H5P_exist_pclass
 
2789
 PURPOSE
 
2790
    Internal routine to query the existance of a property in a property class.
 
2791
 USAGE
 
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
 
2795
 RETURNS
 
2796
    Success: Positive if the property exists in the property list, zero
 
2797
            if the property does not exist.
 
2798
    Failure: negative value
 
2799
 DESCRIPTION
 
2800
        This routine checks if a property exists within a property list.
 
2801
 
 
2802
 GLOBAL VARIABLES
 
2803
 COMMENTS, BUGS, ASSUMPTIONS
 
2804
 EXAMPLES
 
2805
 REVISION LOG
 
2806
--------------------------------------------------------------------------*/
 
2807
static htri_t
 
2808
H5P_exist_pclass(H5P_genclass_t *pclass, const char *name)
 
2809
{
 
2810
    htri_t ret_value=FAIL;     /* return value */
 
2811
 
 
2812
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_pclass);
 
2813
 
 
2814
    assert(pclass);
 
2815
    assert(name);
 
2816
 
 
2817
    /* Check for property in property list */
 
2818
    if(H5SL_search(pclass->props,name)==NULL)
 
2819
        ret_value=0;
 
2820
    else
 
2821
        ret_value=1;
 
2822
 
 
2823
    FUNC_LEAVE_NOAPI(ret_value);
 
2824
}   /* H5P_exist_pclass() */
 
2825
 
 
2826
 
 
2827
/*--------------------------------------------------------------------------
 
2828
 NAME
 
2829
    H5Pexist
 
2830
 PURPOSE
 
2831
    Routine to query the existance of a property in a property object.
 
2832
 USAGE
 
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
 
2836
 RETURNS
 
2837
    Success: Positive if the property exists in the property object, zero
 
2838
            if the property does not exist.
 
2839
    Failure: negative value
 
2840
 DESCRIPTION
 
2841
        This routine checks if a property exists within a property list or
 
2842
    class.
 
2843
 
 
2844
 GLOBAL VARIABLES
 
2845
 COMMENTS, BUGS, ASSUMPTIONS
 
2846
 EXAMPLES
 
2847
 REVISION LOG
 
2848
--------------------------------------------------------------------------*/
 
2849
htri_t
 
2850
H5Pexist(hid_t id, const char *name)
 
2851
{
 
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 */
 
2855
 
 
2856
    FUNC_ENTER_API(H5Pexist, FAIL);
 
2857
    H5TRACE2("t","is",id,name);
 
2858
 
 
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");
 
2864
 
 
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");
 
2871
    } /* end if */
 
2872
    else
 
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");
 
2878
        } /* end if */
 
2879
        else
 
2880
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
 
2881
 
 
2882
done:
 
2883
    FUNC_LEAVE_API(ret_value);
 
2884
}   /* H5Pexist() */
 
2885
 
 
2886
 
 
2887
/*--------------------------------------------------------------------------
 
2888
 NAME
 
2889
    H5P_get_size_plist
 
2890
 PURPOSE
 
2891
    Internal routine to query the size of a property in a property list.
 
2892
 USAGE
 
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
 
2897
 RETURNS
 
2898
    Success: non-negative value
 
2899
    Failure: negative value
 
2900
 DESCRIPTION
 
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.
 
2903
 
 
2904
 GLOBAL VARIABLES
 
2905
 COMMENTS, BUGS, ASSUMPTIONS
 
2906
 EXAMPLES
 
2907
 REVISION LOG
 
2908
--------------------------------------------------------------------------*/
 
2909
static herr_t
 
2910
H5P_get_size_plist(H5P_genplist_t *plist, const char *name, size_t *size)
 
2911
{
 
2912
    H5P_genprop_t *prop;        /* Temporary property pointer */
 
2913
    herr_t ret_value=SUCCEED;      /* return value */
 
2914
 
 
2915
    FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_plist);
 
2916
 
 
2917
    assert(plist);
 
2918
    assert(name);
 
2919
    assert(size);
 
2920
 
 
2921
    /* Find property */
 
2922
    if((prop=H5P_find_prop_plist(plist,name))==NULL)
 
2923
        HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
 
2924
 
 
2925
    /* Get property size */
 
2926
    *size=prop->size;
 
2927
 
 
2928
done:
 
2929
    FUNC_LEAVE_NOAPI(ret_value);
 
2930
}   /* H5P_get_size_plist() */
 
2931
 
 
2932
 
 
2933
/*--------------------------------------------------------------------------
 
2934
 NAME
 
2935
    H5P_get_size_pclass
 
2936
 PURPOSE
 
2937
    Internal routine to query the size of a property in a property class.
 
2938
 USAGE
 
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
 
2943
 RETURNS
 
2944
    Success: non-negative value
 
2945
    Failure: negative value
 
2946
 DESCRIPTION
 
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.
 
2949
 
 
2950
 GLOBAL VARIABLES
 
2951
 COMMENTS, BUGS, ASSUMPTIONS
 
2952
 EXAMPLES
 
2953
 REVISION LOG
 
2954
--------------------------------------------------------------------------*/
 
2955
static herr_t
 
2956
H5P_get_size_pclass(H5P_genclass_t *pclass, const char *name, size_t *size)
 
2957
{
 
2958
    H5P_genprop_t *prop;        /* Temporary property pointer */
 
2959
    herr_t ret_value=SUCCEED;      /* return value */
 
2960
 
 
2961
    FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_pclass);
 
2962
 
 
2963
    assert(pclass);
 
2964
    assert(name);
 
2965
    assert(size);
 
2966
 
 
2967
    /* Find property */
 
2968
    if((prop=H5P_find_prop_pclass(pclass,name))==NULL)
 
2969
        HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
 
2970
 
 
2971
    /* Get property size */
 
2972
    *size=prop->size;
 
2973
 
 
2974
done:
 
2975
    FUNC_LEAVE_NOAPI(ret_value);
 
2976
}   /* H5P_get_size_pclass() */
 
2977
 
 
2978
 
 
2979
/*--------------------------------------------------------------------------
 
2980
 NAME
 
2981
    H5Pget_size
 
2982
 PURPOSE
 
2983
    Routine to query the size of a property in a property list or class.
 
2984
 USAGE
 
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
 
2989
 RETURNS
 
2990
    Success: non-negative value
 
2991
    Failure: negative value
 
2992
 DESCRIPTION
 
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.
 
2996
 
 
2997
 GLOBAL VARIABLES
 
2998
 COMMENTS, BUGS, ASSUMPTIONS
 
2999
 EXAMPLES
 
3000
 REVISION LOG
 
3001
--------------------------------------------------------------------------*/
 
3002
herr_t
 
3003
H5Pget_size(hid_t id, const char *name, size_t *size)
 
3004
{
 
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 */
 
3008
 
 
3009
    FUNC_ENTER_API(H5Pget_size, FAIL);
 
3010
    H5TRACE3("e","is*z",id,name,size);
 
3011
 
 
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");
 
3017
    if (size==NULL)
 
3018
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property size");
 
3019
 
 
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");
 
3023
 
 
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");
 
3027
    } /* end if */
 
3028
    else
 
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");
 
3032
 
 
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");
 
3036
        } /* end if */
 
3037
        else
 
3038
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
 
3039
 
 
3040
done:
 
3041
    FUNC_LEAVE_API(ret_value);
 
3042
}   /* H5Pget_size() */
 
3043
 
 
3044
 
 
3045
/*--------------------------------------------------------------------------
 
3046
 NAME
 
3047
    H5P_get_class
 
3048
 PURPOSE
 
3049
    Internal routine to query the class of a generic property list
 
3050
 USAGE
 
3051
    H5P_genclass_t *H5P_get_class(plist)
 
3052
        H5P_genplist_t *plist;    IN: Property list to check
 
3053
 RETURNS
 
3054
    Success: Pointer to the class for a property list
 
3055
    Failure: NULL
 
3056
 DESCRIPTION
 
3057
    This routine retrieves a pointer to the class for a property list.
 
3058
 
 
3059
 GLOBAL VARIABLES
 
3060
 COMMENTS, BUGS, ASSUMPTIONS
 
3061
 EXAMPLES
 
3062
 REVISION LOG
 
3063
--------------------------------------------------------------------------*/
 
3064
static H5P_genclass_t *
 
3065
H5P_get_class(H5P_genplist_t *plist)
 
3066
{
 
3067
    H5P_genclass_t *ret_value;      /* return value */
 
3068
 
 
3069
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class);
 
3070
 
 
3071
    assert(plist);
 
3072
 
 
3073
    /* Get property size */
 
3074
    ret_value=plist->pclass;
 
3075
 
 
3076
    FUNC_LEAVE_NOAPI(ret_value);
 
3077
}   /* H5P_get_class() */
 
3078
 
 
3079
 
 
3080
/*--------------------------------------------------------------------------
 
3081
 NAME
 
3082
    H5Pget_class
 
3083
 PURPOSE
 
3084
    Routine to query the class of a generic property list
 
3085
 USAGE
 
3086
    hid_t H5Pget_class(plist_id)
 
3087
        hid_t plist_id;         IN: Property list to query
 
3088
 RETURNS
 
3089
    Success: ID of class object
 
3090
    Failure: negative
 
3091
 DESCRIPTION
 
3092
    This routine retrieves the class of a property list.
 
3093
 
 
3094
 GLOBAL VARIABLES
 
3095
 COMMENTS, BUGS, ASSUMPTIONS
 
3096
    Change the name of this function to H5Pget_class (and remove old H5Pget_class)
 
3097
 EXAMPLES
 
3098
 REVISION LOG
 
3099
--------------------------------------------------------------------------*/
 
3100
hid_t
 
3101
H5Pget_class(hid_t plist_id)
 
3102
{
 
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 */
 
3106
 
 
3107
    FUNC_ENTER_API(H5Pget_class, FAIL);
 
3108
    H5TRACE1("i","i",plist_id);
 
3109
 
 
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");
 
3113
 
 
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");
 
3117
 
 
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");
 
3121
 
 
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");
 
3125
 
 
3126
done:
 
3127
    if (ret_value<0 && pclass)
 
3128
        H5P_close_class(pclass);
 
3129
 
 
3130
    FUNC_LEAVE_API(ret_value);
 
3131
}   /* H5Pget_class() */
 
3132
 
 
3133
 
 
3134
/*--------------------------------------------------------------------------
 
3135
 NAME
 
3136
    H5P_get_nprops_plist
 
3137
 PURPOSE
 
3138
    Internal routine to query the number of properties in a property list
 
3139
 USAGE
 
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
 
3143
 RETURNS
 
3144
    Success: non-negative value
 
3145
    Failure: negative value
 
3146
 DESCRIPTION
 
3147
        This routine retrieves the number of a properties in a property list.
 
3148
 
 
3149
 GLOBAL VARIABLES
 
3150
 COMMENTS, BUGS, ASSUMPTIONS
 
3151
 EXAMPLES
 
3152
 REVISION LOG
 
3153
--------------------------------------------------------------------------*/
 
3154
static herr_t
 
3155
H5P_get_nprops_plist(H5P_genplist_t *plist, size_t *nprops)
 
3156
{
 
3157
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_nprops_plist);
 
3158
 
 
3159
    assert(plist);
 
3160
    assert(nprops);
 
3161
 
 
3162
    /* Get property size */
 
3163
    *nprops=plist->nprops;
 
3164
 
 
3165
    FUNC_LEAVE_NOAPI(SUCCEED);
 
3166
}   /* H5P_get_nprops_plist() */
 
3167
 
 
3168
 
 
3169
/*--------------------------------------------------------------------------
 
3170
 NAME
 
3171
    H5P_get_nprops_pclass
 
3172
 PURPOSE
 
3173
    Internal routine to query the number of properties in a property class
 
3174
 USAGE
 
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
 
3178
 RETURNS
 
3179
    Success: non-negative value (can't fail)
 
3180
    Failure: negative value
 
3181
 DESCRIPTION
 
3182
    This routine retrieves the number of a properties in a property class.
 
3183
 
 
3184
 GLOBAL VARIABLES
 
3185
 COMMENTS, BUGS, ASSUMPTIONS
 
3186
 EXAMPLES
 
3187
 REVISION LOG
 
3188
--------------------------------------------------------------------------*/
 
3189
herr_t
 
3190
H5P_get_nprops_pclass(H5P_genclass_t *pclass, size_t *nprops)
 
3191
{
 
3192
    herr_t ret_value = SUCCEED;         /* Return value */
 
3193
 
 
3194
    FUNC_ENTER_NOAPI(H5P_get_nprops_pclass, FAIL)
 
3195
 
 
3196
    assert(pclass);
 
3197
    assert(nprops);
 
3198
 
 
3199
    /* Get number of properties */
 
3200
    *nprops=pclass->nprops;
 
3201
 
 
3202
done:
 
3203
    FUNC_LEAVE_NOAPI(ret_value)
 
3204
}   /* H5P_get_nprops_pclass() */
 
3205
 
 
3206
 
 
3207
/*--------------------------------------------------------------------------
 
3208
 NAME
 
3209
    H5Pget_nprops
 
3210
 PURPOSE
 
3211
    Routine to query the size of a property in a property list or class.
 
3212
 USAGE
 
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
 
3216
 RETURNS
 
3217
    Success: non-negative value
 
3218
    Failure: negative value
 
3219
 DESCRIPTION
 
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.
 
3224
 
 
3225
 GLOBAL VARIABLES
 
3226
 COMMENTS, BUGS, ASSUMPTIONS
 
3227
 EXAMPLES
 
3228
 REVISION LOG
 
3229
--------------------------------------------------------------------------*/
 
3230
herr_t
 
3231
H5Pget_nprops(hid_t id, size_t *nprops)
 
3232
{
 
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 */
 
3236
 
 
3237
    FUNC_ENTER_API(H5Pget_nprops, FAIL);
 
3238
    H5TRACE2("e","i*z",id,nprops);
 
3239
 
 
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");
 
3243
    if (nprops==NULL)
 
3244
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property nprops pointer");
 
3245
 
 
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");
 
3251
    } /* end if */
 
3252
    else
 
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");
 
3258
        } /* end if */
 
3259
        else
 
3260
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
 
3261
 
 
3262
done:
 
3263
    FUNC_LEAVE_API(ret_value);
 
3264
}   /* H5Pget_nprops() */
 
3265
 
 
3266
 
 
3267
/*--------------------------------------------------------------------------
 
3268
 NAME
 
3269
    H5P_cmp_prop
 
3270
 PURPOSE
 
3271
    Internal routine to compare two generic properties
 
3272
 USAGE
 
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
 
3276
 RETURNS
 
3277
    Success: negative if prop1 "less" than prop2, positive if prop1 "greater"
 
3278
        than prop2, zero if prop1 is "equal" to prop2
 
3279
    Failure: can't fail
 
3280
 DESCRIPTION
 
3281
        This function compares two generic properties together to see if
 
3282
    they are the same property.
 
3283
 
 
3284
 GLOBAL VARIABLES
 
3285
 COMMENTS, BUGS, ASSUMPTIONS
 
3286
 EXAMPLES
 
3287
 REVISION LOG
 
3288
--------------------------------------------------------------------------*/
 
3289
static int
 
3290
H5P_cmp_prop(H5P_genprop_t *prop1, H5P_genprop_t *prop2)
 
3291
{
 
3292
    int cmp_value;             /* Value from comparison */
 
3293
    int ret_value=0;         /* return value */
 
3294
 
 
3295
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_prop);
 
3296
 
 
3297
    assert(prop1);
 
3298
    assert(prop2);
 
3299
 
 
3300
    /* Check the name */
 
3301
    if((cmp_value=HDstrcmp(prop1->name,prop2->name))!=0)
 
3302
        HGOTO_DONE(cmp_value);
 
3303
 
 
3304
    /* Check the size of properties */
 
3305
    if(prop1->size < prop2->size) HGOTO_DONE(-1);
 
3306
    if(prop1->size > prop2->size) HGOTO_DONE(1);
 
3307
 
 
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);
 
3312
 
 
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);
 
3317
 
 
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);
 
3322
 
 
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);
 
3327
 
 
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);
 
3332
 
 
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);
 
3337
 
 
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);
 
3342
 
 
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);
 
3350
    } /* end if */
 
3351
 
 
3352
done:
 
3353
    FUNC_LEAVE_NOAPI(ret_value);
 
3354
}   /* H5P_cmp_prop() */
 
3355
 
 
3356
 
 
3357
/*--------------------------------------------------------------------------
 
3358
 NAME
 
3359
    H5P_cmp_class
 
3360
 PURPOSE
 
3361
    Internal routine to compare two generic property classes
 
3362
 USAGE
 
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
 
3366
 RETURNS
 
3367
    Success: negative if class1 "less" than class2, positive if class1 "greater"
 
3368
        than class2, zero if class1 is "equal" to class2
 
3369
    Failure: can't fail
 
3370
 DESCRIPTION
 
3371
        This function compares two generic property classes together to see if
 
3372
    they are the same class.
 
3373
 
 
3374
 GLOBAL VARIABLES
 
3375
 COMMENTS, BUGS, ASSUMPTIONS
 
3376
 EXAMPLES
 
3377
 REVISION LOG
 
3378
--------------------------------------------------------------------------*/
 
3379
static int
 
3380
H5P_cmp_class(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2)
 
3381
{
 
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 */
 
3385
 
 
3386
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_class);
 
3387
 
 
3388
    assert(pclass1);
 
3389
    assert(pclass2);
 
3390
 
 
3391
    /* Use the revision number to quickly check for identical classes */
 
3392
    if(pclass1->revision==pclass2->revision)
 
3393
        HGOTO_DONE(0);
 
3394
 
 
3395
    /* Check the name */
 
3396
    if((cmp_value=HDstrcmp(pclass1->name,pclass2->name))!=0)
 
3397
        HGOTO_DONE(cmp_value);
 
3398
 
 
3399
    /* Check the number of properties */
 
3400
    if(pclass1->nprops < pclass2->nprops) HGOTO_DONE(-1);
 
3401
    if(pclass1->nprops > pclass2->nprops) HGOTO_DONE(1);
 
3402
 
 
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);
 
3406
 
 
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);
 
3410
 
 
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);
 
3414
 
 
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);
 
3418
 
 
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);
 
3422
 
 
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);
 
3429
 
 
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);
 
3436
 
 
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 */
 
3442
 
 
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);
 
3446
 
 
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);
 
3452
 
 
3453
        /* Advance the pointers */
 
3454
        tnode1=H5SL_next(tnode1);
 
3455
        tnode2=H5SL_next(tnode2);
 
3456
    } /* end while */
 
3457
 
 
3458
done:
 
3459
    FUNC_LEAVE_NOAPI(ret_value);
 
3460
}   /* H5P_cmp_class() */
 
3461
 
 
3462
 
 
3463
/*--------------------------------------------------------------------------
 
3464
 NAME
 
3465
    H5P_cmp_plist
 
3466
 PURPOSE
 
3467
    Internal routine to compare two generic property lists
 
3468
 USAGE
 
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
 
3472
 RETURNS
 
3473
    Success: negative if list1 "less" than list2, positive if list1 "greater"
 
3474
        than list2, zero if list1 is "equal" to list2
 
3475
    Failure: can't fail
 
3476
 DESCRIPTION
 
3477
        This function compares two generic property lists together to see if
 
3478
    they are the same list.
 
3479
 
 
3480
 GLOBAL VARIABLES
 
3481
 COMMENTS, BUGS, ASSUMPTIONS
 
3482
 EXAMPLES
 
3483
 REVISION LOG
 
3484
--------------------------------------------------------------------------*/
 
3485
static int
 
3486
H5P_cmp_plist(H5P_genplist_t *plist1, H5P_genplist_t *plist2)
 
3487
{
 
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 */
 
3491
 
 
3492
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_plist);
 
3493
 
 
3494
    assert(plist1);
 
3495
    assert(plist2);
 
3496
 
 
3497
    /* Check the number of properties */
 
3498
    if(plist1->nprops < plist2->nprops) HGOTO_DONE(-1);
 
3499
    if(plist1->nprops > plist2->nprops) HGOTO_DONE(1);
 
3500
 
 
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);
 
3504
 
 
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);
 
3509
 
 
3510
        tnode1=H5SL_first(plist1->del);
 
3511
        tnode2=H5SL_first(plist2->del);
 
3512
        while(tnode1 || tnode2) {
 
3513
            const char *name1, *name2;   /* Name for node */
 
3514
 
 
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);
 
3518
 
 
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);
 
3524
 
 
3525
            /* Advance the pointers */
 
3526
            tnode1=H5SL_next(tnode1);
 
3527
            tnode2=H5SL_next(tnode2);
 
3528
        } /* end while */
 
3529
    } /* end if */
 
3530
    else
 
3531
        if(H5SL_count(plist2->del)>0) HGOTO_DONE (-1);
 
3532
 
 
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);
 
3537
 
 
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 */
 
3542
 
 
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);
 
3546
 
 
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);
 
3552
 
 
3553
            /* Advance the pointers */
 
3554
            tnode1=H5SL_next(tnode1);
 
3555
            tnode2=H5SL_next(tnode2);
 
3556
        } /* end while */
 
3557
    } /* end if */
 
3558
    else
 
3559
        if(H5SL_count(plist2->props)>0) HGOTO_DONE (-1);
 
3560
 
 
3561
    /* Check the parent classes */
 
3562
    if((cmp_value=H5P_cmp_class(plist1->pclass,plist2->pclass))!=0)
 
3563
        HGOTO_DONE(cmp_value);
 
3564
 
 
3565
done:
 
3566
    FUNC_LEAVE_NOAPI(ret_value);
 
3567
}   /* H5P_cmp_plist() */
 
3568
 
 
3569
 
 
3570
/*--------------------------------------------------------------------------
 
3571
 NAME
 
3572
    H5Pequal
 
3573
 PURPOSE
 
3574
    Routine to query whether two property lists or two property classes are equal
 
3575
 USAGE
 
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
 
3579
 RETURNS
 
3580
    Success: TRUE if equal, FALSE if unequal
 
3581
    Failure: negative
 
3582
 DESCRIPTION
 
3583
    Determines whether two property lists or two property classes are equal.
 
3584
 
 
3585
 GLOBAL VARIABLES
 
3586
 COMMENTS, BUGS, ASSUMPTIONS
 
3587
 EXAMPLES
 
3588
 REVISION LOG
 
3589
--------------------------------------------------------------------------*/
 
3590
htri_t
 
3591
H5Pequal(hid_t id1, hid_t id2)
 
3592
{
 
3593
    void *obj1, *obj2;          /* Property objects to compare */
 
3594
    htri_t ret_value=FALSE;     /* return value */
 
3595
 
 
3596
    FUNC_ENTER_API(H5Pequal, FAIL);
 
3597
    H5TRACE2("t","ii",id1,id2);
 
3598
 
 
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");
 
3607
 
 
3608
    /* Compare property lists */
 
3609
    if(H5I_GENPROP_LST == H5I_get_type(id1)) {
 
3610
        if(H5P_cmp_plist(obj1,obj2)==0)
 
3611
            ret_value=TRUE;
 
3612
    } /* end if */
 
3613
    /* Must be property classes */
 
3614
    else {
 
3615
        if(H5P_cmp_class(obj1,obj2)==0)
 
3616
            ret_value=TRUE;
 
3617
    } /* end else */
 
3618
 
 
3619
done:
 
3620
    FUNC_LEAVE_API(ret_value);
 
3621
}   /* H5Pequal() */
 
3622
 
 
3623
 
 
3624
/*--------------------------------------------------------------------------
 
3625
 NAME
 
3626
    H5P_isa_class_real
 
3627
 PURPOSE
 
3628
    Internal routine to query whether a property class is the same as another
 
3629
    class.
 
3630
 USAGE
 
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
 
3634
 RETURNS
 
3635
    Success: TRUE (1) or FALSE (0)
 
3636
    Failure: negative value
 
3637
 DESCRIPTION
 
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.
 
3641
 
 
3642
 GLOBAL VARIABLES
 
3643
 COMMENTS, BUGS, ASSUMPTIONS
 
3644
 EXAMPLES
 
3645
 REVISION LOG
 
3646
--------------------------------------------------------------------------*/
 
3647
static htri_t
 
3648
H5P_isa_class_real(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2)
 
3649
{
 
3650
    htri_t ret_value;
 
3651
 
 
3652
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_isa_class_real);
 
3653
 
 
3654
    assert(pclass1);
 
3655
    assert(pclass2);
 
3656
 
 
3657
    /* Compare property classes */
 
3658
    if(H5P_cmp_class(pclass1,pclass2)==0) {
 
3659
        HGOTO_DONE(TRUE);
 
3660
    } else {
 
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);
 
3664
        else
 
3665
            HGOTO_DONE(FALSE);
 
3666
    } /* end else */
 
3667
 
 
3668
done:
 
3669
    FUNC_LEAVE_NOAPI(ret_value);
 
3670
}   /* H5P_isa_class_real() */
 
3671
 
 
3672
 
 
3673
/*--------------------------------------------------------------------------
 
3674
 NAME
 
3675
    H5P_isa_class
 
3676
 PURPOSE
 
3677
    Internal routine to query whether a property list is a certain class
 
3678
 USAGE
 
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
 
3682
 RETURNS
 
3683
    Success: TRUE (1) or FALSE (0)
 
3684
    Failure: negative
 
3685
 DESCRIPTION
 
3686
    This routine queries whether a property list is a member of the property
 
3687
    list class.
 
3688
 
 
3689
 GLOBAL VARIABLES
 
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
 
3695
 EXAMPLES
 
3696
 REVISION LOG
 
3697
--------------------------------------------------------------------------*/
 
3698
htri_t
 
3699
H5P_isa_class(hid_t plist_id, hid_t pclass_id)
 
3700
{
 
3701
    H5P_genplist_t  *plist;         /* Property list to query */
 
3702
    H5P_genclass_t  *pclass;        /* Property list class */
 
3703
    htri_t ret_value;                   /* return value */
 
3704
 
 
3705
    FUNC_ENTER_NOAPI(H5P_isa_class, FAIL);
 
3706
 
 
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");
 
3712
 
 
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");
 
3716
 
 
3717
done:
 
3718
    FUNC_LEAVE_NOAPI(ret_value);
 
3719
}   /* H5P_isa_class() */
 
3720
 
 
3721
 
 
3722
/*--------------------------------------------------------------------------
 
3723
 NAME
 
3724
    H5Pisa_class
 
3725
 PURPOSE
 
3726
    Routine to query whether a property list is a certain class
 
3727
 USAGE
 
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
 
3731
 RETURNS
 
3732
    Success: TRUE (1) or FALSE (0)
 
3733
    Failure: negative
 
3734
 DESCRIPTION
 
3735
    This routine queries whether a property list is a member of the property
 
3736
    list class.
 
3737
 
 
3738
 GLOBAL VARIABLES
 
3739
 COMMENTS, BUGS, ASSUMPTIONS
 
3740
    What about returning a value indicating that the property class is further
 
3741
    up the class hierarchy?
 
3742
 EXAMPLES
 
3743
 REVISION LOG
 
3744
--------------------------------------------------------------------------*/
 
3745
htri_t
 
3746
H5Pisa_class(hid_t plist_id, hid_t pclass_id)
 
3747
{
 
3748
    htri_t ret_value;                   /* return value */
 
3749
 
 
3750
    FUNC_ENTER_API(H5Pisa_class, FAIL);
 
3751
    H5TRACE2("t","ii",plist_id,pclass_id);
 
3752
 
 
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");
 
3758
 
 
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");
 
3762
 
 
3763
done:
 
3764
    FUNC_LEAVE_API(ret_value);
 
3765
}   /* H5Pisa_class() */
 
3766
 
 
3767
 
 
3768
/*--------------------------------------------------------------------------
 
3769
 NAME
 
3770
    H5P_object_verify
 
3771
 PURPOSE
 
3772
    Internal routine to query whether a property list is a certain class and
 
3773
        retrieve the property list object associated with it.
 
3774
 USAGE
 
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
 
3778
 RETURNS
 
3779
    Success: valid pointer to a property list object
 
3780
    Failure: NULL
 
3781
 DESCRIPTION
 
3782
    This routine queries whether a property list is member of a certain class
 
3783
    and retrieves the property list object associated with it.
 
3784
 
 
3785
 GLOBAL VARIABLES
 
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
 
3791
 
 
3792
    This function is similar (in spirit) to H5I_object_verify()
 
3793
 EXAMPLES
 
3794
 REVISION LOG
 
3795
--------------------------------------------------------------------------*/
 
3796
void *
 
3797
H5P_object_verify(hid_t plist_id, hid_t pclass_id)
 
3798
{
 
3799
    void *ret_value;                   /* return value */
 
3800
 
 
3801
    FUNC_ENTER_NOAPI(H5P_object_verify, NULL);
 
3802
 
 
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");
 
3806
 
 
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");
 
3810
 
 
3811
done:
 
3812
    FUNC_LEAVE_NOAPI(ret_value);
 
3813
}   /* H5P_object_verify() */
 
3814
 
 
3815
 
 
3816
/*--------------------------------------------------------------------------
 
3817
 NAME
 
3818
    H5P_iterate_plist
 
3819
 PURPOSE
 
3820
    Internal routine to iterate over the properties in a property list
 
3821
 USAGE
 
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
 
3828
 RETURNS
 
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
 
3832
 DESCRIPTION
 
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
 
3840
returns non-zero.
 
3841
 
 
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.
 
3847
 
 
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
 
3856
        property.
 
3857
 
 
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.
 
3861
 
 
3862
 GLOBAL VARIABLES
 
3863
 COMMENTS, BUGS, ASSUMPTIONS
 
3864
 EXAMPLES
 
3865
 REVISION LOG
 
3866
--------------------------------------------------------------------------*/
 
3867
static int
 
3868
H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_data)
 
3869
{
 
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 */
 
3877
 
 
3878
    FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_plist);
 
3879
 
 
3880
    assert(idx);
 
3881
    assert(iter_func);
 
3882
 
 
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");
 
3886
 
 
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");
 
3890
 
 
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);
 
3897
 
 
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);
 
3902
 
 
3903
                if(ret_value!=0)
 
3904
                    HGOTO_DONE(ret_value);
 
3905
            } /* end if */
 
3906
 
 
3907
            /* Increment the current index */
 
3908
            curr_idx++;
 
3909
 
 
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");
 
3913
 
 
3914
            /* Get the next property node in the skip list */
 
3915
            curr_node=H5SL_next(curr_node);
 
3916
        } /* end while */
 
3917
    } /* end if */
 
3918
 
 
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);
 
3928
 
 
3929
                /* Only call iterator callback for properties we haven't seen
 
3930
                 * before and that haven't been deleted
 
3931
                 */
 
3932
                if(H5SL_search(seen,tmp->name)==NULL &&
 
3933
                        H5SL_search(plist->del,tmp->name)==NULL) {
 
3934
 
 
3935
 
 
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);
 
3940
 
 
3941
                        if(ret_value!=0)
 
3942
                            HGOTO_DONE(ret_value);
 
3943
                    } /* end if */
 
3944
 
 
3945
                    /* Increment the current index */
 
3946
                    curr_idx++;
 
3947
 
 
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");
 
3951
                } /* end if */
 
3952
 
 
3953
                /* Get the next property node in the skip list */
 
3954
                curr_node=H5SL_next(curr_node);
 
3955
            } /* end while */
 
3956
        } /* end if */
 
3957
 
 
3958
        /* Go up to parent class */
 
3959
        tclass=tclass->parent;
 
3960
    } /* end while */
 
3961
 
 
3962
done:
 
3963
    /* Set the index we stopped at */
 
3964
    *idx=curr_idx;
 
3965
 
 
3966
    /* Release the skip list of 'seen' properties */
 
3967
    if(seen!=NULL)
 
3968
        H5SL_close(seen);
 
3969
 
 
3970
    FUNC_LEAVE_NOAPI(ret_value);
 
3971
}   /* H5P_iterate_plist() */
 
3972
 
 
3973
 
 
3974
/*--------------------------------------------------------------------------
 
3975
 NAME
 
3976
    H5P_iterate_pclass
 
3977
 PURPOSE
 
3978
    Internal routine to iterate over the properties in a property class
 
3979
 USAGE
 
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
 
3986
 RETURNS
 
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
 
3990
 DESCRIPTION
 
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
 
3998
returns non-zero.
 
3999
 
 
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.
 
4005
 
 
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
 
4014
        property.
 
4015
 
 
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.
 
4019
 
 
4020
 GLOBAL VARIABLES
 
4021
 COMMENTS, BUGS, ASSUMPTIONS
 
4022
 EXAMPLES
 
4023
 REVISION LOG
 
4024
--------------------------------------------------------------------------*/
 
4025
static int
 
4026
H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *iter_data)
 
4027
{
 
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 */
 
4033
 
 
4034
    FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_pclass);
 
4035
 
 
4036
    assert(idx);
 
4037
    assert(iter_func);
 
4038
 
 
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");
 
4042
 
 
4043
    /* Cycle through the properties and call the callback */
 
4044
    curr_idx=0;
 
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);
 
4050
 
 
4051
            /* Call the callback function */
 
4052
            ret_value=(*iter_func)(pclass_id,prop->name,iter_data);
 
4053
 
 
4054
            /* Check if iteration function succeeded */
 
4055
            if(ret_value!=0)
 
4056
                HGOTO_DONE(ret_value);
 
4057
        } /* end if */
 
4058
 
 
4059
        /* Increment the iteration index */
 
4060
        curr_idx++;
 
4061
 
 
4062
        /* Get the next property node in the skip list */
 
4063
        curr_node=H5SL_next(curr_node);
 
4064
    } /* end while */
 
4065
 
 
4066
done:
 
4067
    /* Set the index we stopped at */
 
4068
    *idx=curr_idx;
 
4069
 
 
4070
    FUNC_LEAVE_NOAPI(ret_value);
 
4071
}   /* H5P_iterate_pclass() */
 
4072
 
 
4073
 
 
4074
/*--------------------------------------------------------------------------
 
4075
 NAME
 
4076
    H5Piterate
 
4077
 PURPOSE
 
4078
    Routine to iterate over the properties in a property list or class
 
4079
 USAGE
 
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
 
4086
 RETURNS
 
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
 
4090
 DESCRIPTION
 
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).
 
4101
 
 
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.
 
4107
 
 
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
 
4116
        property.
 
4117
 
 
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.
 
4121
 
 
4122
 GLOBAL VARIABLES
 
4123
 COMMENTS, BUGS, ASSUMPTIONS
 
4124
 EXAMPLES
 
4125
 REVISION LOG
 
4126
--------------------------------------------------------------------------*/
 
4127
int
 
4128
H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func, void *iter_data)
 
4129
{
 
4130
    int fake_idx=0;         /* Index when user doesn't provide one */
 
4131
    int ret_value;          /* return value */
 
4132
 
 
4133
    FUNC_ENTER_API(H5Piterate, FAIL);
 
4134
    H5TRACE4("Is","i*Isxx",id,idx,iter_func,iter_data);
 
4135
 
 
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");
 
4141
 
 
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");
 
4146
    } /* end if */
 
4147
    else
 
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");
 
4152
        } /* end if */
 
4153
        else
 
4154
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
 
4155
 
 
4156
done:
 
4157
    FUNC_LEAVE_API(ret_value);
 
4158
}   /* H5Piterate() */
 
4159
 
 
4160
 
 
4161
/*--------------------------------------------------------------------------
 
4162
 NAME
 
4163
    H5P_peek_unsigned
 
4164
 PURPOSE
 
4165
    Internal routine to quickly retrieve the value of a property in a property list.
 
4166
 USAGE
 
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
 
4170
 RETURNS
 
4171
    Directly returns the value of the property in the list
 
4172
 DESCRIPTION
 
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
 
4178
    catch all errors.
 
4179
        This function does call the user's 'get' callback routine still.
 
4180
 
 
4181
 GLOBAL VARIABLES
 
4182
 COMMENTS, BUGS, ASSUMPTIONS
 
4183
    No error checking!
 
4184
    Use with caution!
 
4185
 EXAMPLES
 
4186
 REVISION LOG
 
4187
--------------------------------------------------------------------------*/
 
4188
unsigned
 
4189
H5P_peek_unsigned(H5P_genplist_t *plist, const char *name)
 
4190
{
 
4191
    unsigned ret_value;            /* return value */
 
4192
 
 
4193
    FUNC_ENTER_NOAPI(H5P_peek_unsigned, UFAIL);
 
4194
 
 
4195
    assert(plist);
 
4196
    assert(name);
 
4197
 
 
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);
 
4200
 
 
4201
done:
 
4202
    FUNC_LEAVE_NOAPI(ret_value);
 
4203
}   /* H5P_peek_unsigned() */
 
4204
 
 
4205
 
 
4206
/*--------------------------------------------------------------------------
 
4207
 NAME
 
4208
    H5P_peek_hid_t
 
4209
 PURPOSE
 
4210
    Internal routine to quickly retrieve the value of a property in a property list.
 
4211
 USAGE
 
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
 
4215
 RETURNS
 
4216
    Directly returns the value of the property in the list
 
4217
 DESCRIPTION
 
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
 
4223
    catch all errors.
 
4224
        This function does call the user's 'get' callback routine still.
 
4225
 
 
4226
 GLOBAL VARIABLES
 
4227
 COMMENTS, BUGS, ASSUMPTIONS
 
4228
    No error checking!
 
4229
    Use with caution!
 
4230
 EXAMPLES
 
4231
 REVISION LOG
 
4232
--------------------------------------------------------------------------*/
 
4233
hid_t
 
4234
H5P_peek_hid_t(H5P_genplist_t *plist, const char *name)
 
4235
{
 
4236
    hid_t ret_value;            /* return value */
 
4237
 
 
4238
    FUNC_ENTER_NOAPI(H5P_peek_hid_t, FAIL);
 
4239
 
 
4240
    assert(plist);
 
4241
    assert(name);
 
4242
 
 
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);
 
4245
 
 
4246
done:
 
4247
    FUNC_LEAVE_NOAPI(ret_value);
 
4248
}   /* H5P_peek_hid_t() */
 
4249
 
 
4250
 
 
4251
/*--------------------------------------------------------------------------
 
4252
 NAME
 
4253
    H5P_peek_voidp
 
4254
 PURPOSE
 
4255
    Internal routine to quickly retrieve the value of a property in a property list.
 
4256
 USAGE
 
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
 
4260
 RETURNS
 
4261
    Directly returns the value of the property in the list
 
4262
 DESCRIPTION
 
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
 
4268
    catch all errors.
 
4269
        This function does call the user's 'get' callback routine still.
 
4270
 
 
4271
 GLOBAL VARIABLES
 
4272
 COMMENTS, BUGS, ASSUMPTIONS
 
4273
    No error checking!
 
4274
    Use with caution!
 
4275
 EXAMPLES
 
4276
 REVISION LOG
 
4277
--------------------------------------------------------------------------*/
 
4278
void *
 
4279
H5P_peek_voidp(H5P_genplist_t *plist, const char *name)
 
4280
{
 
4281
    void * ret_value;            /* return value */
 
4282
 
 
4283
    FUNC_ENTER_NOAPI(H5P_peek_voidp, NULL);
 
4284
 
 
4285
    assert(plist);
 
4286
    assert(name);
 
4287
 
 
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);
 
4290
 
 
4291
done:
 
4292
    FUNC_LEAVE_NOAPI(ret_value);
 
4293
}   /* H5P_peek_voidp() */
 
4294
 
 
4295
 
 
4296
/*--------------------------------------------------------------------------
 
4297
 NAME
 
4298
    H5P_peek_size_t
 
4299
 PURPOSE
 
4300
    Internal routine to quickly retrieve the value of a property in a property list.
 
4301
 USAGE
 
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
 
4305
 RETURNS
 
4306
    Directly returns the value of the property in the list
 
4307
 DESCRIPTION
 
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
 
4313
    catch all errors.
 
4314
        This function does call the user's 'get' callback routine still.
 
4315
 
 
4316
 GLOBAL VARIABLES
 
4317
 COMMENTS, BUGS, ASSUMPTIONS
 
4318
    No error checking!
 
4319
    Use with caution!
 
4320
 EXAMPLES
 
4321
 REVISION LOG
 
4322
--------------------------------------------------------------------------*/
 
4323
size_t
 
4324
H5P_peek_size_t(H5P_genplist_t *plist, const char *name)
 
4325
{
 
4326
    size_t ret_value;            /* return value */
 
4327
 
 
4328
    FUNC_ENTER_NOAPI(H5P_peek_size_t, UFAIL);
 
4329
 
 
4330
    assert(plist);
 
4331
    assert(name);
 
4332
 
 
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);
 
4335
 
 
4336
done:
 
4337
    FUNC_LEAVE_NOAPI(ret_value);
 
4338
}   /* H5P_peek_size_t() */
 
4339
 
 
4340
 
 
4341
/*--------------------------------------------------------------------------
 
4342
 NAME
 
4343
    H5P_get
 
4344
 PURPOSE
 
4345
    Internal routine to query the value of a property in a property list.
 
4346
 USAGE
 
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
 
4351
 RETURNS
 
4352
    Returns non-negative on success, negative on failure.
 
4353
 DESCRIPTION
 
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
 
4359
    from this routine.
 
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.
 
4363
 
 
4364
 GLOBAL VARIABLES
 
4365
 COMMENTS, BUGS, ASSUMPTIONS
 
4366
 EXAMPLES
 
4367
 REVISION LOG
 
4368
--------------------------------------------------------------------------*/
 
4369
herr_t
 
4370
H5P_get(H5P_genplist_t *plist, const char *name, void *value)
 
4371
{
 
4372
    H5P_genclass_t *tclass;     /* Temporary class pointer */
 
4373
    H5P_genprop_t *prop;        /* Temporary property pointer */
 
4374
    herr_t      ret_value=SUCCEED;       /* Return value */
 
4375
 
 
4376
    FUNC_ENTER_NOAPI(H5P_get, FAIL);
 
4377
 
 
4378
    assert(plist);
 
4379
    assert(name);
 
4380
    assert(value);
 
4381
 
 
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");
 
4385
 
 
4386
    /* Find property */
 
4387
    if((prop=H5SL_search(plist->props,name))!=NULL) {
 
4388
        /* Check for property size >0 */
 
4389
        if(prop->size==0)
 
4390
            HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
 
4391
 
 
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 */
 
4395
 
 
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);
 
4400
 
 
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");
 
4404
 
 
4405
            /* Copy new [possibly unchanged] value into return value */
 
4406
            HDmemcpy(value,tmp_value,prop->size);
 
4407
 
 
4408
            /* Free the temporary value buffer */
 
4409
            H5MM_xfree(tmp_value);
 
4410
        } /* end if */
 
4411
        /* No 'get' callback, just copy value */
 
4412
        else
 
4413
            HDmemcpy(value,prop->value,prop->size);
 
4414
    } /* end if */
 
4415
    else {
 
4416
        /*
 
4417
         * Check if we should get class properties (up through list of parent classes also),
 
4418
         * & make property 'get' callback.
 
4419
         */
 
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 */
 
4426
                    if(prop->size==0)
 
4427
                        HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size");
 
4428
 
 
4429
                    /* Call the 'get' callback, if there is one */
 
4430
                    if(prop->get!=NULL) {
 
4431
                        void *tmp_value;            /* Temporary value for property */
 
4432
 
 
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);
 
4437
 
 
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");
 
4442
                        } /* end if */
 
4443
 
 
4444
                        if(HDmemcmp(tmp_value,prop->value,prop->size)) {
 
4445
                            H5P_genprop_t *pcopy;  /* Copy of property to insert into skip list */
 
4446
 
 
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");
 
4450
 
 
4451
                            /* Copy new value into property value */
 
4452
                            HDmemcpy(pcopy->value,tmp_value,prop->size);
 
4453
 
 
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");
 
4457
                        } /* end if */
 
4458
 
 
4459
                        /* Copy new [possibly unchanged] value into return value */
 
4460
                        HDmemcpy(value,tmp_value,prop->size);
 
4461
 
 
4462
                        /* Free the temporary value buffer */
 
4463
                        H5MM_xfree(tmp_value);
 
4464
                    } /* end if */
 
4465
                    /* No 'get' callback, just copy value */
 
4466
                    else
 
4467
                        HDmemcpy(value,prop->value,prop->size);
 
4468
 
 
4469
                    /* Leave */
 
4470
                    HGOTO_DONE(SUCCEED);
 
4471
                } /* end while */
 
4472
            } /* end if */
 
4473
 
 
4474
            /* Go up to parent class */
 
4475
            tclass=tclass->parent;
 
4476
        } /* end while */
 
4477
 
 
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
 
4480
         */
 
4481
        HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
 
4482
    } /* end else */
 
4483
 
 
4484
done:
 
4485
    FUNC_LEAVE_NOAPI(ret_value);
 
4486
}   /* H5P_get() */
 
4487
 
 
4488
 
 
4489
/*--------------------------------------------------------------------------
 
4490
 NAME
 
4491
    H5Pget
 
4492
 PURPOSE
 
4493
    Routine to query the value of a property in a property list.
 
4494
 USAGE
 
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
 
4499
 RETURNS
 
4500
    Returns non-negative on success, negative on failure.
 
4501
 DESCRIPTION
 
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
 
4507
    from this routine.
 
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.
 
4511
 
 
4512
 GLOBAL VARIABLES
 
4513
 COMMENTS, BUGS, ASSUMPTIONS
 
4514
 EXAMPLES
 
4515
 REVISION LOG
 
4516
--------------------------------------------------------------------------*/
 
4517
herr_t
 
4518
H5Pget(hid_t plist_id, const char *name, void *value)
 
4519
{
 
4520
    H5P_genplist_t *plist;      /* Property list pointer */
 
4521
    herr_t ret_value=SUCCEED;   /* return value */
 
4522
 
 
4523
    FUNC_ENTER_API(H5Pget, FAIL);
 
4524
    H5TRACE3("e","isx",plist_id,name,value);
 
4525
 
 
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");
 
4531
    if (value==NULL)
 
4532
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value");
 
4533
 
 
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");
 
4537
 
 
4538
done:
 
4539
    FUNC_LEAVE_API(ret_value);
 
4540
}   /* H5Pget() */
 
4541
 
 
4542
 
 
4543
/*--------------------------------------------------------------------------
 
4544
 NAME
 
4545
    H5P_remove
 
4546
 PURPOSE
 
4547
    Internal routine to remove a property from a property list.
 
4548
 USAGE
 
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
 
4552
 RETURNS
 
4553
    Returns non-negative on success, negative on failure.
 
4554
 DESCRIPTION
 
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.
 
4563
 
 
4564
 GLOBAL VARIABLES
 
4565
 COMMENTS, BUGS, ASSUMPTIONS
 
4566
 EXAMPLES
 
4567
 REVISION LOG
 
4568
--------------------------------------------------------------------------*/
 
4569
herr_t
 
4570
H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name)
 
4571
{
 
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 */
 
4576
 
 
4577
    FUNC_ENTER_NOAPI(H5P_remove,FAIL);
 
4578
 
 
4579
    assert(plist);
 
4580
    assert(name);
 
4581
 
 
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");
 
4585
 
 
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");
 
4593
        } /* end if */
 
4594
 
 
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");
 
4598
 
 
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");
 
4602
 
 
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");
 
4606
 
 
4607
        /* Free the property, ignoring return value, nothing we can do */
 
4608
        H5P_free_prop(prop);
 
4609
 
 
4610
        /* Decrement the number of properties in list */
 
4611
        plist->nprops--;
 
4612
    } /* end if */
 
4613
    /* Walk through all the properties in the class hierarchy, looking for the property */
 
4614
    else {
 
4615
        /*
 
4616
         * Check if we should delete class properties (up through list of parent classes also),
 
4617
         * & make property 'delete' callback.
 
4618
         */
 
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 */
 
4627
 
 
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);
 
4632
 
 
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");
 
4637
                        } /* end if */
 
4638
 
 
4639
                        /* Release the temporary value buffer */
 
4640
                        H5MM_xfree(tmp_value);
 
4641
                    } /* end if */
 
4642
 
 
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");
 
4646
 
 
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");
 
4650
 
 
4651
                    /* Decrement the number of properties in list */
 
4652
                    plist->nprops--;
 
4653
 
 
4654
                    /* Leave */
 
4655
                    HGOTO_DONE(SUCCEED);
 
4656
                } /* end while */
 
4657
            } /* end if */
 
4658
 
 
4659
            /* Go up to parent class */
 
4660
            tclass=tclass->parent;
 
4661
        } /* end while */
 
4662
 
 
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
 
4665
         */
 
4666
        HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
 
4667
    } /* end else */
 
4668
 
 
4669
done:
 
4670
    FUNC_LEAVE_NOAPI(ret_value);
 
4671
}   /* H5P_remove() */
 
4672
 
 
4673
 
 
4674
/*--------------------------------------------------------------------------
 
4675
 NAME
 
4676
    H5Premove
 
4677
 PURPOSE
 
4678
    Routine to remove a property from a property list.
 
4679
 USAGE
 
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
 
4683
 RETURNS
 
4684
    Returns non-negative on success, negative on failure.
 
4685
 DESCRIPTION
 
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.
 
4694
 
 
4695
 GLOBAL VARIABLES
 
4696
 COMMENTS, BUGS, ASSUMPTIONS
 
4697
 EXAMPLES
 
4698
 REVISION LOG
 
4699
--------------------------------------------------------------------------*/
 
4700
herr_t
 
4701
H5Premove(hid_t plist_id, const char *name)
 
4702
{
 
4703
    H5P_genplist_t  *plist;    /* Property list to modify */
 
4704
    herr_t ret_value;           /* return value */
 
4705
 
 
4706
    FUNC_ENTER_API(H5Premove, FAIL);
 
4707
    H5TRACE2("e","is",plist_id,name);
 
4708
 
 
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");
 
4714
 
 
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");
 
4718
 
 
4719
done:
 
4720
    FUNC_LEAVE_API(ret_value);
 
4721
}   /* H5Premove() */
 
4722
 
 
4723
 
 
4724
/*--------------------------------------------------------------------------
 
4725
 NAME
 
4726
    H5P_copy_prop_plist
 
4727
 PURPOSE
 
4728
    Internal routine to copy a property from one list to another
 
4729
 USAGE
 
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
 
4734
 RETURNS
 
4735
    Success: non-negative value.
 
4736
    Failure: negative value.
 
4737
 DESCRIPTION
 
4738
    Copies a property from one property list to another.
 
4739
 
 
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).
 
4745
 
 
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).
 
4749
 
 
4750
 GLOBAL VARIABLES
 
4751
 COMMENTS, BUGS, ASSUMPTIONS
 
4752
 EXAMPLES
 
4753
 REVISION LOG
 
4754
--------------------------------------------------------------------------*/
 
4755
static herr_t
 
4756
H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name)
 
4757
{
 
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 */
 
4763
 
 
4764
    FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_plist);
 
4765
 
 
4766
    assert(name);
 
4767
 
 
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");
 
4771
 
 
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");
 
4777
 
 
4778
        /* Get the pointer to the source property */
 
4779
        prop=H5P_find_prop_plist(src_plist,name);
 
4780
 
 
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");
 
4784
 
 
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");
 
4789
        } /* end if */
 
4790
 
 
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");
 
4794
 
 
4795
        /* Increment the number of properties in list */
 
4796
        dst_plist->nprops++;
 
4797
    } /* end if */
 
4798
    /* If not, get the information required to do an H5Pinsert with the property into the destination list */
 
4799
    else {
 
4800
        /* Get the pointer to the source property */
 
4801
        prop=H5P_find_prop_plist(src_plist,name);
 
4802
 
 
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");
 
4806
 
 
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");
 
4811
        } /* end if */
 
4812
 
 
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");
 
4816
 
 
4817
        /* Increment property count for class */
 
4818
        dst_plist->nprops++;
 
4819
 
 
4820
    } /* end else */
 
4821
 
 
4822
done:
 
4823
    /* Cleanup, if necessary */
 
4824
    if(ret_value<0) {
 
4825
        if(new_prop!=NULL)
 
4826
            H5P_free_prop(new_prop);
 
4827
    } /* end if */
 
4828
 
 
4829
    FUNC_LEAVE_NOAPI(ret_value);
 
4830
}   /* H5P_copy_prop_plist() */
 
4831
 
 
4832
 
 
4833
/*--------------------------------------------------------------------------
 
4834
 NAME
 
4835
    H5P_copy_prop_pclass
 
4836
 PURPOSE
 
4837
    Internal routine to copy a property from one class to another
 
4838
 USAGE
 
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
 
4843
 RETURNS
 
4844
    Success: non-negative value.
 
4845
    Failure: negative value.
 
4846
 DESCRIPTION
 
4847
    Copies a property from one property class to another.
 
4848
 
 
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
 
4852
    destination class.
 
4853
 
 
4854
    If the property does not exist in the destination class or list, this call
 
4855
    is equivalent to calling H5Pregister.
 
4856
 
 
4857
 GLOBAL VARIABLES
 
4858
 COMMENTS, BUGS, ASSUMPTIONS
 
4859
 EXAMPLES
 
4860
 REVISION LOG
 
4861
--------------------------------------------------------------------------*/
 
4862
static herr_t
 
4863
H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t *src_pclass, const char *name)
 
4864
{
 
4865
    H5P_genprop_t *prop;            /* Temporary property pointer */
 
4866
    herr_t ret_value=SUCCEED;       /* return value */
 
4867
 
 
4868
    FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_pclass);
 
4869
 
 
4870
    assert(dst_pclass);
 
4871
    assert(src_pclass);
 
4872
    assert(name);
 
4873
 
 
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");
 
4879
    } /* end if */
 
4880
 
 
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");
 
4884
 
 
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");
 
4888
 
 
4889
done:
 
4890
    /* Cleanup, if necessary */
 
4891
 
 
4892
    FUNC_LEAVE_NOAPI(ret_value);
 
4893
}   /* H5P_copy_prop_pclass() */
 
4894
 
 
4895
 
 
4896
/*--------------------------------------------------------------------------
 
4897
 NAME
 
4898
    H5Pcopy_prop
 
4899
 PURPOSE
 
4900
    Routine to copy a property from one list or class to another
 
4901
 USAGE
 
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
 
4906
 RETURNS
 
4907
    Success: non-negative value.
 
4908
    Failure: negative value.
 
4909
 DESCRIPTION
 
4910
    Copies a property from one property list or class to another.
 
4911
 
 
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
 
4915
    destination class.
 
4916
 
 
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).
 
4922
 
 
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
 
4927
    property).
 
4928
 
 
4929
 GLOBAL VARIABLES
 
4930
 COMMENTS, BUGS, ASSUMPTIONS
 
4931
 EXAMPLES
 
4932
 REVISION LOG
 
4933
--------------------------------------------------------------------------*/
 
4934
herr_t
 
4935
H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name)
 
4936
{
 
4937
    void *src_obj, *dst_obj;    /* Property objects to copy between */
 
4938
    herr_t ret_value=SUCCEED;      /* return value */
 
4939
 
 
4940
    FUNC_ENTER_API(H5Pcopy_prop, FAIL);
 
4941
    H5TRACE3("e","iis",dst_id,src_id,name);
 
4942
 
 
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");
 
4953
 
 
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");
 
4958
    } /* end if */
 
4959
    /* Must be property classes */
 
4960
    else {
 
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");
 
4963
    } /* end else */
 
4964
 
 
4965
done:
 
4966
    FUNC_LEAVE_API(ret_value);
 
4967
}   /* H5Pcopy_prop() */
 
4968
 
 
4969
 
 
4970
/*--------------------------------------------------------------------------
 
4971
 NAME
 
4972
    H5P_unregister
 
4973
 PURPOSE
 
4974
    Internal routine to remove a property from a property list class.
 
4975
 USAGE
 
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
 
4979
 RETURNS
 
4980
    Returns non-negative on success, negative on failure.
 
4981
 DESCRIPTION
 
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.
 
4985
 
 
4986
 GLOBAL VARIABLES
 
4987
 COMMENTS, BUGS, ASSUMPTIONS
 
4988
 EXAMPLES
 
4989
 REVISION LOG
 
4990
--------------------------------------------------------------------------*/
 
4991
static herr_t
 
4992
H5P_unregister(H5P_genclass_t *pclass, const char *name)
 
4993
{
 
4994
    H5P_genprop_t *prop;        /* Temporary property pointer */
 
4995
    herr_t      ret_value=SUCCEED;       /* Return value */
 
4996
 
 
4997
    FUNC_ENTER_NOAPI_NOINIT(H5P_unregister);
 
4998
 
 
4999
    assert(pclass);
 
5000
    assert(name);
 
5001
 
 
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");
 
5005
 
 
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");
 
5009
 
 
5010
    /* Free the property, ignoring return value, nothing we can do */
 
5011
    H5P_free_prop(prop);
 
5012
 
 
5013
    /* Decrement the number of registered properties in class */
 
5014
    pclass->nprops--;
 
5015
 
 
5016
    /* Update the revision for the class */
 
5017
    pclass->revision = H5P_GET_NEXT_REV;
 
5018
 
 
5019
done:
 
5020
    FUNC_LEAVE_NOAPI(ret_value);
 
5021
}   /* H5P_unregister() */
 
5022
 
 
5023
 
 
5024
/*--------------------------------------------------------------------------
 
5025
 NAME
 
5026
    H5Punregister
 
5027
 PURPOSE
 
5028
    Routine to remove a property from a property list class.
 
5029
 USAGE
 
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
 
5033
 RETURNS
 
5034
    Returns non-negative on success, negative on failure.
 
5035
 DESCRIPTION
 
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.
 
5039
 
 
5040
 GLOBAL VARIABLES
 
5041
 COMMENTS, BUGS, ASSUMPTIONS
 
5042
 EXAMPLES
 
5043
 REVISION LOG
 
5044
--------------------------------------------------------------------------*/
 
5045
herr_t
 
5046
H5Punregister(hid_t pclass_id, const char *name)
 
5047
{
 
5048
    H5P_genclass_t  *pclass;   /* Property list class to modify */
 
5049
    herr_t ret_value;           /* return value */
 
5050
 
 
5051
    FUNC_ENTER_API(H5Punregister, FAIL);
 
5052
    H5TRACE2("e","is",pclass_id,name);
 
5053
 
 
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");
 
5059
 
 
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");
 
5063
 
 
5064
done:
 
5065
    FUNC_LEAVE_API(ret_value);
 
5066
}   /* H5Punregister() */
 
5067
 
 
5068
 
 
5069
/*--------------------------------------------------------------------------
 
5070
 NAME
 
5071
    H5P_close
 
5072
 PURPOSE
 
5073
    Internal routine to close a property list.
 
5074
 USAGE
 
5075
    herr_t H5P_close(plist)
 
5076
        H5P_genplist_t *plist;  IN: Property list to close
 
5077
 RETURNS
 
5078
    Returns non-negative on success, negative on failure.
 
5079
 DESCRIPTION
 
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.
 
5084
 
 
5085
 GLOBAL VARIABLES
 
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
 
5089
    being called
 
5090
 EXAMPLES
 
5091
 REVISION LOG
 
5092
--------------------------------------------------------------------------*/
 
5093
herr_t
 
5094
H5P_close(void *_plist)
 
5095
{
 
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 */
 
5106
 
 
5107
    FUNC_ENTER_NOAPI_NOINIT(H5P_close);
 
5108
 
 
5109
    assert(plist);
 
5110
 
 
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);
 
5115
    } /* end if */
 
5116
 
 
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)
 
5121
     */
 
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");
 
5124
    nseen=0;
 
5125
 
 
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);
 
5132
 
 
5133
            /* Call property close callback, if it exists */
 
5134
            if(tmp->close) {
 
5135
                /* Call the 'close' callback */
 
5136
                (tmp->close)(tmp->name,tmp->size,tmp->value);
 
5137
            } /* end if */
 
5138
 
 
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");
 
5142
            nseen++;
 
5143
 
 
5144
            /* Get the next property node in the skip list */
 
5145
            curr_node=H5SL_next(curr_node);
 
5146
        } /* end while */
 
5147
    } /* end if */
 
5148
 
 
5149
    /* Determine number of deleted items from property list */
 
5150
    ndel=H5SL_count(plist->del);
 
5151
 
 
5152
    /*
 
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.
 
5155
     */
 
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);
 
5165
 
 
5166
                /* Only "delete" properties we haven't seen before
 
5167
                 * and that haven't already been deleted
 
5168
                 */
 
5169
                if((nseen==0 || H5SL_search(seen,tmp->name)==NULL) &&
 
5170
                        (ndel==0 || H5SL_search(plist->del,tmp->name)==NULL)) {
 
5171
 
 
5172
                    /* Call property close callback, if it exists */
 
5173
                    if(tmp->close) {
 
5174
                        void *tmp_value;       /* Temporary value buffer */
 
5175
 
 
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);
 
5180
 
 
5181
                        /* Call the 'close' callback */
 
5182
                        (tmp->close)(tmp->name,tmp->size,tmp_value);
 
5183
 
 
5184
                        /* Release the temporary value buffer */
 
5185
                        H5MM_xfree(tmp_value);
 
5186
                    } /* end if */
 
5187
 
 
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");
 
5192
                        nseen++;
 
5193
                    } /* end if */
 
5194
                } /* end if */
 
5195
 
 
5196
                /* Get the next property node in the skip list */
 
5197
                curr_node=H5SL_next(curr_node);
 
5198
            } /* end while */
 
5199
        } /* end if */
 
5200
 
 
5201
        /* Go up to parent class */
 
5202
        tclass=tclass->parent;
 
5203
    } /* end while */
 
5204
 
 
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");
 
5208
 
 
5209
    /* Free the list of 'seen' properties */
 
5210
    H5SL_close(seen);
 
5211
    seen=NULL;
 
5212
 
 
5213
    /* Free the list of deleted property names */
 
5214
    H5SL_destroy(plist->del,H5P_free_del_name_cb,NULL);
 
5215
 
 
5216
    /* Free the properties */
 
5217
    H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb);
 
5218
 
 
5219
    /* Destroy property list object */
 
5220
    H5FL_FREE(H5P_genplist_t,plist);
 
5221
 
 
5222
done:
 
5223
    /* Release the skip list of 'seen' properties */
 
5224
    if(seen!=NULL)
 
5225
        H5SL_close(seen);
 
5226
 
 
5227
    FUNC_LEAVE_NOAPI(ret_value);
 
5228
}   /* H5P_close() */
 
5229
 
 
5230
 
 
5231
/*--------------------------------------------------------------------------
 
5232
 NAME
 
5233
    H5Pclose
 
5234
 PURPOSE
 
5235
    Routine to close a property list.
 
5236
 USAGE
 
5237
    herr_t H5Pclose(plist_id)
 
5238
        hid_t plist_id;       IN: Property list to close
 
5239
 RETURNS
 
5240
    Returns non-negative on success, negative on failure.
 
5241
 DESCRIPTION
 
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.
 
5246
 
 
5247
 GLOBAL VARIABLES
 
5248
 COMMENTS, BUGS, ASSUMPTIONS
 
5249
 EXAMPLES
 
5250
 REVISION LOG
 
5251
--------------------------------------------------------------------------*/
 
5252
herr_t
 
5253
H5Pclose(hid_t plist_id)
 
5254
{
 
5255
    herr_t ret_value=SUCCEED;      /* return value */
 
5256
 
 
5257
    FUNC_ENTER_API(H5Pclose, FAIL);
 
5258
    H5TRACE1("e","i",plist_id);
 
5259
 
 
5260
    if (plist_id==H5P_DEFAULT)
 
5261
        HGOTO_DONE(SUCCEED);
 
5262
 
 
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");
 
5266
 
 
5267
    /* Close the property list */
 
5268
    if (H5I_dec_ref(plist_id) < 0)
 
5269
        HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close");
 
5270
 
 
5271
done:
 
5272
    FUNC_LEAVE_API(ret_value);
 
5273
}   /* H5Pclose() */
 
5274
 
 
5275
 
 
5276
/*--------------------------------------------------------------------------
 
5277
 NAME
 
5278
    H5P_get_class_name
 
5279
 PURPOSE
 
5280
    Internal routine to query the name of a generic property list class
 
5281
 USAGE
 
5282
    char *H5P_get_class_name(pclass)
 
5283
        H5P_genclass_t *pclass;    IN: Property list class to check
 
5284
 RETURNS
 
5285
    Success: Pointer to a malloc'ed string containing the class name
 
5286
    Failure: NULL
 
5287
 DESCRIPTION
 
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.
 
5290
 
 
5291
 GLOBAL VARIABLES
 
5292
 COMMENTS, BUGS, ASSUMPTIONS
 
5293
 EXAMPLES
 
5294
 REVISION LOG
 
5295
--------------------------------------------------------------------------*/
 
5296
char *
 
5297
H5P_get_class_name(H5P_genclass_t *pclass)
 
5298
{
 
5299
    char *ret_value;      /* return value */
 
5300
 
 
5301
    FUNC_ENTER_NOAPI(H5P_get_class_name, NULL);
 
5302
 
 
5303
    assert(pclass);
 
5304
 
 
5305
    /* Get class name */
 
5306
    ret_value=H5MM_xstrdup(pclass->name);
 
5307
 
 
5308
done:
 
5309
    FUNC_LEAVE_NOAPI(ret_value);
 
5310
}   /* H5P_get_class_name() */
 
5311
 
 
5312
 
 
5313
/*--------------------------------------------------------------------------
 
5314
 NAME
 
5315
    H5Pget_class_name
 
5316
 PURPOSE
 
5317
    Routine to query the name of a generic property list class
 
5318
 USAGE
 
5319
    char *H5Pget_class_name(pclass_id)
 
5320
        hid_t pclass_id;         IN: Property class to query
 
5321
 RETURNS
 
5322
    Success: Pointer to a malloc'ed string containing the class name
 
5323
    Failure: NULL
 
5324
 DESCRIPTION
 
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.
 
5327
 
 
5328
 GLOBAL VARIABLES
 
5329
 COMMENTS, BUGS, ASSUMPTIONS
 
5330
 EXAMPLES
 
5331
 REVISION LOG
 
5332
--------------------------------------------------------------------------*/
 
5333
char *
 
5334
H5Pget_class_name(hid_t pclass_id)
 
5335
{
 
5336
    H5P_genclass_t  *pclass;    /* Property class to query */
 
5337
    char *ret_value;       /* return value */
 
5338
 
 
5339
    FUNC_ENTER_API(H5Pget_class_name, NULL);
 
5340
 
 
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");
 
5344
 
 
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");
 
5348
 
 
5349
done:
 
5350
    FUNC_LEAVE_API(ret_value);
 
5351
}   /* H5Pget_class_name() */
 
5352
 
 
5353
 
 
5354
/*--------------------------------------------------------------------------
 
5355
 NAME
 
5356
    H5P_get_class_path
 
5357
 PURPOSE
 
5358
    Internal routine to query the full path of a generic property list class
 
5359
 USAGE
 
5360
    char *H5P_get_class_name(pclass)
 
5361
        H5P_genclass_t *pclass;    IN: Property list class to check
 
5362
 RETURNS
 
5363
    Success: Pointer to a malloc'ed string containing the full path of class
 
5364
    Failure: NULL
 
5365
 DESCRIPTION
 
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.
 
5369
 
 
5370
 GLOBAL VARIABLES
 
5371
 COMMENTS, BUGS, ASSUMPTIONS
 
5372
 EXAMPLES
 
5373
 REVISION LOG
 
5374
--------------------------------------------------------------------------*/
 
5375
char *
 
5376
H5P_get_class_path(H5P_genclass_t *pclass)
 
5377
{
 
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 */
 
5382
 
 
5383
    FUNC_ENTER_NOAPI_NOINIT(H5P_get_class_path);
 
5384
 
 
5385
    assert(pclass);
 
5386
 
 
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);
 
5395
 
 
5396
            /* Allocate enough space for the parent class's path, plus the '/'
 
5397
             * separator, this class's name and the string terminator
 
5398
             */
 
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");
 
5401
 
 
5402
            /* Build the full path for this class */
 
5403
            HDstrcpy(ret_value,par_path);
 
5404
            HDstrcat(ret_value,"/");
 
5405
            HDstrcat(ret_value,pclass->name);
 
5406
 
 
5407
            /* Free the parent class's path */
 
5408
            H5MM_xfree(par_path);
 
5409
        } /* end if */
 
5410
        else
 
5411
            ret_value=H5MM_xstrdup(pclass->name);
 
5412
    } /* end if */
 
5413
    else
 
5414
        ret_value=H5MM_xstrdup(pclass->name);
 
5415
 
 
5416
done:
 
5417
    FUNC_LEAVE_NOAPI(ret_value);
 
5418
}   /* H5P_get_class_path() */
 
5419
 
 
5420
 
 
5421
/*--------------------------------------------------------------------------
 
5422
 NAME
 
5423
    H5P_open_class_path
 
5424
 PURPOSE
 
5425
    Internal routine to open [a copy of] a class with its full path name
 
5426
 USAGE
 
5427
    H5P_genclass_t *H5P_open_class_path(path)
 
5428
        const char *path;       IN: Full path name of class to open [copy of]
 
5429
 RETURNS
 
5430
    Success: Pointer to a generic property class object
 
5431
    Failure: NULL
 
5432
 DESCRIPTION
 
5433
    This routine opens [a copy] of the class indicated by the full path.
 
5434
 
 
5435
 GLOBAL VARIABLES
 
5436
 COMMENTS, BUGS, ASSUMPTIONS
 
5437
 EXAMPLES
 
5438
 REVISION LOG
 
5439
--------------------------------------------------------------------------*/
 
5440
H5P_genclass_t *
 
5441
H5P_open_class_path(const char *path)
 
5442
{
 
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 */
 
5449
 
 
5450
    FUNC_ENTER_NOAPI_NOINIT(H5P_open_class_path);
 
5451
 
 
5452
    assert(path);
 
5453
 
 
5454
    /* Duplicate the path to use */
 
5455
    tmp_path=HDstrdup(path);
 
5456
    assert(tmp_path);
 
5457
 
 
5458
    /* Find the generic property class with this full path */
 
5459
    curr_name=tmp_path;
 
5460
    curr_class=NULL;
 
5461
    while((delimit=HDstrchr(curr_name,'/'))!=NULL) {
 
5462
        /* Change the delimiter to terminate the string */
 
5463
        *delimit='\0';
 
5464
 
 
5465
        /* Set up the search structure */
 
5466
        check_info.parent=curr_class;
 
5467
        check_info.name=curr_name;
 
5468
 
 
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");
 
5472
 
 
5473
        /* Advance the pointer in the path to the start of the next component */
 
5474
        curr_name=delimit+1;
 
5475
    } /* end while */
 
5476
 
 
5477
    /* Should be pointing to the last component in the path name now... */
 
5478
 
 
5479
    /* Set up the search structure */
 
5480
    check_info.parent=curr_class;
 
5481
    check_info.name=curr_name;
 
5482
 
 
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");
 
5486
 
 
5487
    /* Copy it */
 
5488
    if((ret_value=H5P_copy_pclass(curr_class))==NULL)
 
5489
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL, "can't copy property class");
 
5490
 
 
5491
done:
 
5492
    /* Free the duplicated path */
 
5493
    H5MM_xfree(tmp_path);
 
5494
 
 
5495
    FUNC_LEAVE_NOAPI(ret_value);
 
5496
}   /* H5P_open_class_path() */
 
5497
 
 
5498
 
 
5499
/*--------------------------------------------------------------------------
 
5500
 NAME
 
5501
    H5P_get_class_parent
 
5502
 PURPOSE
 
5503
    Internal routine to query the parent class of a generic property class
 
5504
 USAGE
 
5505
    H5P_genclass_t *H5P_get_class_parent(pclass)
 
5506
        H5P_genclass_t *pclass;    IN: Property class to check
 
5507
 RETURNS
 
5508
    Success: Pointer to the parent class of a property class
 
5509
    Failure: NULL
 
5510
 DESCRIPTION
 
5511
    This routine retrieves a pointer to the parent class for a property class.
 
5512
 
 
5513
 GLOBAL VARIABLES
 
5514
 COMMENTS, BUGS, ASSUMPTIONS
 
5515
 EXAMPLES
 
5516
 REVISION LOG
 
5517
--------------------------------------------------------------------------*/
 
5518
static H5P_genclass_t *
 
5519
H5P_get_class_parent(H5P_genclass_t *pclass)
 
5520
{
 
5521
    H5P_genclass_t *ret_value;      /* return value */
 
5522
 
 
5523
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class_parent);
 
5524
 
 
5525
    assert(pclass);
 
5526
 
 
5527
    /* Get property size */
 
5528
    ret_value=pclass->parent;
 
5529
 
 
5530
    FUNC_LEAVE_NOAPI(ret_value);
 
5531
}   /* H5P_get_class_parent() */
 
5532
 
 
5533
 
 
5534
/*--------------------------------------------------------------------------
 
5535
 NAME
 
5536
    H5Pget_class_parent
 
5537
 PURPOSE
 
5538
    routine to query the parent class of a generic property class
 
5539
 USAGE
 
5540
    hid_t H5Pget_class_parent(pclass_id)
 
5541
        hid_t pclass_id;         IN: Property class to query
 
5542
 RETURNS
 
5543
    Success: ID of parent class object
 
5544
    Failure: NULL
 
5545
 DESCRIPTION
 
5546
    This routine retrieves an ID for the parent class of a property class.
 
5547
 
 
5548
 GLOBAL VARIABLES
 
5549
 COMMENTS, BUGS, ASSUMPTIONS
 
5550
 EXAMPLES
 
5551
 REVISION LOG
 
5552
--------------------------------------------------------------------------*/
 
5553
hid_t
 
5554
H5Pget_class_parent(hid_t pclass_id)
 
5555
{
 
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 */
 
5559
 
 
5560
    FUNC_ENTER_API(H5Pget_class_parent, FAIL);
 
5561
    H5TRACE1("i","i",pclass_id);
 
5562
 
 
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");
 
5566
 
 
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");
 
5570
 
 
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");
 
5574
 
 
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");
 
5578
 
 
5579
done:
 
5580
    if (ret_value<0 && parent)
 
5581
        H5P_close_class(parent);
 
5582
 
 
5583
    FUNC_LEAVE_API(ret_value);
 
5584
}   /* H5Pget_class_parent() */
 
5585
 
 
5586
 
 
5587
/*--------------------------------------------------------------------------
 
5588
 NAME
 
5589
    H5P_close_class
 
5590
 PURPOSE
 
5591
    Internal routine to close a property list class.
 
5592
 USAGE
 
5593
    herr_t H5P_close_class(class)
 
5594
        H5P_genclass_t *class;  IN: Property list class to close
 
5595
 RETURNS
 
5596
    Returns non-negative on success, negative on failure.
 
5597
 DESCRIPTION
 
5598
    Releases memory and de-attach a class from the property list class hierarchy.
 
5599
 GLOBAL VARIABLES
 
5600
 COMMENTS, BUGS, ASSUMPTIONS
 
5601
 EXAMPLES
 
5602
 REVISION LOG
 
5603
--------------------------------------------------------------------------*/
 
5604
herr_t
 
5605
H5P_close_class(void *_pclass)
 
5606
{
 
5607
    H5P_genclass_t *pclass=(H5P_genclass_t *)_pclass;
 
5608
    herr_t      ret_value=SUCCEED;       /* Return value */
 
5609
 
 
5610
    FUNC_ENTER_NOAPI_NOINIT(H5P_close_class);
 
5611
 
 
5612
    assert(pclass);
 
5613
 
 
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");
 
5617
 
 
5618
done:
 
5619
    FUNC_LEAVE_NOAPI(ret_value);
 
5620
}   /* H5P_close_class() */
 
5621
 
 
5622
 
 
5623
/*--------------------------------------------------------------------------
 
5624
 NAME
 
5625
    H5Pclose_class
 
5626
 PURPOSE
 
5627
    Close a property list class.
 
5628
 USAGE
 
5629
    herr_t H5Pclose_class(cls_id)
 
5630
        hid_t cls_id;       IN: Property list class ID to class
 
5631
 
 
5632
 RETURNS
 
5633
    Returns non-negative on success, negative on failure.
 
5634
 DESCRIPTION
 
5635
    Releases memory and de-attach a class from the property list class hierarchy.
 
5636
 GLOBAL VARIABLES
 
5637
 COMMENTS, BUGS, ASSUMPTIONS
 
5638
 EXAMPLES
 
5639
 REVISION LOG
 
5640
--------------------------------------------------------------------------*/
 
5641
herr_t
 
5642
H5Pclose_class(hid_t cls_id)
 
5643
{
 
5644
    hid_t  ret_value = SUCCEED;    /* Return value      */
 
5645
 
 
5646
    FUNC_ENTER_API(H5Pclose_class, FAIL);
 
5647
    H5TRACE1("e","i",cls_id);
 
5648
 
 
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");
 
5652
 
 
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");
 
5656
 
 
5657
done:
 
5658
    FUNC_LEAVE_API(ret_value);
 
5659
}   /* H5Pclose_class() */