Coverage Report

Created: 2026-04-29 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5Tconv_float.c
Line
Count
Source
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*
14
 * Purpose: Datatype conversion functions for floating-point datatypes
15
 */
16
17
/****************/
18
/* Module Setup */
19
/****************/
20
#include "H5Tmodule.h" /* This source code file is part of the H5T module */
21
22
/***********/
23
/* Headers */
24
/***********/
25
#include "H5private.h" /* Generic Functions                    */
26
#include "H5Tconv.h"   /* Datatype conversions                 */
27
#include "H5Tconv_macros.h"
28
#include "H5Tconv_complex.h"
29
#include "H5Tconv_integer.h"
30
#include "H5Tconv_float.h"
31
32
/*-------------------------------------------------------------------------
33
 * Function:    H5T__conv_f_f
34
 *
35
 * Purpose:     Convert one floating point type to another. This is a catch
36
 *              all for floating point conversions and is probably not
37
 *              particularly fast!
38
 *
39
 * Return:      Non-negative on success/Negative on failure
40
 *
41
 *-------------------------------------------------------------------------
42
 */
43
herr_t
44
H5T__conv_f_f(const H5T_t *src_p, const H5T_t *dst_p, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
45
              size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
46
              void H5_ATTR_UNUSED *bkg)
47
0
{
48
0
    herr_t ret_value = SUCCEED;
49
50
0
    FUNC_ENTER_PACKAGE
51
52
0
    switch (cdata->command) {
53
0
        case H5T_CONV_INIT: {
54
0
            H5T_atomic_t src_atomic; /* source datatype atomic info      */
55
0
            H5T_atomic_t dst_atomic; /* destination datatype atomic info */
56
57
0
            if (NULL == src_p || NULL == dst_p)
58
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
59
0
            src_atomic = src_p->shared->u.atomic;
60
0
            dst_atomic = dst_p->shared->u.atomic;
61
0
            if (H5T_ORDER_LE != src_atomic.order && H5T_ORDER_BE != src_atomic.order &&
62
0
                H5T_ORDER_VAX != src_atomic.order)
63
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
64
0
            if (H5T_ORDER_LE != dst_atomic.order && H5T_ORDER_BE != dst_atomic.order &&
65
0
                H5T_ORDER_VAX != dst_atomic.order)
66
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
67
0
            if (dst_p->shared->size > TEMP_FLOAT_CONV_BUFFER_SIZE)
68
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large");
69
0
            if (8 * sizeof(int64_t) - 1 < src_atomic.u.f.esize ||
70
0
                8 * sizeof(int64_t) - 1 < dst_atomic.u.f.esize)
71
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large");
72
0
            cdata->need_bkg = H5T_BKG_NO;
73
74
0
            break;
75
0
        }
76
77
0
        case H5T_CONV_FREE:
78
0
            break;
79
80
0
        case H5T_CONV_CONV:
81
0
            if (NULL == src_p || NULL == dst_p)
82
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
83
0
            if (NULL == conv_ctx)
84
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer");
85
0
            if (H5T__conv_f_f_loop(src_p, dst_p, conv_ctx, nelmts, buf_stride, buf) < 0)
86
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "unable to convert data values");
87
0
            break;
88
89
0
        default:
90
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
91
0
    }
92
93
0
done:
94
0
    FUNC_LEAVE_NOAPI(ret_value)
95
0
} /* end H5T__conv_f_f() */
96
97
/*-------------------------------------------------------------------------
98
 * Function:    H5T__conv_f_f_loop
99
 *
100
 * Purpose:     Implements the body of the conversion loop when converting
101
 *              floating-point values to another floating-point type
102
 *              (including complex number types). Encapsulates common
103
 *              code that is shared between the H5T__conv_f_f conversion
104
 *              function and other functions where the logic is nearly
105
 *              identical, such as H5T__conv_f_complex and
106
 *              H5T__conv_complex_f.
107
 *
108
 * Return:      Non-negative on success/Negative on failure
109
 *
110
 *-------------------------------------------------------------------------
111
 */
112
herr_t
113
H5T__conv_f_f_loop(const H5T_t *src_p, const H5T_t *dst_p, const H5T_conv_ctx_t *conv_ctx, size_t nelmts,
114
                   size_t buf_stride, void *buf)
115
0
{
116
0
    H5T_atomic_t src_atomic;                        /* source datatype atomic info      */
117
0
    H5T_atomic_t dst_atomic;                        /* destination datatype atomic info */
118
0
    hssize_t     expo_max;                          /* maximum possible dst exponent    */
119
0
    ssize_t      src_delta, dst_delta;              /* source & destination stride      */
120
0
    uint8_t     *s, *sp, *d, *dp;                   /* source and dest traversal ptrs   */
121
0
    uint8_t     *src_rev = NULL;                    /* order-reversed source buffer     */
122
0
    uint8_t      dbuf[TEMP_FLOAT_CONV_BUFFER_SIZE]; /* temp destination buffer          */
123
0
    size_t       olap;                              /* num overlapping elements         */
124
0
    int          direction;                         /* forward or backward traversal    */
125
0
    herr_t       ret_value = SUCCEED;
126
127
0
    FUNC_ENTER_PACKAGE
128
129
0
    assert(src_p);
130
0
    assert(src_p->shared->type == H5T_FLOAT || src_p->shared->type == H5T_COMPLEX);
131
0
    assert(dst_p);
132
0
    assert(dst_p->shared->type == H5T_FLOAT || dst_p->shared->type == H5T_COMPLEX);
133
0
    assert(conv_ctx);
134
0
    assert(buf);
135
136
0
    if (src_p->shared->type == H5T_COMPLEX)
137
0
        src_atomic = src_p->shared->parent->shared->u.atomic;
138
0
    else
139
0
        src_atomic = src_p->shared->u.atomic;
140
0
    if (dst_p->shared->type == H5T_COMPLEX)
141
0
        dst_atomic = dst_p->shared->parent->shared->u.atomic;
142
0
    else
143
0
        dst_atomic = dst_p->shared->u.atomic;
144
145
0
    expo_max = ((hssize_t)1 << dst_atomic.u.f.esize) - 1;
146
147
#ifndef NDEBUG
148
    /* Are we converting between a floating-point type and a complex number
149
     * type consisting of the same floating-point type? This function is
150
     * only intended for converting between different floating-point types
151
     * and will produce incorrect results otherwise.
152
     */
153
    if ((src_p->shared->type == H5T_COMPLEX && dst_p->shared->type == H5T_FLOAT) ||
154
        (src_p->shared->type == H5T_FLOAT && dst_p->shared->type == H5T_COMPLEX)) {
155
        const H5T_t *src_base = (src_p->shared->type == H5T_FLOAT) ? src_p : src_p->shared->parent;
156
        const H5T_t *dst_base = (dst_p->shared->type == H5T_FLOAT) ? dst_p : dst_p->shared->parent;
157
        assert(0 != (H5T_cmp(src_base, dst_base, false)));
158
    }
159
#endif
160
161
    /*
162
     * Do we process the values from beginning to end or vice versa? Also,
163
     * how many of the elements have the source and destination areas
164
     * overlapping?
165
     */
166
0
    if (src_p->shared->size == dst_p->shared->size || buf_stride) {
167
0
        sp = dp   = (uint8_t *)buf;
168
0
        direction = 1;
169
0
        olap      = nelmts;
170
0
    }
171
0
    else if (src_p->shared->size >= dst_p->shared->size) {
172
0
        double olap_d =
173
0
            ceil((double)(dst_p->shared->size) / (double)(src_p->shared->size - dst_p->shared->size));
174
0
        olap = (size_t)olap_d;
175
0
        sp = dp   = (uint8_t *)buf;
176
0
        direction = 1;
177
0
    }
178
0
    else {
179
0
        double olap_d =
180
0
            ceil((double)(src_p->shared->size) / (double)(dst_p->shared->size - src_p->shared->size));
181
0
        olap      = (size_t)olap_d;
182
0
        sp        = (uint8_t *)buf + (nelmts - 1) * src_p->shared->size;
183
0
        dp        = (uint8_t *)buf + (nelmts - 1) * dst_p->shared->size;
184
0
        direction = -1;
185
0
    }
186
187
    /* Direction & size of buffer traversal */
188
0
    H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t);
189
0
    H5_CHECK_OVERFLOW(src_p->shared->size, size_t, ssize_t);
190
0
    H5_CHECK_OVERFLOW(dst_p->shared->size, size_t, ssize_t);
191
0
    src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src_p->shared->size);
192
0
    dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst_p->shared->size);
193
194
    /* Allocate space for order-reversed source buffer */
195
0
    if (conv_ctx->u.conv.cb_struct.func)
196
0
        if (NULL == (src_rev = H5MM_calloc(src_p->shared->size)))
197
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "couldn't allocate temporary buffer");
198
199
    /* The conversion loop */
200
0
    for (size_t elmtno = 0; elmtno < nelmts; elmtno++) {
201
0
        H5T_conv_float_specval_t specval_type; /* floating-point value type (regular, +/-Inf, +/-0, NaN) */
202
0
        H5T_conv_ret_t except_ret = H5T_CONV_UNHANDLED; /* return of conversion exception callback function */
203
0
        ssize_t        bitno      = 0;                  /* bit number                                       */
204
0
        int64_t        expo;                            /* exponent                                         */
205
0
        size_t         implied;                         /* destination implied bits                         */
206
0
        size_t         mpos;                            /* offset to useful mant in src                     */
207
0
        size_t         msize = 0;                       /* useful size of mantissa in src                   */
208
0
        size_t         mrsh;                            /* amount to right shift mantissa                   */
209
0
        bool           reverse      = true;             /* if reversed the order of destination             */
210
0
        bool           denormalized = false;            /* is either source or destination denormalized?    */
211
0
        bool           carry        = false;            /* carry after rounding mantissa                    */
212
213
        /*
214
         * If the source and destination buffers overlap then use a
215
         * temporary buffer for the destination.
216
         */
217
0
        s = sp;
218
0
        if (direction > 0)
219
0
            d = elmtno < olap ? dbuf : dp;
220
0
        else
221
0
            d = elmtno + olap >= nelmts ? dbuf : dp;
222
0
        if (d == dbuf)
223
0
            memset(dbuf, 0, sizeof(dbuf));
224
225
#ifndef NDEBUG
226
        if (d == dbuf) {
227
            assert((dp >= sp && dp < sp + src_p->shared->size) ||
228
                   (sp >= dp && sp < dp + dst_p->shared->size));
229
        }
230
        else {
231
            assert((dp < sp && dp + dst_p->shared->size <= sp) ||
232
                   (sp < dp && sp + src_p->shared->size <= dp));
233
        }
234
#endif
235
236
        /*
237
         * Put the data in little endian order so our loops aren't so
238
         * complicated. We'll do all the conversion stuff assuming
239
         * little endian and then we'll fix the order at the end.
240
         */
241
0
        if (H5T_ORDER_BE == src_atomic.order) {
242
0
            size_t half_size = src_p->shared->size / 2;
243
244
0
            if (H5T_FLOAT == src_p->shared->type) {
245
0
                for (size_t j = 0; j < half_size; j++)
246
0
                    H5_SWAP_BYTES(s, j, src_p->shared->size - (j + 1));
247
0
            }
248
0
            else {
249
0
                uint8_t *cur_part = s;
250
                /* Swap real part of complex number element */
251
0
                for (size_t j = 0; j < half_size / 2; j++)
252
0
                    H5_SWAP_BYTES(cur_part, j, half_size - (j + 1));
253
                /* Swap imaginary part of complex number element */
254
0
                cur_part += half_size;
255
0
                for (size_t j = 0; j < half_size / 2; j++)
256
0
                    H5_SWAP_BYTES(cur_part, j, half_size - (j + 1));
257
0
            }
258
0
        }
259
0
        else if (H5T_ORDER_VAX == src_atomic.order) {
260
0
            if (H5T_FLOAT == src_p->shared->type) {
261
0
                uint8_t tmp1, tmp2;
262
0
                size_t  tsize = src_p->shared->size;
263
0
                assert(0 == tsize % 2);
264
265
0
                for (size_t i = 0; i < tsize; i += 4) {
266
0
                    tmp1 = s[i];
267
0
                    tmp2 = s[i + 1];
268
269
0
                    s[i]     = s[(tsize - 2) - i];
270
0
                    s[i + 1] = s[(tsize - 1) - i];
271
272
0
                    s[(tsize - 2) - i] = tmp1;
273
0
                    s[(tsize - 1) - i] = tmp2;
274
0
                }
275
0
            }
276
0
            else
277
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
278
0
                            "VAX byte ordering is unsupported for complex number type conversions");
279
0
        }
280
281
        /* Check for special cases: +0, -0, +Inf, -Inf, NaN */
282
0
        specval_type = H5T__conv_float_find_special(s, &src_atomic, NULL);
283
0
        if (specval_type == H5T_CONV_FLOAT_SPECVAL_POSZERO ||
284
0
            specval_type == H5T_CONV_FLOAT_SPECVAL_NEGZERO) {
285
0
            H5T__bit_copy(d, dst_atomic.u.f.sign, s, src_atomic.u.f.sign, (size_t)1);
286
0
            H5T__bit_set(d, dst_atomic.u.f.epos, dst_atomic.u.f.esize, false);
287
0
            H5T__bit_set(d, dst_atomic.u.f.mpos, dst_atomic.u.f.msize, false);
288
0
            goto padding;
289
0
        }
