Coverage Report

Created: 2025-08-28 06:37

/src/hdf5/src/H5EAtest.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 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: Extensible array testing functions.
15
 *
16
 */
17
18
/**********************/
19
/* Module Declaration */
20
/**********************/
21
22
#include "H5EAmodule.h" /* This source code file is part of the H5EA module */
23
#define H5EA_TESTING
24
25
/***********************/
26
/* Other Packages Used */
27
/***********************/
28
29
/***********/
30
/* Headers */
31
/***********/
32
#include "H5private.h"   /* Generic Functions     */
33
#include "H5Eprivate.h"  /* Error handling        */
34
#include "H5EApkg.h"     /* Extensible Arrays     */
35
#include "H5FLprivate.h" /* Free Lists                           */
36
#include "H5VMprivate.h" /* Vector functions      */
37
38
/****************/
39
/* Local Macros */
40
/****************/
41
42
/* Sanity checking value for callback contexts */
43
0
#define H5EA__TEST_BOGUS_VAL 42
44
45
/******************/
46
/* Local Typedefs */
47
/******************/
48
49
/* Callback context */
50
typedef struct H5EA__test_ctx_t {
51
    uint32_t        bogus; /* Placeholder field to verify that context is working */
52
    H5EA__ctx_cb_t *cb;    /* Pointer to context's callback action */
53
} H5EA__test_ctx_t;
54
55
/********************/
56
/* Package Typedefs */
57
/********************/
58
59
/********************/
60
/* Local Prototypes */
61
/********************/
62
63
/* Extensible array class callbacks */
64
static void  *H5EA__test_crt_context(void *udata);
65
static herr_t H5EA__test_dst_context(void *ctx);
66
static herr_t H5EA__test_fill(void *nat_blk, size_t nelmts);
67
static herr_t H5EA__test_encode(void *raw, const void *elmt, size_t nelmts, void *ctx);
68
static herr_t H5EA__test_decode(const void *raw, void *elmt, size_t nelmts, void *ctx);
69
static herr_t H5EA__test_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt);
70
static void  *H5EA__test_crt_dbg_context(H5F_t H5_ATTR_UNUSED *f, haddr_t H5_ATTR_UNUSED obj_addr);
71
static herr_t H5EA__test_dst_dbg_context(void *_ctx);
72
73
/*********************/
74
/* Package Variables */
75
/*********************/
76
77
/* Extensible array testing class information */
78
const H5EA_class_t H5EA_CLS_TEST[1] = {{
79
    H5EA_CLS_TEST_ID,           /* Type of Extensible array */
80
    "Testing",                  /* Name of Extensible Array class */
81
    sizeof(uint64_t),           /* Size of native element */
82
    H5EA__test_crt_context,     /* Create context */
83
    H5EA__test_dst_context,     /* Destroy context */
84
    H5EA__test_fill,            /* Fill block of missing elements callback */
85
    H5EA__test_encode,          /* Element encoding callback */
86
    H5EA__test_decode,          /* Element decoding callback */
87
    H5EA__test_debug,           /* Element debugging callback */
88
    H5EA__test_crt_dbg_context, /* Create debugging context */
89
    H5EA__test_dst_dbg_context  /* Destroy debugging context */
90
}};
91
92
/*****************************/
93
/* Library Private Variables */
94
/*****************************/
95
96
/*******************/
97
/* Local Variables */
98
/*******************/
99
100
/* Declare a free list to manage the H5EA__test_ctx_t struct */
101
H5FL_DEFINE_STATIC(H5EA__test_ctx_t);
102
103
/* Declare a free list to manage the H5EA__ctx_cb_t struct */
104
H5FL_DEFINE_STATIC(H5EA__ctx_cb_t);
105
106
/*-------------------------------------------------------------------------
107
 * Function:  H5EA__test_crt_context
108
 *
109
 * Purpose: Create context for callbacks
110
 *
111
 * Return:  Success:  non-NULL
112
 *    Failure:  NULL
113
 *
114
 *-------------------------------------------------------------------------
115
 */
