Coverage Report

Created: 2026-01-16 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5Tnative.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
 * Module Info: This module contains the functionality for querying
15
 *      a "native" datatype for the H5T interface.
16
 */
17
18
#include "H5Tmodule.h" /* This source code file is part of the H5T module */
19
20
#include "H5private.h"   /* Generic Functions            */
21
#include "H5Eprivate.h"  /* Error handling              */
22
#include "H5Iprivate.h"  /* IDs                      */
23
#include "H5MMprivate.h" /* Memory management            */
24
#include "H5Tpkg.h"      /* Datatypes                */
25
26
/* Static local functions */
27
static H5T_t *H5T__get_native_type(H5T_t *dt, H5T_direction_t direction, size_t *struct_align, size_t *offset,
28
                                   size_t *comp_size);
29
static H5T_t *H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
30
                                      size_t *struct_align, size_t *offset, size_t *comp_size);
31
static H5T_t *H5T__get_native_float(const H5T_t *dtype, H5T_direction_t direction, size_t *struct_align,
32
                                    size_t *offset, size_t *comp_size);
33
static H5T_t *H5T__get_native_bitfield(size_t prec, H5T_direction_t direction, size_t *struct_align,
34
                                       size_t *offset, size_t *comp_size);
35
static herr_t H5T__cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, size_t nelems,
36
                              size_t align, size_t *struct_align);
37
38
/*-------------------------------------------------------------------------
39
 * Function:    H5Tget_native_type
40
 *
41
 * Purpose:     High-level API to return the native type of a datatype.
42
 *              The native type is chosen by matching the size and class of
43
 *              queried datatype from the following native primitive
44
 *              datatypes:
45
 *                      H5T_NATIVE_CHAR         H5T_NATIVE_UCHAR
46
 *                      H5T_NATIVE_SHORT        H5T_NATIVE_USHORT
47
 *                      H5T_NATIVE_INT          H5T_NATIVE_UINT
48
 *                      H5T_NATIVE_LONG         H5T_NATIVE_ULONG
49
 *                      H5T_NATIVE_LLONG        H5T_NATIVE_ULLONG
50
 *
51
 *                      H5T_NATIVE_FLOAT16 (if available)
52
 *                      H5T_NATIVE_FLOAT
53
 *                      H5T_NATIVE_DOUBLE
54
 *                      H5T_NATIVE_LDOUBLE
55
 *
56
 *                      H5T_NATIVE_FLOAT_COMPLEX (if available)
57
 *                      H5T_NATIVE_DOUBLE_COMPLEX (if available)
58
 *                      H5T_NATIVE_LDOUBLE_COMPLEX (if available)
59
 *
60
 *              Compound, array, enum, and VL types all choose among these
61
 *              types for their members.  Time, Bitfield, Opaque, Reference
62
 *              types are only copy out.
63
 *
64
 * Return:      Success:        Returns the native data type if successful.
65
 *
66
 *              Failure:        negative
67
 *
68
 *-------------------------------------------------------------------------
69
 */
70
hid_t
71
H5Tget_native_type(hid_t type_id, H5T_direction_t direction)
72
0
{
73
0
    H5T_t *dt;               /* Datatype to create native datatype from */
74
0
    H5T_t *new_dt    = NULL; /* Datatype for native datatype created */
75
0
    size_t comp_size = 0;    /* Compound datatype's size */
76
0
    hid_t  ret_value;        /* Return value */
77
78
0
    FUNC_ENTER_API(H5I_INVALID_HID)
79
80
    /* Check arguments */
81
0
    if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
82
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a data type");
83
0
    if (direction != H5T_DIR_DEFAULT && direction != H5T_DIR_ASCEND && direction != H5T_DIR_DESCEND)
84
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not valid direction value");
85
86
    /* Get the native type */
87
0
    if (NULL == (new_dt = H5T__get_native_type(dt, direction, NULL, NULL, &comp_size)))
88
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "cannot retrieve native type");
89
90
    /* Get an ID for the new type */
91
0
    if ((ret_value = H5I_register(H5I_DATATYPE, new_dt, true)) < 0)
92
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register data type");
93
94
0
done:
95
    /* Error cleanup */
96
0
    if (ret_value < 0)
97
0
        if (new_dt && H5T_close_real(new_dt) < 0)
98
0
            HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release datatype");
99
100
0
    FUNC_LEAVE_API(ret_value)
101
0
} /* end H5Tget_native_type() */
102
103
/*-------------------------------------------------------------------------
104
 * Function:    H5T__get_native_type
105
 *
106
 * Purpose:     Returns the native type of a datatype.
107
 *
108
 * Return:      Success:        Returns the native data type if successful.
109
 *
110
 *              Failure:        negative
111
 *
112
 *-------------------------------------------------------------------------
113
 */
114
static H5T_t *
115
H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_align, size_t *offset,
116
                     size_t *comp_size)
117
0
{
118
0
    H5T_t  *super_type;       /* Super type of VL, array and enum datatypes */
119
0
    H5T_t  *nat_super_type;   /* Native form of VL, array & enum super datatype */
120
0
    H5T_t  *new_type  = NULL; /* New native datatype */
121
0
    H5T_t  *memb_type = NULL; /* Datatype of member */
122
0
    H5T_t **memb_list = NULL; /* List of compound member IDs */
123
0
    size_t *memb_offset =
124
0
        NULL; /* List of member offsets in compound type, including member size and alignment */
125
0
    char      **comp_mname     = NULL; /* List of member names in compound type */
126
0
    char       *memb_name      = NULL; /* Enum's member name */
127
0
    void       *memb_value     = NULL; /* Enum's member value */
128
0
    void       *tmp_memb_value = NULL; /* Enum's member value */
129
0
    hsize_t    *dims           = NULL; /* Dimension sizes for array */
130
0
    H5T_class_t h5_class;              /* Class of datatype to make native */
131
0
    size_t      size;                  /* Size of datatype to make native */
132
0
    size_t      prec;                  /* Precision of datatype to make native */
133
0
    int         snmemb;                /* Number of members in compound & enum types */
134
0
    unsigned    nmemb = 0;             /* Number of members in compound & enum types */
135
0
    unsigned    u;                     /* Local index variable */
136
0
    H5T_t      *ret_value = NULL;      /* Return value */
137
138
0
    FUNC_ENTER_PACKAGE
139
140
0
    assert(dtype);
141
142
0
    if (H5T_NO_CLASS == (h5_class = H5T_get_class(dtype, false)))
143
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class");
144
145
0
    if (0 == (size = H5T_get_size(dtype)))
146
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid size");
147
148
0
    switch (h5_class) {
149
0
        case H5T_INTEGER: {
150
0
            H5T_sign_t sign; /* Signedness of integer type */
151
152
0
            if (H5T_SGN_ERROR == (sign = H5T_get_sign(dtype)))
153
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid signess");
154
155
0
            prec = dtype->shared->u.atomic.prec;
156
157
0
            if (NULL ==
158
0
                (ret_value = H5T__get_native_integer(prec, sign, direction, struct_align, offset, comp_size)))
159
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve integer type");
160
0
        } /* end case */
161
0
        break;
162
163
0
        case H5T_FLOAT:
164
0
            if (NULL ==
165
0
                (ret_value = H5T__get_native_float(dtype, direction, struct_align, offset, comp_size)))
166
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type");
167
168
0
            break;
169
170
0
        case H5T_STRING:
171
0
            if (NULL == (ret_value = H5T_copy(dtype, H5T_COPY_TRANSIENT)))
172
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type");
173
174
0
            if (H5T_IS_VL_STRING(dtype->shared)) {
175
                /* Update size, offset and compound alignment for parent. */
176
0
                if (H5T__cmp_offset(comp_size, offset, sizeof(char *), (size_t)1, H5T_POINTER_ALIGN_g,
177
0
                                    struct_align) < 0)
178
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
179
0
            } /* end if */
180
0
            else {
181
                /* Update size, offset and compound alignment for parent. */
182
0
                if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_ALIGN_g,
183
0
                                    struct_align) < 0)
184
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
185
0
            } /* end else */
186
0
            break;
187
188
        /* The time type will be supported in the future.  Simply return "not supported"
189
         * message for now.*/
190
0
        case H5T_TIME:
191
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "time type is not supported yet");
192
193
0
        case H5T_BITFIELD: {
194
0
            prec = dtype->shared->u.atomic.prec;
195
196
0
            if (NULL ==
197
0
                (ret_value = H5T__get_native_bitfield(prec, direction, struct_align, offset, comp_size)))
198
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve integer for bitfield type");
199
0
        } /* end case */
200
0
        break;
