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  * Programmer:	Robb Matzke <matzke@llnl.gov>
16  *		Wednesday, April 15, 1998
17  *
18  * Purpose:	Data filter pipeline message.
19  */
20 
21 #include "H5Omodule.h"          /* This source code file is part of the H5O module */
22 #define H5Z_FRIEND		/*suppress error about including H5Zpkg	  */
23 
24 
25 #include "H5private.h"		/* Generic Functions			*/
26 #include "H5Dprivate.h"		/* Datasets				*/
27 #include "H5Eprivate.h"		/* Error handling		  	*/
28 #include "H5FLprivate.h"	/* Free Lists				*/
29 #include "H5MMprivate.h"	/* Memory management			*/
30 #include "H5Opkg.h"             /* Object headers			*/
31 #include "H5Zpkg.h"		/* Data filters				*/
32 
33 
34 /* PRIVATE PROTOTYPES */
35 static herr_t H5O_pline_encode(H5F_t *f, uint8_t *p, const void *mesg);
36 static void *H5O_pline_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
37     unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
38 static void *H5O_pline_copy(const void *_mesg, void *_dest);
39 static size_t H5O_pline_size(const H5F_t *f, const void *_mesg);
40 static herr_t H5O_pline_reset(void *_mesg);
41 static herr_t H5O_pline_free(void *_mesg);
42 static herr_t H5O_pline_pre_copy_file(H5F_t *file_src,
43     const void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata);
44 static herr_t H5O_pline_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
45     FILE * stream, int indent, int fwidth);
46 
47 /* Set up & include shared message "interface" info */
48 #define H5O_SHARED_TYPE			H5O_MSG_PLINE
49 #define H5O_SHARED_DECODE		H5O_pline_shared_decode
50 #define H5O_SHARED_DECODE_REAL		H5O_pline_decode
51 #define H5O_SHARED_ENCODE		H5O_pline_shared_encode
52 #define H5O_SHARED_ENCODE_REAL		H5O_pline_encode
53 #define H5O_SHARED_SIZE			H5O_pline_shared_size
54 #define H5O_SHARED_SIZE_REAL		H5O_pline_size
55 #define H5O_SHARED_DELETE		H5O_pline_shared_delete
56 #undef H5O_SHARED_DELETE_REAL
57 #define H5O_SHARED_LINK			H5O_pline_shared_link
58 #undef H5O_SHARED_LINK_REAL
59 #define H5O_SHARED_COPY_FILE		H5O_pline_shared_copy_file
60 #undef H5O_SHARED_COPY_FILE_REAL
61 #define H5O_SHARED_POST_COPY_FILE	H5O_pline_shared_post_copy_file
62 #undef H5O_SHARED_POST_COPY_FILE_REAL
63 #undef  H5O_SHARED_POST_COPY_FILE_UPD
64 #define H5O_SHARED_DEBUG		H5O_pline_shared_debug
65 #define H5O_SHARED_DEBUG_REAL		H5O_pline_debug
66 #include "H5Oshared.h"			/* Shared Object Header Message Callbacks */
67 
68 /* This message derives from H5O message class */
69 const H5O_msg_class_t H5O_MSG_PLINE[1] = {{
70     H5O_PLINE_ID,		/* message id number		*/
71     "filter pipeline",		/* message name for debugging	*/
72     sizeof(H5O_pline_t),	/* native message size		*/
73     H5O_SHARE_IS_SHARABLE|H5O_SHARE_IN_OHDR,	/* messages are sharable?       */
74     H5O_pline_shared_decode,	/* decode message		*/
75     H5O_pline_shared_encode,	/* encode message		*/
76     H5O_pline_copy,		/* copy the native value	*/
77     H5O_pline_shared_size,	/* size of raw message		*/
78     H5O_pline_reset,		/* reset method			*/
79     H5O_pline_free,		/* free method			*/
80     H5O_pline_shared_delete,    /* file delete method		*/
81     H5O_pline_shared_link,	/* link method			*/
82     NULL,			/* set share method		*/
83     NULL,		    	/*can share method		*/
84     H5O_pline_pre_copy_file,	/* pre copy native value to file */
85     H5O_pline_shared_copy_file,	/* copy native value to file    */
86     H5O_pline_shared_post_copy_file,	/* post copy native value to file    */
87     NULL,			/* get creation index		*/
88     NULL,			/* set creation index		*/
89     H5O_pline_shared_debug	/* debug the message		*/
90 }};
91 
92 
93 /* Declare a free list to manage the H5O_pline_t struct */
94 H5FL_DEFINE(H5O_pline_t);
95 
96 
97 /*-------------------------------------------------------------------------
98  * Function:	H5O_pline_decode
99  *
100  * Purpose:	Decodes a filter pipeline message.
101  *
102  * Return:	Success:	Ptr to the native message.
103  *		Failure:	NULL
104  *
105  * Programmer:	Robb Matzke
106  *              Wednesday, April 15, 1998
107  *
108  *-------------------------------------------------------------------------
109  */
110 static void *
H5O_pline_decode(H5F_t H5_ATTR_UNUSED * f,hid_t H5_ATTR_UNUSED dxpl_id,H5O_t H5_ATTR_UNUSED * open_oh,unsigned H5_ATTR_UNUSED mesg_flags,unsigned H5_ATTR_UNUSED * ioflags,const uint8_t * p)111 H5O_pline_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh,
112     unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, const uint8_t *p)
113 {
114     H5O_pline_t		*pline = NULL;          /* Pipeline message */
115     H5Z_filter_info_t   *filter;                /* Filter to decode */
116     size_t		name_length;            /* Length of filter name */
117     size_t		i;                      /* Local index variable */
118     void		*ret_value = NULL;      /* Return value */
119 
120     FUNC_ENTER_NOAPI_NOINIT
121 
122     /* check args */
123     HDassert(p);
124 
125     /* Allocate space for I/O pipeline message */
126     if(NULL == (pline = H5FL_CALLOC(H5O_pline_t)))
127 	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
128 
129     /* Version */
130     pline->version = *p++;
131     if(pline->version < H5O_PLINE_VERSION_1 || pline->version > H5O_PLINE_VERSION_LATEST)
132 	HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "bad version number for filter pipeline message")
133 
134     /* Number of filters */
135     pline->nused = *p++;
136     if(pline->nused > H5Z_MAX_NFILTERS)
137 	HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter pipeline message has too many filters")
138 
139     /* Reserved */
140     if(pline->version == H5O_PLINE_VERSION_1)
141         p += 6;
142 
143     /* Allocate array for filters */
144     pline->nalloc = pline->nused;
145     if(NULL == (pline->filter = (H5Z_filter_info_t *)H5MM_calloc(pline->nalloc * sizeof(pline->filter[0]))))
146 	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
147 
148     /* Decode filters */
149     for(i = 0, filter = &pline->filter[0]; i < pline->nused; i++, filter++) {
150         /* Filter ID */
151 	UINT16DECODE(p, filter->id);
152 
153         /* Length of filter name */
154         if(pline->version > H5O_PLINE_VERSION_1 && filter->id < H5Z_FILTER_RESERVED)
155             name_length = 0;
156         else {
157             UINT16DECODE(p, name_length);
158             if(pline->version == H5O_PLINE_VERSION_1 && name_length % 8)
159                 HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter name length is not a multiple of eight")
160         } /* end if */
161 
162         /* Filter flags */
163 	UINT16DECODE(p, filter->flags);
164 
165         /* Number of filter parameters ("client data elements") */
166 	UINT16DECODE(p, filter->cd_nelmts);
167 
168         /* Filter name, if there is one */
169 	if(name_length) {
170             size_t actual_name_length;          /* Actual length of name */
171 
172             /* Determine actual name length (without padding, but with null terminator) */
173 	    actual_name_length = HDstrlen((const char *)p) + 1;
174 	    HDassert(actual_name_length <= name_length);
175 
176             /* Allocate space for the filter name, or use the internal buffer */
177             if(actual_name_length > H5Z_COMMON_NAME_LEN) {
178                 filter->name = (char *)H5MM_malloc(actual_name_length);
179                 if(NULL == filter->name)
180                     HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for filter name")
181             } /* end if */
182             else
183                 filter->name = filter->_name;
184 
185 	    HDstrncpy(filter->name, (const char *)p, actual_name_length);
186 	    p += name_length;
187 	} /* end if */
188 
189         /* Filter parameters */
190 	if(filter->cd_nelmts) {
191             size_t	j;              /* Local index variable */
192 
193             /* Allocate space for the client data elements, or use the internal buffer */
194             if(filter->cd_nelmts > H5Z_COMMON_CD_VALUES) {
195                 filter->cd_values = (unsigned *)H5MM_malloc(filter->cd_nelmts * sizeof(unsigned));
196                 if(NULL == filter->cd_values)
197                     HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for client data")
198             } /* end if */
199             else
200                 filter->cd_values = filter->_cd_values;
201 
202 	    /*
203 	     * Read the client data values and the padding
204 	     */
205 	    for(j = 0; j < filter->cd_nelmts; j++)
206 		UINT32DECODE(p, filter->cd_values[j]);
207             if(pline->version == H5O_PLINE_VERSION_1)
208                 if(filter->cd_nelmts % 2)
209                     p += 4; /*padding*/
210 	} /* end if */
211     } /* end for */
212 
213     /* Set return value */
214     ret_value = pline;
215 
216 done:
217     if(NULL == ret_value && pline) {
218         H5O_pline_reset(pline);
219         H5O_pline_free(pline);
220     } /* end if */
221 
222     FUNC_LEAVE_NOAPI(ret_value)
223 } /* end H5O_pline_decode() */
224 
225 
226 /*-------------------------------------------------------------------------
227  * Function:	H5O_pline_encode
228  *
229  * Purpose:	Encodes message MESG into buffer P.
230  *
231  * Return:	Non-negative on success/Negative on failure
232  *
233  * Programmer:	Robb Matzke
234  *              Wednesday, April 15, 1998
235  *
236  *-------------------------------------------------------------------------
237  */
238 static herr_t
H5O_pline_encode(H5F_t H5_ATTR_UNUSED * f,uint8_t * p,const void * mesg)239 H5O_pline_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p/*out*/, const void *mesg)
240 {
241     const H5O_pline_t	*pline = (const H5O_pline_t*)mesg;      /* Pipeline message to encode */
242     const       H5Z_filter_info_t *filter;      /* Filter to encode */
243     size_t	i, j;                   /* Local index variables */
244 
245     FUNC_ENTER_NOAPI_NOINIT_NOERR
246 
247     /* Check args */
248     HDassert(p);
249     HDassert(mesg);
250 
251     /* Message header */
252     *p++ = (uint8_t)pline->version;
253     *p++ = (uint8_t)(pline->nused);
254     if(pline->version == H5O_PLINE_VERSION_1) {
255         *p++ = 0;	/*reserved 1*/
256         *p++ = 0;	/*reserved 2*/
257         *p++ = 0;	/*reserved 3*/
258         *p++ = 0;	/*reserved 4*/
259         *p++ = 0;	/*reserved 5*/
260         *p++ = 0;	/*reserved 6*/
261     } /* end if */
262 
263     /* Encode filters */
264     for(i = 0, filter = &pline->filter[0]; i < pline->nused; i++, filter++) {
265         const char	*name;                  /* Filter name */
266         size_t		name_length;            /* Length of filter name */
267 
268         /* Filter ID */
269 	UINT16ENCODE(p, filter->id);
270 
271         /* Skip writing the name length & name if the filter is an internal filter */
272         if(pline->version > H5O_PLINE_VERSION_1 && filter->id < H5Z_FILTER_RESERVED) {
273             name_length = 0;
274             name = NULL;
275         } /* end if */
276         else {
277             H5Z_class2_t	*cls;                   /* Filter class */
278 
279             /*
280              * Get the filter name.  If the pipeline message has a name in it then
281              * use that one.  Otherwise try to look up the filter and get the name
282              * as it was registered.
283              */
284             if(NULL == (name = filter->name) && (cls = H5Z_find(filter->id)))
285                 name = cls->name;
286             name_length = name ? HDstrlen(name) + 1 : 0;
287 
288             /* Filter name length */
289             UINT16ENCODE(p, pline->version == H5O_PLINE_VERSION_1 ? H5O_ALIGN_OLD(name_length) : name_length);
290         } /* end else */
291 
292         /* Filter flags */
293 	UINT16ENCODE(p, filter->flags);
294 
295         /* # of filter parameters */
296 	UINT16ENCODE(p, filter->cd_nelmts);
297 
298         /* Encode name, if there is one to encode */
299 	if(name_length > 0) {
300             /* Store name, with null terminator */
301 	    HDmemcpy(p, name, name_length);
302 	    p += name_length;
303 
304             /* Pad out name to alignment, in older versions */
305             if(pline->version == H5O_PLINE_VERSION_1)
306                 while(name_length++ % 8)
307                     *p++ = 0;
308 	} /* end if */
309 
310         /* Filter parameters */
311 	for(j = 0; j < filter->cd_nelmts; j++)
312 	    UINT32ENCODE(p, filter->cd_values[j]);
313 
314         /* Align the parameters for older versions of the format */
315         if(pline->version == H5O_PLINE_VERSION_1)
316             if(filter->cd_nelmts % 2)
317                 UINT32ENCODE(p, 0);
318     } /* end for */
319 
320     FUNC_LEAVE_NOAPI(SUCCEED)
321 } /* end H5O_pline_encode() */
322 
323 
324 /*-------------------------------------------------------------------------
325  * Function:	H5O_pline_copy
326  *
327  * Purpose:	Copies a filter pipeline message from SRC to DST allocating
328  *		DST if necessary.  If DST is already allocated then we assume
329  *		that it isn't initialized.
330  *
331  * Return:	Success:	Ptr to DST or allocated result.
332  *
333  *		Failure:	NULL
334  *
335  * Programmer:	Robb Matzke
336  *              Wednesday, April 15, 1998
337  *
338  *-------------------------------------------------------------------------
339  */
340 static void *
H5O_pline_copy(const void * _src,void * _dst)341 H5O_pline_copy(const void *_src, void *_dst/*out*/)
342 {
343     const H5O_pline_t	*src = (const H5O_pline_t *)_src;       /* Source pipeline message */
344     H5O_pline_t		*dst = (H5O_pline_t *)_dst;             /* Destination pipeline message */
345     size_t		i;                      /* Local index variable */
346     H5O_pline_t		*ret_value = NULL;      /* Return value */
347 
348     FUNC_ENTER_NOAPI_NOINIT
349 
350     /* Allocate pipeline message, if not provided */
351     if(!dst && NULL == (dst = H5FL_MALLOC(H5O_pline_t)))
352 	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
353 
354     /* Shallow copy basic fields */
355     *dst = *src;
356 
357     /* Copy over filters, if any */
358     dst->nalloc = dst->nused;
359     if(dst->nalloc) {
360         /* Allocate array to hold filters */
361 	if(NULL == (dst->filter = (H5Z_filter_info_t *)H5MM_calloc(dst->nalloc * sizeof(dst->filter[0]))))
362 	    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
363 
364         /* Deep-copy filters */
365         for(i = 0; i < src->nused; i++) {
366             /* Basic filter information */
367             dst->filter[i] = src->filter[i];
368 
369             /* Filter name */
370             if(src->filter[i].name) {
371                 size_t namelen;         /* Length of source filter name, including null terminator  */
372 
373                 namelen = HDstrlen(src->filter[i].name) + 1;
374 
375                 /* Allocate space for the filter name, or use the internal buffer */
376                 if(namelen > H5Z_COMMON_NAME_LEN) {
377                     dst->filter[i].name = (char *)H5MM_strdup(src->filter[i].name);
378                     if(NULL == dst->filter[i].name)
379                         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for filter name")
380                 } /* end if */
381                 else
382                     dst->filter[i].name = dst->filter[i]._name;
383             } /* end if */
384 
385             /* Filter parameters */
386             if(src->filter[i].cd_nelmts > 0) {
387                 /* Allocate space for the client data elements, or use the internal buffer */
388                 if(src->filter[i].cd_nelmts > H5Z_COMMON_CD_VALUES) {
389                     if(NULL == (dst->filter[i].cd_values = (unsigned *)H5MM_malloc(src->filter[i].cd_nelmts* sizeof(unsigned))))
390                         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
391 
392                     HDmemcpy(dst->filter[i].cd_values, src->filter[i].cd_values,
393                             src->filter[i].cd_nelmts * sizeof(unsigned));
394                 } /* end if */
395                 else
396                     dst->filter[i].cd_values = dst->filter[i]._cd_values;
397             } /* end if */
398         } /* end for */
399     } /* end if */
400     else
401 	dst->filter = NULL;
402 
403     /* Set return value */
404     ret_value = dst;
405 
406 done:
407     if(!ret_value && dst) {
408         H5O_pline_reset(dst);
409 	if(!_dst)
410             H5O_pline_free(dst);
411     } /* end if */
412 
413     FUNC_LEAVE_NOAPI(ret_value)
414 } /* end H5O_pline_copy() */
415 
416 
417 /*-------------------------------------------------------------------------
418  * Function:	H5O_pline_size
419  *
420  * Purpose:	Determines the size of a raw filter pipeline message.
421  *
422  * Return:	Success:	Size of message.
423  *
424  *		Failure:	zero
425  *
426  * Programmer:	Robb Matzke
427  *              Wednesday, April 15, 1998
428  *
429  *-------------------------------------------------------------------------
430  */
431 static size_t
H5O_pline_size(const H5F_t H5_ATTR_UNUSED * f,const void * mesg)432 H5O_pline_size(const H5F_t H5_ATTR_UNUSED *f, const void *mesg)
433 {
434     const H5O_pline_t	*pline = (const H5O_pline_t*)mesg;      /* Pipeline message */
435     size_t i;                   /* Local index variable */
436     size_t ret_value = 0;       /* Return value */
437 
438     FUNC_ENTER_NOAPI_NOINIT_NOERR
439 
440     /* Message header */
441     ret_value = 1 +			/*version			*/
442 	   1 +				/*number of filters		*/
443 	   (pline->version == H5O_PLINE_VERSION_1 ? 6 : 0);	/*reserved			*/
444 
445     /* Calculate size of each filter in pipeline */
446     for(i = 0; i < pline->nused; i++) {
447         size_t	name_len;               /* Length of filter name */
448         const char *name;               /* Filter name */
449 
450         /* Don't write the name length & name if the filter is an internal filter */
451         if(pline->version > H5O_PLINE_VERSION_1 && pline->filter[i].id < H5Z_FILTER_RESERVED)
452             name_len = 0;
453         else {
454             H5Z_class2_t	*cls;                   /* Filter class */
455 
456             /* Get the name of the filter, same as done with H5O_pline_encode() */
457             if(NULL == (name = pline->filter[i].name) && (cls = H5Z_find(pline->filter[i].id)))
458                 name = cls->name;
459             name_len = name ? HDstrlen(name) + 1 : 0;
460         } /* end else */
461 
462 	ret_value += 2 +			/*filter identification number	*/
463 		(size_t)((pline->version == H5O_PLINE_VERSION_1 || pline->filter[i].id >= H5Z_FILTER_RESERVED) ? 2 : 0) +				/*name length			*/
464 		2 +				/*flags				*/
465 		2 +				/*number of client data values	*/
466 		(pline->version == H5O_PLINE_VERSION_1 ? (size_t)H5O_ALIGN_OLD(name_len) : name_len);	/*length of the filter name	*/
467 
468 	ret_value += pline->filter[i].cd_nelmts * 4;
469         if(pline->version == H5O_PLINE_VERSION_1)
470             if(pline->filter[i].cd_nelmts % 2)
471                 ret_value += 4;
472     } /* end for */
473 
474     FUNC_LEAVE_NOAPI(ret_value)
475 } /* end H5O_pline_size() */
476 
477 
478 /*-------------------------------------------------------------------------
479  * Function:	H5O_pline_reset
480  *
481  * Purpose:	Resets a filter pipeline message by clearing all filters.
482  *		The MESG buffer is not freed.
483  *
484  * Return:	Non-negative on success/Negative on failure
485  *
486  * Programmer:	Robb Matzke
487  *              Wednesday, April 15, 1998
488  *
489  *-------------------------------------------------------------------------
490  */
491 static herr_t
H5O_pline_reset(void * mesg)492 H5O_pline_reset(void *mesg)
493 {
494     H5O_pline_t	*pline = (H5O_pline_t*)mesg;    /* Pipeline message */
495     size_t	i;                              /* Local index variable */
496 
497     FUNC_ENTER_NOAPI_NOINIT_NOERR
498 
499     HDassert(pline);
500 
501     /* Free information for each filter */
502     for(i = 0; i < pline->nused; i++) {
503         if(pline->filter[i].name && pline->filter[i].name != pline->filter[i]._name)
504             HDassert((HDstrlen(pline->filter[i].name) + 1) > H5Z_COMMON_NAME_LEN);
505         if(pline->filter[i].name != pline->filter[i]._name)
506             pline->filter[i].name = (char *)H5MM_xfree(pline->filter[i].name);
507         if(pline->filter[i].cd_values && pline->filter[i].cd_values != pline->filter[i]._cd_values)
508             HDassert(pline->filter[i].cd_nelmts > H5Z_COMMON_CD_VALUES);
509         if(pline->filter[i].cd_values != pline->filter[i]._cd_values)
510             pline->filter[i].cd_values = (unsigned *)H5MM_xfree(pline->filter[i].cd_values);
511     } /* end for */
512 
513     /* Free filter array */
514     if(pline->filter)
515         pline->filter = (H5Z_filter_info_t *)H5MM_xfree(pline->filter);
516 
517     /* Reset # of filters */
518     pline->nused = pline->nalloc = 0;
519 
520     /* Reset version # of pipeline message */
521     pline->version = H5O_PLINE_VERSION_1;
522 
523     FUNC_LEAVE_NOAPI(SUCCEED)
524 } /* end H5O_pline_reset() */
525 
526 
527 /*-------------------------------------------------------------------------
528  * Function:	H5O_pline_free
529  *
530  * Purpose:	Free's the message
531  *
532  * Return:	Non-negative on success/Negative on failure
533  *
534  * Programmer:	Quincey Koziol
535  *              Saturday, March 11, 2000
536  *
537  *-------------------------------------------------------------------------
538  */
539 static herr_t
H5O_pline_free(void * mesg)540 H5O_pline_free(void *mesg)
541 {
542     FUNC_ENTER_NOAPI_NOINIT_NOERR
543 
544     HDassert(mesg);
545 
546     mesg = H5FL_FREE(H5O_pline_t, mesg);
547 
548     FUNC_LEAVE_NOAPI(SUCCEED)
549 } /* end H5O_pline_free() */
550 
551 
552 /*-------------------------------------------------------------------------
553  * Function:    H5O_pline_pre_copy_file
554  *
555  * Purpose:     Perform any necessary actions before copying message between
556  *              files
557  *
558  * Return:      Success:        Non-negative
559  *
560  *              Failure:        Negative
561  *
562  * Programmer:  Peter Cao
563  *              December 27, 2005
564  *
565  *-------------------------------------------------------------------------
566  */
567 static herr_t
H5O_pline_pre_copy_file(H5F_t H5_ATTR_UNUSED * file_src,const void * mesg_src,hbool_t H5_ATTR_UNUSED * deleted,const H5O_copy_t H5_ATTR_UNUSED * cpy_info,void * _udata)568 H5O_pline_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *mesg_src,
569     hbool_t H5_ATTR_UNUSED *deleted, const H5O_copy_t H5_ATTR_UNUSED *cpy_info, void *_udata)
570 {
571     const H5O_pline_t *pline_src = (const H5O_pline_t *)mesg_src;    /* Source datatype */
572     H5O_copy_file_ud_common_t *udata = (H5O_copy_file_ud_common_t *)_udata; /* Object copying user data */
573     herr_t             ret_value = SUCCEED;                     /* Return value */
574 
575     FUNC_ENTER_NOAPI_NOINIT
576 
577     /* check args */
578     HDassert(pline_src);
579 
580     /* If the user data is non-NULL, assume we are copying a dataset or group
581      * and make a copy of the filter pipeline for later in
582      * the object copying process.
583      */
584     if(udata)
585         if(NULL == (udata->src_pline = (H5O_pline_t *)H5O_pline_copy(pline_src, NULL)))
586             HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to copy")
587 
588 done:
589     FUNC_LEAVE_NOAPI(ret_value)
590 } /* end H5O_pline_pre_copy_file() */
591 
592 
593 /*-------------------------------------------------------------------------
594  * Function:	H5O_pline_debug
595  *
596  * Purpose:	Prints debugging information for filter pipeline message MESG
597  *		on output stream STREAM.  Each line is indented INDENT
598  *		characters and the field name takes up FWIDTH characters.
599  *
600  * Return:	Non-negative on success/Negative on failure
601  *
602  * Programmer:	Robb Matzke
603  *              Wednesday, April 15, 1998
604  *
605  *-------------------------------------------------------------------------
606  */
607 static herr_t
H5O_pline_debug(H5F_t H5_ATTR_UNUSED * f,hid_t H5_ATTR_UNUSED dxpl_id,const void * mesg,FILE * stream,int indent,int fwidth)608 H5O_pline_debug(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, const void *mesg, FILE *stream,
609 		int indent, int fwidth)
610 {
611     const H5O_pline_t	*pline = (const H5O_pline_t *)mesg;
612     size_t		i, j;
613 
614     FUNC_ENTER_NOAPI_NOINIT_NOERR
615 
616     /* check args */
617     HDassert(f);
618     HDassert(pline);
619     HDassert(stream);
620     HDassert(indent >= 0);
621     HDassert(fwidth >= 0);
622 
623     HDfprintf(stream, "%*s%-*s %Zu/%Zu\n", indent, "", fwidth,
624 	    "Number of filters:",
625 	    pline->nused,
626 	    pline->nalloc);
627 
628     /* Loop over all the filters */
629     for(i = 0; i < pline->nused; i++) {
630 	char		name[32];
631 
632 	HDsnprintf(name, sizeof(name), "Filter at position %u", (unsigned)i);
633 	HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth, name);
634 	HDfprintf(stream, "%*s%-*s 0x%04x\n", indent + 3, "", MAX(0, fwidth - 3),
635 		"Filter identification:",
636 		(unsigned)(pline->filter[i].id));
637 	if(pline->filter[i].name)
638 	    HDfprintf(stream, "%*s%-*s \"%s\"\n", indent + 3, "", MAX(0, fwidth - 3),
639 		    "Filter name:",
640 		    pline->filter[i].name);
641 	else
642 	    HDfprintf(stream, "%*s%-*s NONE\n", indent + 3, "", MAX(0, fwidth - 3),
643 		    "Filter name:");
644 	HDfprintf(stream, "%*s%-*s 0x%04x\n", indent + 3, "", MAX(0, fwidth - 3),
645 		"Flags:",
646 		pline->filter[i].flags);
647 	HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
648 		"Num CD values:",
649 		pline->filter[i].cd_nelmts);
650 
651         /* Filter parameters */
652 	for(j = 0; j < pline->filter[i].cd_nelmts; j++) {
653 	    char	field_name[32];
654 
655 	    HDsnprintf(field_name, sizeof(field_name), "CD value %lu", (unsigned long)j);
656 	    HDfprintf(stream, "%*s%-*s %u\n", indent + 6, "", MAX(0, fwidth - 6),
657 		    field_name,
658 		    pline->filter[i].cd_values[j]);
659 	} /* end for */
660     } /* end for */
661 
662     FUNC_LEAVE_NOAPI(SUCCEED)
663 } /* end H5O_pline_debug() */
664 
665 
666 /*-------------------------------------------------------------------------
667  * Function:    H5O_pline_set_latest_version
668  *
669  * Purpose:     Set the encoding for a I/O filter pipeline to the latest version.
670  *
671  * Return:	Non-negative on success/Negative on failure
672  *
673  * Programmer:  Quincey Koziol
674  *              Tuesday, July 24, 2007
675  *
676  *-------------------------------------------------------------------------
677  */
678 herr_t
H5O_pline_set_latest_version(H5O_pline_t * pline)679 H5O_pline_set_latest_version(H5O_pline_t *pline)
680 {
681     FUNC_ENTER_NOAPI_NOINIT_NOERR
682 
683     /* Sanity check */
684     HDassert(pline);
685 
686     /* Set encoding of I/O pipeline to latest version */
687     pline->version = H5O_PLINE_VERSION_LATEST;
688 
689     FUNC_LEAVE_NOAPI(SUCCEED)
690 } /* end H5O_pline_set_latest_version() */
691 
692