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, H5O_t *open_oh, unsigned mesg_flags,
37 unsigned *ioflags, size_t p_size, 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, const void *_mesg, FILE * stream,
45 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 /* Format version bounds for filter pipleline */
93 const unsigned H5O_pline_ver_bounds[] = {
94 H5O_PLINE_VERSION_1, /* H5F_LIBVER_EARLIEST */
95 H5O_PLINE_VERSION_2, /* H5F_LIBVER_V18 */
96 H5O_PLINE_VERSION_LATEST /* H5F_LIBVER_LATEST */
97 };
98
99 /* Declare a free list to manage the H5O_pline_t struct */
100 H5FL_DEFINE(H5O_pline_t);
101
102
103 /*-------------------------------------------------------------------------
104 * Function: H5O__pline_decode
105 *
106 * Purpose: Decodes a filter pipeline message.
107 *
108 * Return: Success: Ptr to the native message.
109 * Failure: NULL
110 *
111 * Programmer: Robb Matzke
112 * Wednesday, April 15, 1998
113 *
114 *-------------------------------------------------------------------------
115 */
116 static void *
H5O__pline_decode(H5F_t H5_ATTR_UNUSED * f,H5O_t H5_ATTR_UNUSED * open_oh,unsigned H5_ATTR_UNUSED mesg_flags,unsigned H5_ATTR_UNUSED * ioflags,size_t p_size,const uint8_t * p)117 H5O__pline_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh,
118 unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags,
119 size_t p_size, const uint8_t *p)
120 {
121 H5O_pline_t *pline = NULL; /* Pipeline message */
122 H5Z_filter_info_t *filter; /* Filter to decode */
123 size_t name_length; /* Length of filter name */
124 size_t i; /* Local index variable */
125 const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */
126 void *ret_value = NULL; /* Return value */
127
128 FUNC_ENTER_STATIC
129
130 /* check args */
131 HDassert(p);
132
133 /* Allocate space for I/O pipeline message */
134 if(NULL == (pline = H5FL_CALLOC(H5O_pline_t)))
135 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
136
137 /* Version */
138 pline->version = *p++;
139 if(pline->version < H5O_PLINE_VERSION_1 || pline->version > H5O_PLINE_VERSION_LATEST)
140 HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "bad version number for filter pipeline message")
141
142 /* Number of filters */
143 pline->nused = *p++;
144 if(pline->nused > H5Z_MAX_NFILTERS) {
145
146 /* Reset the number of filters used to avoid array traversal in error
147 * handling code.
148 */
149 pline->nused = 0;
150
151 HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter pipeline message has too many filters")
152 }
153
154 /* Reserved */
155 if(pline->version == H5O_PLINE_VERSION_1)
156 p += 6;
157
158 /* Allocate array for filters */
159 pline->nalloc = pline->nused;
160 if(NULL == (pline->filter = (H5Z_filter_info_t *)H5MM_calloc(pline->nalloc * sizeof(pline->filter[0]))))
161 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
162
163 /* Decode filters */
164 for(i = 0, filter = &pline->filter[0]; i < pline->nused; i++, filter++) {
165 /* Filter ID */
166 UINT16DECODE(p, filter->id);
167
168 /* Length of filter name */
169 if(pline->version > H5O_PLINE_VERSION_1 && filter->id < H5Z_FILTER_RESERVED)
170 name_length = 0;
171 else {
172 UINT16DECODE(p, name_length);
173 if(pline->version == H5O_PLINE_VERSION_1 && name_length % 8)
174 HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter name length is not a multiple of eight")
175 } /* end if */
176
177 /* Filter flags */
178 UINT16DECODE(p, filter->flags);
179
180 /* Number of filter parameters ("client data elements") */
181 UINT16DECODE(p, filter->cd_nelmts);
182
183 /* Filter name, if there is one */
184 if(name_length) {
185 size_t actual_name_length; /* Actual length of name */
186
187 /* Determine actual name length (without padding, but with null terminator) */
188 actual_name_length = HDstrlen((const char *)p) + 1;
189 HDassert(actual_name_length <= name_length);
190
191 /* Allocate space for the filter name, or use the internal buffer */
192 if(actual_name_length > H5Z_COMMON_NAME_LEN) {
193 filter->name = (char *)H5MM_malloc(actual_name_length);
194 if(NULL == filter->name)
195 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for filter name")
196 } /* end if */
197 else
198 filter->name = filter->_name;
199
200 HDstrncpy(filter->name, (const char *)p, actual_name_length);
201 p += name_length;
202 } /* end if */
203
204 /* Filter parameters */
205 if(filter->cd_nelmts) {
206 size_t j; /* Local index variable */
207
208 /* Allocate space for the client data elements, or use the internal buffer */
209 if(filter->cd_nelmts > H5Z_COMMON_CD_VALUES) {
210 filter->cd_values = (unsigned *)H5MM_malloc(filter->cd_nelmts * sizeof(unsigned));
211 if(NULL == filter->cd_values)
212 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for client data")
213 } /* end if */
214 else
215 filter->cd_values = filter->_cd_values;
216
217 /*
218 * Read the client data values and the padding
219 */
220 for (j = 0; j < filter->cd_nelmts; j++) {
221 if (p + 4 - 1 <= p_end)
222 UINT32DECODE(p, filter->cd_values[j])
223 else
224 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "ran off the end of the buffer: current p = %p, p_size = %zu, p_end = %p", p, p_size, p_end)
225 }
226
227 if(pline->version == H5O_PLINE_VERSION_1)
228 if(filter->cd_nelmts % 2)
229 p += 4; /*padding*/
230 } /* end if */
231 } /* end for */
232
233 /* Set return value */
234 ret_value = pline;
235
236 done:
237 if(NULL == ret_value && pline) {
238 H5O__pline_reset(pline);
239 H5O__pline_free(pline);
240 } /* end if */
241
242 FUNC_LEAVE_NOAPI(ret_value)
243 } /* end H5O__pline_decode() */
244
245
246 /*-------------------------------------------------------------------------
247 * Function: H5O_pline_encode
248 *
249 * Purpose: Encodes message MESG into buffer P.
250 *
251 * Return: Non-negative on success/Negative on failure
252 *
253 * Programmer: Robb Matzke
254 * Wednesday, April 15, 1998
255 *
256 *-------------------------------------------------------------------------
257 */
258 static herr_t
H5O_pline_encode(H5F_t H5_ATTR_UNUSED * f,uint8_t * p,const void * mesg)259 H5O_pline_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p/*out*/, const void *mesg)
260 {
261 const H5O_pline_t *pline = (const H5O_pline_t*)mesg; /* Pipeline message to encode */
262 const H5Z_filter_info_t *filter; /* Filter to encode */
263 size_t i, j; /* Local index variables */
264
265 FUNC_ENTER_NOAPI_NOINIT_NOERR
266
267 /* Check args */
268 HDassert(p);
269 HDassert(mesg);
270
271 /* Message header */
272 *p++ = (uint8_t)pline->version;
273 *p++ = (uint8_t)(pline->nused);
274 if(pline->version == H5O_PLINE_VERSION_1) {
275 *p++ = 0; /*reserved 1*/
276 *p++ = 0; /*reserved 2*/
277 *p++ = 0; /*reserved 3*/
278 *p++ = 0; /*reserved 4*/
279 *p++ = 0; /*reserved 5*/
280 *p++ = 0; /*reserved 6*/
281 } /* end if */
282
283 /* Encode filters */
284 for(i = 0, filter = &pline->filter[0]; i < pline->nused; i++, filter++) {
285 const char *name; /* Filter name */
286 size_t name_length; /* Length of filter name */
287
288 /* Filter ID */
289 UINT16ENCODE(p, filter->id);
290
291 /* Skip writing the name length & name if the filter is an internal filter */
292 if(pline->version > H5O_PLINE_VERSION_1 && filter->id < H5Z_FILTER_RESERVED) {
293 name_length = 0;
294 name = NULL;
295 } /* end if */
296 else {
297 H5Z_class2_t *cls; /* Filter class */
298
299 /*
300 * Get the filter name. If the pipeline message has a name in it then
301 * use that one. Otherwise try to look up the filter and get the name
302 * as it was registered.
303 */
304 if(NULL == (name = filter->name) && (cls = H5Z_find(filter->id)))
305 name = cls->name;
306 name_length = name ? HDstrlen(name) + 1 : 0;
307
308 /* Filter name length */
309 UINT16ENCODE(p, pline->version == H5O_PLINE_VERSION_1 ? H5O_ALIGN_OLD(name_length) : name_length);
310 } /* end else */
311
312 /* Filter flags */
313 UINT16ENCODE(p, filter->flags);
314
315 /* # of filter parameters */
316 UINT16ENCODE(p, filter->cd_nelmts);
317
318 /* Encode name, if there is one to encode */
319 if(name_length > 0) {
320 /* Store name, with null terminator */
321 HDmemcpy(p, name, name_length);
322 p += name_length;
323
324 /* Pad out name to alignment, in older versions */
325 if(pline->version == H5O_PLINE_VERSION_1)
326 while(name_length++ % 8)
327 *p++ = 0;
328 } /* end if */
329
330 /* Filter parameters */
331 for(j = 0; j < filter->cd_nelmts; j++)
332 UINT32ENCODE(p, filter->cd_values[j]);
333
334 /* Align the parameters for older versions of the format */
335 if(pline->version == H5O_PLINE_VERSION_1)
336 if(filter->cd_nelmts % 2)
337 UINT32ENCODE(p, 0);
338 } /* end for */
339
340 FUNC_LEAVE_NOAPI(SUCCEED)
341 } /* end H5O_pline_encode() */
342
343
344 /*-------------------------------------------------------------------------
345 * Function: H5O_pline_copy
346 *
347 * Purpose: Copies a filter pipeline message from SRC to DST allocating
348 * DST if necessary. If DST is already allocated then we assume
349 * that it isn't initialized.
350 *
351 * Return: Success: Ptr to DST or allocated result.
352 *
353 * Failure: NULL
354 *
355 * Programmer: Robb Matzke
356 * Wednesday, April 15, 1998
357 *
358 *-------------------------------------------------------------------------
359 */
360 static void *
H5O_pline_copy(const void * _src,void * _dst)361 H5O_pline_copy(const void *_src, void *_dst/*out*/)
362 {
363 const H5O_pline_t *src = (const H5O_pline_t *)_src; /* Source pipeline message */
364 H5O_pline_t *dst = (H5O_pline_t *)_dst; /* Destination pipeline message */
365 size_t i; /* Local index variable */
366 H5O_pline_t *ret_value = NULL; /* Return value */
367
368 FUNC_ENTER_NOAPI_NOINIT
369
370 /* Allocate pipeline message, if not provided */
371 if(!dst && NULL == (dst = H5FL_MALLOC(H5O_pline_t)))
372 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
373
374 /* Shallow copy basic fields */
375 *dst = *src;
376
377 /* Copy over filters, if any */
378 dst->nalloc = dst->nused;
379 if(dst->nalloc) {
380 /* Allocate array to hold filters */
381 if(NULL == (dst->filter = (H5Z_filter_info_t *)H5MM_calloc(dst->nalloc * sizeof(dst->filter[0]))))
382 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
383
384 /* Deep-copy filters */
385 for(i = 0; i < src->nused; i++) {
386 /* Basic filter information */
387 dst->filter[i] = src->filter[i];
388
389 /* Filter name */
390 if(src->filter[i].name) {
391 size_t namelen; /* Length of source filter name, including null terminator */
392
393 namelen = HDstrlen(src->filter[i].name) + 1;
394
395 /* Allocate space for the filter name, or use the internal buffer */
396 if(namelen > H5Z_COMMON_NAME_LEN) {
397 dst->filter[i].name = (char *)H5MM_strdup(src->filter[i].name);
398 if(NULL == dst->filter[i].name)
399 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for filter name")
400 } /* end if */
401 else
402 dst->filter[i].name = dst->filter[i]._name;
403 } /* end if */
404
405 /* Filter parameters */
406 if(src->filter[i].cd_nelmts > 0) {
407 /* Allocate space for the client data elements, or use the internal buffer */
408 if(src->filter[i].cd_nelmts > H5Z_COMMON_CD_VALUES) {
409 if(NULL == (dst->filter[i].cd_values = (unsigned *)H5MM_malloc(src->filter[i].cd_nelmts* sizeof(unsigned))))
410 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
411
412 HDmemcpy(dst->filter[i].cd_values, src->filter[i].cd_values,
413 src->filter[i].cd_nelmts * sizeof(unsigned));
414 } /* end if */
415 else
416 dst->filter[i].cd_values = dst->filter[i]._cd_values;
417 } /* end if */
418 } /* end for */
419 } /* end if */
420 else
421 dst->filter = NULL;
422
423 /* Set return value */
424 ret_value = dst;
425
426 done:
427 if(!ret_value && dst) {
428 H5O__pline_reset(dst);
429 if(!_dst)
430 H5O__pline_free(dst);
431 } /* end if */
432
433 FUNC_LEAVE_NOAPI(ret_value)
434 } /* end H5O_pline_copy() */
435
436
437 /*-------------------------------------------------------------------------
438 * Function: H5O_pline_size
439 *
440 * Purpose: Determines the size of a raw filter pipeline message.
441 *
442 * Return: Success: Size of message.
443 *
444 * Failure: zero
445 *
446 * Programmer: Robb Matzke
447 * Wednesday, April 15, 1998
448 *
449 *-------------------------------------------------------------------------
450 */
451 static size_t
H5O_pline_size(const H5F_t H5_ATTR_UNUSED * f,const void * mesg)452 H5O_pline_size(const H5F_t H5_ATTR_UNUSED *f, const void *mesg)
453 {
454 const H5O_pline_t *pline = (const H5O_pline_t*)mesg; /* Pipeline message */
455 size_t i; /* Local index variable */
456 size_t ret_value = 0; /* Return value */
457
458 FUNC_ENTER_NOAPI_NOINIT_NOERR
459
460 /* Message header */
461 ret_value = 1 + /*version */
462 1 + /*number of filters */
463 (pline->version == H5O_PLINE_VERSION_1 ? 6 : 0); /*reserved */
464
465 /* Calculate size of each filter in pipeline */
466 for(i = 0; i < pline->nused; i++) {
467 size_t name_len; /* Length of filter name */
468 const char *name; /* Filter name */
469
470 /* Don't write the name length & name if the filter is an internal filter */
471 if(pline->version > H5O_PLINE_VERSION_1 && pline->filter[i].id < H5Z_FILTER_RESERVED)
472 name_len = 0;
473 else {
474 H5Z_class2_t *cls; /* Filter class */
475
476 /* Get the name of the filter, same as done with H5O_pline_encode() */
477 if(NULL == (name = pline->filter[i].name) && (cls = H5Z_find(pline->filter[i].id)))
478 name = cls->name;
479 name_len = name ? HDstrlen(name) + 1 : 0;
480 } /* end else */
481
482 ret_value += 2 + /*filter identification number */
483 (size_t)((pline->version == H5O_PLINE_VERSION_1 || pline->filter[i].id >= H5Z_FILTER_RESERVED) ? 2 : 0) + /*name length */
484 2 + /*flags */
485 2 + /*number of client data values */
486 (pline->version == H5O_PLINE_VERSION_1 ? (size_t)H5O_ALIGN_OLD(name_len) : name_len); /*length of the filter name */
487
488 ret_value += pline->filter[i].cd_nelmts * 4;
489 if(pline->version == H5O_PLINE_VERSION_1)
490 if(pline->filter[i].cd_nelmts % 2)
491 ret_value += 4;
492 } /* end for */
493
494 FUNC_LEAVE_NOAPI(ret_value)
495 } /* end H5O_pline_size() */
496
497
498 /*-------------------------------------------------------------------------
499 * Function: H5O__pline_reset
500 *
501 * Purpose: Resets a filter pipeline message by clearing all filters.
502 * The MESG buffer is not freed.
503 *
504 * Return: Non-negative on success/Negative on failure
505 *
506 * Programmer: Robb Matzke
507 * Wednesday, April 15, 1998
508 *
509 *-------------------------------------------------------------------------
510 */
511 static herr_t
H5O__pline_reset(void * mesg)512 H5O__pline_reset(void *mesg)
513 {
514 H5O_pline_t *pline = (H5O_pline_t*)mesg; /* Pipeline message */
515 size_t i; /* Local index variable */
516
517 FUNC_ENTER_STATIC_NOERR
518
519 /* NOTE: This function can be called during error processing from
520 * other API calls so DO NOT ASSUME THAT ANY VALUES ARE SANE.
521 */
522
523 HDassert(pline);
524
525 /* Free the filter information and array */
526 if (pline->filter) {
527
528 /* Free information for each filter */
529 for(i = 0; i < pline->nused; i++) {
530 if(pline->filter[i].name && pline->filter[i].name != pline->filter[i]._name)
531 HDassert((HDstrlen(pline->filter[i].name) + 1) > H5Z_COMMON_NAME_LEN);
532 if(pline->filter[i].name != pline->filter[i]._name)
533 pline->filter[i].name = (char *)H5MM_xfree(pline->filter[i].name);
534 if(pline->filter[i].cd_values && pline->filter[i].cd_values != pline->filter[i]._cd_values)
535 HDassert(pline->filter[i].cd_nelmts > H5Z_COMMON_CD_VALUES);
536 if(pline->filter[i].cd_values != pline->filter[i]._cd_values)
537 pline->filter[i].cd_values = (unsigned *)H5MM_xfree(pline->filter[i].cd_values);
538 } /* end for */
539
540 /* Free filter array */
541 pline->filter = (H5Z_filter_info_t *)H5MM_xfree(pline->filter);
542 }
543
544 /* Reset # of filters */
545 pline->nused = pline->nalloc = 0;
546
547 /* Reset version # of pipeline message */
548 pline->version = H5O_PLINE_VERSION_1;
549
550 FUNC_LEAVE_NOAPI(SUCCEED)
551 } /* end H5O__pline_reset() */
552
553
554 /*-------------------------------------------------------------------------
555 * Function: H5O__pline_free
556 *
557 * Purpose: Frees the message
558 *
559 * Return: Non-negative on success/Negative on failure
560 *
561 * Programmer: Quincey Koziol
562 * Saturday, March 11, 2000
563 *
564 *-------------------------------------------------------------------------
565 */
566 static herr_t
H5O__pline_free(void * mesg)567 H5O__pline_free(void *mesg)
568 {
569 FUNC_ENTER_STATIC_NOERR
570
571 HDassert(mesg);
572
573 mesg = H5FL_FREE(H5O_pline_t, mesg);
574
575 FUNC_LEAVE_NOAPI(SUCCEED)
576 } /* end H5O__pline_free() */
577
578
579 /*-------------------------------------------------------------------------
580 * Function: H5O_pline_pre_copy_file
581 *
582 * Purpose: Perform any necessary actions before copying message between
583 * files
584 *
585 * Return: Success: Non-negative
586 *
587 * Failure: Negative
588 *
589 * Programmer: Peter Cao
590 * December 27, 2005
591 *
592 *-------------------------------------------------------------------------
593 */
594 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 * cpy_info,void * _udata)595 H5O_pline_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *mesg_src,
596 hbool_t H5_ATTR_UNUSED *deleted, const H5O_copy_t *cpy_info, void *_udata)
597 {
598 const H5O_pline_t *pline_src = (const H5O_pline_t *)mesg_src; /* Source pline */
599 H5O_copy_file_ud_common_t *udata = (H5O_copy_file_ud_common_t *)_udata; /* Object copying user data */
600 herr_t ret_value = SUCCEED; /* Return value */
601
602 FUNC_ENTER_NOAPI_NOINIT
603
604 /* check args */
605 HDassert(pline_src);
606 HDassert(cpy_info);
607 HDassert(cpy_info->file_dst);
608
609 /* Check to ensure that the version of the message to be copied does not exceed
610 the message version allowed by the destination file's high bound */
611 if(pline_src->version > H5O_pline_ver_bounds[H5F_HIGH_BOUND(cpy_info->file_dst)])
612 HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "pline message version out of bounds")
613
614 /* If the user data is non-NULL, assume we are copying a dataset or group
615 * and make a copy of the filter pipeline for later in
616 * the object copying process.
617 */
618 if(udata)
619 if(NULL == (udata->src_pline = (H5O_pline_t *)H5O_pline_copy(pline_src, NULL)))
620 HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to copy")
621
622 done:
623 FUNC_LEAVE_NOAPI(ret_value)
624 } /* end H5O_pline_pre_copy_file() */
625
626
627 /*-------------------------------------------------------------------------
628 * Function: H5O__pline_debug
629 *
630 * Purpose: Prints debugging information for filter pipeline message MESG
631 * on output stream STREAM. Each line is indented INDENT
632 * characters and the field name takes up FWIDTH characters.
633 *
634 * Return: Non-negative on success/Negative on failure
635 *
636 * Programmer: Robb Matzke
637 * Wednesday, April 15, 1998
638 *
639 *-------------------------------------------------------------------------
640 */
641 static herr_t
H5O__pline_debug(H5F_t H5_ATTR_UNUSED * f,const void * mesg,FILE * stream,int indent,int fwidth)642 H5O__pline_debug(H5F_t H5_ATTR_UNUSED *f, const void *mesg, FILE *stream,
643 int indent, int fwidth)
644 {
645 const H5O_pline_t *pline = (const H5O_pline_t *)mesg;
646 size_t i, j;
647
648 FUNC_ENTER_STATIC_NOERR
649
650 /* check args */
651 HDassert(f);
652 HDassert(pline);
653 HDassert(stream);
654 HDassert(indent >= 0);
655 HDassert(fwidth >= 0);
656
657 HDfprintf(stream, "%*s%-*s %Zu/%Zu\n", indent, "", fwidth,
658 "Number of filters:",
659 pline->nused,
660 pline->nalloc);
661
662 /* Loop over all the filters */
663 for(i = 0; i < pline->nused; i++) {
664 char name[32];
665
666 HDsnprintf(name, sizeof(name), "Filter at position %u", (unsigned)i);
667 HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth, name);
668 HDfprintf(stream, "%*s%-*s 0x%04x\n", indent + 3, "", MAX(0, fwidth - 3),
669 "Filter identification:",
670 (unsigned)(pline->filter[i].id));
671 if(pline->filter[i].name)
672 HDfprintf(stream, "%*s%-*s \"%s\"\n", indent + 3, "", MAX(0, fwidth - 3),
673 "Filter name:",
674 pline->filter[i].name);
675 else
676 HDfprintf(stream, "%*s%-*s NONE\n", indent + 3, "", MAX(0, fwidth - 3),
677 "Filter name:");
678 HDfprintf(stream, "%*s%-*s 0x%04x\n", indent + 3, "", MAX(0, fwidth - 3),
679 "Flags:",
680 pline->filter[i].flags);
681 HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
682 "Num CD values:",
683 pline->filter[i].cd_nelmts);
684
685 /* Filter parameters */
686 for(j = 0; j < pline->filter[i].cd_nelmts; j++) {
687 char field_name[32];
688
689 HDsnprintf(field_name, sizeof(field_name), "CD value %lu", (unsigned long)j);
690 HDfprintf(stream, "%*s%-*s %u\n", indent + 6, "", MAX(0, fwidth - 6),
691 field_name,
692 pline->filter[i].cd_values[j]);
693 } /* end for */
694 } /* end for */
695
696 FUNC_LEAVE_NOAPI(SUCCEED)
697 } /* end H5O__pline_debug() */
698
699
700 /*-------------------------------------------------------------------------
701 * Function: H5O_pline_set_version
702 *
703 * Purpose: Set the version to encode an I/O filter pipeline with.
704 *
705 * Return: Non-negative on success/Negative on failure
706 *
707 * Programmer: Vailin Choi; December 2017
708 *
709 *-------------------------------------------------------------------------
710 */
711 herr_t
H5O_pline_set_version(H5F_t * f,H5O_pline_t * pline)712 H5O_pline_set_version(H5F_t *f, H5O_pline_t *pline)
713 {
714 unsigned version; /* Message version */
715 herr_t ret_value = SUCCEED; /* Return value */
716
717 FUNC_ENTER_NOAPI(FAIL)
718
719 /* Sanity check */
720 HDassert(f);
721 HDassert(pline);
722
723 /* Upgrade to the version indicated by the file's low bound if higher */
724 version = MAX(pline->version, H5O_pline_ver_bounds[H5F_LOW_BOUND(f)]);
725
726 /* Version bounds check */
727 if(version > H5O_pline_ver_bounds[H5F_HIGH_BOUND(f)])
728 HGOTO_ERROR(H5E_PLINE, H5E_BADRANGE, FAIL, "Filter pipeline version out of bounds")
729
730 /* Set the message version */
731 pline->version = version;
732
733 done:
734 FUNC_LEAVE_NOAPI(ret_value)
735 } /* end H5O_pline_set_version() */
736