Coverage Report

Created: 2024-06-18 06:29

/src/hdf5/src/H5Oainfo.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:             H5Oainfo.c
16
 *
17
 * Purpose:             Attribute Information messages.
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
#define H5A_FRIEND     /*suppress error about including H5Apkg    */
23
#include "H5Omodule.h" /* This source code file is part of the H5O module */
24
25
#include "H5private.h"   /* Generic Functions     */
26
#include "H5Apkg.h"      /* Attributes        */
27
#include "H5Eprivate.h"  /* Error handling        */
28
#include "H5FLprivate.h" /* Free lists                           */
29
#include "H5Opkg.h"      /* Object headers      */
30
31
/* PRIVATE PROTOTYPES */
32
static void  *H5O__ainfo_decode(H5F_t *f, H5O_t *open_oh, unsigned mesg_flags, unsigned *ioflags,
33
                                size_t p_size, const uint8_t *p);
34
static herr_t H5O__ainfo_encode(H5F_t *f, bool disable_shared, size_t H5_ATTR_UNUSED p_size, uint8_t *p,
35
                                const void *_mesg);
36
static void  *H5O__ainfo_copy(const void *_mesg, void *_dest);
37
static size_t H5O__ainfo_size(const H5F_t *f, bool disable_shared, const void *_mesg);
38
static herr_t H5O__ainfo_free(void *_mesg);
39
static herr_t H5O__ainfo_delete(H5F_t *f, H5O_t *open_oh, void *_mesg);
40
static herr_t H5O__ainfo_pre_copy_file(H5F_t *file_src, const void *mesg_src, bool *deleted,
41
                                       const H5O_copy_t *cpy_info, void *udata);
42
static void  *H5O__ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, bool *recompute_size,
43
                                   unsigned *mesg_flags, H5O_copy_t *cpy_info, void *udata);
44
static herr_t H5O__ainfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
45
                                        void *mesg_dst, unsigned *mesg_flags, H5O_copy_t *cpy_info);
46
static herr_t H5O__ainfo_debug(H5F_t *f, const void *_mesg, FILE *stream, int indent, int fwidth);
47
48
/* This message derives from H5O message class */
49
const H5O_msg_class_t H5O_MSG_AINFO[1] = {{
50
    H5O_AINFO_ID,              /*message id number             */
51
    "ainfo",                   /*message name for debugging    */
52
    sizeof(H5O_ainfo_t),       /*native message size           */
53
    0,                         /* messages are shareable?       */
54
    H5O__ainfo_decode,         /*decode message                */
55
    H5O__ainfo_encode,         /*encode message                */
56
    H5O__ainfo_copy,           /*copy the native value         */
57
    H5O__ainfo_size,           /*size of symbol table entry    */
58
    NULL,                      /*default reset method          */
59
    H5O__ainfo_free,           /* free method     */
60
    H5O__ainfo_delete,         /* file delete method    */
61
    NULL,                      /* link method     */
62
    NULL,                      /*set share method   */
63
    NULL,                      /*can share method   */
64
    H5O__ainfo_pre_copy_file,  /* pre copy native value to file */
65
    H5O__ainfo_copy_file,      /* copy native value to file    */
66
    H5O__ainfo_post_copy_file, /* post copy native value to file */
67
    NULL,                      /* get creation index    */
68
    NULL,                      /* set creation index    */
69
    H5O__ainfo_debug           /*debug the message             */
70
}};
71
72
/* Current version of attribute info information */
73
0
#define H5O_AINFO_VERSION 0
74
75
/* Flags for attribute info flag encoding */
76
0
#define H5O_AINFO_TRACK_CORDER 0x01
77
0
#define H5O_AINFO_INDEX_CORDER 0x02
78
0
#define H5O_AINFO_ALL_FLAGS    (H5O_AINFO_TRACK_CORDER | H5O_AINFO_INDEX_CORDER)
79
80
/* Declare a free list to manage the H5O_ainfo_t struct */
81
H5FL_DEFINE_STATIC(H5O_ainfo_t);
82
83
/*-------------------------------------------------------------------------
84
 * Function:    H5O__ainfo_decode
85
 *
86
 * Purpose:     Decode a message and return a pointer to a newly allocated one.
87
 *
88
 * Return:      Success:        Ptr to new message in native form.
89
 *              Failure:        NULL
90
 *-------------------------------------------------------------------------
91
 */
92
static void *
93
H5O__ainfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags,
94
                  unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p)