290
0
        else if (specval_type != H5T_CONV_FLOAT_SPECVAL_REGULAR) {
291
            /* If user's exception handler is present, use it */
292
0
            if (conv_ctx->u.conv.cb_struct.func) {
293
0
                H5T_conv_except_t except_type; /* type of conversion exception that occurred */
294
295
                /* Reverse source buffer order first */
296
0
                H5T__reverse_order(src_rev, s, src_p);
297
298
0
                if (specval_type == H5T_CONV_FLOAT_SPECVAL_POSINF)
299
0
                    except_type = H5T_CONV_EXCEPT_PINF;
300
0
                else if (specval_type == H5T_CONV_FLOAT_SPECVAL_NEGINF)
301
0
                    except_type = H5T_CONV_EXCEPT_NINF;
302
0
                else
303
0
                    except_type = H5T_CONV_EXCEPT_NAN;
304
305
                /* Prepare & restore library for user callback */
306
0
                H5_BEFORE_USER_CB(FAIL)
307
0
                    {
308
0
                        except_ret = (conv_ctx->u.conv.cb_struct.func)(
309
0
                            except_type, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, src_rev,
310
0
                            d, conv_ctx->u.conv.cb_struct.user_data);
311
0
                    }
312
0
                H5_AFTER_USER_CB(FAIL)
313
0
            }
314
315
0
            if (except_ret == H5T_CONV_UNHANDLED) {
316
0
                H5T__bit_copy(d, dst_atomic.u.f.sign, s, src_atomic.u.f.sign, (size_t)1);
317
0
                H5T__bit_set(d, dst_atomic.u.f.epos, dst_atomic.u.f.esize, true);
318
0
                if (specval_type == H5T_CONV_FLOAT_SPECVAL_NAN)
319
                    /* There are many NaN values, so we just set all bits of the significand. */
320
0
                    H5T__bit_set(d, dst_atomic.u.f.mpos, dst_atomic.u.f.msize, true);
321
0
                else {
322
                    /* +/-Inf */
323
0
                    H5T__bit_set(d, dst_atomic.u.f.mpos, dst_atomic.u.f.msize, false);
324
                    /* If the destination has no implied mantissa bit, we'll need to set
325
                     * the 1st bit of mantissa to 1. The Intel-Linux "long double" is
326
                     * this case. */
327
0
                    if (H5T_NORM_NONE == dst_atomic.u.f.norm)
328
0
                        H5T__bit_set(d, dst_atomic.u.f.mpos + dst_atomic.u.f.msize - 1, (size_t)1, true);
329
0
                }
330
0
            }
331
0
            else if (except_ret == H5T_CONV_HANDLED) {
332
                /* No need to reverse the order of destination because user handles it */
333
0
                reverse = false;
334
0
                goto next;
335
0
            }
336
0
            else if (except_ret == H5T_CONV_ABORT)
337
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
338
339
0
            goto padding;
340
            /* Temporary solution to handle VAX special values.
341
             * Note that even though we don't support VAX anymore, we
342
             * still need to handle legacy VAX files so this code must
343
             * remain in place.
344
             */
345
0
        }
346
347
        /*
348
         * Get the exponent as an unsigned quantity from the section of
349
         * the source bit field where it's located. Don't worry about
350
         * the exponent bias yet.
351
         */
352
0
        expo = (int64_t)H5T__bit_get_d(s, src_atomic.u.f.epos, src_atomic.u.f.esize);
353
354
0
        if (expo == 0)
355
0
            denormalized = true;
356
357
        /*
358
         * Set markers for the source mantissa, excluding the leading `1'
359
         * (might be implied).
360
         */
361
0
        implied = 1;
362
0
        mpos    = src_atomic.u.f.mpos;
363
0
        mrsh    = 0;
364
0
        if (0 == expo || H5T_NORM_NONE == src_atomic.u.f.norm) {
365
0
            if ((bitno = H5T__bit_find(s, src_atomic.u.f.mpos, src_atomic.u.f.msize, H5T_BIT_MSB, true)) >
366
0
                0) {
367
0
                msize = (size_t)bitno;
368
0
            }
369
0
            else if (0 == bitno) {
370
0
                msize = 1;
371
0
                H5T__bit_set(s, src_atomic.u.f.mpos, (size_t)1, false);
372
0
            }
373
0
        }
374
0
        else if (H5T_NORM_IMPLIED == src_atomic.u.f.norm) {
375
0
            msize = src_atomic.u.f.msize;
376
0
        }
377
0
        else {
378
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "normalization method not implemented yet");
379
0
        }
380
381
        /*
382
         * The sign for the destination is the same as the sign for the
383
         * source in all cases.
384
         */
385
0
        H5T__bit_copy(d, dst_atomic.u.f.sign, s, src_atomic.u.f.sign, (size_t)1);
386
387
        /*
388
         * Calculate the true source exponent by adjusting according to
389
         * the source exponent bias.
390
         */
391
0
        if (0 == expo || H5T_NORM_NONE == src_atomic.u.f.norm) {
392
0
            assert(bitno >= 0);
393
0
            expo -= (int64_t)((src_atomic.u.f.ebias - 1) + (src_atomic.u.f.msize - (size_t)bitno));
394
0
        }
395
0
        else if (H5T_NORM_IMPLIED == src_atomic.u.f.norm) {
396
0
            expo -= (int64_t)src_atomic.u.f.ebias;
397
0
        }
398
0
        else {
399
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "normalization method not implemented yet");
400
0
        }
401
402
        /*
403
         * If the destination is not normalized then right shift the
404
         * mantissa by one.
405
         */
406
0
        if (H5T_NORM_NONE == dst_atomic.u.f.norm)
407
0
            mrsh++;
408
409
        /*
410
         * Calculate the destination exponent by adding the destination
411
         * bias and clipping by the minimum and maximum possible
412
         * destination exponent values.
413
         */
414
0
        expo += (int64_t)dst_atomic.u.f.ebias;
415
416
0
        if (expo < -(hssize_t)(dst_atomic.u.f.msize)) {
417
            /* The exponent is way too small.  Result is zero. */
418
0
            expo = 0;
419
0
            H5T__bit_set(d, dst_atomic.u.f.mpos, dst_atomic.u.f.msize, false);
420
0
            msize = 0;
421
0
        }
422
0
        else if (expo <= 0) {
423
            /*
424
             * The exponent is too small to fit in the exponent field,
425
             * but by shifting the mantissa to the right we can
426
             * accommodate that value.  The mantissa of course is no
427
             * longer normalized.
428
             */
429
0
            mrsh += (size_t)(1 - expo);
430
0
            expo         = 0;
431
0
            denormalized = true;
432
0
        }
433
0
        else if (expo >= expo_max) {
434
            /*
435
             * The exponent is too large to fit in the available region
436
             * or it results in the maximum possible value. Use positive
437
             * or negative infinity instead unless the application
438
             * specifies something else. Before calling the overflow
439
             * handler make sure the source buffer we hand it is in the
440
             * original byte order.
441
             */
442
0
            if (conv_ctx->u.conv.cb_struct.func) { /* If user's exception handler is present, use it */
443
                /* Reverse source buffer order first */
444
0
                H5T__reverse_order(src_rev, s, src_p);
445
446
                /* Prepare & restore library for user callback */
447
0
                H5_BEFORE_USER_CB(FAIL)
448
0
                    {
449
0
                        except_ret = (conv_ctx->u.conv.cb_struct.func)(
450
0
                            H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id,
451
0
                            conv_ctx->u.conv.dst_type_id, src_rev, d, conv_ctx->u.conv.cb_struct.user_data);
452
0
                    }
453
0
                H5_AFTER_USER_CB(FAIL)
454
0
            }
455
456
0
            if (except_ret == H5T_CONV_UNHANDLED) {
457
0
                expo = expo_max;
458
0
                H5T__bit_set(d, dst_atomic.u.f.mpos, dst_atomic.u.f.msize, false);
459
0
                msize = 0;
460
0
            }
461
0
            else if (except_ret == H5T_CONV_HANDLED) {
462
0
                reverse = false;
463
0
                goto next;
464
0
            }
465
0
            else if (except_ret == H5T_CONV_ABORT)
466
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
467
0
        }
468
469
        /*
470
         * If the destination mantissa is smaller than the source
471
         * mantissa then round the source mantissa. Rounding may cause a
472
         * carry in which case the exponent has to be re-evaluated for
473
         * overflow. That is, if `carry' is clear then the implied
474
         * mantissa bit is `1', else it is `10' binary.
475
         */
476
0
        if (msize > 0 && mrsh <= dst_atomic.u.f.msize && mrsh + msize > dst_atomic.u.f.msize) {
477
0
            bitno = (ssize_t)(mrsh + msize - dst_atomic.u.f.msize);
478
0
            assert(bitno >= 0 && (size_t)bitno <= msize);
479
            /* If the 1st bit being cut off is set and source isn't denormalized. */
480
0
            if (H5T__bit_get_d(s, (mpos + (size_t)bitno) - 1, (size_t)1) && !denormalized) {
481
                /* Don't do rounding if exponent is 111...110 and mantissa is 111...11.
482
                 * To do rounding and increment exponent in this case will create an infinity value. */
483
0
                if ((H5T__bit_find(s, mpos + (size_t)bitno, msize - (size_t)bitno, H5T_BIT_LSB, false) >= 0 ||
484
0
                     expo < expo_max - 1)) {
485
0
                    carry = H5T__bit_inc(s, mpos + (size_t)bitno - 1, 1 + msize - (size_t)bitno);
486
0
                    if (carry)
487
0
                        implied = 2;
488
0
                }
489
0
            }
490
0
            else if (H5T__bit_get_d(s, (mpos + (size_t)bitno) - 1, (size_t)1) && denormalized)
491
                /* For either source or destination, denormalized value doesn't increment carry. */
492
0
                H5T__bit_inc(s, mpos + (size_t)bitno - 1, 1 + msize - (size_t)bitno);
493
0
        }
494
0
        else
495
0
            carry = false;
496
497
        /*
498
         * Write the mantissa to the destination
499
         */
500
0
        if (mrsh > dst_atomic.u.f.msize + 1) {
501
0
            H5T__bit_set(d, dst_atomic.u.f.mpos, dst_atomic.u.f.msize, false);
502
0
        }
503
0
        else if (mrsh == dst_atomic.u.f.msize + 1) {
504
0
            H5T__bit_set(d, dst_atomic.u.f.mpos + 1, dst_atomic.u.f.msize - 1, false);
505
0
            H5T__bit_set(d, dst_atomic.u.f.mpos, (size_t)1, true);
506
0
        }
507
0
        else if (mrsh == dst_atomic.u.f.msize) {
508
0
            H5T__bit_set(d, dst_atomic.u.f.mpos, dst_atomic.u.f.msize, false);
509
0
            H5T__bit_set_d(d, dst_atomic.u.f.mpos, MIN(2, dst_atomic.u.f.msize), (hsize_t)implied);
510
0
        }
511
0
        else {
512
0
            if (mrsh > 0) {
513
0
                H5T__bit_set(d, dst_atomic.u.f.mpos + dst_atomic.u.f.msize - mrsh, mrsh, false);
514
0
                H5T__bit_set_d(d, dst_atomic.u.f.mpos + dst_atomic.u.f.msize - mrsh, (size_t)2,
515
0
                               (hsize_t)implied);
516
0
            }
517
0
            if (mrsh + msize >= dst_atomic.u.f.msize) {
518
0
                H5T__bit_copy(d, dst_atomic.u.f.mpos, s, (mpos + msize + mrsh - dst_atomic.u.f.msize),
519
0
                              dst_atomic.u.f.msize - mrsh);
520
0
            }
521
0
            else {
522
0
                H5T__bit_copy(d, dst_atomic.u.f.mpos + dst_atomic.u.f.msize - (mrsh + msize), s, mpos, msize);
523
0
                H5T__bit_set(d, dst_atomic.u.f.mpos, dst_atomic.u.f.msize - (mrsh + msize), false);
524
0
            }
525
0
        }
526
527
        /* Write the exponent */
528
0
        if (carry) {
529
0
            expo++;
530
0
            if (expo >= expo_max) {
531
                /*
532
                 * The exponent is too large to fit in the available
533
                 * region or it results in the maximum possible value.
534
                 * Use positive or negative infinity instead unless the
535
                 * application specifies something else. Before calling
536
                 * the overflow handler make sure the source buffer we
537
                 * hand it is in the original byte order.
538
                 */
539
0
                if (conv_ctx->u.conv.cb_struct.func) { /* If user's exception handler is present, use it */
540
                    /* Reverse source buffer order first */
541
0
                    H5T__reverse_order(src_rev, s, src_p);
542
543
                    /* Prepare & restore library for user callback */
544
0
                    H5_BEFORE_USER_CB(FAIL)
545
0
                        {
546
0
                            except_ret = (conv_ctx->u.conv.cb_struct.func)(
547
0
                                H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id,
548
0
                                conv_ctx->u.conv.dst_type_id, src_rev, d,
549
0
                                conv_ctx->u.conv.cb_struct.user_data);
550
0
                        }
551
0
                    H5_AFTER_USER_CB(FAIL)
552
0
                }
553
554
0
                if (except_ret == H5T_CONV_UNHANDLED) {
555
0
                    expo = expo_max;
556
0
                    H5T__bit_set(d, dst_atomic.u.f.mpos, dst_atomic.u.f.msize, false);
557
0
                }
558
0
                else if (except_ret == H5T_CONV_HANDLED) {
559
0
                    reverse = false;
560
0
                    goto next;
561
0
                }
562
0
                else if (except_ret == H5T_CONV_ABORT)
563
0
                    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
564
0
            }
565
0
        }
566
567
0
        carry = false;
568
569
0
        H5_CHECK_OVERFLOW(expo, hssize_t, hsize_t);
570
0
        H5T__bit_set_d(d, dst_atomic.u.f.epos, dst_atomic.u.f.esize, (hsize_t)expo);
571
572
0
padding:
573
        /*
574
         * Set external padding areas
575
         */
576
0
        if (dst_atomic.offset > 0) {
577
0
            assert(H5T_PAD_ZERO == dst_atomic.lsb_pad || H5T_PAD_ONE == dst_atomic.lsb_pad);
578
0
            H5T__bit_set(d, (size_t)0, dst_atomic.offset, (bool)(H5T_PAD_ONE == dst_atomic.lsb_pad));
579
0
        }
580
0
        {
581
0
            size_t type_size;
582
583
0
            if (dst_p->shared->type == H5T_FLOAT)
584
0
                type_size = dst_p->shared->size;
585
0
            else
586
0
                type_size = dst_p->shared->parent->shared->size;
587
588
0
            if (dst_atomic.offset + dst_atomic.prec != 8 * type_size) {
589
0
                assert(H5T_PAD_ZERO == dst_atomic.msb_pad || H5T_PAD_ONE == dst_atomic.msb_pad);
590
0
                H5T__bit_set(d, dst_atomic.offset + dst_atomic.prec,
591
0
                             8 * type_size - (dst_atomic.offset + dst_atomic.prec),
592
0
                             (bool)(H5T_PAD_ONE == dst_atomic.msb_pad));
593
0
            }
594
0
        }
595
596
        /*
597
         * Put the destination in the correct byte order. See note at
598
         * beginning of loop. Only the "real" part of a complex number
599
         * element is swapped. By the C standard, the "imaginary" part
600
         * should just be zeroed when converting a real value to a
601
         * complex value.
602
         */
603
0
        if (H5T_ORDER_BE == dst_atomic.order && reverse) {
604
0
            size_t half_size = dst_p->shared->size / 2;
605
606
0
            if (H5T_FLOAT == dst_p->shared->type) {
607
0
                for (size_t j = 0; j < half_size; j++)
608
0
                    H5_SWAP_BYTES(d, j, dst_p->shared->size - (j + 1));
609
0
            }
610
0
            else {
611
0
                for (size_t j = 0; j < half_size / 2; j++)
612
0
                    H5_SWAP_BYTES(d, j, half_size - (j + 1));
613
0
            }
614
0
        }