116
static void *
117
H5EA__test_crt_context(void *_udata)
118
0
{
119
0
    H5EA__test_ctx_t *ctx;                                  /* Context for callbacks */
120
0
    H5EA__ctx_cb_t   *udata     = (H5EA__ctx_cb_t *)_udata; /* User data for context */
121
0
    void             *ret_value = NULL;
122
123
0
    FUNC_ENTER_PACKAGE
124
125
    /* Allocate new context structure */
126
0
    if (NULL == (ctx = H5FL_MALLOC(H5EA__test_ctx_t)))
127
0
        HGOTO_ERROR(H5E_EARRAY, H5E_CANTALLOC, NULL,
128
0
                    "can't allocate extensible array client callback context");
129
130
    /* Initialize the context */
131
0
    ctx->bogus = H5EA__TEST_BOGUS_VAL;
132
0
    ctx->cb    = udata;
133
134
    /* Set return value */
135
0
    ret_value = ctx;
136
137
0
done:
138
0
    FUNC_LEAVE_NOAPI(ret_value)
139
0
} /* end H5EA__test_crt_context() */
140
141
/*-------------------------------------------------------------------------
142
 * Function:  H5EA__test_dst_context
143
 *
144
 * Purpose: Destroy context for callbacks
145
 *
146
 * Return:  Success:  non-negative
147
 *    Failure:  negative
148
 *
149
 *-------------------------------------------------------------------------
150
 */
151
static herr_t
152
H5EA__test_dst_context(void *_ctx)
153
0
{
154
0
    H5EA__test_ctx_t *ctx = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */
155
156
0
    FUNC_ENTER_PACKAGE_NOERR
157
158
    /* Sanity checks */
159
0
    assert(H5EA__TEST_BOGUS_VAL == ctx->bogus);
160
161
    /* Release context structure */
162
0
    ctx = H5FL_FREE(H5EA__test_ctx_t, ctx);
163
164
0
    FUNC_LEAVE_NOAPI(SUCCEED)
165
0
} /* end H5EA__test_dst_context() */
166
167
/*-------------------------------------------------------------------------
168
 * Function:  H5EA__test_fill
169
 *
170
 * Purpose: Fill "missing elements" in block of elements
171
 *
172
 * Return:  Success:  non-negative
173
 *    Failure:  negative
174
 *
175
 *-------------------------------------------------------------------------
176
 */
177
static herr_t
178
H5EA__test_fill(void *nat_blk, size_t nelmts)
179
0
{
180
0
    uint64_t fill_val = H5EA_TEST_FILL; /* Value to fill elements with */
181
182
0
    FUNC_ENTER_PACKAGE_NOERR
183
184
    /* Sanity checks */
185
0
    assert(nat_blk);
186
0
    assert(nelmts);
187
188
0
    H5VM_array_fill(nat_blk, &fill_val, sizeof(uint64_t), nelmts);
189
190
0
    FUNC_LEAVE_NOAPI(SUCCEED)
191
0
} /* end H5EA__test_fill() */
192
193
/*-------------------------------------------------------------------------
194
 * Function:  H5EA__test_encode
195
 *
196
 * Purpose: Encode an element from "native" to "raw" form
197
 *
198
 * Return:  Success:  non-negative
199
 *    Failure:  negative
200
 *
201
 *-------------------------------------------------------------------------
202
 */
203
static herr_t
204
H5EA__test_encode(void *raw, const void *_elmt, size_t nelmts, void *_ctx)
205
0
{
206
0
    H5EA__test_ctx_t *ctx       = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */
207
0
    const uint64_t   *elmt      = (const uint64_t *)_elmt;  /* Convenience pointer to native elements */
208
0
    herr_t            ret_value = SUCCEED;
209
210
0
    FUNC_ENTER_PACKAGE
211
212
    /* Sanity checks */
213
0
    assert(raw);
214
0
    assert(elmt);
215
0
    assert(nelmts);
216
0
    assert(H5EA__TEST_BOGUS_VAL == ctx->bogus);
217
218
    /* Check for callback action */
219
0
    if (ctx->cb) {
220
0
        if ((*ctx->cb->encode)(elmt, nelmts, ctx->cb->udata) < 0)
221
0
            HGOTO_ERROR(H5E_EARRAY, H5E_BADVALUE, FAIL, "extensible array testing callback action failed");
222
0
    }
223
224
    /* Encode native elements into raw elements */
225
0
    while (nelmts) {
226
        /* Encode element - advances 'raw' pointer */
227
0
        UINT64ENCODE(raw, *elmt);
228
229
        /* Advance native element pointer */
230
0
        elmt++;
231
232
        /* Decrement # of elements to encode */
233
0
        nelmts--;
234
0
    }
235
236
0
done:
237
0
    FUNC_LEAVE_NOAPI(ret_value)
238
0
} /* end H5EA__test_encode() */
239
240
/*-------------------------------------------------------------------------
241
 * Function:  H5EA__test_decode
242
 *
243
 * Purpose: Decode an element from "raw" to "native" form
244
 *
245
 * Return:  Success:  non-negative
246
 *    Failure:  negative
247
 *
248
 *-------------------------------------------------------------------------
249
 */