201
202
0
        case H5T_OPAQUE:
203
0
            if (NULL == (ret_value = H5T_copy(dtype, H5T_COPY_TRANSIENT)))
204
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type");
205
206
            /* Update size, offset and compound alignment for parent. */
207
0
            if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_ALIGN_g,
208
0
                                struct_align) < 0)
209
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
210
0
            break;
211
212
0
        case H5T_REFERENCE: {
213
0
            H5T_t *dt; /* Datatype to make native */
214
0
            size_t align;
215
0
            size_t ref_size;
216
217
0
            if (NULL == (ret_value = H5T_copy(dtype, H5T_COPY_TRANSIENT)))
218
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy reference type");
219
220
            /* Decide if the data type is object reference. */
221
0
            if (NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_OBJ_g)))
222
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
223
224
            /* Update size, offset and compound alignment for parent. */
225
0
            if (0 == H5T_cmp(ret_value, dt, false)) {
226
0
                align    = H5T_HOBJREF_ALIGN_g;
227
0
                ref_size = sizeof(hobj_ref_t);
228
0
            } /* end if */
229
0
            else {
230
                /* Decide if the data type is dataset region reference. */
231
0
                if (NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_DSETREG_g)))
232
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
233
234
0
                if (0 == H5T_cmp(ret_value, dt, false)) {
235
0
                    align    = H5T_HDSETREGREF_ALIGN_g;
236
0
                    ref_size = sizeof(hdset_reg_ref_t);
237
0
                } /* end if */
238
0
                else {
239
                    /* Only pointers to underlying opaque reference types */
240
0
                    align    = H5T_REF_ALIGN_g;
241
0
                    ref_size = sizeof(H5R_ref_t);
242
0
                } /* end else */
243
0
            }     /* end else */
244
245
0
            if (H5T__cmp_offset(comp_size, offset, ref_size, (size_t)1, align, struct_align) < 0)
246
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
247
0
        } /* end case */
248
0
        break;
249
250
0
        case H5T_COMPOUND: {
251
0
            size_t children_size = 0; /* Total size of compound members */
252
0
            size_t children_st_align =
253
0
                0; /* The max alignment among compound members.  This'll be the compound alignment */
254
255
0
            if ((snmemb = H5T_get_nmembers(dtype)) <= 0)
256
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "compound data type doesn't have any member");
257
0
            H5_CHECKED_ASSIGN(nmemb, unsigned, snmemb, int);
258
259
0
            if (NULL == (memb_list = (H5T_t **)H5MM_calloc(nmemb * sizeof(H5T_t *))))
260
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory");
261
0
            if (NULL == (memb_offset = (size_t *)H5MM_calloc(nmemb * sizeof(size_t))))
262
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory");
263
0
            if (NULL == (comp_mname = (char **)H5MM_calloc(nmemb * sizeof(char *))))
264
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory");
265
266
            /* Construct child compound type and retrieve a list of their IDs, offsets, total size, and
267
             * alignment for compound type. */
268
0
            for (u = 0; u < nmemb; u++) {
269
0
                if (NULL == (memb_type = H5T_get_member_type(dtype, u)))
270
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed");
271
272
0
                if (NULL == (comp_mname[u] = H5T__get_member_name(dtype, u)))
273
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed");
274
275
0
                if (NULL == (memb_list[u] = H5T__get_native_type(memb_type, direction, &children_st_align,
276
0
                                                                 &(memb_offset[u]), &children_size)))
277
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member identifier retrieval failed");
278
279
0
                if (H5T_close_real(memb_type) < 0)
280
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype");
281
0
            } /* end for */
282
283
            /* The alignment for whole compound type */
284
0
            if (children_st_align && children_size % children_st_align)
285
0
                children_size += children_st_align - (children_size % children_st_align);
286
287
            /* Construct new compound type based on native type */
288
0
            if (NULL == (new_type = H5T__create(H5T_COMPOUND, children_size)))
289
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot create a compound type");
290
291
            /* Insert members for the new compound type */
292
0
            for (u = 0; u < nmemb; u++)
293
0
                if (H5T__insert(new_type, comp_mname[u], memb_offset[u], memb_list[u]) < 0)
294
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot insert member to compound datatype");
295
296
            /* Update size, offset and compound alignment for parent in the case of
297
             * nested compound type.  The alignment for a compound type as one field in
298
             * a compound type is the biggest compound alignment among all its members.
299
             * e.g. in the structure
300
             *    typedef struct s1 {
301
             *        char            c;
302
             *        int             i;
303
             *        s2              st;
304
             *        unsigned long long       l;
305
             *    } s1;
306
             *    typedef struct s2 {
307
             *        short           c2;
308
             *        long            l2;
309
             *        long long       ll2;
310
             *    } s2;
311
             * The alignment for ST in S1 is the biggest structure alignment of all the
312
             * members of S2, which is probably the LL2 of 'long long'. -SLU 2010/4/28
313
             */
314
0
            if (H5T__cmp_offset(comp_size, offset, children_size, (size_t)1, children_st_align,
315
0
                                struct_align) < 0)
316
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
317
318
            /* Close member data type */
319
0
            for (u = 0; u < nmemb; u++) {
320
0
                if (H5T_close_real(memb_list[u]) < 0)
321
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype");
322
323
                /* Free member names in list */
324
0
                comp_mname[u] = (char *)H5MM_xfree(comp_mname[u]);
325
0
            } /* end for */
326
327
            /* Free lists for members */
328
0
            memb_list   = (H5T_t **)H5MM_xfree(memb_list);
329
0
            memb_offset = (size_t *)H5MM_xfree(memb_offset);
330
0
            comp_mname  = (char **)H5MM_xfree(comp_mname);
331
332
0
            ret_value = new_type;
333
0
        } /* end case */
334
0
        break;
335
336
0
        case H5T_ENUM: {
337
0
            H5T_path_t *tpath; /* Type conversion info    */
338
339
            /* Don't need to do anything special for alignment, offset since the ENUM type usually is integer.
340
             */
341
342
            /* Retrieve base type for enumerated type */
343
0
            if (NULL == (super_type = H5T_get_super(dtype)))
344
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get base type for enumerate type");
345
0
            if (NULL == (nat_super_type =
346
0
                             H5T__get_native_type(super_type, direction, struct_align, offset, comp_size)))
347
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "base native type retrieval failed");
348
349
            /* Allocate room for the enum values */
350
0
            if (NULL == (tmp_memb_value = H5MM_calloc(H5T_get_size(super_type))))
351
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory");
352
0
            if (NULL == (memb_value = H5MM_calloc(H5T_get_size(nat_super_type))))
353
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory");
354
355
            /* Construct new enum type based on native type */
356
0
            if (NULL == (new_type = H5T__enum_create(nat_super_type)))
357
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create enum type");
358
359
            /* Find the conversion function */
360
0
            if (NULL == (tpath = H5T_path_find(super_type, nat_super_type)))
361
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL,
362
0
                            "unable to convert between src and dst data types");
363
364
            /* Retrieve member info and insert members into new enum type */
365
0
            if ((snmemb = H5T_get_nmembers(dtype)) <= 0)
366
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "enumerate data type doesn't have any member");
367
0
            H5_CHECKED_ASSIGN(nmemb, unsigned, snmemb, int);
368
0
            for (u = 0; u < nmemb; u++) {
369
0
                if (NULL == (memb_name = H5T__get_member_name(dtype, u)))
370
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member name");
371
0
                if (H5T__get_member_value(dtype, u, tmp_memb_value) < 0)
372
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value");
373
0
                H5MM_memcpy(memb_value, tmp_memb_value, H5T_get_size(super_type));
374
375
0
                if (H5T_convert(tpath, super_type, nat_super_type, (size_t)1, (size_t)0, (size_t)0,
376
0
                                memb_value, NULL) < 0)
377
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value");
378
379
0
                if (H5T__enum_insert(new_type, memb_name, memb_value) < 0)
380
0
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot insert member");
381
0
                memb_name = (char *)H5MM_xfree(memb_name);
382
0
            }
383
0
            memb_value     = H5MM_xfree(memb_value);
384
0
            tmp_memb_value = H5MM_xfree(tmp_memb_value);
385
386
0
            if (H5T_close(nat_super_type) < 0)
387
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "can't close datatype");
388
0
            if (H5T_close(super_type) < 0)
389
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "can't close datatype");
390
391
0
            ret_value = new_type;
392
0
        } /* end case */
393
0
        break;