95
0
{
96
0
    const uint8_t *p_end = p + p_size - 1; /* End of input buffer */
97
0
    H5O_ainfo_t   *ainfo = NULL;           /* Attribute info */
98
0
    unsigned char  flags;                  /* Flags for encoding attribute info */
99
0
    uint8_t        sizeof_addr;            /* Size of addresses in this file */
100
0
    void          *ret_value = NULL;       /* Return value */
101
102
0
    FUNC_ENTER_PACKAGE
103
104
0
    assert(f);
105
0
    assert(p);
106
107
0
    sizeof_addr = H5F_sizeof_addr(f);
108
109
    /* Version of message */
110
0
    if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end))
111
0
        HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
112
0
    if (*p++ != H5O_AINFO_VERSION)
113
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message");
114
115
    /* Allocate space for message */
116
0
    if (NULL == (ainfo = H5FL_MALLOC(H5O_ainfo_t)))
117
0
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
118
119
    /* Get the flags for the message */
120
0
    if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end))
121
0
        HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
122
0
    flags = *p++;
123
0
    if (flags & ~H5O_AINFO_ALL_FLAGS)
124
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag value for message");
125
0
    ainfo->track_corder = (flags & H5O_AINFO_TRACK_CORDER) ? true : false;
126
0
    ainfo->index_corder = (flags & H5O_AINFO_INDEX_CORDER) ? true : false;
127
128
    /* Set the number of attributes on the object to an invalid value, so we query it later */
129
0
    ainfo->nattrs = HSIZET_MAX;
130
131
    /* Max. creation order value for the object */
132
0
    if (ainfo->track_corder) {
133
0
        if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end))
134
0
            HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
135
0
        UINT16DECODE(p, ainfo->max_crt_idx);
136
0
    }
137
0
    else
138
0
        ainfo->max_crt_idx = H5O_MAX_CRT_ORDER_IDX;
139
140
    /* Address of fractal heap to store "dense" attributes */
141
0
    H5_GCC_CLANG_DIAG_OFF("type-limits")
142
0
    if (H5_IS_BUFFER_OVERFLOW(p, sizeof_addr, p_end))
143
0
        HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
144
0
    H5_GCC_CLANG_DIAG_ON("type-limits")
145
0
    H5F_addr_decode(f, &p, &(ainfo->fheap_addr));
146
147
    /* Address of v2 B-tree to index names of attributes (names are always indexed) */
148
0
    H5_GCC_CLANG_DIAG_OFF("type-limits")
149
0
    if (H5_IS_BUFFER_OVERFLOW(p, sizeof_addr, p_end))
150
0
        HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
151
0
    H5_GCC_CLANG_DIAG_ON("type-limits")
152
0
    H5F_addr_decode(f, &p, &(ainfo->name_bt2_addr));
153
154
    /* Address of v2 B-tree to index creation order of links, if there is one */
155
0
    if (ainfo->index_corder) {
156
0
        H5_GCC_CLANG_DIAG_OFF("type-limits")
157
0
        if (H5_IS_BUFFER_OVERFLOW(p, sizeof_addr, p_end))
158
0
            HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding");
159
0
        H5_GCC_CLANG_DIAG_ON("type-limits")
160
0
        H5F_addr_decode(f, &p, &(ainfo->corder_bt2_addr));
161
0
    }
162
0
    else
163
0
        ainfo->corder_bt2_addr = HADDR_UNDEF;
164
165
    /* Set return value */
166
0
    ret_value = ainfo;
167
168
0
done:
169
0
    if (ret_value == NULL && ainfo != NULL)
170
0
        ainfo = H5FL_FREE(H5O_ainfo_t, ainfo);
171
172
0
    FUNC_LEAVE_NOAPI(ret_value)
173
0
} /* end H5O__ainfo_decode() */
174
175
/*-------------------------------------------------------------------------
176
 * Function:    H5O__ainfo_encode
177
 *
178
 * Purpose:     Encodes a message.
179
 *
180
 * Return:      Non-negative on success/Negative on failure
181
 *
182
 *-------------------------------------------------------------------------
183
 */
184
static herr_t
185
H5O__ainfo_encode(H5F_t *f, bool H5_ATTR_UNUSED disable_shared, size_t H5_ATTR_UNUSED p_size, uint8_t *p,
186
                  const void *_mesg)
