Coverage Report

Created: 2024-06-18 06:29

/src/hdf5/src/H5Torder.c
Line
Count
Source (jump to first uncovered line)
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the COPYING file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*
14
 * Module Info: This module contains the functionality for setting & querying
15
 *      the datatype byte order for the H5T interface.
16
 */
17
18
/****************/
19
/* Module Setup */
20
/****************/
21
22
#include "H5Tmodule.h" /* This source code file is part of the H5T module */
23
24
/***********/
25
/* Headers */
26
/***********/
27
#include "H5private.h"  /* Generic Functions      */
28
#include "H5Eprivate.h" /* Error handling       */
29
#include "H5Iprivate.h" /* IDs            */
30
#include "H5Tpkg.h"     /* Datatypes        */
31
32
/****************/
33
/* Local Macros */
34
/****************/
35
36
/******************/
37
/* Local Typedefs */
38
/******************/
39
40
/********************/
41
/* Package Typedefs */
42
/********************/
43
44
/********************/
45
/* Local Prototypes */
46
/********************/
47
static herr_t H5T__set_order(H5T_t *dtype, H5T_order_t order);
48
49
/*********************/
50
/* Public Variables */
51
/*********************/
52
53
/*********************/
54
/* Package Variables */
55
/*********************/
56
57
/*****************************/
58
/* Library Private Variables */
59
/*****************************/
60
61
/*******************/
62
/* Local Variables */
63
/*******************/
64
65
/*-------------------------------------------------------------------------
66
 * Function:  H5Tget_order
67
 *
68
 * Purpose: Returns the byte order of a datatype.
69
 *
70
 * Return:  Success:  A byte order constant.  If the type is compound
71
 *        and its members have mixed orders, this function
72
 *        returns H5T_ORDER_MIXED.
73
 *    Failure:  H5T_ORDER_ERROR (Negative)
74
 *
75
 *-------------------------------------------------------------------------
76
 */
77
H5T_order_t
78
H5Tget_order(hid_t type_id)
79
0
{
80
0
    H5T_t      *dt;        /* Datatype to query */
81
0
    H5T_order_t ret_value; /* Return value */
82
83
0
    FUNC_ENTER_API(H5T_ORDER_ERROR)
84
85
    /* Check args */
86
0
    if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
87
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, H5T_ORDER_ERROR, "not a datatype");
88
89
    /* Get order */
90
0
    if (H5T_ORDER_ERROR == (ret_value = H5T_get_order(dt)))
91
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, H5T_ORDER_ERROR, "can't get order for specified datatype");
92
93
0
done:
94
0
    FUNC_LEAVE_API(ret_value)
95
0
} /* end H5Tget_order() */
96
97
/*-------------------------------------------------------------------------
98
 * Function:  H5T_get_order
99
 *
100
 * Purpose: Returns the byte order of a datatype.
101
 *
102
 * Return:  Success:  A byte order constant
103
 *    Failure:  H5T_ORDER_ERROR (Negative)
104
 *
105
 *-------------------------------------------------------------------------
106
 */
107
H5T_order_t
108
H5T_get_order(const H5T_t *dtype)
109
0
{
110
0
    H5T_order_t ret_value = H5T_ORDER_NONE; /* Return value */
111
112
0
    FUNC_ENTER_NOAPI(H5T_ORDER_ERROR)
113
114
    /* Defer to parent */
115
0
    while (dtype->shared->parent)
116
0
        dtype = dtype->shared->parent;
117
118
    /* Set order for atomic type. */
119
0
    if (H5T_IS_ATOMIC(dtype->shared))
120
0
        ret_value = dtype->shared->u.atomic.order;
121
0
    else {
122
        /* Check for compound datatype */
123
0
        if (H5T_COMPOUND == dtype->shared->type) {
124
0
            H5T_order_t memb_order = H5T_ORDER_NONE;
125
0
            int         nmemb; /* Number of members in compound & enum types */
126
0
            int         i;     /* Local index variable */
127
128
            /* Retrieve the number of members */
129
0
            if ((nmemb = H5T_get_nmembers(dtype)) < 0)
130
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_ORDER_ERROR,
131
0
                            "can't get number of members from compound data type");
132
133
            /* Get order for each compound member type. */
134
0
            for (i = 0; i < nmemb; i++) {
135
                /* Get order for member */
136
0
                if ((memb_order = H5T_get_order(dtype->shared->u.compnd.memb[i].type)) == H5T_ORDER_ERROR)
137
0
                    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5T_ORDER_ERROR,
138
0
                                "can't get order for compound member");
139
140
                /* Ignore the H5T_ORDER_NONE, write down the first non H5T_ORDER_NONE order. */
141
0
                if (memb_order != H5T_ORDER_NONE && ret_value == H5T_ORDER_NONE)
142
0
                    ret_value = memb_order;
143
144
                /* If the orders are mixed, stop the loop and report it.
145
                 * (H5T_ORDER_NONE is ignored)
146
                 */
147
0
                if (memb_order != H5T_ORDER_NONE && ret_value != H5T_ORDER_NONE && memb_order != ret_value) {
148
0
                    ret_value = H5T_ORDER_MIXED;
149
0
                    break;
150
0
                } /* end if */
151
0
            }     /* end for */
152
0
        }         /* end if */