394
395
0
        case H5T_ARRAY: {
396
0
            int      sarray_rank; /* Array's rank */
397
0
            unsigned array_rank;  /* Array's rank */
398
0
            hsize_t  nelems       = 1;
399
0
            size_t   super_offset = 0;
400
0
            size_t   super_size   = 0;
401
0
            size_t   super_align  = 0;
402
403
            /* Retrieve dimension information for array data type */
404
0
            if ((sarray_rank = H5T__get_array_ndims(dtype)) <= 0)
405
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get dimension rank");
406
0
            H5_CHECKED_ASSIGN(array_rank, unsigned, sarray_rank, int);
407
0
            if (NULL == (dims = (hsize_t *)H5MM_malloc(array_rank * sizeof(hsize_t))))
408
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory");
409
0
            if (H5T__get_array_dims(dtype, dims) < 0)
410
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get dimension size");
411
412
            /* Retrieve base type for array type */
413
0
            if (NULL == (super_type = H5T_get_super(dtype)))
414
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get parent type for array type");
415
0
            if (NULL == (nat_super_type = H5T__get_native_type(super_type, direction, &super_align,
416
0
                                                               &super_offset, &super_size)))
417
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "parent native type retrieval failed");
418
419
            /* Close super type */
420
0
            if (H5T_close_real(super_type) < 0)
421
0
                HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype");
422
423
            /* Create a new array type based on native type */
424
0
            if (NULL == (new_type = H5T__array_create(nat_super_type, array_rank, dims)))
425
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create array type");
426
427
            /* Close base type */
428
0
            if (H5T_close_real(nat_super_type) < 0)
429
0
                HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype");
430
431
0
            for (u = 0; u < array_rank; u++)
432
0
                nelems *= dims[u];
433
0
            H5_CHECK_OVERFLOW(nelems, hsize_t, size_t);
434
0
            if (H5T__cmp_offset(comp_size, offset, super_size, (size_t)nelems, super_align, struct_align) < 0)
435
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
436
437
0
            dims = (hsize_t *)H5MM_xfree(dims);
438
439
0
            ret_value = new_type;
440
0
        } /* end case */
441
0
        break;
442
443
0
        case H5T_VLEN: {
444
0
            size_t vl_align   = 0;
445
0
            size_t vl_size    = 0;
446
0
            size_t super_size = 0;
447
448
            /* Retrieve base type for variable-length type */
449
0
            if (NULL == (super_type = H5T_get_super(dtype)))
450
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get parent type for VL type");
451
            /* Don't need alignment, offset information if this VL isn't a field of compound type.  If it
452
             * is, go to a few steps below to compute the information directly. */
453
0
            if (NULL ==
454
0
                (nat_super_type = H5T__get_native_type(super_type, direction, NULL, NULL, &super_size)))
455
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "parent native type retrieval failed");
456
457
            /* Close super type */
458
0
            if (H5T_close_real(super_type) < 0)
459
0
                HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype");
460
461
            /* Create a new variable-length type based on native type */
462
0
            if (NULL == (new_type = H5T__vlen_create(nat_super_type)))
463
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create VL type");
464
465
            /* Close base type */
466
0
            if (H5T_close_real(nat_super_type) < 0)
467
0
                HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype");
468
469
            /* Update size, offset and compound alignment for parent compound type directly. */
470
0
            vl_align = H5T_HVL_ALIGN_g;
471
0
            vl_size  = sizeof(hvl_t);
472
473
0
            if (H5T__cmp_offset(comp_size, offset, vl_size, (size_t)1, vl_align, struct_align) < 0)
474
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
475
476
0
            ret_value = new_type;
477
0
        } /* end case */
478
0
        break;
479
480
0
        case H5T_COMPLEX: {
481
0
            size_t super_offset = 0;
482
0
            size_t super_size   = 0;
483
0
            size_t super_align  = 0;
484
485
            /* Retrieve base type for complex number type */
486
0
            if (NULL == (super_type = H5T_get_super(dtype)))
487
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get parent type for complex number type");
488
489
0
            if (NULL == (nat_super_type = H5T__get_native_type(super_type, direction, &super_align,
490
0
                                                               &super_offset, &super_size)))
491
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "parent native type retrieval failed");
492
493
            /* Close super type */
494
0
            if (H5T_close_real(super_type) < 0)
495
0
                HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype");
496
497
            /* Create a new complex number type based on native type */
498
0
            if (NULL == (new_type = H5T__complex_create(nat_super_type)))
499
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create complex number type");
500
501
            /* Close base type */
502
0
            if (H5T_close_real(nat_super_type) < 0)
503
0
                HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype");
504
505
0
            if (H5T__cmp_offset(comp_size, offset, new_type->shared->size, 1, super_align, struct_align) < 0)
506
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
507
508
0
            ret_value = new_type;
509
0
        } /* end case */
510
0
        break;
511
512
0
        case H5T_NO_CLASS:
513
0
        case H5T_NCLASSES:
514
0
        default:
515
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "data type doesn't match any native type");
516
0
    } /* end switch */
517
518
0
done:
519
    /* Error cleanup */
520
0
    if (NULL == ret_value) {
521
0
        if (new_type)
522
0
            if (H5T_close_real(new_type) < 0)
523
0
                HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, NULL, "unable to release datatype");
524
525
        /* Free lists for members */
526
0
        if (memb_list) {
527
0
            for (u = 0; u < nmemb; u++)
528
0
                if (memb_list[u] && H5T_close_real(memb_list[u]) < 0)
529
0
                    HDONE_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype");
530
531
0
            memb_list = (H5T_t **)H5MM_xfree(memb_list);
532
0
        } /* end if */
533
0
        memb_offset = (size_t *)H5MM_xfree(memb_offset);
534
0
        if (comp_mname) {
535
0
            for (u = 0; u < nmemb; u++)
536
0
                if (comp_mname[u])
537
0
                    H5MM_xfree(comp_mname[u]);
538
0
            comp_mname = (char **)H5MM_xfree(comp_mname);
539
0
        } /* end if */
540
0
        memb_name      = (char *)H5MM_xfree(memb_name);
541
0
        memb_value     = H5MM_xfree(memb_value);
542
0
        tmp_memb_value = H5MM_xfree(tmp_memb_value);
543
0
        dims           = (hsize_t *)H5MM_xfree(dims);
544
0
    } /* end if */
545
546
0
    FUNC_LEAVE_NOAPI(ret_value)
547
0
} /* end H5T__get_native_type() */
548
549
/*-------------------------------------------------------------------------
550
 * Function:    H5T__get_native_integer
551
 *
552
 * Purpose:     Returns the native integer type of a datatype.
553
 *
554
 * Return:      Success:        Returns the native data type if successful.
555
 *
556
 *              Failure:        negative
557
 *
558
 *-------------------------------------------------------------------------
559
 */
560
static H5T_t *
561
H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, size_t *struct_align,
562
                        size_t *offset, size_t *comp_size)
563
0
{
564
0
    H5T_t *dt;                 /* Appropriate native datatype to copy */
565
0
    hid_t  tid         = (-1); /* Datatype ID of appropriate native datatype */
566
0
    size_t align       = 0;    /* Alignment necessary for native datatype */
567
0
    size_t native_size = 0;    /* Datatype size of the native type */
568
0
    enum match_type {          /* The different kinds of integers we can match */
569
0
                      H5T_NATIVE_INT_MATCH_CHAR,
570
0
                      H5T_NATIVE_INT_MATCH_SHORT,
571
0
                      H5T_NATIVE_INT_MATCH_INT,
572
0
                      H5T_NATIVE_INT_MATCH_LONG,
573
0
                      H5T_NATIVE_INT_MATCH_LLONG,
574
0
                      H5T_NATIVE_INT_MATCH_UNKNOWN
575
0
    } match          = H5T_NATIVE_INT_MATCH_UNKNOWN;
576
0
    H5T_t *ret_value = NULL; /* Return value */
577
578
0
    FUNC_ENTER_PACKAGE
579
580
0
    H5_WARN_DUPLICATED_BRANCHES_OFF
581
0
    if (direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) {
582
0
        if (prec <= H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_SCHAR_g))) {
583
0
            match       = H5T_NATIVE_INT_MATCH_CHAR;
584
0
            native_size = sizeof(char);
585
0
        }
586
0
        else if (prec <= H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_SHORT_g))) {
587
0
            match       = H5T_NATIVE_INT_MATCH_SHORT;
588
0
            native_size = sizeof(short);
589
0
        }
590
0
        else if (prec <= H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_INT_g))) {
591
0
            match       = H5T_NATIVE_INT_MATCH_INT;
592
0
            native_size = sizeof(int);
593
0
        }
594
0
        else if (prec <= H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_LONG_g))) {
595
0
            match       = H5T_NATIVE_INT_MATCH_LONG;
596
0
            native_size = sizeof(long);
597
0
        }