615
0
        else if (H5T_ORDER_VAX == dst_atomic.order && reverse) {
616
0
            if (H5T_FLOAT == dst_p->shared->type) {
617
0
                uint8_t tmp1, tmp2;
618
0
                size_t  tsize = dst_p->shared->size / 2;
619
0
                assert(0 == tsize % 2);
620
621
0
                for (size_t i = 0; i < tsize; i += 4) {
622
0
                    tmp1 = d[i];
623
0
                    tmp2 = d[i + 1];
624
625
0
                    d[i]     = d[(tsize - 2) - i];
626
0
                    d[i + 1] = d[(tsize - 1) - i];
627
628
0
                    d[(tsize - 2) - i] = tmp1;
629
0
                    d[(tsize - 1) - i] = tmp2;
630
0
                }
631
0
            }
632
0
            else
633
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
634
0
                            "VAX byte ordering is unsupported for complex number type conversions");
635
0
        }
636
637
0
next:
638
        /*
639
         * If we had used a temporary buffer for the destination then we
640
         * should copy the value to the true destination buffer.
641
         */
642
0
        if (d == dbuf) {
643
0
            if (H5T_FLOAT == dst_p->shared->type)
644
0
                H5MM_memcpy(dp, d, dst_p->shared->size);
645
0
            else
646
0
                H5MM_memcpy(dp, d, dst_p->shared->size / 2);
647
0
        }
648
649
        /* Ensure imaginary part of complex number is zeroed */
650
0
        if (H5T_COMPLEX == dst_p->shared->type)
651
0
            memset(dp + (dst_p->shared->size / 2), 0, dst_p->shared->size / 2);
652
653
        /* Advance source & destination pointers by delta amounts */
654
0
        sp += src_delta;
655
0
        dp += dst_delta;
656
0
    } /* end conversion loop */
657
658
0
done:
659
0
    H5MM_free(src_rev);
660
661
0
    FUNC_LEAVE_NOAPI(ret_value)
662
0
} /* end H5T__conv_f_f_loop() */
663
664
/*-------------------------------------------------------------------------
665
 * Function:    H5T__conv_float_find_special
666
 *
667
 * Purpose:     Helper function to inspect the bits of a floating-point
668
 *              value during data conversions and determine if that value
669
 *              is a special value (+/-Inf, +/-0, NaN).
670
 *
671
 *              If `sign_out` is non-NULL, it is set to the value of the
672
 *              sign bit of the floating-point value.
673
 *
674
 * Return:      Non-negative on success/Negative on failure
675
 *
676
 *-------------------------------------------------------------------------
677
 */
678
H5T_conv_float_specval_t
679
H5T__conv_float_find_special(const uint8_t *src_buf, const H5T_atomic_t *src_atomic, uint64_t *sign_out)
680
0
{
681
0
    uint64_t                 sign; /* sign bit value */
682
0
    H5T_conv_float_specval_t ret_value = H5T_CONV_FLOAT_SPECVAL_REGULAR;
683
684
0
    FUNC_ENTER_PACKAGE_NOERR
685
686
0
    assert(src_buf);
687
0
    assert(src_atomic);
688
689
    /* Find the sign bit value of the source. */
690
0
    sign = H5T__bit_get_d(src_buf, src_atomic->u.f.sign, (size_t)1);
691
692
    /* Is the mantissa all 0 bits? */
693
0
    if (H5T__bit_find(src_buf, src_atomic->u.f.mpos, src_atomic->u.f.msize, H5T_BIT_LSB, true) < 0) {
694
        /* Is the exponent all 0 bits? */
695
0
        if (H5T__bit_find(src_buf, src_atomic->u.f.epos, src_atomic->u.f.esize, H5T_BIT_LSB, true) < 0)
696
            /* +0 or -0 */
697
0
            ret_value = sign ? H5T_CONV_FLOAT_SPECVAL_NEGZERO : H5T_CONV_FLOAT_SPECVAL_POSZERO;
698
        /* Is the exponent all 1 bits? */
699
0
        else if (H5T__bit_find(src_buf, src_atomic->u.f.epos, src_atomic->u.f.esize, H5T_BIT_LSB, false) < 0)
700
            /* +Inf or -Inf */
701
0
            ret_value = sign ? H5T_CONV_FLOAT_SPECVAL_NEGINF : H5T_CONV_FLOAT_SPECVAL_POSINF;
702
0
    }
703
0
    else {
704
0
        bool exp_all_ones =
705
0
            (H5T__bit_find(src_buf, src_atomic->u.f.epos, src_atomic->u.f.esize, H5T_BIT_LSB, false) < 0);
706
707
        /* For a source value with no implied mantissa bit, if the exponent bits
708
         * are all 1s and only the 1st bit of the mantissa is set to 1, the value
709
         * is infinity. The Intel-Linux "long double" is this case.
710
         */
711
0
        if (H5T_NORM_NONE == src_atomic->u.f.norm && exp_all_ones &&
712
0
            H5T__bit_find(src_buf, src_atomic->u.f.mpos, src_atomic->u.f.msize - 1, H5T_BIT_LSB, true) < 0)
713
0
            ret_value = sign ? H5T_CONV_FLOAT_SPECVAL_NEGINF : H5T_CONV_FLOAT_SPECVAL_POSINF;
714
0
        else if (exp_all_ones)
715
0
            ret_value = H5T_CONV_FLOAT_SPECVAL_NAN;
716
0
    }
717
718
0
    if (sign_out)
719
0
        *sign_out = sign;
720
721
0
    FUNC_LEAVE_NOAPI(ret_value);
722
0
} /* end H5T__conv_float_find_special() */
723
724
/*-------------------------------------------------------------------------
725
 * Function:    H5T__conv_f_i
726
 *
727
 * Purpose:     Convert one floating-point type to an integer. This is
728
 *              the catch-all function for float-integer conversions and
729
 *              is probably not particularly fast.
730
 *
731
 * Return:      Non-negative on success/Negative on failure
732
 *
733
 *-------------------------------------------------------------------------
734
 */
735
herr_t
736
H5T__conv_f_i(const H5T_t *src_p, const H5T_t *dst_p, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
737
              size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
738
              void H5_ATTR_UNUSED *bkg)
739
0
{
740
0
    herr_t ret_value = SUCCEED;
741
742
0
    FUNC_ENTER_PACKAGE
743
744
0
    switch (cdata->command) {
745
0
        case H5T_CONV_INIT: {
746
0
            H5T_atomic_t src_atomic; /* source datatype atomic info      */
747
0
            H5T_atomic_t dst_atomic; /* destination datatype atomic info */
748
749
0
            if (NULL == src_p || NULL == dst_p)
750
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
751
0
            src_atomic = src_p->shared->u.atomic;
752
0
            dst_atomic = dst_p->shared->u.atomic;
753
0
            if (H5T_ORDER_LE != src_atomic.order && H5T_ORDER_BE != src_atomic.order &&
754
0
                H5T_ORDER_VAX != src_atomic.order)
755
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
756
0
            if (H5T_ORDER_LE != dst_atomic.order && H5T_ORDER_BE != dst_atomic.order &&
757
0
                H5T_ORDER_VAX != dst_atomic.order)
758
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
759
0
            if (dst_p->shared->size > TEMP_INT_CONV_BUFFER_SIZE)
760
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large");
761
0
            if (8 * sizeof(hssize_t) - 1 < src_atomic.u.f.esize)
762
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large");
763
0
            cdata->need_bkg = H5T_BKG_NO;
764
765
0
            break;
766
0
        }
767
768
0
        case H5T_CONV_FREE:
769
0
            break;
770
771
0
        case H5T_CONV_CONV:
772
0
            if (NULL == src_p || NULL == dst_p)
773
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
774
0
            if (NULL == conv_ctx)
775
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer");
776
777
0
            if (H5T__conv_f_i_loop(src_p, dst_p, conv_ctx, nelmts, buf_stride, buf) < 0)
778
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "unable to convert data values");
779
0
            break;
780
781
0
        default:
782
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
783
0
    } /* end switch */
784
785
0
done:
786
0
    FUNC_LEAVE_NOAPI(ret_value)
787
0
} /* end H5T__conv_f_i() */
788
789
/*-------------------------------------------------------------------------
790
 * Function:    H5T__conv_f_i_loop
791
 *
792
 * Purpose:     Implements the body of the conversion loop when converting
793
 *              floating-point values (including complex number values) to
794
 *              integer values. Encapsulates common code that is shared
795
 *              between the H5T__conv_f_i conversion function and other
796
 *              functions where the logic is nearly identical, such as
797
 *              H5T__conv_complex_i.
798
 *
799
 * Return:      Non-negative on success/Negative on failure
800
 *
801
 *-------------------------------------------------------------------------
802
 */
803
herr_t
804
H5T__conv_f_i_loop(const H5T_t *src_p, const H5T_t *dst_p, const H5T_conv_ctx_t *conv_ctx, size_t nelmts,
805
                   size_t buf_stride, void *buf)
806
0
{
807
0
    H5T_atomic_t src_atomic;                      /* source datatype atomic info      */
808
0
    H5T_atomic_t dst_atomic;                      /* destination datatype atomic info */
809
0
    ssize_t      src_delta, dst_delta;            /* source & destination stride      */
810
0
    uint8_t     *s, *sp, *d, *dp;                 /* source and dest traversal ptrs   */
811
0
    uint8_t     *int_buf = NULL;                  /* buffer for temporary value       */
812
0
    uint8_t     *src_rev = NULL;                  /* order-reversed source buffer     */
813
0
    uint8_t      dbuf[TEMP_INT_CONV_BUFFER_SIZE]; /* temp destination buffer          */
814
0
    size_t       int_buf_size;                    /* buffer size for temporary value  */
815
0
    size_t       src_base_size;                   /* size of source base datatype     */
816
0
    size_t       olap;                            /* num overlapping elements         */
817
0
    int          direction;                       /* forward or backward traversal    */
818
0
    herr_t       ret_value = SUCCEED;
819
820
0
    FUNC_ENTER_PACKAGE
821
822
0
    assert(src_p);
823
0
    assert(src_p->shared->type == H5T_FLOAT || src_p->shared->type == H5T_COMPLEX);
824
0
    assert(dst_p);
825
0
    assert(dst_p->shared->type == H5T_INTEGER);
826
0
    assert(conv_ctx);
827
0
    assert(buf);
828
829
0
    if (src_p->shared->type == H5T_COMPLEX)
830
0
        src_atomic = src_p->shared->parent->shared->u.atomic;
831
0
    else
832
0
        src_atomic = src_p->shared->u.atomic;
833
0
    dst_atomic = dst_p->shared->u.atomic;
834
835
    /*
836
     * Do we process the values from beginning to end or vice versa? Also,
837
     * how many of the elements have the source and destination areas
838
     * overlapping?
839
     */
840
0
    if (src_p->shared->size == dst_p->shared->size || buf_stride) {
841
0
        sp = dp   = (uint8_t *)buf;
842
0
        direction = 1;
843
0
        olap      = nelmts;
844
0
    }
845
0
    else if (src_p->shared->size >= dst_p->shared->size) {
846
0
        double olap_d =
847
0
            ceil((double)(dst_p->shared->size) / (double)(src_p->shared->size - dst_p->shared->size));
848
0
        olap = (size_t)olap_d;
849
0
        sp = dp   = (uint8_t *)buf;
850
0
        direction = 1;
851
0
    }
852
0
    else {
853
0
        double olap_d =
854
0
            ceil((double)(src_p->shared->size) / (double)(dst_p->shared->size - src_p->shared->size));
855
0
        olap      = (size_t)olap_d;
856
0
        sp        = (uint8_t *)buf + (nelmts - 1) * src_p->shared->size;
857
0
        dp        = (uint8_t *)buf + (nelmts - 1) * dst_p->shared->size;
858
0
        direction = -1;
859
0
    }
860
861
    /* Direction & size of buffer traversal */
862
0
    H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t);
863
0
    H5_CHECK_OVERFLOW(src_p->shared->size, size_t, ssize_t);
864
0
    H5_CHECK_OVERFLOW(dst_p->shared->size, size_t, ssize_t);
865
0
    src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src_p->shared->size);
866
0
    dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst_p->shared->size);
867
868
    /* Allocate enough space for the buffer holding temporary converted value */
869
0
    src_base_size =
870
0
        (H5T_FLOAT == src_p->shared->type) ? src_p->shared->size : src_p->shared->parent->shared->size;
871
0
    if (dst_atomic.prec / 8 > src_base_size)
872
0
        int_buf_size = (dst_atomic.prec + 7) / 8;
873
0
    else
874
0
        int_buf_size = src_base_size;
875
0
    if (NULL == (int_buf = H5MM_calloc(int_buf_size)))
876
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "couldn't allocate temporary buffer");
877
878
    /* Allocate space for order-reversed source buffer */
879
0
    if (conv_ctx->u.conv.cb_struct.func)
880
0
        if (NULL == (src_rev = H5MM_calloc(src_p->shared->size)))
881
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "couldn't allocate temporary buffer");
882
883
    /* The conversion loop */
884
0
    for (size_t elmtno = 0; elmtno < nelmts; elmtno++) {
885
0
        H5T_conv_float_specval_t specval_type; /* floating-point value type (regular, +/-Inf, +/-0, NaN) */
886
0
        H5T_conv_ret_t except_ret = H5T_CONV_UNHANDLED; /* return of conversion exception callback function */
887
0
        uint64_t       sign;              /* source sign bit value                                  */
888
0
        hssize_t       expo;              /* source exponent                                        */
889
0
        hssize_t       shift_val;         /* shift value when shifting mantissa by exponent         */
890
0
        ssize_t        msb_pos_s;         /* first bit(MSB) in an integer                           */
891
0
        ssize_t        new_msb_pos;       /* MSB position after shifting mantissa by exponent       */
892
0
        bool           truncated = false; /* if fraction value is dropped                           */
893
0
        bool           reverse   = true;  /* if reversed the order of destination                   */
894
895
        /*
896
         * If the source and destination buffers overlap then use a
897
         * temporary buffer for the destination.
898
         */
899
0
        s = sp;
900
0
        if (direction > 0)
901
0
            d = elmtno < olap ? dbuf : dp;
902
0
        else
903
0
            d = elmtno + olap >= nelmts ? dbuf : dp;
904
0
        if (d == dbuf)
905
0
            memset(dbuf, 0, sizeof(dbuf));
906
907
#ifndef NDEBUG
908
        if (d == dbuf) {
909
            assert((dp >= sp && dp < sp + src_p->shared->size) ||
910
                   (sp >= dp && sp < dp + dst_p->shared->size));
911
        }
912
        else {
913
            assert((dp < sp && dp + dst_p->shared->size <= sp) ||
914
                   (sp < dp && sp + src_p->shared->size <= dp));
915
        }
916
#endif
917
918
        /*
919
         * Put the data in little endian order so our loops aren't so
920
         * complicated.  We'll do all the conversion stuff assuming
921
         * little endian and then we'll fix the order at the end.
922
         */
923
0
        if (H5T_ORDER_BE == src_atomic.order) {
924
0
            size_t half_size = src_p->shared->size / 2;
925
926
0
            if (H5T_FLOAT == src_p->shared->type) {
927
0
                for (size_t i = 0; i < half_size; i++)
928
0
                    H5_SWAP_BYTES(s, i, src_p->shared->size - (i + 1));
929
0
            }
930
0
            else {
931
0
                uint8_t *cur_part = s;
932
                /* Swap real part of complex number element */
933
0
                for (size_t i = 0; i < half_size / 2; i++)
934
0
                    H5_SWAP_BYTES(cur_part, i, half_size - (i + 1));
935
                /* Swap imaginary part of complex number element */
936
0
                cur_part += half_size;
937
0
                for (size_t i = 0; i < half_size / 2; i++)
938
0
                    H5_SWAP_BYTES(cur_part, i, half_size - (i + 1));
939
0
            }
940
0
        }
941
0
        else if (H5T_ORDER_VAX == src_atomic.order) {
942
0
            if (H5T_FLOAT == src_p->shared->type) {
943
0
                uint8_t tmp1, tmp2;
944
0
                size_t  tsize = src_p->shared->size;
945
0
                assert(0 == tsize % 2);
946
947
0
                for (size_t i = 0; i < tsize; i += 4) {
948
0
                    tmp1 = s[i];
949
0
                    tmp2 = s[i + 1];
950
951
0
                    s[i]     = s[(tsize - 2) - i];
952
0
                    s[i + 1] = s[(tsize - 1) - i];
953
954
0
                    s[(tsize - 2) - i] = tmp1;
955
0
                    s[(tsize - 1) - i] = tmp2;
956
0
                }
957
0
            }
958
0
            else
959
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
960
0
                            "VAX byte ordering is unsupported for complex number type conversions");
961
0
        }
