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() */ |