598
0
        else if (prec <= H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_LLONG_g))) {
599
0
            match       = H5T_NATIVE_INT_MATCH_LLONG;
600
0
            native_size = sizeof(long long);
601
0
        }
602
0
        else { /* If no native type matches the queried datatype, simply choose the type of biggest size. */
603
0
            match       = H5T_NATIVE_INT_MATCH_LLONG;
604
0
            native_size = sizeof(long long);
605
0
        }
606
0
    }
607
0
    else if (direction == H5T_DIR_DESCEND) {
608
0
        if (prec > H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_LONG_g))) {
609
0
            match       = H5T_NATIVE_INT_MATCH_LLONG;
610
0
            native_size = sizeof(long long);
611
0
        }
612
0
        else if (prec > H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_INT_g))) {
613
0
            match       = H5T_NATIVE_INT_MATCH_LONG;
614
0
            native_size = sizeof(long);
615
0
        }
616
0
        else if (prec > H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_SHORT_g))) {
617
0
            match       = H5T_NATIVE_INT_MATCH_INT;
618
0
            native_size = sizeof(int);
619
0
        }
620
0
        else if (prec > H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_SCHAR_g))) {
621
0
            match       = H5T_NATIVE_INT_MATCH_SHORT;
622
0
            native_size = sizeof(short);
623
0
        }
624
0
        else {
625
0
            match       = H5T_NATIVE_INT_MATCH_CHAR;
626
0
            native_size = sizeof(char);
627
0
        }
628
0
    }
629
0
    H5_WARN_DUPLICATED_BRANCHES_ON
630
631
    /* Set the appropriate native datatype information */
632
0
    switch (match) {
633
0
        case H5T_NATIVE_INT_MATCH_CHAR:
634
0
            if (sign == H5T_SGN_2)
635
0
                tid = H5T_NATIVE_SCHAR;
636
0
            else
637
0
                tid = H5T_NATIVE_UCHAR;
638
639
0
            align = H5T_NATIVE_SCHAR_ALIGN_g;
640
0
            break;
641
642
0
        case H5T_NATIVE_INT_MATCH_SHORT:
643
0
            if (sign == H5T_SGN_2)
644
0
                tid = H5T_NATIVE_SHORT;
645
0
            else
646
0
                tid = H5T_NATIVE_USHORT;
647
0
            align = H5T_NATIVE_SHORT_ALIGN_g;
648
0
            break;
649
650
0
        case H5T_NATIVE_INT_MATCH_INT:
651
0
            if (sign == H5T_SGN_2)
652
0
                tid = H5T_NATIVE_INT;
653
0
            else
654
0
                tid = H5T_NATIVE_UINT;
655
656
0
            align = H5T_NATIVE_INT_ALIGN_g;
657
0
            break;
658
659
0
        case H5T_NATIVE_INT_MATCH_LONG:
660
0
            if (sign == H5T_SGN_2)
661
0
                tid = H5T_NATIVE_LONG;
662
0
            else
663
0
                tid = H5T_NATIVE_ULONG;
664
665
0
            align = H5T_NATIVE_LONG_ALIGN_g;
666
0
            break;
667
668
0
        case H5T_NATIVE_INT_MATCH_LLONG:
669
0
            if (sign == H5T_SGN_2)
670
0
                tid = H5T_NATIVE_LLONG;
671
0
            else
672
0
                tid = H5T_NATIVE_ULLONG;
673
674
0
            align = H5T_NATIVE_LLONG_ALIGN_g;
675
0
            break;
676
677
0
        case H5T_NATIVE_INT_MATCH_UNKNOWN:
678
0
        default:
679
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "Unknown native integer match");
680
0
    } /* end switch */
681
682
    /* Create new native type */
683
0
    assert(tid >= 0);
684
0
    if (NULL == (dt = (H5T_t *)H5I_object(tid)))
685
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
686
687
0
    if (NULL == (ret_value = H5T_copy(dt, H5T_COPY_TRANSIENT)))
688
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy type");
689
690
    /* compute size and offset of compound type member. */
691
0
    if (H5T__cmp_offset(comp_size, offset, native_size, (size_t)1, align, struct_align) < 0)
692
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
693
694
0
done:
695
0
    FUNC_LEAVE_NOAPI(ret_value)
696
0
} /* end H5T__get_native_integer() */
697
698
/*-------------------------------------------------------------------------
699
 * Function:    H5T__get_native_float
700
 *
701
 * Purpose:     Returns the native float type of a datatype.
702
 *
703
 * Return:      Success:        Returns the native data type if successful.
704
 *
705
 *              Failure:        negative
706
 *
707
 *-------------------------------------------------------------------------
708
 */
709
static H5T_t *
710
H5T__get_native_float(const H5T_t *dtype, H5T_direction_t direction, size_t *struct_align, size_t *offset,
711
                      size_t *comp_size)
