Coverage Report

Created: 2024-06-18 06:29

/src/hdf5/src/H5Pocpl.c
Line
Count
Source (jump to first uncovered line)
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
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 COPYING file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*-------------------------------------------------------------------------
14
 *
15
 * Created:   H5Pocpl.c
16
 *
17
 * Purpose:   Object creation property list class routines
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
/****************/
23
/* Module Setup */
24
/****************/
25
26
#define H5O_FRIEND     /*suppress error about including H5Opkg      */
27
#include "H5Pmodule.h" /* This source code file is part of the H5P module */
28
29
/***********/
30
/* Headers */
31
/***********/
32
#include "H5private.h"   /* Generic Functions                        */
33
#include "H5Eprivate.h"  /* Error handling                           */
34
#include "H5MMprivate.h" /* Memory management                        */
35
#include "H5Opkg.h"      /* Object headers                           */
36
#include "H5Ppkg.h"      /* Property lists                           */
37
#include "H5VMprivate.h" /* Vector Functions                         */
38
#include "H5Zprivate.h"  /* Filter pipeline                          */
39
40
/****************/
41
/* Local Macros */
42
/****************/
43
44
/* ========= Object Creation properties ============ */
45
/* Definitions for the max. # of attributes to store compactly */
46
1
#define H5O_CRT_ATTR_MAX_COMPACT_SIZE sizeof(unsigned)
47
1
#define H5O_CRT_ATTR_MAX_COMPACT_ENC  H5P__encode_unsigned
48
1
#define H5O_CRT_ATTR_MAX_COMPACT_DEC  H5P__decode_unsigned
49
/* Definitions for the min. # of attributes to store densely */
50
1
#define H5O_CRT_ATTR_MIN_DENSE_SIZE sizeof(unsigned)
51
1
#define H5O_CRT_ATTR_MIN_DENSE_ENC  H5P__encode_unsigned
52
1
#define H5O_CRT_ATTR_MIN_DENSE_DEC  H5P__decode_unsigned
53
/* Definitions for object header flags */
54
1
#define H5O_CRT_OHDR_FLAGS_SIZE sizeof(uint8_t)
55
1
#define H5O_CRT_OHDR_FLAGS_ENC  H5P__encode_uint8_t
56
1
#define H5O_CRT_OHDR_FLAGS_DEC  H5P__decode_uint8_t
57
/* Definitions for filter pipeline */
58
1
#define H5O_CRT_PIPELINE_SIZE  sizeof(H5O_pline_t)
59
1
#define H5O_CRT_PIPELINE_SET   H5P__ocrt_pipeline_set
60
1
#define H5O_CRT_PIPELINE_GET   H5P__ocrt_pipeline_get
61
1
#define H5O_CRT_PIPELINE_ENC   H5P__ocrt_pipeline_enc
62
1
#define H5O_CRT_PIPELINE_DEC   H5P__ocrt_pipeline_dec
63
1
#define H5O_CRT_PIPELINE_DEL   H5P__ocrt_pipeline_del
64
1
#define H5O_CRT_PIPELINE_COPY  H5P__ocrt_pipeline_copy
65
1
#define H5O_CRT_PIPELINE_CMP   H5P__ocrt_pipeline_cmp
66
1
#define H5O_CRT_PIPELINE_CLOSE H5P__ocrt_pipeline_close
67
68
/******************/
69
/* Local Typedefs */
70
/******************/
71
72
/********************/
73
/* Package Typedefs */
74
/********************/
75
76
/********************/
77
/* Local Prototypes */
78
/********************/
79
80
/* Property class callbacks */
81
static herr_t H5P__ocrt_reg_prop(H5P_genclass_t *pclass);
82
83
/* Property callbacks */
84
static herr_t H5P__ocrt_pipeline_enc(const void *value, void **_pp, size_t *size);
85
static herr_t H5P__ocrt_pipeline_dec(const void **_pp, void *value);
86
static herr_t H5P__ocrt_pipeline_set(hid_t prop_id, const char *name, size_t size, void *value);
87
static herr_t H5P__ocrt_pipeline_get(hid_t prop_id, const char *name, size_t size, void *value);
88
static herr_t H5P__ocrt_pipeline_del(hid_t prop_id, const char *name, size_t size, void *value);
89
static herr_t H5P__ocrt_pipeline_copy(const char *name, size_t size, void *value);
90
static int    H5P__ocrt_pipeline_cmp(const void *value1, const void *value2, size_t size);
91
static herr_t H5P__ocrt_pipeline_close(const char *name, size_t size, void *value);
92
93
/* Local routines */
94
static herr_t H5P__set_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned int flags,
95
                              size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]);
96
97
/*********************/
98
/* Package Variables */
99
/*********************/
100
101
/* Object creation property list class library initialization object */
102
const H5P_libclass_t H5P_CLS_OCRT[1] = {{
103
    "object create",        /* Class name for debugging     */
104
    H5P_TYPE_OBJECT_CREATE, /* Class type                   */
105
106
    &H5P_CLS_ROOT_g,             /* Parent class                 */
107
    &H5P_CLS_OBJECT_CREATE_g,    /* Pointer to class             */
108
    &H5P_CLS_OBJECT_CREATE_ID_g, /* Pointer to class ID          */
109
    NULL,                        /* Pointer to default property list ID   */
110
    H5P__ocrt_reg_prop,          /* Default property registration routine */
111
112
    NULL, /* Class creation callback      */
113
    NULL, /* Class creation callback info */
114
    NULL, /* Class copy callback          */
115
    NULL, /* Class copy callback info     */
116
    NULL, /* Class close callback         */
117
    NULL  /* Class close callback info    */
118
}};
119
120
/*****************************/
121
/* Library Private Variables */
122
/*****************************/
123
124
/*******************/
125
/* Local Variables */
126
/*******************/
127
128
/* Property value defaults */
129
static const unsigned H5O_def_attr_max_compact_g =
130
    H5O_CRT_ATTR_MAX_COMPACT_DEF; /* Default max. compact attribute storage settings */
131
static const unsigned H5O_def_attr_min_dense_g =
132
    H5O_CRT_ATTR_MIN_DENSE_DEF; /* Default min. dense attribute storage settings */
133
static const uint8_t H5O_def_ohdr_flags_g = H5O_CRT_OHDR_FLAGS_DEF; /* Default object header flag settings */
134
static const H5O_pline_t H5O_def_pline_g  = H5O_CRT_PIPELINE_DEF;   /* Default I/O pipeline setting */
135
136
/*-------------------------------------------------------------------------
137
 * Function:    H5P__ocrt_reg_prop
138
 *
139
 * Purpose:     Initialize the object creation property list class
140
 *
141
 * Return:      Non-negative on success/Negative on failure
142
 *
143
 *-------------------------------------------------------------------------
144
 */
145
static herr_t
146
H5P__ocrt_reg_prop(H5P_genclass_t *pclass)
147
1
{
148
1
    herr_t ret_value = SUCCEED; /* Return value */
149
150
1
    FUNC_ENTER_PACKAGE
151
152
    /* Register max. compact attribute storage property */
153
1
    if (H5P__register_real(pclass, H5O_CRT_ATTR_MAX_COMPACT_NAME, H5O_CRT_ATTR_MAX_COMPACT_SIZE,
154
1
                           &H5O_def_attr_max_compact_g, NULL, NULL, NULL, H5O_CRT_ATTR_MAX_COMPACT_ENC,
155
1
                           H5O_CRT_ATTR_MAX_COMPACT_DEC, NULL, NULL, NULL, NULL) < 0)
156
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
157
158
    /* Register min. dense attribute storage property */
159
1
    if (H5P__register_real(pclass, H5O_CRT_ATTR_MIN_DENSE_NAME, H5O_CRT_ATTR_MIN_DENSE_SIZE,
160
1
                           &H5O_def_attr_min_dense_g, NULL, NULL, NULL, H5O_CRT_ATTR_MIN_DENSE_ENC,
161
1
                           H5O_CRT_ATTR_MIN_DENSE_DEC, NULL, NULL, NULL, NULL) < 0)
162
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
163
164
    /* Register object header flags property */
165
1
    if (H5P__register_real(pclass, H5O_CRT_OHDR_FLAGS_NAME, H5O_CRT_OHDR_FLAGS_SIZE, &H5O_def_ohdr_flags_g,
166
1
                           NULL, NULL, NULL, H5O_CRT_OHDR_FLAGS_ENC, H5O_CRT_OHDR_FLAGS_DEC, NULL, NULL, NULL,
167
1
                           NULL) < 0)
168
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
169
170
    /* Register the pipeline property */
171
1
    if (H5P__register_real(pclass, H5O_CRT_PIPELINE_NAME, H5O_CRT_PIPELINE_SIZE, &H5O_def_pline_g, NULL,
172
1
                           H5O_CRT_PIPELINE_SET, H5O_CRT_PIPELINE_GET, H5O_CRT_PIPELINE_ENC,
173
1
                           H5O_CRT_PIPELINE_DEC, H5O_CRT_PIPELINE_DEL, H5O_CRT_PIPELINE_COPY,
174
1
                           H5O_CRT_PIPELINE_CMP, H5O_CRT_PIPELINE_CLOSE) < 0)
175
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
176
177
1
done:
178
1
    FUNC_LEAVE_NOAPI(ret_value)
179
1
} /* end H5P__ocrt_reg_prop() */
180
181
/*-------------------------------------------------------------------------
182
 * Function:    H5Pset_attr_phase_change
183
 *
184
 * Purpose:    Sets the cutoff values for indexes storing attributes
185
 *              in object headers for this file.  If more than max_compact
186
 *              attributes are in an object header, the attributes will be
187
 *              moved to a heap and indexed with a B-tree.
188
 *              Likewise, an object header containing fewer than min_dense
189
 *              attributes will be converted back to storing the attributes
190
 *              directly in the object header.
191
 *
192
 *              If the max_compact is zero then attributes for this object will
193
 *              never be stored in the object header but will be always be
194
 *              stored in a heap.
195
 *
196
 * Return:    Non-negative on success/Negative on failure
197
 *
198
 *-------------------------------------------------------------------------
199
 */
