Coverage Report

Created: 2024-06-18 06:29

/src/hdf5/src/H5Oginfo.c
Line
Count
Source (jump to first uncovered line)
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 COPYING 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
 *
15
 * Created:             H5Oginfo.c
16
 *
17
 * Purpose:             Group Information messages
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
#include "H5Omodule.h" /* This source code file is part of the H5O module */
23
24
#include "H5private.h"   /* Generic Functions     */
25
#include "H5Eprivate.h"  /* Error handling        */
26
#include "H5FLprivate.h" /* Free lists                           */
27
#include "H5Opkg.h"      /* Object headers      */
28
29
/* PRIVATE PROTOTYPES */
30
static void  *H5O__ginfo_decode(H5F_t *f, H5O_t *open_oh, unsigned mesg_flags, unsigned *ioflags,
31
                                size_t p_size, const uint8_t *p);
32
static herr_t H5O__ginfo_encode(H5F_t *f, bool disable_shared, size_t H5_ATTR_UNUSED p_size, uint8_t *p,
33
                                const void *_mesg);
34
static void  *H5O__ginfo_copy(const void *_mesg, void *_dest);
35
static size_t H5O__ginfo_size(const H5F_t *f, bool disable_shared, const void *_mesg);
36
static herr_t H5O__ginfo_free(void *_mesg);
37
static herr_t H5O__ginfo_debug(H5F_t *f, const void *_mesg, FILE *stream, int indent, int fwidth);
38
39
/* This message derives from H5O message class */
40
const H5O_msg_class_t H5O_MSG_GINFO[1] = {{
41
    H5O_GINFO_ID,        /*message id number             */
42
    "ginfo",             /*message name for debugging    */
43
    sizeof(H5O_ginfo_t), /*native message size           */
44
    0,                   /* messages are shareable?       */
45
    H5O__ginfo_decode,   /*decode message                */
46
    H5O__ginfo_encode,   /*encode message                */
47
    H5O__ginfo_copy,     /*copy the native value         */
48
    H5O__ginfo_size,     /*size of symbol table entry    */
49
    NULL,                /*default reset method          */
50
    H5O__ginfo_free,     /* free method     */
51
    NULL,                /* file delete method    */
52
    NULL,                /* link method     */
53
    NULL,                /*set share method   */
54
    NULL,                /*can share method   */
55
    NULL,                /* pre copy native value to file */
56
    NULL,                /* copy native value to file    */
57
    NULL,                /* post copy native value to file    */
58
    NULL,                /* get creation index    */
59
    NULL,                /* set creation index    */
60
    H5O__ginfo_debug     /*debug the message             */
61
}};
62
63
/* Current version of group info information */
64
0
#define H5O_GINFO_VERSION 0
65
66
/* Flags for group info flag encoding */
67
0
#define H5O_GINFO_STORE_PHASE_CHANGE   0x01
68
0
#define H5O_GINFO_STORE_EST_ENTRY_INFO 0x02
69
0
#define H5O_GINFO_ALL_FLAGS            (H5O_GINFO_STORE_PHASE_CHANGE | H5O_GINFO_STORE_EST_ENTRY_INFO)
70
71
/* Declare a free list to manage the H5O_ginfo_t struct */
72
H5FL_DEFINE_STATIC(H5O_ginfo_t);
73
74
/*-------------------------------------------------------------------------
75
 * Function:    H5O__ginfo_decode
76
 *
77
 * Purpose:     Decode a message and return a pointer to
78
 *              a newly allocated one.
79
 *
80
 * Return:      Success:    Pointer to new message in native order
81
 *              Failure:    NULL
82
 *-------------------------------------------------------------------------
83
 */
84
static void *
85
H5O__ginfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags,
86
                  unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p)
87
0
{
88
0
    H5O_ginfo_t   *ginfo = NULL;               /* Pointer to group information message */
89
0
    unsigned char  flags;                      /* Flags for encoding group info */
90
0
    const uint8_t *p_end     = p + p_size - 1; /* End of the p buffer */
91
0
    void          *ret_value = NULL;
92
93
0
    FUNC_ENTER_PACKAGE
94
95
0
    assert(f);
96
0
    assert(p);
97
98
    /* Version of message */
99
0
    if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end))
100
0
        HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
101
0
    if (*p++ != H5O_GINFO_VERSION)
102
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message");
103
104
    /* Allocate space for message */
105
0
    if (NULL == (ginfo = H5FL_CALLOC(H5O_ginfo_t)))
106
0
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
107
108
    /* Get the flags for the group */
109
0
    if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end))