712
0
{
713
0
    H5T_t *dt          = NULL; /* Appropriate native datatype to copy */
714
0
    hid_t  tid         = (-1); /* Datatype ID of appropriate native datatype */
715
0
    size_t size        = 0;    /* Size of datatype to make native */
716
0
    size_t align       = 0;    /* Alignment necessary for native datatype */
717
0
    size_t native_size = 0;    /* Datatype size of the native type */
718
0
    enum match_type {          /* The different kinds of floating point types we can match */
719
0
                      H5T_NATIVE_FLOAT_MATCH_FLOAT16,
720
0
                      H5T_NATIVE_FLOAT_MATCH_FLOAT,
721
0
                      H5T_NATIVE_FLOAT_MATCH_DOUBLE,
722
0
                      H5T_NATIVE_FLOAT_MATCH_LDOUBLE,
723
0
                      H5T_NATIVE_FLOAT_MATCH_UNKNOWN
724
0
    } match          = H5T_NATIVE_FLOAT_MATCH_UNKNOWN;
725
0
    H5T_t *ret_value = NULL; /* Return value */
726
727
0
    FUNC_ENTER_PACKAGE
728
729
0
    if (0 == (size = H5T_get_size(dtype)))
730
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid size");
731
732
0
    H5_WARN_DUPLICATED_BRANCHES_OFF
733
0
    if (direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) {
734
0
        if (size == 1) {
735
#ifdef H5_HAVE__FLOAT16
736
            /*
737
             * When _Float16 support is available, map specific types to
738
             * the native _Float16 type and all other types of this size
739
             * group without a specific carve-out to the native float type.
740
             */
741
            H5T_t *f8_e4m3_dt = NULL; /* Datatype for FP8 E4M3 */
742
            H5T_t *f8_e5m2_dt = NULL; /* Datatype for FP8 E5M2 */
743
            H5T_t *f6_e2m3_dt = NULL; /* Datatype for FP6 E2M3 */
744
            H5T_t *f6_e3m2_dt = NULL; /* Datatype for FP6 E3M2 */
745
            H5T_t *f4_e2m1_dt = NULL; /* Datatype for FP4 E2M1 */
746
747
            if (NULL == (f8_e4m3_dt = H5I_object(H5T_FLOAT_F8E4M3)))
748
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
749
            if (NULL == (f8_e5m2_dt = H5I_object(H5T_FLOAT_F8E5M2)))
750
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
751
            if (NULL == (f6_e2m3_dt = H5I_object(H5T_FLOAT_F6E2M3)))
752
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
753
            if (NULL == (f6_e3m2_dt = H5I_object(H5T_FLOAT_F6E3M2)))
754
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
755
            if (NULL == (f4_e2m1_dt = H5I_object(H5T_FLOAT_F4E2M1)))
756
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
757
758
            if (0 == H5T_cmp(dtype, f8_e4m3_dt, false) || 0 == H5T_cmp(dtype, f8_e5m2_dt, false) ||
759
                0 == H5T_cmp(dtype, f6_e2m3_dt, false) || 0 == H5T_cmp(dtype, f6_e3m2_dt, false) ||
760
                0 == H5T_cmp(dtype, f4_e2m1_dt, false)) {
761
                match       = H5T_NATIVE_FLOAT_MATCH_FLOAT16;
762
                native_size = sizeof(H5__Float16);
763
            }
764
            else {
765
                match       = H5T_NATIVE_FLOAT_MATCH_FLOAT;
766
                native_size = sizeof(float);
767
            }
768
#else
769
            /* When _Float16 support is not available, just map all types of
770
             * this size group without a specific carve-out to the native
771
             * float type.
772
             */
773
0
            match       = H5T_NATIVE_FLOAT_MATCH_FLOAT;
774
0
            native_size = sizeof(float);
775
0
#endif
776
0
        }
777
0
        else if (size == 2) {
778
#ifdef H5_HAVE__FLOAT16
779
            /*
780
             * When _Float16 support is available, map _Float16-like types
781
             * to the native type and all other types of this size group
782
             * without a specific carve-out to the native float type.
783
             */
784
            H5T_t *f16_le_dt = NULL; /* Datatype for little-endian float16 */
785
            H5T_t *f16_be_dt = NULL; /* Datatype for big-endian float16 */
786
787
            if (NULL == (f16_le_dt = H5I_object(H5T_IEEE_F16LE)))
788
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
789
            if (NULL == (f16_be_dt = H5I_object(H5T_IEEE_F16BE)))
790
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
791
792
            if (0 == H5T_cmp(dtype, f16_le_dt, false) || 0 == H5T_cmp(dtype, f16_be_dt, false)) {
793
                match       = H5T_NATIVE_FLOAT_MATCH_FLOAT16;
794
                native_size = sizeof(H5__Float16);
795
            }
796
            else {
797
                match       = H5T_NATIVE_FLOAT_MATCH_FLOAT;
798
                native_size = sizeof(float);
799
            }
800
#else
801
            /* When _Float16 support is not available, just map all types of
802
             * this size group without a specific carve-out to the native
803
             * float type.
804
             */
805
0
            match       = H5T_NATIVE_FLOAT_MATCH_FLOAT;
806
0
            native_size = sizeof(float);
807
0
#endif
808
0
        }
809
0
        else if (size <= sizeof(float)) {
810
0
            match       = H5T_NATIVE_FLOAT_MATCH_FLOAT;
811
0
            native_size = sizeof(float);
812
0
        }
813
0
        else if (size <= sizeof(double)) {
814
0
            match       = H5T_NATIVE_FLOAT_MATCH_DOUBLE;
815
0
            native_size = sizeof(double);
816
0
        }
817
0
        else if (size <= sizeof(long double)) {
818
0
            match       = H5T_NATIVE_FLOAT_MATCH_LDOUBLE;
819
0
            native_size = sizeof(long double);
820
0
        }
821
0
        else { /* If not match, return the biggest datatype */
822
0
            match       = H5T_NATIVE_FLOAT_MATCH_LDOUBLE;
823
0
            native_size = sizeof(long double);
824
0
        }
825
0
    }
826
0
    else {
827
0
        if (size > sizeof(double)) {
828
0
            match       = H5T_NATIVE_FLOAT_MATCH_LDOUBLE;
829
0
            native_size = sizeof(long double);
830
0
        }
831
0
        else if (size > sizeof(float)) {
832
0
            match       = H5T_NATIVE_FLOAT_MATCH_DOUBLE;
833
0
            native_size = sizeof(double);
834
0
        }
835
0
        else {
836
#ifdef H5_HAVE__FLOAT16
837
            if (size > sizeof(H5__Float16)) {
838
                match       = H5T_NATIVE_FLOAT_MATCH_FLOAT;
839
                native_size = sizeof(float);
840
            }
841
            else if (size > 1) {
842
                /*
843
                 * When _Float16 support is available, map _Float16-like types
844
                 * to the native type and all other types of this size group
845
                 * without a specific carve-out to the native float type.
846
                 */
847
                H5T_t *f16_le_dt = NULL; /* Datatype for little-endian float16 */
848
                H5T_t *f16_be_dt = NULL; /* Datatype for big-endian float16 */
849
850
                if (NULL == (f16_le_dt = H5I_object(H5T_IEEE_F16LE)))
851
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
852
                if (NULL == (f16_be_dt = H5I_object(H5T_IEEE_F16BE)))
853
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
854
855
                if (0 == H5T_cmp(dtype, f16_le_dt, false) || 0 == H5T_cmp(dtype, f16_be_dt, false)) {
856
                    match       = H5T_NATIVE_FLOAT_MATCH_FLOAT16;
857
                    native_size = sizeof(H5__Float16);
858
                }
859
                else {
860
                    match       = H5T_NATIVE_FLOAT_MATCH_FLOAT;
861
                    native_size = sizeof(float);
862
                }
863
            }
864
            else {
865
                /*
866
                 * When _Float16 support is available, map specific types to
867
                 * the native _Float16 type and all other types of this size
868
                 * group without a specific carve-out to the native float type.
869
                 */
870
                H5T_t *f8_e4m3_dt = NULL; /* Datatype for FP8 E4M3 */
871
                H5T_t *f8_e5m2_dt = NULL; /* Datatype for FP8 E5M2 */
872
                H5T_t *f6_e2m3_dt = NULL; /* Datatype for FP6 E2M3 */
873
                H5T_t *f6_e3m2_dt = NULL; /* Datatype for FP6 E3M2 */
874
                H5T_t *f4_e2m1_dt = NULL; /* Datatype for FP4 E2M1 */
875
876
                if (NULL == (f8_e4m3_dt = H5I_object(H5T_FLOAT_F8E4M3)))
877
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
878
                if (NULL == (f8_e5m2_dt = H5I_object(H5T_FLOAT_F8E5M2)))
879
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
880
                if (NULL == (f6_e2m3_dt = H5I_object(H5T_FLOAT_F6E2M3)))
881
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
882
                if (NULL == (f6_e3m2_dt = H5I_object(H5T_FLOAT_F6E3M2)))
883
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
884
                if (NULL == (f4_e2m1_dt = H5I_object(H5T_FLOAT_F4E2M1)))
885
                    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
886
887
                if (0 == H5T_cmp(dtype, f8_e4m3_dt, false) || 0 == H5T_cmp(dtype, f8_e5m2_dt, false) ||
888
                    0 == H5T_cmp(dtype, f6_e2m3_dt, false) || 0 == H5T_cmp(dtype, f6_e3m2_dt, false) ||
889
                    0 == H5T_cmp(dtype, f4_e2m1_dt, false)) {
890
                    match       = H5T_NATIVE_FLOAT_MATCH_FLOAT16;
891
                    native_size = sizeof(H5__Float16);
892
                }
893
                else {
894
                    match       = H5T_NATIVE_FLOAT_MATCH_FLOAT;
895
                    native_size = sizeof(float);
896
                }
897
            }
898
#else
899
            /* When _Float16 support is not available, just map all types of
900
             * this size group without a specific carve-out to the native
901
             * float type.
902
             */
903
0
            match       = H5T_NATIVE_FLOAT_MATCH_FLOAT;
904
0
            native_size = sizeof(float);
905
0
#endif
906
0
        }
907
0
    }
908
0
    H5_WARN_DUPLICATED_BRANCHES_ON
909
910
    /* Set the appropriate native floating point information */
911
0
    switch (match) {
912
0
        case H5T_NATIVE_FLOAT_MATCH_FLOAT16:
913
0
            tid   = H5T_NATIVE_FLOAT16;
914
0
            align = H5T_NATIVE_FLOAT16_ALIGN_g;
915
0
            break;
916
917
0
        case H5T_NATIVE_FLOAT_MATCH_FLOAT:
918
0
            tid   = H5T_NATIVE_FLOAT;
919
0
            align = H5T_NATIVE_FLOAT_ALIGN_g;
920
0
            break;
921
922
0
        case H5T_NATIVE_FLOAT_MATCH_DOUBLE:
923
0
            tid   = H5T_NATIVE_DOUBLE;
924
0
            align = H5T_NATIVE_DOUBLE_ALIGN_g;
925
0
            break;
926
927
0
        case H5T_NATIVE_FLOAT_MATCH_LDOUBLE:
928
0
            tid   = H5T_NATIVE_LDOUBLE;
929
0
            align = H5T_NATIVE_LDOUBLE_ALIGN_g;
930
0
            break;
931
932
0
        case H5T_NATIVE_FLOAT_MATCH_UNKNOWN:
933
0
        default:
934
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "Unknown native floating-point match");
935
0
    } /* end switch */
936
937
    /* Create new native type */
938
0
    assert(tid >= 0);
939
0
    if (NULL == (dt = (H5T_t *)H5I_object(tid)))
940
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
941
0
    if ((ret_value = H5T_copy(dt, H5T_COPY_TRANSIENT)) == NULL)
942
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type");
943
944
    /* compute offset of compound type member. */
945
0
    if (H5T__cmp_offset(comp_size, offset, native_size, (size_t)1, align, struct_align) < 0)
946
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
947
948
0
done:
949
0
    FUNC_LEAVE_NOAPI(ret_value)