187
0
{
188
0
    const H5O_ainfo_t *ainfo = (const H5O_ainfo_t *)_mesg;
189
0
    unsigned char      flags; /* Flags for encoding attribute info */
190
191
0
    FUNC_ENTER_PACKAGE_NOERR
192
193
    /* check args */
194
0
    assert(f);
195
0
    assert(p);
196
0
    assert(ainfo);
197
198
    /* Message version */
199
0
    *p++ = H5O_AINFO_VERSION;
200
201
    /* The flags for the attribute indices */
202
0
    flags = (unsigned char)(ainfo->track_corder ? H5O_AINFO_TRACK_CORDER : 0);
203
0
    flags = (unsigned char)(flags | (ainfo->index_corder ? H5O_AINFO_INDEX_CORDER : 0));
204
0
    *p++  = flags;
205
206
    /* Max. creation order value for the object */
207
0
    if (ainfo->track_corder)
208
0
        UINT16ENCODE(p, ainfo->max_crt_idx);
209
210
    /* Address of fractal heap to store "dense" attributes */
211
0
    H5F_addr_encode(f, &p, ainfo->fheap_addr);
212
213
    /* Address of v2 B-tree to index names of attributes */
214
0
    H5F_addr_encode(f, &p, ainfo->name_bt2_addr);
215
216
    /* Address of v2 B-tree to index creation order of attributes, if they are indexed */
217
0
    if (ainfo->index_corder)
218
0
        H5F_addr_encode(f, &p, ainfo->corder_bt2_addr);
219
0
    else
220
0
        assert(!H5_addr_defined(ainfo->corder_bt2_addr));
221
222
0
    FUNC_LEAVE_NOAPI(SUCCEED)
223
0
} /* end H5O__ainfo_encode() */
224
225
/*-------------------------------------------------------------------------
226
 * Function:    H5O__ainfo_copy
227
 *
228
 * Purpose:     Copies a message from _MESG to _DEST, allocating _DEST if
229
 *              necessary.
230
 *
231
 * Return:      Success:        Ptr to _DEST
232
 *              Failure:        NULL
233
 *
234
 *-------------------------------------------------------------------------
235
 */
236
static void *
237
H5O__ainfo_copy(const void *_mesg, void *_dest)
238
0
{
239
0
    const H5O_ainfo_t *ainfo     = (const H5O_ainfo_t *)_mesg;
240
0
    H5O_ainfo_t       *dest      = (H5O_ainfo_t *)_dest;
241
0
    void              *ret_value = NULL; /* Return value */
242
243
0
    FUNC_ENTER_PACKAGE
244
245
    /* check args */
246
0
    assert(ainfo);
247
0
    if (!dest && NULL == (dest = H5FL_MALLOC(H5O_ainfo_t)))
248
0
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
249
250
    /* copy */
251
0
    *dest = *ainfo;
252
253
    /* Set return value */
254
0
    ret_value = dest;
255
256
0
done:
257
0
    FUNC_LEAVE_NOAPI(ret_value)
258
0
} /* end H5O__ainfo_copy() */
259
260
/*-------------------------------------------------------------------------
261
 * Function:    H5O__ainfo_size
262
 *
263
 * Purpose:     Returns the size of the raw message in bytes not counting
264
 *              the message type or size fields, but only the data fields.
265
 *              This function doesn't take into account alignment.
266
 *
267
 * Return:      Success:        Message data size in bytes without alignment.
268
 *              Failure:        zero
269
 *
270
 *-------------------------------------------------------------------------
271
 */
272
static size_t
273
H5O__ainfo_size(const H5F_t *f, bool H5_ATTR_UNUSED disable_shared, const void *_mesg)
274
0
{
275
0
    const H5O_ainfo_t *ainfo     = (const H5O_ainfo_t *)_mesg;
276
0
    size_t             ret_value = 0; /* Return value */
277
278
0
    FUNC_ENTER_PACKAGE_NOERR
279
280
    /* Set return value */
281
0
    ret_value =
282
0
        (size_t)(1                               /* Version */
283
0
                 + 1                             /* Index flags */
284
0
                 + (ainfo->track_corder ? 2 : 0) /* Curr. max. creation order value */
285
                 + H5F_SIZEOF_ADDR(f)            /* Address of fractal heap to store "dense" attributes */
286
                 + H5F_SIZEOF_ADDR(f)            /* Address of v2 B-tree for indexing names of attributes */
287
0
                 + (ainfo->index_corder
288
0
                        ? H5F_SIZEOF_ADDR(f)
289
0
                        : 0)); /* Address of v2 B-tree for indexing creation order values of attributes */
290
291
0
    FUNC_LEAVE_NOAPI(ret_value)
292
0
} /* end H5O__ainfo_size() */
293
294
/*-------------------------------------------------------------------------
295
 * Function:  H5O__ainfo_free
296
 *
297
 * Purpose: Frees the message
298
 *
299
 * Return:  Non-negative on success/Negative on failure
300
 *
301
 *-------------------------------------------------------------------------
302
 */