200
herr_t
201
H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense)
202
0
{
203
0
    H5P_genplist_t *plist;               /* Property list pointer */
204
0
    herr_t          ret_value = SUCCEED; /* Return value */
205
206
0
    FUNC_ENTER_API(FAIL)
207
208
    /* Range check values */
209
0
    if (max_compact < min_dense)
210
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "max compact value must be >= min dense value");
211
0
    if (max_compact > 65535)
212
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "max compact value must be < 65536");
213
0
    if (min_dense > 65535)
214
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "min dense value must be < 65536");
215
216
    /* Get the plist structure */
217
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
218
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
219
220
    /* Set property values */
221
0
    if (H5P_set(plist, H5O_CRT_ATTR_MAX_COMPACT_NAME, &max_compact) < 0)
222
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set max. # of compact attributes in property list");
223
0
    if (H5P_set(plist, H5O_CRT_ATTR_MIN_DENSE_NAME, &min_dense) < 0)
224
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set min. # of dense attributes in property list");
225
226
0
done:
227
0
    FUNC_LEAVE_API(ret_value)
228
0
} /* end H5Pset_attr_phase_change */
229
230
/*-------------------------------------------------------------------------
231
 * Function:    H5Pget_attr_phase_change
232
 *
233
 * Purpose:    Gets the phase change values for attribute storage
234
 *
235
 * Return:    Non-negative on success/Negative on failure
236
 *
237
 *-------------------------------------------------------------------------
238
 */
239
herr_t
240
H5Pget_attr_phase_change(hid_t plist_id, unsigned *max_compact /*out*/, unsigned *min_dense /*out*/)
241
0
{
242
0
    H5P_genplist_t *plist;               /* Property list pointer */
243
0
    herr_t          ret_value = SUCCEED; /* Return value */
244
245
0
    FUNC_ENTER_API(FAIL)
246
247
    /* Get the plist structure */
248
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
249
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
250
251
    /* Get values */
252
0
    if (max_compact) {
253
0
        if (H5P_get(plist, H5O_CRT_ATTR_MAX_COMPACT_NAME, max_compact) < 0)
254
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get max. # of compact attributes");
255
0
    } /* end if */
256
0
    if (min_dense) {
257
0
        if (H5P_get(plist, H5O_CRT_ATTR_MIN_DENSE_NAME, min_dense) < 0)
258
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get min. # of dense attributes");
259
0
    } /* end if */
260
261
0
done:
262
0
    FUNC_LEAVE_API(ret_value)
263
0
} /* end H5Pget_attr_phase_change() */
264
265
/*-------------------------------------------------------------------------
266
 * Function:    H5Pset_attr_creation_order
267
 *
268
 * Purpose:     Set the flags for creation order of attributes on an object
269
 *
270
 * Return:      Non-negative on success/Negative on failure
271
 *
272
 *-------------------------------------------------------------------------
273
 */
274
herr_t
275
H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flags)
276
0
{
277
0
    H5P_genplist_t *plist;               /* Property list pointer */
278
0
    uint8_t         ohdr_flags;          /* Object header flags */
279
0
    herr_t          ret_value = SUCCEED; /* Return value */
280
281
0
    FUNC_ENTER_API(FAIL)
282
283
    /* Check for bad combination of flags */
284
0
    if (!(crt_order_flags & H5P_CRT_ORDER_TRACKED) && (crt_order_flags & H5P_CRT_ORDER_INDEXED))
285
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "tracking creation order is required for index");
286
287
    /* Get the plist structure */
288
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
289
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
290
291
    /* Get object header flags */
292
0
    if (H5P_get(plist, H5O_CRT_OHDR_FLAGS_NAME, &ohdr_flags) < 0)
293
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags");
294
295
    /* Mask off previous attribute creation order flag settings */
296
0
    ohdr_flags &= (uint8_t) ~(H5O_HDR_ATTR_CRT_ORDER_TRACKED | H5O_HDR_ATTR_CRT_ORDER_INDEXED);
297
298
    /* Update with new attribute creation order flags */
299
0
    ohdr_flags = (uint8_t)(ohdr_flags |
300
0
                           ((crt_order_flags & H5P_CRT_ORDER_TRACKED) ? H5O_HDR_ATTR_CRT_ORDER_TRACKED : 0));
301
0
    ohdr_flags = (uint8_t)(ohdr_flags |
302
0
                           ((crt_order_flags & H5P_CRT_ORDER_INDEXED) ? H5O_HDR_ATTR_CRT_ORDER_INDEXED : 0));
303
304
    /* Set object header flags */
305
0
    if (H5P_set(plist, H5O_CRT_OHDR_FLAGS_NAME, &ohdr_flags) < 0)
306
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set object header flags");
307
308
0
done:
309
0
    FUNC_LEAVE_API(ret_value)
310
0
} /* end H5Pset_attr_creation_order() */
311
312
/*-------------------------------------------------------------------------
313
 * Function:    H5Pget_attr_creation_order
314
 *
315
 * Purpose:     Returns the flags indicating creation order is tracked/indexed
316
 *              for attributes on an object.
317
 *
318
 * Return:      Non-negative on success/Negative on failure
319
 *
320
 *-------------------------------------------------------------------------
321
 */
322
herr_t
323
H5Pget_attr_creation_order(hid_t plist_id, unsigned *crt_order_flags /*out*/)
324
0
{
325
0
    herr_t ret_value = SUCCEED; /* return value */
326
327
0
    FUNC_ENTER_API(FAIL)
328
329
    /* Get values */
330
0
    if (crt_order_flags) {
331
0
        H5P_genplist_t *plist;      /* Property list pointer */
332
0
        uint8_t         ohdr_flags; /* Object header flags */
333
334
        /* Reset the value to return */
335
0
        *crt_order_flags = 0;
336
337
        /* Get the plist structure */
338
0
        if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
339
0
            HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
340
341
        /* Get object header flags */
342
0
        if (H5P_get(plist, H5O_CRT_OHDR_FLAGS_NAME, &ohdr_flags) < 0)
343
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags");
344
345
        /* Set creation order flags to return */
346
0
        *crt_order_flags |= (ohdr_flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) ? H5P_CRT_ORDER_TRACKED : 0;
347
0
        *crt_order_flags |= (ohdr_flags & H5O_HDR_ATTR_CRT_ORDER_INDEXED) ? H5P_CRT_ORDER_INDEXED : 0;
348
0
    } /* end if */
349
350
0
done:
351
0
    FUNC_LEAVE_API(ret_value)
352
0
} /* end H5Pget_attr_creation_order() */
353
354
/*-------------------------------------------------------------------------
355
 * Function:    H5Pset_obj_track_times
356
 *
357
 * Purpose:     Set whether the birth, access, modification & change times for
358
 *              an object are stored.
359
 *
360
 *              Birth time is the time the object was created.  Access time is
361
 *              the last time that metadata or raw data was read from this
362
 *              object.  Modification time is the last time the data for
363
 *              this object was changed (either writing raw data to a dataset
364
 *              or inserting/modifying/deleting a link in a group).  Change
365
 *              time is the last time the metadata for this object was written
366
 *              (adding/modifying/deleting an attribute on an object, extending
367
 *              the size of a dataset, etc).
368
 *
369
 *              If these times are not tracked, they will be reported as
370
 *              12:00 AM UDT, Jan. 1, 1970 (i.e. 0 seconds past the UNIX
371
 *              epoch) when queried.
372
 *
373
 * Return:      Non-negative on success/Negative on failure
374
 *
375
 *-------------------------------------------------------------------------
376
 */
377
herr_t
378
H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times)
379
0
{
380
0
    H5P_genplist_t *plist;               /* Property list pointer */
381
0
    uint8_t         ohdr_flags;          /* Object header flags */
382
0
    herr_t          ret_value = SUCCEED; /* Return value */
383
384
0
    FUNC_ENTER_API(FAIL)
385
386
    /* Get the plist structure */
387
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
388
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
389
390
    /* Get object header flags */
391
0
    if (H5P_get(plist, H5O_CRT_OHDR_FLAGS_NAME, &ohdr_flags) < 0)
392
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags");
393
394
    /* Mask off previous time tracking flag settings */
395
0
    ohdr_flags &= (uint8_t)~H5O_HDR_STORE_TIMES;
396
397
    /* Update with new time tracking flag */
398
0
    ohdr_flags = (uint8_t)(ohdr_flags | (track_times ? H5O_HDR_STORE_TIMES : 0));
399
400
    /* Set object header flags */
401
0
    if (H5P_set(plist, H5O_CRT_OHDR_FLAGS_NAME, &ohdr_flags) < 0)
402
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set object header flags");
403
404
0
done:
405
0
    FUNC_LEAVE_API(ret_value)
406
0
} /* end H5Pset_obj_track_times() */
407
408
/*-------------------------------------------------------------------------
409
 * Function:    H5Pget_obj_track_times
410
 *
411
 * Purpose:     Returns whether times are tracked for an object.
412
 *
413
 * Return:      Non-negative on success/Negative on failure
414
 *
415
 *-------------------------------------------------------------------------
416
 */