950
0
} /* end H5T__get_native_float() */
951
952
/*-------------------------------------------------------------------------
953
 * Function:    H5T__get_native_bitfield
954
 *
955
 * Purpose:     Returns the native bitfield type of a datatype.  Bitfield
956
 *              is similar to unsigned integer.
957
 *
958
 * Return:      Success:        Returns the native data type if successful.
959
 *
960
 *              Failure:        negative
961
 *
962
 *-------------------------------------------------------------------------
963
 */
964
static H5T_t *
965
H5T__get_native_bitfield(size_t prec, H5T_direction_t direction, size_t *struct_align, size_t *offset,
966
                         size_t *comp_size)
967
0
{
968
0
    H5T_t *dt;                 /* Appropriate native datatype to copy */
969
0
    hid_t  tid         = (-1); /* Datatype ID of appropriate native datatype */
970
0
    size_t align       = 0;    /* Alignment necessary for native datatype */
971
0
    size_t native_size = 0;    /* Datatype size of the native type */
972
0
    H5T_t *ret_value   = NULL; /* Return value */
973
974
0
    FUNC_ENTER_PACKAGE
975
976
0
    H5_WARN_DUPLICATED_BRANCHES_OFF
977
0
    if (direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) {
978
0
        if (prec <= H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_B8_g))) {
979
0
            tid         = H5T_NATIVE_B8;
980
0
            native_size = 1;
981
0
            align       = H5T_NATIVE_UINT8_ALIGN_g;
982
0
        }
983
0
        else if (prec <= H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_B16_g))) {
984
0
            tid         = H5T_NATIVE_B16;
985
0
            native_size = 2;
986
0
            align       = H5T_NATIVE_UINT16_ALIGN_g;
987
0
        }
988
0
        else if (prec <= H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_B32_g))) {
989
0
            tid         = H5T_NATIVE_B32;
990
0
            native_size = 4;
991
0
            align       = H5T_NATIVE_UINT32_ALIGN_g;
992
0
        }
993
0
        else if (prec <= H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_B64_g))) {
994
0
            tid         = H5T_NATIVE_B64;
995
0
            native_size = 8;
996
0
            align       = H5T_NATIVE_UINT64_ALIGN_g;
997
0
        }
998
0
        else { /* If no native type matches the queried datatype, simply choose the type of biggest size. */
999
0
            tid         = H5T_NATIVE_B64;
1000
0
            native_size = 8;
1001
0
            align       = H5T_NATIVE_UINT64_ALIGN_g;
1002
0
        }
1003
0
    }
1004
0
    else if (direction == H5T_DIR_DESCEND) {
1005
0
        if (prec > H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_B32_g))) {
1006
0
            tid         = H5T_NATIVE_B64;
1007
0
            native_size = 8;
1008
0
            align       = H5T_NATIVE_UINT64_ALIGN_g;
1009
0
        }
1010
0
        else if (prec > H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_B16_g))) {
1011
0
            tid         = H5T_NATIVE_B32;
1012
0
            native_size = 4;
1013
0
            align       = H5T_NATIVE_UINT32_ALIGN_g;
1014
0
        }
1015
0
        else if (prec > H5T_get_precision((H5T_t *)H5I_object(H5T_NATIVE_B8_g))) {
1016
0
            tid         = H5T_NATIVE_B16;
1017
0
            native_size = 2;
1018
0
            align       = H5T_NATIVE_UINT16_ALIGN_g;
1019
0
        }
1020
0
        else {
1021
0
            tid         = H5T_NATIVE_B8;
1022
0
            native_size = 1;
1023
0
            align       = H5T_NATIVE_UINT8_ALIGN_g;
1024
0
        }
1025
0
    }
1026
0
    H5_WARN_DUPLICATED_BRANCHES_ON
1027
1028
    /* Create new native type */
1029
0
    assert(tid >= 0);
1030
0
    if (NULL == (dt = (H5T_t *)H5I_object(tid)))
1031
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
1032
1033
0
    if ((ret_value = H5T_copy(dt, H5T_COPY_TRANSIENT)) == NULL)
1034
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy type");
1035
1036
    /* compute size and offset of compound type member. */
1037
0
    if (H5T__cmp_offset(comp_size, offset, native_size, (size_t)1, align, struct_align) < 0)
1038
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
1039
1040
0
done:
1041
0
    FUNC_LEAVE_NOAPI(ret_value)
1042
0
} /* end H5T__get_native_bitfield() */
1043
1044
/*-------------------------------------------------------------------------
1045
 * Function:    H5T__cmp_offset
1046
 *
1047
 * Purpose:    This function is only for convenience.  It computes the
1048
 *              compound type size, offset of the member being considered
1049
 *              and the alignment for the whole compound type.
1050
 *
1051
 * Return:    Success:        Non-negative value.
1052
 *
1053
 *            Failure:        Negative value.
1054
 *
1055
 *-------------------------------------------------------------------------
1056
 */
1057
static herr_t
1058
H5T__cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, size_t nelems, size_t align,
1059
                size_t *struct_align)
1060
0
{
1061
0
    FUNC_ENTER_PACKAGE_NOERR
1062
1063
0
    if (offset && comp_size) {
1064
0
        if (align > 1 && *comp_size % align) {
1065
            /* Add alignment value */
1066
0
            *offset = *comp_size + (align - *comp_size % align);
1067
0
            *comp_size += (align - *comp_size % align);
1068
0
        } /* end if */
1069
0
        else
1070
0
            *offset = *comp_size;
1071
1072
        /* compute size of compound type member. */
1073
0
        *comp_size += nelems * elem_size;
1074
0
    } /* end if */
1075
1076
0
    if (struct_align && *struct_align < align)
1077
0
        *struct_align = align;
1078
1079
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1080
0
} /* end H5T__cmp_offset() */
1081
1082
44
#define TAG_ALIGNMENT(tag) (offsetof(alignments_t, tag.x) - offsetof(alignments_t, tag))
1083
1084
/* clang-format off */
1085
36
#define NATIVE_ENTRY_INITIALIZER(tag, type, precision, has_sign) {  \
1086
36
  .alignmentp = &H5T_NATIVE_##tag##_ALIGN_g                         \
1087
36
, .alignment = TAG_ALIGNMENT(tag)                                   \
1088
36
, .hidp = &H5T_NATIVE_##tag##_g                                     \
1089
36
, .size = sizeof(type)                                              \
1090
36
, .atomic = {                                                       \
1091
36
      .offset   = 0                                                 \
1092
36
    , .prec     = (precision != 0) ? precision : (sizeof(type) * 8) \
1093
36
    , .lsb_pad  = H5T_PAD_ZERO                                      \
1094
36
    , .msb_pad  = H5T_PAD_ZERO                                      \
1095
36
    , .u.i.sign = has_sign ? H5T_SGN_2 : H5T_SGN_NONE               \
1096
36
    }                                                               \
1097
36
}
1098
/* clang-format on */
1099
1100
static H5T_order_t
1101
get_host_byte_order(void)
1102
1
{
1103
1
    static const union {
1104
1
        uint64_t u64;
1105
1
        char     byte[8];
1106
1
    } endian_exemplar = {.byte = {1}};
1107
1108
1
    return (endian_exemplar.u64 == 1) ? H5T_ORDER_LE : H5T_ORDER_BE;
1109
1
}
1110
1111
/* Establish `H5T_t`s for C99 integer types including fixed- and
1112
 * minimum-width types (uint16_t, uint_least16_t, uint_fast16_t, ...).
1113
 *
1114
 * Also establish alignment for some miscellaneous types: pointers,
1115
 * HDF5 references, and so on.
1116
 */
