Coverage Report

Created: 2026-01-08 06:16

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