417
herr_t
418
H5Pget_obj_track_times(hid_t plist_id, hbool_t *track_times /*out*/)
419
0
{
420
0
    herr_t ret_value = SUCCEED; /* return value */
421
422
0
    FUNC_ENTER_API(FAIL)
423
424
    /* Get values */
425
0
    if (track_times) {
426
0
        H5P_genplist_t *plist;      /* Property list pointer */
427
0
        uint8_t         ohdr_flags; /* Object header flags */
428
429
        /* Get the plist structure */
430
0
        if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
431
0
            HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
432
433
        /* Get object header flags */
434
0
        if (H5P_get(plist, H5O_CRT_OHDR_FLAGS_NAME, &ohdr_flags) < 0)
435
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags");
436
437
        /* Set track times flag to return */
438
0
        *track_times = (bool)((ohdr_flags & H5O_HDR_STORE_TIMES) ? true : false);
439
0
    } /* end if */
440
441
0
done:
442
0
    FUNC_LEAVE_API(ret_value)
443
0
} /* end H5Pget_obj_track_times() */
444
445
/*-------------------------------------------------------------------------
446
 * Function:    H5P_modify_filter
447
 *
448
 * Purpose:    Modifies the specified FILTER in the
449
 *        transient or permanent output filter pipeline
450
 *        depending on whether PLIST is a dataset creation or dataset
451
 *        transfer property list.  The FLAGS argument specifies certain
452
 *        general properties of the filter and is documented below.
453
 *        The CD_VALUES is an array of CD_NELMTS integers which are
454
 *        auxiliary data for the filter.  The integer values will be
455
 *        stored in the dataset object header as part of the filter
456
 *        information.
457
 *
458
 *         The FLAGS argument is a bit vector of the following fields:
459
 *
460
 *         H5Z_FLAG_OPTIONAL(0x0001)
461
 *        If this bit is set then the filter is optional.  If the
462
 *        filter fails during an H5Dwrite() operation then the filter
463
 *        is just excluded from the pipeline for the chunk for which it
464
 *        failed; the filter will not participate in the pipeline
465
 *        during an H5Dread() of the chunk.  If this bit is clear and
466
 *        the filter fails then the entire I/O operation fails.
467
 *      If this bit is set but encoding is disabled for a filter,
468
 *      attempting to write will generate an error.
469
 *
470
 * Note:    This function currently supports only the permanent filter
471
 *        pipeline.  That is, PLIST_ID must be a dataset creation
472
 *        property list.
473
 *
474
 * Return:    Non-negative on success/Negative on failure
475
 *
476
 *-------------------------------------------------------------------------
477
 */
478
herr_t
479
H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned flags, size_t cd_nelmts,
480
                  const unsigned cd_values[/*cd_nelmts*/])
481
0
{
482
0
    H5O_pline_t pline;
483
0
    herr_t      ret_value = SUCCEED; /* return value */
484
485
0
    FUNC_ENTER_NOAPI(FAIL)
486
487
    /* Get the pipeline property to modify */
488
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
489
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
490
491
    /* Modify the filter parameters of the I/O pipeline */
492
0
    if (H5Z_modify(&pline, filter, flags, cd_nelmts, cd_values) < 0)
493
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline");
494
495
    /* Put the I/O pipeline information back into the property list */
496
0
    if (H5P_poke(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
497
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline");
498
499
0
done:
500
0
    FUNC_LEAVE_NOAPI(ret_value)
501
0
} /* end H5P_modify_filter() */
502
503
/*-------------------------------------------------------------------------
504
 * Function:    H5Pmodify_filter
505
 *
506
 * Purpose:     Modifies the specified FILTER in the
507
 *              transient or permanent output filter pipeline
508
 *              depending on whether PLIST is a dataset creation or dataset
509
 *              transfer property list.  The FLAGS argument specifies certain
510
 *              general properties of the filter and is documented below.
511
 *              The CD_VALUES is an array of CD_NELMTS integers which are
512
 *              auxiliary data for the filter.  The integer values will be
513
 *              stored in the dataset object header as part of the filter
514
 *              information.
515
 *
516
 *              The FLAGS argument is a bit vector of the following fields:
517
 *
518
 *              H5Z_FLAG_OPTIONAL(0x0001)
519
 *              If this bit is set then the filter is optional.  If the
520
 *              filter fails during an H5Dwrite() operation then the filter
521
 *              is just excluded from the pipeline for the chunk for which it
522
 *              failed; the filter will not participate in the pipeline
523
 *              during an H5Dread() of the chunk.  If this bit is clear and
524
 *              the filter fails then the entire I/O operation fails.
525
 *      If this bit is set but encoding is disabled for a filter,
526
 *      attempting to write will generate an error.
527
 *
528
 * Note:        This function currently supports only the permanent filter
529
 *              pipeline.  That is, PLIST_ID must be a dataset creation
530
 *              property list.
531
 *
532
 * Return:      Non-negative on success/Negative on failure
533
 *
534
 *-------------------------------------------------------------------------
535
 */
536
herr_t
537
H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts,
538
                 const unsigned int cd_values[/*cd_nelmts*/])
539
0
{
540
0
    H5P_genplist_t *plist;               /* Property list */
541
0
    herr_t          ret_value = SUCCEED; /* return value */
542
543
0
    FUNC_ENTER_API(FAIL)
544
545
    /* Check args */
546
0
    if (filter < 0 || filter > H5Z_FILTER_MAX)
547
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier");
548
0
    if (flags & ~((unsigned)H5Z_FLAG_DEFMASK))
549
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags");
550
0
    if (cd_nelmts > 0 && !cd_values)
551
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied");
552
553
    /* Get the plist structure */
554
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
555
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
556
557
    /* Modify the filter parameters of the I/O pipeline */
558
0
    if (H5P_modify_filter(plist, filter, flags, cd_nelmts, cd_values) < 0)
559
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't modify filter");
560
561
0
done:
562
0
    FUNC_LEAVE_API(ret_value)
563
0
} /* end H5Pmodify_filter() */
564
565
/*-------------------------------------------------------------------------
566
 * Function:    H5Pset_filter
567
 *
568
 * Purpose:    Adds the specified FILTER and corresponding properties to the
569
 *        end of the data or link output filter pipeline
570
 *        depending on whether PLIST is a dataset creation or group
571
 *        creation property list.  The FLAGS argument specifies certain
572
 *        general properties of the filter and is documented below.
573
 *        The CD_VALUES is an array of CD_NELMTS integers which are
574
 *        auxiliary data for the filter.  The integer values will be
575
 *        stored in the dataset object header as part of the filter
576
 *        information.
577
 *
578
 *         The FLAGS argument is a bit vector of the following fields:
579
 *
580
 *         H5Z_FLAG_OPTIONAL(0x0001)
581
 *        If this bit is set then the filter is optional.  If the
582
 *        filter fails during an H5Dwrite() operation then the filter
583
 *        is just excluded from the pipeline for the chunk for which it
584
 *        failed; the filter will not participate in the pipeline
585
 *        during an H5Dread() of the chunk.  If this bit is clear and
586
 *        the filter fails then the entire I/O operation fails.
587
 *      If this bit is set but encoding is disabled for a filter,
588
 *      attempting to write will generate an error.
589
 *
590
 * Return:    Non-negative on success/Negative on failure
591
 *
592
 *-------------------------------------------------------------------------
593
 */
594
herr_t
595
H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts,
596
              const unsigned int cd_values[/*cd_nelmts*/])
597
0
{
598
0
    H5P_genplist_t *plist;               /* Property list */
599
0
    herr_t          ret_value = SUCCEED; /* return value */
600
601
0
    FUNC_ENTER_API(FAIL)
602
603
    /* Check args */
604
0
    if (filter < 0 || filter > H5Z_FILTER_MAX)
605
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier");
606
0
    if (flags & ~((unsigned)H5Z_FLAG_DEFMASK))
607
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags");
608
0
    if (cd_nelmts > 0 && !cd_values)
609
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied");
610
611
    /* Get the plist structure */
612
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
613
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
614
615
    /* Call the private function */
616
0
    if (H5P__set_filter(plist, filter, flags, cd_nelmts, cd_values) < 0)
617
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "failed to call private function");
618
619
0
done:
620
0
    FUNC_LEAVE_API(ret_value)