153
0
    }             /* end else */
154
155
0
done:
156
0
    FUNC_LEAVE_NOAPI(ret_value)
157
0
} /* end H5T_get_order() */
158
159
/*-------------------------------------------------------------------------
160
 * Function:  H5Tset_order
161
 *
162
 * Purpose: Sets the byte order for a datatype.
163
 *
164
 * Notes: There are some restrictions on this operation:
165
 *    1. For enum type, members shouldn't be defined yet.
166
 *    2. H5T_ORDER_NONE only works for reference and fixed-length
167
 *      string.
168
 *    3. For opaque type, the order will be ignored.
169
 *    4. For compound type, all restrictions above apply to the
170
 *      members.
171
 *
172
 * Return:  Non-negative on success/Negative on failure
173
 *
174
 *-------------------------------------------------------------------------
175
 */
176
herr_t
177
H5Tset_order(hid_t type_id, H5T_order_t order)
178
0
{
179
0
    H5T_t *dt        = NULL;    /* Datatype to modify */
180
0
    herr_t ret_value = SUCCEED; /* Return value */
181
182
0
    FUNC_ENTER_API(FAIL)
183
184
    /* Check args */
185
0
    if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
186
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype");
187
0
    if (order < H5T_ORDER_LE || order > H5T_ORDER_NONE || order == H5T_ORDER_MIXED)
188
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "illegal byte order");
189
0
    if (NULL != dt->vol_obj)
190
0
        HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is already committed");
191
0
    if (H5T_STATE_TRANSIENT != dt->shared->state)
192
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype is read-only");
193
194
    /* Call internal routine to set the order */
195
0
    if (H5T__set_order(dt, order) < 0)
196
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "can't set order");
197
198
0
done:
199
0
    FUNC_LEAVE_API(ret_value)
200
0
} /* end H5Tset_order() */
201
202
/*-------------------------------------------------------------------------
203
 * Function:  H5T__set_order
204
 *
205
 * Purpose: Private function to set the byte order for a datatype.
206
 *
207
 * Return:  Non-negative on success/Negative on failure
208
 *
209
 *-------------------------------------------------------------------------
210
 */
211
static herr_t
212
H5T__set_order(H5T_t *dtype, H5T_order_t order)
213
0
{
214
0
    herr_t ret_value = SUCCEED; /* Return value */
215
216
0
    FUNC_ENTER_PACKAGE
217
218
0
    if (H5T_ENUM == dtype->shared->type && dtype->shared->u.enumer.nmembs > 0)
219
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "operation not allowed after enum members are defined");
220
221
    /* For derived data type, defer to parent */
222
0
    while (dtype->shared->parent)
223
0
        dtype = dtype->shared->parent;
224
225
    /* Check for setting order on inappropriate datatype */
226
0
    if (order == H5T_ORDER_NONE && !(H5T_REFERENCE == dtype->shared->type ||
227
0
                                     H5T_OPAQUE == dtype->shared->type || H5T_IS_FIXED_STRING(dtype->shared)))
228
0
        HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "illegal byte order for type");
229
230
    /* For atomic data type */
231
0
    if (H5T_IS_ATOMIC(dtype->shared))
232
0
        dtype->shared->u.atomic.order = order;
233
0
    else {
234
        /* Check for compound datatype */
235
0
        if (H5T_COMPOUND == dtype->shared->type) {
236
0
            int nmemb; /* Number of members in type */
237
0
            int i;     /* Local index variable */
238
239
            /* Retrieve the number of fields in the compound datatype */
240
0
            if ((nmemb = H5T_get_nmembers(dtype)) < 0)
241
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL,
242
0
                            "can't get number of members from compound data type");
243
244
            /* Check for uninitialized compound datatype */
245
0
            if (nmemb == 0)
246
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNINITIALIZED, FAIL, "no member is in the compound data type");
247
248
            /* Loop through all fields of compound type, setting the order */
249
0
            for (i = 0; i < nmemb; i++)
250
0
                if (H5T__set_order(dtype->shared->u.compnd.memb[i].type, order) < 0)
251
0
                    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set order for compound member");
252
0
        } /* end if */
253
0
    }     /* end else */
254
255
0
done:
256
0
    FUNC_LEAVE_NOAPI(ret_value)
257
0
} /* end H5T__set_order() */