962
963
        /* zero-set all destination bits */
964
0
        H5T__bit_set(d, dst_atomic.offset, dst_atomic.prec, false);
965
966
        /* Check for special cases: +0, -0, +Inf, -Inf, NaN */
967
0
        specval_type = H5T__conv_float_find_special(s, &src_atomic, &sign);
968
0
        if (specval_type == H5T_CONV_FLOAT_SPECVAL_POSZERO ||
969
0
            specval_type == H5T_CONV_FLOAT_SPECVAL_NEGZERO) {
970
            /* +0 or -0; Set all bits to zero */
971
0
            goto padding;
972
0
        }
973
0
        else if (specval_type != H5T_CONV_FLOAT_SPECVAL_REGULAR) {
974
            /* If user's exception handler is present, use it */
975
0
            if (conv_ctx->u.conv.cb_struct.func) {
976
0
                H5T_conv_except_t except_type; /* type of conversion exception that occurred */
977
978
                /* Reverse source buffer order first */
979
0
                H5T__reverse_order(src_rev, s, src_p);
980
981
0
                if (specval_type == H5T_CONV_FLOAT_SPECVAL_POSINF)
982
0
                    except_type = H5T_CONV_EXCEPT_PINF;
983
0
                else if (specval_type == H5T_CONV_FLOAT_SPECVAL_NEGINF)
984
0
                    except_type = H5T_CONV_EXCEPT_NINF;
985
0
                else
986
0
                    except_type = H5T_CONV_EXCEPT_NAN;
987
988
                /* Prepare & restore library for user callback */
989
0
                H5_BEFORE_USER_CB(FAIL)
990
0
                    {
991
0
                        except_ret = (conv_ctx->u.conv.cb_struct.func)(
992
0
                            except_type, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, src_rev,
993
0
                            d, conv_ctx->u.conv.cb_struct.user_data);
994
0
                    }
995
0
                H5_AFTER_USER_CB(FAIL)
996
0
            }
997
998
0
            if (except_ret == H5T_CONV_UNHANDLED) {
999
0
                if (specval_type == H5T_CONV_FLOAT_SPECVAL_NAN)
1000
0
                    goto padding; /* Just set all bits to zero. */
1001
0
                else if (specval_type == H5T_CONV_FLOAT_SPECVAL_POSINF) {
1002
0
                    if (H5T_SGN_NONE == dst_atomic.u.i.sign)
1003
0
                        H5T__bit_set(d, dst_atomic.offset, dst_atomic.prec, true);
1004
0
                    else if (H5T_SGN_2 == dst_atomic.u.i.sign)
1005
0
                        H5T__bit_set(d, dst_atomic.offset, dst_atomic.prec - 1, true);
1006
0
                }
1007
0
                else if (specval_type == H5T_CONV_FLOAT_SPECVAL_NEGINF) {
1008
0
                    if (H5T_SGN_2 == dst_atomic.u.i.sign)
1009
0
                        H5T__bit_set(d, dst_atomic.prec - 1, (size_t)1, true);
1010
0
                }
1011
0
            }
1012
0
            else if (except_ret == H5T_CONV_HANDLED) {
1013
                /* No need to reverse the order of destination because user handles it */
1014
0
                reverse = false;
1015
0
                goto next;
1016
0
            }
1017
0
            else if (except_ret == H5T_CONV_ABORT)
1018
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
1019
1020
0
            goto padding;
1021
0
        }
1022
1023
        /*
1024
         * Get the exponent as an unsigned quantity from the section of
1025
         * the source bit field where it's located. Not expecting
1026
         * exponent to be greater than the maximal value of hssize_t.
1027
         */
1028
0
        expo = (hssize_t)H5T__bit_get_d(s, src_atomic.u.f.epos, src_atomic.u.f.esize);
1029
1030
        /*
1031
         * Calculate the true source exponent by adjusting according to
1032
         * the source exponent bias.
1033
         */
1034
0
        if (0 == expo || H5T_NORM_NONE == src_atomic.u.f.norm)
1035
0
            expo -= (hssize_t)(src_atomic.u.f.ebias - 1);
1036
0
        else if (H5T_NORM_IMPLIED == src_atomic.u.f.norm)
1037
0
            expo -= (hssize_t)src_atomic.u.f.ebias;
1038
0
        else
1039
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "normalization method not implemented yet");
1040
1041
        /*
1042
         * Get the mantissa as bit vector from the section of
1043
         * the source bit field where it's located.
1044
         * Keep the little-endian order in the buffer.
1045
         * A sequence 0x01020304 will be like in the buffer,
1046
         *      04      03      02      01
1047
         *      |       |       |       |
1048
         *      V       V       V       V
1049
         *    buf[0]  buf[1]  buf[2]  buf[3]
1050
         */
1051
0
        H5T__bit_copy(int_buf, (size_t)0, s, src_atomic.u.f.mpos, src_atomic.u.f.msize);
1052
1053
        /*
1054
         * Restore the implicit bit for mantissa if it's implied.
1055
         * Equivalent to mantissa |= (hsize_t)1 << src_atomic.u.f.msize.
1056
         */
1057
0
        if (H5T_NORM_IMPLIED == src_atomic.u.f.norm)
1058
0
            H5T__bit_inc(int_buf, src_atomic.u.f.msize, 8 * int_buf_size - src_atomic.u.f.msize);
1059
1060
        /*
1061
         * What is the bit position for the most significant bit(MSB) of S
1062
         * which is set? This is checked before shifting and before possibly
1063
         * converting to a negative integer. Note that later use of this value
1064
         * assumes that H5T__bit_shift will always shift in 0 during a right
1065
         * shift.
1066
         */
1067
0
        msb_pos_s = H5T__bit_find(int_buf, (size_t)0, src_atomic.prec, H5T_BIT_MSB, true);
1068
1069
        /* The temporary buffer has no bits set and must therefore be zero; nothing to do. */
1070
0
        if (msb_pos_s < 0)
1071
0
            goto padding;
1072
1073
        /*
1074
         * Shift mantissa part by exponent minus mantissa size(right shift),
1075
         * or by mantissa size minus exponent(left shift).  Example: Sequence
1076
         * 10...010111, expo=20, expo-msize=-3.  Right-shift the sequence, we get
1077
         * 00010...10.  The last three bits were dropped.
1078
         */
1079
0
        shift_val = expo - (ssize_t)src_atomic.u.f.msize;
1080
0
        H5T__bit_shift(int_buf, shift_val, (size_t)0, int_buf_size * 8);
1081
1082
        /* Calculate the new position of the MSB after shifting and
1083
         * skip to the padding section if we shifted exactly to 0
1084
         * (MSB position is -1)
1085
         */
1086
0
        new_msb_pos = msb_pos_s + shift_val;
1087
0
        if (new_msb_pos == -1)
1088
0
            goto padding;
1089
1090
        /*
1091
         * If expo is less than mantissa size, the fractional value is dropped off
1092
         * during conversion. Set exception type to be "truncate"
1093
         */
1094
0
        if ((size_t)expo < src_atomic.u.f.msize && conv_ctx->u.conv.cb_struct.func)
1095
0
            truncated = true;
1096
1097
0
        if (H5T_SGN_NONE == dst_atomic.u.i.sign) { /* destination is unsigned */
1098
            /*
1099
             * Destination is unsigned. Library's default way: If the source value
1100
             * is greater than the maximal destination value then it overflows, the
1101
             * destination will be set to the maximum possible value. When the
1102
             * source is negative, underflow happens. Set the destination to be
1103
             * zero (do nothing). If user's exception handler is set, call it and
1104
             * let user handle it.
1105
             */
1106
0
            if (sign) { /* source is negative */
1107
                /* If user's exception handler is present, use it */
1108
0
                if (conv_ctx->u.conv.cb_struct.func) {
1109
                    /* Reverse source buffer order first */
1110
0
                    H5T__reverse_order(src_rev, s, src_p);
1111
1112
                    /* Prepare & restore library for user callback */
1113
0
                    H5_BEFORE_USER_CB(FAIL)
1114
0
                        {
1115
0
                            except_ret = (conv_ctx->u.conv.cb_struct.func)(
1116
0
                                H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id,
1117
0
                                conv_ctx->u.conv.dst_type_id, src_rev, d,
1118
0
                                conv_ctx->u.conv.cb_struct.user_data);
1119
0
                        }
1120
0
                    H5_AFTER_USER_CB(FAIL)
1121
1122
0
                    if (except_ret == H5T_CONV_HANDLED) {
1123
                        /* No need to reverse the order of destination because user handles it */
1124
0
                        reverse = false;
1125
0
                        goto next;
1126
0
                    }
1127
0
                    else if (except_ret == H5T_CONV_ABORT)
1128
0
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
1129
0
                }
1130
0
            }
1131
0
            else { /* source is positive */
1132
0
                if (new_msb_pos >= (ssize_t)dst_atomic.prec) {
1133
                    /* overflow - if user's exception handler is present, use it */
1134
0
                    if (conv_ctx->u.conv.cb_struct.func) {
1135
                        /* Reverse source buffer order first */
1136
0
                        H5T__reverse_order(src_rev, s, src_p);
1137
1138
                        /* Prepare & restore library for user callback */
1139
0
                        H5_BEFORE_USER_CB(FAIL)
1140
0
                            {
1141
0
                                except_ret = (conv_ctx->u.conv.cb_struct.func)(
1142
0
                                    H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id,
1143
0
                                    conv_ctx->u.conv.dst_type_id, src_rev, d,
1144
0
                                    conv_ctx->u.conv.cb_struct.user_data);
1145
0
                            }
1146
0
                        H5_AFTER_USER_CB(FAIL)
1147
0
                    }
1148
1149
0
                    if (except_ret == H5T_CONV_UNHANDLED)
1150
0
                        H5T__bit_set(d, dst_atomic.offset, dst_atomic.prec, true);
1151
0
                    else if (except_ret == H5T_CONV_HANDLED) {
1152
                        /* No need to reverse the order of destination because user handles it */
1153
0
                        reverse = false;
1154
0
                        goto next;
1155
0
                    }
1156
0
                    else if (except_ret == H5T_CONV_ABORT)
1157
0
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
1158
0
                }
1159
0
                else {
1160
                    /* If user's exception handler is present, use it */
1161
0
                    if (truncated && conv_ctx->u.conv.cb_struct.func) {
1162
                        /* Reverse source buffer order first */
1163
0
                        H5T__reverse_order(src_rev, s, src_p);
1164
1165
                        /* Prepare & restore library for user callback */
1166
0
                        H5_BEFORE_USER_CB(FAIL)
1167
0
                            {
1168
0
                                except_ret = (conv_ctx->u.conv.cb_struct.func)(
1169
0
                                    H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id,
1170
0
                                    conv_ctx->u.conv.dst_type_id, src_rev, d,
1171
0
                                    conv_ctx->u.conv.cb_struct.user_data);
1172
0
                            }
1173
0
                        H5_AFTER_USER_CB(FAIL)
1174
0
                    }
1175
1176
0
                    if (except_ret == H5T_CONV_UNHANDLED) {
1177
                        /* copy source value into it if case is ignored by user handler */
1178
0
                        if (new_msb_pos >= 0)
1179
0
                            H5T__bit_copy(d, dst_atomic.offset, int_buf, (size_t)0, (size_t)new_msb_pos + 1);
1180
0
                    }
1181
0
                    else if (except_ret == H5T_CONV_HANDLED) {
1182
                        /* No need to reverse the order of destination because user handles it */
1183
0
                        reverse = false;
1184
0
                        goto next;
1185
0
                    }
1186
0
                    else if (except_ret == H5T_CONV_ABORT)
1187
0
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
1188
0
                }
1189
0
            }
1190
0
        }