621
0
} /* end H5Pset_filter() */
622
623
/*-------------------------------------------------------------------------
624
 * Function:    H5P__set_filter
625
 *
626
 * Purpose:    Adds the specified FILTER and corresponding properties to the
627
 *        end of the data or link output filter pipeline
628
 *        depending on whether PLIST is a dataset creation or group
629
 *        creation property list.  The FLAGS argument specifies certain
630
 *        general properties of the filter and is documented below.
631
 *        The CD_VALUES is an array of CD_NELMTS integers which are
632
 *        auxiliary data for the filter.  The integer values will be
633
 *        stored in the dataset object header as part of the filter
634
 *        information.
635
 *
636
 *         The FLAGS argument is a bit vector of the following fields:
637
 *
638
 *         H5Z_FLAG_OPTIONAL(0x0001)
639
 *        If this bit is set then the filter is optional.  If the
640
 *        filter fails during an H5Dwrite() operation then the filter
641
 *        is just excluded from the pipeline for the chunk for which it
642
 *        failed; the filter will not participate in the pipeline
643
 *        during an H5Dread() of the chunk.  If this bit is clear and
644
 *        the filter fails then the entire I/O operation fails.
645
 *        If this bit is set but encoding is disabled for a filter,
646
 *        attempting to write will generate an error.
647
 *
648
 *              If the filter is not registered, this function tries to load
649
 *              it dynamically during run time.
650
 *
651
 * Return:    Non-negative on success/Negative on failure
652
 *
653
 *-------------------------------------------------------------------------
654
 */
655
static herr_t
656
H5P__set_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts,
657
                const unsigned int cd_values[/*cd_nelmts*/])
658
0
{
659
0
    H5O_pline_t pline;               /* Filter pipeline */
660
0
    htri_t      filter_avail;        /* Filter availability */
661
0
    herr_t      ret_value = SUCCEED; /* Return value */
662
663
0
    FUNC_ENTER_PACKAGE
664
665
    /* Check if filter is already available */
666
0
    if ((filter_avail = H5Z_filter_avail(filter)) < 0)
667
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't check filter availability");
668
669
    /* Get the pipeline property to append to */
670
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
671
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
672
673
    /* Add the filter to the I/O pipeline */
674
0
    if (H5Z_append(&pline, filter, flags, cd_nelmts, cd_values) < 0)
675
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline");
676
677
    /* Put the I/O pipeline information back into the property list */
678
0
    if (H5P_poke(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
679
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline");
680
681
0
done:
682
0
    FUNC_LEAVE_NOAPI(ret_value)
683
0
} /* end H5P__set_filter() */
684
685
/*-------------------------------------------------------------------------
686
 * Function:    H5Pget_nfilters
687
 *
688
 * Purpose:    Returns the number of filters in the data or link
689
 *        pipeline depending on whether PLIST_ID is a dataset creation
690
 *        or group creation property list.  In each pipeline the
691
 *        filters are numbered from zero through N-1 where N is the
692
 *        value returned by this function.  During output to the file
693
 *        the filters of a pipeline are applied in increasing order
694
 *        (the inverse is true for input).
695
 *
696
 * Return:    Success:    Number of filters or zero if there are none.
697
 *
698
 *        Failure:    Negative
699
 *
700
 *-------------------------------------------------------------------------
701
 */
702
int
703
H5Pget_nfilters(hid_t plist_id)
704
37
{
705
37
    H5P_genplist_t *plist;     /* Property list */
706
37
    H5O_pline_t     pline;     /* Filter pipeline */
707
37
    int             ret_value; /* return value */
708
709
74
    FUNC_ENTER_API(FAIL)
710
711
    /* Get the plist structure */
712
74
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
713
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
714
715
    /* Get the pipeline property to query */
716
37
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
717
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
718
719
    /* Set return value */
720
37
    ret_value = (int)(pline.nused);
721
722
37
done:
723
37
    FUNC_LEAVE_API(ret_value)
724
37
} /* end H5Pget_nfilters */
725
726
/*-------------------------------------------------------------------------
727
 * Function:    H5Pget_filter2
728
 *
729
 * Purpose:    This is the query counterpart of H5Pset_filter() and returns
730
 *        information about a particular filter number in a permanent
731
 *        or transient pipeline depending on whether PLIST_ID is a
732
 *        dataset creation or transfer property list.  On input,
733
 *        CD_NELMTS indicates the number of entries in the CD_VALUES
734
 *        array allocated by the caller while on exit it contains the
735
 *        number of values defined by the filter.  FILTER_CONFIG is a bit
736
 *      field containing encode/decode flags from H5Zpublic.h.  The IDX
737
 *      should be a value between zero and N-1 as described for
738
 *      H5Pget_nfilters() and the function will return failure if the
739
 *      filter number is out of range.
740
 *
741
 * Return:    Success:    Filter identification number.
742
 *
743
 *        Failure:    H5Z_FILTER_ERROR (Negative)
744
 *
745
 *-------------------------------------------------------------------------
746
 */
747
H5Z_filter_t
748
H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags /*out*/, size_t *cd_nelmts /*in,out*/,
749
               unsigned cd_values[] /*out*/, size_t namelen, char name[] /*out*/,
750
               unsigned *filter_config /*out*/)
751
0
{
752
0
    H5P_genplist_t          *plist;     /* Property list */
753
0
    H5O_pline_t              pline;     /* Filter pipeline */
754
0
    const H5Z_filter_info_t *filter;    /* Pointer to filter information */
755
0
    H5Z_filter_t             ret_value; /* return value */
756
757
0
    FUNC_ENTER_API(H5Z_FILTER_ERROR)
758
759
    /* Check args */
760
0
    if (cd_nelmts || cd_values) {
761
        /*
762
         * It's likely that users forget to initialize this on input, so
763
         * we'll check that it has a reasonable value.  The actual number
764
         * is unimportant because the H5O layer will detect when a message
765
         * is too large.
766
         */
767
0
        if (cd_nelmts && *cd_nelmts > 256)
768
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR,
769
0
                        "probable uninitialized *cd_nelmts argument");
770
0
        if (cd_nelmts && *cd_nelmts > 0 && !cd_values)
771
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied");
772
773
        /*
774
         * If cd_nelmts is null but cd_values is non-null then just ignore
775
         * cd_values
776
         */
777
0
        if (!cd_nelmts)
778
0
            cd_values = NULL;
779
0
    } /* end if */
780
781
    /* Get the plist structure */
782
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
783
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, H5Z_FILTER_ERROR, "can't find object for ID");
784
785
    /* Get the pipeline property to query */
786
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
787
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline");
788
789
    /* Check index */
790
0
    if (idx >= pline.nused)
791
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid");
792
793
    /* Set pointer to particular filter to query */
794
0
    filter = &pline.filter[idx];
795
796
    /* Get filter information */
797
0
    if (H5P__get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
798
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info");
799
800
    /* Set return value */
801
0
    ret_value = filter->id;
802
803
0
done:
804
0
    FUNC_LEAVE_API(ret_value)
805
0
} /* end H5Pget_filter2() */
806
807
/*-------------------------------------------------------------------------
808
 * Function:    H5P_get_filter_by_id
809
 *
810
 * Purpose:    This is an additional query counterpart of H5Pset_filter() and
811
 *              returns information about a particular filter in a permanent
812
 *        or transient pipeline depending on whether PLIST_ID is a
813
 *        dataset creation or transfer property list.  On input,
814
 *        CD_NELMTS indicates the number of entries in the CD_VALUES
815
 *        array allocated by the caller while on exit it contains the
816
 *        number of values defined by the filter.  FILTER_CONFIG is a bit
817
 *      field containing encode/decode flags from H5Zpublic.h.  The ID
818
 *      should be the filter ID to retrieve the parameters for.  If the
819
 *      filter is not set for the property list, an error will be returned.
820
 *
821
 * Return:    Success:    Non-negative
822
 *        Failure:    Negative
823
 *
824
 *-------------------------------------------------------------------------
825
 */
826
herr_t
827
H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, unsigned int *flags /*out*/,
828
                     size_t *cd_nelmts /*in,out*/, unsigned cd_values[] /*out*/, size_t namelen,
829
                     char name[] /*out*/, unsigned *filter_config)
830
0
{
831
0
    H5O_pline_t        pline;               /* Filter pipeline */
832
0
    H5Z_filter_info_t *filter;              /* Pointer to filter information */
833
0
    herr_t             ret_value = SUCCEED; /* Return value */
834
835
0
    FUNC_ENTER_NOAPI(FAIL)
836
837
    /* Get pipeline info */
838
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
839
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
840
841
    /* Get pointer to filter in pipeline */
842
0
    if (NULL == (filter = H5Z_filter_info(&pline, id)))
843
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid");
844
845
    /* Get filter information */
846
0
    if (H5P__get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
847
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info");
848
849
0
done:
850
0
    FUNC_LEAVE_NOAPI(ret_value)
851
0
} /* end H5P_get_filter_by_id() */
852
853
/*-------------------------------------------------------------------------
854
 * Function:    H5Pget_filter_by_id2
855
 *
856
 * Purpose:    This is an additional query counterpart of H5Pset_filter() and
857
 *              returns information about a particular filter in a permanent
858
 *        or transient pipeline depending on whether PLIST_ID is a
859
 *        dataset creation or transfer property list.  On input,
860
 *        CD_NELMTS indicates the number of entries in the CD_VALUES
861
 *        array allocated by the caller while on exit it contains the
862
 *        number of values defined by the filter.  FILTER_CONFIG is a bit
863
 *      field containing encode/decode flags from H5Zpublic.h.  The ID
864
 *      should be the filter ID to retrieve the parameters for.  If the
865
 *      filter is not set for the property list, an error will be returned.
866
 *
867
 * Return:    Success:    Non-negative
868
 *        Failure:    Negative
869
 *
870
 *-------------------------------------------------------------------------
871
 */
872
herr_t
873
H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags /*out*/,
874
                     size_t *cd_nelmts /*in,out*/, unsigned cd_values[] /*out*/, size_t namelen,
875
                     char name[] /*out*/, unsigned *filter_config /*out*/)
