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 /* Programmer:  Robb Matzke <matzke@llnl.gov>
15  *              Wednesday, September 30, 1998
16  *
17  * Purpose:    The fill message indicates a bit pattern to use for
18  *        uninitialized data points of a dataset.
19  */
20 
21 #include "H5Omodule.h"          /* This source code file is part of the H5O module */
22 
23 
24 #include "H5private.h"      /* Generic Functions    */
25 #include "H5Dprivate.h"     /* Datasets                */
26 #include "H5Eprivate.h"     /* Error handling       */
27 #include "H5FLprivate.h"    /* Free Lists           */
28 #include "H5Iprivate.h"     /* IDs                  */
29 #include "H5MMprivate.h"    /* Memory management    */
30 #include "H5Opkg.h"         /* Object headers       */
31 #include "H5Pprivate.h"     /* Property lists       */
32 #include "H5Sprivate.h"     /* Dataspaces           */
33 
34 
35 static void  *H5O_fill_old_decode(H5F_t *f, H5O_t *open_oh, unsigned mesg_flags,
36     unsigned *ioflags, size_t p_size, const uint8_t *p);
37 static herr_t H5O_fill_old_encode(H5F_t *f, uint8_t *p, const void *_mesg);
38 static size_t H5O_fill_old_size(const H5F_t *f, const void *_mesg);
39 static void  *H5O_fill_new_decode(H5F_t *f, H5O_t *open_oh, unsigned mesg_flags,
40     unsigned *ioflags, size_t p_size, const uint8_t *p);
41 static herr_t H5O_fill_new_encode(H5F_t *f, uint8_t *p, const void *_mesg);
42 static size_t H5O_fill_new_size(const H5F_t *f, const void *_mesg);
43 static void  *H5O_fill_copy(const void *_mesg, void *_dest);
44 static herr_t H5O__fill_reset(void *_mesg);
45 static herr_t H5O__fill_free(void *_mesg);
46 static herr_t H5O__fill_pre_copy_file(H5F_t *file_src, const void *mesg_src,
47     hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata);
48 static herr_t H5O__fill_debug(H5F_t *f, const void *_mesg, FILE *stream,
49     int indent, int fwidth);
50 
51 /* Set up & include shared message "interface" info */
52 #define H5O_SHARED_TYPE            H5O_MSG_FILL
53 #define H5O_SHARED_DECODE        H5O_fill_shared_decode
54 #define H5O_SHARED_DECODE_REAL        H5O_fill_old_decode
55 #define H5O_SHARED_ENCODE        H5O_fill_shared_encode
56 #define H5O_SHARED_ENCODE_REAL        H5O_fill_old_encode
57 #define H5O_SHARED_SIZE            H5O_fill_shared_size
58 #define H5O_SHARED_SIZE_REAL        H5O_fill_old_size
59 #define H5O_SHARED_DELETE        H5O__fill_shared_delete
60 #undef H5O_SHARED_DELETE_REAL
61 #define H5O_SHARED_LINK            H5O__fill_shared_link
62 #undef H5O_SHARED_LINK_REAL
63 #define H5O_SHARED_COPY_FILE        H5O__fill_shared_copy_file
64 #undef H5O_SHARED_COPY_FILE_REAL
65 #define H5O_SHARED_POST_COPY_FILE    H5O_fill_shared_post_copy_file
66 #undef H5O_SHARED_POST_COPY_FILE_REAL
67 #undef  H5O_SHARED_POST_COPY_FILE_UPD
68 #define H5O_SHARED_DEBUG        H5O_fill_shared_debug
69 #define H5O_SHARED_DEBUG_REAL        H5O__fill_debug
70 #include "H5Oshared.h"            /* Shared Object Header Message Callbacks */
71 
72 /* Set up & include shared message "interface" info */
73 /* (Kludgy 'undef's in order to re-include the H5Oshared.h header) */
74 #undef H5O_SHARED_TYPE
75 #define H5O_SHARED_TYPE            H5O_MSG_FILL_NEW
76 #undef H5O_SHARED_DECODE
77 #define H5O_SHARED_DECODE        H5O_fill_new_shared_decode
78 #undef H5O_SHARED_DECODE_REAL
79 #define H5O_SHARED_DECODE_REAL        H5O_fill_new_decode
80 #undef H5O_SHARED_ENCODE
81 #define H5O_SHARED_ENCODE        H5O_fill_new_shared_encode
82 #undef H5O_SHARED_ENCODE_REAL
83 #define H5O_SHARED_ENCODE_REAL        H5O_fill_new_encode
84 #undef H5O_SHARED_SIZE
85 #define H5O_SHARED_SIZE            H5O_fill_new_shared_size
86 #undef H5O_SHARED_SIZE_REAL
87 #define H5O_SHARED_SIZE_REAL        H5O_fill_new_size
88 #undef H5O_SHARED_DELETE
89 #define H5O_SHARED_DELETE        H5O__fill_new_shared_delete
90 #undef H5O_SHARED_DELETE_REAL
91 #undef H5O_SHARED_LINK
92 #define H5O_SHARED_LINK            H5O__fill_new_shared_link
93 #undef H5O_SHARED_LINK_REAL
94 #undef H5O_SHARED_COPY_FILE
95 #define H5O_SHARED_COPY_FILE        H5O__fill_new_shared_copy_file
96 #undef H5O_SHARED_COPY_FILE_REAL
97 #undef H5O_SHARED_POST_COPY_FILE
98 #define H5O_SHARED_POST_COPY_FILE    H5O_fill_new_shared_post_copy_file
99 #undef H5O_SHARED_POST_COPY_FILE_REAL
100 #undef  H5O_SHARED_POST_COPY_FILE_UPD
101 #undef H5O_SHARED_DEBUG
102 #define H5O_SHARED_DEBUG        H5O_fill_new_shared_debug
103 #undef H5O_SHARED_DEBUG_REAL
104 #define H5O_SHARED_DEBUG_REAL        H5O__fill_debug
105 #undef H5Oshared_H
106 #include "H5Oshared.h"            /* Shared Object Header Message Callbacks */
107 
108 /* This message derives from H5O message class, for old fill value before version 1.5 */
109 const H5O_msg_class_t H5O_MSG_FILL[1] = {{
110     H5O_FILL_ID,                /*message id number                         */
111     "fill",                     /*message name for debugging                */
112     sizeof(H5O_fill_t),         /*native message size                       */
113     H5O_SHARE_IS_SHARABLE|H5O_SHARE_IN_OHDR,    /* messages are sharable?   */
114     H5O_fill_shared_decode,     /*decode message                            */
115     H5O_fill_shared_encode,     /*encode message                            */
116     H5O_fill_copy,              /*copy the native value                     */
117     H5O_fill_shared_size,       /*raw message size                          */
118     H5O__fill_reset,            /*free internal memory                      */
119     H5O__fill_free,             /* free method                              */
120     H5O__fill_shared_delete,    /* file delete method                       */
121     H5O__fill_shared_link,      /* link method                              */
122     NULL,                       /* set share method                         */
123     NULL,                       /*can share method                          */
124     H5O__fill_pre_copy_file,    /* pre copy native value to file            */
125     H5O__fill_shared_copy_file, /* copy native value to file                */
126     H5O_fill_shared_post_copy_file, /* post copy native value to file       */
127     NULL,                       /* get creation index                       */
128     NULL,                       /* set creation index                       */
129     H5O_fill_shared_debug       /*debug the message                         */
130 }};
131 
132 /* This message derives from H5O message class, for new fill value after version 1.4  */
133 const H5O_msg_class_t H5O_MSG_FILL_NEW[1] = {{
134     H5O_FILL_NEW_ID,                    /*message id number                 */
135     "fill_new",                         /*message name for debugging        */
136     sizeof(H5O_fill_t),                 /*native message size               */
137     H5O_SHARE_IS_SHARABLE|H5O_SHARE_IN_OHDR,    /* messages are sharable?   */
138     H5O_fill_new_shared_decode,         /*decode message                    */
139     H5O_fill_new_shared_encode,         /*encode message                    */
140     H5O_fill_copy,                      /*copy the native value             */
141     H5O_fill_new_shared_size,           /*raw message size                  */
142     H5O__fill_reset,                    /*free internal memory              */
143     H5O__fill_free,                     /* free method                      */
144     H5O__fill_new_shared_delete,        /* file delete method               */
145     H5O__fill_new_shared_link,          /* link method                      */
146     NULL,                               /* set share method                 */
147     NULL,                               /*can share method                  */
148     H5O__fill_pre_copy_file,            /* pre copy native value to file    */
149     H5O__fill_new_shared_copy_file,      /* copy native value to file        */
150     H5O_fill_new_shared_post_copy_file, /* post copy native value to file   */
151     NULL,                               /* get creation index               */
152     NULL,                               /* set creation index               */
153     H5O_fill_new_shared_debug           /*debug the message                    */
154 }};
155 
156 /* Format version bounds for fill value */
157 const unsigned H5O_fill_ver_bounds[] = {
158     H5O_FILL_VERSION_1,     /* H5F_LIBVER_EARLIEST */
159     H5O_FILL_VERSION_3,     /* H5F_LIBVER_V18 */
160     H5O_FILL_VERSION_LATEST /* H5F_LIBVER_LATEST */
161 };
162 
163 /* Masks, shift values & flags for fill value message */
164 #define H5O_FILL_MASK_ALLOC_TIME        0x03
165 #define H5O_FILL_SHIFT_ALLOC_TIME       0
166 #define H5O_FILL_MASK_FILL_TIME         0x03
167 #define H5O_FILL_SHIFT_FILL_TIME        2
168 #define H5O_FILL_FLAG_UNDEFINED_VALUE   0x10
169 #define H5O_FILL_FLAG_HAVE_VALUE        0x20
170 #define H5O_FILL_FLAGS_ALL              (H5O_FILL_MASK_ALLOC_TIME | (H5O_FILL_MASK_FILL_TIME << H5O_FILL_SHIFT_FILL_TIME) | H5O_FILL_FLAG_UNDEFINED_VALUE | H5O_FILL_FLAG_HAVE_VALUE)
171 
172 /* Declare a free list to manage the H5O_fill_t struct */
173 H5FL_DEFINE(H5O_fill_t);
174 
175 /* Declare extern the free list to manage blocks of type conversion data */
176 H5FL_BLK_EXTERN(type_conv);
177 
178 
179 /*-------------------------------------------------------------------------
180  * Function:    H5O_fill_new_decode
181  *
182  * Purpose:    Decode a new fill value message.  The new fill value
183  *          message is fill value plus space allocation time and
184  *          fill value writing time and whether fill value is defined.
185  *
186  * Return:    Success:    Ptr to new message in native struct.
187  *          Failure:    NULL
188  *
189  * Programmer:  Raymond Lu
190  *              Feb 26, 2002
191  *
192  *-------------------------------------------------------------------------
193  */
194 static void *
H5O_fill_new_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)195 H5O_fill_new_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh,
196     unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags,
197     size_t p_size, const uint8_t *p)
198 {
199     H5O_fill_t    *fill = NULL;
200     void *ret_value = NULL;     /* Return value */
201 
202     FUNC_ENTER_NOAPI_NOINIT
203 
204     HDassert(f);
205     HDassert(p);
206 
207     if(NULL == (fill = H5FL_CALLOC(H5O_fill_t)))
208         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message")
209 
210     /* Version */
211     fill->version = *p++;
212     if(fill->version < H5O_FILL_VERSION_1 || fill->version > H5O_FILL_VERSION_LATEST)
213         HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for fill value message")
214 
215     /* Decode each version */
216     if(fill->version < H5O_FILL_VERSION_3) {
217         /* Space allocation time */
218         fill->alloc_time = (H5D_alloc_time_t)*p++;
219 
220         /* Fill value write time */
221         fill->fill_time = (H5D_fill_time_t)*p++;
222 
223         /* Whether fill value is defined */
224         fill->fill_defined = *p++;
225 
226         /* Only decode fill value information if one is defined */
227         if(fill->fill_defined) {
228             INT32DECODE(p, fill->size);
229             if(fill->size > 0) {
230                 H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t);
231                 if((size_t)fill->size > p_size)
232                     HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "destination buffer too small")
233                 if(NULL == (fill->buf = H5MM_malloc((size_t)fill->size)))
234                     HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value")
235                 HDmemcpy(fill->buf, p, (size_t)fill->size);
236             } /* end if */
237         } /* end if */
238         else
239             fill->size = (-1);
240     } /* end if */
241     else {
242         unsigned flags;          /* Status flags */
243 
244         /* Flags */
245         flags = *p++;
246 
247         /* Check for unknown flags */
248         if(flags & (unsigned)~H5O_FILL_FLAGS_ALL)
249             HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown flag for fill value message")
250 
251         /* Space allocation time */
252         fill->alloc_time = (H5D_alloc_time_t)((flags >> H5O_FILL_SHIFT_ALLOC_TIME) & H5O_FILL_MASK_ALLOC_TIME);
253 
254         /* Fill value write time */
255         fill->fill_time = (H5D_fill_time_t)((flags >> H5O_FILL_SHIFT_FILL_TIME) & H5O_FILL_MASK_FILL_TIME);
256 
257         /* Check for undefined fill value */
258         if(flags & H5O_FILL_FLAG_UNDEFINED_VALUE) {
259             /* Sanity check */
260             HDassert(!(flags & H5O_FILL_FLAG_HAVE_VALUE));
261 
262             /* Set value for "undefined" fill value */
263             fill->size = (-1);
264         } /* end if */
265         else if(flags & H5O_FILL_FLAG_HAVE_VALUE) {
266             /* Fill value size */
267             UINT32DECODE(p, fill->size);
268 
269             /* Fill value */
270             H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t);
271             if(NULL == (fill->buf = H5MM_malloc((size_t)fill->size)))
272                 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value")
273             HDmemcpy(fill->buf, p, (size_t)fill->size);
274 
275             /* Set the "defined" flag */
276             fill->fill_defined = TRUE;
277         } /* end else */
278         else {
279             /* Set the "defined" flag */
280             fill->fill_defined = TRUE;
281         } /* end else */
282     } /* end else */
283 
284     /* Set return value */
285     ret_value = (void *)fill;
286 
287 done:
288     if(!ret_value && fill) {
289         if(fill->buf)
290             H5MM_xfree(fill->buf);
291         fill = H5FL_FREE(H5O_fill_t, fill);
292     } /* end if */
293 
294     FUNC_LEAVE_NOAPI(ret_value)
295 } /* end H5O_fill_new_decode() */
296 
297 
298 /*-------------------------------------------------------------------------
299  * Function:    H5O_fill_old_decode
300  *
301  * Purpose:     Decode an old fill value message.
302  *
303  * Return:      Success:        Ptr to new message in native struct.
304  *              Failure:        NULL
305  *
306  * Programmer:  Robb Matzke
307  *              Wednesday, September 30, 1998
308  *
309  *-------------------------------------------------------------------------
310  */
311 static void *
H5O_fill_old_decode(H5F_t * f,H5O_t * open_oh,unsigned H5_ATTR_UNUSED mesg_flags,unsigned H5_ATTR_UNUSED * ioflags,size_t p_size,const uint8_t * p)312 H5O_fill_old_decode(H5F_t *f, H5O_t *open_oh,
313     unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags,
314     size_t p_size, const uint8_t *p)
315 {
316     H5O_fill_t *fill = NULL;    /* Decoded fill value message */
317     htri_t exists = FALSE;
318     H5T_t *dt = NULL;
319     void *ret_value = NULL;     /* Return value */
320 
321     FUNC_ENTER_NOAPI_NOINIT
322 
323     HDassert(f);
324     HDassert(p);
325 
326     if(NULL == (fill = H5FL_CALLOC(H5O_fill_t)))
327         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message")
328 
329     /* Set non-zero default fields */
330     fill->version = H5O_FILL_VERSION_2;
331     fill->alloc_time = H5D_ALLOC_TIME_LATE;
332     fill->fill_time = H5D_FILL_TIME_IFSET;
333 
334     /* Fill value size */
335     UINT32DECODE(p, fill->size);
336 
337     /* Only decode the fill value itself if there is one */
338     if(fill->size > 0) {
339         H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t);
340         if((size_t)fill->size > p_size)
341             HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "destination buffer too small")
342 
343         /* Get the datatype message  */
344         if((exists = H5O_msg_exists_oh(open_oh, H5O_DTYPE_ID)) < 0)
345             HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read object header")
346         if(exists) {
347             if((dt = H5O_msg_read_oh(f, open_oh, H5O_DTYPE_ID, NULL)) < 0)
348                 HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't read DTYPE message")
349             /* Verify size */
350             if(fill->size != H5T_GET_SIZE(dt))
351                 HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "inconsistent fill value size")
352         }
353 
354         if(NULL == (fill->buf = H5MM_malloc((size_t)fill->size)))
355             HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value")
356         HDmemcpy(fill->buf, p, (size_t)fill->size);
357         fill->fill_defined = TRUE;
358     } /* end if */
359     else
360         fill->size = (-1);
361 
362     /* Set return value */
363     ret_value = (void*)fill;
364 
365 done:
366     if(dt)
367         H5O_msg_free(H5O_DTYPE_ID, dt);
368 
369     if(!ret_value && fill) {
370         if(fill->buf)
371             H5MM_xfree(fill->buf);
372         fill = H5FL_FREE(H5O_fill_t, fill);
373     } /* end if */
374 
375     FUNC_LEAVE_NOAPI(ret_value)
376 } /* end H5O_fill_old_decode() */
377 
378 
379 /*-------------------------------------------------------------------------
380  * Function:    H5O_fill_new_encode
381  *
382  * Purpose:    Encode a new fill value message.  The new fill value
383  *          message is fill value plus space allocation time and
384  *          fill value writing time and whether fill value is defined.
385  *
386  * Return:    Non-negative on success/Negative on failure
387  *
388  * Programmer:  Raymond Lu
389  *              Feb 26, 2002
390  *
391  *-------------------------------------------------------------------------
392  */
393 static herr_t
H5O_fill_new_encode(H5F_t H5_ATTR_UNUSED * f,uint8_t * p,const void * _fill)394 H5O_fill_new_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p, const void *_fill)
395 {
396     const H5O_fill_t    *fill = (const H5O_fill_t *)_fill;
397 
398     FUNC_ENTER_NOAPI_NOINIT_NOERR
399 
400     HDassert(f);
401     HDassert(p);
402     HDassert(fill && NULL == fill->type);
403 
404     /* Version */
405     *p++ = (uint8_t)fill->version;
406 
407     if(fill->version < H5O_FILL_VERSION_3) {
408         /* Space allocation time */
409         *p++ = fill->alloc_time;
410 
411         /* Fill value writing time */
412         *p++ = fill->fill_time;
413 
414         /* Whether fill value is defined */
415         *p++ = (uint8_t)fill->fill_defined;
416 
417         /* Only write out the size and fill value if it is defined */
418         if(fill->fill_defined) {
419             UINT32ENCODE(p, fill->size);
420             if(fill->size > 0)
421                 if(fill->buf) {
422                     H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t);
423                     HDmemcpy(p, fill->buf, (size_t)fill->size);
424                 } /* end if */
425         } /* end if */
426     } /* end if */
427     else {
428         uint8_t flags = 0;      /* Fill value setting flags */
429 
430         /* Encode space allocation time */
431         HDassert(fill->alloc_time == (H5O_FILL_MASK_ALLOC_TIME & fill->alloc_time));
432         flags = (uint8_t)(flags | ((H5O_FILL_MASK_ALLOC_TIME & fill->alloc_time) << H5O_FILL_SHIFT_ALLOC_TIME));
433 
434         /* Encode fill value writing time */
435         HDassert(fill->fill_time == (H5O_FILL_MASK_FILL_TIME & fill->fill_time));
436         flags = (uint8_t)(flags | ((H5O_FILL_MASK_FILL_TIME & fill->fill_time) << H5O_FILL_SHIFT_FILL_TIME));
437 
438         /* Check if we need to encode a fill value size */
439         if(fill->size < 0) {
440             /* Indicate that the fill value has been "undefined" by the user */
441             flags |= H5O_FILL_FLAG_UNDEFINED_VALUE;
442 
443             /* Flags */
444             *p++ = (uint8_t)flags;
445 
446             /* Sanity check */
447             HDassert(!fill->buf);
448         } /* end if */
449         else if(fill->size > 0) {
450             /* Indicate that a fill value size is present */
451             flags |= H5O_FILL_FLAG_HAVE_VALUE;
452 
453             /* Flags */
454             *p++ = (uint8_t)flags;
455 
456             /* Encode the size of fill value */
457             INT32ENCODE(p, fill->size);
458 
459             /* Encode the fill value */
460             HDassert(fill->buf);
461             H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t);
462             HDmemcpy(p, fill->buf, (size_t)fill->size);
463         } /* end if */
464         else {
465             /* Flags */
466             *p++ = (uint8_t)flags;
467 
468             /* Sanity check */
469             HDassert(!fill->buf);
470         } /* end else */
471     } /* end else */
472 
473     FUNC_LEAVE_NOAPI(SUCCEED)
474 } /* end H5O_fill_new_encode() */
475 
476 
477 /*-------------------------------------------------------------------------
478  * Function:    H5O_fill_old_encode
479  *
480  * Purpose:     Encode an old fill value message.
481  *
482  * Return:      Non-negative on success/Negative on failure
483  *
484  * Programmer:  Robb Matzke
485  *              Thursday, October  1, 1998
486  *
487  *-------------------------------------------------------------------------
488  */
489 static herr_t
H5O_fill_old_encode(H5F_t H5_ATTR_UNUSED * f,uint8_t * p,const void * _fill)490 H5O_fill_old_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p, const void *_fill)
491 {
492     const H5O_fill_t *fill = (const H5O_fill_t *)_fill;
493 
494     FUNC_ENTER_NOAPI_NOINIT_NOERR
495 
496     HDassert(f);
497     HDassert(p);
498     HDassert(fill && NULL == fill->type);
499 
500     UINT32ENCODE(p, fill->size);
501     if(fill->buf)
502         HDmemcpy(p, fill->buf, (size_t)fill->size);
503 
504     FUNC_LEAVE_NOAPI(SUCCEED)
505 } /* end H5O_fill_old_encode() */
506 
507 
508 /*-------------------------------------------------------------------------
509  * Function:    H5O_fill_copy
510  *
511  * Purpose:    Copies a message from _MESG to _DEST, allocating _DEST if
512  *        necessary.  The new fill value message is fill value plus
513  *        space allocation time and fill value writing time and
514  *        whether fill value is defined.
515  *
516  * Return:    Success:    Ptr to _DEST
517  *            Failure:    NULL
518  *
519  * Programmer:  Raymond Lu
520  *              Feb 26, 2002
521  *
522  *-------------------------------------------------------------------------
523  */
524 static void *
H5O_fill_copy(const void * _src,void * _dst)525 H5O_fill_copy(const void *_src, void *_dst)
526 {
527     const H5O_fill_t    *src = (const H5O_fill_t *)_src;
528     H5O_fill_t          *dst = (H5O_fill_t *)_dst;
529     void                *ret_value = NULL;      /* Return value */
530 
531     FUNC_ENTER_NOAPI_NOINIT
532 
533     HDassert(src);
534 
535     if(!dst && NULL == (dst = H5FL_MALLOC(H5O_fill_t)))
536         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill message")
537 
538     /* Shallow copy basic fields */
539     *dst = *src;
540 
541     /* Copy data type of fill value */
542     if(src->type) {
543         if(NULL == (dst->type = H5T_copy(src->type, H5T_COPY_TRANSIENT)))
544             HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "can't copy datatype")
545     } /* end if */
546     else
547         dst->type = NULL;
548 
549     /* Copy fill value and its size */
550     if(src->buf) {
551         H5_CHECK_OVERFLOW(src->size, ssize_t, size_t);
552         if(NULL == (dst->buf = H5MM_malloc((size_t)src->size)))
553             HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value")
554         HDmemcpy(dst->buf, src->buf, (size_t)src->size);
555 
556         /* Check for needing to convert/copy fill value */
557         if(src->type) {
558             H5T_path_t *tpath;      /* Conversion information */
559 
560             /* Set up type conversion function */
561             if(NULL == (tpath = H5T_path_find(src->type, dst->type)))
562                 HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, NULL, "unable to convert between src and dst data types")
563 
564             /* If necessary, convert fill value datatypes (which copies VL components, etc.) */
565             if(!H5T_path_noop(tpath)) {
566                 hid_t dst_id, src_id;       /* Source & destination datatypes for type conversion */
567                 uint8_t *bkg_buf = NULL;    /* Background conversion buffer */
568                 size_t bkg_size;            /* Size of background buffer */
569 
570                 /* Wrap copies of types to convert */
571                 dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->type, H5T_COPY_TRANSIENT), FALSE);
572                 if(dst_id < 0)
573                     HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy/register datatype")
574                 src_id = H5I_register(H5I_DATATYPE, H5T_copy(src->type, H5T_COPY_ALL), FALSE);
575                 if(src_id < 0) {
576                     H5I_dec_ref(dst_id);
577                     HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy/register datatype")
578                 } /* end if */
579 
580                 /* Allocate a background buffer */
581                 bkg_size = MAX(H5T_get_size(dst->type), H5T_get_size(src->type));
582                 if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, bkg_size))) {
583                     H5I_dec_ref(src_id);
584                     H5I_dec_ref(dst_id);
585                     HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
586                 } /* end if */
587 
588                 /* Convert fill value */
589                 if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, dst->buf, bkg_buf) < 0) {
590                     H5I_dec_ref(src_id);
591                     H5I_dec_ref(dst_id);
592                     if(bkg_buf)
593                         bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf);
594                     HGOTO_ERROR(H5E_OHDR, H5E_CANTCONVERT, NULL, "datatype conversion failed")
595                 } /* end if */
596 
597                 /* Release the background buffer */
598                 H5I_dec_ref(src_id);
599                 H5I_dec_ref(dst_id);
600                 if(bkg_buf)
601                     bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf);
602             } /* end if */
603         } /* end if */
604     } /* end if */
605     else
606         dst->buf = NULL;
607 
608     /* Set return value */
609     ret_value = dst;
610 
611 done:
612     if(!ret_value && dst) {
613         if(dst->buf)
614             H5MM_xfree(dst->buf);
615         if(dst->type)
616             (void)H5T_close_real(dst->type);
617         if(!_dst)
618             dst = H5FL_FREE(H5O_fill_t, dst);
619     } /* end if */
620 
621     FUNC_LEAVE_NOAPI(ret_value)
622 } /* end H5O_fill_copy() */
623 
624 
625 /*-------------------------------------------------------------------------
626  * Function:    H5O_fill_new_size
627  *
628  * Purpose:    Returns the size of the raw message in bytes not counting the
629  *          message type or size fields, but only the data fields.  This
630  *          function doesn't take into account alignment.  The new fill
631  *          value message is fill value plus space allocation time and
632  *          fill value writing time and whether fill value is defined.
633  *
634  * Return:    Success:    Message data size in bytes w/o alignment.
635  *          Failure:    0
636  *
637  * Programmer:  Raymond Lu
638  *              Feb 26, 2002
639  *
640  *-------------------------------------------------------------------------
641  */
642 static size_t
H5O_fill_new_size(const H5F_t H5_ATTR_UNUSED * f,const void * _fill)643 H5O_fill_new_size(const H5F_t H5_ATTR_UNUSED *f, const void *_fill)
644 {
645     const H5O_fill_t    *fill = (const H5O_fill_t *)_fill;
646     size_t              ret_value = 0;          /* Return value */
647 
648     FUNC_ENTER_NOAPI_NOINIT_NOERR
649 
650     HDassert(f);
651     HDassert(fill);
652 
653     /* Determine size for different versions */
654     if(fill->version < H5O_FILL_VERSION_3) {
655         ret_value = 1 +             /* Version number        */
656                     1 +         /* Space allocation time */
657                     1 +         /* Fill value write time */
658                     1;             /* Fill value defined    */
659         if(fill->fill_defined)
660             ret_value += 4 +    /* Fill value size     */
661                     (fill->size > 0 ? (size_t)fill->size : 0);    /* Size of fill value     */
662     } /* end if */
663     else {
664         ret_value = 1 +             /* Version number        */
665                     1;            /* Status flags          */
666         if(fill->size > 0)
667             ret_value += 4 +        /* Fill value size     */
668                     (size_t)fill->size;        /* Size of fill value     */
669     } /* end else */
670 
671     FUNC_LEAVE_NOAPI(ret_value)
672 } /* end H5O_fill_new_size() */
673 
674 
675 /*-------------------------------------------------------------------------
676  * Function:    H5O_fill_old_size
677  *
678  * Purpose:     Returns the size of the raw message in bytes not counting the
679  *              message type or size fields, but only the data fields.  This
680  *              function doesn't take into account alignment.
681  *
682  * Return:      Success:        Message data size in bytes w/o alignment.
683  *              Failure:        0
684  *
685  * Programmer:  Robb Matzke
686  *              Thursday, October  1, 1998
687  *
688  *-------------------------------------------------------------------------
689  */
690 static size_t
H5O_fill_old_size(const H5F_t H5_ATTR_UNUSED * f,const void * _fill)691 H5O_fill_old_size(const H5F_t H5_ATTR_UNUSED *f, const void *_fill)
692 {
693     const H5O_fill_t *fill = (const H5O_fill_t *)_fill;
694 
695     FUNC_ENTER_NOAPI_NOINIT_NOERR
696 
697     HDassert(fill);
698 
699     FUNC_LEAVE_NOAPI(4 + (size_t)fill->size)
700 } /* end H5O_fill_old_size() */
701 
702 
703 /*-------------------------------------------------------------------------
704  * Function:    H5O_fill_reset_dyn
705  *
706  * Purpose:    Resets dynamic fill value fields
707  *
708  * Return:    Non-negative on success/Negative on failure
709  *
710  * Programmer:    Quincey Koziol
711  *              Monday, January 22, 2007
712  *
713  *-------------------------------------------------------------------------
714  */
715 herr_t
H5O_fill_reset_dyn(H5O_fill_t * fill)716 H5O_fill_reset_dyn(H5O_fill_t *fill)
717 {
718     hid_t fill_type_id = -1;            /* Datatype ID for fill value datatype when reclaiming VL fill values */
719     herr_t ret_value = SUCCEED;         /* Return value */
720 
721     FUNC_ENTER_NOAPI(FAIL)
722 
723     HDassert(fill);
724 
725     if(fill->buf) {
726         if(fill->type && H5T_detect_class(fill->type, H5T_VLEN, FALSE) > 0) {
727             H5T_t *fill_type;           /* Copy of fill value datatype */
728             H5S_t *fill_space;          /* Scalar dataspace for fill value element */
729 
730             /* Copy the fill value datatype and get an ID for it */
731             if(NULL == (fill_type = H5T_copy(fill->type, H5T_COPY_TRANSIENT)))
732                 HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy fill value datatype")
733             if((fill_type_id = H5I_register(H5I_DATATYPE, fill_type, FALSE)) < 0) {
734                 (void)H5T_close_real(fill_type);
735                 HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, FAIL, "unable to register fill value datatype")
736             } /* end if */
737 
738             /* Create a scalar dataspace for the fill value element */
739             if(NULL == (fill_space = H5S_create(H5S_SCALAR)))
740                 HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create scalar dataspace")
741 
742             /* Reclaim any variable length components of the fill value */
743             if(H5D_vlen_reclaim(fill_type_id, fill_space, fill->buf) < 0) {
744                 H5S_close(fill_space);
745                 HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to reclaim variable-length fill value data")
746             } /* end if */
747 
748             /* Release the scalar fill value dataspace */
749             H5S_close(fill_space);
750         } /* end if */
751 
752         /* Release the fill value buffer now */
753         fill->buf = H5MM_xfree(fill->buf);
754     } /* end if */
755     fill->size = 0;
756     if(fill->type) {
757     (void)H5T_close_real(fill->type);
758     fill->type = NULL;
759     } /* end if */
760 
761 done:
762     if(fill_type_id > 0 && H5I_dec_ref(fill_type_id) < 0)
763         HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement ref count for temp ID")
764 
765     FUNC_LEAVE_NOAPI(ret_value)
766 } /* end H5O_fill_reset_dyn() */
767 
768 
769 /*-------------------------------------------------------------------------
770  * Function:    H5O__fill_reset
771  *
772  * Purpose:    Resets a message to an initial state.
773  *
774  * Return:    Non-negative on success/Negative on failure
775  *
776  * Programmer:    Robb Matzke
777  *              Thursday, October  1, 1998
778  *
779  *-------------------------------------------------------------------------
780  */
781 static herr_t
H5O__fill_reset(void * _fill)782 H5O__fill_reset(void *_fill)
783 {
784     H5O_fill_t    *fill = (H5O_fill_t *)_fill;
785 
786     FUNC_ENTER_STATIC_NOERR
787 
788     HDassert(fill);
789 
790     /* Reset dynamic fields */
791     H5O_fill_reset_dyn(fill);
792 
793     /* Reset value fields */
794     fill->alloc_time   = H5D_ALLOC_TIME_LATE;
795     fill->fill_time    = H5D_FILL_TIME_IFSET;
796     fill->fill_defined = FALSE;
797 
798     FUNC_LEAVE_NOAPI(SUCCEED)
799 } /* end H5O__fill_reset() */
800 
801 
802 /*-------------------------------------------------------------------------
803  * Function:    H5O__fill_free
804  *
805  * Purpose:    Frees the message
806  *
807  * Return:    Non-negative on success/Negative on failure
808  *
809  * Programmer:    Quincey Koziol
810  *              Thursday, December 5, 2002
811  *
812  *-------------------------------------------------------------------------
813  */
814 static herr_t
H5O__fill_free(void * fill)815 H5O__fill_free(void *fill)
816 {
817     FUNC_ENTER_STATIC_NOERR
818 
819     HDassert(fill);
820 
821     fill = H5FL_FREE(H5O_fill_t, fill);
822 
823     FUNC_LEAVE_NOAPI(SUCCEED)
824 } /* end H5O__fill_free() */
825 
826 
827 /*-------------------------------------------------------------------------
828  * Function:    H5O__fill_pre_copy_file
829  *
830  * Purpose:     Perform any necessary actions before copying message between
831  *              files.
832  *
833  * Return:      Success:        Non-negative
834  *              Failure:        Negative
835  *
836  * Programmer:  Vailin Choi; Dec 2017
837  *
838  *-------------------------------------------------------------------------
839  */
840 static herr_t
H5O__fill_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 H5_ATTR_UNUSED * udata)841 H5O__fill_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *mesg_src,
842     hbool_t H5_ATTR_UNUSED *deleted, const H5O_copy_t *cpy_info, void H5_ATTR_UNUSED *udata)
843 {
844     const H5O_fill_t    *fill_src = (const H5O_fill_t *)mesg_src;   /* Source fill value */
845     herr_t ret_value = SUCCEED;   /* Return value */
846 
847     FUNC_ENTER_STATIC
848 
849     /* check args */
850     HDassert(cpy_info);
851     HDassert(cpy_info->file_dst);
852 
853     /* Check to ensure that the version of the message to be copied does not exceed
854        the message version allowed by the destination file's high bound */
855     if(fill_src->version > H5O_fill_ver_bounds[H5F_HIGH_BOUND(cpy_info->file_dst)])
856         HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "fill value message version out of bounds")
857 
858 done:
859     FUNC_LEAVE_NOAPI(ret_value)
860 } /* end H5O__fill_pre_copy_file() */
861 
862 
863 /*-------------------------------------------------------------------------
864  * Function:    H5O__fill_debug
865  *
866  * Purpose:    Prints debugging info for the message.
867  *
868  * Return:    Non-negative on success/Negative on failure
869  *
870  * Programmer:    Robb Matzke
871  *              Thursday, October  1, 1998
872  *
873  *-------------------------------------------------------------------------
874  */
875 static herr_t
H5O__fill_debug(H5F_t H5_ATTR_UNUSED * f,const void * _fill,FILE * stream,int indent,int fwidth)876 H5O__fill_debug(H5F_t H5_ATTR_UNUSED *f, const void *_fill, FILE *stream,
877     int indent, int fwidth)
878 {
879     const H5O_fill_t *fill = (const H5O_fill_t *)_fill;
880     H5D_fill_value_t fill_status;       /* Whether the fill value is defined */
881 
882     FUNC_ENTER_STATIC_NOERR
883 
884     HDassert(f);
885     HDassert(fill);
886     HDassert(stream);
887     HDassert(indent >= 0);
888     HDassert(fwidth >= 0);
889 
890     HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Space Allocation Time:");
891     switch(fill->alloc_time) {
892         case H5D_ALLOC_TIME_EARLY:
893             HDfprintf(stream,"Early\n");
894             break;
895 
896         case H5D_ALLOC_TIME_LATE:
897             HDfprintf(stream,"Late\n");
898             break;
899 
900         case H5D_ALLOC_TIME_INCR:
901             HDfprintf(stream,"Incremental\n");
902             break;
903 
904         case H5D_ALLOC_TIME_DEFAULT:
905         case H5D_ALLOC_TIME_ERROR:
906         default:
907             HDfprintf(stream,"Unknown!\n");
908             break;
909     } /* end switch */
910     HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Fill Time:");
911     switch(fill->fill_time) {
912         case H5D_FILL_TIME_ALLOC:
913             HDfprintf(stream,"On Allocation\n");
914             break;
915 
916         case H5D_FILL_TIME_NEVER:
917             HDfprintf(stream,"Never\n");
918             break;
919 
920         case H5D_FILL_TIME_IFSET:
921             HDfprintf(stream,"If Set\n");
922             break;
923 
924         case H5D_FILL_TIME_ERROR:
925         default:
926             HDfprintf(stream,"Unknown!\n");
927             break;
928 
929     } /* end switch */
930     HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Fill Value Defined:");
931     H5P_is_fill_value_defined((const H5O_fill_t *)fill, &fill_status);
932     switch(fill_status) {
933         case H5D_FILL_VALUE_UNDEFINED:
934             HDfprintf(stream,"Undefined\n");
935             break;
936 
937         case H5D_FILL_VALUE_DEFAULT:
938             HDfprintf(stream,"Default\n");
939             break;
940 
941         case H5D_FILL_VALUE_USER_DEFINED:
942             HDfprintf(stream,"User Defined\n");
943             break;
944 
945         case H5D_FILL_VALUE_ERROR:
946         default:
947             HDfprintf(stream,"Unknown!\n");
948             break;
949 
950     } /* end switch */
951     HDfprintf(stream, "%*s%-*s %Zd\n", indent, "", fwidth,
952         "Size:", fill->size);
953     HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Data type:");
954     if(fill->type) {
955         H5T_debug(fill->type, stream);
956         HDfprintf(stream, "\n");
957     } /* end if */
958     else
959         HDfprintf(stream, "<dataset type>\n");
960 
961     FUNC_LEAVE_NOAPI(SUCCEED)
962 } /* end H5O__fill_debug() */
963 
964 
965 /*-------------------------------------------------------------------------
966  * Function:    H5O_fill_convert
967  *
968  * Purpose:    Convert a fill value from whatever data type it currently has
969  *          to the specified dataset type.  The `type' field of the fill
970  *          value struct will be set to NULL to indicate that it has the
971  *          same type as the dataset.
972  *
973  * Return:    Non-negative on success/Negative on failure
974  *
975  * Programmer:    Robb Matzke
976  *              Thursday, October  1, 1998
977  *
978  *-------------------------------------------------------------------------
979  */
980 herr_t
H5O_fill_convert(H5O_fill_t * fill,H5T_t * dset_type,hbool_t * fill_changed)981 H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type, hbool_t *fill_changed)
982 {
983     H5T_path_t        *tpath;                /* Type conversion info    */
984     void        *buf = NULL, *bkg = NULL;   /* Conversion buffers    */
985     hid_t        src_id = -1, dst_id = -1;   /* Datatype identifiers    */
986     herr_t          ret_value = SUCCEED;        /* Return value */
987 
988     FUNC_ENTER_NOAPI_NOINIT
989 
990     HDassert(fill);
991     HDassert(dset_type);
992     HDassert(fill_changed);
993 
994     /* No-op cases */
995     if(!fill->buf || !fill->type || 0 == H5T_cmp(fill->type, dset_type, FALSE)) {
996         /* Don't need datatype for fill value */
997         if(fill->type)
998             (void)H5T_close_real(fill->type);
999         fill->type = NULL;
1000 
1001         /* Note that the fill value info has changed */
1002         *fill_changed = TRUE;
1003 
1004         HGOTO_DONE(SUCCEED);
1005     } /* end if */
1006 
1007     /*
1008      * Can we convert between source and destination data types?
1009      */
1010     if(NULL == (tpath = H5T_path_find(fill->type, dset_type)))
1011     HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to convert between src and dst datatypes")
1012 
1013     /* Don't bother doing anything if there will be no actual conversion */
1014     if(!H5T_path_noop(tpath)) {
1015         if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill->type, H5T_COPY_ALL), FALSE)) < 0 ||
1016                 (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dset_type, H5T_COPY_ALL), FALSE)) < 0)
1017             HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy/register data type")
1018 
1019         /*
1020          * Datatype conversions are always done in place, so we need a buffer
1021          * that is large enough for both source and destination.
1022          */
1023         if(H5T_get_size(fill->type) >= H5T_get_size(dset_type))
1024             buf = fill->buf;
1025         else {
1026             if(NULL == (buf = H5MM_malloc(H5T_get_size(dset_type))))
1027                 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
1028             HDmemcpy(buf, fill->buf, H5T_get_size(fill->type));
1029         } /* end else */
1030 
1031         /* Use CALLOC here to clear the buffer in case later the library thinks there's
1032          * data in the background. */
1033         if(H5T_path_bkg(tpath) && NULL == (bkg = H5MM_calloc(H5T_get_size(dset_type))))
1034             HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
1035 
1036         /* Do the conversion */
1037         if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, buf, bkg) < 0)
1038             HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "datatype conversion failed")
1039 
1040         /* Update the fill message */
1041         if(buf != fill->buf) {
1042             H5T_vlen_reclaim_elmt(fill->buf, fill->type);
1043             H5MM_xfree(fill->buf);
1044             fill->buf = buf;
1045         } /* end if */
1046         (void)H5T_close_real(fill->type);
1047         fill->type = NULL;
1048         H5_CHECKED_ASSIGN(fill->size, ssize_t, H5T_get_size(dset_type), size_t);
1049 
1050         /* Note that the fill value info has changed */
1051         *fill_changed = TRUE;
1052     } /* end if */
1053 
1054 done:
1055     if(src_id >= 0 && H5I_dec_ref(src_id) < 0)
1056         HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement ref count for temp ID")
1057     if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0)
1058         HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement ref count for temp ID")
1059     if(buf != fill->buf)
1060         H5MM_xfree(buf);
1061     if(bkg)
1062         H5MM_xfree(bkg);
1063 
1064     FUNC_LEAVE_NOAPI(ret_value)
1065 } /* end H5O_fill_convert() */
1066 
1067 
1068 /*-------------------------------------------------------------------------
1069  * Function:    H5O_fill_set_version
1070  *
1071  * Purpose:     Set the version to encode a fill value with.
1072  *
1073  * Return:      Non-negative on success/Negative on failure
1074  *
1075  * Programmer:  Vailin Choi; December 2017
1076  *
1077  *-------------------------------------------------------------------------
1078  */
1079 herr_t
H5O_fill_set_version(H5F_t * f,H5O_fill_t * fill)1080 H5O_fill_set_version(H5F_t *f, H5O_fill_t *fill)
1081 {
1082     unsigned version;           /* Message version */
1083     herr_t ret_value = SUCCEED; /* Return value */
1084 
1085     FUNC_ENTER_NOAPI(FAIL)
1086 
1087     /* Sanity check */
1088     HDassert(f);
1089     HDassert(fill);
1090 
1091     /* Upgrade to the version indicated by the file's low bound if higher */
1092     version = MAX(fill->version, H5O_fill_ver_bounds[H5F_LOW_BOUND(f)]);
1093 
1094     /* Version bounds check */
1095     if(version > H5O_fill_ver_bounds[H5F_HIGH_BOUND(f)])
1096         HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "Filter pipeline version out of bounds")
1097 
1098     /* Set the message version */
1099     fill->version = version;
1100 
1101 done:
1102     FUNC_LEAVE_NOAPI(ret_value)
1103 } /* end H5O_fill_set_version() */
1104 
1105