1191
0
        else if (H5T_SGN_2 == dst_atomic.u.i.sign) { /* Destination is signed */
1192
0
            if (sign) {                              /* source is negative */
1193
0
                if ((new_msb_pos >= 0) && ((size_t)new_msb_pos < dst_atomic.prec - 1)) {
1194
                    /* If user's exception handler is present, use it */
1195
0
                    if (truncated && conv_ctx->u.conv.cb_struct.func) {
1196
                        /* Reverse source buffer order first */
1197
0
                        H5T__reverse_order(src_rev, s, src_p);
1198
1199
                        /* Prepare & restore library for user callback */
1200
0
                        H5_BEFORE_USER_CB(FAIL)
1201
0
                            {
1202
0
                                except_ret = (conv_ctx->u.conv.cb_struct.func)(
1203
0
                                    H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id,
1204
0
                                    conv_ctx->u.conv.dst_type_id, src_rev, d,
1205
0
                                    conv_ctx->u.conv.cb_struct.user_data);
1206
0
                            }
1207
0
                        H5_AFTER_USER_CB(FAIL)
1208
0
                    }
1209
1210
0
                    if (except_ret == H5T_CONV_UNHANDLED) { /* If this case ignored by user handler */
1211
                        /* Convert to integer representation. Equivalent to ~(value - 1). */
1212
0
                        H5T__bit_dec(int_buf, (size_t)0, dst_atomic.prec);
1213
0
                        H5T__bit_neg(int_buf, (size_t)0, dst_atomic.prec);
1214
1215
                        /* copy source value into destination */
1216
0
                        H5T__bit_copy(d, dst_atomic.offset, int_buf, (size_t)0, dst_atomic.prec - 1);
1217
0
                        H5T__bit_set(d, (dst_atomic.offset + dst_atomic.prec - 1), (size_t)1, true);
1218
0
                    }
1219
0
                    else if (except_ret == H5T_CONV_HANDLED) {
1220
                        /* No need to reverse the order of destination because user handles it */
1221
0
                        reverse = false;
1222
0
                        goto next;
1223
0
                    }
1224
0
                    else if (except_ret == H5T_CONV_ABORT)
1225
0
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
1226
0
                }
1227
0
                else {
1228
                    /* if underflows and no callback, do nothing except turn on
1229
                     * the sign bit because 0x80...00 is the biggest negative value.
1230
                     * If user's exception handler is present, use it
1231
                     */
1232
0
                    if (conv_ctx->u.conv.cb_struct.func) {
1233
                        /* Reverse source buffer order first */
1234
0
                        H5T__reverse_order(src_rev, s, src_p);
1235
1236
                        /* Prepare & restore library for user callback */
1237
0
                        H5_BEFORE_USER_CB(FAIL)
1238
0
                            {
1239
0
                                except_ret = (conv_ctx->u.conv.cb_struct.func)(
1240
0
                                    H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id,
1241
0
                                    conv_ctx->u.conv.dst_type_id, src_rev, d,
1242
0
                                    conv_ctx->u.conv.cb_struct.user_data);
1243
0
                            }
1244
0
                        H5_AFTER_USER_CB(FAIL)
1245
0
                    }
1246
1247
0
                    if (except_ret == H5T_CONV_UNHANDLED)
1248
0
                        H5T__bit_set(d, (dst_atomic.offset + dst_atomic.prec - 1), (size_t)1, true);
1249
0
                    else if (except_ret == H5T_CONV_HANDLED) {
1250
                        /* No need to reverse the order of destination because user handles it */
1251
0
                        reverse = false;
1252
0
                        goto next;
1253
0
                    }
1254
0
                    else if (except_ret == H5T_CONV_ABORT)
1255
0
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
1256
0
                }
1257
0
            }
1258
0
            else { /* source is positive */
1259
0
                if (new_msb_pos >= (ssize_t)dst_atomic.prec - 1) {
1260
                    /* overflow - if user's exception handler is present, use it */
1261
0
                    if (conv_ctx->u.conv.cb_struct.func) {
1262
                        /* Reverse source buffer order first */
1263
0
                        H5T__reverse_order(src_rev, s, src_p);
1264
1265
                        /* Prepare & restore library for user callback */
1266
0
                        H5_BEFORE_USER_CB(FAIL)
1267
0
                            {
1268
0
                                except_ret = (conv_ctx->u.conv.cb_struct.func)(
1269
0
                                    H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id,
1270
0
                                    conv_ctx->u.conv.dst_type_id, src_rev, d,
1271
0
                                    conv_ctx->u.conv.cb_struct.user_data);
1272
0
                            }
1273
0
                        H5_AFTER_USER_CB(FAIL)
1274
0
                    }
1275
1276
0
                    if (except_ret == H5T_CONV_UNHANDLED)
1277
0
                        H5T__bit_set(d, dst_atomic.offset, dst_atomic.prec - 1, true);
1278
0
                    else if (except_ret == H5T_CONV_HANDLED) {
1279
                        /* No need to reverse the order of destination because user handles it */
1280
0
                        reverse = false;
1281
0
                        goto next;
1282
0
                    }
1283
0
                    else if (except_ret == H5T_CONV_ABORT)
1284
0
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
1285
0
                }
1286
0
                else if (new_msb_pos < (ssize_t)dst_atomic.prec - 1) {
1287
                    /* If user's exception handler is present, use it */
1288
0
                    if (truncated && conv_ctx->u.conv.cb_struct.func) {
1289
                        /* Reverse source buffer order first */
1290
0
                        H5T__reverse_order(src_rev, s, src_p);
1291
1292
                        /* Prepare & restore library for user callback */
1293
0
                        H5_BEFORE_USER_CB(FAIL)
1294
0
                            {
1295
0
                                except_ret = (conv_ctx->u.conv.cb_struct.func)(
1296
0
                                    H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id,
1297
0
                                    conv_ctx->u.conv.dst_type_id, src_rev, d,
1298
0
                                    conv_ctx->u.conv.cb_struct.user_data);
1299
0
                            }
1300
0
                        H5_AFTER_USER_CB(FAIL)
1301
0
                    }
1302
1303
0
                    if (except_ret == H5T_CONV_UNHANDLED) {
1304
                        /* copy source value into it if case is ignored by user handler */
1305
0
                        if (new_msb_pos >= 0)
1306
0
                            H5T__bit_copy(d, dst_atomic.offset, int_buf, (size_t)0, (size_t)new_msb_pos + 1);
1307
0
                    }
1308
0
                    else if (except_ret == H5T_CONV_HANDLED) {
1309
                        /* No need to reverse the order of destination because user handles it */
1310
0
                        reverse = false;
1311
0
                        goto next;
1312
0
                    }
1313
0
                    else if (except_ret == H5T_CONV_ABORT)
1314
0
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception");
1315
0
                }
1316
0
            }
1317
0
        }
1318
1319
0
padding:
1320
        /* Set padding areas in destination. */
1321
0
        if (dst_atomic.offset > 0) {
1322
0
            assert(H5T_PAD_ZERO == dst_atomic.lsb_pad || H5T_PAD_ONE == dst_atomic.lsb_pad);
1323
0
            H5T__bit_set(d, (size_t)0, dst_atomic.offset, (bool)(H5T_PAD_ONE == dst_atomic.lsb_pad));
1324
0
        }
1325
0
        if (dst_atomic.offset + dst_atomic.prec != 8 * dst_p->shared->size) {
1326
0
            assert(H5T_PAD_ZERO == dst_atomic.msb_pad || H5T_PAD_ONE == dst_atomic.msb_pad);
1327
0
            H5T__bit_set(d, dst_atomic.offset + dst_atomic.prec,
1328
0
                         8 * dst_p->shared->size - (dst_atomic.offset + dst_atomic.prec),
1329
0
                         (bool)(H5T_PAD_ONE == dst_atomic.msb_pad));
1330
0
        }
1331
1332
        /*
1333
         * Put the destination in the correct byte order. See note at
1334
         * beginning of loop.
1335
         */
1336
0
        if (H5T_ORDER_BE == dst_atomic.order && reverse)
1337
0
            for (size_t i = 0; i < dst_p->shared->size / 2; i++)
1338
0
                H5_SWAP_BYTES(d, i, dst_p->shared->size - (i + 1));
1339
1340
0
next:
1341
        /*
1342
         * If we had used a temporary buffer for the destination then we
1343
         * should copy the value to the true destination buffer.
1344
         */
1345
0
        if (d == dbuf)
1346
0
            H5MM_memcpy(dp, d, dst_p->shared->size);
1347
1348
        /* Advance source & destination pointers by delta amounts */
1349
0
        sp += src_delta;
1350
0
        dp += dst_delta;
1351
1352
0
        memset(int_buf, 0, int_buf_size);
1353
0
    } /* end conversion loop */
1354
1355
0
done:
1356
0
    H5MM_free(src_rev);
1357
0
    H5MM_free(int_buf);
1358
1359
0
    FUNC_LEAVE_NOAPI(ret_value)
1360
0
} /* H5T__conv_f_i_loop() */
1361
1362
/*-------------------------------------------------------------------------
1363
 * Function:    H5T__conv_f_complex
1364
 *
1365
 * Purpose:     Convert floating-point values to complex number values.
1366
 *              This is the catch-all function for float-complex number
1367
 *              conversions and is probably not particularly fast.
1368
 *
1369
 * Return:      Non-negative on success/Negative on failure
1370
 *
1371
 *-------------------------------------------------------------------------
1372
 */
1373
herr_t
1374
H5T__conv_f_complex(const H5T_t *src_p, const H5T_t *dst_p, H5T_cdata_t *cdata,
1375
                    const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
1376
                    size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
1377
0
{
1378
0
    bool   equal_cplx_conv = false; /* if converting between complex and matching float */
1379
0
    herr_t ret_value       = SUCCEED;
1380
1381
0
    FUNC_ENTER_PACKAGE
1382
1383
0
    switch (cdata->command) {
1384
0
        case H5T_CONV_INIT: {
1385
0
            H5T_atomic_t src_atomic; /* source datatype atomic info      */
1386
0
            H5T_atomic_t dst_atomic; /* destination datatype atomic info */
1387
1388
0
            if (!src_p || !dst_p)
1389
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
1390
0
            if (!H5T_IS_ATOMIC(dst_p->shared->parent->shared))
1391
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid complex number datatype");
1392
0
            src_atomic = src_p->shared->u.atomic;
1393
0
            dst_atomic = dst_p->shared->parent->shared->u.atomic;
1394
0
            if (H5T_ORDER_LE != src_atomic.order && H5T_ORDER_BE != src_atomic.order &&
1395
0
                H5T_ORDER_VAX != src_atomic.order)
1396
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
1397
0
                            "unsupported byte order for source datatype");
1398
0
            if (H5T_ORDER_LE != dst_atomic.order && H5T_ORDER_BE != dst_atomic.order)
1399
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
1400
0
                            "unsupported byte order for destination datatype");
1401
0
            if (dst_p->shared->size > TEMP_FLOAT_CONV_BUFFER_SIZE)
1402
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination datatype size is too large");
1403
0
            if (8 * sizeof(int64_t) - 1 < src_atomic.u.f.esize ||
1404
0
                8 * sizeof(int64_t) - 1 < dst_atomic.u.f.esize)
1405
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large");
1406
0
            cdata->need_bkg = H5T_BKG_NO;
1407
1408
0
            break;
1409
0
        }
1410
1411
0
        case H5T_CONV_FREE:
1412
0
            break;
1413
1414
0
        case H5T_CONV_CONV:
1415
0
            if (!src_p || !dst_p)
1416
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
1417
0
            if (NULL == conv_ctx)
1418
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer");
1419
1420
            /* Are we converting between a floating-point type and a complex number
1421
             * type consisting of the same floating-point type?
1422
             */
1423
0
            equal_cplx_conv = (0 == H5T_cmp(src_p, dst_p->shared->parent, false));
1424
0
            if (!equal_cplx_conv) {
1425
                /* If floating-point types differ, use generic f_f loop */
1426
0
                if (H5T__conv_f_f_loop(src_p, dst_p, conv_ctx, nelmts, buf_stride, buf) < 0)
1427
0
                    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "unable to convert data values");
1428
0
            }
1429
0
            else {
1430
                /* If floating-point types are the same, use specialized loop */
1431
0
                if (H5T__conv_complex_f_matched(src_p, dst_p, conv_ctx, nelmts, buf_stride, buf) < 0)
1432
0
                    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "unable to convert data values");
1433
0
            }
1434
1435
0
            break;
1436
1437
0
        default:
1438
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
1439
0
    }
1440
1441
0
done:
1442
0
    FUNC_LEAVE_NOAPI(ret_value)
1443
0
} /* end H5T__conv_f_complex() */
1444
1445
#ifdef H5_HAVE__FLOAT16
1446
/*-------------------------------------------------------------------------
1447
 * Function:    H5T__conv__Float16_schar
1448
 *
1449
 * Purpose:     Converts `_Float16' to `signed char'
1450
 *
1451
 * Return:      Non-negative on success/Negative on failure
1452
 *
1453
 *-------------------------------------------------------------------------
1454
 */
1455
herr_t
1456
H5T__conv__Float16_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1457
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1458
                         void H5_ATTR_UNUSED *bkg)
1459
{
1460
    H5_WARN_FLOAT_EQUAL_OFF
1461
    H5T_CONV_Fx(FLOAT16, SCHAR, H5__Float16, signed char, SCHAR_MIN, SCHAR_MAX);
1462
    H5_WARN_FLOAT_EQUAL_ON
1463
}
1464
1465
/*-------------------------------------------------------------------------
1466
 * Function:    H5T__conv__Float16_uchar
1467
 *
1468
 * Purpose:     Converts `_Float16' to `unsigned char'
1469
 *
1470
 * Return:      Non-negative on success/Negative on failure
1471
 *
1472
 *-------------------------------------------------------------------------
1473
 */
1474
herr_t
1475
H5T__conv__Float16_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1476
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1477
                         void H5_ATTR_UNUSED *bkg)
1478
{
1479
    H5_WARN_FLOAT_EQUAL_OFF
1480
    H5T_CONV_Fx(FLOAT16, UCHAR, H5__Float16, unsigned char, 0, UCHAR_MAX);
1481
    H5_WARN_FLOAT_EQUAL_ON
1482
}
1483
1484
/*-------------------------------------------------------------------------
1485
 * Function:    H5T__conv__Float16_short
1486
 *
1487
 * Purpose:     Converts `_Float16' to `signed short'
1488
 *
1489
 * Return:      Non-negative on success/Negative on failure
1490
 *
1491
 *-------------------------------------------------------------------------
1492
 */
1493
herr_t
1494
H5T__conv__Float16_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1495
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1496
                         void H5_ATTR_UNUSED *bkg)
1497
{
1498
    H5_WARN_FLOAT_EQUAL_OFF
1499
    H5T_CONV_Fx(FLOAT16, SHORT, H5__Float16, short, SHRT_MIN, SHRT_MAX);
1500
    H5_WARN_FLOAT_EQUAL_ON
1501
}
1502
1503
/*-------------------------------------------------------------------------
1504
 * Function:    H5T__conv__Float16_ushort
1505
 *
1506
 * Purpose:     Converts `_Float16' to `unsigned short'
1507
 *
1508
 * Return:      Non-negative on success/Negative on failure
1509
 *
1510
 *-------------------------------------------------------------------------
1511
 */
1512
herr_t
1513
H5T__conv__Float16_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
1514
                          const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
1515
                          size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
1516
{
1517
    H5T_CONV_fX(FLOAT16, USHORT, H5__Float16, unsigned short, 0, USHRT_MAX);
1518
}
1519
1520
/*-------------------------------------------------------------------------
1521
 * Function:    H5T__conv__Float16_int
1522
 *
1523
 * Purpose:     Converts `_Float16' to `signed int'
1524
 *
1525
 * Return:      Non-negative on success/Negative on failure
1526
 *
1527
 *-------------------------------------------------------------------------
1528
 */
1529
herr_t
1530
H5T__conv__Float16_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1531
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1532
                       void H5_ATTR_UNUSED *bkg)
1533
{
1534
    H5T_CONV_fX(FLOAT16, INT, H5__Float16, int, INT_MIN, INT_MAX);
1535
}
1536
1537
/*-------------------------------------------------------------------------
1538
 * Function:    H5T__conv__Float16_uint
1539
 *
1540
 * Purpose:     Converts `_Float16' to `unsigned int'
1541
 *
1542
 * Return:      Non-negative on success/Negative on failure
1543
 *
1544
 *-------------------------------------------------------------------------
1545
 */
1546
herr_t
1547
H5T__conv__Float16_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1548
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1549
                        void H5_ATTR_UNUSED *bkg)