876
0
{
877
0
    H5P_genplist_t *plist;               /* Property list */
878
0
    herr_t          ret_value = SUCCEED; /* Return value */
879
880
0
    FUNC_ENTER_API(FAIL)
881
882
    /* Check args */
883
0
    if (id < 0 || id > H5Z_FILTER_MAX)
884
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID value out of range");
885
0
    if (cd_nelmts || cd_values) {
886
        /*
887
         * It's likely that users forget to initialize this on input, so
888
         * we'll check that it has a reasonable value.  The actual number
889
         * is unimportant because the H5O layer will detect when a message
890
         * is too large.
891
         */
892
0
        if (cd_nelmts && *cd_nelmts > 256)
893
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument");
894
0
        if (cd_nelmts && *cd_nelmts > 0 && !cd_values)
895
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied");
896
897
        /*
898
         * If cd_nelmts is null but cd_values is non-null then just ignore
899
         * cd_values
900
         */
901
0
        if (!cd_nelmts)
902
0
            cd_values = NULL;
903
0
    } /* end if */
904
905
    /* Get the plist structure */
906
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
907
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
908
909
    /* Get filter information */
910
0
    if (H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
911
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info");
912
913
0
done:
914
0
    FUNC_LEAVE_API(ret_value)
915
0
} /* end H5Pget_filter_by_id2() */
916
917
/*-------------------------------------------------------------------------
918
 * Function:    H5Pall_filters_avail
919
 *
920
 * Purpose:    This is a query routine to verify that all the filters set
921
 *              in the dataset creation property list are available currently.
922
 *
923
 * Return:    Success:    true if all filters available, false if one or
924
 *                              more filters not currently available.
925
 *        Failure:    FAIL on error
926
 *
927
 *-------------------------------------------------------------------------
928
 */
929
htri_t
930
H5Pall_filters_avail(hid_t plist_id)
931
0
{
932
0
    H5P_genplist_t *plist;     /* Property list */
933
0
    H5O_pline_t     pline;     /* Filter pipeline */
934
0
    htri_t          ret_value; /* Return value */
935
936
0
    FUNC_ENTER_API(FAIL)
937
938
    /* Get the plist structure */
939
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
940
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
941
942
    /* Get the pipeline property to query */
943
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
944
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
945
946
    /* Check if all filters are available */
947
0
    if ((ret_value = H5Z_all_filters_avail(&pline)) < 0)
948
0
        HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't check pipeline information");
949
950
0
done:
951
0
    FUNC_LEAVE_API(ret_value)
952
0
} /* end H5Pall_filters_avail() */
953
954
/*-------------------------------------------------------------------------
955
 * Function:    H5P_filter_in_pline
956
 *
957
 * Purpose:    Check whether the filter is in the pipeline of the object
958
 *              creation property list.
959
 *
960
 * Return:    true:        found
961
 *        false:        not found
962
 *              FAIL:         error
963
 *
964
 *-------------------------------------------------------------------------
965
 */
966
htri_t
967
H5P_filter_in_pline(H5P_genplist_t *plist, H5Z_filter_t id)
968
0
{
969
0
    H5O_pline_t pline;               /* Filter pipeline */
970
0
    htri_t      ret_value = SUCCEED; /* Return value */
971
972
0
    FUNC_ENTER_NOAPI(FAIL)
973
974
    /* Get pipeline info */
975
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
976
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
977
978
    /* Check if the file is in the pipeline */
979
0
    if ((ret_value = H5Z_filter_in_pline(&pline, id)) < 0)
980
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTCOMPARE, FAIL, "can't find filter");
981
982
0
done:
983
0
    FUNC_LEAVE_NOAPI(ret_value)
984
0
} /* end H5P_filter_in_pline() */
985
986
/*-------------------------------------------------------------------------
987
 * Function: H5Premove_filter
988
 *
989
 * Purpose: Deletes a filter from the dataset creation property list;
990
 *  deletes all filters if FILTER is H5Z_FILTER_ALL
991
 *
992
 * Return: Non-negative on success/Negative on failure
993
 *
994
 *-------------------------------------------------------------------------
995
 */