303
static herr_t
304
H5O__ainfo_free(void *mesg)
305
0
{
306
0
    FUNC_ENTER_PACKAGE_NOERR
307
308
0
    assert(mesg);
309
310
0
    mesg = H5FL_FREE(H5O_ainfo_t, mesg);
311
312
0
    FUNC_LEAVE_NOAPI(SUCCEED)
313
0
} /* end H5O__ainfo_free() */
314
315
/*-------------------------------------------------------------------------
316
 * Function:    H5O__ainfo_delete
317
 *
318
 * Purpose:     Free file space referenced by message.  Note that open_oh
319
 *              *must* be non-NULL - this means that calls to
320
 *              H5O_msg_delete must include an oh if the type is ainfo.
321
 *
322
 * Return:      Non-negative on success/Negative on failure
323
 *
324
 *-------------------------------------------------------------------------
325
 */
326
static herr_t
327
H5O__ainfo_delete(H5F_t *f, H5O_t H5_ATTR_NDEBUG_UNUSED *open_oh, void *_mesg)
328
0
{
329
0
    H5O_ainfo_t *ainfo     = (H5O_ainfo_t *)_mesg;
330
0
    herr_t       ret_value = SUCCEED; /* Return value */
331
332
0
    FUNC_ENTER_PACKAGE
333
334
    /* check args */
335
0
    assert(f);
336
0
    assert(ainfo);
337
0
    assert(open_oh);
338
339
    /* If the object is using "dense" attribute storage, delete it */
340
0
    if (H5_addr_defined(ainfo->fheap_addr))
341
        /* Delete the attribute */
342
0
        if (H5A__dense_delete(f, ainfo) < 0)
343
0
            HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free dense attribute storage");
344
345
0
done:
346
0
    FUNC_LEAVE_NOAPI(ret_value)
347
0
} /* end H5O__ainfo_delete() */
348
349
/*-------------------------------------------------------------------------
350
 * Function:    H5O__ainfo_pre_copy_file
351
 *
352
 * Purpose:     Perform any necessary actions before copying message between
353
 *              files.
354
 *
355
 * Return:      Success:        Non-negative
356
 *              Failure:        Negative
357
 *
358
 *-------------------------------------------------------------------------
359
 */
360
static herr_t
361
H5O__ainfo_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void H5_ATTR_UNUSED *native_src, bool *deleted,
362
                         const H5O_copy_t *cpy_info, void H5_ATTR_UNUSED *udata)
363
0
{
364
0
    FUNC_ENTER_PACKAGE_NOERR
365
366
    /* check args */
367
0
    assert(deleted);
368
0
    assert(cpy_info);
369
370
    /* If we are not copying attributes into the destination file, indicate
371
     *  that this message should be deleted.
372
     */
373
0
    if (cpy_info->copy_without_attr)
374
0
        *deleted = true;
375
376
0
    FUNC_LEAVE_NOAPI(SUCCEED)
377
0
} /* end H5O__ainfo_pre_copy_file() */
378
379
/*-------------------------------------------------------------------------
380
 * Function:    H5O__ainfo_copy_file
381
 *
382
 * Purpose:     Copies a message from _MESG to _DEST in file
383
 *
384
 * Return:      Success:        Ptr to _DEST
385
 *              Failure:        NULL
386
 *
387
 *-------------------------------------------------------------------------
388
 */
389
static void *
390
H5O__ainfo_copy_file(H5F_t H5_ATTR_NDEBUG_UNUSED *file_src, void *mesg_src, H5F_t *file_dst,
391
                     bool H5_ATTR_UNUSED *recompute_size, unsigned H5_ATTR_UNUSED *mesg_flags,
392
                     H5O_copy_t H5_ATTR_NDEBUG_UNUSED *cpy_info, void H5_ATTR_UNUSED *udata)
393
0
{
394
0
    H5O_ainfo_t *ainfo_src = (H5O_ainfo_t *)mesg_src;
395
0
    H5O_ainfo_t *ainfo_dst = NULL;
396
0
    void        *ret_value = NULL; /* Return value */
397
398
0
    FUNC_ENTER_PACKAGE
399
400
    /* check args */
401
0
    assert(file_src);
402
0
    assert(ainfo_src);
403
0
    assert(file_dst);
404
0
    assert(cpy_info);
405
0
    assert(!cpy_info->copy_without_attr);
406
407
    /* Allocate space for the destination message */
408
0
    if (NULL == (ainfo_dst = H5FL_MALLOC(H5O_ainfo_t)))
409
0
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
410
411
    /* Copy the top level of the information */
412
0
    *ainfo_dst = *ainfo_src;
413
414
0
    if (H5_addr_defined(ainfo_src->fheap_addr)) {
415
        /* Prepare to copy dense attributes - actual copy in post_copy */
416
417
        /* Set copied metadata tag */
418
0
        H5_BEGIN_TAG(H5AC__COPIED_TAG)
419
420
0
        if (H5A__dense_create(file_dst, ainfo_dst) < 0)
421
0
            HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINIT, NULL, "unable to create dense storage for attributes");
422
423
        /* Reset metadata tag */
424
0
        H5_END_TAG
425
0
    } /* end if */