1550
{
1551
    H5T_CONV_fX(FLOAT16, UINT, H5__Float16, unsigned int, 0, UINT_MAX);
1552
}
1553
1554
/*-------------------------------------------------------------------------
1555
 * Function:    H5T__conv__Float16_long
1556
 *
1557
 * Purpose:     Converts `_Float16' to `signed long'
1558
 *
1559
 * Return:      Non-negative on success/Negative on failure
1560
 *
1561
 *-------------------------------------------------------------------------
1562
 */
1563
herr_t
1564
H5T__conv__Float16_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1565
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1566
                        void H5_ATTR_UNUSED *bkg)
1567
{
1568
    H5T_CONV_fX(FLOAT16, LONG, H5__Float16, long, LONG_MIN, LONG_MAX);
1569
}
1570
1571
/*-------------------------------------------------------------------------
1572
 * Function:    H5T__conv__Float16_ulong
1573
 *
1574
 * Purpose:     Converts `_Float16' to `unsigned long'
1575
 *
1576
 * Return:      Non-negative on success/Negative on failure
1577
 *
1578
 *-------------------------------------------------------------------------
1579
 */
1580
herr_t
1581
H5T__conv__Float16_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1582
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1583
                         void H5_ATTR_UNUSED *bkg)
1584
{
1585
    H5T_CONV_fX(FLOAT16, ULONG, H5__Float16, unsigned long, 0, ULONG_MAX);
1586
}
1587
1588
/*-------------------------------------------------------------------------
1589
 * Function:    H5T__conv__Float16_llong
1590
 *
1591
 * Purpose:     Converts `_Float16' to `signed long long'
1592
 *
1593
 * Return:      Non-negative on success/Negative on failure
1594
 *
1595
 *-------------------------------------------------------------------------
1596
 */
1597
herr_t
1598
H5T__conv__Float16_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1599
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1600
                         void H5_ATTR_UNUSED *bkg)
1601
{
1602
    H5T_CONV_fX(FLOAT16, LLONG, H5__Float16, long long, LLONG_MIN, LLONG_MAX);
1603
}
1604
1605
/*-------------------------------------------------------------------------
1606
 * Function:    H5T__conv__Float16_ullong
1607
 *
1608
 * Purpose:     Converts `_Float16' to `unsigned long long'
1609
 *
1610
 * Return:      Non-negative on success/Negative on failure
1611
 *
1612
 *-------------------------------------------------------------------------
1613
 */
1614
herr_t
1615
H5T__conv__Float16_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
1616
                          const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
1617
                          size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
1618
{
1619
    H5T_CONV_fX(FLOAT16, ULLONG, H5__Float16, unsigned long long, 0, ULLONG_MAX);
1620
}
1621
1622
/*-------------------------------------------------------------------------
1623
 * Function:    H5T__conv__Float16_float
1624
 *
1625
 * Purpose:     Converts `_Float16' to `float'
1626
 *
1627
 * Return:      Non-negative on success/Negative on failure
1628
 *
1629
 *-------------------------------------------------------------------------
1630
 */
1631
herr_t
1632
H5T__conv__Float16_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1633
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1634
                         void H5_ATTR_UNUSED *bkg)
1635
{
1636
    H5T_CONV_fF(FLOAT16, FLOAT, H5__Float16, float, -, -);
1637
}
1638
1639
/*-------------------------------------------------------------------------
1640
 * Function:    H5T__conv__Float16_double
1641
 *
1642
 * Purpose:     Converts `_Float16' to `double'
1643
 *
1644
 * Return:      Non-negative on success/Negative on failure
1645
 *
1646
 *-------------------------------------------------------------------------
1647
 */
1648
herr_t
1649
H5T__conv__Float16_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
1650
                          const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
1651
                          size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
1652
{
1653
    H5T_CONV_fF(FLOAT16, DOUBLE, H5__Float16, double, -, -);
1654
}
1655
1656
/*-------------------------------------------------------------------------
1657
 * Function:    H5T__conv__Float16_ldouble
1658
 *
1659
 * Purpose:     Converts `_Float16' to `long double'
1660
 *
1661
 * Return:      Non-negative on success/Negative on failure
1662
 *
1663
 *-------------------------------------------------------------------------
1664
 */
1665
herr_t
1666
H5T__conv__Float16_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
1667
                           const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
1668
                           size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
1669
{
1670
    H5T_CONV_fF(FLOAT16, LDOUBLE, H5__Float16, long double, -, -);
1671
}
1672
1673
#ifdef H5_HAVE_COMPLEX_NUMBERS
1674
/*-------------------------------------------------------------------------
1675
 * Function:    H5T__conv__Float16_fcomplex
1676
 *
1677
 * Purpose:     Converts `_Float16' to `float _Complex' / `_Fcomplex'
1678
 *
1679
 * Return:      Non-negative on success/Negative on failure
1680
 *
1681
 *-------------------------------------------------------------------------
1682
 */
1683
herr_t
1684
H5T__conv__Float16_fcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
1685
                            const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
1686
                            size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
1687
{
1688
    H5T_CONV_fZ(FLOAT16, FLOAT_COMPLEX, H5__Float16, H5_float_complex, -, -);
1689
}
1690
1691
/*-------------------------------------------------------------------------
1692
 * Function:    H5T__conv__Float16_dcomplex
1693
 *
1694
 * Purpose:     Converts `_Float16' to `double _Complex' / `_Dcomplex'
1695
 *
1696
 * Return:      Non-negative on success/Negative on failure
1697
 *
1698
 *-------------------------------------------------------------------------
1699
 */
1700
herr_t
1701
H5T__conv__Float16_dcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
1702
                            const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
1703
                            size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
1704
{
1705
    H5T_CONV_fZ(FLOAT16, DOUBLE_COMPLEX, H5__Float16, H5_double_complex, -, -);
1706
}
1707
1708
/*-------------------------------------------------------------------------
1709
 * Function:    H5T__conv__Float16_lcomplex
1710
 *
1711
 * Purpose:     Converts `_Float16' to `long double _Complex' / `_Lcomplex'
1712
 *
1713
 * Return:      Non-negative on success/Negative on failure
1714
 *
1715
 *-------------------------------------------------------------------------
1716
 */
1717
herr_t
1718
H5T__conv__Float16_lcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
1719
                            const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
1720
                            size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
1721
{
1722
    H5T_CONV_fZ(FLOAT16, LDOUBLE_COMPLEX, H5__Float16, H5_ldouble_complex, -, -);
1723
}
1724
#endif
1725
#endif
1726
1727
/*-------------------------------------------------------------------------
1728
 * Function:    H5T__conv_float_schar
1729
 *
1730
 * Purpose:     Convert native float to native signed char using
1731
 *              hardware. This is a fast special case.
1732
 *
1733
 * Return:      Non-negative on success/Negative on failure
1734
 *
1735
 *-------------------------------------------------------------------------
1736
 */
1737
herr_t
1738
H5T__conv_float_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1739
                      size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1740
                      void H5_ATTR_UNUSED *bkg)
1741
4
{
1742
4
    H5_WARN_FLOAT_EQUAL_OFF
1743
4
    H5T_CONV_Fx(FLOAT, SCHAR, float, signed char, SCHAR_MIN, SCHAR_MAX);
1744
4
    H5_WARN_FLOAT_EQUAL_ON
1745
4
}
1746
1747
/*-------------------------------------------------------------------------
1748
 * Function:    H5T__conv_float_uchar
1749
 *
1750
 * Purpose:     Convert native float to native unsigned char using
1751
 *              hardware. This is a fast special case.
1752
 *
1753
 * Return:      Non-negative on success/Negative on failure
1754
 *
1755
 *-------------------------------------------------------------------------
1756
 */
1757
herr_t
1758
H5T__conv_float_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1759
                      size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1760
                      void H5_ATTR_UNUSED *bkg)
1761
4
{
1762
4
    H5_WARN_FLOAT_EQUAL_OFF
1763
4
    H5T_CONV_Fx(FLOAT, UCHAR, float, unsigned char, 0, UCHAR_MAX);
1764
4
    H5_WARN_FLOAT_EQUAL_ON
1765
4
}
1766
1767
/*-------------------------------------------------------------------------
1768
 * Function:    H5T__conv_float_short
1769
 *
1770
 * Purpose:     Convert native float to native short using
1771
 *              hardware. This is a fast special case.
1772
 *
1773
 * Return:      Non-negative on success/Negative on failure
1774
 *
1775
 *-------------------------------------------------------------------------
1776
 */
1777
herr_t
1778
H5T__conv_float_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1779
                      size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1780
                      void H5_ATTR_UNUSED *bkg)
1781
4
{
1782
4
    H5_WARN_FLOAT_EQUAL_OFF
1783
4
    H5T_CONV_Fx(FLOAT, SHORT, float, short, SHRT_MIN, SHRT_MAX);
1784
4
    H5_WARN_FLOAT_EQUAL_ON
1785
4
}
1786
1787
/*-------------------------------------------------------------------------
1788
 * Function:    H5T__conv_float_ushort
1789
 *
1790
 * Purpose:     Convert native float to native unsigned short using
1791
 *              hardware. This is a fast special case.
1792
 *
1793
 * Return:      Non-negative on success/Negative on failure
1794
 *
1795
 *-------------------------------------------------------------------------
1796
 */
1797
herr_t
1798
H5T__conv_float_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1799
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1800
                       void H5_ATTR_UNUSED *bkg)
1801
4
{
1802
4
    H5_WARN_FLOAT_EQUAL_OFF
1803
4
    H5T_CONV_Fx(FLOAT, USHORT, float, unsigned short, 0, USHRT_MAX);
1804
4
    H5_WARN_FLOAT_EQUAL_ON
1805
4
}
1806
1807
/*-------------------------------------------------------------------------
1808
 * Function:    H5T__conv_float_int
1809
 *
1810
 * Purpose:     Convert native float to native int using
1811
 *              hardware. This is a fast special case.
1812
 *
1813
 * Return:      Non-negative on success/Negative on failure
1814
 *
1815
 *-------------------------------------------------------------------------
1816
 */
1817
herr_t
1818
H5T__conv_float_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1819
                    size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1820
                    void H5_ATTR_UNUSED *bkg)
1821
4
{
1822
4
    H5_WARN_FLOAT_EQUAL_OFF
1823
4
    H5T_CONV_Fx(FLOAT, INT, float, int, INT_MIN, INT_MAX);
1824
4
    H5_WARN_FLOAT_EQUAL_ON
1825
4
}
1826
1827
/*-------------------------------------------------------------------------
1828
 * Function:    H5T__conv_float_uint
1829
 *
1830
 * Purpose:     Convert native float to native unsigned int using
1831
 *              hardware. This is a fast special case.
1832
 *
1833
 * Return:      Non-negative on success/Negative on failure
1834
 *
1835
 *-------------------------------------------------------------------------
1836
 */
1837
herr_t
1838
H5T__conv_float_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1839
                     size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1840
                     void H5_ATTR_UNUSED *bkg)
1841
4
{
1842
4
    H5_WARN_FLOAT_EQUAL_OFF
1843
4
    H5T_CONV_Fx(FLOAT, UINT, float, unsigned int, 0, UINT_MAX);
1844
4
    H5_WARN_FLOAT_EQUAL_ON
1845
4
}
1846
1847
/*-------------------------------------------------------------------------
1848
 * Function:    H5T__conv_float_long
1849
 *
1850
 * Purpose:     Convert native float to native long using
1851
 *              hardware. This is a fast special case.
1852
 *
1853
 * Return:      Non-negative on success/Negative on failure
1854
 *
1855
 *-------------------------------------------------------------------------
1856
 */
1857
herr_t
1858
H5T__conv_float_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1859
                     size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1860
                     void H5_ATTR_UNUSED *bkg)
1861
4
{
1862
4
    H5_WARN_FLOAT_EQUAL_OFF
1863
4
    H5T_CONV_Fx(FLOAT, LONG, float, long, LONG_MIN, LONG_MAX);
1864
4
    H5_WARN_FLOAT_EQUAL_ON
1865
4
}
1866
1867
/*-------------------------------------------------------------------------
1868
 * Function:    H5T__conv_float_ulong
1869
 *
1870
 * Purpose:     Convert native float to native unsigned long using
1871
 *              hardware. This is a fast special case.
1872
 *
1873
 * Return:      Non-negative on success/Negative on failure
1874
 *
1875
 *-------------------------------------------------------------------------
1876
 */
1877
herr_t
1878
H5T__conv_float_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1879
                      size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1880
                      void H5_ATTR_UNUSED *bkg)
1881
4
{
1882
4
    H5_WARN_FLOAT_EQUAL_OFF
1883
4
    H5T_CONV_Fx(FLOAT, ULONG, float, unsigned long, 0, ULONG_MAX);
1884
4
    H5_WARN_FLOAT_EQUAL_ON
1885
4
}
1886
1887
/*-------------------------------------------------------------------------
1888
 * Function:    H5T__conv_float_llong
1889
 *
1890
 * Purpose:     Convert native float to native long long using
1891
 *              hardware. This is a fast special case.
1892
 *
1893
 * Return:      Non-negative on success/Negative on failure
1894
 *
1895
 *-------------------------------------------------------------------------
1896
 */
1897
herr_t
1898
H5T__conv_float_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1899
                      size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1900
                      void H5_ATTR_UNUSED *bkg)
1901
0
{
1902
0
    H5_WARN_FLOAT_EQUAL_OFF
1903
0
    H5T_CONV_Fx(FLOAT, LLONG, float, long long, LLONG_MIN, LLONG_MAX);
1904
0
    H5_WARN_FLOAT_EQUAL_ON
1905
0
}
1906
1907
/*-------------------------------------------------------------------------
1908
 * Function:    H5T__conv_float_ullong
1909
 *
1910
 * Purpose:     Convert native float to native unsigned long long using
1911
 *              hardware. This is a fast special case.
1912
 *
1913
 * Return:      Non-negative on success/Negative on failure
1914
 *
1915
 *-------------------------------------------------------------------------
1916
 */
1917
herr_t
1918
H5T__conv_float_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1919
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1920
                       void H5_ATTR_UNUSED *bkg)
1921
0
{
1922
0
    H5_WARN_FLOAT_EQUAL_OFF
1923
0
    H5T_CONV_Fx(FLOAT, ULLONG, float, unsigned long long, 0, ULLONG_MAX);
1924
0
    H5_WARN_FLOAT_EQUAL_ON
1925
0
}
1926
1927
#ifdef H5_HAVE__FLOAT16
1928
/*-------------------------------------------------------------------------
1929
 * Function:    H5T__conv_float__Float16
1930
 *
1931
 * Purpose:     Convert native float to native _Float16 using hardware.
1932
 *              This is a fast special case.
1933
 *
1934
 * Return:      Non-negative on success/Negative on failure
1935
 *
1936
 *-------------------------------------------------------------------------
1937
 */