250
static herr_t
251
H5EA__test_decode(const void *_raw, void *_elmt, size_t nelmts, void H5_ATTR_NDEBUG_UNUSED *_ctx)
252
0
{
253
#ifndef NDEBUG
254
    H5EA__test_ctx_t *ctx = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */
255
#endif                                                /* NDEBUG */
256
0
    uint64_t      *elmt = (uint64_t *)_elmt;          /* Convenience pointer to native elements */
257
0
    const uint8_t *raw  = (const uint8_t *)_raw;      /* Convenience pointer to raw elements */
258
259
0
    FUNC_ENTER_PACKAGE_NOERR
260
261
    /* Sanity checks */
262
0
    assert(raw);
263
0
    assert(elmt);
264
0
    assert(nelmts);
265
0
    assert(H5EA__TEST_BOGUS_VAL == ctx->bogus);
266
267
    /* Decode raw elements into native elements */
268
0
    while (nelmts) {
269
        /* Decode element - advances 'raw' pointer */
270
0
        UINT64DECODE(raw, *elmt);
271
272
        /* Advance native element pointer */
273
0
        elmt++;
274
275
        /* Decrement # of elements to decode */
276
0
        nelmts--;
277
0
    }
278
279
0
    FUNC_LEAVE_NOAPI(SUCCEED)
280
0
} /* end H5EA__test_decode() */
281
282
/*-------------------------------------------------------------------------
283
 * Function:  H5EA__test_debug
284
 *
285
 * Purpose: Display an element for debugging
286
 *
287
 * Return:  Success:  non-negative
288
 *    Failure:  negative
289
 *
290
 *-------------------------------------------------------------------------
291
 */
292
static herr_t
293
H5EA__test_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt)
294
0
{
295
0
    char temp_str[128]; /* Temporary string, for formatting */
296
297
0
    FUNC_ENTER_PACKAGE_NOERR
298
299
    /* Sanity checks */
300
0
    assert(stream);
301
0
    assert(elmt);
302
303
    /* Print element */
304
0
    snprintf(temp_str, sizeof(temp_str), "Element #%llu:", (unsigned long long)idx);
305
0
    fprintf(stream, "%*s%-*s %llu\n", indent, "", fwidth, temp_str,
306
0
            (unsigned long long)*(const uint64_t *)elmt);
307
308
0
    FUNC_LEAVE_NOAPI(SUCCEED)
309
0
} /* end H5EA__test_debug() */
310
311
/*-------------------------------------------------------------------------
312
 * Function:    H5EA__test_crt_dbg_context
313
 *
314
 * Purpose:     Create context for debugging callback
315
 *
316
 * Return:      Success:        non-NULL
317
 *              Failure:        NULL
318
 *
319
 *-------------------------------------------------------------------------
320
 */
321
static void *
322
H5EA__test_crt_dbg_context(H5F_t H5_ATTR_UNUSED *f, haddr_t H5_ATTR_UNUSED obj_addr)
323
0
{
324
0
    H5EA__ctx_cb_t *ctx; /* Context for callbacks */
325
0
    void           *ret_value = NULL;
326
327
0
    FUNC_ENTER_PACKAGE
328
329
    /* Allocate new context structure */
330
0
    if (NULL == (ctx = H5FL_MALLOC(H5EA__ctx_cb_t)))
331
0
        HGOTO_ERROR(H5E_EARRAY, H5E_CANTALLOC, NULL,
332
0
                    "can't allocate extensible array client callback context");
333
334
    /* Set return value */
335
0
    ret_value = ctx;
336
337
0
done:
338
0
    FUNC_LEAVE_NOAPI(ret_value)
339
0
} /* end H5EA__test_crt_dbg_context() */
340
341
/*-------------------------------------------------------------------------
342
 * Function:  H5EA__test_dst_dbg_context
343
 *
344
 * Purpose: Destroy context for callbacks
345
 *
346
 * Return:  Success:  non-negative
347
 *    Failure:  negative
348
 *
349
 *-------------------------------------------------------------------------
350
 */