426
427
    /* Set return value */
428
0
    ret_value = ainfo_dst;
429
430
0
done:
431
    /* Release destination attribute information on failure */
432
0
    if (!ret_value && ainfo_dst)
433
0
        ainfo_dst = H5FL_FREE(H5O_ainfo_t, ainfo_dst);
434
435
0
    FUNC_LEAVE_NOAPI(ret_value)
436
0
} /* H5O__ainfo_copy_file() */
437
438
/*-------------------------------------------------------------------------
439
 * Function:    H5O__ainfo_post_copy_file
440
 *
441
 * Purpose:     Finish copying a message from between files.
442
 *              We have to copy the values of a reference attribute in the
443
 *              post copy because H5O_post_copy_file() fails in the case that
444
 *              an object may have a reference attribute that points to the
445
 *              object itself.
446
 *
447
 * Return:      Non-negative on success/Negative on failure
448
 *
449
 *-------------------------------------------------------------------------
450
 */
451
static herr_t
452
H5O__ainfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
453
                          void *mesg_dst, unsigned H5_ATTR_UNUSED *mesg_flags, H5O_copy_t *cpy_info)
454
0
{
455
0
    const H5O_ainfo_t *ainfo_src = (const H5O_ainfo_t *)mesg_src;
456
0
    herr_t             ret_value = SUCCEED; /* Return value */
457
458
0
    FUNC_ENTER_PACKAGE
459
460
0
    assert(ainfo_src);
461
462
0
    if (H5_addr_defined(ainfo_src->fheap_addr))
463
0
        if (H5A__dense_post_copy_file_all(src_oloc, ainfo_src, dst_oloc, (H5O_ainfo_t *)mesg_dst, cpy_info) <
464
0
            0)
465
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "can't copy attribute");
466
467
0
done:
468
0
    FUNC_LEAVE_NOAPI(ret_value)
469
0
} /* H5O__ainfo_post_copy_file() */
470
471
/*-------------------------------------------------------------------------
472
 * Function:    H5O__ainfo_debug
473
 *
474
 * Purpose:     Prints debugging info for a message.
475
 *
476
 * Return:      Non-negative on success/Negative on failure
477
 *
478
 *-------------------------------------------------------------------------
479
 */
480
static herr_t
481
H5O__ainfo_debug(H5F_t H5_ATTR_UNUSED *f, const void *_mesg, FILE *stream, int indent, int fwidth)
482
0
{
483
0
    const H5O_ainfo_t *ainfo = (const H5O_ainfo_t *)_mesg;
484
485
0
    FUNC_ENTER_PACKAGE_NOERR
486
487
    /* check args */
488
0
    assert(f);
489
0
    assert(ainfo);
490
0
    assert(stream);
491
0
    assert(indent >= 0);
492
0
    assert(fwidth >= 0);
493
494
0
    fprintf(stream, "%*s%-*s %" PRIuHSIZE "\n", indent, "", fwidth, "Number of attributes:", ainfo->nattrs);
495
0
    fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
496
0
            "Track creation order of attributes:", ainfo->track_corder ? "TRUE" : "FALSE");
497
0
    fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
498
0
            "Index creation order of attributes:", ainfo->index_corder ? "TRUE" : "FALSE");
499
0
    fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
500
0
            "Max. creation index value:", (unsigned)ainfo->max_crt_idx);
501
0
    fprintf(stream, "%*s%-*s %" PRIuHADDR "\n", indent, "", fwidth,
502
0
            "'Dense' attribute storage fractal heap address:", ainfo->fheap_addr);
503
0
    fprintf(stream, "%*s%-*s %" PRIuHADDR "\n", indent, "", fwidth,
504
0
            "'Dense' attribute storage name index v2 B-tree address:", ainfo->name_bt2_addr);
505
0
    fprintf(stream, "%*s%-*s %" PRIuHADDR "\n", indent, "", fwidth,
506
0
            "'Dense' attribute storage creation order index v2 B-tree address:", ainfo->corder_bt2_addr);
507
508
0
    FUNC_LEAVE_NOAPI(SUCCEED)
509
0
} /* end H5O__ainfo_debug() */