1938
herr_t
1939
H5T__conv_float__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1940
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1941
                         void H5_ATTR_UNUSED *bkg)
1942
{
1943
    /* Suppress warning about non-standard floating-point literal suffix */
1944
    H5_WARN_NONSTD_SUFFIX_OFF
1945
    H5T_CONV_Ff(FLOAT, FLOAT16, float, H5__Float16, -FLT16_MAX, FLT16_MAX);
1946
    H5_WARN_NONSTD_SUFFIX_ON
1947
}
1948
#endif
1949
1950
/*-------------------------------------------------------------------------
1951
 * Function:    H5T__conv_float_double
1952
 *
1953
 * Purpose:     Convert native `float' to native `double' using hardware.
1954
 *              This is a fast special case.
1955
 *
1956
 * Return:      Non-negative on success/Negative on failure
1957
 *
1958
 *-------------------------------------------------------------------------
1959
 */
1960
herr_t
1961
H5T__conv_float_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1962
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1963
                       void H5_ATTR_UNUSED *bkg)
1964
4
{
1965
4
    H5T_CONV_fF(FLOAT, DOUBLE, float, double, -, -);
1966
4
}
1967
1968
/*-------------------------------------------------------------------------
1969
 * Function:    H5T__conv_float_ldouble
1970
 *
1971
 * Purpose:     Convert native `float' to native `long double' using
1972
 *              hardware. This is a fast special case.
1973
 *
1974
 * Return:      Non-negative on success/Negative on failure
1975
 *
1976
 *-------------------------------------------------------------------------
1977
 */
1978
herr_t
1979
H5T__conv_float_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
1980
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
1981
                        void H5_ATTR_UNUSED *bkg)
1982
4
{
1983
4
    H5T_CONV_fF(FLOAT, LDOUBLE, float, long double, -, -);
1984
4
}
1985
1986
#ifdef H5_HAVE_COMPLEX_NUMBERS
1987
/*-------------------------------------------------------------------------
1988
 * Function:    H5T__conv_float_fcomplex
1989
 *
1990
 * Purpose:     Convert native `float' to native
1991
 *              `float _Complex' / `_Fcomplex' using hardware. This is a
1992
 *              fast special case.
1993
 *
1994
 * Return:      Non-negative on success/Negative on failure
1995
 *
1996
 *-------------------------------------------------------------------------
1997
 */
1998
herr_t
1999
H5T__conv_float_fcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2000
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2001
                         void H5_ATTR_UNUSED *bkg)
2002
4
{
2003
4
    H5T_CONV_fz(FLOAT, FLOAT_COMPLEX, float, H5_float_complex, -, -);
2004
4
}
2005
2006
/*-------------------------------------------------------------------------
2007
 * Function:    H5T__conv_float_dcomplex
2008
 *
2009
 * Purpose:     Convert native `float' to native
2010
 *              `double _Complex' / `_Dcomplex' using hardware. This is a
2011
 *              fast special case.
2012
 *
2013
 * Return:      Non-negative on success/Negative on failure
2014
 *
2015
 *-------------------------------------------------------------------------
2016
 */
2017
herr_t
2018
H5T__conv_float_dcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2019
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2020
                         void H5_ATTR_UNUSED *bkg)
2021
4
{
2022
4
    H5T_CONV_fZ(FLOAT, DOUBLE_COMPLEX, float, H5_double_complex, -, -);
2023
4
}
2024
2025
/*-------------------------------------------------------------------------
2026
 * Function:    H5T__conv_float_lcomplex
2027
 *
2028
 * Purpose:     Convert native `float' to native
2029
 *              `long double _Complex' / `_Lcomplex' using hardware. This
2030
 *              is a fast special case.
2031
 *
2032
 * Return:      Non-negative on success/Negative on failure
2033
 *
2034
 *-------------------------------------------------------------------------
2035
 */
2036
herr_t
2037
H5T__conv_float_lcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2038
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2039
                         void H5_ATTR_UNUSED *bkg)
2040
4
{
2041
4
    H5T_CONV_fZ(FLOAT, LDOUBLE_COMPLEX, float, H5_ldouble_complex, -, -);
2042
4
}
2043
#endif
2044
2045
/*-------------------------------------------------------------------------
2046
 * Function:    H5T__conv_double_schar
2047
 *
2048
 * Purpose:     Convert native double to native signed char using
2049
 *              hardware. This is a fast special case.
2050
 *
2051
 * Return:      Non-negative on success/Negative on failure
2052
 *
2053
 *-------------------------------------------------------------------------
2054
 */
2055
herr_t
2056
H5T__conv_double_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2057
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2058
                       void H5_ATTR_UNUSED *bkg)
2059
4
{
2060
4
    H5_WARN_FLOAT_EQUAL_OFF
2061
4
    H5T_CONV_Fx(DOUBLE, SCHAR, double, signed char, SCHAR_MIN, SCHAR_MAX);
2062
4
    H5_WARN_FLOAT_EQUAL_ON
2063
4
}
2064
2065
/*-------------------------------------------------------------------------
2066
 * Function:    H5T__conv_double_uchar
2067
 *
2068
 * Purpose:     Convert native double to native unsigned char using
2069
 *              hardware. This is a fast special case.
2070
 *
2071
 * Return:      Non-negative on success/Negative on failure
2072
 *
2073
 *-------------------------------------------------------------------------
2074
 */
2075
herr_t
2076
H5T__conv_double_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2077
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2078
                       void H5_ATTR_UNUSED *bkg)
2079
4
{
2080
4
    H5_WARN_FLOAT_EQUAL_OFF
2081
4
    H5T_CONV_Fx(DOUBLE, UCHAR, double, unsigned char, 0, UCHAR_MAX);
2082
4
    H5_WARN_FLOAT_EQUAL_ON
2083
4
}
2084
2085
/*-------------------------------------------------------------------------
2086
 * Function:    H5T__conv_double_short
2087
 *
2088
 * Purpose:     Convert native double to native short using
2089
 *              hardware. This is a fast special case.
2090
 *
2091
 * Return:      Non-negative on success/Negative on failure
2092
 *
2093
 *-------------------------------------------------------------------------
2094
 */
2095
herr_t
2096
H5T__conv_double_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2097
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2098
                       void H5_ATTR_UNUSED *bkg)
2099
4
{
2100
4
    H5_WARN_FLOAT_EQUAL_OFF
2101
4
    H5T_CONV_Fx(DOUBLE, SHORT, double, short, SHRT_MIN, SHRT_MAX);
2102
4
    H5_WARN_FLOAT_EQUAL_ON
2103
4
}
2104
2105
/*-------------------------------------------------------------------------
2106
 * Function:    H5T__conv_double_ushort
2107
 *
2108
 * Purpose:     Convert native double to native unsigned short using
2109
 *              hardware. This is a fast special case.
2110
 *
2111
 * Return:      Non-negative on success/Negative on failure
2112
 *
2113
 *-------------------------------------------------------------------------
2114
 */
2115
herr_t
2116
H5T__conv_double_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2117
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2118
                        void H5_ATTR_UNUSED *bkg)
2119
4
{
2120
4
    H5_WARN_FLOAT_EQUAL_OFF
2121
4
    H5T_CONV_Fx(DOUBLE, USHORT, double, unsigned short, 0, USHRT_MAX);
2122
4
    H5_WARN_FLOAT_EQUAL_ON
2123
4
}
2124
2125
/*-------------------------------------------------------------------------
2126
 * Function:    H5T__conv_double_int
2127
 *
2128
 * Purpose:     Convert native double to native int using
2129
 *              hardware. This is a fast special case.
2130
 *
2131
 * Return:      Non-negative on success/Negative on failure
2132
 *
2133
 *-------------------------------------------------------------------------
2134
 */
2135
herr_t
2136
H5T__conv_double_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2137
                     size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2138
                     void H5_ATTR_UNUSED *bkg)
2139
4
{
2140
4
    H5_WARN_FLOAT_EQUAL_OFF
2141
4
    H5T_CONV_Fx(DOUBLE, INT, double, int, INT_MIN, INT_MAX);
2142
4
    H5_WARN_FLOAT_EQUAL_ON
2143
4
}
2144
2145
/*-------------------------------------------------------------------------
2146
 * Function:    H5T__conv_double_uint
2147
 *
2148
 * Purpose:     Convert native double to native unsigned int using
2149
 *              hardware. This is a fast special case.
2150
 *
2151
 * Return:      Non-negative on success/Negative on failure
2152
 *
2153
 *-------------------------------------------------------------------------
2154
 */
2155
herr_t
2156
H5T__conv_double_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2157
                      size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2158
                      void H5_ATTR_UNUSED *bkg)
2159
4
{
2160
4
    H5_WARN_FLOAT_EQUAL_OFF
2161
4
    H5T_CONV_Fx(DOUBLE, UINT, double, unsigned int, 0, UINT_MAX);
2162
4
    H5_WARN_FLOAT_EQUAL_ON
2163
4
}
2164
2165
/*-------------------------------------------------------------------------
2166
 * Function:    H5T__conv_double_long
2167
 *
2168
 * Purpose:     Convert native double to native long using
2169
 *              hardware. This is a fast special case.
2170
 *
2171
 * Return:      Non-negative on success/Negative on failure
2172
 *
2173
 *-------------------------------------------------------------------------
2174
 */
2175
herr_t
2176
H5T__conv_double_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2177
                      size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2178
                      void H5_ATTR_UNUSED *bkg)
2179
4
{
2180
4
    H5_WARN_FLOAT_EQUAL_OFF
2181
4
    H5T_CONV_Fx(DOUBLE, LONG, double, long, LONG_MIN, LONG_MAX);
2182
4
    H5_WARN_FLOAT_EQUAL_ON
2183
4
}
2184
2185
/*-------------------------------------------------------------------------
2186
 * Function:    H5T__conv_double_ulong
2187
 *
2188
 * Purpose:     Convert native double to native unsigned long using
2189
 *              hardware. This is a fast special case.
2190
 *
2191
 * Return:      Non-negative on success/Negative on failure
2192
 *
2193
 *-------------------------------------------------------------------------
2194
 */
2195
herr_t
2196
H5T__conv_double_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2197
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2198
                       void H5_ATTR_UNUSED *bkg)
2199
4
{
2200
4
    H5_WARN_FLOAT_EQUAL_OFF
2201
4
    H5T_CONV_Fx(DOUBLE, ULONG, double, unsigned long, 0, ULONG_MAX);
2202
4
    H5_WARN_FLOAT_EQUAL_ON
2203
4
}
2204
2205
/*-------------------------------------------------------------------------
2206
 * Function:    H5T__conv_double_llong
2207
 *
2208
 * Purpose:     Convert native double to native long long using
2209
 *              hardware. This is a fast special case.
2210
 *
2211
 * Return:      Non-negative on success/Negative on failure
2212
 *
2213
 *-------------------------------------------------------------------------
2214
 */
2215
herr_t
2216
H5T__conv_double_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2217
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2218
                       void H5_ATTR_UNUSED *bkg)
2219
0
{
2220
0
    H5_WARN_FLOAT_EQUAL_OFF
2221
0
    H5T_CONV_Fx(DOUBLE, LLONG, double, long long, LLONG_MIN, LLONG_MAX);
2222
0
    H5_WARN_FLOAT_EQUAL_ON
2223
0
}
2224
2225
/*-------------------------------------------------------------------------
2226
 * Function:    H5T__conv_double_ullong
2227
 *
2228
 * Purpose:     Convert native double to native unsigned long long using
2229
 *              hardware. This is a fast special case.
2230
 *
2231
 * Return:      Non-negative on success/Negative on failure
2232
 *
2233
 *-------------------------------------------------------------------------
2234
 */
2235
herr_t
2236
H5T__conv_double_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2237
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2238
                        void H5_ATTR_UNUSED *bkg)
2239
0
{
2240
0
    H5_WARN_FLOAT_EQUAL_OFF
2241
0
    H5T_CONV_Fx(DOUBLE, ULLONG, double, unsigned long long, 0, ULLONG_MAX);
2242
0
    H5_WARN_FLOAT_EQUAL_ON
2243
0
}
2244
2245
#ifdef H5_HAVE__FLOAT16
2246
/*-------------------------------------------------------------------------
2247
 * Function:    H5T__conv_double__Float16
2248
 *
2249
 * Purpose:     Convert native double to native _Float16 using hardware.
2250
 *              This is a fast special case.
2251
 *
2252
 * Return:      Non-negative on success/Negative on failure
2253
 *
2254
 *-------------------------------------------------------------------------
2255
 */
2256
herr_t
2257
H5T__conv_double__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
2258
                          const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
2259
                          size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
2260
{
2261
    /* Suppress warning about non-standard floating-point literal suffix */
2262
    H5_WARN_NONSTD_SUFFIX_OFF
2263
    H5T_CONV_Ff(DOUBLE, FLOAT16, double, H5__Float16, -FLT16_MAX, FLT16_MAX);
2264
    H5_WARN_NONSTD_SUFFIX_ON
2265
}
2266
#endif
2267
2268
/*-------------------------------------------------------------------------
2269
 * Function:    H5T__conv_double_float
2270
 *
2271
 * Purpose:     Convert native `double' to native `float' using hardware.
2272
 *              This is a fast special case.
2273
 *
2274
 * Return:      Non-negative on success/Negative on failure
2275
 *
2276
 *-------------------------------------------------------------------------
2277
 */
2278
herr_t
2279
H5T__conv_double_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2280
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2281
                       void H5_ATTR_UNUSED *bkg)
2282
4
{
2283
4
    H5T_CONV_Ff(DOUBLE, FLOAT, double, float, -FLT_MAX, FLT_MAX);
2284
4
}
2285
2286
/*-------------------------------------------------------------------------
2287
 * Function:    H5T__conv_double_ldouble
2288
 *
2289
 * Purpose:     Convert native `double' to native `long double' using
2290
 *              hardware. This is a fast special case.
2291
 *
2292
 * Return:      Non-negative on success/Negative on failure
2293
 *
2294
 *-------------------------------------------------------------------------
2295
 */
2296
herr_t
2297
H5T__conv_double_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2298
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2299
                         void H5_ATTR_UNUSED *bkg)
2300
4
{
2301
4
    H5T_CONV_fF(DOUBLE, LDOUBLE, double, long double, -, -);
2302
4
}
2303
2304
#ifdef H5_HAVE_COMPLEX_NUMBERS
2305
/*-------------------------------------------------------------------------
2306
 * Function:    H5T__conv_double_fcomplex
2307
 *
2308
 * Purpose:     Convert native `double' to native
2309
 *              `float _Complex' / `_Fcomplex' using hardware. This is a
2310
 *              fast special case.
2311
 *
2312
 * Return:      Non-negative on success/Negative on failure
2313
 *
2314
 *-------------------------------------------------------------------------
2315
 */
2316
herr_t
2317
H5T__conv_double_fcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
2318
                          const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
2319
                          size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