351
static herr_t
352
H5EA__test_dst_dbg_context(void *_ctx)
353
0
{
354
0
    H5EA__ctx_cb_t *ctx = (H5EA__ctx_cb_t *)_ctx; /* Callback context to destroy */
355
356
0
    FUNC_ENTER_PACKAGE_NOERR
357
358
0
    assert(_ctx);
359
360
    /* Release context structure */
361
0
    ctx = H5FL_FREE(H5EA__ctx_cb_t, ctx);
362
363
0
    FUNC_LEAVE_NOAPI(SUCCEED)
364
0
} /* end H5EA__test_dst_dbg_context() */
365
366
/*-------------------------------------------------------------------------
367
 * Function:  H5EA__get_cparam_test
368
 *
369
 * Purpose: Retrieve the parameters used to create the extensible array
370
 *
371
 * Return:  Success:  non-negative
372
 *    Failure:  negative
373
 *
374
 *-------------------------------------------------------------------------
375
 */
376
herr_t
377
H5EA__get_cparam_test(const H5EA_t *ea, H5EA_create_t *cparam)
378
0
{
379
0
    FUNC_ENTER_PACKAGE_NOERR
380
381
    /* Check arguments. */
382
0
    assert(ea);
383
0
    assert(cparam);
384
385
    /* Get extensible array creation parameters */
386
0
    cparam->raw_elmt_size             = ea->hdr->cparam.raw_elmt_size;
387
0
    cparam->max_nelmts_bits           = ea->hdr->cparam.max_nelmts_bits;
388
0
    cparam->idx_blk_elmts             = ea->hdr->cparam.idx_blk_elmts;
389
0
    cparam->sup_blk_min_data_ptrs     = ea->hdr->cparam.sup_blk_min_data_ptrs;
390
0
    cparam->data_blk_min_elmts        = ea->hdr->cparam.data_blk_min_elmts;
391
0
    cparam->max_dblk_page_nelmts_bits = ea->hdr->cparam.max_dblk_page_nelmts_bits;
392
393
0
    FUNC_LEAVE_NOAPI(SUCCEED)
394
0
} /* end H5EA__get_cparam_test() */
395
396
/*-------------------------------------------------------------------------
397
 * Function:  H5EA__cmp_cparam_test
398
 *
399
 * Purpose: Compare the parameters used to create the extensible array
400
 *
401
 * Return:  Success:  non-negative
402
 *    Failure:  negative
403
 *
404
 *-------------------------------------------------------------------------
405
 */
406
int
407
H5EA__cmp_cparam_test(const H5EA_create_t *cparam1, const H5EA_create_t *cparam2)
408
0
{
409
0
    int ret_value = 0;
410
411
0
    FUNC_ENTER_PACKAGE_NOERR
412
413
    /* Check arguments */
414
0
    assert(cparam1);
415
0
    assert(cparam2);
416
417
    /* Compare creation parameters for array */
418
0
    if (cparam1->raw_elmt_size < cparam2->raw_elmt_size)
419
0
        HGOTO_DONE(-1);
420
0
    else if (cparam1->raw_elmt_size > cparam2->raw_elmt_size)
421
0
        HGOTO_DONE(1);
422
423
0
    if (cparam1->max_nelmts_bits < cparam2->max_nelmts_bits)
424
0
        HGOTO_DONE(-1);
425
0
    else if (cparam1->max_nelmts_bits > cparam2->max_nelmts_bits)
426
0
        HGOTO_DONE(1);
427
428
0
    if (cparam1->idx_blk_elmts < cparam2->idx_blk_elmts)
429
0
        HGOTO_DONE(-1);
430
0
    else if (cparam1->idx_blk_elmts > cparam2->idx_blk_elmts)
431
0
        HGOTO_DONE(1);
432
433
0
    if (cparam1->sup_blk_min_data_ptrs < cparam2->sup_blk_min_data_ptrs)
434
0
        HGOTO_DONE(-1);
435
0
    else if (cparam1->sup_blk_min_data_ptrs > cparam2->sup_blk_min_data_ptrs)
436
0
        HGOTO_DONE(1);
437
438
0
    if (cparam1->data_blk_min_elmts < cparam2->data_blk_min_elmts)
439
0
        HGOTO_DONE(-1);
440
0
    else if (cparam1->data_blk_min_elmts > cparam2->data_blk_min_elmts)
441
0
        HGOTO_DONE(1);
442
443
0
    if (cparam1->max_dblk_page_nelmts_bits < cparam2->max_dblk_page_nelmts_bits)
444
0
        HGOTO_DONE(-1);
445
0
    else if (cparam1->max_dblk_page_nelmts_bits > cparam2->max_dblk_page_nelmts_bits)
446
0
        HGOTO_DONE(1);
447
448
0
done:
449
0
    FUNC_LEAVE_NOAPI(ret_value)
450
0
} /* end H5EA__cmp_cparam_test() */