1117
herr_t
1118
H5T__init_native_internal(void)
1119
1
{
1120
    /* Here we construct a type that lets us find alignment constraints
1121
     * without using the alignof operator, which is not available in C99.
1122
     *
1123
     * Between each sub-struct's `char` member `c` and member `x`, the
1124
     * compiler must insert padding to ensure proper alignment of `x`.
1125
     * We can find the alignment constraint of each `x` by looking at
1126
     * its offset from the beginning of its sub-struct.
1127
     */
1128
1
    typedef struct {
1129
1
        struct {
1130
1
            char        c;
1131
1
            signed char x;
1132
1
        } SCHAR;
1133
1
        struct {
1134
1
            char          c;
1135
1
            unsigned char x;
1136
1
        } UCHAR;
1137
1
        struct {
1138
1
            char  c;
1139
1
            short x;
1140
1
        } SHORT;
1141
1
        struct {
1142
1
            char           c;
1143
1
            unsigned short x;
1144
1
        } USHORT;
1145
1
        struct {
1146
1
            char c;
1147
1
            int  x;
1148
1
        } INT;
1149
1
        struct {
1150
1
            char         c;
1151
1
            unsigned int x;
1152
1
        } UINT;
1153
1
        struct {
1154
1
            char c;
1155
1
            long x;
1156
1
        } LONG;
1157
1
        struct {
1158
1
            char          c;
1159
1
            unsigned long x;
1160
1
        } ULONG;
1161
1
        struct {
1162
1
            char      c;
1163
1
            long long x;
1164
1
        } LLONG;
1165
1
        struct {
1166
1
            char               c;
1167
1
            unsigned long long x;
1168
1
        } ULLONG;
1169
1
        struct {
1170
1
            char   c;
1171
1
            int8_t x;
1172
1
        } INT8;
1173
1
        struct {
1174
1
            char    c;
1175
1
            uint8_t x;
1176
1
        } UINT8;
1177
1
        struct {
1178
1
            char         c;
1179
1
            int_least8_t x;
1180
1
        } INT_LEAST8;
1181
1
        struct {
1182
1
            char          c;
1183
1
            uint_least8_t x;
1184
1
        } UINT_LEAST8;
1185
1
        struct {
1186
1
            char        c;
1187
1
            int_fast8_t x;
1188
1
        } INT_FAST8;
1189
1
        struct {
1190
1
            char         c;
1191
1
            uint_fast8_t x;
1192
1
        } UINT_FAST8;
1193
1
        struct {
1194
1
            char    c;
1195
1
            int16_t x;
1196
1
        } INT16;
1197
1
        struct {
1198
1
            char     c;
1199
1
            uint16_t x;
1200
1
        } UINT16;
1201
1
        struct {
1202
1
            char          c;
1203
1
            int_least16_t x;
1204
1
        } INT_LEAST16;
1205
1
        struct {
1206
1
            char           c;
1207
1
            uint_least16_t x;
1208
1
        } UINT_LEAST16;
1209
1
        struct {
1210
1
            char         c;
1211
1
            int_fast16_t x;
1212
1
        } INT_FAST16;
1213
1
        struct {
1214
1
            char          c;
1215
1
            uint_fast16_t x;
1216
1
        } UINT_FAST16;
1217
1
        struct {
1218
1
            char    c;
1219
1
            int32_t x;
1220
1
        } INT32;
1221
1
        struct {
1222
1
            char     c;
1223
1
            uint32_t x;
1224
1
        } UINT32;
1225
1
        struct {
1226
1
            char          c;
1227
1
            int_least32_t x;
1228
1
        } INT_LEAST32;
1229
1
        struct {
1230
1
            char           c;
1231
1
            uint_least32_t x;
1232
1
        } UINT_LEAST32;
1233
1
        struct {
1234
1
            char         c;
1235
1
            int_fast32_t x;
1236
1
        } INT_FAST32;
1237
1
        struct {
1238
1
            char          c;
1239
1
            uint_fast32_t x;
1240
1
        } UINT_FAST32;
1241
1
        struct {
1242
1
            char    c;
1243
1
            int64_t x;
1244
1
        } INT64;
1245
1
        struct {
1246
1
            char     c;
1247
1
            uint64_t x;
1248
1
        } UINT64;
1249
1
        struct {
1250
1
            char          c;
1251
1
            int_least64_t x;
1252
1
        } INT_LEAST64;
1253
1
        struct {
1254
1
            char           c;
1255
1
            uint_least64_t x;
1256
1
        } UINT_LEAST64;
1257
1
        struct {
1258
1
            char         c;
1259
1
            int_fast64_t x;
1260
1
        } INT_FAST64;
1261
1
        struct {
1262
1
            char          c;
1263
1
            uint_fast64_t x;
1264
1
        } UINT_FAST64;
1265
1
        struct {
1266
1
            char  c;
1267
1
            void *x;
1268
1
        } pointer;
1269
1
        struct {
1270
1
            char  c;
1271
1
            hvl_t x;
1272
1
        } hvl;
1273
1
        struct {
1274
1
            char       c;
1275
1
            hobj_ref_t x;
1276
1
        } hobjref;
1277
1
        struct {
1278
1
            char            c;
1279
1
            hdset_reg_ref_t x;
1280
1
        } hdsetregref;
1281
1
        struct {
1282
1
            char      c;
1283
1
            H5R_ref_t x;
1284
1
        } ref;
1285
1
    } alignments_t;
1286
1287
    /* Describe a C99 type, `type`, and tell where to write its
1288
     * H5T_t identifier and alignment.  Tables of these descriptions
1289
     * drive the initialization of `H5T_t`s.
1290
     */
1291
1
    typedef struct {
1292
        /* Pointer to the global variable that receives the
1293
         * alignment of `type`:
1294
         */
1295
1
        size_t *alignmentp;
1296
1
        size_t  alignment; // natural alignment of `type`
1297
        /* Pointer to the global variable that receives the
1298
         * identifier for `type`'s H5T_t:
1299
         */
1300
1
        hid_t       *hidp;
1301
1
        size_t       size;   // sizeof(`type`)
1302
1
        H5T_atomic_t atomic; // `type` facts such as signedness
1303
1
    } native_int_t;
1304
1305
1
    typedef struct {
1306
1
        const native_int_t *table;
1307
1
        size_t              nelmts;
1308
1
    } native_int_table_t;
1309
1310
    /* clang-format off */
1311
1312
    /* Version 19.10 of the PGI C compiler croaks on the following
1313
     * tables if they are `static`, so make them `static` only if
1314
     * some other compiler is used.
1315
     */
1316
#if defined(__PGIC__) && __PGIC__ == 19 && __PGIC_MINOR__ == 10
1317
#   define static_unless_buggy_pgic
1318
#else
1319
4
#   define static_unless_buggy_pgic static
1320
1
#endif
1321
1322
    /* The library compiles with a limit on `static` object size, so
1323
     * I broke this table into three.
1324
     */
1325
1
    static_unless_buggy_pgic const native_int_t table1[] = {
1326
1
      NATIVE_ENTRY_INITIALIZER(SCHAR, signed char, 0, true)
1327
1
    , NATIVE_ENTRY_INITIALIZER(UCHAR, unsigned char, 0, false)
1328
1
    , NATIVE_ENTRY_INITIALIZER(SHORT, short, 0, true)
1329
1
    , NATIVE_ENTRY_INITIALIZER(USHORT, unsigned short, 0, false)
1330
1
    , NATIVE_ENTRY_INITIALIZER(INT, int, 0, true)
1331
1
    , NATIVE_ENTRY_INITIALIZER(UINT, unsigned int, 0, false)
1332
1
    , NATIVE_ENTRY_INITIALIZER(INT, int, 0, true)
1333
1
    , NATIVE_ENTRY_INITIALIZER(UINT, unsigned int, 0, false)
1334
1
    , NATIVE_ENTRY_INITIALIZER(LONG, long, 0, true)
1335
1
    , NATIVE_ENTRY_INITIALIZER(ULONG, unsigned long, 0, false)
1336
1
    , NATIVE_ENTRY_INITIALIZER(LLONG, long long, 0, true)
1337
1
    , NATIVE_ENTRY_INITIALIZER(ULLONG, unsigned long long, 0, false)
1338
1
    };
1339
1
    static_unless_buggy_pgic const native_int_t table2[] = {
1340
1
      NATIVE_ENTRY_INITIALIZER(INT8, int8_t, 0, true)
1341
1
    , NATIVE_ENTRY_INITIALIZER(UINT8, uint8_t, 0, false)
1342
1
    , NATIVE_ENTRY_INITIALIZER(INT_LEAST8, int_least8_t, 0, true)
1343
1
    , NATIVE_ENTRY_INITIALIZER(UINT_LEAST8, uint_least8_t, 0, false)
1344
1
    , NATIVE_ENTRY_INITIALIZER(INT_FAST8, int_fast8_t, 0, true)
1345
1
    , NATIVE_ENTRY_INITIALIZER(UINT_FAST8, uint_fast8_t, 0, false)
1346
1
    , NATIVE_ENTRY_INITIALIZER(INT16, int16_t, 0, true)
1347
1
    , NATIVE_ENTRY_INITIALIZER(UINT16, uint16_t, 0, false)
1348
1
    , NATIVE_ENTRY_INITIALIZER(INT_LEAST16, int_least16_t, 0, true)
1349
1
    , NATIVE_ENTRY_INITIALIZER(UINT_LEAST16, uint_least16_t, 0, false)
1350
1
    , NATIVE_ENTRY_INITIALIZER(INT_FAST16, int_fast16_t, 0, true)
1351
1
    , NATIVE_ENTRY_INITIALIZER(UINT_FAST16, uint_fast16_t, 0, false)
1352
1
    };
1353
1
    static_unless_buggy_pgic const native_int_t table3[] = {
1354
1
      NATIVE_ENTRY_INITIALIZER(INT32, int32_t, 0, true)
1355
1
    , NATIVE_ENTRY_INITIALIZER(UINT32, uint32_t, 0, false)
1356
1
    , NATIVE_ENTRY_INITIALIZER(INT_LEAST32, int_least32_t, 0, true)
1357
1
    , NATIVE_ENTRY_INITIALIZER(UINT_LEAST32, uint_least32_t, 0, false)
1358
1
    , NATIVE_ENTRY_INITIALIZER(INT_FAST32, int_fast32_t, 0, true)
1359
1
    , NATIVE_ENTRY_INITIALIZER(UINT_FAST32, uint_fast32_t, 0, false)
1360
1
    , NATIVE_ENTRY_INITIALIZER(INT64, int64_t, 0, true)
1361
1
    , NATIVE_ENTRY_INITIALIZER(UINT64, uint64_t, 0, false)
1362
1
    , NATIVE_ENTRY_INITIALIZER(INT_LEAST64, int_least64_t, 0, true)
1363
1
    , NATIVE_ENTRY_INITIALIZER(UINT_LEAST64, uint_least64_t, 0, false)
1364
1
    , NATIVE_ENTRY_INITIALIZER(INT_FAST64, int_fast64_t, 0, true)
1365
1
    , NATIVE_ENTRY_INITIALIZER(UINT_FAST64, uint_fast64_t, 0, false)
1366
1
    };
1367
1
    static_unless_buggy_pgic const native_int_table_t table_table[] = {
1368
1
      {table1, NELMTS(table1)}
1369
1
    , {table2, NELMTS(table2)}
1370
1
    , {table3, NELMTS(table3)}
1371
1
    };
1372
1
#undef static_unless_buggy_pgic
1373
    /* clang-format on */
1374
1375
1
    size_t      i, j;
1376
1
    H5T_order_t byte_order = get_host_byte_order();
1377
1378
4
    for (i = 0; i < NELMTS(table_table); i++) {
1379
3
        const native_int_t *table  = table_table[i].table;
1380
3
        size_t              nelmts = table_table[i].nelmts;
1381
1382
        /* For each C99 type in `table`, create its H5T_t,
1383
         * register a hid_t for the H5T_t, and record the type's
1384
         * alignment and hid_t in the variables named by the
1385
         * table.
1386
         */
1387
39
        for (j = 0; j < nelmts; j++) {
1388
36
            H5T_t *dt;
1389
1390
36
            if (NULL == (dt = H5T__alloc()))
1391
0
                return FAIL;
1392
1393
36
            dt->shared->state          = H5T_STATE_IMMUTABLE;
1394
36
            dt->shared->type           = H5T_INTEGER;
1395
36
            dt->shared->size           = table[j].size;
1396
36
            dt->shared->u.atomic       = table[j].atomic;
1397
36
            dt->shared->u.atomic.order = byte_order;
1398
36
            *table[j].alignmentp       = table[j].alignment;
1399
1400
36
            if ((*table[j].hidp = H5I_register(H5I_DATATYPE, dt, false)) < 0)
1401
0
                return FAIL;
1402
36
        }
1403
3
    }
1404
1405
1
    H5T_POINTER_ALIGN_g     = TAG_ALIGNMENT(pointer);
1406
1
    H5T_HVL_ALIGN_g         = TAG_ALIGNMENT(hvl);
1407
1
    H5T_HOBJREF_ALIGN_g     = TAG_ALIGNMENT(hobjref);
1408
1
    H5T_HDSETREGREF_ALIGN_g = TAG_ALIGNMENT(hdsetregref);
1409
1
    H5T_REF_ALIGN_g         = TAG_ALIGNMENT(ref);
1410
1411
1
    return SUCCEED;
1412
1
}
1413
1414
#ifdef H5_HAVE_COMPLEX_NUMBERS
1415
/*-------------------------------------------------------------------------
1416
 * Function:    H5T__init_native_complex_types
1417
 *
1418
 * Purpose:     Initializes native complex number datatypes
1419
 *
1420
 * Return:      Non-negative on success/Negative on failure
1421
 *-------------------------------------------------------------------------
1422
 */