2320
4
{
2321
4
    H5T_CONV_Fz(DOUBLE, FLOAT_COMPLEX, double, H5_float_complex, -FLT_MAX, FLT_MAX);
2322
4
}
2323
2324
/*-------------------------------------------------------------------------
2325
 * Function:    H5T__conv_double_dcomplex
2326
 *
2327
 * Purpose:     Convert native `double' to native
2328
 *              `double _Complex' / `_Dcomplex' using hardware. This is a
2329
 *              fast special case.
2330
 *
2331
 * Return:      Non-negative on success/Negative on failure
2332
 *
2333
 *-------------------------------------------------------------------------
2334
 */
2335
herr_t
2336
H5T__conv_double_dcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
2337
                          const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
2338
                          size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
2339
4
{
2340
4
    H5T_CONV_fz(DOUBLE, DOUBLE_COMPLEX, double, H5_double_complex, -, -);
2341
4
}
2342
2343
/*-------------------------------------------------------------------------
2344
 * Function:    H5T__conv_double_lcomplex
2345
 *
2346
 * Purpose:     Convert native `double' to native
2347
 *              `long double _Complex' / `_Lcomplex' using hardware. This
2348
 *              is a fast special case.
2349
 *
2350
 * Return:      Non-negative on success/Negative on failure
2351
 *
2352
 *-------------------------------------------------------------------------
2353
 */
2354
herr_t
2355
H5T__conv_double_lcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
2356
                          const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
2357
                          size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
2358
4
{
2359
4
    H5T_CONV_fZ(DOUBLE, LDOUBLE_COMPLEX, double, H5_ldouble_complex, -, -);
2360
4
}
2361
#endif
2362
2363
/*-------------------------------------------------------------------------
2364
 * Function:    H5T__conv_ldouble_schar
2365
 *
2366
 * Purpose:     Convert native long double to native signed char using
2367
 *              hardware. This is a fast special case.
2368
 *
2369
 * Return:      Non-negative on success/Negative on failure
2370
 *
2371
 *-------------------------------------------------------------------------
2372
 */
2373
herr_t
2374
H5T__conv_ldouble_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2375
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2376
                        void H5_ATTR_UNUSED *bkg)
2377
4
{
2378
4
    H5_WARN_FLOAT_EQUAL_OFF
2379
4
    H5T_CONV_Fx(LDOUBLE, SCHAR, long double, signed char, SCHAR_MIN, SCHAR_MAX);
2380
4
    H5_WARN_FLOAT_EQUAL_ON
2381
4
}
2382
2383
/*-------------------------------------------------------------------------
2384
 * Function:    H5T__conv_ldouble_uchar
2385
 *
2386
 * Purpose:     Convert native long double to native unsigned char using
2387
 *              hardware. This is a fast special case.
2388
 *
2389
 * Return:      Non-negative on success/Negative on failure
2390
 *
2391
 *-------------------------------------------------------------------------
2392
 */
2393
herr_t
2394
H5T__conv_ldouble_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2395
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2396
                        void H5_ATTR_UNUSED *bkg)
2397
4
{
2398
4
    H5_WARN_FLOAT_EQUAL_OFF
2399
4
    H5T_CONV_Fx(LDOUBLE, UCHAR, long double, unsigned char, 0, UCHAR_MAX);
2400
4
    H5_WARN_FLOAT_EQUAL_ON
2401
4
}
2402
2403
/*-------------------------------------------------------------------------
2404
 * Function:    H5T__conv_ldouble_short
2405
 *
2406
 * Purpose:     Convert native long double to native short using
2407
 *              hardware. This is a fast special case.
2408
 *
2409
 * Return:      Non-negative on success/Negative on failure
2410
 *
2411
 *-------------------------------------------------------------------------
2412
 */
2413
herr_t
2414
H5T__conv_ldouble_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2415
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2416
                        void H5_ATTR_UNUSED *bkg)
2417
4
{
2418
4
    H5_WARN_FLOAT_EQUAL_OFF
2419
4
    H5T_CONV_Fx(LDOUBLE, SHORT, long double, short, SHRT_MIN, SHRT_MAX);
2420
4
    H5_WARN_FLOAT_EQUAL_ON
2421
4
}
2422
2423
/*-------------------------------------------------------------------------
2424
 * Function:    H5T__conv_ldouble_ushort
2425
 *
2426
 * Purpose:     Convert native long double to native unsigned short using
2427
 *              hardware. This is a fast special case.
2428
 *
2429
 * Return:      Non-negative on success/Negative on failure
2430
 *
2431
 *-------------------------------------------------------------------------
2432
 */
2433
herr_t
2434
H5T__conv_ldouble_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2435
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2436
                         void H5_ATTR_UNUSED *bkg)
2437
4
{
2438
4
    H5_WARN_FLOAT_EQUAL_OFF
2439
4
    H5T_CONV_Fx(LDOUBLE, USHORT, long double, unsigned short, 0, USHRT_MAX);
2440
4
    H5_WARN_FLOAT_EQUAL_ON
2441
4
}
2442
2443
/*-------------------------------------------------------------------------
2444
 * Function:    H5T__conv_ldouble_int
2445
 *
2446
 * Purpose:     Convert native long double to native int using
2447
 *              hardware. This is a fast special case.
2448
 *
2449
 * Return:      Non-negative on success/Negative on failure
2450
 *
2451
 *-------------------------------------------------------------------------
2452
 */
2453
herr_t
2454
H5T__conv_ldouble_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2455
                      size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2456
                      void H5_ATTR_UNUSED *bkg)
2457
4
{
2458
4
    H5_WARN_FLOAT_EQUAL_OFF
2459
4
    H5T_CONV_Fx(LDOUBLE, INT, long double, int, INT_MIN, INT_MAX);
2460
4
    H5_WARN_FLOAT_EQUAL_ON
2461
4
}
2462
2463
/*-------------------------------------------------------------------------
2464
 * Function:    H5T__conv_ldouble_uint
2465
 *
2466
 * Purpose:     Convert native long double to native unsigned int using
2467
 *              hardware. This is a fast special case.
2468
 *
2469
 * Return:      Non-negative on success/Negative on failure
2470
 *
2471
 *-------------------------------------------------------------------------
2472
 */
2473
herr_t
2474
H5T__conv_ldouble_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2475
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2476
                       void H5_ATTR_UNUSED *bkg)
2477
4
{
2478
4
    H5_WARN_FLOAT_EQUAL_OFF
2479
4
    H5T_CONV_Fx(LDOUBLE, UINT, long double, unsigned int, 0, UINT_MAX);
2480
4
    H5_WARN_FLOAT_EQUAL_ON
2481
4
}
2482
2483
/*-------------------------------------------------------------------------
2484
 * Function:    H5T__conv_ldouble_long
2485
 *
2486
 * Purpose:     Convert native long double to native long using
2487
 *              hardware. This is a fast special case.
2488
 *
2489
 * Return:      Non-negative on success/Negative on failure
2490
 *
2491
 *-------------------------------------------------------------------------
2492
 */
2493
herr_t
2494
H5T__conv_ldouble_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2495
                       size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2496
                       void H5_ATTR_UNUSED *bkg)
2497
4
{
2498
4
    H5_WARN_FLOAT_EQUAL_OFF
2499
4
    H5T_CONV_Fx(LDOUBLE, LONG, long double, long, LONG_MIN, LONG_MAX);
2500
4
    H5_WARN_FLOAT_EQUAL_ON
2501
4
}
2502
2503
/*-------------------------------------------------------------------------
2504
 * Function:    H5T__conv_ldouble_ulong
2505
 *
2506
 * Purpose:     Convert native long double to native unsigned long using
2507
 *              hardware. This is a fast special case.
2508
 *
2509
 * Return:      Non-negative on success/Negative on failure
2510
 *
2511
 *-------------------------------------------------------------------------
2512
 */
2513
herr_t
2514
H5T__conv_ldouble_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2515
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2516
                        void H5_ATTR_UNUSED *bkg)
2517
4
{
2518
4
    H5_WARN_FLOAT_EQUAL_OFF
2519
4
    H5T_CONV_Fx(LDOUBLE, ULONG, long double, unsigned long, 0, ULONG_MAX);
2520
4
    H5_WARN_FLOAT_EQUAL_ON
2521
4
}
2522
2523
/*-------------------------------------------------------------------------
2524
 * Function:    H5T__conv_ldouble_llong
2525
 *
2526
 * Purpose:     Convert native long double to native long long using
2527
 *              hardware. This is a fast special case.
2528
 *
2529
 * Return:      Non-negative on success/Negative on failure
2530
 *
2531
 *-------------------------------------------------------------------------
2532
 */
2533
#ifdef H5T_CONV_INTERNAL_LDOUBLE_LLONG
2534
herr_t
2535
H5T__conv_ldouble_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2536
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2537
                        void H5_ATTR_UNUSED *bkg)
2538
0
{
2539
0
    H5_WARN_FLOAT_EQUAL_OFF
2540
0
    H5T_CONV_Fx(LDOUBLE, LLONG, long double, long long, LLONG_MIN, LLONG_MAX);
2541
0
    H5_WARN_FLOAT_EQUAL_ON
2542
0
}
2543
#endif /*H5T_CONV_INTERNAL_LDOUBLE_LLONG*/
2544
2545
/*-------------------------------------------------------------------------
2546
 * Function:    H5T__conv_ldouble_ullong
2547
 *
2548
 * Purpose:     Convert native long double to native unsigned long long using
2549
 *              hardware. This is a fast special case.
2550
 *
2551
 * Return:      Non-negative on success/Negative on failure
2552
 *
2553
 *-------------------------------------------------------------------------
2554
 */
2555
#ifdef H5T_CONV_INTERNAL_LDOUBLE_ULLONG
2556
herr_t
2557
H5T__conv_ldouble_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2558
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2559
                         void H5_ATTR_UNUSED *bkg)
2560
0
{
2561
0
    H5_WARN_FLOAT_EQUAL_OFF
2562
0
    H5T_CONV_Fx(LDOUBLE, ULLONG, long double, unsigned long long, 0, ULLONG_MAX);
2563
0
    H5_WARN_FLOAT_EQUAL_ON
2564
0
}
2565
#endif /*H5T_CONV_INTERNAL_LDOUBLE_ULLONG*/
2566
2567
#ifdef H5_HAVE__FLOAT16
2568
#ifdef H5T_CONV_INTERNAL_LDOUBLE_FLOAT16
2569
/*-------------------------------------------------------------------------
2570
 * Function:    H5T__conv_ldouble__Float16
2571
 *
2572
 * Purpose:     Convert native long double to native _Float16 using
2573
 *              hardware. This is a fast special case.
2574
 *
2575
 * Return:      Non-negative on success/Negative on failure
2576
 *
2577
 *-------------------------------------------------------------------------
2578
 */
2579
herr_t
2580
H5T__conv_ldouble__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
2581
                           const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
2582
                           size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
2583
{
2584
    /* Suppress warning about non-standard floating-point literal suffix */
2585
    H5_WARN_NONSTD_SUFFIX_OFF
2586
    H5T_CONV_Ff(LDOUBLE, FLOAT16, long double, H5__Float16, -FLT16_MAX, FLT16_MAX);
2587
    H5_WARN_NONSTD_SUFFIX_ON
2588
}
2589
#endif
2590
#endif
2591
2592
/*-------------------------------------------------------------------------
2593
 * Function:    H5T__conv_ldouble_float
2594
 *
2595
 * Purpose:     Convert native `long double' to native `float' using
2596
 *              hardware. This is a fast special case.
2597
 *
2598
 * Return:      Non-negative on success/Negative on failure
2599
 *
2600
 *-------------------------------------------------------------------------
2601
 */
2602
herr_t
2603
H5T__conv_ldouble_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2604
                        size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2605
                        void H5_ATTR_UNUSED *bkg)
2606
4
{
2607
4
    H5T_CONV_Ff(LDOUBLE, FLOAT, long double, float, -FLT_MAX, FLT_MAX);
2608
4
}
2609
2610
/*-------------------------------------------------------------------------
2611
 * Function:    H5T__conv_ldouble_double
2612
 *
2613
 * Purpose:     Convert native `long double' to native `double' using
2614
 *              hardware. This is a fast special case.
2615
 *
2616
 * Return:      Non-negative on success/Negative on failure
2617
 *
2618
 *-------------------------------------------------------------------------
2619
 */
2620
herr_t
2621
H5T__conv_ldouble_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx,
2622
                         size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf,
2623
                         void H5_ATTR_UNUSED *bkg)
2624
4
{
2625
4
    H5T_CONV_Ff(LDOUBLE, DOUBLE, long double, double, -DBL_MAX, DBL_MAX);
2626
4
}
2627
2628
#ifdef H5_HAVE_COMPLEX_NUMBERS
2629
/*-------------------------------------------------------------------------
2630
 * Function:    H5T__conv_ldouble_fcomplex
2631
 *
2632
 * Purpose:     Convert native `long double' to native
2633
 *              `float _Complex' / `_Fcomplex' using hardware. This is a
2634
 *              fast special case.
2635
 *
2636
 * Return:      Non-negative on success/Negative on failure
2637
 *
2638
 *-------------------------------------------------------------------------
2639
 */
2640
herr_t
2641
H5T__conv_ldouble_fcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
2642
                           const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
2643
                           size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
2644
4
{
2645
4
    H5T_CONV_Fz(LDOUBLE, FLOAT_COMPLEX, long double, H5_float_complex, -FLT_MAX, FLT_MAX);
2646
4
}
2647
2648
/*-------------------------------------------------------------------------
2649
 * Function:    H5T__conv_ldouble_dcomplex
2650
 *
2651
 * Purpose:     Convert native `long double' to native
2652
 *              `double _Complex' / `_Dcomplex' using hardware. This is a
2653
 *              fast special case.
2654
 *
2655
 * Return:      Non-negative on success/Negative on failure
2656
 *
2657
 *-------------------------------------------------------------------------
2658
 */
2659
herr_t
2660
H5T__conv_ldouble_dcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
2661
                           const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
2662
                           size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
2663
4
{
2664
4
    H5T_CONV_Fz(LDOUBLE, DOUBLE_COMPLEX, long double, H5_double_complex, -DBL_MAX, DBL_MAX);
2665
4
}
2666
2667
/*-------------------------------------------------------------------------
2668
 * Function:    H5T__conv_ldouble_lcomplex
2669
 *
2670
 * Purpose:     Convert native `long double' to native
2671
 *              `long double _Complex' / `_Lcomplex' using hardware. This
2672
 *              is a fast special case.
2673
 *
2674
 * Return:      Non-negative on success/Negative on failure
2675
 *
2676
 *-------------------------------------------------------------------------
2677
 */
2678
herr_t
2679
H5T__conv_ldouble_lcomplex(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata,
2680
                           const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
2681
                           size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
2682
4
{
2683
    H5T_CONV_fz(LDOUBLE, LDOUBLE_COMPLEX, long double, H5_ldouble_complex, -, -);
2684
4
}
2685
#endif