996
herr_t
997
H5Premove_filter(hid_t plist_id, H5Z_filter_t filter)
998
0
{
999
0
    H5P_genplist_t *plist;               /* Property list */
1000
0
    H5O_pline_t     pline;               /* Filter pipeline */
1001
0
    herr_t          ret_value = SUCCEED; /* return value          */
1002
1003
0
    FUNC_ENTER_API(FAIL)
1004
1005
    /* Get the plist structure */
1006
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
1007
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1008
1009
    /* Get the pipeline property to modify */
1010
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
1011
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
1012
1013
    /* Check if there are any filters */
1014
0
    if (pline.filter) {
1015
        /* Delete filter */
1016
0
        if (H5Z_delete(&pline, filter) < 0)
1017
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't delete filter");
1018
1019
        /* Put the I/O pipeline information back into the property list */
1020
0
        if (H5P_poke(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
1021
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline");
1022
0
    } /* end if */
1023
1024
0
done:
1025
0
    FUNC_LEAVE_API(ret_value)
1026
0
} /* end H5Premove_filter() */
1027
1028
/*-------------------------------------------------------------------------
1029
 * Function:    H5Pset_deflate
1030
 *
1031
 * Purpose:     Sets the compression method for a dataset or group link
1032
 *              filter pipeline (depending on whether PLIST_ID is a dataset
1033
 *              creation or group creation property list) to H5Z_FILTER_DEFLATE
1034
 *              and the compression level to LEVEL which should be a value
1035
 *              between zero and nine, inclusive.  Lower compression levels
1036
 *              are faster but result in less compression.  This is the same
1037
 *              algorithm as used by the GNU gzip program.
1038
 *
1039
 * Return:      Non-negative on success/Negative on failure
1040
 *
1041
 *-------------------------------------------------------------------------
1042
 */
1043
herr_t
1044
H5Pset_deflate(hid_t plist_id, unsigned level)
1045
0
{
1046
0
    H5P_genplist_t *plist;               /* Property list */
1047
0
    H5O_pline_t     pline;               /* Filter pipeline */
1048
0
    herr_t          ret_value = SUCCEED; /* return value */
1049
1050
0
    FUNC_ENTER_API(FAIL)
1051
1052
    /* Check arguments */
1053
0
    if (level > 9)
1054
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid deflate level");
1055
1056
    /* Get the plist structure */
1057
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
1058
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1059
1060
    /* Get the pipeline property to append to */
1061
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
1062
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
1063
1064
    /* Add the filter */
1065
0
    if (H5Z_append(&pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &level) < 0)
1066
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add deflate filter to pipeline");
1067
1068
    /* Put the I/O pipeline information back into the property list */
1069
0
    if (H5P_poke(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
1070
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline");
1071
1072
0
done:
1073
0
    FUNC_LEAVE_API(ret_value)
1074
0
} /* end H5Pset_deflate() */
1075
1076
/*-------------------------------------------------------------------------
1077
 * Function:    H5Pset_fletcher32
1078
 *
1079
 * Purpose:     Sets Fletcher32 checksum of EDC for a dataset creation
1080
 *              property list or group creation property list.
1081
 *
1082
 * Return:      Non-negative on success/Negative on failure
1083
 *
1084
 *-------------------------------------------------------------------------
1085
 */
1086
herr_t
1087
H5Pset_fletcher32(hid_t plist_id)
1088
0
{
1089
0
    H5P_genplist_t *plist;               /* Property list */
1090
0
    H5O_pline_t     pline;               /* Filter pipeline */
1091
0
    herr_t          ret_value = SUCCEED; /* return value */
1092
1093
0
    FUNC_ENTER_API(FAIL)
1094
1095
    /* Get the plist structure */
1096
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
1097
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1098
1099
    /* Get the pipeline property to append to */
1100
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
1101
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
1102
1103
    /* Add the Fletcher32 checksum as a filter */
1104
0
    if (H5Z_append(&pline, H5Z_FILTER_FLETCHER32, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0)
1105
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add fletcher32 filter to pipeline");
1106
1107
    /* Put the I/O pipeline information back into the property list */
1108
0
    if (H5P_poke(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
1109
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline");
1110
1111
0
done:
1112
0
    FUNC_LEAVE_API(ret_value)
1113
0
} /* end H5Pset_fletcher32() */
1114
1115
/*-------------------------------------------------------------------------
1116
 * Function:    H5P__get_filter
1117
 *
1118
 * Purpose:    Internal component of H5Pget_filter & H5Pget_filter_id
1119
 *
1120
 * Return:    Non-negative on success/Negative on failure
1121
 *
1122
 *-------------------------------------------------------------------------
1123
 */
1124
herr_t
1125
H5P__get_filter(const H5Z_filter_info_t *filter, unsigned int *flags /*out*/, size_t *cd_nelmts /*in,out*/,
1126
                unsigned cd_values[] /*out*/, size_t namelen, char name[] /*out*/,
1127
                unsigned *filter_config /*out*/)
1128
0
{
1129
0
    FUNC_ENTER_PACKAGE_NOERR
1130
1131
    /* Check arguments */
1132
0
    assert(filter);
1133
1134
    /* Filter flags */
1135
0
    if (flags)
1136
0
        *flags = filter->flags;
1137
1138
    /* Filter parameters */
1139
0
    if (cd_values) {
1140
0
        size_t i; /* Local index variable */
1141
1142
0
        for (i = 0; i < filter->cd_nelmts && i < *cd_nelmts; i++)
1143
0
            cd_values[i] = filter->cd_values[i];
1144
0
    } /* end if */
1145
1146
    /* Number of filter parameters */
1147
0
    if (cd_nelmts)
1148
0
        *cd_nelmts = filter->cd_nelmts;
1149
1150
    /* Filter name */
1151
0
    if (namelen > 0 && name) {
1152
0
        const char *s = filter->name;
1153
1154
        /* If there's no name on the filter, use the class's filter name */
1155
0
        if (!s) {
1156
0
            H5Z_class2_t *cls = H5Z_find(filter->id);
1157
1158
0
            if (cls)
1159
0
                s = cls->name;
1160
0
        } /* end if */
1161
1162
        /* Check for actual name */
1163
0
        if (s) {
1164
0
            strncpy(name, s, namelen);
1165
0
            name[namelen - 1] = '\0';
1166
0
        } /* end if */
1167
0
        else {
1168
            /* Check for unknown library filter */
1169
            /* (probably from a future version of the library) */
1170
0
            if (filter->id < 256) {
1171
0
                strncpy(name, "Unknown library filter", namelen);
1172
0
                name[namelen - 1] = '\0';
1173
0
            } /* end if */
1174
0
            else
1175
0
                name[0] = '\0';
1176
0
        } /* end if */
1177
0
    }     /* end if */
1178
1179
    /* Filter configuration (assume filter ID has already been checked) */
1180
0
    if (filter_config)
1181
0
        H5Z_get_filter_info(filter->id, filter_config);
1182
1183
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1184
0
} /* end H5P__get_filter() */
1185
1186
/*-------------------------------------------------------------------------
1187
 * Function:    H5P__ocrt_pipeline_set
1188
 *
1189
 * Purpose:     Copies an I/O pipeline property when it's set for a property list
1190
 *
1191
 * Return:      Success:        Non-negative
1192
 *              Failure:        Negative
1193
 *
1194
 *-------------------------------------------------------------------------
1195
 */
1196
static herr_t
1197
H5P__ocrt_pipeline_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
1198
                       size_t H5_ATTR_UNUSED size, void *value)
1199
0
{
1200
0
    H5O_pline_t *pline = (H5O_pline_t *)value; /* Create local aliases for values */
1201
0
    H5O_pline_t  new_pline;
1202
0
    herr_t       ret_value = SUCCEED; /* Return value */
1203
1204
0
    FUNC_ENTER_PACKAGE
1205
1206
    /* Sanity check */
1207
0
    assert(value);
1208
1209
    /* Make copy of I/O pipeline */
1210
0
    if (NULL == H5O_msg_copy(H5O_PLINE_ID, pline, &new_pline))
1211
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy I/O pipeline");
1212
1213
    /* Copy new I/O pipeline message over old one */
1214
0
    *pline = new_pline;
1215
1216
0
done:
1217
0
    FUNC_LEAVE_NOAPI(ret_value)
1218
0
} /* end H5P__ocrt_pipeline_set() */
1219
1220
/*-------------------------------------------------------------------------
1221
 * Function:    H5P__ocrt_pipeline_get
1222
 *
1223
 * Purpose:     Copies a layout property when it's retrieved from a property list
1224
 *
1225
 * Return:      Success:        Non-negative
1226
 *              Failure:        Negative
1227
 *
1228
 *-------------------------------------------------------------------------
1229
 */
1230
static herr_t
1231
H5P__ocrt_pipeline_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
1232
                       size_t H5_ATTR_UNUSED size, void *value)
1233
1
{
1234
1
    H5O_pline_t *pline = (H5O_pline_t *)value; /* Create local aliases for values */
1235
1
    H5O_pline_t  new_pline;
1236
1
    herr_t       ret_value = SUCCEED; /* Return value */
1237
1238
1
    FUNC_ENTER_PACKAGE
1239
1240
    /* Sanity check */
1241
1
    assert(value);
1242
1243
    /* Make copy of I/O pipeline */
1244
1
    if (NULL == H5O_msg_copy(H5O_PLINE_ID, pline, &new_pline))
1245
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy I/O pipeline");
1246
1247
    /* Copy new I/O pipeline message over old one */
1248
1
    *pline = new_pline;
1249
1250
1
done:
1251
1
    FUNC_LEAVE_NOAPI(ret_value)
1252
1
} /* end H5P__ocrt_pipeline_get() */
1253
1254
/*-------------------------------------------------------------------------
1255
 * Function:       H5P__ocrt_pipeline_enc
1256
 *
1257
 * Purpose:        Callback routine which is called whenever the pipeline
1258
 *                 property in the dataset access property list is
1259
 *                 decoded.
1260
 *
1261
 * Return:       Success:    Non-negative
1262
 *           Failure:    Negative
1263
 *
1264
 *-------------------------------------------------------------------------
1265
 */
1266
static herr_t
1267
H5P__ocrt_pipeline_enc(const void *value, void **_pp, size_t *size)
1268
0
{
1269
0
    const H5O_pline_t *pline = (const H5O_pline_t *)value;
1270
0
    uint8_t          **pp    = (uint8_t **)_pp;
1271
0
    size_t             u; /* Local index variable */
1272
1273
0
    FUNC_ENTER_PACKAGE_NOERR
1274
1275
0
    assert(pline);
1276
0
    assert(size);
1277
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
1278
1279
0
    if (NULL != *pp) {
1280
0
        unsigned enc_size;
1281
0
        uint64_t enc_value;
1282
1283
        /* Encode size of unsigned */
1284
0
        *(*pp)++ = (uint8_t)sizeof(unsigned);
1285
1286
        /* encode nused value */
1287
0
        enc_value = (uint64_t)pline->nused;
1288
0
        enc_size  = H5VM_limit_enc_size(enc_value);
1289
0
        assert(enc_size < 256);
1290
0
        *(*pp)++ = (uint8_t)enc_size;
1291
0
        UINT64ENCODE_VAR(*pp, enc_value, enc_size);
1292
1293
        /* encode each pipeline */
1294
0
        for (u = 0; u < pline->nused; u++) {
1295
0
            unsigned v; /* Local index variable */
1296
1297
            /* encode filter ID */
1298
0
            INT32ENCODE(*pp, pline->filter[u].id);
1299
1300
            /* encode filter flags */
1301
0
            H5_ENCODE_UNSIGNED(*pp, pline->filter[u].flags);
1302
1303
            /* encode filter name if it exists */
1304
0
            if (NULL != pline->filter[u].name) {
1305
                /* encode true indicating that it exits */
1306
0
                *(*pp)++ = (uint8_t) true;
1307
1308
                /* encode filter name */
1309
0
                H5MM_memcpy(*pp, (uint8_t *)(pline->filter[u].name), H5Z_COMMON_NAME_LEN);
1310
0
                *pp += H5Z_COMMON_NAME_LEN;
1311
0
            } /* end if */
1312
0
            else
1313
                /* encode false indicating that it does not exist */
1314
0
                *(*pp)++ = (uint8_t) false;
1315
1316
            /* encode cd_nelmts */
1317
0
            enc_value = (uint64_t)pline->filter[u].cd_nelmts;
1318
0
            enc_size  = H5VM_limit_enc_size(enc_value);
1319
0
            assert(enc_size < 256);
1320
0
            *(*pp)++ = (uint8_t)enc_size;
1321
0
            UINT64ENCODE_VAR(*pp, enc_value, enc_size);
1322
1323
            /* encode all values */
1324
0
            for (v = 0; v < pline->filter[u].cd_nelmts; v++)
1325
0
                H5_ENCODE_UNSIGNED(*pp, pline->filter[u].cd_values[v]);
1326
0
        } /* end for */
1327
0
    }     /* end if */
1328
1329
    /* calculate size required for encoding */
1330
0
    *size += 1;
1331
0
    *size += (1 + H5VM_limit_enc_size((uint64_t)pline->nused));
1332
0
    for (u = 0; u < pline->nused; u++) {
1333
0
        *size += (sizeof(int32_t) + sizeof(unsigned) + 1);
1334
0
        if (NULL != pline->filter[u].name)
1335
0
            *size += H5Z_COMMON_NAME_LEN;
1336
0
        *size += (1 + H5VM_limit_enc_size((uint64_t)pline->filter[u].cd_nelmts));
1337
0
        *size += pline->filter[u].cd_nelmts * sizeof(unsigned);
1338
0
    } /* end for */
1339
1340
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1341
0
} /* end H5P__ocrt_pipeline_enc() */
1342
1343
/*-------------------------------------------------------------------------
1344
 * Function:       H5P__ocrt_pipeline_dec
1345
 *
1346
 * Purpose:        Callback routine which is called whenever the pipeline
1347
 *                 property in the dataset access property list is
1348
 *                 decoded.
1349
 *
1350
 * Return:       Success:    Non-negative
1351
 *           Failure:    Negative
1352
 *
1353
 *-------------------------------------------------------------------------
1354
 */
1355
static herr_t
1356
H5P__ocrt_pipeline_dec(const void **_pp, void *_value)
1357
0
{
1358
0
    H5O_pline_t    *pline = (H5O_pline_t *)_value; /* Property to set */
1359
0
    const uint8_t **pp    = (const uint8_t **)_pp;
1360
0
    size_t          nused;               /* Number of filters used for pipeline */
1361
0
    unsigned        enc_size;            /* Size of encoded value (in bytes) */
1362
0
    uint64_t        enc_value;           /* Value to encode */
1363
0
    size_t          u;                   /* Local index variable */
1364
0
    herr_t          ret_value = SUCCEED; /* Return value */
1365
1366
0
    FUNC_ENTER_PACKAGE
1367
1368
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
1369
1370
    /* Decode the size of size_t */
1371
0
    enc_size = *(*pp)++;
1372
0
    if (enc_size != sizeof(unsigned))
1373
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unsigned value can't be decoded");
1374
1375
    /* decode nused */
1376
0
    enc_size = *(*pp)++;
1377
0
    assert(enc_size < 256);
1378
0
    UINT64DECODE_VAR(*pp, enc_value, enc_size);
1379
0
    nused = (size_t)enc_value;
1380
1381
    /* Set property default value */
1382
0
    memset(pline, 0, sizeof(H5O_pline_t));
1383
0
    *pline = H5O_def_pline_g;
1384
1385
0
    for (u = 0; u < nused; u++) {
1386
0
        H5Z_filter_info_t filter;   /* Filter info, for pipeline */
1387
0
        uint8_t           has_name; /* Flag to indicate whether filter has a name */
1388
0
        unsigned          v;        /* Local index variable */
1389
1390
        /* decode filter id */
1391
0
        INT32DECODE(*pp, filter.id);
1392
1393
        /* decode filter flags */
1394
0
        H5_DECODE_UNSIGNED(*pp, filter.flags);
1395
1396
        /* decode value indicating if the name is encoded */
1397
0
        has_name = *(*pp)++;
1398
0
        if (has_name) {
1399
            /* decode name */
1400
0
            filter.name = H5MM_xstrdup((const char *)(*pp));
1401
0
            *pp += H5Z_COMMON_NAME_LEN;
1402
0
        } /* end if */
1403
0
        else
1404
0
            filter.name = NULL;
1405
1406
        /* decode num elements */
1407
0
        enc_size = *(*pp)++;
1408
0
        assert(enc_size < 256);
1409
0
        UINT64DECODE_VAR(*pp, enc_value, enc_size);
1410
0
        filter.cd_nelmts = (size_t)enc_value;
1411
1412
0
        if (filter.cd_nelmts) {
1413
0
            if (NULL == (filter.cd_values = (unsigned *)H5MM_malloc(sizeof(unsigned) * filter.cd_nelmts)))
1414
0
                HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for cd_values");
1415
0
        } /* end if */
1416
0
        else
1417
0
            filter.cd_values = NULL;
1418
1419
        /* decode values */
1420
0
        for (v = 0; v < filter.cd_nelmts; v++)
1421
0
            H5_DECODE_UNSIGNED(*pp, filter.cd_values[v]);
1422
1423
        /* Add the filter to the I/O pipeline */
1424
0
        if (H5Z_append(pline, filter.id, filter.flags, filter.cd_nelmts, filter.cd_values) < 0)
1425
0
            HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline");
1426
1427
        /* Free cd_values, if it was allocated */
1428
0
        filter.cd_values = (unsigned *)H5MM_xfree(filter.cd_values);
1429
0
    } /* end for */
1430
1431
0
done:
1432
0
    FUNC_LEAVE_NOAPI(ret_value)
1433
0
} /* H5P__ocrt_pipeline_dec() */
1434
1435
/*-------------------------------------------------------------------------
1436
 * Function:    H5P__ocrt_pipeline_del
1437
 *
1438
 * Purpose:     Frees memory used to store the I/O pipeline property
1439
 *
1440
 * Return:      Success:        Non-negative
1441
 *              Failure:        Negative
1442
 *
1443
 *-------------------------------------------------------------------------
1444
 */
1445
static herr_t
1446
H5P__ocrt_pipeline_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
1447
                       size_t H5_ATTR_UNUSED size, void *value)
1448
0
{
1449
0
    herr_t ret_value = SUCCEED; /* Return value */
1450
1451
0
    FUNC_ENTER_PACKAGE
1452
1453
    /* Sanity check */
1454
0
    assert(value);
1455
1456
    /* Reset the old I/O pipeline */
1457
0
    if (H5O_msg_reset(H5O_PLINE_ID, value) < 0)
1458
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release I/O pipeline message");
1459
1460
0
done:
1461
0
    FUNC_LEAVE_NOAPI(ret_value)
1462
0
} /* end H5P__ocrt_pipeline_del() */
1463
1464
/*--------------------------------------------------------------------------
1465
 * Function:    H5P__ocrt_pipeline_copy
1466
 *
1467
 * Purpose:     Copy the I/O pipeline property
1468
 *
1469
 * Return:      Success:        Non-negative
1470
 *              Failure:        Negative
1471
 *
1472
 *--------------------------------------------------------------------------
1473
 */
1474
static herr_t
1475
H5P__ocrt_pipeline_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
1476
102
{
1477
102
    H5O_pline_t *pline = (H5O_pline_t *)value; /* Create local aliases for values */
1478
102
    H5O_pline_t  new_pline;
1479
102
    herr_t       ret_value = SUCCEED;
1480
1481
102
    FUNC_ENTER_PACKAGE
1482
1483
    /* Sanity check */
1484
102
    assert(pline);
1485
1486
    /* Make copy of I/O pipeline */
1487
102
    if (NULL == H5O_msg_copy(H5O_PLINE_ID, pline, &new_pline))
1488
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy I/O pipeline");
1489
1490
    /* Copy new I/O pipeline message over old one */
1491
102
    *pline = new_pline;
1492
1493
102
done:
1494
102
    FUNC_LEAVE_NOAPI(ret_value)
1495
102
} /* end H5P__ocrt_pipeline_copy() */
1496
1497
/*-------------------------------------------------------------------------
1498
 * Function:       H5P__ocrt_pipeline_cmp
1499
 *
1500
 * Purpose:        Callback routine which is called whenever a filter pipeline
1501
 *                 property in a property list is compared.
1502
 *
1503
 * Return:         positive if VALUE1 is greater than VALUE2, negative if
1504
 *                      VALUE2 is greater than VALUE1 and zero if VALUE1 and
1505
 *                      VALUE2 are equal.
1506
 *
1507
 *-------------------------------------------------------------------------
1508
 */
1509
static int
1510
H5P__ocrt_pipeline_cmp(const void *_pline1, const void *_pline2, size_t H5_ATTR_UNUSED size)
1511
0
{
1512
0
    const H5O_pline_t *pline1 = (const H5O_pline_t *)_pline1, /* Create local aliases for values */
1513
0
        *pline2               = (const H5O_pline_t *)_pline2;
1514
0
    int    cmp_value;     /* Value from comparison */
1515
0
    herr_t ret_value = 0; /* Return value */
1516
1517
0
    FUNC_ENTER_PACKAGE_NOERR
1518
1519
    /* Sanity check */
1520
0
    assert(pline1);
1521
0
    assert(pline2);
1522
0
    assert(size == sizeof(H5O_pline_t));
1523
1524
    /* Check the number of used pipeline entries */
1525
0
    if (pline1->nused < pline2->nused)
1526
0
        HGOTO_DONE(-1);
1527
0
    if (pline1->nused > pline2->nused)
1528
0
        HGOTO_DONE(1);
1529
1530
    /* Check the filter entry information */
1531
0
    if (pline1->filter == NULL && pline2->filter != NULL)
1532
0
        HGOTO_DONE(-1);
1533
0
    if (pline1->filter != NULL && pline2->filter == NULL)
1534
0
        HGOTO_DONE(1);
1535
0
    if (pline1->filter != NULL && pline1->nused > 0) {
1536
0
        size_t u; /* Local index variable */
1537
1538
        /* Loop through all filters, comparing them */
1539
0
        for (u = 0; u < pline1->nused; u++) {
1540
            /* Check the ID of the filter */
1541
0
            if (pline1->filter[u].id < pline2->filter[u].id)
1542
0
                HGOTO_DONE(-1);
1543
0
            if (pline1->filter[u].id > pline2->filter[u].id)
1544
0
                HGOTO_DONE(1);
1545
1546
            /* Check the flags for the filter */
1547
0
            if (pline1->filter[u].flags < pline2->filter[u].flags)
1548
0
                HGOTO_DONE(-1);
1549
0
            if (pline1->filter[u].flags > pline2->filter[u].flags)
1550
0
                HGOTO_DONE(1);
1551
1552
            /* Check the name of the filter */
1553
0
            if (pline1->filter[u].name == NULL && pline2->filter[u].name != NULL)
1554
0
                HGOTO_DONE(-1);
1555
0
            if (pline1->filter[u].name != NULL && pline2->filter[u].name == NULL)
1556
0
                HGOTO_DONE(1);
1557
0
            if (pline1->filter[u].name != NULL)
1558
0
                if ((cmp_value = strcmp(pline1->filter[u].name, pline2->filter[u].name)) != 0)
1559
0
                    HGOTO_DONE(cmp_value);
1560
1561
            /* Check the number of parameters for the filter */
1562
0
            if (pline1->filter[u].cd_nelmts < pline2->filter[u].cd_nelmts)
1563
0
                HGOTO_DONE(-1);
1564
0
            if (pline1->filter[u].cd_nelmts > pline2->filter[u].cd_nelmts)
1565
0
                HGOTO_DONE(1);
1566
1567
            /* Check the filter parameter information */
1568
0
            if (pline1->filter[u].cd_values == NULL && pline2->filter[u].cd_values != NULL)
1569
0
                HGOTO_DONE(-1);
1570
0
            if (pline1->filter[u].cd_values != NULL && pline2->filter[u].cd_values == NULL)
1571
0
                HGOTO_DONE(1);
1572
0
            if (pline1->filter[u].cd_values != NULL && pline1->filter[u].cd_nelmts > 0) {
1573
0
                size_t v; /* Local index variable */
1574
1575
                /* Loop through all parameters, comparing them */
1576
0
                for (v = 0; v < pline1->filter[u].cd_nelmts; v++) {
1577
                    /* Check each parameter for the filter */
1578
0
                    if (pline1->filter[u].cd_values[v] < pline2->filter[u].cd_values[v])
1579
0
                        HGOTO_DONE(-1);
1580
0
                    if (pline1->filter[u].cd_values[v] > pline2->filter[u].cd_values[v])
1581
0
                        HGOTO_DONE(1);
1582
0
                } /* end for */
1583
0
            }     /* end if */
1584
0
        }         /* end for */
1585
0
    }             /* end if */
1586
1587
0
done:
1588
0
    FUNC_LEAVE_NOAPI(ret_value)
1589
0
} /* end H5P__ocrt_pipeline_cmp() */
1590
1591
/*-------------------------------------------------------------------------
1592
 * Function:    H5P__ocrt_pipeline_close
1593
 *
1594
 * Purpose:     Frees memory used to store the I/O pipeline property
1595
 *
1596
 * Return:      Success:        Non-negative
1597
 *              Failure:        Negative
1598
 *
1599
 *-------------------------------------------------------------------------
1600
 */
1601
static herr_t
1602
H5P__ocrt_pipeline_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
1603
107
{
1604
107
    herr_t ret_value = SUCCEED; /* Return value */
1605
1606
107
    FUNC_ENTER_PACKAGE
1607
1608
    /* Sanity check */
1609
107
    assert(value);
1610
1611
    /* Reset the old I/O pipeline */
1612
107
    if (H5O_msg_reset(H5O_PLINE_ID, value) < 0)
1613
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release I/O pipeline message");
1614
1615
107
done:
1616
107
    FUNC_LEAVE_NOAPI(ret_value)
1617
107
} /* end H5P__ocrt_pipeline_close() */
1618
1619
#ifndef H5_NO_DEPRECATED_SYMBOLS
1620
1621
/*-------------------------------------------------------------------------
1622
 * Function:    H5Pget_filter1
1623
 *
1624
 * Purpose:    This is the query counterpart of H5Pset_filter() and returns
1625
 *        information about a particular filter number in a permanent
1626
 *        or transient pipeline depending on whether PLIST_ID is a
1627
 *        dataset creation or transfer property list.  On input,
1628
 *        CD_NELMTS indicates the number of entries in the CD_VALUES
1629
 *        array allocated by the caller while on exit it contains the
1630
 *        number of values defined by the filter.  The IDX
1631
 *      should be a value between zero and N-1 as described for
1632
 *      H5Pget_nfilters() and the function will return failure if the
1633
 *      filter number is out of range.
1634
 *
1635
 * Return:    Success:    Filter identification number.
1636
 *
1637
 *        Failure:    H5Z_FILTER_ERROR (Negative)
1638
 *
1639
 *-------------------------------------------------------------------------
1640
 */
1641
H5Z_filter_t
1642
H5Pget_filter1(hid_t plist_id, unsigned idx, unsigned int *flags /*out*/, size_t *cd_nelmts /*in,out*/,
1643
               unsigned cd_values[] /*out*/, size_t namelen, char name[] /*out*/)
1644
{
1645
    H5O_pline_t              pline;     /* Filter pipeline */
1646
    const H5Z_filter_info_t *filter;    /* Pointer to filter information */
1647
    H5P_genplist_t          *plist;     /* Property list pointer */
1648
    H5Z_filter_t             ret_value; /* return value */
1649
1650
    FUNC_ENTER_API(H5Z_FILTER_ERROR)
1651
1652
    /* Check args */
1653
    if (cd_nelmts || cd_values) {
1654
        /*
1655
         * It's likely that users forget to initialize this on input, so
1656
         * we'll check that it has a reasonable value.  The actual number
1657
         * is unimportant because the H5O layer will detect when a message
1658
         * is too large.
1659
         */
1660
        if (cd_nelmts && *cd_nelmts > 256)
1661
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR,
1662
                        "probable uninitialized *cd_nelmts argument");
1663
        if (cd_nelmts && *cd_nelmts > 0 && !cd_values)
1664
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied");
1665
1666
        /*
1667
         * If cd_nelmts is null but cd_values is non-null then just ignore
1668
         * cd_values
1669
         */
1670
        if (!cd_nelmts)
1671
            cd_values = NULL;
1672
    } /* end if */
1673
1674
    /* Get the plist structure */
1675
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
1676
        HGOTO_ERROR(H5E_ID, H5E_BADID, H5Z_FILTER_ERROR, "can't find object for ID");
1677
1678
    /* Get pipeline info */
1679
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
1680
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline");
1681
1682
    /* Check more args */
1683
    if (idx >= pline.nused)
1684
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid");
1685
1686
    /* Set pointer to particular filter to query */
1687
    filter = &pline.filter[idx];
1688
1689
    /* Get filter information */
1690
    if (H5P__get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0)
1691
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info");
1692
1693
    /* Set return value */
1694
    ret_value = filter->id;
1695
1696
done:
1697
    FUNC_LEAVE_API(ret_value)
1698
} /* end H5Pget_filter1() */
1699
1700
/*-------------------------------------------------------------------------
1701
 * Function:    H5Pget_filter_by_id1
1702
 *
1703
 * Purpose:    This is an additional query counterpart of H5Pset_filter() and
1704
 *              returns information about a particular filter in a permanent
1705
 *        or transient pipeline depending on whether PLIST_ID is a
1706
 *        dataset creation or transfer property list.  On input,
1707
 *        CD_NELMTS indicates the number of entries in the CD_VALUES
1708
 *        array allocated by the caller while on exit it contains the
1709
 *        number of values defined by the filter.  The ID
1710
 *      should be the filter ID to retrieve the parameters for.  If the
1711
 *      filter is not set for the property list, an error will be returned.
1712
 *
1713
 * Return:    Success:    Non-negative
1714
 *        Failure:    Negative
1715
 *
1716
 *-------------------------------------------------------------------------
1717
 */
1718
herr_t
1719
H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags /*out*/,
1720
                     size_t *cd_nelmts /*in,out*/, unsigned cd_values[] /*out*/, size_t namelen,
1721
                     char name[] /*out*/)
1722
{
1723
    H5P_genplist_t *plist;               /* Property list pointer */
1724
    herr_t          ret_value = SUCCEED; /* Return value */
1725
1726
    FUNC_ENTER_API(FAIL)
1727
1728
    /* Check args */
1729
    if (id < 0 || id > H5Z_FILTER_MAX)
1730
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID value out of range");
1731
    if (cd_nelmts || cd_values) {
1732
        /*
1733
         * It's likely that users forget to initialize this on input, so
1734
         * we'll check that it has a reasonable value.  The actual number
1735
         * is unimportant because the H5O layer will detect when a message
1736
         * is too large.
1737
         */
1738
        if (cd_nelmts && *cd_nelmts > 256)
1739
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument");
1740
        if (cd_nelmts && *cd_nelmts > 0 && !cd_values)
1741
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied");
1742
1743
        /*
1744
         * If cd_nelmts is null but cd_values is non-null then just ignore
1745
         * cd_values
1746
         */
1747
        if (!cd_nelmts)
1748
            cd_values = NULL;
1749
    } /* end if */
1750
1751
    /* Get the plist structure */
1752
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
1753
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1754
1755
    /* Get filter info */
1756
    if (H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0)
1757
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info");
1758
1759
done:
1760
    FUNC_LEAVE_API(ret_value)
1761
} /* end H5Pget_filter_by_id1() */
1762
#endif /* H5_NO_DEPRECATED_SYMBOLS */