1423
herr_t
1424
H5T__init_native_complex_types(void)
1425
1
{
1426
1
    H5T_t *native_float   = NULL; /* Datatype structure for native float */
1427
1
    H5T_t *native_double  = NULL; /* Datatype structure for native double */
1428
1
    H5T_t *native_ldouble = NULL; /* Datatype structure for native long double */
1429
1
    H5T_t *dt             = NULL;
1430
1
    herr_t ret_value      = SUCCEED;
1431
1432
1
    FUNC_ENTER_PACKAGE
1433
1434
    /* Assumes that native floating-point types are already initialized */
1435
1
    assert(H5T_NATIVE_FLOAT_g != H5I_INVALID_HID);
1436
1
    assert(H5T_NATIVE_DOUBLE_g != H5I_INVALID_HID);
1437
1
    assert(H5T_NATIVE_LDOUBLE_g != H5I_INVALID_HID);
1438
1439
    /* Declare structure for finding alignment of each type */
1440
1
    typedef struct {
1441
1
        struct {
1442
1
            char             c;
1443
1
            H5_float_complex x;
1444
1
        } FLOAT_COMPLEX;
1445
1
        struct {
1446
1
            char              c;
1447
1
            H5_double_complex x;
1448
1
        } DOUBLE_COMPLEX;
1449
1
        struct {
1450
1
            char               c;
1451
1
            H5_ldouble_complex x;
1452
1
        } LDOUBLE_COMPLEX;
1453
1
    } alignments_t;
1454
1455
1
    if (NULL == (native_float = (H5T_t *)H5I_object(H5T_NATIVE_FLOAT_g)))
1456
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get datatype structure for native float type");
1457
1
    if (NULL == (native_double = (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE_g)))
1458
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get datatype structure for native double type");
1459
1
    if (NULL == (native_ldouble = (H5T_t *)H5I_object(H5T_NATIVE_LDOUBLE_g)))
1460
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get datatype structure for native long double type");
1461
1462
    /* H5T_NATIVE_FLOAT_COMPLEX */
1463
1464
1
    if (NULL == (dt = H5T__complex_create(native_float)))
1465
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't create native float complex datatype");
1466
1
    dt->shared->state = H5T_STATE_IMMUTABLE;
1467
1468
    /* Register the type and set global variables */
1469
1
    if ((H5T_NATIVE_FLOAT_COMPLEX_g = H5I_register(H5I_DATATYPE, dt, false)) < 0)
1470
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't register ID for native float complex datatype");
1471
1
    H5T_NATIVE_FLOAT_COMPLEX_ALIGN_g = TAG_ALIGNMENT(FLOAT_COMPLEX);
1472
1473
1
    dt = NULL;
1474
1475
    /* H5T_NATIVE_DOUBLE_COMPLEX */
1476
1477
1
    if (NULL == (dt = H5T__complex_create(native_double)))
1478
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't create native double complex datatype");
1479
1
    dt->shared->state = H5T_STATE_IMMUTABLE;
1480
1481
    /* Register the type and set global variables */
1482
1
    if ((H5T_NATIVE_DOUBLE_COMPLEX_g = H5I_register(H5I_DATATYPE, dt, false)) < 0)
1483
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't register ID for native double complex datatype");
1484
1
    H5T_NATIVE_DOUBLE_COMPLEX_ALIGN_g = TAG_ALIGNMENT(DOUBLE_COMPLEX);
1485
1486
1
    dt = NULL;
1487
1488
    /* H5T_NATIVE_LDOUBLE_COMPLEX */
1489
1490
1
    if (NULL == (dt = H5T__complex_create(native_ldouble)))
1491
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't create native long double complex datatype");
1492
1
    dt->shared->state = H5T_STATE_IMMUTABLE;
1493
1494
    /* Register the type and set global variables */
1495
1
    if ((H5T_NATIVE_LDOUBLE_COMPLEX_g = H5I_register(H5I_DATATYPE, dt, false)) < 0)
1496
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
1497
1
                    "can't register ID for native long double complex datatype");
1498
1
    H5T_NATIVE_LDOUBLE_COMPLEX_ALIGN_g = TAG_ALIGNMENT(LDOUBLE_COMPLEX);
1499
1500
1
    dt = NULL;
1501
1502
1
done:
1503
1
    if (ret_value < 0) {
1504
0
        if (dt && (H5T_close(dt) < 0))
1505
0
            HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close datatype");
1506
0
    }
1507
1508
1
    FUNC_LEAVE_NOAPI(ret_value)
1509
1
}
1510
#endif