110
0
        HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
111
112
0
    flags = *p++;
113
0
    if (flags & ~H5O_GINFO_ALL_FLAGS)
114
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag value for message");
115
0
    ginfo->store_link_phase_change = (flags & H5O_GINFO_STORE_PHASE_CHANGE) ? true : false;
116
0
    ginfo->store_est_entry_info    = (flags & H5O_GINFO_STORE_EST_ENTRY_INFO) ? true : false;
117
118
    /* Get the max. # of links to store compactly & the min. # of links to store densely */
119
0
    if (ginfo->store_link_phase_change) {
120
0
        if (H5_IS_BUFFER_OVERFLOW(p, 2 * 2, p_end))
121
0
            HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
122
0
        UINT16DECODE(p, ginfo->max_compact);
123
0
        UINT16DECODE(p, ginfo->min_dense);
124
0
    }
125
0
    else {
126
0
        ginfo->max_compact = H5G_CRT_GINFO_MAX_COMPACT;
127
0
        ginfo->min_dense   = H5G_CRT_GINFO_MIN_DENSE;
128
0
    }
129
130
    /* Get the estimated # of entries & name lengths */
131
0
    if (ginfo->store_est_entry_info) {
132
0
        if (H5_IS_BUFFER_OVERFLOW(p, 2 * 2, p_end))
133
0
            HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
134
0
        UINT16DECODE(p, ginfo->est_num_entries);
135
0
        UINT16DECODE(p, ginfo->est_name_len);
136
0
    }
137
0
    else {
138
0
        ginfo->est_num_entries = H5G_CRT_GINFO_EST_NUM_ENTRIES;
139
0
        ginfo->est_name_len    = H5G_CRT_GINFO_EST_NAME_LEN;
140
0
    }
141
142
    /* Set return value */
143
0
    ret_value = ginfo;
144
145
0
done:
146
0
    if (!ret_value && ginfo)
147
0
        H5FL_FREE(H5O_ginfo_t, ginfo);
148
149
0
    FUNC_LEAVE_NOAPI(ret_value)
150
0
} /* end H5O__ginfo_decode() */
151
152
/*-------------------------------------------------------------------------
153
 * Function:    H5O__ginfo_encode
154
 *
155
 * Purpose:     Encodes a message.
156
 *
157
 * Return:      Non-negative on success/Negative on failure
158
 *
159
 *-------------------------------------------------------------------------
160
 */
161
static herr_t
162
H5O__ginfo_encode(H5F_t H5_ATTR_UNUSED *f, bool H5_ATTR_UNUSED disable_shared, size_t H5_ATTR_UNUSED p_size,
163
                  uint8_t *p, const void *_mesg)
164
0
{
165
0
    const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *)_mesg;
166
0
    unsigned char      flags = 0; /* Flags for encoding group info */
167
168
0
    FUNC_ENTER_PACKAGE_NOERR
169
170
    /* check args */
171
0
    assert(p);
172
0
    assert(ginfo);
173
174
    /* Message version */
175
0
    *p++ = H5O_GINFO_VERSION;
176
177
    /* The flags for the group info */
178
0
    flags = (unsigned char)(ginfo->store_link_phase_change ? H5O_GINFO_STORE_PHASE_CHANGE : 0);
179
0
    flags = (unsigned char)(flags | (ginfo->store_est_entry_info ? H5O_GINFO_STORE_EST_ENTRY_INFO : 0));
180
0
    *p++  = flags;
181
182
    /* Store the max. # of links to store compactly & the min. # of links to store densely */
183
0
    if (ginfo->store_link_phase_change) {
184
0
        UINT16ENCODE(p, ginfo->max_compact);
185
0
        UINT16ENCODE(p, ginfo->min_dense);
186
0
    } /* end if */
187
188
    /* Estimated # of entries & name lengths */
189
0
    if (ginfo->store_est_entry_info) {
190
0
        UINT16ENCODE(p, ginfo->est_num_entries);
191
0
        UINT16ENCODE(p, ginfo->est_name_len);
192
0
    } /* end if */
193
194
0
    FUNC_LEAVE_NOAPI(SUCCEED)
195
0
} /* end H5O__ginfo_encode() */
196
197
/*-------------------------------------------------------------------------
198
 * Function:    H5O__ginfo_copy
199
 *
200
 * Purpose:     Copies a message from _MESG to _DEST, allocating _DEST if
201
 *              necessary.
202
 *
203
 * Return:      Success:        Ptr to _DEST
204
 *
205
 *              Failure:        NULL
206
 *
207
 *-------------------------------------------------------------------------
208
 */
