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