209
static void *
210
H5O__ginfo_copy(const void *_mesg, void *_dest)
211
0
{
212
0
    const H5O_ginfo_t *ginfo     = (const H5O_ginfo_t *)_mesg;
213
0
    H5O_ginfo_t       *dest      = (H5O_ginfo_t *)_dest;
214
0
    void              *ret_value = NULL; /* Return value */
215
216
0
    FUNC_ENTER_PACKAGE
217
218
    /* check args */
219
0
    assert(ginfo);
220
0
    if (!dest && NULL == (dest = H5FL_MALLOC(H5O_ginfo_t)))
221
0
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
222
223
    /* copy */
224
0
    *dest = *ginfo;
225
226
    /* Set return value */
227
0
    ret_value = dest;
228
229
0
done:
230
0
    FUNC_LEAVE_NOAPI(ret_value)
231
0
} /* end H5O__ginfo_copy() */
232
233
/*-------------------------------------------------------------------------
234
 * Function:    H5O__ginfo_size
235
 *
236
 * Purpose:     Returns the size of the raw message in bytes not counting
237
 *              the message type or size fields, but only the data fields.
238
 *              This function doesn't take into account alignment.
239
 *
240
 * Return:      Success:        Message data size in bytes without alignment.
241
 *
242
 *              Failure:        zero
243
 *
244
 *-------------------------------------------------------------------------
245
 */
246
static size_t
247
H5O__ginfo_size(const H5F_t H5_ATTR_UNUSED *f, bool H5_ATTR_UNUSED disable_shared, const void *_mesg)
248
0
{
249
0
    const H5O_ginfo_t *ginfo     = (const H5O_ginfo_t *)_mesg;
250
0
    size_t             ret_value = 0; /* Return value */
251
252
0
    FUNC_ENTER_PACKAGE_NOERR
253
254
    /* Set return value */
255
0
    ret_value = 1 +                                             /* Version */
256
0
                1 +                                             /* Flags */
257
0
                (ginfo->store_link_phase_change ? ((size_t)(2 + /* "Max compact" links */
258
0
                                                            2)  /* "Min dense" links */
259
0
                                                   )
260
0
                                                : 0) +       /* "Min dense" links */
261
0
                (ginfo->store_est_entry_info ? ((size_t)(2 + /* Estimated # of entries in group */
262
0
                                                         2)  /* Estimated length of name of entry in group */
263
0
                                                )
264
0
                                             : 0);
265
266
0
    FUNC_LEAVE_NOAPI(ret_value)
267
0
} /* end H5O__ginfo_size() */
268
269
/*-------------------------------------------------------------------------
270
 * Function:  H5O__ginfo_free
271
 *
272
 * Purpose: Frees the message
273
 *
274
 * Return:  Non-negative on success/Negative on failure
275
 *
276
 *-------------------------------------------------------------------------
277
 */
278
static herr_t
279
H5O__ginfo_free(void *mesg)
280
0
{
281
0
    FUNC_ENTER_PACKAGE_NOERR
282
283
0
    assert(mesg);
284
285
0
    mesg = H5FL_FREE(H5O_ginfo_t, mesg);
286
287
0
    FUNC_LEAVE_NOAPI(SUCCEED)
288
0
} /* end H5O__ginfo_free() */
289
290
/*-------------------------------------------------------------------------
291
 * Function:    H5O__ginfo_debug
292
 *
293
 * Purpose:     Prints debugging info for a message.
294
 *
295
 * Return:      Non-negative on success/Negative on failure
296
 *
297
 *-------------------------------------------------------------------------
298
 */
299
static herr_t
300
H5O__ginfo_debug(H5F_t H5_ATTR_UNUSED *f, const void *_mesg, FILE *stream, int indent, int fwidth)
301
0
{
302
0
    const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *)_mesg;
303
304
0
    FUNC_ENTER_PACKAGE_NOERR
305
306
    /* check args */
307
0
    assert(f);
308
0
    assert(ginfo);
309
0
    assert(stream);
310
0
    assert(indent >= 0);
311
0
    assert(fwidth >= 0);
312
313
0
    fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Max. compact links:", ginfo->max_compact);
314
0
    fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Min. dense links:", ginfo->min_dense);
315
0
    fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
316
0
            "Estimated # of objects in group:", ginfo->est_num_entries);
317
0
    fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
318
0
            "Estimated length of object in group's name:", ginfo->est_name_len);
319
320
0
    FUNC_LEAVE_NOAPI(SUCCEED)
321
0
} /* end H5O__ginfo_debug() */